diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 0134c5a21d..cbf40d445a 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 1.6.0 +current_version = 1.13.0 commit = False tag = False @@ -9,9 +9,9 @@ tag = False [bumpversion:file:packages/ai-components/package.json] -[bumpversion:file:packages/core/package.json] +[bumpversion:file:packages/components/package.json] -[bumpversion:file:packages/datasheet/package.json] +[bumpversion:file:packages/core/package.json] [bumpversion:file:packages/cypress/package.json] @@ -21,7 +21,7 @@ tag = False [bumpversion:file:packages/databus-wasm-web/package.json] -[bumpversion:file:packages/components/package.json] +[bumpversion:file:packages/datasheet/package.json] [bumpversion:file:packages/i18n-lang/package.json] diff --git a/.eslintrc b/.eslintrc index 5fa14786a6..df236d0e79 100644 --- a/.eslintrc +++ b/.eslintrc @@ -2,7 +2,7 @@ "root": true, "parser": "@typescript-eslint/parser", "plugins": ["vika", "@typescript-eslint", "react-hooks", "react"], - "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"], + "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"], "rules": { "@typescript-eslint/no-var-requires": 0, "vika/use-t-function": 0, diff --git a/.github/linters/.jscpd.json b/.github/linters/.jscpd.json index 17bb7941ec..cd59df1f47 100644 --- a/.github/linters/.jscpd.json +++ b/.github/linters/.jscpd.json @@ -1,5 +1,5 @@ { - "threshold": 25, + "threshold": 40, "reporters": [ "consoleFull" ], diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 373cd1f830..263918e564 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -22,7 +22,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Fetch Sources - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Node.js uses: actions/setup-node@v3 with: @@ -31,7 +31,7 @@ jobs: with: version: 8.7.5 - name: Set up JDK - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '17' distribution: 'corretto' @@ -57,7 +57,7 @@ jobs: matrix: command: [ test-init-db-docker, test-ut-backend-docker, test-ut-room-docker, _test-ut-core ] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Node.js uses: actions/setup-node@v3 with: @@ -66,7 +66,7 @@ jobs: with: version: 8.7.5 - name: Set up JDK - uses: actions/setup-java@v3 + uses: actions/setup-java@v4 with: java-version: '17' distribution: 'corretto' @@ -88,7 +88,7 @@ jobs: APITABLE_DOCKER_HUB_TOKEN: ${{ secrets.APITABLE_DOCKER_HUB_TOKEN }} steps: - name: Fetch Sources - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up QEMU uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx @@ -107,7 +107,7 @@ jobs: APITABLE_DOCKER_HUB_TOKEN: ${{ secrets.APITABLE_DOCKER_HUB_TOKEN }} steps: - name: Fetch Sources - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Build APITable and Push run: | cp -pr gateway/ packaging/all-in-one/all-in-one/ @@ -127,7 +127,7 @@ jobs: APITABLE_DOCKER_HUB_TOKEN: ${{ secrets.APITABLE_DOCKER_HUB_TOKEN }} steps: - name: Fetch Sources - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up QEMU uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 2f0470abbb..794be62cff 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -27,77 +27,77 @@ jobs: contents: read security-events: write steps: - - name: Checkout repository - uses: actions/checkout@v3 - - name: Set up JDK - uses: actions/setup-java@v3 - with: - java-version: '17' - distribution: 'corretto' - cache: 'gradle' - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v2 - with: - languages: java - - run: | - make _build-java - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 - with: - category: "/language:java" - -# analyze-js-core: -# name: Analyze (javascript-core) -# runs-on: ubuntu-latest -# permissions: -# actions: read -# contents: read -# security-events: write -# steps: -# - name: Checkout repository -# uses: actions/checkout@v3 -# # Initializes the CodeQL tools for scanning. -# - name: Initialize CodeQL -# uses: github/codeql-action/init@v2 -# with: -# languages: javascript -# - run: | -# make _build-core -# - name: Perform CodeQL Analysis -# uses: github/codeql-action/analyze@v2 -# with: -# category: "/language:javascript" - -# analyze-js-room: -# name: Analyze (javascript-room) -# runs-on: ubuntu-latest -# permissions: -# actions: read -# contents: read -# security-events: write -# steps: -# - name: Checkout repository -# uses: actions/checkout@v3 -# - name: Install build-essential -# run: sudo apt-get update -y && sudo apt-get install -y build-essential -# - name: Set up Rust -# uses: actions-rs/toolchain@v1 -# with: -# toolchain: nightly -# profile: minimal -# override: true -# # Initializes the CodeQL tools for scanning. -# - name: Initialize CodeQL -# uses: github/codeql-action/init@v2 -# with: -# languages: javascript -# - run: | -# make _build-room -# - name: Perform CodeQL Analysis -# uses: github/codeql-action/analyze@v2 -# with: -# category: "/language:javascript" + - name: Checkout repository + uses: actions/checkout@v4 + - name: Set up JDK + uses: actions/setup-java@v4 + with: + java-version: '17' + distribution: 'corretto' + cache: 'gradle' + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v2 + with: + languages: java + - run: | + make _build-java + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v2 + with: + category: "/language:java" + + # analyze-js-core: + # name: Analyze (javascript-core) + # runs-on: ubuntu-latest + # permissions: + # actions: read + # contents: read + # security-events: write + # steps: + # - name: Checkout repository + # uses: actions/checkout@v4 + # # Initializes the CodeQL tools for scanning. + # - name: Initialize CodeQL + # uses: github/codeql-action/init@v2 + # with: + # languages: javascript + # - run: | + # make _build-core + # - name: Perform CodeQL Analysis + # uses: github/codeql-action/analyze@v2 + # with: + # category: "/language:javascript" + + # analyze-js-room: + # name: Analyze (javascript-room) + # runs-on: ubuntu-latest + # permissions: + # actions: read + # contents: read + # security-events: write + # steps: + # - name: Checkout repository + # uses: actions/checkout@v4 + # - name: Install build-essential + # run: sudo apt-get update -y && sudo apt-get install -y build-essential + # - name: Set up Rust + # uses: actions-rs/toolchain@v1 + # with: + # toolchain: nightly + # profile: minimal + # override: true + # # Initializes the CodeQL tools for scanning. + # - name: Initialize CodeQL + # uses: github/codeql-action/init@v2 + # with: + # languages: javascript + # - run: | + # make _build-room + # - name: Perform CodeQL Analysis + # uses: github/codeql-action/analyze@v2 + # with: + # category: "/language:javascript" # analyze-js-web: # name: Analyze (javascript-web) @@ -108,7 +108,7 @@ jobs: # security-events: write # steps: # - name: Checkout repository - # uses: actions/checkout@v3 + # uses: actions/checkout@v4 # # Initializes the CodeQL tools for scanning. # - name: Initialize CodeQL # uses: github/codeql-action/init@v2 @@ -140,7 +140,7 @@ jobs: # steps: # - name: Checkout repository - # uses: actions/checkout@v3 + # uses: actions/checkout@v4 # # Initializes the CodeQL tools for scanning. # - name: Initialize CodeQL diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 69aa8068e6..b0f0f4eb71 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -5,7 +5,7 @@ # Source repository: https://github.com/actions/dependency-review-action # Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement name: 'Dependency Review' -on: [pull_request] +on: [ pull_request ] permissions: contents: read @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest steps: - name: 'Checkout Repository' - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: 'Dependency Review' uses: actions/dependency-review-action@v2 with: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 9c9dc124cd..0e9e63495e 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -30,7 +30,7 @@ jobs: actions: read steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Node.js uses: actions/setup-node@v3 with: @@ -74,7 +74,7 @@ jobs: # Checkout the code base # ########################## - name: Checkout Code - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: # Full git history is needed to get a proper # list of changed files within `super-linter` @@ -106,3 +106,4 @@ jobs: JAVA_FILE_NAME: checkstyle.xml VALIDATE_SHELL_SHFMT: false VALIDATE_DOCKERFILE_HADOLINT: false + VALIDATE_JSCPD: false diff --git a/.gitignore b/.gitignore index 83a6a32176..01c451c9c8 100644 --- a/.gitignore +++ b/.gitignore @@ -95,6 +95,8 @@ eslint-results.sarif /packages/room-native-api/Cargo.lock # openapi generated -/backend-server/application/.openapi-generator/ +/backend-server/shared/starters/databus/.openapi-generator/ .nx + +/scripts/enterprise diff --git a/.gitpod.yml b/.gitpod.yml index 38a4dc3908..4f730bbcd3 100644 --- a/.gitpod.yml +++ b/.gitpod.yml @@ -5,7 +5,7 @@ image: tasks: - name: install dependency init: | - npm install -g pnpm + npm install -g pnpm@8.13.1 make install command: | echo "Happy Coding" diff --git a/.husky/pre-commit b/.husky/pre-commit index 3d9decf774..6fb808431a 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -10,5 +10,3 @@ function check_forbidden_folder() { fi } -npx git-format-staged -f 'prettier --ignore-unknown --stdin-filepath "{}"' "*.ts,*.tsx" - diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000000..ab98950d85 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,6 @@ + +**/*.json +**/*.yaml +**/*.yml + +**/*.*.json diff --git a/.prettierrc b/.prettierrc index a03ce771ee..13bf0b1bf8 100644 --- a/.prettierrc +++ b/.prettierrc @@ -4,6 +4,6 @@ "semi": true, "singleQuote": true, "tabWidth": 2, - "trailingComma": "all", + "trailingComma": "es5", "useTabs": false -} \ No newline at end of file +} diff --git a/.version b/.version index dc1e644a10..feaae22bac 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -1.6.0 +1.13.0 diff --git a/.vscode/settings.json b/.vscode/settings.json index 6ff325f6e3..c13dd11bb9 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,7 @@ { "typescript.tsdk": ".yarn/sdks/typescript/lib", "editor.codeActionsOnSave": { - "source.fixAll.eslint": true + "source.fixAll.eslint": "explicit" }, "editor.formatOnSave": false, "[typescriptreact]": { diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ce2d4bfa0..0c378559d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,909 +1,988 @@ # APITable CHANGELOG -## [v1.6.0-beta.1](https://github.com/apitable/apitable/releases/tag/v1.6.0-beta.1) (2023-12-11) +## [v1.10.0-beta.3](https://github.com/apitable/apitable/releases/tag/v1.10.0-beta.3) (2024-05-06) + + +### What's more + +* sync: hosted cloud ([#1734](https://github.com/apitable/apitable/pull/1734)) @zoe-icu +* refactor: add changelog ([#1721](https://github.com/apitable/apitable/pull/1721)) @zoe-icu +* chore: upgrade mysql2 ([#11084](https://github.com/apitable/apitable/pull/1734/commits/d299e369b8047f577e915adfe3b627317af3028c)) @zoe-icu +## [v1.10.0-beta.2](https://github.com/apitable/apitable/releases/tag/v1.10.0-beta.2) (2024-04-17) ### Bug fixes -* fix: env IS_SELFHOST default true ([#1515](https://github.com/apitable/apitable/pull/1515)) @wangkailang +* fix: delete automation trigger ([#1657](https://github.com/apitable/apitable/pull/1657)) @zoe-icu ### What's more -* chore: tune gitpod dockerfile ([#1509](https://github.com/apitable/apitable/pull/1509)) @ChambersChan -* sync: hosted cloud ([#1519](https://github.com/apitable/apitable/pull/1519)) @JoverZhang -## [v1.6.0-beta](https://github.com/apitable/apitable/releases/tag/v1.6.0-beta) (2023-12-04) +* sync: hosted cloud ([#1720](https://github.com/apitable/apitable/pull/1720)) @zoe-icu +## [v1.10.0-beta](https://github.com/apitable/apitable/releases/tag/v1.10.0-beta) (2024-03-11) + + +### What's more + +* sync: hosted cloud ([#1652](https://github.com/apitable/apitable/pull/1652)) @ChambersChan +## [v1.9.0-beta](https://github.com/apitable/apitable/releases/tag/v1.9.0-beta) (2024-01-29) ### Bug fixes -* fix: room-server start error ([#1505](https://github.com/apitable/apitable/pull/1505)) @chalme -* fix: csrf filter ([#1506](https://github.com/apitable/apitable/pull/1506)) @ChambersChan +* fix: usage warn func ([#1573](https://github.com/apitable/apitable/pull/1573)) @wangkailang ### What's more -* sync: hosted cloud ([#1503](https://github.com/apitable/apitable/pull/1503)) @chalme -## [v1.5.0-beta.1](https://github.com/apitable/apitable/releases/tag/v1.5.0-beta.1) (2023-11-27) +* sync: hosted cloud ([#1571](https://github.com/apitable/apitable/pull/1571)) @chalme +* chore: changelog update ([#1574](https://github.com/apitable/apitable/pull/1574)) @chalme +* Sync/hosted ([#1581](https://github.com/apitable/apitable/pull/1581)) @jeremyyin2012 +* chore: changelog update ([#1583](https://github.com/apitable/apitable/pull/1583)) @jeremyyin2012 +* sync: hosted cloud ([#1592](https://github.com/apitable/apitable/pull/1592)) @JoverZhang +## [v1.8.0-beta.3](https://github.com/apitable/apitable/releases/tag/v1.8.0-beta.3) (2024-01-23) ### What's more -* sync: hosted cloud ([#1481](https://github.com/apitable/apitable/pull/1481)) @shawndenggh +* Sync/hosted ([#1581](https://github.com/apitable/apitable/pull/1581)) @jeremyyin2012 +## [v1.8.0-beta.2](https://github.com/apitable/apitable/releases/tag/v1.8.0-beta.2) (2024-01-15) -## [v1.5.0-beta](https://github.com/apitable/apitable/releases/tag/v1.5.0-beta) (2023-11-20) +### Bug fixes + +* fix: usage warn func ([#1573](https://github.com/apitable/apitable/pull/1573)) @wangkailang ### What's more -* sync: hosted cloud ([#1469](https://github.com/apitable/apitable/pull/1469)) @robot518 +* sync: hosted cloud ([#1571](https://github.com/apitable/apitable/pull/1571)) @chalme +## [v1.8.0-beta.1](https://github.com/apitable/apitable/releases/tag/v1.8.0-beta.1) (2024-01-08) -## [v1.4.0-beta.3](https://github.com/apitable/apitable/releases/tag/v1.4.0-beta.3) (2023-11-13) +### What's more + +* sync: hosted cloud ([#1561](https://github.com/apitable/apitable/pull/1561)) @robot518 +## [v1.8.0-beta](https://github.com/apitable/apitable/releases/tag/v1.8.0-beta) (2024-01-02) + +### Bug fixes + +- fix: func undefined check ([#1542](https://github.com/apitable/apitable/pull/1542)) @wangkailang +- fix: usage warn func check ([#1555](https://github.com/apitable/apitable/pull/1555)) @wangkailang + +### What's more + +- refactor: use_responsive hook ([#1419](https://github.com/apitable/apitable/pull/1419)) @liaoliao666 +- sync: hosted cloud ([#1540](https://github.com/apitable/apitable/pull/1540)) @ChambersChan +- docs: changelog for v1.7.0 ([#1544](https://github.com/apitable/apitable/pull/1544)) @ChambersChan +- sync: hosted cloud ([#1553](https://github.com/apitable/apitable/pull/1553)) @zoe-icu + +## [v1.7.0-beta.1](https://github.com/apitable/apitable/releases/tag/v1.7.0-beta.1) (2023-12-25) + +### Bug fixes + +- fix: func undefined check ([#1542](https://github.com/apitable/apitable/pull/1542)) @wangkailang + +### What's more + +- refactor: use_responsive hook ([#1419](https://github.com/apitable/apitable/pull/1419)) @liaoliao666 +- sync: hosted cloud ([#1540](https://github.com/apitable/apitable/pull/1540)) @ChambersChan + +## [v1.7.0-beta](https://github.com/apitable/apitable/releases/tag/v1.7.0-beta) (2023-12-18) + +### What's more + +- docs: update readme.md ([#1523](https://github.com/apitable/apitable/pull/1523)) @ChambersChan +- sync: hosted cloud ([#1528](https://github.com/apitable/apitable/pull/1528)) @jeremyyin2012 + +## [v1.6.0-beta.1](https://github.com/apitable/apitable/releases/tag/v1.6.0-beta.1) (2023-12-11) + +### Bug fixes + +- fix: env IS_SELFHOST default true ([#1515](https://github.com/apitable/apitable/pull/1515)) @wangkailang + +### What's more + +- chore: tune gitpod dockerfile ([#1509](https://github.com/apitable/apitable/pull/1509)) @ChambersChan +- sync: hosted cloud ([#1519](https://github.com/apitable/apitable/pull/1519)) @JoverZhang + +## [v1.6.0-beta](https://github.com/apitable/apitable/releases/tag/v1.6.0-beta) (2023-12-04) + +### Bug fixes + +- fix: room-server start error ([#1505](https://github.com/apitable/apitable/pull/1505)) @chalme +- fix: csrf filter ([#1506](https://github.com/apitable/apitable/pull/1506)) @ChambersChan + +### What's more + +- sync: hosted cloud ([#1503](https://github.com/apitable/apitable/pull/1503)) @chalme + +## [v1.5.0-beta.1](https://github.com/apitable/apitable/releases/tag/v1.5.0-beta.1) (2023-11-27) + +### What's more + +- sync: hosted cloud ([#1481](https://github.com/apitable/apitable/pull/1481)) @shawndenggh + +## [v1.5.0-beta](https://github.com/apitable/apitable/releases/tag/v1.5.0-beta) (2023-11-20) + +### What's more + +- sync: hosted cloud ([#1469](https://github.com/apitable/apitable/pull/1469)) @robot518 + +## [v1.4.0-beta.3](https://github.com/apitable/apitable/releases/tag/v1.4.0-beta.3) (2023-11-13) ### Features and enhancements -* feat: gen ce api client module ([#1445](https://github.com/apitable/apitable/pull/1445)) @ranglang -* feat: change contactus url ([#1454](https://github.com/apitable/apitable/pull/1454)) @yo-ooiii +- feat: gen ce api client module ([#1445](https://github.com/apitable/apitable/pull/1445)) @ranglang +- feat: change contactus url ([#1454](https://github.com/apitable/apitable/pull/1454)) @yo-ooiii ### Bug fixes -* fix: workdoc with env ([#1463](https://github.com/apitable/apitable/pull/1463)) @wangkailang +- fix: workdoc with env ([#1463](https://github.com/apitable/apitable/pull/1463)) @wangkailang ### What's more -* sync: hosted cloud ([#1460](https://github.com/apitable/apitable/pull/1460)) @ziqiangai -## [v1.4.0-beta.2](https://github.com/apitable/apitable/releases/tag/v1.4.0-beta.2) (2023-11-06) +- sync: hosted cloud ([#1460](https://github.com/apitable/apitable/pull/1460)) @ziqiangai +## [v1.4.0-beta.2](https://github.com/apitable/apitable/releases/tag/v1.4.0-beta.2) (2023-11-06) ### What's more -* chore: fix all-in-one pnpm canvas path ([#1431](https://github.com/apitable/apitable/pull/1431)) @networkhermit -* merge Release/1.4.0 fix back develop ([#1437](https://github.com/apitable/apitable/pull/1437)) @jeremyyin2012 -* sync: hosted cloud ([#1440](https://github.com/apitable/apitable/pull/1440)) @chalme +- chore: fix all-in-one pnpm canvas path ([#1431](https://github.com/apitable/apitable/pull/1431)) @networkhermit +- merge Release/1.4.0 fix back develop ([#1437](https://github.com/apitable/apitable/pull/1437)) @jeremyyin2012 +- sync: hosted cloud ([#1440](https://github.com/apitable/apitable/pull/1440)) @chalme ## [v1.4.0-beta.1](https://github.com/apitable/apitable/releases/tag/v1.4.0-beta.1) (2023-10-31) - ### What's more -* fix: ai components build by ([#1430](https://github.com/apitable/apitable/pull/1430)) @jeremyyin2012 +- fix: ai components build by ([#1430](https://github.com/apitable/apitable/pull/1430)) @jeremyyin2012 ## [v1.4.0-beta](https://github.com/apitable/apitable/releases/tag/v1.4.0-beta) (2023-10-30) - ### Bug fixes -* fix: welcome crash ([#1429](https://github.com/apitable/apitable/pull/1429)) @wangkailang +- fix: welcome crash ([#1429](https://github.com/apitable/apitable/pull/1429)) @wangkailang ### What's more -* docs: add one-click-deploy link @jbgh -* add Dome one-click badge @jbgh -* docs: add one-click-deploy link ([#1378](https://github.com/apitable/apitable/pull/1378)) @paylm -* sync: hosted cloud ([#1407](https://github.com/apitable/apitable/pull/1407)) @shawndenggh -* sync: hosted cloud ([#1427](https://github.com/apitable/apitable/pull/1427)) @jeremyyin2012 -## [v1.3.0-beta.1](https://github.com/apitable/apitable/releases/tag/v1.3.0-beta.1) (2023-10-17) +- docs: add one-click-deploy link @jbgh +- add Dome one-click badge @jbgh +- docs: add one-click-deploy link ([#1378](https://github.com/apitable/apitable/pull/1378)) @paylm +- sync: hosted cloud ([#1407](https://github.com/apitable/apitable/pull/1407)) @shawndenggh +- sync: hosted cloud ([#1427](https://github.com/apitable/apitable/pull/1427)) @jeremyyin2012 +## [v1.3.0-beta.1](https://github.com/apitable/apitable/releases/tag/v1.3.0-beta.1) (2023-10-17) ### Bug fixes -* fix: Update CHANGELOG.md ([#1374](https://github.com/apitable/apitable/pull/1374)) @robot518 -* fix: room-server use pnpm command ([#1384](https://github.com/apitable/apitable/pull/1384)) @cloud0072 -* fix: record_archive db changelog ([#1388](https://github.com/apitable/apitable/pull/1388)) @chalme -* fix: change update ([#1389](https://github.com/apitable/apitable/pull/1389)) @chalme -* fix: archived crash @laboonly -* fix: Tooltip components import path @laboonly -* fix: archived crash ([#1392](https://github.com/apitable/apitable/pull/1392)) @laboonly +- fix: Update CHANGELOG.md ([#1374](https://github.com/apitable/apitable/pull/1374)) @robot518 +- fix: room-server use pnpm command ([#1384](https://github.com/apitable/apitable/pull/1384)) @cloud0072 +- fix: record_archive db changelog ([#1388](https://github.com/apitable/apitable/pull/1388)) @chalme +- fix: change update ([#1389](https://github.com/apitable/apitable/pull/1389)) @chalme +- fix: archived crash @laboonly +- fix: Tooltip components import path @laboonly +- fix: archived crash ([#1392](https://github.com/apitable/apitable/pull/1392)) @laboonly ### What's more -* sync: hosted cloud ([#1385](https://github.com/apitable/apitable/pull/1385)) @JoverZhang -* chore: make web server arm64 build as experimental ([#1390](https://github.com/apitable/apitable/pull/1390)) @networkhermit -## [v1.3.0-beta](https://github.com/apitable/apitable/releases/tag/v1.3.0-beta) (2023-10-09) +- sync: hosted cloud ([#1385](https://github.com/apitable/apitable/pull/1385)) @JoverZhang +- chore: make web server arm64 build as experimental ([#1390](https://github.com/apitable/apitable/pull/1390)) @networkhermit +## [v1.3.0-beta](https://github.com/apitable/apitable/releases/tag/v1.3.0-beta) (2023-10-09) ### Bug fixes -* fix: widget-sdk pkg with js files ([#1362](https://github.com/apitable/apitable/pull/1362)) @Kilian -* fix: project startup error @JaneSu -* fix: project startup error ([#1370](https://github.com/apitable/apitable/pull/1370)) @Aria +- fix: widget-sdk pkg with js files ([#1362](https://github.com/apitable/apitable/pull/1362)) @Kilian +- fix: project startup error @JaneSu +- fix: project startup error ([#1370](https://github.com/apitable/apitable/pull/1370)) @Aria ### What's more -* ci: test ci @JaneSu -* ci: test ci @JaneSu -* ci: test ci @JaneSu -* ci: test ci @JaneSu -* ci: test ci @JaneSu -* ci: test ci ([#1366](https://github.com/apitable/apitable/pull/1366)) @Aria -* sync: hosted cloud ([#1367](https://github.com/apitable/apitable/pull/1367)) @Robot Ye Chen -## [v1.2.0-beta](https://github.com/apitable/apitable/releases/tag/v1.2.0-beta) (2023-09-25) +- ci: test ci @JaneSu +- ci: test ci @JaneSu +- ci: test ci @JaneSu +- ci: test ci @JaneSu +- ci: test ci @JaneSu +- ci: test ci ([#1366](https://github.com/apitable/apitable/pull/1366)) @Aria +- sync: hosted cloud ([#1367](https://github.com/apitable/apitable/pull/1367)) @Robot Ye Chen +## [v1.2.0-beta](https://github.com/apitable/apitable/releases/tag/v1.2.0-beta) (2023-09-25) ### What's more -* sync: hosted cloud ([#1336](https://github.com/apitable/apitable/pull/1336)) @functionChenGuoFeng -* chore: gitpod automatic pnpm ([#1337](https://github.com/apitable/apitable/pull/1337)) @functionChenGuoFeng -## [v1.1.0-beta](https://github.com/apitable/apitable/releases/tag/v1.1.0-beta) (2023-09-18) +- sync: hosted cloud ([#1336](https://github.com/apitable/apitable/pull/1336)) @functionChenGuoFeng +- chore: gitpod automatic pnpm ([#1337](https://github.com/apitable/apitable/pull/1337)) @functionChenGuoFeng +## [v1.1.0-beta](https://github.com/apitable/apitable/releases/tag/v1.1.0-beta) (2023-09-18) ### What's more -* sync: hosted cloud ([#1319](https://github.com/apitable/apitable/pull/1319)) @ChambersChan -## [v1.0.0-beta.1](https://github.com/apitable/apitable/releases/tag/v1.0.0-beta.1) (2023-09-11) +- sync: hosted cloud ([#1319](https://github.com/apitable/apitable/pull/1319)) @ChambersChan +## [v1.0.0-beta.1](https://github.com/apitable/apitable/releases/tag/v1.0.0-beta.1) (2023-09-11) ### Features and enhancements -* feat: changelog update @chalme +- feat: changelog update @chalme ### What's more -* chore: changelog for v1.0.0-beta ([#1278](https://github.com/apitable/apitable/pull/1278)) @chalme -* sync: hosted cloud ([#1301](https://github.com/apitable/apitable/pull/1301)) @shawndenggh +- chore: changelog for v1.0.0-beta ([#1278](https://github.com/apitable/apitable/pull/1278)) @chalme +- sync: hosted cloud ([#1301](https://github.com/apitable/apitable/pull/1301)) @shawndenggh ## [v1.0.0-beta](https://github.com/apitable/apitable/releases/tag/v1.0.0-beta) (2023-09-05) - ### Bug fixes -* fix: fusion path proxy ([#1261](https://github.com/apitable/apitable/pull/1261)) @ChambersChan +- fix: fusion path proxy ([#1261](https://github.com/apitable/apitable/pull/1261)) @ChambersChan ### What's more -* chore: changelog for v0.99.1-beta.1 ([#1254](https://github.com/apitable/apitable/pull/1254)) @robot518 -* Update README.md @mr-kelly -* chore: update readme.md ([#1274](https://github.com/apitable/apitable/pull/1274)) @shawndenggh -* sync: hosted cloud ([#1276](https://github.com/apitable/apitable/pull/1276)) @chalme -## [v0.99.1-beta.1](https://github.com/apitable/apitable/releases/tag/v0.99.1-beta.1) (2023-08-28) +- chore: changelog for v0.99.1-beta.1 ([#1254](https://github.com/apitable/apitable/pull/1254)) @robot518 +- Update README.md @mr-kelly +- chore: update readme.md ([#1274](https://github.com/apitable/apitable/pull/1274)) @shawndenggh +- sync: hosted cloud ([#1276](https://github.com/apitable/apitable/pull/1276)) @chalme +## [v0.99.1-beta.1](https://github.com/apitable/apitable/releases/tag/v0.99.1-beta.1) (2023-08-28) ### Bug fixes -* fix: delete link field crash ([#1253](https://github.com/apitable/apitable/pull/1253)) @wangkailang +- fix: delete link field crash ([#1253](https://github.com/apitable/apitable/pull/1253)) @wangkailang ### What's more -* chore: changelog for v0.99.1-beta ([#1243](https://github.com/apitable/apitable/pull/1243)) @BinsonZoom -* sync: hosted cloud ([#1248](https://github.com/apitable/apitable/pull/1248)) @robot518 -## [v0.99.1-beta](https://github.com/apitable/apitable/releases/tag/v0.99.1-beta) (2023-08-22) +- chore: changelog for v0.99.1-beta ([#1243](https://github.com/apitable/apitable/pull/1243)) @BinsonZoom +- sync: hosted cloud ([#1248](https://github.com/apitable/apitable/pull/1248)) @robot518 +## [v0.99.1-beta](https://github.com/apitable/apitable/releases/tag/v0.99.1-beta) (2023-08-22) ### What's more -* sync: hosted cloud ([#1207](https://github.com/apitable/apitable/pull/1207)) @zoe-icu -* sync: hosted cloud ([#1237](https://github.com/apitable/apitable/pull/1237)) @BinsonZoom -## [v0.99.0-beta](https://github.com/apitable/apitable/releases/tag/v0.99.0-beta) (2023-08-07) +- sync: hosted cloud ([#1207](https://github.com/apitable/apitable/pull/1207)) @zoe-icu +- sync: hosted cloud ([#1237](https://github.com/apitable/apitable/pull/1237)) @BinsonZoom +## [v0.99.0-beta](https://github.com/apitable/apitable/releases/tag/v0.99.0-beta) (2023-08-07) ### Bug fixes -* fix: fix code issues @ranglang -* fix:press Enter to login ([#1147](https://github.com/apitable/apitable/pull/1147)) @yo-ooiii -* fix: typo ([#1170](https://github.com/apitable/apitable/pull/1170)) @okisdev -* fix: fix code issues @ranglang -* fix: fix code issues @ranglang -* fix: remove the deprecated vscode extension ([#1178](https://github.com/apitable/apitable/pull/1178)) @okisdev +- fix: fix code issues @ranglang +- fix:press Enter to login ([#1147](https://github.com/apitable/apitable/pull/1147)) @yo-ooiii +- fix: typo ([#1170](https://github.com/apitable/apitable/pull/1170)) @okisdev +- fix: fix code issues @ranglang +- fix: fix code issues @ranglang +- fix: remove the deprecated vscode extension ([#1178](https://github.com/apitable/apitable/pull/1178)) @okisdev ### What's more -* Press Enter to submit the form @yo-ooiii -* chore: 0.99.0 release ([#1167](https://github.com/apitable/apitable/pull/1167)) @dage233 -* Merge branch 'develop' into fix/password-enter-login @yo-ooiii -* Feature/robot rich test ([#1175](https://github.com/apitable/apitable/pull/1175)) @JaneSu -* sync: hosted cloud ([#1183](https://github.com/apitable/apitable/pull/1183)) @Exclamation-mark -## [v0.99.0-alpha](https://github.com/apitable/apitable/releases/tag/v0.99.0-alpha) (2023-08-01) +- Press Enter to submit the form @yo-ooiii +- chore: 0.99.0 release ([#1167](https://github.com/apitable/apitable/pull/1167)) @dage233 +- Merge branch 'develop' into fix/password-enter-login @yo-ooiii +- Feature/robot rich test ([#1175](https://github.com/apitable/apitable/pull/1175)) @JaneSu +- sync: hosted cloud ([#1183](https://github.com/apitable/apitable/pull/1183)) @Exclamation-mark +## [v0.99.0-alpha](https://github.com/apitable/apitable/releases/tag/v0.99.0-alpha) (2023-08-01) ### Features and enhancements -* feat: add deploy to digitalocean ([#951](https://github.com/apitable/apitable/pull/951)) @networkhermit -* feat:register user default language ([#1007](https://github.com/apitable/apitable/pull/1007)) @Exclamation-mark -* feat: enable delete space ([#1079](https://github.com/apitable/apitable/pull/1079)) @wmEvie -* feat: enable experimental multi-arch build for linux/amd64 and linux/arm64 ([#1103](https://github.com/apitable/apitable/pull/1103)) @networkhermit -* feat: auto use browser language ([#1152](https://github.com/apitable/apitable/pull/1152)) @qiuqfang - -### Bug fixes - -* fix: add missing alt attribute to Upgrade Succeed image ([#941](https://github.com/apitable/apitable/pull/941)) @shunyue1320 -* fix: allow unit_id to be empty string @zoe-icu -* fix: allow unit_id to be empty string ([#953](https://github.com/apitable/apitable/pull/953)) @zoe-icu -* fix: fix scrollbar's bg style ([#5138](https://github.com/apitable/apitable/pull/5138)) @ranglang -* fix: fix scrollbar's bg style ([#5138](https://github.com/apitable/apitable/pull/5138)) (#988) @JaneSu -* fix: fix checkbox emoj for cell value @ranglang -* fix: fix checkbox emoj for cell value ([#999](https://github.com/apitable/apitable/pull/999)) @ranglang -* fix: zh-CN.strings error ([#1006](https://github.com/apitable/apitable/pull/1006)) @Exclamation-mark -* fix: fusion api select new option error ([#1014](https://github.com/apitable/apitable/pull/1014)) @arucil -* fix: quote template sub node sync failure ([#1018](https://github.com/apitable/apitable/pull/1018)) @ChambersChan -* fix: get error language code und ([#1022](https://github.com/apitable/apitable/pull/1022)) @Exclamation-mark -* fix: changelog version error @Exclamation-mark -* fix: fix dashboard connected for widget [#5133](https://github.com/apitable/apitable/pull/5133) (#1059) @ranglang -* fix: Improved security by replacing the custom secret CR_PAT with the built-in GITHUB_TOKEN in the GitHub Actions workflow file ai_code_reviewer.yml. ([#1075](https://github.com/apitable/apitable/pull/1075)) @mr-kelly -* fix: sign up password match issue ([#1052](https://github.com/apitable/apitable/pull/1052)) (#1074) @llkevin13579 -* fix: fix i18n tips ([#1078](https://github.com/apitable/apitable/pull/1078)) @ranglang -* fix: disable USE_NATIVE_MODULE by default ([#1086](https://github.com/apitable/apitable/pull/1086)) @maltoze -* fix: update error message ([#1097](https://github.com/apitable/apitable/pull/1097)) @llkevin13579 -* fix: duplicate bucket path ([#1146](https://github.com/apitable/apitable/pull/1146)) @ChambersChan - -### What's more - -* chore: add config for specifying rust version ([#947](https://github.com/apitable/apitable/pull/947)) @arucil -* chore: changelog for 0.22.0-alpha ([#948](https://github.com/apitable/apitable/pull/948)) @shawndenggh -* sync: hosted cloud ([#967](https://github.com/apitable/apitable/pull/967)) @ChambersChan -* sync: hosted cloud ([#969](https://github.com/apitable/apitable/pull/969)) @ChambersChan -* chore: changelog for v0.22.0-beta ([#970](https://github.com/apitable/apitable/pull/970)) @ChambersChan -* sync: hosted cloud ([#989](https://github.com/apitable/apitable/pull/989)) @Exclamation-mark -* chore: changelog for v0.22.0-beta.1 @Exclamation-mark -* Merge branch 'develop' into feature/fix-checkbox-emoj @JaneSu -* sync: hosted ([#1013](https://github.com/apitable/apitable/pull/1013)) @arucil -* sync: hosted cloud ([#1056](https://github.com/apitable/apitable/pull/1056)) @Exclamation-mark -* chore: changelog for v0.23.0-release @Exclamation-mark -* chore(deps-dev): bump stylelint from 13.9.0 to 15.10.1 ([#1046](https://github.com/apitable/apitable/pull/1046)) @dependabot[bot] -* chore(deps): bump semver from 7.3.8 to 7.5.2 ([#983](https://github.com/apitable/apitable/pull/983)) @dependabot[bot] -* chore(deps): bump posthog-js from 1.51.1 to 1.57.2 ([#843](https://github.com/apitable/apitable/pull/843)) @dependabot[bot] -* chore(deps): bump @grpc/grpc-js from 1.7.1 to 1.8.8 ([#1031](https://github.com/apitable/apitable/pull/1031)) @dependabot[bot] -* chore(deps): bump socket.io-parser from 3.3.0 to 3.3.3 ([#863](https://github.com/apitable/apitable/pull/863)) @dependabot[bot] -* chore: Added GitHub Actions workflow file for AI code review. ([#1071](https://github.com/apitable/apitable/pull/1071)) @mr-kelly -* sync: hosted cloud ([#1094](https://github.com/apitable/apitable/pull/1094)) @ChambersChan -* chore: changelog for v0.23.0-beta.2 ([#1099](https://github.com/apitable/apitable/pull/1099)) @ChambersChan -* chore: trigger multi-arch build only on tag as it is extreme slow ([#1106](https://github.com/apitable/apitable/pull/1106)) @networkhermit -* chore(deps): bump word-wrap from 1.2.3 to 1.2.4 ([#1104](https://github.com/apitable/apitable/pull/1104)) @dependabot[bot] -* sync/hosted into develop ([#1123](https://github.com/apitable/apitable/pull/1123)) @functionChenGuoFeng -* chore: update v0.24.0-alpha changelog ([#1131](https://github.com/apitable/apitable/pull/1131)) @functionChenGuoFeng -* Update ja-JP/README.md ([#1030](https://github.com/apitable/apitable/pull/1030)) @eltociear -* Make mail STARTTLS settings configurable ([#1072](https://github.com/apitable/apitable/pull/1072)) @spantaleev -* docs: remove duplicate contribution introduction in readme ([#1156](https://github.com/apitable/apitable/pull/1156)) @ChambersChan -* Revert "feat: auto use browser language" ([#1166](https://github.com/apitable/apitable/pull/1166)) @wangkailang -* sync: hosted cloud ([#1164](https://github.com/apitable/apitable/pull/1164)) @dage233 - +- feat: add deploy to digitalocean ([#951](https://github.com/apitable/apitable/pull/951)) @networkhermit +- feat:register user default language ([#1007](https://github.com/apitable/apitable/pull/1007)) @Exclamation-mark +- feat: enable delete space ([#1079](https://github.com/apitable/apitable/pull/1079)) @wmEvie +- feat: enable experimental multi-arch build for linux/amd64 and linux/arm64 ([#1103](https://github.com/apitable/apitable/pull/1103)) @networkhermit +- feat: auto use browser language ([#1152](https://github.com/apitable/apitable/pull/1152)) @qiuqfang + +### Bug fixes + +- fix: add missing alt attribute to Upgrade Succeed image ([#941](https://github.com/apitable/apitable/pull/941)) @shunyue1320 +- fix: allow unit_id to be empty string @zoe-icu +- fix: allow unit_id to be empty string ([#953](https://github.com/apitable/apitable/pull/953)) @zoe-icu +- fix: fix scrollbar's bg style ([#5138](https://github.com/apitable/apitable/pull/5138)) @ranglang +- fix: fix scrollbar's bg style ([#5138](https://github.com/apitable/apitable/pull/5138)) (#988) @JaneSu +- fix: fix checkbox emoj for cell value @ranglang +- fix: fix checkbox emoj for cell value ([#999](https://github.com/apitable/apitable/pull/999)) @ranglang +- fix: zh-CN.strings error ([#1006](https://github.com/apitable/apitable/pull/1006)) @Exclamation-mark +- fix: fusion api select new option error ([#1014](https://github.com/apitable/apitable/pull/1014)) @arucil +- fix: quote template sub node sync failure ([#1018](https://github.com/apitable/apitable/pull/1018)) @ChambersChan +- fix: get error language code und ([#1022](https://github.com/apitable/apitable/pull/1022)) @Exclamation-mark +- fix: changelog version error @Exclamation-mark +- fix: fix dashboard connected for widget [#5133](https://github.com/apitable/apitable/pull/5133) (#1059) @ranglang +- fix: Improved security by replacing the custom secret CR_PAT with the built-in GITHUB_TOKEN in the GitHub Actions workflow file ai_code_reviewer.yml. ([#1075](https://github.com/apitable/apitable/pull/1075)) @mr-kelly +- fix: sign up password match issue ([#1052](https://github.com/apitable/apitable/pull/1052)) (#1074) @llkevin13579 +- fix: fix i18n tips ([#1078](https://github.com/apitable/apitable/pull/1078)) @ranglang +- fix: disable USE_NATIVE_MODULE by default ([#1086](https://github.com/apitable/apitable/pull/1086)) @maltoze +- fix: update error message ([#1097](https://github.com/apitable/apitable/pull/1097)) @llkevin13579 +- fix: duplicate bucket path ([#1146](https://github.com/apitable/apitable/pull/1146)) @ChambersChan + +### What's more + +- chore: add config for specifying rust version ([#947](https://github.com/apitable/apitable/pull/947)) @arucil +- chore: changelog for 0.22.0-alpha ([#948](https://github.com/apitable/apitable/pull/948)) @shawndenggh +- sync: hosted cloud ([#967](https://github.com/apitable/apitable/pull/967)) @ChambersChan +- sync: hosted cloud ([#969](https://github.com/apitable/apitable/pull/969)) @ChambersChan +- chore: changelog for v0.22.0-beta ([#970](https://github.com/apitable/apitable/pull/970)) @ChambersChan +- sync: hosted cloud ([#989](https://github.com/apitable/apitable/pull/989)) @Exclamation-mark +- chore: changelog for v0.22.0-beta.1 @Exclamation-mark +- Merge branch 'develop' into feature/fix-checkbox-emoj @JaneSu +- sync: hosted ([#1013](https://github.com/apitable/apitable/pull/1013)) @arucil +- sync: hosted cloud ([#1056](https://github.com/apitable/apitable/pull/1056)) @Exclamation-mark +- chore: changelog for v0.23.0-release @Exclamation-mark +- chore(deps-dev): bump stylelint from 13.9.0 to 15.10.1 ([#1046](https://github.com/apitable/apitable/pull/1046)) @dependabot[bot] +- chore(deps): bump semver from 7.3.8 to 7.5.2 ([#983](https://github.com/apitable/apitable/pull/983)) @dependabot[bot] +- chore(deps): bump posthog-js from 1.51.1 to 1.57.2 ([#843](https://github.com/apitable/apitable/pull/843)) @dependabot[bot] +- chore(deps): bump @grpc/grpc-js from 1.7.1 to 1.8.8 ([#1031](https://github.com/apitable/apitable/pull/1031)) @dependabot[bot] +- chore(deps): bump socket.io-parser from 3.3.0 to 3.3.3 ([#863](https://github.com/apitable/apitable/pull/863)) @dependabot[bot] +- chore: Added GitHub Actions workflow file for AI code review. ([#1071](https://github.com/apitable/apitable/pull/1071)) @mr-kelly +- sync: hosted cloud ([#1094](https://github.com/apitable/apitable/pull/1094)) @ChambersChan +- chore: changelog for v0.23.0-beta.2 ([#1099](https://github.com/apitable/apitable/pull/1099)) @ChambersChan +- chore: trigger multi-arch build only on tag as it is extreme slow ([#1106](https://github.com/apitable/apitable/pull/1106)) @networkhermit +- chore(deps): bump word-wrap from 1.2.3 to 1.2.4 ([#1104](https://github.com/apitable/apitable/pull/1104)) @dependabot[bot] +- sync/hosted into develop ([#1123](https://github.com/apitable/apitable/pull/1123)) @functionChenGuoFeng +- chore: update v0.24.0-alpha changelog ([#1131](https://github.com/apitable/apitable/pull/1131)) @functionChenGuoFeng +- Update ja-JP/README.md ([#1030](https://github.com/apitable/apitable/pull/1030)) @eltociear +- Make mail STARTTLS settings configurable ([#1072](https://github.com/apitable/apitable/pull/1072)) @spantaleev +- docs: remove duplicate contribution introduction in readme ([#1156](https://github.com/apitable/apitable/pull/1156)) @ChambersChan +- Revert "feat: auto use browser language" ([#1166](https://github.com/apitable/apitable/pull/1166)) @wangkailang +- sync: hosted cloud ([#1164](https://github.com/apitable/apitable/pull/1164)) @dage233 ## [v0.24.0-alpha](https://github.com/apitable/apitable/releases/tag/v0.24.0-alpha) (2023-07-25) - ### Features and enhancements -* feat: enable experimental multi-arch build for linux/amd64 and linux/arm64 ([#1103](https://github.com/apitable/apitable/pull/1103)) @networkhermit +- feat: enable experimental multi-arch build for linux/amd64 and linux/arm64 ([#1103](https://github.com/apitable/apitable/pull/1103)) @networkhermit ### Bug fixes -* fix: update error message ([#1097](https://github.com/apitable/apitable/pull/1097)) @llkevin13579 +- fix: update error message ([#1097](https://github.com/apitable/apitable/pull/1097)) @llkevin13579 ### What's more -* chore: changelog for v0.23.0-beta.2 ([#1099](https://github.com/apitable/apitable/pull/1099)) @ChambersChan -* chore: trigger multi-arch build only on tag as it is extreme slow ([#1106](https://github.com/apitable/apitable/pull/1106)) @networkhermit -* chore(deps): bump word-wrap from 1.2.3 to 1.2.4 ([#1104](https://github.com/apitable/apitable/pull/1104)) @dependabot[bot] -* sync/hosted into develop ([#1123](https://github.com/apitable/apitable/pull/1123)) @functionChenGuoFeng - +- chore: changelog for v0.23.0-beta.2 ([#1099](https://github.com/apitable/apitable/pull/1099)) @ChambersChan +- chore: trigger multi-arch build only on tag as it is extreme slow ([#1106](https://github.com/apitable/apitable/pull/1106)) @networkhermit +- chore(deps): bump word-wrap from 1.2.3 to 1.2.4 ([#1104](https://github.com/apitable/apitable/pull/1104)) @dependabot[bot] +- sync/hosted into develop ([#1123](https://github.com/apitable/apitable/pull/1123)) @functionChenGuoFeng ## [v0.23.0-beta.2](https://github.com/apitable/apitable/releases/tag/v0.23.0-beta.2) (2023-07-18) - ### Features and enhancements -* feat: enable delete space ([#1079](https://github.com/apitable/apitable/pull/1079)) @wmEvie +- feat: enable delete space ([#1079](https://github.com/apitable/apitable/pull/1079)) @wmEvie ### Bug fixes -* fix: fix dashboard connected for widget [#5133](https://github.com/apitable/apitable/pull/5133) (#1059) @ranglang -* fix: Improved security by replacing the custom secret CR_PAT with the built-in GITHUB_TOKEN in the GitHub Actions workflow file ai_code_reviewer.yml. ([#1075](https://github.com/apitable/apitable/pull/1075)) @mr-kelly -* fix: sign up password match issue ([#1052](https://github.com/apitable/apitable/pull/1052)) (#1074) @llkevin13579 -* fix: fix i18n tips ([#1078](https://github.com/apitable/apitable/pull/1078)) @ranglang -* fix: disable USE_NATIVE_MODULE by default ([#1086](https://github.com/apitable/apitable/pull/1086)) @maltoze +- fix: fix dashboard connected for widget [#5133](https://github.com/apitable/apitable/pull/5133) (#1059) @ranglang +- fix: Improved security by replacing the custom secret CR_PAT with the built-in GITHUB_TOKEN in the GitHub Actions workflow file ai_code_reviewer.yml. ([#1075](https://github.com/apitable/apitable/pull/1075)) @mr-kelly +- fix: sign up password match issue ([#1052](https://github.com/apitable/apitable/pull/1052)) (#1074) @llkevin13579 +- fix: fix i18n tips ([#1078](https://github.com/apitable/apitable/pull/1078)) @ranglang +- fix: disable USE_NATIVE_MODULE by default ([#1086](https://github.com/apitable/apitable/pull/1086)) @maltoze ### What's more -* chore(deps-dev): bump stylelint from 13.9.0 to 15.10.1 ([#1046](https://github.com/apitable/apitable/pull/1046)) @dependabot[bot] -* chore(deps): bump semver from 7.3.8 to 7.5.2 ([#983](https://github.com/apitable/apitable/pull/983)) @dependabot[bot] -* chore(deps): bump posthog-js from 1.51.1 to 1.57.2 ([#843](https://github.com/apitable/apitable/pull/843)) @dependabot[bot] -* chore(deps): bump @grpc/grpc-js from 1.7.1 to 1.8.8 ([#1031](https://github.com/apitable/apitable/pull/1031)) @dependabot[bot] -* chore(deps): bump socket.io-parser from 3.3.0 to 3.3.3 ([#863](https://github.com/apitable/apitable/pull/863)) @dependabot[bot] -* chore: Added GitHub Actions workflow file for AI code review. ([#1071](https://github.com/apitable/apitable/pull/1071)) @mr-kelly -* sync: hosted cloud ([#1094](https://github.com/apitable/apitable/pull/1094)) @ChambersChan - +- chore(deps-dev): bump stylelint from 13.9.0 to 15.10.1 ([#1046](https://github.com/apitable/apitable/pull/1046)) @dependabot[bot] +- chore(deps): bump semver from 7.3.8 to 7.5.2 ([#983](https://github.com/apitable/apitable/pull/983)) @dependabot[bot] +- chore(deps): bump posthog-js from 1.51.1 to 1.57.2 ([#843](https://github.com/apitable/apitable/pull/843)) @dependabot[bot] +- chore(deps): bump @grpc/grpc-js from 1.7.1 to 1.8.8 ([#1031](https://github.com/apitable/apitable/pull/1031)) @dependabot[bot] +- chore(deps): bump socket.io-parser from 3.3.0 to 3.3.3 ([#863](https://github.com/apitable/apitable/pull/863)) @dependabot[bot] +- chore: Added GitHub Actions workflow file for AI code review. ([#1071](https://github.com/apitable/apitable/pull/1071)) @mr-kelly +- sync: hosted cloud ([#1094](https://github.com/apitable/apitable/pull/1094)) @ChambersChan ## [v0.23.0-beta.1](https://github.com/apitable/apitable/releases/tag/v0.23.0-beta.1) (2023-07-10) - ### Bug fixes -* fix: quote template sub node sync failure ([#1018](https://github.com/apitable/apitable/pull/1018)) @ChambersChan -* fix: get error language code und ([#1022](https://github.com/apitable/apitable/pull/1022)) @Exclamation-mark +- fix: quote template sub node sync failure ([#1018](https://github.com/apitable/apitable/pull/1018)) @ChambersChan +- fix: get error language code und ([#1022](https://github.com/apitable/apitable/pull/1022)) @Exclamation-mark ### What's more -* sync: hosted cloud ([#1056](https://github.com/apitable/apitable/pull/1056)) @Exclamation-mark - +- sync: hosted cloud ([#1056](https://github.com/apitable/apitable/pull/1056)) @Exclamation-mark ## [v0.23.0-alpha](https://github.com/apitable/apitable/releases/tag/v0.23.0-alpha) (2023-07-03) - ### Features and enhancements -* feat:register user default language ([#1007](https://github.com/apitable/apitable/pull/1007)) @Exclamation-mark +- feat:register user default language ([#1007](https://github.com/apitable/apitable/pull/1007)) @Exclamation-mark ### Bug fixes -* fix: fix scrollbar's bg style ([#5138](https://github.com/apitable/apitable/pull/5138)) (#988) @JaneSu -* fix: fix checkbox emoj for cell value ([#999](https://github.com/apitable/apitable/pull/999)) @ranglang -* fix: zh-CN.strings error ([#1006](https://github.com/apitable/apitable/pull/1006)) @Exclamation-mark -* fix: fusion api select new option error ([#1014](https://github.com/apitable/apitable/pull/1014)) @arucil -* fix: quote template sub node sync failure ([#1018](https://github.com/apitable/apitable/pull/1018)) @ChambersChan -* fix: get error language code und ([#1022](https://github.com/apitable/apitable/pull/1022)) @Exclamation-mark +- fix: fix scrollbar's bg style ([#5138](https://github.com/apitable/apitable/pull/5138)) (#988) @JaneSu +- fix: fix checkbox emoj for cell value ([#999](https://github.com/apitable/apitable/pull/999)) @ranglang +- fix: zh-CN.strings error ([#1006](https://github.com/apitable/apitable/pull/1006)) @Exclamation-mark +- fix: fusion api select new option error ([#1014](https://github.com/apitable/apitable/pull/1014)) @arucil +- fix: quote template sub node sync failure ([#1018](https://github.com/apitable/apitable/pull/1018)) @ChambersChan +- fix: get error language code und ([#1022](https://github.com/apitable/apitable/pull/1022)) @Exclamation-mark ### What's more -* chore: changelog for v0.22.0-beta.1 @Exclamation-mark -* Merge branch 'develop' into feature/fix-checkbox-emoj @JaneSu -* sync: hosted ([#1013](https://github.com/apitable/apitable/pull/1013)) @arucil -* sync: hosted cloud ([#1056](https://github.com/apitable/apitable/pull/1056)) @Exclamation-mark -## [v0.22.0-beta.1](https://github.com/apitable/apitable/releases/tag/v0.22.0-beta.1) (2023-06-26) +- chore: changelog for v0.22.0-beta.1 @Exclamation-mark +- Merge branch 'develop' into feature/fix-checkbox-emoj @JaneSu +- sync: hosted ([#1013](https://github.com/apitable/apitable/pull/1013)) @arucil +- sync: hosted cloud ([#1056](https://github.com/apitable/apitable/pull/1056)) @Exclamation-mark +## [v0.22.0-beta.1](https://github.com/apitable/apitable/releases/tag/v0.22.0-beta.1) (2023-06-26) ### What's more -* chore: changelog for v0.22.0-beta ([#970](https://github.com/apitable/apitable/pull/970)) @ChambersChan -* sync: hosted cloud ([#989](https://github.com/apitable/apitable/pull/989)) @Exclamation-mark -## [v0.22.0-beta](https://github.com/apitable/apitable/releases/tag/v0.22.0-beta) (2023-06-19) +- chore: changelog for v0.22.0-beta ([#970](https://github.com/apitable/apitable/pull/970)) @ChambersChan +- sync: hosted cloud ([#989](https://github.com/apitable/apitable/pull/989)) @Exclamation-mark +## [v0.22.0-beta](https://github.com/apitable/apitable/releases/tag/v0.22.0-beta) (2023-06-19) ### Features and enhancements -* feat: add deploy to digitalocean ([#951](https://github.com/apitable/apitable/pull/951)) @networkhermit +- feat: add deploy to digitalocean ([#951](https://github.com/apitable/apitable/pull/951)) @networkhermit ### Bug fixes -* fix: add missing alt attribute to Upgrade Succeed image ([#941](https://github.com/apitable/apitable/pull/941)) @shunyue1320 -* fix: allow unit_id to be empty string @zoe-icu -* fix: allow unit_id to be empty string ([#953](https://github.com/apitable/apitable/pull/953)) @zoe-icu +- fix: add missing alt attribute to Upgrade Succeed image ([#941](https://github.com/apitable/apitable/pull/941)) @shunyue1320 +- fix: allow unit_id to be empty string @zoe-icu +- fix: allow unit_id to be empty string ([#953](https://github.com/apitable/apitable/pull/953)) @zoe-icu ### What's more -* chore: add config for specifying rust version ([#947](https://github.com/apitable/apitable/pull/947)) @arucil -* chore: changelog for 0.22.0-alpha ([#948](https://github.com/apitable/apitable/pull/948)) @shawndenggh -* sync: hosted cloud ([#967](https://github.com/apitable/apitable/pull/967)) @ChambersChan -* sync: hosted cloud ([#969](https://github.com/apitable/apitable/pull/969)) @ChambersChan -## [v0.22.0-alpha](https://github.com/apitable/apitable/releases/tag/v0.22.0-alpha) (2023-06-12) +- chore: add config for specifying rust version ([#947](https://github.com/apitable/apitable/pull/947)) @arucil +- chore: changelog for 0.22.0-alpha ([#948](https://github.com/apitable/apitable/pull/948)) @shawndenggh +- sync: hosted cloud ([#967](https://github.com/apitable/apitable/pull/967)) @ChambersChan +- sync: hosted cloud ([#969](https://github.com/apitable/apitable/pull/969)) @ChambersChan +## [v0.22.0-alpha](https://github.com/apitable/apitable/releases/tag/v0.22.0-alpha) (2023-06-12) ### What's more -* sync: hosted cloud ([#944](https://github.com/apitable/apitable/pull/944)) @shawndenggh -* chore: merge release/0.21.0 into develop ([#945](https://github.com/apitable/apitable/pull/945)) @shawndenggh -## [v0.21.0-rc.1](https://github.com/apitable/apitable/releases/tag/v0.21.0-rc.1) (2023-06-05) +- sync: hosted cloud ([#944](https://github.com/apitable/apitable/pull/944)) @shawndenggh +- chore: merge release/0.21.0 into develop ([#945](https://github.com/apitable/apitable/pull/945)) @shawndenggh +## [v0.21.0-rc.1](https://github.com/apitable/apitable/releases/tag/v0.21.0-rc.1) (2023-06-05) ### Features and enhancements -* feat: add gzip support in nginx gateway ([#901](https://github.com/apitable/apitable/pull/901)) @networkhermit +- feat: add gzip support in nginx gateway ([#901](https://github.com/apitable/apitable/pull/901)) @networkhermit ### Bug fixes -* fix: improve toolbar view @xieyhn -* fix: option search not case sensitive ([#892](https://github.com/apitable/apitable/pull/892)) @wangkailang -* fix: components unit test error ([#867](https://github.com/apitable/apitable/pull/867)) @GreenMashimaro -* fix/tooltip-flicker @wangkailang -* fix: improve toolbar view ([#869](https://github.com/apitable/apitable/pull/869)) @JaneSu +- fix: improve toolbar view @xieyhn +- fix: option search not case sensitive ([#892](https://github.com/apitable/apitable/pull/892)) @wangkailang +- fix: components unit test error ([#867](https://github.com/apitable/apitable/pull/867)) @GreenMashimaro +- fix/tooltip-flicker @wangkailang +- fix: improve toolbar view ([#869](https://github.com/apitable/apitable/pull/869)) @JaneSu ### What's more -* docs: remove databus guide ([#873](https://github.com/apitable/apitable/pull/873)) @arucil -* docs: publish cookbook and self-hosted doc replace original developer guide ([#886](https://github.com/apitable/apitable/pull/886)) @mr-kelly -* New Crowdin updates ([#796](https://github.com/apitable/apitable/pull/796)) @mr-kelly -* chore: clarify title of issue templates ([#899](https://github.com/apitable/apitable/pull/899)) @arucil -* sync: hosted cloud ([#916](https://github.com/apitable/apitable/pull/916)) @yort-feng -## [v0.21.0-rc](https://github.com/apitable/apitable/releases/tag/v0.21.0-rc) (2023-05-29) +- docs: remove databus guide ([#873](https://github.com/apitable/apitable/pull/873)) @arucil +- docs: publish cookbook and self-hosted doc replace original developer guide ([#886](https://github.com/apitable/apitable/pull/886)) @mr-kelly +- New Crowdin updates ([#796](https://github.com/apitable/apitable/pull/796)) @mr-kelly +- chore: clarify title of issue templates ([#899](https://github.com/apitable/apitable/pull/899)) @arucil +- sync: hosted cloud ([#916](https://github.com/apitable/apitable/pull/916)) @yort-feng +## [v0.21.0-rc](https://github.com/apitable/apitable/releases/tag/v0.21.0-rc) (2023-05-29) ### Features and enhancements -* feat:add language feed back link to datasheet env ([#842](https://github.com/apitable/apitable/pull/842)) @Exclamation-mark +- feat:add language feed back link to datasheet env ([#842](https://github.com/apitable/apitable/pull/842)) @Exclamation-mark ### Bug fixes -* fix: API panel click more button redirects to a blank page ([#829](https://github.com/apitable/apitable/pull/829)) (#833) @luckyyyyy -* fix: field undefined crash ([#884](https://github.com/apitable/apitable/pull/884)) @wangkailang +- fix: API panel click more button redirects to a blank page ([#829](https://github.com/apitable/apitable/pull/829)) (#833) @luckyyyyy +- fix: field undefined crash ([#884](https://github.com/apitable/apitable/pull/884)) @wangkailang ### What's more -* chore: update translation feedback help url @wmEvie -* chore: update translation feedback help url ([#841](https://github.com/apitable/apitable/pull/841)) @wmEvie -* docs: delete duplicated sentences ([#808](https://github.com/apitable/apitable/pull/808)) @noahlam -* refactor: de-duplications npm packages ([#847](https://github.com/apitable/apitable/pull/847)) @mr-kelly -* sync: hosted cloud ([#881](https://github.com/apitable/apitable/pull/881)) @yort-feng -## [v0.21.0-beta](https://github.com/apitable/apitable/releases/tag/v0.21.0-beta) (2023-05-22) +- chore: update translation feedback help url @wmEvie +- chore: update translation feedback help url ([#841](https://github.com/apitable/apitable/pull/841)) @wmEvie +- docs: delete duplicated sentences ([#808](https://github.com/apitable/apitable/pull/808)) @noahlam +- refactor: de-duplications npm packages ([#847](https://github.com/apitable/apitable/pull/847)) @mr-kelly +- sync: hosted cloud ([#881](https://github.com/apitable/apitable/pull/881)) @yort-feng +## [v0.21.0-beta](https://github.com/apitable/apitable/releases/tag/v0.21.0-beta) (2023-05-22) ### Features and enhancements -* feat: upgrade liquibase version ([#801](https://github.com/apitable/apitable/pull/801)) @shawndenggh -* feat: add new email templates @xukecheng -* feat: add new email templates ([#831](https://github.com/apitable/apitable/pull/831)) @xukecheng +- feat: upgrade liquibase version ([#801](https://github.com/apitable/apitable/pull/801)) @shawndenggh +- feat: add new email templates @xukecheng +- feat: add new email templates ([#831](https://github.com/apitable/apitable/pull/831)) @xukecheng ### Bug fixes -* fix: remove pre-init-db since upgrade liquibase ([#824](https://github.com/apitable/apitable/pull/824)) @shawndenggh +- fix: remove pre-init-db since upgrade liquibase ([#824](https://github.com/apitable/apitable/pull/824)) @shawndenggh ### What's more -* docs: guide on setting up python and gcc ([#802](https://github.com/apitable/apitable/pull/802)) @arucil -* docs: add clearer description of language versions ([#827](https://github.com/apitable/apitable/pull/827)) @arucil -* sync: hosted cloud ([#840](https://github.com/apitable/apitable/pull/840)) @yort-feng -* chore: update translation feedback help url @wmEvie -* chore: update translation feedback help url ([#841](https://github.com/apitable/apitable/pull/841)) @wmEvie -## [v0.21.0-alpha](https://github.com/apitable/apitable/releases/tag/v0.21.0-alpha) (2023-05-15) +- docs: guide on setting up python and gcc ([#802](https://github.com/apitable/apitable/pull/802)) @arucil +- docs: add clearer description of language versions ([#827](https://github.com/apitable/apitable/pull/827)) @arucil +- sync: hosted cloud ([#840](https://github.com/apitable/apitable/pull/840)) @yort-feng +- chore: update translation feedback help url @wmEvie +- chore: update translation feedback help url ([#841](https://github.com/apitable/apitable/pull/841)) @wmEvie +## [v0.21.0-alpha](https://github.com/apitable/apitable/releases/tag/v0.21.0-alpha) (2023-05-15) ### Features and enhancements -* feat:support language de-DE,es-ES,it-IT,es-ES,it-IT,ja-JP,ko-KR,ru-RU @Exclamation-mark -* feat: update node-gyp to latest version ([#793](https://github.com/apitable/apitable/pull/793)) @arucil +- feat:support language de-DE,es-ES,it-IT,es-ES,it-IT,ja-JP,ko-KR,ru-RU @Exclamation-mark +- feat: update node-gyp to latest version ([#793](https://github.com/apitable/apitable/pull/793)) @arucil ### Bug fixes -* fix(room-server): missing dependencies in image ([#4926](https://github.com/apitable/apitable/pull/4926)) (#777) @arucil -* fix:add missing architecture-overview.png ([#782](https://github.com/apitable/apitable/pull/782)) @Exclamation-mark -* fix: login icon bug @laboonly -* fix: login icon bug ([#799](https://github.com/apitable/apitable/pull/799)) @laboonly +- fix(room-server): missing dependencies in image ([#4926](https://github.com/apitable/apitable/pull/4926)) (#777) @arucil +- fix:add missing architecture-overview.png ([#782](https://github.com/apitable/apitable/pull/782)) @Exclamation-mark +- fix: login icon bug @laboonly +- fix: login icon bug ([#799](https://github.com/apitable/apitable/pull/799)) @laboonly ### What's more -* docs: README ([#769](https://github.com/apitable/apitable/pull/769)) @mr-kelly -* New Crowdin updates ([#749](https://github.com/apitable/apitable/pull/749)) @mr-kelly -* docs: create bug report in zh-CN ([#788](https://github.com/apitable/apitable/pull/788)) @mr-kelly -* docs: issue template of bug report cn ([#789](https://github.com/apitable/apitable/pull/789)) @mr-kelly -* sync: hosted cloud ([#794](https://github.com/apitable/apitable/pull/794)) @yort-feng -* chore: changelog for v0.20.0-rc.1 release ([#795](https://github.com/apitable/apitable/pull/795)) @yort-feng -## [v0.20.0-rc.1](https://github.com/apitable/apitable/releases/tag/v0.20.0-rc.1) (2023-05-08) +- docs: README ([#769](https://github.com/apitable/apitable/pull/769)) @mr-kelly +- New Crowdin updates ([#749](https://github.com/apitable/apitable/pull/749)) @mr-kelly +- docs: create bug report in zh-CN ([#788](https://github.com/apitable/apitable/pull/788)) @mr-kelly +- docs: issue template of bug report cn ([#789](https://github.com/apitable/apitable/pull/789)) @mr-kelly +- sync: hosted cloud ([#794](https://github.com/apitable/apitable/pull/794)) @yort-feng +- chore: changelog for v0.20.0-rc.1 release ([#795](https://github.com/apitable/apitable/pull/795)) @yort-feng +## [v0.20.0-rc.1](https://github.com/apitable/apitable/releases/tag/v0.20.0-rc.1) (2023-05-08) ### Features and enhancements -* feat(l10n):support french && chinese traditional ([#741](https://github.com/apitable/apitable/pull/741)) @Exclamation-mark +- feat(l10n):support french && chinese traditional ([#741](https://github.com/apitable/apitable/pull/741)) @Exclamation-mark ### Bug fixes -* fix: avoid loading room-native-api if USE_NATIVE_MODULE is disabled ([#743](https://github.com/apitable/apitable/pull/743)) @arucil -* fix: disable forbid unknow values ([#750](https://github.com/apitable/apitable/pull/750)) @yort-feng -* fix: add multi language images ([#751](https://github.com/apitable/apitable/pull/751)) @luoyunyao +- fix: avoid loading room-native-api if USE_NATIVE_MODULE is disabled ([#743](https://github.com/apitable/apitable/pull/743)) @arucil +- fix: disable forbid unknow values ([#750](https://github.com/apitable/apitable/pull/750)) @yort-feng +- fix: add multi language images ([#751](https://github.com/apitable/apitable/pull/751)) @luoyunyao ### What's more -* Crowdin add French strings([#684](https://github.com/apitable/apitable/pull/684)) @mr-kelly -* docs: design system ([#748](https://github.com/apitable/apitable/pull/748)) @mr-kelly -* docs: discord invite link update ([#726](https://github.com/apitable/apitable/pull/726)) @mr-kelly -* docs: update Crowdin translate link ([#760](https://github.com/apitable/apitable/pull/760)) @Exclamation-mark -* docs: submit a detail PRD issue ([#762](https://github.com/apitable/apitable/pull/762)) @mr-kelly -* chore: sorts of chores ([#763](https://github.com/apitable/apitable/pull/763)) @mr-kelly -* sync: hosted cloud ([#766](https://github.com/apitable/apitable/pull/766)) @yort-feng -## [v0.20.0-rc](https://github.com/apitable/apitable/releases/tag/v0.20.0-rc) (2023-04-25) +- Crowdin add French strings([#684](https://github.com/apitable/apitable/pull/684)) @mr-kelly +- docs: design system ([#748](https://github.com/apitable/apitable/pull/748)) @mr-kelly +- docs: discord invite link update ([#726](https://github.com/apitable/apitable/pull/726)) @mr-kelly +- docs: update Crowdin translate link ([#760](https://github.com/apitable/apitable/pull/760)) @Exclamation-mark +- docs: submit a detail PRD issue ([#762](https://github.com/apitable/apitable/pull/762)) @mr-kelly +- chore: sorts of chores ([#763](https://github.com/apitable/apitable/pull/763)) @mr-kelly +- sync: hosted cloud ([#766](https://github.com/apitable/apitable/pull/766)) @yort-feng +## [v0.20.0-rc](https://github.com/apitable/apitable/releases/tag/v0.20.0-rc) (2023-04-25) ### Features and enhancements -* feat(l10n):Crowdin support translate strings.en-US.json ([#731](https://github.com/apitable/apitable/pull/731)) @Exclamation-mark +- feat(l10n):Crowdin support translate strings.en-US.json ([#731](https://github.com/apitable/apitable/pull/731)) @Exclamation-mark ### Bug fixes -* fix: widget filter ([#714](https://github.com/apitable/apitable/pull/714)) @yort-feng -* fix: init the custom widget command error ([#719](https://github.com/apitable/apitable/pull/719)) @Sky-FE -* fix: folder favorite click crash ([#735](https://github.com/apitable/apitable/pull/735)) @wangkailang -* fix: strings default crash ([#740](https://github.com/apitable/apitable/pull/740)) @wangkailang +- fix: widget filter ([#714](https://github.com/apitable/apitable/pull/714)) @yort-feng +- fix: init the custom widget command error ([#719](https://github.com/apitable/apitable/pull/719)) @Sky-FE +- fix: folder favorite click crash ([#735](https://github.com/apitable/apitable/pull/735)) @wangkailang +- fix: strings default crash ([#740](https://github.com/apitable/apitable/pull/740)) @wangkailang ### What's more -* release: v0.20.0-alpha ([#698](https://github.com/apitable/apitable/pull/698)) @yort-feng -* docs: add Scripting Widget documentation link ([#711](https://github.com/apitable/apitable/pull/711)) @mr-kelly -* sync: hosted cloud ([#739](https://github.com/apitable/apitable/pull/739)) @yort-feng -## [v0.20.0-beta](https://github.com/apitable/apitable/releases/tag/v0.20.0-beta) (2023-04-17) +- release: v0.20.0-alpha ([#698](https://github.com/apitable/apitable/pull/698)) @yort-feng +- docs: add Scripting Widget documentation link ([#711](https://github.com/apitable/apitable/pull/711)) @mr-kelly +- sync: hosted cloud ([#739](https://github.com/apitable/apitable/pull/739)) @yort-feng +## [v0.20.0-beta](https://github.com/apitable/apitable/releases/tag/v0.20.0-beta) (2023-04-17) ### Bug fixes -* fix: widget filter ([#714](https://github.com/apitable/apitable/pull/714)) @yort-feng +- fix: widget filter ([#714](https://github.com/apitable/apitable/pull/714)) @yort-feng ### What's more -* release: v0.20.0-alpha ([#698](https://github.com/apitable/apitable/pull/698)) @yort-feng -* docs: add Scripting Widget documentation link ([#711](https://github.com/apitable/apitable/pull/711)) @mr-kelly -* sync: hosted cloud ([#713](https://github.com/apitable/apitable/pull/713)) @yort-feng -## [v0.20.0-alpha](https://github.com/apitable/apitable/releases/tag/v0.20.0-alpha) (2023-04-10) +- release: v0.20.0-alpha ([#698](https://github.com/apitable/apitable/pull/698)) @yort-feng +- docs: add Scripting Widget documentation link ([#711](https://github.com/apitable/apitable/pull/711)) @mr-kelly +- sync: hosted cloud ([#713](https://github.com/apitable/apitable/pull/713)) @yort-feng +## [v0.20.0-alpha](https://github.com/apitable/apitable/releases/tag/v0.20.0-alpha) (2023-04-10) ### Bug fixes -* fix: recommend widget icon display ([#681](https://github.com/apitable/apitable/pull/681)) @ChambersChan -* fix: recover deleted node failure issue ([#695](https://github.com/apitable/apitable/pull/695)) @ChambersChan -* fix: add cascader strings ([#696](https://github.com/apitable/apitable/pull/696)) @wangkailang +- fix: recommend widget icon display ([#681](https://github.com/apitable/apitable/pull/681)) @ChambersChan +- fix: recover deleted node failure issue ([#695](https://github.com/apitable/apitable/pull/695)) @ChambersChan +- fix: add cascader strings ([#696](https://github.com/apitable/apitable/pull/696)) @wangkailang ### What's more -* New Crowdin updates ([#653](https://github.com/apitable/apitable/pull/653)) @mr-kelly -* docs: databus guide ([#683](https://github.com/apitable/apitable/pull/683)) @arucil -* sync: hosted cloud ([#689](https://github.com/apitable/apitable/pull/689)) @yort-feng -## [v0.19.0-rc](https://github.com/apitable/apitable/releases/tag/v0.19.0-rc) (2023-04-03) +- New Crowdin updates ([#653](https://github.com/apitable/apitable/pull/653)) @mr-kelly +- docs: databus guide ([#683](https://github.com/apitable/apitable/pull/683)) @arucil +- sync: hosted cloud ([#689](https://github.com/apitable/apitable/pull/689)) @yort-feng +## [v0.19.0-rc](https://github.com/apitable/apitable/releases/tag/v0.19.0-rc) (2023-04-03) ### Bug fixes -* fix: widget package submit error issue ([#671](https://github.com/apitable/apitable/pull/671)) @ChambersChan +- fix: widget package submit error issue ([#671](https://github.com/apitable/apitable/pull/671)) @ChambersChan ### What's more -* docs: widget-sdk documentation ([#652](https://github.com/apitable/apitable/pull/652)) @mr-kelly -* docs: Improve translation of README and developer-guide in other languages ([#285](https://github.com/apitable/apitable/pull/285)) @mr-kelly -* docs: add brew install canvas ([#599](https://github.com/apitable/apitable/pull/599)) (#654) @Exclamation-mark -* docs: remove description of default username in readme ([#657](https://github.com/apitable/apitable/pull/657)) @ChambersChan -* docs: developer-guide add multilingual translation (l10n) workflow ([#661](https://github.com/apitable/apitable/pull/661)) @Exclamation-mark -* docs: add multi-language images ([#663](https://github.com/apitable/apitable/pull/663)) @luoyunyao -* sync: hosted cloud ([#670](https://github.com/apitable/apitable/pull/670)) @yort-feng -## [v0.19.0-beta](https://github.com/apitable/apitable/releases/tag/v0.19.0-beta) (2023-03-27) +- docs: widget-sdk documentation ([#652](https://github.com/apitable/apitable/pull/652)) @mr-kelly +- docs: Improve translation of README and developer-guide in other languages ([#285](https://github.com/apitable/apitable/pull/285)) @mr-kelly +- docs: add brew install canvas ([#599](https://github.com/apitable/apitable/pull/599)) (#654) @Exclamation-mark +- docs: remove description of default username in readme ([#657](https://github.com/apitable/apitable/pull/657)) @ChambersChan +- docs: developer-guide add multilingual translation (l10n) workflow ([#661](https://github.com/apitable/apitable/pull/661)) @Exclamation-mark +- docs: add multi-language images ([#663](https://github.com/apitable/apitable/pull/663)) @luoyunyao +- sync: hosted cloud ([#670](https://github.com/apitable/apitable/pull/670)) @yort-feng +## [v0.19.0-beta](https://github.com/apitable/apitable/releases/tag/v0.19.0-beta) (2023-03-27) ### Bug fixes -* fix: sign up password placeholder string @laboonly -* fix: sign up password placeholder string ([#590](https://github.com/apitable/apitable/pull/590)) @laboonly -* fix: subscription key undefined check ([#629](https://github.com/apitable/apitable/pull/629)) @wangkailang -* fix: level card subscription check ([#648](https://github.com/apitable/apitable/pull/648)) @wangkailang +- fix: sign up password placeholder string @laboonly +- fix: sign up password placeholder string ([#590](https://github.com/apitable/apitable/pull/590)) @laboonly +- fix: subscription key undefined check ([#629](https://github.com/apitable/apitable/pull/629)) @wangkailang +- fix: level card subscription check ([#648](https://github.com/apitable/apitable/pull/648)) @wangkailang ### What's more -* docs: update developer-guide.md ([#605](https://github.com/apitable/apitable/pull/605)) @mr-kelly -* doc: answer api document address ([#606](https://github.com/apitable/apitable/pull/606)) @shawndenggh -* docs: answer smtp configure & the limitation of widget quantity in da… ([#608](https://github.com/apitable/apitable/pull/608)) @ChambersChan -* docs: answer default port and upgrade @paylm -* docs: answer default port ([#613](https://github.com/apitable/apitable/pull/613)) @paylm -* sync: hosted cloud ([#611](https://github.com/apitable/apitable/pull/611)) @ChambersChan -* docs: developer guide questions ([#609](https://github.com/apitable/apitable/pull/609)) @yort-feng -* chore: contributing in readme ([#624](https://github.com/apitable/apitable/pull/624)) @mr-kelly -* chore: update async view config @wmEvie -* chore: update async view config ([#632](https://github.com/apitable/apitable/pull/632)) @wmEvie -* chore: heartbeat cron ([#641](https://github.com/apitable/apitable/pull/641)) @ChambersChan -* sync: hosted cloud ([#642](https://github.com/apitable/apitable/pull/642)) @yort-feng -## [v0.19.0-alpha](https://github.com/apitable/apitable/releases/tag/v0.19.0-alpha) (2023-03-20) +- docs: update developer-guide.md ([#605](https://github.com/apitable/apitable/pull/605)) @mr-kelly +- doc: answer api document address ([#606](https://github.com/apitable/apitable/pull/606)) @shawndenggh +- docs: answer smtp configure & the limitation of widget quantity in da… ([#608](https://github.com/apitable/apitable/pull/608)) @ChambersChan +- docs: answer default port and upgrade @paylm +- docs: answer default port ([#613](https://github.com/apitable/apitable/pull/613)) @paylm +- sync: hosted cloud ([#611](https://github.com/apitable/apitable/pull/611)) @ChambersChan +- docs: developer guide questions ([#609](https://github.com/apitable/apitable/pull/609)) @yort-feng +- chore: contributing in readme ([#624](https://github.com/apitable/apitable/pull/624)) @mr-kelly +- chore: update async view config @wmEvie +- chore: update async view config ([#632](https://github.com/apitable/apitable/pull/632)) @wmEvie +- chore: heartbeat cron ([#641](https://github.com/apitable/apitable/pull/641)) @ChambersChan +- sync: hosted cloud ([#642](https://github.com/apitable/apitable/pull/642)) @yort-feng +## [v0.19.0-alpha](https://github.com/apitable/apitable/releases/tag/v0.19.0-alpha) (2023-03-20) ### Bug fixes -* fix: remove unused test file ([#565](https://github.com/apitable/apitable/pull/565)) @shawndenggh -* fix: disable awsc ignore verification ([#577](https://github.com/apitable/apitable/pull/577)) @wangkailang -* fix: sign up password placeholder string @laboonly -* fix: sign up password placeholder string ([#590](https://github.com/apitable/apitable/pull/590)) @laboonly +- fix: remove unused test file ([#565](https://github.com/apitable/apitable/pull/565)) @shawndenggh +- fix: disable awsc ignore verification ([#577](https://github.com/apitable/apitable/pull/577)) @wangkailang +- fix: sign up password placeholder string @laboonly +- fix: sign up password placeholder string ([#590](https://github.com/apitable/apitable/pull/590)) @laboonly ### What's more -* release: v0.18.0-rc.2 ([#556](https://github.com/apitable/apitable/pull/556)) @yort-feng -* sync: hosted cloud ([#589](https://github.com/apitable/apitable/pull/589)) @yort-feng -## [v0.18.0-rc.2](https://github.com/apitable/apitable/releases/tag/v0.18.0-rc.2) (2023-03-13) +- release: v0.18.0-rc.2 ([#556](https://github.com/apitable/apitable/pull/556)) @yort-feng +- sync: hosted cloud ([#589](https://github.com/apitable/apitable/pull/589)) @yort-feng +## [v0.18.0-rc.2](https://github.com/apitable/apitable/releases/tag/v0.18.0-rc.2) (2023-03-13) ### Features and enhancements -* feat: optimize patch records api ([#526](https://github.com/apitable/apitable/pull/526)) @yort-feng -* feat: optimize post records api ([#544](https://github.com/apitable/apitable/pull/544)) @yort-feng -* feat: add a snippet code of prodcut analytics ([#547](https://github.com/apitable/apitable/pull/547)) @Sky-FE -* feat: support huaweicloud OBS for Oss ([#537](https://github.com/apitable/apitable/pull/537)) @showlovetommy +- feat: optimize patch records api ([#526](https://github.com/apitable/apitable/pull/526)) @yort-feng +- feat: optimize post records api ([#544](https://github.com/apitable/apitable/pull/544)) @yort-feng +- feat: add a snippet code of prodcut analytics ([#547](https://github.com/apitable/apitable/pull/547)) @Sky-FE +- feat: support huaweicloud OBS for Oss ([#537](https://github.com/apitable/apitable/pull/537)) @showlovetommy ### Bug fixes -* fix: correct env value about all-in-one dockerfile ([#528](https://github.com/apitable/apitable/pull/528)) @ChambersChan -* fix: init theme in widget runtime ([#542](https://github.com/apitable/apitable/pull/542)) @boris-w -* fix: query may be undefined ([#553](https://github.com/apitable/apitable/pull/553)) @boris-w +- fix: correct env value about all-in-one dockerfile ([#528](https://github.com/apitable/apitable/pull/528)) @ChambersChan +- fix: init theme in widget runtime ([#542](https://github.com/apitable/apitable/pull/542)) @boris-w +- fix: query may be undefined ([#553](https://github.com/apitable/apitable/pull/553)) @boris-w ### What's more -* refactor: replace node cte sql ([#473](https://github.com/apitable/apitable/pull/473)) @ChambersChan -* sync: hosted cloud ([#551](https://github.com/apitable/apitable/pull/551)) @yort-feng -## [v0.18.0-rc.1](https://github.com/apitable/apitable/releases/tag/v0.18.0-rc.1) (2023-03-06) +- refactor: replace node cte sql ([#473](https://github.com/apitable/apitable/pull/473)) @ChambersChan +- sync: hosted cloud ([#551](https://github.com/apitable/apitable/pull/551)) @yort-feng +## [v0.18.0-rc.1](https://github.com/apitable/apitable/releases/tag/v0.18.0-rc.1) (2023-03-06) ### Features and enhancements -* feat: fix existing unidir link ([#3333](https://github.com/apitable/apitable/pull/3333)) @arucil -* feat: apitable support to reset password ([#3278](https://github.com/apitable/apitable/pull/3278)) @zoe-icu -* feat: timezone fe ([#3268](https://github.com/apitable/apitable/pull/3268)) @wangkailang -* feat: apitable change password ([#3369](https://github.com/apitable/apitable/pull/3369)) @laboonly -* feat: components color change ([#3386](https://github.com/apitable/apitable/pull/3386)) @laboonly -* feat: add apitable cloud reset password error message ([#3438](https://github.com/apitable/apitable/pull/3438)) @laboonly -* feat: auth0 email varify ([#3465](https://github.com/apitable/apitable/pull/3465)) @zoe-icu -* feat: apitable email verification page ([#3456](https://github.com/apitable/apitable/pull/3456)) @laboonly -* feat: node update/create api modify ([#3477](https://github.com/apitable/apitable/pull/3477)) @zoe-icu -* feat: infoflow share form permission ([#3469](https://github.com/apitable/apitable/pull/3469)) @zoe-icu -* feat: design icons ([#3442](https://github.com/apitable/apitable/pull/3442)) @Sky-FE -* feat: migrate getRecordsById to rust ([#3391](https://github.com/apitable/apitable/pull/3391)) @arucil -* feat: merge test/0.18.1 into develop ([#3515](https://github.com/apitable/apitable/pull/3515)) @arucil -* feat: set system default timezone ([#3517](https://github.com/apitable/apitable/pull/3517)) @LiuZijingBron -* feat: phone and email input add input rules ([#3523](https://github.com/apitable/apitable/pull/3523)) @laboonly -* feat: static icons migration ([#3531](https://github.com/apitable/apitable/pull/3531)) @Sky-FE -* feat: api modify view name support to define view name length ([#3592](https://github.com/apitable/apitable/pull/3592)) @zoe-icu -* feat: schedule task for reporting ([#3585](https://github.com/apitable/apitable/pull/3585)) @shawndenggh -* feat: embed support manual save ([#3619](https://github.com/apitable/apitable/pull/3619)) @JaneSu - -### Bug fixes - -* fix: core unit test errors ([#3355](https://github.com/apitable/apitable/pull/3355)) @arucil -* fix: dayjs plugin ts error ([#3365](https://github.com/apitable/apitable/pull/3365)) @wangkailang -* fix: link auth0 user provider should not be null ([#3377](https://github.com/apitable/apitable/pull/3377)) @zoe-icu -* fix: use sensors env ([#3404](https://github.com/apitable/apitable/pull/3404)) @wangkailang -* fix: avoid form commit no change jot ([#3437](https://github.com/apitable/apitable/pull/3437)) @wangkailang -* fix: only enterprise set symlinks false ([#3448](https://github.com/apitable/apitable/pull/3448)) @wangkailang -* fix: mobile style ([#3453](https://github.com/apitable/apitable/pull/3453)) @wangkailang -* fix: modify node info cannot be synchronized ([#3452](https://github.com/apitable/apitable/pull/3452)) @zoe-icu -* fix: share embed modal form hidden logo ([#3459](https://github.com/apitable/apitable/pull/3459)) @laboonly -* fix: mirror add record ([#3462](https://github.com/apitable/apitable/pull/3462)) @arucil -* fix: sensors not found ([#3464](https://github.com/apitable/apitable/pull/3464)) @wangkailang -* fix: widget menu render ([#3468](https://github.com/apitable/apitable/pull/3468)) @boris-w -* fix: collaborative add widget in the dashboard does not get the entity ([#3480](https://github.com/apitable/apitable/pull/3480)) @boris-w -* fix: mobile menu group style ([#3487](https://github.com/apitable/apitable/pull/3487)) @wangkailang -* fix: widget grid layout init in the dashborad ([#3488](https://github.com/apitable/apitable/pull/3488)) @boris-w -* fix: popup css error ([#3489](https://github.com/apitable/apitable/pull/3489)) @wangkailang -* fix: dashboard init layout ([#3509](https://github.com/apitable/apitable/pull/3509)) @boris-w -* fix: safari create team fail ([#3507](https://github.com/apitable/apitable/pull/3507)) @wangkailang -* fix: View name length handling error ([#3521](https://github.com/apitable/apitable/pull/3521)) @JaneSu -* fix: embed link expand record show comment pane ([#3547](https://github.com/apitable/apitable/pull/3547)) @laboonly -* fix: databus unit test type errors ([#3546](https://github.com/apitable/apitable/pull/3546)) @arucil -* fix: email and phone feild input add rules ([#3561](https://github.com/apitable/apitable/pull/3561)) @laboonly -* fix: unknown column issue ([#3562](https://github.com/apitable/apitable/pull/3562)) @yort-feng -* fix: env control nps disable ([#3578](https://github.com/apitable/apitable/pull/3578)) @wangkailang -* fix: reset password get verify code ([#3586](https://github.com/apitable/apitable/pull/3586)) @wangkailang -* fix: space manual view save not work on embed link ([#3581](https://github.com/apitable/apitable/pull/3581)) @zoe-icu -* fix: web ci fail ([#3593](https://github.com/apitable/apitable/pull/3593)) @wangkailang -* fix: icon style ([#3600](https://github.com/apitable/apitable/pull/3600)) @Sky-FE -* fix: multi timeZone serializer ([#3580](https://github.com/apitable/apitable/pull/3580)) @LiuZijingBron -* fix: apitable register bugfix @laboonly -* fix: clear console.log @laboonly -* fix: the logo on the create space page supports the dark theme ([#508](https://github.com/apitable/apitable/pull/508)) @boris-w -* fix: missing import @laboonly -* fix: apitable register bugfix ([#509](https://github.com/apitable/apitable/pull/509)) @laboonly - -### What's more - -* chore: upgrade email copy right @xukecheng -* Merge branch 'develop' into chore/upgrade_email_copy_right @xukecheng -* Fix/iteration14 bugfix ([#3351](https://github.com/apitable/apitable/pull/3351)) @laboonly -* Feat/iframe ([#3361](https://github.com/apitable/apitable/pull/3361)) @JaneSu -* test: add update user timezone unit test ([#3366](https://github.com/apitable/apitable/pull/3366)) @LiuZijingBron -* sync: APITable Merge commit 'e6f50e43c1595fd16906c1eabd400f7fdf442542' into develop @mr-kelly -* Feat/apitable change password ([#3371](https://github.com/apitable/apitable/pull/3371)) @laboonly -* sync: APITable Merge commit '15856531bd388cc9272c474b19930af398c23c07' into develop @mr-kelly -* Feat/apitable change password ([#3374](https://github.com/apitable/apitable/pull/3374)) @laboonly -* Fix cola ([#3381](https://github.com/apitable/apitable/pull/3381)) @JaneSu -* chore: classify enterprise dir ([#3372](https://github.com/apitable/apitable/pull/3372)) @shawndenggh -* Merge commit '4d600c938308566f6776d3dfadd8860fd5959fe0' into develop @mr-kelly -* Fix cola ([#3415](https://github.com/apitable/apitable/pull/3415)) @JaneSu -* refactor: integrate DataBus into frontend ([#3037](https://github.com/apitable/apitable/pull/3037)) @arucil -* Feat/embed dashboard ([#3440](https://github.com/apitable/apitable/pull/3440)) @JaneSu -* chore: merge release/0.18.0 to develop ([#3433](https://github.com/apitable/apitable/pull/3433)) @boris-w -* chore: apply edition db changeset depend on local differ edition development ([#3447](https://github.com/apitable/apitable/pull/3447)) @shawndenggh -* refactor: view derivation calculated data ([#2853](https://github.com/apitable/apitable/pull/2853)) @boris-w -* revert: restore init-appdata service in dataenv-up ([#3450](https://github.com/apitable/apitable/pull/3450)) @shawndenggh -* Feat/embed dashboard ([#3451](https://github.com/apitable/apitable/pull/3451)) @JaneSu -* sync: APITable Merge commit '8eb02d1f6fbd1ab43827fadc3e13cc7189c7d02d' into develop @mr-kelly -* chore: unified data services image version ([#3460](https://github.com/apitable/apitable/pull/3460)) @shawndenggh -* chore: apitable data services image version change ([#3461](https://github.com/apitable/apitable/pull/3461)) @shawndenggh -* chore: third-party scripts env ([#3457](https://github.com/apitable/apitable/pull/3457)) @wangkailang -* Feat/embed dashboard ([#3470](https://github.com/apitable/apitable/pull/3470)) @JaneSu -* chore: tune mail starter ([#3483](https://github.com/apitable/apitable/pull/3483)) @ChambersChan -* sync: APITable Merge commit '4135b4e190bca5828c6e19b253e3401575eb3108' into develop @mr-kelly -* sync: APITable Merge branch 'develop' of github.com:vikadata/vikadata into develop @mr-kelly -* Revert "feat: migrate getRecordsById to rust ([#3391](https://github.com/apitable/apitable/pull/3391))" (#3500) @arucil -* chore: tune afs starter & upload afs verify ([#3512](https://github.com/apitable/apitable/pull/3512)) @ChambersChan -* sync: APITable Merge commit '99f80b54f12d3f68dc5af318dee10696760b4aa6' into develop @mr-kelly -* refactor: resolve merge conflict ([#3533](https://github.com/apitable/apitable/pull/3533)) @zoe-icu -* sync: apitable to vikadata ([#3540](https://github.com/apitable/apitable/pull/3540)) @yort-feng -* chore: ci for cross compiling room-native-api to arm64 ([#3536](https://github.com/apitable/apitable/pull/3536)) @arucil -* sync: apitable ([#3564](https://github.com/apitable/apitable/pull/3564)) @Sky-FE -* Revert "sync: apitable" ([#3583](https://github.com/apitable/apitable/pull/3583)) @yort-feng -* Merge commit '1815a91b6f96361fefcd1de83b7463f0efeecb58' into develop @yort-feng -* chore: revert commit codes manully due to auto merge issue @yort-feng -* Merge branch 'develop' into sync/apitable-23022802 @yort-feng -* Feat/apitable ce register ([#3606](https://github.com/apitable/apitable/pull/3606)) @laboonly -* chore: merge conflict @Sky-FE -* Sync/hosted ([#487](https://github.com/apitable/apitable/pull/487)) @laboonly -* chore: sync env to all-in-one dockerfile ([#491](https://github.com/apitable/apitable/pull/491)) @ChambersChan -* docs: improve zh-CN translation ([#367](https://github.com/apitable/apitable/pull/367)) @xianjianlf2 -* chore: upgrade email copy right ([#298](https://github.com/apitable/apitable/pull/298)) @xukecheng -* hpm log with api prefix ([#476](https://github.com/apitable/apitable/pull/476)) @buzuosheng -* Merge branch 'develop' into fix/register-bugfix @laboonly -* Merge branch 'develop' into fix/register-bugfix @laboonly -* Merge branch 'fix/register-bugfix' of github.com:apitable/apitable into fix/register-bugfix @laboonly -* sync: hosted cloud ([#511](https://github.com/apitable/apitable/pull/511)) @yort-feng -## [v0.18.0-rc](https://github.com/apitable/apitable/releases/tag/v0.18.0-rc) (2023-02-28) +- feat: fix existing unidir link ([#3333](https://github.com/apitable/apitable/pull/3333)) @arucil +- feat: apitable support to reset password ([#3278](https://github.com/apitable/apitable/pull/3278)) @zoe-icu +- feat: timezone fe ([#3268](https://github.com/apitable/apitable/pull/3268)) @wangkailang +- feat: apitable change password ([#3369](https://github.com/apitable/apitable/pull/3369)) @laboonly +- feat: components color change ([#3386](https://github.com/apitable/apitable/pull/3386)) @laboonly +- feat: add apitable cloud reset password error message ([#3438](https://github.com/apitable/apitable/pull/3438)) @laboonly +- feat: auth0 email varify ([#3465](https://github.com/apitable/apitable/pull/3465)) @zoe-icu +- feat: apitable email verification page ([#3456](https://github.com/apitable/apitable/pull/3456)) @laboonly +- feat: node update/create api modify ([#3477](https://github.com/apitable/apitable/pull/3477)) @zoe-icu +- feat: infoflow share form permission ([#3469](https://github.com/apitable/apitable/pull/3469)) @zoe-icu +- feat: design icons ([#3442](https://github.com/apitable/apitable/pull/3442)) @Sky-FE +- feat: migrate getRecordsById to rust ([#3391](https://github.com/apitable/apitable/pull/3391)) @arucil +- feat: merge test/0.18.1 into develop ([#3515](https://github.com/apitable/apitable/pull/3515)) @arucil +- feat: set system default timezone ([#3517](https://github.com/apitable/apitable/pull/3517)) @LiuZijingBron +- feat: phone and email input add input rules ([#3523](https://github.com/apitable/apitable/pull/3523)) @laboonly +- feat: static icons migration ([#3531](https://github.com/apitable/apitable/pull/3531)) @Sky-FE +- feat: api modify view name support to define view name length ([#3592](https://github.com/apitable/apitable/pull/3592)) @zoe-icu +- feat: schedule task for reporting ([#3585](https://github.com/apitable/apitable/pull/3585)) @shawndenggh +- feat: embed support manual save ([#3619](https://github.com/apitable/apitable/pull/3619)) @JaneSu + +### Bug fixes + +- fix: core unit test errors ([#3355](https://github.com/apitable/apitable/pull/3355)) @arucil +- fix: dayjs plugin ts error ([#3365](https://github.com/apitable/apitable/pull/3365)) @wangkailang +- fix: link auth0 user provider should not be null ([#3377](https://github.com/apitable/apitable/pull/3377)) @zoe-icu +- fix: use sensors env ([#3404](https://github.com/apitable/apitable/pull/3404)) @wangkailang +- fix: avoid form commit no change jot ([#3437](https://github.com/apitable/apitable/pull/3437)) @wangkailang +- fix: only enterprise set symlinks false ([#3448](https://github.com/apitable/apitable/pull/3448)) @wangkailang +- fix: mobile style ([#3453](https://github.com/apitable/apitable/pull/3453)) @wangkailang +- fix: modify node info cannot be synchronized ([#3452](https://github.com/apitable/apitable/pull/3452)) @zoe-icu +- fix: share embed modal form hidden logo ([#3459](https://github.com/apitable/apitable/pull/3459)) @laboonly +- fix: mirror add record ([#3462](https://github.com/apitable/apitable/pull/3462)) @arucil +- fix: sensors not found ([#3464](https://github.com/apitable/apitable/pull/3464)) @wangkailang +- fix: widget menu render ([#3468](https://github.com/apitable/apitable/pull/3468)) @boris-w +- fix: collaborative add widget in the dashboard does not get the entity ([#3480](https://github.com/apitable/apitable/pull/3480)) @boris-w +- fix: mobile menu group style ([#3487](https://github.com/apitable/apitable/pull/3487)) @wangkailang +- fix: widget grid layout init in the dashborad ([#3488](https://github.com/apitable/apitable/pull/3488)) @boris-w +- fix: popup css error ([#3489](https://github.com/apitable/apitable/pull/3489)) @wangkailang +- fix: dashboard init layout ([#3509](https://github.com/apitable/apitable/pull/3509)) @boris-w +- fix: safari create team fail ([#3507](https://github.com/apitable/apitable/pull/3507)) @wangkailang +- fix: View name length handling error ([#3521](https://github.com/apitable/apitable/pull/3521)) @JaneSu +- fix: embed link expand record show comment pane ([#3547](https://github.com/apitable/apitable/pull/3547)) @laboonly +- fix: databus unit test type errors ([#3546](https://github.com/apitable/apitable/pull/3546)) @arucil +- fix: email and phone feild input add rules ([#3561](https://github.com/apitable/apitable/pull/3561)) @laboonly +- fix: unknown column issue ([#3562](https://github.com/apitable/apitable/pull/3562)) @yort-feng +- fix: env control nps disable ([#3578](https://github.com/apitable/apitable/pull/3578)) @wangkailang +- fix: reset password get verify code ([#3586](https://github.com/apitable/apitable/pull/3586)) @wangkailang +- fix: space manual view save not work on embed link ([#3581](https://github.com/apitable/apitable/pull/3581)) @zoe-icu +- fix: web ci fail ([#3593](https://github.com/apitable/apitable/pull/3593)) @wangkailang +- fix: icon style ([#3600](https://github.com/apitable/apitable/pull/3600)) @Sky-FE +- fix: multi timeZone serializer ([#3580](https://github.com/apitable/apitable/pull/3580)) @LiuZijingBron +- fix: apitable register bugfix @laboonly +- fix: clear console.log @laboonly +- fix: the logo on the create space page supports the dark theme ([#508](https://github.com/apitable/apitable/pull/508)) @boris-w +- fix: missing import @laboonly +- fix: apitable register bugfix ([#509](https://github.com/apitable/apitable/pull/509)) @laboonly + +### What's more + +- chore: upgrade email copy right @xukecheng +- Merge branch 'develop' into chore/upgrade_email_copy_right @xukecheng +- Fix/iteration14 bugfix ([#3351](https://github.com/apitable/apitable/pull/3351)) @laboonly +- Feat/iframe ([#3361](https://github.com/apitable/apitable/pull/3361)) @JaneSu +- test: add update user timezone unit test ([#3366](https://github.com/apitable/apitable/pull/3366)) @LiuZijingBron +- sync: APITable Merge commit 'e6f50e43c1595fd16906c1eabd400f7fdf442542' into develop @mr-kelly +- Feat/apitable change password ([#3371](https://github.com/apitable/apitable/pull/3371)) @laboonly +- sync: APITable Merge commit '15856531bd388cc9272c474b19930af398c23c07' into develop @mr-kelly +- Feat/apitable change password ([#3374](https://github.com/apitable/apitable/pull/3374)) @laboonly +- Fix cola ([#3381](https://github.com/apitable/apitable/pull/3381)) @JaneSu +- chore: classify enterprise dir ([#3372](https://github.com/apitable/apitable/pull/3372)) @shawndenggh +- Merge commit '4d600c938308566f6776d3dfadd8860fd5959fe0' into develop @mr-kelly +- Fix cola ([#3415](https://github.com/apitable/apitable/pull/3415)) @JaneSu +- refactor: integrate DataBus into frontend ([#3037](https://github.com/apitable/apitable/pull/3037)) @arucil +- Feat/embed dashboard ([#3440](https://github.com/apitable/apitable/pull/3440)) @JaneSu +- chore: merge release/0.18.0 to develop ([#3433](https://github.com/apitable/apitable/pull/3433)) @boris-w +- chore: apply edition db changeset depend on local differ edition development ([#3447](https://github.com/apitable/apitable/pull/3447)) @shawndenggh +- refactor: view derivation calculated data ([#2853](https://github.com/apitable/apitable/pull/2853)) @boris-w +- revert: restore init-appdata service in dataenv-up ([#3450](https://github.com/apitable/apitable/pull/3450)) @shawndenggh +- Feat/embed dashboard ([#3451](https://github.com/apitable/apitable/pull/3451)) @JaneSu +- sync: APITable Merge commit '8eb02d1f6fbd1ab43827fadc3e13cc7189c7d02d' into develop @mr-kelly +- chore: unified data services image version ([#3460](https://github.com/apitable/apitable/pull/3460)) @shawndenggh +- chore: apitable data services image version change ([#3461](https://github.com/apitable/apitable/pull/3461)) @shawndenggh +- chore: third-party scripts env ([#3457](https://github.com/apitable/apitable/pull/3457)) @wangkailang +- Feat/embed dashboard ([#3470](https://github.com/apitable/apitable/pull/3470)) @JaneSu +- chore: tune mail starter ([#3483](https://github.com/apitable/apitable/pull/3483)) @ChambersChan +- sync: APITable Merge commit '4135b4e190bca5828c6e19b253e3401575eb3108' into develop @mr-kelly +- sync: APITable Merge branch 'develop' of github.com:vikadata/vikadata into develop @mr-kelly +- Revert "feat: migrate getRecordsById to rust ([#3391](https://github.com/apitable/apitable/pull/3391))" (#3500) @arucil +- chore: tune afs starter & upload afs verify ([#3512](https://github.com/apitable/apitable/pull/3512)) @ChambersChan +- sync: APITable Merge commit '99f80b54f12d3f68dc5af318dee10696760b4aa6' into develop @mr-kelly +- refactor: resolve merge conflict ([#3533](https://github.com/apitable/apitable/pull/3533)) @zoe-icu +- sync: apitable to vikadata ([#3540](https://github.com/apitable/apitable/pull/3540)) @yort-feng +- chore: ci for cross compiling room-native-api to arm64 ([#3536](https://github.com/apitable/apitable/pull/3536)) @arucil +- sync: apitable ([#3564](https://github.com/apitable/apitable/pull/3564)) @Sky-FE +- Revert "sync: apitable" ([#3583](https://github.com/apitable/apitable/pull/3583)) @yort-feng +- Merge commit '1815a91b6f96361fefcd1de83b7463f0efeecb58' into develop @yort-feng +- chore: revert commit codes manully due to auto merge issue @yort-feng +- Merge branch 'develop' into sync/apitable-23022802 @yort-feng +- Feat/apitable ce register ([#3606](https://github.com/apitable/apitable/pull/3606)) @laboonly +- chore: merge conflict @Sky-FE +- Sync/hosted ([#487](https://github.com/apitable/apitable/pull/487)) @laboonly +- chore: sync env to all-in-one dockerfile ([#491](https://github.com/apitable/apitable/pull/491)) @ChambersChan +- docs: improve zh-CN translation ([#367](https://github.com/apitable/apitable/pull/367)) @xianjianlf2 +- chore: upgrade email copy right ([#298](https://github.com/apitable/apitable/pull/298)) @xukecheng +- hpm log with api prefix ([#476](https://github.com/apitable/apitable/pull/476)) @buzuosheng +- Merge branch 'develop' into fix/register-bugfix @laboonly +- Merge branch 'develop' into fix/register-bugfix @laboonly +- Merge branch 'fix/register-bugfix' of github.com:apitable/apitable into fix/register-bugfix @laboonly +- sync: hosted cloud ([#511](https://github.com/apitable/apitable/pull/511)) @yort-feng +## [v0.18.0-rc](https://github.com/apitable/apitable/releases/tag/v0.18.0-rc) (2023-02-28) ### Features and enhancements -* feat: register api ([#440](https://github.com/apitable/apitable/pull/440)) @ChambersChan -* feat: replace controller's swagger2 annotation with openapi annotation @LiuZijingBron -* feat: modify lint.yml @LiuZijingBron -* feat: modify .jscpd.json @LiuZijingBron -* feat: Add email template: task-due-remind ([#438](https://github.com/apitable/apitable/pull/438)) @wmEvie - -### Bug fixes - -* fix: widget crash @JaneSu -* fix: widget crash ([#448](https://github.com/apitable/apitable/pull/448)) @JaneSu -* fix: parse date strings in the mobile calendar month picker according to standard format ([#449](https://github.com/apitable/apitable/pull/449)) @Sky-FE -* fix: trash error ([#455](https://github.com/apitable/apitable/pull/455)) @wangkailang -* fix: README spell ([#441](https://github.com/apitable/apitable/pull/441)) @0xflotus -* fix: robot error ([#458](https://github.com/apitable/apitable/pull/458)) @oolongTea007 - -### What's more - -* release: v0.18.0-beta ([#432](https://github.com/apitable/apitable/pull/432)) @yort-feng -* docs: remove start socket server introduce ([#436](https://github.com/apitable/apitable/pull/436)) @ChambersChan -* Add email template: task-due-remind @wmEvie -* chore: replace swagger2 with springdoc-openapi @LiuZijingBron -* Update subject.properties @wmEvie -* Merge branch 'develop' into chore-knife4j-swagger @LiuZijingBron -* chore: replace swagger2 with springdoc-openapi ([#439](https://github.com/apitable/apitable/pull/439)) @LiuZijingBron -* chore: replace model swagger2 annotation with openapi annotation @LiuZijingBron -* Merge branch 'develop' into chore-openapi-model @LiuZijingBron -* chore: replace model swagger2 annotation with openapi annotation ([#460](https://github.com/apitable/apitable/pull/460)) @LiuZijingBron -* docs: fix L10N readme href ([#456](https://github.com/apitable/apitable/pull/456)) @Jealee3000 -* chroe: Remove task due remind template @wmEvie -* chroe: Remove task due reminder template ([#466](https://github.com/apitable/apitable/pull/466)) @wmEvie -* test: add property based tests to DataBus ([#140](https://github.com/apitable/apitable/pull/140)) (#467) @Exclamation-mark -* refactor: replace dynamic sql in getUserInfo ([#453](https://github.com/apitable/apitable/pull/453)) @Jealee3000 -* sync: hosted cloud ([#470](https://github.com/apitable/apitable/pull/470)) @yort-feng -* chore: compatible widget icons ([#471](https://github.com/apitable/apitable/pull/471)) @Sky-FE -* Revert "refactor: replace dynamic sql in getUserInfo" ([#475](https://github.com/apitable/apitable/pull/475)) @yort-feng -## [v0.18.0-beta](https://github.com/apitable/apitable/releases/tag/v0.18.0-beta) (2023-02-22) +- feat: register api ([#440](https://github.com/apitable/apitable/pull/440)) @ChambersChan +- feat: replace controller's swagger2 annotation with openapi annotation @LiuZijingBron +- feat: modify lint.yml @LiuZijingBron +- feat: modify .jscpd.json @LiuZijingBron +- feat: Add email template: task-due-remind ([#438](https://github.com/apitable/apitable/pull/438)) @wmEvie + +### Bug fixes + +- fix: widget crash @JaneSu +- fix: widget crash ([#448](https://github.com/apitable/apitable/pull/448)) @JaneSu +- fix: parse date strings in the mobile calendar month picker according to standard format ([#449](https://github.com/apitable/apitable/pull/449)) @Sky-FE +- fix: trash error ([#455](https://github.com/apitable/apitable/pull/455)) @wangkailang +- fix: README spell ([#441](https://github.com/apitable/apitable/pull/441)) @0xflotus +- fix: robot error ([#458](https://github.com/apitable/apitable/pull/458)) @oolongTea007 + +### What's more + +- release: v0.18.0-beta ([#432](https://github.com/apitable/apitable/pull/432)) @yort-feng +- docs: remove start socket server introduce ([#436](https://github.com/apitable/apitable/pull/436)) @ChambersChan +- Add email template: task-due-remind @wmEvie +- chore: replace swagger2 with springdoc-openapi @LiuZijingBron +- Update subject.properties @wmEvie +- Merge branch 'develop' into chore-knife4j-swagger @LiuZijingBron +- chore: replace swagger2 with springdoc-openapi ([#439](https://github.com/apitable/apitable/pull/439)) @LiuZijingBron +- chore: replace model swagger2 annotation with openapi annotation @LiuZijingBron +- Merge branch 'develop' into chore-openapi-model @LiuZijingBron +- chore: replace model swagger2 annotation with openapi annotation ([#460](https://github.com/apitable/apitable/pull/460)) @LiuZijingBron +- docs: fix L10N readme href ([#456](https://github.com/apitable/apitable/pull/456)) @Jealee3000 +- chroe: Remove task due remind template @wmEvie +- chroe: Remove task due reminder template ([#466](https://github.com/apitable/apitable/pull/466)) @wmEvie +- test: add property based tests to DataBus ([#140](https://github.com/apitable/apitable/pull/140)) (#467) @Exclamation-mark +- refactor: replace dynamic sql in getUserInfo ([#453](https://github.com/apitable/apitable/pull/453)) @Jealee3000 +- sync: hosted cloud ([#470](https://github.com/apitable/apitable/pull/470)) @yort-feng +- chore: compatible widget icons ([#471](https://github.com/apitable/apitable/pull/471)) @Sky-FE +- Revert "refactor: replace dynamic sql in getUserInfo" ([#475](https://github.com/apitable/apitable/pull/475)) @yort-feng +## [v0.18.0-beta](https://github.com/apitable/apitable/releases/tag/v0.18.0-beta) (2023-02-22) ### Features and enhancements -* feat: fix existing unidir link & APITable support to reset password & timezone adjust ([#382](https://github.com/apitable/apitable/pull/382)) @mr-kelly -* feat: APITable support to reset password ([#401](https://github.com/apitable/apitable/pull/401)) @mr-kelly - -### Bug fixes - -* fix: oss host env variable value ([#346](https://github.com/apitable/apitable/pull/346)) @ChambersChan -* fix: reset password page @laboonly -* fix: reset password page ([#385](https://github.com/apitable/apitable/pull/385)) @laboonly -* fix: disable cdn resource ([#384](https://github.com/apitable/apitable/pull/384)) @wangkailang -* fix: env control sensors.js ([#397](https://github.com/apitable/apitable/pull/397)) @wangkailang -* fix: use sensors env ([#402](https://github.com/apitable/apitable/pull/402)) @wangkailang -* fix: gitpod setup install error ([#404](https://github.com/apitable/apitable/pull/404)) @shawndenggh -* fix: the formula of IS_ERROR is incorrectly calculated ([#427](https://github.com/apitable/apitable/pull/427)) @Sky-FE -* fix: record menu subscription item displayed incorrectly ([#428](https://github.com/apitable/apitable/pull/428)) @Sky-FE -* fix: formula WORKDAY_DIFF calculation error ([#435](https://github.com/apitable/apitable/pull/435)) @Sky-FE - -### What's more - -* chore(deps): bump @sideway/formula from 3.0.0 to 3.0.1 @dependabot[bot] -* release: v0.18.0-alpha ([#345](https://github.com/apitable/apitable/pull/345)) @mr-kelly -* refactor: merge forwarding about sokcet server ([#349](https://github.com/apitable/apitable/pull/349)) @ChambersChan -* chore: add all-in-one dockerfile and image build ([#355](https://github.com/apitable/apitable/pull/355)) @networkhermit -* chore: integrate semver to image build ([#358](https://github.com/apitable/apitable/pull/358)) @networkhermit -* unit module unit test ([#335](https://github.com/apitable/apitable/pull/335)) @wuyitaoBoomboommm -* chore(deps): bump @sideway/formula from 3.0.0 to 3.0.1 ([#340](https://github.com/apitable/apitable/pull/340)) @JaneSu -* chore: make LOGGER_MAX_HISTORY_DAYS an env variable and 7 by default ([#370](https://github.com/apitable/apitable/pull/370)) @yort-feng -* sync: hosted cloud ([#373](https://github.com/apitable/apitable/pull/373)) @mr-kelly -* docs: add all-in-one installation method ([#374](https://github.com/apitable/apitable/pull/374)) @networkhermit -* chore: set room server log file keep days to 7 by default ([#375](https://github.com/apitable/apitable/pull/375)) @yort-feng -* chore: modify mail configuration ([#418](https://github.com/apitable/apitable/pull/418)) @ChambersChan -* chore: replace share node tree ([#420](https://github.com/apitable/apitable/pull/420)) @ChambersChan -* chore: keep the default settings the same with devenv ([#426](https://github.com/apitable/apitable/pull/426)) @yort-feng -* docs: improve zh-HK translation ([#395](https://github.com/apitable/apitable/pull/395)) @KelvinAhKe -## [v0.18.0-alpha](https://github.com/apitable/apitable/releases/tag/v0.18.0-alpha) (2023-02-09) +- feat: fix existing unidir link & APITable support to reset password & timezone adjust ([#382](https://github.com/apitable/apitable/pull/382)) @mr-kelly +- feat: APITable support to reset password ([#401](https://github.com/apitable/apitable/pull/401)) @mr-kelly +### Bug fixes + +- fix: oss host env variable value ([#346](https://github.com/apitable/apitable/pull/346)) @ChambersChan +- fix: reset password page @laboonly +- fix: reset password page ([#385](https://github.com/apitable/apitable/pull/385)) @laboonly +- fix: disable cdn resource ([#384](https://github.com/apitable/apitable/pull/384)) @wangkailang +- fix: env control sensors.js ([#397](https://github.com/apitable/apitable/pull/397)) @wangkailang +- fix: use sensors env ([#402](https://github.com/apitable/apitable/pull/402)) @wangkailang +- fix: gitpod setup install error ([#404](https://github.com/apitable/apitable/pull/404)) @shawndenggh +- fix: the formula of IS_ERROR is incorrectly calculated ([#427](https://github.com/apitable/apitable/pull/427)) @Sky-FE +- fix: record menu subscription item displayed incorrectly ([#428](https://github.com/apitable/apitable/pull/428)) @Sky-FE +- fix: formula WORKDAY_DIFF calculation error ([#435](https://github.com/apitable/apitable/pull/435)) @Sky-FE + +### What's more + +- chore(deps): bump @sideway/formula from 3.0.0 to 3.0.1 @dependabot[bot] +- release: v0.18.0-alpha ([#345](https://github.com/apitable/apitable/pull/345)) @mr-kelly +- refactor: merge forwarding about sokcet server ([#349](https://github.com/apitable/apitable/pull/349)) @ChambersChan +- chore: add all-in-one dockerfile and image build ([#355](https://github.com/apitable/apitable/pull/355)) @networkhermit +- chore: integrate semver to image build ([#358](https://github.com/apitable/apitable/pull/358)) @networkhermit +- unit module unit test ([#335](https://github.com/apitable/apitable/pull/335)) @wuyitaoBoomboommm +- chore(deps): bump @sideway/formula from 3.0.0 to 3.0.1 ([#340](https://github.com/apitable/apitable/pull/340)) @JaneSu +- chore: make LOGGER_MAX_HISTORY_DAYS an env variable and 7 by default ([#370](https://github.com/apitable/apitable/pull/370)) @yort-feng +- sync: hosted cloud ([#373](https://github.com/apitable/apitable/pull/373)) @mr-kelly +- docs: add all-in-one installation method ([#374](https://github.com/apitable/apitable/pull/374)) @networkhermit +- chore: set room server log file keep days to 7 by default ([#375](https://github.com/apitable/apitable/pull/375)) @yort-feng +- chore: modify mail configuration ([#418](https://github.com/apitable/apitable/pull/418)) @ChambersChan +- chore: replace share node tree ([#420](https://github.com/apitable/apitable/pull/420)) @ChambersChan +- chore: keep the default settings the same with devenv ([#426](https://github.com/apitable/apitable/pull/426)) @yort-feng +- docs: improve zh-HK translation ([#395](https://github.com/apitable/apitable/pull/395)) @KelvinAhKe + +## [v0.18.0-alpha](https://github.com/apitable/apitable/releases/tag/v0.18.0-alpha) (2023-02-09) ### Bug fixes -* fix: error logo in email templates @xukecheng -* fix: wrong left padding of views ([#278](https://github.com/apitable/apitable/pull/278)) @Sky-FE -* fix: correct space apply mail link ([#277](https://github.com/apitable/apitable/pull/277)) @ChambersChan -* fix: the gantt view is exported as a png image misplaced ([#281](https://github.com/apitable/apitable/pull/281)) @Sky-FE -* fix: error logo in email templates ([#276](https://github.com/apitable/apitable/pull/276)) @xukecheng -* fix: assets url ([#309](https://github.com/apitable/apitable/pull/309)) @Pengap -* fix: formula parser doesn't recognize single negation expresison ([#192](https://github.com/apitable/apitable/pull/192)) @arucil -* fix: space list sort issue ([#312](https://github.com/apitable/apitable/pull/312)) @ChambersChan -* fix: path get actions miss id and type id ([#317](https://github.com/apitable/apitable/pull/317)) @wuyitaoBoomboommm -* fix: active robot error validation ([#318](https://github.com/apitable/apitable/pull/318)) @wuyitaoBoomboommm -* fix: start web-server cause room-server compile error ([#324](https://github.com/apitable/apitable/pull/324)) @arucil -* fix: email contact us url ([#330](https://github.com/apitable/apitable/pull/330)) @xukecheng -* fix: missing .proto files ([#329](https://github.com/apitable/apitable/pull/329)) @yort-feng -* fix: there are wrong css for button in email @xukecheng -* fix: there are wrong css for button in email ([#333](https://github.com/apitable/apitable/pull/333)) @xukecheng - -### What's more - -* perf: help menu auto layout ([#260](https://github.com/apitable/apitable/pull/260)) @Sky-FE -* Fix: fix readme typo ([#262](https://github.com/apitable/apitable/pull/262)) @x1ah -* docs: improve zh-CN translations ([#265](https://github.com/apitable/apitable/pull/265)) @alexzhang1030 -* chore: contributing in readme ([#284](https://github.com/apitable/apitable/pull/284)) @mr-kelly -* Update README.md ([#302](https://github.com/apitable/apitable/pull/302)) @garyli27 -* style: upgrade jsx-ast-utils to support Optional Chaining ([#311](https://github.com/apitable/apitable/pull/311)) @yort-feng -* sync: hosted cloud ([#316](https://github.com/apitable/apitable/pull/316)) @mr-kelly -* chore: replace the sql statement with ORM api. ([#273](https://github.com/apitable/apitable/pull/273)) @wuyitaoBoomboommm -* chore: root README_ZH.md ([#287](https://github.com/apitable/apitable/pull/287)) @mr-kelly -* chore: replace contact url @xukecheng -* chore: upgrade email copy right @xukecheng -* docs: add better uptime badge and clarify installation requirement ([#328](https://github.com/apitable/apitable/pull/328)) @networkhermit -* chore: replace logo to png @xukecheng -* test: mirror service unit test ([#280](https://github.com/apitable/apitable/pull/280)) @yort-feng -* sync: hosted cloud ([#339](https://github.com/apitable/apitable/pull/339)) @Pengap -* docs: super link for architecture overview ([#341](https://github.com/apitable/apitable/pull/341)) @yort-feng -* docs: README for APITable.com cloud version ([#342](https://github.com/apitable/apitable/pull/342)) @mr-kelly -## [v0.17.0-rc](https://github.com/apitable/apitable/releases/tag/v0.17.0-rc) (2023-01-23) +- fix: error logo in email templates @xukecheng +- fix: wrong left padding of views ([#278](https://github.com/apitable/apitable/pull/278)) @Sky-FE +- fix: correct space apply mail link ([#277](https://github.com/apitable/apitable/pull/277)) @ChambersChan +- fix: the gantt view is exported as a png image misplaced ([#281](https://github.com/apitable/apitable/pull/281)) @Sky-FE +- fix: error logo in email templates ([#276](https://github.com/apitable/apitable/pull/276)) @xukecheng +- fix: assets url ([#309](https://github.com/apitable/apitable/pull/309)) @Pengap +- fix: formula parser doesn't recognize single negation expresison ([#192](https://github.com/apitable/apitable/pull/192)) @arucil +- fix: space list sort issue ([#312](https://github.com/apitable/apitable/pull/312)) @ChambersChan +- fix: path get actions miss id and type id ([#317](https://github.com/apitable/apitable/pull/317)) @wuyitaoBoomboommm +- fix: active robot error validation ([#318](https://github.com/apitable/apitable/pull/318)) @wuyitaoBoomboommm +- fix: start web-server cause room-server compile error ([#324](https://github.com/apitable/apitable/pull/324)) @arucil +- fix: email contact us url ([#330](https://github.com/apitable/apitable/pull/330)) @xukecheng +- fix: missing .proto files ([#329](https://github.com/apitable/apitable/pull/329)) @yort-feng +- fix: there are wrong css for button in email @xukecheng +- fix: there are wrong css for button in email ([#333](https://github.com/apitable/apitable/pull/333)) @xukecheng + +### What's more + +- perf: help menu auto layout ([#260](https://github.com/apitable/apitable/pull/260)) @Sky-FE +- Fix: fix readme typo ([#262](https://github.com/apitable/apitable/pull/262)) @x1ah +- docs: improve zh-CN translations ([#265](https://github.com/apitable/apitable/pull/265)) @alexzhang1030 +- chore: contributing in readme ([#284](https://github.com/apitable/apitable/pull/284)) @mr-kelly +- Update README.md ([#302](https://github.com/apitable/apitable/pull/302)) @garyli27 +- style: upgrade jsx-ast-utils to support Optional Chaining ([#311](https://github.com/apitable/apitable/pull/311)) @yort-feng +- sync: hosted cloud ([#316](https://github.com/apitable/apitable/pull/316)) @mr-kelly +- chore: replace the sql statement with ORM api. ([#273](https://github.com/apitable/apitable/pull/273)) @wuyitaoBoomboommm +- chore: root README_ZH.md ([#287](https://github.com/apitable/apitable/pull/287)) @mr-kelly +- chore: replace contact url @xukecheng +- chore: upgrade email copy right @xukecheng +- docs: add better uptime badge and clarify installation requirement ([#328](https://github.com/apitable/apitable/pull/328)) @networkhermit +- chore: replace logo to png @xukecheng +- test: mirror service unit test ([#280](https://github.com/apitable/apitable/pull/280)) @yort-feng +- sync: hosted cloud ([#339](https://github.com/apitable/apitable/pull/339)) @Pengap +- docs: super link for architecture overview ([#341](https://github.com/apitable/apitable/pull/341)) @yort-feng +- docs: README for APITable.com cloud version ([#342](https://github.com/apitable/apitable/pull/342)) @mr-kelly +## [v0.17.0-rc](https://github.com/apitable/apitable/releases/tag/v0.17.0-rc) (2023-01-23) ### Bug fixes -* fix: make minor semver conflict @mr-kelly -* fix: replace wrong email logo @xukecheng -* fix: wrong variable @xukecheng -* fix: replace wrong email templates ([#190](https://github.com/apitable/apitable/pull/190)) @xukecheng -* fix: unable to operate members and teams ([#214](https://github.com/apitable/apitable/pull/214)) @MrWangQAQ -* fix: the default value of the percent field cannot be reset ([#215](https://github.com/apitable/apitable/pull/215)) @alolonghun -* fix: fusion api param validation decorators & qr code download failed & unable to operate members and teams ([#217](https://github.com/apitable/apitable/pull/217)) @mr-kelly -* fix: the page crashes when the option field configures the color ([#219](https://github.com/apitable/apitable/pull/219)) @alolonghun -* fix: expand record comment emoji reply ([#218](https://github.com/apitable/apitable/pull/218)) @MrWangQAQ -* fix: color match ([#220](https://github.com/apitable/apitable/pull/220)) @alolonghun -* fix: sync hosted version & fusion api param validation error & login page QR code cannot be displayed & wrong email folder name ([#223](https://github.com/apitable/apitable/pull/223)) @mr-kelly +- fix: make minor semver conflict @mr-kelly +- fix: replace wrong email logo @xukecheng +- fix: wrong variable @xukecheng +- fix: replace wrong email templates ([#190](https://github.com/apitable/apitable/pull/190)) @xukecheng +- fix: unable to operate members and teams ([#214](https://github.com/apitable/apitable/pull/214)) @MrWangQAQ +- fix: the default value of the percent field cannot be reset ([#215](https://github.com/apitable/apitable/pull/215)) @alolonghun +- fix: fusion api param validation decorators & qr code download failed & unable to operate members and teams ([#217](https://github.com/apitable/apitable/pull/217)) @mr-kelly +- fix: the page crashes when the option field configures the color ([#219](https://github.com/apitable/apitable/pull/219)) @alolonghun +- fix: expand record comment emoji reply ([#218](https://github.com/apitable/apitable/pull/218)) @MrWangQAQ +- fix: color match ([#220](https://github.com/apitable/apitable/pull/220)) @alolonghun +- fix: sync hosted version & fusion api param validation error & login page QR code cannot be displayed & wrong email folder name ([#223](https://github.com/apitable/apitable/pull/223)) @mr-kelly ### What's more -* Merge branch 'develop' into release/0.17.0 @mr-kelly -* chore: init changelog.md @mr-kelly -* Chore/merge new feature ([#203](https://github.com/apitable/apitable/pull/203)) @laboonly -* docs: change log @laboonly -* docs: change log ([#204](https://github.com/apitable/apitable/pull/204)) @laboonly -* Merge branch 'develop' into fix/wrong-email-logo @xukecheng -* chore: disable eslint validate of super linter ([#211](https://github.com/apitable/apitable/pull/211)) @yort-feng -* test: user module unit test ([#191](https://github.com/apitable/apitable/pull/191)) @yort-feng -* chore: README show latest release tag ([#209](https://github.com/apitable/apitable/pull/209)) @mr-kelly -* l10n: translation init ([#137](https://github.com/apitable/apitable/pull/137)) @mr-kelly -## [v0.17.0-beta](https://github.com/apitable/apitable/releases/tag/v0.17.0-beta) (2023-01-16) +- Merge branch 'develop' into release/0.17.0 @mr-kelly +- chore: init changelog.md @mr-kelly +- Chore/merge new feature ([#203](https://github.com/apitable/apitable/pull/203)) @laboonly +- docs: change log @laboonly +- docs: change log ([#204](https://github.com/apitable/apitable/pull/204)) @laboonly +- Merge branch 'develop' into fix/wrong-email-logo @xukecheng +- chore: disable eslint validate of super linter ([#211](https://github.com/apitable/apitable/pull/211)) @yort-feng +- test: user module unit test ([#191](https://github.com/apitable/apitable/pull/191)) @yort-feng +- chore: README show latest release tag ([#209](https://github.com/apitable/apitable/pull/209)) @mr-kelly +- l10n: translation init ([#137](https://github.com/apitable/apitable/pull/137)) @mr-kelly +## [v0.17.0-beta](https://github.com/apitable/apitable/releases/tag/v0.17.0-beta) (2023-01-16) ### Features and enhancements -* feat: hosted version update, event manager refactor, mobile date-picker i18n, new env config ([#148](https://github.com/apitable/apitable/pull/148)) @mr-kelly -* feat: github issues templates of docs and question ([#175](https://github.com/apitable/apitable/pull/175)) @mr-kelly -* feat: clear a bad smell code ([#179](https://github.com/apitable/apitable/pull/179)) @zhou-yg -* feat: enable super-lint ([#194](https://github.com/apitable/apitable/pull/194)) @mr-kelly -* feat: timezone environment variables support ([#187](https://github.com/apitable/apitable/pull/187)) @shawndenggh - -### Bug fixes - -* fix: stop satackey/action-docker-layer-caching for building success ([#149](https://github.com/apitable/apitable/pull/149)) @mr-kelly -* fix: share crash @wangkailang -* fix: share crash ([#151](https://github.com/apitable/apitable/pull/151)) @JaneSu -* fix: web-server local start axios base url ([#155](https://github.com/apitable/apitable/pull/155)) @wangkailang -* fix: copy cell menu item is hidden in gallery and kanban view ([#158](https://github.com/apitable/apitable/pull/158)) @alolonghun -* fix: import-double-quotes-to-single-quotes ([#163](https://github.com/apitable/apitable/pull/163)) @wuyitaoBoomboommm -* fix: eslint error and ass scripts ([#164](https://github.com/apitable/apitable/pull/164)) @wangkailang -* fix: template usage crash @wangkailang -* fix: add pre-action releaseLocks before init-db run ([#165](https://github.com/apitable/apitable/pull/165)) @shawndenggh -* fix: template usage crash ([#166](https://github.com/apitable/apitable/pull/166)) @JaneSu -* fix: the content is missing after the mobile form is submitted ([#168](https://github.com/apitable/apitable/pull/168)) @alolonghun -* fix: add main widget message listener ([#169](https://github.com/apitable/apitable/pull/169)) @MrWangQAQ -* fix: avtar color is covered when edit user nickName @LiuZijingBron -* fix: avtar color is covered when edit user nickName ([#170](https://github.com/apitable/apitable/pull/170)) @LiuZijingBron -* fix: replace billing field ([#172](https://github.com/apitable/apitable/pull/172)) @shawndenggh -* fix: eslint error ([#182](https://github.com/apitable/apitable/pull/182)) @wangkailang -* fix: modify spring mail config ([#186](https://github.com/apitable/apitable/pull/186)) @LiuZijingBron -* fix: register user default avatar may be null @LiuZijingBron -* fix: register user default avatar may be null ([#189](https://github.com/apitable/apitable/pull/189)) @LiuZijingBron -* fix: eslint fix & super-linter ready ([#181](https://github.com/apitable/apitable/pull/181)) @mr-kelly -* fix: register user default avatar may be null & avatar renderer ([#193](https://github.com/apitable/apitable/pull/193)) @mr-kelly -* fix: super-linter jscpg ignore test files ([#202](https://github.com/apitable/apitable/pull/202)) @mr-kelly - -### What's more - -* release: v0.17.0-alpha ([#146](https://github.com/apitable/apitable/pull/146)) @mr-kelly -* chore: fix devenv & integrate appdata ([#154](https://github.com/apitable/apitable/pull/154)) @networkhermit -* refactor: split database module to submodules ([#152](https://github.com/apitable/apitable/pull/152)) @yort-feng -* chore: performance profiling tools ([#159](https://github.com/apitable/apitable/pull/159)) @arucil -* Merge branch 'develop' into fix/template-usage-crash @JaneSu -* Merge branch 'develop' into fix/template-usage-crash @wangkailang -* chore: hosted sync @mr-kelly -* chore: optimise email verify html ([#184](https://github.com/apitable/apitable/pull/184)) @xukecheng -* chore(deps): bump class-validator from 0.12.2 to 0.14.0 ([#183](https://github.com/apitable/apitable/pull/183)) @dependabot[bot] -* chore(deps): bump json5 from 1.0.1 to 1.0.2 ([#132](https://github.com/apitable/apitable/pull/132)) @dependabot[bot] -* test: developer module unit test ([#171](https://github.com/apitable/apitable/pull/171)) @yort-feng +- feat: hosted version update, event manager refactor, mobile date-picker i18n, new env config ([#148](https://github.com/apitable/apitable/pull/148)) @mr-kelly +- feat: github issues templates of docs and question ([#175](https://github.com/apitable/apitable/pull/175)) @mr-kelly +- feat: clear a bad smell code ([#179](https://github.com/apitable/apitable/pull/179)) @zhou-yg +- feat: enable super-lint ([#194](https://github.com/apitable/apitable/pull/194)) @mr-kelly +- feat: timezone environment variables support ([#187](https://github.com/apitable/apitable/pull/187)) @shawndenggh + +### Bug fixes + +- fix: stop satackey/action-docker-layer-caching for building success ([#149](https://github.com/apitable/apitable/pull/149)) @mr-kelly +- fix: share crash @wangkailang +- fix: share crash ([#151](https://github.com/apitable/apitable/pull/151)) @JaneSu +- fix: web-server local start axios base url ([#155](https://github.com/apitable/apitable/pull/155)) @wangkailang +- fix: copy cell menu item is hidden in gallery and kanban view ([#158](https://github.com/apitable/apitable/pull/158)) @alolonghun +- fix: import-double-quotes-to-single-quotes ([#163](https://github.com/apitable/apitable/pull/163)) @wuyitaoBoomboommm +- fix: eslint error and ass scripts ([#164](https://github.com/apitable/apitable/pull/164)) @wangkailang +- fix: template usage crash @wangkailang +- fix: add pre-action releaseLocks before init-db run ([#165](https://github.com/apitable/apitable/pull/165)) @shawndenggh +- fix: template usage crash ([#166](https://github.com/apitable/apitable/pull/166)) @JaneSu +- fix: the content is missing after the mobile form is submitted ([#168](https://github.com/apitable/apitable/pull/168)) @alolonghun +- fix: add main widget message listener ([#169](https://github.com/apitable/apitable/pull/169)) @MrWangQAQ +- fix: avtar color is covered when edit user nickName @LiuZijingBron +- fix: avtar color is covered when edit user nickName ([#170](https://github.com/apitable/apitable/pull/170)) @LiuZijingBron +- fix: replace billing field ([#172](https://github.com/apitable/apitable/pull/172)) @shawndenggh +- fix: eslint error ([#182](https://github.com/apitable/apitable/pull/182)) @wangkailang +- fix: modify spring mail config ([#186](https://github.com/apitable/apitable/pull/186)) @LiuZijingBron +- fix: register user default avatar may be null @LiuZijingBron +- fix: register user default avatar may be null ([#189](https://github.com/apitable/apitable/pull/189)) @LiuZijingBron +- fix: eslint fix & super-linter ready ([#181](https://github.com/apitable/apitable/pull/181)) @mr-kelly +- fix: register user default avatar may be null & avatar renderer ([#193](https://github.com/apitable/apitable/pull/193)) @mr-kelly +- fix: super-linter jscpg ignore test files ([#202](https://github.com/apitable/apitable/pull/202)) @mr-kelly + +### What's more + +- release: v0.17.0-alpha ([#146](https://github.com/apitable/apitable/pull/146)) @mr-kelly +- chore: fix devenv & integrate appdata ([#154](https://github.com/apitable/apitable/pull/154)) @networkhermit +- refactor: split database module to submodules ([#152](https://github.com/apitable/apitable/pull/152)) @yort-feng +- chore: performance profiling tools ([#159](https://github.com/apitable/apitable/pull/159)) @arucil +- Merge branch 'develop' into fix/template-usage-crash @JaneSu +- Merge branch 'develop' into fix/template-usage-crash @wangkailang +- chore: hosted sync @mr-kelly +- chore: optimise email verify html ([#184](https://github.com/apitable/apitable/pull/184)) @xukecheng +- chore(deps): bump class-validator from 0.12.2 to 0.14.0 ([#183](https://github.com/apitable/apitable/pull/183)) @dependabot[bot] +- chore(deps): bump json5 from 1.0.1 to 1.0.2 ([#132](https://github.com/apitable/apitable/pull/132)) @dependabot[bot] +- test: developer module unit test ([#171](https://github.com/apitable/apitable/pull/171)) @yort-feng + ## [v0.17.0-alpha](https://github.com/vikadata/vikadata/releases/tag/v0.17.0-alpha) (2023-01-05) First release of APITable. diff --git a/Makefile b/Makefile index 15aac9d840..c3c22cd102 100644 --- a/Makefile +++ b/Makefile @@ -188,6 +188,7 @@ test-ut-room-docker: -e MYSQL_HOST=test-mysql \ -e REDIS_HOST=test-redis \ -e RABBITMQ_HOST=test-rabbitmq \ + -e TZ=UTC \ unit-test-room pnpm run test:ut:room:cov @echo "${GREEN}finished unit test, clean up images...${RESET}" @@ -225,6 +226,7 @@ test-ut-backend-run: RABBITMQ_PORT=5672 \ RABBITMQ_USERNAME=apitable \ RABBITMQ_PASSWORD=password \ + BACKEND_GRPC_PORT=-1 \ ./gradlew testCodeCoverageReport --stacktrace ###### 【backend server unit test】 ###### @@ -510,6 +512,9 @@ _l10n: ## l10n apitable-ce bash ./scripts/l10n.sh ./packages/i18n-lang/src ./packages/l10n/gen ./packages/l10n/base ./packages/l10n/base ./ pnpm run build +wizard: ## wizard update + npx ts-node ./scripts/enterprise/wizard-update.ts + ### help .PHONY: search search: diff --git a/README_ZH.md b/README_ZH.md index e1bb8854d4..d93e6d9ad8 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -245,7 +245,7 @@ APITable 将提供一个数据表查询语言(DQL)来查询您的数据库电子 curl https://apitable.github.io/install.sh | bash ``` -然后在您的浏览器中打开 [https://localhost:80](https://localhost:80) 访问它。 +然后在您的浏览器中打开 [http://localhost:80](http://localhost:80) 访问它。 如果你想要设置你的本地开发环境,请阅读我们的 [🧑‍💻 开发者指南 ](./docs/contribute/developer-guide.md) diff --git a/backend-server/.version b/backend-server/.version index dc1e644a10..feaae22bac 100644 --- a/backend-server/.version +++ b/backend-server/.version @@ -1 +1 @@ -1.6.0 +1.13.0 diff --git a/backend-server/application/build.gradle b/backend-server/application/build.gradle index 4b53c690cb..2aac752095 100644 --- a/backend-server/application/build.gradle +++ b/backend-server/application/build.gradle @@ -17,6 +17,7 @@ dependencies { implementation project(':shared:starters:oss') implementation project(':shared:starters:socketio') implementation project(':shared:starters:beetl') + implementation project(':shared:starters:databus') // spring boot starters dependencies implementation platform(libs.spring.boot.dependencies) @@ -32,6 +33,7 @@ dependencies { implementation libs.spring.boot.thymeleaf implementation libs.spring.integration.redis implementation libs.spring.session.redis + implementation libs.spring.boot.oauth2.client implementation libs.mysql runtimeOnly libs.mysql implementation libs.spring.security.cas @@ -40,14 +42,17 @@ dependencies { implementation libs.commons.pool2 implementation libs.jedis implementation libs.prometheus.pushgateway - implementation libs.bundles.okhttp3 - implementation 'javax.annotation:javax.annotation-api:1.3.2' + implementation libs.httpclient5 + implementation libs.annotation.api // other spring boot starter dependencies implementation(libs.mybatis.plus) { exclude(group: 'org.mybatis', module: 'mybatis-spring') } implementation libs.mybatis.spring + + // sentry dependencies + implementation(platform(libs.sentry.dependencies)) implementation libs.bundles.sentry implementation libs.bundles.apidoc @@ -65,11 +70,11 @@ dependencies { // utilities dependencies implementation libs.p6spy implementation libs.semver - implementation libs.javax.ws - implementation libs.gson.fire - implementation libs.jackson.databind.nullable implementation libs.jsoup - implementation libs.bundles.easyexcel + implementation(libs.bundles.easyexcel) { + exclude(group: 'org.apache.commons', module: 'commons-compress') + } + implementation(libs.commons.compress) implementation libs.bundles.hutool implementation(libs.bundles.pdfbox) { exclude(group: 'commons-logging', module: 'commons-logging') @@ -77,10 +82,17 @@ dependencies { implementation libs.bundles.shedlock // for enterprise module - implementation libs.bundles.social - implementation libs.v.client + implementation(libs.bundles.social) { + exclude(group: 'com.thoughtworks.xstream', module: 'xstream') + } + implementation(libs.xstream) + implementation(libs.v.client) { + exclude(group: 'log4j', module: 'log4j') + } implementation libs.auth0 implementation libs.pingpp + implementation libs.alipay.easy + implementation libs.wechatpay implementation libs.stripe implementation(libs.aliyun.core) { exclude(group: 'commons-logging', module: 'commons-logging') @@ -88,7 +100,6 @@ dependencies { implementation libs.aliyun.afs implementation libs.nimbus implementation libs.jose4j - implementation files('lib/aegis-java-sdk-2.3.3.jar') implementation libs.wx.open implementation libs.sensors implementation libs.posthog @@ -100,7 +111,6 @@ dependencies { testImplementation libs.spring.security.test testImplementation libs.mybatis.plus.test testImplementation libs.visible.assertions - testImplementation libs.okhttp3.mockwebserver testImplementation libs.reactor testImplementation libs.assertj testImplementation libs.awaitility diff --git a/backend-server/application/lib/aegis-java-sdk-2.3.3-sources.jar b/backend-server/application/lib/aegis-java-sdk-2.3.3-sources.jar deleted file mode 100644 index 2b3b6340b3..0000000000 Binary files a/backend-server/application/lib/aegis-java-sdk-2.3.3-sources.jar and /dev/null differ diff --git a/backend-server/application/lib/aegis-java-sdk-2.3.3.jar b/backend-server/application/lib/aegis-java-sdk-2.3.3.jar deleted file mode 100644 index 19875c053d..0000000000 Binary files a/backend-server/application/lib/aegis-java-sdk-2.3.3.jar and /dev/null differ diff --git a/backend-server/application/src/main/java/com/apitable/asset/vo/AssetUrlSignatureVo.java b/backend-server/application/src/main/java/com/apitable/asset/vo/AssetUrlSignatureVo.java index 676a5ae385..9fdf6a140f 100644 --- a/backend-server/application/src/main/java/com/apitable/asset/vo/AssetUrlSignatureVo.java +++ b/backend-server/application/src/main/java/com/apitable/asset/vo/AssetUrlSignatureVo.java @@ -14,9 +14,10 @@ @Schema(description = "Attachment resource url add signature") public class AssetUrlSignatureVo { @Schema(description = "File Access Path(possibly non-final value)", - example = "/space/2023/03/07/8195212453744848953f87c54dc0369b") + example = "space/2023/03/07/8195212453744848953f87c54dc0369b") private String resourceKey; @Schema(description = "Path after signature", - example = "https://s1-test.vika.ltd//space/2023/03/07/8195212453744848953f87c54dc0369b?sign=6bede194fb458c876676139f469b5576&t=64d4bb25") + example = "https://aitable.ai/space/2023/03/07/8195212453744848953f87c54dc0369b" + + "?sign=6bede194fb458c876676139f469b5576&t=64d4bb25") private String url; } diff --git a/backend-server/application/src/main/java/com/apitable/auth/controller/AuthController.java b/backend-server/application/src/main/java/com/apitable/auth/controller/AuthController.java index 54ab1355ca..51b1d12f2d 100644 --- a/backend-server/application/src/main/java/com/apitable/auth/controller/AuthController.java +++ b/backend-server/application/src/main/java/com/apitable/auth/controller/AuthController.java @@ -60,7 +60,7 @@ * Authorization interface. */ @RestController -@Tag(name = "Authorization related interface") +@Tag(name = "Authorization") @ApiResource public class AuthController { @@ -101,7 +101,8 @@ public ResponseData register(@RequestBody @Valid final RegisterRO data) { if (BooleanUtil.isFalse(skipRegisterValidate)) { return ResponseData.error("Validate failure"); } - Long userId = iAuthService.register(data.getUsername(), data.getCredential()); + Long userId = + iAuthService.register(data.getUsername(), data.getCredential(), data.getLang()); SessionContext.setUserId(userId); return ResponseData.success(); } diff --git a/backend-server/application/src/main/java/com/apitable/auth/ro/RegisterRO.java b/backend-server/application/src/main/java/com/apitable/auth/ro/RegisterRO.java index 8df417ebf9..58b2141fd3 100644 --- a/backend-server/application/src/main/java/com/apitable/auth/ro/RegisterRO.java +++ b/backend-server/application/src/main/java/com/apitable/auth/ro/RegisterRO.java @@ -38,4 +38,8 @@ public class RegisterRO { @Schema(description = "Credential(password/verify code...)", example = "qwer1234 || 261527", requiredMode = RequiredMode.REQUIRED) private String credential; + + @Schema(description = "Language", + example = "en-US", requiredMode = RequiredMode.NOT_REQUIRED) + private String lang; } diff --git a/backend-server/application/src/main/java/com/apitable/auth/service/IAuthService.java b/backend-server/application/src/main/java/com/apitable/auth/service/IAuthService.java index 0a7930e8f4..375c49e538 100644 --- a/backend-server/application/src/main/java/com/apitable/auth/service/IAuthService.java +++ b/backend-server/application/src/main/java/com/apitable/auth/service/IAuthService.java @@ -35,6 +35,16 @@ public interface IAuthService { */ Long register(String username, String password); + /** + * Register. + * + * @param username username + * @param password password + * @param lang language code + * @return user id + */ + Long register(String username, String password, String lang); + /** * Password login, only log in existing users, no need to automatically register an account. * diff --git a/backend-server/application/src/main/java/com/apitable/auth/service/impl/AuthServiceImpl.java b/backend-server/application/src/main/java/com/apitable/auth/service/impl/AuthServiceImpl.java index aa3649bddd..0c3a8ff93c 100644 --- a/backend-server/application/src/main/java/com/apitable/auth/service/impl/AuthServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/auth/service/impl/AuthServiceImpl.java @@ -49,6 +49,7 @@ import com.apitable.shared.captcha.ValidateCodeProcessorManage; import com.apitable.shared.captcha.ValidateCodeType; import com.apitable.shared.captcha.ValidateTarget; +import com.apitable.shared.component.LanguageManager; import com.apitable.shared.security.PasswordService; import com.apitable.user.entity.UserEntity; import com.apitable.user.service.IUserService; @@ -91,14 +92,22 @@ public class AuthServiceImpl implements IAuthService { @Resource private EntitlementServiceFacade entitlementServiceFacade; + @Resource + private LanguageManager languageManager; + @Override public Long register(final String username, final String password) { + return register(username, password, languageManager.getDefaultLanguageTag()); + } + + @Override + public Long register(final String username, final String password, String lang) { // Check email format and if exists ExceptionUtil.isTrue(Validator.isEmail(username), REGISTER_EMAIL_ERROR); boolean exist = iUserService.checkByEmail(username); ExceptionUtil.isFalse(exist, REGISTER_EMAIL_HAS_EXIST); // Register User - return this.registerUserUsingEmail(username, password, null); + return this.registerUserUsingEmail(username, password, null, lang); } @Override @@ -213,12 +222,12 @@ public UserLoginDTO loginUsingEmailCode(LoginRo loginRo) { iUserService.updateLoginTime(userId); // Query whether there is a space member corresponding to the mailbox, // only new registration will have this operation - List inactiveMembers = iMemberService.getInactiveMemberDtoByEmail(email); + List inactiveMembers = iMemberService.getInactiveMemberByEmail(email); iMemberService.activeIfExistInvitationSpace(userId, inactiveMembers.stream().map(MemberDTO::getId).collect(Collectors.toList())); } else { // Email automatic registration users do not provide third-party scan code login binding - userId = registerUserUsingEmail(email, null, loginRo.getSpaceId()); + userId = registerUserUsingEmail(email, null, loginRo.getSpaceId(), languageManager.getDefaultLanguageTag()); result.setIsSignUp(true); } // delete verification code @@ -244,12 +253,12 @@ private Long registerUserUsingMobilePhone(String areaCode, String mobile, return user.getId(); } - private Long registerUserUsingEmail(final String email, final String password, String spaceId) { + private Long registerUserUsingEmail(final String email, final String password, String spaceId, String lang) { // Create a new user based on the mailbox and activate the corresponding member - UserEntity user = iUserService.createUserByEmail(email, password); + UserEntity user = iUserService.createUserByEmail(email, password, lang); // Query whether there is a space member corresponding to the mailbox, only new // registration will have this operation - List inactiveMembers = iMemberService.getInactiveMemberDtoByEmail(email); + List inactiveMembers = iMemberService.getInactiveMemberByEmail(email); // Invite new users to join the space station to reward attachment capacity, // asynchronous operation if (spaceId != null) { diff --git a/backend-server/application/src/main/java/com/apitable/automation/controller/AutomationRobotController.java b/backend-server/application/src/main/java/com/apitable/automation/controller/AutomationRobotController.java index 6cb4cf4b71..1029486ecb 100644 --- a/backend-server/application/src/main/java/com/apitable/automation/controller/AutomationRobotController.java +++ b/backend-server/application/src/main/java/com/apitable/automation/controller/AutomationRobotController.java @@ -20,6 +20,7 @@ import cn.hutool.core.util.StrUtil; import com.apitable.automation.model.ActionVO; +import com.apitable.automation.model.AutomationRunTaskVO; import com.apitable.automation.model.AutomationSimpleVO; import com.apitable.automation.model.AutomationTaskSimpleVO; import com.apitable.automation.model.AutomationVO; @@ -47,6 +48,7 @@ import com.apitable.workspace.mapper.NodeDescMapper; import com.apitable.workspace.ro.NodeUpdateOpRo; import com.apitable.workspace.service.INodeService; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameters; @@ -215,13 +217,29 @@ public ResponseData deleteRobot(@PathVariable String resourceId, } /** - * Get automation run history. + * Get automation run history detail. * - * @param pageSize page query parameter - * @param pageNum page query parameter + * @param taskId task id + * @return {@link ResponseData} + */ + @GetResource(path = "/run-history/{taskId}", requiredPermission = false, requiredLogin = false) + @Parameter(name = "taskId", description = "task id", required = true, schema = @Schema(type = "string"), in = ParameterIn.PATH, example = "123****") + @Operation(summary = "Get automation run history task details") + @ApiResponses(@ApiResponse(responseCode = "200", useReturnTypeSchema = true)) + public ResponseData getRunHistoryTaskDetail( + @PathVariable String taskId) { + return ResponseData.success(iAutomationRunHistoryService.getByTaskDetail(taskId)); + } + + /** + * get automation run history. + * + * @param pageSize page size of automation run history + * @param pageNum page number + * @param shareId share id * @param resourceId resource id * @param robotId robot id - * @return {@link ResponseData} + * @return response */ @GetResource(path = "/{resourceId}/roots/{robotId}/run-history", requiredPermission = false, requiredLogin = false) @Parameters({ @@ -243,8 +261,10 @@ public ResponseData> getRunHistory( iPermissionService.checkPermissionBySessionOrShare(resourceId, shareId, NodePermission.READ_NODE, status -> ExceptionUtil.isTrue(status, PermissionException.NODE_OPERATION_DENIED)); + String spaceId = iNodeService.getSpaceIdByNodeId(resourceId); + Page page = Page.of(pageNum, pageSize); return ResponseData.success( - iAutomationRunHistoryService.getRobotRunHistory(robotId, pageSize, pageNum)); + iAutomationRunHistoryService.getRobotRunHistory(spaceId, robotId, page)); } /** @@ -270,9 +290,8 @@ public ResponseData> createTrigger( iPermissionService.checkPermissionBySessionOrShare(resourceId, shareId, NodePermission.EDIT_NODE, status -> ExceptionUtil.isTrue(status, PermissionException.NODE_OPERATION_DENIED)); - return ResponseData.success( - iAutomationTriggerService.createByDatabus(userId, data)); - + String spaceId = iNodeService.getSpaceIdByNodeId(resourceId); + return ResponseData.success(iAutomationTriggerService.create(userId, spaceId, data)); } /** @@ -293,15 +312,16 @@ public ResponseData> createTrigger( public ResponseData> updateTrigger( @PathVariable String resourceId, @PathVariable String triggerId, - @RequestBody UpdateTriggerRO data, + @RequestBody @Valid UpdateTriggerRO data, @RequestParam(name = "shareId", required = false) String shareId ) { Long userId = SessionContext.getUserId(); iPermissionService.checkPermissionBySessionOrShare(resourceId, shareId, NodePermission.EDIT_NODE, status -> ExceptionUtil.isTrue(status, PermissionException.NODE_OPERATION_DENIED)); + String spaceId = iNodeService.getSpaceIdByNodeId(resourceId); return ResponseData.success( - iAutomationTriggerService.updateByDatabus(triggerId, userId, data)); + iAutomationTriggerService.update(userId, triggerId, spaceId, data)); } /** @@ -328,7 +348,7 @@ public ResponseData deleteTrigger(@PathVariable String resourceId, iPermissionService.checkPermissionBySessionOrShare(resourceId, null, NodePermission.EDIT_NODE, status -> ExceptionUtil.isTrue(status, PermissionException.NODE_OPERATION_DENIED)); - iAutomationTriggerService.deleteByDatabus(robotId, triggerId, userId); + iAutomationTriggerService.deleteByTriggerId(robotId, triggerId, userId); return ResponseData.success(); } diff --git a/backend-server/application/src/main/java/com/apitable/automation/entity/AutomationActionTypeEntity.java b/backend-server/application/src/main/java/com/apitable/automation/entity/AutomationActionTypeEntity.java new file mode 100644 index 0000000000..5151d4166c --- /dev/null +++ b/backend-server/application/src/main/java/com/apitable/automation/entity/AutomationActionTypeEntity.java @@ -0,0 +1,126 @@ +/* + * APITable Ltd. + * Copyright (C) 2022 APITable Ltd. + * + * This code file is part of APITable Enterprise Edition. + * + * It is subject to the APITable Commercial License and conditional on having a fully paid-up license from APITable. + * + * Access to this code file or other code files in this `enterprise` directory and its subdirectories does not constitute permission to use this code or APITable Enterprise Edition features. + * + * Unless otherwise noted, all files Copyright © 2022 APITable Ltd. + * + * For purchase of APITable Enterprise Edition license, please contact . + */ + +package com.apitable.automation.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableLogic; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.time.LocalDateTime; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +/** + *

+ * Automation - Action Type Table. + *

+ * + * @author Mybatis Generator Tool + */ +@Data +@Builder(toBuilder = true) +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +@EqualsAndHashCode +@TableName(keepGlobalPrefix = true, value = "automation_action_type") +public class AutomationActionTypeEntity implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * Primary Key. + */ + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + /** + * Service ID (link#xxxx_automation_service#service_id). + */ + private String serviceId; + + /** + * Custom action prototype ID. + */ + private String actionTypeId; + + /** + * Name. + */ + private String name; + + /** + * Description. + */ + private String description; + + /** + * Input JSON normal form. + */ + private String inputJsonSchema; + + /** + * Output JSON normal form. + */ + private String outputJsonSchema; + + /** + * Call interface. + */ + private String endpoint; + + /** + * Internationalized Language Pack. + */ + private String i18n; + + /** + * Delete Tag(0: No, 1: Yes). + */ + @TableLogic + private Integer isDeleted; + + /** + * Creator. + */ + @TableField(fill = FieldFill.INSERT) + private Long createdBy; + + /** + * Last Update By. + */ + @TableField(fill = FieldFill.INSERT_UPDATE) + private Long updatedBy; + + /** + * Create Time. + */ + private LocalDateTime createdAt; + + /** + * Update Time. + */ + private LocalDateTime updatedAt; + + +} diff --git a/backend-server/application/src/main/java/com/apitable/automation/entity/AutomationRunHistoryEntity.java b/backend-server/application/src/main/java/com/apitable/automation/entity/AutomationRunHistoryEntity.java new file mode 100644 index 0000000000..90247edd80 --- /dev/null +++ b/backend-server/application/src/main/java/com/apitable/automation/entity/AutomationRunHistoryEntity.java @@ -0,0 +1,87 @@ +/* + * APITable + * Copyright (C) 2022 APITable Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.apitable.automation.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.math.BigInteger; +import java.time.LocalDateTime; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +/** + *

+ * Automation - Run history table. + *

+ * + * @author Mybatis Generator Tool + */ +@Data +@Builder(toBuilder = true) +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +@EqualsAndHashCode +@TableName(keepGlobalPrefix = true, value = "automation_run_history") +public class AutomationRunHistoryEntity implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * Primary Key. + */ + @TableId(value = "id", type = IdType.ASSIGN_ID) + private BigInteger id; + + /** + * Task ID. + */ + private String taskId; + + /** + * Custom Robot ID. + */ + private String robotId; + + /** + * Space ID. + */ + private String spaceId; + + /** + * Running status (0: Running, 1: Success, 2: Failure). + */ + private Integer status; + + /** + * Run Context Details. + */ + private String data; + + /** + * Create Time. + */ + private LocalDateTime createdAt; +} diff --git a/packages/datasheet/src/pc/components/expand_record/activity_pane/index.ts b/backend-server/application/src/main/java/com/apitable/automation/enums/AutomationActionType.java similarity index 72% rename from packages/datasheet/src/pc/components/expand_record/activity_pane/index.ts rename to backend-server/application/src/main/java/com/apitable/automation/enums/AutomationActionType.java index c7a1a7e310..e254495e22 100644 --- a/packages/datasheet/src/pc/components/expand_record/activity_pane/index.ts +++ b/backend-server/application/src/main/java/com/apitable/automation/enums/AutomationActionType.java @@ -1,4 +1,4 @@ -/** +/* * APITable * Copyright (C) 2022 APITable Ltd. * @@ -16,4 +16,26 @@ * along with this program. If not, see . */ -export * from './activity_pane'; + +package com.apitable.automation.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * automation action type. + */ +@Getter +@AllArgsConstructor +public enum AutomationActionType { + + SEND_MAIL("sendMail"), + + SEND_REQUEST("sendRequest"), + + + ; + + + private final String type; +} diff --git a/backend-server/application/src/main/java/com/apitable/automation/enums/AutomationException.java b/backend-server/application/src/main/java/com/apitable/automation/enums/AutomationException.java index ae1525a12e..d971e1f7f7 100644 --- a/backend-server/application/src/main/java/com/apitable/automation/enums/AutomationException.java +++ b/backend-server/application/src/main/java/com/apitable/automation/enums/AutomationException.java @@ -41,7 +41,11 @@ public enum AutomationException implements BaseException { AUTOMATION_ROBOT_NOT_EXIST(1104, "The automation not exits"), - AUTOMATION_TRIGGER_LIMIT(1105, "The number of triggers cannot exceed 3"); + AUTOMATION_TRIGGER_LIMIT(1105, "The number of triggers cannot exceed 3"), + + AUTOMATION_TRIGGER_NOT_EXIST(1106, "The trigger not exits"), + + ; private final Integer code; diff --git a/backend-server/application/src/main/java/com/apitable/automation/enums/AutomationTriggerType.java b/backend-server/application/src/main/java/com/apitable/automation/enums/AutomationTriggerType.java index 0faac76dd9..6956792eaf 100644 --- a/backend-server/application/src/main/java/com/apitable/automation/enums/AutomationTriggerType.java +++ b/backend-server/application/src/main/java/com/apitable/automation/enums/AutomationTriggerType.java @@ -36,6 +36,8 @@ public enum AutomationTriggerType { BUTTON_CLICKED("button_clicked"), + SCHEDULED_TIME_ARRIVE("scheduled_time_arrive"), + ; diff --git a/backend-server/application/src/main/java/com/apitable/automation/mapper/AutomationActionMapper.java b/backend-server/application/src/main/java/com/apitable/automation/mapper/AutomationActionMapper.java index 8a94fb0537..46d8cd49cd 100644 --- a/backend-server/application/src/main/java/com/apitable/automation/mapper/AutomationActionMapper.java +++ b/backend-server/application/src/main/java/com/apitable/automation/mapper/AutomationActionMapper.java @@ -58,4 +58,11 @@ int updateActionTypeIdAndInputByRobotId(@Param("robotId") String robotId, String updatedActionTypeId, @Param("updatedInput") String updatedInput); + /** + * query by action id. + * + * @param actionId action id + * @return AutomationActionEntity + */ + AutomationActionEntity selectByActionId(@Param("actionId") String actionId); } diff --git a/backend-server/application/src/main/java/com/apitable/automation/mapper/AutomationActionTypeMapper.java b/backend-server/application/src/main/java/com/apitable/automation/mapper/AutomationActionTypeMapper.java new file mode 100644 index 0000000000..c605ba0f2c --- /dev/null +++ b/backend-server/application/src/main/java/com/apitable/automation/mapper/AutomationActionTypeMapper.java @@ -0,0 +1,47 @@ +/* + * APITable + * Copyright (C) 2022 APITable Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.apitable.automation.mapper; + +import com.apitable.automation.entity.AutomationActionTypeEntity; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Param; + +/** + * action type mapping. + */ +public interface AutomationActionTypeMapper extends BaseMapper { + + /** + * Get action type by endpoint. + * + * @param endpoint invocation interface + * @return action type + */ + String getActionTypeIdByEndpoint(@Param("endpoint") String endpoint); + + Long selectIdByActionTypeId(@Param("actionTypeId") String actionTypeId); + + /** + * query endpoint. + * + * @param actionTypeId action type id + * @return endpoint + */ + String selectEndpointByActionTypeId(@Param("actionTypeId") String actionTypeId); +} diff --git a/backend-server/application/src/main/java/com/apitable/automation/mapper/AutomationRobotMapper.java b/backend-server/application/src/main/java/com/apitable/automation/mapper/AutomationRobotMapper.java index 6bb51b940b..ae1e7c278a 100644 --- a/backend-server/application/src/main/java/com/apitable/automation/mapper/AutomationRobotMapper.java +++ b/backend-server/application/src/main/java/com/apitable/automation/mapper/AutomationRobotMapper.java @@ -104,4 +104,30 @@ void updateIsDeletedByResourceIds(@Param("userId") Long userId, */ List getRobotTriggers(@Param("seqId") String seqId, @Param("resourceId") String resourceId); + + /** + * query count by robot id. + * + * @param robotId robot id + * @return Integer + */ + Integer selectCountByRobotId(@Param("robotId") String robotId); + + /** + * update robot info. + * + * @param robotId robot id + * @param updatedBy updater + * @return rows + */ + int updateUpdatedByRobotId(@Param("robotId") String robotId, + @Param("updatedBy") Long updatedBy); + + /** + * query robot id exists. + * + * @param robotIds robot id + * @return resource id of robot + */ + List selectResourceIdsByRobotIds(@Param("robotIds") List robotIds); } diff --git a/backend-server/application/src/main/java/com/apitable/automation/mapper/AutomationRunHistoryMapper.java b/backend-server/application/src/main/java/com/apitable/automation/mapper/AutomationRunHistoryMapper.java new file mode 100644 index 0000000000..3718cdbb8c --- /dev/null +++ b/backend-server/application/src/main/java/com/apitable/automation/mapper/AutomationRunHistoryMapper.java @@ -0,0 +1,65 @@ +/* + * APITable + * Copyright (C) 2022 APITable Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.apitable.automation.mapper; + +import com.apitable.automation.entity.AutomationRunHistoryEntity; +import com.apitable.automation.model.AutomationRunHistoryDTO; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import java.time.LocalDate; +import java.util.List; +import org.apache.ibatis.annotations.Param; + +/** + * automation history mapper. + */ +public interface AutomationRunHistoryMapper extends BaseMapper { + /** + * query id by robot id and created at. + * + * @param spaceId space id + * @param robotId robot id + * @param startAt start times + * @param endAt end times + * @param page page + * @return IPage NodeStatisticsDTO + */ + IPage selectIdByRobotIdAndSpaceIdAndBetweenWithPage(@Param("robotId") String robotId, + @Param("spaceId") String spaceId, + @Param("startAt") LocalDate startAt, + @Param("endAt") LocalDate endAt, + Page page); + + /** + * query base info. + * + * @param ids primary keys + * @return AutomationRunHistoryDTO + */ + List selectByIds(@Param("ids") List ids); + + /** + * query detail. + * + * @param taskId task id + * @return AutomationRunHistoryEntity + */ + AutomationRunHistoryEntity selectByTaskId(@Param("taskId") String taskId); +} diff --git a/backend-server/application/src/main/java/com/apitable/automation/mapper/AutomationTriggerMapper.java b/backend-server/application/src/main/java/com/apitable/automation/mapper/AutomationTriggerMapper.java index 003b686ac3..7654e6dabd 100644 --- a/backend-server/application/src/main/java/com/apitable/automation/mapper/AutomationTriggerMapper.java +++ b/backend-server/application/src/main/java/com/apitable/automation/mapper/AutomationTriggerMapper.java @@ -77,4 +77,29 @@ void updateByTriggerId(@Param("triggerId") String triggerId, void updateTriggerInputByRobotIdsAndTriggerType(@Param("robotIds") List robotIds, @Param("triggerTypeId") String triggerTypeId, @Param("input") String input); + + /** + * get count by trigger id. + * + * @param robotId robot id + * @return total amount + */ + Integer selectCountByRobotId(@Param("robotId") String robotId); + + /** + * query trigger. + * + * @param triggerId trigger + * @return AutomationTriggerEntity + */ + AutomationTriggerEntity selectByTriggerId(@Param("triggerId") String triggerId); + + /** + * query trigger. + * + * @param resourceIds resource id + * @return AutomationTriggerDto + */ + List selectRobotIdByResourceIds(@Param("resourceIds") List resourceIds); + } diff --git a/backend-server/application/src/main/java/com/apitable/automation/model/ActionVO.java b/backend-server/application/src/main/java/com/apitable/automation/model/ActionVO.java index c192bb829e..c5d3b4950c 100644 --- a/backend-server/application/src/main/java/com/apitable/automation/model/ActionVO.java +++ b/backend-server/application/src/main/java/com/apitable/automation/model/ActionVO.java @@ -19,7 +19,6 @@ package com.apitable.automation.model; import com.apitable.shared.support.serializer.NullObjectSerializer; -import com.apitable.shared.support.serializer.StringToJsonObjectSerializer; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; @@ -36,6 +35,6 @@ @Setter public class ActionVO extends ActionSimpleVO { @Schema(description = "Action input", type = "java.lang.String", example = "{}") - @JsonSerialize(nullsUsing = NullObjectSerializer.class, using = StringToJsonObjectSerializer.class) - private String input; + @JsonSerialize(nullsUsing = NullObjectSerializer.class) + private Object input; } diff --git a/backend-server/application/src/main/java/com/apitable/automation/model/AutomationRunHistoryDTO.java b/backend-server/application/src/main/java/com/apitable/automation/model/AutomationRunHistoryDTO.java new file mode 100644 index 0000000000..6a3b5b0ae0 --- /dev/null +++ b/backend-server/application/src/main/java/com/apitable/automation/model/AutomationRunHistoryDTO.java @@ -0,0 +1,44 @@ +/* + * APITable + * Copyright (C) 2022 APITable Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.apitable.automation.model; + +import java.time.LocalDateTime; +import lombok.Data; + +/** + * AutomationRunHistoryDTO base info. + */ +@Data +public class AutomationRunHistoryDTO { + + private String robotId; + + private String taskId; + + private Integer status; + + private LocalDateTime createdAt; + + private String actionIds; + + private String actionTypeIds; + + private String errorMessages; + +} diff --git a/backend-server/application/src/main/java/com/apitable/automation/model/AutomationRunTaskVO.java b/backend-server/application/src/main/java/com/apitable/automation/model/AutomationRunTaskVO.java new file mode 100644 index 0000000000..67386de78c --- /dev/null +++ b/backend-server/application/src/main/java/com/apitable/automation/model/AutomationRunTaskVO.java @@ -0,0 +1,67 @@ +/* + * APITable + * Copyright (C) 2022 APITable Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.apitable.automation.model; + +import com.apitable.shared.support.serializer.NullNumberSerializer; +import com.apitable.shared.support.serializer.NullObjectSerializer; +import com.apitable.shared.support.serializer.NullStringSerializer; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import io.swagger.v3.oas.annotations.media.Schema; +import java.time.LocalDateTime; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +/** + * AutomationRunTaskVO. + */ +@NoArgsConstructor +@AllArgsConstructor +@Getter +@Setter +public class AutomationRunTaskVO { + @Schema(description = "id", type = "java.lang.String") + @JsonSerialize(nullsUsing = NullStringSerializer.class) + private String id; + + @Schema(description = "taskId", type = "java.lang.String") + @JsonSerialize(nullsUsing = NullStringSerializer.class) + private String taskId; + + @Schema(description = "robotId", type = "java.lang.String") + @JsonSerialize(nullsUsing = NullStringSerializer.class) + private String robotId; + + @Schema(description = "spaceId", type = "java.lang.String") + @JsonSerialize(nullsUsing = NullStringSerializer.class) + private String spaceId; + + @Schema(description = "status", type = "java.lang.Integer") + @JsonSerialize(nullsUsing = NullNumberSerializer.class) + private Integer status; + + @Schema(description = "createdAt", type = "java.lang.String", example = "{}") + @JsonSerialize(nullsUsing = NullStringSerializer.class) + private LocalDateTime createdAt; + + @Schema(description = "Action input", type = "java.lang.String", example = "{}") + @JsonSerialize(nullsUsing = NullObjectSerializer.class) + private Object data; +} diff --git a/backend-server/application/src/main/java/com/apitable/automation/model/AutomationServiceCreateRO.java b/backend-server/application/src/main/java/com/apitable/automation/model/AutomationServiceCreateRO.java deleted file mode 100644 index f6e0acdee1..0000000000 --- a/backend-server/application/src/main/java/com/apitable/automation/model/AutomationServiceCreateRO.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * APITable - * Copyright (C) 2022 APITable Ltd. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package com.apitable.automation.model; - -import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotBlank; -import lombok.Data; - -/** - * AutomationServiceCreateRO. - */ -@Data -@Schema(description = "Automation Service Create RO") -public class AutomationServiceCreateRO { - - @Schema(description = "service id") - private String serviceId; - - @Schema(description = "service slug") - @NotBlank - private String slug; - - @Schema(description = "name") - @NotBlank - private String name; - - @Schema(description = "description") - private String description; - - @Schema(description = "input JSON format") - private String logo; - - @Schema(description = "output JSON format") - private String baseUrl; - - @Schema(description = "i18n package") - private String i18n; - -} diff --git a/backend-server/application/src/main/java/com/apitable/automation/model/TriggerRO.java b/backend-server/application/src/main/java/com/apitable/automation/model/TriggerRO.java index f5a8f161df..dfff4ae332 100644 --- a/backend-server/application/src/main/java/com/apitable/automation/model/TriggerRO.java +++ b/backend-server/application/src/main/java/com/apitable/automation/model/TriggerRO.java @@ -1,6 +1,7 @@ package com.apitable.automation.model; import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; import jakarta.validation.constraints.NotBlank; import lombok.AllArgsConstructor; import lombok.Data; @@ -27,4 +28,42 @@ public abstract class TriggerRO { @Schema(description = "prev trigger id", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "atr") private String prevTriggerId; + + @Schema(description = "schedule config", requiredMode = Schema.RequiredMode.NOT_REQUIRED, example = "{}") + @Valid + private TriggerScheduleConfig scheduleConfig; + + /** + * schedule config. + */ + @Data + @Schema(description = "Trigger schedule config ro") + public static class TriggerScheduleConfig { + @Schema(description = "second", requiredMode = Schema.RequiredMode.REQUIRED, example = "*") + private String second; + + @Schema(description = "minute", requiredMode = Schema.RequiredMode.REQUIRED, example = "*") + @NotBlank(message = "minute cannot be empty") + private String minute; + + @Schema(description = "hour", requiredMode = Schema.RequiredMode.REQUIRED, example = "*") + @NotBlank(message = "hour cannot be empty") + private String hour; + + @Schema(description = "month", requiredMode = Schema.RequiredMode.REQUIRED, example = "*") + @NotBlank(message = "month cannot be empty") + private String month; + + @Schema(description = "dayOfMonth", requiredMode = Schema.RequiredMode.REQUIRED, example = "*") + @NotBlank(message = "dayOfMonth cannot be empty") + private String dayOfMonth; + + @Schema(description = "dayOfWeek", requiredMode = Schema.RequiredMode.REQUIRED, example = "*") + @NotBlank(message = "dayOfWeek cannot be empty") + private String dayOfWeek; + + @Schema(description = "timeZone", requiredMode = Schema.RequiredMode.REQUIRED, example = "UTC") + @NotBlank(message = "timeZone cannot be empty") + private String timeZone; + } } diff --git a/backend-server/application/src/main/java/com/apitable/automation/model/TriggerTypeCreateRO.java b/backend-server/application/src/main/java/com/apitable/automation/model/TriggerTypeCreateRO.java deleted file mode 100644 index 721cf24d91..0000000000 --- a/backend-server/application/src/main/java/com/apitable/automation/model/TriggerTypeCreateRO.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * APITable - * Copyright (C) 2022 APITable Ltd. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package com.apitable.automation.model; - -import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotBlank; -import lombok.Data; - -/** - * TriggerTypeCreateRO. - */ -@Data -@Schema(description = "TriggerTypeCreateRO") -public class TriggerTypeCreateRO { - - @Schema(description = "service id") - @NotBlank - private String serviceId; - - @Schema(description = "trigger type id") - private String triggerTypeId; - - @Schema(description = "name") - @NotBlank - private String name; - - @Schema(description = "description") - private String description; - - @Schema(description = "input JSON format") - private String inputJsonSchema; - - @Schema(description = "output JSON format") - private String outputJsonSchema; - - @Schema(description = "trigger prototype endpoint") - @NotBlank - private String endpoint; - - @Schema(description = "i18n package") - private String i18n; - -} diff --git a/backend-server/application/src/main/java/com/apitable/automation/service/IAutomationActionService.java b/backend-server/application/src/main/java/com/apitable/automation/service/IAutomationActionService.java index 3e252176d1..4129fafbe8 100644 --- a/backend-server/application/src/main/java/com/apitable/automation/service/IAutomationActionService.java +++ b/backend-server/application/src/main/java/com/apitable/automation/service/IAutomationActionService.java @@ -18,6 +18,7 @@ package com.apitable.automation.service; +import cn.hutool.json.JSON; import com.apitable.automation.entity.AutomationActionEntity; import com.apitable.automation.model.ActionVO; import com.apitable.automation.model.CreateActionRO; @@ -83,4 +84,12 @@ public interface IAutomationActionService { * @param userId operator user id */ void deleteByDatabus(String robotId, String actionId, Long userId); -} + + /** + * handle action input, replace password. + * + * @param input input + * @return input + */ + JSON handleActionInput(String input); +} \ No newline at end of file diff --git a/backend-server/application/src/main/java/com/apitable/base/service/IActionService.java b/backend-server/application/src/main/java/com/apitable/automation/service/IAutomationActionTypeService.java similarity index 71% rename from backend-server/application/src/main/java/com/apitable/base/service/IActionService.java rename to backend-server/application/src/main/java/com/apitable/automation/service/IAutomationActionTypeService.java index 4277c76a03..a542322156 100644 --- a/backend-server/application/src/main/java/com/apitable/base/service/IActionService.java +++ b/backend-server/application/src/main/java/com/apitable/automation/service/IAutomationActionTypeService.java @@ -16,20 +16,21 @@ * along with this program. If not, see . */ -package com.apitable.base.service; -import com.apitable.organization.vo.InviteInfoVo; +package com.apitable.automation.service; /** - * action service. + * interface for action type. */ -public interface IActionService { +public interface IAutomationActionTypeService { + + String getActionTypeIdByEndpoint(String endpoint); /** - * Activate invited users. + * weather is send email action. * - * @param inviteToken invitation token - * @return Invitation related information view + * @param actionTypeId action type + * @return boolean */ - InviteInfoVo inviteValidate(String inviteToken); + boolean isSendEmailAction(String actionTypeId); } diff --git a/backend-server/application/src/main/java/com/apitable/automation/service/IAutomationRobotService.java b/backend-server/application/src/main/java/com/apitable/automation/service/IAutomationRobotService.java index 09e9e9fbc2..4a7770984d 100644 --- a/backend-server/application/src/main/java/com/apitable/automation/service/IAutomationRobotService.java +++ b/backend-server/application/src/main/java/com/apitable/automation/service/IAutomationRobotService.java @@ -84,6 +84,13 @@ void copyByDatabus(Long userId, List resourceIds, */ void updateByRobotId(AutomationRobotEntity robot); + /** + * Update by robot id. + * + * @param robotId robot id + */ + void updateUpdaterByRobotId(String robotId, Long updatedBy); + /** * update automation robot by robot id. * @@ -140,4 +147,19 @@ void copyByDatabus(Long userId, List resourceIds, * @return robot runs count */ long getRobotRunsCountBySpaceId(String spaceId); + + /** + * check robot exists. + * + * @param robotId robot id + */ + void checkRobotExists(String robotId); + + /** + * get robot count. + * + * @param nodeIds dst id + * @return count + */ + boolean linkByOutsideAutomation(List nodeIds); } diff --git a/backend-server/application/src/main/java/com/apitable/automation/service/IAutomationRunHistoryService.java b/backend-server/application/src/main/java/com/apitable/automation/service/IAutomationRunHistoryService.java index a08eb46f56..fc6773bf0f 100644 --- a/backend-server/application/src/main/java/com/apitable/automation/service/IAutomationRunHistoryService.java +++ b/backend-server/application/src/main/java/com/apitable/automation/service/IAutomationRunHistoryService.java @@ -18,15 +18,34 @@ package com.apitable.automation.service; +import com.apitable.automation.entity.AutomationRunHistoryEntity; +import com.apitable.automation.model.AutomationRunTaskVO; import com.apitable.automation.model.AutomationTaskSimpleVO; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.IService; import java.util.List; /** * Automation run history service interface. */ -public interface IAutomationRunHistoryService { +public interface IAutomationRunHistoryService extends IService { - List getRobotRunHistory(String robotId, Integer pageSize, - Integer pageNum); + /** + * query the history with page. + * + * @param spaceId space id + * @param robotId robot id + * @param page page + * @return AutomationTaskSimpleVO + */ + List getRobotRunHistory(String spaceId, String robotId, + Page page); + /** + * query the history with task id. + * + * @param taskId task id + * @return AutomationTriggerEntity + */ + AutomationRunTaskVO getByTaskDetail(String taskId); } diff --git a/backend-server/application/src/main/java/com/apitable/automation/service/IAutomationTriggerService.java b/backend-server/application/src/main/java/com/apitable/automation/service/IAutomationTriggerService.java index a0cfcef27b..e5d8d6f341 100644 --- a/backend-server/application/src/main/java/com/apitable/automation/service/IAutomationTriggerService.java +++ b/backend-server/application/src/main/java/com/apitable/automation/service/IAutomationTriggerService.java @@ -51,30 +51,34 @@ public interface IAutomationTriggerService { /** * Create trigger. * - * @param userId creator's user id - * @param data data + * @param userId creator's user id + * @param data data + * @param spaceId space id * @return TriggerVO */ - List createByDatabus(Long userId, CreateTriggerRO data); + List create(Long userId, String spaceId, CreateTriggerRO data); + /** - * Update trigger. + * Create trigger. * - * @param userId creator's user id + * @param userId creator's user id + * @param data data + * @param spaceId space id * @param triggerId trigger id - * @param data data * @return TriggerVO */ - List updateByDatabus(String triggerId, Long userId, UpdateTriggerRO data); + List update(Long userId, String triggerId, String spaceId, UpdateTriggerRO data); + /** * Delete trigger. * * @param robotId robot id * @param triggerId trigger id - * @param userId operator user id + * @param userId operator user id */ - void deleteByDatabus(String robotId, String triggerId, Long userId); + void deleteByTriggerId(String robotId, String triggerId, Long userId); /** * copy trigger. @@ -104,4 +108,13 @@ TriggerCopyResultDto copy(Long userId, AutomationCopyOptions options, */ void updateInputByRobotIdsAndTriggerTypeIds(List robotIds, String triggerTypeId, String input); + + /** + * get node linked robot id list. + * + * @param nodeIds node id + * @return robot id list + */ + List getRobotIdsByResourceIds(List nodeIds); + } diff --git a/backend-server/application/src/main/java/com/apitable/automation/service/IAutomationTriggerTypeService.java b/backend-server/application/src/main/java/com/apitable/automation/service/IAutomationTriggerTypeService.java index 8b316789aa..5e1353d71e 100644 --- a/backend-server/application/src/main/java/com/apitable/automation/service/IAutomationTriggerTypeService.java +++ b/backend-server/application/src/main/java/com/apitable/automation/service/IAutomationTriggerTypeService.java @@ -18,19 +18,13 @@ package com.apitable.automation.service; -import com.apitable.automation.model.TriggerTypeCreateRO; -import com.apitable.automation.model.TriggerTypeEditRO; +import com.apitable.automation.entity.AutomationTriggerTypeEntity; +import com.baomidou.mybatisplus.extension.service.IService; /** * IAutomationTriggerTypeService. */ -public interface IAutomationTriggerTypeService { +public interface IAutomationTriggerTypeService extends IService { String getTriggerTypeByEndpoint(String endpoint); - - String create(Long userId, TriggerTypeCreateRO ro); - - void edit(Long userId, String triggerTypeId, TriggerTypeEditRO ro); - - void delete(Long userId, String triggerTypeId); } diff --git a/backend-server/application/src/main/java/com/apitable/automation/service/impl/AutomationActionServiceImpl.java b/backend-server/application/src/main/java/com/apitable/automation/service/impl/AutomationActionServiceImpl.java index 8dd236d47a..83d9a5845e 100644 --- a/backend-server/application/src/main/java/com/apitable/automation/service/impl/AutomationActionServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/automation/service/impl/AutomationActionServiceImpl.java @@ -24,6 +24,11 @@ import static java.util.stream.Collectors.toList; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.lang.Dict; +import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSON; +import cn.hutool.json.JSONArray; +import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.apitable.automation.entity.AutomationActionEntity; import com.apitable.automation.mapper.AutomationActionMapper; @@ -32,14 +37,14 @@ import com.apitable.automation.model.TriggerCopyResultDto; import com.apitable.automation.model.UpdateActionRO; import com.apitable.automation.service.IAutomationActionService; +import com.apitable.automation.service.IAutomationActionTypeService; import com.apitable.core.util.ExceptionUtil; -import com.apitable.databusclient.ApiException; -import com.apitable.databusclient.api.AutomationDaoApiApi; -import com.apitable.databusclient.model.ApiResponseAutomationActionPO; -import com.apitable.databusclient.model.AutomationActionPO; -import com.apitable.databusclient.model.AutomationRobotActionRO; import com.apitable.shared.config.properties.LimitProperties; import com.apitable.shared.util.IdUtil; +import com.apitable.starter.databus.client.api.AutomationDaoApiApi; +import com.apitable.starter.databus.client.model.ApiResponseAutomationActionPO; +import com.apitable.starter.databus.client.model.AutomationActionPO; +import com.apitable.starter.databus.client.model.AutomationRobotActionRO; import com.baomidou.mybatisplus.core.toolkit.IdWorker; import jakarta.annotation.Resource; import java.math.BigInteger; @@ -49,6 +54,7 @@ import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import org.springframework.web.client.RestClientException; /** * automation action service impl. @@ -57,6 +63,8 @@ @Service public class AutomationActionServiceImpl implements IAutomationActionService { + public static final String EMAIL_SHOW_PASSWORD = "******"; + @Resource private AutomationActionMapper actionMapper; @@ -66,6 +74,9 @@ public class AutomationActionServiceImpl implements IAutomationActionService { @Resource private AutomationDaoApiApi automationDaoApiApi; + @Resource + private IAutomationActionTypeService iAutomationActionTypeService; + @Override public void create(AutomationActionEntity action) { actionMapper.insert(action); @@ -134,48 +145,96 @@ public List createByDatabus(Long userId, CreateActionRO data) { AUTOMATION_TRIGGER_LIMIT.getCode().equals(response.getCode()), AUTOMATION_TRIGGER_LIMIT); return formatVoFromDatabusResponse(response.getData()); - } catch (ApiException e) { + } catch (RestClientException e) { log.error("Robot create action: {}", data.getRobotId(), e); } return new ArrayList<>(); } + @Override - public List updateByDatabus(String actionId, Long userId, UpdateActionRO data) { + public void deleteByDatabus(String robotId, String actionId, Long userId) { AutomationRobotActionRO ro = new AutomationRobotActionRO(); ro.setUserId(userId); - ro.setInput(JSONUtil.toJsonStr(data.getInput())); - ro.setPrevActionId(data.getPrevActionId()); - ro.setActionTypeId(data.getActionTypeId()); + ro.setIsDeleted(true); ro.setActionId(actionId); try { ApiResponseAutomationActionPO response = - automationDaoApiApi.daoCreateOrUpdateAutomationRobotAction(data.getRobotId(), ro); + automationDaoApiApi.daoCreateOrUpdateAutomationRobotAction(robotId, ro); ExceptionUtil.isFalse( AUTOMATION_ROBOT_NOT_EXIST.getCode().equals(response.getCode()), AUTOMATION_ROBOT_NOT_EXIST); - return formatVoFromDatabusResponse(response.getData()); - } catch (ApiException e) { - log.error("Robot update action: {}", data.getRobotId(), e); + } catch (RestClientException e) { + log.error("Delete action: {}", actionId, e); } - return new ArrayList<>(); } @Override - public void deleteByDatabus(String robotId, String actionId, Long userId) { + public JSON handleActionInput(String input) { + if (null == input) { + return null; + } + JSONObject inputObj = JSONUtil.parseObj(input); + if (inputObj.containsKey("value")) { + JSONObject inputValue = JSONUtil.parseObj(inputObj.get("value")); + if (inputValue.containsKey("operands")) { + JSONArray operands = JSONUtil.parseArray(inputValue.get("operands")); + if (operands.contains("password")) { + int passwordIndex = operands.indexOf("password"); + Dict passwordValue = + new Dict().set("value", EMAIL_SHOW_PASSWORD).set("type", "Literal"); + operands.set(passwordIndex + 1, passwordValue); + } + inputValue.set("operands", operands); + } + inputObj.set("value", inputValue); + } + return inputObj; + } + + @Override + public List updateByDatabus(String actionId, Long userId, UpdateActionRO data) { + // handle input + String input = getActionInputStringFromRo(actionId, data.getInput()); AutomationRobotActionRO ro = new AutomationRobotActionRO(); ro.setUserId(userId); - ro.setIsDeleted(true); + ro.setInput(input); + ro.setPrevActionId(data.getPrevActionId()); + ro.setActionTypeId(data.getActionTypeId()); ro.setActionId(actionId); try { ApiResponseAutomationActionPO response = - automationDaoApiApi.daoCreateOrUpdateAutomationRobotAction(robotId, ro); + automationDaoApiApi.daoCreateOrUpdateAutomationRobotAction(data.getRobotId(), ro); ExceptionUtil.isFalse( AUTOMATION_ROBOT_NOT_EXIST.getCode().equals(response.getCode()), AUTOMATION_ROBOT_NOT_EXIST); - } catch (ApiException e) { - log.error("Delete action: {}", actionId, e); + return formatVoFromDatabusResponse(response.getData()); + } catch (RestClientException e) { + log.error("Robot update action: {}", data.getRobotId(), e); + } + return new ArrayList<>(); + } + + private String getActionInputStringFromRo(String actionId, Object inputObj) { + String input = JSONUtil.toJsonStr(inputObj); + if (null == input) { + return null; + } + AutomationActionEntity action = actionMapper.selectByActionId(actionId); + if (null == action) { + return null; + } + // change send email input, should check password + if (!input.equals(JSONUtil.toJsonStr(JSONUtil.createObj())) + && iAutomationActionTypeService.isSendEmailAction(action.getActionTypeId())) { + String newPassword = getSendEmailActionPassword(input); + // should set old password to new password + if (EMAIL_SHOW_PASSWORD.equals(newPassword)) { + String oldPassword = getSendEmailActionPassword(action.getInput()); + return setSendEmailActionPassword(input, oldPassword); + } } + return input; } private List formatVoFromDatabusResponse(List data) { @@ -185,11 +244,52 @@ private List formatVoFromDatabusResponse(List data vo.setActionId(i.getActionId()); vo.setActionTypeId(i.getActionTypeId()); vo.setPrevActionId(i.getPrevActionId()); - vo.setInput(i.getInput()); + vo.setInput(handleActionInput(i.getInput())); return vo; }).sorted(actionComparator).collect(toList()); } return new ArrayList<>(); } + private String getSendEmailActionPassword(String input) { + if (null == input) { + return null; + } + JSONObject inputObj = JSONUtil.parseObj(input); + if (inputObj.containsKey("value")) { + JSONObject inputValue = JSONUtil.parseObj(inputObj.get("value")); + if (inputValue.containsKey("operands")) { + JSONArray operands = JSONUtil.parseArray(inputValue.get("operands")); + if (operands.contains("password")) { + int passwordIndex = operands.indexOf("password"); + JSONObject passwordValue = JSONUtil.parseObj(operands.get(passwordIndex + 1)); + return StrUtil.toString(passwordValue.get("value")); + } + } + } + return null; + } + + private String setSendEmailActionPassword(String input, String password) { + if (null == input) { + return null; + } + JSONObject inputObj = JSONUtil.parseObj(input); + if (inputObj.containsKey("value")) { + JSONObject inputValue = JSONUtil.parseObj(inputObj.get("value")); + if (inputValue.containsKey("operands")) { + JSONArray operands = JSONUtil.parseArray(inputValue.get("operands")); + if (operands.contains("password")) { + int passwordIndex = operands.indexOf("password"); + Dict passwordValue = + new Dict().set("value", password).set("type", "Literal"); + operands.set(passwordIndex + 1, passwordValue); + } + inputValue.set("operands", operands); + } + inputObj.set("value", inputValue); + } + return JSONUtil.toJsonStr(inputObj); + } + } diff --git a/backend-server/application/src/main/java/com/apitable/automation/service/impl/AutomationActionTypeServiceImpl.java b/backend-server/application/src/main/java/com/apitable/automation/service/impl/AutomationActionTypeServiceImpl.java new file mode 100644 index 0000000000..1f84f4de87 --- /dev/null +++ b/backend-server/application/src/main/java/com/apitable/automation/service/impl/AutomationActionTypeServiceImpl.java @@ -0,0 +1,50 @@ +/* + * APITable + * Copyright (C) 2022 APITable Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.apitable.automation.service.impl; + +import cn.hutool.core.util.StrUtil; +import com.apitable.automation.enums.AutomationActionType; +import com.apitable.automation.mapper.AutomationActionTypeMapper; +import com.apitable.automation.service.IAutomationActionTypeService; +import jakarta.annotation.Resource; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +/** + * action type service implementation. + */ +@Slf4j +@Service +public class AutomationActionTypeServiceImpl implements IAutomationActionTypeService { + + @Resource + private AutomationActionTypeMapper actionTypeMapper; + + @Override + public String getActionTypeIdByEndpoint(String endpoint) { + return actionTypeMapper.getActionTypeIdByEndpoint(endpoint); + } + + @Override + public boolean isSendEmailAction(String actionTypeId) { + String endpoint = actionTypeMapper.selectEndpointByActionTypeId(actionTypeId); + return StrUtil.equals(endpoint, AutomationActionType.SEND_MAIL.getType()); + } + +} diff --git a/backend-server/application/src/main/java/com/apitable/automation/service/impl/AutomationRobotServiceImpl.java b/backend-server/application/src/main/java/com/apitable/automation/service/impl/AutomationRobotServiceImpl.java index 1994ea1fa8..2b77133148 100644 --- a/backend-server/application/src/main/java/com/apitable/automation/service/impl/AutomationRobotServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/automation/service/impl/AutomationRobotServiceImpl.java @@ -18,6 +18,7 @@ package com.apitable.automation.service.impl; +import static com.apitable.automation.enums.AutomationException.AUTOMATION_ROBOT_NOT_EXIST; import static com.apitable.automation.model.ActionSimpleVO.actionComparator; import static com.apitable.automation.model.TriggerSimpleVO.triggerComparator; import static java.util.stream.Collectors.groupingBy; @@ -46,19 +47,19 @@ import com.apitable.automation.service.IAutomationTriggerService; import com.apitable.automation.service.IAutomationTriggerTypeService; import com.apitable.core.exception.BusinessException; -import com.apitable.databusclient.ApiException; -import com.apitable.databusclient.api.AutomationDaoApiApi; -import com.apitable.databusclient.model.AutomationActionIntroductionPO; -import com.apitable.databusclient.model.AutomationRobotCopyRO; -import com.apitable.databusclient.model.AutomationRobotIntroductionPO; -import com.apitable.databusclient.model.AutomationRobotIntroductionSO; -import com.apitable.databusclient.model.AutomationRobotSO; -import com.apitable.databusclient.model.AutomationRobotUpdateRO; -import com.apitable.databusclient.model.AutomationSO; -import com.apitable.databusclient.model.AutomationTriggerIntroductionPO; +import com.apitable.core.util.ExceptionUtil; import com.apitable.internal.service.impl.InternalSpaceServiceImpl; import com.apitable.internal.vo.InternalSpaceAutomationRunMessageV0; import com.apitable.shared.util.IdUtil; +import com.apitable.starter.databus.client.api.AutomationDaoApiApi; +import com.apitable.starter.databus.client.model.AutomationActionIntroductionPO; +import com.apitable.starter.databus.client.model.AutomationRobotCopyRO; +import com.apitable.starter.databus.client.model.AutomationRobotIntroductionPO; +import com.apitable.starter.databus.client.model.AutomationRobotIntroductionSO; +import com.apitable.starter.databus.client.model.AutomationRobotSO; +import com.apitable.starter.databus.client.model.AutomationRobotUpdateRO; +import com.apitable.starter.databus.client.model.AutomationSO; +import com.apitable.starter.databus.client.model.AutomationTriggerIntroductionPO; import com.apitable.template.enums.TemplateException; import com.apitable.user.service.IUserService; import com.apitable.user.vo.UserSimpleVO; @@ -67,12 +68,14 @@ import com.apitable.workspace.vo.NodeInfo; import com.apitable.workspace.vo.NodeSimpleVO; import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; import jakarta.annotation.Resource; import java.math.BigInteger; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; @@ -80,6 +83,7 @@ import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import org.springframework.web.client.RestClientException; /** * automation robot service impl. @@ -177,7 +181,7 @@ public void copyByDatabus(Long userId, List resourceIds, AutomationCopyO } try { automationDaoApiApi.daoCopyAutomationRobot(robots); - } catch (ApiException e) { + } catch (RestClientException e) { log.error("Copy automation error:{}", resourceIds, e); throw new BusinessException(NodeException.NODE_COPY_FOLDER_ERROR); } @@ -326,7 +330,7 @@ public AutomationVO getRobotByRobotId(String robotId) { List actions = Optional.of(automation.getActions()).orElse(new ArrayList<>()).stream().map(i -> { ActionVO action = new ActionVO(); - action.setInput(i.getInput()); + action.setInput(iAutomationActionService.handleActionInput(i.getInput())); action.setActionId(i.getActionId()); action.setPrevActionId(i.getPrevActionId()); action.setActionTypeId(i.getActionTypeId()); @@ -358,6 +362,7 @@ public void checkAutomationReference(List subNodeIds, List resou List referenceResourceIds = triggers.stream() .map(AutomationTriggerDto::getResourceId) .filter(StrUtil::isNotBlank).collect(Collectors.toList()); + referenceResourceIds = iNodeService.getExistNodeIdsBySelf(referenceResourceIds); Collection subtract = CollUtil.subtract(referenceResourceIds, subNodeIds); if (CollUtil.isEmpty(subtract)) { return; @@ -365,13 +370,13 @@ public void checkAutomationReference(List subNodeIds, List resou Optional trigger = triggers.stream() .filter(i -> i.getResourceId().equals(CollUtil.getFirst(subtract))) .findFirst(); - if (!trigger.isPresent()) { + if (trigger.isEmpty()) { return; } Optional robot = robots.stream() .filter(i -> i.getRobotId().equals(trigger.get().getRobotId())) .findFirst(); - if (!robot.isPresent()) { + if (robot.isEmpty()) { return; } List nodeIds = new ArrayList<>(); @@ -411,7 +416,7 @@ public boolean update(String robotId, Long updater, UpdateRobotRO data) { try { automationDaoApiApi.daoUpdateAutomationRobot(robotId, ro); return true; - } catch (ApiException e) { + } catch (RestClientException e) { log.error("Update automation error", e); return false; } @@ -424,7 +429,7 @@ public void deleteRobot(String robotId, Long updater) { ro.setIsDeleted(true); try { automationDaoApiApi.daoUpdateAutomationRobot(robotId, ro); - } catch (ApiException e) { + } catch (RestClientException e) { log.error("Delete automation error", e); } } @@ -441,6 +446,27 @@ public long getRobotRunsCountBySpaceId(String spaceId) { } } + @Override + public void checkRobotExists(String robotId) { + ExceptionUtil.isTrue(SqlHelper.retBool(robotMapper.selectCountByRobotId(robotId)), + AUTOMATION_ROBOT_NOT_EXIST); + } + + @Override + public boolean linkByOutsideAutomation(List nodeIds) { + List robotIds = iAutomationTriggerService.getRobotIdsByResourceIds(nodeIds); + if (CollUtil.isNotEmpty(robotIds)) { + List resourceIds = robotMapper.selectResourceIdsByRobotIds(robotIds); + return !new HashSet<>(nodeIds).containsAll(resourceIds); + } + return false; + } + + @Override + public void updateUpdaterByRobotId(String robotId, Long updatedBy) { + robotMapper.updateUpdatedByRobotId(robotId, updatedBy); + } + private AutomationRobotIntroductionSO getRobotsByResourceIdFromDatabus(String resourceId) { try { AutomationRobotIntroductionSO result = @@ -453,7 +479,7 @@ private AutomationRobotIntroductionSO getRobotsByResourceIdFromDatabus(String re return null; } return result; - } catch (ApiException e) { + } catch (RestClientException e) { log.error("Get automation error", e); return null; } @@ -462,7 +488,7 @@ private AutomationRobotIntroductionSO getRobotsByResourceIdFromDatabus(String re private AutomationSO getRobotByRobotIdFromDatabus(String robotId) { try { return automationDaoApiApi.daoGetRobotByRobotId(robotId).getData(); - } catch (ApiException e) { + } catch (RestClientException e) { log.error("Get automation detail error", e); return null; } diff --git a/backend-server/application/src/main/java/com/apitable/automation/service/impl/AutomationRunHistoryServiceImpl.java b/backend-server/application/src/main/java/com/apitable/automation/service/impl/AutomationRunHistoryServiceImpl.java index 2f627d5d16..27bd2d4358 100644 --- a/backend-server/application/src/main/java/com/apitable/automation/service/impl/AutomationRunHistoryServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/automation/service/impl/AutomationRunHistoryServiceImpl.java @@ -18,21 +18,29 @@ package com.apitable.automation.service.impl; +import static com.apitable.automation.service.impl.AutomationActionServiceImpl.EMAIL_SHOW_PASSWORD; + import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.date.LocalDateTimeUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSON; +import cn.hutool.json.JSONArray; +import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; +import com.apitable.automation.entity.AutomationRunHistoryEntity; +import com.apitable.automation.mapper.AutomationRunHistoryMapper; +import com.apitable.automation.model.AutomationRunHistoryDTO; +import com.apitable.automation.model.AutomationRunTaskVO; import com.apitable.automation.model.AutomationTaskSimpleVO; import com.apitable.automation.service.IAutomationRunHistoryService; -import com.apitable.databusclient.api.AutomationDaoApiApi; -import com.apitable.databusclient.model.AutomationRunHistoryPO; import com.apitable.shared.clock.spring.ClockManager; import com.apitable.workspace.enums.IdRulePrefixEnum; -import jakarta.annotation.Resource; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import java.time.LocalDate; import java.util.ArrayList; import java.util.List; -import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -41,69 +49,105 @@ */ @Slf4j @Service -public class AutomationRunHistoryServiceImpl implements IAutomationRunHistoryService { - - @Resource - private AutomationDaoApiApi automationDaoApiApi; +public class AutomationRunHistoryServiceImpl + extends ServiceImpl + implements IAutomationRunHistoryService { + @Override + public List getRobotRunHistory(String spaceId, String robotId, + Page page) { + LocalDate date = LocalDate.now().plusDays(1); + IPage historyIds = + baseMapper.selectIdByRobotIdAndSpaceIdAndBetweenWithPage(robotId, spaceId, + getPreviousMonthFirstDay(date), date, page); + if (historyIds.getRecords().isEmpty()) { + return new ArrayList<>(); + } + List runHistories = + baseMapper.selectByIds(historyIds.getRecords()); + return runHistories.stream().map(this::formatTaskSimpleVo).toList(); + } @Override - public List getRobotRunHistory(String robotId, Integer pageSize, - Integer pageNum) { - return getAutomationRobotRunHistoryFromDatabus(robotId, pageSize, pageNum); + public AutomationRunTaskVO getByTaskDetail(String taskId) { + AutomationRunHistoryEntity task = baseMapper.selectByTaskId(taskId); + if (ObjectUtil.isNull(task)) { + return null; + } + AutomationRunTaskVO vo = new AutomationRunTaskVO(); + vo.setTaskId(task.getTaskId()); + vo.setId(task.getId().toString()); + vo.setId(task.getRobotId()); + vo.setStatus(task.getStatus()); + vo.setSpaceId(task.getSpaceId()); + vo.setRobotId(task.getRobotId()); + vo.setData(formatExecuteData(task.getData())); + return vo; + } + + private LocalDate getPreviousMonthFirstDay(LocalDate date) { + return date.minusMonths(1).withDayOfMonth(1); } - private List getAutomationRobotRunHistoryFromDatabus(String robotId, - Integer pageSize, - Integer pageNum) { - List results = new ArrayList<>(); - try { - List tasks = - automationDaoApiApi.daoGetAutomationRunHistory(pageSize, pageNum, robotId) - .getData(); - if (null == tasks) { - return results; + private AutomationTaskSimpleVO formatTaskSimpleVo(AutomationRunHistoryDTO history) { + AutomationTaskSimpleVO vo = new AutomationTaskSimpleVO(); + vo.setRobotId(history.getRobotId()); + vo.setStatus(history.getStatus()); + vo.setTaskId(history.getTaskId()); + vo.setCreatedAt( + history.getCreatedAt().atZone(ClockManager.me().getDefaultTimeZone()).toInstant() + .toEpochMilli()); + if (StrUtil.isNotBlank(history.getActionIds())) { + List executions = new ArrayList<>(); + List actionIds = JSONUtil.parseArray(history.getActionIds()); + List actionTypeIds = JSONUtil.parseArray(history.getActionTypeIds()); + List errorMessages = JSONUtil.parseArray(history.getErrorMessages()); + for (int i = 0; i < actionIds.size(); i++) { + AutomationTaskSimpleVO.ActionExecutionVO execution = + new AutomationTaskSimpleVO.ActionExecutionVO(); + // exclude trigger + if (!StrUtil.startWith(actionIds.get(i).toString(), + IdRulePrefixEnum.AUTOMATION_TRIGGER.getIdRulePrefixEnum())) { + execution.setActionId(actionIds.get(i).toString()); + execution.setActionTypeId(actionTypeIds.get(i).toString()); + execution.setSuccess(ObjectUtil.isNull(CollUtil.get(errorMessages, i))); + executions.add(execution); + } } - tasks.forEach(task -> { - AutomationTaskSimpleVO result = new AutomationTaskSimpleVO(); - result.setRobotId(task.getRobotId()); - result.setStatus(task.getStatus()); - result.setTaskId(task.getTaskId()); - result.setCreatedAt( - LocalDateTimeUtil.parse(task.getCreatedAt()) - .atZone(ClockManager.me().getDefaultTimeZone()).toInstant().toEpochMilli()); - result.setRobotId(task.getRobotId()); - // format action execution list - if (StrUtil.isNotBlank(task.getActionIds())) { - List executions = new ArrayList<>(); - List actionIds = - new ArrayList<>(JSONUtil.parseArray(task.getActionIds())); - List actionTypeIds = - new ArrayList<>(JSONUtil.parseArray(task.getActionTypeIds())); - List> errorMessages = - new ArrayList<>( - JSONUtil.parseArray(task.getErrorStacks())).stream().map( - JSONUtil::parseArray).collect(Collectors.toList()); - for (int i = 0; i < actionIds.size(); i++) { - AutomationTaskSimpleVO.ActionExecutionVO execution = - new AutomationTaskSimpleVO.ActionExecutionVO(); - // exclude trigger - if (!ObjectUtil.contains(actionIds.get(i), - IdRulePrefixEnum.AUTOMATION_TRIGGER.getIdRulePrefixEnum())) { - execution.setActionId(actionIds.get(i).toString()); - execution.setActionTypeId(actionTypeIds.get(i).toString()); - execution.setSuccess(CollUtil.get(errorMessages, i).isEmpty()); - executions.add(execution); - } + vo.setExecutedActions(executions); + } + return vo; + } + + private JSON formatExecuteData(String dataStr) { + JSONObject data = JSONUtil.parseObj(dataStr); + // handle multi triggers + JSONArray executedNodeIds = data.getJSONArray("executedNodeIds"); + if (null != executedNodeIds) { + executedNodeIds.removeIf(i -> { + int index = executedNodeIds.indexOf(i); + return 0 != index && i.toString() + .startsWith(IdRulePrefixEnum.AUTOMATION_TRIGGER.getIdRulePrefixEnum()); + }); + data.set("executedNodeIds", executedNodeIds); + } + // handle send mail action password + JSONObject nodeByIds = data.getJSONObject("nodeByIds"); + if (null != nodeByIds) { + for (Object executedNodeId : nodeByIds.keySet()) { + if (executedNodeId.toString() + .startsWith(IdRulePrefixEnum.AUTOMATION_ACTION.getIdRulePrefixEnum())) { + JSONObject executedAction = nodeByIds.getJSONObject(executedNodeId.toString()); + JSONObject actionInput = executedAction.getJSONObject("input"); + if (null != actionInput && actionInput.containsKey("password")) { + actionInput.set("password", EMAIL_SHOW_PASSWORD); + executedAction.set("input", actionInput); + nodeByIds.set(executedNodeId.toString(), executedAction); + data.set("nodeByIds", nodeByIds); } - result.setExecutedActions(executions); } - results.add(result); - }); - return results; - } catch (Exception e) { - log.error("Get automation history error: {}", robotId, e); - return results; + } } + return data; } } diff --git a/backend-server/application/src/main/java/com/apitable/automation/service/impl/AutomationServiceImpl.java b/backend-server/application/src/main/java/com/apitable/automation/service/impl/AutomationServiceImpl.java deleted file mode 100644 index 5ecc903c37..0000000000 --- a/backend-server/application/src/main/java/com/apitable/automation/service/impl/AutomationServiceImpl.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * APITable - * Copyright (C) 2022 APITable Ltd. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package com.apitable.automation.service.impl; - -import cn.hutool.core.bean.BeanUtil; -import cn.hutool.core.util.StrUtil; -import com.apitable.automation.entity.AutomationServiceEntity; -import com.apitable.automation.mapper.AutomationServiceMapper; -import com.apitable.automation.model.AutomationServiceCreateRO; -import com.apitable.automation.model.AutomationServiceEditRO; -import com.apitable.automation.service.IAutomationService; -import com.apitable.base.enums.DatabaseException; -import com.apitable.core.exception.BusinessException; -import com.apitable.core.util.ExceptionUtil; -import com.apitable.shared.util.IdUtil; -import com.baomidou.mybatisplus.core.toolkit.IdWorker; -import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; -import jakarta.annotation.Resource; -import java.util.Optional; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Service; - -/** - * AutomationServiceImpl. - */ -@Slf4j -@Service -public class AutomationServiceImpl implements IAutomationService { - - @Resource - private AutomationServiceMapper serviceMapper; - - @Override - public void checkServiceIfExist(String serviceId) { - this.getIdByServiceId(serviceId); - } - - @Override - public String createService(Long userId, AutomationServiceCreateRO ro) { - this.checkServicePlugIfExist(ro.getSlug()); - String serviceId = StrUtil.isNotBlank(ro.getServiceId()) - ? ro.getServiceId() : IdUtil.createAutomationServiceId(); - AutomationServiceEntity entity = - BeanUtil.copyProperties(ro, AutomationServiceEntity.class); - entity.setId(IdWorker.getId()); - entity.setServiceId(serviceId); - entity.setCreatedBy(userId); - entity.setUpdatedBy(userId); - boolean flag = SqlHelper.retBool(serviceMapper.insert(entity)); - ExceptionUtil.isTrue(flag, DatabaseException.INSERT_ERROR); - return serviceId; - } - - @Override - public void editService(Long userId, String serviceId, AutomationServiceEditRO ro) { - Long id = this.getIdByServiceId(serviceId); - AutomationServiceEntity entity = - BeanUtil.copyProperties(ro, AutomationServiceEntity.class); - entity.setId(id); - entity.setUpdatedBy(userId); - boolean flag = SqlHelper.retBool(serviceMapper.updateById(entity)); - ExceptionUtil.isTrue(flag, DatabaseException.EDIT_ERROR); - } - - @Override - public void deleteService(Long userId, String serviceId) { - Long id = this.getIdByServiceId(serviceId); - boolean flag = SqlHelper.retBool(serviceMapper.deleteById(id)); - ExceptionUtil.isTrue(flag, DatabaseException.DELETE_ERROR); - } - - private Long getIdByServiceId(String serviceId) { - Long id = serviceMapper.selectIdByServiceId(serviceId); - return Optional.ofNullable(id) - .orElseThrow(() -> new BusinessException("Automation Service not exist.")); - } - - private void checkServicePlugIfExist(String slug) { - Long id = serviceMapper.selectIdBySlugIncludeDeleted(slug); - if (id != null) { - throw new BusinessException("Slug have been existed."); - } - } - -} diff --git a/backend-server/application/src/main/java/com/apitable/automation/service/impl/AutomationTriggerServiceImpl.java b/backend-server/application/src/main/java/com/apitable/automation/service/impl/AutomationTriggerServiceImpl.java index 6831c87e1c..d6601717d5 100644 --- a/backend-server/application/src/main/java/com/apitable/automation/service/impl/AutomationTriggerServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/automation/service/impl/AutomationTriggerServiceImpl.java @@ -18,12 +18,14 @@ package com.apitable.automation.service.impl; -import static com.apitable.automation.enums.AutomationException.AUTOMATION_ROBOT_NOT_EXIST; import static com.apitable.automation.enums.AutomationException.AUTOMATION_TRIGGER_LIMIT; +import static com.apitable.automation.enums.AutomationException.AUTOMATION_TRIGGER_NOT_EXIST; import static com.apitable.automation.model.TriggerSimpleVO.triggerComparator; import static java.util.stream.Collectors.toList; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.collection.ListUtil; +import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; import com.apitable.automation.entity.AutomationTriggerEntity; @@ -35,16 +37,15 @@ import com.apitable.automation.model.TriggerCopyResultDto; import com.apitable.automation.model.TriggerVO; import com.apitable.automation.model.UpdateTriggerRO; +import com.apitable.automation.service.IAutomationRobotService; import com.apitable.automation.service.IAutomationTriggerService; import com.apitable.automation.service.IAutomationTriggerTypeService; import com.apitable.core.util.ExceptionUtil; -import com.apitable.databusclient.ApiException; -import com.apitable.databusclient.api.AutomationDaoApiApi; -import com.apitable.databusclient.model.ApiResponseAutomationTriggerPO; -import com.apitable.databusclient.model.AutomationRobotTriggerRO; -import com.apitable.databusclient.model.AutomationTriggerPO; +import com.apitable.interfaces.automation.facede.AutomationServiceFacade; import com.apitable.shared.config.properties.LimitProperties; import com.apitable.shared.util.IdUtil; +import com.apitable.starter.databus.client.api.AutomationDaoApiApi; +import com.apitable.starter.databus.client.model.AutomationTriggerSO; import com.baomidou.mybatisplus.core.toolkit.IdWorker; import jakarta.annotation.Resource; import java.math.BigInteger; @@ -55,6 +56,7 @@ import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; /** * automation trigger service impl. @@ -62,9 +64,10 @@ @Slf4j @Service public class AutomationTriggerServiceImpl implements IAutomationTriggerService { - + @Resource private AutomationDaoApiApi automationDaoApiApi; + @Resource private AutomationTriggerMapper triggerMapper; @@ -74,6 +77,12 @@ public class AutomationTriggerServiceImpl implements IAutomationTriggerService { @Resource private IAutomationTriggerTypeService iAutomationTriggerTypeService; + @Resource + private AutomationServiceFacade automationServiceFacade; + + @Resource + private IAutomationRobotService iAutomationRobotService; + @Override public List getTriggersByRobotIds(List robotIds) { return triggerMapper.selectTriggersByRobotIds(robotIds); @@ -85,70 +94,78 @@ public void create(AutomationTriggerEntity entity) { } @Override - public List createByDatabus(Long userId, CreateTriggerRO data) { - AutomationRobotTriggerRO ro = new AutomationRobotTriggerRO(); - ro.setResourceId(data.getRelatedResourceId()); - ro.setUserId(userId); - ro.setInput(JSONUtil.toJsonStr(data.getInput())); - ro.setPrevTriggerId(data.getPrevTriggerId()); - ro.setTriggerTypeId(data.getTriggerTypeId()); - ro.setLimitCount(Long.valueOf(limitProperties.getAutomationTriggerCount())); - try { - ApiResponseAutomationTriggerPO response = - automationDaoApiApi.daoCreateOrUpdateAutomationRobotTrigger(data.getRobotId(), ro); - ExceptionUtil.isFalse( - AUTOMATION_ROBOT_NOT_EXIST.getCode().equals(response.getCode()), - AUTOMATION_ROBOT_NOT_EXIST); - ExceptionUtil.isFalse( - AUTOMATION_TRIGGER_LIMIT.getCode().equals(response.getCode()), - AUTOMATION_TRIGGER_LIMIT); - if (null == response.getData()) { - log.error("CreateTriggerEmpty:{}", data.getRobotId()); - } - return formatVoFromDatabusResponse(response.getData()); - } catch (ApiException e) { - log.error("Robot create trigger: {}", data.getRobotId(), e); + @Transactional(rollbackFor = Exception.class) + public List create(Long userId, String spaceId, CreateTriggerRO data) { + iAutomationRobotService.checkRobotExists(data.getRobotId()); + checkTriggerLimitation(data.getRobotId()); + String scheduleTriggerTypeId = iAutomationTriggerTypeService.getTriggerTypeByEndpoint( + AutomationTriggerType.SCHEDULED_TIME_ARRIVE.getType()); + AutomationTriggerEntity entity = AutomationTriggerEntity.builder() + .robotId(data.getRobotId()) + .triggerTypeId(data.getTriggerTypeId()) + .prevTriggerId(data.getPrevTriggerId()) + .resourceId(data.getRelatedResourceId()) + .input(JSONUtil.toJsonStr(data.getInput())) + .triggerId(IdUtil.createAutomationTriggerId()) + .build(); + create(entity); + iAutomationRobotService.updateUpdaterByRobotId(data.getRobotId(), userId); + if (StrUtil.equals(scheduleTriggerTypeId, data.getTriggerTypeId())) { + automationServiceFacade.createSchedule(spaceId, entity.getTriggerId(), + JSONUtil.toJsonStr( + ObjectUtil.defaultIfNull(data.getScheduleConfig(), JSONUtil.createObj()))); } - return new ArrayList<>(); + return formatVoFromEntities(ListUtil.of(entity)); } @Override - public List updateByDatabus(String triggerId, Long userId, UpdateTriggerRO data) { - AutomationRobotTriggerRO ro = new AutomationRobotTriggerRO(); - ro.setResourceId(data.getRelatedResourceId()); - ro.setUserId(userId); - ro.setInput(JSONUtil.toJsonStr(data.getInput())); - ro.setPrevTriggerId(data.getPrevTriggerId()); - ro.setTriggerTypeId(data.getTriggerTypeId()); - ro.setTriggerId(triggerId); - try { - ApiResponseAutomationTriggerPO response = - automationDaoApiApi.daoCreateOrUpdateAutomationRobotTrigger(data.getRobotId(), ro); - ExceptionUtil.isFalse( - AUTOMATION_ROBOT_NOT_EXIST.getCode().equals(response.getCode()), - AUTOMATION_ROBOT_NOT_EXIST); - return formatVoFromDatabusResponse(response.getData()); - } catch (ApiException e) { - log.error("Robot update trigger: {}", data.getRobotId(), e); + @Transactional(rollbackFor = Exception.class) + public List update(Long userId, String triggerId, String spaceId, + UpdateTriggerRO data) { + iAutomationRobotService.checkRobotExists(data.getRobotId()); + AutomationTriggerEntity trigger = + triggerMapper.selectByTriggerId(triggerId); + ExceptionUtil.isNotNull(trigger, AUTOMATION_TRIGGER_NOT_EXIST); + String scheduleTriggerTypeId = iAutomationTriggerTypeService.getTriggerTypeByEndpoint( + AutomationTriggerType.SCHEDULED_TIME_ARRIVE.getType()); + if (StrUtil.isNotBlank(data.getTriggerTypeId()) + && !trigger.getTriggerTypeId().equals(data.getTriggerTypeId())) { + // change trigger type should reset schedule config to empty object {} + automationServiceFacade.updateSchedule(triggerId, + JSONUtil.toJsonStr(JSONUtil.createObj())); + trigger.setTriggerTypeId(data.getTriggerTypeId()); } - return new ArrayList<>(); + if (StrUtil.isNotBlank(data.getPrevTriggerId())) { + trigger.setPrevTriggerId(data.getPrevTriggerId()); + } + if (ObjectUtil.isNotNull(data.getInput())) { + trigger.setInput(JSONUtil.toJsonStr(data.getInput())); + } + if (StrUtil.isNotBlank(data.getRelatedResourceId())) { + trigger.setResourceId(data.getRelatedResourceId()); + } + if (ObjectUtil.isNotNull(data.getScheduleConfig())) { + automationServiceFacade.updateSchedule(triggerId, + JSONUtil.toJsonStr(data.getScheduleConfig())); + } + iAutomationRobotService.updateUpdaterByRobotId(data.getRobotId(), userId); + triggerMapper.updateById(trigger); + return formatVoFromEntities(ListUtil.of(trigger)); } + @Override - public void deleteByDatabus(String robotId, String triggerId, Long userId) { - AutomationRobotTriggerRO ro = new AutomationRobotTriggerRO(); - ro.setUserId(userId); - ro.setIsDeleted(true); - ro.setTriggerId(triggerId); - try { - ApiResponseAutomationTriggerPO response = - automationDaoApiApi.daoCreateOrUpdateAutomationRobotTrigger(robotId, ro); - ExceptionUtil.isFalse( - AUTOMATION_ROBOT_NOT_EXIST.getCode().equals(response.getCode()), - AUTOMATION_ROBOT_NOT_EXIST); - } catch (ApiException e) { - log.error("Delete trigger: {}", triggerId, e); + @Transactional(rollbackFor = Exception.class) + public void deleteByTriggerId(String robotId, String triggerId, Long userId) { + AutomationTriggerEntity trigger = triggerMapper.selectByTriggerId(triggerId); + ExceptionUtil.isNotNull(trigger, AUTOMATION_TRIGGER_NOT_EXIST); + String scheduleTriggerTypeId = iAutomationTriggerTypeService.getTriggerTypeByEndpoint( + AutomationTriggerType.SCHEDULED_TIME_ARRIVE.getType()); + if (trigger.getTriggerTypeId().equals(scheduleTriggerTypeId)) { + automationServiceFacade.deleteSchedule(triggerId, userId); } + triggerMapper.deleteById(trigger.getId()); + iAutomationRobotService.updateUpdaterByRobotId(robotId, userId); } @Override @@ -204,6 +221,7 @@ public TriggerCopyResultDto copy(Long userId, AutomationCopyOptions options, Map> robotIdToTriggerIdsMap = triggers.stream().collect(Collectors.groupingBy(AutomationTriggerEntity::getRobotId, Collectors.mapping(AutomationTriggerEntity::getTriggerId, toList()))); + automationServiceFacade.copy(newTriggerMap); return new TriggerCopyResultDto(robotIdToTriggerIdsMap, newTriggerMap); } @@ -219,9 +237,32 @@ public void updateInputByRobotIdsAndTriggerTypeIds(List robotIds, String triggerMapper.updateTriggerInputByRobotIdsAndTriggerType(robotIds, triggerTypeId, input); } - private List formatVoFromDatabusResponse(List data) { + @Override + public List getRobotIdsByResourceIds(List nodeIds) { + return triggerMapper.selectRobotIdByResourceIds(nodeIds); + } + + private List handleTriggerResponse(List data) { if (null != data) { return data.stream().map(i -> { + TriggerVO vo = new TriggerVO(); + vo.setTriggerId(i.getTriggerId()); + vo.setTriggerTypeId(i.getTriggerTypeId()); + vo.setRelatedResourceId(i.getResourceId()); + vo.setPrevTriggerId(i.getPrevTriggerId()); + vo.setInput(i.getInput()); + if (null != i.getScheduleId()) { + automationServiceFacade.publishSchedule(i.getScheduleId()); + } + return vo; + }).sorted(triggerComparator).collect(toList()); + } + return new ArrayList<>(); + } + + private List formatVoFromEntities(List entities) { + if (null != entities) { + return entities.stream().map(i -> { TriggerVO vo = new TriggerVO(); vo.setTriggerId(i.getTriggerId()); vo.setTriggerTypeId(i.getTriggerTypeId()); @@ -233,4 +274,10 @@ private List formatVoFromDatabusResponse(List da } return new ArrayList<>(); } + + private void checkTriggerLimitation(String robotId) { + Integer triggerCount = triggerMapper.selectCountByRobotId(robotId); + ExceptionUtil.isFalse(triggerCount >= limitProperties.getAutomationTriggerCount(), + AUTOMATION_TRIGGER_LIMIT); + } } diff --git a/backend-server/application/src/main/java/com/apitable/automation/service/impl/AutomationTriggerTypeServiceImpl.java b/backend-server/application/src/main/java/com/apitable/automation/service/impl/AutomationTriggerTypeServiceImpl.java index 576c4451dd..fafc326cbe 100644 --- a/backend-server/application/src/main/java/com/apitable/automation/service/impl/AutomationTriggerTypeServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/automation/service/impl/AutomationTriggerTypeServiceImpl.java @@ -18,22 +18,11 @@ package com.apitable.automation.service.impl; -import cn.hutool.core.bean.BeanUtil; -import cn.hutool.core.util.StrUtil; import com.apitable.automation.entity.AutomationTriggerTypeEntity; import com.apitable.automation.mapper.AutomationTriggerTypeMapper; -import com.apitable.automation.model.TriggerTypeCreateRO; -import com.apitable.automation.model.TriggerTypeEditRO; -import com.apitable.automation.service.IAutomationService; import com.apitable.automation.service.IAutomationTriggerTypeService; -import com.apitable.base.enums.DatabaseException; -import com.apitable.core.exception.BusinessException; -import com.apitable.core.util.ExceptionUtil; -import com.apitable.shared.util.IdUtil; -import com.baomidou.mybatisplus.core.toolkit.IdWorker; -import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import jakarta.annotation.Resource; -import java.util.Optional; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; @@ -42,10 +31,9 @@ */ @Slf4j @Service -public class AutomationTriggerTypeServiceImpl implements IAutomationTriggerTypeService { - - @Resource - private IAutomationService iAutomationService; +public class AutomationTriggerTypeServiceImpl + extends ServiceImpl + implements IAutomationTriggerTypeService { @Resource private AutomationTriggerTypeMapper triggerTypeMapper; @@ -54,44 +42,4 @@ public class AutomationTriggerTypeServiceImpl implements IAutomationTriggerTypeS public String getTriggerTypeByEndpoint(String endpoint) { return triggerTypeMapper.getTriggerTypeByEndpoint(endpoint); } - - @Override - public String create(Long userId, TriggerTypeCreateRO ro) { - iAutomationService.checkServiceIfExist(ro.getServiceId()); - String triggerTypeId = StrUtil.isNotBlank(ro.getTriggerTypeId()) - ? ro.getTriggerTypeId() : IdUtil.createAutomationTriggerTypeId(); - AutomationTriggerTypeEntity entity = - BeanUtil.copyProperties(ro, AutomationTriggerTypeEntity.class); - entity.setId(IdWorker.getId()); - entity.setTriggerTypeId(triggerTypeId); - entity.setCreatedBy(userId); - entity.setUpdatedBy(userId); - boolean flag = SqlHelper.retBool(triggerTypeMapper.insert(entity)); - ExceptionUtil.isTrue(flag, DatabaseException.INSERT_ERROR); - return triggerTypeId; - } - - @Override - public void edit(Long userId, String triggerTypeId, TriggerTypeEditRO ro) { - Long id = this.getIdByTriggerTypeId(triggerTypeId); - AutomationTriggerTypeEntity entity = - BeanUtil.copyProperties(ro, AutomationTriggerTypeEntity.class); - entity.setId(id); - entity.setUpdatedBy(userId); - boolean flag = SqlHelper.retBool(triggerTypeMapper.updateById(entity)); - ExceptionUtil.isTrue(flag, DatabaseException.EDIT_ERROR); - } - - @Override - public void delete(Long userId, String triggerTypeId) { - Long id = this.getIdByTriggerTypeId(triggerTypeId); - boolean flag = SqlHelper.retBool(triggerTypeMapper.deleteById(id)); - ExceptionUtil.isTrue(flag, DatabaseException.DELETE_ERROR); - } - - private Long getIdByTriggerTypeId(String triggerTypeId) { - Long id = triggerTypeMapper.selectIdByTriggerTypeId(triggerTypeId); - return Optional.ofNullable(id) - .orElseThrow(() -> new BusinessException("Trigger Type not exist.")); - } } diff --git a/backend-server/application/src/main/java/com/apitable/base/controller/ActionController.java b/backend-server/application/src/main/java/com/apitable/base/controller/ActionController.java index 8a17226160..1d84709fd0 100644 --- a/backend-server/application/src/main/java/com/apitable/base/controller/ActionController.java +++ b/backend-server/application/src/main/java/com/apitable/base/controller/ActionController.java @@ -22,14 +22,12 @@ import com.apitable.base.enums.SmsCodeType; import com.apitable.base.ro.EmailOpRo; import com.apitable.base.ro.SmsOpRo; -import com.apitable.base.service.IActionService; import com.apitable.core.support.ResponseData; import com.apitable.interfaces.eventbus.facade.EventBusFacade; import com.apitable.interfaces.eventbus.model.CaptchaEvent; import com.apitable.interfaces.security.facade.HumanVerificationServiceFacade; import com.apitable.interfaces.security.model.NonRobotMetadata; import com.apitable.organization.ro.InviteValidRo; -import com.apitable.organization.vo.InviteInfoVo; import com.apitable.shared.captcha.CodeValidateScope; import com.apitable.shared.captcha.ValidateCodeProcessor; import com.apitable.shared.captcha.ValidateCodeProcessorManage; @@ -39,6 +37,8 @@ import com.apitable.shared.component.scanner.annotation.PostResource; import com.apitable.shared.util.information.ClientOriginInfo; import com.apitable.shared.util.information.InformationUtil; +import com.apitable.space.service.ISpaceInvitationService; +import com.apitable.space.vo.EmailInvitationValidateVO; import com.apitable.user.ro.EmailCodeValidateRo; import com.apitable.user.ro.SmsCodeValidateRo; import com.apitable.user.service.IUserService; @@ -59,7 +59,7 @@ public class ActionController { @Resource - private IActionService iActionService; + private ISpaceInvitationService iSpaceInvitationService; @Resource private IUserService userService; @@ -163,13 +163,17 @@ public ResponseData validateEmail(@RequestBody @Valid EmailCodeValidateRo /** * Invitation temporary code verification. */ + @Deprecated(since = "v1.10.0") @PostResource(path = "/invite/valid", requiredLogin = false) @Operation(summary = "Invitation temporary code verification", description = "Invitation link token verification, the relevant invitation" + " information can be obtained after the verification is successful") - public ResponseData inviteTokenValid(@RequestBody @Valid InviteValidRo data) { + public ResponseData inviteTokenValid( + @RequestBody @Valid InviteValidRo data + ) { // Invitation code verification - InviteInfoVo inviteInfoVo = iActionService.inviteValidate(data.getToken()); + EmailInvitationValidateVO inviteInfoVo = + iSpaceInvitationService.validEmailInvitation(data.getToken()); return ResponseData.success(inviteInfoVo); } } diff --git a/backend-server/application/src/main/java/com/apitable/base/service/impl/ActionServiceImpl.java b/backend-server/application/src/main/java/com/apitable/base/service/impl/ActionServiceImpl.java deleted file mode 100644 index 6534c3d636..0000000000 --- a/backend-server/application/src/main/java/com/apitable/base/service/impl/ActionServiceImpl.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * APITable - * Copyright (C) 2022 APITable Ltd. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package com.apitable.base.service.impl; - -import static com.apitable.organization.enums.OrganizationException.INVITE_EXPIRE; -import static com.apitable.organization.enums.OrganizationException.INVITE_URL_ERROR; - -import com.apitable.base.service.IActionService; -import com.apitable.core.util.ExceptionUtil; -import com.apitable.core.util.HttpContextUtil; -import com.apitable.interfaces.user.facade.UserServiceFacade; -import com.apitable.organization.entity.MemberEntity; -import com.apitable.organization.service.IMemberService; -import com.apitable.organization.vo.InviteInfoVo; -import com.apitable.space.entity.SpaceEntity; -import com.apitable.space.entity.SpaceInviteRecordEntity; -import com.apitable.space.mapper.SpaceInviteRecordMapper; -import com.apitable.space.service.ISpaceService; -import com.apitable.user.entity.UserEntity; -import com.apitable.user.service.IUserService; -import jakarta.annotation.Resource; -import org.springframework.stereotype.Service; - -/** - * action service implement. - */ -@Service -public class ActionServiceImpl implements IActionService { - - @Resource - private IUserService iUserService; - - @Resource - private UserServiceFacade userServiceFacade; - - @Resource - private ISpaceService iSpaceService; - - @Resource - private SpaceInviteRecordMapper spaceInviteRecordMapper; - - @Resource - private IMemberService iMemberService; - - @Override - public InviteInfoVo inviteValidate(String inviteToken) { - // is it a illegal link - SpaceInviteRecordEntity record = spaceInviteRecordMapper.selectByInviteToken(inviteToken); - // determine whether it is illegal - ExceptionUtil.isNotNull(record, INVITE_URL_ERROR); - // determine whether it expired - ExceptionUtil.isFalse(record.getIsExpired(), INVITE_EXPIRE); - String inviteSpaceId = record.getInviteSpaceId(); - SpaceEntity spaceEntity = iSpaceService.isSpaceAvailable(inviteSpaceId); - String inviteSpaceName = spaceEntity.getName(); - String inviteEmail = record.getInviteEmail(); - MemberEntity member = iMemberService.getByIdIgnoreDelete(record.getInviteMemberId()); - InviteInfoVo inviteInfoVo = new InviteInfoVo(); - inviteInfoVo.setSpaceId(inviteSpaceId); - inviteInfoVo.setSpaceName(inviteSpaceName); - inviteInfoVo.setInviter(member.getMemberName()); - inviteInfoVo.setInviteEmail(inviteEmail); - // Whether the binding is bound to the mailbox - boolean inviteBindUser = this.checkInviteBindUser(inviteEmail); - inviteInfoVo.setIsBound(inviteBindUser); - boolean isLogin = this.checkUserInSession(); - inviteInfoVo.setIsLogin(isLogin); - // get the link creator's personal invitation code - String inviteCode = userServiceFacade.getUserInvitationCode(member.getUserId()).getCode(); - inviteInfoVo.setInviteCode(inviteCode); - return inviteInfoVo; - } - - /** - * Check if a session exists for the current request. - * - * @return true | false - */ - private boolean checkUserInSession() { - return HttpContextUtil.getSession(false) != null; - } - - /** - * Check if the mailbox is bound to another user. - * - * @param inviteEmail invitation email - * @return true | false - */ - private boolean checkInviteBindUser(String inviteEmail) { - UserEntity inviteUser = iUserService.getByEmail(inviteEmail); - return inviteUser != null; - } -} diff --git a/backend-server/application/src/main/java/com/apitable/base/service/impl/RestTemplateServiceImpl.java b/backend-server/application/src/main/java/com/apitable/base/service/impl/RestTemplateServiceImpl.java index 78fad6455d..e5a187188b 100644 --- a/backend-server/application/src/main/java/com/apitable/base/service/impl/RestTemplateServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/base/service/impl/RestTemplateServiceImpl.java @@ -30,10 +30,9 @@ import java.util.Collections; import java.util.List; import lombok.extern.slf4j.Slf4j; -import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.stereotype.Service; -import org.springframework.web.client.RestTemplate; +import org.springframework.web.client.RestClient; /** * RestTemplate service implementation class. @@ -43,7 +42,7 @@ public class RestTemplateServiceImpl implements RestTemplateService { @Resource - private RestTemplate restTemplate; + private RestClient restClient; @Resource private SocketProperties socketProperties; @@ -54,8 +53,12 @@ public void disableNodeShareNotify(List message) { HttpHeaders headers = new HttpHeaders(); headers.put("token", Collections.singletonList(socketProperties.getToken())); String url = socketProperties.getDomain() + socketProperties.getDisableNodeShareNotify(); - HttpEntity request = new HttpEntity<>(message, headers); - String result = restTemplate.postForObject(url, request, String.class); + String result = restClient.post() + .uri(url) + .headers(header -> header.addAll(headers)) + .body(message) + .retrieve() + .body(String.class); Integer code = JSONUtil.parseObj(result).getInt("code"); if (!code.equals(DEFAULT_SUCCESS_CODE)) { throw new BusinessException("Failed to close the node share notification call!Msg: " @@ -70,8 +73,12 @@ public void fieldPermissionChangeNotify(FieldPermissionChangeNotifyRo message) { headers.put("token", Collections.singletonList(socketProperties.getToken())); String url = socketProperties.getDomain() + socketProperties.getFieldPermissionChangeNotify(); - HttpEntity request = new HttpEntity<>(message, headers); - String result = restTemplate.postForObject(url, request, String.class); + String result = restClient.post() + .uri(url) + .headers(header -> header.addAll(headers)) + .body(message) + .retrieve() + .body(String.class); Integer code = JSONUtil.parseObj(result).getInt("code"); if (!code.equals(DEFAULT_SUCCESS_CODE)) { throw new BusinessException("Field permission change notification call failed!Msg: " diff --git a/backend-server/application/src/main/java/com/apitable/client/task/ClientTasks.java b/backend-server/application/src/main/java/com/apitable/client/task/ClientTasks.java index 0e51c2a128..ba4624edaf 100644 --- a/backend-server/application/src/main/java/com/apitable/client/task/ClientTasks.java +++ b/backend-server/application/src/main/java/com/apitable/client/task/ClientTasks.java @@ -30,10 +30,9 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Configuration; -import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.web.client.RestTemplate; +import org.springframework.web.client.RestClient; /** * Client task class. @@ -44,7 +43,7 @@ public class ClientTasks { @Resource - private RestTemplate restTemplate; + private RestClient restClient; @Resource private ConstProperties constProperties; @@ -68,8 +67,12 @@ public void heartbeat() { message.put("serverDomain", constProperties.getServerDomain()); } message.put("locale", constProperties.getLanguageTag()); - HttpEntity request = new HttpEntity<>(message, headers); - restTemplate.postForObject(heartbeatUrl, request, String.class); + restClient.post() + .uri(heartbeatUrl) + .headers(header -> header.addAll(headers)) + .body(message) + .retrieve() + .body(String.class); } } diff --git a/backend-server/application/src/main/java/com/apitable/control/infrastructure/ControlTemplate.java b/backend-server/application/src/main/java/com/apitable/control/infrastructure/ControlTemplate.java index aad920df3f..0d93155118 100644 --- a/backend-server/application/src/main/java/com/apitable/control/infrastructure/ControlTemplate.java +++ b/backend-server/application/src/main/java/com/apitable/control/infrastructure/ControlTemplate.java @@ -259,6 +259,10 @@ protected ControlRoleDict doExecute(Principal principal, ControlId controlId, List unitIds = iUnitService.getUnitIdsByRefIds(CollUtil.newArrayList(principal.getPrincipal())); return doExecute(unitIds, controlId, requestWrapper); + } else if (principal.getPrincipalType() == PrincipalType.TAG_ID) { + List unitIds = + iUnitService.getUnitIdsByRefIds(CollUtil.newArrayList(principal.getPrincipal())); + return doExecute(unitIds, controlId, requestWrapper); } else { throw new UnknownPrincipalTypeException(principal.getPrincipalType()); } diff --git a/backend-server/application/src/main/java/com/apitable/control/infrastructure/PrincipalType.java b/backend-server/application/src/main/java/com/apitable/control/infrastructure/PrincipalType.java index dd53117763..d5c08cdf7e 100644 --- a/backend-server/application/src/main/java/com/apitable/control/infrastructure/PrincipalType.java +++ b/backend-server/application/src/main/java/com/apitable/control/infrastructure/PrincipalType.java @@ -28,7 +28,8 @@ public enum PrincipalType { UNIT_ID(0), MEMBER_ID(1), TEAM_ID(2), - ROLE_ID(3); + ROLE_ID(3), + TAG_ID(4); private final int val; diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/ApiCallback.java b/backend-server/application/src/main/java/com/apitable/databusclient/ApiCallback.java deleted file mode 100644 index ee74acac58..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/ApiCallback.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient; - -import java.io.IOException; - -import java.util.Map; -import java.util.List; - -/** - * Callback for asynchronous API call. - * - * @param The return type - */ -public interface ApiCallback { - /** - * This is called when the API call fails. - * - * @param e The exception causing the failure - * @param statusCode Status code of the response if available, otherwise it would be 0 - * @param responseHeaders Headers of the response if available, otherwise it would be null - */ - void onFailure(ApiException e, int statusCode, Map> responseHeaders); - - /** - * This is called when the API call succeeded. - * - * @param result The result deserialized from response - * @param statusCode Status code of the response - * @param responseHeaders Headers of the response - */ - void onSuccess(T result, int statusCode, Map> responseHeaders); - - /** - * This is called when the API upload processing. - * - * @param bytesWritten bytes Written - * @param contentLength content length of request body - * @param done write end - */ - void onUploadProgress(long bytesWritten, long contentLength, boolean done); - - /** - * This is called when the API download processing. - * - * @param bytesRead bytes Read - * @param contentLength content length of the response - * @param done Read end - */ - void onDownloadProgress(long bytesRead, long contentLength, boolean done); -} diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/ApiClient.java b/backend-server/application/src/main/java/com/apitable/databusclient/ApiClient.java deleted file mode 100644 index 11c093b4b0..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/ApiClient.java +++ /dev/null @@ -1,1550 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient; - -import okhttp3.*; -import okhttp3.internal.http.HttpMethod; -import okhttp3.internal.tls.OkHostnameVerifier; -import okhttp3.logging.HttpLoggingInterceptor; -import okhttp3.logging.HttpLoggingInterceptor.Level; -import okio.Buffer; -import okio.BufferedSink; -import okio.Okio; - -import javax.net.ssl.*; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; -import java.lang.reflect.Type; -import java.net.URI; -import java.net.URLConnection; -import java.net.URLEncoder; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.security.GeneralSecurityException; -import java.security.KeyStore; -import java.security.SecureRandom; -import java.security.cert.Certificate; -import java.security.cert.CertificateException; -import java.security.cert.CertificateFactory; -import java.security.cert.X509Certificate; -import java.text.DateFormat; -import java.time.LocalDate; -import java.time.OffsetDateTime; -import java.time.format.DateTimeFormatter; -import java.util.*; -import java.util.Map.Entry; -import java.util.concurrent.TimeUnit; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import com.apitable.databusclient.auth.Authentication; -import com.apitable.databusclient.auth.HttpBasicAuth; -import com.apitable.databusclient.auth.HttpBearerAuth; -import com.apitable.databusclient.auth.ApiKeyAuth; - -/** - *

ApiClient class.

- */ -public class ApiClient { - - private String basePath = "http://localhost"; - protected List servers = new ArrayList(Arrays.asList( - new ServerConfiguration( - "", - "No description provided", - new HashMap() - ) - )); - protected Integer serverIndex = 0; - protected Map serverVariables = null; - private boolean debugging = false; - private Map defaultHeaderMap = new HashMap(); - private Map defaultCookieMap = new HashMap(); - private String tempFolderPath = null; - - private Map authentications; - - private DateFormat dateFormat; - private DateFormat datetimeFormat; - private boolean lenientDatetimeFormat; - private int dateLength; - - private InputStream sslCaCert; - private boolean verifyingSsl; - private KeyManager[] keyManagers; - - private OkHttpClient httpClient; - private JSON json; - - private HttpLoggingInterceptor loggingInterceptor; - - /** - * Basic constructor for ApiClient - */ - public ApiClient() { - init(); - initHttpClient(); - - // Setup authentications (key: authentication name, value: authentication). - // Prevent the authentications from being modified. - authentications = Collections.unmodifiableMap(authentications); - } - - /** - * Basic constructor with custom OkHttpClient - * - * @param client a {@link okhttp3.OkHttpClient} object - */ - public ApiClient(OkHttpClient client) { - init(); - - httpClient = client; - - // Setup authentications (key: authentication name, value: authentication). - // Prevent the authentications from being modified. - authentications = Collections.unmodifiableMap(authentications); - } - - private void initHttpClient() { - initHttpClient(Collections.emptyList()); - } - - private void initHttpClient(List interceptors) { - OkHttpClient.Builder builder = new OkHttpClient.Builder(); - builder.addNetworkInterceptor(getProgressInterceptor()); - for (Interceptor interceptor: interceptors) { - builder.addInterceptor(interceptor); - } - - httpClient = builder.build(); - } - - private void init() { - verifyingSsl = true; - - json = new JSON(); - - // Set default User-Agent. - setUserAgent("OpenAPI-Generator/1.2.0/java"); - - authentications = new HashMap(); - } - - /** - * Get base path - * - * @return Base path - */ - public String getBasePath() { - return basePath; - } - - /** - * Set base path - * - * @param basePath Base path of the URL (e.g http://localhost - * @return An instance of OkHttpClient - */ - public ApiClient setBasePath(String basePath) { - this.basePath = basePath; - this.serverIndex = null; - return this; - } - - public List getServers() { - return servers; - } - - public ApiClient setServers(List servers) { - this.servers = servers; - return this; - } - - public Integer getServerIndex() { - return serverIndex; - } - - public ApiClient setServerIndex(Integer serverIndex) { - this.serverIndex = serverIndex; - return this; - } - - public Map getServerVariables() { - return serverVariables; - } - - public ApiClient setServerVariables(Map serverVariables) { - this.serverVariables = serverVariables; - return this; - } - - /** - * Get HTTP client - * - * @return An instance of OkHttpClient - */ - public OkHttpClient getHttpClient() { - return httpClient; - } - - /** - * Set HTTP client, which must never be null. - * - * @param newHttpClient An instance of OkHttpClient - * @return Api Client - * @throws java.lang.NullPointerException when newHttpClient is null - */ - public ApiClient setHttpClient(OkHttpClient newHttpClient) { - this.httpClient = Objects.requireNonNull(newHttpClient, "HttpClient must not be null!"); - return this; - } - - /** - * Get JSON - * - * @return JSON object - */ - public JSON getJSON() { - return json; - } - - /** - * Set JSON - * - * @param json JSON object - * @return Api client - */ - public ApiClient setJSON(JSON json) { - this.json = json; - return this; - } - - /** - * True if isVerifyingSsl flag is on - * - * @return True if isVerifySsl flag is on - */ - public boolean isVerifyingSsl() { - return verifyingSsl; - } - - /** - * Configure whether to verify certificate and hostname when making https requests. - * Default to true. - * NOTE: Do NOT set to false in production code, otherwise you would face multiple types of cryptographic attacks. - * - * @param verifyingSsl True to verify TLS/SSL connection - * @return ApiClient - */ - public ApiClient setVerifyingSsl(boolean verifyingSsl) { - this.verifyingSsl = verifyingSsl; - applySslSettings(); - return this; - } - - /** - * Get SSL CA cert. - * - * @return Input stream to the SSL CA cert - */ - public InputStream getSslCaCert() { - return sslCaCert; - } - - /** - * Configure the CA certificate to be trusted when making https requests. - * Use null to reset to default. - * - * @param sslCaCert input stream for SSL CA cert - * @return ApiClient - */ - public ApiClient setSslCaCert(InputStream sslCaCert) { - this.sslCaCert = sslCaCert; - applySslSettings(); - return this; - } - - /** - *

Getter for the field keyManagers.

- * - * @return an array of {@link javax.net.ssl.KeyManager} objects - */ - public KeyManager[] getKeyManagers() { - return keyManagers; - } - - /** - * Configure client keys to use for authorization in an SSL session. - * Use null to reset to default. - * - * @param managers The KeyManagers to use - * @return ApiClient - */ - public ApiClient setKeyManagers(KeyManager[] managers) { - this.keyManagers = managers; - applySslSettings(); - return this; - } - - /** - *

Getter for the field dateFormat.

- * - * @return a {@link java.text.DateFormat} object - */ - public DateFormat getDateFormat() { - return dateFormat; - } - - /** - *

Setter for the field dateFormat.

- * - * @param dateFormat a {@link java.text.DateFormat} object - * @return a {@link com.apitable.databusclient.ApiClient} object - */ - public ApiClient setDateFormat(DateFormat dateFormat) { - JSON.setDateFormat(dateFormat); - return this; - } - - /** - *

Set SqlDateFormat.

- * - * @param dateFormat a {@link java.text.DateFormat} object - * @return a {@link com.apitable.databusclient.ApiClient} object - */ - public ApiClient setSqlDateFormat(DateFormat dateFormat) { - JSON.setSqlDateFormat(dateFormat); - return this; - } - - /** - *

Set OffsetDateTimeFormat.

- * - * @param dateFormat a {@link java.time.format.DateTimeFormatter} object - * @return a {@link com.apitable.databusclient.ApiClient} object - */ - public ApiClient setOffsetDateTimeFormat(DateTimeFormatter dateFormat) { - JSON.setOffsetDateTimeFormat(dateFormat); - return this; - } - - /** - *

Set LocalDateFormat.

- * - * @param dateFormat a {@link java.time.format.DateTimeFormatter} object - * @return a {@link com.apitable.databusclient.ApiClient} object - */ - public ApiClient setLocalDateFormat(DateTimeFormatter dateFormat) { - JSON.setLocalDateFormat(dateFormat); - return this; - } - - /** - *

Set LenientOnJson.

- * - * @param lenientOnJson a boolean - * @return a {@link com.apitable.databusclient.ApiClient} object - */ - public ApiClient setLenientOnJson(boolean lenientOnJson) { - JSON.setLenientOnJson(lenientOnJson); - return this; - } - - /** - * Get authentications (key: authentication name, value: authentication). - * - * @return Map of authentication objects - */ - public Map getAuthentications() { - return authentications; - } - - /** - * Get authentication for the given name. - * - * @param authName The authentication name - * @return The authentication, null if not found - */ - public Authentication getAuthentication(String authName) { - return authentications.get(authName); - } - - - /** - * Helper method to set username for the first HTTP basic authentication. - * - * @param username Username - */ - public void setUsername(String username) { - for (Authentication auth : authentications.values()) { - if (auth instanceof HttpBasicAuth) { - ((HttpBasicAuth) auth).setUsername(username); - return; - } - } - throw new RuntimeException("No HTTP basic authentication configured!"); - } - - /** - * Helper method to set password for the first HTTP basic authentication. - * - * @param password Password - */ - public void setPassword(String password) { - for (Authentication auth : authentications.values()) { - if (auth instanceof HttpBasicAuth) { - ((HttpBasicAuth) auth).setPassword(password); - return; - } - } - throw new RuntimeException("No HTTP basic authentication configured!"); - } - - /** - * Helper method to set API key value for the first API key authentication. - * - * @param apiKey API key - */ - public void setApiKey(String apiKey) { - for (Authentication auth : authentications.values()) { - if (auth instanceof ApiKeyAuth) { - ((ApiKeyAuth) auth).setApiKey(apiKey); - return; - } - } - throw new RuntimeException("No API key authentication configured!"); - } - - /** - * Helper method to set API key prefix for the first API key authentication. - * - * @param apiKeyPrefix API key prefix - */ - public void setApiKeyPrefix(String apiKeyPrefix) { - for (Authentication auth : authentications.values()) { - if (auth instanceof ApiKeyAuth) { - ((ApiKeyAuth) auth).setApiKeyPrefix(apiKeyPrefix); - return; - } - } - throw new RuntimeException("No API key authentication configured!"); - } - - /** - * Helper method to set access token for the first OAuth2 authentication. - * - * @param accessToken Access token - */ - public void setAccessToken(String accessToken) { - throw new RuntimeException("No OAuth2 authentication configured!"); - } - - /** - * Helper method to set credentials for AWSV4 Signature - * - * @param accessKey Access Key - * @param secretKey Secret Key - * @param region Region - * @param service Service to access to - */ - public void setAWS4Configuration(String accessKey, String secretKey, String region, String service) { - throw new RuntimeException("No AWS4 authentication configured!"); - } - - /** - * Set the User-Agent header's value (by adding to the default header map). - * - * @param userAgent HTTP request's user agent - * @return ApiClient - */ - public ApiClient setUserAgent(String userAgent) { - addDefaultHeader("User-Agent", userAgent); - return this; - } - - /** - * Add a default header. - * - * @param key The header's key - * @param value The header's value - * @return ApiClient - */ - public ApiClient addDefaultHeader(String key, String value) { - defaultHeaderMap.put(key, value); - return this; - } - - /** - * Add a default cookie. - * - * @param key The cookie's key - * @param value The cookie's value - * @return ApiClient - */ - public ApiClient addDefaultCookie(String key, String value) { - defaultCookieMap.put(key, value); - return this; - } - - /** - * Check that whether debugging is enabled for this API client. - * - * @return True if debugging is enabled, false otherwise. - */ - public boolean isDebugging() { - return debugging; - } - - /** - * Enable/disable debugging for this API client. - * - * @param debugging To enable (true) or disable (false) debugging - * @return ApiClient - */ - public ApiClient setDebugging(boolean debugging) { - if (debugging != this.debugging) { - if (debugging) { - loggingInterceptor = new HttpLoggingInterceptor(); - loggingInterceptor.setLevel(Level.BODY); - httpClient = httpClient.newBuilder().addInterceptor(loggingInterceptor).build(); - } else { - final OkHttpClient.Builder builder = httpClient.newBuilder(); - builder.interceptors().remove(loggingInterceptor); - httpClient = builder.build(); - loggingInterceptor = null; - } - } - this.debugging = debugging; - return this; - } - - /** - * The path of temporary folder used to store downloaded files from endpoints - * with file response. The default value is null, i.e. using - * the system's default temporary folder. - * - * @see createTempFile - * @return Temporary folder path - */ - public String getTempFolderPath() { - return tempFolderPath; - } - - /** - * Set the temporary folder path (for downloading files) - * - * @param tempFolderPath Temporary folder path - * @return ApiClient - */ - public ApiClient setTempFolderPath(String tempFolderPath) { - this.tempFolderPath = tempFolderPath; - return this; - } - - /** - * Get connection timeout (in milliseconds). - * - * @return Timeout in milliseconds - */ - public int getConnectTimeout() { - return httpClient.connectTimeoutMillis(); - } - - /** - * Sets the connect timeout (in milliseconds). - * A value of 0 means no timeout, otherwise values must be between 1 and - * {@link java.lang.Integer#MAX_VALUE}. - * - * @param connectionTimeout connection timeout in milliseconds - * @return Api client - */ - public ApiClient setConnectTimeout(int connectionTimeout) { - httpClient = httpClient.newBuilder().connectTimeout(connectionTimeout, TimeUnit.MILLISECONDS).build(); - return this; - } - - /** - * Get read timeout (in milliseconds). - * - * @return Timeout in milliseconds - */ - public int getReadTimeout() { - return httpClient.readTimeoutMillis(); - } - - /** - * Sets the read timeout (in milliseconds). - * A value of 0 means no timeout, otherwise values must be between 1 and - * {@link java.lang.Integer#MAX_VALUE}. - * - * @param readTimeout read timeout in milliseconds - * @return Api client - */ - public ApiClient setReadTimeout(int readTimeout) { - httpClient = httpClient.newBuilder().readTimeout(readTimeout, TimeUnit.MILLISECONDS).build(); - return this; - } - - /** - * Get write timeout (in milliseconds). - * - * @return Timeout in milliseconds - */ - public int getWriteTimeout() { - return httpClient.writeTimeoutMillis(); - } - - /** - * Sets the write timeout (in milliseconds). - * A value of 0 means no timeout, otherwise values must be between 1 and - * {@link java.lang.Integer#MAX_VALUE}. - * - * @param writeTimeout connection timeout in milliseconds - * @return Api client - */ - public ApiClient setWriteTimeout(int writeTimeout) { - httpClient = httpClient.newBuilder().writeTimeout(writeTimeout, TimeUnit.MILLISECONDS).build(); - return this; - } - - - /** - * Format the given parameter object into string. - * - * @param param Parameter - * @return String representation of the parameter - */ - public String parameterToString(Object param) { - if (param == null) { - return ""; - } else if (param instanceof Date || param instanceof OffsetDateTime || param instanceof LocalDate) { - //Serialize to json string and remove the " enclosing characters - String jsonStr = JSON.serialize(param); - return jsonStr.substring(1, jsonStr.length() - 1); - } else if (param instanceof Collection) { - StringBuilder b = new StringBuilder(); - for (Object o : (Collection) param) { - if (b.length() > 0) { - b.append(","); - } - b.append(o); - } - return b.toString(); - } else { - return String.valueOf(param); - } - } - - /** - * Formats the specified query parameter to a list containing a single {@code Pair} object. - * - * Note that {@code value} must not be a collection. - * - * @param name The name of the parameter. - * @param value The value of the parameter. - * @return A list containing a single {@code Pair} object. - */ - public List parameterToPair(String name, Object value) { - List params = new ArrayList(); - - // preconditions - if (name == null || name.isEmpty() || value == null || value instanceof Collection) { - return params; - } - - params.add(new Pair(name, parameterToString(value))); - return params; - } - - /** - * Formats the specified collection query parameters to a list of {@code Pair} objects. - * - * Note that the values of each of the returned Pair objects are percent-encoded. - * - * @param collectionFormat The collection format of the parameter. - * @param name The name of the parameter. - * @param value The value of the parameter. - * @return A list of {@code Pair} objects. - */ - public List parameterToPairs(String collectionFormat, String name, Collection value) { - List params = new ArrayList(); - - // preconditions - if (name == null || name.isEmpty() || value == null || value.isEmpty()) { - return params; - } - - // create the params based on the collection format - if ("multi".equals(collectionFormat)) { - for (Object item : value) { - params.add(new Pair(name, escapeString(parameterToString(item)))); - } - return params; - } - - // collectionFormat is assumed to be "csv" by default - String delimiter = ","; - - // escape all delimiters except commas, which are URI reserved - // characters - if ("ssv".equals(collectionFormat)) { - delimiter = escapeString(" "); - } else if ("tsv".equals(collectionFormat)) { - delimiter = escapeString("\t"); - } else if ("pipes".equals(collectionFormat)) { - delimiter = escapeString("|"); - } - - StringBuilder sb = new StringBuilder(); - for (Object item : value) { - sb.append(delimiter); - sb.append(escapeString(parameterToString(item))); - } - - params.add(new Pair(name, sb.substring(delimiter.length()))); - - return params; - } - - /** - * Formats the specified collection path parameter to a string value. - * - * @param collectionFormat The collection format of the parameter. - * @param value The value of the parameter. - * @return String representation of the parameter - */ - public String collectionPathParameterToString(String collectionFormat, Collection value) { - // create the value based on the collection format - if ("multi".equals(collectionFormat)) { - // not valid for path params - return parameterToString(value); - } - - // collectionFormat is assumed to be "csv" by default - String delimiter = ","; - - if ("ssv".equals(collectionFormat)) { - delimiter = " "; - } else if ("tsv".equals(collectionFormat)) { - delimiter = "\t"; - } else if ("pipes".equals(collectionFormat)) { - delimiter = "|"; - } - - StringBuilder sb = new StringBuilder() ; - for (Object item : value) { - sb.append(delimiter); - sb.append(parameterToString(item)); - } - - return sb.substring(delimiter.length()); - } - - /** - * Sanitize filename by removing path. - * e.g. ../../sun.gif becomes sun.gif - * - * @param filename The filename to be sanitized - * @return The sanitized filename - */ - public String sanitizeFilename(String filename) { - return filename.replaceAll(".*[/\\\\]", ""); - } - - /** - * Check if the given MIME is a JSON MIME. - * JSON MIME examples: - * application/json - * application/json; charset=UTF8 - * APPLICATION/JSON - * application/vnd.company+json - * "* / *" is also default to JSON - * @param mime MIME (Multipurpose Internet Mail Extensions) - * @return True if the given MIME is JSON, false otherwise. - */ - public boolean isJsonMime(String mime) { - String jsonMime = "(?i)^(application/json|[^;/ \t]+/[^;/ \t]+[+]json)[ \t]*(;.*)?$"; - return mime != null && (mime.matches(jsonMime) || mime.equals("*/*")); - } - - /** - * Select the Accept header's value from the given accepts array: - * if JSON exists in the given array, use it; - * otherwise use all of them (joining into a string) - * - * @param accepts The accepts array to select from - * @return The Accept header to use. If the given array is empty, - * null will be returned (not to set the Accept header explicitly). - */ - public String selectHeaderAccept(String[] accepts) { - if (accepts.length == 0) { - return null; - } - for (String accept : accepts) { - if (isJsonMime(accept)) { - return accept; - } - } - return StringUtil.join(accepts, ","); - } - - /** - * Select the Content-Type header's value from the given array: - * if JSON exists in the given array, use it; - * otherwise use the first one of the array. - * - * @param contentTypes The Content-Type array to select from - * @return The Content-Type header to use. If the given array is empty, - * returns null. If it matches "any", JSON will be used. - */ - public String selectHeaderContentType(String[] contentTypes) { - if (contentTypes.length == 0) { - return null; - } - - if (contentTypes[0].equals("*/*")) { - return "application/json"; - } - - for (String contentType : contentTypes) { - if (isJsonMime(contentType)) { - return contentType; - } - } - - return contentTypes[0]; - } - - /** - * Escape the given string to be used as URL query value. - * - * @param str String to be escaped - * @return Escaped string - */ - public String escapeString(String str) { - try { - return URLEncoder.encode(str, "utf8").replaceAll("\\+", "%20"); - } catch (UnsupportedEncodingException e) { - return str; - } - } - - /** - * Deserialize response body to Java object, according to the return type and - * the Content-Type response header. - * - * @param Type - * @param response HTTP response - * @param returnType The type of the Java object - * @return The deserialized Java object - * @throws com.apitable.databusclient.ApiException If fail to deserialize response body, i.e. cannot read response body - * or the Content-Type of the response is not supported. - */ - @SuppressWarnings("unchecked") - public T deserialize(Response response, Type returnType) throws ApiException { - if (response == null || returnType == null) { - return null; - } - - if ("byte[]".equals(returnType.toString())) { - // Handle binary response (byte array). - try { - return (T) response.body().bytes(); - } catch (IOException e) { - throw new ApiException(e); - } - } else if (returnType.equals(File.class)) { - // Handle file downloading. - return (T) downloadFileFromResponse(response); - } - - String respBody; - try { - if (response.body() != null) - respBody = response.body().string(); - else - respBody = null; - } catch (IOException e) { - throw new ApiException(e); - } - - if (respBody == null || "".equals(respBody)) { - return null; - } - - String contentType = response.headers().get("Content-Type"); - if (contentType == null) { - // ensuring a default content type - contentType = "application/json"; - } - if (isJsonMime(contentType)) { - return JSON.deserialize(respBody, returnType); - } else if (returnType.equals(String.class)) { - // Expecting string, return the raw response body. - return (T) respBody; - } else { - throw new ApiException( - "Content type \"" + contentType + "\" is not supported for type: " + returnType, - response.code(), - response.headers().toMultimap(), - respBody); - } - } - - /** - * Serialize the given Java object into request body according to the object's - * class and the request Content-Type. - * - * @param obj The Java object - * @param contentType The request Content-Type - * @return The serialized request body - * @throws com.apitable.databusclient.ApiException If fail to serialize the given object - */ - public RequestBody serialize(Object obj, String contentType) throws ApiException { - if (obj instanceof byte[]) { - // Binary (byte array) body parameter support. - return RequestBody.create((byte[]) obj, MediaType.parse(contentType)); - } else if (obj instanceof File) { - // File body parameter support. - return RequestBody.create((File) obj, MediaType.parse(contentType)); - } else if ("text/plain".equals(contentType) && obj instanceof String) { - return RequestBody.create((String) obj, MediaType.parse(contentType)); - } else if (isJsonMime(contentType)) { - String content; - if (obj != null) { - content = JSON.serialize(obj); - } else { - content = null; - } - return RequestBody.create(content, MediaType.parse(contentType)); - } else if (obj instanceof String) { - return RequestBody.create((String) obj, MediaType.parse(contentType)); - } else { - throw new ApiException("Content type \"" + contentType + "\" is not supported"); - } - } - - /** - * Download file from the given response. - * - * @param response An instance of the Response object - * @throws com.apitable.databusclient.ApiException If fail to read file content from response and write to disk - * @return Downloaded file - */ - public File downloadFileFromResponse(Response response) throws ApiException { - try { - File file = prepareDownloadFile(response); - BufferedSink sink = Okio.buffer(Okio.sink(file)); - sink.writeAll(response.body().source()); - sink.close(); - return file; - } catch (IOException e) { - throw new ApiException(e); - } - } - - /** - * Prepare file for download - * - * @param response An instance of the Response object - * @return Prepared file for the download - * @throws java.io.IOException If fail to prepare file for download - */ - public File prepareDownloadFile(Response response) throws IOException { - String filename = null; - String contentDisposition = response.header("Content-Disposition"); - if (contentDisposition != null && !"".equals(contentDisposition)) { - // Get filename from the Content-Disposition header. - Pattern pattern = Pattern.compile("filename=['\"]?([^'\"\\s]+)['\"]?"); - Matcher matcher = pattern.matcher(contentDisposition); - if (matcher.find()) { - filename = sanitizeFilename(matcher.group(1)); - } - } - - String prefix = null; - String suffix = null; - if (filename == null) { - prefix = "download-"; - suffix = ""; - } else { - int pos = filename.lastIndexOf("."); - if (pos == -1) { - prefix = filename + "-"; - } else { - prefix = filename.substring(0, pos) + "-"; - suffix = filename.substring(pos); - } - // Files.createTempFile requires the prefix to be at least three characters long - if (prefix.length() < 3) - prefix = "download-"; - } - - if (tempFolderPath == null) - return Files.createTempFile(prefix, suffix).toFile(); - else - return Files.createTempFile(Paths.get(tempFolderPath), prefix, suffix).toFile(); - } - - /** - * {@link #execute(Call, Type)} - * - * @param Type - * @param call An instance of the Call object - * @return ApiResponse<T> - * @throws com.apitable.databusclient.ApiException If fail to execute the call - */ - public ApiResponse execute(Call call) throws ApiException { - return execute(call, null); - } - - /** - * Execute HTTP call and deserialize the HTTP response body into the given return type. - * - * @param returnType The return type used to deserialize HTTP response body - * @param The return type corresponding to (same with) returnType - * @param call Call - * @return ApiResponse object containing response status, headers and - * data, which is a Java object deserialized from response body and would be null - * when returnType is null. - * @throws com.apitable.databusclient.ApiException If fail to execute the call - */ - public ApiResponse execute(Call call, Type returnType) throws ApiException { - try { - Response response = call.execute(); - T data = handleResponse(response, returnType); - return new ApiResponse(response.code(), response.headers().toMultimap(), data); - } catch (IOException e) { - throw new ApiException(e); - } - } - - /** - * {@link #executeAsync(Call, Type, ApiCallback)} - * - * @param Type - * @param call An instance of the Call object - * @param callback ApiCallback<T> - */ - public void executeAsync(Call call, ApiCallback callback) { - executeAsync(call, null, callback); - } - - /** - * Execute HTTP call asynchronously. - * - * @param Type - * @param call The callback to be executed when the API call finishes - * @param returnType Return type - * @param callback ApiCallback - * @see #execute(Call, Type) - */ - @SuppressWarnings("unchecked") - public void executeAsync(Call call, final Type returnType, final ApiCallback callback) { - call.enqueue(new Callback() { - @Override - public void onFailure(Call call, IOException e) { - callback.onFailure(new ApiException(e), 0, null); - } - - @Override - public void onResponse(Call call, Response response) throws IOException { - T result; - try { - result = (T) handleResponse(response, returnType); - } catch (ApiException e) { - callback.onFailure(e, response.code(), response.headers().toMultimap()); - return; - } catch (Exception e) { - callback.onFailure(new ApiException(e), response.code(), response.headers().toMultimap()); - return; - } - callback.onSuccess(result, response.code(), response.headers().toMultimap()); - } - }); - } - - /** - * Handle the given response, return the deserialized object when the response is successful. - * - * @param Type - * @param response Response - * @param returnType Return type - * @return Type - * @throws com.apitable.databusclient.ApiException If the response has an unsuccessful status code or - * fail to deserialize the response body - */ - public T handleResponse(Response response, Type returnType) throws ApiException { - if (response.isSuccessful()) { - if (returnType == null || response.code() == 204) { - // returning null if the returnType is not defined, - // or the status code is 204 (No Content) - if (response.body() != null) { - try { - response.body().close(); - } catch (Exception e) { - throw new ApiException(response.message(), e, response.code(), response.headers().toMultimap()); - } - } - return null; - } else { - return deserialize(response, returnType); - } - } else { - String respBody = null; - if (response.body() != null) { - try { - respBody = response.body().string(); - } catch (IOException e) { - throw new ApiException(response.message(), e, response.code(), response.headers().toMultimap()); - } - } - throw new ApiException(response.message(), response.code(), response.headers().toMultimap(), respBody); - } - } - - /** - * Build HTTP call with the given options. - * - * @param baseUrl The base URL - * @param path The sub-path of the HTTP URL - * @param method The request method, one of "GET", "HEAD", "OPTIONS", "POST", "PUT", "PATCH" and "DELETE" - * @param queryParams The query parameters - * @param collectionQueryParams The collection query parameters - * @param body The request body object - * @param headerParams The header parameters - * @param cookieParams The cookie parameters - * @param formParams The form parameters - * @param authNames The authentications to apply - * @param callback Callback for upload/download progress - * @return The HTTP call - * @throws com.apitable.databusclient.ApiException If fail to serialize the request body object - */ - public Call buildCall(String baseUrl, String path, String method, List queryParams, List collectionQueryParams, Object body, Map headerParams, Map cookieParams, Map formParams, String[] authNames, ApiCallback callback) throws ApiException { - Request request = buildRequest(baseUrl, path, method, queryParams, collectionQueryParams, body, headerParams, cookieParams, formParams, authNames, callback); - - return httpClient.newCall(request); - } - - /** - * Build an HTTP request with the given options. - * - * @param baseUrl The base URL - * @param path The sub-path of the HTTP URL - * @param method The request method, one of "GET", "HEAD", "OPTIONS", "POST", "PUT", "PATCH" and "DELETE" - * @param queryParams The query parameters - * @param collectionQueryParams The collection query parameters - * @param body The request body object - * @param headerParams The header parameters - * @param cookieParams The cookie parameters - * @param formParams The form parameters - * @param authNames The authentications to apply - * @param callback Callback for upload/download progress - * @return The HTTP request - * @throws com.apitable.databusclient.ApiException If fail to serialize the request body object - */ - public Request buildRequest(String baseUrl, String path, String method, List queryParams, List collectionQueryParams, Object body, Map headerParams, Map cookieParams, Map formParams, String[] authNames, ApiCallback callback) throws ApiException { - // aggregate queryParams (non-collection) and collectionQueryParams into allQueryParams - List allQueryParams = new ArrayList(queryParams); - allQueryParams.addAll(collectionQueryParams); - - final String url = buildUrl(baseUrl, path, queryParams, collectionQueryParams); - - // prepare HTTP request body - RequestBody reqBody; - String contentType = headerParams.get("Content-Type"); - String contentTypePure = contentType; - if (contentTypePure != null && contentTypePure.contains(";")) { - contentTypePure = contentType.substring(0, contentType.indexOf(";")); - } - if (!HttpMethod.permitsRequestBody(method)) { - reqBody = null; - } else if ("application/x-www-form-urlencoded".equals(contentTypePure)) { - reqBody = buildRequestBodyFormEncoding(formParams); - } else if ("multipart/form-data".equals(contentTypePure)) { - reqBody = buildRequestBodyMultipart(formParams); - } else if (body == null) { - if ("DELETE".equals(method)) { - // allow calling DELETE without sending a request body - reqBody = null; - } else { - // use an empty request body (for POST, PUT and PATCH) - reqBody = RequestBody.create("", contentType == null ? null : MediaType.parse(contentType)); - } - } else { - reqBody = serialize(body, contentType); - } - - // update parameters with authentication settings - updateParamsForAuth(authNames, allQueryParams, headerParams, cookieParams, requestBodyToString(reqBody), method, URI.create(url)); - - final Request.Builder reqBuilder = new Request.Builder().url(url); - processHeaderParams(headerParams, reqBuilder); - processCookieParams(cookieParams, reqBuilder); - - // Associate callback with request (if not null) so interceptor can - // access it when creating ProgressResponseBody - reqBuilder.tag(callback); - - Request request = null; - - if (callback != null && reqBody != null) { - ProgressRequestBody progressRequestBody = new ProgressRequestBody(reqBody, callback); - request = reqBuilder.method(method, progressRequestBody).build(); - } else { - request = reqBuilder.method(method, reqBody).build(); - } - - return request; - } - - /** - * Build full URL by concatenating base path, the given sub path and query parameters. - * - * @param baseUrl The base URL - * @param path The sub path - * @param queryParams The query parameters - * @param collectionQueryParams The collection query parameters - * @return The full URL - */ - public String buildUrl(String baseUrl, String path, List queryParams, List collectionQueryParams) { - final StringBuilder url = new StringBuilder(); - if (baseUrl != null) { - url.append(baseUrl).append(path); - } else { - String baseURL; - if (serverIndex != null) { - if (serverIndex < 0 || serverIndex >= servers.size()) { - throw new ArrayIndexOutOfBoundsException(String.format( - "Invalid index %d when selecting the host settings. Must be less than %d", serverIndex, servers.size() - )); - } - baseURL = servers.get(serverIndex).URL(serverVariables); - } else { - baseURL = basePath; - } - url.append(baseURL).append(path); - } - - if (queryParams != null && !queryParams.isEmpty()) { - // support (constant) query string in `path`, e.g. "/posts?draft=1" - String prefix = path.contains("?") ? "&" : "?"; - for (Pair param : queryParams) { - if (param.getValue() != null) { - if (prefix != null) { - url.append(prefix); - prefix = null; - } else { - url.append("&"); - } - String value = parameterToString(param.getValue()); - url.append(escapeString(param.getName())).append("=").append(escapeString(value)); - } - } - } - - if (collectionQueryParams != null && !collectionQueryParams.isEmpty()) { - String prefix = url.toString().contains("?") ? "&" : "?"; - for (Pair param : collectionQueryParams) { - if (param.getValue() != null) { - if (prefix != null) { - url.append(prefix); - prefix = null; - } else { - url.append("&"); - } - String value = parameterToString(param.getValue()); - // collection query parameter value already escaped as part of parameterToPairs - url.append(escapeString(param.getName())).append("=").append(value); - } - } - } - - return url.toString(); - } - - /** - * Set header parameters to the request builder, including default headers. - * - * @param headerParams Header parameters in the form of Map - * @param reqBuilder Request.Builder - */ - public void processHeaderParams(Map headerParams, Request.Builder reqBuilder) { - for (Entry param : headerParams.entrySet()) { - reqBuilder.header(param.getKey(), parameterToString(param.getValue())); - } - for (Entry header : defaultHeaderMap.entrySet()) { - if (!headerParams.containsKey(header.getKey())) { - reqBuilder.header(header.getKey(), parameterToString(header.getValue())); - } - } - } - - /** - * Set cookie parameters to the request builder, including default cookies. - * - * @param cookieParams Cookie parameters in the form of Map - * @param reqBuilder Request.Builder - */ - public void processCookieParams(Map cookieParams, Request.Builder reqBuilder) { - for (Entry param : cookieParams.entrySet()) { - reqBuilder.addHeader("Cookie", String.format("%s=%s", param.getKey(), param.getValue())); - } - for (Entry param : defaultCookieMap.entrySet()) { - if (!cookieParams.containsKey(param.getKey())) { - reqBuilder.addHeader("Cookie", String.format("%s=%s", param.getKey(), param.getValue())); - } - } - } - - /** - * Update query and header parameters based on authentication settings. - * - * @param authNames The authentications to apply - * @param queryParams List of query parameters - * @param headerParams Map of header parameters - * @param cookieParams Map of cookie parameters - * @param payload HTTP request body - * @param method HTTP method - * @param uri URI - * @throws com.apitable.databusclient.ApiException If fails to update the parameters - */ - public void updateParamsForAuth(String[] authNames, List queryParams, Map headerParams, - Map cookieParams, String payload, String method, URI uri) throws ApiException { - for (String authName : authNames) { - Authentication auth = authentications.get(authName); - if (auth == null) { - throw new RuntimeException("Authentication undefined: " + authName); - } - auth.applyToParams(queryParams, headerParams, cookieParams, payload, method, uri); - } - } - - /** - * Build a form-encoding request body with the given form parameters. - * - * @param formParams Form parameters in the form of Map - * @return RequestBody - */ - public RequestBody buildRequestBodyFormEncoding(Map formParams) { - okhttp3.FormBody.Builder formBuilder = new okhttp3.FormBody.Builder(); - for (Entry param : formParams.entrySet()) { - formBuilder.add(param.getKey(), parameterToString(param.getValue())); - } - return formBuilder.build(); - } - - /** - * Build a multipart (file uploading) request body with the given form parameters, - * which could contain text fields and file fields. - * - * @param formParams Form parameters in the form of Map - * @return RequestBody - */ - public RequestBody buildRequestBodyMultipart(Map formParams) { - MultipartBody.Builder mpBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM); - for (Entry param : formParams.entrySet()) { - if (param.getValue() instanceof File) { - File file = (File) param.getValue(); - addPartToMultiPartBuilder(mpBuilder, param.getKey(), file); - } else if (param.getValue() instanceof List) { - List list = (List) param.getValue(); - for (Object item: list) { - if (item instanceof File) { - addPartToMultiPartBuilder(mpBuilder, param.getKey(), (File) item); - } else { - addPartToMultiPartBuilder(mpBuilder, param.getKey(), param.getValue()); - } - } - } else { - addPartToMultiPartBuilder(mpBuilder, param.getKey(), param.getValue()); - } - } - return mpBuilder.build(); - } - - /** - * Guess Content-Type header from the given file (defaults to "application/octet-stream"). - * - * @param file The given file - * @return The guessed Content-Type - */ - public String guessContentTypeFromFile(File file) { - String contentType = URLConnection.guessContentTypeFromName(file.getName()); - if (contentType == null) { - return "application/octet-stream"; - } else { - return contentType; - } - } - - /** - * Add a Content-Disposition Header for the given key and file to the MultipartBody Builder. - * - * @param mpBuilder MultipartBody.Builder - * @param key The key of the Header element - * @param file The file to add to the Header - */ - private void addPartToMultiPartBuilder(MultipartBody.Builder mpBuilder, String key, File file) { - Headers partHeaders = Headers.of("Content-Disposition", "form-data; name=\"" + key + "\"; filename=\"" + file.getName() + "\""); - MediaType mediaType = MediaType.parse(guessContentTypeFromFile(file)); - mpBuilder.addPart(partHeaders, RequestBody.create(file, mediaType)); - } - - /** - * Add a Content-Disposition Header for the given key and complex object to the MultipartBody Builder. - * - * @param mpBuilder MultipartBody.Builder - * @param key The key of the Header element - * @param obj The complex object to add to the Header - */ - private void addPartToMultiPartBuilder(MultipartBody.Builder mpBuilder, String key, Object obj) { - RequestBody requestBody; - if (obj instanceof String) { - requestBody = RequestBody.create((String) obj, MediaType.parse("text/plain")); - } else { - String content; - if (obj != null) { - content = JSON.serialize(obj); - } else { - content = null; - } - requestBody = RequestBody.create(content, MediaType.parse("application/json")); - } - - Headers partHeaders = Headers.of("Content-Disposition", "form-data; name=\"" + key + "\""); - mpBuilder.addPart(partHeaders, requestBody); - } - - /** - * Get network interceptor to add it to the httpClient to track download progress for - * async requests. - */ - private Interceptor getProgressInterceptor() { - return new Interceptor() { - @Override - public Response intercept(Interceptor.Chain chain) throws IOException { - final Request request = chain.request(); - final Response originalResponse = chain.proceed(request); - if (request.tag() instanceof ApiCallback) { - final ApiCallback callback = (ApiCallback) request.tag(); - return originalResponse.newBuilder() - .body(new ProgressResponseBody(originalResponse.body(), callback)) - .build(); - } - return originalResponse; - } - }; - } - - /** - * Apply SSL related settings to httpClient according to the current values of - * verifyingSsl and sslCaCert. - */ - private void applySslSettings() { - try { - TrustManager[] trustManagers; - HostnameVerifier hostnameVerifier; - if (!verifyingSsl) { - trustManagers = new TrustManager[]{ - new X509TrustManager() { - @Override - public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { - } - - @Override - public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException { - } - - @Override - public java.security.cert.X509Certificate[] getAcceptedIssuers() { - return new java.security.cert.X509Certificate[]{}; - } - } - }; - hostnameVerifier = new HostnameVerifier() { - @Override - public boolean verify(String hostname, SSLSession session) { - return true; - } - }; - } else { - TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - - if (sslCaCert == null) { - trustManagerFactory.init((KeyStore) null); - } else { - char[] password = null; // Any password will work. - CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); - Collection certificates = certificateFactory.generateCertificates(sslCaCert); - if (certificates.isEmpty()) { - throw new IllegalArgumentException("expected non-empty set of trusted certificates"); - } - KeyStore caKeyStore = newEmptyKeyStore(password); - int index = 0; - for (Certificate certificate : certificates) { - String certificateAlias = "ca" + (index++); - caKeyStore.setCertificateEntry(certificateAlias, certificate); - } - trustManagerFactory.init(caKeyStore); - } - trustManagers = trustManagerFactory.getTrustManagers(); - hostnameVerifier = OkHostnameVerifier.INSTANCE; - } - - SSLContext sslContext = SSLContext.getInstance("TLS"); - sslContext.init(keyManagers, trustManagers, new SecureRandom()); - httpClient = httpClient.newBuilder() - .sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustManagers[0]) - .hostnameVerifier(hostnameVerifier) - .build(); - } catch (GeneralSecurityException e) { - throw new RuntimeException(e); - } - } - - private KeyStore newEmptyKeyStore(char[] password) throws GeneralSecurityException { - try { - KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); - keyStore.load(null, password); - return keyStore; - } catch (IOException e) { - throw new AssertionError(e); - } - } - - /** - * Convert the HTTP request body to a string. - * - * @param requestBody The HTTP request object - * @return The string representation of the HTTP request body - * @throws com.apitable.databusclient.ApiException If fail to serialize the request body object into a string - */ - private String requestBodyToString(RequestBody requestBody) throws ApiException { - if (requestBody != null) { - try { - final Buffer buffer = new Buffer(); - requestBody.writeTo(buffer); - return buffer.readUtf8(); - } catch (final IOException e) { - throw new ApiException(e); - } - } - - // empty http request body - return ""; - } -} diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/ApiException.java b/backend-server/application/src/main/java/com/apitable/databusclient/ApiException.java deleted file mode 100644 index bbdf984a58..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/ApiException.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient; - -import java.util.Map; -import java.util.List; - - -/** - *

ApiException class.

- */ -@SuppressWarnings("serial") -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class ApiException extends Exception { - private int code = 0; - private Map> responseHeaders = null; - private String responseBody = null; - - /** - *

Constructor for ApiException.

- */ - public ApiException() {} - - /** - *

Constructor for ApiException.

- * - * @param throwable a {@link java.lang.Throwable} object - */ - public ApiException(Throwable throwable) { - super(throwable); - } - - /** - *

Constructor for ApiException.

- * - * @param message the error message - */ - public ApiException(String message) { - super(message); - } - - /** - *

Constructor for ApiException.

- * - * @param message the error message - * @param throwable a {@link java.lang.Throwable} object - * @param code HTTP status code - * @param responseHeaders a {@link java.util.Map} of HTTP response headers - * @param responseBody the response body - */ - public ApiException(String message, Throwable throwable, int code, Map> responseHeaders, String responseBody) { - super(message, throwable); - this.code = code; - this.responseHeaders = responseHeaders; - this.responseBody = responseBody; - } - - /** - *

Constructor for ApiException.

- * - * @param message the error message - * @param code HTTP status code - * @param responseHeaders a {@link java.util.Map} of HTTP response headers - * @param responseBody the response body - */ - public ApiException(String message, int code, Map> responseHeaders, String responseBody) { - this(message, (Throwable) null, code, responseHeaders, responseBody); - } - - /** - *

Constructor for ApiException.

- * - * @param message the error message - * @param throwable a {@link java.lang.Throwable} object - * @param code HTTP status code - * @param responseHeaders a {@link java.util.Map} of HTTP response headers - */ - public ApiException(String message, Throwable throwable, int code, Map> responseHeaders) { - this(message, throwable, code, responseHeaders, null); - } - - /** - *

Constructor for ApiException.

- * - * @param code HTTP status code - * @param responseHeaders a {@link java.util.Map} of HTTP response headers - * @param responseBody the response body - */ - public ApiException(int code, Map> responseHeaders, String responseBody) { - this("Response Code: " + code + " Response Body: " + responseBody, (Throwable) null, code, responseHeaders, responseBody); - } - - /** - *

Constructor for ApiException.

- * - * @param code HTTP status code - * @param message a {@link java.lang.String} object - */ - public ApiException(int code, String message) { - super(message); - this.code = code; - } - - /** - *

Constructor for ApiException.

- * - * @param code HTTP status code - * @param message the error message - * @param responseHeaders a {@link java.util.Map} of HTTP response headers - * @param responseBody the response body - */ - public ApiException(int code, String message, Map> responseHeaders, String responseBody) { - this(code, message); - this.responseHeaders = responseHeaders; - this.responseBody = responseBody; - } - - /** - * Get the HTTP status code. - * - * @return HTTP status code - */ - public int getCode() { - return code; - } - - /** - * Get the HTTP response headers. - * - * @return A map of list of string - */ - public Map> getResponseHeaders() { - return responseHeaders; - } - - /** - * Get the HTTP response body. - * - * @return Response body in the form of string - */ - public String getResponseBody() { - return responseBody; - } - - /** - * Get the exception message including HTTP response data. - * - * @return The exception message - */ - public String getMessage() { - return String.format("Message: %s%nHTTP response code: %s%nHTTP response body: %s%nHTTP response headers: %s", - super.getMessage(), this.getCode(), this.getResponseBody(), this.getResponseHeaders()); - } -} diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/ApiResponse.java b/backend-server/application/src/main/java/com/apitable/databusclient/ApiResponse.java deleted file mode 100644 index 0cd1a34f5a..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/ApiResponse.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient; - -import java.util.List; -import java.util.Map; - -/** - * API response returned by API call. - */ -public class ApiResponse { - final private int statusCode; - final private Map> headers; - final private T data; - - /** - *

Constructor for ApiResponse.

- * - * @param statusCode The status code of HTTP response - * @param headers The headers of HTTP response - */ - public ApiResponse(int statusCode, Map> headers) { - this(statusCode, headers, null); - } - - /** - *

Constructor for ApiResponse.

- * - * @param statusCode The status code of HTTP response - * @param headers The headers of HTTP response - * @param data The object deserialized from response bod - */ - public ApiResponse(int statusCode, Map> headers, T data) { - this.statusCode = statusCode; - this.headers = headers; - this.data = data; - } - - /** - *

Get the status code.

- * - * @return the status code - */ - public int getStatusCode() { - return statusCode; - } - - /** - *

Get the headers.

- * - * @return a {@link java.util.Map} of headers - */ - public Map> getHeaders() { - return headers; - } - - /** - *

Get the data.

- * - * @return the data - */ - public T getData() { - return data; - } -} diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/Configuration.java b/backend-server/application/src/main/java/com/apitable/databusclient/Configuration.java deleted file mode 100644 index d38b9ea2c2..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/Configuration.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient; - -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class Configuration { - public static final String VERSION = "1.2.0"; - - private static ApiClient defaultApiClient = new ApiClient(); - - /** - * Get the default API client, which would be used when creating API - * instances without providing an API client. - * - * @return Default API client - */ - public static ApiClient getDefaultApiClient() { - return defaultApiClient; - } - - /** - * Set the default API client, which would be used when creating API - * instances without providing an API client. - * - * @param apiClient API client - */ - public static void setDefaultApiClient(ApiClient apiClient) { - defaultApiClient = apiClient; - } -} diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/GzipRequestInterceptor.java b/backend-server/application/src/main/java/com/apitable/databusclient/GzipRequestInterceptor.java deleted file mode 100644 index 5a83aa5992..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/GzipRequestInterceptor.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient; - -import okhttp3.*; -import okio.Buffer; -import okio.BufferedSink; -import okio.GzipSink; -import okio.Okio; - -import java.io.IOException; - -/** - * Encodes request bodies using gzip. - * - * Taken from https://github.com/square/okhttp/issues/350 - */ -class GzipRequestInterceptor implements Interceptor { - @Override - public Response intercept(Chain chain) throws IOException { - Request originalRequest = chain.request(); - if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) { - return chain.proceed(originalRequest); - } - - Request compressedRequest = originalRequest.newBuilder() - .header("Content-Encoding", "gzip") - .method(originalRequest.method(), forceContentLength(gzip(originalRequest.body()))) - .build(); - return chain.proceed(compressedRequest); - } - - private RequestBody forceContentLength(final RequestBody requestBody) throws IOException { - final Buffer buffer = new Buffer(); - requestBody.writeTo(buffer); - return new RequestBody() { - @Override - public MediaType contentType() { - return requestBody.contentType(); - } - - @Override - public long contentLength() { - return buffer.size(); - } - - @Override - public void writeTo(BufferedSink sink) throws IOException { - sink.write(buffer.snapshot()); - } - }; - } - - private RequestBody gzip(final RequestBody body) { - return new RequestBody() { - @Override - public MediaType contentType() { - return body.contentType(); - } - - @Override - public long contentLength() { - return -1; // We don't know the compressed length in advance! - } - - @Override - public void writeTo(BufferedSink sink) throws IOException { - BufferedSink gzipSink = Okio.buffer(new GzipSink(sink)); - body.writeTo(gzipSink); - gzipSink.close(); - } - }; - } -} diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/JSON.java b/backend-server/application/src/main/java/com/apitable/databusclient/JSON.java deleted file mode 100644 index 1d6824eaef..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/JSON.java +++ /dev/null @@ -1,470 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapter; -import com.google.gson.internal.bind.util.ISO8601Utils; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import com.google.gson.JsonElement; -import io.gsonfire.GsonFireBuilder; -import io.gsonfire.TypeSelector; - -import okio.ByteString; - -import java.io.IOException; -import java.io.StringReader; -import java.lang.reflect.Type; -import java.text.DateFormat; -import java.text.ParseException; -import java.text.ParsePosition; -import java.time.LocalDate; -import java.time.OffsetDateTime; -import java.time.format.DateTimeFormatter; -import java.util.Date; -import java.util.Locale; -import java.util.Map; -import java.util.HashMap; - -/* - * A JSON utility class - * - * NOTE: in the future, this class may be converted to static, which may break - * backward-compatibility - */ -public class JSON { - private static Gson gson; - private static boolean isLenientOnJson = false; - private static DateTypeAdapter dateTypeAdapter = new DateTypeAdapter(); - private static SqlDateTypeAdapter sqlDateTypeAdapter = new SqlDateTypeAdapter(); - private static OffsetDateTimeTypeAdapter offsetDateTimeTypeAdapter = new OffsetDateTimeTypeAdapter(); - private static LocalDateTypeAdapter localDateTypeAdapter = new LocalDateTypeAdapter(); - private static ByteArrayAdapter byteArrayAdapter = new ByteArrayAdapter(); - - @SuppressWarnings("unchecked") - public static GsonBuilder createGson() { - GsonFireBuilder fireBuilder = new GsonFireBuilder() - ; - GsonBuilder builder = fireBuilder.createGsonBuilder(); - return builder; - } - - private static String getDiscriminatorValue(JsonElement readElement, String discriminatorField) { - JsonElement element = readElement.getAsJsonObject().get(discriminatorField); - if (null == element) { - throw new IllegalArgumentException("missing discriminator field: <" + discriminatorField + ">"); - } - return element.getAsString(); - } - - /** - * Returns the Java class that implements the OpenAPI schema for the specified discriminator value. - * - * @param classByDiscriminatorValue The map of discriminator values to Java classes. - * @param discriminatorValue The value of the OpenAPI discriminator in the input data. - * @return The Java class that implements the OpenAPI schema - */ - private static Class getClassByDiscriminator(Map classByDiscriminatorValue, String discriminatorValue) { - Class clazz = (Class) classByDiscriminatorValue.get(discriminatorValue); - if (null == clazz) { - throw new IllegalArgumentException("cannot determine model class of name: <" + discriminatorValue + ">"); - } - return clazz; - } - - { - GsonBuilder gsonBuilder = createGson(); - gsonBuilder.registerTypeAdapter(Date.class, dateTypeAdapter); - gsonBuilder.registerTypeAdapter(java.sql.Date.class, sqlDateTypeAdapter); - gsonBuilder.registerTypeAdapter(OffsetDateTime.class, offsetDateTimeTypeAdapter); - gsonBuilder.registerTypeAdapter(LocalDate.class, localDateTypeAdapter); - gsonBuilder.registerTypeAdapter(byte[].class, byteArrayAdapter); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.AiNode.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.AiPO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.AlarmUser.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.AnyBaseField.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.ApiRecordDto.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.ApiResponseAiPO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.ApiResponseAutomationActionPO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.ApiResponseAutomationRobotIntroductionSO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.ApiResponseAutomationRunHistoryPO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.ApiResponseAutomationSO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.ApiResponseAutomationTriggerPO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.ApiResponseDatasheetPackSO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.ApiResponseEmptySO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.ApiResponseRecordVos.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.AutomationActionIntroductionPO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.AutomationActionPO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.AutomationHistoryRO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.AutomationHistoryStatusRO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.AutomationRobotActionRO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.AutomationRobotCopyRO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.AutomationRobotIntroductionPO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.AutomationRobotIntroductionSO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.AutomationRobotSO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.AutomationRobotTriggerRO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.AutomationRobotUpdateRO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.AutomationRunHistoryPO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.AutomationSO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.AutomationTriggerIntroductionPO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.AutomationTriggerPO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.BaseDatasheetPackSO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.ColorOption.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.CommentMsg.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.Comments.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.DatasheetMetaSO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.DatasheetPackSO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.DatasheetSnapshotSO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.DocumentOperationRO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.DocumentRO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.FieldExtraMapValue.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.FieldPropertySO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.FieldSO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.FieldUpdateRO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.FieldUpdatedValue.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.GanttColorOption.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.IFilterCondition.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.IFilterInfo.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.ISortInfo.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.ISortedField.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.IViewLockInfo.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.LinkedFields.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.ListVO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.LookUpFilterPO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.NodePermissionStateSO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.NodeSO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.NodeSimplePO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.RecordAlarm.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.RecordMeta.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.RecordSO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.RecordUpdateRO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.RecordVo.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.SingleSelectProperty.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.SingleTextFieldPropertySO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.SortRO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.UnitSO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.ViewColumnSO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.ViewRowSO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.ViewSO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.ViewStyleSo.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.WidgetInPanelSO.CustomTypeAdapterFactory()); - gsonBuilder.registerTypeAdapterFactory(new com.apitable.databusclient.model.WidgetPanelSO.CustomTypeAdapterFactory()); - gson = gsonBuilder.create(); - } - - /** - * Get Gson. - * - * @return Gson - */ - public static Gson getGson() { - return gson; - } - - /** - * Set Gson. - * - * @param gson Gson - */ - public static void setGson(Gson gson) { - JSON.gson = gson; - } - - public static void setLenientOnJson(boolean lenientOnJson) { - isLenientOnJson = lenientOnJson; - } - - /** - * Serialize the given Java object into JSON string. - * - * @param obj Object - * @return String representation of the JSON - */ - public static String serialize(Object obj) { - return gson.toJson(obj); - } - - /** - * Deserialize the given JSON string to Java object. - * - * @param Type - * @param body The JSON string - * @param returnType The type to deserialize into - * @return The deserialized Java object - */ - @SuppressWarnings("unchecked") - public static T deserialize(String body, Type returnType) { - try { - if (isLenientOnJson) { - JsonReader jsonReader = new JsonReader(new StringReader(body)); - // see https://google-gson.googlecode.com/svn/trunk/gson/docs/javadocs/com/google/gson/stream/JsonReader.html#setLenient(boolean) - jsonReader.setLenient(true); - return gson.fromJson(jsonReader, returnType); - } else { - return gson.fromJson(body, returnType); - } - } catch (JsonParseException e) { - // Fallback processing when failed to parse JSON form response body: - // return the response body string directly for the String return type; - if (returnType.equals(String.class)) { - return (T) body; - } else { - throw (e); - } - } - } - - /** - * Gson TypeAdapter for Byte Array type - */ - public static class ByteArrayAdapter extends TypeAdapter { - - @Override - public void write(JsonWriter out, byte[] value) throws IOException { - if (value == null) { - out.nullValue(); - } else { - out.value(ByteString.of(value).base64()); - } - } - - @Override - public byte[] read(JsonReader in) throws IOException { - switch (in.peek()) { - case NULL: - in.nextNull(); - return null; - default: - String bytesAsBase64 = in.nextString(); - ByteString byteString = ByteString.decodeBase64(bytesAsBase64); - return byteString.toByteArray(); - } - } - } - - /** - * Gson TypeAdapter for JSR310 OffsetDateTime type - */ - public static class OffsetDateTimeTypeAdapter extends TypeAdapter { - - private DateTimeFormatter formatter; - - public OffsetDateTimeTypeAdapter() { - this(DateTimeFormatter.ISO_OFFSET_DATE_TIME); - } - - public OffsetDateTimeTypeAdapter(DateTimeFormatter formatter) { - this.formatter = formatter; - } - - public void setFormat(DateTimeFormatter dateFormat) { - this.formatter = dateFormat; - } - - @Override - public void write(JsonWriter out, OffsetDateTime date) throws IOException { - if (date == null) { - out.nullValue(); - } else { - out.value(formatter.format(date)); - } - } - - @Override - public OffsetDateTime read(JsonReader in) throws IOException { - switch (in.peek()) { - case NULL: - in.nextNull(); - return null; - default: - String date = in.nextString(); - if (date.endsWith("+0000")) { - date = date.substring(0, date.length()-5) + "Z"; - } - return OffsetDateTime.parse(date, formatter); - } - } - } - - /** - * Gson TypeAdapter for JSR310 LocalDate type - */ - public static class LocalDateTypeAdapter extends TypeAdapter { - - private DateTimeFormatter formatter; - - public LocalDateTypeAdapter() { - this(DateTimeFormatter.ISO_LOCAL_DATE); - } - - public LocalDateTypeAdapter(DateTimeFormatter formatter) { - this.formatter = formatter; - } - - public void setFormat(DateTimeFormatter dateFormat) { - this.formatter = dateFormat; - } - - @Override - public void write(JsonWriter out, LocalDate date) throws IOException { - if (date == null) { - out.nullValue(); - } else { - out.value(formatter.format(date)); - } - } - - @Override - public LocalDate read(JsonReader in) throws IOException { - switch (in.peek()) { - case NULL: - in.nextNull(); - return null; - default: - String date = in.nextString(); - return LocalDate.parse(date, formatter); - } - } - } - - public static void setOffsetDateTimeFormat(DateTimeFormatter dateFormat) { - offsetDateTimeTypeAdapter.setFormat(dateFormat); - } - - public static void setLocalDateFormat(DateTimeFormatter dateFormat) { - localDateTypeAdapter.setFormat(dateFormat); - } - - /** - * Gson TypeAdapter for java.sql.Date type - * If the dateFormat is null, a simple "yyyy-MM-dd" format will be used - * (more efficient than SimpleDateFormat). - */ - public static class SqlDateTypeAdapter extends TypeAdapter { - - private DateFormat dateFormat; - - public SqlDateTypeAdapter() {} - - public SqlDateTypeAdapter(DateFormat dateFormat) { - this.dateFormat = dateFormat; - } - - public void setFormat(DateFormat dateFormat) { - this.dateFormat = dateFormat; - } - - @Override - public void write(JsonWriter out, java.sql.Date date) throws IOException { - if (date == null) { - out.nullValue(); - } else { - String value; - if (dateFormat != null) { - value = dateFormat.format(date); - } else { - value = date.toString(); - } - out.value(value); - } - } - - @Override - public java.sql.Date read(JsonReader in) throws IOException { - switch (in.peek()) { - case NULL: - in.nextNull(); - return null; - default: - String date = in.nextString(); - try { - if (dateFormat != null) { - return new java.sql.Date(dateFormat.parse(date).getTime()); - } - return new java.sql.Date(ISO8601Utils.parse(date, new ParsePosition(0)).getTime()); - } catch (ParseException e) { - throw new JsonParseException(e); - } - } - } - } - - /** - * Gson TypeAdapter for java.util.Date type - * If the dateFormat is null, ISO8601Utils will be used. - */ - public static class DateTypeAdapter extends TypeAdapter { - - private DateFormat dateFormat; - - public DateTypeAdapter() {} - - public DateTypeAdapter(DateFormat dateFormat) { - this.dateFormat = dateFormat; - } - - public void setFormat(DateFormat dateFormat) { - this.dateFormat = dateFormat; - } - - @Override - public void write(JsonWriter out, Date date) throws IOException { - if (date == null) { - out.nullValue(); - } else { - String value; - if (dateFormat != null) { - value = dateFormat.format(date); - } else { - value = ISO8601Utils.format(date, true); - } - out.value(value); - } - } - - @Override - public Date read(JsonReader in) throws IOException { - try { - switch (in.peek()) { - case NULL: - in.nextNull(); - return null; - default: - String date = in.nextString(); - try { - if (dateFormat != null) { - return dateFormat.parse(date); - } - return ISO8601Utils.parse(date, new ParsePosition(0)); - } catch (ParseException e) { - throw new JsonParseException(e); - } - } - } catch (IllegalArgumentException e) { - throw new JsonParseException(e); - } - } - } - - public static void setDateFormat(DateFormat dateFormat) { - dateTypeAdapter.setFormat(dateFormat); - } - - public static void setSqlDateFormat(DateFormat dateFormat) { - sqlDateTypeAdapter.setFormat(dateFormat); - } -} diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/Pair.java b/backend-server/application/src/main/java/com/apitable/databusclient/Pair.java deleted file mode 100644 index 8947d88328..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/Pair.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient; - -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class Pair { - private String name = ""; - private String value = ""; - - public Pair (String name, String value) { - setName(name); - setValue(value); - } - - private void setName(String name) { - if (!isValidString(name)) { - return; - } - - this.name = name; - } - - private void setValue(String value) { - if (!isValidString(value)) { - return; - } - - this.value = value; - } - - public String getName() { - return this.name; - } - - public String getValue() { - return this.value; - } - - private boolean isValidString(String arg) { - if (arg == null) { - return false; - } - - return true; - } -} diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/ProgressRequestBody.java b/backend-server/application/src/main/java/com/apitable/databusclient/ProgressRequestBody.java deleted file mode 100644 index 323b0b0f90..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/ProgressRequestBody.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient; - -import okhttp3.MediaType; -import okhttp3.RequestBody; - -import java.io.IOException; - -import okio.Buffer; -import okio.BufferedSink; -import okio.ForwardingSink; -import okio.Okio; -import okio.Sink; - -public class ProgressRequestBody extends RequestBody { - - private final RequestBody requestBody; - - private final ApiCallback callback; - - public ProgressRequestBody(RequestBody requestBody, ApiCallback callback) { - this.requestBody = requestBody; - this.callback = callback; - } - - @Override - public MediaType contentType() { - return requestBody.contentType(); - } - - @Override - public long contentLength() throws IOException { - return requestBody.contentLength(); - } - - @Override - public void writeTo(BufferedSink sink) throws IOException { - BufferedSink bufferedSink = Okio.buffer(sink(sink)); - requestBody.writeTo(bufferedSink); - bufferedSink.flush(); - } - - private Sink sink(Sink sink) { - return new ForwardingSink(sink) { - - long bytesWritten = 0L; - long contentLength = 0L; - - @Override - public void write(Buffer source, long byteCount) throws IOException { - super.write(source, byteCount); - if (contentLength == 0) { - contentLength = contentLength(); - } - - bytesWritten += byteCount; - callback.onUploadProgress(bytesWritten, contentLength, bytesWritten == contentLength); - } - }; - } -} diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/ProgressResponseBody.java b/backend-server/application/src/main/java/com/apitable/databusclient/ProgressResponseBody.java deleted file mode 100644 index b22650b246..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/ProgressResponseBody.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient; - -import okhttp3.MediaType; -import okhttp3.ResponseBody; - -import java.io.IOException; - -import okio.Buffer; -import okio.BufferedSource; -import okio.ForwardingSource; -import okio.Okio; -import okio.Source; - -public class ProgressResponseBody extends ResponseBody { - - private final ResponseBody responseBody; - private final ApiCallback callback; - private BufferedSource bufferedSource; - - public ProgressResponseBody(ResponseBody responseBody, ApiCallback callback) { - this.responseBody = responseBody; - this.callback = callback; - } - - @Override - public MediaType contentType() { - return responseBody.contentType(); - } - - @Override - public long contentLength() { - return responseBody.contentLength(); - } - - @Override - public BufferedSource source() { - if (bufferedSource == null) { - bufferedSource = Okio.buffer(source(responseBody.source())); - } - return bufferedSource; - } - - private Source source(Source source) { - return new ForwardingSource(source) { - long totalBytesRead = 0L; - - @Override - public long read(Buffer sink, long byteCount) throws IOException { - long bytesRead = super.read(sink, byteCount); - // read() returns the number of bytes read, or -1 if this source is exhausted. - totalBytesRead += bytesRead != -1 ? bytesRead : 0; - callback.onDownloadProgress(totalBytesRead, responseBody.contentLength(), bytesRead == -1); - return bytesRead; - } - }; - } -} diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/StringUtil.java b/backend-server/application/src/main/java/com/apitable/databusclient/StringUtil.java deleted file mode 100644 index 5f2f8aab7a..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/StringUtil.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient; - -import java.util.Collection; -import java.util.Iterator; - -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class StringUtil { - /** - * Check if the given array contains the given value (with case-insensitive comparison). - * - * @param array The array - * @param value The value to search - * @return true if the array contains the value - */ - public static boolean containsIgnoreCase(String[] array, String value) { - for (String str : array) { - if (value == null && str == null) { - return true; - } - if (value != null && value.equalsIgnoreCase(str)) { - return true; - } - } - return false; - } - - /** - * Join an array of strings with the given separator. - *

- * Note: This might be replaced by utility method from commons-lang or guava someday - * if one of those libraries is added as dependency. - *

- * - * @param array The array of strings - * @param separator The separator - * @return the resulting string - */ - public static String join(String[] array, String separator) { - int len = array.length; - if (len == 0) { - return ""; - } - - StringBuilder out = new StringBuilder(); - out.append(array[0]); - for (int i = 1; i < len; i++) { - out.append(separator).append(array[i]); - } - return out.toString(); - } - - /** - * Join a list of strings with the given separator. - * - * @param list The list of strings - * @param separator The separator - * @return the resulting string - */ - public static String join(Collection list, String separator) { - Iterator iterator = list.iterator(); - StringBuilder out = new StringBuilder(); - if (iterator.hasNext()) { - out.append(iterator.next()); - } - while (iterator.hasNext()) { - out.append(separator).append(iterator.next()); - } - return out.toString(); - } -} diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/api/AutomationDaoApiApi.java b/backend-server/application/src/main/java/com/apitable/databusclient/api/AutomationDaoApiApi.java deleted file mode 100644 index dfb05ddb2e..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/api/AutomationDaoApiApi.java +++ /dev/null @@ -1,1749 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.api; - -import com.apitable.databusclient.ApiCallback; -import com.apitable.databusclient.ApiClient; -import com.apitable.databusclient.ApiException; -import com.apitable.databusclient.ApiResponse; -import com.apitable.databusclient.Configuration; -import com.apitable.databusclient.Pair; -import com.apitable.databusclient.ProgressRequestBody; -import com.apitable.databusclient.ProgressResponseBody; - -import com.apitable.databusclient.model.*; -import com.google.gson.reflect.TypeToken; - -import java.io.IOException; - - -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class AutomationDaoApiApi { - private ApiClient localVarApiClient; - private int localHostIndex; - private String localCustomBaseUrl; - - public AutomationDaoApiApi() { - this(Configuration.getDefaultApiClient()); - } - - public AutomationDaoApiApi(ApiClient apiClient) { - this.localVarApiClient = apiClient; - } - - public ApiClient getApiClient() { - return localVarApiClient; - } - - public void setApiClient(ApiClient apiClient) { - this.localVarApiClient = apiClient; - } - - public int getHostIndex() { - return localHostIndex; - } - - public void setHostIndex(int hostIndex) { - this.localHostIndex = hostIndex; - } - - public String getCustomBaseUrl() { - return localCustomBaseUrl; - } - - public void setCustomBaseUrl(String customBaseUrl) { - this.localCustomBaseUrl = customBaseUrl; - } - - /** - * Build call for daoCopyAutomationRobot - * @param automationRobotCopyRO (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Create automation robot successfully -
- */ - public okhttp3.Call daoCopyAutomationRobotCall(List automationRobotCopyRO, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = automationRobotCopyRO; - - // create path and map variables - String localVarPath = "/databus/dao/automations/robots/copy"; - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - final String[] localVarAccepts = { - "application/json" - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - "application/json" - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "POST", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call daoCopyAutomationRobotValidateBeforeCall(List automationRobotCopyRO, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'automationRobotCopyRO' is set - if (automationRobotCopyRO == null) { - throw new ApiException("Missing the required parameter 'automationRobotCopyRO' when calling daoCopyAutomationRobot(Async)"); - } - - return daoCopyAutomationRobotCall(automationRobotCopyRO, _callback); - - } - - /** - * Create automation robot - * Create automation robot - * @param automationRobotCopyRO (required) - * @return ApiResponseEmptySO - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Create automation robot successfully -
- */ - public ApiResponseEmptySO daoCopyAutomationRobot(List automationRobotCopyRO) throws ApiException { - ApiResponse localVarResp = daoCopyAutomationRobotWithHttpInfo(automationRobotCopyRO); - return localVarResp.getData(); - } - - /** - * Create automation robot - * Create automation robot - * @param automationRobotCopyRO (required) - * @return ApiResponse<ApiResponseEmptySO> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Create automation robot successfully -
- */ - public ApiResponse daoCopyAutomationRobotWithHttpInfo(List automationRobotCopyRO) throws ApiException { - okhttp3.Call localVarCall = daoCopyAutomationRobotValidateBeforeCall(automationRobotCopyRO, null); - Type localVarReturnType = new TypeToken(){}.getType(); - return localVarApiClient.execute(localVarCall, localVarReturnType); - } - - /** - * Create automation robot (asynchronously) - * Create automation robot - * @param automationRobotCopyRO (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Create automation robot successfully -
- */ - public okhttp3.Call daoCopyAutomationRobotAsync(List automationRobotCopyRO, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = daoCopyAutomationRobotValidateBeforeCall(automationRobotCopyRO, _callback); - Type localVarReturnType = new TypeToken(){}.getType(); - localVarApiClient.executeAsync(localVarCall, localVarReturnType, _callback); - return localVarCall; - } - /** - * Build call for daoCreateAutomationRunHistory - * @param robotId robot id (required) - * @param body (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 create automation run history task success -
- */ - public okhttp3.Call daoCreateAutomationRunHistoryCall(String robotId, Object body, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = body; - - // create path and map variables - String localVarPath = "/databus/dao/automations/{robot_id}/histories" - .replace("{" + "robot_id" + "}", localVarApiClient.escapeString(robotId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - "application/json" - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "POST", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call daoCreateAutomationRunHistoryValidateBeforeCall(String robotId, Object body, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'robotId' is set - if (robotId == null) { - throw new ApiException("Missing the required parameter 'robotId' when calling daoCreateAutomationRunHistory(Async)"); - } - - // verify the required parameter 'body' is set - if (body == null) { - throw new ApiException("Missing the required parameter 'body' when calling daoCreateAutomationRunHistory(Async)"); - } - - return daoCreateAutomationRunHistoryCall(robotId, body, _callback); - - } - - /** - * create automation run history task success todo - * create automation run history task success todo - * @param robotId robot id (required) - * @param body (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 create automation run history task success -
- */ - public void daoCreateAutomationRunHistory(String robotId, Object body) throws ApiException { - daoCreateAutomationRunHistoryWithHttpInfo(robotId, body); - } - - /** - * create automation run history task success todo - * create automation run history task success todo - * @param robotId robot id (required) - * @param body (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 create automation run history task success -
- */ - public ApiResponse daoCreateAutomationRunHistoryWithHttpInfo(String robotId, Object body) throws ApiException { - okhttp3.Call localVarCall = daoCreateAutomationRunHistoryValidateBeforeCall(robotId, body, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * create automation run history task success todo (asynchronously) - * create automation run history task success todo - * @param robotId robot id (required) - * @param body (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 create automation run history task success -
- */ - public okhttp3.Call daoCreateAutomationRunHistoryAsync(String robotId, Object body, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = daoCreateAutomationRunHistoryValidateBeforeCall(robotId, body, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for daoCreateOrUpdateAutomationRobotAction - * @param robotId robot id (required) - * @param automationRobotActionRO (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - - -
Status Code Description Response Headers
200 Update automation robot action successfully -
201 Create automation robot action successfully -
- */ - public okhttp3.Call daoCreateOrUpdateAutomationRobotActionCall(String robotId, AutomationRobotActionRO automationRobotActionRO, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = automationRobotActionRO; - - // create path and map variables - String localVarPath = "/databus/dao/automations/robots/{robot_id}/actions" - .replace("{" + "robot_id" + "}", localVarApiClient.escapeString(robotId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - final String[] localVarAccepts = { - "application/json" - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - "application/json" - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "PUT", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call daoCreateOrUpdateAutomationRobotActionValidateBeforeCall(String robotId, AutomationRobotActionRO automationRobotActionRO, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'robotId' is set - if (robotId == null) { - throw new ApiException("Missing the required parameter 'robotId' when calling daoCreateOrUpdateAutomationRobotAction(Async)"); - } - - // verify the required parameter 'automationRobotActionRO' is set - if (automationRobotActionRO == null) { - throw new ApiException("Missing the required parameter 'automationRobotActionRO' when calling daoCreateOrUpdateAutomationRobotAction(Async)"); - } - - return daoCreateOrUpdateAutomationRobotActionCall(robotId, automationRobotActionRO, _callback); - - } - - /** - * Add or create automation robot action - * Add or create automation robot action - * @param robotId robot id (required) - * @param automationRobotActionRO (required) - * @return ApiResponseAutomationActionPO - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - - -
Status Code Description Response Headers
200 Update automation robot action successfully -
201 Create automation robot action successfully -
- */ - public ApiResponseAutomationActionPO daoCreateOrUpdateAutomationRobotAction(String robotId, AutomationRobotActionRO automationRobotActionRO) throws ApiException { - ApiResponse localVarResp = daoCreateOrUpdateAutomationRobotActionWithHttpInfo(robotId, automationRobotActionRO); - return localVarResp.getData(); - } - - /** - * Add or create automation robot action - * Add or create automation robot action - * @param robotId robot id (required) - * @param automationRobotActionRO (required) - * @return ApiResponse<ApiResponseAutomationActionPO> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - - -
Status Code Description Response Headers
200 Update automation robot action successfully -
201 Create automation robot action successfully -
- */ - public ApiResponse daoCreateOrUpdateAutomationRobotActionWithHttpInfo(String robotId, AutomationRobotActionRO automationRobotActionRO) throws ApiException { - okhttp3.Call localVarCall = daoCreateOrUpdateAutomationRobotActionValidateBeforeCall(robotId, automationRobotActionRO, null); - Type localVarReturnType = new TypeToken(){}.getType(); - return localVarApiClient.execute(localVarCall, localVarReturnType); - } - - /** - * Add or create automation robot action (asynchronously) - * Add or create automation robot action - * @param robotId robot id (required) - * @param automationRobotActionRO (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - - -
Status Code Description Response Headers
200 Update automation robot action successfully -
201 Create automation robot action successfully -
- */ - public okhttp3.Call daoCreateOrUpdateAutomationRobotActionAsync(String robotId, AutomationRobotActionRO automationRobotActionRO, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = daoCreateOrUpdateAutomationRobotActionValidateBeforeCall(robotId, automationRobotActionRO, _callback); - Type localVarReturnType = new TypeToken(){}.getType(); - localVarApiClient.executeAsync(localVarCall, localVarReturnType, _callback); - return localVarCall; - } - /** - * Build call for daoCreateOrUpdateAutomationRobotTrigger - * @param robotId robot id (required) - * @param automationRobotTriggerRO (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - - -
Status Code Description Response Headers
200 Update automation robot trigger successfully -
201 Create automation robot trigger successfully -
- */ - public okhttp3.Call daoCreateOrUpdateAutomationRobotTriggerCall(String robotId, AutomationRobotTriggerRO automationRobotTriggerRO, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = automationRobotTriggerRO; - - // create path and map variables - String localVarPath = "/databus/dao/automations/robots/{robot_id}/triggers" - .replace("{" + "robot_id" + "}", localVarApiClient.escapeString(robotId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - final String[] localVarAccepts = { - "application/json" - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - "application/json" - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "PUT", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call daoCreateOrUpdateAutomationRobotTriggerValidateBeforeCall(String robotId, AutomationRobotTriggerRO automationRobotTriggerRO, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'robotId' is set - if (robotId == null) { - throw new ApiException("Missing the required parameter 'robotId' when calling daoCreateOrUpdateAutomationRobotTrigger(Async)"); - } - - // verify the required parameter 'automationRobotTriggerRO' is set - if (automationRobotTriggerRO == null) { - throw new ApiException("Missing the required parameter 'automationRobotTriggerRO' when calling daoCreateOrUpdateAutomationRobotTrigger(Async)"); - } - - return daoCreateOrUpdateAutomationRobotTriggerCall(robotId, automationRobotTriggerRO, _callback); - - } - - /** - * Add or create automation robot trigger - * Add or create automation robot trigger - * @param robotId robot id (required) - * @param automationRobotTriggerRO (required) - * @return ApiResponseAutomationTriggerPO - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - - -
Status Code Description Response Headers
200 Update automation robot trigger successfully -
201 Create automation robot trigger successfully -
- */ - public ApiResponseAutomationTriggerPO daoCreateOrUpdateAutomationRobotTrigger(String robotId, AutomationRobotTriggerRO automationRobotTriggerRO) throws ApiException { - ApiResponse localVarResp = daoCreateOrUpdateAutomationRobotTriggerWithHttpInfo(robotId, automationRobotTriggerRO); - return localVarResp.getData(); - } - - /** - * Add or create automation robot trigger - * Add or create automation robot trigger - * @param robotId robot id (required) - * @param automationRobotTriggerRO (required) - * @return ApiResponse<ApiResponseAutomationTriggerPO> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - - -
Status Code Description Response Headers
200 Update automation robot trigger successfully -
201 Create automation robot trigger successfully -
- */ - public ApiResponse daoCreateOrUpdateAutomationRobotTriggerWithHttpInfo(String robotId, AutomationRobotTriggerRO automationRobotTriggerRO) throws ApiException { - okhttp3.Call localVarCall = daoCreateOrUpdateAutomationRobotTriggerValidateBeforeCall(robotId, automationRobotTriggerRO, null); - Type localVarReturnType = new TypeToken(){}.getType(); - return localVarApiClient.execute(localVarCall, localVarReturnType); - } - - /** - * Add or create automation robot trigger (asynchronously) - * Add or create automation robot trigger - * @param robotId robot id (required) - * @param automationRobotTriggerRO (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - - -
Status Code Description Response Headers
200 Update automation robot trigger successfully -
201 Create automation robot trigger successfully -
- */ - public okhttp3.Call daoCreateOrUpdateAutomationRobotTriggerAsync(String robotId, AutomationRobotTriggerRO automationRobotTriggerRO, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = daoCreateOrUpdateAutomationRobotTriggerValidateBeforeCall(robotId, automationRobotTriggerRO, _callback); - Type localVarReturnType = new TypeToken(){}.getType(); - localVarApiClient.executeAsync(localVarCall, localVarReturnType, _callback); - return localVarCall; - } - /** - * Build call for daoGetAutomationRunContext - * @param taskId task id (required) - * @param actionId action id (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get automation run history task context -
- */ - public okhttp3.Call daoGetAutomationRunContextCall(String taskId, String actionId, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/databus/dao/automations/histories/{task_id}/contexts/{action_id}" - .replace("{" + "task_id" + "}", localVarApiClient.escapeString(taskId.toString())) - .replace("{" + "action_id" + "}", localVarApiClient.escapeString(actionId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call daoGetAutomationRunContextValidateBeforeCall(String taskId, String actionId, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'taskId' is set - if (taskId == null) { - throw new ApiException("Missing the required parameter 'taskId' when calling daoGetAutomationRunContext(Async)"); - } - - // verify the required parameter 'actionId' is set - if (actionId == null) { - throw new ApiException("Missing the required parameter 'actionId' when calling daoGetAutomationRunContext(Async)"); - } - - return daoGetAutomationRunContextCall(taskId, actionId, _callback); - - } - - /** - * Get automation task input and output todo - * Get automation task input and output todo - * @param taskId task id (required) - * @param actionId action id (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get automation run history task context -
- */ - public void daoGetAutomationRunContext(String taskId, String actionId) throws ApiException { - daoGetAutomationRunContextWithHttpInfo(taskId, actionId); - } - - /** - * Get automation task input and output todo - * Get automation task input and output todo - * @param taskId task id (required) - * @param actionId action id (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get automation run history task context -
- */ - public ApiResponse daoGetAutomationRunContextWithHttpInfo(String taskId, String actionId) throws ApiException { - okhttp3.Call localVarCall = daoGetAutomationRunContextValidateBeforeCall(taskId, actionId, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * Get automation task input and output todo (asynchronously) - * Get automation task input and output todo - * @param taskId task id (required) - * @param actionId action id (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get automation run history task context -
- */ - public okhttp3.Call daoGetAutomationRunContextAsync(String taskId, String actionId, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = daoGetAutomationRunContextValidateBeforeCall(taskId, actionId, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for daoGetAutomationRunHistory - * @param pageSize (required) - * @param pageNum (required) - * @param robotId robot id (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get automation run history list -
- */ - public okhttp3.Call daoGetAutomationRunHistoryCall(Integer pageSize, Integer pageNum, String robotId, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/databus/dao/automations/{robot_id}/histories" - .replace("{" + "robot_id" + "}", localVarApiClient.escapeString(robotId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (pageSize != null) { - localVarQueryParams.addAll(localVarApiClient.parameterToPair("page_size", pageSize)); - } - - if (pageNum != null) { - localVarQueryParams.addAll(localVarApiClient.parameterToPair("page_num", pageNum)); - } - - final String[] localVarAccepts = { - "application/json" - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call daoGetAutomationRunHistoryValidateBeforeCall(Integer pageSize, Integer pageNum, String robotId, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'pageSize' is set - if (pageSize == null) { - throw new ApiException("Missing the required parameter 'pageSize' when calling daoGetAutomationRunHistory(Async)"); - } - - // verify the required parameter 'pageNum' is set - if (pageNum == null) { - throw new ApiException("Missing the required parameter 'pageNum' when calling daoGetAutomationRunHistory(Async)"); - } - - // verify the required parameter 'robotId' is set - if (robotId == null) { - throw new ApiException("Missing the required parameter 'robotId' when calling daoGetAutomationRunHistory(Async)"); - } - - return daoGetAutomationRunHistoryCall(pageSize, pageNum, robotId, _callback); - - } - - /** - * Get automation run history list - * Get automation run history list - * @param pageSize (required) - * @param pageNum (required) - * @param robotId robot id (required) - * @return ApiResponseAutomationRunHistoryPO - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get automation run history list -
- */ - public ApiResponseAutomationRunHistoryPO daoGetAutomationRunHistory(Integer pageSize, Integer pageNum, String robotId) throws ApiException { - ApiResponse localVarResp = daoGetAutomationRunHistoryWithHttpInfo(pageSize, pageNum, robotId); - return localVarResp.getData(); - } - - /** - * Get automation run history list - * Get automation run history list - * @param pageSize (required) - * @param pageNum (required) - * @param robotId robot id (required) - * @return ApiResponse<ApiResponseAutomationRunHistoryPO> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get automation run history list -
- */ - public ApiResponse daoGetAutomationRunHistoryWithHttpInfo(Integer pageSize, Integer pageNum, String robotId) throws ApiException { - okhttp3.Call localVarCall = daoGetAutomationRunHistoryValidateBeforeCall(pageSize, pageNum, robotId, null); - Type localVarReturnType = new TypeToken(){}.getType(); - return localVarApiClient.execute(localVarCall, localVarReturnType); - } - - /** - * Get automation run history list (asynchronously) - * Get automation run history list - * @param pageSize (required) - * @param pageNum (required) - * @param robotId robot id (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get automation run history list -
- */ - public okhttp3.Call daoGetAutomationRunHistoryAsync(Integer pageSize, Integer pageNum, String robotId, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = daoGetAutomationRunHistoryValidateBeforeCall(pageSize, pageNum, robotId, _callback); - Type localVarReturnType = new TypeToken(){}.getType(); - localVarApiClient.executeAsync(localVarCall, localVarReturnType, _callback); - return localVarCall; - } - /** - * Build call for daoGetAutomationRunHistoryDetail - * @param taskId task id (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get automation run history detail -
- */ - public okhttp3.Call daoGetAutomationRunHistoryDetailCall(String taskId, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/databus/dao/automations/histories/{task_id}" - .replace("{" + "task_id" + "}", localVarApiClient.escapeString(taskId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call daoGetAutomationRunHistoryDetailValidateBeforeCall(String taskId, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'taskId' is set - if (taskId == null) { - throw new ApiException("Missing the required parameter 'taskId' when calling daoGetAutomationRunHistoryDetail(Async)"); - } - - return daoGetAutomationRunHistoryDetailCall(taskId, _callback); - - } - - /** - * Get automation run task details todo - * Get automation run task details todo - * @param taskId task id (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get automation run history detail -
- */ - public void daoGetAutomationRunHistoryDetail(String taskId) throws ApiException { - daoGetAutomationRunHistoryDetailWithHttpInfo(taskId); - } - - /** - * Get automation run task details todo - * Get automation run task details todo - * @param taskId task id (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get automation run history detail -
- */ - public ApiResponse daoGetAutomationRunHistoryDetailWithHttpInfo(String taskId) throws ApiException { - okhttp3.Call localVarCall = daoGetAutomationRunHistoryDetailValidateBeforeCall(taskId, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * Get automation run task details todo (asynchronously) - * Get automation run task details todo - * @param taskId task id (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get automation run history detail -
- */ - public okhttp3.Call daoGetAutomationRunHistoryDetailAsync(String taskId, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = daoGetAutomationRunHistoryDetailValidateBeforeCall(taskId, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for daoGetRobotByRobotId - * @param robotId Automation robot id (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 get automation detail -
- */ - public okhttp3.Call daoGetRobotByRobotIdCall(String robotId, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/databus/dao/automations/robots/{robot_id}" - .replace("{" + "robot_id" + "}", localVarApiClient.escapeString(robotId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - final String[] localVarAccepts = { - "application/json" - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call daoGetRobotByRobotIdValidateBeforeCall(String robotId, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'robotId' is set - if (robotId == null) { - throw new ApiException("Missing the required parameter 'robotId' when calling daoGetRobotByRobotId(Async)"); - } - - return daoGetRobotByRobotIdCall(robotId, _callback); - - } - - /** - * Get automation robot detail. - * Get automation robot detail. - * @param robotId Automation robot id (required) - * @return ApiResponseAutomationSO - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 get automation detail -
- */ - public ApiResponseAutomationSO daoGetRobotByRobotId(String robotId) throws ApiException { - ApiResponse localVarResp = daoGetRobotByRobotIdWithHttpInfo(robotId); - return localVarResp.getData(); - } - - /** - * Get automation robot detail. - * Get automation robot detail. - * @param robotId Automation robot id (required) - * @return ApiResponse<ApiResponseAutomationSO> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 get automation detail -
- */ - public ApiResponse daoGetRobotByRobotIdWithHttpInfo(String robotId) throws ApiException { - okhttp3.Call localVarCall = daoGetRobotByRobotIdValidateBeforeCall(robotId, null); - Type localVarReturnType = new TypeToken(){}.getType(); - return localVarApiClient.execute(localVarCall, localVarReturnType); - } - - /** - * Get automation robot detail. (asynchronously) - * Get automation robot detail. - * @param robotId Automation robot id (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 get automation detail -
- */ - public okhttp3.Call daoGetRobotByRobotIdAsync(String robotId, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = daoGetRobotByRobotIdValidateBeforeCall(robotId, _callback); - Type localVarReturnType = new TypeToken(){}.getType(); - localVarApiClient.executeAsync(localVarCall, localVarReturnType, _callback); - return localVarCall; - } - /** - * Build call for daoGetRobotsByResourceId - * @param resourceId (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 get automations triggers -
- */ - public okhttp3.Call daoGetRobotsByResourceIdCall(String resourceId, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/databus/dao/automations/robots"; - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (resourceId != null) { - localVarQueryParams.addAll(localVarApiClient.parameterToPair("resource_id", resourceId)); - } - - final String[] localVarAccepts = { - "application/json" - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call daoGetRobotsByResourceIdValidateBeforeCall(String resourceId, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'resourceId' is set - if (resourceId == null) { - throw new ApiException("Missing the required parameter 'resourceId' when calling daoGetRobotsByResourceId(Async)"); - } - - return daoGetRobotsByResourceIdCall(resourceId, _callback); - - } - - /** - * get automations triggers todo - * get automations triggers todo - * @param resourceId (required) - * @return ApiResponseAutomationRobotIntroductionSO - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 get automations triggers -
- */ - public ApiResponseAutomationRobotIntroductionSO daoGetRobotsByResourceId(String resourceId) throws ApiException { - ApiResponse localVarResp = daoGetRobotsByResourceIdWithHttpInfo(resourceId); - return localVarResp.getData(); - } - - /** - * get automations triggers todo - * get automations triggers todo - * @param resourceId (required) - * @return ApiResponse<ApiResponseAutomationRobotIntroductionSO> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 get automations triggers -
- */ - public ApiResponse daoGetRobotsByResourceIdWithHttpInfo(String resourceId) throws ApiException { - okhttp3.Call localVarCall = daoGetRobotsByResourceIdValidateBeforeCall(resourceId, null); - Type localVarReturnType = new TypeToken(){}.getType(); - return localVarApiClient.execute(localVarCall, localVarReturnType); - } - - /** - * get automations triggers todo (asynchronously) - * get automations triggers todo - * @param resourceId (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 get automations triggers -
- */ - public okhttp3.Call daoGetRobotsByResourceIdAsync(String resourceId, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = daoGetRobotsByResourceIdValidateBeforeCall(resourceId, _callback); - Type localVarReturnType = new TypeToken(){}.getType(); - localVarApiClient.executeAsync(localVarCall, localVarReturnType, _callback); - return localVarCall; - } - /** - * Build call for daoGetRobotsTriggers - * @param robotIds (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 get automations triggers -
- */ - public okhttp3.Call daoGetRobotsTriggersCall(List robotIds, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/databus/dao/automations/triggers"; - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (robotIds != null) { - localVarCollectionQueryParams.addAll(localVarApiClient.parameterToPairs("multi", "robot_ids", robotIds)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call daoGetRobotsTriggersValidateBeforeCall(List robotIds, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'robotIds' is set - if (robotIds == null) { - throw new ApiException("Missing the required parameter 'robotIds' when calling daoGetRobotsTriggers(Async)"); - } - - return daoGetRobotsTriggersCall(robotIds, _callback); - - } - - /** - * get automations triggers todo - * get automations triggers todo - * @param robotIds (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 get automations triggers -
- */ - public void daoGetRobotsTriggers(List robotIds) throws ApiException { - daoGetRobotsTriggersWithHttpInfo(robotIds); - } - - /** - * get automations triggers todo - * get automations triggers todo - * @param robotIds (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 get automations triggers -
- */ - public ApiResponse daoGetRobotsTriggersWithHttpInfo(List robotIds) throws ApiException { - okhttp3.Call localVarCall = daoGetRobotsTriggersValidateBeforeCall(robotIds, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * get automations triggers todo (asynchronously) - * get automations triggers todo - * @param robotIds (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 get automations triggers -
- */ - public okhttp3.Call daoGetRobotsTriggersAsync(List robotIds, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = daoGetRobotsTriggersValidateBeforeCall(robotIds, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for daoUpdateAutomationRobot - * @param robotId robot id (required) - * @param automationRobotUpdateRO (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Update automation robot successfully -
- */ - public okhttp3.Call daoUpdateAutomationRobotCall(String robotId, AutomationRobotUpdateRO automationRobotUpdateRO, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = automationRobotUpdateRO; - - // create path and map variables - String localVarPath = "/databus/dao/automations/robots/{robot_id}" - .replace("{" + "robot_id" + "}", localVarApiClient.escapeString(robotId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - final String[] localVarAccepts = { - "application/json" - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - "application/json" - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "PATCH", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call daoUpdateAutomationRobotValidateBeforeCall(String robotId, AutomationRobotUpdateRO automationRobotUpdateRO, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'robotId' is set - if (robotId == null) { - throw new ApiException("Missing the required parameter 'robotId' when calling daoUpdateAutomationRobot(Async)"); - } - - // verify the required parameter 'automationRobotUpdateRO' is set - if (automationRobotUpdateRO == null) { - throw new ApiException("Missing the required parameter 'automationRobotUpdateRO' when calling daoUpdateAutomationRobot(Async)"); - } - - return daoUpdateAutomationRobotCall(robotId, automationRobotUpdateRO, _callback); - - } - - /** - * Update automation robot - * Update automation robot - * @param robotId robot id (required) - * @param automationRobotUpdateRO (required) - * @return ApiResponseEmptySO - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Update automation robot successfully -
- */ - public ApiResponseEmptySO daoUpdateAutomationRobot(String robotId, AutomationRobotUpdateRO automationRobotUpdateRO) throws ApiException { - ApiResponse localVarResp = daoUpdateAutomationRobotWithHttpInfo(robotId, automationRobotUpdateRO); - return localVarResp.getData(); - } - - /** - * Update automation robot - * Update automation robot - * @param robotId robot id (required) - * @param automationRobotUpdateRO (required) - * @return ApiResponse<ApiResponseEmptySO> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Update automation robot successfully -
- */ - public ApiResponse daoUpdateAutomationRobotWithHttpInfo(String robotId, AutomationRobotUpdateRO automationRobotUpdateRO) throws ApiException { - okhttp3.Call localVarCall = daoUpdateAutomationRobotValidateBeforeCall(robotId, automationRobotUpdateRO, null); - Type localVarReturnType = new TypeToken(){}.getType(); - return localVarApiClient.execute(localVarCall, localVarReturnType); - } - - /** - * Update automation robot (asynchronously) - * Update automation robot - * @param robotId robot id (required) - * @param automationRobotUpdateRO (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Update automation robot successfully -
- */ - public okhttp3.Call daoUpdateAutomationRobotAsync(String robotId, AutomationRobotUpdateRO automationRobotUpdateRO, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = daoUpdateAutomationRobotValidateBeforeCall(robotId, automationRobotUpdateRO, _callback); - Type localVarReturnType = new TypeToken(){}.getType(); - localVarApiClient.executeAsync(localVarCall, localVarReturnType, _callback); - return localVarCall; - } - /** - * Build call for daoUpdateAutomationRunHistoryStatus - * @param taskId task id (required) - * @param automationHistoryStatusRO (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get automation run history task context -
- */ - public okhttp3.Call daoUpdateAutomationRunHistoryStatusCall(String taskId, AutomationHistoryStatusRO automationHistoryStatusRO, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = automationHistoryStatusRO; - - // create path and map variables - String localVarPath = "/databus/dao/automations/histories/{task_id}/status" - .replace("{" + "task_id" + "}", localVarApiClient.escapeString(taskId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - "application/json" - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "PUT", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call daoUpdateAutomationRunHistoryStatusValidateBeforeCall(String taskId, AutomationHistoryStatusRO automationHistoryStatusRO, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'taskId' is set - if (taskId == null) { - throw new ApiException("Missing the required parameter 'taskId' when calling daoUpdateAutomationRunHistoryStatus(Async)"); - } - - // verify the required parameter 'automationHistoryStatusRO' is set - if (automationHistoryStatusRO == null) { - throw new ApiException("Missing the required parameter 'automationHistoryStatusRO' when calling daoUpdateAutomationRunHistoryStatus(Async)"); - } - - return daoUpdateAutomationRunHistoryStatusCall(taskId, automationHistoryStatusRO, _callback); - - } - - /** - * Get automation task input and output todo - * Get automation task input and output todo - * @param taskId task id (required) - * @param automationHistoryStatusRO (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get automation run history task context -
- */ - public void daoUpdateAutomationRunHistoryStatus(String taskId, AutomationHistoryStatusRO automationHistoryStatusRO) throws ApiException { - daoUpdateAutomationRunHistoryStatusWithHttpInfo(taskId, automationHistoryStatusRO); - } - - /** - * Get automation task input and output todo - * Get automation task input and output todo - * @param taskId task id (required) - * @param automationHistoryStatusRO (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get automation run history task context -
- */ - public ApiResponse daoUpdateAutomationRunHistoryStatusWithHttpInfo(String taskId, AutomationHistoryStatusRO automationHistoryStatusRO) throws ApiException { - okhttp3.Call localVarCall = daoUpdateAutomationRunHistoryStatusValidateBeforeCall(taskId, automationHistoryStatusRO, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * Get automation task input and output todo (asynchronously) - * Get automation task input and output todo - * @param taskId task id (required) - * @param automationHistoryStatusRO (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get automation run history task context -
- */ - public okhttp3.Call daoUpdateAutomationRunHistoryStatusAsync(String taskId, AutomationHistoryStatusRO automationHistoryStatusRO, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = daoUpdateAutomationRunHistoryStatusValidateBeforeCall(taskId, automationHistoryStatusRO, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - - /** - * Build call for daoGetRobotRunsBySpaceId - * @param spaceId space id (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 get automation robot running times -
- */ - public okhttp3.Call daoGetRobotRunsBySpaceIdCall(String spaceId, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/databus/dao/automations/robots/runs/{space_id}" - .replace("{" + "space_id" + "}", localVarApiClient.escapeString(spaceId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - final String[] localVarAccepts = { - "application/json" - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call daoGetRobotRunsBySpaceIdValidateBeforeCall(String spaceId, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'spaceId' is set - if (spaceId == null) { - throw new ApiException("Missing the required parameter 'spaceId' when calling daoGetRobotRunsBySpaceId(Async)"); - } - - return daoGetRobotRunsBySpaceIdCall(spaceId, _callback); - - } - - /** - * Get automation robot running times. - * Get automation robot running times. - * @param spaceId space id (required) - * @return ApiResponseAutomationRobotRunNumsSO - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 get automation robot running times -
- */ - public ApiResponseAutomationRobotRunNumsSO daoGetRobotRunsBySpaceId(String spaceId) throws ApiException { - ApiResponse localVarResp = daoGetRobotRunsBySpaceIdWithHttpInfo(spaceId); - return localVarResp.getData(); - } - - /** - * Get automation robot running times. - * Get automation robot running times. - * @param spaceId space id (required) - * @return ApiResponse<ApiResponseAutomationRobotRunNumsSO> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 get automation robot running times -
- */ - public ApiResponse daoGetRobotRunsBySpaceIdWithHttpInfo(String spaceId) throws ApiException { - okhttp3.Call localVarCall = daoGetRobotRunsBySpaceIdValidateBeforeCall(spaceId, null); - Type localVarReturnType = new TypeToken(){}.getType(); - return localVarApiClient.execute(localVarCall, localVarReturnType); - } - - /** - * Get automation robot running times. (asynchronously) - * Get automation robot running times. - * @param spaceId space id (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 get automation robot running times -
- */ - public okhttp3.Call daoGetRobotRunsBySpaceIdAsync(String spaceId, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = daoGetRobotRunsBySpaceIdValidateBeforeCall(spaceId, _callback); - Type localVarReturnType = new TypeToken(){}.getType(); - localVarApiClient.executeAsync(localVarCall, localVarReturnType, _callback); - return localVarCall; - } -} diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/api/CrateApi.java b/backend-server/application/src/main/java/com/apitable/databusclient/api/CrateApi.java deleted file mode 100644 index 82c43bc238..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/api/CrateApi.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.api; - -import com.apitable.databusclient.ApiCallback; -import com.apitable.databusclient.ApiClient; -import com.apitable.databusclient.ApiException; -import com.apitable.databusclient.ApiResponse; -import com.apitable.databusclient.Configuration; -import com.apitable.databusclient.Pair; -import com.apitable.databusclient.ProgressRequestBody; -import com.apitable.databusclient.ProgressResponseBody; - -import com.google.gson.reflect.TypeToken; - -import java.io.IOException; - - - -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class CrateApi { - private ApiClient localVarApiClient; - private int localHostIndex; - private String localCustomBaseUrl; - - public CrateApi() { - this(Configuration.getDefaultApiClient()); - } - - public CrateApi(ApiClient apiClient) { - this.localVarApiClient = apiClient; - } - - public ApiClient getApiClient() { - return localVarApiClient; - } - - public void setApiClient(ApiClient apiClient) { - this.localVarApiClient = apiClient; - } - - public int getHostIndex() { - return localHostIndex; - } - - public void setHostIndex(int hostIndex) { - this.localHostIndex = hostIndex; - } - - public String getCustomBaseUrl() { - return localCustomBaseUrl; - } - - public void setCustomBaseUrl(String customBaseUrl) { - this.localCustomBaseUrl = customBaseUrl; - } - - /** - * Build call for databusHome - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Databus Home -
- */ - public okhttp3.Call databusHomeCall(final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/databus"; - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call databusHomeValidateBeforeCall(final ApiCallback _callback) throws ApiException { - return databusHomeCall(_callback); - - } - - /** - * Homepage, for liveness check - * Homepage, for liveness check - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Databus Home -
- */ - public void databusHome() throws ApiException { - databusHomeWithHttpInfo(); - } - - /** - * Homepage, for liveness check - * Homepage, for liveness check - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Databus Home -
- */ - public ApiResponse databusHomeWithHttpInfo() throws ApiException { - okhttp3.Call localVarCall = databusHomeValidateBeforeCall(null); - return localVarApiClient.execute(localVarCall); - } - - /** - * Homepage, for liveness check (asynchronously) - * Homepage, for liveness check - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Databus Home -
- */ - public okhttp3.Call databusHomeAsync(final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = databusHomeValidateBeforeCall(_callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } -} diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/api/DataDaoApiApi.java b/backend-server/application/src/main/java/com/apitable/databusclient/api/DataDaoApiApi.java deleted file mode 100644 index d768c49218..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/api/DataDaoApiApi.java +++ /dev/null @@ -1,573 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.api; - -import com.apitable.databusclient.ApiCallback; -import com.apitable.databusclient.ApiClient; -import com.apitable.databusclient.ApiException; -import com.apitable.databusclient.ApiResponse; -import com.apitable.databusclient.Configuration; -import com.apitable.databusclient.Pair; -import com.apitable.databusclient.ProgressRequestBody; -import com.apitable.databusclient.ProgressResponseBody; - -import com.google.gson.reflect.TypeToken; - -import java.io.IOException; - - -import com.apitable.databusclient.model.ApiResponseAiPO; - -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class DataDaoApiApi { - private ApiClient localVarApiClient; - private int localHostIndex; - private String localCustomBaseUrl; - - public DataDaoApiApi() { - this(Configuration.getDefaultApiClient()); - } - - public DataDaoApiApi(ApiClient apiClient) { - this.localVarApiClient = apiClient; - } - - public ApiClient getApiClient() { - return localVarApiClient; - } - - public void setApiClient(ApiClient apiClient) { - this.localVarApiClient = apiClient; - } - - public int getHostIndex() { - return localHostIndex; - } - - public void setHostIndex(int hostIndex) { - this.localHostIndex = hostIndex; - } - - public String getCustomBaseUrl() { - return localCustomBaseUrl; - } - - public void setCustomBaseUrl(String customBaseUrl) { - this.localCustomBaseUrl = customBaseUrl; - } - - /** - * Build call for daoGetAiDatasheetIds - * @param aiId ai id (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get AI's datasheets success -
- */ - public okhttp3.Call daoGetAiDatasheetIdsCall(String aiId, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/databus/dao/get_ai_datasheet_ids/{ai_id}" - .replace("{" + "ai_id" + "}", localVarApiClient.escapeString(aiId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call daoGetAiDatasheetIdsValidateBeforeCall(String aiId, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'aiId' is set - if (aiId == null) { - throw new ApiException("Missing the required parameter 'aiId' when calling daoGetAiDatasheetIds(Async)"); - } - - return daoGetAiDatasheetIdsCall(aiId, _callback); - - } - - /** - * Get AI's binding datasheet ids by AI ID - * Get AI's binding datasheet ids by AI ID - * @param aiId ai id (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get AI's datasheets success -
- */ - public void daoGetAiDatasheetIds(String aiId) throws ApiException { - daoGetAiDatasheetIdsWithHttpInfo(aiId); - } - - /** - * Get AI's binding datasheet ids by AI ID - * Get AI's binding datasheet ids by AI ID - * @param aiId ai id (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get AI's datasheets success -
- */ - public ApiResponse daoGetAiDatasheetIdsWithHttpInfo(String aiId) throws ApiException { - okhttp3.Call localVarCall = daoGetAiDatasheetIdsValidateBeforeCall(aiId, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * Get AI's binding datasheet ids by AI ID (asynchronously) - * Get AI's binding datasheet ids by AI ID - * @param aiId ai id (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get AI's datasheets success -
- */ - public okhttp3.Call daoGetAiDatasheetIdsAsync(String aiId, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = daoGetAiDatasheetIdsValidateBeforeCall(aiId, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for daoGetAiNode - * @param aiId ai id (required) - * @param nodeId node id (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get AI Node success -
- */ - public okhttp3.Call daoGetAiNodeCall(String aiId, String nodeId, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/databus/dao/get_ai_node"; - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (aiId != null) { - localVarQueryParams.addAll(localVarApiClient.parameterToPair("ai_id", aiId)); - } - - if (nodeId != null) { - localVarQueryParams.addAll(localVarApiClient.parameterToPair("node_id", nodeId)); - } - - final String[] localVarAccepts = { - "application/json" - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call daoGetAiNodeValidateBeforeCall(String aiId, String nodeId, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'aiId' is set - if (aiId == null) { - throw new ApiException("Missing the required parameter 'aiId' when calling daoGetAiNode(Async)"); - } - - // verify the required parameter 'nodeId' is set - if (nodeId == null) { - throw new ApiException("Missing the required parameter 'nodeId' when calling daoGetAiNode(Async)"); - } - - return daoGetAiNodeCall(aiId, nodeId, _callback); - - } - - /** - * Get AI Node by AI ID - * Get AI Node by AI ID - * @param aiId ai id (required) - * @param nodeId node id (required) - * @return ApiResponseAiPO - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get AI Node success -
- */ - public ApiResponseAiPO daoGetAiNode(String aiId, String nodeId) throws ApiException { - ApiResponse localVarResp = daoGetAiNodeWithHttpInfo(aiId, nodeId); - return localVarResp.getData(); - } - - /** - * Get AI Node by AI ID - * Get AI Node by AI ID - * @param aiId ai id (required) - * @param nodeId node id (required) - * @return ApiResponse<ApiResponseAiPO> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get AI Node success -
- */ - public ApiResponse daoGetAiNodeWithHttpInfo(String aiId, String nodeId) throws ApiException { - okhttp3.Call localVarCall = daoGetAiNodeValidateBeforeCall(aiId, nodeId, null); - Type localVarReturnType = new TypeToken(){}.getType(); - return localVarApiClient.execute(localVarCall, localVarReturnType); - } - - /** - * Get AI Node by AI ID (asynchronously) - * Get AI Node by AI ID - * @param aiId ai id (required) - * @param nodeId node id (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get AI Node success -
- */ - public okhttp3.Call daoGetAiNodeAsync(String aiId, String nodeId, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = daoGetAiNodeValidateBeforeCall(aiId, nodeId, _callback); - Type localVarReturnType = new TypeToken(){}.getType(); - localVarApiClient.executeAsync(localVarCall, localVarReturnType, _callback); - return localVarCall; - } - /** - * Build call for daoGetAiPo - * @param aiId ai id (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get AI success -
- */ - public okhttp3.Call daoGetAiPoCall(String aiId, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/databus/dao/get_ai/{ai_id}" - .replace("{" + "ai_id" + "}", localVarApiClient.escapeString(aiId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - final String[] localVarAccepts = { - "application/json" - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call daoGetAiPoValidateBeforeCall(String aiId, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'aiId' is set - if (aiId == null) { - throw new ApiException("Missing the required parameter 'aiId' when calling daoGetAiPo(Async)"); - } - - return daoGetAiPoCall(aiId, _callback); - - } - - /** - * Get AI Entity by AI ID - * Get AI Entity by AI ID - * @param aiId ai id (required) - * @return ApiResponseAiPO - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get AI success -
- */ - public ApiResponseAiPO daoGetAiPo(String aiId) throws ApiException { - ApiResponse localVarResp = daoGetAiPoWithHttpInfo(aiId); - return localVarResp.getData(); - } - - /** - * Get AI Entity by AI ID - * Get AI Entity by AI ID - * @param aiId ai id (required) - * @return ApiResponse<ApiResponseAiPO> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get AI success -
- */ - public ApiResponse daoGetAiPoWithHttpInfo(String aiId) throws ApiException { - okhttp3.Call localVarCall = daoGetAiPoValidateBeforeCall(aiId, null); - Type localVarReturnType = new TypeToken(){}.getType(); - return localVarApiClient.execute(localVarCall, localVarReturnType); - } - - /** - * Get AI Entity by AI ID (asynchronously) - * Get AI Entity by AI ID - * @param aiId ai id (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get AI success -
- */ - public okhttp3.Call daoGetAiPoAsync(String aiId, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = daoGetAiPoValidateBeforeCall(aiId, _callback); - Type localVarReturnType = new TypeToken(){}.getType(); - localVarApiClient.executeAsync(localVarCall, localVarReturnType, _callback); - return localVarCall; - } - /** - * Build call for daoGetRevision - * @param datasheetId datasheet_id (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Revision number success -
- */ - public okhttp3.Call daoGetRevisionCall(String datasheetId, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/databus/dao/get_revision/{datasheet_id}" - .replace("{" + "datasheet_id" + "}", localVarApiClient.escapeString(datasheetId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call daoGetRevisionValidateBeforeCall(String datasheetId, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'datasheetId' is set - if (datasheetId == null) { - throw new ApiException("Missing the required parameter 'datasheetId' when calling daoGetRevision(Async)"); - } - - return daoGetRevisionCall(datasheetId, _callback); - - } - - /** - * Get Datasheet's Revision number - * Get Datasheet's Revision number - * @param datasheetId datasheet_id (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Revision number success -
- */ - public void daoGetRevision(String datasheetId) throws ApiException { - daoGetRevisionWithHttpInfo(datasheetId); - } - - /** - * Get Datasheet's Revision number - * Get Datasheet's Revision number - * @param datasheetId datasheet_id (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Revision number success -
- */ - public ApiResponse daoGetRevisionWithHttpInfo(String datasheetId) throws ApiException { - okhttp3.Call localVarCall = daoGetRevisionValidateBeforeCall(datasheetId, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * Get Datasheet's Revision number (asynchronously) - * Get Datasheet's Revision number - * @param datasheetId datasheet_id (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Revision number success -
- */ - public okhttp3.Call daoGetRevisionAsync(String datasheetId, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = daoGetRevisionValidateBeforeCall(datasheetId, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } -} diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/api/DataServicesApiApi.java b/backend-server/application/src/main/java/com/apitable/databusclient/api/DataServicesApiApi.java deleted file mode 100644 index 1ddd131bd2..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/api/DataServicesApiApi.java +++ /dev/null @@ -1,366 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.api; - -import com.apitable.databusclient.ApiCallback; -import com.apitable.databusclient.ApiClient; -import com.apitable.databusclient.ApiException; -import com.apitable.databusclient.ApiResponse; -import com.apitable.databusclient.Configuration; -import com.apitable.databusclient.Pair; -import com.apitable.databusclient.ProgressRequestBody; -import com.apitable.databusclient.ProgressResponseBody; - -import com.google.gson.reflect.TypeToken; - -import java.io.IOException; - - -import com.apitable.databusclient.model.ApiResponseDatasheetPackSO; - -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class DataServicesApiApi { - private ApiClient localVarApiClient; - private int localHostIndex; - private String localCustomBaseUrl; - - public DataServicesApiApi() { - this(Configuration.getDefaultApiClient()); - } - - public DataServicesApiApi(ApiClient apiClient) { - this.localVarApiClient = apiClient; - } - - public ApiClient getApiClient() { - return localVarApiClient; - } - - public void setApiClient(ApiClient apiClient) { - this.localVarApiClient = apiClient; - } - - public int getHostIndex() { - return localHostIndex; - } - - public void setHostIndex(int hostIndex) { - this.localHostIndex = hostIndex; - } - - public String getCustomBaseUrl() { - return localCustomBaseUrl; - } - - public void setCustomBaseUrl(String customBaseUrl) { - this.localCustomBaseUrl = customBaseUrl; - } - - /** - * Build call for getDatasheetPack - * @param id datasheet id (required) - * @param userId (optional) - * @param spaceId (optional) - * @param viewId (optional) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 get data pack data -
- */ - public okhttp3.Call getDatasheetPackCall(String id, String userId, String spaceId, String viewId, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/databus/get_datasheet_pack/{id}" - .replace("{" + "id" + "}", localVarApiClient.escapeString(id.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (userId != null) { - localVarQueryParams.addAll(localVarApiClient.parameterToPair("userId", userId)); - } - - if (spaceId != null) { - localVarQueryParams.addAll(localVarApiClient.parameterToPair("spaceId", spaceId)); - } - - if (viewId != null) { - localVarQueryParams.addAll(localVarApiClient.parameterToPair("viewId", viewId)); - } - - final String[] localVarAccepts = { - "application/json" - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call getDatasheetPackValidateBeforeCall(String id, String userId, String spaceId, String viewId, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'id' is set - if (id == null) { - throw new ApiException("Missing the required parameter 'id' when calling getDatasheetPack(Async)"); - } - - return getDatasheetPackCall(id, userId, spaceId, viewId, _callback); - - } - - /** - * - * - * @param id datasheet id (required) - * @param userId (optional) - * @param spaceId (optional) - * @param viewId (optional) - * @return ApiResponseDatasheetPackSO - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 get data pack data -
- */ - public ApiResponseDatasheetPackSO getDatasheetPack(String id, String userId, String spaceId, String viewId) throws ApiException { - ApiResponse localVarResp = getDatasheetPackWithHttpInfo(id, userId, spaceId, viewId); - return localVarResp.getData(); - } - - /** - * - * - * @param id datasheet id (required) - * @param userId (optional) - * @param spaceId (optional) - * @param viewId (optional) - * @return ApiResponse<ApiResponseDatasheetPackSO> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 get data pack data -
- */ - public ApiResponse getDatasheetPackWithHttpInfo(String id, String userId, String spaceId, String viewId) throws ApiException { - okhttp3.Call localVarCall = getDatasheetPackValidateBeforeCall(id, userId, spaceId, viewId, null); - Type localVarReturnType = new TypeToken(){}.getType(); - return localVarApiClient.execute(localVarCall, localVarReturnType); - } - - /** - * (asynchronously) - * - * @param id datasheet id (required) - * @param userId (optional) - * @param spaceId (optional) - * @param viewId (optional) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 get data pack data -
- */ - public okhttp3.Call getDatasheetPackAsync(String id, String userId, String spaceId, String viewId, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = getDatasheetPackValidateBeforeCall(id, userId, spaceId, viewId, _callback); - Type localVarReturnType = new TypeToken(){}.getType(); - localVarApiClient.executeAsync(localVarCall, localVarReturnType, _callback); - return localVarCall; - } - /** - * Build call for getRecords - * @param dstId (optional) - * @param userId (optional) - * @param spaceId (optional) - * @param viewId (optional) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - - -
Status Code Description Response Headers
200 Patch completed -
406 Not accepted -
- */ - public okhttp3.Call getRecordsCall(String dstId, String userId, String spaceId, String viewId, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/databus/get_records"; - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (dstId != null) { - localVarQueryParams.addAll(localVarApiClient.parameterToPair("dstId", dstId)); - } - - if (userId != null) { - localVarQueryParams.addAll(localVarApiClient.parameterToPair("userId", userId)); - } - - if (spaceId != null) { - localVarQueryParams.addAll(localVarApiClient.parameterToPair("spaceId", spaceId)); - } - - if (viewId != null) { - localVarQueryParams.addAll(localVarApiClient.parameterToPair("viewId", viewId)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call getRecordsValidateBeforeCall(String dstId, String userId, String spaceId, String viewId, final ApiCallback _callback) throws ApiException { - return getRecordsCall(dstId, userId, spaceId, viewId, _callback); - - } - - /** - * - * - * @param dstId (optional) - * @param userId (optional) - * @param spaceId (optional) - * @param viewId (optional) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - - -
Status Code Description Response Headers
200 Patch completed -
406 Not accepted -
- */ - public void getRecords(String dstId, String userId, String spaceId, String viewId) throws ApiException { - getRecordsWithHttpInfo(dstId, userId, spaceId, viewId); - } - - /** - * - * - * @param dstId (optional) - * @param userId (optional) - * @param spaceId (optional) - * @param viewId (optional) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - - -
Status Code Description Response Headers
200 Patch completed -
406 Not accepted -
- */ - public ApiResponse getRecordsWithHttpInfo(String dstId, String userId, String spaceId, String viewId) throws ApiException { - okhttp3.Call localVarCall = getRecordsValidateBeforeCall(dstId, userId, spaceId, viewId, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * (asynchronously) - * - * @param dstId (optional) - * @param userId (optional) - * @param spaceId (optional) - * @param viewId (optional) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - - -
Status Code Description Response Headers
200 Patch completed -
406 Not accepted -
- */ - public okhttp3.Call getRecordsAsync(String dstId, String userId, String spaceId, String viewId, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = getRecordsValidateBeforeCall(dstId, userId, spaceId, viewId, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } -} diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/api/DocumentDaoApiApi.java b/backend-server/application/src/main/java/com/apitable/databusclient/api/DocumentDaoApiApi.java deleted file mode 100644 index d8234f1ca6..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/api/DocumentDaoApiApi.java +++ /dev/null @@ -1,558 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.api; - -import com.apitable.databusclient.ApiCallback; -import com.apitable.databusclient.ApiClient; -import com.apitable.databusclient.ApiException; -import com.apitable.databusclient.ApiResponse; -import com.apitable.databusclient.Configuration; -import com.apitable.databusclient.Pair; -import com.apitable.databusclient.ProgressRequestBody; -import com.apitable.databusclient.ProgressResponseBody; - -import com.google.gson.reflect.TypeToken; - -import java.io.IOException; - - -import com.apitable.databusclient.model.DocumentOperationRO; -import com.apitable.databusclient.model.DocumentRO; - -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class DocumentDaoApiApi { - private ApiClient localVarApiClient; - private int localHostIndex; - private String localCustomBaseUrl; - - public DocumentDaoApiApi() { - this(Configuration.getDefaultApiClient()); - } - - public DocumentDaoApiApi(ApiClient apiClient) { - this.localVarApiClient = apiClient; - } - - public ApiClient getApiClient() { - return localVarApiClient; - } - - public void setApiClient(ApiClient apiClient) { - this.localVarApiClient = apiClient; - } - - public int getHostIndex() { - return localHostIndex; - } - - public void setHostIndex(int hostIndex) { - this.localHostIndex = hostIndex; - } - - public String getCustomBaseUrl() { - return localCustomBaseUrl; - } - - public void setCustomBaseUrl(String customBaseUrl) { - this.localCustomBaseUrl = customBaseUrl; - } - - /** - * Build call for daoCreateDocumentOperation - * @param documentName document name (required) - * @param documentOperationRO (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 create document operation successfully -
- */ - public okhttp3.Call daoCreateDocumentOperationCall(String documentName, DocumentOperationRO documentOperationRO, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = documentOperationRO; - - // create path and map variables - String localVarPath = "/databus/dao/documents/{document_name}/operations" - .replace("{" + "document_name" + "}", localVarApiClient.escapeString(documentName.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - "application/json" - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "POST", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call daoCreateDocumentOperationValidateBeforeCall(String documentName, DocumentOperationRO documentOperationRO, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'documentName' is set - if (documentName == null) { - throw new ApiException("Missing the required parameter 'documentName' when calling daoCreateDocumentOperation(Async)"); - } - - // verify the required parameter 'documentOperationRO' is set - if (documentOperationRO == null) { - throw new ApiException("Missing the required parameter 'documentOperationRO' when calling daoCreateDocumentOperation(Async)"); - } - - return daoCreateDocumentOperationCall(documentName, documentOperationRO, _callback); - - } - - /** - * create document operation success - * create document operation success - * @param documentName document name (required) - * @param documentOperationRO (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 create document operation successfully -
- */ - public void daoCreateDocumentOperation(String documentName, DocumentOperationRO documentOperationRO) throws ApiException { - daoCreateDocumentOperationWithHttpInfo(documentName, documentOperationRO); - } - - /** - * create document operation success - * create document operation success - * @param documentName document name (required) - * @param documentOperationRO (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 create document operation successfully -
- */ - public ApiResponse daoCreateDocumentOperationWithHttpInfo(String documentName, DocumentOperationRO documentOperationRO) throws ApiException { - okhttp3.Call localVarCall = daoCreateDocumentOperationValidateBeforeCall(documentName, documentOperationRO, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * create document operation success (asynchronously) - * create document operation success - * @param documentName document name (required) - * @param documentOperationRO (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 create document operation successfully -
- */ - public okhttp3.Call daoCreateDocumentOperationAsync(String documentName, DocumentOperationRO documentOperationRO, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = daoCreateDocumentOperationValidateBeforeCall(documentName, documentOperationRO, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for daoCreateOrUpdateDocument - * @param documentName document name (required) - * @param documentRO (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Create or update document successfully -
- */ - public okhttp3.Call daoCreateOrUpdateDocumentCall(String documentName, DocumentRO documentRO, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = documentRO; - - // create path and map variables - String localVarPath = "/databus/dao/documents/{document_name}" - .replace("{" + "document_name" + "}", localVarApiClient.escapeString(documentName.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - "application/json" - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "PUT", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call daoCreateOrUpdateDocumentValidateBeforeCall(String documentName, DocumentRO documentRO, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'documentName' is set - if (documentName == null) { - throw new ApiException("Missing the required parameter 'documentName' when calling daoCreateOrUpdateDocument(Async)"); - } - - // verify the required parameter 'documentRO' is set - if (documentRO == null) { - throw new ApiException("Missing the required parameter 'documentRO' when calling daoCreateOrUpdateDocument(Async)"); - } - - return daoCreateOrUpdateDocumentCall(documentName, documentRO, _callback); - - } - - /** - * Create or update document - * Create or update document - * @param documentName document name (required) - * @param documentRO (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Create or update document successfully -
- */ - public void daoCreateOrUpdateDocument(String documentName, DocumentRO documentRO) throws ApiException { - daoCreateOrUpdateDocumentWithHttpInfo(documentName, documentRO); - } - - /** - * Create or update document - * Create or update document - * @param documentName document name (required) - * @param documentRO (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Create or update document successfully -
- */ - public ApiResponse daoCreateOrUpdateDocumentWithHttpInfo(String documentName, DocumentRO documentRO) throws ApiException { - okhttp3.Call localVarCall = daoCreateOrUpdateDocumentValidateBeforeCall(documentName, documentRO, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * Create or update document (asynchronously) - * Create or update document - * @param documentName document name (required) - * @param documentRO (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Create or update document successfully -
- */ - public okhttp3.Call daoCreateOrUpdateDocumentAsync(String documentName, DocumentRO documentRO, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = daoCreateOrUpdateDocumentValidateBeforeCall(documentName, documentRO, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for daoGetDocumentData - * @param documentName document name (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get document data successfully -
- */ - public okhttp3.Call daoGetDocumentDataCall(String documentName, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/databus/dao/documents/{document_name}/data" - .replace("{" + "document_name" + "}", localVarApiClient.escapeString(documentName.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call daoGetDocumentDataValidateBeforeCall(String documentName, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'documentName' is set - if (documentName == null) { - throw new ApiException("Missing the required parameter 'documentName' when calling daoGetDocumentData(Async)"); - } - - return daoGetDocumentDataCall(documentName, _callback); - - } - - /** - * Get document data - * Get document data - * @param documentName document name (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get document data successfully -
- */ - public void daoGetDocumentData(String documentName) throws ApiException { - daoGetDocumentDataWithHttpInfo(documentName); - } - - /** - * Get document data - * Get document data - * @param documentName document name (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get document data successfully -
- */ - public ApiResponse daoGetDocumentDataWithHttpInfo(String documentName) throws ApiException { - okhttp3.Call localVarCall = daoGetDocumentDataValidateBeforeCall(documentName, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * Get document data (asynchronously) - * Get document data - * @param documentName document name (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get document data successfully -
- */ - public okhttp3.Call daoGetDocumentDataAsync(String documentName, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = daoGetDocumentDataValidateBeforeCall(documentName, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for daoGetNewDocumentName - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get new document name successfully -
- */ - public okhttp3.Call daoGetNewDocumentNameCall(final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/databus/dao/documents/name"; - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call daoGetNewDocumentNameValidateBeforeCall(final ApiCallback _callback) throws ApiException { - return daoGetNewDocumentNameCall(_callback); - - } - - /** - * Get new document name - * Get new document name - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get new document name successfully -
- */ - public void daoGetNewDocumentName() throws ApiException { - daoGetNewDocumentNameWithHttpInfo(); - } - - /** - * Get new document name - * Get new document name - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get new document name successfully -
- */ - public ApiResponse daoGetNewDocumentNameWithHttpInfo() throws ApiException { - okhttp3.Call localVarCall = daoGetNewDocumentNameValidateBeforeCall(null); - return localVarApiClient.execute(localVarCall); - } - - /** - * Get new document name (asynchronously) - * Get new document name - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get new document name successfully -
- */ - public okhttp3.Call daoGetNewDocumentNameAsync(final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = daoGetNewDocumentNameValidateBeforeCall(_callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } -} diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/api/EnterpriseFusionApiApi.java b/backend-server/application/src/main/java/com/apitable/databusclient/api/EnterpriseFusionApiApi.java deleted file mode 100644 index 2455227493..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/api/EnterpriseFusionApiApi.java +++ /dev/null @@ -1,3670 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.api; - -import com.apitable.databusclient.ApiCallback; -import com.apitable.databusclient.ApiClient; -import com.apitable.databusclient.ApiException; -import com.apitable.databusclient.ApiResponse; -import com.apitable.databusclient.Configuration; -import com.apitable.databusclient.Pair; -import com.apitable.databusclient.ProgressRequestBody; -import com.apitable.databusclient.ProgressResponseBody; - -import com.google.gson.reflect.TypeToken; - -import java.io.IOException; - - - -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class EnterpriseFusionApiApi { - private ApiClient localVarApiClient; - private int localHostIndex; - private String localCustomBaseUrl; - - public EnterpriseFusionApiApi() { - this(Configuration.getDefaultApiClient()); - } - - public EnterpriseFusionApiApi(ApiClient apiClient) { - this.localVarApiClient = apiClient; - } - - public ApiClient getApiClient() { - return localVarApiClient; - } - - public void setApiClient(ApiClient apiClient) { - this.localVarApiClient = apiClient; - } - - public int getHostIndex() { - return localHostIndex; - } - - public void setHostIndex(int hostIndex) { - this.localHostIndex = hostIndex; - } - - public String getCustomBaseUrl() { - return localCustomBaseUrl; - } - - public void setCustomBaseUrl(String customBaseUrl) { - this.localCustomBaseUrl = customBaseUrl; - } - - /** - * Build call for batchDeleteView - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 batch_delete_view successfully -
- */ - public okhttp3.Call batchDeleteViewCall(String dstId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/datasheets/{dst_id}/views" - .replace("{" + "dst_id" + "}", localVarApiClient.escapeString(dstId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "DELETE", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call batchDeleteViewValidateBeforeCall(String dstId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'dstId' is set - if (dstId == null) { - throw new ApiException("Missing the required parameter 'dstId' when calling batchDeleteView(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling batchDeleteView(Async)"); - } - - return batchDeleteViewCall(dstId, authorization, _callback); - - } - - /** - * batch_delete_view - * batch_delete_view Batch delete views in a specified datasheet - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 batch_delete_view successfully -
- */ - public void batchDeleteView(String dstId, String authorization) throws ApiException { - batchDeleteViewWithHttpInfo(dstId, authorization); - } - - /** - * batch_delete_view - * batch_delete_view Batch delete views in a specified datasheet - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 batch_delete_view successfully -
- */ - public ApiResponse batchDeleteViewWithHttpInfo(String dstId, String authorization) throws ApiException { - okhttp3.Call localVarCall = batchDeleteViewValidateBeforeCall(dstId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * batch_delete_view (asynchronously) - * batch_delete_view Batch delete views in a specified datasheet - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 batch_delete_view successfully -
- */ - public okhttp3.Call batchDeleteViewAsync(String dstId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = batchDeleteViewValidateBeforeCall(dstId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for copyView - * @param dstId dst_id (required) - * @param viewId view_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 copy_view successfully -
- */ - public okhttp3.Call copyViewCall(String dstId, String viewId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/datasheets/{dst_id}/views/{view_id}/duplicate" - .replace("{" + "dst_id" + "}", localVarApiClient.escapeString(dstId.toString())) - .replace("{" + "view_id" + "}", localVarApiClient.escapeString(viewId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "POST", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call copyViewValidateBeforeCall(String dstId, String viewId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'dstId' is set - if (dstId == null) { - throw new ApiException("Missing the required parameter 'dstId' when calling copyView(Async)"); - } - - // verify the required parameter 'viewId' is set - if (viewId == null) { - throw new ApiException("Missing the required parameter 'viewId' when calling copyView(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling copyView(Async)"); - } - - return copyViewCall(dstId, viewId, authorization, _callback); - - } - - /** - * copy_view - * copy_view copy a view at a specified datasheet - * @param dstId dst_id (required) - * @param viewId view_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 copy_view successfully -
- */ - public void copyView(String dstId, String viewId, String authorization) throws ApiException { - copyViewWithHttpInfo(dstId, viewId, authorization); - } - - /** - * copy_view - * copy_view copy a view at a specified datasheet - * @param dstId dst_id (required) - * @param viewId view_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 copy_view successfully -
- */ - public ApiResponse copyViewWithHttpInfo(String dstId, String viewId, String authorization) throws ApiException { - okhttp3.Call localVarCall = copyViewValidateBeforeCall(dstId, viewId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * copy_view (asynchronously) - * copy_view copy a view at a specified datasheet - * @param dstId dst_id (required) - * @param viewId view_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 copy_view successfully -
- */ - public okhttp3.Call copyViewAsync(String dstId, String viewId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = copyViewValidateBeforeCall(dstId, viewId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for createChatCompletion - * @param aiId ai_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 create_chat_completion successfully -
- */ - public okhttp3.Call createChatCompletionCall(String aiId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/ai/{ai_id}/chat/completions" - .replace("{" + "ai_id" + "}", localVarApiClient.escapeString(aiId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "POST", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call createChatCompletionValidateBeforeCall(String aiId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'aiId' is set - if (aiId == null) { - throw new ApiException("Missing the required parameter 'aiId' when calling createChatCompletion(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling createChatCompletion(Async)"); - } - - return createChatCompletionCall(aiId, authorization, _callback); - - } - - /** - * create_chat_completion - * create_chat_completion Creates a model response for the given chat conversation - * @param aiId ai_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 create_chat_completion successfully -
- */ - public void createChatCompletion(String aiId, String authorization) throws ApiException { - createChatCompletionWithHttpInfo(aiId, authorization); - } - - /** - * create_chat_completion - * create_chat_completion Creates a model response for the given chat conversation - * @param aiId ai_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 create_chat_completion successfully -
- */ - public ApiResponse createChatCompletionWithHttpInfo(String aiId, String authorization) throws ApiException { - okhttp3.Call localVarCall = createChatCompletionValidateBeforeCall(aiId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * create_chat_completion (asynchronously) - * create_chat_completion Creates a model response for the given chat conversation - * @param aiId ai_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 create_chat_completion successfully -
- */ - public okhttp3.Call createChatCompletionAsync(String aiId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = createChatCompletionValidateBeforeCall(aiId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for createEmbedLink - * @param spaceId space_id (required) - * @param nodeId node_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 create_embed_link successfully -
- */ - public okhttp3.Call createEmbedLinkCall(String spaceId, String nodeId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/spaces/{space_id}/nodes/{node_id}/embedlinks" - .replace("{" + "space_id" + "}", localVarApiClient.escapeString(spaceId.toString())) - .replace("{" + "node_id" + "}", localVarApiClient.escapeString(nodeId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "POST", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call createEmbedLinkValidateBeforeCall(String spaceId, String nodeId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'spaceId' is set - if (spaceId == null) { - throw new ApiException("Missing the required parameter 'spaceId' when calling createEmbedLink(Async)"); - } - - // verify the required parameter 'nodeId' is set - if (nodeId == null) { - throw new ApiException("Missing the required parameter 'nodeId' when calling createEmbedLink(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling createEmbedLink(Async)"); - } - - return createEmbedLinkCall(spaceId, nodeId, authorization, _callback); - - } - - /** - * create_embed_link - * create_embed_link Creates an \"embed link\" for the specified node - * @param spaceId space_id (required) - * @param nodeId node_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 create_embed_link successfully -
- */ - public void createEmbedLink(String spaceId, String nodeId, String authorization) throws ApiException { - createEmbedLinkWithHttpInfo(spaceId, nodeId, authorization); - } - - /** - * create_embed_link - * create_embed_link Creates an \"embed link\" for the specified node - * @param spaceId space_id (required) - * @param nodeId node_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 create_embed_link successfully -
- */ - public ApiResponse createEmbedLinkWithHttpInfo(String spaceId, String nodeId, String authorization) throws ApiException { - okhttp3.Call localVarCall = createEmbedLinkValidateBeforeCall(spaceId, nodeId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * create_embed_link (asynchronously) - * create_embed_link Creates an \"embed link\" for the specified node - * @param spaceId space_id (required) - * @param nodeId node_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 create_embed_link successfully -
- */ - public okhttp3.Call createEmbedLinkAsync(String spaceId, String nodeId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = createEmbedLinkValidateBeforeCall(spaceId, nodeId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for createMember - * @param spaceId space_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 create_member successfully -
- */ - public okhttp3.Call createMemberCall(String spaceId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/spaces/{space_id}/members" - .replace("{" + "space_id" + "}", localVarApiClient.escapeString(spaceId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "POST", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call createMemberValidateBeforeCall(String spaceId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'spaceId' is set - if (spaceId == null) { - throw new ApiException("Missing the required parameter 'spaceId' when calling createMember(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling createMember(Async)"); - } - - return createMemberCall(spaceId, authorization, _callback); - - } - - /** - * create_member - * create_member Create a member for a specified space - * @param spaceId space_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 create_member successfully -
- */ - public void createMember(String spaceId, String authorization) throws ApiException { - createMemberWithHttpInfo(spaceId, authorization); - } - - /** - * create_member - * create_member Create a member for a specified space - * @param spaceId space_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 create_member successfully -
- */ - public ApiResponse createMemberWithHttpInfo(String spaceId, String authorization) throws ApiException { - okhttp3.Call localVarCall = createMemberValidateBeforeCall(spaceId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * create_member (asynchronously) - * create_member Create a member for a specified space - * @param spaceId space_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 create_member successfully -
- */ - public okhttp3.Call createMemberAsync(String spaceId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = createMemberValidateBeforeCall(spaceId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for createRole - * @param spaceId space_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 create_role successfully -
- */ - public okhttp3.Call createRoleCall(String spaceId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/spaces/{space_id}/roles" - .replace("{" + "space_id" + "}", localVarApiClient.escapeString(spaceId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "POST", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call createRoleValidateBeforeCall(String spaceId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'spaceId' is set - if (spaceId == null) { - throw new ApiException("Missing the required parameter 'spaceId' when calling createRole(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling createRole(Async)"); - } - - return createRoleCall(spaceId, authorization, _callback); - - } - - /** - * create_role - * create_role Create a role for a specified space. - * @param spaceId space_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 create_role successfully -
- */ - public void createRole(String spaceId, String authorization) throws ApiException { - createRoleWithHttpInfo(spaceId, authorization); - } - - /** - * create_role - * create_role Create a role for a specified space. - * @param spaceId space_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 create_role successfully -
- */ - public ApiResponse createRoleWithHttpInfo(String spaceId, String authorization) throws ApiException { - okhttp3.Call localVarCall = createRoleValidateBeforeCall(spaceId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * create_role (asynchronously) - * create_role Create a role for a specified space. - * @param spaceId space_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 create_role successfully -
- */ - public okhttp3.Call createRoleAsync(String spaceId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = createRoleValidateBeforeCall(spaceId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for createTeam - * @param spaceId space_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 create_team successfully -
- */ - public okhttp3.Call createTeamCall(String spaceId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/spaces/{space_id}/teams" - .replace("{" + "space_id" + "}", localVarApiClient.escapeString(spaceId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "POST", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call createTeamValidateBeforeCall(String spaceId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'spaceId' is set - if (spaceId == null) { - throw new ApiException("Missing the required parameter 'spaceId' when calling createTeam(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling createTeam(Async)"); - } - - return createTeamCall(spaceId, authorization, _callback); - - } - - /** - * create_team - * create_team Create a team for a specified space. - * @param spaceId space_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 create_team successfully -
- */ - public void createTeam(String spaceId, String authorization) throws ApiException { - createTeamWithHttpInfo(spaceId, authorization); - } - - /** - * create_team - * create_team Create a team for a specified space. - * @param spaceId space_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 create_team successfully -
- */ - public ApiResponse createTeamWithHttpInfo(String spaceId, String authorization) throws ApiException { - okhttp3.Call localVarCall = createTeamValidateBeforeCall(spaceId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * create_team (asynchronously) - * create_team Create a team for a specified space. - * @param spaceId space_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 create_team successfully -
- */ - public okhttp3.Call createTeamAsync(String spaceId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = createTeamValidateBeforeCall(spaceId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for createView - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 create_view successfully -
- */ - public okhttp3.Call createViewCall(String dstId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/datasheets/{dst_id}/views" - .replace("{" + "dst_id" + "}", localVarApiClient.escapeString(dstId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "POST", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call createViewValidateBeforeCall(String dstId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'dstId' is set - if (dstId == null) { - throw new ApiException("Missing the required parameter 'dstId' when calling createView(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling createView(Async)"); - } - - return createViewCall(dstId, authorization, _callback); - - } - - /** - * create_view - * create_view Add a view to a specified datasheet - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 create_view successfully -
- */ - public void createView(String dstId, String authorization) throws ApiException { - createViewWithHttpInfo(dstId, authorization); - } - - /** - * create_view - * create_view Add a view to a specified datasheet - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 create_view successfully -
- */ - public ApiResponse createViewWithHttpInfo(String dstId, String authorization) throws ApiException { - okhttp3.Call localVarCall = createViewValidateBeforeCall(dstId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * create_view (asynchronously) - * create_view Add a view to a specified datasheet - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 create_view successfully -
- */ - public okhttp3.Call createViewAsync(String dstId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = createViewValidateBeforeCall(dstId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for createWidget - * @param dashboardId dashboard_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 create_widget successfully -
- */ - public okhttp3.Call createWidgetCall(String dashboardId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/dashboards/{dashboard_id}/widgets" - .replace("{" + "dashboard_id" + "}", localVarApiClient.escapeString(dashboardId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "POST", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call createWidgetValidateBeforeCall(String dashboardId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'dashboardId' is set - if (dashboardId == null) { - throw new ApiException("Missing the required parameter 'dashboardId' when calling createWidget(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling createWidget(Async)"); - } - - return createWidgetCall(dashboardId, authorization, _callback); - - } - - /** - * create_widget - * create_widget Add a widget to a specified dashboard - * @param dashboardId dashboard_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 create_widget successfully -
- */ - public void createWidget(String dashboardId, String authorization) throws ApiException { - createWidgetWithHttpInfo(dashboardId, authorization); - } - - /** - * create_widget - * create_widget Add a widget to a specified dashboard - * @param dashboardId dashboard_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 create_widget successfully -
- */ - public ApiResponse createWidgetWithHttpInfo(String dashboardId, String authorization) throws ApiException { - okhttp3.Call localVarCall = createWidgetValidateBeforeCall(dashboardId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * create_widget (asynchronously) - * create_widget Add a widget to a specified dashboard - * @param dashboardId dashboard_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 create_widget successfully -
- */ - public okhttp3.Call createWidgetAsync(String dashboardId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = createWidgetValidateBeforeCall(dashboardId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for deleteEmbedLink - * @param spaceId space_id (required) - * @param nodeId node_id (required) - * @param linkId link_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 delete_embed_link successfully -
- */ - public okhttp3.Call deleteEmbedLinkCall(String spaceId, String nodeId, String linkId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/spaces/{space_id}/nodes/{node_id}/embedlinks/{link_id}" - .replace("{" + "space_id" + "}", localVarApiClient.escapeString(spaceId.toString())) - .replace("{" + "node_id" + "}", localVarApiClient.escapeString(nodeId.toString())) - .replace("{" + "link_id" + "}", localVarApiClient.escapeString(linkId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "DELETE", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call deleteEmbedLinkValidateBeforeCall(String spaceId, String nodeId, String linkId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'spaceId' is set - if (spaceId == null) { - throw new ApiException("Missing the required parameter 'spaceId' when calling deleteEmbedLink(Async)"); - } - - // verify the required parameter 'nodeId' is set - if (nodeId == null) { - throw new ApiException("Missing the required parameter 'nodeId' when calling deleteEmbedLink(Async)"); - } - - // verify the required parameter 'linkId' is set - if (linkId == null) { - throw new ApiException("Missing the required parameter 'linkId' when calling deleteEmbedLink(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling deleteEmbedLink(Async)"); - } - - return deleteEmbedLinkCall(spaceId, nodeId, linkId, authorization, _callback); - - } - - /** - * delete_embed_link - * delete_embed_link Removes the specified Advanced Embed link. After deleted, the link cannot be accessed. - * @param spaceId space_id (required) - * @param nodeId node_id (required) - * @param linkId link_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 delete_embed_link successfully -
- */ - public void deleteEmbedLink(String spaceId, String nodeId, String linkId, String authorization) throws ApiException { - deleteEmbedLinkWithHttpInfo(spaceId, nodeId, linkId, authorization); - } - - /** - * delete_embed_link - * delete_embed_link Removes the specified Advanced Embed link. After deleted, the link cannot be accessed. - * @param spaceId space_id (required) - * @param nodeId node_id (required) - * @param linkId link_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 delete_embed_link successfully -
- */ - public ApiResponse deleteEmbedLinkWithHttpInfo(String spaceId, String nodeId, String linkId, String authorization) throws ApiException { - okhttp3.Call localVarCall = deleteEmbedLinkValidateBeforeCall(spaceId, nodeId, linkId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * delete_embed_link (asynchronously) - * delete_embed_link Removes the specified Advanced Embed link. After deleted, the link cannot be accessed. - * @param spaceId space_id (required) - * @param nodeId node_id (required) - * @param linkId link_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 delete_embed_link successfully -
- */ - public okhttp3.Call deleteEmbedLinkAsync(String spaceId, String nodeId, String linkId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = deleteEmbedLinkValidateBeforeCall(spaceId, nodeId, linkId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for deleteMember - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 delete_member successfully -
- */ - public okhttp3.Call deleteMemberCall(String spaceId, String unitId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/spaces/{space_id}/members/{unit_id}" - .replace("{" + "space_id" + "}", localVarApiClient.escapeString(spaceId.toString())) - .replace("{" + "unit_id" + "}", localVarApiClient.escapeString(unitId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "DELETE", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call deleteMemberValidateBeforeCall(String spaceId, String unitId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'spaceId' is set - if (spaceId == null) { - throw new ApiException("Missing the required parameter 'spaceId' when calling deleteMember(Async)"); - } - - // verify the required parameter 'unitId' is set - if (unitId == null) { - throw new ApiException("Missing the required parameter 'unitId' when calling deleteMember(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling deleteMember(Async)"); - } - - return deleteMemberCall(spaceId, unitId, authorization, _callback); - - } - - /** - * delete_member - * delete_member Delete a member for a specified space. - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 delete_member successfully -
- */ - public void deleteMember(String spaceId, String unitId, String authorization) throws ApiException { - deleteMemberWithHttpInfo(spaceId, unitId, authorization); - } - - /** - * delete_member - * delete_member Delete a member for a specified space. - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 delete_member successfully -
- */ - public ApiResponse deleteMemberWithHttpInfo(String spaceId, String unitId, String authorization) throws ApiException { - okhttp3.Call localVarCall = deleteMemberValidateBeforeCall(spaceId, unitId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * delete_member (asynchronously) - * delete_member Delete a member for a specified space. - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 delete_member successfully -
- */ - public okhttp3.Call deleteMemberAsync(String spaceId, String unitId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = deleteMemberValidateBeforeCall(spaceId, unitId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for deleteRole - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 delete_role successfully -
- */ - public okhttp3.Call deleteRoleCall(String spaceId, String unitId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/spaces/{space_id}/roles/{unit_id}" - .replace("{" + "space_id" + "}", localVarApiClient.escapeString(spaceId.toString())) - .replace("{" + "unit_id" + "}", localVarApiClient.escapeString(unitId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "DELETE", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call deleteRoleValidateBeforeCall(String spaceId, String unitId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'spaceId' is set - if (spaceId == null) { - throw new ApiException("Missing the required parameter 'spaceId' when calling deleteRole(Async)"); - } - - // verify the required parameter 'unitId' is set - if (unitId == null) { - throw new ApiException("Missing the required parameter 'unitId' when calling deleteRole(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling deleteRole(Async)"); - } - - return deleteRoleCall(spaceId, unitId, authorization, _callback); - - } - - /** - * delete_role - * delete_role Delete a role for a specified space - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 delete_role successfully -
- */ - public void deleteRole(String spaceId, String unitId, String authorization) throws ApiException { - deleteRoleWithHttpInfo(spaceId, unitId, authorization); - } - - /** - * delete_role - * delete_role Delete a role for a specified space - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 delete_role successfully -
- */ - public ApiResponse deleteRoleWithHttpInfo(String spaceId, String unitId, String authorization) throws ApiException { - okhttp3.Call localVarCall = deleteRoleValidateBeforeCall(spaceId, unitId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * delete_role (asynchronously) - * delete_role Delete a role for a specified space - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 delete_role successfully -
- */ - public okhttp3.Call deleteRoleAsync(String spaceId, String unitId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = deleteRoleValidateBeforeCall(spaceId, unitId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for deleteTeam - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 delete_team successfully -
- */ - public okhttp3.Call deleteTeamCall(String spaceId, String unitId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/spaces/{space_id}/teams/{unit_id}" - .replace("{" + "space_id" + "}", localVarApiClient.escapeString(spaceId.toString())) - .replace("{" + "unit_id" + "}", localVarApiClient.escapeString(unitId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "DELETE", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call deleteTeamValidateBeforeCall(String spaceId, String unitId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'spaceId' is set - if (spaceId == null) { - throw new ApiException("Missing the required parameter 'spaceId' when calling deleteTeam(Async)"); - } - - // verify the required parameter 'unitId' is set - if (unitId == null) { - throw new ApiException("Missing the required parameter 'unitId' when calling deleteTeam(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling deleteTeam(Async)"); - } - - return deleteTeamCall(spaceId, unitId, authorization, _callback); - - } - - /** - * delete_team - * delete_team Delete a team for a specified space - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 delete_team successfully -
- */ - public void deleteTeam(String spaceId, String unitId, String authorization) throws ApiException { - deleteTeamWithHttpInfo(spaceId, unitId, authorization); - } - - /** - * delete_team - * delete_team Delete a team for a specified space - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 delete_team successfully -
- */ - public ApiResponse deleteTeamWithHttpInfo(String spaceId, String unitId, String authorization) throws ApiException { - okhttp3.Call localVarCall = deleteTeamValidateBeforeCall(spaceId, unitId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * delete_team (asynchronously) - * delete_team Delete a team for a specified space - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 delete_team successfully -
- */ - public okhttp3.Call deleteTeamAsync(String spaceId, String unitId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = deleteTeamValidateBeforeCall(spaceId, unitId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for deleteView - * @param dstId dst_id (required) - * @param viewId view_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 delete_view successfully -
- */ - public okhttp3.Call deleteViewCall(String dstId, String viewId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/datasheets/{dst_id}/views/{view_id}" - .replace("{" + "dst_id" + "}", localVarApiClient.escapeString(dstId.toString())) - .replace("{" + "view_id" + "}", localVarApiClient.escapeString(viewId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "DELETE", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call deleteViewValidateBeforeCall(String dstId, String viewId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'dstId' is set - if (dstId == null) { - throw new ApiException("Missing the required parameter 'dstId' when calling deleteView(Async)"); - } - - // verify the required parameter 'viewId' is set - if (viewId == null) { - throw new ApiException("Missing the required parameter 'viewId' when calling deleteView(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling deleteView(Async)"); - } - - return deleteViewCall(dstId, viewId, authorization, _callback); - - } - - /** - * delete_view - * delete_view Delete a view in a specified datasheet - * @param dstId dst_id (required) - * @param viewId view_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 delete_view successfully -
- */ - public void deleteView(String dstId, String viewId, String authorization) throws ApiException { - deleteViewWithHttpInfo(dstId, viewId, authorization); - } - - /** - * delete_view - * delete_view Delete a view in a specified datasheet - * @param dstId dst_id (required) - * @param viewId view_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 delete_view successfully -
- */ - public ApiResponse deleteViewWithHttpInfo(String dstId, String viewId, String authorization) throws ApiException { - okhttp3.Call localVarCall = deleteViewValidateBeforeCall(dstId, viewId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * delete_view (asynchronously) - * delete_view Delete a view in a specified datasheet - * @param dstId dst_id (required) - * @param viewId view_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 delete_view successfully -
- */ - public okhttp3.Call deleteViewAsync(String dstId, String viewId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = deleteViewValidateBeforeCall(dstId, viewId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for deleteWidget - * @param dashboardId dashboard_id (required) - * @param widgetId widget_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 delete_widget successfully -
- */ - public okhttp3.Call deleteWidgetCall(String dashboardId, String widgetId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/dashboards/{dashboard_id}/widgets/{widget_id}" - .replace("{" + "dashboard_id" + "}", localVarApiClient.escapeString(dashboardId.toString())) - .replace("{" + "widget_id" + "}", localVarApiClient.escapeString(widgetId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "DELETE", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call deleteWidgetValidateBeforeCall(String dashboardId, String widgetId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'dashboardId' is set - if (dashboardId == null) { - throw new ApiException("Missing the required parameter 'dashboardId' when calling deleteWidget(Async)"); - } - - // verify the required parameter 'widgetId' is set - if (widgetId == null) { - throw new ApiException("Missing the required parameter 'widgetId' when calling deleteWidget(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling deleteWidget(Async)"); - } - - return deleteWidgetCall(dashboardId, widgetId, authorization, _callback); - - } - - /** - * delete_widget - * delete_widget delete widget in a specified dashboard - * @param dashboardId dashboard_id (required) - * @param widgetId widget_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 delete_widget successfully -
- */ - public void deleteWidget(String dashboardId, String widgetId, String authorization) throws ApiException { - deleteWidgetWithHttpInfo(dashboardId, widgetId, authorization); - } - - /** - * delete_widget - * delete_widget delete widget in a specified dashboard - * @param dashboardId dashboard_id (required) - * @param widgetId widget_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 delete_widget successfully -
- */ - public ApiResponse deleteWidgetWithHttpInfo(String dashboardId, String widgetId, String authorization) throws ApiException { - okhttp3.Call localVarCall = deleteWidgetValidateBeforeCall(dashboardId, widgetId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * delete_widget (asynchronously) - * delete_widget delete widget in a specified dashboard - * @param dashboardId dashboard_id (required) - * @param widgetId widget_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 delete_widget successfully -
- */ - public okhttp3.Call deleteWidgetAsync(String dashboardId, String widgetId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = deleteWidgetValidateBeforeCall(dashboardId, widgetId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for getEmbedLinkList - * @param spaceId space_id (required) - * @param nodeId node_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 get_embed_link_list successfully -
- */ - public okhttp3.Call getEmbedLinkListCall(String spaceId, String nodeId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/spaces/{space_id}/nodes/{node_id}/embedlinks" - .replace("{" + "space_id" + "}", localVarApiClient.escapeString(spaceId.toString())) - .replace("{" + "node_id" + "}", localVarApiClient.escapeString(nodeId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call getEmbedLinkListValidateBeforeCall(String spaceId, String nodeId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'spaceId' is set - if (spaceId == null) { - throw new ApiException("Missing the required parameter 'spaceId' when calling getEmbedLinkList(Async)"); - } - - // verify the required parameter 'nodeId' is set - if (nodeId == null) { - throw new ApiException("Missing the required parameter 'nodeId' when calling getEmbedLinkList(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling getEmbedLinkList(Async)"); - } - - return getEmbedLinkListCall(spaceId, nodeId, authorization, _callback); - - } - - /** - * get_embed_link_list - * get_embed_link_list Get all embedded links for a specified node - * @param spaceId space_id (required) - * @param nodeId node_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 get_embed_link_list successfully -
- */ - public void getEmbedLinkList(String spaceId, String nodeId, String authorization) throws ApiException { - getEmbedLinkListWithHttpInfo(spaceId, nodeId, authorization); - } - - /** - * get_embed_link_list - * get_embed_link_list Get all embedded links for a specified node - * @param spaceId space_id (required) - * @param nodeId node_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 get_embed_link_list successfully -
- */ - public ApiResponse getEmbedLinkListWithHttpInfo(String spaceId, String nodeId, String authorization) throws ApiException { - okhttp3.Call localVarCall = getEmbedLinkListValidateBeforeCall(spaceId, nodeId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * get_embed_link_list (asynchronously) - * get_embed_link_list Get all embedded links for a specified node - * @param spaceId space_id (required) - * @param nodeId node_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 get_embed_link_list successfully -
- */ - public okhttp3.Call getEmbedLinkListAsync(String spaceId, String nodeId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = getEmbedLinkListValidateBeforeCall(spaceId, nodeId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for memberDetail - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 member_detail successfully -
- */ - public okhttp3.Call memberDetailCall(String spaceId, String unitId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/spaces/{space_id}/members/{unit_id}" - .replace("{" + "space_id" + "}", localVarApiClient.escapeString(spaceId.toString())) - .replace("{" + "unit_id" + "}", localVarApiClient.escapeString(unitId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call memberDetailValidateBeforeCall(String spaceId, String unitId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'spaceId' is set - if (spaceId == null) { - throw new ApiException("Missing the required parameter 'spaceId' when calling memberDetail(Async)"); - } - - // verify the required parameter 'unitId' is set - if (unitId == null) { - throw new ApiException("Missing the required parameter 'unitId' when calling memberDetail(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling memberDetail(Async)"); - } - - return memberDetailCall(spaceId, unitId, authorization, _callback); - - } - - /** - * member_detail - * member_detail Get member details information - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 member_detail successfully -
- */ - public void memberDetail(String spaceId, String unitId, String authorization) throws ApiException { - memberDetailWithHttpInfo(spaceId, unitId, authorization); - } - - /** - * member_detail - * member_detail Get member details information - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 member_detail successfully -
- */ - public ApiResponse memberDetailWithHttpInfo(String spaceId, String unitId, String authorization) throws ApiException { - okhttp3.Call localVarCall = memberDetailValidateBeforeCall(spaceId, unitId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * member_detail (asynchronously) - * member_detail Get member details information - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 member_detail successfully -
- */ - public okhttp3.Call memberDetailAsync(String spaceId, String unitId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = memberDetailValidateBeforeCall(spaceId, unitId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for roleList - * @param spaceId space_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 role_list successfully -
- */ - public okhttp3.Call roleListCall(String spaceId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/spaces/{space_id}/roles" - .replace("{" + "space_id" + "}", localVarApiClient.escapeString(spaceId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call roleListValidateBeforeCall(String spaceId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'spaceId' is set - if (spaceId == null) { - throw new ApiException("Missing the required parameter 'spaceId' when calling roleList(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling roleList(Async)"); - } - - return roleListCall(spaceId, authorization, _callback); - - } - - /** - * role_list - * role_list Get roles for a specified space - * @param spaceId space_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 role_list successfully -
- */ - public void roleList(String spaceId, String authorization) throws ApiException { - roleListWithHttpInfo(spaceId, authorization); - } - - /** - * role_list - * role_list Get roles for a specified space - * @param spaceId space_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 role_list successfully -
- */ - public ApiResponse roleListWithHttpInfo(String spaceId, String authorization) throws ApiException { - okhttp3.Call localVarCall = roleListValidateBeforeCall(spaceId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * role_list (asynchronously) - * role_list Get roles for a specified space - * @param spaceId space_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 role_list successfully -
- */ - public okhttp3.Call roleListAsync(String spaceId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = roleListValidateBeforeCall(spaceId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for roleUnitList - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 role_unit_list successfully -
- */ - public okhttp3.Call roleUnitListCall(String spaceId, String unitId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/spaces/{space_id}/roles/{unit_id}/units" - .replace("{" + "space_id" + "}", localVarApiClient.escapeString(spaceId.toString())) - .replace("{" + "unit_id" + "}", localVarApiClient.escapeString(unitId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call roleUnitListValidateBeforeCall(String spaceId, String unitId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'spaceId' is set - if (spaceId == null) { - throw new ApiException("Missing the required parameter 'spaceId' when calling roleUnitList(Async)"); - } - - // verify the required parameter 'unitId' is set - if (unitId == null) { - throw new ApiException("Missing the required parameter 'unitId' when calling roleUnitList(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling roleUnitList(Async)"); - } - - return roleUnitListCall(spaceId, unitId, authorization, _callback); - - } - - /** - * role_unit_list - * role_unit_list Get the organizational units under the specified role unitId, the returned data includes teams and members. - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 role_unit_list successfully -
- */ - public void roleUnitList(String spaceId, String unitId, String authorization) throws ApiException { - roleUnitListWithHttpInfo(spaceId, unitId, authorization); - } - - /** - * role_unit_list - * role_unit_list Get the organizational units under the specified role unitId, the returned data includes teams and members. - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 role_unit_list successfully -
- */ - public ApiResponse roleUnitListWithHttpInfo(String spaceId, String unitId, String authorization) throws ApiException { - okhttp3.Call localVarCall = roleUnitListValidateBeforeCall(spaceId, unitId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * role_unit_list (asynchronously) - * role_unit_list Get the organizational units under the specified role unitId, the returned data includes teams and members. - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 role_unit_list successfully -
- */ - public okhttp3.Call roleUnitListAsync(String spaceId, String unitId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = roleUnitListValidateBeforeCall(spaceId, unitId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for subTeamList - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 sub_team_list successfully -
- */ - public okhttp3.Call subTeamListCall(String spaceId, String unitId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/spaces/{space_id}/teams/{unit_id}/children" - .replace("{" + "space_id" + "}", localVarApiClient.escapeString(spaceId.toString())) - .replace("{" + "unit_id" + "}", localVarApiClient.escapeString(unitId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call subTeamListValidateBeforeCall(String spaceId, String unitId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'spaceId' is set - if (spaceId == null) { - throw new ApiException("Missing the required parameter 'spaceId' when calling subTeamList(Async)"); - } - - // verify the required parameter 'unitId' is set - if (unitId == null) { - throw new ApiException("Missing the required parameter 'unitId' when calling subTeamList(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling subTeamList(Async)"); - } - - return subTeamListCall(spaceId, unitId, authorization, _callback); - - } - - /** - * sub_team_list - * sub_team_list Get the list of sub teams of a team by UnitId. - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 sub_team_list successfully -
- */ - public void subTeamList(String spaceId, String unitId, String authorization) throws ApiException { - subTeamListWithHttpInfo(spaceId, unitId, authorization); - } - - /** - * sub_team_list - * sub_team_list Get the list of sub teams of a team by UnitId. - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 sub_team_list successfully -
- */ - public ApiResponse subTeamListWithHttpInfo(String spaceId, String unitId, String authorization) throws ApiException { - okhttp3.Call localVarCall = subTeamListValidateBeforeCall(spaceId, unitId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * sub_team_list (asynchronously) - * sub_team_list Get the list of sub teams of a team by UnitId. - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 sub_team_list successfully -
- */ - public okhttp3.Call subTeamListAsync(String spaceId, String unitId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = subTeamListValidateBeforeCall(spaceId, unitId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for teamMemberList - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 team_member_list successfully -
- */ - public okhttp3.Call teamMemberListCall(String spaceId, String unitId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/spaces/{space_id}/teams/{unit_id}/members" - .replace("{" + "space_id" + "}", localVarApiClient.escapeString(spaceId.toString())) - .replace("{" + "unit_id" + "}", localVarApiClient.escapeString(unitId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call teamMemberListValidateBeforeCall(String spaceId, String unitId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'spaceId' is set - if (spaceId == null) { - throw new ApiException("Missing the required parameter 'spaceId' when calling teamMemberList(Async)"); - } - - // verify the required parameter 'unitId' is set - if (unitId == null) { - throw new ApiException("Missing the required parameter 'unitId' when calling teamMemberList(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling teamMemberList(Async)"); - } - - return teamMemberListCall(spaceId, unitId, authorization, _callback); - - } - - /** - * team_member_list - * team_member_list List members under team. - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 team_member_list successfully -
- */ - public void teamMemberList(String spaceId, String unitId, String authorization) throws ApiException { - teamMemberListWithHttpInfo(spaceId, unitId, authorization); - } - - /** - * team_member_list - * team_member_list List members under team. - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 team_member_list successfully -
- */ - public ApiResponse teamMemberListWithHttpInfo(String spaceId, String unitId, String authorization) throws ApiException { - okhttp3.Call localVarCall = teamMemberListValidateBeforeCall(spaceId, unitId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * team_member_list (asynchronously) - * team_member_list List members under team. - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 team_member_list successfully -
- */ - public okhttp3.Call teamMemberListAsync(String spaceId, String unitId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = teamMemberListValidateBeforeCall(spaceId, unitId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for updateMember - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 update_member successfully -
- */ - public okhttp3.Call updateMemberCall(String spaceId, String unitId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/spaces/{space_id}/members/{unit_id}" - .replace("{" + "space_id" + "}", localVarApiClient.escapeString(spaceId.toString())) - .replace("{" + "unit_id" + "}", localVarApiClient.escapeString(unitId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "PUT", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call updateMemberValidateBeforeCall(String spaceId, String unitId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'spaceId' is set - if (spaceId == null) { - throw new ApiException("Missing the required parameter 'spaceId' when calling updateMember(Async)"); - } - - // verify the required parameter 'unitId' is set - if (unitId == null) { - throw new ApiException("Missing the required parameter 'unitId' when calling updateMember(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling updateMember(Async)"); - } - - return updateMemberCall(spaceId, unitId, authorization, _callback); - - } - - /** - * update_member - * update_member Update a member for a specified space. - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 update_member successfully -
- */ - public void updateMember(String spaceId, String unitId, String authorization) throws ApiException { - updateMemberWithHttpInfo(spaceId, unitId, authorization); - } - - /** - * update_member - * update_member Update a member for a specified space. - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 update_member successfully -
- */ - public ApiResponse updateMemberWithHttpInfo(String spaceId, String unitId, String authorization) throws ApiException { - okhttp3.Call localVarCall = updateMemberValidateBeforeCall(spaceId, unitId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * update_member (asynchronously) - * update_member Update a member for a specified space. - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 update_member successfully -
- */ - public okhttp3.Call updateMemberAsync(String spaceId, String unitId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = updateMemberValidateBeforeCall(spaceId, unitId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for updateRole - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 update_role successfully -
- */ - public okhttp3.Call updateRoleCall(String spaceId, String unitId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/spaces/{space_id}/roles/{unit_id}" - .replace("{" + "space_id" + "}", localVarApiClient.escapeString(spaceId.toString())) - .replace("{" + "unit_id" + "}", localVarApiClient.escapeString(unitId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "PUT", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call updateRoleValidateBeforeCall(String spaceId, String unitId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'spaceId' is set - if (spaceId == null) { - throw new ApiException("Missing the required parameter 'spaceId' when calling updateRole(Async)"); - } - - // verify the required parameter 'unitId' is set - if (unitId == null) { - throw new ApiException("Missing the required parameter 'unitId' when calling updateRole(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling updateRole(Async)"); - } - - return updateRoleCall(spaceId, unitId, authorization, _callback); - - } - - /** - * update_role - * update_role Update roles for a specified space - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 update_role successfully -
- */ - public void updateRole(String spaceId, String unitId, String authorization) throws ApiException { - updateRoleWithHttpInfo(spaceId, unitId, authorization); - } - - /** - * update_role - * update_role Update roles for a specified space - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 update_role successfully -
- */ - public ApiResponse updateRoleWithHttpInfo(String spaceId, String unitId, String authorization) throws ApiException { - okhttp3.Call localVarCall = updateRoleValidateBeforeCall(spaceId, unitId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * update_role (asynchronously) - * update_role Update roles for a specified space - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 update_role successfully -
- */ - public okhttp3.Call updateRoleAsync(String spaceId, String unitId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = updateRoleValidateBeforeCall(spaceId, unitId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for updateTeam - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 update_team successfully -
- */ - public okhttp3.Call updateTeamCall(String spaceId, String unitId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/spaces/{space_id}/teams/{unit_id}" - .replace("{" + "space_id" + "}", localVarApiClient.escapeString(spaceId.toString())) - .replace("{" + "unit_id" + "}", localVarApiClient.escapeString(unitId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "PUT", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call updateTeamValidateBeforeCall(String spaceId, String unitId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'spaceId' is set - if (spaceId == null) { - throw new ApiException("Missing the required parameter 'spaceId' when calling updateTeam(Async)"); - } - - // verify the required parameter 'unitId' is set - if (unitId == null) { - throw new ApiException("Missing the required parameter 'unitId' when calling updateTeam(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling updateTeam(Async)"); - } - - return updateTeamCall(spaceId, unitId, authorization, _callback); - - } - - /** - * update_team - * update_team Update a for a specified space - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 update_team successfully -
- */ - public void updateTeam(String spaceId, String unitId, String authorization) throws ApiException { - updateTeamWithHttpInfo(spaceId, unitId, authorization); - } - - /** - * update_team - * update_team Update a for a specified space - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 update_team successfully -
- */ - public ApiResponse updateTeamWithHttpInfo(String spaceId, String unitId, String authorization) throws ApiException { - okhttp3.Call localVarCall = updateTeamValidateBeforeCall(spaceId, unitId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * update_team (asynchronously) - * update_team Update a for a specified space - * @param spaceId space_id (required) - * @param unitId unit_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 update_team successfully -
- */ - public okhttp3.Call updateTeamAsync(String spaceId, String unitId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = updateTeamValidateBeforeCall(spaceId, unitId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for updateView - * @param dstId dst_id (required) - * @param viewId view_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 update_view successfully -
- */ - public okhttp3.Call updateViewCall(String dstId, String viewId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/datasheets/{dst_id}/views/{view_id}" - .replace("{" + "dst_id" + "}", localVarApiClient.escapeString(dstId.toString())) - .replace("{" + "view_id" + "}", localVarApiClient.escapeString(viewId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "PUT", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call updateViewValidateBeforeCall(String dstId, String viewId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'dstId' is set - if (dstId == null) { - throw new ApiException("Missing the required parameter 'dstId' when calling updateView(Async)"); - } - - // verify the required parameter 'viewId' is set - if (viewId == null) { - throw new ApiException("Missing the required parameter 'viewId' when calling updateView(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling updateView(Async)"); - } - - return updateViewCall(dstId, viewId, authorization, _callback); - - } - - /** - * update_view - * update_view update a view in a specified datasheet - * @param dstId dst_id (required) - * @param viewId view_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 update_view successfully -
- */ - public void updateView(String dstId, String viewId, String authorization) throws ApiException { - updateViewWithHttpInfo(dstId, viewId, authorization); - } - - /** - * update_view - * update_view update a view in a specified datasheet - * @param dstId dst_id (required) - * @param viewId view_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 update_view successfully -
- */ - public ApiResponse updateViewWithHttpInfo(String dstId, String viewId, String authorization) throws ApiException { - okhttp3.Call localVarCall = updateViewValidateBeforeCall(dstId, viewId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * update_view (asynchronously) - * update_view update a view in a specified datasheet - * @param dstId dst_id (required) - * @param viewId view_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 update_view successfully -
- */ - public okhttp3.Call updateViewAsync(String dstId, String viewId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = updateViewValidateBeforeCall(dstId, viewId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for updateWidget - * @param dashboardId dashboard_id (required) - * @param widgetId widget_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 update_widget successfully -
- */ - public okhttp3.Call updateWidgetCall(String dashboardId, String widgetId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/dashboards/{dashboard_id}/widgets/{widget_id}" - .replace("{" + "dashboard_id" + "}", localVarApiClient.escapeString(dashboardId.toString())) - .replace("{" + "widget_id" + "}", localVarApiClient.escapeString(widgetId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "PUT", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call updateWidgetValidateBeforeCall(String dashboardId, String widgetId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'dashboardId' is set - if (dashboardId == null) { - throw new ApiException("Missing the required parameter 'dashboardId' when calling updateWidget(Async)"); - } - - // verify the required parameter 'widgetId' is set - if (widgetId == null) { - throw new ApiException("Missing the required parameter 'widgetId' when calling updateWidget(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling updateWidget(Async)"); - } - - return updateWidgetCall(dashboardId, widgetId, authorization, _callback); - - } - - /** - * update_widget - * update_widget modify widget in a specified dashboard - * @param dashboardId dashboard_id (required) - * @param widgetId widget_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 update_widget successfully -
- */ - public void updateWidget(String dashboardId, String widgetId, String authorization) throws ApiException { - updateWidgetWithHttpInfo(dashboardId, widgetId, authorization); - } - - /** - * update_widget - * update_widget modify widget in a specified dashboard - * @param dashboardId dashboard_id (required) - * @param widgetId widget_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 update_widget successfully -
- */ - public ApiResponse updateWidgetWithHttpInfo(String dashboardId, String widgetId, String authorization) throws ApiException { - okhttp3.Call localVarCall = updateWidgetValidateBeforeCall(dashboardId, widgetId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * update_widget (asynchronously) - * update_widget modify widget in a specified dashboard - * @param dashboardId dashboard_id (required) - * @param widgetId widget_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 update_widget successfully -
- */ - public okhttp3.Call updateWidgetAsync(String dashboardId, String widgetId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = updateWidgetValidateBeforeCall(dashboardId, widgetId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } -} diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/api/FusionApiApi.java b/backend-server/application/src/main/java/com/apitable/databusclient/api/FusionApiApi.java deleted file mode 100644 index e54750dd23..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/api/FusionApiApi.java +++ /dev/null @@ -1,2201 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.api; - -import com.apitable.databusclient.ApiCallback; -import com.apitable.databusclient.ApiClient; -import com.apitable.databusclient.ApiException; -import com.apitable.databusclient.ApiResponse; -import com.apitable.databusclient.Configuration; -import com.apitable.databusclient.Pair; -import com.apitable.databusclient.ProgressRequestBody; -import com.apitable.databusclient.ProgressResponseBody; - -import com.google.gson.reflect.TypeToken; - -import java.io.IOException; - - -import com.apitable.databusclient.model.ApiResponseRecordVos; -import com.apitable.databusclient.model.CellFormatEnum; -import com.apitable.databusclient.model.FieldKeyEnum; -import com.apitable.databusclient.model.ListVO; -import com.apitable.databusclient.model.RecordUpdateRO; -import com.apitable.databusclient.model.SortRO; - -import java.lang.reflect.Type; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class FusionApiApi { - private ApiClient localVarApiClient; - private int localHostIndex; - private String localCustomBaseUrl; - - public FusionApiApi() { - this(Configuration.getDefaultApiClient()); - } - - public FusionApiApi(ApiClient apiClient) { - this.localVarApiClient = apiClient; - } - - public ApiClient getApiClient() { - return localVarApiClient; - } - - public void setApiClient(ApiClient apiClient) { - this.localVarApiClient = apiClient; - } - - public int getHostIndex() { - return localHostIndex; - } - - public void setHostIndex(int hostIndex) { - this.localHostIndex = hostIndex; - } - - public String getCustomBaseUrl() { - return localCustomBaseUrl; - } - - public void setCustomBaseUrl(String customBaseUrl) { - this.localCustomBaseUrl = customBaseUrl; - } - - /** - * Build call for addRecords - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet -
- */ - public okhttp3.Call addRecordsCall(String dstId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/datasheets/{dst_id}/records" - .replace("{" + "dst_id" + "}", localVarApiClient.escapeString(dstId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "POST", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call addRecordsValidateBeforeCall(String dstId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'dstId' is set - if (dstId == null) { - throw new ApiException("Missing the required parameter 'dstId' when calling addRecords(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling addRecords(Async)"); - } - - return addRecordsCall(dstId, authorization, _callback); - - } - - /** - * Add multiple rows to a specified datasheet - * Add multiple rows to a specified datasheet Up to 10 records can be created in a single request. You need to bring `Content-Type: application/json` in the Request Header to submit data in raw json format. The POST data is a JSON object, which should contain an array: `records`, the records array contains multiple records to be created. The object `fields` contains the values of the fields to be created in a record, and can contain any number of field values, not necessarily all of them. If there are field defaults set, field values that are not passed in will be saved according to the default values at the time the fields were set. - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet -
- */ - public void addRecords(String dstId, String authorization) throws ApiException { - addRecordsWithHttpInfo(dstId, authorization); - } - - /** - * Add multiple rows to a specified datasheet - * Add multiple rows to a specified datasheet Up to 10 records can be created in a single request. You need to bring `Content-Type: application/json` in the Request Header to submit data in raw json format. The POST data is a JSON object, which should contain an array: `records`, the records array contains multiple records to be created. The object `fields` contains the values of the fields to be created in a record, and can contain any number of field values, not necessarily all of them. If there are field defaults set, field values that are not passed in will be saved according to the default values at the time the fields were set. - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet -
- */ - public ApiResponse addRecordsWithHttpInfo(String dstId, String authorization) throws ApiException { - okhttp3.Call localVarCall = addRecordsValidateBeforeCall(dstId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * Add multiple rows to a specified datasheet (asynchronously) - * Add multiple rows to a specified datasheet Up to 10 records can be created in a single request. You need to bring `Content-Type: application/json` in the Request Header to submit data in raw json format. The POST data is a JSON object, which should contain an array: `records`, the records array contains multiple records to be created. The object `fields` contains the values of the fields to be created in a record, and can contain any number of field values, not necessarily all of them. If there are field defaults set, field values that are not passed in will be saved according to the default values at the time the fields were set. - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet -
- */ - public okhttp3.Call addRecordsAsync(String dstId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = addRecordsValidateBeforeCall(dstId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for createDatasheet - * @param spaceId space_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet Fields -
- */ - public okhttp3.Call createDatasheetCall(String spaceId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/spaces/{space_id}/datasheets" - .replace("{" + "space_id" + "}", localVarApiClient.escapeString(spaceId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "POST", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call createDatasheetValidateBeforeCall(String spaceId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'spaceId' is set - if (spaceId == null) { - throw new ApiException("Missing the required parameter 'spaceId' when calling createDatasheet(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling createDatasheet(Async)"); - } - - return createDatasheetCall(spaceId, authorization, _callback); - - } - - /** - * Create Datasheet - * Create Datasheet Create Datasheet and their fields - * @param spaceId space_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet Fields -
- */ - public void createDatasheet(String spaceId, String authorization) throws ApiException { - createDatasheetWithHttpInfo(spaceId, authorization); - } - - /** - * Create Datasheet - * Create Datasheet Create Datasheet and their fields - * @param spaceId space_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet Fields -
- */ - public ApiResponse createDatasheetWithHttpInfo(String spaceId, String authorization) throws ApiException { - okhttp3.Call localVarCall = createDatasheetValidateBeforeCall(spaceId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * Create Datasheet (asynchronously) - * Create Datasheet Create Datasheet and their fields - * @param spaceId space_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet Fields -
- */ - public okhttp3.Call createDatasheetAsync(String spaceId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = createDatasheetValidateBeforeCall(spaceId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for createFields - * @param spaceId space_id (required) - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet Fields -
- */ - public okhttp3.Call createFieldsCall(String spaceId, String dstId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/spaces/{space_id}/datasheets/{dst_id}/fields" - .replace("{" + "space_id" + "}", localVarApiClient.escapeString(spaceId.toString())) - .replace("{" + "dst_id" + "}", localVarApiClient.escapeString(dstId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "POST", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call createFieldsValidateBeforeCall(String spaceId, String dstId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'spaceId' is set - if (spaceId == null) { - throw new ApiException("Missing the required parameter 'spaceId' when calling createFields(Async)"); - } - - // verify the required parameter 'dstId' is set - if (dstId == null) { - throw new ApiException("Missing the required parameter 'dstId' when calling createFields(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling createFields(Async)"); - } - - return createFieldsCall(spaceId, dstId, authorization, _callback); - - } - - /** - * create_fields - * create_fields create_fields - * @param spaceId space_id (required) - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet Fields -
- */ - public void createFields(String spaceId, String dstId, String authorization) throws ApiException { - createFieldsWithHttpInfo(spaceId, dstId, authorization); - } - - /** - * create_fields - * create_fields create_fields - * @param spaceId space_id (required) - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet Fields -
- */ - public ApiResponse createFieldsWithHttpInfo(String spaceId, String dstId, String authorization) throws ApiException { - okhttp3.Call localVarCall = createFieldsValidateBeforeCall(spaceId, dstId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * create_fields (asynchronously) - * create_fields create_fields - * @param spaceId space_id (required) - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet Fields -
- */ - public okhttp3.Call createFieldsAsync(String spaceId, String dstId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = createFieldsValidateBeforeCall(spaceId, dstId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for deleteFields - * @param spaceId space_id (required) - * @param dstId dst_id (required) - * @param fieldId field_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet Fields -
- */ - public okhttp3.Call deleteFieldsCall(String spaceId, String dstId, String fieldId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/spaces/{space_id}/datasheets/{dst_id}/fields/{field_id}" - .replace("{" + "space_id" + "}", localVarApiClient.escapeString(spaceId.toString())) - .replace("{" + "dst_id" + "}", localVarApiClient.escapeString(dstId.toString())) - .replace("{" + "field_id" + "}", localVarApiClient.escapeString(fieldId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "DELETE", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call deleteFieldsValidateBeforeCall(String spaceId, String dstId, String fieldId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'spaceId' is set - if (spaceId == null) { - throw new ApiException("Missing the required parameter 'spaceId' when calling deleteFields(Async)"); - } - - // verify the required parameter 'dstId' is set - if (dstId == null) { - throw new ApiException("Missing the required parameter 'dstId' when calling deleteFields(Async)"); - } - - // verify the required parameter 'fieldId' is set - if (fieldId == null) { - throw new ApiException("Missing the required parameter 'fieldId' when calling deleteFields(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling deleteFields(Async)"); - } - - return deleteFieldsCall(spaceId, dstId, fieldId, authorization, _callback); - - } - - /** - * Delete field - * Delete field Delete field - * @param spaceId space_id (required) - * @param dstId dst_id (required) - * @param fieldId field_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet Fields -
- */ - public void deleteFields(String spaceId, String dstId, String fieldId, String authorization) throws ApiException { - deleteFieldsWithHttpInfo(spaceId, dstId, fieldId, authorization); - } - - /** - * Delete field - * Delete field Delete field - * @param spaceId space_id (required) - * @param dstId dst_id (required) - * @param fieldId field_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet Fields -
- */ - public ApiResponse deleteFieldsWithHttpInfo(String spaceId, String dstId, String fieldId, String authorization) throws ApiException { - okhttp3.Call localVarCall = deleteFieldsValidateBeforeCall(spaceId, dstId, fieldId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * Delete field (asynchronously) - * Delete field Delete field - * @param spaceId space_id (required) - * @param dstId dst_id (required) - * @param fieldId field_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet Fields -
- */ - public okhttp3.Call deleteFieldsAsync(String spaceId, String dstId, String fieldId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = deleteFieldsValidateBeforeCall(spaceId, dstId, fieldId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for deleteRecords - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet successfully -
- */ - public okhttp3.Call deleteRecordsCall(String dstId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/datasheets/{dst_id}/records" - .replace("{" + "dst_id" + "}", localVarApiClient.escapeString(dstId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "DELETE", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call deleteRecordsValidateBeforeCall(String dstId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'dstId' is set - if (dstId == null) { - throw new ApiException("Missing the required parameter 'dstId' when calling deleteRecords(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling deleteRecords(Async)"); - } - - return deleteRecordsCall(dstId, authorization, _callback); - - } - - /** - * Delete records - * Delete records Delete a number of records from a datasheet - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet successfully -
- */ - public void deleteRecords(String dstId, String authorization) throws ApiException { - deleteRecordsWithHttpInfo(dstId, authorization); - } - - /** - * Delete records - * Delete records Delete a number of records from a datasheet - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet successfully -
- */ - public ApiResponse deleteRecordsWithHttpInfo(String dstId, String authorization) throws ApiException { - okhttp3.Call localVarCall = deleteRecordsValidateBeforeCall(dstId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * Delete records (asynchronously) - * Delete records Delete a number of records from a datasheet - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet successfully -
- */ - public okhttp3.Call deleteRecordsAsync(String dstId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = deleteRecordsValidateBeforeCall(dstId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for executeCommand - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 execute_command successfully -
- */ - public okhttp3.Call executeCommandCall(String dstId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/datasheets/{dst_id}/executeCommand" - .replace("{" + "dst_id" + "}", localVarApiClient.escapeString(dstId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "POST", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call executeCommandValidateBeforeCall(String dstId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'dstId' is set - if (dstId == null) { - throw new ApiException("Missing the required parameter 'dstId' when calling executeCommand(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling executeCommand(Async)"); - } - - return executeCommandCall(dstId, authorization, _callback); - - } - - /** - * Create the op of the resource - * Create the op of the resource For flexibility reasons and for internal automation testing, provide an interface to freely create commands - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 execute_command successfully -
- */ - public void executeCommand(String dstId, String authorization) throws ApiException { - executeCommandWithHttpInfo(dstId, authorization); - } - - /** - * Create the op of the resource - * Create the op of the resource For flexibility reasons and for internal automation testing, provide an interface to freely create commands - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 execute_command successfully -
- */ - public ApiResponse executeCommandWithHttpInfo(String dstId, String authorization) throws ApiException { - okhttp3.Call localVarCall = executeCommandValidateBeforeCall(dstId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * Create the op of the resource (asynchronously) - * Create the op of the resource For flexibility reasons and for internal automation testing, provide an interface to freely create commands - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 execute_command successfully -
- */ - public okhttp3.Call executeCommandAsync(String dstId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = executeCommandValidateBeforeCall(dstId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for getFields - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet Fields -
- */ - public okhttp3.Call getFieldsCall(String dstId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/datasheets/{dst_id}/fields" - .replace("{" + "dst_id" + "}", localVarApiClient.escapeString(dstId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call getFieldsValidateBeforeCall(String dstId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'dstId' is set - if (dstId == null) { - throw new ApiException("Missing the required parameter 'dstId' when calling getFields(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling getFields(Async)"); - } - - return getFieldsCall(dstId, authorization, _callback); - - } - - /** - * Query all fields of a datasheet - * Query all fields of a datasheet All lines of the doc comment will be included to operation description. - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet Fields -
- */ - public void getFields(String dstId, String authorization) throws ApiException { - getFieldsWithHttpInfo(dstId, authorization); - } - - /** - * Query all fields of a datasheet - * Query all fields of a datasheet All lines of the doc comment will be included to operation description. - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet Fields -
- */ - public ApiResponse getFieldsWithHttpInfo(String dstId, String authorization) throws ApiException { - okhttp3.Call localVarCall = getFieldsValidateBeforeCall(dstId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * Query all fields of a datasheet (asynchronously) - * Query all fields of a datasheet All lines of the doc comment will be included to operation description. - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet Fields -
- */ - public okhttp3.Call getFieldsAsync(String dstId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = getFieldsValidateBeforeCall(dstId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for getNodes - * @param spaceId space_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 get_nodes successfully -
- */ - public okhttp3.Call getNodesCall(String spaceId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/spaces/{space_id}/nodes" - .replace("{" + "space_id" + "}", localVarApiClient.escapeString(spaceId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call getNodesValidateBeforeCall(String spaceId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'spaceId' is set - if (spaceId == null) { - throw new ApiException("Missing the required parameter 'spaceId' when calling getNodes(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling getNodes(Async)"); - } - - return getNodesCall(spaceId, authorization, _callback); - - } - - /** - * get_nodes - * get_nodes Query the list of space station level 1 document nodes - * @param spaceId space_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 get_nodes successfully -
- */ - public void getNodes(String spaceId, String authorization) throws ApiException { - getNodesWithHttpInfo(spaceId, authorization); - } - - /** - * get_nodes - * get_nodes Query the list of space station level 1 document nodes - * @param spaceId space_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 get_nodes successfully -
- */ - public ApiResponse getNodesWithHttpInfo(String spaceId, String authorization) throws ApiException { - okhttp3.Call localVarCall = getNodesValidateBeforeCall(spaceId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * get_nodes (asynchronously) - * get_nodes Query the list of space station level 1 document nodes - * @param spaceId space_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 get_nodes successfully -
- */ - public okhttp3.Call getNodesAsync(String spaceId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = getNodesValidateBeforeCall(spaceId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for getPresignedUrl - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 get_presigned_url successfully -
- */ - public okhttp3.Call getPresignedUrlCall(String dstId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/datasheets/{dst_id}/attachments/presignedUrl" - .replace("{" + "dst_id" + "}", localVarApiClient.escapeString(dstId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call getPresignedUrlValidateBeforeCall(String dstId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'dstId' is set - if (dstId == null) { - throw new ApiException("Missing the required parameter 'dstId' when calling getPresignedUrl(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling getPresignedUrl(Async)"); - } - - return getPresignedUrlCall(dstId, authorization, _callback); - - } - - /** - * get_presigned_url - * get_presigned_url Get the pre-signed URL of the datasheet attachment - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 get_presigned_url successfully -
- */ - public void getPresignedUrl(String dstId, String authorization) throws ApiException { - getPresignedUrlWithHttpInfo(dstId, authorization); - } - - /** - * get_presigned_url - * get_presigned_url Get the pre-signed URL of the datasheet attachment - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 get_presigned_url successfully -
- */ - public ApiResponse getPresignedUrlWithHttpInfo(String dstId, String authorization) throws ApiException { - okhttp3.Call localVarCall = getPresignedUrlValidateBeforeCall(dstId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * get_presigned_url (asynchronously) - * get_presigned_url Get the pre-signed URL of the datasheet attachment - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 get_presigned_url successfully -
- */ - public okhttp3.Call getPresignedUrlAsync(String dstId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = getPresignedUrlValidateBeforeCall(dstId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for getRecordByDatasheetId - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @param pageSize (optional) - * @param maxRecords (optional) - * @param pageNum (optional) - * @param sort (optional) - * @param recordIds (optional) - * @param viewId (optional) - * @param fields (optional) - * @param filterByFormula (optional) - * @param cellFormat (optional) - * @param fieldKey (optional) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet -
- */ - public okhttp3.Call getRecordByDatasheetIdCall(String dstId, String authorization, Integer pageSize, Integer maxRecords, Integer pageNum, List sort, List recordIds, String viewId, List fields, String filterByFormula, CellFormatEnum cellFormat, FieldKeyEnum fieldKey, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/datasheets/{dst_id}/records" - .replace("{" + "dst_id" + "}", localVarApiClient.escapeString(dstId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (pageSize != null) { - localVarQueryParams.addAll(localVarApiClient.parameterToPair("pageSize", pageSize)); - } - - if (maxRecords != null) { - localVarQueryParams.addAll(localVarApiClient.parameterToPair("maxRecords", maxRecords)); - } - - if (pageNum != null) { - localVarQueryParams.addAll(localVarApiClient.parameterToPair("pageNum", pageNum)); - } - - if (sort != null) { - localVarCollectionQueryParams.addAll(localVarApiClient.parameterToPairs("multi", "sort", sort)); - } - - if (recordIds != null) { - localVarCollectionQueryParams.addAll(localVarApiClient.parameterToPairs("multi", "recordIds", recordIds)); - } - - if (viewId != null) { - localVarQueryParams.addAll(localVarApiClient.parameterToPair("viewId", viewId)); - } - - if (fields != null) { - localVarCollectionQueryParams.addAll(localVarApiClient.parameterToPairs("multi", "fields", fields)); - } - - if (filterByFormula != null) { - localVarQueryParams.addAll(localVarApiClient.parameterToPair("filterByFormula", filterByFormula)); - } - - if (cellFormat != null) { - localVarQueryParams.addAll(localVarApiClient.parameterToPair("cellFormat", cellFormat)); - } - - if (fieldKey != null) { - localVarQueryParams.addAll(localVarApiClient.parameterToPair("fieldKey", fieldKey)); - } - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - "application/json" - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call getRecordByDatasheetIdValidateBeforeCall(String dstId, String authorization, Integer pageSize, Integer maxRecords, Integer pageNum, List sort, List recordIds, String viewId, List fields, String filterByFormula, CellFormatEnum cellFormat, FieldKeyEnum fieldKey, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'dstId' is set - if (dstId == null) { - throw new ApiException("Missing the required parameter 'dstId' when calling getRecordByDatasheetId(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling getRecordByDatasheetId(Async)"); - } - - return getRecordByDatasheetIdCall(dstId, authorization, pageSize, maxRecords, pageNum, sort, recordIds, viewId, fields, filterByFormula, cellFormat, fieldKey, _callback); - - } - - /** - * Get multiple records of a datasheet - * Get multiple records of a datasheet - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @param pageSize (optional) - * @param maxRecords (optional) - * @param pageNum (optional) - * @param sort (optional) - * @param recordIds (optional) - * @param viewId (optional) - * @param fields (optional) - * @param filterByFormula (optional) - * @param cellFormat (optional) - * @param fieldKey (optional) - * @return ApiResponseRecordVos - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet -
- */ - public ApiResponseRecordVos getRecordByDatasheetId(String dstId, String authorization, Integer pageSize, Integer maxRecords, Integer pageNum, List sort, List recordIds, String viewId, List fields, String filterByFormula, CellFormatEnum cellFormat, FieldKeyEnum fieldKey) throws ApiException { - ApiResponse localVarResp = getRecordByDatasheetIdWithHttpInfo(dstId, authorization, pageSize, maxRecords, pageNum, sort, recordIds, viewId, fields, filterByFormula, cellFormat, fieldKey); - return localVarResp.getData(); - } - - /** - * Get multiple records of a datasheet - * Get multiple records of a datasheet - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @param pageSize (optional) - * @param maxRecords (optional) - * @param pageNum (optional) - * @param sort (optional) - * @param recordIds (optional) - * @param viewId (optional) - * @param fields (optional) - * @param filterByFormula (optional) - * @param cellFormat (optional) - * @param fieldKey (optional) - * @return ApiResponse<ApiResponseRecordVos> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet -
- */ - public ApiResponse getRecordByDatasheetIdWithHttpInfo(String dstId, String authorization, Integer pageSize, Integer maxRecords, Integer pageNum, List sort, List recordIds, String viewId, List fields, String filterByFormula, CellFormatEnum cellFormat, FieldKeyEnum fieldKey) throws ApiException { - okhttp3.Call localVarCall = getRecordByDatasheetIdValidateBeforeCall(dstId, authorization, pageSize, maxRecords, pageNum, sort, recordIds, viewId, fields, filterByFormula, cellFormat, fieldKey, null); - Type localVarReturnType = new TypeToken(){}.getType(); - return localVarApiClient.execute(localVarCall, localVarReturnType); - } - - /** - * Get multiple records of a datasheet (asynchronously) - * Get multiple records of a datasheet - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @param pageSize (optional) - * @param maxRecords (optional) - * @param pageNum (optional) - * @param sort (optional) - * @param recordIds (optional) - * @param viewId (optional) - * @param fields (optional) - * @param filterByFormula (optional) - * @param cellFormat (optional) - * @param fieldKey (optional) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet -
- */ - public okhttp3.Call getRecordByDatasheetIdAsync(String dstId, String authorization, Integer pageSize, Integer maxRecords, Integer pageNum, List sort, List recordIds, String viewId, List fields, String filterByFormula, CellFormatEnum cellFormat, FieldKeyEnum fieldKey, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = getRecordByDatasheetIdValidateBeforeCall(dstId, authorization, pageSize, maxRecords, pageNum, sort, recordIds, viewId, fields, filterByFormula, cellFormat, fieldKey, _callback); - Type localVarReturnType = new TypeToken(){}.getType(); - localVarApiClient.executeAsync(localVarCall, localVarReturnType, _callback); - return localVarCall; - } - /** - * Build call for getSpaces - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 get_spaces successfully -
- */ - public okhttp3.Call getSpacesCall(String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/spaces"; - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call getSpacesValidateBeforeCall(String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling getSpaces(Async)"); - } - - return getSpacesCall(authorization, _callback); - - } - - /** - * get_spaces - * get_spaces Query space list - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 get_spaces successfully -
- */ - public void getSpaces(String authorization) throws ApiException { - getSpacesWithHttpInfo(authorization); - } - - /** - * get_spaces - * get_spaces Query space list - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 get_spaces successfully -
- */ - public ApiResponse getSpacesWithHttpInfo(String authorization) throws ApiException { - okhttp3.Call localVarCall = getSpacesValidateBeforeCall(authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * get_spaces (asynchronously) - * get_spaces Query space list - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 get_spaces successfully -
- */ - public okhttp3.Call getSpacesAsync(String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = getSpacesValidateBeforeCall(authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for getViews - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet Fields -
- */ - public okhttp3.Call getViewsCall(String dstId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/datasheets/{dst_id}/views" - .replace("{" + "dst_id" + "}", localVarApiClient.escapeString(dstId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call getViewsValidateBeforeCall(String dstId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'dstId' is set - if (dstId == null) { - throw new ApiException("Missing the required parameter 'dstId' when calling getViews(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling getViews(Async)"); - } - - return getViewsCall(dstId, authorization, _callback); - - } - - /** - * Query all views of a datasheet - * Query all views of a datasheet A datasheet can create up to 30 views and return them all at once when requesting a view, without paging. - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet Fields -
- */ - public void getViews(String dstId, String authorization) throws ApiException { - getViewsWithHttpInfo(dstId, authorization); - } - - /** - * Query all views of a datasheet - * Query all views of a datasheet A datasheet can create up to 30 views and return them all at once when requesting a view, without paging. - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet Fields -
- */ - public ApiResponse getViewsWithHttpInfo(String dstId, String authorization) throws ApiException { - okhttp3.Call localVarCall = getViewsValidateBeforeCall(dstId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * Query all views of a datasheet (asynchronously) - * Query all views of a datasheet A datasheet can create up to 30 views and return them all at once when requesting a view, without paging. - * @param dstId dst_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet Fields -
- */ - public okhttp3.Call getViewsAsync(String dstId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = getViewsValidateBeforeCall(dstId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for nodeDetail - * @param nodeId node_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 node_detail successfully -
- */ - public okhttp3.Call nodeDetailCall(String nodeId, String authorization, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = null; - - // create path and map variables - String localVarPath = "/fusion/v3/nodes/{node_id}" - .replace("{" + "node_id" + "}", localVarApiClient.escapeString(nodeId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (authorization != null) { - localVarHeaderParams.put("Authorization", localVarApiClient.parameterToString(authorization)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "GET", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call nodeDetailValidateBeforeCall(String nodeId, String authorization, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'nodeId' is set - if (nodeId == null) { - throw new ApiException("Missing the required parameter 'nodeId' when calling nodeDetail(Async)"); - } - - // verify the required parameter 'authorization' is set - if (authorization == null) { - throw new ApiException("Missing the required parameter 'authorization' when calling nodeDetail(Async)"); - } - - return nodeDetailCall(nodeId, authorization, _callback); - - } - - /** - * Query Node Details - * Query Node Details Query the details of the specified file node - * @param nodeId node_id (required) - * @param authorization Current csrf token of user (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 node_detail successfully -
- */ - public void nodeDetail(String nodeId, String authorization) throws ApiException { - nodeDetailWithHttpInfo(nodeId, authorization); - } - - /** - * Query Node Details - * Query Node Details Query the details of the specified file node - * @param nodeId node_id (required) - * @param authorization Current csrf token of user (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 node_detail successfully -
- */ - public ApiResponse nodeDetailWithHttpInfo(String nodeId, String authorization) throws ApiException { - okhttp3.Call localVarCall = nodeDetailValidateBeforeCall(nodeId, authorization, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * Query Node Details (asynchronously) - * Query Node Details Query the details of the specified file node - * @param nodeId node_id (required) - * @param authorization Current csrf token of user (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 node_detail successfully -
- */ - public okhttp3.Call nodeDetailAsync(String nodeId, String authorization, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = nodeDetailValidateBeforeCall(nodeId, authorization, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for updateRecordsPatch - * @param dstId dst_id (required) - * @param userId (required) - * @param viewId (required) - * @param recordUpdateRO (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet -
- */ - public okhttp3.Call updateRecordsPatchCall(String dstId, String userId, String viewId, RecordUpdateRO recordUpdateRO, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = recordUpdateRO; - - // create path and map variables - String localVarPath = "/fusion/v3/datasheets/{dst_id}/records" - .replace("{" + "dst_id" + "}", localVarApiClient.escapeString(dstId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (userId != null) { - localVarQueryParams.addAll(localVarApiClient.parameterToPair("userId", userId)); - } - - if (viewId != null) { - localVarQueryParams.addAll(localVarApiClient.parameterToPair("viewId", viewId)); - } - - final String[] localVarAccepts = { - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - "application/json" - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "PATCH", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call updateRecordsPatchValidateBeforeCall(String dstId, String userId, String viewId, RecordUpdateRO recordUpdateRO, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'dstId' is set - if (dstId == null) { - throw new ApiException("Missing the required parameter 'dstId' when calling updateRecordsPatch(Async)"); - } - - // verify the required parameter 'userId' is set - if (userId == null) { - throw new ApiException("Missing the required parameter 'userId' when calling updateRecordsPatch(Async)"); - } - - // verify the required parameter 'viewId' is set - if (viewId == null) { - throw new ApiException("Missing the required parameter 'viewId' when calling updateRecordsPatch(Async)"); - } - - // verify the required parameter 'recordUpdateRO' is set - if (recordUpdateRO == null) { - throw new ApiException("Missing the required parameter 'recordUpdateRO' when calling updateRecordsPatch(Async)"); - } - - return updateRecordsPatchCall(dstId, userId, viewId, recordUpdateRO, _callback); - - } - - /** - * Update Records - * Update Records Update several records of a datasheet. When submitted using the PUT method, only the fields that are specified will have their data updated, and fields that are not specified will retain their old values. - * @param dstId dst_id (required) - * @param userId (required) - * @param viewId (required) - * @param recordUpdateRO (required) - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet -
- */ - public void updateRecordsPatch(String dstId, String userId, String viewId, RecordUpdateRO recordUpdateRO) throws ApiException { - updateRecordsPatchWithHttpInfo(dstId, userId, viewId, recordUpdateRO); - } - - /** - * Update Records - * Update Records Update several records of a datasheet. When submitted using the PUT method, only the fields that are specified will have their data updated, and fields that are not specified will retain their old values. - * @param dstId dst_id (required) - * @param userId (required) - * @param viewId (required) - * @param recordUpdateRO (required) - * @return ApiResponse<Void> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet -
- */ - public ApiResponse updateRecordsPatchWithHttpInfo(String dstId, String userId, String viewId, RecordUpdateRO recordUpdateRO) throws ApiException { - okhttp3.Call localVarCall = updateRecordsPatchValidateBeforeCall(dstId, userId, viewId, recordUpdateRO, null); - return localVarApiClient.execute(localVarCall); - } - - /** - * Update Records (asynchronously) - * Update Records Update several records of a datasheet. When submitted using the PUT method, only the fields that are specified will have their data updated, and fields that are not specified will retain their old values. - * @param dstId dst_id (required) - * @param userId (required) - * @param viewId (required) - * @param recordUpdateRO (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Get Datasheet -
- */ - public okhttp3.Call updateRecordsPatchAsync(String dstId, String userId, String viewId, RecordUpdateRO recordUpdateRO, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = updateRecordsPatchValidateBeforeCall(dstId, userId, viewId, recordUpdateRO, _callback); - localVarApiClient.executeAsync(localVarCall, _callback); - return localVarCall; - } - /** - * Build call for updateRecordsPut - * @param dstId dst_id (required) - * @param userId (required) - * @param viewId (required) - * @param recordUpdateRO (required) - * @param _callback Callback for upload/download progress - * @return Call to execute - * @throws ApiException If fail to serialize the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Update records successfully -
- */ - public okhttp3.Call updateRecordsPutCall(String dstId, String userId, String viewId, RecordUpdateRO recordUpdateRO, final ApiCallback _callback) throws ApiException { - String basePath = null; - // Operation Servers - String[] localBasePaths = new String[] { }; - - // Determine Base Path to Use - if (localCustomBaseUrl != null){ - basePath = localCustomBaseUrl; - } else if ( localBasePaths.length > 0 ) { - basePath = localBasePaths[localHostIndex]; - } else { - basePath = null; - } - - Object localVarPostBody = recordUpdateRO; - - // create path and map variables - String localVarPath = "/fusion/v3/datasheets/{dst_id}/records" - .replace("{" + "dst_id" + "}", localVarApiClient.escapeString(dstId.toString())); - - List localVarQueryParams = new ArrayList(); - List localVarCollectionQueryParams = new ArrayList(); - Map localVarHeaderParams = new HashMap(); - Map localVarCookieParams = new HashMap(); - Map localVarFormParams = new HashMap(); - - if (userId != null) { - localVarQueryParams.addAll(localVarApiClient.parameterToPair("userId", userId)); - } - - if (viewId != null) { - localVarQueryParams.addAll(localVarApiClient.parameterToPair("viewId", viewId)); - } - - final String[] localVarAccepts = { - "application/json" - }; - final String localVarAccept = localVarApiClient.selectHeaderAccept(localVarAccepts); - if (localVarAccept != null) { - localVarHeaderParams.put("Accept", localVarAccept); - } - - final String[] localVarContentTypes = { - "application/json" - }; - final String localVarContentType = localVarApiClient.selectHeaderContentType(localVarContentTypes); - if (localVarContentType != null) { - localVarHeaderParams.put("Content-Type", localVarContentType); - } - - String[] localVarAuthNames = new String[] { }; - return localVarApiClient.buildCall(basePath, localVarPath, "PUT", localVarQueryParams, localVarCollectionQueryParams, localVarPostBody, localVarHeaderParams, localVarCookieParams, localVarFormParams, localVarAuthNames, _callback); - } - - @SuppressWarnings("rawtypes") - private okhttp3.Call updateRecordsPutValidateBeforeCall(String dstId, String userId, String viewId, RecordUpdateRO recordUpdateRO, final ApiCallback _callback) throws ApiException { - // verify the required parameter 'dstId' is set - if (dstId == null) { - throw new ApiException("Missing the required parameter 'dstId' when calling updateRecordsPut(Async)"); - } - - // verify the required parameter 'userId' is set - if (userId == null) { - throw new ApiException("Missing the required parameter 'userId' when calling updateRecordsPut(Async)"); - } - - // verify the required parameter 'viewId' is set - if (viewId == null) { - throw new ApiException("Missing the required parameter 'viewId' when calling updateRecordsPut(Async)"); - } - - // verify the required parameter 'recordUpdateRO' is set - if (recordUpdateRO == null) { - throw new ApiException("Missing the required parameter 'recordUpdateRO' when calling updateRecordsPut(Async)"); - } - - return updateRecordsPutCall(dstId, userId, viewId, recordUpdateRO, _callback); - - } - - /** - * Update Records - * Update Records Update several records of a datasheet. When submitted using the PUT method, only the fields that are specified will have their data updated, and fields that are not specified will retain their old values. - * @param dstId dst_id (required) - * @param userId (required) - * @param viewId (required) - * @param recordUpdateRO (required) - * @return ListVO - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Update records successfully -
- */ - public ListVO updateRecordsPut(String dstId, String userId, String viewId, RecordUpdateRO recordUpdateRO) throws ApiException { - ApiResponse localVarResp = updateRecordsPutWithHttpInfo(dstId, userId, viewId, recordUpdateRO); - return localVarResp.getData(); - } - - /** - * Update Records - * Update Records Update several records of a datasheet. When submitted using the PUT method, only the fields that are specified will have their data updated, and fields that are not specified will retain their old values. - * @param dstId dst_id (required) - * @param userId (required) - * @param viewId (required) - * @param recordUpdateRO (required) - * @return ApiResponse<ListVO> - * @throws ApiException If fail to call the API, e.g. server error or cannot deserialize the response body - * @http.response.details - - - -
Status Code Description Response Headers
200 Update records successfully -
- */ - public ApiResponse updateRecordsPutWithHttpInfo(String dstId, String userId, String viewId, RecordUpdateRO recordUpdateRO) throws ApiException { - okhttp3.Call localVarCall = updateRecordsPutValidateBeforeCall(dstId, userId, viewId, recordUpdateRO, null); - Type localVarReturnType = new TypeToken(){}.getType(); - return localVarApiClient.execute(localVarCall, localVarReturnType); - } - - /** - * Update Records (asynchronously) - * Update Records Update several records of a datasheet. When submitted using the PUT method, only the fields that are specified will have their data updated, and fields that are not specified will retain their old values. - * @param dstId dst_id (required) - * @param userId (required) - * @param viewId (required) - * @param recordUpdateRO (required) - * @param _callback The callback to be executed when the API call finishes - * @return The request call - * @throws ApiException If fail to process the API call, e.g. serializing the request body object - * @http.response.details - - - -
Status Code Description Response Headers
200 Update records successfully -
- */ - public okhttp3.Call updateRecordsPutAsync(String dstId, String userId, String viewId, RecordUpdateRO recordUpdateRO, final ApiCallback _callback) throws ApiException { - - okhttp3.Call localVarCall = updateRecordsPutValidateBeforeCall(dstId, userId, viewId, recordUpdateRO, _callback); - Type localVarReturnType = new TypeToken(){}.getType(); - localVarApiClient.executeAsync(localVarCall, localVarReturnType, _callback); - return localVarCall; - } -} diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/auth/ApiKeyAuth.java b/backend-server/application/src/main/java/com/apitable/databusclient/auth/ApiKeyAuth.java deleted file mode 100644 index cef3e39843..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/auth/ApiKeyAuth.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.auth; - -import com.apitable.databusclient.ApiException; -import com.apitable.databusclient.Pair; - -import java.net.URI; -import java.util.Map; -import java.util.List; - -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class ApiKeyAuth implements Authentication { - private final String location; - private final String paramName; - - private String apiKey; - private String apiKeyPrefix; - - public ApiKeyAuth(String location, String paramName) { - this.location = location; - this.paramName = paramName; - } - - public String getLocation() { - return location; - } - - public String getParamName() { - return paramName; - } - - public String getApiKey() { - return apiKey; - } - - public void setApiKey(String apiKey) { - this.apiKey = apiKey; - } - - public String getApiKeyPrefix() { - return apiKeyPrefix; - } - - public void setApiKeyPrefix(String apiKeyPrefix) { - this.apiKeyPrefix = apiKeyPrefix; - } - - @Override - public void applyToParams(List queryParams, Map headerParams, Map cookieParams, - String payload, String method, URI uri) throws ApiException { - if (apiKey == null) { - return; - } - String value; - if (apiKeyPrefix != null) { - value = apiKeyPrefix + " " + apiKey; - } else { - value = apiKey; - } - if ("query".equals(location)) { - queryParams.add(new Pair(paramName, value)); - } else if ("header".equals(location)) { - headerParams.put(paramName, value); - } else if ("cookie".equals(location)) { - cookieParams.put(paramName, value); - } - } -} diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/auth/Authentication.java b/backend-server/application/src/main/java/com/apitable/databusclient/auth/Authentication.java deleted file mode 100644 index 939106556f..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/auth/Authentication.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.auth; - -import com.apitable.databusclient.Pair; -import com.apitable.databusclient.ApiException; - -import java.net.URI; -import java.util.Map; -import java.util.List; - -public interface Authentication { - /** - * Apply authentication settings to header and query params. - * - * @param queryParams List of query parameters - * @param headerParams Map of header parameters - * @param cookieParams Map of cookie parameters - * @param payload HTTP request body - * @param method HTTP method - * @param uri URI - * @throws ApiException if failed to update the parameters - */ - void applyToParams(List queryParams, Map headerParams, Map cookieParams, String payload, String method, URI uri) throws ApiException; -} diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/auth/HttpBasicAuth.java b/backend-server/application/src/main/java/com/apitable/databusclient/auth/HttpBasicAuth.java deleted file mode 100644 index 4ad3d540aa..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/auth/HttpBasicAuth.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.auth; - -import com.apitable.databusclient.Pair; -import com.apitable.databusclient.ApiException; - -import okhttp3.Credentials; - -import java.net.URI; -import java.util.Map; -import java.util.List; - -import java.io.UnsupportedEncodingException; - -public class HttpBasicAuth implements Authentication { - private String username; - private String password; - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public String getPassword() { - return password; - } - - public void setPassword(String password) { - this.password = password; - } - - @Override - public void applyToParams(List queryParams, Map headerParams, Map cookieParams, - String payload, String method, URI uri) throws ApiException { - if (username == null && password == null) { - return; - } - headerParams.put("Authorization", Credentials.basic( - username == null ? "" : username, - password == null ? "" : password)); - } -} diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/auth/HttpBearerAuth.java b/backend-server/application/src/main/java/com/apitable/databusclient/auth/HttpBearerAuth.java deleted file mode 100644 index 0a3239b9a0..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/auth/HttpBearerAuth.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.auth; - -import com.apitable.databusclient.ApiException; -import com.apitable.databusclient.Pair; - -import java.net.URI; -import java.util.Map; -import java.util.List; - -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class HttpBearerAuth implements Authentication { - private final String scheme; - private String bearerToken; - - public HttpBearerAuth(String scheme) { - this.scheme = scheme; - } - - /** - * Gets the token, which together with the scheme, will be sent as the value of the Authorization header. - * - * @return The bearer token - */ - public String getBearerToken() { - return bearerToken; - } - - /** - * Sets the token, which together with the scheme, will be sent as the value of the Authorization header. - * - * @param bearerToken The bearer token to send in the Authorization header - */ - public void setBearerToken(String bearerToken) { - this.bearerToken = bearerToken; - } - - @Override - public void applyToParams(List queryParams, Map headerParams, Map cookieParams, - String payload, String method, URI uri) throws ApiException { - if (bearerToken == null) { - return; - } - - headerParams.put("Authorization", (scheme != null ? upperCaseBearer(scheme) + " " : "") + bearerToken); - } - - private static String upperCaseBearer(String scheme) { - return ("bearer".equalsIgnoreCase(scheme)) ? "Bearer" : scheme; - } -} diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/AbstractOpenApiSchema.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/AbstractOpenApiSchema.java deleted file mode 100644 index c78546659b..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/AbstractOpenApiSchema.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import com.apitable.databusclient.ApiException; -import java.util.Objects; -import java.lang.reflect.Type; -import java.util.Map; - -//import com.fasterxml.jackson.annotation.JsonValue; - -/** - * Abstract class for oneOf,anyOf schemas defined in OpenAPI spec - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public abstract class AbstractOpenApiSchema { - - // store the actual instance of the schema/object - private Object instance; - - // is nullable - private Boolean isNullable; - - // schema type (e.g. oneOf, anyOf) - private final String schemaType; - - public AbstractOpenApiSchema(String schemaType, Boolean isNullable) { - this.schemaType = schemaType; - this.isNullable = isNullable; - } - - /** - * Get the list of oneOf/anyOf composed schemas allowed to be stored in this object - * - * @return an instance of the actual schema/object - */ - public abstract Map> getSchemas(); - - /** - * Get the actual instance - * - * @return an instance of the actual schema/object - */ - //@JsonValue - public Object getActualInstance() {return instance;} - - /** - * Set the actual instance - * - * @param instance the actual instance of the schema/object - */ - public void setActualInstance(Object instance) {this.instance = instance;} - - /** - * Get the instant recursively when the schemas defined in oneOf/anyof happen to be oneOf/anyOf schema as well - * - * @return an instance of the actual schema/object - */ - public Object getActualInstanceRecursively() { - return getActualInstanceRecursively(this); - } - - private Object getActualInstanceRecursively(AbstractOpenApiSchema object) { - if (object.getActualInstance() == null) { - return null; - } else if (object.getActualInstance() instanceof AbstractOpenApiSchema) { - return getActualInstanceRecursively((AbstractOpenApiSchema)object.getActualInstance()); - } else { - return object.getActualInstance(); - } - } - - /** - * Get the schema type (e.g. anyOf, oneOf) - * - * @return the schema type - */ - public String getSchemaType() { - return schemaType; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class ").append(getClass()).append(" {\n"); - sb.append(" instance: ").append(toIndentedString(instance)).append("\n"); - sb.append(" isNullable: ").append(toIndentedString(isNullable)).append("\n"); - sb.append(" schemaType: ").append(toIndentedString(schemaType)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - AbstractOpenApiSchema a = (AbstractOpenApiSchema) o; - return Objects.equals(this.instance, a.instance) && - Objects.equals(this.isNullable, a.isNullable) && - Objects.equals(this.schemaType, a.schemaType); - } - - @Override - public int hashCode() { - return Objects.hash(instance, isNullable, schemaType); - } - - /** - * Is nullable - * - * @return true if it's nullable - */ - public Boolean isNullable() { - if (Boolean.TRUE.equals(isNullable)) { - return Boolean.TRUE; - } else { - return Boolean.FALSE; - } - } - - - -} diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/AiNode.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/AiNode.java deleted file mode 100644 index 85e3d2cb8c..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/AiNode.java +++ /dev/null @@ -1,336 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * AiNode - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class AiNode { - public static final String SERIALIZED_NAME_AI_ID = "aiId"; - @SerializedName(SERIALIZED_NAME_AI_ID) - private String aiId; - - public static final String SERIALIZED_NAME_NODE_ID = "nodeId"; - @SerializedName(SERIALIZED_NAME_NODE_ID) - private String nodeId; - - public static final String SERIALIZED_NAME_NODE_TYPE = "nodeType"; - @SerializedName(SERIALIZED_NAME_NODE_TYPE) - private Integer nodeType; - - public static final String SERIALIZED_NAME_SETTING = "setting"; - @SerializedName(SERIALIZED_NAME_SETTING) - private Object setting = null; - - public static final String SERIALIZED_NAME_VERSION = "version"; - @SerializedName(SERIALIZED_NAME_VERSION) - private Integer version; - - public AiNode() { - } - - public AiNode aiId(String aiId) { - - this.aiId = aiId; - return this; - } - - /** - * Get aiId - * @return aiId - **/ - @javax.annotation.Nonnull - public String getAiId() { - return aiId; - } - - - public void setAiId(String aiId) { - this.aiId = aiId; - } - - - public AiNode nodeId(String nodeId) { - - this.nodeId = nodeId; - return this; - } - - /** - * Get nodeId - * @return nodeId - **/ - @javax.annotation.Nonnull - public String getNodeId() { - return nodeId; - } - - - public void setNodeId(String nodeId) { - this.nodeId = nodeId; - } - - - public AiNode nodeType(Integer nodeType) { - - this.nodeType = nodeType; - return this; - } - - /** - * Get nodeType - * @return nodeType - **/ - @javax.annotation.Nonnull - public Integer getNodeType() { - return nodeType; - } - - - public void setNodeType(Integer nodeType) { - this.nodeType = nodeType; - } - - - public AiNode setting(Object setting) { - - this.setting = setting; - return this; - } - - /** - * Get setting - * @return setting - **/ - @javax.annotation.Nullable - public Object getSetting() { - return setting; - } - - - public void setSetting(Object setting) { - this.setting = setting; - } - - - public AiNode version(Integer version) { - - this.version = version; - return this; - } - - /** - * Get version - * @return version - **/ - @javax.annotation.Nonnull - public Integer getVersion() { - return version; - } - - - public void setVersion(Integer version) { - this.version = version; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - AiNode aiNode = (AiNode) o; - return Objects.equals(this.aiId, aiNode.aiId) && - Objects.equals(this.nodeId, aiNode.nodeId) && - Objects.equals(this.nodeType, aiNode.nodeType) && - Objects.equals(this.setting, aiNode.setting) && - Objects.equals(this.version, aiNode.version); - } - - @Override - public int hashCode() { - return Objects.hash(aiId, nodeId, nodeType, setting, version); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class AiNode {\n"); - sb.append(" aiId: ").append(toIndentedString(aiId)).append("\n"); - sb.append(" nodeId: ").append(toIndentedString(nodeId)).append("\n"); - sb.append(" nodeType: ").append(toIndentedString(nodeType)).append("\n"); - sb.append(" setting: ").append(toIndentedString(setting)).append("\n"); - sb.append(" version: ").append(toIndentedString(version)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("aiId"); - openapiFields.add("nodeId"); - openapiFields.add("nodeType"); - openapiFields.add("setting"); - openapiFields.add("version"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("aiId"); - openapiRequiredFields.add("nodeId"); - openapiRequiredFields.add("nodeType"); - openapiRequiredFields.add("setting"); - openapiRequiredFields.add("version"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to AiNode - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!AiNode.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in AiNode is not found in the empty JSON string", AiNode.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!AiNode.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `AiNode` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : AiNode.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if (!jsonObj.get("aiId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `aiId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("aiId").toString())); - } - if (!jsonObj.get("nodeId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `nodeId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("nodeId").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!AiNode.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'AiNode' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(AiNode.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, AiNode value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public AiNode read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of AiNode given an JSON string - * - * @param jsonString JSON string - * @return An instance of AiNode - * @throws IOException if the JSON string is invalid with respect to AiNode - */ - public static AiNode fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, AiNode.class); - } - - /** - * Convert an instance of AiNode to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/AiPO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/AiPO.java deleted file mode 100644 index 3010eb7449..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/AiPO.java +++ /dev/null @@ -1,448 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * AiPO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class AiPO { - public static final String SERIALIZED_NAME_AI_ID = "aiId"; - @SerializedName(SERIALIZED_NAME_AI_ID) - private String aiId; - - public static final String SERIALIZED_NAME_EMBEDDING_MODEL = "embeddingModel"; - @SerializedName(SERIALIZED_NAME_EMBEDDING_MODEL) - private String embeddingModel; - - public static final String SERIALIZED_NAME_MODEL = "model"; - @SerializedName(SERIALIZED_NAME_MODEL) - private String model; - - public static final String SERIALIZED_NAME_NAME = "name"; - @SerializedName(SERIALIZED_NAME_NAME) - private String name; - - public static final String SERIALIZED_NAME_PROLOGUE = "prologue"; - @SerializedName(SERIALIZED_NAME_PROLOGUE) - private String prologue; - - public static final String SERIALIZED_NAME_PROMPT = "prompt"; - @SerializedName(SERIALIZED_NAME_PROMPT) - private String prompt; - - public static final String SERIALIZED_NAME_SETTING = "setting"; - @SerializedName(SERIALIZED_NAME_SETTING) - private String setting; - - public static final String SERIALIZED_NAME_TYPE = "type"; - @SerializedName(SERIALIZED_NAME_TYPE) - private String type; - - public AiPO() { - } - - public AiPO aiId(String aiId) { - - this.aiId = aiId; - return this; - } - - /** - * Get aiId - * @return aiId - **/ - @javax.annotation.Nonnull - public String getAiId() { - return aiId; - } - - - public void setAiId(String aiId) { - this.aiId = aiId; - } - - - public AiPO embeddingModel(String embeddingModel) { - - this.embeddingModel = embeddingModel; - return this; - } - - /** - * Get embeddingModel - * @return embeddingModel - **/ - @javax.annotation.Nullable - public String getEmbeddingModel() { - return embeddingModel; - } - - - public void setEmbeddingModel(String embeddingModel) { - this.embeddingModel = embeddingModel; - } - - - public AiPO model(String model) { - - this.model = model; - return this; - } - - /** - * Get model - * @return model - **/ - @javax.annotation.Nullable - public String getModel() { - return model; - } - - - public void setModel(String model) { - this.model = model; - } - - - public AiPO name(String name) { - - this.name = name; - return this; - } - - /** - * Get name - * @return name - **/ - @javax.annotation.Nonnull - public String getName() { - return name; - } - - - public void setName(String name) { - this.name = name; - } - - - public AiPO prologue(String prologue) { - - this.prologue = prologue; - return this; - } - - /** - * Get prologue - * @return prologue - **/ - @javax.annotation.Nullable - public String getPrologue() { - return prologue; - } - - - public void setPrologue(String prologue) { - this.prologue = prologue; - } - - - public AiPO prompt(String prompt) { - - this.prompt = prompt; - return this; - } - - /** - * Get prompt - * @return prompt - **/ - @javax.annotation.Nullable - public String getPrompt() { - return prompt; - } - - - public void setPrompt(String prompt) { - this.prompt = prompt; - } - - - public AiPO setting(String setting) { - - this.setting = setting; - return this; - } - - /** - * Get setting - * @return setting - **/ - @javax.annotation.Nullable - public String getSetting() { - return setting; - } - - - public void setSetting(String setting) { - this.setting = setting; - } - - - public AiPO type(String type) { - - this.type = type; - return this; - } - - /** - * Get type - * @return type - **/ - @javax.annotation.Nonnull - public String getType() { - return type; - } - - - public void setType(String type) { - this.type = type; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - AiPO aiPO = (AiPO) o; - return Objects.equals(this.aiId, aiPO.aiId) && - Objects.equals(this.embeddingModel, aiPO.embeddingModel) && - Objects.equals(this.model, aiPO.model) && - Objects.equals(this.name, aiPO.name) && - Objects.equals(this.prologue, aiPO.prologue) && - Objects.equals(this.prompt, aiPO.prompt) && - Objects.equals(this.setting, aiPO.setting) && - Objects.equals(this.type, aiPO.type); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(aiId, embeddingModel, model, name, prologue, prompt, setting, type); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class AiPO {\n"); - sb.append(" aiId: ").append(toIndentedString(aiId)).append("\n"); - sb.append(" embeddingModel: ").append(toIndentedString(embeddingModel)).append("\n"); - sb.append(" model: ").append(toIndentedString(model)).append("\n"); - sb.append(" name: ").append(toIndentedString(name)).append("\n"); - sb.append(" prologue: ").append(toIndentedString(prologue)).append("\n"); - sb.append(" prompt: ").append(toIndentedString(prompt)).append("\n"); - sb.append(" setting: ").append(toIndentedString(setting)).append("\n"); - sb.append(" type: ").append(toIndentedString(type)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("aiId"); - openapiFields.add("embeddingModel"); - openapiFields.add("model"); - openapiFields.add("name"); - openapiFields.add("prologue"); - openapiFields.add("prompt"); - openapiFields.add("setting"); - openapiFields.add("type"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("aiId"); - openapiRequiredFields.add("name"); - openapiRequiredFields.add("type"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to AiPO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!AiPO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in AiPO is not found in the empty JSON string", AiPO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!AiPO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `AiPO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : AiPO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if (!jsonObj.get("aiId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `aiId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("aiId").toString())); - } - if ((jsonObj.get("embeddingModel") != null && !jsonObj.get("embeddingModel").isJsonNull()) && !jsonObj.get("embeddingModel").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `embeddingModel` to be a primitive type in the JSON string but got `%s`", jsonObj.get("embeddingModel").toString())); - } - if ((jsonObj.get("model") != null && !jsonObj.get("model").isJsonNull()) && !jsonObj.get("model").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `model` to be a primitive type in the JSON string but got `%s`", jsonObj.get("model").toString())); - } - if (!jsonObj.get("name").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `name` to be a primitive type in the JSON string but got `%s`", jsonObj.get("name").toString())); - } - if ((jsonObj.get("prologue") != null && !jsonObj.get("prologue").isJsonNull()) && !jsonObj.get("prologue").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `prologue` to be a primitive type in the JSON string but got `%s`", jsonObj.get("prologue").toString())); - } - if ((jsonObj.get("prompt") != null && !jsonObj.get("prompt").isJsonNull()) && !jsonObj.get("prompt").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `prompt` to be a primitive type in the JSON string but got `%s`", jsonObj.get("prompt").toString())); - } - if ((jsonObj.get("setting") != null && !jsonObj.get("setting").isJsonNull()) && !jsonObj.get("setting").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `setting` to be a primitive type in the JSON string but got `%s`", jsonObj.get("setting").toString())); - } - if (!jsonObj.get("type").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `type` to be a primitive type in the JSON string but got `%s`", jsonObj.get("type").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!AiPO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'AiPO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(AiPO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, AiPO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public AiPO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of AiPO given an JSON string - * - * @param jsonString JSON string - * @return An instance of AiPO - * @throws IOException if the JSON string is invalid with respect to AiPO - */ - public static AiPO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, AiPO.class); - } - - /** - * Convert an instance of AiPO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/AlarmUser.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/AlarmUser.java deleted file mode 100644 index fa3b090869..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/AlarmUser.java +++ /dev/null @@ -1,247 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.apitable.databusclient.model.AlarmUsersType; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * AlarmUser - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class AlarmUser { - public static final String SERIALIZED_NAME_DATA = "data"; - @SerializedName(SERIALIZED_NAME_DATA) - private String data; - - public static final String SERIALIZED_NAME_TYPE = "type"; - @SerializedName(SERIALIZED_NAME_TYPE) - private AlarmUsersType type; - - public AlarmUser() { - } - - public AlarmUser data(String data) { - - this.data = data; - return this; - } - - /** - * Get data - * @return data - **/ - @javax.annotation.Nonnull - public String getData() { - return data; - } - - - public void setData(String data) { - this.data = data; - } - - - public AlarmUser type(AlarmUsersType type) { - - this.type = type; - return this; - } - - /** - * Get type - * @return type - **/ - @javax.annotation.Nonnull - public AlarmUsersType getType() { - return type; - } - - - public void setType(AlarmUsersType type) { - this.type = type; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - AlarmUser alarmUser = (AlarmUser) o; - return Objects.equals(this.data, alarmUser.data) && - Objects.equals(this.type, alarmUser.type); - } - - @Override - public int hashCode() { - return Objects.hash(data, type); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class AlarmUser {\n"); - sb.append(" data: ").append(toIndentedString(data)).append("\n"); - sb.append(" type: ").append(toIndentedString(type)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("data"); - openapiFields.add("type"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("data"); - openapiRequiredFields.add("type"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to AlarmUser - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!AlarmUser.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in AlarmUser is not found in the empty JSON string", AlarmUser.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!AlarmUser.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `AlarmUser` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : AlarmUser.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if (!jsonObj.get("data").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `data` to be a primitive type in the JSON string but got `%s`", jsonObj.get("data").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!AlarmUser.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'AlarmUser' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(AlarmUser.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, AlarmUser value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public AlarmUser read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of AlarmUser given an JSON string - * - * @param jsonString JSON string - * @return An instance of AlarmUser - * @throws IOException if the JSON string is invalid with respect to AlarmUser - */ - public static AlarmUser fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, AlarmUser.class); - } - - /** - * Convert an instance of AlarmUser to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/AlarmUsersType.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/AlarmUsersType.java deleted file mode 100644 index bdfb13185a..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/AlarmUsersType.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.annotations.SerializedName; - -import java.io.IOException; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; - -/** - * Gets or Sets AlarmUsersType - */ -@JsonAdapter(AlarmUsersType.Adapter.class) -public enum AlarmUsersType { - - FIELD("Field"), - - MEMBER("Member"); - - private String value; - - AlarmUsersType(String value) { - this.value = value; - } - - public String getValue() { - return value; - } - - @Override - public String toString() { - return String.valueOf(value); - } - - public static AlarmUsersType fromValue(String value) { - for (AlarmUsersType b : AlarmUsersType.values()) { - if (b.value.equals(value)) { - return b; - } - } - throw new IllegalArgumentException("Unexpected value '" + value + "'"); - } - - public static class Adapter extends TypeAdapter { - @Override - public void write(final JsonWriter jsonWriter, final AlarmUsersType enumeration) throws IOException { - jsonWriter.value(enumeration.getValue()); - } - - @Override - public AlarmUsersType read(final JsonReader jsonReader) throws IOException { - String value = jsonReader.nextString(); - return AlarmUsersType.fromValue(value); - } - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/AnyBaseField.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/AnyBaseField.java deleted file mode 100644 index 996a99bb74..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/AnyBaseField.java +++ /dev/null @@ -1,329 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; - - - -import java.io.IOException; -import java.lang.reflect.Type; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashSet; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapter; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.JsonPrimitive; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonSerializationContext; -import com.google.gson.JsonSerializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonArray; -import com.google.gson.JsonParseException; - -import com.apitable.databusclient.JSON; - -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class AnyBaseField extends AbstractOpenApiSchema { - private static final Logger log = Logger.getLogger(AnyBaseField.class.getName()); - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!AnyBaseField.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'AnyBaseField' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter adapterInteger = gson.getDelegateAdapter(this, TypeToken.get(Integer.class)); - final TypeAdapter adapterString = gson.getDelegateAdapter(this, TypeToken.get(String.class)); - final TypeAdapter adapterDouble = gson.getDelegateAdapter(this, TypeToken.get(Double.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, AnyBaseField value) throws IOException { - if (value == null || value.getActualInstance() == null) { - elementAdapter.write(out, null); - return; - } - - // check if the actual instance is of the type `Integer` - if (value.getActualInstance() instanceof Integer) { - JsonPrimitive primitive = adapterInteger.toJsonTree((Integer)value.getActualInstance()).getAsJsonPrimitive(); - elementAdapter.write(out, primitive); - return; - } - // check if the actual instance is of the type `String` - if (value.getActualInstance() instanceof String) { - JsonPrimitive primitive = adapterString.toJsonTree((String)value.getActualInstance()).getAsJsonPrimitive(); - elementAdapter.write(out, primitive); - return; - } - // check if the actual instance is of the type `Double` - if (value.getActualInstance() instanceof Double) { - JsonPrimitive primitive = adapterDouble.toJsonTree((Double)value.getActualInstance()).getAsJsonPrimitive(); - elementAdapter.write(out, primitive); - return; - } - throw new IOException("Failed to serialize as the type doesn't match oneOf schemas: Double, Integer, String"); - } - - @Override - public AnyBaseField read(JsonReader in) throws IOException { - Object deserialized = null; - JsonElement jsonElement = elementAdapter.read(in); - - int match = 0; - ArrayList errorMessages = new ArrayList<>(); - TypeAdapter actualAdapter = elementAdapter; - - // deserialize Integer - try { - // validate the JSON object to see if any exception is thrown - if(!jsonElement.getAsJsonPrimitive().isNumber()) { - throw new IllegalArgumentException(String.format("Expected json element to be of type Number in the JSON string but got `%s`", jsonElement.toString())); - } - actualAdapter = adapterInteger; - match++; - log.log(Level.FINER, "Input data matches schema 'Integer'"); - } catch (Exception e) { - // deserialization failed, continue - errorMessages.add(String.format("Deserialization for Integer failed with `%s`.", e.getMessage())); - log.log(Level.FINER, "Input data does not match schema 'Integer'", e); - } - // deserialize String - try { - // validate the JSON object to see if any exception is thrown - if(!jsonElement.getAsJsonPrimitive().isString()) { - throw new IllegalArgumentException(String.format("Expected json element to be of type String in the JSON string but got `%s`", jsonElement.toString())); - } - actualAdapter = adapterString; - match++; - log.log(Level.FINER, "Input data matches schema 'String'"); - } catch (Exception e) { - // deserialization failed, continue - errorMessages.add(String.format("Deserialization for String failed with `%s`.", e.getMessage())); - log.log(Level.FINER, "Input data does not match schema 'String'", e); - } - // deserialize Double - try { - // validate the JSON object to see if any exception is thrown - if(!jsonElement.getAsJsonPrimitive().isNumber()) { - throw new IllegalArgumentException(String.format("Expected json element to be of type Number in the JSON string but got `%s`", jsonElement.toString())); - } - actualAdapter = adapterDouble; - match++; - log.log(Level.FINER, "Input data matches schema 'Double'"); - } catch (Exception e) { - // deserialization failed, continue - errorMessages.add(String.format("Deserialization for Double failed with `%s`.", e.getMessage())); - log.log(Level.FINER, "Input data does not match schema 'Double'", e); - } - - if (match == 1) { - AnyBaseField ret = new AnyBaseField(); - ret.setActualInstance(actualAdapter.fromJsonTree(jsonElement)); - return ret; - } - - throw new IOException(String.format("Failed deserialization for AnyBaseField: %d classes match result, expected 1. Detailed failure message for oneOf schemas: %s. JSON: %s", match, errorMessages, jsonElement.toString())); - } - }.nullSafe(); - } - } - - // store a list of schema names defined in oneOf - public static final Map> schemas = new HashMap>(); - - public AnyBaseField() { - super("oneOf", Boolean.FALSE); - } - - public AnyBaseField(Double o) { - super("oneOf", Boolean.FALSE); - setActualInstance(o); - } - - public AnyBaseField(Integer o) { - super("oneOf", Boolean.FALSE); - setActualInstance(o); - } - - public AnyBaseField(String o) { - super("oneOf", Boolean.FALSE); - setActualInstance(o); - } - - static { - schemas.put("Integer", Integer.class); - schemas.put("String", String.class); - schemas.put("Double", Double.class); - } - - @Override - public Map> getSchemas() { - return AnyBaseField.schemas; - } - - /** - * Set the instance that matches the oneOf child schema, check - * the instance parameter is valid against the oneOf child schemas: - * Double, Integer, String - * - * It could be an instance of the 'oneOf' schemas. - */ - @Override - public void setActualInstance(Object instance) { - if (instance instanceof Integer) { - super.setActualInstance(instance); - return; - } - - if (instance instanceof String) { - super.setActualInstance(instance); - return; - } - - if (instance instanceof Double) { - super.setActualInstance(instance); - return; - } - - throw new RuntimeException("Invalid instance type. Must be Double, Integer, String"); - } - - /** - * Get the actual instance, which can be the following: - * Double, Integer, String - * - * @return The actual instance (Double, Integer, String) - */ - @Override - public Object getActualInstance() { - return super.getActualInstance(); - } - - /** - * Get the actual instance of `Integer`. If the actual instance is not `Integer`, - * the ClassCastException will be thrown. - * - * @return The actual instance of `Integer` - * @throws ClassCastException if the instance is not `Integer` - */ - public Integer getInteger() throws ClassCastException { - return (Integer)super.getActualInstance(); - } - /** - * Get the actual instance of `String`. If the actual instance is not `String`, - * the ClassCastException will be thrown. - * - * @return The actual instance of `String` - * @throws ClassCastException if the instance is not `String` - */ - public String getString() throws ClassCastException { - return (String)super.getActualInstance(); - } - /** - * Get the actual instance of `Double`. If the actual instance is not `Double`, - * the ClassCastException will be thrown. - * - * @return The actual instance of `Double` - * @throws ClassCastException if the instance is not `Double` - */ - public Double getDouble() throws ClassCastException { - return (Double)super.getActualInstance(); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to AnyBaseField - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - // validate oneOf schemas one by one - int validCount = 0; - ArrayList errorMessages = new ArrayList<>(); - // validate the json string with Integer - try { - if(!jsonElement.getAsJsonPrimitive().isNumber()) { - throw new IllegalArgumentException(String.format("Expected json element to be of type Number in the JSON string but got `%s`", jsonElement.toString())); - } - validCount++; - } catch (Exception e) { - errorMessages.add(String.format("Deserialization for Integer failed with `%s`.", e.getMessage())); - // continue to the next one - } - // validate the json string with String - try { - if(!jsonElement.getAsJsonPrimitive().isString()) { - throw new IllegalArgumentException(String.format("Expected json element to be of type String in the JSON string but got `%s`", jsonElement.toString())); - } - validCount++; - } catch (Exception e) { - errorMessages.add(String.format("Deserialization for String failed with `%s`.", e.getMessage())); - // continue to the next one - } - // validate the json string with Double - try { - if(!jsonElement.getAsJsonPrimitive().isNumber()) { - throw new IllegalArgumentException(String.format("Expected json element to be of type Number in the JSON string but got `%s`", jsonElement.toString())); - } - validCount++; - } catch (Exception e) { - errorMessages.add(String.format("Deserialization for Double failed with `%s`.", e.getMessage())); - // continue to the next one - } - if (validCount != 1) { - throw new IOException(String.format("The JSON string is invalid for AnyBaseField with oneOf schemas: Double, Integer, String. %d class(es) match the result, expected 1. Detailed failure message for oneOf schemas: %s. JSON: %s", validCount, errorMessages, jsonElement.toString())); - } - } - - /** - * Create an instance of AnyBaseField given an JSON string - * - * @param jsonString JSON string - * @return An instance of AnyBaseField - * @throws IOException if the JSON string is invalid with respect to AnyBaseField - */ - public static AnyBaseField fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, AnyBaseField.class); - } - - /** - * Convert an instance of AnyBaseField to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiRecordDto.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiRecordDto.java deleted file mode 100644 index e811d64b42..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiRecordDto.java +++ /dev/null @@ -1,314 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * ApiRecordDto - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class ApiRecordDto { - public static final String SERIALIZED_NAME_CREATED_AT = "createdAt"; - @SerializedName(SERIALIZED_NAME_CREATED_AT) - private Long createdAt; - - public static final String SERIALIZED_NAME_FIELDS = "fields"; - @SerializedName(SERIALIZED_NAME_FIELDS) - private Map fields = new HashMap<>(); - - public static final String SERIALIZED_NAME_RECORD_ID = "recordId"; - @SerializedName(SERIALIZED_NAME_RECORD_ID) - private String recordId; - - public static final String SERIALIZED_NAME_UPDATED_AT = "updatedAt"; - @SerializedName(SERIALIZED_NAME_UPDATED_AT) - private Long updatedAt; - - public ApiRecordDto() { - } - - public ApiRecordDto createdAt(Long createdAt) { - - this.createdAt = createdAt; - return this; - } - - /** - * Get createdAt - * @return createdAt - **/ - @javax.annotation.Nonnull - public Long getCreatedAt() { - return createdAt; - } - - - public void setCreatedAt(Long createdAt) { - this.createdAt = createdAt; - } - - - public ApiRecordDto fields(Map fields) { - - this.fields = fields; - return this; - } - - public ApiRecordDto putFieldsItem(String key, String fieldsItem) { - if (this.fields == null) { - this.fields = new HashMap<>(); - } - this.fields.put(key, fieldsItem); - return this; - } - - /** - * Get fields - * @return fields - **/ - @javax.annotation.Nonnull - public Map getFields() { - return fields; - } - - - public void setFields(Map fields) { - this.fields = fields; - } - - - public ApiRecordDto recordId(String recordId) { - - this.recordId = recordId; - return this; - } - - /** - * Get recordId - * @return recordId - **/ - @javax.annotation.Nonnull - public String getRecordId() { - return recordId; - } - - - public void setRecordId(String recordId) { - this.recordId = recordId; - } - - - public ApiRecordDto updatedAt(Long updatedAt) { - - this.updatedAt = updatedAt; - return this; - } - - /** - * Get updatedAt - * @return updatedAt - **/ - @javax.annotation.Nonnull - public Long getUpdatedAt() { - return updatedAt; - } - - - public void setUpdatedAt(Long updatedAt) { - this.updatedAt = updatedAt; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ApiRecordDto apiRecordDto = (ApiRecordDto) o; - return Objects.equals(this.createdAt, apiRecordDto.createdAt) && - Objects.equals(this.fields, apiRecordDto.fields) && - Objects.equals(this.recordId, apiRecordDto.recordId) && - Objects.equals(this.updatedAt, apiRecordDto.updatedAt); - } - - @Override - public int hashCode() { - return Objects.hash(createdAt, fields, recordId, updatedAt); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class ApiRecordDto {\n"); - sb.append(" createdAt: ").append(toIndentedString(createdAt)).append("\n"); - sb.append(" fields: ").append(toIndentedString(fields)).append("\n"); - sb.append(" recordId: ").append(toIndentedString(recordId)).append("\n"); - sb.append(" updatedAt: ").append(toIndentedString(updatedAt)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("createdAt"); - openapiFields.add("fields"); - openapiFields.add("recordId"); - openapiFields.add("updatedAt"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("createdAt"); - openapiRequiredFields.add("fields"); - openapiRequiredFields.add("recordId"); - openapiRequiredFields.add("updatedAt"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to ApiRecordDto - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!ApiRecordDto.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in ApiRecordDto is not found in the empty JSON string", ApiRecordDto.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!ApiRecordDto.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `ApiRecordDto` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : ApiRecordDto.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if (!jsonObj.get("recordId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `recordId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("recordId").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!ApiRecordDto.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'ApiRecordDto' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(ApiRecordDto.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, ApiRecordDto value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public ApiRecordDto read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of ApiRecordDto given an JSON string - * - * @param jsonString JSON string - * @return An instance of ApiRecordDto - * @throws IOException if the JSON string is invalid with respect to ApiRecordDto - */ - public static ApiRecordDto fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, ApiRecordDto.class); - } - - /** - * Convert an instance of ApiRecordDto to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiResponseAiPO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiResponseAiPO.java deleted file mode 100644 index ca124a2c14..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiResponseAiPO.java +++ /dev/null @@ -1,321 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.apitable.databusclient.model.AiPO; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * ApiResponseAiPO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class ApiResponseAiPO { - public static final String SERIALIZED_NAME_CODE = "code"; - @SerializedName(SERIALIZED_NAME_CODE) - private Integer code; - - public static final String SERIALIZED_NAME_DATA = "data"; - @SerializedName(SERIALIZED_NAME_DATA) - private AiPO data; - - public static final String SERIALIZED_NAME_MESSAGE = "message"; - @SerializedName(SERIALIZED_NAME_MESSAGE) - private String message; - - public static final String SERIALIZED_NAME_SUCCESS = "success"; - @SerializedName(SERIALIZED_NAME_SUCCESS) - private Boolean success; - - public ApiResponseAiPO() { - } - - public ApiResponseAiPO code(Integer code) { - - this.code = code; - return this; - } - - /** - * Get code - * minimum: 0 - * @return code - **/ - @javax.annotation.Nonnull - public Integer getCode() { - return code; - } - - - public void setCode(Integer code) { - this.code = code; - } - - - public ApiResponseAiPO data(AiPO data) { - - this.data = data; - return this; - } - - /** - * Get data - * @return data - **/ - @javax.annotation.Nullable - public AiPO getData() { - return data; - } - - - public void setData(AiPO data) { - this.data = data; - } - - - public ApiResponseAiPO message(String message) { - - this.message = message; - return this; - } - - /** - * Get message - * @return message - **/ - @javax.annotation.Nonnull - public String getMessage() { - return message; - } - - - public void setMessage(String message) { - this.message = message; - } - - - public ApiResponseAiPO success(Boolean success) { - - this.success = success; - return this; - } - - /** - * Get success - * @return success - **/ - @javax.annotation.Nonnull - public Boolean getSuccess() { - return success; - } - - - public void setSuccess(Boolean success) { - this.success = success; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ApiResponseAiPO apiResponseAiPO = (ApiResponseAiPO) o; - return Objects.equals(this.code, apiResponseAiPO.code) && - Objects.equals(this.data, apiResponseAiPO.data) && - Objects.equals(this.message, apiResponseAiPO.message) && - Objects.equals(this.success, apiResponseAiPO.success); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(code, data, message, success); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class ApiResponseAiPO {\n"); - sb.append(" code: ").append(toIndentedString(code)).append("\n"); - sb.append(" data: ").append(toIndentedString(data)).append("\n"); - sb.append(" message: ").append(toIndentedString(message)).append("\n"); - sb.append(" success: ").append(toIndentedString(success)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("code"); - openapiFields.add("data"); - openapiFields.add("message"); - openapiFields.add("success"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("code"); - openapiRequiredFields.add("message"); - openapiRequiredFields.add("success"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to ApiResponseAiPO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!ApiResponseAiPO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in ApiResponseAiPO is not found in the empty JSON string", ApiResponseAiPO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!ApiResponseAiPO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `ApiResponseAiPO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : ApiResponseAiPO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - // validate the optional field `data` - if (jsonObj.get("data") != null && !jsonObj.get("data").isJsonNull()) { - AiPO.validateJsonElement(jsonObj.get("data")); - } - if (!jsonObj.get("message").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `message` to be a primitive type in the JSON string but got `%s`", jsonObj.get("message").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!ApiResponseAiPO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'ApiResponseAiPO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(ApiResponseAiPO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, ApiResponseAiPO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public ApiResponseAiPO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of ApiResponseAiPO given an JSON string - * - * @param jsonString JSON string - * @return An instance of ApiResponseAiPO - * @throws IOException if the JSON string is invalid with respect to ApiResponseAiPO - */ - public static ApiResponseAiPO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, ApiResponseAiPO.class); - } - - /** - * Convert an instance of ApiResponseAiPO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiResponseAutomationActionPO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiResponseAutomationActionPO.java deleted file mode 100644 index c1a2da8fe1..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiResponseAutomationActionPO.java +++ /dev/null @@ -1,341 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.apitable.databusclient.model.AutomationActionPO; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * ApiResponseAutomationActionPO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class ApiResponseAutomationActionPO { - public static final String SERIALIZED_NAME_CODE = "code"; - @SerializedName(SERIALIZED_NAME_CODE) - private Integer code; - - public static final String SERIALIZED_NAME_DATA = "data"; - @SerializedName(SERIALIZED_NAME_DATA) - private List data; - - public static final String SERIALIZED_NAME_MESSAGE = "message"; - @SerializedName(SERIALIZED_NAME_MESSAGE) - private String message; - - public static final String SERIALIZED_NAME_SUCCESS = "success"; - @SerializedName(SERIALIZED_NAME_SUCCESS) - private Boolean success; - - public ApiResponseAutomationActionPO() { - } - - public ApiResponseAutomationActionPO code(Integer code) { - - this.code = code; - return this; - } - - /** - * Get code - * minimum: 0 - * @return code - **/ - @javax.annotation.Nonnull - public Integer getCode() { - return code; - } - - - public void setCode(Integer code) { - this.code = code; - } - - - public ApiResponseAutomationActionPO data(List data) { - - this.data = data; - return this; - } - - public ApiResponseAutomationActionPO addDataItem(AutomationActionPO dataItem) { - if (this.data == null) { - this.data = new ArrayList<>(); - } - this.data.add(dataItem); - return this; - } - - /** - * Get data - * @return data - **/ - @javax.annotation.Nullable - public List getData() { - return data; - } - - - public void setData(List data) { - this.data = data; - } - - - public ApiResponseAutomationActionPO message(String message) { - - this.message = message; - return this; - } - - /** - * Get message - * @return message - **/ - @javax.annotation.Nonnull - public String getMessage() { - return message; - } - - - public void setMessage(String message) { - this.message = message; - } - - - public ApiResponseAutomationActionPO success(Boolean success) { - - this.success = success; - return this; - } - - /** - * Get success - * @return success - **/ - @javax.annotation.Nonnull - public Boolean getSuccess() { - return success; - } - - - public void setSuccess(Boolean success) { - this.success = success; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ApiResponseAutomationActionPO apiResponseAutomationActionPO = (ApiResponseAutomationActionPO) o; - return Objects.equals(this.code, apiResponseAutomationActionPO.code) && - Objects.equals(this.data, apiResponseAutomationActionPO.data) && - Objects.equals(this.message, apiResponseAutomationActionPO.message) && - Objects.equals(this.success, apiResponseAutomationActionPO.success); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(code, data, message, success); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class ApiResponseAutomationActionPO {\n"); - sb.append(" code: ").append(toIndentedString(code)).append("\n"); - sb.append(" data: ").append(toIndentedString(data)).append("\n"); - sb.append(" message: ").append(toIndentedString(message)).append("\n"); - sb.append(" success: ").append(toIndentedString(success)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("code"); - openapiFields.add("data"); - openapiFields.add("message"); - openapiFields.add("success"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("code"); - openapiRequiredFields.add("message"); - openapiRequiredFields.add("success"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to ApiResponseAutomationActionPO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!ApiResponseAutomationActionPO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in ApiResponseAutomationActionPO is not found in the empty JSON string", ApiResponseAutomationActionPO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!ApiResponseAutomationActionPO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `ApiResponseAutomationActionPO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : ApiResponseAutomationActionPO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if (jsonObj.get("data") != null && !jsonObj.get("data").isJsonNull()) { - JsonArray jsonArraydata = jsonObj.getAsJsonArray("data"); - if (jsonArraydata != null) { - // ensure the json data is an array - if (!jsonObj.get("data").isJsonArray()) { - throw new IllegalArgumentException(String.format("Expected the field `data` to be an array in the JSON string but got `%s`", jsonObj.get("data").toString())); - } - - // validate the optional field `data` (array) - for (int i = 0; i < jsonArraydata.size(); i++) { - AutomationActionPO.validateJsonElement(jsonArraydata.get(i)); - }; - } - } - if (!jsonObj.get("message").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `message` to be a primitive type in the JSON string but got `%s`", jsonObj.get("message").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!ApiResponseAutomationActionPO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'ApiResponseAutomationActionPO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(ApiResponseAutomationActionPO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, ApiResponseAutomationActionPO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public ApiResponseAutomationActionPO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of ApiResponseAutomationActionPO given an JSON string - * - * @param jsonString JSON string - * @return An instance of ApiResponseAutomationActionPO - * @throws IOException if the JSON string is invalid with respect to ApiResponseAutomationActionPO - */ - public static ApiResponseAutomationActionPO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, ApiResponseAutomationActionPO.class); - } - - /** - * Convert an instance of ApiResponseAutomationActionPO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiResponseAutomationRobotIntroductionSO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiResponseAutomationRobotIntroductionSO.java deleted file mode 100644 index 9eed67014d..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiResponseAutomationRobotIntroductionSO.java +++ /dev/null @@ -1,321 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.apitable.databusclient.model.AutomationRobotIntroductionSO; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * ApiResponseAutomationRobotIntroductionSO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class ApiResponseAutomationRobotIntroductionSO { - public static final String SERIALIZED_NAME_CODE = "code"; - @SerializedName(SERIALIZED_NAME_CODE) - private Integer code; - - public static final String SERIALIZED_NAME_DATA = "data"; - @SerializedName(SERIALIZED_NAME_DATA) - private AutomationRobotIntroductionSO data; - - public static final String SERIALIZED_NAME_MESSAGE = "message"; - @SerializedName(SERIALIZED_NAME_MESSAGE) - private String message; - - public static final String SERIALIZED_NAME_SUCCESS = "success"; - @SerializedName(SERIALIZED_NAME_SUCCESS) - private Boolean success; - - public ApiResponseAutomationRobotIntroductionSO() { - } - - public ApiResponseAutomationRobotIntroductionSO code(Integer code) { - - this.code = code; - return this; - } - - /** - * Get code - * minimum: 0 - * @return code - **/ - @javax.annotation.Nonnull - public Integer getCode() { - return code; - } - - - public void setCode(Integer code) { - this.code = code; - } - - - public ApiResponseAutomationRobotIntroductionSO data(AutomationRobotIntroductionSO data) { - - this.data = data; - return this; - } - - /** - * Get data - * @return data - **/ - @javax.annotation.Nullable - public AutomationRobotIntroductionSO getData() { - return data; - } - - - public void setData(AutomationRobotIntroductionSO data) { - this.data = data; - } - - - public ApiResponseAutomationRobotIntroductionSO message(String message) { - - this.message = message; - return this; - } - - /** - * Get message - * @return message - **/ - @javax.annotation.Nonnull - public String getMessage() { - return message; - } - - - public void setMessage(String message) { - this.message = message; - } - - - public ApiResponseAutomationRobotIntroductionSO success(Boolean success) { - - this.success = success; - return this; - } - - /** - * Get success - * @return success - **/ - @javax.annotation.Nonnull - public Boolean getSuccess() { - return success; - } - - - public void setSuccess(Boolean success) { - this.success = success; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ApiResponseAutomationRobotIntroductionSO apiResponseAutomationRobotIntroductionSO = (ApiResponseAutomationRobotIntroductionSO) o; - return Objects.equals(this.code, apiResponseAutomationRobotIntroductionSO.code) && - Objects.equals(this.data, apiResponseAutomationRobotIntroductionSO.data) && - Objects.equals(this.message, apiResponseAutomationRobotIntroductionSO.message) && - Objects.equals(this.success, apiResponseAutomationRobotIntroductionSO.success); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(code, data, message, success); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class ApiResponseAutomationRobotIntroductionSO {\n"); - sb.append(" code: ").append(toIndentedString(code)).append("\n"); - sb.append(" data: ").append(toIndentedString(data)).append("\n"); - sb.append(" message: ").append(toIndentedString(message)).append("\n"); - sb.append(" success: ").append(toIndentedString(success)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("code"); - openapiFields.add("data"); - openapiFields.add("message"); - openapiFields.add("success"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("code"); - openapiRequiredFields.add("message"); - openapiRequiredFields.add("success"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to ApiResponseAutomationRobotIntroductionSO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!ApiResponseAutomationRobotIntroductionSO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in ApiResponseAutomationRobotIntroductionSO is not found in the empty JSON string", ApiResponseAutomationRobotIntroductionSO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!ApiResponseAutomationRobotIntroductionSO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `ApiResponseAutomationRobotIntroductionSO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : ApiResponseAutomationRobotIntroductionSO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - // validate the optional field `data` - if (jsonObj.get("data") != null && !jsonObj.get("data").isJsonNull()) { - AutomationRobotIntroductionSO.validateJsonElement(jsonObj.get("data")); - } - if (!jsonObj.get("message").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `message` to be a primitive type in the JSON string but got `%s`", jsonObj.get("message").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!ApiResponseAutomationRobotIntroductionSO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'ApiResponseAutomationRobotIntroductionSO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(ApiResponseAutomationRobotIntroductionSO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, ApiResponseAutomationRobotIntroductionSO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public ApiResponseAutomationRobotIntroductionSO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of ApiResponseAutomationRobotIntroductionSO given an JSON string - * - * @param jsonString JSON string - * @return An instance of ApiResponseAutomationRobotIntroductionSO - * @throws IOException if the JSON string is invalid with respect to ApiResponseAutomationRobotIntroductionSO - */ - public static ApiResponseAutomationRobotIntroductionSO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, ApiResponseAutomationRobotIntroductionSO.class); - } - - /** - * Convert an instance of ApiResponseAutomationRobotIntroductionSO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiResponseAutomationRobotRunNumsSO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiResponseAutomationRobotRunNumsSO.java deleted file mode 100644 index 6f69a87051..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiResponseAutomationRobotRunNumsSO.java +++ /dev/null @@ -1,320 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.apitable.databusclient.model.AutomationRobotRunNumsSO; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * ApiResponseAutomationRobotRunNumsSO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class ApiResponseAutomationRobotRunNumsSO { - public static final String SERIALIZED_NAME_CODE = "code"; - @SerializedName(SERIALIZED_NAME_CODE) - private Integer code; - - public static final String SERIALIZED_NAME_DATA = "data"; - @SerializedName(SERIALIZED_NAME_DATA) - private AutomationRobotRunNumsSO data; - - public static final String SERIALIZED_NAME_MESSAGE = "message"; - @SerializedName(SERIALIZED_NAME_MESSAGE) - private String message; - - public static final String SERIALIZED_NAME_SUCCESS = "success"; - @SerializedName(SERIALIZED_NAME_SUCCESS) - private Boolean success; - - public ApiResponseAutomationRobotRunNumsSO() { - } - - public ApiResponseAutomationRobotRunNumsSO code(Integer code) { - - this.code = code; - return this; - } - - /** - * Get code - * minimum: 0 - * @return code - **/ - @javax.annotation.Nonnull - public Integer getCode() { - return code; - } - - - public void setCode(Integer code) { - this.code = code; - } - - - public ApiResponseAutomationRobotRunNumsSO data(AutomationRobotRunNumsSO data) { - - this.data = data; - return this; - } - - /** - * Get data - * @return data - **/ - @javax.annotation.Nullable - public AutomationRobotRunNumsSO getData() { - return data; - } - - - public void setData(AutomationRobotRunNumsSO data) { - this.data = data; - } - - - public ApiResponseAutomationRobotRunNumsSO message(String message) { - - this.message = message; - return this; - } - - /** - * Get message - * @return message - **/ - @javax.annotation.Nonnull - public String getMessage() { - return message; - } - - - public void setMessage(String message) { - this.message = message; - } - - - public ApiResponseAutomationRobotRunNumsSO success(Boolean success) { - - this.success = success; - return this; - } - - /** - * Get success - * @return success - **/ - @javax.annotation.Nonnull - public Boolean getSuccess() { - return success; - } - - - public void setSuccess(Boolean success) { - this.success = success; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ApiResponseAutomationRobotRunNumsSO apiResponseAutomationRobotRunNumsSO = (ApiResponseAutomationRobotRunNumsSO) o; - return Objects.equals(this.code, apiResponseAutomationRobotRunNumsSO.code) && - Objects.equals(this.data, apiResponseAutomationRobotRunNumsSO.data) && - Objects.equals(this.message, apiResponseAutomationRobotRunNumsSO.message) && - Objects.equals(this.success, apiResponseAutomationRobotRunNumsSO.success); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(code, data, message, success); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class ApiResponseAutomationRobotRunNumsSO {\n"); - sb.append(" code: ").append(toIndentedString(code)).append("\n"); - sb.append(" data: ").append(toIndentedString(data)).append("\n"); - sb.append(" message: ").append(toIndentedString(message)).append("\n"); - sb.append(" success: ").append(toIndentedString(success)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("code"); - openapiFields.add("data"); - openapiFields.add("message"); - openapiFields.add("success"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("code"); - openapiRequiredFields.add("message"); - openapiRequiredFields.add("success"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to ApiResponseAutomationRobotRunNumsSO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!ApiResponseAutomationRobotRunNumsSO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in ApiResponseAutomationRobotRunNumsSO is not found in the empty JSON string", ApiResponseAutomationRobotRunNumsSO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Map.Entry entry : entries) { - if (!ApiResponseAutomationRobotRunNumsSO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `ApiResponseAutomationRobotRunNumsSO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : ApiResponseAutomationRobotRunNumsSO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - // validate the optional field `data` - if (jsonObj.get("data") != null && !jsonObj.get("data").isJsonNull()) { - AutomationRobotRunNumsSO.validateJsonElement(jsonObj.get("data")); - } - if (!jsonObj.get("message").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `message` to be a primitive type in the JSON string but got `%s`", jsonObj.get("message").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!ApiResponseAutomationRobotRunNumsSO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'ApiResponseAutomationRobotRunNumsSO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(ApiResponseAutomationRobotRunNumsSO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, ApiResponseAutomationRobotRunNumsSO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public ApiResponseAutomationRobotRunNumsSO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of ApiResponseAutomationRobotRunNumsSO given an JSON string - * - * @param jsonString JSON string - * @return An instance of ApiResponseAutomationRobotRunNumsSO - * @throws IOException if the JSON string is invalid with respect to ApiResponseAutomationRobotRunNumsSO - */ - public static ApiResponseAutomationRobotRunNumsSO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, ApiResponseAutomationRobotRunNumsSO.class); - } - - /** - * Convert an instance of ApiResponseAutomationRobotRunNumsSO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiResponseAutomationRunHistoryPO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiResponseAutomationRunHistoryPO.java deleted file mode 100644 index 7fbfeee111..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiResponseAutomationRunHistoryPO.java +++ /dev/null @@ -1,341 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.apitable.databusclient.model.AutomationRunHistoryPO; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * ApiResponseAutomationRunHistoryPO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class ApiResponseAutomationRunHistoryPO { - public static final String SERIALIZED_NAME_CODE = "code"; - @SerializedName(SERIALIZED_NAME_CODE) - private Integer code; - - public static final String SERIALIZED_NAME_DATA = "data"; - @SerializedName(SERIALIZED_NAME_DATA) - private List data; - - public static final String SERIALIZED_NAME_MESSAGE = "message"; - @SerializedName(SERIALIZED_NAME_MESSAGE) - private String message; - - public static final String SERIALIZED_NAME_SUCCESS = "success"; - @SerializedName(SERIALIZED_NAME_SUCCESS) - private Boolean success; - - public ApiResponseAutomationRunHistoryPO() { - } - - public ApiResponseAutomationRunHistoryPO code(Integer code) { - - this.code = code; - return this; - } - - /** - * Get code - * minimum: 0 - * @return code - **/ - @javax.annotation.Nonnull - public Integer getCode() { - return code; - } - - - public void setCode(Integer code) { - this.code = code; - } - - - public ApiResponseAutomationRunHistoryPO data(List data) { - - this.data = data; - return this; - } - - public ApiResponseAutomationRunHistoryPO addDataItem(AutomationRunHistoryPO dataItem) { - if (this.data == null) { - this.data = new ArrayList<>(); - } - this.data.add(dataItem); - return this; - } - - /** - * Get data - * @return data - **/ - @javax.annotation.Nullable - public List getData() { - return data; - } - - - public void setData(List data) { - this.data = data; - } - - - public ApiResponseAutomationRunHistoryPO message(String message) { - - this.message = message; - return this; - } - - /** - * Get message - * @return message - **/ - @javax.annotation.Nonnull - public String getMessage() { - return message; - } - - - public void setMessage(String message) { - this.message = message; - } - - - public ApiResponseAutomationRunHistoryPO success(Boolean success) { - - this.success = success; - return this; - } - - /** - * Get success - * @return success - **/ - @javax.annotation.Nonnull - public Boolean getSuccess() { - return success; - } - - - public void setSuccess(Boolean success) { - this.success = success; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ApiResponseAutomationRunHistoryPO apiResponseAutomationRunHistoryPO = (ApiResponseAutomationRunHistoryPO) o; - return Objects.equals(this.code, apiResponseAutomationRunHistoryPO.code) && - Objects.equals(this.data, apiResponseAutomationRunHistoryPO.data) && - Objects.equals(this.message, apiResponseAutomationRunHistoryPO.message) && - Objects.equals(this.success, apiResponseAutomationRunHistoryPO.success); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(code, data, message, success); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class ApiResponseAutomationRunHistoryPO {\n"); - sb.append(" code: ").append(toIndentedString(code)).append("\n"); - sb.append(" data: ").append(toIndentedString(data)).append("\n"); - sb.append(" message: ").append(toIndentedString(message)).append("\n"); - sb.append(" success: ").append(toIndentedString(success)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("code"); - openapiFields.add("data"); - openapiFields.add("message"); - openapiFields.add("success"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("code"); - openapiRequiredFields.add("message"); - openapiRequiredFields.add("success"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to ApiResponseAutomationRunHistoryPO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!ApiResponseAutomationRunHistoryPO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in ApiResponseAutomationRunHistoryPO is not found in the empty JSON string", ApiResponseAutomationRunHistoryPO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!ApiResponseAutomationRunHistoryPO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `ApiResponseAutomationRunHistoryPO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : ApiResponseAutomationRunHistoryPO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if (jsonObj.get("data") != null && !jsonObj.get("data").isJsonNull()) { - JsonArray jsonArraydata = jsonObj.getAsJsonArray("data"); - if (jsonArraydata != null) { - // ensure the json data is an array - if (!jsonObj.get("data").isJsonArray()) { - throw new IllegalArgumentException(String.format("Expected the field `data` to be an array in the JSON string but got `%s`", jsonObj.get("data").toString())); - } - - // validate the optional field `data` (array) - for (int i = 0; i < jsonArraydata.size(); i++) { - AutomationRunHistoryPO.validateJsonElement(jsonArraydata.get(i)); - }; - } - } - if (!jsonObj.get("message").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `message` to be a primitive type in the JSON string but got `%s`", jsonObj.get("message").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!ApiResponseAutomationRunHistoryPO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'ApiResponseAutomationRunHistoryPO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(ApiResponseAutomationRunHistoryPO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, ApiResponseAutomationRunHistoryPO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public ApiResponseAutomationRunHistoryPO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of ApiResponseAutomationRunHistoryPO given an JSON string - * - * @param jsonString JSON string - * @return An instance of ApiResponseAutomationRunHistoryPO - * @throws IOException if the JSON string is invalid with respect to ApiResponseAutomationRunHistoryPO - */ - public static ApiResponseAutomationRunHistoryPO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, ApiResponseAutomationRunHistoryPO.class); - } - - /** - * Convert an instance of ApiResponseAutomationRunHistoryPO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiResponseAutomationSO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiResponseAutomationSO.java deleted file mode 100644 index ef8b07bb4e..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiResponseAutomationSO.java +++ /dev/null @@ -1,321 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.apitable.databusclient.model.AutomationSO; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * ApiResponseAutomationSO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class ApiResponseAutomationSO { - public static final String SERIALIZED_NAME_CODE = "code"; - @SerializedName(SERIALIZED_NAME_CODE) - private Integer code; - - public static final String SERIALIZED_NAME_DATA = "data"; - @SerializedName(SERIALIZED_NAME_DATA) - private AutomationSO data; - - public static final String SERIALIZED_NAME_MESSAGE = "message"; - @SerializedName(SERIALIZED_NAME_MESSAGE) - private String message; - - public static final String SERIALIZED_NAME_SUCCESS = "success"; - @SerializedName(SERIALIZED_NAME_SUCCESS) - private Boolean success; - - public ApiResponseAutomationSO() { - } - - public ApiResponseAutomationSO code(Integer code) { - - this.code = code; - return this; - } - - /** - * Get code - * minimum: 0 - * @return code - **/ - @javax.annotation.Nonnull - public Integer getCode() { - return code; - } - - - public void setCode(Integer code) { - this.code = code; - } - - - public ApiResponseAutomationSO data(AutomationSO data) { - - this.data = data; - return this; - } - - /** - * Get data - * @return data - **/ - @javax.annotation.Nullable - public AutomationSO getData() { - return data; - } - - - public void setData(AutomationSO data) { - this.data = data; - } - - - public ApiResponseAutomationSO message(String message) { - - this.message = message; - return this; - } - - /** - * Get message - * @return message - **/ - @javax.annotation.Nonnull - public String getMessage() { - return message; - } - - - public void setMessage(String message) { - this.message = message; - } - - - public ApiResponseAutomationSO success(Boolean success) { - - this.success = success; - return this; - } - - /** - * Get success - * @return success - **/ - @javax.annotation.Nonnull - public Boolean getSuccess() { - return success; - } - - - public void setSuccess(Boolean success) { - this.success = success; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ApiResponseAutomationSO apiResponseAutomationSO = (ApiResponseAutomationSO) o; - return Objects.equals(this.code, apiResponseAutomationSO.code) && - Objects.equals(this.data, apiResponseAutomationSO.data) && - Objects.equals(this.message, apiResponseAutomationSO.message) && - Objects.equals(this.success, apiResponseAutomationSO.success); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(code, data, message, success); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class ApiResponseAutomationSO {\n"); - sb.append(" code: ").append(toIndentedString(code)).append("\n"); - sb.append(" data: ").append(toIndentedString(data)).append("\n"); - sb.append(" message: ").append(toIndentedString(message)).append("\n"); - sb.append(" success: ").append(toIndentedString(success)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("code"); - openapiFields.add("data"); - openapiFields.add("message"); - openapiFields.add("success"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("code"); - openapiRequiredFields.add("message"); - openapiRequiredFields.add("success"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to ApiResponseAutomationSO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!ApiResponseAutomationSO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in ApiResponseAutomationSO is not found in the empty JSON string", ApiResponseAutomationSO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!ApiResponseAutomationSO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `ApiResponseAutomationSO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : ApiResponseAutomationSO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - // validate the optional field `data` - if (jsonObj.get("data") != null && !jsonObj.get("data").isJsonNull()) { - AutomationSO.validateJsonElement(jsonObj.get("data")); - } - if (!jsonObj.get("message").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `message` to be a primitive type in the JSON string but got `%s`", jsonObj.get("message").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!ApiResponseAutomationSO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'ApiResponseAutomationSO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(ApiResponseAutomationSO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, ApiResponseAutomationSO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public ApiResponseAutomationSO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of ApiResponseAutomationSO given an JSON string - * - * @param jsonString JSON string - * @return An instance of ApiResponseAutomationSO - * @throws IOException if the JSON string is invalid with respect to ApiResponseAutomationSO - */ - public static ApiResponseAutomationSO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, ApiResponseAutomationSO.class); - } - - /** - * Convert an instance of ApiResponseAutomationSO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiResponseAutomationTriggerPO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiResponseAutomationTriggerPO.java deleted file mode 100644 index f6564a9b55..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiResponseAutomationTriggerPO.java +++ /dev/null @@ -1,341 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.apitable.databusclient.model.AutomationTriggerPO; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * ApiResponseAutomationTriggerPO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class ApiResponseAutomationTriggerPO { - public static final String SERIALIZED_NAME_CODE = "code"; - @SerializedName(SERIALIZED_NAME_CODE) - private Integer code; - - public static final String SERIALIZED_NAME_DATA = "data"; - @SerializedName(SERIALIZED_NAME_DATA) - private List data; - - public static final String SERIALIZED_NAME_MESSAGE = "message"; - @SerializedName(SERIALIZED_NAME_MESSAGE) - private String message; - - public static final String SERIALIZED_NAME_SUCCESS = "success"; - @SerializedName(SERIALIZED_NAME_SUCCESS) - private Boolean success; - - public ApiResponseAutomationTriggerPO() { - } - - public ApiResponseAutomationTriggerPO code(Integer code) { - - this.code = code; - return this; - } - - /** - * Get code - * minimum: 0 - * @return code - **/ - @javax.annotation.Nonnull - public Integer getCode() { - return code; - } - - - public void setCode(Integer code) { - this.code = code; - } - - - public ApiResponseAutomationTriggerPO data(List data) { - - this.data = data; - return this; - } - - public ApiResponseAutomationTriggerPO addDataItem(AutomationTriggerPO dataItem) { - if (this.data == null) { - this.data = new ArrayList<>(); - } - this.data.add(dataItem); - return this; - } - - /** - * Get data - * @return data - **/ - @javax.annotation.Nullable - public List getData() { - return data; - } - - - public void setData(List data) { - this.data = data; - } - - - public ApiResponseAutomationTriggerPO message(String message) { - - this.message = message; - return this; - } - - /** - * Get message - * @return message - **/ - @javax.annotation.Nonnull - public String getMessage() { - return message; - } - - - public void setMessage(String message) { - this.message = message; - } - - - public ApiResponseAutomationTriggerPO success(Boolean success) { - - this.success = success; - return this; - } - - /** - * Get success - * @return success - **/ - @javax.annotation.Nonnull - public Boolean getSuccess() { - return success; - } - - - public void setSuccess(Boolean success) { - this.success = success; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ApiResponseAutomationTriggerPO apiResponseAutomationTriggerPO = (ApiResponseAutomationTriggerPO) o; - return Objects.equals(this.code, apiResponseAutomationTriggerPO.code) && - Objects.equals(this.data, apiResponseAutomationTriggerPO.data) && - Objects.equals(this.message, apiResponseAutomationTriggerPO.message) && - Objects.equals(this.success, apiResponseAutomationTriggerPO.success); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(code, data, message, success); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class ApiResponseAutomationTriggerPO {\n"); - sb.append(" code: ").append(toIndentedString(code)).append("\n"); - sb.append(" data: ").append(toIndentedString(data)).append("\n"); - sb.append(" message: ").append(toIndentedString(message)).append("\n"); - sb.append(" success: ").append(toIndentedString(success)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("code"); - openapiFields.add("data"); - openapiFields.add("message"); - openapiFields.add("success"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("code"); - openapiRequiredFields.add("message"); - openapiRequiredFields.add("success"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to ApiResponseAutomationTriggerPO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!ApiResponseAutomationTriggerPO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in ApiResponseAutomationTriggerPO is not found in the empty JSON string", ApiResponseAutomationTriggerPO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!ApiResponseAutomationTriggerPO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `ApiResponseAutomationTriggerPO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : ApiResponseAutomationTriggerPO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if (jsonObj.get("data") != null && !jsonObj.get("data").isJsonNull()) { - JsonArray jsonArraydata = jsonObj.getAsJsonArray("data"); - if (jsonArraydata != null) { - // ensure the json data is an array - if (!jsonObj.get("data").isJsonArray()) { - throw new IllegalArgumentException(String.format("Expected the field `data` to be an array in the JSON string but got `%s`", jsonObj.get("data").toString())); - } - - // validate the optional field `data` (array) - for (int i = 0; i < jsonArraydata.size(); i++) { - AutomationTriggerPO.validateJsonElement(jsonArraydata.get(i)); - }; - } - } - if (!jsonObj.get("message").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `message` to be a primitive type in the JSON string but got `%s`", jsonObj.get("message").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!ApiResponseAutomationTriggerPO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'ApiResponseAutomationTriggerPO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(ApiResponseAutomationTriggerPO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, ApiResponseAutomationTriggerPO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public ApiResponseAutomationTriggerPO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of ApiResponseAutomationTriggerPO given an JSON string - * - * @param jsonString JSON string - * @return An instance of ApiResponseAutomationTriggerPO - * @throws IOException if the JSON string is invalid with respect to ApiResponseAutomationTriggerPO - */ - public static ApiResponseAutomationTriggerPO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, ApiResponseAutomationTriggerPO.class); - } - - /** - * Convert an instance of ApiResponseAutomationTriggerPO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiResponseDatasheetPackSO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiResponseDatasheetPackSO.java deleted file mode 100644 index 6fe010646c..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiResponseDatasheetPackSO.java +++ /dev/null @@ -1,321 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.apitable.databusclient.model.DatasheetPackSO; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * ApiResponseDatasheetPackSO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class ApiResponseDatasheetPackSO { - public static final String SERIALIZED_NAME_CODE = "code"; - @SerializedName(SERIALIZED_NAME_CODE) - private Integer code; - - public static final String SERIALIZED_NAME_DATA = "data"; - @SerializedName(SERIALIZED_NAME_DATA) - private DatasheetPackSO data; - - public static final String SERIALIZED_NAME_MESSAGE = "message"; - @SerializedName(SERIALIZED_NAME_MESSAGE) - private String message; - - public static final String SERIALIZED_NAME_SUCCESS = "success"; - @SerializedName(SERIALIZED_NAME_SUCCESS) - private Boolean success; - - public ApiResponseDatasheetPackSO() { - } - - public ApiResponseDatasheetPackSO code(Integer code) { - - this.code = code; - return this; - } - - /** - * Get code - * minimum: 0 - * @return code - **/ - @javax.annotation.Nonnull - public Integer getCode() { - return code; - } - - - public void setCode(Integer code) { - this.code = code; - } - - - public ApiResponseDatasheetPackSO data(DatasheetPackSO data) { - - this.data = data; - return this; - } - - /** - * Get data - * @return data - **/ - @javax.annotation.Nullable - public DatasheetPackSO getData() { - return data; - } - - - public void setData(DatasheetPackSO data) { - this.data = data; - } - - - public ApiResponseDatasheetPackSO message(String message) { - - this.message = message; - return this; - } - - /** - * Get message - * @return message - **/ - @javax.annotation.Nonnull - public String getMessage() { - return message; - } - - - public void setMessage(String message) { - this.message = message; - } - - - public ApiResponseDatasheetPackSO success(Boolean success) { - - this.success = success; - return this; - } - - /** - * Get success - * @return success - **/ - @javax.annotation.Nonnull - public Boolean getSuccess() { - return success; - } - - - public void setSuccess(Boolean success) { - this.success = success; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ApiResponseDatasheetPackSO apiResponseDatasheetPackSO = (ApiResponseDatasheetPackSO) o; - return Objects.equals(this.code, apiResponseDatasheetPackSO.code) && - Objects.equals(this.data, apiResponseDatasheetPackSO.data) && - Objects.equals(this.message, apiResponseDatasheetPackSO.message) && - Objects.equals(this.success, apiResponseDatasheetPackSO.success); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(code, data, message, success); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class ApiResponseDatasheetPackSO {\n"); - sb.append(" code: ").append(toIndentedString(code)).append("\n"); - sb.append(" data: ").append(toIndentedString(data)).append("\n"); - sb.append(" message: ").append(toIndentedString(message)).append("\n"); - sb.append(" success: ").append(toIndentedString(success)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("code"); - openapiFields.add("data"); - openapiFields.add("message"); - openapiFields.add("success"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("code"); - openapiRequiredFields.add("message"); - openapiRequiredFields.add("success"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to ApiResponseDatasheetPackSO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!ApiResponseDatasheetPackSO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in ApiResponseDatasheetPackSO is not found in the empty JSON string", ApiResponseDatasheetPackSO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!ApiResponseDatasheetPackSO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `ApiResponseDatasheetPackSO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : ApiResponseDatasheetPackSO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - // validate the optional field `data` - if (jsonObj.get("data") != null && !jsonObj.get("data").isJsonNull()) { - DatasheetPackSO.validateJsonElement(jsonObj.get("data")); - } - if (!jsonObj.get("message").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `message` to be a primitive type in the JSON string but got `%s`", jsonObj.get("message").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!ApiResponseDatasheetPackSO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'ApiResponseDatasheetPackSO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(ApiResponseDatasheetPackSO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, ApiResponseDatasheetPackSO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public ApiResponseDatasheetPackSO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of ApiResponseDatasheetPackSO given an JSON string - * - * @param jsonString JSON string - * @return An instance of ApiResponseDatasheetPackSO - * @throws IOException if the JSON string is invalid with respect to ApiResponseDatasheetPackSO - */ - public static ApiResponseDatasheetPackSO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, ApiResponseDatasheetPackSO.class); - } - - /** - * Convert an instance of ApiResponseDatasheetPackSO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiResponseEmptySO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiResponseEmptySO.java deleted file mode 100644 index 9e22d4883f..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiResponseEmptySO.java +++ /dev/null @@ -1,316 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * ApiResponseEmptySO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class ApiResponseEmptySO { - public static final String SERIALIZED_NAME_CODE = "code"; - @SerializedName(SERIALIZED_NAME_CODE) - private Integer code; - - public static final String SERIALIZED_NAME_DATA = "data"; - @SerializedName(SERIALIZED_NAME_DATA) - private Boolean data; - - public static final String SERIALIZED_NAME_MESSAGE = "message"; - @SerializedName(SERIALIZED_NAME_MESSAGE) - private String message; - - public static final String SERIALIZED_NAME_SUCCESS = "success"; - @SerializedName(SERIALIZED_NAME_SUCCESS) - private Boolean success; - - public ApiResponseEmptySO() { - } - - public ApiResponseEmptySO code(Integer code) { - - this.code = code; - return this; - } - - /** - * Get code - * minimum: 0 - * @return code - **/ - @javax.annotation.Nonnull - public Integer getCode() { - return code; - } - - - public void setCode(Integer code) { - this.code = code; - } - - - public ApiResponseEmptySO data(Boolean data) { - - this.data = data; - return this; - } - - /** - * Get data - * @return data - **/ - @javax.annotation.Nullable - public Boolean getData() { - return data; - } - - - public void setData(Boolean data) { - this.data = data; - } - - - public ApiResponseEmptySO message(String message) { - - this.message = message; - return this; - } - - /** - * Get message - * @return message - **/ - @javax.annotation.Nonnull - public String getMessage() { - return message; - } - - - public void setMessage(String message) { - this.message = message; - } - - - public ApiResponseEmptySO success(Boolean success) { - - this.success = success; - return this; - } - - /** - * Get success - * @return success - **/ - @javax.annotation.Nonnull - public Boolean getSuccess() { - return success; - } - - - public void setSuccess(Boolean success) { - this.success = success; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ApiResponseEmptySO apiResponseEmptySO = (ApiResponseEmptySO) o; - return Objects.equals(this.code, apiResponseEmptySO.code) && - Objects.equals(this.data, apiResponseEmptySO.data) && - Objects.equals(this.message, apiResponseEmptySO.message) && - Objects.equals(this.success, apiResponseEmptySO.success); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(code, data, message, success); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class ApiResponseEmptySO {\n"); - sb.append(" code: ").append(toIndentedString(code)).append("\n"); - sb.append(" data: ").append(toIndentedString(data)).append("\n"); - sb.append(" message: ").append(toIndentedString(message)).append("\n"); - sb.append(" success: ").append(toIndentedString(success)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("code"); - openapiFields.add("data"); - openapiFields.add("message"); - openapiFields.add("success"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("code"); - openapiRequiredFields.add("message"); - openapiRequiredFields.add("success"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to ApiResponseEmptySO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!ApiResponseEmptySO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in ApiResponseEmptySO is not found in the empty JSON string", ApiResponseEmptySO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!ApiResponseEmptySO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `ApiResponseEmptySO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : ApiResponseEmptySO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if (!jsonObj.get("message").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `message` to be a primitive type in the JSON string but got `%s`", jsonObj.get("message").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!ApiResponseEmptySO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'ApiResponseEmptySO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(ApiResponseEmptySO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, ApiResponseEmptySO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public ApiResponseEmptySO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of ApiResponseEmptySO given an JSON string - * - * @param jsonString JSON string - * @return An instance of ApiResponseEmptySO - * @throws IOException if the JSON string is invalid with respect to ApiResponseEmptySO - */ - public static ApiResponseEmptySO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, ApiResponseEmptySO.class); - } - - /** - * Convert an instance of ApiResponseEmptySO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiResponseRecordVos.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiResponseRecordVos.java deleted file mode 100644 index 4eafad2223..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/ApiResponseRecordVos.java +++ /dev/null @@ -1,341 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.apitable.databusclient.model.RecordVo; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * ApiResponseRecordVos - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class ApiResponseRecordVos { - public static final String SERIALIZED_NAME_CODE = "code"; - @SerializedName(SERIALIZED_NAME_CODE) - private Integer code; - - public static final String SERIALIZED_NAME_DATA = "data"; - @SerializedName(SERIALIZED_NAME_DATA) - private List data; - - public static final String SERIALIZED_NAME_MESSAGE = "message"; - @SerializedName(SERIALIZED_NAME_MESSAGE) - private String message; - - public static final String SERIALIZED_NAME_SUCCESS = "success"; - @SerializedName(SERIALIZED_NAME_SUCCESS) - private Boolean success; - - public ApiResponseRecordVos() { - } - - public ApiResponseRecordVos code(Integer code) { - - this.code = code; - return this; - } - - /** - * Get code - * minimum: 0 - * @return code - **/ - @javax.annotation.Nonnull - public Integer getCode() { - return code; - } - - - public void setCode(Integer code) { - this.code = code; - } - - - public ApiResponseRecordVos data(List data) { - - this.data = data; - return this; - } - - public ApiResponseRecordVos addDataItem(RecordVo dataItem) { - if (this.data == null) { - this.data = new ArrayList<>(); - } - this.data.add(dataItem); - return this; - } - - /** - * Get data - * @return data - **/ - @javax.annotation.Nullable - public List getData() { - return data; - } - - - public void setData(List data) { - this.data = data; - } - - - public ApiResponseRecordVos message(String message) { - - this.message = message; - return this; - } - - /** - * Get message - * @return message - **/ - @javax.annotation.Nonnull - public String getMessage() { - return message; - } - - - public void setMessage(String message) { - this.message = message; - } - - - public ApiResponseRecordVos success(Boolean success) { - - this.success = success; - return this; - } - - /** - * Get success - * @return success - **/ - @javax.annotation.Nonnull - public Boolean getSuccess() { - return success; - } - - - public void setSuccess(Boolean success) { - this.success = success; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ApiResponseRecordVos apiResponseRecordVos = (ApiResponseRecordVos) o; - return Objects.equals(this.code, apiResponseRecordVos.code) && - Objects.equals(this.data, apiResponseRecordVos.data) && - Objects.equals(this.message, apiResponseRecordVos.message) && - Objects.equals(this.success, apiResponseRecordVos.success); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(code, data, message, success); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class ApiResponseRecordVos {\n"); - sb.append(" code: ").append(toIndentedString(code)).append("\n"); - sb.append(" data: ").append(toIndentedString(data)).append("\n"); - sb.append(" message: ").append(toIndentedString(message)).append("\n"); - sb.append(" success: ").append(toIndentedString(success)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("code"); - openapiFields.add("data"); - openapiFields.add("message"); - openapiFields.add("success"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("code"); - openapiRequiredFields.add("message"); - openapiRequiredFields.add("success"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to ApiResponseRecordVos - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!ApiResponseRecordVos.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in ApiResponseRecordVos is not found in the empty JSON string", ApiResponseRecordVos.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!ApiResponseRecordVos.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `ApiResponseRecordVos` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : ApiResponseRecordVos.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if (jsonObj.get("data") != null && !jsonObj.get("data").isJsonNull()) { - JsonArray jsonArraydata = jsonObj.getAsJsonArray("data"); - if (jsonArraydata != null) { - // ensure the json data is an array - if (!jsonObj.get("data").isJsonArray()) { - throw new IllegalArgumentException(String.format("Expected the field `data` to be an array in the JSON string but got `%s`", jsonObj.get("data").toString())); - } - - // validate the optional field `data` (array) - for (int i = 0; i < jsonArraydata.size(); i++) { - RecordVo.validateJsonElement(jsonArraydata.get(i)); - }; - } - } - if (!jsonObj.get("message").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `message` to be a primitive type in the JSON string but got `%s`", jsonObj.get("message").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!ApiResponseRecordVos.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'ApiResponseRecordVos' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(ApiResponseRecordVos.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, ApiResponseRecordVos value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public ApiResponseRecordVos read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of ApiResponseRecordVos given an JSON string - * - * @param jsonString JSON string - * @return An instance of ApiResponseRecordVos - * @throws IOException if the JSON string is invalid with respect to ApiResponseRecordVos - */ - public static ApiResponseRecordVos fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, ApiResponseRecordVos.class); - } - - /** - * Convert an instance of ApiResponseRecordVos to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationActionIntroductionPO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationActionIntroductionPO.java deleted file mode 100644 index 51ad136fed..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationActionIntroductionPO.java +++ /dev/null @@ -1,324 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * AutomationActionIntroductionPO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class AutomationActionIntroductionPO { - public static final String SERIALIZED_NAME_ACTION_ID = "actionId"; - @SerializedName(SERIALIZED_NAME_ACTION_ID) - private String actionId; - - public static final String SERIALIZED_NAME_ACTION_TYPE_ID = "actionTypeId"; - @SerializedName(SERIALIZED_NAME_ACTION_TYPE_ID) - private String actionTypeId; - - public static final String SERIALIZED_NAME_PREV_ACTION_ID = "prevActionId"; - @SerializedName(SERIALIZED_NAME_PREV_ACTION_ID) - private String prevActionId; - - public static final String SERIALIZED_NAME_ROBOT_ID = "robotId"; - @SerializedName(SERIALIZED_NAME_ROBOT_ID) - private String robotId; - - public AutomationActionIntroductionPO() { - } - - public AutomationActionIntroductionPO actionId(String actionId) { - - this.actionId = actionId; - return this; - } - - /** - * Get actionId - * @return actionId - **/ - @javax.annotation.Nonnull - public String getActionId() { - return actionId; - } - - - public void setActionId(String actionId) { - this.actionId = actionId; - } - - - public AutomationActionIntroductionPO actionTypeId(String actionTypeId) { - - this.actionTypeId = actionTypeId; - return this; - } - - /** - * Get actionTypeId - * @return actionTypeId - **/ - @javax.annotation.Nonnull - public String getActionTypeId() { - return actionTypeId; - } - - - public void setActionTypeId(String actionTypeId) { - this.actionTypeId = actionTypeId; - } - - - public AutomationActionIntroductionPO prevActionId(String prevActionId) { - - this.prevActionId = prevActionId; - return this; - } - - /** - * Get prevActionId - * @return prevActionId - **/ - @javax.annotation.Nullable - public String getPrevActionId() { - return prevActionId; - } - - - public void setPrevActionId(String prevActionId) { - this.prevActionId = prevActionId; - } - - - public AutomationActionIntroductionPO robotId(String robotId) { - - this.robotId = robotId; - return this; - } - - /** - * Get robotId - * @return robotId - **/ - @javax.annotation.Nonnull - public String getRobotId() { - return robotId; - } - - - public void setRobotId(String robotId) { - this.robotId = robotId; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - AutomationActionIntroductionPO automationActionIntroductionPO = (AutomationActionIntroductionPO) o; - return Objects.equals(this.actionId, automationActionIntroductionPO.actionId) && - Objects.equals(this.actionTypeId, automationActionIntroductionPO.actionTypeId) && - Objects.equals(this.prevActionId, automationActionIntroductionPO.prevActionId) && - Objects.equals(this.robotId, automationActionIntroductionPO.robotId); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(actionId, actionTypeId, prevActionId, robotId); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class AutomationActionIntroductionPO {\n"); - sb.append(" actionId: ").append(toIndentedString(actionId)).append("\n"); - sb.append(" actionTypeId: ").append(toIndentedString(actionTypeId)).append("\n"); - sb.append(" prevActionId: ").append(toIndentedString(prevActionId)).append("\n"); - sb.append(" robotId: ").append(toIndentedString(robotId)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("actionId"); - openapiFields.add("actionTypeId"); - openapiFields.add("prevActionId"); - openapiFields.add("robotId"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("actionId"); - openapiRequiredFields.add("actionTypeId"); - openapiRequiredFields.add("robotId"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to AutomationActionIntroductionPO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!AutomationActionIntroductionPO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in AutomationActionIntroductionPO is not found in the empty JSON string", AutomationActionIntroductionPO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!AutomationActionIntroductionPO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `AutomationActionIntroductionPO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : AutomationActionIntroductionPO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if (!jsonObj.get("actionId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `actionId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("actionId").toString())); - } - if (!jsonObj.get("actionTypeId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `actionTypeId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("actionTypeId").toString())); - } - if ((jsonObj.get("prevActionId") != null && !jsonObj.get("prevActionId").isJsonNull()) && !jsonObj.get("prevActionId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `prevActionId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("prevActionId").toString())); - } - if (!jsonObj.get("robotId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `robotId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("robotId").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!AutomationActionIntroductionPO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'AutomationActionIntroductionPO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(AutomationActionIntroductionPO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, AutomationActionIntroductionPO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public AutomationActionIntroductionPO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of AutomationActionIntroductionPO given an JSON string - * - * @param jsonString JSON string - * @return An instance of AutomationActionIntroductionPO - * @throws IOException if the JSON string is invalid with respect to AutomationActionIntroductionPO - */ - public static AutomationActionIntroductionPO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, AutomationActionIntroductionPO.class); - } - - /** - * Convert an instance of AutomationActionIntroductionPO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationActionPO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationActionPO.java deleted file mode 100644 index 400cfdd9df..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationActionPO.java +++ /dev/null @@ -1,355 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * AutomationActionPO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class AutomationActionPO { - public static final String SERIALIZED_NAME_ACTION_ID = "actionId"; - @SerializedName(SERIALIZED_NAME_ACTION_ID) - private String actionId; - - public static final String SERIALIZED_NAME_ACTION_TYPE_ID = "actionTypeId"; - @SerializedName(SERIALIZED_NAME_ACTION_TYPE_ID) - private String actionTypeId; - - public static final String SERIALIZED_NAME_INPUT = "input"; - @SerializedName(SERIALIZED_NAME_INPUT) - private String input; - - public static final String SERIALIZED_NAME_PREV_ACTION_ID = "prevActionId"; - @SerializedName(SERIALIZED_NAME_PREV_ACTION_ID) - private String prevActionId; - - public static final String SERIALIZED_NAME_ROBOT_ID = "robotId"; - @SerializedName(SERIALIZED_NAME_ROBOT_ID) - private String robotId; - - public AutomationActionPO() { - } - - public AutomationActionPO actionId(String actionId) { - - this.actionId = actionId; - return this; - } - - /** - * Get actionId - * @return actionId - **/ - @javax.annotation.Nonnull - public String getActionId() { - return actionId; - } - - - public void setActionId(String actionId) { - this.actionId = actionId; - } - - - public AutomationActionPO actionTypeId(String actionTypeId) { - - this.actionTypeId = actionTypeId; - return this; - } - - /** - * Get actionTypeId - * @return actionTypeId - **/ - @javax.annotation.Nonnull - public String getActionTypeId() { - return actionTypeId; - } - - - public void setActionTypeId(String actionTypeId) { - this.actionTypeId = actionTypeId; - } - - - public AutomationActionPO input(String input) { - - this.input = input; - return this; - } - - /** - * Get input - * @return input - **/ - @javax.annotation.Nullable - public String getInput() { - return input; - } - - - public void setInput(String input) { - this.input = input; - } - - - public AutomationActionPO prevActionId(String prevActionId) { - - this.prevActionId = prevActionId; - return this; - } - - /** - * Get prevActionId - * @return prevActionId - **/ - @javax.annotation.Nullable - public String getPrevActionId() { - return prevActionId; - } - - - public void setPrevActionId(String prevActionId) { - this.prevActionId = prevActionId; - } - - - public AutomationActionPO robotId(String robotId) { - - this.robotId = robotId; - return this; - } - - /** - * Get robotId - * @return robotId - **/ - @javax.annotation.Nonnull - public String getRobotId() { - return robotId; - } - - - public void setRobotId(String robotId) { - this.robotId = robotId; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - AutomationActionPO automationActionPO = (AutomationActionPO) o; - return Objects.equals(this.actionId, automationActionPO.actionId) && - Objects.equals(this.actionTypeId, automationActionPO.actionTypeId) && - Objects.equals(this.input, automationActionPO.input) && - Objects.equals(this.prevActionId, automationActionPO.prevActionId) && - Objects.equals(this.robotId, automationActionPO.robotId); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(actionId, actionTypeId, input, prevActionId, robotId); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class AutomationActionPO {\n"); - sb.append(" actionId: ").append(toIndentedString(actionId)).append("\n"); - sb.append(" actionTypeId: ").append(toIndentedString(actionTypeId)).append("\n"); - sb.append(" input: ").append(toIndentedString(input)).append("\n"); - sb.append(" prevActionId: ").append(toIndentedString(prevActionId)).append("\n"); - sb.append(" robotId: ").append(toIndentedString(robotId)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("actionId"); - openapiFields.add("actionTypeId"); - openapiFields.add("input"); - openapiFields.add("prevActionId"); - openapiFields.add("robotId"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("actionId"); - openapiRequiredFields.add("actionTypeId"); - openapiRequiredFields.add("robotId"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to AutomationActionPO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!AutomationActionPO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in AutomationActionPO is not found in the empty JSON string", AutomationActionPO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!AutomationActionPO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `AutomationActionPO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : AutomationActionPO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if (!jsonObj.get("actionId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `actionId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("actionId").toString())); - } - if (!jsonObj.get("actionTypeId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `actionTypeId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("actionTypeId").toString())); - } - if ((jsonObj.get("input") != null && !jsonObj.get("input").isJsonNull()) && !jsonObj.get("input").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `input` to be a primitive type in the JSON string but got `%s`", jsonObj.get("input").toString())); - } - if ((jsonObj.get("prevActionId") != null && !jsonObj.get("prevActionId").isJsonNull()) && !jsonObj.get("prevActionId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `prevActionId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("prevActionId").toString())); - } - if (!jsonObj.get("robotId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `robotId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("robotId").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!AutomationActionPO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'AutomationActionPO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(AutomationActionPO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, AutomationActionPO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public AutomationActionPO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of AutomationActionPO given an JSON string - * - * @param jsonString JSON string - * @return An instance of AutomationActionPO - * @throws IOException if the JSON string is invalid with respect to AutomationActionPO - */ - public static AutomationActionPO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, AutomationActionPO.class); - } - - /** - * Convert an instance of AutomationActionPO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationHistoryRO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationHistoryRO.java deleted file mode 100644 index 278deac1ab..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationHistoryRO.java +++ /dev/null @@ -1,319 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * AutomationHistoryRO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class AutomationHistoryRO { - public static final String SERIALIZED_NAME_DATA = "data"; - @SerializedName(SERIALIZED_NAME_DATA) - private Object data = null; - - public static final String SERIALIZED_NAME_SPACE_ID = "space_id"; - @SerializedName(SERIALIZED_NAME_SPACE_ID) - private String spaceId; - - public static final String SERIALIZED_NAME_STATUS = "status"; - @SerializedName(SERIALIZED_NAME_STATUS) - private Integer status; - - public static final String SERIALIZED_NAME_TASK_ID = "task_id"; - @SerializedName(SERIALIZED_NAME_TASK_ID) - private String taskId; - - public AutomationHistoryRO() { - } - - public AutomationHistoryRO data(Object data) { - - this.data = data; - return this; - } - - /** - * Get data - * @return data - **/ - @javax.annotation.Nullable - public Object getData() { - return data; - } - - - public void setData(Object data) { - this.data = data; - } - - - public AutomationHistoryRO spaceId(String spaceId) { - - this.spaceId = spaceId; - return this; - } - - /** - * Get spaceId - * @return spaceId - **/ - @javax.annotation.Nonnull - public String getSpaceId() { - return spaceId; - } - - - public void setSpaceId(String spaceId) { - this.spaceId = spaceId; - } - - - public AutomationHistoryRO status(Integer status) { - - this.status = status; - return this; - } - - /** - * Get status - * minimum: 0 - * @return status - **/ - @javax.annotation.Nonnull - public Integer getStatus() { - return status; - } - - - public void setStatus(Integer status) { - this.status = status; - } - - - public AutomationHistoryRO taskId(String taskId) { - - this.taskId = taskId; - return this; - } - - /** - * Get taskId - * @return taskId - **/ - @javax.annotation.Nonnull - public String getTaskId() { - return taskId; - } - - - public void setTaskId(String taskId) { - this.taskId = taskId; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - AutomationHistoryRO automationHistoryRO = (AutomationHistoryRO) o; - return Objects.equals(this.data, automationHistoryRO.data) && - Objects.equals(this.spaceId, automationHistoryRO.spaceId) && - Objects.equals(this.status, automationHistoryRO.status) && - Objects.equals(this.taskId, automationHistoryRO.taskId); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(data, spaceId, status, taskId); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class AutomationHistoryRO {\n"); - sb.append(" data: ").append(toIndentedString(data)).append("\n"); - sb.append(" spaceId: ").append(toIndentedString(spaceId)).append("\n"); - sb.append(" status: ").append(toIndentedString(status)).append("\n"); - sb.append(" taskId: ").append(toIndentedString(taskId)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("data"); - openapiFields.add("space_id"); - openapiFields.add("status"); - openapiFields.add("task_id"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("space_id"); - openapiRequiredFields.add("status"); - openapiRequiredFields.add("task_id"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to AutomationHistoryRO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!AutomationHistoryRO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in AutomationHistoryRO is not found in the empty JSON string", AutomationHistoryRO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!AutomationHistoryRO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `AutomationHistoryRO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : AutomationHistoryRO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if (!jsonObj.get("space_id").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `space_id` to be a primitive type in the JSON string but got `%s`", jsonObj.get("space_id").toString())); - } - if (!jsonObj.get("task_id").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `task_id` to be a primitive type in the JSON string but got `%s`", jsonObj.get("task_id").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!AutomationHistoryRO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'AutomationHistoryRO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(AutomationHistoryRO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, AutomationHistoryRO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public AutomationHistoryRO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of AutomationHistoryRO given an JSON string - * - * @param jsonString JSON string - * @return An instance of AutomationHistoryRO - * @throws IOException if the JSON string is invalid with respect to AutomationHistoryRO - */ - public static AutomationHistoryRO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, AutomationHistoryRO.class); - } - - /** - * Convert an instance of AutomationHistoryRO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationHistoryStatusRO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationHistoryStatusRO.java deleted file mode 100644 index 8bfd5442b8..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationHistoryStatusRO.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * AutomationHistoryStatusRO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class AutomationHistoryStatusRO { - public static final String SERIALIZED_NAME_STATUS = "status"; - @SerializedName(SERIALIZED_NAME_STATUS) - private Integer status; - - public AutomationHistoryStatusRO() { - } - - public AutomationHistoryStatusRO status(Integer status) { - - this.status = status; - return this; - } - - /** - * Get status - * minimum: 0 - * @return status - **/ - @javax.annotation.Nonnull - public Integer getStatus() { - return status; - } - - - public void setStatus(Integer status) { - this.status = status; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - AutomationHistoryStatusRO automationHistoryStatusRO = (AutomationHistoryStatusRO) o; - return Objects.equals(this.status, automationHistoryStatusRO.status); - } - - @Override - public int hashCode() { - return Objects.hash(status); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class AutomationHistoryStatusRO {\n"); - sb.append(" status: ").append(toIndentedString(status)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("status"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("status"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to AutomationHistoryStatusRO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!AutomationHistoryStatusRO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in AutomationHistoryStatusRO is not found in the empty JSON string", AutomationHistoryStatusRO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!AutomationHistoryStatusRO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `AutomationHistoryStatusRO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : AutomationHistoryStatusRO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!AutomationHistoryStatusRO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'AutomationHistoryStatusRO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(AutomationHistoryStatusRO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, AutomationHistoryStatusRO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public AutomationHistoryStatusRO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of AutomationHistoryStatusRO given an JSON string - * - * @param jsonString JSON string - * @return An instance of AutomationHistoryStatusRO - * @throws IOException if the JSON string is invalid with respect to AutomationHistoryStatusRO - */ - public static AutomationHistoryStatusRO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, AutomationHistoryStatusRO.class); - } - - /** - * Convert an instance of AutomationHistoryStatusRO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationRobotActionRO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationRobotActionRO.java deleted file mode 100644 index d5fdc532a0..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationRobotActionRO.java +++ /dev/null @@ -1,407 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * AutomationRobotActionRO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class AutomationRobotActionRO { - public static final String SERIALIZED_NAME_ACTION_ID = "action_id"; - @SerializedName(SERIALIZED_NAME_ACTION_ID) - private String actionId; - - public static final String SERIALIZED_NAME_ACTION_TYPE_ID = "action_type_id"; - @SerializedName(SERIALIZED_NAME_ACTION_TYPE_ID) - private String actionTypeId; - - public static final String SERIALIZED_NAME_INPUT = "input"; - @SerializedName(SERIALIZED_NAME_INPUT) - private String input; - - public static final String SERIALIZED_NAME_IS_DELETED = "is_deleted"; - @SerializedName(SERIALIZED_NAME_IS_DELETED) - private Boolean isDeleted; - - public static final String SERIALIZED_NAME_LIMIT_COUNT = "limit_count"; - @SerializedName(SERIALIZED_NAME_LIMIT_COUNT) - private Long limitCount; - - public static final String SERIALIZED_NAME_PREV_ACTION_ID = "prev_action_id"; - @SerializedName(SERIALIZED_NAME_PREV_ACTION_ID) - private String prevActionId; - - public static final String SERIALIZED_NAME_USER_ID = "user_id"; - @SerializedName(SERIALIZED_NAME_USER_ID) - private Long userId; - - public AutomationRobotActionRO() { - } - - public AutomationRobotActionRO actionId(String actionId) { - - this.actionId = actionId; - return this; - } - - /** - * Get actionId - * @return actionId - **/ - @javax.annotation.Nullable - public String getActionId() { - return actionId; - } - - - public void setActionId(String actionId) { - this.actionId = actionId; - } - - - public AutomationRobotActionRO actionTypeId(String actionTypeId) { - - this.actionTypeId = actionTypeId; - return this; - } - - /** - * Get actionTypeId - * @return actionTypeId - **/ - @javax.annotation.Nullable - public String getActionTypeId() { - return actionTypeId; - } - - - public void setActionTypeId(String actionTypeId) { - this.actionTypeId = actionTypeId; - } - - - public AutomationRobotActionRO input(String input) { - - this.input = input; - return this; - } - - /** - * Get input - * @return input - **/ - @javax.annotation.Nullable - public String getInput() { - return input; - } - - - public void setInput(String input) { - this.input = input; - } - - - public AutomationRobotActionRO isDeleted(Boolean isDeleted) { - - this.isDeleted = isDeleted; - return this; - } - - /** - * Get isDeleted - * @return isDeleted - **/ - @javax.annotation.Nullable - public Boolean getIsDeleted() { - return isDeleted; - } - - - public void setIsDeleted(Boolean isDeleted) { - this.isDeleted = isDeleted; - } - - - public AutomationRobotActionRO limitCount(Long limitCount) { - - this.limitCount = limitCount; - return this; - } - - /** - * Get limitCount - * @return limitCount - **/ - @javax.annotation.Nullable - public Long getLimitCount() { - return limitCount; - } - - - public void setLimitCount(Long limitCount) { - this.limitCount = limitCount; - } - - - public AutomationRobotActionRO prevActionId(String prevActionId) { - - this.prevActionId = prevActionId; - return this; - } - - /** - * Get prevActionId - * @return prevActionId - **/ - @javax.annotation.Nullable - public String getPrevActionId() { - return prevActionId; - } - - - public void setPrevActionId(String prevActionId) { - this.prevActionId = prevActionId; - } - - - public AutomationRobotActionRO userId(Long userId) { - - this.userId = userId; - return this; - } - - /** - * Get userId - * minimum: 0 - * @return userId - **/ - @javax.annotation.Nonnull - public Long getUserId() { - return userId; - } - - - public void setUserId(Long userId) { - this.userId = userId; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - AutomationRobotActionRO automationRobotActionRO = (AutomationRobotActionRO) o; - return Objects.equals(this.actionId, automationRobotActionRO.actionId) && - Objects.equals(this.actionTypeId, automationRobotActionRO.actionTypeId) && - Objects.equals(this.input, automationRobotActionRO.input) && - Objects.equals(this.isDeleted, automationRobotActionRO.isDeleted) && - Objects.equals(this.limitCount, automationRobotActionRO.limitCount) && - Objects.equals(this.prevActionId, automationRobotActionRO.prevActionId) && - Objects.equals(this.userId, automationRobotActionRO.userId); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(actionId, actionTypeId, input, isDeleted, limitCount, prevActionId, userId); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class AutomationRobotActionRO {\n"); - sb.append(" actionId: ").append(toIndentedString(actionId)).append("\n"); - sb.append(" actionTypeId: ").append(toIndentedString(actionTypeId)).append("\n"); - sb.append(" input: ").append(toIndentedString(input)).append("\n"); - sb.append(" isDeleted: ").append(toIndentedString(isDeleted)).append("\n"); - sb.append(" limitCount: ").append(toIndentedString(limitCount)).append("\n"); - sb.append(" prevActionId: ").append(toIndentedString(prevActionId)).append("\n"); - sb.append(" userId: ").append(toIndentedString(userId)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("action_id"); - openapiFields.add("action_type_id"); - openapiFields.add("input"); - openapiFields.add("is_deleted"); - openapiFields.add("limit_count"); - openapiFields.add("prev_action_id"); - openapiFields.add("user_id"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("user_id"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to AutomationRobotActionRO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!AutomationRobotActionRO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in AutomationRobotActionRO is not found in the empty JSON string", AutomationRobotActionRO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!AutomationRobotActionRO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `AutomationRobotActionRO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : AutomationRobotActionRO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if ((jsonObj.get("action_id") != null && !jsonObj.get("action_id").isJsonNull()) && !jsonObj.get("action_id").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `action_id` to be a primitive type in the JSON string but got `%s`", jsonObj.get("action_id").toString())); - } - if ((jsonObj.get("action_type_id") != null && !jsonObj.get("action_type_id").isJsonNull()) && !jsonObj.get("action_type_id").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `action_type_id` to be a primitive type in the JSON string but got `%s`", jsonObj.get("action_type_id").toString())); - } - if ((jsonObj.get("input") != null && !jsonObj.get("input").isJsonNull()) && !jsonObj.get("input").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `input` to be a primitive type in the JSON string but got `%s`", jsonObj.get("input").toString())); - } - if ((jsonObj.get("prev_action_id") != null && !jsonObj.get("prev_action_id").isJsonNull()) && !jsonObj.get("prev_action_id").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `prev_action_id` to be a primitive type in the JSON string but got `%s`", jsonObj.get("prev_action_id").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!AutomationRobotActionRO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'AutomationRobotActionRO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(AutomationRobotActionRO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, AutomationRobotActionRO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public AutomationRobotActionRO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of AutomationRobotActionRO given an JSON string - * - * @param jsonString JSON string - * @return An instance of AutomationRobotActionRO - * @throws IOException if the JSON string is invalid with respect to AutomationRobotActionRO - */ - public static AutomationRobotActionRO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, AutomationRobotActionRO.class); - } - - /** - * Convert an instance of AutomationRobotActionRO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationRobotCopyRO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationRobotCopyRO.java deleted file mode 100644 index 5464d414a1..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationRobotCopyRO.java +++ /dev/null @@ -1,322 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * AutomationRobotCopyRO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class AutomationRobotCopyRO { - public static final String SERIALIZED_NAME_AUTOMATION_NAME = "automation_name"; - @SerializedName(SERIALIZED_NAME_AUTOMATION_NAME) - private String automationName; - - public static final String SERIALIZED_NAME_ORIGINAL_RESOURCE_ID = "original_resource_id"; - @SerializedName(SERIALIZED_NAME_ORIGINAL_RESOURCE_ID) - private String originalResourceId; - - public static final String SERIALIZED_NAME_RESOURCE_ID = "resource_id"; - @SerializedName(SERIALIZED_NAME_RESOURCE_ID) - private String resourceId; - - public static final String SERIALIZED_NAME_USER_ID = "user_id"; - @SerializedName(SERIALIZED_NAME_USER_ID) - private Long userId; - - public AutomationRobotCopyRO() { - } - - public AutomationRobotCopyRO automationName(String automationName) { - - this.automationName = automationName; - return this; - } - - /** - * Get automationName - * @return automationName - **/ - @javax.annotation.Nullable - public String getAutomationName() { - return automationName; - } - - - public void setAutomationName(String automationName) { - this.automationName = automationName; - } - - - public AutomationRobotCopyRO originalResourceId(String originalResourceId) { - - this.originalResourceId = originalResourceId; - return this; - } - - /** - * Get originalResourceId - * @return originalResourceId - **/ - @javax.annotation.Nonnull - public String getOriginalResourceId() { - return originalResourceId; - } - - - public void setOriginalResourceId(String originalResourceId) { - this.originalResourceId = originalResourceId; - } - - - public AutomationRobotCopyRO resourceId(String resourceId) { - - this.resourceId = resourceId; - return this; - } - - /** - * Get resourceId - * @return resourceId - **/ - @javax.annotation.Nonnull - public String getResourceId() { - return resourceId; - } - - - public void setResourceId(String resourceId) { - this.resourceId = resourceId; - } - - - public AutomationRobotCopyRO userId(Long userId) { - - this.userId = userId; - return this; - } - - /** - * Get userId - * minimum: 0 - * @return userId - **/ - @javax.annotation.Nonnull - public Long getUserId() { - return userId; - } - - - public void setUserId(Long userId) { - this.userId = userId; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - AutomationRobotCopyRO automationRobotCopyRO = (AutomationRobotCopyRO) o; - return Objects.equals(this.automationName, automationRobotCopyRO.automationName) && - Objects.equals(this.originalResourceId, automationRobotCopyRO.originalResourceId) && - Objects.equals(this.resourceId, automationRobotCopyRO.resourceId) && - Objects.equals(this.userId, automationRobotCopyRO.userId); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(automationName, originalResourceId, resourceId, userId); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class AutomationRobotCopyRO {\n"); - sb.append(" automationName: ").append(toIndentedString(automationName)).append("\n"); - sb.append(" originalResourceId: ").append(toIndentedString(originalResourceId)).append("\n"); - sb.append(" resourceId: ").append(toIndentedString(resourceId)).append("\n"); - sb.append(" userId: ").append(toIndentedString(userId)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("automation_name"); - openapiFields.add("original_resource_id"); - openapiFields.add("resource_id"); - openapiFields.add("user_id"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("original_resource_id"); - openapiRequiredFields.add("resource_id"); - openapiRequiredFields.add("user_id"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to AutomationRobotCopyRO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!AutomationRobotCopyRO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in AutomationRobotCopyRO is not found in the empty JSON string", AutomationRobotCopyRO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!AutomationRobotCopyRO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `AutomationRobotCopyRO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : AutomationRobotCopyRO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if ((jsonObj.get("automation_name") != null && !jsonObj.get("automation_name").isJsonNull()) && !jsonObj.get("automation_name").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `automation_name` to be a primitive type in the JSON string but got `%s`", jsonObj.get("automation_name").toString())); - } - if (!jsonObj.get("original_resource_id").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `original_resource_id` to be a primitive type in the JSON string but got `%s`", jsonObj.get("original_resource_id").toString())); - } - if (!jsonObj.get("resource_id").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `resource_id` to be a primitive type in the JSON string but got `%s`", jsonObj.get("resource_id").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!AutomationRobotCopyRO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'AutomationRobotCopyRO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(AutomationRobotCopyRO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, AutomationRobotCopyRO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public AutomationRobotCopyRO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of AutomationRobotCopyRO given an JSON string - * - * @param jsonString JSON string - * @return An instance of AutomationRobotCopyRO - * @throws IOException if the JSON string is invalid with respect to AutomationRobotCopyRO - */ - public static AutomationRobotCopyRO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, AutomationRobotCopyRO.class); - } - - /** - * Convert an instance of AutomationRobotCopyRO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationRobotIntroductionPO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationRobotIntroductionPO.java deleted file mode 100644 index 8c483ff02d..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationRobotIntroductionPO.java +++ /dev/null @@ -1,385 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * AutomationRobotIntroductionPO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class AutomationRobotIntroductionPO { - public static final String SERIALIZED_NAME_DESCRIPTION = "description"; - @SerializedName(SERIALIZED_NAME_DESCRIPTION) - private String description; - - public static final String SERIALIZED_NAME_IS_ACTIVE = "isActive"; - @SerializedName(SERIALIZED_NAME_IS_ACTIVE) - private Integer isActive; - - public static final String SERIALIZED_NAME_NAME = "name"; - @SerializedName(SERIALIZED_NAME_NAME) - private String name; - - public static final String SERIALIZED_NAME_PROPS = "props"; - @SerializedName(SERIALIZED_NAME_PROPS) - private String props; - - public static final String SERIALIZED_NAME_RESOURCE_ID = "resourceId"; - @SerializedName(SERIALIZED_NAME_RESOURCE_ID) - private String resourceId; - - public static final String SERIALIZED_NAME_ROBOT_ID = "robotId"; - @SerializedName(SERIALIZED_NAME_ROBOT_ID) - private String robotId; - - public AutomationRobotIntroductionPO() { - } - - public AutomationRobotIntroductionPO description(String description) { - - this.description = description; - return this; - } - - /** - * Get description - * @return description - **/ - @javax.annotation.Nullable - public String getDescription() { - return description; - } - - - public void setDescription(String description) { - this.description = description; - } - - - public AutomationRobotIntroductionPO isActive(Integer isActive) { - - this.isActive = isActive; - return this; - } - - /** - * Get isActive - * minimum: 0 - * @return isActive - **/ - @javax.annotation.Nonnull - public Integer getIsActive() { - return isActive; - } - - - public void setIsActive(Integer isActive) { - this.isActive = isActive; - } - - - public AutomationRobotIntroductionPO name(String name) { - - this.name = name; - return this; - } - - /** - * Get name - * @return name - **/ - @javax.annotation.Nonnull - public String getName() { - return name; - } - - - public void setName(String name) { - this.name = name; - } - - - public AutomationRobotIntroductionPO props(String props) { - - this.props = props; - return this; - } - - /** - * Get props - * @return props - **/ - @javax.annotation.Nullable - public String getProps() { - return props; - } - - - public void setProps(String props) { - this.props = props; - } - - - public AutomationRobotIntroductionPO resourceId(String resourceId) { - - this.resourceId = resourceId; - return this; - } - - /** - * Get resourceId - * @return resourceId - **/ - @javax.annotation.Nonnull - public String getResourceId() { - return resourceId; - } - - - public void setResourceId(String resourceId) { - this.resourceId = resourceId; - } - - - public AutomationRobotIntroductionPO robotId(String robotId) { - - this.robotId = robotId; - return this; - } - - /** - * Get robotId - * @return robotId - **/ - @javax.annotation.Nonnull - public String getRobotId() { - return robotId; - } - - - public void setRobotId(String robotId) { - this.robotId = robotId; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - AutomationRobotIntroductionPO automationRobotIntroductionPO = (AutomationRobotIntroductionPO) o; - return Objects.equals(this.description, automationRobotIntroductionPO.description) && - Objects.equals(this.isActive, automationRobotIntroductionPO.isActive) && - Objects.equals(this.name, automationRobotIntroductionPO.name) && - Objects.equals(this.props, automationRobotIntroductionPO.props) && - Objects.equals(this.resourceId, automationRobotIntroductionPO.resourceId) && - Objects.equals(this.robotId, automationRobotIntroductionPO.robotId); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(description, isActive, name, props, resourceId, robotId); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class AutomationRobotIntroductionPO {\n"); - sb.append(" description: ").append(toIndentedString(description)).append("\n"); - sb.append(" isActive: ").append(toIndentedString(isActive)).append("\n"); - sb.append(" name: ").append(toIndentedString(name)).append("\n"); - sb.append(" props: ").append(toIndentedString(props)).append("\n"); - sb.append(" resourceId: ").append(toIndentedString(resourceId)).append("\n"); - sb.append(" robotId: ").append(toIndentedString(robotId)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("description"); - openapiFields.add("isActive"); - openapiFields.add("name"); - openapiFields.add("props"); - openapiFields.add("resourceId"); - openapiFields.add("robotId"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("isActive"); - openapiRequiredFields.add("name"); - openapiRequiredFields.add("resourceId"); - openapiRequiredFields.add("robotId"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to AutomationRobotIntroductionPO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!AutomationRobotIntroductionPO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in AutomationRobotIntroductionPO is not found in the empty JSON string", AutomationRobotIntroductionPO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!AutomationRobotIntroductionPO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `AutomationRobotIntroductionPO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : AutomationRobotIntroductionPO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if ((jsonObj.get("description") != null && !jsonObj.get("description").isJsonNull()) && !jsonObj.get("description").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `description` to be a primitive type in the JSON string but got `%s`", jsonObj.get("description").toString())); - } - if (!jsonObj.get("name").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `name` to be a primitive type in the JSON string but got `%s`", jsonObj.get("name").toString())); - } - if ((jsonObj.get("props") != null && !jsonObj.get("props").isJsonNull()) && !jsonObj.get("props").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `props` to be a primitive type in the JSON string but got `%s`", jsonObj.get("props").toString())); - } - if (!jsonObj.get("resourceId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `resourceId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("resourceId").toString())); - } - if (!jsonObj.get("robotId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `robotId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("robotId").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!AutomationRobotIntroductionPO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'AutomationRobotIntroductionPO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(AutomationRobotIntroductionPO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, AutomationRobotIntroductionPO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public AutomationRobotIntroductionPO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of AutomationRobotIntroductionPO given an JSON string - * - * @param jsonString JSON string - * @return An instance of AutomationRobotIntroductionPO - * @throws IOException if the JSON string is invalid with respect to AutomationRobotIntroductionPO - */ - public static AutomationRobotIntroductionPO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, AutomationRobotIntroductionPO.class); - } - - /** - * Convert an instance of AutomationRobotIntroductionPO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationRobotIntroductionSO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationRobotIntroductionSO.java deleted file mode 100644 index e0669e08f0..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationRobotIntroductionSO.java +++ /dev/null @@ -1,331 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.apitable.databusclient.model.AutomationActionIntroductionPO; -import com.apitable.databusclient.model.AutomationRobotIntroductionPO; -import com.apitable.databusclient.model.AutomationTriggerIntroductionPO; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * AutomationRobotIntroductionSO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class AutomationRobotIntroductionSO { - public static final String SERIALIZED_NAME_ACTIONS = "actions"; - @SerializedName(SERIALIZED_NAME_ACTIONS) - private List actions = new ArrayList<>(); - - public static final String SERIALIZED_NAME_ROBOTS = "robots"; - @SerializedName(SERIALIZED_NAME_ROBOTS) - private List robots = new ArrayList<>(); - - public static final String SERIALIZED_NAME_TRIGGERS = "triggers"; - @SerializedName(SERIALIZED_NAME_TRIGGERS) - private List triggers = new ArrayList<>(); - - public AutomationRobotIntroductionSO() { - } - - public AutomationRobotIntroductionSO actions(List actions) { - - this.actions = actions; - return this; - } - - public AutomationRobotIntroductionSO addActionsItem(AutomationActionIntroductionPO actionsItem) { - if (this.actions == null) { - this.actions = new ArrayList<>(); - } - this.actions.add(actionsItem); - return this; - } - - /** - * Get actions - * @return actions - **/ - @javax.annotation.Nonnull - public List getActions() { - return actions; - } - - - public void setActions(List actions) { - this.actions = actions; - } - - - public AutomationRobotIntroductionSO robots(List robots) { - - this.robots = robots; - return this; - } - - public AutomationRobotIntroductionSO addRobotsItem(AutomationRobotIntroductionPO robotsItem) { - if (this.robots == null) { - this.robots = new ArrayList<>(); - } - this.robots.add(robotsItem); - return this; - } - - /** - * Get robots - * @return robots - **/ - @javax.annotation.Nonnull - public List getRobots() { - return robots; - } - - - public void setRobots(List robots) { - this.robots = robots; - } - - - public AutomationRobotIntroductionSO triggers(List triggers) { - - this.triggers = triggers; - return this; - } - - public AutomationRobotIntroductionSO addTriggersItem(AutomationTriggerIntroductionPO triggersItem) { - if (this.triggers == null) { - this.triggers = new ArrayList<>(); - } - this.triggers.add(triggersItem); - return this; - } - - /** - * Get triggers - * @return triggers - **/ - @javax.annotation.Nonnull - public List getTriggers() { - return triggers; - } - - - public void setTriggers(List triggers) { - this.triggers = triggers; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - AutomationRobotIntroductionSO automationRobotIntroductionSO = (AutomationRobotIntroductionSO) o; - return Objects.equals(this.actions, automationRobotIntroductionSO.actions) && - Objects.equals(this.robots, automationRobotIntroductionSO.robots) && - Objects.equals(this.triggers, automationRobotIntroductionSO.triggers); - } - - @Override - public int hashCode() { - return Objects.hash(actions, robots, triggers); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class AutomationRobotIntroductionSO {\n"); - sb.append(" actions: ").append(toIndentedString(actions)).append("\n"); - sb.append(" robots: ").append(toIndentedString(robots)).append("\n"); - sb.append(" triggers: ").append(toIndentedString(triggers)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("actions"); - openapiFields.add("robots"); - openapiFields.add("triggers"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("actions"); - openapiRequiredFields.add("robots"); - openapiRequiredFields.add("triggers"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to AutomationRobotIntroductionSO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!AutomationRobotIntroductionSO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in AutomationRobotIntroductionSO is not found in the empty JSON string", AutomationRobotIntroductionSO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!AutomationRobotIntroductionSO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `AutomationRobotIntroductionSO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : AutomationRobotIntroductionSO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - // ensure the json data is an array - if (!jsonObj.get("actions").isJsonArray()) { - throw new IllegalArgumentException(String.format("Expected the field `actions` to be an array in the JSON string but got `%s`", jsonObj.get("actions").toString())); - } - - JsonArray jsonArrayactions = jsonObj.getAsJsonArray("actions"); - // validate the required field `actions` (array) - for (int i = 0; i < jsonArrayactions.size(); i++) { - AutomationActionIntroductionPO.validateJsonElement(jsonArrayactions.get(i)); - }; - // ensure the json data is an array - if (!jsonObj.get("robots").isJsonArray()) { - throw new IllegalArgumentException(String.format("Expected the field `robots` to be an array in the JSON string but got `%s`", jsonObj.get("robots").toString())); - } - - JsonArray jsonArrayrobots = jsonObj.getAsJsonArray("robots"); - // validate the required field `robots` (array) - for (int i = 0; i < jsonArrayrobots.size(); i++) { - AutomationRobotIntroductionPO.validateJsonElement(jsonArrayrobots.get(i)); - }; - // ensure the json data is an array - if (!jsonObj.get("triggers").isJsonArray()) { - throw new IllegalArgumentException(String.format("Expected the field `triggers` to be an array in the JSON string but got `%s`", jsonObj.get("triggers").toString())); - } - - JsonArray jsonArraytriggers = jsonObj.getAsJsonArray("triggers"); - // validate the required field `triggers` (array) - for (int i = 0; i < jsonArraytriggers.size(); i++) { - AutomationTriggerIntroductionPO.validateJsonElement(jsonArraytriggers.get(i)); - }; - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!AutomationRobotIntroductionSO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'AutomationRobotIntroductionSO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(AutomationRobotIntroductionSO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, AutomationRobotIntroductionSO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public AutomationRobotIntroductionSO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of AutomationRobotIntroductionSO given an JSON string - * - * @param jsonString JSON string - * @return An instance of AutomationRobotIntroductionSO - * @throws IOException if the JSON string is invalid with respect to AutomationRobotIntroductionSO - */ - public static AutomationRobotIntroductionSO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, AutomationRobotIntroductionSO.class); - } - - /** - * Convert an instance of AutomationRobotIntroductionSO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationRobotRunNumsSO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationRobotRunNumsSO.java deleted file mode 100644 index a2d6095a08..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationRobotRunNumsSO.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * AutomationRobotRunNumsSO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class AutomationRobotRunNumsSO { - public static final String SERIALIZED_NAME_RECENTLY_RUN_COUNT = "recentlyRunCount"; - @SerializedName(SERIALIZED_NAME_RECENTLY_RUN_COUNT) - private Long recentlyRunCount; - - public AutomationRobotRunNumsSO() { - } - - public AutomationRobotRunNumsSO recentlyRunCount(Long recentlyRunCount) { - - this.recentlyRunCount = recentlyRunCount; - return this; - } - - /** - * Get recentlyRunCount - * @return recentlyRunCount - **/ - @javax.annotation.Nonnull - public Long getRecentlyRunCount() { - return recentlyRunCount; - } - - - public void setRecentlyRunCount(Long recentlyRunCount) { - this.recentlyRunCount = recentlyRunCount; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - AutomationRobotRunNumsSO automationRobotRunNumsSO = (AutomationRobotRunNumsSO) o; - return Objects.equals(this.recentlyRunCount, automationRobotRunNumsSO.recentlyRunCount); - } - - @Override - public int hashCode() { - return Objects.hash(recentlyRunCount); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class AutomationRobotRunNumsSO {\n"); - sb.append(" recentlyRunCount: ").append(toIndentedString(recentlyRunCount)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("recentlyRunCount"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("recentlyRunCount"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to AutomationRobotRunNumsSO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!AutomationRobotRunNumsSO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in AutomationRobotRunNumsSO is not found in the empty JSON string", AutomationRobotRunNumsSO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Map.Entry entry : entries) { - if (!AutomationRobotRunNumsSO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `AutomationRobotRunNumsSO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : AutomationRobotRunNumsSO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!AutomationRobotRunNumsSO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'AutomationRobotRunNumsSO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(AutomationRobotRunNumsSO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, AutomationRobotRunNumsSO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public AutomationRobotRunNumsSO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of AutomationRobotRunNumsSO given an JSON string - * - * @param jsonString JSON string - * @return An instance of AutomationRobotRunNumsSO - * @throws IOException if the JSON string is invalid with respect to AutomationRobotRunNumsSO - */ - public static AutomationRobotRunNumsSO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, AutomationRobotRunNumsSO.class); - } - - /** - * Convert an instance of AutomationRobotRunNumsSO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationRobotSO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationRobotSO.java deleted file mode 100644 index 2e78f590b5..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationRobotSO.java +++ /dev/null @@ -1,471 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * AutomationRobotSO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class AutomationRobotSO { - public static final String SERIALIZED_NAME_DESCRIPTION = "description"; - @SerializedName(SERIALIZED_NAME_DESCRIPTION) - private String description; - - public static final String SERIALIZED_NAME_IS_ACTIVE = "isActive"; - @SerializedName(SERIALIZED_NAME_IS_ACTIVE) - private Integer isActive; - - public static final String SERIALIZED_NAME_NAME = "name"; - @SerializedName(SERIALIZED_NAME_NAME) - private String name; - - public static final String SERIALIZED_NAME_PROPS = "props"; - @SerializedName(SERIALIZED_NAME_PROPS) - private String props; - - public static final String SERIALIZED_NAME_RECENTLY_RUN_COUNT = "recentlyRunCount"; - @SerializedName(SERIALIZED_NAME_RECENTLY_RUN_COUNT) - private Long recentlyRunCount; - - public static final String SERIALIZED_NAME_RESOURCE_ID = "resourceId"; - @SerializedName(SERIALIZED_NAME_RESOURCE_ID) - private String resourceId; - - public static final String SERIALIZED_NAME_ROBOT_ID = "robotId"; - @SerializedName(SERIALIZED_NAME_ROBOT_ID) - private String robotId; - - public static final String SERIALIZED_NAME_UPDATED_AT = "updatedAt"; - @SerializedName(SERIALIZED_NAME_UPDATED_AT) - private Long updatedAt; - - public static final String SERIALIZED_NAME_UPDATED_BY = "updatedBy"; - @SerializedName(SERIALIZED_NAME_UPDATED_BY) - private Long updatedBy; - - public AutomationRobotSO() { - } - - public AutomationRobotSO description(String description) { - - this.description = description; - return this; - } - - /** - * Get description - * @return description - **/ - @javax.annotation.Nullable - public String getDescription() { - return description; - } - - - public void setDescription(String description) { - this.description = description; - } - - - public AutomationRobotSO isActive(Integer isActive) { - - this.isActive = isActive; - return this; - } - - /** - * Get isActive - * minimum: 0 - * @return isActive - **/ - @javax.annotation.Nonnull - public Integer getIsActive() { - return isActive; - } - - - public void setIsActive(Integer isActive) { - this.isActive = isActive; - } - - - public AutomationRobotSO name(String name) { - - this.name = name; - return this; - } - - /** - * Get name - * @return name - **/ - @javax.annotation.Nonnull - public String getName() { - return name; - } - - - public void setName(String name) { - this.name = name; - } - - - public AutomationRobotSO props(String props) { - - this.props = props; - return this; - } - - /** - * Get props - * @return props - **/ - @javax.annotation.Nullable - public String getProps() { - return props; - } - - - public void setProps(String props) { - this.props = props; - } - - - public AutomationRobotSO recentlyRunCount(Long recentlyRunCount) { - - this.recentlyRunCount = recentlyRunCount; - return this; - } - - /** - * Get recentlyRunCount - * @return recentlyRunCount - **/ - @javax.annotation.Nonnull - public Long getRecentlyRunCount() { - return recentlyRunCount; - } - - - public void setRecentlyRunCount(Long recentlyRunCount) { - this.recentlyRunCount = recentlyRunCount; - } - - - public AutomationRobotSO resourceId(String resourceId) { - - this.resourceId = resourceId; - return this; - } - - /** - * Get resourceId - * @return resourceId - **/ - @javax.annotation.Nonnull - public String getResourceId() { - return resourceId; - } - - - public void setResourceId(String resourceId) { - this.resourceId = resourceId; - } - - - public AutomationRobotSO robotId(String robotId) { - - this.robotId = robotId; - return this; - } - - /** - * Get robotId - * @return robotId - **/ - @javax.annotation.Nonnull - public String getRobotId() { - return robotId; - } - - - public void setRobotId(String robotId) { - this.robotId = robotId; - } - - - public AutomationRobotSO updatedAt(Long updatedAt) { - - this.updatedAt = updatedAt; - return this; - } - - /** - * Get updatedAt - * @return updatedAt - **/ - @javax.annotation.Nullable - public Long getUpdatedAt() { - return updatedAt; - } - - - public void setUpdatedAt(Long updatedAt) { - this.updatedAt = updatedAt; - } - - - public AutomationRobotSO updatedBy(Long updatedBy) { - - this.updatedBy = updatedBy; - return this; - } - - /** - * Get updatedBy - * minimum: 0 - * @return updatedBy - **/ - @javax.annotation.Nullable - public Long getUpdatedBy() { - return updatedBy; - } - - - public void setUpdatedBy(Long updatedBy) { - this.updatedBy = updatedBy; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - AutomationRobotSO automationRobotSO = (AutomationRobotSO) o; - return Objects.equals(this.description, automationRobotSO.description) && - Objects.equals(this.isActive, automationRobotSO.isActive) && - Objects.equals(this.name, automationRobotSO.name) && - Objects.equals(this.props, automationRobotSO.props) && - Objects.equals(this.recentlyRunCount, automationRobotSO.recentlyRunCount) && - Objects.equals(this.resourceId, automationRobotSO.resourceId) && - Objects.equals(this.robotId, automationRobotSO.robotId) && - Objects.equals(this.updatedAt, automationRobotSO.updatedAt) && - Objects.equals(this.updatedBy, automationRobotSO.updatedBy); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(description, isActive, name, props, recentlyRunCount, resourceId, robotId, updatedAt, updatedBy); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class AutomationRobotSO {\n"); - sb.append(" description: ").append(toIndentedString(description)).append("\n"); - sb.append(" isActive: ").append(toIndentedString(isActive)).append("\n"); - sb.append(" name: ").append(toIndentedString(name)).append("\n"); - sb.append(" props: ").append(toIndentedString(props)).append("\n"); - sb.append(" recentlyRunCount: ").append(toIndentedString(recentlyRunCount)).append("\n"); - sb.append(" resourceId: ").append(toIndentedString(resourceId)).append("\n"); - sb.append(" robotId: ").append(toIndentedString(robotId)).append("\n"); - sb.append(" updatedAt: ").append(toIndentedString(updatedAt)).append("\n"); - sb.append(" updatedBy: ").append(toIndentedString(updatedBy)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("description"); - openapiFields.add("isActive"); - openapiFields.add("name"); - openapiFields.add("props"); - openapiFields.add("recentlyRunCount"); - openapiFields.add("resourceId"); - openapiFields.add("robotId"); - openapiFields.add("updatedAt"); - openapiFields.add("updatedBy"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("isActive"); - openapiRequiredFields.add("name"); - openapiRequiredFields.add("recentlyRunCount"); - openapiRequiredFields.add("resourceId"); - openapiRequiredFields.add("robotId"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to AutomationRobotSO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!AutomationRobotSO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in AutomationRobotSO is not found in the empty JSON string", AutomationRobotSO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!AutomationRobotSO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `AutomationRobotSO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : AutomationRobotSO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if ((jsonObj.get("description") != null && !jsonObj.get("description").isJsonNull()) && !jsonObj.get("description").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `description` to be a primitive type in the JSON string but got `%s`", jsonObj.get("description").toString())); - } - if (!jsonObj.get("name").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `name` to be a primitive type in the JSON string but got `%s`", jsonObj.get("name").toString())); - } - if ((jsonObj.get("props") != null && !jsonObj.get("props").isJsonNull()) && !jsonObj.get("props").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `props` to be a primitive type in the JSON string but got `%s`", jsonObj.get("props").toString())); - } - if (!jsonObj.get("resourceId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `resourceId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("resourceId").toString())); - } - if (!jsonObj.get("robotId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `robotId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("robotId").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!AutomationRobotSO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'AutomationRobotSO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(AutomationRobotSO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, AutomationRobotSO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public AutomationRobotSO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of AutomationRobotSO given an JSON string - * - * @param jsonString JSON string - * @return An instance of AutomationRobotSO - * @throws IOException if the JSON string is invalid with respect to AutomationRobotSO - */ - public static AutomationRobotSO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, AutomationRobotSO.class); - } - - /** - * Convert an instance of AutomationRobotSO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationRobotTriggerRO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationRobotTriggerRO.java deleted file mode 100644 index a3ca19cac0..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationRobotTriggerRO.java +++ /dev/null @@ -1,438 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * AutomationRobotTriggerRO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class AutomationRobotTriggerRO { - public static final String SERIALIZED_NAME_INPUT = "input"; - @SerializedName(SERIALIZED_NAME_INPUT) - private String input; - - public static final String SERIALIZED_NAME_IS_DELETED = "is_deleted"; - @SerializedName(SERIALIZED_NAME_IS_DELETED) - private Boolean isDeleted; - - public static final String SERIALIZED_NAME_LIMIT_COUNT = "limit_count"; - @SerializedName(SERIALIZED_NAME_LIMIT_COUNT) - private Long limitCount; - - public static final String SERIALIZED_NAME_PREV_TRIGGER_ID = "prev_trigger_id"; - @SerializedName(SERIALIZED_NAME_PREV_TRIGGER_ID) - private String prevTriggerId; - - public static final String SERIALIZED_NAME_RESOURCE_ID = "resource_id"; - @SerializedName(SERIALIZED_NAME_RESOURCE_ID) - private String resourceId; - - public static final String SERIALIZED_NAME_TRIGGER_ID = "trigger_id"; - @SerializedName(SERIALIZED_NAME_TRIGGER_ID) - private String triggerId; - - public static final String SERIALIZED_NAME_TRIGGER_TYPE_ID = "trigger_type_id"; - @SerializedName(SERIALIZED_NAME_TRIGGER_TYPE_ID) - private String triggerTypeId; - - public static final String SERIALIZED_NAME_USER_ID = "user_id"; - @SerializedName(SERIALIZED_NAME_USER_ID) - private Long userId; - - public AutomationRobotTriggerRO() { - } - - public AutomationRobotTriggerRO input(String input) { - - this.input = input; - return this; - } - - /** - * Get input - * @return input - **/ - @javax.annotation.Nullable - public String getInput() { - return input; - } - - - public void setInput(String input) { - this.input = input; - } - - - public AutomationRobotTriggerRO isDeleted(Boolean isDeleted) { - - this.isDeleted = isDeleted; - return this; - } - - /** - * Get isDeleted - * @return isDeleted - **/ - @javax.annotation.Nullable - public Boolean getIsDeleted() { - return isDeleted; - } - - - public void setIsDeleted(Boolean isDeleted) { - this.isDeleted = isDeleted; - } - - - public AutomationRobotTriggerRO limitCount(Long limitCount) { - - this.limitCount = limitCount; - return this; - } - - /** - * Get limitCount - * @return limitCount - **/ - @javax.annotation.Nullable - public Long getLimitCount() { - return limitCount; - } - - - public void setLimitCount(Long limitCount) { - this.limitCount = limitCount; - } - - - public AutomationRobotTriggerRO prevTriggerId(String prevTriggerId) { - - this.prevTriggerId = prevTriggerId; - return this; - } - - /** - * Get prevTriggerId - * @return prevTriggerId - **/ - @javax.annotation.Nullable - public String getPrevTriggerId() { - return prevTriggerId; - } - - - public void setPrevTriggerId(String prevTriggerId) { - this.prevTriggerId = prevTriggerId; - } - - - public AutomationRobotTriggerRO resourceId(String resourceId) { - - this.resourceId = resourceId; - return this; - } - - /** - * Get resourceId - * @return resourceId - **/ - @javax.annotation.Nullable - public String getResourceId() { - return resourceId; - } - - - public void setResourceId(String resourceId) { - this.resourceId = resourceId; - } - - - public AutomationRobotTriggerRO triggerId(String triggerId) { - - this.triggerId = triggerId; - return this; - } - - /** - * Get triggerId - * @return triggerId - **/ - @javax.annotation.Nullable - public String getTriggerId() { - return triggerId; - } - - - public void setTriggerId(String triggerId) { - this.triggerId = triggerId; - } - - - public AutomationRobotTriggerRO triggerTypeId(String triggerTypeId) { - - this.triggerTypeId = triggerTypeId; - return this; - } - - /** - * Get triggerTypeId - * @return triggerTypeId - **/ - @javax.annotation.Nullable - public String getTriggerTypeId() { - return triggerTypeId; - } - - - public void setTriggerTypeId(String triggerTypeId) { - this.triggerTypeId = triggerTypeId; - } - - - public AutomationRobotTriggerRO userId(Long userId) { - - this.userId = userId; - return this; - } - - /** - * Get userId - * minimum: 0 - * @return userId - **/ - @javax.annotation.Nonnull - public Long getUserId() { - return userId; - } - - - public void setUserId(Long userId) { - this.userId = userId; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - AutomationRobotTriggerRO automationRobotTriggerRO = (AutomationRobotTriggerRO) o; - return Objects.equals(this.input, automationRobotTriggerRO.input) && - Objects.equals(this.isDeleted, automationRobotTriggerRO.isDeleted) && - Objects.equals(this.limitCount, automationRobotTriggerRO.limitCount) && - Objects.equals(this.prevTriggerId, automationRobotTriggerRO.prevTriggerId) && - Objects.equals(this.resourceId, automationRobotTriggerRO.resourceId) && - Objects.equals(this.triggerId, automationRobotTriggerRO.triggerId) && - Objects.equals(this.triggerTypeId, automationRobotTriggerRO.triggerTypeId) && - Objects.equals(this.userId, automationRobotTriggerRO.userId); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(input, isDeleted, limitCount, prevTriggerId, resourceId, triggerId, triggerTypeId, userId); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class AutomationRobotTriggerRO {\n"); - sb.append(" input: ").append(toIndentedString(input)).append("\n"); - sb.append(" isDeleted: ").append(toIndentedString(isDeleted)).append("\n"); - sb.append(" limitCount: ").append(toIndentedString(limitCount)).append("\n"); - sb.append(" prevTriggerId: ").append(toIndentedString(prevTriggerId)).append("\n"); - sb.append(" resourceId: ").append(toIndentedString(resourceId)).append("\n"); - sb.append(" triggerId: ").append(toIndentedString(triggerId)).append("\n"); - sb.append(" triggerTypeId: ").append(toIndentedString(triggerTypeId)).append("\n"); - sb.append(" userId: ").append(toIndentedString(userId)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("input"); - openapiFields.add("is_deleted"); - openapiFields.add("limit_count"); - openapiFields.add("prev_trigger_id"); - openapiFields.add("resource_id"); - openapiFields.add("trigger_id"); - openapiFields.add("trigger_type_id"); - openapiFields.add("user_id"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("user_id"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to AutomationRobotTriggerRO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!AutomationRobotTriggerRO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in AutomationRobotTriggerRO is not found in the empty JSON string", AutomationRobotTriggerRO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!AutomationRobotTriggerRO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `AutomationRobotTriggerRO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : AutomationRobotTriggerRO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if ((jsonObj.get("input") != null && !jsonObj.get("input").isJsonNull()) && !jsonObj.get("input").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `input` to be a primitive type in the JSON string but got `%s`", jsonObj.get("input").toString())); - } - if ((jsonObj.get("prev_trigger_id") != null && !jsonObj.get("prev_trigger_id").isJsonNull()) && !jsonObj.get("prev_trigger_id").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `prev_trigger_id` to be a primitive type in the JSON string but got `%s`", jsonObj.get("prev_trigger_id").toString())); - } - if ((jsonObj.get("resource_id") != null && !jsonObj.get("resource_id").isJsonNull()) && !jsonObj.get("resource_id").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `resource_id` to be a primitive type in the JSON string but got `%s`", jsonObj.get("resource_id").toString())); - } - if ((jsonObj.get("trigger_id") != null && !jsonObj.get("trigger_id").isJsonNull()) && !jsonObj.get("trigger_id").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `trigger_id` to be a primitive type in the JSON string but got `%s`", jsonObj.get("trigger_id").toString())); - } - if ((jsonObj.get("trigger_type_id") != null && !jsonObj.get("trigger_type_id").isJsonNull()) && !jsonObj.get("trigger_type_id").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `trigger_type_id` to be a primitive type in the JSON string but got `%s`", jsonObj.get("trigger_type_id").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!AutomationRobotTriggerRO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'AutomationRobotTriggerRO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(AutomationRobotTriggerRO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, AutomationRobotTriggerRO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public AutomationRobotTriggerRO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of AutomationRobotTriggerRO given an JSON string - * - * @param jsonString JSON string - * @return An instance of AutomationRobotTriggerRO - * @throws IOException if the JSON string is invalid with respect to AutomationRobotTriggerRO - */ - public static AutomationRobotTriggerRO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, AutomationRobotTriggerRO.class); - } - - /** - * Convert an instance of AutomationRobotTriggerRO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationRobotUpdateRO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationRobotUpdateRO.java deleted file mode 100644 index 2e5302a60e..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationRobotUpdateRO.java +++ /dev/null @@ -1,376 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * AutomationRobotUpdateRO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class AutomationRobotUpdateRO { - public static final String SERIALIZED_NAME_DESCRIPTION = "description"; - @SerializedName(SERIALIZED_NAME_DESCRIPTION) - private String description; - - public static final String SERIALIZED_NAME_IS_ACTIVE = "is_active"; - @SerializedName(SERIALIZED_NAME_IS_ACTIVE) - private Boolean isActive; - - public static final String SERIALIZED_NAME_IS_DELETED = "is_deleted"; - @SerializedName(SERIALIZED_NAME_IS_DELETED) - private Boolean isDeleted; - - public static final String SERIALIZED_NAME_NAME = "name"; - @SerializedName(SERIALIZED_NAME_NAME) - private String name; - - public static final String SERIALIZED_NAME_PROPS = "props"; - @SerializedName(SERIALIZED_NAME_PROPS) - private String props; - - public static final String SERIALIZED_NAME_UPDATED_BY = "updated_by"; - @SerializedName(SERIALIZED_NAME_UPDATED_BY) - private Long updatedBy; - - public AutomationRobotUpdateRO() { - } - - public AutomationRobotUpdateRO description(String description) { - - this.description = description; - return this; - } - - /** - * Get description - * @return description - **/ - @javax.annotation.Nullable - public String getDescription() { - return description; - } - - - public void setDescription(String description) { - this.description = description; - } - - - public AutomationRobotUpdateRO isActive(Boolean isActive) { - - this.isActive = isActive; - return this; - } - - /** - * Get isActive - * @return isActive - **/ - @javax.annotation.Nullable - public Boolean getIsActive() { - return isActive; - } - - - public void setIsActive(Boolean isActive) { - this.isActive = isActive; - } - - - public AutomationRobotUpdateRO isDeleted(Boolean isDeleted) { - - this.isDeleted = isDeleted; - return this; - } - - /** - * Get isDeleted - * @return isDeleted - **/ - @javax.annotation.Nullable - public Boolean getIsDeleted() { - return isDeleted; - } - - - public void setIsDeleted(Boolean isDeleted) { - this.isDeleted = isDeleted; - } - - - public AutomationRobotUpdateRO name(String name) { - - this.name = name; - return this; - } - - /** - * Get name - * @return name - **/ - @javax.annotation.Nullable - public String getName() { - return name; - } - - - public void setName(String name) { - this.name = name; - } - - - public AutomationRobotUpdateRO props(String props) { - - this.props = props; - return this; - } - - /** - * Get props - * @return props - **/ - @javax.annotation.Nullable - public String getProps() { - return props; - } - - - public void setProps(String props) { - this.props = props; - } - - - public AutomationRobotUpdateRO updatedBy(Long updatedBy) { - - this.updatedBy = updatedBy; - return this; - } - - /** - * Get updatedBy - * minimum: 0 - * @return updatedBy - **/ - @javax.annotation.Nonnull - public Long getUpdatedBy() { - return updatedBy; - } - - - public void setUpdatedBy(Long updatedBy) { - this.updatedBy = updatedBy; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - AutomationRobotUpdateRO automationRobotUpdateRO = (AutomationRobotUpdateRO) o; - return Objects.equals(this.description, automationRobotUpdateRO.description) && - Objects.equals(this.isActive, automationRobotUpdateRO.isActive) && - Objects.equals(this.isDeleted, automationRobotUpdateRO.isDeleted) && - Objects.equals(this.name, automationRobotUpdateRO.name) && - Objects.equals(this.props, automationRobotUpdateRO.props) && - Objects.equals(this.updatedBy, automationRobotUpdateRO.updatedBy); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(description, isActive, isDeleted, name, props, updatedBy); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class AutomationRobotUpdateRO {\n"); - sb.append(" description: ").append(toIndentedString(description)).append("\n"); - sb.append(" isActive: ").append(toIndentedString(isActive)).append("\n"); - sb.append(" isDeleted: ").append(toIndentedString(isDeleted)).append("\n"); - sb.append(" name: ").append(toIndentedString(name)).append("\n"); - sb.append(" props: ").append(toIndentedString(props)).append("\n"); - sb.append(" updatedBy: ").append(toIndentedString(updatedBy)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("description"); - openapiFields.add("is_active"); - openapiFields.add("is_deleted"); - openapiFields.add("name"); - openapiFields.add("props"); - openapiFields.add("updated_by"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("updated_by"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to AutomationRobotUpdateRO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!AutomationRobotUpdateRO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in AutomationRobotUpdateRO is not found in the empty JSON string", AutomationRobotUpdateRO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!AutomationRobotUpdateRO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `AutomationRobotUpdateRO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : AutomationRobotUpdateRO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if ((jsonObj.get("description") != null && !jsonObj.get("description").isJsonNull()) && !jsonObj.get("description").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `description` to be a primitive type in the JSON string but got `%s`", jsonObj.get("description").toString())); - } - if ((jsonObj.get("name") != null && !jsonObj.get("name").isJsonNull()) && !jsonObj.get("name").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `name` to be a primitive type in the JSON string but got `%s`", jsonObj.get("name").toString())); - } - if ((jsonObj.get("props") != null && !jsonObj.get("props").isJsonNull()) && !jsonObj.get("props").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `props` to be a primitive type in the JSON string but got `%s`", jsonObj.get("props").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!AutomationRobotUpdateRO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'AutomationRobotUpdateRO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(AutomationRobotUpdateRO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, AutomationRobotUpdateRO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public AutomationRobotUpdateRO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of AutomationRobotUpdateRO given an JSON string - * - * @param jsonString JSON string - * @return An instance of AutomationRobotUpdateRO - * @throws IOException if the JSON string is invalid with respect to AutomationRobotUpdateRO - */ - public static AutomationRobotUpdateRO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, AutomationRobotUpdateRO.class); - } - - /** - * Convert an instance of AutomationRobotUpdateRO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationRunHistoryPO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationRunHistoryPO.java deleted file mode 100644 index ed155115ed..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationRunHistoryPO.java +++ /dev/null @@ -1,416 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * AutomationRunHistoryPO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class AutomationRunHistoryPO { - public static final String SERIALIZED_NAME_ACTION_IDS = "actionIds"; - @SerializedName(SERIALIZED_NAME_ACTION_IDS) - private String actionIds; - - public static final String SERIALIZED_NAME_ACTION_TYPE_IDS = "actionTypeIds"; - @SerializedName(SERIALIZED_NAME_ACTION_TYPE_IDS) - private String actionTypeIds; - - public static final String SERIALIZED_NAME_CREATED_AT = "createdAt"; - @SerializedName(SERIALIZED_NAME_CREATED_AT) - private String createdAt; - - public static final String SERIALIZED_NAME_ERROR_STACKS = "errorStacks"; - @SerializedName(SERIALIZED_NAME_ERROR_STACKS) - private String errorStacks; - - public static final String SERIALIZED_NAME_ROBOT_ID = "robotId"; - @SerializedName(SERIALIZED_NAME_ROBOT_ID) - private String robotId; - - public static final String SERIALIZED_NAME_STATUS = "status"; - @SerializedName(SERIALIZED_NAME_STATUS) - private Integer status; - - public static final String SERIALIZED_NAME_TASK_ID = "taskId"; - @SerializedName(SERIALIZED_NAME_TASK_ID) - private String taskId; - - public AutomationRunHistoryPO() { - } - - public AutomationRunHistoryPO actionIds(String actionIds) { - - this.actionIds = actionIds; - return this; - } - - /** - * Get actionIds - * @return actionIds - **/ - @javax.annotation.Nullable - public String getActionIds() { - return actionIds; - } - - - public void setActionIds(String actionIds) { - this.actionIds = actionIds; - } - - - public AutomationRunHistoryPO actionTypeIds(String actionTypeIds) { - - this.actionTypeIds = actionTypeIds; - return this; - } - - /** - * Get actionTypeIds - * @return actionTypeIds - **/ - @javax.annotation.Nullable - public String getActionTypeIds() { - return actionTypeIds; - } - - - public void setActionTypeIds(String actionTypeIds) { - this.actionTypeIds = actionTypeIds; - } - - - public AutomationRunHistoryPO createdAt(String createdAt) { - - this.createdAt = createdAt; - return this; - } - - /** - * Get createdAt - * @return createdAt - **/ - @javax.annotation.Nonnull - public String getCreatedAt() { - return createdAt; - } - - - public void setCreatedAt(String createdAt) { - this.createdAt = createdAt; - } - - - public AutomationRunHistoryPO errorStacks(String errorStacks) { - - this.errorStacks = errorStacks; - return this; - } - - /** - * Get errorStacks - * @return errorStacks - **/ - @javax.annotation.Nullable - public String getErrorStacks() { - return errorStacks; - } - - - public void setErrorStacks(String errorStacks) { - this.errorStacks = errorStacks; - } - - - public AutomationRunHistoryPO robotId(String robotId) { - - this.robotId = robotId; - return this; - } - - /** - * Get robotId - * @return robotId - **/ - @javax.annotation.Nonnull - public String getRobotId() { - return robotId; - } - - - public void setRobotId(String robotId) { - this.robotId = robotId; - } - - - public AutomationRunHistoryPO status(Integer status) { - - this.status = status; - return this; - } - - /** - * Get status - * minimum: 0 - * @return status - **/ - @javax.annotation.Nonnull - public Integer getStatus() { - return status; - } - - - public void setStatus(Integer status) { - this.status = status; - } - - - public AutomationRunHistoryPO taskId(String taskId) { - - this.taskId = taskId; - return this; - } - - /** - * Get taskId - * @return taskId - **/ - @javax.annotation.Nonnull - public String getTaskId() { - return taskId; - } - - - public void setTaskId(String taskId) { - this.taskId = taskId; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - AutomationRunHistoryPO automationRunHistoryPO = (AutomationRunHistoryPO) o; - return Objects.equals(this.actionIds, automationRunHistoryPO.actionIds) && - Objects.equals(this.actionTypeIds, automationRunHistoryPO.actionTypeIds) && - Objects.equals(this.createdAt, automationRunHistoryPO.createdAt) && - Objects.equals(this.errorStacks, automationRunHistoryPO.errorStacks) && - Objects.equals(this.robotId, automationRunHistoryPO.robotId) && - Objects.equals(this.status, automationRunHistoryPO.status) && - Objects.equals(this.taskId, automationRunHistoryPO.taskId); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(actionIds, actionTypeIds, createdAt, errorStacks, robotId, status, taskId); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class AutomationRunHistoryPO {\n"); - sb.append(" actionIds: ").append(toIndentedString(actionIds)).append("\n"); - sb.append(" actionTypeIds: ").append(toIndentedString(actionTypeIds)).append("\n"); - sb.append(" createdAt: ").append(toIndentedString(createdAt)).append("\n"); - sb.append(" errorStacks: ").append(toIndentedString(errorStacks)).append("\n"); - sb.append(" robotId: ").append(toIndentedString(robotId)).append("\n"); - sb.append(" status: ").append(toIndentedString(status)).append("\n"); - sb.append(" taskId: ").append(toIndentedString(taskId)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("actionIds"); - openapiFields.add("actionTypeIds"); - openapiFields.add("createdAt"); - openapiFields.add("errorStacks"); - openapiFields.add("robotId"); - openapiFields.add("status"); - openapiFields.add("taskId"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("createdAt"); - openapiRequiredFields.add("robotId"); - openapiRequiredFields.add("status"); - openapiRequiredFields.add("taskId"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to AutomationRunHistoryPO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!AutomationRunHistoryPO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in AutomationRunHistoryPO is not found in the empty JSON string", AutomationRunHistoryPO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!AutomationRunHistoryPO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `AutomationRunHistoryPO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : AutomationRunHistoryPO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if ((jsonObj.get("actionIds") != null && !jsonObj.get("actionIds").isJsonNull()) && !jsonObj.get("actionIds").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `actionIds` to be a primitive type in the JSON string but got `%s`", jsonObj.get("actionIds").toString())); - } - if ((jsonObj.get("actionTypeIds") != null && !jsonObj.get("actionTypeIds").isJsonNull()) && !jsonObj.get("actionTypeIds").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `actionTypeIds` to be a primitive type in the JSON string but got `%s`", jsonObj.get("actionTypeIds").toString())); - } - if (!jsonObj.get("createdAt").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `createdAt` to be a primitive type in the JSON string but got `%s`", jsonObj.get("createdAt").toString())); - } - if ((jsonObj.get("errorStacks") != null && !jsonObj.get("errorStacks").isJsonNull()) && !jsonObj.get("errorStacks").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `errorStacks` to be a primitive type in the JSON string but got `%s`", jsonObj.get("errorStacks").toString())); - } - if (!jsonObj.get("robotId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `robotId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("robotId").toString())); - } - if (!jsonObj.get("taskId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `taskId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("taskId").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!AutomationRunHistoryPO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'AutomationRunHistoryPO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(AutomationRunHistoryPO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, AutomationRunHistoryPO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public AutomationRunHistoryPO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of AutomationRunHistoryPO given an JSON string - * - * @param jsonString JSON string - * @return An instance of AutomationRunHistoryPO - * @throws IOException if the JSON string is invalid with respect to AutomationRunHistoryPO - */ - public static AutomationRunHistoryPO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, AutomationRunHistoryPO.class); - } - - /** - * Convert an instance of AutomationRunHistoryPO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationSO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationSO.java deleted file mode 100644 index ed4a0ec312..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationSO.java +++ /dev/null @@ -1,378 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.apitable.databusclient.model.AutomationActionPO; -import com.apitable.databusclient.model.AutomationRobotSO; -import com.apitable.databusclient.model.AutomationTriggerPO; -import com.apitable.databusclient.model.NodeSimplePO; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * AutomationSO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class AutomationSO { - public static final String SERIALIZED_NAME_ACTIONS = "actions"; - @SerializedName(SERIALIZED_NAME_ACTIONS) - private List actions = new ArrayList<>(); - - public static final String SERIALIZED_NAME_RELATED_RESOURCES = "relatedResources"; - @SerializedName(SERIALIZED_NAME_RELATED_RESOURCES) - private List relatedResources; - - public static final String SERIALIZED_NAME_ROBOT = "robot"; - @SerializedName(SERIALIZED_NAME_ROBOT) - private AutomationRobotSO robot; - - public static final String SERIALIZED_NAME_TRIGGERS = "triggers"; - @SerializedName(SERIALIZED_NAME_TRIGGERS) - private List triggers = new ArrayList<>(); - - public AutomationSO() { - } - - public AutomationSO actions(List actions) { - - this.actions = actions; - return this; - } - - public AutomationSO addActionsItem(AutomationActionPO actionsItem) { - if (this.actions == null) { - this.actions = new ArrayList<>(); - } - this.actions.add(actionsItem); - return this; - } - - /** - * Get actions - * @return actions - **/ - @javax.annotation.Nonnull - public List getActions() { - return actions; - } - - - public void setActions(List actions) { - this.actions = actions; - } - - - public AutomationSO relatedResources(List relatedResources) { - - this.relatedResources = relatedResources; - return this; - } - - public AutomationSO addRelatedResourcesItem(NodeSimplePO relatedResourcesItem) { - if (this.relatedResources == null) { - this.relatedResources = new ArrayList<>(); - } - this.relatedResources.add(relatedResourcesItem); - return this; - } - - /** - * Get relatedResources - * @return relatedResources - **/ - @javax.annotation.Nullable - public List getRelatedResources() { - return relatedResources; - } - - - public void setRelatedResources(List relatedResources) { - this.relatedResources = relatedResources; - } - - - public AutomationSO robot(AutomationRobotSO robot) { - - this.robot = robot; - return this; - } - - /** - * Get robot - * @return robot - **/ - @javax.annotation.Nonnull - public AutomationRobotSO getRobot() { - return robot; - } - - - public void setRobot(AutomationRobotSO robot) { - this.robot = robot; - } - - - public AutomationSO triggers(List triggers) { - - this.triggers = triggers; - return this; - } - - public AutomationSO addTriggersItem(AutomationTriggerPO triggersItem) { - if (this.triggers == null) { - this.triggers = new ArrayList<>(); - } - this.triggers.add(triggersItem); - return this; - } - - /** - * Get triggers - * @return triggers - **/ - @javax.annotation.Nonnull - public List getTriggers() { - return triggers; - } - - - public void setTriggers(List triggers) { - this.triggers = triggers; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - AutomationSO automationSO = (AutomationSO) o; - return Objects.equals(this.actions, automationSO.actions) && - Objects.equals(this.relatedResources, automationSO.relatedResources) && - Objects.equals(this.robot, automationSO.robot) && - Objects.equals(this.triggers, automationSO.triggers); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(actions, relatedResources, robot, triggers); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class AutomationSO {\n"); - sb.append(" actions: ").append(toIndentedString(actions)).append("\n"); - sb.append(" relatedResources: ").append(toIndentedString(relatedResources)).append("\n"); - sb.append(" robot: ").append(toIndentedString(robot)).append("\n"); - sb.append(" triggers: ").append(toIndentedString(triggers)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("actions"); - openapiFields.add("relatedResources"); - openapiFields.add("robot"); - openapiFields.add("triggers"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("actions"); - openapiRequiredFields.add("robot"); - openapiRequiredFields.add("triggers"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to AutomationSO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!AutomationSO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in AutomationSO is not found in the empty JSON string", AutomationSO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!AutomationSO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `AutomationSO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : AutomationSO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - // ensure the json data is an array - if (!jsonObj.get("actions").isJsonArray()) { - throw new IllegalArgumentException(String.format("Expected the field `actions` to be an array in the JSON string but got `%s`", jsonObj.get("actions").toString())); - } - - JsonArray jsonArrayactions = jsonObj.getAsJsonArray("actions"); - // validate the required field `actions` (array) - for (int i = 0; i < jsonArrayactions.size(); i++) { - AutomationActionPO.validateJsonElement(jsonArrayactions.get(i)); - }; - if (jsonObj.get("relatedResources") != null && !jsonObj.get("relatedResources").isJsonNull()) { - JsonArray jsonArrayrelatedResources = jsonObj.getAsJsonArray("relatedResources"); - if (jsonArrayrelatedResources != null) { - // ensure the json data is an array - if (!jsonObj.get("relatedResources").isJsonArray()) { - throw new IllegalArgumentException(String.format("Expected the field `relatedResources` to be an array in the JSON string but got `%s`", jsonObj.get("relatedResources").toString())); - } - - // validate the optional field `relatedResources` (array) - for (int i = 0; i < jsonArrayrelatedResources.size(); i++) { - NodeSimplePO.validateJsonElement(jsonArrayrelatedResources.get(i)); - }; - } - } - // validate the required field `robot` - AutomationRobotSO.validateJsonElement(jsonObj.get("robot")); - // ensure the json data is an array - if (!jsonObj.get("triggers").isJsonArray()) { - throw new IllegalArgumentException(String.format("Expected the field `triggers` to be an array in the JSON string but got `%s`", jsonObj.get("triggers").toString())); - } - - JsonArray jsonArraytriggers = jsonObj.getAsJsonArray("triggers"); - // validate the required field `triggers` (array) - for (int i = 0; i < jsonArraytriggers.size(); i++) { - AutomationTriggerPO.validateJsonElement(jsonArraytriggers.get(i)); - }; - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!AutomationSO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'AutomationSO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(AutomationSO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, AutomationSO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public AutomationSO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of AutomationSO given an JSON string - * - * @param jsonString JSON string - * @return An instance of AutomationSO - * @throws IOException if the JSON string is invalid with respect to AutomationSO - */ - public static AutomationSO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, AutomationSO.class); - } - - /** - * Convert an instance of AutomationSO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationTriggerIntroductionPO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationTriggerIntroductionPO.java deleted file mode 100644 index c028cb3812..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationTriggerIntroductionPO.java +++ /dev/null @@ -1,324 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * AutomationTriggerIntroductionPO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class AutomationTriggerIntroductionPO { - public static final String SERIALIZED_NAME_PREV_TRIGGER_ID = "prevTriggerId"; - @SerializedName(SERIALIZED_NAME_PREV_TRIGGER_ID) - private String prevTriggerId; - - public static final String SERIALIZED_NAME_ROBOT_ID = "robotId"; - @SerializedName(SERIALIZED_NAME_ROBOT_ID) - private String robotId; - - public static final String SERIALIZED_NAME_TRIGGER_ID = "triggerId"; - @SerializedName(SERIALIZED_NAME_TRIGGER_ID) - private String triggerId; - - public static final String SERIALIZED_NAME_TRIGGER_TYPE_ID = "triggerTypeId"; - @SerializedName(SERIALIZED_NAME_TRIGGER_TYPE_ID) - private String triggerTypeId; - - public AutomationTriggerIntroductionPO() { - } - - public AutomationTriggerIntroductionPO prevTriggerId(String prevTriggerId) { - - this.prevTriggerId = prevTriggerId; - return this; - } - - /** - * Get prevTriggerId - * @return prevTriggerId - **/ - @javax.annotation.Nullable - public String getPrevTriggerId() { - return prevTriggerId; - } - - - public void setPrevTriggerId(String prevTriggerId) { - this.prevTriggerId = prevTriggerId; - } - - - public AutomationTriggerIntroductionPO robotId(String robotId) { - - this.robotId = robotId; - return this; - } - - /** - * Get robotId - * @return robotId - **/ - @javax.annotation.Nonnull - public String getRobotId() { - return robotId; - } - - - public void setRobotId(String robotId) { - this.robotId = robotId; - } - - - public AutomationTriggerIntroductionPO triggerId(String triggerId) { - - this.triggerId = triggerId; - return this; - } - - /** - * Get triggerId - * @return triggerId - **/ - @javax.annotation.Nonnull - public String getTriggerId() { - return triggerId; - } - - - public void setTriggerId(String triggerId) { - this.triggerId = triggerId; - } - - - public AutomationTriggerIntroductionPO triggerTypeId(String triggerTypeId) { - - this.triggerTypeId = triggerTypeId; - return this; - } - - /** - * Get triggerTypeId - * @return triggerTypeId - **/ - @javax.annotation.Nonnull - public String getTriggerTypeId() { - return triggerTypeId; - } - - - public void setTriggerTypeId(String triggerTypeId) { - this.triggerTypeId = triggerTypeId; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - AutomationTriggerIntroductionPO automationTriggerIntroductionPO = (AutomationTriggerIntroductionPO) o; - return Objects.equals(this.prevTriggerId, automationTriggerIntroductionPO.prevTriggerId) && - Objects.equals(this.robotId, automationTriggerIntroductionPO.robotId) && - Objects.equals(this.triggerId, automationTriggerIntroductionPO.triggerId) && - Objects.equals(this.triggerTypeId, automationTriggerIntroductionPO.triggerTypeId); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(prevTriggerId, robotId, triggerId, triggerTypeId); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class AutomationTriggerIntroductionPO {\n"); - sb.append(" prevTriggerId: ").append(toIndentedString(prevTriggerId)).append("\n"); - sb.append(" robotId: ").append(toIndentedString(robotId)).append("\n"); - sb.append(" triggerId: ").append(toIndentedString(triggerId)).append("\n"); - sb.append(" triggerTypeId: ").append(toIndentedString(triggerTypeId)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("prevTriggerId"); - openapiFields.add("robotId"); - openapiFields.add("triggerId"); - openapiFields.add("triggerTypeId"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("robotId"); - openapiRequiredFields.add("triggerId"); - openapiRequiredFields.add("triggerTypeId"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to AutomationTriggerIntroductionPO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!AutomationTriggerIntroductionPO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in AutomationTriggerIntroductionPO is not found in the empty JSON string", AutomationTriggerIntroductionPO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!AutomationTriggerIntroductionPO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `AutomationTriggerIntroductionPO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : AutomationTriggerIntroductionPO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if ((jsonObj.get("prevTriggerId") != null && !jsonObj.get("prevTriggerId").isJsonNull()) && !jsonObj.get("prevTriggerId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `prevTriggerId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("prevTriggerId").toString())); - } - if (!jsonObj.get("robotId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `robotId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("robotId").toString())); - } - if (!jsonObj.get("triggerId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `triggerId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("triggerId").toString())); - } - if (!jsonObj.get("triggerTypeId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `triggerTypeId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("triggerTypeId").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!AutomationTriggerIntroductionPO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'AutomationTriggerIntroductionPO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(AutomationTriggerIntroductionPO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, AutomationTriggerIntroductionPO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public AutomationTriggerIntroductionPO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of AutomationTriggerIntroductionPO given an JSON string - * - * @param jsonString JSON string - * @return An instance of AutomationTriggerIntroductionPO - * @throws IOException if the JSON string is invalid with respect to AutomationTriggerIntroductionPO - */ - public static AutomationTriggerIntroductionPO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, AutomationTriggerIntroductionPO.class); - } - - /** - * Convert an instance of AutomationTriggerIntroductionPO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationTriggerPO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationTriggerPO.java deleted file mode 100644 index a455e9fbe3..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/AutomationTriggerPO.java +++ /dev/null @@ -1,386 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * AutomationTriggerPO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class AutomationTriggerPO { - public static final String SERIALIZED_NAME_INPUT = "input"; - @SerializedName(SERIALIZED_NAME_INPUT) - private String input; - - public static final String SERIALIZED_NAME_PREV_TRIGGER_ID = "prevTriggerId"; - @SerializedName(SERIALIZED_NAME_PREV_TRIGGER_ID) - private String prevTriggerId; - - public static final String SERIALIZED_NAME_RESOURCE_ID = "resourceId"; - @SerializedName(SERIALIZED_NAME_RESOURCE_ID) - private String resourceId; - - public static final String SERIALIZED_NAME_ROBOT_ID = "robotId"; - @SerializedName(SERIALIZED_NAME_ROBOT_ID) - private String robotId; - - public static final String SERIALIZED_NAME_TRIGGER_ID = "triggerId"; - @SerializedName(SERIALIZED_NAME_TRIGGER_ID) - private String triggerId; - - public static final String SERIALIZED_NAME_TRIGGER_TYPE_ID = "triggerTypeId"; - @SerializedName(SERIALIZED_NAME_TRIGGER_TYPE_ID) - private String triggerTypeId; - - public AutomationTriggerPO() { - } - - public AutomationTriggerPO input(String input) { - - this.input = input; - return this; - } - - /** - * Get input - * @return input - **/ - @javax.annotation.Nullable - public String getInput() { - return input; - } - - - public void setInput(String input) { - this.input = input; - } - - - public AutomationTriggerPO prevTriggerId(String prevTriggerId) { - - this.prevTriggerId = prevTriggerId; - return this; - } - - /** - * Get prevTriggerId - * @return prevTriggerId - **/ - @javax.annotation.Nullable - public String getPrevTriggerId() { - return prevTriggerId; - } - - - public void setPrevTriggerId(String prevTriggerId) { - this.prevTriggerId = prevTriggerId; - } - - - public AutomationTriggerPO resourceId(String resourceId) { - - this.resourceId = resourceId; - return this; - } - - /** - * Get resourceId - * @return resourceId - **/ - @javax.annotation.Nullable - public String getResourceId() { - return resourceId; - } - - - public void setResourceId(String resourceId) { - this.resourceId = resourceId; - } - - - public AutomationTriggerPO robotId(String robotId) { - - this.robotId = robotId; - return this; - } - - /** - * Get robotId - * @return robotId - **/ - @javax.annotation.Nonnull - public String getRobotId() { - return robotId; - } - - - public void setRobotId(String robotId) { - this.robotId = robotId; - } - - - public AutomationTriggerPO triggerId(String triggerId) { - - this.triggerId = triggerId; - return this; - } - - /** - * Get triggerId - * @return triggerId - **/ - @javax.annotation.Nonnull - public String getTriggerId() { - return triggerId; - } - - - public void setTriggerId(String triggerId) { - this.triggerId = triggerId; - } - - - public AutomationTriggerPO triggerTypeId(String triggerTypeId) { - - this.triggerTypeId = triggerTypeId; - return this; - } - - /** - * Get triggerTypeId - * @return triggerTypeId - **/ - @javax.annotation.Nonnull - public String getTriggerTypeId() { - return triggerTypeId; - } - - - public void setTriggerTypeId(String triggerTypeId) { - this.triggerTypeId = triggerTypeId; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - AutomationTriggerPO automationTriggerPO = (AutomationTriggerPO) o; - return Objects.equals(this.input, automationTriggerPO.input) && - Objects.equals(this.prevTriggerId, automationTriggerPO.prevTriggerId) && - Objects.equals(this.resourceId, automationTriggerPO.resourceId) && - Objects.equals(this.robotId, automationTriggerPO.robotId) && - Objects.equals(this.triggerId, automationTriggerPO.triggerId) && - Objects.equals(this.triggerTypeId, automationTriggerPO.triggerTypeId); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(input, prevTriggerId, resourceId, robotId, triggerId, triggerTypeId); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class AutomationTriggerPO {\n"); - sb.append(" input: ").append(toIndentedString(input)).append("\n"); - sb.append(" prevTriggerId: ").append(toIndentedString(prevTriggerId)).append("\n"); - sb.append(" resourceId: ").append(toIndentedString(resourceId)).append("\n"); - sb.append(" robotId: ").append(toIndentedString(robotId)).append("\n"); - sb.append(" triggerId: ").append(toIndentedString(triggerId)).append("\n"); - sb.append(" triggerTypeId: ").append(toIndentedString(triggerTypeId)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("input"); - openapiFields.add("prevTriggerId"); - openapiFields.add("resourceId"); - openapiFields.add("robotId"); - openapiFields.add("triggerId"); - openapiFields.add("triggerTypeId"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("robotId"); - openapiRequiredFields.add("triggerId"); - openapiRequiredFields.add("triggerTypeId"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to AutomationTriggerPO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!AutomationTriggerPO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in AutomationTriggerPO is not found in the empty JSON string", AutomationTriggerPO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!AutomationTriggerPO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `AutomationTriggerPO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : AutomationTriggerPO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if ((jsonObj.get("input") != null && !jsonObj.get("input").isJsonNull()) && !jsonObj.get("input").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `input` to be a primitive type in the JSON string but got `%s`", jsonObj.get("input").toString())); - } - if ((jsonObj.get("prevTriggerId") != null && !jsonObj.get("prevTriggerId").isJsonNull()) && !jsonObj.get("prevTriggerId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `prevTriggerId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("prevTriggerId").toString())); - } - if ((jsonObj.get("resourceId") != null && !jsonObj.get("resourceId").isJsonNull()) && !jsonObj.get("resourceId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `resourceId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("resourceId").toString())); - } - if (!jsonObj.get("robotId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `robotId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("robotId").toString())); - } - if (!jsonObj.get("triggerId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `triggerId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("triggerId").toString())); - } - if (!jsonObj.get("triggerTypeId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `triggerTypeId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("triggerTypeId").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!AutomationTriggerPO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'AutomationTriggerPO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(AutomationTriggerPO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, AutomationTriggerPO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public AutomationTriggerPO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of AutomationTriggerPO given an JSON string - * - * @param jsonString JSON string - * @return An instance of AutomationTriggerPO - * @throws IOException if the JSON string is invalid with respect to AutomationTriggerPO - */ - public static AutomationTriggerPO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, AutomationTriggerPO.class); - } - - /** - * Convert an instance of AutomationTriggerPO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/BaseDatasheetPackSO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/BaseDatasheetPackSO.java deleted file mode 100644 index b27d6b0e35..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/BaseDatasheetPackSO.java +++ /dev/null @@ -1,286 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.apitable.databusclient.model.DatasheetSnapshotSO; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * BaseDatasheetPackSO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class BaseDatasheetPackSO { - public static final String SERIALIZED_NAME_DATASHEET = "datasheet"; - @SerializedName(SERIALIZED_NAME_DATASHEET) - private Object datasheet = null; - - public static final String SERIALIZED_NAME_FIELD_PERMISSION_MAP = "fieldPermissionMap"; - @SerializedName(SERIALIZED_NAME_FIELD_PERMISSION_MAP) - private Object fieldPermissionMap = null; - - public static final String SERIALIZED_NAME_SNAPSHOT = "snapshot"; - @SerializedName(SERIALIZED_NAME_SNAPSHOT) - private DatasheetSnapshotSO snapshot; - - public BaseDatasheetPackSO() { - } - - public BaseDatasheetPackSO datasheet(Object datasheet) { - - this.datasheet = datasheet; - return this; - } - - /** - * Get datasheet - * @return datasheet - **/ - @javax.annotation.Nullable - public Object getDatasheet() { - return datasheet; - } - - - public void setDatasheet(Object datasheet) { - this.datasheet = datasheet; - } - - - public BaseDatasheetPackSO fieldPermissionMap(Object fieldPermissionMap) { - - this.fieldPermissionMap = fieldPermissionMap; - return this; - } - - /** - * Get fieldPermissionMap - * @return fieldPermissionMap - **/ - @javax.annotation.Nullable - public Object getFieldPermissionMap() { - return fieldPermissionMap; - } - - - public void setFieldPermissionMap(Object fieldPermissionMap) { - this.fieldPermissionMap = fieldPermissionMap; - } - - - public BaseDatasheetPackSO snapshot(DatasheetSnapshotSO snapshot) { - - this.snapshot = snapshot; - return this; - } - - /** - * Get snapshot - * @return snapshot - **/ - @javax.annotation.Nonnull - public DatasheetSnapshotSO getSnapshot() { - return snapshot; - } - - - public void setSnapshot(DatasheetSnapshotSO snapshot) { - this.snapshot = snapshot; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - BaseDatasheetPackSO baseDatasheetPackSO = (BaseDatasheetPackSO) o; - return Objects.equals(this.datasheet, baseDatasheetPackSO.datasheet) && - Objects.equals(this.fieldPermissionMap, baseDatasheetPackSO.fieldPermissionMap) && - Objects.equals(this.snapshot, baseDatasheetPackSO.snapshot); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(datasheet, fieldPermissionMap, snapshot); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class BaseDatasheetPackSO {\n"); - sb.append(" datasheet: ").append(toIndentedString(datasheet)).append("\n"); - sb.append(" fieldPermissionMap: ").append(toIndentedString(fieldPermissionMap)).append("\n"); - sb.append(" snapshot: ").append(toIndentedString(snapshot)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("datasheet"); - openapiFields.add("fieldPermissionMap"); - openapiFields.add("snapshot"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("datasheet"); - openapiRequiredFields.add("snapshot"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to BaseDatasheetPackSO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!BaseDatasheetPackSO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in BaseDatasheetPackSO is not found in the empty JSON string", BaseDatasheetPackSO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!BaseDatasheetPackSO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `BaseDatasheetPackSO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : BaseDatasheetPackSO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - // validate the required field `snapshot` - DatasheetSnapshotSO.validateJsonElement(jsonObj.get("snapshot")); - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!BaseDatasheetPackSO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'BaseDatasheetPackSO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(BaseDatasheetPackSO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, BaseDatasheetPackSO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public BaseDatasheetPackSO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of BaseDatasheetPackSO given an JSON string - * - * @param jsonString JSON string - * @return An instance of BaseDatasheetPackSO - * @throws IOException if the JSON string is invalid with respect to BaseDatasheetPackSO - */ - public static BaseDatasheetPackSO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, BaseDatasheetPackSO.class); - } - - /** - * Convert an instance of BaseDatasheetPackSO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/CellFormatEnum.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/CellFormatEnum.java deleted file mode 100644 index 5028fb0523..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/CellFormatEnum.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.annotations.SerializedName; - -import java.io.IOException; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; - -/** - * Gets or Sets CellFormatEnum - */ -@JsonAdapter(CellFormatEnum.Adapter.class) -public enum CellFormatEnum { - - STRING("STRING"), - - JSON("JSON"); - - private String value; - - CellFormatEnum(String value) { - this.value = value; - } - - public String getValue() { - return value; - } - - @Override - public String toString() { - return String.valueOf(value); - } - - public static CellFormatEnum fromValue(String value) { - for (CellFormatEnum b : CellFormatEnum.values()) { - if (b.value.equals(value)) { - return b; - } - } - throw new IllegalArgumentException("Unexpected value '" + value + "'"); - } - - public static class Adapter extends TypeAdapter { - @Override - public void write(final JsonWriter jsonWriter, final CellFormatEnum enumeration) throws IOException { - jsonWriter.value(enumeration.getValue()); - } - - @Override - public CellFormatEnum read(final JsonReader jsonReader) throws IOException { - String value = jsonReader.nextString(); - return CellFormatEnum.fromValue(value); - } - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/ColorOption.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/ColorOption.java deleted file mode 100644 index 4a7257265f..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/ColorOption.java +++ /dev/null @@ -1,249 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * ColorOption - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class ColorOption { - public static final String SERIALIZED_NAME_COLOR = "color"; - @SerializedName(SERIALIZED_NAME_COLOR) - private Integer color; - - public static final String SERIALIZED_NAME_FIELD_ID = "field_id"; - @SerializedName(SERIALIZED_NAME_FIELD_ID) - private String fieldId; - - public ColorOption() { - } - - public ColorOption color(Integer color) { - - this.color = color; - return this; - } - - /** - * Get color - * @return color - **/ - @javax.annotation.Nullable - public Integer getColor() { - return color; - } - - - public void setColor(Integer color) { - this.color = color; - } - - - public ColorOption fieldId(String fieldId) { - - this.fieldId = fieldId; - return this; - } - - /** - * Get fieldId - * @return fieldId - **/ - @javax.annotation.Nullable - public String getFieldId() { - return fieldId; - } - - - public void setFieldId(String fieldId) { - this.fieldId = fieldId; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ColorOption colorOption = (ColorOption) o; - return Objects.equals(this.color, colorOption.color) && - Objects.equals(this.fieldId, colorOption.fieldId); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(color, fieldId); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class ColorOption {\n"); - sb.append(" color: ").append(toIndentedString(color)).append("\n"); - sb.append(" fieldId: ").append(toIndentedString(fieldId)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("color"); - openapiFields.add("field_id"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to ColorOption - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!ColorOption.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in ColorOption is not found in the empty JSON string", ColorOption.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!ColorOption.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `ColorOption` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if ((jsonObj.get("field_id") != null && !jsonObj.get("field_id").isJsonNull()) && !jsonObj.get("field_id").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `field_id` to be a primitive type in the JSON string but got `%s`", jsonObj.get("field_id").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!ColorOption.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'ColorOption' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(ColorOption.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, ColorOption value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public ColorOption read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of ColorOption given an JSON string - * - * @param jsonString JSON string - * @return An instance of ColorOption - * @throws IOException if the JSON string is invalid with respect to ColorOption - */ - public static ColorOption fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, ColorOption.class); - } - - /** - * Convert an instance of ColorOption to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/CommentMsg.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/CommentMsg.java deleted file mode 100644 index 4745034448..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/CommentMsg.java +++ /dev/null @@ -1,363 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * CommentMsg - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class CommentMsg { - public static final String SERIALIZED_NAME_COMMENT_TYPE = "commentType"; - @SerializedName(SERIALIZED_NAME_COMMENT_TYPE) - private String commentType; - - public static final String SERIALIZED_NAME_CONTENT = "content"; - @SerializedName(SERIALIZED_NAME_CONTENT) - private String content; - - public static final String SERIALIZED_NAME_EMOJIS = "emojis"; - @SerializedName(SERIALIZED_NAME_EMOJIS) - private Map> emojis; - - public static final String SERIALIZED_NAME_HTML = "html"; - @SerializedName(SERIALIZED_NAME_HTML) - private String html; - - public static final String SERIALIZED_NAME_REPLY = "reply"; - @SerializedName(SERIALIZED_NAME_REPLY) - private String reply; - - public CommentMsg() { - } - - public CommentMsg commentType(String commentType) { - - this.commentType = commentType; - return this; - } - - /** - * Get commentType - * @return commentType - **/ - @javax.annotation.Nonnull - public String getCommentType() { - return commentType; - } - - - public void setCommentType(String commentType) { - this.commentType = commentType; - } - - - public CommentMsg content(String content) { - - this.content = content; - return this; - } - - /** - * Get content - * @return content - **/ - @javax.annotation.Nonnull - public String getContent() { - return content; - } - - - public void setContent(String content) { - this.content = content; - } - - - public CommentMsg emojis(Map> emojis) { - - this.emojis = emojis; - return this; - } - - public CommentMsg putEmojisItem(String key, List emojisItem) { - if (this.emojis == null) { - this.emojis = new HashMap<>(); - } - this.emojis.put(key, emojisItem); - return this; - } - - /** - * Get emojis - * @return emojis - **/ - @javax.annotation.Nullable - public Map> getEmojis() { - return emojis; - } - - - public void setEmojis(Map> emojis) { - this.emojis = emojis; - } - - - public CommentMsg html(String html) { - - this.html = html; - return this; - } - - /** - * Get html - * @return html - **/ - @javax.annotation.Nonnull - public String getHtml() { - return html; - } - - - public void setHtml(String html) { - this.html = html; - } - - - public CommentMsg reply(String reply) { - - this.reply = reply; - return this; - } - - /** - * Get reply - * @return reply - **/ - @javax.annotation.Nullable - public String getReply() { - return reply; - } - - - public void setReply(String reply) { - this.reply = reply; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - CommentMsg commentMsg = (CommentMsg) o; - return Objects.equals(this.commentType, commentMsg.commentType) && - Objects.equals(this.content, commentMsg.content) && - Objects.equals(this.emojis, commentMsg.emojis) && - Objects.equals(this.html, commentMsg.html) && - Objects.equals(this.reply, commentMsg.reply); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(commentType, content, emojis, html, reply); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class CommentMsg {\n"); - sb.append(" commentType: ").append(toIndentedString(commentType)).append("\n"); - sb.append(" content: ").append(toIndentedString(content)).append("\n"); - sb.append(" emojis: ").append(toIndentedString(emojis)).append("\n"); - sb.append(" html: ").append(toIndentedString(html)).append("\n"); - sb.append(" reply: ").append(toIndentedString(reply)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("commentType"); - openapiFields.add("content"); - openapiFields.add("emojis"); - openapiFields.add("html"); - openapiFields.add("reply"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("commentType"); - openapiRequiredFields.add("content"); - openapiRequiredFields.add("html"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to CommentMsg - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!CommentMsg.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in CommentMsg is not found in the empty JSON string", CommentMsg.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!CommentMsg.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `CommentMsg` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : CommentMsg.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if (!jsonObj.get("commentType").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `commentType` to be a primitive type in the JSON string but got `%s`", jsonObj.get("commentType").toString())); - } - if (!jsonObj.get("content").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `content` to be a primitive type in the JSON string but got `%s`", jsonObj.get("content").toString())); - } - if (!jsonObj.get("html").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `html` to be a primitive type in the JSON string but got `%s`", jsonObj.get("html").toString())); - } - if ((jsonObj.get("reply") != null && !jsonObj.get("reply").isJsonNull()) && !jsonObj.get("reply").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `reply` to be a primitive type in the JSON string but got `%s`", jsonObj.get("reply").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!CommentMsg.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'CommentMsg' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(CommentMsg.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, CommentMsg value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public CommentMsg read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of CommentMsg given an JSON string - * - * @param jsonString JSON string - * @return An instance of CommentMsg - * @throws IOException if the JSON string is invalid with respect to CommentMsg - */ - public static CommentMsg fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, CommentMsg.class); - } - - /** - * Convert an instance of CommentMsg to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/Comments.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/Comments.java deleted file mode 100644 index ab6ace5eaa..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/Comments.java +++ /dev/null @@ -1,382 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.apitable.databusclient.model.CommentMsg; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * Comments - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class Comments { - public static final String SERIALIZED_NAME_COMMENT_ID = "commentId"; - @SerializedName(SERIALIZED_NAME_COMMENT_ID) - private String commentId; - - public static final String SERIALIZED_NAME_COMMENT_MSG = "commentMsg"; - @SerializedName(SERIALIZED_NAME_COMMENT_MSG) - private CommentMsg commentMsg; - - public static final String SERIALIZED_NAME_CREATED_AT = "createdAt"; - @SerializedName(SERIALIZED_NAME_CREATED_AT) - private Long createdAt; - - public static final String SERIALIZED_NAME_REVISION = "revision"; - @SerializedName(SERIALIZED_NAME_REVISION) - private Integer revision; - - public static final String SERIALIZED_NAME_UNIT_ID = "unitId"; - @SerializedName(SERIALIZED_NAME_UNIT_ID) - private String unitId; - - public static final String SERIALIZED_NAME_UPDATED_AT = "updatedAt"; - @SerializedName(SERIALIZED_NAME_UPDATED_AT) - private Long updatedAt; - - public Comments() { - } - - public Comments commentId(String commentId) { - - this.commentId = commentId; - return this; - } - - /** - * Get commentId - * @return commentId - **/ - @javax.annotation.Nonnull - public String getCommentId() { - return commentId; - } - - - public void setCommentId(String commentId) { - this.commentId = commentId; - } - - - public Comments commentMsg(CommentMsg commentMsg) { - - this.commentMsg = commentMsg; - return this; - } - - /** - * Get commentMsg - * @return commentMsg - **/ - @javax.annotation.Nonnull - public CommentMsg getCommentMsg() { - return commentMsg; - } - - - public void setCommentMsg(CommentMsg commentMsg) { - this.commentMsg = commentMsg; - } - - - public Comments createdAt(Long createdAt) { - - this.createdAt = createdAt; - return this; - } - - /** - * Get createdAt - * minimum: 0 - * @return createdAt - **/ - @javax.annotation.Nonnull - public Long getCreatedAt() { - return createdAt; - } - - - public void setCreatedAt(Long createdAt) { - this.createdAt = createdAt; - } - - - public Comments revision(Integer revision) { - - this.revision = revision; - return this; - } - - /** - * Get revision - * minimum: 0 - * @return revision - **/ - @javax.annotation.Nonnull - public Integer getRevision() { - return revision; - } - - - public void setRevision(Integer revision) { - this.revision = revision; - } - - - public Comments unitId(String unitId) { - - this.unitId = unitId; - return this; - } - - /** - * Get unitId - * @return unitId - **/ - @javax.annotation.Nonnull - public String getUnitId() { - return unitId; - } - - - public void setUnitId(String unitId) { - this.unitId = unitId; - } - - - public Comments updatedAt(Long updatedAt) { - - this.updatedAt = updatedAt; - return this; - } - - /** - * Get updatedAt - * minimum: 0 - * @return updatedAt - **/ - @javax.annotation.Nullable - public Long getUpdatedAt() { - return updatedAt; - } - - - public void setUpdatedAt(Long updatedAt) { - this.updatedAt = updatedAt; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Comments comments = (Comments) o; - return Objects.equals(this.commentId, comments.commentId) && - Objects.equals(this.commentMsg, comments.commentMsg) && - Objects.equals(this.createdAt, comments.createdAt) && - Objects.equals(this.revision, comments.revision) && - Objects.equals(this.unitId, comments.unitId) && - Objects.equals(this.updatedAt, comments.updatedAt); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(commentId, commentMsg, createdAt, revision, unitId, updatedAt); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class Comments {\n"); - sb.append(" commentId: ").append(toIndentedString(commentId)).append("\n"); - sb.append(" commentMsg: ").append(toIndentedString(commentMsg)).append("\n"); - sb.append(" createdAt: ").append(toIndentedString(createdAt)).append("\n"); - sb.append(" revision: ").append(toIndentedString(revision)).append("\n"); - sb.append(" unitId: ").append(toIndentedString(unitId)).append("\n"); - sb.append(" updatedAt: ").append(toIndentedString(updatedAt)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("commentId"); - openapiFields.add("commentMsg"); - openapiFields.add("createdAt"); - openapiFields.add("revision"); - openapiFields.add("unitId"); - openapiFields.add("updatedAt"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("commentId"); - openapiRequiredFields.add("commentMsg"); - openapiRequiredFields.add("createdAt"); - openapiRequiredFields.add("revision"); - openapiRequiredFields.add("unitId"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to Comments - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!Comments.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in Comments is not found in the empty JSON string", Comments.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!Comments.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `Comments` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : Comments.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if (!jsonObj.get("commentId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `commentId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("commentId").toString())); - } - // validate the required field `commentMsg` - CommentMsg.validateJsonElement(jsonObj.get("commentMsg")); - if (!jsonObj.get("unitId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `unitId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("unitId").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!Comments.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'Comments' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(Comments.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, Comments value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public Comments read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of Comments given an JSON string - * - * @param jsonString JSON string - * @return An instance of Comments - * @throws IOException if the JSON string is invalid with respect to Comments - */ - public static Comments fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, Comments.class); - } - - /** - * Convert an instance of Comments to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/DatasheetMetaSO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/DatasheetMetaSO.java deleted file mode 100644 index baa3dc9e29..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/DatasheetMetaSO.java +++ /dev/null @@ -1,378 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.apitable.databusclient.model.FieldSO; -import com.apitable.databusclient.model.ViewSO; -import com.apitable.databusclient.model.WidgetPanelSO; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * DatasheetMetaSO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class DatasheetMetaSO { - public static final String SERIALIZED_NAME_ARCHIVED_RECORD_IDS = "archivedRecordIds"; - @SerializedName(SERIALIZED_NAME_ARCHIVED_RECORD_IDS) - private List archivedRecordIds; - - public static final String SERIALIZED_NAME_FIELD_MAP = "fieldMap"; - @SerializedName(SERIALIZED_NAME_FIELD_MAP) - private Map fieldMap = new HashMap<>(); - - public static final String SERIALIZED_NAME_VIEWS = "views"; - @SerializedName(SERIALIZED_NAME_VIEWS) - private List views = new ArrayList<>(); - - public static final String SERIALIZED_NAME_WIDGET_PANELS = "widgetPanels"; - @SerializedName(SERIALIZED_NAME_WIDGET_PANELS) - private List widgetPanels; - - public DatasheetMetaSO() { - } - - public DatasheetMetaSO archivedRecordIds(List archivedRecordIds) { - - this.archivedRecordIds = archivedRecordIds; - return this; - } - - public DatasheetMetaSO addArchivedRecordIdsItem(String archivedRecordIdsItem) { - if (this.archivedRecordIds == null) { - this.archivedRecordIds = new ArrayList<>(); - } - this.archivedRecordIds.add(archivedRecordIdsItem); - return this; - } - - /** - * Get archivedRecordIds - * @return archivedRecordIds - **/ - @javax.annotation.Nullable - public List getArchivedRecordIds() { - return archivedRecordIds; - } - - - public void setArchivedRecordIds(List archivedRecordIds) { - this.archivedRecordIds = archivedRecordIds; - } - - - public DatasheetMetaSO fieldMap(Map fieldMap) { - - this.fieldMap = fieldMap; - return this; - } - - public DatasheetMetaSO putFieldMapItem(String key, FieldSO fieldMapItem) { - if (this.fieldMap == null) { - this.fieldMap = new HashMap<>(); - } - this.fieldMap.put(key, fieldMapItem); - return this; - } - - /** - * Get fieldMap - * @return fieldMap - **/ - @javax.annotation.Nonnull - public Map getFieldMap() { - return fieldMap; - } - - - public void setFieldMap(Map fieldMap) { - this.fieldMap = fieldMap; - } - - - public DatasheetMetaSO views(List views) { - - this.views = views; - return this; - } - - public DatasheetMetaSO addViewsItem(ViewSO viewsItem) { - if (this.views == null) { - this.views = new ArrayList<>(); - } - this.views.add(viewsItem); - return this; - } - - /** - * Get views - * @return views - **/ - @javax.annotation.Nonnull - public List getViews() { - return views; - } - - - public void setViews(List views) { - this.views = views; - } - - - public DatasheetMetaSO widgetPanels(List widgetPanels) { - - this.widgetPanels = widgetPanels; - return this; - } - - public DatasheetMetaSO addWidgetPanelsItem(WidgetPanelSO widgetPanelsItem) { - if (this.widgetPanels == null) { - this.widgetPanels = new ArrayList<>(); - } - this.widgetPanels.add(widgetPanelsItem); - return this; - } - - /** - * Get widgetPanels - * @return widgetPanels - **/ - @javax.annotation.Nullable - public List getWidgetPanels() { - return widgetPanels; - } - - - public void setWidgetPanels(List widgetPanels) { - this.widgetPanels = widgetPanels; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - DatasheetMetaSO datasheetMetaSO = (DatasheetMetaSO) o; - return Objects.equals(this.archivedRecordIds, datasheetMetaSO.archivedRecordIds) && - Objects.equals(this.fieldMap, datasheetMetaSO.fieldMap) && - Objects.equals(this.views, datasheetMetaSO.views) && - Objects.equals(this.widgetPanels, datasheetMetaSO.widgetPanels); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(archivedRecordIds, fieldMap, views, widgetPanels); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class DatasheetMetaSO {\n"); - sb.append(" archivedRecordIds: ").append(toIndentedString(archivedRecordIds)).append("\n"); - sb.append(" fieldMap: ").append(toIndentedString(fieldMap)).append("\n"); - sb.append(" views: ").append(toIndentedString(views)).append("\n"); - sb.append(" widgetPanels: ").append(toIndentedString(widgetPanels)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("archivedRecordIds"); - openapiFields.add("fieldMap"); - openapiFields.add("views"); - openapiFields.add("widgetPanels"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("fieldMap"); - openapiRequiredFields.add("views"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to DatasheetMetaSO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!DatasheetMetaSO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in DatasheetMetaSO is not found in the empty JSON string", DatasheetMetaSO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!DatasheetMetaSO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `DatasheetMetaSO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : DatasheetMetaSO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - // ensure the optional json data is an array if present - if (jsonObj.get("archivedRecordIds") != null && !jsonObj.get("archivedRecordIds").isJsonNull() && !jsonObj.get("archivedRecordIds").isJsonArray()) { - throw new IllegalArgumentException(String.format("Expected the field `archivedRecordIds` to be an array in the JSON string but got `%s`", jsonObj.get("archivedRecordIds").toString())); - } - // ensure the json data is an array - if (!jsonObj.get("views").isJsonArray()) { - throw new IllegalArgumentException(String.format("Expected the field `views` to be an array in the JSON string but got `%s`", jsonObj.get("views").toString())); - } - - JsonArray jsonArrayviews = jsonObj.getAsJsonArray("views"); - // validate the required field `views` (array) - for (int i = 0; i < jsonArrayviews.size(); i++) { - ViewSO.validateJsonElement(jsonArrayviews.get(i)); - }; - if (jsonObj.get("widgetPanels") != null && !jsonObj.get("widgetPanels").isJsonNull()) { - JsonArray jsonArraywidgetPanels = jsonObj.getAsJsonArray("widgetPanels"); - if (jsonArraywidgetPanels != null) { - // ensure the json data is an array - if (!jsonObj.get("widgetPanels").isJsonArray()) { - throw new IllegalArgumentException(String.format("Expected the field `widgetPanels` to be an array in the JSON string but got `%s`", jsonObj.get("widgetPanels").toString())); - } - - // validate the optional field `widgetPanels` (array) - for (int i = 0; i < jsonArraywidgetPanels.size(); i++) { - WidgetPanelSO.validateJsonElement(jsonArraywidgetPanels.get(i)); - }; - } - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!DatasheetMetaSO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'DatasheetMetaSO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(DatasheetMetaSO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, DatasheetMetaSO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public DatasheetMetaSO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of DatasheetMetaSO given an JSON string - * - * @param jsonString JSON string - * @return An instance of DatasheetMetaSO - * @throws IOException if the JSON string is invalid with respect to DatasheetMetaSO - */ - public static DatasheetMetaSO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, DatasheetMetaSO.class); - } - - /** - * Convert an instance of DatasheetMetaSO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/DatasheetPackSO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/DatasheetPackSO.java deleted file mode 100644 index 10bf8e6da6..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/DatasheetPackSO.java +++ /dev/null @@ -1,381 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.apitable.databusclient.model.BaseDatasheetPackSO; -import com.apitable.databusclient.model.DatasheetSnapshotSO; -import com.apitable.databusclient.model.NodeSO; -import com.apitable.databusclient.model.UnitSO; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * DatasheetPackSO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class DatasheetPackSO { - public static final String SERIALIZED_NAME_DATASHEET = "datasheet"; - @SerializedName(SERIALIZED_NAME_DATASHEET) - private NodeSO datasheet; - - public static final String SERIALIZED_NAME_FIELD_PERMISSION_MAP = "fieldPermissionMap"; - @SerializedName(SERIALIZED_NAME_FIELD_PERMISSION_MAP) - private Object fieldPermissionMap = null; - - public static final String SERIALIZED_NAME_FOREIGN_DATASHEET_MAP = "foreignDatasheetMap"; - @SerializedName(SERIALIZED_NAME_FOREIGN_DATASHEET_MAP) - private Map foreignDatasheetMap; - - public static final String SERIALIZED_NAME_SNAPSHOT = "snapshot"; - @SerializedName(SERIALIZED_NAME_SNAPSHOT) - private DatasheetSnapshotSO snapshot; - - public static final String SERIALIZED_NAME_UNITS = "units"; - @SerializedName(SERIALIZED_NAME_UNITS) - private List units; - - public DatasheetPackSO() { - } - - public DatasheetPackSO datasheet(NodeSO datasheet) { - - this.datasheet = datasheet; - return this; - } - - /** - * Get datasheet - * @return datasheet - **/ - @javax.annotation.Nonnull - public NodeSO getDatasheet() { - return datasheet; - } - - - public void setDatasheet(NodeSO datasheet) { - this.datasheet = datasheet; - } - - - public DatasheetPackSO fieldPermissionMap(Object fieldPermissionMap) { - - this.fieldPermissionMap = fieldPermissionMap; - return this; - } - - /** - * Get fieldPermissionMap - * @return fieldPermissionMap - **/ - @javax.annotation.Nullable - public Object getFieldPermissionMap() { - return fieldPermissionMap; - } - - - public void setFieldPermissionMap(Object fieldPermissionMap) { - this.fieldPermissionMap = fieldPermissionMap; - } - - - public DatasheetPackSO foreignDatasheetMap(Map foreignDatasheetMap) { - - this.foreignDatasheetMap = foreignDatasheetMap; - return this; - } - - public DatasheetPackSO putForeignDatasheetMapItem(String key, BaseDatasheetPackSO foreignDatasheetMapItem) { - if (this.foreignDatasheetMap == null) { - this.foreignDatasheetMap = new HashMap<>(); - } - this.foreignDatasheetMap.put(key, foreignDatasheetMapItem); - return this; - } - - /** - * Get foreignDatasheetMap - * @return foreignDatasheetMap - **/ - @javax.annotation.Nullable - public Map getForeignDatasheetMap() { - return foreignDatasheetMap; - } - - - public void setForeignDatasheetMap(Map foreignDatasheetMap) { - this.foreignDatasheetMap = foreignDatasheetMap; - } - - - public DatasheetPackSO snapshot(DatasheetSnapshotSO snapshot) { - - this.snapshot = snapshot; - return this; - } - - /** - * Get snapshot - * @return snapshot - **/ - @javax.annotation.Nonnull - public DatasheetSnapshotSO getSnapshot() { - return snapshot; - } - - - public void setSnapshot(DatasheetSnapshotSO snapshot) { - this.snapshot = snapshot; - } - - - public DatasheetPackSO units(List units) { - - this.units = units; - return this; - } - - public DatasheetPackSO addUnitsItem(UnitSO unitsItem) { - if (this.units == null) { - this.units = new ArrayList<>(); - } - this.units.add(unitsItem); - return this; - } - - /** - * Get units - * @return units - **/ - @javax.annotation.Nullable - public List getUnits() { - return units; - } - - - public void setUnits(List units) { - this.units = units; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - DatasheetPackSO datasheetPackSO = (DatasheetPackSO) o; - return Objects.equals(this.datasheet, datasheetPackSO.datasheet) && - Objects.equals(this.fieldPermissionMap, datasheetPackSO.fieldPermissionMap) && - Objects.equals(this.foreignDatasheetMap, datasheetPackSO.foreignDatasheetMap) && - Objects.equals(this.snapshot, datasheetPackSO.snapshot) && - Objects.equals(this.units, datasheetPackSO.units); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(datasheet, fieldPermissionMap, foreignDatasheetMap, snapshot, units); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class DatasheetPackSO {\n"); - sb.append(" datasheet: ").append(toIndentedString(datasheet)).append("\n"); - sb.append(" fieldPermissionMap: ").append(toIndentedString(fieldPermissionMap)).append("\n"); - sb.append(" foreignDatasheetMap: ").append(toIndentedString(foreignDatasheetMap)).append("\n"); - sb.append(" snapshot: ").append(toIndentedString(snapshot)).append("\n"); - sb.append(" units: ").append(toIndentedString(units)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("datasheet"); - openapiFields.add("fieldPermissionMap"); - openapiFields.add("foreignDatasheetMap"); - openapiFields.add("snapshot"); - openapiFields.add("units"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("datasheet"); - openapiRequiredFields.add("snapshot"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to DatasheetPackSO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!DatasheetPackSO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in DatasheetPackSO is not found in the empty JSON string", DatasheetPackSO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!DatasheetPackSO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `DatasheetPackSO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : DatasheetPackSO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - // validate the required field `datasheet` - NodeSO.validateJsonElement(jsonObj.get("datasheet")); - // validate the required field `snapshot` - DatasheetSnapshotSO.validateJsonElement(jsonObj.get("snapshot")); - if (jsonObj.get("units") != null && !jsonObj.get("units").isJsonNull()) { - JsonArray jsonArrayunits = jsonObj.getAsJsonArray("units"); - if (jsonArrayunits != null) { - // ensure the json data is an array - if (!jsonObj.get("units").isJsonArray()) { - throw new IllegalArgumentException(String.format("Expected the field `units` to be an array in the JSON string but got `%s`", jsonObj.get("units").toString())); - } - - // validate the optional field `units` (array) - for (int i = 0; i < jsonArrayunits.size(); i++) { - UnitSO.validateJsonElement(jsonArrayunits.get(i)); - }; - } - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!DatasheetPackSO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'DatasheetPackSO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(DatasheetPackSO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, DatasheetPackSO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public DatasheetPackSO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of DatasheetPackSO given an JSON string - * - * @param jsonString JSON string - * @return An instance of DatasheetPackSO - * @throws IOException if the JSON string is invalid with respect to DatasheetPackSO - */ - public static DatasheetPackSO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, DatasheetPackSO.class); - } - - /** - * Convert an instance of DatasheetPackSO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/DatasheetSnapshotSO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/DatasheetSnapshotSO.java deleted file mode 100644 index 5aaccee8e4..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/DatasheetSnapshotSO.java +++ /dev/null @@ -1,289 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.apitable.databusclient.model.DatasheetMetaSO; -import com.apitable.databusclient.model.RecordSO; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * DatasheetSnapshotSO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class DatasheetSnapshotSO { - public static final String SERIALIZED_NAME_DATASHEET_ID = "datasheetId"; - @SerializedName(SERIALIZED_NAME_DATASHEET_ID) - private String datasheetId; - - public static final String SERIALIZED_NAME_META = "meta"; - @SerializedName(SERIALIZED_NAME_META) - private DatasheetMetaSO meta; - - public static final String SERIALIZED_NAME_RECORD_MAP = "recordMap"; - @SerializedName(SERIALIZED_NAME_RECORD_MAP) - private Map recordMap = new HashMap<>(); - - public DatasheetSnapshotSO() { - } - - public DatasheetSnapshotSO datasheetId(String datasheetId) { - - this.datasheetId = datasheetId; - return this; - } - - /** - * Get datasheetId - * @return datasheetId - **/ - @javax.annotation.Nonnull - public String getDatasheetId() { - return datasheetId; - } - - - public void setDatasheetId(String datasheetId) { - this.datasheetId = datasheetId; - } - - - public DatasheetSnapshotSO meta(DatasheetMetaSO meta) { - - this.meta = meta; - return this; - } - - /** - * Get meta - * @return meta - **/ - @javax.annotation.Nonnull - public DatasheetMetaSO getMeta() { - return meta; - } - - - public void setMeta(DatasheetMetaSO meta) { - this.meta = meta; - } - - - public DatasheetSnapshotSO recordMap(Map recordMap) { - - this.recordMap = recordMap; - return this; - } - - public DatasheetSnapshotSO putRecordMapItem(String key, RecordSO recordMapItem) { - if (this.recordMap == null) { - this.recordMap = new HashMap<>(); - } - this.recordMap.put(key, recordMapItem); - return this; - } - - /** - * Get recordMap - * @return recordMap - **/ - @javax.annotation.Nonnull - public Map getRecordMap() { - return recordMap; - } - - - public void setRecordMap(Map recordMap) { - this.recordMap = recordMap; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - DatasheetSnapshotSO datasheetSnapshotSO = (DatasheetSnapshotSO) o; - return Objects.equals(this.datasheetId, datasheetSnapshotSO.datasheetId) && - Objects.equals(this.meta, datasheetSnapshotSO.meta) && - Objects.equals(this.recordMap, datasheetSnapshotSO.recordMap); - } - - @Override - public int hashCode() { - return Objects.hash(datasheetId, meta, recordMap); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class DatasheetSnapshotSO {\n"); - sb.append(" datasheetId: ").append(toIndentedString(datasheetId)).append("\n"); - sb.append(" meta: ").append(toIndentedString(meta)).append("\n"); - sb.append(" recordMap: ").append(toIndentedString(recordMap)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("datasheetId"); - openapiFields.add("meta"); - openapiFields.add("recordMap"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("datasheetId"); - openapiRequiredFields.add("meta"); - openapiRequiredFields.add("recordMap"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to DatasheetSnapshotSO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!DatasheetSnapshotSO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in DatasheetSnapshotSO is not found in the empty JSON string", DatasheetSnapshotSO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!DatasheetSnapshotSO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `DatasheetSnapshotSO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : DatasheetSnapshotSO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if (!jsonObj.get("datasheetId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `datasheetId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("datasheetId").toString())); - } - // validate the required field `meta` - DatasheetMetaSO.validateJsonElement(jsonObj.get("meta")); - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!DatasheetSnapshotSO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'DatasheetSnapshotSO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(DatasheetSnapshotSO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, DatasheetSnapshotSO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public DatasheetSnapshotSO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of DatasheetSnapshotSO given an JSON string - * - * @param jsonString JSON string - * @return An instance of DatasheetSnapshotSO - * @throws IOException if the JSON string is invalid with respect to DatasheetSnapshotSO - */ - public static DatasheetSnapshotSO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, DatasheetSnapshotSO.class); - } - - /** - * Convert an instance of DatasheetSnapshotSO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/DocumentOperationRO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/DocumentOperationRO.java deleted file mode 100644 index 5c6f725635..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/DocumentOperationRO.java +++ /dev/null @@ -1,288 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.File; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * DocumentOperationRO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class DocumentOperationRO { - public static final String SERIALIZED_NAME_CREATED_BY = "created_by"; - @SerializedName(SERIALIZED_NAME_CREATED_BY) - private Long createdBy; - - public static final String SERIALIZED_NAME_SPACE_ID = "space_id"; - @SerializedName(SERIALIZED_NAME_SPACE_ID) - private String spaceId; - - public static final String SERIALIZED_NAME_UPDATE_DATA = "update_data"; - @SerializedName(SERIALIZED_NAME_UPDATE_DATA) - private File updateData; - - public DocumentOperationRO() { - } - - public DocumentOperationRO createdBy(Long createdBy) { - - this.createdBy = createdBy; - return this; - } - - /** - * Get createdBy - * minimum: 0 - * @return createdBy - **/ - @javax.annotation.Nullable - public Long getCreatedBy() { - return createdBy; - } - - - public void setCreatedBy(Long createdBy) { - this.createdBy = createdBy; - } - - - public DocumentOperationRO spaceId(String spaceId) { - - this.spaceId = spaceId; - return this; - } - - /** - * Get spaceId - * @return spaceId - **/ - @javax.annotation.Nonnull - public String getSpaceId() { - return spaceId; - } - - - public void setSpaceId(String spaceId) { - this.spaceId = spaceId; - } - - - public DocumentOperationRO updateData(File updateData) { - - this.updateData = updateData; - return this; - } - - /** - * Get updateData - * @return updateData - **/ - @javax.annotation.Nonnull - public File getUpdateData() { - return updateData; - } - - - public void setUpdateData(File updateData) { - this.updateData = updateData; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - DocumentOperationRO documentOperationRO = (DocumentOperationRO) o; - return Objects.equals(this.createdBy, documentOperationRO.createdBy) && - Objects.equals(this.spaceId, documentOperationRO.spaceId) && - Objects.equals(this.updateData, documentOperationRO.updateData); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(createdBy, spaceId, updateData); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class DocumentOperationRO {\n"); - sb.append(" createdBy: ").append(toIndentedString(createdBy)).append("\n"); - sb.append(" spaceId: ").append(toIndentedString(spaceId)).append("\n"); - sb.append(" updateData: ").append(toIndentedString(updateData)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("created_by"); - openapiFields.add("space_id"); - openapiFields.add("update_data"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("space_id"); - openapiRequiredFields.add("update_data"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to DocumentOperationRO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!DocumentOperationRO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in DocumentOperationRO is not found in the empty JSON string", DocumentOperationRO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!DocumentOperationRO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `DocumentOperationRO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : DocumentOperationRO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if (!jsonObj.get("space_id").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `space_id` to be a primitive type in the JSON string but got `%s`", jsonObj.get("space_id").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!DocumentOperationRO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'DocumentOperationRO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(DocumentOperationRO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, DocumentOperationRO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public DocumentOperationRO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of DocumentOperationRO given an JSON string - * - * @param jsonString JSON string - * @return An instance of DocumentOperationRO - * @throws IOException if the JSON string is invalid with respect to DocumentOperationRO - */ - public static DocumentOperationRO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, DocumentOperationRO.class); - } - - /** - * Convert an instance of DocumentOperationRO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/DocumentRO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/DocumentRO.java deleted file mode 100644 index 76052e79e0..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/DocumentRO.java +++ /dev/null @@ -1,412 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.File; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * DocumentRO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class DocumentRO { - public static final String SERIALIZED_NAME_DATA = "data"; - @SerializedName(SERIALIZED_NAME_DATA) - private File data; - - public static final String SERIALIZED_NAME_DOCUMENT_TYPE = "document_type"; - @SerializedName(SERIALIZED_NAME_DOCUMENT_TYPE) - private Integer documentType; - - public static final String SERIALIZED_NAME_PROPS = "props"; - @SerializedName(SERIALIZED_NAME_PROPS) - private String props; - - public static final String SERIALIZED_NAME_RESOURCE_ID = "resource_id"; - @SerializedName(SERIALIZED_NAME_RESOURCE_ID) - private String resourceId; - - public static final String SERIALIZED_NAME_SPACE_ID = "space_id"; - @SerializedName(SERIALIZED_NAME_SPACE_ID) - private String spaceId; - - public static final String SERIALIZED_NAME_TITLE = "title"; - @SerializedName(SERIALIZED_NAME_TITLE) - private String title; - - public static final String SERIALIZED_NAME_UPDATED_BY = "updated_by"; - @SerializedName(SERIALIZED_NAME_UPDATED_BY) - private Long updatedBy; - - public DocumentRO() { - } - - public DocumentRO data(File data) { - - this.data = data; - return this; - } - - /** - * Get data - * @return data - **/ - @javax.annotation.Nonnull - public File getData() { - return data; - } - - - public void setData(File data) { - this.data = data; - } - - - public DocumentRO documentType(Integer documentType) { - - this.documentType = documentType; - return this; - } - - /** - * Get documentType - * minimum: 0 - * @return documentType - **/ - @javax.annotation.Nonnull - public Integer getDocumentType() { - return documentType; - } - - - public void setDocumentType(Integer documentType) { - this.documentType = documentType; - } - - - public DocumentRO props(String props) { - - this.props = props; - return this; - } - - /** - * Get props - * @return props - **/ - @javax.annotation.Nullable - public String getProps() { - return props; - } - - - public void setProps(String props) { - this.props = props; - } - - - public DocumentRO resourceId(String resourceId) { - - this.resourceId = resourceId; - return this; - } - - /** - * Get resourceId - * @return resourceId - **/ - @javax.annotation.Nonnull - public String getResourceId() { - return resourceId; - } - - - public void setResourceId(String resourceId) { - this.resourceId = resourceId; - } - - - public DocumentRO spaceId(String spaceId) { - - this.spaceId = spaceId; - return this; - } - - /** - * Get spaceId - * @return spaceId - **/ - @javax.annotation.Nonnull - public String getSpaceId() { - return spaceId; - } - - - public void setSpaceId(String spaceId) { - this.spaceId = spaceId; - } - - - public DocumentRO title(String title) { - - this.title = title; - return this; - } - - /** - * Get title - * @return title - **/ - @javax.annotation.Nullable - public String getTitle() { - return title; - } - - - public void setTitle(String title) { - this.title = title; - } - - - public DocumentRO updatedBy(Long updatedBy) { - - this.updatedBy = updatedBy; - return this; - } - - /** - * Get updatedBy - * minimum: 0 - * @return updatedBy - **/ - @javax.annotation.Nullable - public Long getUpdatedBy() { - return updatedBy; - } - - - public void setUpdatedBy(Long updatedBy) { - this.updatedBy = updatedBy; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - DocumentRO documentRO = (DocumentRO) o; - return Objects.equals(this.data, documentRO.data) && - Objects.equals(this.documentType, documentRO.documentType) && - Objects.equals(this.props, documentRO.props) && - Objects.equals(this.resourceId, documentRO.resourceId) && - Objects.equals(this.spaceId, documentRO.spaceId) && - Objects.equals(this.title, documentRO.title) && - Objects.equals(this.updatedBy, documentRO.updatedBy); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(data, documentType, props, resourceId, spaceId, title, updatedBy); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class DocumentRO {\n"); - sb.append(" data: ").append(toIndentedString(data)).append("\n"); - sb.append(" documentType: ").append(toIndentedString(documentType)).append("\n"); - sb.append(" props: ").append(toIndentedString(props)).append("\n"); - sb.append(" resourceId: ").append(toIndentedString(resourceId)).append("\n"); - sb.append(" spaceId: ").append(toIndentedString(spaceId)).append("\n"); - sb.append(" title: ").append(toIndentedString(title)).append("\n"); - sb.append(" updatedBy: ").append(toIndentedString(updatedBy)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("data"); - openapiFields.add("document_type"); - openapiFields.add("props"); - openapiFields.add("resource_id"); - openapiFields.add("space_id"); - openapiFields.add("title"); - openapiFields.add("updated_by"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("data"); - openapiRequiredFields.add("document_type"); - openapiRequiredFields.add("resource_id"); - openapiRequiredFields.add("space_id"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to DocumentRO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!DocumentRO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in DocumentRO is not found in the empty JSON string", DocumentRO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!DocumentRO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `DocumentRO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : DocumentRO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if ((jsonObj.get("props") != null && !jsonObj.get("props").isJsonNull()) && !jsonObj.get("props").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `props` to be a primitive type in the JSON string but got `%s`", jsonObj.get("props").toString())); - } - if (!jsonObj.get("resource_id").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `resource_id` to be a primitive type in the JSON string but got `%s`", jsonObj.get("resource_id").toString())); - } - if (!jsonObj.get("space_id").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `space_id` to be a primitive type in the JSON string but got `%s`", jsonObj.get("space_id").toString())); - } - if ((jsonObj.get("title") != null && !jsonObj.get("title").isJsonNull()) && !jsonObj.get("title").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `title` to be a primitive type in the JSON string but got `%s`", jsonObj.get("title").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!DocumentRO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'DocumentRO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(DocumentRO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, DocumentRO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public DocumentRO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of DocumentRO given an JSON string - * - * @param jsonString JSON string - * @return An instance of DocumentRO - * @throws IOException if the JSON string is invalid with respect to DocumentRO - */ - public static DocumentRO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, DocumentRO.class); - } - - /** - * Convert an instance of DocumentRO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/FieldExtraMapValue.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/FieldExtraMapValue.java deleted file mode 100644 index 98d96ee1a6..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/FieldExtraMapValue.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.apitable.databusclient.model.RecordAlarm; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * FieldExtraMapValue - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class FieldExtraMapValue { - public static final String SERIALIZED_NAME_ALARM = "alarm"; - @SerializedName(SERIALIZED_NAME_ALARM) - private RecordAlarm alarm; - - public FieldExtraMapValue() { - } - - public FieldExtraMapValue alarm(RecordAlarm alarm) { - - this.alarm = alarm; - return this; - } - - /** - * Get alarm - * @return alarm - **/ - @javax.annotation.Nullable - public RecordAlarm getAlarm() { - return alarm; - } - - - public void setAlarm(RecordAlarm alarm) { - this.alarm = alarm; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - FieldExtraMapValue fieldExtraMapValue = (FieldExtraMapValue) o; - return Objects.equals(this.alarm, fieldExtraMapValue.alarm); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(alarm); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class FieldExtraMapValue {\n"); - sb.append(" alarm: ").append(toIndentedString(alarm)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("alarm"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to FieldExtraMapValue - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!FieldExtraMapValue.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in FieldExtraMapValue is not found in the empty JSON string", FieldExtraMapValue.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!FieldExtraMapValue.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `FieldExtraMapValue` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - // validate the optional field `alarm` - if (jsonObj.get("alarm") != null && !jsonObj.get("alarm").isJsonNull()) { - RecordAlarm.validateJsonElement(jsonObj.get("alarm")); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!FieldExtraMapValue.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'FieldExtraMapValue' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(FieldExtraMapValue.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, FieldExtraMapValue value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public FieldExtraMapValue read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of FieldExtraMapValue given an JSON string - * - * @param jsonString JSON string - * @return An instance of FieldExtraMapValue - * @throws IOException if the JSON string is invalid with respect to FieldExtraMapValue - */ - public static FieldExtraMapValue fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, FieldExtraMapValue.class); - } - - /** - * Convert an instance of FieldExtraMapValue to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/FieldSO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/FieldSO.java deleted file mode 100644 index 2c7a92a14d..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/FieldSO.java +++ /dev/null @@ -1,383 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.apitable.databusclient.model.FieldKindSO; -import com.apitable.databusclient.model.FieldPropertySO; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * FieldSO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class FieldSO { - public static final String SERIALIZED_NAME_DESC = "desc"; - @SerializedName(SERIALIZED_NAME_DESC) - private String desc; - - public static final String SERIALIZED_NAME_ID = "id"; - @SerializedName(SERIALIZED_NAME_ID) - private String id; - - public static final String SERIALIZED_NAME_NAME = "name"; - @SerializedName(SERIALIZED_NAME_NAME) - private String name; - - public static final String SERIALIZED_NAME_PROPERTY = "property"; - @SerializedName(SERIALIZED_NAME_PROPERTY) - private FieldPropertySO property; - - public static final String SERIALIZED_NAME_REQUIRED = "required"; - @SerializedName(SERIALIZED_NAME_REQUIRED) - private Boolean required; - - public static final String SERIALIZED_NAME_TYPE = "type"; - @SerializedName(SERIALIZED_NAME_TYPE) - private FieldKindSO type; - - public FieldSO() { - } - - public FieldSO desc(String desc) { - - this.desc = desc; - return this; - } - - /** - * Get desc - * @return desc - **/ - @javax.annotation.Nullable - public String getDesc() { - return desc; - } - - - public void setDesc(String desc) { - this.desc = desc; - } - - - public FieldSO id(String id) { - - this.id = id; - return this; - } - - /** - * Get id - * @return id - **/ - @javax.annotation.Nonnull - public String getId() { - return id; - } - - - public void setId(String id) { - this.id = id; - } - - - public FieldSO name(String name) { - - this.name = name; - return this; - } - - /** - * Get name - * @return name - **/ - @javax.annotation.Nonnull - public String getName() { - return name; - } - - - public void setName(String name) { - this.name = name; - } - - - public FieldSO property(FieldPropertySO property) { - - this.property = property; - return this; - } - - /** - * Get property - * @return property - **/ - @javax.annotation.Nullable - public FieldPropertySO getProperty() { - return property; - } - - - public void setProperty(FieldPropertySO property) { - this.property = property; - } - - - public FieldSO required(Boolean required) { - - this.required = required; - return this; - } - - /** - * Get required - * @return required - **/ - @javax.annotation.Nullable - public Boolean getRequired() { - return required; - } - - - public void setRequired(Boolean required) { - this.required = required; - } - - - public FieldSO type(FieldKindSO type) { - - this.type = type; - return this; - } - - /** - * Get type - * @return type - **/ - @javax.annotation.Nonnull - public FieldKindSO getType() { - return type; - } - - - public void setType(FieldKindSO type) { - this.type = type; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - FieldSO fieldSO = (FieldSO) o; - return Objects.equals(this.desc, fieldSO.desc) && - Objects.equals(this.id, fieldSO.id) && - Objects.equals(this.name, fieldSO.name) && - Objects.equals(this.property, fieldSO.property) && - Objects.equals(this.required, fieldSO.required) && - Objects.equals(this.type, fieldSO.type); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(desc, id, name, property, required, type); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class FieldSO {\n"); - sb.append(" desc: ").append(toIndentedString(desc)).append("\n"); - sb.append(" id: ").append(toIndentedString(id)).append("\n"); - sb.append(" name: ").append(toIndentedString(name)).append("\n"); - sb.append(" property: ").append(toIndentedString(property)).append("\n"); - sb.append(" required: ").append(toIndentedString(required)).append("\n"); - sb.append(" type: ").append(toIndentedString(type)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("desc"); - openapiFields.add("id"); - openapiFields.add("name"); - openapiFields.add("property"); - openapiFields.add("required"); - openapiFields.add("type"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("id"); - openapiRequiredFields.add("name"); - openapiRequiredFields.add("type"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to FieldSO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!FieldSO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in FieldSO is not found in the empty JSON string", FieldSO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!FieldSO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `FieldSO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : FieldSO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if ((jsonObj.get("desc") != null && !jsonObj.get("desc").isJsonNull()) && !jsonObj.get("desc").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `desc` to be a primitive type in the JSON string but got `%s`", jsonObj.get("desc").toString())); - } - if (!jsonObj.get("id").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `id` to be a primitive type in the JSON string but got `%s`", jsonObj.get("id").toString())); - } - if (!jsonObj.get("name").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `name` to be a primitive type in the JSON string but got `%s`", jsonObj.get("name").toString())); - } - // validate the optional field `property` - if (jsonObj.get("property") != null && !jsonObj.get("property").isJsonNull()) { - FieldPropertySO.validateJsonElement(jsonObj.get("property")); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!FieldSO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'FieldSO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(FieldSO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, FieldSO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public FieldSO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of FieldSO given an JSON string - * - * @param jsonString JSON string - * @return An instance of FieldSO - * @throws IOException if the JSON string is invalid with respect to FieldSO - */ - public static FieldSO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, FieldSO.class); - } - - /** - * Convert an instance of FieldSO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/FieldUpdateRO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/FieldUpdateRO.java deleted file mode 100644 index 85601781f1..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/FieldUpdateRO.java +++ /dev/null @@ -1,256 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * FieldUpdateRO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class FieldUpdateRO { - public static final String SERIALIZED_NAME_FIELDS = "fields"; - @SerializedName(SERIALIZED_NAME_FIELDS) - private Map fields = new HashMap<>(); - - public static final String SERIALIZED_NAME_RECORD_ID = "recordId"; - @SerializedName(SERIALIZED_NAME_RECORD_ID) - private String recordId; - - public FieldUpdateRO() { - } - - public FieldUpdateRO fields(Map fields) { - - this.fields = fields; - return this; - } - - public FieldUpdateRO putFieldsItem(String key, Object fieldsItem) { - if (this.fields == null) { - this.fields = new HashMap<>(); - } - this.fields.put(key, fieldsItem); - return this; - } - - /** - * Get fields - * @return fields - **/ - @javax.annotation.Nonnull - public Map getFields() { - return fields; - } - - - public void setFields(Map fields) { - this.fields = fields; - } - - - public FieldUpdateRO recordId(String recordId) { - - this.recordId = recordId; - return this; - } - - /** - * Get recordId - * @return recordId - **/ - @javax.annotation.Nonnull - public String getRecordId() { - return recordId; - } - - - public void setRecordId(String recordId) { - this.recordId = recordId; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - FieldUpdateRO fieldUpdateRO = (FieldUpdateRO) o; - return Objects.equals(this.fields, fieldUpdateRO.fields) && - Objects.equals(this.recordId, fieldUpdateRO.recordId); - } - - @Override - public int hashCode() { - return Objects.hash(fields, recordId); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class FieldUpdateRO {\n"); - sb.append(" fields: ").append(toIndentedString(fields)).append("\n"); - sb.append(" recordId: ").append(toIndentedString(recordId)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("fields"); - openapiFields.add("recordId"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("fields"); - openapiRequiredFields.add("recordId"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to FieldUpdateRO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!FieldUpdateRO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in FieldUpdateRO is not found in the empty JSON string", FieldUpdateRO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!FieldUpdateRO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `FieldUpdateRO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : FieldUpdateRO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if (!jsonObj.get("recordId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `recordId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("recordId").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!FieldUpdateRO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'FieldUpdateRO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(FieldUpdateRO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, FieldUpdateRO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public FieldUpdateRO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of FieldUpdateRO given an JSON string - * - * @param jsonString JSON string - * @return An instance of FieldUpdateRO - * @throws IOException if the JSON string is invalid with respect to FieldUpdateRO - */ - public static FieldUpdateRO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, FieldUpdateRO.class); - } - - /** - * Convert an instance of FieldUpdateRO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/FieldUpdatedValue.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/FieldUpdatedValue.java deleted file mode 100644 index adc7f4b2ed..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/FieldUpdatedValue.java +++ /dev/null @@ -1,279 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * FieldUpdatedValue - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class FieldUpdatedValue { - public static final String SERIALIZED_NAME_AT = "at"; - @SerializedName(SERIALIZED_NAME_AT) - private Long at; - - public static final String SERIALIZED_NAME_AUTO_NUMBER = "autoNumber"; - @SerializedName(SERIALIZED_NAME_AUTO_NUMBER) - private Long autoNumber; - - public static final String SERIALIZED_NAME_BY = "by"; - @SerializedName(SERIALIZED_NAME_BY) - private String by; - - public FieldUpdatedValue() { - } - - public FieldUpdatedValue at(Long at) { - - this.at = at; - return this; - } - - /** - * Get at - * minimum: 0 - * @return at - **/ - @javax.annotation.Nullable - public Long getAt() { - return at; - } - - - public void setAt(Long at) { - this.at = at; - } - - - public FieldUpdatedValue autoNumber(Long autoNumber) { - - this.autoNumber = autoNumber; - return this; - } - - /** - * Get autoNumber - * minimum: 0 - * @return autoNumber - **/ - @javax.annotation.Nullable - public Long getAutoNumber() { - return autoNumber; - } - - - public void setAutoNumber(Long autoNumber) { - this.autoNumber = autoNumber; - } - - - public FieldUpdatedValue by(String by) { - - this.by = by; - return this; - } - - /** - * Get by - * @return by - **/ - @javax.annotation.Nullable - public String getBy() { - return by; - } - - - public void setBy(String by) { - this.by = by; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - FieldUpdatedValue fieldUpdatedValue = (FieldUpdatedValue) o; - return Objects.equals(this.at, fieldUpdatedValue.at) && - Objects.equals(this.autoNumber, fieldUpdatedValue.autoNumber) && - Objects.equals(this.by, fieldUpdatedValue.by); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(at, autoNumber, by); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class FieldUpdatedValue {\n"); - sb.append(" at: ").append(toIndentedString(at)).append("\n"); - sb.append(" autoNumber: ").append(toIndentedString(autoNumber)).append("\n"); - sb.append(" by: ").append(toIndentedString(by)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("at"); - openapiFields.add("autoNumber"); - openapiFields.add("by"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to FieldUpdatedValue - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!FieldUpdatedValue.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in FieldUpdatedValue is not found in the empty JSON string", FieldUpdatedValue.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!FieldUpdatedValue.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `FieldUpdatedValue` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if ((jsonObj.get("by") != null && !jsonObj.get("by").isJsonNull()) && !jsonObj.get("by").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `by` to be a primitive type in the JSON string but got `%s`", jsonObj.get("by").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!FieldUpdatedValue.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'FieldUpdatedValue' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(FieldUpdatedValue.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, FieldUpdatedValue value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public FieldUpdatedValue read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of FieldUpdatedValue given an JSON string - * - * @param jsonString JSON string - * @return An instance of FieldUpdatedValue - * @throws IOException if the JSON string is invalid with respect to FieldUpdatedValue - */ - public static FieldUpdatedValue fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, FieldUpdatedValue.class); - } - - /** - * Convert an instance of FieldUpdatedValue to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/GanttColorOption.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/GanttColorOption.java deleted file mode 100644 index 3253ecc968..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/GanttColorOption.java +++ /dev/null @@ -1,286 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.apitable.databusclient.model.GanttColorType; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * GanttColorOption - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class GanttColorOption { - public static final String SERIALIZED_NAME_COLOR = "color"; - @SerializedName(SERIALIZED_NAME_COLOR) - private Integer color; - - public static final String SERIALIZED_NAME_FIELD_ID = "field_id"; - @SerializedName(SERIALIZED_NAME_FIELD_ID) - private String fieldId; - - public static final String SERIALIZED_NAME_TYPE = "type"; - @SerializedName(SERIALIZED_NAME_TYPE) - private GanttColorType type; - - public GanttColorOption() { - } - - public GanttColorOption color(Integer color) { - - this.color = color; - return this; - } - - /** - * Get color - * @return color - **/ - @javax.annotation.Nullable - public Integer getColor() { - return color; - } - - - public void setColor(Integer color) { - this.color = color; - } - - - public GanttColorOption fieldId(String fieldId) { - - this.fieldId = fieldId; - return this; - } - - /** - * Get fieldId - * @return fieldId - **/ - @javax.annotation.Nullable - public String getFieldId() { - return fieldId; - } - - - public void setFieldId(String fieldId) { - this.fieldId = fieldId; - } - - - public GanttColorOption type(GanttColorType type) { - - this.type = type; - return this; - } - - /** - * Get type - * @return type - **/ - @javax.annotation.Nonnull - public GanttColorType getType() { - return type; - } - - - public void setType(GanttColorType type) { - this.type = type; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - GanttColorOption ganttColorOption = (GanttColorOption) o; - return Objects.equals(this.color, ganttColorOption.color) && - Objects.equals(this.fieldId, ganttColorOption.fieldId) && - Objects.equals(this.type, ganttColorOption.type); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(color, fieldId, type); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class GanttColorOption {\n"); - sb.append(" color: ").append(toIndentedString(color)).append("\n"); - sb.append(" fieldId: ").append(toIndentedString(fieldId)).append("\n"); - sb.append(" type: ").append(toIndentedString(type)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("color"); - openapiFields.add("field_id"); - openapiFields.add("type"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("type"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to GanttColorOption - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!GanttColorOption.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in GanttColorOption is not found in the empty JSON string", GanttColorOption.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!GanttColorOption.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `GanttColorOption` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : GanttColorOption.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if ((jsonObj.get("field_id") != null && !jsonObj.get("field_id").isJsonNull()) && !jsonObj.get("field_id").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `field_id` to be a primitive type in the JSON string but got `%s`", jsonObj.get("field_id").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!GanttColorOption.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'GanttColorOption' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(GanttColorOption.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, GanttColorOption value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public GanttColorOption read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of GanttColorOption given an JSON string - * - * @param jsonString JSON string - * @return An instance of GanttColorOption - * @throws IOException if the JSON string is invalid with respect to GanttColorOption - */ - public static GanttColorOption fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, GanttColorOption.class); - } - - /** - * Convert an instance of GanttColorOption to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/IFilterCondition.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/IFilterCondition.java deleted file mode 100644 index 3325d73da0..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/IFilterCondition.java +++ /dev/null @@ -1,349 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.apitable.databusclient.model.FOperator; -import com.apitable.databusclient.model.FieldKindSO; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * IFilterCondition - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class IFilterCondition { - public static final String SERIALIZED_NAME_CONDITION_ID = "conditionId"; - @SerializedName(SERIALIZED_NAME_CONDITION_ID) - private String conditionId; - - public static final String SERIALIZED_NAME_FIELD_ID = "fieldId"; - @SerializedName(SERIALIZED_NAME_FIELD_ID) - private String fieldId; - - public static final String SERIALIZED_NAME_FIELD_TYPE = "fieldType"; - @SerializedName(SERIALIZED_NAME_FIELD_TYPE) - private FieldKindSO fieldType; - - public static final String SERIALIZED_NAME_OPERATOR = "operator"; - @SerializedName(SERIALIZED_NAME_OPERATOR) - private FOperator operator; - - public static final String SERIALIZED_NAME_VALUE = "value"; - @SerializedName(SERIALIZED_NAME_VALUE) - private Object value = null; - - public IFilterCondition() { - } - - public IFilterCondition conditionId(String conditionId) { - - this.conditionId = conditionId; - return this; - } - - /** - * Get conditionId - * @return conditionId - **/ - @javax.annotation.Nonnull - public String getConditionId() { - return conditionId; - } - - - public void setConditionId(String conditionId) { - this.conditionId = conditionId; - } - - - public IFilterCondition fieldId(String fieldId) { - - this.fieldId = fieldId; - return this; - } - - /** - * Get fieldId - * @return fieldId - **/ - @javax.annotation.Nonnull - public String getFieldId() { - return fieldId; - } - - - public void setFieldId(String fieldId) { - this.fieldId = fieldId; - } - - - public IFilterCondition fieldType(FieldKindSO fieldType) { - - this.fieldType = fieldType; - return this; - } - - /** - * Get fieldType - * @return fieldType - **/ - @javax.annotation.Nonnull - public FieldKindSO getFieldType() { - return fieldType; - } - - - public void setFieldType(FieldKindSO fieldType) { - this.fieldType = fieldType; - } - - - public IFilterCondition operator(FOperator operator) { - - this.operator = operator; - return this; - } - - /** - * Get operator - * @return operator - **/ - @javax.annotation.Nonnull - public FOperator getOperator() { - return operator; - } - - - public void setOperator(FOperator operator) { - this.operator = operator; - } - - - public IFilterCondition value(Object value) { - - this.value = value; - return this; - } - - /** - * Get value - * @return value - **/ - @javax.annotation.Nullable - public Object getValue() { - return value; - } - - - public void setValue(Object value) { - this.value = value; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - IFilterCondition ifilterCondition = (IFilterCondition) o; - return Objects.equals(this.conditionId, ifilterCondition.conditionId) && - Objects.equals(this.fieldId, ifilterCondition.fieldId) && - Objects.equals(this.fieldType, ifilterCondition.fieldType) && - Objects.equals(this.operator, ifilterCondition.operator) && - Objects.equals(this.value, ifilterCondition.value); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(conditionId, fieldId, fieldType, operator, value); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class IFilterCondition {\n"); - sb.append(" conditionId: ").append(toIndentedString(conditionId)).append("\n"); - sb.append(" fieldId: ").append(toIndentedString(fieldId)).append("\n"); - sb.append(" fieldType: ").append(toIndentedString(fieldType)).append("\n"); - sb.append(" operator: ").append(toIndentedString(operator)).append("\n"); - sb.append(" value: ").append(toIndentedString(value)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("conditionId"); - openapiFields.add("fieldId"); - openapiFields.add("fieldType"); - openapiFields.add("operator"); - openapiFields.add("value"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("conditionId"); - openapiRequiredFields.add("fieldId"); - openapiRequiredFields.add("fieldType"); - openapiRequiredFields.add("operator"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to IFilterCondition - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!IFilterCondition.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in IFilterCondition is not found in the empty JSON string", IFilterCondition.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!IFilterCondition.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `IFilterCondition` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : IFilterCondition.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if (!jsonObj.get("conditionId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `conditionId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("conditionId").toString())); - } - if (!jsonObj.get("fieldId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `fieldId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("fieldId").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!IFilterCondition.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'IFilterCondition' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(IFilterCondition.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, IFilterCondition value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public IFilterCondition read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of IFilterCondition given an JSON string - * - * @param jsonString JSON string - * @return An instance of IFilterCondition - * @throws IOException if the JSON string is invalid with respect to IFilterCondition - */ - public static IFilterCondition fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, IFilterCondition.class); - } - - /** - * Convert an instance of IFilterCondition to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/IFilterInfo.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/IFilterInfo.java deleted file mode 100644 index d0ea0fbff5..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/IFilterInfo.java +++ /dev/null @@ -1,280 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.apitable.databusclient.model.FilterConjunction; -import com.apitable.databusclient.model.IFilterCondition; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * IFilterInfo - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class IFilterInfo { - public static final String SERIALIZED_NAME_CONDITIONS = "conditions"; - @SerializedName(SERIALIZED_NAME_CONDITIONS) - private List conditions; - - public static final String SERIALIZED_NAME_CONJUNCTION = "conjunction"; - @SerializedName(SERIALIZED_NAME_CONJUNCTION) - private FilterConjunction conjunction; - - public IFilterInfo() { - } - - public IFilterInfo conditions(List conditions) { - - this.conditions = conditions; - return this; - } - - public IFilterInfo addConditionsItem(IFilterCondition conditionsItem) { - if (this.conditions == null) { - this.conditions = new ArrayList<>(); - } - this.conditions.add(conditionsItem); - return this; - } - - /** - * Get conditions - * @return conditions - **/ - @javax.annotation.Nullable - public List getConditions() { - return conditions; - } - - - public void setConditions(List conditions) { - this.conditions = conditions; - } - - - public IFilterInfo conjunction(FilterConjunction conjunction) { - - this.conjunction = conjunction; - return this; - } - - /** - * Get conjunction - * @return conjunction - **/ - @javax.annotation.Nonnull - public FilterConjunction getConjunction() { - return conjunction; - } - - - public void setConjunction(FilterConjunction conjunction) { - this.conjunction = conjunction; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - IFilterInfo ifilterInfo = (IFilterInfo) o; - return Objects.equals(this.conditions, ifilterInfo.conditions) && - Objects.equals(this.conjunction, ifilterInfo.conjunction); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(conditions, conjunction); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class IFilterInfo {\n"); - sb.append(" conditions: ").append(toIndentedString(conditions)).append("\n"); - sb.append(" conjunction: ").append(toIndentedString(conjunction)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("conditions"); - openapiFields.add("conjunction"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("conjunction"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to IFilterInfo - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!IFilterInfo.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in IFilterInfo is not found in the empty JSON string", IFilterInfo.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!IFilterInfo.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `IFilterInfo` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : IFilterInfo.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if (jsonObj.get("conditions") != null && !jsonObj.get("conditions").isJsonNull()) { - JsonArray jsonArrayconditions = jsonObj.getAsJsonArray("conditions"); - if (jsonArrayconditions != null) { - // ensure the json data is an array - if (!jsonObj.get("conditions").isJsonArray()) { - throw new IllegalArgumentException(String.format("Expected the field `conditions` to be an array in the JSON string but got `%s`", jsonObj.get("conditions").toString())); - } - - // validate the optional field `conditions` (array) - for (int i = 0; i < jsonArrayconditions.size(); i++) { - IFilterCondition.validateJsonElement(jsonArrayconditions.get(i)); - }; - } - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!IFilterInfo.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'IFilterInfo' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(IFilterInfo.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, IFilterInfo value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public IFilterInfo read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of IFilterInfo given an JSON string - * - * @param jsonString JSON string - * @return An instance of IFilterInfo - * @throws IOException if the JSON string is invalid with respect to IFilterInfo - */ - public static IFilterInfo fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, IFilterInfo.class); - } - - /** - * Convert an instance of IFilterInfo to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/ISortInfo.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/ISortInfo.java deleted file mode 100644 index 9f4a36f74c..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/ISortInfo.java +++ /dev/null @@ -1,275 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.apitable.databusclient.model.ISortedField; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * ISortInfo - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class ISortInfo { - public static final String SERIALIZED_NAME_KEEP_SORT = "keepSort"; - @SerializedName(SERIALIZED_NAME_KEEP_SORT) - private Boolean keepSort; - - public static final String SERIALIZED_NAME_RULES = "rules"; - @SerializedName(SERIALIZED_NAME_RULES) - private List rules = new ArrayList<>(); - - public ISortInfo() { - } - - public ISortInfo keepSort(Boolean keepSort) { - - this.keepSort = keepSort; - return this; - } - - /** - * Get keepSort - * @return keepSort - **/ - @javax.annotation.Nullable - public Boolean getKeepSort() { - return keepSort; - } - - - public void setKeepSort(Boolean keepSort) { - this.keepSort = keepSort; - } - - - public ISortInfo rules(List rules) { - - this.rules = rules; - return this; - } - - public ISortInfo addRulesItem(ISortedField rulesItem) { - if (this.rules == null) { - this.rules = new ArrayList<>(); - } - this.rules.add(rulesItem); - return this; - } - - /** - * Get rules - * @return rules - **/ - @javax.annotation.Nonnull - public List getRules() { - return rules; - } - - - public void setRules(List rules) { - this.rules = rules; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ISortInfo isortInfo = (ISortInfo) o; - return Objects.equals(this.keepSort, isortInfo.keepSort) && - Objects.equals(this.rules, isortInfo.rules); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(keepSort, rules); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class ISortInfo {\n"); - sb.append(" keepSort: ").append(toIndentedString(keepSort)).append("\n"); - sb.append(" rules: ").append(toIndentedString(rules)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("keepSort"); - openapiFields.add("rules"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("rules"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to ISortInfo - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!ISortInfo.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in ISortInfo is not found in the empty JSON string", ISortInfo.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!ISortInfo.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `ISortInfo` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : ISortInfo.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - // ensure the json data is an array - if (!jsonObj.get("rules").isJsonArray()) { - throw new IllegalArgumentException(String.format("Expected the field `rules` to be an array in the JSON string but got `%s`", jsonObj.get("rules").toString())); - } - - JsonArray jsonArrayrules = jsonObj.getAsJsonArray("rules"); - // validate the required field `rules` (array) - for (int i = 0; i < jsonArrayrules.size(); i++) { - ISortedField.validateJsonElement(jsonArrayrules.get(i)); - }; - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!ISortInfo.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'ISortInfo' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(ISortInfo.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, ISortInfo value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public ISortInfo read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of ISortInfo given an JSON string - * - * @param jsonString JSON string - * @return An instance of ISortInfo - * @throws IOException if the JSON string is invalid with respect to ISortInfo - */ - public static ISortInfo fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, ISortInfo.class); - } - - /** - * Convert an instance of ISortInfo to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/ISortedField.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/ISortedField.java deleted file mode 100644 index 92ec630d54..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/ISortedField.java +++ /dev/null @@ -1,257 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * ISortedField - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class ISortedField { - public static final String SERIALIZED_NAME_DESC = "desc"; - @SerializedName(SERIALIZED_NAME_DESC) - private Boolean desc; - - public static final String SERIALIZED_NAME_FIELD_ID = "fieldId"; - @SerializedName(SERIALIZED_NAME_FIELD_ID) - private String fieldId; - - public ISortedField() { - } - - public ISortedField desc(Boolean desc) { - - this.desc = desc; - return this; - } - - /** - * Get desc - * @return desc - **/ - @javax.annotation.Nonnull - public Boolean getDesc() { - return desc; - } - - - public void setDesc(Boolean desc) { - this.desc = desc; - } - - - public ISortedField fieldId(String fieldId) { - - this.fieldId = fieldId; - return this; - } - - /** - * Get fieldId - * @return fieldId - **/ - @javax.annotation.Nullable - public String getFieldId() { - return fieldId; - } - - - public void setFieldId(String fieldId) { - this.fieldId = fieldId; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ISortedField isortedField = (ISortedField) o; - return Objects.equals(this.desc, isortedField.desc) && - Objects.equals(this.fieldId, isortedField.fieldId); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(desc, fieldId); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class ISortedField {\n"); - sb.append(" desc: ").append(toIndentedString(desc)).append("\n"); - sb.append(" fieldId: ").append(toIndentedString(fieldId)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("desc"); - openapiFields.add("fieldId"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("desc"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to ISortedField - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!ISortedField.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in ISortedField is not found in the empty JSON string", ISortedField.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!ISortedField.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `ISortedField` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : ISortedField.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if ((jsonObj.get("fieldId") != null && !jsonObj.get("fieldId").isJsonNull()) && !jsonObj.get("fieldId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `fieldId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("fieldId").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!ISortedField.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'ISortedField' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(ISortedField.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, ISortedField value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public ISortedField read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of ISortedField given an JSON string - * - * @param jsonString JSON string - * @return An instance of ISortedField - * @throws IOException if the JSON string is invalid with respect to ISortedField - */ - public static ISortedField fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, ISortedField.class); - } - - /** - * Convert an instance of ISortedField to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/IViewLockInfo.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/IViewLockInfo.java deleted file mode 100644 index e94aafd5dc..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/IViewLockInfo.java +++ /dev/null @@ -1,260 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * IViewLockInfo - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class IViewLockInfo { - public static final String SERIALIZED_NAME_DESCRIPTION = "description"; - @SerializedName(SERIALIZED_NAME_DESCRIPTION) - private String description; - - public static final String SERIALIZED_NAME_UNIT_ID = "unitId"; - @SerializedName(SERIALIZED_NAME_UNIT_ID) - private String unitId; - - public IViewLockInfo() { - } - - public IViewLockInfo description(String description) { - - this.description = description; - return this; - } - - /** - * Get description - * @return description - **/ - @javax.annotation.Nullable - public String getDescription() { - return description; - } - - - public void setDescription(String description) { - this.description = description; - } - - - public IViewLockInfo unitId(String unitId) { - - this.unitId = unitId; - return this; - } - - /** - * Get unitId - * @return unitId - **/ - @javax.annotation.Nonnull - public String getUnitId() { - return unitId; - } - - - public void setUnitId(String unitId) { - this.unitId = unitId; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - IViewLockInfo iviewLockInfo = (IViewLockInfo) o; - return Objects.equals(this.description, iviewLockInfo.description) && - Objects.equals(this.unitId, iviewLockInfo.unitId); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(description, unitId); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class IViewLockInfo {\n"); - sb.append(" description: ").append(toIndentedString(description)).append("\n"); - sb.append(" unitId: ").append(toIndentedString(unitId)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("description"); - openapiFields.add("unitId"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("unitId"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to IViewLockInfo - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!IViewLockInfo.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in IViewLockInfo is not found in the empty JSON string", IViewLockInfo.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!IViewLockInfo.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `IViewLockInfo` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : IViewLockInfo.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if ((jsonObj.get("description") != null && !jsonObj.get("description").isJsonNull()) && !jsonObj.get("description").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `description` to be a primitive type in the JSON string but got `%s`", jsonObj.get("description").toString())); - } - if (!jsonObj.get("unitId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `unitId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("unitId").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!IViewLockInfo.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'IViewLockInfo' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(IViewLockInfo.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, IViewLockInfo value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public IViewLockInfo read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of IViewLockInfo given an JSON string - * - * @param jsonString JSON string - * @return An instance of IViewLockInfo - * @throws IOException if the JSON string is invalid with respect to IViewLockInfo - */ - public static IViewLockInfo fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, IViewLockInfo.class); - } - - /** - * Convert an instance of IViewLockInfo to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/LinkedFields.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/LinkedFields.java deleted file mode 100644 index 236bd4f61e..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/LinkedFields.java +++ /dev/null @@ -1,279 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * LinkedFields - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class LinkedFields { - public static final String SERIALIZED_NAME_ID = "id"; - @SerializedName(SERIALIZED_NAME_ID) - private String id; - - public static final String SERIALIZED_NAME_NAME = "name"; - @SerializedName(SERIALIZED_NAME_NAME) - private String name; - - public static final String SERIALIZED_NAME_TYPE = "type"; - @SerializedName(SERIALIZED_NAME_TYPE) - private Integer type; - - public LinkedFields() { - } - - public LinkedFields id(String id) { - - this.id = id; - return this; - } - - /** - * Get id - * @return id - **/ - @javax.annotation.Nonnull - public String getId() { - return id; - } - - - public void setId(String id) { - this.id = id; - } - - - public LinkedFields name(String name) { - - this.name = name; - return this; - } - - /** - * Get name - * @return name - **/ - @javax.annotation.Nonnull - public String getName() { - return name; - } - - - public void setName(String name) { - this.name = name; - } - - - public LinkedFields type(Integer type) { - - this.type = type; - return this; - } - - /** - * Get type - * minimum: 0 - * @return type - **/ - @javax.annotation.Nonnull - public Integer getType() { - return type; - } - - - public void setType(Integer type) { - this.type = type; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - LinkedFields linkedFields = (LinkedFields) o; - return Objects.equals(this.id, linkedFields.id) && - Objects.equals(this.name, linkedFields.name) && - Objects.equals(this.type, linkedFields.type); - } - - @Override - public int hashCode() { - return Objects.hash(id, name, type); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class LinkedFields {\n"); - sb.append(" id: ").append(toIndentedString(id)).append("\n"); - sb.append(" name: ").append(toIndentedString(name)).append("\n"); - sb.append(" type: ").append(toIndentedString(type)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("id"); - openapiFields.add("name"); - openapiFields.add("type"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("id"); - openapiRequiredFields.add("name"); - openapiRequiredFields.add("type"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to LinkedFields - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!LinkedFields.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in LinkedFields is not found in the empty JSON string", LinkedFields.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!LinkedFields.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `LinkedFields` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : LinkedFields.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if (!jsonObj.get("id").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `id` to be a primitive type in the JSON string but got `%s`", jsonObj.get("id").toString())); - } - if (!jsonObj.get("name").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `name` to be a primitive type in the JSON string but got `%s`", jsonObj.get("name").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!LinkedFields.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'LinkedFields' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(LinkedFields.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, LinkedFields value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public LinkedFields read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of LinkedFields given an JSON string - * - * @param jsonString JSON string - * @return An instance of LinkedFields - * @throws IOException if the JSON string is invalid with respect to LinkedFields - */ - public static LinkedFields fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, LinkedFields.class); - } - - /** - * Convert an instance of LinkedFields to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/ListVO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/ListVO.java deleted file mode 100644 index e929e3940e..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/ListVO.java +++ /dev/null @@ -1,235 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.apitable.databusclient.model.ApiRecordDto; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * ListVO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class ListVO { - public static final String SERIALIZED_NAME_RECORDS = "records"; - @SerializedName(SERIALIZED_NAME_RECORDS) - private List records = new ArrayList<>(); - - public ListVO() { - } - - public ListVO records(List records) { - - this.records = records; - return this; - } - - public ListVO addRecordsItem(ApiRecordDto recordsItem) { - if (this.records == null) { - this.records = new ArrayList<>(); - } - this.records.add(recordsItem); - return this; - } - - /** - * Get records - * @return records - **/ - @javax.annotation.Nonnull - public List getRecords() { - return records; - } - - - public void setRecords(List records) { - this.records = records; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ListVO listVO = (ListVO) o; - return Objects.equals(this.records, listVO.records); - } - - @Override - public int hashCode() { - return Objects.hash(records); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class ListVO {\n"); - sb.append(" records: ").append(toIndentedString(records)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("records"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("records"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to ListVO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!ListVO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in ListVO is not found in the empty JSON string", ListVO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!ListVO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `ListVO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : ListVO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - // ensure the json data is an array - if (!jsonObj.get("records").isJsonArray()) { - throw new IllegalArgumentException(String.format("Expected the field `records` to be an array in the JSON string but got `%s`", jsonObj.get("records").toString())); - } - - JsonArray jsonArrayrecords = jsonObj.getAsJsonArray("records"); - // validate the required field `records` (array) - for (int i = 0; i < jsonArrayrecords.size(); i++) { - ApiRecordDto.validateJsonElement(jsonArrayrecords.get(i)); - }; - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!ListVO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'ListVO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(ListVO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, ListVO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public ListVO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of ListVO given an JSON string - * - * @param jsonString JSON string - * @return An instance of ListVO - * @throws IOException if the JSON string is invalid with respect to ListVO - */ - public static ListVO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, ListVO.class); - } - - /** - * Convert an instance of ListVO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/LookUpFilterPO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/LookUpFilterPO.java deleted file mode 100644 index 5d490813f6..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/LookUpFilterPO.java +++ /dev/null @@ -1,262 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * LookUpFilterPO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class LookUpFilterPO { - public static final String SERIALIZED_NAME_CONDITIONS = "conditions"; - @SerializedName(SERIALIZED_NAME_CONDITIONS) - private List conditions = new ArrayList<>(); - - public static final String SERIALIZED_NAME_CONJUNCTION = "conjunction"; - @SerializedName(SERIALIZED_NAME_CONJUNCTION) - private String conjunction; - - public LookUpFilterPO() { - } - - public LookUpFilterPO conditions(List conditions) { - - this.conditions = conditions; - return this; - } - - public LookUpFilterPO addConditionsItem(Object conditionsItem) { - if (this.conditions == null) { - this.conditions = new ArrayList<>(); - } - this.conditions.add(conditionsItem); - return this; - } - - /** - * Get conditions - * @return conditions - **/ - @javax.annotation.Nonnull - public List getConditions() { - return conditions; - } - - - public void setConditions(List conditions) { - this.conditions = conditions; - } - - - public LookUpFilterPO conjunction(String conjunction) { - - this.conjunction = conjunction; - return this; - } - - /** - * Get conjunction - * @return conjunction - **/ - @javax.annotation.Nonnull - public String getConjunction() { - return conjunction; - } - - - public void setConjunction(String conjunction) { - this.conjunction = conjunction; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - LookUpFilterPO lookUpFilterPO = (LookUpFilterPO) o; - return Objects.equals(this.conditions, lookUpFilterPO.conditions) && - Objects.equals(this.conjunction, lookUpFilterPO.conjunction); - } - - @Override - public int hashCode() { - return Objects.hash(conditions, conjunction); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class LookUpFilterPO {\n"); - sb.append(" conditions: ").append(toIndentedString(conditions)).append("\n"); - sb.append(" conjunction: ").append(toIndentedString(conjunction)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("conditions"); - openapiFields.add("conjunction"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("conditions"); - openapiRequiredFields.add("conjunction"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to LookUpFilterPO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!LookUpFilterPO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in LookUpFilterPO is not found in the empty JSON string", LookUpFilterPO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!LookUpFilterPO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `LookUpFilterPO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : LookUpFilterPO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - // ensure the required json array is present - if (jsonObj.get("conditions") == null) { - throw new IllegalArgumentException("Expected the field `linkedContent` to be an array in the JSON string but got `null`"); - } else if (!jsonObj.get("conditions").isJsonArray()) { - throw new IllegalArgumentException(String.format("Expected the field `conditions` to be an array in the JSON string but got `%s`", jsonObj.get("conditions").toString())); - } - if (!jsonObj.get("conjunction").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `conjunction` to be a primitive type in the JSON string but got `%s`", jsonObj.get("conjunction").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!LookUpFilterPO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'LookUpFilterPO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(LookUpFilterPO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, LookUpFilterPO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public LookUpFilterPO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of LookUpFilterPO given an JSON string - * - * @param jsonString JSON string - * @return An instance of LookUpFilterPO - * @throws IOException if the JSON string is invalid with respect to LookUpFilterPO - */ - public static LookUpFilterPO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, LookUpFilterPO.class); - } - - /** - * Convert an instance of LookUpFilterPO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/NodePermissionStateSO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/NodePermissionStateSO.java deleted file mode 100644 index 1669d3ae17..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/NodePermissionStateSO.java +++ /dev/null @@ -1,218 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * NodePermissionStateSO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class NodePermissionStateSO { - public static final String SERIALIZED_NAME_IS_DELETED = "isDeleted"; - @SerializedName(SERIALIZED_NAME_IS_DELETED) - private Boolean isDeleted; - - public NodePermissionStateSO() { - } - - public NodePermissionStateSO isDeleted(Boolean isDeleted) { - - this.isDeleted = isDeleted; - return this; - } - - /** - * Get isDeleted - * @return isDeleted - **/ - @javax.annotation.Nullable - public Boolean getIsDeleted() { - return isDeleted; - } - - - public void setIsDeleted(Boolean isDeleted) { - this.isDeleted = isDeleted; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - NodePermissionStateSO nodePermissionStateSO = (NodePermissionStateSO) o; - return Objects.equals(this.isDeleted, nodePermissionStateSO.isDeleted); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(isDeleted); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class NodePermissionStateSO {\n"); - sb.append(" isDeleted: ").append(toIndentedString(isDeleted)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("isDeleted"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to NodePermissionStateSO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!NodePermissionStateSO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in NodePermissionStateSO is not found in the empty JSON string", NodePermissionStateSO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!NodePermissionStateSO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `NodePermissionStateSO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!NodePermissionStateSO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'NodePermissionStateSO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(NodePermissionStateSO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, NodePermissionStateSO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public NodePermissionStateSO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of NodePermissionStateSO given an JSON string - * - * @param jsonString JSON string - * @return An instance of NodePermissionStateSO - * @throws IOException if the JSON string is invalid with respect to NodePermissionStateSO - */ - public static NodePermissionStateSO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, NodePermissionStateSO.class); - } - - /** - * Convert an instance of NodePermissionStateSO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/NodeSO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/NodeSO.java deleted file mode 100644 index 944af70430..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/NodeSO.java +++ /dev/null @@ -1,657 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.apitable.databusclient.model.NodePermissionStateSO; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * NodeSO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class NodeSO { - public static final String SERIALIZED_NAME_ACTIVE_VIEW = "activeView"; - @SerializedName(SERIALIZED_NAME_ACTIVE_VIEW) - private String activeView; - - public static final String SERIALIZED_NAME_DESCRIPTION = "description"; - @SerializedName(SERIALIZED_NAME_DESCRIPTION) - private String description; - - public static final String SERIALIZED_NAME_EXTRA = "extra"; - @SerializedName(SERIALIZED_NAME_EXTRA) - private Object extra = null; - - public static final String SERIALIZED_NAME_ICON = "icon"; - @SerializedName(SERIALIZED_NAME_ICON) - private String icon; - - public static final String SERIALIZED_NAME_ID = "id"; - @SerializedName(SERIALIZED_NAME_ID) - private String id; - - public static final String SERIALIZED_NAME_IS_GHOST_NODE = "isGhostNode"; - @SerializedName(SERIALIZED_NAME_IS_GHOST_NODE) - private Boolean isGhostNode; - - public static final String SERIALIZED_NAME_NAME = "name"; - @SerializedName(SERIALIZED_NAME_NAME) - private String name; - - public static final String SERIALIZED_NAME_NODE_FAVORITE = "nodeFavorite"; - @SerializedName(SERIALIZED_NAME_NODE_FAVORITE) - private Boolean nodeFavorite; - - public static final String SERIALIZED_NAME_NODE_PERMIT_SET = "nodePermitSet"; - @SerializedName(SERIALIZED_NAME_NODE_PERMIT_SET) - private Boolean nodePermitSet; - - public static final String SERIALIZED_NAME_NODE_SHARED = "nodeShared"; - @SerializedName(SERIALIZED_NAME_NODE_SHARED) - private Boolean nodeShared; - - public static final String SERIALIZED_NAME_PARENT_ID = "parentId"; - @SerializedName(SERIALIZED_NAME_PARENT_ID) - private String parentId; - - public static final String SERIALIZED_NAME_PERMISSIONS = "permissions"; - @SerializedName(SERIALIZED_NAME_PERMISSIONS) - private NodePermissionStateSO permissions; - - public static final String SERIALIZED_NAME_REVISION = "revision"; - @SerializedName(SERIALIZED_NAME_REVISION) - private Integer revision; - - public static final String SERIALIZED_NAME_ROLE = "role"; - @SerializedName(SERIALIZED_NAME_ROLE) - private String role; - - public static final String SERIALIZED_NAME_SPACE_ID = "spaceId"; - @SerializedName(SERIALIZED_NAME_SPACE_ID) - private String spaceId; - - public NodeSO() { - } - - public NodeSO activeView(String activeView) { - - this.activeView = activeView; - return this; - } - - /** - * Get activeView - * @return activeView - **/ - @javax.annotation.Nullable - public String getActiveView() { - return activeView; - } - - - public void setActiveView(String activeView) { - this.activeView = activeView; - } - - - public NodeSO description(String description) { - - this.description = description; - return this; - } - - /** - * Get description - * @return description - **/ - @javax.annotation.Nonnull - public String getDescription() { - return description; - } - - - public void setDescription(String description) { - this.description = description; - } - - - public NodeSO extra(Object extra) { - - this.extra = extra; - return this; - } - - /** - * Get extra - * @return extra - **/ - @javax.annotation.Nullable - public Object getExtra() { - return extra; - } - - - public void setExtra(Object extra) { - this.extra = extra; - } - - - public NodeSO icon(String icon) { - - this.icon = icon; - return this; - } - - /** - * Get icon - * @return icon - **/ - @javax.annotation.Nonnull - public String getIcon() { - return icon; - } - - - public void setIcon(String icon) { - this.icon = icon; - } - - - public NodeSO id(String id) { - - this.id = id; - return this; - } - - /** - * Get id - * @return id - **/ - @javax.annotation.Nonnull - public String getId() { - return id; - } - - - public void setId(String id) { - this.id = id; - } - - - public NodeSO isGhostNode(Boolean isGhostNode) { - - this.isGhostNode = isGhostNode; - return this; - } - - /** - * Get isGhostNode - * @return isGhostNode - **/ - @javax.annotation.Nullable - public Boolean getIsGhostNode() { - return isGhostNode; - } - - - public void setIsGhostNode(Boolean isGhostNode) { - this.isGhostNode = isGhostNode; - } - - - public NodeSO name(String name) { - - this.name = name; - return this; - } - - /** - * Get name - * @return name - **/ - @javax.annotation.Nonnull - public String getName() { - return name; - } - - - public void setName(String name) { - this.name = name; - } - - - public NodeSO nodeFavorite(Boolean nodeFavorite) { - - this.nodeFavorite = nodeFavorite; - return this; - } - - /** - * Get nodeFavorite - * @return nodeFavorite - **/ - @javax.annotation.Nonnull - public Boolean getNodeFavorite() { - return nodeFavorite; - } - - - public void setNodeFavorite(Boolean nodeFavorite) { - this.nodeFavorite = nodeFavorite; - } - - - public NodeSO nodePermitSet(Boolean nodePermitSet) { - - this.nodePermitSet = nodePermitSet; - return this; - } - - /** - * Get nodePermitSet - * @return nodePermitSet - **/ - @javax.annotation.Nonnull - public Boolean getNodePermitSet() { - return nodePermitSet; - } - - - public void setNodePermitSet(Boolean nodePermitSet) { - this.nodePermitSet = nodePermitSet; - } - - - public NodeSO nodeShared(Boolean nodeShared) { - - this.nodeShared = nodeShared; - return this; - } - - /** - * Get nodeShared - * @return nodeShared - **/ - @javax.annotation.Nonnull - public Boolean getNodeShared() { - return nodeShared; - } - - - public void setNodeShared(Boolean nodeShared) { - this.nodeShared = nodeShared; - } - - - public NodeSO parentId(String parentId) { - - this.parentId = parentId; - return this; - } - - /** - * Get parentId - * @return parentId - **/ - @javax.annotation.Nonnull - public String getParentId() { - return parentId; - } - - - public void setParentId(String parentId) { - this.parentId = parentId; - } - - - public NodeSO permissions(NodePermissionStateSO permissions) { - - this.permissions = permissions; - return this; - } - - /** - * Get permissions - * @return permissions - **/ - @javax.annotation.Nonnull - public NodePermissionStateSO getPermissions() { - return permissions; - } - - - public void setPermissions(NodePermissionStateSO permissions) { - this.permissions = permissions; - } - - - public NodeSO revision(Integer revision) { - - this.revision = revision; - return this; - } - - /** - * Get revision - * minimum: 0 - * @return revision - **/ - @javax.annotation.Nonnull - public Integer getRevision() { - return revision; - } - - - public void setRevision(Integer revision) { - this.revision = revision; - } - - - public NodeSO role(String role) { - - this.role = role; - return this; - } - - /** - * Get role - * @return role - **/ - @javax.annotation.Nonnull - public String getRole() { - return role; - } - - - public void setRole(String role) { - this.role = role; - } - - - public NodeSO spaceId(String spaceId) { - - this.spaceId = spaceId; - return this; - } - - /** - * Get spaceId - * @return spaceId - **/ - @javax.annotation.Nonnull - public String getSpaceId() { - return spaceId; - } - - - public void setSpaceId(String spaceId) { - this.spaceId = spaceId; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - NodeSO nodeSO = (NodeSO) o; - return Objects.equals(this.activeView, nodeSO.activeView) && - Objects.equals(this.description, nodeSO.description) && - Objects.equals(this.extra, nodeSO.extra) && - Objects.equals(this.icon, nodeSO.icon) && - Objects.equals(this.id, nodeSO.id) && - Objects.equals(this.isGhostNode, nodeSO.isGhostNode) && - Objects.equals(this.name, nodeSO.name) && - Objects.equals(this.nodeFavorite, nodeSO.nodeFavorite) && - Objects.equals(this.nodePermitSet, nodeSO.nodePermitSet) && - Objects.equals(this.nodeShared, nodeSO.nodeShared) && - Objects.equals(this.parentId, nodeSO.parentId) && - Objects.equals(this.permissions, nodeSO.permissions) && - Objects.equals(this.revision, nodeSO.revision) && - Objects.equals(this.role, nodeSO.role) && - Objects.equals(this.spaceId, nodeSO.spaceId); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(activeView, description, extra, icon, id, isGhostNode, name, nodeFavorite, nodePermitSet, nodeShared, parentId, permissions, revision, role, spaceId); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class NodeSO {\n"); - sb.append(" activeView: ").append(toIndentedString(activeView)).append("\n"); - sb.append(" description: ").append(toIndentedString(description)).append("\n"); - sb.append(" extra: ").append(toIndentedString(extra)).append("\n"); - sb.append(" icon: ").append(toIndentedString(icon)).append("\n"); - sb.append(" id: ").append(toIndentedString(id)).append("\n"); - sb.append(" isGhostNode: ").append(toIndentedString(isGhostNode)).append("\n"); - sb.append(" name: ").append(toIndentedString(name)).append("\n"); - sb.append(" nodeFavorite: ").append(toIndentedString(nodeFavorite)).append("\n"); - sb.append(" nodePermitSet: ").append(toIndentedString(nodePermitSet)).append("\n"); - sb.append(" nodeShared: ").append(toIndentedString(nodeShared)).append("\n"); - sb.append(" parentId: ").append(toIndentedString(parentId)).append("\n"); - sb.append(" permissions: ").append(toIndentedString(permissions)).append("\n"); - sb.append(" revision: ").append(toIndentedString(revision)).append("\n"); - sb.append(" role: ").append(toIndentedString(role)).append("\n"); - sb.append(" spaceId: ").append(toIndentedString(spaceId)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("activeView"); - openapiFields.add("description"); - openapiFields.add("extra"); - openapiFields.add("icon"); - openapiFields.add("id"); - openapiFields.add("isGhostNode"); - openapiFields.add("name"); - openapiFields.add("nodeFavorite"); - openapiFields.add("nodePermitSet"); - openapiFields.add("nodeShared"); - openapiFields.add("parentId"); - openapiFields.add("permissions"); - openapiFields.add("revision"); - openapiFields.add("role"); - openapiFields.add("spaceId"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("description"); - openapiRequiredFields.add("icon"); - openapiRequiredFields.add("id"); - openapiRequiredFields.add("name"); - openapiRequiredFields.add("nodeFavorite"); - openapiRequiredFields.add("nodePermitSet"); - openapiRequiredFields.add("nodeShared"); - openapiRequiredFields.add("parentId"); - openapiRequiredFields.add("permissions"); - openapiRequiredFields.add("revision"); - openapiRequiredFields.add("role"); - openapiRequiredFields.add("spaceId"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to NodeSO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!NodeSO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in NodeSO is not found in the empty JSON string", NodeSO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!NodeSO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `NodeSO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : NodeSO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if ((jsonObj.get("activeView") != null && !jsonObj.get("activeView").isJsonNull()) && !jsonObj.get("activeView").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `activeView` to be a primitive type in the JSON string but got `%s`", jsonObj.get("activeView").toString())); - } - if (!jsonObj.get("description").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `description` to be a primitive type in the JSON string but got `%s`", jsonObj.get("description").toString())); - } - if (!jsonObj.get("icon").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `icon` to be a primitive type in the JSON string but got `%s`", jsonObj.get("icon").toString())); - } - if (!jsonObj.get("id").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `id` to be a primitive type in the JSON string but got `%s`", jsonObj.get("id").toString())); - } - if (!jsonObj.get("name").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `name` to be a primitive type in the JSON string but got `%s`", jsonObj.get("name").toString())); - } - if (!jsonObj.get("parentId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `parentId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("parentId").toString())); - } - // validate the required field `permissions` - NodePermissionStateSO.validateJsonElement(jsonObj.get("permissions")); - if (!jsonObj.get("role").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `role` to be a primitive type in the JSON string but got `%s`", jsonObj.get("role").toString())); - } - if (!jsonObj.get("spaceId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `spaceId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("spaceId").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!NodeSO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'NodeSO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(NodeSO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, NodeSO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public NodeSO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of NodeSO given an JSON string - * - * @param jsonString JSON string - * @return An instance of NodeSO - * @throws IOException if the JSON string is invalid with respect to NodeSO - */ - public static NodeSO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, NodeSO.class); - } - - /** - * Convert an instance of NodeSO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/NodeSimplePO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/NodeSimplePO.java deleted file mode 100644 index b81ac63400..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/NodeSimplePO.java +++ /dev/null @@ -1,292 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * NodeSimplePO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class NodeSimplePO { - public static final String SERIALIZED_NAME_ICON = "icon"; - @SerializedName(SERIALIZED_NAME_ICON) - private String icon; - - public static final String SERIALIZED_NAME_NODE_ID = "nodeId"; - @SerializedName(SERIALIZED_NAME_NODE_ID) - private String nodeId; - - public static final String SERIALIZED_NAME_NODE_NAME = "nodeName"; - @SerializedName(SERIALIZED_NAME_NODE_NAME) - private String nodeName; - - public NodeSimplePO() { - } - - public NodeSimplePO icon(String icon) { - - this.icon = icon; - return this; - } - - /** - * Get icon - * @return icon - **/ - @javax.annotation.Nullable - public String getIcon() { - return icon; - } - - - public void setIcon(String icon) { - this.icon = icon; - } - - - public NodeSimplePO nodeId(String nodeId) { - - this.nodeId = nodeId; - return this; - } - - /** - * Get nodeId - * @return nodeId - **/ - @javax.annotation.Nonnull - public String getNodeId() { - return nodeId; - } - - - public void setNodeId(String nodeId) { - this.nodeId = nodeId; - } - - - public NodeSimplePO nodeName(String nodeName) { - - this.nodeName = nodeName; - return this; - } - - /** - * Get nodeName - * @return nodeName - **/ - @javax.annotation.Nonnull - public String getNodeName() { - return nodeName; - } - - - public void setNodeName(String nodeName) { - this.nodeName = nodeName; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - NodeSimplePO nodeSimplePO = (NodeSimplePO) o; - return Objects.equals(this.icon, nodeSimplePO.icon) && - Objects.equals(this.nodeId, nodeSimplePO.nodeId) && - Objects.equals(this.nodeName, nodeSimplePO.nodeName); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(icon, nodeId, nodeName); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class NodeSimplePO {\n"); - sb.append(" icon: ").append(toIndentedString(icon)).append("\n"); - sb.append(" nodeId: ").append(toIndentedString(nodeId)).append("\n"); - sb.append(" nodeName: ").append(toIndentedString(nodeName)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("icon"); - openapiFields.add("nodeId"); - openapiFields.add("nodeName"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("nodeId"); - openapiRequiredFields.add("nodeName"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to NodeSimplePO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!NodeSimplePO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in NodeSimplePO is not found in the empty JSON string", NodeSimplePO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!NodeSimplePO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `NodeSimplePO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : NodeSimplePO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if ((jsonObj.get("icon") != null && !jsonObj.get("icon").isJsonNull()) && !jsonObj.get("icon").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `icon` to be a primitive type in the JSON string but got `%s`", jsonObj.get("icon").toString())); - } - if (!jsonObj.get("nodeId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `nodeId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("nodeId").toString())); - } - if (!jsonObj.get("nodeName").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `nodeName` to be a primitive type in the JSON string but got `%s`", jsonObj.get("nodeName").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!NodeSimplePO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'NodeSimplePO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(NodeSimplePO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, NodeSimplePO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public NodeSimplePO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of NodeSimplePO given an JSON string - * - * @param jsonString JSON string - * @return An instance of NodeSimplePO - * @throws IOException if the JSON string is invalid with respect to NodeSimplePO - */ - public static NodeSimplePO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, NodeSimplePO.class); - } - - /** - * Convert an instance of NodeSimplePO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/RecordAlarm.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/RecordAlarm.java deleted file mode 100644 index 366c68414f..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/RecordAlarm.java +++ /dev/null @@ -1,437 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.apitable.databusclient.model.AlarmUser; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * RecordAlarm - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class RecordAlarm { - public static final String SERIALIZED_NAME_ALARM_AT = "alarmAt"; - @SerializedName(SERIALIZED_NAME_ALARM_AT) - private String alarmAt; - - public static final String SERIALIZED_NAME_ALARM_USERS = "alarmUsers"; - @SerializedName(SERIALIZED_NAME_ALARM_USERS) - private List alarmUsers; - - public static final String SERIALIZED_NAME_FIELD_ID = "fieldId"; - @SerializedName(SERIALIZED_NAME_FIELD_ID) - private String fieldId; - - public static final String SERIALIZED_NAME_ID = "id"; - @SerializedName(SERIALIZED_NAME_ID) - private String id; - - public static final String SERIALIZED_NAME_RECORD_ID = "recordId"; - @SerializedName(SERIALIZED_NAME_RECORD_ID) - private String recordId; - - public static final String SERIALIZED_NAME_SUBTRACT = "subtract"; - @SerializedName(SERIALIZED_NAME_SUBTRACT) - private String subtract; - - public static final String SERIALIZED_NAME_TIME = "time"; - @SerializedName(SERIALIZED_NAME_TIME) - private String time; - - public RecordAlarm() { - } - - public RecordAlarm alarmAt(String alarmAt) { - - this.alarmAt = alarmAt; - return this; - } - - /** - * Get alarmAt - * @return alarmAt - **/ - @javax.annotation.Nullable - public String getAlarmAt() { - return alarmAt; - } - - - public void setAlarmAt(String alarmAt) { - this.alarmAt = alarmAt; - } - - - public RecordAlarm alarmUsers(List alarmUsers) { - - this.alarmUsers = alarmUsers; - return this; - } - - public RecordAlarm addAlarmUsersItem(AlarmUser alarmUsersItem) { - if (this.alarmUsers == null) { - this.alarmUsers = new ArrayList<>(); - } - this.alarmUsers.add(alarmUsersItem); - return this; - } - - /** - * Get alarmUsers - * @return alarmUsers - **/ - @javax.annotation.Nullable - public List getAlarmUsers() { - return alarmUsers; - } - - - public void setAlarmUsers(List alarmUsers) { - this.alarmUsers = alarmUsers; - } - - - public RecordAlarm fieldId(String fieldId) { - - this.fieldId = fieldId; - return this; - } - - /** - * Get fieldId - * @return fieldId - **/ - @javax.annotation.Nullable - public String getFieldId() { - return fieldId; - } - - - public void setFieldId(String fieldId) { - this.fieldId = fieldId; - } - - - public RecordAlarm id(String id) { - - this.id = id; - return this; - } - - /** - * Get id - * @return id - **/ - @javax.annotation.Nonnull - public String getId() { - return id; - } - - - public void setId(String id) { - this.id = id; - } - - - public RecordAlarm recordId(String recordId) { - - this.recordId = recordId; - return this; - } - - /** - * Get recordId - * @return recordId - **/ - @javax.annotation.Nullable - public String getRecordId() { - return recordId; - } - - - public void setRecordId(String recordId) { - this.recordId = recordId; - } - - - public RecordAlarm subtract(String subtract) { - - this.subtract = subtract; - return this; - } - - /** - * Get subtract - * @return subtract - **/ - @javax.annotation.Nullable - public String getSubtract() { - return subtract; - } - - - public void setSubtract(String subtract) { - this.subtract = subtract; - } - - - public RecordAlarm time(String time) { - - this.time = time; - return this; - } - - /** - * Get time - * @return time - **/ - @javax.annotation.Nullable - public String getTime() { - return time; - } - - - public void setTime(String time) { - this.time = time; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - RecordAlarm recordAlarm = (RecordAlarm) o; - return Objects.equals(this.alarmAt, recordAlarm.alarmAt) && - Objects.equals(this.alarmUsers, recordAlarm.alarmUsers) && - Objects.equals(this.fieldId, recordAlarm.fieldId) && - Objects.equals(this.id, recordAlarm.id) && - Objects.equals(this.recordId, recordAlarm.recordId) && - Objects.equals(this.subtract, recordAlarm.subtract) && - Objects.equals(this.time, recordAlarm.time); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(alarmAt, alarmUsers, fieldId, id, recordId, subtract, time); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class RecordAlarm {\n"); - sb.append(" alarmAt: ").append(toIndentedString(alarmAt)).append("\n"); - sb.append(" alarmUsers: ").append(toIndentedString(alarmUsers)).append("\n"); - sb.append(" fieldId: ").append(toIndentedString(fieldId)).append("\n"); - sb.append(" id: ").append(toIndentedString(id)).append("\n"); - sb.append(" recordId: ").append(toIndentedString(recordId)).append("\n"); - sb.append(" subtract: ").append(toIndentedString(subtract)).append("\n"); - sb.append(" time: ").append(toIndentedString(time)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("alarmAt"); - openapiFields.add("alarmUsers"); - openapiFields.add("fieldId"); - openapiFields.add("id"); - openapiFields.add("recordId"); - openapiFields.add("subtract"); - openapiFields.add("time"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("id"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to RecordAlarm - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!RecordAlarm.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in RecordAlarm is not found in the empty JSON string", RecordAlarm.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!RecordAlarm.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `RecordAlarm` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : RecordAlarm.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if ((jsonObj.get("alarmAt") != null && !jsonObj.get("alarmAt").isJsonNull()) && !jsonObj.get("alarmAt").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `alarmAt` to be a primitive type in the JSON string but got `%s`", jsonObj.get("alarmAt").toString())); - } - if (jsonObj.get("alarmUsers") != null && !jsonObj.get("alarmUsers").isJsonNull()) { - JsonArray jsonArrayalarmUsers = jsonObj.getAsJsonArray("alarmUsers"); - if (jsonArrayalarmUsers != null) { - // ensure the json data is an array - if (!jsonObj.get("alarmUsers").isJsonArray()) { - throw new IllegalArgumentException(String.format("Expected the field `alarmUsers` to be an array in the JSON string but got `%s`", jsonObj.get("alarmUsers").toString())); - } - - // validate the optional field `alarmUsers` (array) - for (int i = 0; i < jsonArrayalarmUsers.size(); i++) { - AlarmUser.validateJsonElement(jsonArrayalarmUsers.get(i)); - }; - } - } - if ((jsonObj.get("fieldId") != null && !jsonObj.get("fieldId").isJsonNull()) && !jsonObj.get("fieldId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `fieldId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("fieldId").toString())); - } - if (!jsonObj.get("id").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `id` to be a primitive type in the JSON string but got `%s`", jsonObj.get("id").toString())); - } - if ((jsonObj.get("recordId") != null && !jsonObj.get("recordId").isJsonNull()) && !jsonObj.get("recordId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `recordId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("recordId").toString())); - } - if ((jsonObj.get("subtract") != null && !jsonObj.get("subtract").isJsonNull()) && !jsonObj.get("subtract").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `subtract` to be a primitive type in the JSON string but got `%s`", jsonObj.get("subtract").toString())); - } - if ((jsonObj.get("time") != null && !jsonObj.get("time").isJsonNull()) && !jsonObj.get("time").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `time` to be a primitive type in the JSON string but got `%s`", jsonObj.get("time").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!RecordAlarm.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'RecordAlarm' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(RecordAlarm.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, RecordAlarm value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public RecordAlarm read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of RecordAlarm given an JSON string - * - * @param jsonString JSON string - * @return An instance of RecordAlarm - * @throws IOException if the JSON string is invalid with respect to RecordAlarm - */ - public static RecordAlarm fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, RecordAlarm.class); - } - - /** - * Convert an instance of RecordAlarm to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/RecordMeta.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/RecordMeta.java deleted file mode 100644 index d1e38afce1..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/RecordMeta.java +++ /dev/null @@ -1,386 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.apitable.databusclient.model.FieldExtraMapValue; -import com.apitable.databusclient.model.FieldUpdatedValue; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * RecordMeta - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class RecordMeta { - public static final String SERIALIZED_NAME_CREATED_AT = "createdAt"; - @SerializedName(SERIALIZED_NAME_CREATED_AT) - private Long createdAt; - - public static final String SERIALIZED_NAME_CREATED_BY = "createdBy"; - @SerializedName(SERIALIZED_NAME_CREATED_BY) - private String createdBy; - - public static final String SERIALIZED_NAME_FIELD_EXTRA_MAP = "fieldExtraMap"; - @SerializedName(SERIALIZED_NAME_FIELD_EXTRA_MAP) - private Map fieldExtraMap; - - public static final String SERIALIZED_NAME_FIELD_UPDATED_MAP = "fieldUpdatedMap"; - @SerializedName(SERIALIZED_NAME_FIELD_UPDATED_MAP) - private Map fieldUpdatedMap; - - public static final String SERIALIZED_NAME_UPDATED_AT = "updatedAt"; - @SerializedName(SERIALIZED_NAME_UPDATED_AT) - private Long updatedAt; - - public static final String SERIALIZED_NAME_UPDATED_BY = "updatedBy"; - @SerializedName(SERIALIZED_NAME_UPDATED_BY) - private String updatedBy; - - public RecordMeta() { - } - - public RecordMeta createdAt(Long createdAt) { - - this.createdAt = createdAt; - return this; - } - - /** - * Get createdAt - * minimum: 0 - * @return createdAt - **/ - @javax.annotation.Nullable - public Long getCreatedAt() { - return createdAt; - } - - - public void setCreatedAt(Long createdAt) { - this.createdAt = createdAt; - } - - - public RecordMeta createdBy(String createdBy) { - - this.createdBy = createdBy; - return this; - } - - /** - * Get createdBy - * @return createdBy - **/ - @javax.annotation.Nullable - public String getCreatedBy() { - return createdBy; - } - - - public void setCreatedBy(String createdBy) { - this.createdBy = createdBy; - } - - - public RecordMeta fieldExtraMap(Map fieldExtraMap) { - - this.fieldExtraMap = fieldExtraMap; - return this; - } - - public RecordMeta putFieldExtraMapItem(String key, FieldExtraMapValue fieldExtraMapItem) { - if (this.fieldExtraMap == null) { - this.fieldExtraMap = new HashMap<>(); - } - this.fieldExtraMap.put(key, fieldExtraMapItem); - return this; - } - - /** - * Get fieldExtraMap - * @return fieldExtraMap - **/ - @javax.annotation.Nullable - public Map getFieldExtraMap() { - return fieldExtraMap; - } - - - public void setFieldExtraMap(Map fieldExtraMap) { - this.fieldExtraMap = fieldExtraMap; - } - - - public RecordMeta fieldUpdatedMap(Map fieldUpdatedMap) { - - this.fieldUpdatedMap = fieldUpdatedMap; - return this; - } - - public RecordMeta putFieldUpdatedMapItem(String key, FieldUpdatedValue fieldUpdatedMapItem) { - if (this.fieldUpdatedMap == null) { - this.fieldUpdatedMap = new HashMap<>(); - } - this.fieldUpdatedMap.put(key, fieldUpdatedMapItem); - return this; - } - - /** - * Get fieldUpdatedMap - * @return fieldUpdatedMap - **/ - @javax.annotation.Nullable - public Map getFieldUpdatedMap() { - return fieldUpdatedMap; - } - - - public void setFieldUpdatedMap(Map fieldUpdatedMap) { - this.fieldUpdatedMap = fieldUpdatedMap; - } - - - public RecordMeta updatedAt(Long updatedAt) { - - this.updatedAt = updatedAt; - return this; - } - - /** - * Get updatedAt - * minimum: 0 - * @return updatedAt - **/ - @javax.annotation.Nullable - public Long getUpdatedAt() { - return updatedAt; - } - - - public void setUpdatedAt(Long updatedAt) { - this.updatedAt = updatedAt; - } - - - public RecordMeta updatedBy(String updatedBy) { - - this.updatedBy = updatedBy; - return this; - } - - /** - * Get updatedBy - * @return updatedBy - **/ - @javax.annotation.Nullable - public String getUpdatedBy() { - return updatedBy; - } - - - public void setUpdatedBy(String updatedBy) { - this.updatedBy = updatedBy; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - RecordMeta recordMeta = (RecordMeta) o; - return Objects.equals(this.createdAt, recordMeta.createdAt) && - Objects.equals(this.createdBy, recordMeta.createdBy) && - Objects.equals(this.fieldExtraMap, recordMeta.fieldExtraMap) && - Objects.equals(this.fieldUpdatedMap, recordMeta.fieldUpdatedMap) && - Objects.equals(this.updatedAt, recordMeta.updatedAt) && - Objects.equals(this.updatedBy, recordMeta.updatedBy); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(createdAt, createdBy, fieldExtraMap, fieldUpdatedMap, updatedAt, updatedBy); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class RecordMeta {\n"); - sb.append(" createdAt: ").append(toIndentedString(createdAt)).append("\n"); - sb.append(" createdBy: ").append(toIndentedString(createdBy)).append("\n"); - sb.append(" fieldExtraMap: ").append(toIndentedString(fieldExtraMap)).append("\n"); - sb.append(" fieldUpdatedMap: ").append(toIndentedString(fieldUpdatedMap)).append("\n"); - sb.append(" updatedAt: ").append(toIndentedString(updatedAt)).append("\n"); - sb.append(" updatedBy: ").append(toIndentedString(updatedBy)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("createdAt"); - openapiFields.add("createdBy"); - openapiFields.add("fieldExtraMap"); - openapiFields.add("fieldUpdatedMap"); - openapiFields.add("updatedAt"); - openapiFields.add("updatedBy"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to RecordMeta - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!RecordMeta.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in RecordMeta is not found in the empty JSON string", RecordMeta.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!RecordMeta.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `RecordMeta` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if ((jsonObj.get("createdBy") != null && !jsonObj.get("createdBy").isJsonNull()) && !jsonObj.get("createdBy").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `createdBy` to be a primitive type in the JSON string but got `%s`", jsonObj.get("createdBy").toString())); - } - if ((jsonObj.get("updatedBy") != null && !jsonObj.get("updatedBy").isJsonNull()) && !jsonObj.get("updatedBy").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `updatedBy` to be a primitive type in the JSON string but got `%s`", jsonObj.get("updatedBy").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!RecordMeta.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'RecordMeta' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(RecordMeta.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, RecordMeta value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public RecordMeta read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of RecordMeta given an JSON string - * - * @param jsonString JSON string - * @return An instance of RecordMeta - * @throws IOException if the JSON string is invalid with respect to RecordMeta - */ - public static RecordMeta fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, RecordMeta.class); - } - - /** - * Convert an instance of RecordMeta to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/RecordSO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/RecordSO.java deleted file mode 100644 index 15d3b9fbd2..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/RecordSO.java +++ /dev/null @@ -1,470 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.apitable.databusclient.model.Comments; -import com.apitable.databusclient.model.RecordMeta; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * RecordSO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class RecordSO { - public static final String SERIALIZED_NAME_COMMENT_COUNT = "commentCount"; - @SerializedName(SERIALIZED_NAME_COMMENT_COUNT) - private Integer commentCount; - - public static final String SERIALIZED_NAME_COMMENTS = "comments"; - @SerializedName(SERIALIZED_NAME_COMMENTS) - private List comments; - - public static final String SERIALIZED_NAME_CREATED_AT = "createdAt"; - @SerializedName(SERIALIZED_NAME_CREATED_AT) - private Long createdAt; - - public static final String SERIALIZED_NAME_DATA = "data"; - @SerializedName(SERIALIZED_NAME_DATA) - private Object data = null; - - public static final String SERIALIZED_NAME_ID = "id"; - @SerializedName(SERIALIZED_NAME_ID) - private String id; - - public static final String SERIALIZED_NAME_RECORD_META = "recordMeta"; - @SerializedName(SERIALIZED_NAME_RECORD_META) - private RecordMeta recordMeta; - - public static final String SERIALIZED_NAME_REVISION_HISTORY = "revisionHistory"; - @SerializedName(SERIALIZED_NAME_REVISION_HISTORY) - private List revisionHistory; - - public static final String SERIALIZED_NAME_UPDATED_AT = "updatedAt"; - @SerializedName(SERIALIZED_NAME_UPDATED_AT) - private Long updatedAt; - - public RecordSO() { - } - - public RecordSO commentCount(Integer commentCount) { - - this.commentCount = commentCount; - return this; - } - - /** - * Get commentCount - * minimum: 0 - * @return commentCount - **/ - @javax.annotation.Nonnull - public Integer getCommentCount() { - return commentCount; - } - - - public void setCommentCount(Integer commentCount) { - this.commentCount = commentCount; - } - - - public RecordSO comments(List comments) { - - this.comments = comments; - return this; - } - - public RecordSO addCommentsItem(Comments commentsItem) { - if (this.comments == null) { - this.comments = new ArrayList<>(); - } - this.comments.add(commentsItem); - return this; - } - - /** - * Get comments - * @return comments - **/ - @javax.annotation.Nullable - public List getComments() { - return comments; - } - - - public void setComments(List comments) { - this.comments = comments; - } - - - public RecordSO createdAt(Long createdAt) { - - this.createdAt = createdAt; - return this; - } - - /** - * Get createdAt - * @return createdAt - **/ - @javax.annotation.Nullable - public Long getCreatedAt() { - return createdAt; - } - - - public void setCreatedAt(Long createdAt) { - this.createdAt = createdAt; - } - - - public RecordSO data(Object data) { - - this.data = data; - return this; - } - - /** - * Get data - * @return data - **/ - @javax.annotation.Nullable - public Object getData() { - return data; - } - - - public void setData(Object data) { - this.data = data; - } - - - public RecordSO id(String id) { - - this.id = id; - return this; - } - - /** - * Get id - * @return id - **/ - @javax.annotation.Nonnull - public String getId() { - return id; - } - - - public void setId(String id) { - this.id = id; - } - - - public RecordSO recordMeta(RecordMeta recordMeta) { - - this.recordMeta = recordMeta; - return this; - } - - /** - * Get recordMeta - * @return recordMeta - **/ - @javax.annotation.Nullable - public RecordMeta getRecordMeta() { - return recordMeta; - } - - - public void setRecordMeta(RecordMeta recordMeta) { - this.recordMeta = recordMeta; - } - - - public RecordSO revisionHistory(List revisionHistory) { - - this.revisionHistory = revisionHistory; - return this; - } - - public RecordSO addRevisionHistoryItem(Integer revisionHistoryItem) { - if (this.revisionHistory == null) { - this.revisionHistory = new ArrayList<>(); - } - this.revisionHistory.add(revisionHistoryItem); - return this; - } - - /** - * Get revisionHistory - * @return revisionHistory - **/ - @javax.annotation.Nullable - public List getRevisionHistory() { - return revisionHistory; - } - - - public void setRevisionHistory(List revisionHistory) { - this.revisionHistory = revisionHistory; - } - - - public RecordSO updatedAt(Long updatedAt) { - - this.updatedAt = updatedAt; - return this; - } - - /** - * Get updatedAt - * @return updatedAt - **/ - @javax.annotation.Nullable - public Long getUpdatedAt() { - return updatedAt; - } - - - public void setUpdatedAt(Long updatedAt) { - this.updatedAt = updatedAt; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - RecordSO recordSO = (RecordSO) o; - return Objects.equals(this.commentCount, recordSO.commentCount) && - Objects.equals(this.comments, recordSO.comments) && - Objects.equals(this.createdAt, recordSO.createdAt) && - Objects.equals(this.data, recordSO.data) && - Objects.equals(this.id, recordSO.id) && - Objects.equals(this.recordMeta, recordSO.recordMeta) && - Objects.equals(this.revisionHistory, recordSO.revisionHistory) && - Objects.equals(this.updatedAt, recordSO.updatedAt); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(commentCount, comments, createdAt, data, id, recordMeta, revisionHistory, updatedAt); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class RecordSO {\n"); - sb.append(" commentCount: ").append(toIndentedString(commentCount)).append("\n"); - sb.append(" comments: ").append(toIndentedString(comments)).append("\n"); - sb.append(" createdAt: ").append(toIndentedString(createdAt)).append("\n"); - sb.append(" data: ").append(toIndentedString(data)).append("\n"); - sb.append(" id: ").append(toIndentedString(id)).append("\n"); - sb.append(" recordMeta: ").append(toIndentedString(recordMeta)).append("\n"); - sb.append(" revisionHistory: ").append(toIndentedString(revisionHistory)).append("\n"); - sb.append(" updatedAt: ").append(toIndentedString(updatedAt)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("commentCount"); - openapiFields.add("comments"); - openapiFields.add("createdAt"); - openapiFields.add("data"); - openapiFields.add("id"); - openapiFields.add("recordMeta"); - openapiFields.add("revisionHistory"); - openapiFields.add("updatedAt"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("commentCount"); - openapiRequiredFields.add("data"); - openapiRequiredFields.add("id"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to RecordSO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!RecordSO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in RecordSO is not found in the empty JSON string", RecordSO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!RecordSO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `RecordSO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : RecordSO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if (jsonObj.get("comments") != null && !jsonObj.get("comments").isJsonNull()) { - JsonArray jsonArraycomments = jsonObj.getAsJsonArray("comments"); - if (jsonArraycomments != null) { - // ensure the json data is an array - if (!jsonObj.get("comments").isJsonArray()) { - throw new IllegalArgumentException(String.format("Expected the field `comments` to be an array in the JSON string but got `%s`", jsonObj.get("comments").toString())); - } - - // validate the optional field `comments` (array) - for (int i = 0; i < jsonArraycomments.size(); i++) { - Comments.validateJsonElement(jsonArraycomments.get(i)); - }; - } - } - if (!jsonObj.get("id").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `id` to be a primitive type in the JSON string but got `%s`", jsonObj.get("id").toString())); - } - // validate the optional field `recordMeta` - if (jsonObj.get("recordMeta") != null && !jsonObj.get("recordMeta").isJsonNull()) { - RecordMeta.validateJsonElement(jsonObj.get("recordMeta")); - } - // ensure the optional json data is an array if present - if (jsonObj.get("revisionHistory") != null && !jsonObj.get("revisionHistory").isJsonNull() && !jsonObj.get("revisionHistory").isJsonArray()) { - throw new IllegalArgumentException(String.format("Expected the field `revisionHistory` to be an array in the JSON string but got `%s`", jsonObj.get("revisionHistory").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!RecordSO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'RecordSO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(RecordSO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, RecordSO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public RecordSO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of RecordSO given an JSON string - * - * @param jsonString JSON string - * @return An instance of RecordSO - * @throws IOException if the JSON string is invalid with respect to RecordSO - */ - public static RecordSO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, RecordSO.class); - } - - /** - * Convert an instance of RecordSO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/RecordUpdateRO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/RecordUpdateRO.java deleted file mode 100644 index fd0f27a9f1..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/RecordUpdateRO.java +++ /dev/null @@ -1,265 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.apitable.databusclient.model.FieldKeyEnum; -import com.apitable.databusclient.model.FieldUpdateRO; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * RecordUpdateRO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class RecordUpdateRO { - public static final String SERIALIZED_NAME_FIELD_KEY = "fieldKey"; - @SerializedName(SERIALIZED_NAME_FIELD_KEY) - private FieldKeyEnum fieldKey; - - public static final String SERIALIZED_NAME_RECORDS = "records"; - @SerializedName(SERIALIZED_NAME_RECORDS) - private List records = new ArrayList<>(); - - public RecordUpdateRO() { - } - - public RecordUpdateRO fieldKey(FieldKeyEnum fieldKey) { - - this.fieldKey = fieldKey; - return this; - } - - /** - * Get fieldKey - * @return fieldKey - **/ - @javax.annotation.Nonnull - public FieldKeyEnum getFieldKey() { - return fieldKey; - } - - - public void setFieldKey(FieldKeyEnum fieldKey) { - this.fieldKey = fieldKey; - } - - - public RecordUpdateRO records(List records) { - - this.records = records; - return this; - } - - public RecordUpdateRO addRecordsItem(FieldUpdateRO recordsItem) { - if (this.records == null) { - this.records = new ArrayList<>(); - } - this.records.add(recordsItem); - return this; - } - - /** - * Get records - * @return records - **/ - @javax.annotation.Nonnull - public List getRecords() { - return records; - } - - - public void setRecords(List records) { - this.records = records; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - RecordUpdateRO recordUpdateRO = (RecordUpdateRO) o; - return Objects.equals(this.fieldKey, recordUpdateRO.fieldKey) && - Objects.equals(this.records, recordUpdateRO.records); - } - - @Override - public int hashCode() { - return Objects.hash(fieldKey, records); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class RecordUpdateRO {\n"); - sb.append(" fieldKey: ").append(toIndentedString(fieldKey)).append("\n"); - sb.append(" records: ").append(toIndentedString(records)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("fieldKey"); - openapiFields.add("records"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("fieldKey"); - openapiRequiredFields.add("records"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to RecordUpdateRO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!RecordUpdateRO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in RecordUpdateRO is not found in the empty JSON string", RecordUpdateRO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!RecordUpdateRO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `RecordUpdateRO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : RecordUpdateRO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - // ensure the json data is an array - if (!jsonObj.get("records").isJsonArray()) { - throw new IllegalArgumentException(String.format("Expected the field `records` to be an array in the JSON string but got `%s`", jsonObj.get("records").toString())); - } - - JsonArray jsonArrayrecords = jsonObj.getAsJsonArray("records"); - // validate the required field `records` (array) - for (int i = 0; i < jsonArrayrecords.size(); i++) { - FieldUpdateRO.validateJsonElement(jsonArrayrecords.get(i)); - }; - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!RecordUpdateRO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'RecordUpdateRO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(RecordUpdateRO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, RecordUpdateRO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public RecordUpdateRO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of RecordUpdateRO given an JSON string - * - * @param jsonString JSON string - * @return An instance of RecordUpdateRO - * @throws IOException if the JSON string is invalid with respect to RecordUpdateRO - */ - public static RecordUpdateRO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, RecordUpdateRO.class); - } - - /** - * Convert an instance of RecordUpdateRO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/RecordVo.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/RecordVo.java deleted file mode 100644 index effcfbc01c..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/RecordVo.java +++ /dev/null @@ -1,316 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * RecordVo - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class RecordVo { - public static final String SERIALIZED_NAME_CREATED_AT = "createdAt"; - @SerializedName(SERIALIZED_NAME_CREATED_AT) - private Long createdAt; - - public static final String SERIALIZED_NAME_FIELDS = "fields"; - @SerializedName(SERIALIZED_NAME_FIELDS) - private Map fields = new HashMap<>(); - - public static final String SERIALIZED_NAME_RECORD_ID = "recordId"; - @SerializedName(SERIALIZED_NAME_RECORD_ID) - private String recordId; - - public static final String SERIALIZED_NAME_UPDATED_AT = "updatedAt"; - @SerializedName(SERIALIZED_NAME_UPDATED_AT) - private Long updatedAt; - - public RecordVo() { - } - - public RecordVo createdAt(Long createdAt) { - - this.createdAt = createdAt; - return this; - } - - /** - * Get createdAt - * minimum: 0 - * @return createdAt - **/ - @javax.annotation.Nonnull - public Long getCreatedAt() { - return createdAt; - } - - - public void setCreatedAt(Long createdAt) { - this.createdAt = createdAt; - } - - - public RecordVo fields(Map fields) { - - this.fields = fields; - return this; - } - - public RecordVo putFieldsItem(String key, Object fieldsItem) { - if (this.fields == null) { - this.fields = new HashMap<>(); - } - this.fields.put(key, fieldsItem); - return this; - } - - /** - * Get fields - * @return fields - **/ - @javax.annotation.Nonnull - public Map getFields() { - return fields; - } - - - public void setFields(Map fields) { - this.fields = fields; - } - - - public RecordVo recordId(String recordId) { - - this.recordId = recordId; - return this; - } - - /** - * Get recordId - * @return recordId - **/ - @javax.annotation.Nonnull - public String getRecordId() { - return recordId; - } - - - public void setRecordId(String recordId) { - this.recordId = recordId; - } - - - public RecordVo updatedAt(Long updatedAt) { - - this.updatedAt = updatedAt; - return this; - } - - /** - * Get updatedAt - * minimum: 0 - * @return updatedAt - **/ - @javax.annotation.Nonnull - public Long getUpdatedAt() { - return updatedAt; - } - - - public void setUpdatedAt(Long updatedAt) { - this.updatedAt = updatedAt; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - RecordVo recordVo = (RecordVo) o; - return Objects.equals(this.createdAt, recordVo.createdAt) && - Objects.equals(this.fields, recordVo.fields) && - Objects.equals(this.recordId, recordVo.recordId) && - Objects.equals(this.updatedAt, recordVo.updatedAt); - } - - @Override - public int hashCode() { - return Objects.hash(createdAt, fields, recordId, updatedAt); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class RecordVo {\n"); - sb.append(" createdAt: ").append(toIndentedString(createdAt)).append("\n"); - sb.append(" fields: ").append(toIndentedString(fields)).append("\n"); - sb.append(" recordId: ").append(toIndentedString(recordId)).append("\n"); - sb.append(" updatedAt: ").append(toIndentedString(updatedAt)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("createdAt"); - openapiFields.add("fields"); - openapiFields.add("recordId"); - openapiFields.add("updatedAt"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("createdAt"); - openapiRequiredFields.add("fields"); - openapiRequiredFields.add("recordId"); - openapiRequiredFields.add("updatedAt"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to RecordVo - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!RecordVo.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in RecordVo is not found in the empty JSON string", RecordVo.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!RecordVo.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `RecordVo` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : RecordVo.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if (!jsonObj.get("recordId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `recordId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("recordId").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!RecordVo.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'RecordVo' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(RecordVo.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, RecordVo value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public RecordVo read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of RecordVo given an JSON string - * - * @param jsonString JSON string - * @return An instance of RecordVo - * @throws IOException if the JSON string is invalid with respect to RecordVo - */ - public static RecordVo fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, RecordVo.class); - } - - /** - * Convert an instance of RecordVo to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/SingleSelectProperty.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/SingleSelectProperty.java deleted file mode 100644 index a0f1c44bfc..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/SingleSelectProperty.java +++ /dev/null @@ -1,278 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * SingleSelectProperty - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class SingleSelectProperty { - public static final String SERIALIZED_NAME_COLOR = "color"; - @SerializedName(SERIALIZED_NAME_COLOR) - private Object color = null; - - public static final String SERIALIZED_NAME_ID = "id"; - @SerializedName(SERIALIZED_NAME_ID) - private String id; - - public static final String SERIALIZED_NAME_NAME = "name"; - @SerializedName(SERIALIZED_NAME_NAME) - private String name; - - public SingleSelectProperty() { - } - - public SingleSelectProperty color(Object color) { - - this.color = color; - return this; - } - - /** - * Get color - * @return color - **/ - @javax.annotation.Nullable - public Object getColor() { - return color; - } - - - public void setColor(Object color) { - this.color = color; - } - - - public SingleSelectProperty id(String id) { - - this.id = id; - return this; - } - - /** - * Get id - * @return id - **/ - @javax.annotation.Nonnull - public String getId() { - return id; - } - - - public void setId(String id) { - this.id = id; - } - - - public SingleSelectProperty name(String name) { - - this.name = name; - return this; - } - - /** - * Get name - * @return name - **/ - @javax.annotation.Nonnull - public String getName() { - return name; - } - - - public void setName(String name) { - this.name = name; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - SingleSelectProperty singleSelectProperty = (SingleSelectProperty) o; - return Objects.equals(this.color, singleSelectProperty.color) && - Objects.equals(this.id, singleSelectProperty.id) && - Objects.equals(this.name, singleSelectProperty.name); - } - - @Override - public int hashCode() { - return Objects.hash(color, id, name); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class SingleSelectProperty {\n"); - sb.append(" color: ").append(toIndentedString(color)).append("\n"); - sb.append(" id: ").append(toIndentedString(id)).append("\n"); - sb.append(" name: ").append(toIndentedString(name)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("color"); - openapiFields.add("id"); - openapiFields.add("name"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("color"); - openapiRequiredFields.add("id"); - openapiRequiredFields.add("name"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to SingleSelectProperty - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!SingleSelectProperty.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in SingleSelectProperty is not found in the empty JSON string", SingleSelectProperty.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!SingleSelectProperty.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `SingleSelectProperty` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : SingleSelectProperty.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if (!jsonObj.get("id").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `id` to be a primitive type in the JSON string but got `%s`", jsonObj.get("id").toString())); - } - if (!jsonObj.get("name").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `name` to be a primitive type in the JSON string but got `%s`", jsonObj.get("name").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!SingleSelectProperty.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'SingleSelectProperty' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(SingleSelectProperty.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, SingleSelectProperty value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public SingleSelectProperty read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of SingleSelectProperty given an JSON string - * - * @param jsonString JSON string - * @return An instance of SingleSelectProperty - * @throws IOException if the JSON string is invalid with respect to SingleSelectProperty - */ - public static SingleSelectProperty fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, SingleSelectProperty.class); - } - - /** - * Convert an instance of SingleSelectProperty to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/SingleTextFieldPropertySO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/SingleTextFieldPropertySO.java deleted file mode 100644 index f67e6e8cca..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/SingleTextFieldPropertySO.java +++ /dev/null @@ -1,221 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * SingleTextFieldPropertySO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class SingleTextFieldPropertySO { - public static final String SERIALIZED_NAME_DEFAULT_VALUE = "defaultValue"; - @SerializedName(SERIALIZED_NAME_DEFAULT_VALUE) - private String defaultValue; - - public SingleTextFieldPropertySO() { - } - - public SingleTextFieldPropertySO defaultValue(String defaultValue) { - - this.defaultValue = defaultValue; - return this; - } - - /** - * Get defaultValue - * @return defaultValue - **/ - @javax.annotation.Nullable - public String getDefaultValue() { - return defaultValue; - } - - - public void setDefaultValue(String defaultValue) { - this.defaultValue = defaultValue; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - SingleTextFieldPropertySO singleTextFieldPropertySO = (SingleTextFieldPropertySO) o; - return Objects.equals(this.defaultValue, singleTextFieldPropertySO.defaultValue); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(defaultValue); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class SingleTextFieldPropertySO {\n"); - sb.append(" defaultValue: ").append(toIndentedString(defaultValue)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("defaultValue"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to SingleTextFieldPropertySO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!SingleTextFieldPropertySO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in SingleTextFieldPropertySO is not found in the empty JSON string", SingleTextFieldPropertySO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!SingleTextFieldPropertySO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `SingleTextFieldPropertySO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if ((jsonObj.get("defaultValue") != null && !jsonObj.get("defaultValue").isJsonNull()) && !jsonObj.get("defaultValue").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `defaultValue` to be a primitive type in the JSON string but got `%s`", jsonObj.get("defaultValue").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!SingleTextFieldPropertySO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'SingleTextFieldPropertySO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(SingleTextFieldPropertySO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, SingleTextFieldPropertySO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public SingleTextFieldPropertySO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of SingleTextFieldPropertySO given an JSON string - * - * @param jsonString JSON string - * @return An instance of SingleTextFieldPropertySO - * @throws IOException if the JSON string is invalid with respect to SingleTextFieldPropertySO - */ - public static SingleTextFieldPropertySO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, SingleTextFieldPropertySO.class); - } - - /** - * Convert an instance of SingleTextFieldPropertySO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/SortRO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/SortRO.java deleted file mode 100644 index b66a1c433b..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/SortRO.java +++ /dev/null @@ -1,247 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.apitable.databusclient.model.OrderEnum; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * SortRO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class SortRO { - public static final String SERIALIZED_NAME_FIELD = "field"; - @SerializedName(SERIALIZED_NAME_FIELD) - private String field; - - public static final String SERIALIZED_NAME_ORDER = "order"; - @SerializedName(SERIALIZED_NAME_ORDER) - private OrderEnum order; - - public SortRO() { - } - - public SortRO field(String field) { - - this.field = field; - return this; - } - - /** - * Get field - * @return field - **/ - @javax.annotation.Nonnull - public String getField() { - return field; - } - - - public void setField(String field) { - this.field = field; - } - - - public SortRO order(OrderEnum order) { - - this.order = order; - return this; - } - - /** - * Get order - * @return order - **/ - @javax.annotation.Nonnull - public OrderEnum getOrder() { - return order; - } - - - public void setOrder(OrderEnum order) { - this.order = order; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - SortRO sortRO = (SortRO) o; - return Objects.equals(this.field, sortRO.field) && - Objects.equals(this.order, sortRO.order); - } - - @Override - public int hashCode() { - return Objects.hash(field, order); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class SortRO {\n"); - sb.append(" field: ").append(toIndentedString(field)).append("\n"); - sb.append(" order: ").append(toIndentedString(order)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("field"); - openapiFields.add("order"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("field"); - openapiRequiredFields.add("order"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to SortRO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!SortRO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in SortRO is not found in the empty JSON string", SortRO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!SortRO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `SortRO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : SortRO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if (!jsonObj.get("field").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `field` to be a primitive type in the JSON string but got `%s`", jsonObj.get("field").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!SortRO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'SortRO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(SortRO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, SortRO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public SortRO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of SortRO given an JSON string - * - * @param jsonString JSON string - * @return An instance of SortRO - * @throws IOException if the JSON string is invalid with respect to SortRO - */ - public static SortRO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, SortRO.class); - } - - /** - * Convert an instance of SortRO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/TimeFormat.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/TimeFormat.java deleted file mode 100644 index 4d662ce3c2..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/TimeFormat.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -/** - * Gets or Sets TimeFormat - */ -@JsonAdapter(TimeFormat.Adapter.class) -public enum TimeFormat { - - HHMM("HHmm"); - - private String value; - - TimeFormat(String value) { - this.value = value; - } - - public String getValue() { - return value; - } - - @Override - public String toString() { - return String.valueOf(value); - } - - public static TimeFormat fromValue(String value) { - for (TimeFormat b : TimeFormat.values()) { - if (b.value.equals(value)) { - return b; - } - } - throw new IllegalArgumentException("Unexpected value '" + value + "'"); - } - - public static class Adapter extends TypeAdapter { - @Override - public void write(final JsonWriter jsonWriter, final TimeFormat enumeration) throws IOException { - jsonWriter.value(enumeration.getValue()); - } - - @Override - public TimeFormat read(final JsonReader jsonReader) throws IOException { - String value = jsonReader.nextString(); - return TimeFormat.fromValue(value); - } - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/UnitSO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/UnitSO.java deleted file mode 100644 index 3cbeda080e..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/UnitSO.java +++ /dev/null @@ -1,578 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * UnitSO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class UnitSO { - public static final String SERIALIZED_NAME_AVATAR = "avatar"; - @SerializedName(SERIALIZED_NAME_AVATAR) - private String avatar; - - public static final String SERIALIZED_NAME_AVATAR_COLOR = "avatarColor"; - @SerializedName(SERIALIZED_NAME_AVATAR_COLOR) - private Integer avatarColor; - - public static final String SERIALIZED_NAME_IS_ACTIVE = "isActive"; - @SerializedName(SERIALIZED_NAME_IS_ACTIVE) - private Integer isActive; - - public static final String SERIALIZED_NAME_IS_DELETED = "isDeleted"; - @SerializedName(SERIALIZED_NAME_IS_DELETED) - private Integer isDeleted; - - public static final String SERIALIZED_NAME_IS_MEMBER_NAME_MODIFIED = "isMemberNameModified"; - @SerializedName(SERIALIZED_NAME_IS_MEMBER_NAME_MODIFIED) - private Boolean isMemberNameModified; - - public static final String SERIALIZED_NAME_IS_NICK_NAME_MODIFIED = "isNickNameModified"; - @SerializedName(SERIALIZED_NAME_IS_NICK_NAME_MODIFIED) - private Boolean isNickNameModified; - - public static final String SERIALIZED_NAME_NAME = "name"; - @SerializedName(SERIALIZED_NAME_NAME) - private String name; - - public static final String SERIALIZED_NAME_NICK_NAME = "nickName"; - @SerializedName(SERIALIZED_NAME_NICK_NAME) - private String nickName; - - public static final String SERIALIZED_NAME_ORIGINAL_UNIT_ID = "originalUnitId"; - @SerializedName(SERIALIZED_NAME_ORIGINAL_UNIT_ID) - private String originalUnitId; - - public static final String SERIALIZED_NAME_TYPE = "type"; - @SerializedName(SERIALIZED_NAME_TYPE) - private Integer type; - - public static final String SERIALIZED_NAME_UNIT_ID = "unitId"; - @SerializedName(SERIALIZED_NAME_UNIT_ID) - private String unitId; - - public static final String SERIALIZED_NAME_USER_ID = "userId"; - @SerializedName(SERIALIZED_NAME_USER_ID) - private String userId; - - public static final String SERIALIZED_NAME_UUID = "uuid"; - @SerializedName(SERIALIZED_NAME_UUID) - private String uuid; - - public UnitSO() { - } - - public UnitSO avatar(String avatar) { - - this.avatar = avatar; - return this; - } - - /** - * Get avatar - * @return avatar - **/ - @javax.annotation.Nullable - public String getAvatar() { - return avatar; - } - - - public void setAvatar(String avatar) { - this.avatar = avatar; - } - - - public UnitSO avatarColor(Integer avatarColor) { - - this.avatarColor = avatarColor; - return this; - } - - /** - * Get avatarColor - * @return avatarColor - **/ - @javax.annotation.Nullable - public Integer getAvatarColor() { - return avatarColor; - } - - - public void setAvatarColor(Integer avatarColor) { - this.avatarColor = avatarColor; - } - - - public UnitSO isActive(Integer isActive) { - - this.isActive = isActive; - return this; - } - - /** - * Get isActive - * minimum: 0 - * @return isActive - **/ - @javax.annotation.Nullable - public Integer getIsActive() { - return isActive; - } - - - public void setIsActive(Integer isActive) { - this.isActive = isActive; - } - - - public UnitSO isDeleted(Integer isDeleted) { - - this.isDeleted = isDeleted; - return this; - } - - /** - * Get isDeleted - * minimum: 0 - * @return isDeleted - **/ - @javax.annotation.Nullable - public Integer getIsDeleted() { - return isDeleted; - } - - - public void setIsDeleted(Integer isDeleted) { - this.isDeleted = isDeleted; - } - - - public UnitSO isMemberNameModified(Boolean isMemberNameModified) { - - this.isMemberNameModified = isMemberNameModified; - return this; - } - - /** - * Get isMemberNameModified - * @return isMemberNameModified - **/ - @javax.annotation.Nullable - public Boolean getIsMemberNameModified() { - return isMemberNameModified; - } - - - public void setIsMemberNameModified(Boolean isMemberNameModified) { - this.isMemberNameModified = isMemberNameModified; - } - - - public UnitSO isNickNameModified(Boolean isNickNameModified) { - - this.isNickNameModified = isNickNameModified; - return this; - } - - /** - * Get isNickNameModified - * @return isNickNameModified - **/ - @javax.annotation.Nullable - public Boolean getIsNickNameModified() { - return isNickNameModified; - } - - - public void setIsNickNameModified(Boolean isNickNameModified) { - this.isNickNameModified = isNickNameModified; - } - - - public UnitSO name(String name) { - - this.name = name; - return this; - } - - /** - * Get name - * @return name - **/ - @javax.annotation.Nullable - public String getName() { - return name; - } - - - public void setName(String name) { - this.name = name; - } - - - public UnitSO nickName(String nickName) { - - this.nickName = nickName; - return this; - } - - /** - * Get nickName - * @return nickName - **/ - @javax.annotation.Nullable - public String getNickName() { - return nickName; - } - - - public void setNickName(String nickName) { - this.nickName = nickName; - } - - - public UnitSO originalUnitId(String originalUnitId) { - - this.originalUnitId = originalUnitId; - return this; - } - - /** - * Get originalUnitId - * @return originalUnitId - **/ - @javax.annotation.Nullable - public String getOriginalUnitId() { - return originalUnitId; - } - - - public void setOriginalUnitId(String originalUnitId) { - this.originalUnitId = originalUnitId; - } - - - public UnitSO type(Integer type) { - - this.type = type; - return this; - } - - /** - * Get type - * minimum: 0 - * @return type - **/ - @javax.annotation.Nullable - public Integer getType() { - return type; - } - - - public void setType(Integer type) { - this.type = type; - } - - - public UnitSO unitId(String unitId) { - - this.unitId = unitId; - return this; - } - - /** - * Get unitId - * @return unitId - **/ - @javax.annotation.Nullable - public String getUnitId() { - return unitId; - } - - - public void setUnitId(String unitId) { - this.unitId = unitId; - } - - - public UnitSO userId(String userId) { - - this.userId = userId; - return this; - } - - /** - * Get userId - * @return userId - **/ - @javax.annotation.Nullable - public String getUserId() { - return userId; - } - - - public void setUserId(String userId) { - this.userId = userId; - } - - - public UnitSO uuid(String uuid) { - - this.uuid = uuid; - return this; - } - - /** - * Get uuid - * @return uuid - **/ - @javax.annotation.Nullable - public String getUuid() { - return uuid; - } - - - public void setUuid(String uuid) { - this.uuid = uuid; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - UnitSO unitSO = (UnitSO) o; - return Objects.equals(this.avatar, unitSO.avatar) && - Objects.equals(this.avatarColor, unitSO.avatarColor) && - Objects.equals(this.isActive, unitSO.isActive) && - Objects.equals(this.isDeleted, unitSO.isDeleted) && - Objects.equals(this.isMemberNameModified, unitSO.isMemberNameModified) && - Objects.equals(this.isNickNameModified, unitSO.isNickNameModified) && - Objects.equals(this.name, unitSO.name) && - Objects.equals(this.nickName, unitSO.nickName) && - Objects.equals(this.originalUnitId, unitSO.originalUnitId) && - Objects.equals(this.type, unitSO.type) && - Objects.equals(this.unitId, unitSO.unitId) && - Objects.equals(this.userId, unitSO.userId) && - Objects.equals(this.uuid, unitSO.uuid); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(avatar, avatarColor, isActive, isDeleted, isMemberNameModified, isNickNameModified, name, nickName, originalUnitId, type, unitId, userId, uuid); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class UnitSO {\n"); - sb.append(" avatar: ").append(toIndentedString(avatar)).append("\n"); - sb.append(" avatarColor: ").append(toIndentedString(avatarColor)).append("\n"); - sb.append(" isActive: ").append(toIndentedString(isActive)).append("\n"); - sb.append(" isDeleted: ").append(toIndentedString(isDeleted)).append("\n"); - sb.append(" isMemberNameModified: ").append(toIndentedString(isMemberNameModified)).append("\n"); - sb.append(" isNickNameModified: ").append(toIndentedString(isNickNameModified)).append("\n"); - sb.append(" name: ").append(toIndentedString(name)).append("\n"); - sb.append(" nickName: ").append(toIndentedString(nickName)).append("\n"); - sb.append(" originalUnitId: ").append(toIndentedString(originalUnitId)).append("\n"); - sb.append(" type: ").append(toIndentedString(type)).append("\n"); - sb.append(" unitId: ").append(toIndentedString(unitId)).append("\n"); - sb.append(" userId: ").append(toIndentedString(userId)).append("\n"); - sb.append(" uuid: ").append(toIndentedString(uuid)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("avatar"); - openapiFields.add("avatarColor"); - openapiFields.add("isActive"); - openapiFields.add("isDeleted"); - openapiFields.add("isMemberNameModified"); - openapiFields.add("isNickNameModified"); - openapiFields.add("name"); - openapiFields.add("nickName"); - openapiFields.add("originalUnitId"); - openapiFields.add("type"); - openapiFields.add("unitId"); - openapiFields.add("userId"); - openapiFields.add("uuid"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to UnitSO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!UnitSO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in UnitSO is not found in the empty JSON string", UnitSO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!UnitSO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `UnitSO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if ((jsonObj.get("avatar") != null && !jsonObj.get("avatar").isJsonNull()) && !jsonObj.get("avatar").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `avatar` to be a primitive type in the JSON string but got `%s`", jsonObj.get("avatar").toString())); - } - if ((jsonObj.get("name") != null && !jsonObj.get("name").isJsonNull()) && !jsonObj.get("name").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `name` to be a primitive type in the JSON string but got `%s`", jsonObj.get("name").toString())); - } - if ((jsonObj.get("nickName") != null && !jsonObj.get("nickName").isJsonNull()) && !jsonObj.get("nickName").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `nickName` to be a primitive type in the JSON string but got `%s`", jsonObj.get("nickName").toString())); - } - if ((jsonObj.get("originalUnitId") != null && !jsonObj.get("originalUnitId").isJsonNull()) && !jsonObj.get("originalUnitId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `originalUnitId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("originalUnitId").toString())); - } - if ((jsonObj.get("unitId") != null && !jsonObj.get("unitId").isJsonNull()) && !jsonObj.get("unitId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `unitId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("unitId").toString())); - } - if ((jsonObj.get("userId") != null && !jsonObj.get("userId").isJsonNull()) && !jsonObj.get("userId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `userId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("userId").toString())); - } - if ((jsonObj.get("uuid") != null && !jsonObj.get("uuid").isJsonNull()) && !jsonObj.get("uuid").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `uuid` to be a primitive type in the JSON string but got `%s`", jsonObj.get("uuid").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!UnitSO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'UnitSO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(UnitSO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, UnitSO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public UnitSO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of UnitSO given an JSON string - * - * @param jsonString JSON string - * @return An instance of UnitSO - * @throws IOException if the JSON string is invalid with respect to UnitSO - */ - public static UnitSO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, UnitSO.class); - } - - /** - * Convert an instance of UnitSO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/ViewColumnSO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/ViewColumnSO.java deleted file mode 100644 index 373df15001..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/ViewColumnSO.java +++ /dev/null @@ -1,397 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * ViewColumnSO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class ViewColumnSO { - public static final String SERIALIZED_NAME_FIELD_ID = "fieldId"; - @SerializedName(SERIALIZED_NAME_FIELD_ID) - private String fieldId; - - public static final String SERIALIZED_NAME_HIDDEN = "hidden"; - @SerializedName(SERIALIZED_NAME_HIDDEN) - private Boolean hidden; - - public static final String SERIALIZED_NAME_HIDDEN_IN_CALENDAR = "hiddenInCalendar"; - @SerializedName(SERIALIZED_NAME_HIDDEN_IN_CALENDAR) - private Boolean hiddenInCalendar; - - public static final String SERIALIZED_NAME_HIDDEN_IN_GANTT = "hiddenInGantt"; - @SerializedName(SERIALIZED_NAME_HIDDEN_IN_GANTT) - private Boolean hiddenInGantt; - - public static final String SERIALIZED_NAME_HIDDEN_IN_ORG_CHART = "hiddenInOrgChart"; - @SerializedName(SERIALIZED_NAME_HIDDEN_IN_ORG_CHART) - private Boolean hiddenInOrgChart; - - public static final String SERIALIZED_NAME_STAT_TYPE = "statType"; - @SerializedName(SERIALIZED_NAME_STAT_TYPE) - private Integer statType; - - public static final String SERIALIZED_NAME_WIDTH = "width"; - @SerializedName(SERIALIZED_NAME_WIDTH) - private Double width; - - public ViewColumnSO() { - } - - public ViewColumnSO fieldId(String fieldId) { - - this.fieldId = fieldId; - return this; - } - - /** - * Get fieldId - * @return fieldId - **/ - @javax.annotation.Nonnull - public String getFieldId() { - return fieldId; - } - - - public void setFieldId(String fieldId) { - this.fieldId = fieldId; - } - - - public ViewColumnSO hidden(Boolean hidden) { - - this.hidden = hidden; - return this; - } - - /** - * Get hidden - * @return hidden - **/ - @javax.annotation.Nullable - public Boolean getHidden() { - return hidden; - } - - - public void setHidden(Boolean hidden) { - this.hidden = hidden; - } - - - public ViewColumnSO hiddenInCalendar(Boolean hiddenInCalendar) { - - this.hiddenInCalendar = hiddenInCalendar; - return this; - } - - /** - * Get hiddenInCalendar - * @return hiddenInCalendar - **/ - @javax.annotation.Nullable - public Boolean getHiddenInCalendar() { - return hiddenInCalendar; - } - - - public void setHiddenInCalendar(Boolean hiddenInCalendar) { - this.hiddenInCalendar = hiddenInCalendar; - } - - - public ViewColumnSO hiddenInGantt(Boolean hiddenInGantt) { - - this.hiddenInGantt = hiddenInGantt; - return this; - } - - /** - * Get hiddenInGantt - * @return hiddenInGantt - **/ - @javax.annotation.Nullable - public Boolean getHiddenInGantt() { - return hiddenInGantt; - } - - - public void setHiddenInGantt(Boolean hiddenInGantt) { - this.hiddenInGantt = hiddenInGantt; - } - - - public ViewColumnSO hiddenInOrgChart(Boolean hiddenInOrgChart) { - - this.hiddenInOrgChart = hiddenInOrgChart; - return this; - } - - /** - * Get hiddenInOrgChart - * @return hiddenInOrgChart - **/ - @javax.annotation.Nullable - public Boolean getHiddenInOrgChart() { - return hiddenInOrgChart; - } - - - public void setHiddenInOrgChart(Boolean hiddenInOrgChart) { - this.hiddenInOrgChart = hiddenInOrgChart; - } - - - public ViewColumnSO statType(Integer statType) { - - this.statType = statType; - return this; - } - - /** - * Get statType - * @return statType - **/ - @javax.annotation.Nullable - public Integer getStatType() { - return statType; - } - - - public void setStatType(Integer statType) { - this.statType = statType; - } - - - public ViewColumnSO width(Double width) { - - this.width = width; - return this; - } - - /** - * Get width - * @return width - **/ - @javax.annotation.Nullable - public Double getWidth() { - return width; - } - - - public void setWidth(Double width) { - this.width = width; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ViewColumnSO viewColumnSO = (ViewColumnSO) o; - return Objects.equals(this.fieldId, viewColumnSO.fieldId) && - Objects.equals(this.hidden, viewColumnSO.hidden) && - Objects.equals(this.hiddenInCalendar, viewColumnSO.hiddenInCalendar) && - Objects.equals(this.hiddenInGantt, viewColumnSO.hiddenInGantt) && - Objects.equals(this.hiddenInOrgChart, viewColumnSO.hiddenInOrgChart) && - Objects.equals(this.statType, viewColumnSO.statType) && - Objects.equals(this.width, viewColumnSO.width); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(fieldId, hidden, hiddenInCalendar, hiddenInGantt, hiddenInOrgChart, statType, width); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class ViewColumnSO {\n"); - sb.append(" fieldId: ").append(toIndentedString(fieldId)).append("\n"); - sb.append(" hidden: ").append(toIndentedString(hidden)).append("\n"); - sb.append(" hiddenInCalendar: ").append(toIndentedString(hiddenInCalendar)).append("\n"); - sb.append(" hiddenInGantt: ").append(toIndentedString(hiddenInGantt)).append("\n"); - sb.append(" hiddenInOrgChart: ").append(toIndentedString(hiddenInOrgChart)).append("\n"); - sb.append(" statType: ").append(toIndentedString(statType)).append("\n"); - sb.append(" width: ").append(toIndentedString(width)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("fieldId"); - openapiFields.add("hidden"); - openapiFields.add("hiddenInCalendar"); - openapiFields.add("hiddenInGantt"); - openapiFields.add("hiddenInOrgChart"); - openapiFields.add("statType"); - openapiFields.add("width"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("fieldId"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to ViewColumnSO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!ViewColumnSO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in ViewColumnSO is not found in the empty JSON string", ViewColumnSO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!ViewColumnSO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `ViewColumnSO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : ViewColumnSO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if (!jsonObj.get("fieldId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `fieldId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("fieldId").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!ViewColumnSO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'ViewColumnSO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(ViewColumnSO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, ViewColumnSO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public ViewColumnSO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of ViewColumnSO given an JSON string - * - * @param jsonString JSON string - * @return An instance of ViewColumnSO - * @throws IOException if the JSON string is invalid with respect to ViewColumnSO - */ - public static ViewColumnSO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, ViewColumnSO.class); - } - - /** - * Convert an instance of ViewColumnSO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/ViewRowSO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/ViewRowSO.java deleted file mode 100644 index ce1fd3fd47..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/ViewRowSO.java +++ /dev/null @@ -1,257 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * ViewRowSO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class ViewRowSO { - public static final String SERIALIZED_NAME_HIDDEN = "hidden"; - @SerializedName(SERIALIZED_NAME_HIDDEN) - private Boolean hidden; - - public static final String SERIALIZED_NAME_RECORD_ID = "recordId"; - @SerializedName(SERIALIZED_NAME_RECORD_ID) - private String recordId; - - public ViewRowSO() { - } - - public ViewRowSO hidden(Boolean hidden) { - - this.hidden = hidden; - return this; - } - - /** - * Get hidden - * @return hidden - **/ - @javax.annotation.Nullable - public Boolean getHidden() { - return hidden; - } - - - public void setHidden(Boolean hidden) { - this.hidden = hidden; - } - - - public ViewRowSO recordId(String recordId) { - - this.recordId = recordId; - return this; - } - - /** - * Get recordId - * @return recordId - **/ - @javax.annotation.Nonnull - public String getRecordId() { - return recordId; - } - - - public void setRecordId(String recordId) { - this.recordId = recordId; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ViewRowSO viewRowSO = (ViewRowSO) o; - return Objects.equals(this.hidden, viewRowSO.hidden) && - Objects.equals(this.recordId, viewRowSO.recordId); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(hidden, recordId); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class ViewRowSO {\n"); - sb.append(" hidden: ").append(toIndentedString(hidden)).append("\n"); - sb.append(" recordId: ").append(toIndentedString(recordId)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("hidden"); - openapiFields.add("recordId"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("recordId"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to ViewRowSO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!ViewRowSO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in ViewRowSO is not found in the empty JSON string", ViewRowSO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!ViewRowSO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `ViewRowSO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : ViewRowSO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if (!jsonObj.get("recordId").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `recordId` to be a primitive type in the JSON string but got `%s`", jsonObj.get("recordId").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!ViewRowSO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'ViewRowSO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(ViewRowSO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, ViewRowSO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public ViewRowSO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of ViewRowSO given an JSON string - * - * @param jsonString JSON string - * @return An instance of ViewRowSO - * @throws IOException if the JSON string is invalid with respect to ViewRowSO - */ - public static ViewRowSO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, ViewRowSO.class); - } - - /** - * Convert an instance of ViewRowSO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/ViewSO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/ViewSO.java deleted file mode 100644 index f518d837cb..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/ViewSO.java +++ /dev/null @@ -1,771 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.apitable.databusclient.model.IFilterInfo; -import com.apitable.databusclient.model.ISortInfo; -import com.apitable.databusclient.model.ISortedField; -import com.apitable.databusclient.model.IViewLockInfo; -import com.apitable.databusclient.model.ViewColumnSO; -import com.apitable.databusclient.model.ViewRowSO; -import com.apitable.databusclient.model.ViewStyleSo; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import org.openapitools.jackson.nullable.JsonNullable; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * ViewSO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class ViewSO { - public static final String SERIALIZED_NAME_AUTO_HEAD_HEIGHT = "autoHeadHeight"; - @SerializedName(SERIALIZED_NAME_AUTO_HEAD_HEIGHT) - private Boolean autoHeadHeight; - - public static final String SERIALIZED_NAME_AUTO_SAVE = "autoSave"; - @SerializedName(SERIALIZED_NAME_AUTO_SAVE) - private Boolean autoSave; - - public static final String SERIALIZED_NAME_COLUMNS = "columns"; - @SerializedName(SERIALIZED_NAME_COLUMNS) - private List columns = new ArrayList<>(); - - public static final String SERIALIZED_NAME_DESCRIPTION = "description"; - @SerializedName(SERIALIZED_NAME_DESCRIPTION) - private String description; - - public static final String SERIALIZED_NAME_DISPLAY_HIDDEN_COLUMN_WITHIN_MIRROR = "displayHiddenColumnWithinMirror"; - @SerializedName(SERIALIZED_NAME_DISPLAY_HIDDEN_COLUMN_WITHIN_MIRROR) - private Boolean displayHiddenColumnWithinMirror; - - public static final String SERIALIZED_NAME_FILTER_INFO = "filterInfo"; - @SerializedName(SERIALIZED_NAME_FILTER_INFO) - private IFilterInfo filterInfo; - - public static final String SERIALIZED_NAME_FROZEN_COLUMN_COUNT = "frozenColumnCount"; - @SerializedName(SERIALIZED_NAME_FROZEN_COLUMN_COUNT) - private Integer frozenColumnCount; - - public static final String SERIALIZED_NAME_GROUP_INFO = "groupInfo"; - @SerializedName(SERIALIZED_NAME_GROUP_INFO) - private List groupInfo; - - public static final String SERIALIZED_NAME_HIDDEN = "hidden"; - @SerializedName(SERIALIZED_NAME_HIDDEN) - private Boolean hidden; - - public static final String SERIALIZED_NAME_ID = "id"; - @SerializedName(SERIALIZED_NAME_ID) - private String id; - - public static final String SERIALIZED_NAME_LOCK_INFO = "lockInfo"; - @SerializedName(SERIALIZED_NAME_LOCK_INFO) - private IViewLockInfo lockInfo; - - public static final String SERIALIZED_NAME_NAME = "name"; - @SerializedName(SERIALIZED_NAME_NAME) - private String name; - - public static final String SERIALIZED_NAME_ROW_HEIGHT_LEVEL = "rowHeightLevel"; - @SerializedName(SERIALIZED_NAME_ROW_HEIGHT_LEVEL) - private Integer rowHeightLevel; - - public static final String SERIALIZED_NAME_ROWS = "rows"; - @SerializedName(SERIALIZED_NAME_ROWS) - private List rows; - - public static final String SERIALIZED_NAME_SORT_INFO = "sortInfo"; - @SerializedName(SERIALIZED_NAME_SORT_INFO) - private ISortInfo sortInfo; - - public static final String SERIALIZED_NAME_STYLE = "style"; - @SerializedName(SERIALIZED_NAME_STYLE) - private ViewStyleSo style; - - public static final String SERIALIZED_NAME_TYPE = "type"; - @SerializedName(SERIALIZED_NAME_TYPE) - private Long type; - - public ViewSO() { - } - - public ViewSO autoHeadHeight(Boolean autoHeadHeight) { - - this.autoHeadHeight = autoHeadHeight; - return this; - } - - /** - * Get autoHeadHeight - * @return autoHeadHeight - **/ - @javax.annotation.Nullable - public Boolean getAutoHeadHeight() { - return autoHeadHeight; - } - - - public void setAutoHeadHeight(Boolean autoHeadHeight) { - this.autoHeadHeight = autoHeadHeight; - } - - - public ViewSO autoSave(Boolean autoSave) { - - this.autoSave = autoSave; - return this; - } - - /** - * Get autoSave - * @return autoSave - **/ - @javax.annotation.Nullable - public Boolean getAutoSave() { - return autoSave; - } - - - public void setAutoSave(Boolean autoSave) { - this.autoSave = autoSave; - } - - - public ViewSO columns(List columns) { - - this.columns = columns; - return this; - } - - public ViewSO addColumnsItem(ViewColumnSO columnsItem) { - if (this.columns == null) { - this.columns = new ArrayList<>(); - } - this.columns.add(columnsItem); - return this; - } - - /** - * Get columns - * @return columns - **/ - @javax.annotation.Nonnull - public List getColumns() { - return columns; - } - - - public void setColumns(List columns) { - this.columns = columns; - } - - - public ViewSO description(String description) { - - this.description = description; - return this; - } - - /** - * Get description - * @return description - **/ - @javax.annotation.Nullable - public String getDescription() { - return description; - } - - - public void setDescription(String description) { - this.description = description; - } - - - public ViewSO displayHiddenColumnWithinMirror(Boolean displayHiddenColumnWithinMirror) { - - this.displayHiddenColumnWithinMirror = displayHiddenColumnWithinMirror; - return this; - } - - /** - * Get displayHiddenColumnWithinMirror - * @return displayHiddenColumnWithinMirror - **/ - @javax.annotation.Nullable - public Boolean getDisplayHiddenColumnWithinMirror() { - return displayHiddenColumnWithinMirror; - } - - - public void setDisplayHiddenColumnWithinMirror(Boolean displayHiddenColumnWithinMirror) { - this.displayHiddenColumnWithinMirror = displayHiddenColumnWithinMirror; - } - - - public ViewSO filterInfo(IFilterInfo filterInfo) { - - this.filterInfo = filterInfo; - return this; - } - - /** - * Get filterInfo - * @return filterInfo - **/ - @javax.annotation.Nullable - public IFilterInfo getFilterInfo() { - return filterInfo; - } - - - public void setFilterInfo(IFilterInfo filterInfo) { - this.filterInfo = filterInfo; - } - - - public ViewSO frozenColumnCount(Integer frozenColumnCount) { - - this.frozenColumnCount = frozenColumnCount; - return this; - } - - /** - * Get frozenColumnCount - * @return frozenColumnCount - **/ - @javax.annotation.Nullable - public Integer getFrozenColumnCount() { - return frozenColumnCount; - } - - - public void setFrozenColumnCount(Integer frozenColumnCount) { - this.frozenColumnCount = frozenColumnCount; - } - - - public ViewSO groupInfo(List groupInfo) { - - this.groupInfo = groupInfo; - return this; - } - - public ViewSO addGroupInfoItem(ISortedField groupInfoItem) { - if (this.groupInfo == null) { - this.groupInfo = new ArrayList<>(); - } - this.groupInfo.add(groupInfoItem); - return this; - } - - /** - * Get groupInfo - * @return groupInfo - **/ - @javax.annotation.Nullable - public List getGroupInfo() { - return groupInfo; - } - - - public void setGroupInfo(List groupInfo) { - this.groupInfo = groupInfo; - } - - - public ViewSO hidden(Boolean hidden) { - - this.hidden = hidden; - return this; - } - - /** - * Get hidden - * @return hidden - **/ - @javax.annotation.Nullable - public Boolean getHidden() { - return hidden; - } - - - public void setHidden(Boolean hidden) { - this.hidden = hidden; - } - - - public ViewSO id(String id) { - - this.id = id; - return this; - } - - /** - * Get id - * @return id - **/ - @javax.annotation.Nullable - public String getId() { - return id; - } - - - public void setId(String id) { - this.id = id; - } - - - public ViewSO lockInfo(IViewLockInfo lockInfo) { - - this.lockInfo = lockInfo; - return this; - } - - /** - * Get lockInfo - * @return lockInfo - **/ - @javax.annotation.Nullable - public IViewLockInfo getLockInfo() { - return lockInfo; - } - - - public void setLockInfo(IViewLockInfo lockInfo) { - this.lockInfo = lockInfo; - } - - - public ViewSO name(String name) { - - this.name = name; - return this; - } - - /** - * Get name - * @return name - **/ - @javax.annotation.Nullable - public String getName() { - return name; - } - - - public void setName(String name) { - this.name = name; - } - - - public ViewSO rowHeightLevel(Integer rowHeightLevel) { - - this.rowHeightLevel = rowHeightLevel; - return this; - } - - /** - * Get rowHeightLevel - * @return rowHeightLevel - **/ - @javax.annotation.Nullable - public Integer getRowHeightLevel() { - return rowHeightLevel; - } - - - public void setRowHeightLevel(Integer rowHeightLevel) { - this.rowHeightLevel = rowHeightLevel; - } - - - public ViewSO rows(List rows) { - - this.rows = rows; - return this; - } - - public ViewSO addRowsItem(ViewRowSO rowsItem) { - if (this.rows == null) { - this.rows = new ArrayList<>(); - } - this.rows.add(rowsItem); - return this; - } - - /** - * Get rows - * @return rows - **/ - @javax.annotation.Nullable - public List getRows() { - return rows; - } - - - public void setRows(List rows) { - this.rows = rows; - } - - - public ViewSO sortInfo(ISortInfo sortInfo) { - - this.sortInfo = sortInfo; - return this; - } - - /** - * Get sortInfo - * @return sortInfo - **/ - @javax.annotation.Nullable - public ISortInfo getSortInfo() { - return sortInfo; - } - - - public void setSortInfo(ISortInfo sortInfo) { - this.sortInfo = sortInfo; - } - - - public ViewSO style(ViewStyleSo style) { - - this.style = style; - return this; - } - - /** - * Get style - * @return style - **/ - @javax.annotation.Nullable - public ViewStyleSo getStyle() { - return style; - } - - - public void setStyle(ViewStyleSo style) { - this.style = style; - } - - - public ViewSO type(Long type) { - - this.type = type; - return this; - } - - /** - * Get type - * minimum: 0 - * @return type - **/ - @javax.annotation.Nullable - public Long getType() { - return type; - } - - - public void setType(Long type) { - this.type = type; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ViewSO viewSO = (ViewSO) o; - return Objects.equals(this.autoHeadHeight, viewSO.autoHeadHeight) && - Objects.equals(this.autoSave, viewSO.autoSave) && - Objects.equals(this.columns, viewSO.columns) && - Objects.equals(this.description, viewSO.description) && - Objects.equals(this.displayHiddenColumnWithinMirror, viewSO.displayHiddenColumnWithinMirror) && - Objects.equals(this.filterInfo, viewSO.filterInfo) && - Objects.equals(this.frozenColumnCount, viewSO.frozenColumnCount) && - Objects.equals(this.groupInfo, viewSO.groupInfo) && - Objects.equals(this.hidden, viewSO.hidden) && - Objects.equals(this.id, viewSO.id) && - Objects.equals(this.lockInfo, viewSO.lockInfo) && - Objects.equals(this.name, viewSO.name) && - Objects.equals(this.rowHeightLevel, viewSO.rowHeightLevel) && - Objects.equals(this.rows, viewSO.rows) && - Objects.equals(this.sortInfo, viewSO.sortInfo) && - Objects.equals(this.style, viewSO.style) && - Objects.equals(this.type, viewSO.type); - } - - private static boolean equalsNullable(JsonNullable a, JsonNullable b) { - return a == b || (a != null && b != null && a.isPresent() && b.isPresent() && Objects.deepEquals(a.get(), b.get())); - } - - @Override - public int hashCode() { - return Objects.hash(autoHeadHeight, autoSave, columns, description, displayHiddenColumnWithinMirror, filterInfo, frozenColumnCount, groupInfo, hidden, id, lockInfo, name, rowHeightLevel, rows, sortInfo, style, type); - } - - private static int hashCodeNullable(JsonNullable a) { - if (a == null) { - return 1; - } - return a.isPresent() ? Arrays.deepHashCode(new Object[]{a.get()}) : 31; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class ViewSO {\n"); - sb.append(" autoHeadHeight: ").append(toIndentedString(autoHeadHeight)).append("\n"); - sb.append(" autoSave: ").append(toIndentedString(autoSave)).append("\n"); - sb.append(" columns: ").append(toIndentedString(columns)).append("\n"); - sb.append(" description: ").append(toIndentedString(description)).append("\n"); - sb.append(" displayHiddenColumnWithinMirror: ").append(toIndentedString(displayHiddenColumnWithinMirror)).append("\n"); - sb.append(" filterInfo: ").append(toIndentedString(filterInfo)).append("\n"); - sb.append(" frozenColumnCount: ").append(toIndentedString(frozenColumnCount)).append("\n"); - sb.append(" groupInfo: ").append(toIndentedString(groupInfo)).append("\n"); - sb.append(" hidden: ").append(toIndentedString(hidden)).append("\n"); - sb.append(" id: ").append(toIndentedString(id)).append("\n"); - sb.append(" lockInfo: ").append(toIndentedString(lockInfo)).append("\n"); - sb.append(" name: ").append(toIndentedString(name)).append("\n"); - sb.append(" rowHeightLevel: ").append(toIndentedString(rowHeightLevel)).append("\n"); - sb.append(" rows: ").append(toIndentedString(rows)).append("\n"); - sb.append(" sortInfo: ").append(toIndentedString(sortInfo)).append("\n"); - sb.append(" style: ").append(toIndentedString(style)).append("\n"); - sb.append(" type: ").append(toIndentedString(type)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("autoHeadHeight"); - openapiFields.add("autoSave"); - openapiFields.add("columns"); - openapiFields.add("description"); - openapiFields.add("displayHiddenColumnWithinMirror"); - openapiFields.add("filterInfo"); - openapiFields.add("frozenColumnCount"); - openapiFields.add("groupInfo"); - openapiFields.add("hidden"); - openapiFields.add("id"); - openapiFields.add("lockInfo"); - openapiFields.add("name"); - openapiFields.add("rowHeightLevel"); - openapiFields.add("rows"); - openapiFields.add("sortInfo"); - openapiFields.add("style"); - openapiFields.add("type"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("columns"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to ViewSO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!ViewSO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in ViewSO is not found in the empty JSON string", ViewSO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!ViewSO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `ViewSO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : ViewSO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - // ensure the json data is an array - if (!jsonObj.get("columns").isJsonArray()) { - throw new IllegalArgumentException(String.format("Expected the field `columns` to be an array in the JSON string but got `%s`", jsonObj.get("columns").toString())); - } - - JsonArray jsonArraycolumns = jsonObj.getAsJsonArray("columns"); - // validate the required field `columns` (array) - for (int i = 0; i < jsonArraycolumns.size(); i++) { - ViewColumnSO.validateJsonElement(jsonArraycolumns.get(i)); - }; - if ((jsonObj.get("description") != null && !jsonObj.get("description").isJsonNull()) && !jsonObj.get("description").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `description` to be a primitive type in the JSON string but got `%s`", jsonObj.get("description").toString())); - } - // validate the optional field `filterInfo` - if (jsonObj.get("filterInfo") != null && !jsonObj.get("filterInfo").isJsonNull()) { - IFilterInfo.validateJsonElement(jsonObj.get("filterInfo")); - } - if (jsonObj.get("groupInfo") != null && !jsonObj.get("groupInfo").isJsonNull()) { - JsonArray jsonArraygroupInfo = jsonObj.getAsJsonArray("groupInfo"); - if (jsonArraygroupInfo != null) { - // ensure the json data is an array - if (!jsonObj.get("groupInfo").isJsonArray()) { - throw new IllegalArgumentException(String.format("Expected the field `groupInfo` to be an array in the JSON string but got `%s`", jsonObj.get("groupInfo").toString())); - } - - // validate the optional field `groupInfo` (array) - for (int i = 0; i < jsonArraygroupInfo.size(); i++) { - ISortedField.validateJsonElement(jsonArraygroupInfo.get(i)); - }; - } - } - if ((jsonObj.get("id") != null && !jsonObj.get("id").isJsonNull()) && !jsonObj.get("id").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `id` to be a primitive type in the JSON string but got `%s`", jsonObj.get("id").toString())); - } - // validate the optional field `lockInfo` - if (jsonObj.get("lockInfo") != null && !jsonObj.get("lockInfo").isJsonNull()) { - IViewLockInfo.validateJsonElement(jsonObj.get("lockInfo")); - } - if ((jsonObj.get("name") != null && !jsonObj.get("name").isJsonNull()) && !jsonObj.get("name").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `name` to be a primitive type in the JSON string but got `%s`", jsonObj.get("name").toString())); - } - if (jsonObj.get("rows") != null && !jsonObj.get("rows").isJsonNull()) { - JsonArray jsonArrayrows = jsonObj.getAsJsonArray("rows"); - if (jsonArrayrows != null) { - // ensure the json data is an array - if (!jsonObj.get("rows").isJsonArray()) { - throw new IllegalArgumentException(String.format("Expected the field `rows` to be an array in the JSON string but got `%s`", jsonObj.get("rows").toString())); - } - - // validate the optional field `rows` (array) - for (int i = 0; i < jsonArrayrows.size(); i++) { - ViewRowSO.validateJsonElement(jsonArrayrows.get(i)); - }; - } - } - // validate the optional field `sortInfo` - if (jsonObj.get("sortInfo") != null && !jsonObj.get("sortInfo").isJsonNull()) { - ISortInfo.validateJsonElement(jsonObj.get("sortInfo")); - } - // validate the optional field `style` - if (jsonObj.get("style") != null && !jsonObj.get("style").isJsonNull()) { - ViewStyleSo.validateJsonElement(jsonObj.get("style")); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!ViewSO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'ViewSO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(ViewSO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, ViewSO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public ViewSO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of ViewSO given an JSON string - * - * @param jsonString JSON string - * @return An instance of ViewSO - * @throws IOException if the JSON string is invalid with respect to ViewSO - */ - public static ViewSO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, ViewSO.class); - } - - /** - * Convert an instance of ViewSO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/WidgetInPanelSO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/WidgetInPanelSO.java deleted file mode 100644 index 53aa6921e2..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/WidgetInPanelSO.java +++ /dev/null @@ -1,275 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.Arrays; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * WidgetInPanelSO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class WidgetInPanelSO { - public static final String SERIALIZED_NAME_HEIGHT = "height"; - @SerializedName(SERIALIZED_NAME_HEIGHT) - private Double height; - - public static final String SERIALIZED_NAME_ID = "id"; - @SerializedName(SERIALIZED_NAME_ID) - private String id; - - public static final String SERIALIZED_NAME_Y = "y"; - @SerializedName(SERIALIZED_NAME_Y) - private Double y; - - public WidgetInPanelSO() { - } - - public WidgetInPanelSO height(Double height) { - - this.height = height; - return this; - } - - /** - * Get height - * @return height - **/ - @javax.annotation.Nonnull - public Double getHeight() { - return height; - } - - - public void setHeight(Double height) { - this.height = height; - } - - - public WidgetInPanelSO id(String id) { - - this.id = id; - return this; - } - - /** - * Get id - * @return id - **/ - @javax.annotation.Nonnull - public String getId() { - return id; - } - - - public void setId(String id) { - this.id = id; - } - - - public WidgetInPanelSO y(Double y) { - - this.y = y; - return this; - } - - /** - * Get y - * @return y - **/ - @javax.annotation.Nonnull - public Double getY() { - return y; - } - - - public void setY(Double y) { - this.y = y; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - WidgetInPanelSO widgetInPanelSO = (WidgetInPanelSO) o; - return Objects.equals(this.height, widgetInPanelSO.height) && - Objects.equals(this.id, widgetInPanelSO.id) && - Objects.equals(this.y, widgetInPanelSO.y); - } - - @Override - public int hashCode() { - return Objects.hash(height, id, y); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class WidgetInPanelSO {\n"); - sb.append(" height: ").append(toIndentedString(height)).append("\n"); - sb.append(" id: ").append(toIndentedString(id)).append("\n"); - sb.append(" y: ").append(toIndentedString(y)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("height"); - openapiFields.add("id"); - openapiFields.add("y"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("height"); - openapiRequiredFields.add("id"); - openapiRequiredFields.add("y"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to WidgetInPanelSO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!WidgetInPanelSO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in WidgetInPanelSO is not found in the empty JSON string", WidgetInPanelSO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!WidgetInPanelSO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `WidgetInPanelSO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : WidgetInPanelSO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if (!jsonObj.get("id").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `id` to be a primitive type in the JSON string but got `%s`", jsonObj.get("id").toString())); - } - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!WidgetInPanelSO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'WidgetInPanelSO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(WidgetInPanelSO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, WidgetInPanelSO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public WidgetInPanelSO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of WidgetInPanelSO given an JSON string - * - * @param jsonString JSON string - * @return An instance of WidgetInPanelSO - * @throws IOException if the JSON string is invalid with respect to WidgetInPanelSO - */ - public static WidgetInPanelSO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, WidgetInPanelSO.class); - } - - /** - * Convert an instance of WidgetInPanelSO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/databusclient/model/WidgetPanelSO.java b/backend-server/application/src/main/java/com/apitable/databusclient/model/WidgetPanelSO.java deleted file mode 100644 index cca1e93f20..0000000000 --- a/backend-server/application/src/main/java/com/apitable/databusclient/model/WidgetPanelSO.java +++ /dev/null @@ -1,299 +0,0 @@ -/* - * databus-server - * databus-server APIs - * - * The version of the OpenAPI document: 1.2.0 - * - * - * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). - * https://openapi-generator.tech - * Do not edit the class manually. - */ - - -package com.apitable.databusclient.model; - -import java.util.Objects; -import com.apitable.databusclient.model.WidgetInPanelSO; -import com.google.gson.TypeAdapter; -import com.google.gson.annotations.JsonAdapter; -import com.google.gson.annotations.SerializedName; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonArray; -import com.google.gson.JsonDeserializationContext; -import com.google.gson.JsonDeserializer; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonParseException; -import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import java.io.IOException; - -import java.lang.reflect.Type; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import com.apitable.databusclient.JSON; - -/** - * WidgetPanelSO - */ -@javax.annotation.Generated(value = "org.openapitools.codegen.languages.JavaClientCodegen") -public class WidgetPanelSO { - public static final String SERIALIZED_NAME_ID = "id"; - @SerializedName(SERIALIZED_NAME_ID) - private String id; - - public static final String SERIALIZED_NAME_NAME = "name"; - @SerializedName(SERIALIZED_NAME_NAME) - private String name; - - public static final String SERIALIZED_NAME_WIDGETS = "widgets"; - @SerializedName(SERIALIZED_NAME_WIDGETS) - private List widgets = new ArrayList<>(); - - public WidgetPanelSO() { - } - - public WidgetPanelSO id(String id) { - - this.id = id; - return this; - } - - /** - * Get id - * @return id - **/ - @javax.annotation.Nonnull - public String getId() { - return id; - } - - - public void setId(String id) { - this.id = id; - } - - - public WidgetPanelSO name(String name) { - - this.name = name; - return this; - } - - /** - * Get name - * @return name - **/ - @javax.annotation.Nonnull - public String getName() { - return name; - } - - - public void setName(String name) { - this.name = name; - } - - - public WidgetPanelSO widgets(List widgets) { - - this.widgets = widgets; - return this; - } - - public WidgetPanelSO addWidgetsItem(WidgetInPanelSO widgetsItem) { - if (this.widgets == null) { - this.widgets = new ArrayList<>(); - } - this.widgets.add(widgetsItem); - return this; - } - - /** - * Get widgets - * @return widgets - **/ - @javax.annotation.Nonnull - public List getWidgets() { - return widgets; - } - - - public void setWidgets(List widgets) { - this.widgets = widgets; - } - - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - WidgetPanelSO widgetPanelSO = (WidgetPanelSO) o; - return Objects.equals(this.id, widgetPanelSO.id) && - Objects.equals(this.name, widgetPanelSO.name) && - Objects.equals(this.widgets, widgetPanelSO.widgets); - } - - @Override - public int hashCode() { - return Objects.hash(id, name, widgets); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("class WidgetPanelSO {\n"); - sb.append(" id: ").append(toIndentedString(id)).append("\n"); - sb.append(" name: ").append(toIndentedString(name)).append("\n"); - sb.append(" widgets: ").append(toIndentedString(widgets)).append("\n"); - sb.append("}"); - return sb.toString(); - } - - /** - * Convert the given object to string with each line indented by 4 spaces - * (except the first line). - */ - private String toIndentedString(Object o) { - if (o == null) { - return "null"; - } - return o.toString().replace("\n", "\n "); - } - - - public static HashSet openapiFields; - public static HashSet openapiRequiredFields; - - static { - // a set of all properties/fields (JSON key names) - openapiFields = new HashSet(); - openapiFields.add("id"); - openapiFields.add("name"); - openapiFields.add("widgets"); - - // a set of required properties/fields (JSON key names) - openapiRequiredFields = new HashSet(); - openapiRequiredFields.add("id"); - openapiRequiredFields.add("name"); - openapiRequiredFields.add("widgets"); - } - - /** - * Validates the JSON Element and throws an exception if issues found - * - * @param jsonElement JSON Element - * @throws IOException if the JSON Element is invalid with respect to WidgetPanelSO - */ - public static void validateJsonElement(JsonElement jsonElement) throws IOException { - if (jsonElement == null) { - if (!WidgetPanelSO.openapiRequiredFields.isEmpty()) { // has required fields but JSON element is null - throw new IllegalArgumentException(String.format("The required field(s) %s in WidgetPanelSO is not found in the empty JSON string", WidgetPanelSO.openapiRequiredFields.toString())); - } - } - - Set> entries = jsonElement.getAsJsonObject().entrySet(); - // check to see if the JSON string contains additional fields - for (Entry entry : entries) { - if (!WidgetPanelSO.openapiFields.contains(entry.getKey())) { - throw new IllegalArgumentException(String.format("The field `%s` in the JSON string is not defined in the `WidgetPanelSO` properties. JSON: %s", entry.getKey(), jsonElement.toString())); - } - } - - // check to make sure all required properties/fields are present in the JSON string - for (String requiredField : WidgetPanelSO.openapiRequiredFields) { - if (jsonElement.getAsJsonObject().get(requiredField) == null) { - throw new IllegalArgumentException(String.format("The required field `%s` is not found in the JSON string: %s", requiredField, jsonElement.toString())); - } - } - JsonObject jsonObj = jsonElement.getAsJsonObject(); - if (!jsonObj.get("id").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `id` to be a primitive type in the JSON string but got `%s`", jsonObj.get("id").toString())); - } - if (!jsonObj.get("name").isJsonPrimitive()) { - throw new IllegalArgumentException(String.format("Expected the field `name` to be a primitive type in the JSON string but got `%s`", jsonObj.get("name").toString())); - } - // ensure the json data is an array - if (!jsonObj.get("widgets").isJsonArray()) { - throw new IllegalArgumentException(String.format("Expected the field `widgets` to be an array in the JSON string but got `%s`", jsonObj.get("widgets").toString())); - } - - JsonArray jsonArraywidgets = jsonObj.getAsJsonArray("widgets"); - // validate the required field `widgets` (array) - for (int i = 0; i < jsonArraywidgets.size(); i++) { - WidgetInPanelSO.validateJsonElement(jsonArraywidgets.get(i)); - }; - } - - public static class CustomTypeAdapterFactory implements TypeAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public TypeAdapter create(Gson gson, TypeToken type) { - if (!WidgetPanelSO.class.isAssignableFrom(type.getRawType())) { - return null; // this class only serializes 'WidgetPanelSO' and its subtypes - } - final TypeAdapter elementAdapter = gson.getAdapter(JsonElement.class); - final TypeAdapter thisAdapter - = gson.getDelegateAdapter(this, TypeToken.get(WidgetPanelSO.class)); - - return (TypeAdapter) new TypeAdapter() { - @Override - public void write(JsonWriter out, WidgetPanelSO value) throws IOException { - JsonObject obj = thisAdapter.toJsonTree(value).getAsJsonObject(); - elementAdapter.write(out, obj); - } - - @Override - public WidgetPanelSO read(JsonReader in) throws IOException { - JsonElement jsonElement = elementAdapter.read(in); - validateJsonElement(jsonElement); - return thisAdapter.fromJsonTree(jsonElement); - } - - }.nullSafe(); - } - } - - /** - * Create an instance of WidgetPanelSO given an JSON string - * - * @param jsonString JSON string - * @return An instance of WidgetPanelSO - * @throws IOException if the JSON string is invalid with respect to WidgetPanelSO - */ - public static WidgetPanelSO fromJson(String jsonString) throws IOException { - return JSON.getGson().fromJson(jsonString, WidgetPanelSO.class); - } - - /** - * Convert an instance of WidgetPanelSO to an JSON string - * - * @return JSON string - */ - public String toJson() { - return JSON.getGson().toJson(this); - } -} - diff --git a/backend-server/application/src/main/java/com/apitable/interfaces/ai/facade/AiServiceFacade.java b/backend-server/application/src/main/java/com/apitable/interfaces/ai/facade/AiServiceFacade.java index 7a0b6a9168..5f0866e69d 100644 --- a/backend-server/application/src/main/java/com/apitable/interfaces/ai/facade/AiServiceFacade.java +++ b/backend-server/application/src/main/java/com/apitable/interfaces/ai/facade/AiServiceFacade.java @@ -5,6 +5,7 @@ import com.apitable.interfaces.ai.model.ChartTimeDimension; import com.apitable.interfaces.ai.model.CreditTransactionChartData; import java.math.BigDecimal; +import java.time.LocalDate; import java.util.List; /** @@ -39,10 +40,12 @@ public interface AiServiceFacade { /** * get total credit transaction count. * - * @param spaceId space id + * @param spaceId space id + * @param beginDate begin date + * @param endDate end date * @return total credit transaction count */ - BigDecimal getUsedCreditCount(String spaceId); + BigDecimal getUsedCreditCount(String spaceId, LocalDate beginDate, LocalDate endDate); /** * load credit transaction chart data. diff --git a/backend-server/application/src/main/java/com/apitable/interfaces/ai/facade/DefaultAiServiceFacadeImpl.java b/backend-server/application/src/main/java/com/apitable/interfaces/ai/facade/DefaultAiServiceFacadeImpl.java index 331044d66a..da0c370930 100644 --- a/backend-server/application/src/main/java/com/apitable/interfaces/ai/facade/DefaultAiServiceFacadeImpl.java +++ b/backend-server/application/src/main/java/com/apitable/interfaces/ai/facade/DefaultAiServiceFacadeImpl.java @@ -5,6 +5,7 @@ import com.apitable.interfaces.ai.model.ChartTimeDimension; import com.apitable.interfaces.ai.model.CreditTransactionChartData; import java.math.BigDecimal; +import java.time.LocalDate; import java.util.Collections; import java.util.List; @@ -31,7 +32,7 @@ public void deleteAi(List aiId) { } @Override - public BigDecimal getUsedCreditCount(String spaceId) { + public BigDecimal getUsedCreditCount(String spaceId, LocalDate startDate, LocalDate endDate) { return BigDecimal.ZERO; } diff --git a/backend-server/application/src/main/java/com/apitable/interfaces/ai/model/CreditInfo.java b/backend-server/application/src/main/java/com/apitable/interfaces/ai/model/CreditInfo.java index 1ddc5e52d0..b812ef7814 100644 --- a/backend-server/application/src/main/java/com/apitable/interfaces/ai/model/CreditInfo.java +++ b/backend-server/application/src/main/java/com/apitable/interfaces/ai/model/CreditInfo.java @@ -39,6 +39,10 @@ public BigDecimal remainCredit() { if (BigDecimal.ZERO.equals(usedCredit)) { return BigDecimal.valueOf(maxMessageCredits).setScale(4, HALF_UP); } + if (usedCredit.longValue() > maxMessageCredits) { + // may exceed used credit in a trial period + return BigDecimal.ZERO; + } return BigDecimal.valueOf(maxMessageCredits).subtract(usedCredit).setScale(4, HALF_UP); } diff --git a/backend-server/application/src/main/java/com/apitable/interfaces/automation/AutomationContextConfig.java b/backend-server/application/src/main/java/com/apitable/interfaces/automation/AutomationContextConfig.java new file mode 100644 index 0000000000..3a920828e1 --- /dev/null +++ b/backend-server/application/src/main/java/com/apitable/interfaces/automation/AutomationContextConfig.java @@ -0,0 +1,38 @@ +/* + * APITable + * Copyright (C) 2022 APITable Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.apitable.interfaces.automation; + +import com.apitable.interfaces.automation.facede.AutomationServiceFacade; +import com.apitable.interfaces.automation.facede.DefaultAutomationServiceFacadeImpl; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * automation context config. + */ +@Configuration(proxyBeanMethods = false) +public class AutomationContextConfig { + + @Bean + @ConditionalOnMissingBean + public AutomationServiceFacade defaultAutomationServiceFacade() { + return new DefaultAutomationServiceFacadeImpl(); + } +} diff --git a/backend-server/application/src/main/java/com/apitable/interfaces/automation/facede/AutomationServiceFacade.java b/backend-server/application/src/main/java/com/apitable/interfaces/automation/facede/AutomationServiceFacade.java new file mode 100644 index 0000000000..bbdc79dd64 --- /dev/null +++ b/backend-server/application/src/main/java/com/apitable/interfaces/automation/facede/AutomationServiceFacade.java @@ -0,0 +1,65 @@ +/* + * APITable + * Copyright (C) 2022 APITable Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.apitable.interfaces.automation.facede; + +import java.util.Map; + +/** + * automation service facade. + */ +public interface AutomationServiceFacade { + /** + * publish schedule. + * + * @param scheduleId schedule id + */ + void publishSchedule(Long scheduleId); + + /** + * copy trigger schedule. + * + * @param newTriggerMap old triggerId -> new triggerId + */ + void copy(Map newTriggerMap); + + /** + * create schedule. + * + * @param spaceId space id + * @param triggerId trigger id + * @param scheduleConfig config + */ + void createSchedule(String spaceId, String triggerId, String scheduleConfig); + + /** + * update schedule. + * + * @param triggerId trigger id + * @param scheduleConfig config + */ + void updateSchedule(String triggerId, String scheduleConfig); + + /** + * delete schedule. + * + * @param triggerId trigger id + * @param userId user id + */ + void deleteSchedule(String triggerId, Long userId); +} diff --git a/backend-server/application/src/main/java/com/apitable/interfaces/automation/facede/DefaultAutomationServiceFacadeImpl.java b/backend-server/application/src/main/java/com/apitable/interfaces/automation/facede/DefaultAutomationServiceFacadeImpl.java new file mode 100644 index 0000000000..0aa11f45c7 --- /dev/null +++ b/backend-server/application/src/main/java/com/apitable/interfaces/automation/facede/DefaultAutomationServiceFacadeImpl.java @@ -0,0 +1,51 @@ +/* + * APITable + * Copyright (C) 2022 APITable Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.apitable.interfaces.automation.facede; + +import java.util.Map; + +/** + * default automation service facade implement. + */ +public class DefaultAutomationServiceFacadeImpl implements AutomationServiceFacade { + + @Override + public void publishSchedule(Long scheduleId) { + // do nothing + } + + @Override + public void copy(Map newTriggerMap) { + + } + + @Override + public void createSchedule(String spaceId, String triggerId, String scheduleConfig) { + } + + @Override + public void updateSchedule(String triggerId, String scheduleConfig) { + + } + + @Override + public void deleteSchedule(String triggerId, Long userId) { + + } +} diff --git a/backend-server/application/src/main/java/com/apitable/interfaces/billing/model/CycleDateRange.java b/backend-server/application/src/main/java/com/apitable/interfaces/billing/model/CycleDateRange.java new file mode 100644 index 0000000000..c9498bcdd3 --- /dev/null +++ b/backend-server/application/src/main/java/com/apitable/interfaces/billing/model/CycleDateRange.java @@ -0,0 +1,17 @@ +package com.apitable.interfaces.billing.model; + +import java.time.LocalDate; +import lombok.AllArgsConstructor; +import lombok.Data; + +/** + * cycle Date range class. + */ +@Data +@AllArgsConstructor +public class CycleDateRange { + + private LocalDate cycleStartDate; + + private LocalDate cycleEndDate; +} diff --git a/backend-server/application/src/main/java/com/apitable/interfaces/billing/model/DefaultSubscriptionFeature.java b/backend-server/application/src/main/java/com/apitable/interfaces/billing/model/DefaultSubscriptionFeature.java index f407b4f478..54b3ad8e7c 100644 --- a/backend-server/application/src/main/java/com/apitable/interfaces/billing/model/DefaultSubscriptionFeature.java +++ b/backend-server/application/src/main/java/com/apitable/interfaces/billing/model/DefaultSubscriptionFeature.java @@ -48,6 +48,7 @@ import com.apitable.interfaces.billing.model.SubscriptionFeatures.SubscribeFeatures.AllowOrgApi; import com.apitable.interfaces.billing.model.SubscriptionFeatures.SubscribeFeatures.AllowShare; import com.apitable.interfaces.billing.model.SubscriptionFeatures.SubscribeFeatures.ContactIsolation; +import com.apitable.interfaces.billing.model.SubscriptionFeatures.SubscribeFeatures.ControlFormBrandLogo; import com.apitable.interfaces.billing.model.SubscriptionFeatures.SubscribeFeatures.ForbidCreateOnCatalog; import com.apitable.interfaces.billing.model.SubscriptionFeatures.SubscribeFeatures.RainbowLabel; import com.apitable.interfaces.billing.model.SubscriptionFeatures.SubscribeFeatures.ShowMobileNumber; @@ -195,6 +196,11 @@ public AllowEmbed getAllowEmbed() { return new AllowEmbed(false); } + @Override + public ControlFormBrandLogo getControlFormBrandLogo() { + return new ControlFormBrandLogo(false); + } + @Override public ShowMobileNumber getShowMobileNumber() { return new ShowMobileNumber(false); @@ -227,7 +233,7 @@ public RemainRecordActivityDays getRemainRecordActivityDays() { @Override public AuditQueryDays getAuditQueryDays() { - return new AuditQueryDays(-1L); + return new AuditQueryDays(0L); } @Override diff --git a/backend-server/application/src/main/java/com/apitable/interfaces/billing/model/NumberPlanFeature.java b/backend-server/application/src/main/java/com/apitable/interfaces/billing/model/NumberPlanFeature.java index aa3beb112f..d8a2a0e96d 100644 --- a/backend-server/application/src/main/java/com/apitable/interfaces/billing/model/NumberPlanFeature.java +++ b/backend-server/application/src/main/java/com/apitable/interfaces/billing/model/NumberPlanFeature.java @@ -25,8 +25,15 @@ public class NumberPlanFeature implements PlanFeature { private Long value; + private final boolean unlimited; + public NumberPlanFeature(Long value) { + this(value, value != null && value == -1); + } + + public NumberPlanFeature(Long value, boolean unlimited) { this.value = value; + this.unlimited = unlimited; } public void plus(long other) { @@ -39,7 +46,7 @@ public void plus(long other) { * @return true or false */ public boolean isUnlimited() { - return value != -1; + return unlimited || (value != null && value == -1); } @Override diff --git a/backend-server/application/src/main/java/com/apitable/interfaces/billing/model/SubscriptionFeature.java b/backend-server/application/src/main/java/com/apitable/interfaces/billing/model/SubscriptionFeature.java index 722a965c58..aa8b31b490 100644 --- a/backend-server/application/src/main/java/com/apitable/interfaces/billing/model/SubscriptionFeature.java +++ b/backend-server/application/src/main/java/com/apitable/interfaces/billing/model/SubscriptionFeature.java @@ -55,7 +55,9 @@ import com.apitable.interfaces.billing.model.SubscriptionFeatures.SubscribeFeatures.AllowInvitation; import com.apitable.interfaces.billing.model.SubscriptionFeatures.SubscribeFeatures.AllowOrgApi; import com.apitable.interfaces.billing.model.SubscriptionFeatures.SubscribeFeatures.AllowShare; +import com.apitable.interfaces.billing.model.SubscriptionFeatures.SubscribeFeatures.AuditQuery; import com.apitable.interfaces.billing.model.SubscriptionFeatures.SubscribeFeatures.ContactIsolation; +import com.apitable.interfaces.billing.model.SubscriptionFeatures.SubscribeFeatures.ControlFormBrandLogo; import com.apitable.interfaces.billing.model.SubscriptionFeatures.SubscribeFeatures.ForbidCreateOnCatalog; import com.apitable.interfaces.billing.model.SubscriptionFeatures.SubscribeFeatures.RainbowLabel; import com.apitable.interfaces.billing.model.SubscriptionFeatures.SubscribeFeatures.ShowMobileNumber; @@ -145,6 +147,8 @@ default WidgetNums getWidgetNums() { AllowEmbed getAllowEmbed(); + ControlFormBrandLogo getControlFormBrandLogo(); + ShowMobileNumber getShowMobileNumber(); ContactIsolation getContactIsolation(); @@ -157,8 +161,13 @@ default WidgetNums getWidgetNums() { RemainRecordActivityDays getRemainRecordActivityDays(); + @Deprecated(since = "1.7.0", forRemoval = true) AuditQueryDays getAuditQueryDays(); + default AuditQuery getAuditQuery() { + return new AuditQuery(false); + } + AllowOrgApi getAllowOrgApi(); default AiAgentNums getAiAgentNums() { diff --git a/backend-server/application/src/main/java/com/apitable/interfaces/billing/model/SubscriptionFeatures.java b/backend-server/application/src/main/java/com/apitable/interfaces/billing/model/SubscriptionFeatures.java index 516fca8d1a..f371dc74d6 100644 --- a/backend-server/application/src/main/java/com/apitable/interfaces/billing/model/SubscriptionFeatures.java +++ b/backend-server/application/src/main/java/com/apitable/interfaces/billing/model/SubscriptionFeatures.java @@ -38,6 +38,14 @@ public static class Seat extends NumberPlanFeature { public Seat(Long value) { super(value); } + + public Seat(Long value, boolean unlimited) { + super(value, unlimited); + } + + public static Seat unlimited(Long value) { + return new Seat(value, true); + } } /** @@ -424,6 +432,24 @@ public AllowOrgApi(Boolean value) { super(value); } } + + /** + * Billing OrgApi feature. + */ + public static class AuditQuery extends BooleanPlanFeature { + public AuditQuery(Boolean value) { + super(value); + } + } + + /** + * Billing form brand log feature. + */ + public static class ControlFormBrandLogo extends BooleanPlanFeature { + public ControlFormBrandLogo(Boolean value) { + super(value); + } + } } /** @@ -648,4 +674,12 @@ public static SubscribeFeatures.ForbidCreateOnCatalog buildForbidCreateOnCatalog public static SubscribeFeatures.AllowEmbed buildAllowEmbed(Boolean value) { return new SubscribeFeatures.AllowEmbed(value); } + + public static SubscribeFeatures.AuditQuery buildAuditQuery(Boolean value) { + return new SubscribeFeatures.AuditQuery(value); + } + + public static SubscribeFeatures.ControlFormBrandLogo buildControlFormBrandLogo(Boolean value) { + return new SubscribeFeatures.ControlFormBrandLogo(value); + } } diff --git a/backend-server/application/src/main/java/com/apitable/interfaces/billing/model/SubscriptionInfo.java b/backend-server/application/src/main/java/com/apitable/interfaces/billing/model/SubscriptionInfo.java index 402abbcd46..ac253b6c8f 100644 --- a/backend-server/application/src/main/java/com/apitable/interfaces/billing/model/SubscriptionInfo.java +++ b/backend-server/application/src/main/java/com/apitable/interfaces/billing/model/SubscriptionInfo.java @@ -111,6 +111,19 @@ default LocalDate getEndDate() { return null; } + /** + * return billing cycle day of month. + * + * @param defaultDayOfMonth default day of month if not free + * @return billing cycle day of month + */ + default int cycleDayOfMonth(int defaultDayOfMonth) { + if (getRecurringInterval() == null || getRecurringInterval().isEmpty()) { + return defaultDayOfMonth; + } + return getStartDate().getDayOfMonth(); + } + /** * feature map. * diff --git a/backend-server/application/src/main/java/com/apitable/interfaces/social/facade/DefaultSocialServiceFacade.java b/backend-server/application/src/main/java/com/apitable/interfaces/social/facade/DefaultSocialServiceFacade.java index 49a39ca461..556787e7ba 100644 --- a/backend-server/application/src/main/java/com/apitable/interfaces/social/facade/DefaultSocialServiceFacade.java +++ b/backend-server/application/src/main/java/com/apitable/interfaces/social/facade/DefaultSocialServiceFacade.java @@ -102,4 +102,15 @@ public List fuzzySearchIfSatisfyCondition(String spaceId, String word) { public void eventCall(T event) { } + + /** + * get union id map. + * + * @param userIds user ids + * @return map + */ + @Override + public Map getUnionIdMap(List userIds) { + return Collections.emptyMap(); + } } diff --git a/backend-server/application/src/main/java/com/apitable/interfaces/social/facade/SocialServiceFacade.java b/backend-server/application/src/main/java/com/apitable/interfaces/social/facade/SocialServiceFacade.java index 71a1912f30..e945993291 100644 --- a/backend-server/application/src/main/java/com/apitable/interfaces/social/facade/SocialServiceFacade.java +++ b/backend-server/application/src/main/java/com/apitable/interfaces/social/facade/SocialServiceFacade.java @@ -58,4 +58,12 @@ void checkWhetherSpaceCanChangeMainAdmin(String spaceId, Long opMemberId, Long a List fuzzySearchIfSatisfyCondition(String spaceId, String word); void eventCall(T event); + + /** + * get union id map. + * + * @param userIds user ids + * @return map + */ + Map getUnionIdMap(List userIds); } diff --git a/backend-server/application/src/main/java/com/apitable/interfaces/user/facade/AbstractUserServiceFacadeImpl.java b/backend-server/application/src/main/java/com/apitable/interfaces/user/facade/AbstractUserServiceFacadeImpl.java index 0e35f396f8..2625e00287 100644 --- a/backend-server/application/src/main/java/com/apitable/interfaces/user/facade/AbstractUserServiceFacadeImpl.java +++ b/backend-server/application/src/main/java/com/apitable/interfaces/user/facade/AbstractUserServiceFacadeImpl.java @@ -28,7 +28,7 @@ public abstract class AbstractUserServiceFacadeImpl implements UserServiceFacade { @Override - public void onUserChangeEmailAction(Long userId, String email) { + public void onUserChangeEmailAction(Long userId, String email, String oldEmail) { } diff --git a/backend-server/application/src/main/java/com/apitable/interfaces/user/facade/UserServiceFacade.java b/backend-server/application/src/main/java/com/apitable/interfaces/user/facade/UserServiceFacade.java index 12ab3b2459..9ba6c6c64c 100644 --- a/backend-server/application/src/main/java/com/apitable/interfaces/user/facade/UserServiceFacade.java +++ b/backend-server/application/src/main/java/com/apitable/interfaces/user/facade/UserServiceFacade.java @@ -32,8 +32,9 @@ public interface UserServiceFacade { * * @param userId user id * @param email email address + * @param oldEmail old email address */ - void onUserChangeEmailAction(Long userId, String email); + void onUserChangeEmailAction(Long userId, String email, String oldEmail); /** * event on user change avatar. diff --git a/backend-server/application/src/main/java/com/apitable/interfaces/user/model/InvitationMetadata.java b/backend-server/application/src/main/java/com/apitable/interfaces/user/model/InvitationMetadata.java index 2d6d155a4e..8f627feb2d 100644 --- a/backend-server/application/src/main/java/com/apitable/interfaces/user/model/InvitationMetadata.java +++ b/backend-server/application/src/main/java/com/apitable/interfaces/user/model/InvitationMetadata.java @@ -28,9 +28,9 @@ @AllArgsConstructor public class InvitationMetadata { - private String spaceId; - private Long inviteUserId; + private String spaceId; + private String email; } diff --git a/backend-server/application/src/main/java/com/apitable/interfaces/user/model/MultiInvitationMetadata.java b/backend-server/application/src/main/java/com/apitable/interfaces/user/model/MultiInvitationMetadata.java index 56039c97af..90d8124b74 100644 --- a/backend-server/application/src/main/java/com/apitable/interfaces/user/model/MultiInvitationMetadata.java +++ b/backend-server/application/src/main/java/com/apitable/interfaces/user/model/MultiInvitationMetadata.java @@ -29,9 +29,9 @@ @AllArgsConstructor public class MultiInvitationMetadata { - private String spaceId; - private Long inviteUserId; + private String spaceId; + private List emails; } diff --git a/backend-server/application/src/main/java/com/apitable/internal/assembler/BillingAssembler.java b/backend-server/application/src/main/java/com/apitable/internal/assembler/BillingAssembler.java index 7c3d71fbb7..9af6230edb 100644 --- a/backend-server/application/src/main/java/com/apitable/internal/assembler/BillingAssembler.java +++ b/backend-server/application/src/main/java/com/apitable/internal/assembler/BillingAssembler.java @@ -68,6 +68,7 @@ public InternalSpaceSubscriptionVo toVo(SubscriptionInfo subscriptionInfo) { public InternalSpaceApiUsageVo toApiUsageVo(SubscriptionFeature planFeature) { InternalSpaceApiUsageVo vo = new InternalSpaceApiUsageVo(); vo.setMaxApiUsageCount(planFeature.getApiCallNumsPerMonth().getValue()); + vo.setApiCallNumsPerMonth(planFeature.getApiCallNumsPerMonth().getValue()); vo.setIsAllowOverLimit(true); return vo; } diff --git a/backend-server/application/src/main/java/com/apitable/internal/controller/InternalAssetController.java b/backend-server/application/src/main/java/com/apitable/internal/controller/InternalAssetController.java index 0b433d7e5e..b5d26ba310 100644 --- a/backend-server/application/src/main/java/com/apitable/internal/controller/InternalAssetController.java +++ b/backend-server/application/src/main/java/com/apitable/internal/controller/InternalAssetController.java @@ -41,11 +41,11 @@ import org.springframework.web.bind.annotation.RestController; /** - * Internal Server - Asset API. + * Internal - Asset API. */ @RestController @ApiResource(path = "/internal/asset") -@Tag(name = "Internal Server - Asset API") +@Tag(name = "Internal") public class InternalAssetController { @Resource @@ -77,7 +77,7 @@ public ResponseData> getSpaceCapacity( /** * Get Asset Info. */ - @GetResource(name = "Get Asset Info", path = "/get", requiredLogin = false) + @GetResource(path = "/get", requiredLogin = false) @Operation(summary = "Get Asset Info", description = "scene:Fusion server query the " + "attachment field data before writing") @Parameter(name = "token", description = "resource key", required = true, schema = @Schema(type = diff --git a/backend-server/application/src/main/java/com/apitable/internal/controller/InternalFieldController.java b/backend-server/application/src/main/java/com/apitable/internal/controller/InternalFieldController.java index 043cb738b8..6b4350da87 100644 --- a/backend-server/application/src/main/java/com/apitable/internal/controller/InternalFieldController.java +++ b/backend-server/application/src/main/java/com/apitable/internal/controller/InternalFieldController.java @@ -38,7 +38,7 @@ */ @RestController @ApiResource(path = "/internal/field") -@Tag(name = "Internal Service - Field Service Interface") +@Tag(name = "Internal") public class InternalFieldController { @Resource @@ -48,7 +48,7 @@ public class InternalFieldController { * Get url related information. */ @PostResource(path = "/url/awareContents", requiredPermission = false) - @Operation(summary = "get url related information", description = "get url related information") + @Operation(summary = "Fetch url", description = "get url related information") public ResponseData urlContentsAwareFill( @RequestBody @Valid UrlsWrapperRo ro) { List urls = ro.getUrls(); diff --git a/backend-server/application/src/main/java/com/apitable/internal/controller/InternalFieldPermissionController.java b/backend-server/application/src/main/java/com/apitable/internal/controller/InternalFieldPermissionController.java index f48b7461f9..14216cfce3 100644 --- a/backend-server/application/src/main/java/com/apitable/internal/controller/InternalFieldPermissionController.java +++ b/backend-server/application/src/main/java/com/apitable/internal/controller/InternalFieldPermissionController.java @@ -57,7 +57,7 @@ */ @RestController @ApiResource(path = "/internal") -@Tag(name = "Internal service - data table field permission interface") +@Tag(name = "Internal") public class InternalFieldPermissionController { @Resource @@ -79,7 +79,7 @@ public class InternalFieldPermissionController { * turn off multiple field permissions. */ @PostResource(path = "/datasheet/{dstId}/field/permission/disable", requiredPermission = false) - @Operation(summary = "turn off multiple field permissions", description = "room layer ot " + @Operation(summary = "Disable Field Permissions", description = "Batch disable file permission of a specific datasheet" + "delete field operation call") @Parameters({ @Parameter(name = "dstId", description = "table id", required = true, @@ -110,7 +110,7 @@ public ResponseData disableRoles(@PathVariable("dstId") @NodeMatch String * get field permissions. */ @GetResource(path = "/node/{nodeId}/field/permission", requiredLogin = false) - @Operation(summary = "get field permissions") + @Operation(summary = "Retrieve Single Node Field Permissions") @Parameters({ @Parameter(name = "nodeId", description = "node id", required = true, schema = @Schema (type = "string"), in = ParameterIn.PATH, example = "dstCgcfixAKyeeNsaP"), @@ -145,7 +145,7 @@ public ResponseData getFieldPermission( * get field permission set for multiple nodes. */ @PostResource(path = "/node/field/permission", requiredLogin = false) - @Operation(summary = "get field permission set for multiple nodes") + @Operation(summary = "Retrieve Multi Node Field Permission") public ResponseData> getMultiFieldPermissionViews( @RequestBody @Valid InternalPermissionRo data) { // Filter non-existing nodes to prevent subsequent exceptions from being thrown diff --git a/backend-server/application/src/main/java/com/apitable/internal/controller/InternalNodeController.java b/backend-server/application/src/main/java/com/apitable/internal/controller/InternalNodeController.java index 6710d127b0..bd213e8c70 100644 --- a/backend-server/application/src/main/java/com/apitable/internal/controller/InternalNodeController.java +++ b/backend-server/application/src/main/java/com/apitable/internal/controller/InternalNodeController.java @@ -59,7 +59,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; @@ -71,7 +70,7 @@ */ @RestController @ApiResource(path = "/internal") -@Tag(name = "Internal Service - Node Interface") +@Tag(name = "Internal") public class InternalNodeController { @Resource @@ -92,9 +91,8 @@ public class InternalNodeController { /** * Create a table node. */ - @PostResource(name = "create a table node", path = "/spaces/{spaceId}/datasheets", - requiredPermission = false) - @Operation(summary = "create a table node", description = "create a table node") + @PostResource(path = "/spaces/{spaceId}/datasheets", requiredPermission = false) + @Operation(summary = "Create Node", description = "create a table node") @Notification(templateId = NotificationTemplateId.NODE_CREATE) public ResponseData createDatasheet(@PathVariable("spaceId") String spaceId, @RequestBody CreateDatasheetRo ro) { @@ -129,9 +127,9 @@ public ResponseData createDatasheet(@PathVariable("spaceId") /** * Delete node. */ - @PostResource(name = "delete node", path = "/spaces/{spaceId}/nodes/{nodeId}/delete", + @PostResource(path = "/spaces/{spaceId}/nodes/{nodeId}/delete", requiredPermission = false) - @Operation(summary = "delete node", description = "delete node") + @Operation(summary = "Delete Node", description = "delete node") @Notification(templateId = NotificationTemplateId.NODE_DELETE) public ResponseData deleteNode(@PathVariable("spaceId") String spaceId, @PathVariable("nodeId") String nodeId) { @@ -154,10 +152,8 @@ public ResponseData deleteNode(@PathVariable("spaceId") String spaceId, /** * Get the space station id to which the node belongs. */ - @GetResource(name = "get the space station id to which the node belongs", path = "/spaces" - + "/nodes/{nodeId}/belongSpace", requiredLogin = false, requiredPermission = false) - @Operation(summary = "get the space station id to which the node belongs", description = "get" - + " the space station id to which the node belongs", hidden = true) + @GetResource(path = "/spaces" + "/nodes/{nodeId}/belongSpace", requiredLogin = false) + @Operation(summary = "Retrieve Node", description = "get the space station id to which the node belongs", hidden = true) public ResponseData nodeFromSpace( @RequestHeader(name = ParamsConstants.INTERNAL_REQUEST) String internalRequest, @PathVariable("nodeId") String nodeId) { @@ -198,7 +194,7 @@ public ResponseData> filter(@PathVariable("spaceId") String space List subFilterNodeIds = roleDict.entrySet().stream() .filter(entry -> entry.getValue().isEqualTo(requireRole)) .peek(entry -> nodeIdToNodeRole.put(entry.getKey(), entry.getValue().getRoleTag())) - .map(Map.Entry::getKey).collect(Collectors.toList()); + .map(Map.Entry::getKey).toList(); filterNodeIds.addAll(subFilterNodeIds); }); if (CollUtil.isEmpty(filterNodeIds)) { diff --git a/backend-server/application/src/main/java/com/apitable/internal/controller/InternalNodePermissionController.java b/backend-server/application/src/main/java/com/apitable/internal/controller/InternalNodePermissionController.java index 7428a246e0..071cd2ca22 100644 --- a/backend-server/application/src/main/java/com/apitable/internal/controller/InternalNodePermissionController.java +++ b/backend-server/application/src/main/java/com/apitable/internal/controller/InternalNodePermissionController.java @@ -18,11 +18,16 @@ package com.apitable.internal.controller; +import static com.apitable.workspace.enums.PermissionException.NODE_ACCESS_DENIED; + +import cn.hutool.core.util.StrUtil; import com.apitable.control.annotation.ThirdPartControl; +import com.apitable.core.exception.BusinessException; import com.apitable.core.support.ResponseData; import com.apitable.internal.ro.InternalPermissionRo; import com.apitable.internal.ro.InternalUserNodePermissionRo; import com.apitable.internal.service.IPermissionService; +import com.apitable.organization.service.IUnitService; import com.apitable.shared.component.scanner.annotation.ApiResource; import com.apitable.shared.component.scanner.annotation.GetResource; import com.apitable.shared.component.scanner.annotation.PostResource; @@ -54,7 +59,7 @@ */ @RestController @ApiResource(path = "/internal") -@Tag(name = "Internal Service - Node Permission Interface") +@Tag(name = "Internal") public class InternalNodePermissionController { @Resource @@ -62,6 +67,9 @@ public class InternalNodePermissionController { @Resource private INodeService iNodeService; + @Resource + private IUnitService iUnitService; + /** * Get Node permission. @@ -79,6 +87,12 @@ public ResponseData getNodePermission( @PathVariable("nodeId") String nodeId, @RequestParam(value = "shareId", required = false) String shareId) { Long userId = SessionContext.getUserId(); + // check private + if (StrUtil.isBlank(shareId) + && !iNodeService.getIsTemplateByNodeIds(Collections.singletonList(nodeId)) + && !iNodeService.privateNodeOperation(userId, nodeId)) { + throw new BusinessException(NODE_ACCESS_DENIED); + } List views = iPermissionService.getDatasheetPermissionView(userId, Collections.singletonList(nodeId), shareId); diff --git a/backend-server/application/src/main/java/com/apitable/internal/controller/InternalNotifyController.java b/backend-server/application/src/main/java/com/apitable/internal/controller/InternalNotifyController.java index 786434fb3c..ff5d2ab169 100644 --- a/backend-server/application/src/main/java/com/apitable/internal/controller/InternalNotifyController.java +++ b/backend-server/application/src/main/java/com/apitable/internal/controller/InternalNotifyController.java @@ -37,7 +37,7 @@ */ @RestController @ApiResource(path = "/internal/notification") -@Tag(name = "Internal Service - Notification Interface") +@Tag(name = "Internal") public class InternalNotifyController { @Resource @@ -46,8 +46,8 @@ public class InternalNotifyController { /** * Send a message. */ - @PostResource(name = "send a message", path = "/create", requiredLogin = false) - @Operation(summary = "send a message", description = "send a message") + @PostResource(path = "/create", requiredLogin = false) + @Operation(summary = "Notify Message", description = "send a message") public ResponseData create( @Valid @RequestBody List notificationCreateRoList) { boolean bool = playerNotificationService.batchCreateNotify(notificationCreateRoList); diff --git a/backend-server/application/src/main/java/com/apitable/internal/controller/InternalOrganizationController.java b/backend-server/application/src/main/java/com/apitable/internal/controller/InternalOrganizationController.java index d0f2472ea6..4d21baea01 100644 --- a/backend-server/application/src/main/java/com/apitable/internal/controller/InternalOrganizationController.java +++ b/backend-server/application/src/main/java/com/apitable/internal/controller/InternalOrganizationController.java @@ -37,6 +37,7 @@ import jakarta.annotation.Resource; import jakarta.validation.Valid; import java.util.List; +import java.util.Objects; import org.springframework.web.bind.annotation.RestController; /** @@ -44,7 +45,7 @@ */ @RestController @ApiResource(path = "/internal/org") -@Tag(name = "Internal Server - org API") +@Tag(name = "Internal") public class InternalOrganizationController { @Resource @@ -72,7 +73,9 @@ public class InternalOrganizationController { @Parameter(name = "all", description = "whether to load all departments and members", schema = @Schema(type = "boolean"), in = ParameterIn.QUERY), @Parameter(name = "searchEmail", description = "whether to search for emails", - schema = @Schema(type = "boolean"), in = ParameterIn.QUERY) + schema = @Schema(type = "boolean"), in = ParameterIn.QUERY), + @Parameter(name = "type", description = "the return unit type, 1-department, 3-member", schema = @Schema(type = "integer"), + in = ParameterIn.QUERY, example = "3") }) public ResponseData> loadOrSearch(@Valid LoadSearchDTO params) { // sharing node/template: un login users invoke processing @@ -81,6 +84,11 @@ public ResponseData> loadOrSearch(@Valid LoadSearchDTO params) List vos = iOrganizationService.loadOrSearchInfo(userId, spaceId, params, null); List existUnitInfo = vos.stream().filter(unitInfoVo -> !unitInfoVo.getIsDeleted()).collect(toList()); + if (null != params.getType()) { + existUnitInfo = existUnitInfo.stream() + .filter(unitInfoVo -> Objects.equals(unitInfoVo.getType(), params.getType())) + .collect(toList()); + } return ResponseData.success(existUnitInfo); } } diff --git a/backend-server/application/src/main/java/com/apitable/internal/controller/InternalSpaceController.java b/backend-server/application/src/main/java/com/apitable/internal/controller/InternalSpaceController.java index 2ffe87b8f6..653e083ac9 100644 --- a/backend-server/application/src/main/java/com/apitable/internal/controller/InternalSpaceController.java +++ b/backend-server/application/src/main/java/com/apitable/internal/controller/InternalSpaceController.java @@ -49,7 +49,7 @@ * Internal Service - Space Interface. */ @RestController -@Tag(name = "Internal Service - Space Interface") +@Tag(name = "Internal") @ApiResource(path = "/internal") public class InternalSpaceController { diff --git a/backend-server/application/src/main/java/com/apitable/internal/controller/InternalUserController.java b/backend-server/application/src/main/java/com/apitable/internal/controller/InternalUserController.java index b3cd5878eb..a682804f65 100644 --- a/backend-server/application/src/main/java/com/apitable/internal/controller/InternalUserController.java +++ b/backend-server/application/src/main/java/com/apitable/internal/controller/InternalUserController.java @@ -57,7 +57,7 @@ */ @RestController @ApiResource(path = "/internal") -@Tag(name = "Internal Service - User Interface") +@Tag(name = "Internal") public class InternalUserController { @Resource diff --git a/backend-server/application/src/main/java/com/apitable/internal/service/impl/InternalSpaceServiceImpl.java b/backend-server/application/src/main/java/com/apitable/internal/service/impl/InternalSpaceServiceImpl.java index 14630b5a10..8c88632e1a 100644 --- a/backend-server/application/src/main/java/com/apitable/internal/service/impl/InternalSpaceServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/internal/service/impl/InternalSpaceServiceImpl.java @@ -25,7 +25,7 @@ import com.apitable.automation.service.impl.AutomationRobotServiceImpl; import com.apitable.core.constants.RedisConstants; import com.apitable.interfaces.ai.facade.AiServiceFacade; -import com.apitable.interfaces.billing.facade.EntitlementServiceFacade; +import com.apitable.interfaces.billing.model.CycleDateRange; import com.apitable.interfaces.billing.model.SubscriptionFeature; import com.apitable.interfaces.billing.model.SubscriptionFeatures; import com.apitable.interfaces.billing.model.SubscriptionInfo; @@ -38,11 +38,15 @@ import com.apitable.internal.vo.InternalSpaceAutomationRunMessageV0; import com.apitable.internal.vo.InternalSpaceInfoVo; import com.apitable.internal.vo.InternalSpaceSubscriptionVo; +import com.apitable.shared.clock.spring.ClockManager; +import com.apitable.shared.util.SubscriptionDateRange; import com.apitable.space.enums.LabsFeatureEnum; import com.apitable.space.service.ILabsApplicantService; +import com.apitable.space.service.ISpaceService; import com.apitable.space.service.IStaticsService; import com.apitable.space.vo.LabsFeatureVo; import jakarta.annotation.Resource; +import java.time.LocalDate; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -62,7 +66,7 @@ public class InternalSpaceServiceImpl implements InternalSpaceService { @Resource - private EntitlementServiceFacade entitlementServiceFacade; + private ISpaceService iSpaceService; @Resource private IStaticsService iStaticsService; @@ -87,24 +91,27 @@ public class InternalSpaceServiceImpl implements InternalSpaceService { @Override public InternalSpaceSubscriptionVo getSpaceEntitlementVo(String spaceId) { - SubscriptionInfo subscriptionInfo = entitlementServiceFacade.getSpaceSubscription(spaceId); + SubscriptionInfo subscriptionInfo = iSpaceService.getSpaceSubscription(spaceId); BillingAssembler assembler = new BillingAssembler(); return assembler.toVo(subscriptionInfo); } @Override public InternalCreditUsageVo getSpaceCreditUsageVo(String spaceId) { - SubscriptionInfo subscriptionInfo = entitlementServiceFacade.getSpaceSubscription(spaceId); + SubscriptionInfo subscriptionInfo = iSpaceService.getSpaceSubscription(spaceId); InternalCreditUsageVo vo = new InternalCreditUsageVo(); vo.setAllowOverLimit(subscriptionInfo.getConfig().isAllowCreditOverLimit()); vo.setMaxMessageCredits(subscriptionInfo.getFeature().getMessageCreditNums().getValue()); - vo.setUsedCredit(aiServiceFacade.getUsedCreditCount(spaceId)); + LocalDate now = ClockManager.me().getLocalDateNow(); + CycleDateRange dateRange = SubscriptionDateRange.calculateCycleDate(subscriptionInfo, now); + vo.setUsedCredit(aiServiceFacade.getUsedCreditCount(spaceId, dateRange.getCycleStartDate(), + dateRange.getCycleEndDate())); return vo; } @Override public InternalSpaceAutomationRunMessageV0 getAutomationRunMessageV0(String spaceId) { - SubscriptionInfo subscriptionInfo = entitlementServiceFacade.getSpaceSubscription(spaceId); + SubscriptionInfo subscriptionInfo = iSpaceService.getSpaceSubscription(spaceId); InternalSpaceAutomationRunMessageV0 vo = new InternalSpaceAutomationRunMessageV0(); String redisKey = RedisConstants.getSpaceAutomationRunCountKey(spaceId); long count; @@ -132,18 +139,22 @@ public InternalSpaceAutomationRunMessageV0 getAutomationRunMessageV0(String spac @Override public InternalSpaceApiUsageVo getSpaceEntitlementApiUsageVo(String spaceId) { - SubscriptionInfo subscriptionInfo = entitlementServiceFacade.getSpaceSubscription(spaceId); + SubscriptionInfo subscriptionInfo = iSpaceService.getSpaceSubscription(spaceId); SubscriptionFeature planFeature = subscriptionInfo.getFeature(); BillingAssembler assembler = new BillingAssembler(); InternalSpaceApiUsageVo vo = assembler.toApiUsageVo(planFeature); - vo.setApiUsageUsedCount(iStaticsService.getCurrentMonthApiUsage(spaceId)); + LocalDate now = ClockManager.me().getLocalDateNow(); + CycleDateRange dateRange = SubscriptionDateRange.calculateCycleDate(subscriptionInfo, now); + Long count = iStaticsService.getCurrentMonthApiUsage(spaceId, dateRange.getCycleEndDate()); + vo.setApiUsageUsedCount(count); + vo.setApiCallUsedNumsCurrentMonth(count); vo.setIsAllowOverLimit(true); return vo; } @Override public InternalSpaceApiRateLimitVo getSpaceEntitlementApiRateLimitVo(String spaceId) { - SubscriptionInfo subscriptionInfo = entitlementServiceFacade.getSpaceSubscription(spaceId); + SubscriptionInfo subscriptionInfo = iSpaceService.getSpaceSubscription(spaceId); SubscriptionFeature planFeature = subscriptionInfo.getFeature(); BillingAssembler assembler = new BillingAssembler(); return assembler.toApiRateLimitVo(planFeature); diff --git a/backend-server/application/src/main/java/com/apitable/internal/vo/InternalSpaceApiUsageVo.java b/backend-server/application/src/main/java/com/apitable/internal/vo/InternalSpaceApiUsageVo.java index 30252ea242..69cbcb733b 100644 --- a/backend-server/application/src/main/java/com/apitable/internal/vo/InternalSpaceApiUsageVo.java +++ b/backend-server/application/src/main/java/com/apitable/internal/vo/InternalSpaceApiUsageVo.java @@ -35,11 +35,21 @@ public class InternalSpaceApiUsageVo { @JsonSerialize(nullsUsing = NullBooleanSerializer.class) private Boolean isAllowOverLimit; - @Schema(description = "api usage used", example = "10000") + @Schema(description = "api usage used", example = "10000", deprecated = true) @JsonSerialize(nullsUsing = NullNumberSerializer.class) + @Deprecated(since = "1.8.0", forRemoval = true) private Long apiUsageUsedCount; - @Schema(description = "maximum api usage", example = "60000") + @Schema(description = "api call nums used current month", example = "10000") + @JsonSerialize(nullsUsing = NullNumberSerializer.class) + private Long apiCallUsedNumsCurrentMonth; + + @Schema(description = "maximum api usage", example = "60000", deprecated = true) @JsonSerialize(nullsUsing = NullNumberSerializer.class) + @Deprecated(since = "1.8.0", forRemoval = true) private Long maxApiUsageCount; + + @Schema(description = "maximum api usage", example = "60000") + @JsonSerialize(nullsUsing = NullNumberSerializer.class) + private Long apiCallNumsPerMonth; } diff --git a/backend-server/application/src/main/java/com/apitable/internal/vo/InternalSpaceUsageVo.java b/backend-server/application/src/main/java/com/apitable/internal/vo/InternalSpaceUsageVo.java index d058b97c60..a702d8d373 100644 --- a/backend-server/application/src/main/java/com/apitable/internal/vo/InternalSpaceUsageVo.java +++ b/backend-server/application/src/main/java/com/apitable/internal/vo/InternalSpaceUsageVo.java @@ -52,7 +52,8 @@ public class InternalSpaceUsageVo { @JsonSerialize(nullsUsing = NullNumberSerializer.class) private Long calendarViewNums; - @Schema(description = "Number of used credit", example = "5.0001") + @Schema(description = "Number of used credit", example = "5.0001", deprecated = true) @JsonSerialize(nullsUsing = CreditUnitSerializer.class) + @Deprecated(since = "1.8.0", forRemoval = true) private BigDecimal usedCredit; } diff --git a/backend-server/application/src/main/java/com/apitable/organization/controller/MemberController.java b/backend-server/application/src/main/java/com/apitable/organization/controller/MemberController.java index 019ecb0353..33bc4e8850 100644 --- a/backend-server/application/src/main/java/com/apitable/organization/controller/MemberController.java +++ b/backend-server/application/src/main/java/com/apitable/organization/controller/MemberController.java @@ -19,12 +19,8 @@ package com.apitable.organization.controller; import static com.apitable.base.enums.ParameterException.NO_ARG; -import static com.apitable.core.constants.RedisConstants.GENERAL_LOCKED; import static com.apitable.organization.enums.OrganizationException.DELETE_MEMBER_PARAM_ERROR; import static com.apitable.organization.enums.OrganizationException.DELETE_SPACE_ADMIN_ERROR; -import static com.apitable.organization.enums.OrganizationException.INVITE_EMAIL_HAS_ACTIVE; -import static com.apitable.organization.enums.OrganizationException.INVITE_EMAIL_NOT_FOUND; -import static com.apitable.organization.enums.OrganizationException.INVITE_TOO_OFTEN; import static com.apitable.organization.enums.OrganizationException.NOT_EXIST_MEMBER; import static com.apitable.shared.constants.NotificationConstants.INVOLVE_MEMBER_ID; import static com.apitable.shared.constants.PageConstants.PAGE_DESC; @@ -32,7 +28,6 @@ import static com.apitable.shared.constants.PageConstants.PAGE_SIMPLE_EXAMPLE; import static com.apitable.space.enums.SpaceException.NOT_IN_SPACE; -import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.ListUtil; import cn.hutool.core.lang.Dict; import cn.hutool.core.text.CharSequenceUtil; @@ -41,21 +36,18 @@ import com.apitable.core.exception.BusinessException; import com.apitable.core.support.ResponseData; import com.apitable.core.util.ExceptionUtil; +import com.apitable.interfaces.billing.facade.EntitlementServiceFacade; +import com.apitable.interfaces.billing.model.SubscriptionInfo; import com.apitable.interfaces.security.facade.BlackListServiceFacade; import com.apitable.interfaces.security.facade.HumanVerificationServiceFacade; import com.apitable.interfaces.security.model.NonRobotMetadata; import com.apitable.interfaces.social.facade.SocialServiceFacade; -import com.apitable.interfaces.user.facade.InvitationServiceFacade; -import com.apitable.interfaces.user.model.InvitationMetadata; import com.apitable.organization.entity.MemberEntity; import com.apitable.organization.enums.DeleteMemberType; import com.apitable.organization.mapper.MemberMapper; import com.apitable.organization.mapper.TeamMapper; import com.apitable.organization.ro.DeleteBatchMemberRo; import com.apitable.organization.ro.DeleteMemberRo; -import com.apitable.organization.ro.InviteMemberAgainRo; -import com.apitable.organization.ro.InviteMemberRo; -import com.apitable.organization.ro.InviteRo; import com.apitable.organization.ro.TeamAddMemberRo; import com.apitable.organization.ro.UpdateMemberOpRo; import com.apitable.organization.ro.UpdateMemberRo; @@ -65,7 +57,6 @@ import com.apitable.organization.service.IMemberService; import com.apitable.organization.service.IRoleService; import com.apitable.organization.service.ITeamService; -import com.apitable.organization.service.IUnitService; import com.apitable.organization.vo.MemberInfoVo; import com.apitable.organization.vo.MemberPageVo; import com.apitable.organization.vo.MemberUnitsVo; @@ -83,6 +74,7 @@ import com.apitable.shared.context.LoginContext; import com.apitable.shared.context.SessionContext; import com.apitable.shared.holder.SpaceHolder; +import com.apitable.shared.security.IFrequencyLimitService; import com.apitable.shared.util.page.PageHelper; import com.apitable.shared.util.page.PageInfo; import com.apitable.shared.util.page.PageObjectParam; @@ -108,11 +100,7 @@ import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.List; -import java.util.concurrent.TimeUnit; -import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; -import org.springframework.data.redis.core.BoundValueOperations; -import org.springframework.data.redis.core.RedisTemplate; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; @@ -145,9 +133,6 @@ public class MemberController { @Resource private UserMapper userMapper; - @Resource - private RedisTemplate redisTemplate; - @Resource private ISpaceService iSpaceService; @@ -155,13 +140,13 @@ public class MemberController { private BlackListServiceFacade blackListServiceFacade; @Resource - private IRoleService iRoleService; + private IFrequencyLimitService iFrequencyLimitService; @Resource - private ITeamService iTeamService; + private IRoleService iRoleService; @Resource - private IUnitService iUnitService; + private ITeamService iTeamService; @Resource private SocialServiceFacade socialServiceFacade; @@ -170,7 +155,7 @@ public class MemberController { private HumanVerificationServiceFacade humanVerificationServiceFacade; @Resource - private InvitationServiceFacade invitationServiceFacade; + private EntitlementServiceFacade entitlementServiceFacade; /** * Fuzzy Search Members. @@ -258,8 +243,7 @@ public ResponseData> readPage( */ @Deprecated @GetResource(path = "/checkEmail") - @Operation(summary = "Check whether email in space", - description = "Check whether email in space") + @Operation(summary = "Check whether email in space") @Parameters({ @Parameter(name = ParamsConstants.SPACE_ID, description = "space id", required = true, schema = @Schema(type = "string"), in = ParameterIn.HEADER, example = "spcyQkKp9XJEl"), @@ -325,77 +309,6 @@ public ResponseData getUnits() { return ResponseData.success(unitsVo); } - /** - * Send email to invite members. - */ - @PostResource(path = "/sendInvite", tags = "INVITE_MEMBER") - @Operation(summary = "Send an email to invite members", - description = "Send an email to invite. The email is automatically bound to the platform " - + "user. The invited member will be in the state to be activated, and will not take " - + "effect until the user self activates.") - @Parameter(name = ParamsConstants.SPACE_ID, description = "space id", required = true, - schema = @Schema(type = "string"), in = ParameterIn.HEADER, example = "spcyQkKp9XJEl") - public ResponseData inviteMember(@RequestBody @Valid InviteRo data) { - // human verification - humanVerificationServiceFacade.verifyNonRobot(new NonRobotMetadata(data.getData())); - // space id be invited - String spaceId = LoginContext.me().getSpaceId(); - // whether in black list - blackListServiceFacade.checkSpace(spaceId); - iSpaceService.checkSeatOverLimit(spaceId, data.getInvite().size()); - Long userId = SessionContext.getUserId(); - // check whether space can invite user - iSpaceService.checkCanOperateSpaceUpdate(spaceId); - List inviteMembers = data.getInvite(); - MemberUnitsVo unitsVo = MemberUnitsVo.builder().build(); - // get invited emails - List inviteEmails = inviteMembers.stream() - .map(InviteMemberRo::getEmail) - .filter(StrUtil::isNotBlank).collect(Collectors.toList()); - if (CollUtil.isEmpty(inviteEmails)) { - // without email, response success directly - return ResponseData.success(unitsVo); - } - // invite new members - List memberIds = iMemberService.emailInvitation(userId, spaceId, inviteEmails); - if (!memberIds.isEmpty()) { - List unitIds = iUnitService.getUnitIdsByRefIds(memberIds); - unitsVo.setUnitIds(unitIds); - } - return ResponseData.success(unitsVo); - } - - /** - * Again send an email to invite members. - */ - @PostResource(path = "/sendInviteSingle", tags = "INVITE_MEMBER") - @Operation(summary = "Again send an email to invite members", description = "If a member is " - + "not activated, it can send an invitation again regardless of whether the invitation " - + "has expired. After the invitation is successfully sent, the invitation link sent last " - + "time will be invalid.") - @Parameter(name = ParamsConstants.SPACE_ID, description = "space id", required = true, - schema = @Schema(type = "string"), in = ParameterIn.HEADER, example = "spcyQkKp9XJEl") - public ResponseData inviteMemberSingle(@RequestBody @Valid InviteMemberAgainRo data) { - String spaceId = LoginContext.me().getSpaceId(); - // check black space - blackListServiceFacade.checkSpace(spaceId); - iSpaceService.checkSeatOverLimit(spaceId); - iSpaceService.checkCanOperateSpaceUpdate(spaceId); - // Again email invite members - MemberEntity member = memberMapper.selectBySpaceIdAndEmail(spaceId, data.getEmail()); - ExceptionUtil.isNotNull(member, INVITE_EMAIL_NOT_FOUND); - ExceptionUtil.isFalse(member.getIsActive(), INVITE_EMAIL_HAS_ACTIVE); - // Limit the frequency for 10 minutes - String lockKey = StrUtil.format(GENERAL_LOCKED, "invite:email", data.getEmail()); - BoundValueOperations ops = redisTemplate.boundValueOps(lockKey); - ExceptionUtil.isNull(ops.get(), INVITE_TOO_OFTEN); - ops.set("", 10, TimeUnit.MINUTES); - Long userId = SessionContext.getUserId(); - invitationServiceFacade.sendInvitationEmail( - new InvitationMetadata(spaceId, userId, data.getEmail())); - return ResponseData.success(); - } - /** * Add member. */ @@ -598,12 +511,18 @@ public void downloadTemplate(HttpServletResponse response) { @Parameter(name = ParamsConstants.SPACE_ID, description = "space id", required = true, schema = @Schema(type = "string"), in = ParameterIn.HEADER, example = "spcyQkKp9XJEl") public ResponseData uploadExcel(UploadMemberTemplateRo data) { - // human verification - humanVerificationServiceFacade.verifyNonRobot(new NonRobotMetadata(data.getData())); String spaceId = LoginContext.me().getSpaceId(); // check black space blackListServiceFacade.checkSpace(spaceId); + iFrequencyLimitService.spaceInviteFrequency(spaceId); iSpaceService.checkCanOperateSpaceUpdate(spaceId); + // human verification + humanVerificationServiceFacade.verifyNonRobot(new NonRobotMetadata(data.getData())); + SubscriptionInfo subscriptionInfo = + entitlementServiceFacade.getSpaceSubscription(spaceId); + if (subscriptionInfo.isFree() && iMemberService.shouldPreventInvitation(spaceId)) { + return ResponseData.success(new UploadParseResultVO()); + } UploadParseResultVO resultVo = iMemberService.parseExcelFile(spaceId, data.getFile()); return ResponseData.success(resultVo); } diff --git a/backend-server/application/src/main/java/com/apitable/organization/controller/OrganizationController.java b/backend-server/application/src/main/java/com/apitable/organization/controller/OrganizationController.java index 27f81922e2..0a0a095010 100644 --- a/backend-server/application/src/main/java/com/apitable/organization/controller/OrganizationController.java +++ b/backend-server/application/src/main/java/com/apitable/organization/controller/OrganizationController.java @@ -67,6 +67,7 @@ import jakarta.validation.Valid; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; @@ -289,7 +290,9 @@ public ResponseData getSubUnitList( @Parameter(name = "all", description = "whether to load all departments and members", schema = @Schema(type = "boolean"), in = ParameterIn.QUERY), @Parameter(name = "searchEmail", description = "whether to search for emails", - schema = @Schema(type = "boolean"), in = ParameterIn.QUERY) + schema = @Schema(type = "boolean"), in = ParameterIn.QUERY), + @Parameter(name = "type", description = "the return unit type, 1-department, 3-member", schema = @Schema(type = "integer"), + in = ParameterIn.QUERY, example = "3") }) public ResponseData> loadOrSearch(@Valid LoadSearchDTO params) { // sharing node/template: un login users invoke processing @@ -321,6 +324,11 @@ public ResponseData> loadOrSearch(@Valid LoadSearchDTO params) iOrganizationService.loadOrSearchInfo(userId, spaceId, params, sharer); List existUnitInfo = vos.stream().filter(unitInfoVo -> !unitInfoVo.getIsDeleted()).collect(toList()); + if (null != params.getType()) { + existUnitInfo = existUnitInfo.stream() + .filter(unitInfoVo -> Objects.equals(unitInfoVo.getType(), params.getType())) + .collect(toList()); + } return ResponseData.success(existUnitInfo); } diff --git a/backend-server/application/src/main/java/com/apitable/organization/dto/LoadSearchDTO.java b/backend-server/application/src/main/java/com/apitable/organization/dto/LoadSearchDTO.java index 1971bd792f..f2495c29d0 100644 --- a/backend-server/application/src/main/java/com/apitable/organization/dto/LoadSearchDTO.java +++ b/backend-server/application/src/main/java/com/apitable/organization/dto/LoadSearchDTO.java @@ -45,4 +45,6 @@ public class LoadSearchDTO { private Boolean searchEmail; private String userId; + + private Integer type; } diff --git a/backend-server/application/src/main/java/com/apitable/organization/dto/MemberDTO.java b/backend-server/application/src/main/java/com/apitable/organization/dto/MemberDTO.java index 8b7667876a..b1d8853726 100644 --- a/backend-server/application/src/main/java/com/apitable/organization/dto/MemberDTO.java +++ b/backend-server/application/src/main/java/com/apitable/organization/dto/MemberDTO.java @@ -32,8 +32,12 @@ public class MemberDTO { private Long userId; + private Long unitId; + private String memberName; + private String openId; + private String avatar; private Integer color; diff --git a/backend-server/application/src/main/java/com/apitable/organization/dto/TagInfoDto.java b/backend-server/application/src/main/java/com/apitable/organization/dto/TagInfoDto.java new file mode 100644 index 0000000000..926e111cee --- /dev/null +++ b/backend-server/application/src/main/java/com/apitable/organization/dto/TagInfoDto.java @@ -0,0 +1,17 @@ +package com.apitable.organization.dto; + +import lombok.Data; + +/** + * tag info dto. + */ +@Data +public class TagInfoDto { + + private Long id; + + private Long unitId; + + private String tagName; + +} diff --git a/backend-server/application/src/main/java/com/apitable/organization/dto/UnitBaseInfoDTO.java b/backend-server/application/src/main/java/com/apitable/organization/dto/UnitBaseInfoDTO.java index a59508358a..1f6b4277fb 100644 --- a/backend-server/application/src/main/java/com/apitable/organization/dto/UnitBaseInfoDTO.java +++ b/backend-server/application/src/main/java/com/apitable/organization/dto/UnitBaseInfoDTO.java @@ -14,4 +14,5 @@ public class UnitBaseInfoDTO { private Long unitRefId; + private Long id; } diff --git a/backend-server/application/src/main/java/com/apitable/organization/dto/UnitMemberTeamDTO.java b/backend-server/application/src/main/java/com/apitable/organization/dto/UnitMemberTeamDTO.java new file mode 100644 index 0000000000..10aced4b8f --- /dev/null +++ b/backend-server/application/src/main/java/com/apitable/organization/dto/UnitMemberTeamDTO.java @@ -0,0 +1,32 @@ +package com.apitable.organization.dto; + +import lombok.Data; + +/** + * Unit Member Team DTO. + */ +@Data +public class UnitMemberTeamDTO { + /** + * member's id. + */ + private Long memberId; + + private Long userId; + + private Long unitId; + + private String avatar; + + private Integer avatarColor; + + private String memberName; + /** + * used for cp isv user. + */ + private String openId; + + private String teamName; + + private boolean isDeleted; +} diff --git a/backend-server/application/src/main/java/com/apitable/organization/entity/TagEntity.java b/backend-server/application/src/main/java/com/apitable/organization/entity/TagEntity.java new file mode 100644 index 0000000000..48e38dda74 --- /dev/null +++ b/backend-server/application/src/main/java/com/apitable/organization/entity/TagEntity.java @@ -0,0 +1,71 @@ +package com.apitable.organization.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.time.LocalDateTime; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +/** + *

+ * Tag Structure - unit tag Table. + *

+ * + * @author Mybatis Generator Tool + */ +@Data +@Builder(toBuilder = true) +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +@EqualsAndHashCode +@TableName(keepGlobalPrefix = true, value = "unit_tag") +public class TagEntity implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * Primary Key. + */ + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + + /** + * Tag Group ID(link#xxxx_org_tag_group#id). + */ + private String groupId; + + /** + * Space ID(link#xxxx_space#space_id). + */ + private String spaceId; + + /** + * Tag Name. + */ + private String tagName; + + /** + * Sort in space (default starts from 1). + */ + private int sequence; + + /** + * Create Time. + */ + private LocalDateTime createdAt; + + /** + * Update Time. + */ + private LocalDateTime updatedAt; +} diff --git a/backend-server/application/src/main/java/com/apitable/organization/entity/TagMemberRelEntity.java b/backend-server/application/src/main/java/com/apitable/organization/entity/TagMemberRelEntity.java new file mode 100644 index 0000000000..5f696589ae --- /dev/null +++ b/backend-server/application/src/main/java/com/apitable/organization/entity/TagMemberRelEntity.java @@ -0,0 +1,62 @@ +package com.apitable.organization.entity; + +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.time.LocalDateTime; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import lombok.experimental.Accessors; + +/** + * Tag member rel entity. + */ +@Data +@Builder(toBuilder = true) +@NoArgsConstructor +@AllArgsConstructor +@Accessors(chain = true) +@EqualsAndHashCode +@TableName(keepGlobalPrefix = true, value = "unit_tag_member_rel") +public class TagMemberRelEntity implements Serializable { + private static final long serialVersionUID = 1L; + + /** + * Primary Key. + */ + @TableId(value = "id", type = IdType.ASSIGN_ID) + private Long id; + + + /** + * Tag Group ID(link#xxxx_org_tag_group#id). + */ + private Long tagId; + + /** + * Member ID. + */ + private Long memberId; + + /** + * the creator member id. + */ + @TableField(fill = FieldFill.INSERT) + private Long creator; + + /** + * Create Time. + */ + private LocalDateTime createdAt; + + /** + * Update Time. + */ + private LocalDateTime updatedAt; +} diff --git a/backend-server/application/src/main/java/com/apitable/organization/enums/OrganizationException.java b/backend-server/application/src/main/java/com/apitable/organization/enums/OrganizationException.java index 985d244da9..f92d5f98b0 100644 --- a/backend-server/application/src/main/java/com/apitable/organization/enums/OrganizationException.java +++ b/backend-server/application/src/main/java/com/apitable/organization/enums/OrganizationException.java @@ -78,6 +78,8 @@ public enum OrganizationException implements BaseException { INVITE_EMAIL_HAS_ACTIVE(518, "This email has been activated, please do not send it again"), + INVITE_EMAIL_NOT_MATCH(518, "Invited email does not match"), + INVITE_EMAIL_NOT_EXIT(518, "Invited email does not exist"), INVITE_EMAIL_HAS_LINK(518, @@ -112,7 +114,10 @@ public enum OrganizationException implements BaseException { DUPLICATION_TEAM_NAME(533, "The team name already exists"), - GET_PARENT_TEAM_ERROR(534, "Parent department does not exist, please try again"); + GET_PARENT_TEAM_ERROR(534, "Parent department does not exist, please try again"), + + ILLEGAL_UNIT_ID(535, "Illegal unit id"); + private final Integer code; diff --git a/backend-server/application/src/main/java/com/apitable/organization/enums/UnitType.java b/backend-server/application/src/main/java/com/apitable/organization/enums/UnitType.java index a1ec2e7574..ca31732184 100644 --- a/backend-server/application/src/main/java/com/apitable/organization/enums/UnitType.java +++ b/backend-server/application/src/main/java/com/apitable/organization/enums/UnitType.java @@ -37,7 +37,9 @@ public enum UnitType { ROLE(2), - MEMBER(3); + MEMBER(3), + + TAG(4); private final Integer type; diff --git a/backend-server/application/src/main/java/com/apitable/organization/mapper/MemberMapper.java b/backend-server/application/src/main/java/com/apitable/organization/mapper/MemberMapper.java index eaa957911d..f503276d25 100644 --- a/backend-server/application/src/main/java/com/apitable/organization/mapper/MemberMapper.java +++ b/backend-server/application/src/main/java/com/apitable/organization/mapper/MemberMapper.java @@ -24,7 +24,6 @@ import com.apitable.organization.dto.MemberUserDTO; import com.apitable.organization.dto.SearchMemberDTO; import com.apitable.organization.dto.SpaceMemberDTO; -import com.apitable.organization.dto.SpaceMemberIdDTO; import com.apitable.organization.dto.TenantMemberDto; import com.apitable.organization.entity.MemberEntity; import com.apitable.organization.vo.MemberInfoVo; @@ -185,15 +184,55 @@ List selectIdBySpaceIdAndNames(@Param("spaceId") String spaceId, String selectMemberNameById(@Param("id") Long id); /** - * get member brief info. + * query the user's member id in the space. * * @param userId user id * @param spaceId space id - * @return member brief info + * @return member id + */ + Long selectIdByUserIdAndSpaceId(@Param("userId") Long userId, + @Param("spaceId") String spaceId); + + /** + * query member name by user id and space id. + * + * @param spaceId space id + * @param userId user id + * @return member name */ - MemberDTO selectDtoByUserIdAndSpaceId(@Param("userId") Long userId, + String selectMemberNameByUserIdAndSpaceId(@Param("userId") Long userId, + @Param("spaceId") String spaceId); + + /** + * query by user id and space id. + * + * @param userId user id + * @param spaceId space id + * @return MemberEntity + */ + MemberEntity selectByUserIdAndSpaceId(@Param("userId") Long userId, @Param("spaceId") String spaceId); + /** + * query the user's member id in the space, even if member is deleted. + * + * @param userId user id + * @param spaceId space id + * @return member id + */ + Long selectMemberIdByUserIdAndSpaceIdIncludeDeleted(@Param("userId") Long userId, + @Param("spaceId") String spaceId); + + /** + * query by user id and space id, include deleted member. + * + * @param userId user id + * @param spaceId space id + * @return MemberEntity + */ + MemberEntity selectByUserIdAndSpaceIdIncludeDeleted(@Param("userId") Long userId, + @Param("spaceId") String spaceId); + /** * get member brief info even if he was deleted. * (Avoid losing access to founder information that is no longer in space) @@ -290,25 +329,6 @@ int updateActiveStatusByUserIdAndSpaceId(@Param("userId") Long userId, */ String selectActiveSpaceByUserId(@Param("userId") Long userId); - /** - * query the user's member id in the space. - * - * @param userId user id - * @param spaceId space id - * @return member id - */ - Long selectIdByUserIdAndSpaceId(@Param("userId") Long userId, @Param("spaceId") String spaceId); - - /** - * query user's memberId in space, exclude deleted member. - * - * @param userId user's id - * @param spaceId space's id - * @return memberInfo - */ - MemberInfoDTO selectIdByUserIdAndSpaceIdExcludeDelete(@Param("userId") Long userId, - @Param("spaceId") String spaceId); - /** * Query member information. * @@ -318,16 +338,6 @@ MemberInfoDTO selectIdByUserIdAndSpaceIdExcludeDelete(@Param("userId") Long user */ List selectMemberInfoDTOByIds(@Param("memberIds") Collection memberIds); - /** - * query the user's member id in the space, even if member is deleted. - * - * @param userId user id - * @param spaceId space id - * @return member id - */ - Long selectMemberIdByUserIdAndSpaceIdExcludeDelete(@Param("userId") Long userId, - @Param("spaceId") String spaceId); - /** * query member info by email. * @@ -589,8 +599,8 @@ List selectBindSocialListBySpaceIdWithOffset(@Param("spaceId") Str * @param spaceId space id * @return member id */ - List selectIdsByEmailsAndSpaceId(@Param("emails") List emails, - @Param("spaceId") String spaceId); + List selectEmailBySpaceIdAndEmails(@Param("spaceId") String spaceId, + @Param("emails") List emails); /** * query user id by member id. @@ -630,16 +640,6 @@ List selectMemberInfoByMemberIdsIncludeDelete( List selectDtoBySpaceIdAndUserIds(@Param("spaceId") String spaceId, @Param("userIds") List userIds); - /** - * !!!This query does not query the is deleted field, which may be a historical member or already in the space. - * - * @param userId user id - * @param spaceId space id - * @return MemberEntity - */ - MemberEntity selectByUserIdAndSpaceIdIgnoreDelete(@Param("userId") Long userId, - @Param("spaceId") String spaceId); - /** * !!! even if member is deleted. * @@ -792,16 +792,6 @@ MemberEntity selectBySpaceIdAndOpenId(@Param("spaceId") String spaceId, List selectBySpaceIdAndOpenIds(@Param("spaceId") String spaceId, @Param("openIds") List openIds); - /** - * query by user id and space id. - * - * @param userId user id - * @param spaceId space id - * @return MemberEntity - */ - MemberEntity selectByUserIdAndSpaceId(@Param("userId") Long userId, - @Param("spaceId") String spaceId); - /** * query member info by space id and member ids. * @@ -911,16 +901,6 @@ Long selectRandomMemberExclude(@Param("spaceId") String spaceId, List selectByUserIds(@Param("spaceId") String spaceId, @Param("userIds") List userIds); - /** - * query member name by user id and space id. - * - * @param spaceId space id - * @param userId user id - * @return member name - */ - String selectMemberNameByUserIdAndSpaceId(@Param("userId") Long userId, - @Param("spaceId") String spaceId); - /** * collects statistics on the space owned by users. * @@ -963,17 +943,6 @@ Integer batchUpdateNameAndIsDeletedByIds( */ List selectTeamIdsByMemberId(@Param("memberId") Long memberId); - /** - * query member id list by user id and space id. - * - * @param userId user id - * @param spaceIds space id - * @return SpaceMemberIdDto - */ - List selectMemberIdsByUserIdAndSpaceIds(@Param("userId") Long userId, - @Param("spaceIds") - List spaceIds); - /** * query id by space id and email keyword. * diff --git a/backend-server/application/src/main/java/com/apitable/organization/mapper/TagMapper.java b/backend-server/application/src/main/java/com/apitable/organization/mapper/TagMapper.java new file mode 100644 index 0000000000..258ca28ad8 --- /dev/null +++ b/backend-server/application/src/main/java/com/apitable/organization/mapper/TagMapper.java @@ -0,0 +1,34 @@ +package com.apitable.organization.mapper; + +import com.apitable.organization.dto.TagInfoDto; +import com.apitable.organization.entity.TagEntity; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import java.util.List; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +/** + * tag mapper. + */ +@Mapper +public interface TagMapper extends BaseMapper { + + /** + * Update tag name. + * + * @param tagId tag Id + * @param name tag name + */ + void updateName(@Param("tagId") Long tagId, @Param("name") String name); + + + /** + * query tag info by ids and space id. + * + * @param ids the rows' id + * @param spaceId the space's id + * @return tag info + */ + List selectTagInfoDtoByIdsAndSpaceId(@Param("ids") List ids, + @Param("spaceId") String spaceId); +} diff --git a/backend-server/application/src/main/java/com/apitable/organization/mapper/TagMemberRelMapper.java b/backend-server/application/src/main/java/com/apitable/organization/mapper/TagMemberRelMapper.java new file mode 100644 index 0000000000..399cc5dbea --- /dev/null +++ b/backend-server/application/src/main/java/com/apitable/organization/mapper/TagMemberRelMapper.java @@ -0,0 +1,74 @@ +package com.apitable.organization.mapper; + +import com.apitable.organization.entity.TagMemberRelEntity; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import java.util.Collection; +import java.util.List; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +/** + * tag group member rel mapper. + */ +@Mapper +public interface TagMemberRelMapper extends BaseMapper { + + /** + * insert batch. + * + * @param entities tag-group-member-ref + * @return affected rows + */ + int insertBatch(@Param("entities") List entities); + + /** + * query tag members by tagIds. + * + * @param tagIds tag ids + * @return tag-group-member-ref + */ + List selectByTagIds(@Param("tagIds") List tagIds); + + /** + * query member-ids by tagId. + * + * @param tagIds tag ids + * @return member ids + */ + List selectMemberIdsByTag(@Param("tagIds") List tagIds); + + /** + * delete by member id. + * + * @param memberIds member ids + * @return affected rows + */ + int deleteByMemberIdAndTagId(@Param("tagId") Long tagId, + @Param("memberIds") List memberIds); + + /** + * delete by tag id. + * + * @param tagId tag id + * @return affected rows + */ + int deleteMembersByTagId(@Param("tagId") Long tagId); + + /** + * delete bulk with tag group ids. + * + * @param tagIds tag ids + * @return affected rows + */ + int deleteByTagIds(@Param("tagIds") Collection tagIds); + + + /** + * get tag' id by role member id. + * + * @param memberId the tag member's id + * @return the tag' id of the member's ref. + */ + List selectTagIdsByMemberId(@Param("memberId") Long memberId); + +} diff --git a/backend-server/application/src/main/java/com/apitable/organization/mapper/TeamMemberRelMapper.java b/backend-server/application/src/main/java/com/apitable/organization/mapper/TeamMemberRelMapper.java index 6b8e0a9424..fee09008b6 100644 --- a/backend-server/application/src/main/java/com/apitable/organization/mapper/TeamMemberRelMapper.java +++ b/backend-server/application/src/main/java/com/apitable/organization/mapper/TeamMemberRelMapper.java @@ -53,6 +53,7 @@ public interface TeamMemberRelMapper extends ExpandBaseMapper teamIds); /** diff --git a/backend-server/application/src/main/java/com/apitable/organization/ro/CheckUserEmailRo.java b/backend-server/application/src/main/java/com/apitable/organization/ro/CheckUserEmailRo.java index c87d7804d9..cf4b2a4e17 100644 --- a/backend-server/application/src/main/java/com/apitable/organization/ro/CheckUserEmailRo.java +++ b/backend-server/application/src/main/java/com/apitable/organization/ro/CheckUserEmailRo.java @@ -30,6 +30,7 @@ *

*/ @Data +@Deprecated(since = "v1.10.0") @Schema(description = "User verification and comparison of invited mailbox parameters") public class CheckUserEmailRo { diff --git a/backend-server/application/src/main/java/com/apitable/organization/service/IMemberService.java b/backend-server/application/src/main/java/com/apitable/organization/service/IMemberService.java index 8a22aeb338..e8d74c83b7 100644 --- a/backend-server/application/src/main/java/com/apitable/organization/service/IMemberService.java +++ b/backend-server/application/src/main/java/com/apitable/organization/service/IMemberService.java @@ -20,6 +20,7 @@ import com.apitable.organization.dto.MemberDTO; import com.apitable.organization.dto.TenantMemberDto; +import com.apitable.organization.dto.UnitMemberTeamDTO; import com.apitable.organization.dto.UploadDataDTO; import com.apitable.organization.entity.MemberEntity; import com.apitable.organization.ro.TeamAddMemberRo; @@ -91,6 +92,15 @@ public interface IMemberService extends IService { */ MemberEntity getByUserIdAndSpaceId(Long userId, String spaceId); + /** + * Get member include deleted. + * + * @param userId user id + * @param spaceId space id + * @return MemberId + */ + MemberEntity getByUserIdAndSpaceIdIncludeDeleted(Long userId, String spaceId); + /** * get user info. * @@ -315,14 +325,6 @@ public interface IMemberService extends IService { */ List getSpaceIdWithoutNameModifiedByUserId(Long userId); - /** - * get inactive member by email. - * - * @param email email - * @return MemberDto List - */ - List getInactiveMemberByEmails(String email); - /** * update the user's member name in all spaces. * @@ -401,9 +403,19 @@ public interface IMemberService extends IService { * @param inviteUserId invite user id * @param spaceId space id * @param emails email list - * @return invite member id list + * @return invite email list + */ + List emailInvitation(Long inviteUserId, String spaceId, List emails); + + /** + * Create invitation member. + * + * @param inviteUserId invite user id + * @param spaceId space id + * @param emails email list + * @author Chambers */ - List emailInvitation(Long inviteUserId, String spaceId, List emails); + void createInvitationMember(Long inviteUserId, String spaceId, List emails); /** * send invite email to email. @@ -411,8 +423,9 @@ public interface IMemberService extends IService { * @param spaceId space id * @param fromMemberId the member who invite user * @param email email + * @return invite token */ - void sendInviteEmail(String lang, String spaceId, Long fromMemberId, String email); + String sendInviteEmail(String lang, String spaceId, Long fromMemberId, String email); /** * send an invitation space notification email. @@ -664,12 +677,12 @@ void sendInviteNotification(Long fromUserId, List invitedMemberIds, String List getInactiveMemberDtoByMobile(String mobile); /** - * get inactive space by email. + * get inactive member by email. * * @param email email * @return MemberDto List */ - List getInactiveMemberDtoByEmail(String email); + List getInactiveMemberByEmail(String email); /** * get the user's space's amount. @@ -740,4 +753,21 @@ void sendInviteNotification(Long fromUserId, List invitedMemberIds, String * @return space ids */ List getUserOwnSpaceIds(Long userId); + + /** + * check space invited record. + * + * @param spaceId space id + * @return boolean + */ + boolean shouldPreventInvitation(String spaceId); + + /** + * get member base info. + * + * @param spaceId space id + * @param userIds user id + * @return List UnitMemberTeamDTO + */ + List getMemberBySpaceIdAndUserIds(String spaceId, List userIds); } diff --git a/backend-server/application/src/main/java/com/apitable/organization/service/ITagMemberRelService.java b/backend-server/application/src/main/java/com/apitable/organization/service/ITagMemberRelService.java new file mode 100644 index 0000000000..d390cfd3a3 --- /dev/null +++ b/backend-server/application/src/main/java/com/apitable/organization/service/ITagMemberRelService.java @@ -0,0 +1,22 @@ +package com.apitable.organization.service; + +import com.apitable.organization.entity.TagMemberRelEntity; +import java.util.List; + +/** + * Tag Member rel. + */ +public interface ITagMemberRelService { + + List getByTagIds(List tagIds); + + List getMemberIdByTagIds(List tagIds); + + void removeMembers(Long tagId, List memberIds); + + void addMembers(Long tagId, List memberIds); + + void deleteMembersByTagId(Long tagId); + + List getTagIdsByTagMemberId(Long memberId); +} diff --git a/backend-server/application/src/main/java/com/apitable/organization/service/ITagService.java b/backend-server/application/src/main/java/com/apitable/organization/service/ITagService.java new file mode 100644 index 0000000000..e7076f1fb4 --- /dev/null +++ b/backend-server/application/src/main/java/com/apitable/organization/service/ITagService.java @@ -0,0 +1,47 @@ +package com.apitable.organization.service; + +import com.apitable.organization.vo.TagInfoVo; +import java.util.List; + +/** + * Tag service. + */ +public interface ITagService { + + /** + * create tag. + * + * @param groupId tag groupId , options , default 0 + * @param spaceId space Id + * @param tagName tagName + * @return tagId + */ + Long createTag(Long groupId, String spaceId, String tagName); + + /** + * update tag name. + * + * @param tagId tag id + * @param tagName tag name + */ + void updateTagName(Long tagId, String tagName); + + /** + * delete tag. + * + * @param tagId tag id + */ + void delete(Long tagId); + + + List getTagVos(String spaceId, List tagIds); + + + /** + * get members' id in tag. + * + * @param tagIds the tag' id + * @return the members' id + */ + List getMemberIdsByTagIds(List tagIds); +} diff --git a/backend-server/application/src/main/java/com/apitable/organization/service/ITeamMemberRelService.java b/backend-server/application/src/main/java/com/apitable/organization/service/ITeamMemberRelService.java index 0bca9bad8b..351521490b 100644 --- a/backend-server/application/src/main/java/com/apitable/organization/service/ITeamMemberRelService.java +++ b/backend-server/application/src/main/java/com/apitable/organization/service/ITeamMemberRelService.java @@ -94,4 +94,12 @@ public interface ITeamMemberRelService extends IService { * @param teamIds team id list */ void removeByTeamIdsAndMemberId(Long memberId, List teamIds); + + /** + * get member's team relationship. + * + * @param memberIds member ids + * @return List TeamMemberRelEntity + */ + List getByMemberIds(List memberIds); } diff --git a/backend-server/application/src/main/java/com/apitable/organization/service/ITeamService.java b/backend-server/application/src/main/java/com/apitable/organization/service/ITeamService.java index 9f6f52f8ee..6313b4255b 100644 --- a/backend-server/application/src/main/java/com/apitable/organization/service/ITeamService.java +++ b/backend-server/application/src/main/java/com/apitable/organization/service/ITeamService.java @@ -390,4 +390,12 @@ Map> batchGetFullHierarchyTeamNames(List me * @return TeamEntity */ TeamEntity getTeamByUnitId(String spaceId, String unitId); + + /** + * get member's team name. + * + * @param memberIds member and team rel map + * @return map + */ + Map> getMembersTeamName(List memberIds); } diff --git a/backend-server/application/src/main/java/com/apitable/organization/service/IUnitService.java b/backend-server/application/src/main/java/com/apitable/organization/service/IUnitService.java index fe98ae8040..b59956235d 100644 --- a/backend-server/application/src/main/java/com/apitable/organization/service/IUnitService.java +++ b/backend-server/application/src/main/java/com/apitable/organization/service/IUnitService.java @@ -298,4 +298,12 @@ PageInfo getMembersByTeamId(String spaceId, Long parentTeamId, */ UnitRoleMemberVo getRoleMembers(String spaceId, Long roleId, Boolean sensitiveData); + /** + * check current member whether match unit. + * + * @param memberId current member id + * @param unitId unit id + */ + void checkUnit(Long memberId, String unitId); + } diff --git a/backend-server/application/src/main/java/com/apitable/organization/service/impl/MemberServiceImpl.java b/backend-server/application/src/main/java/com/apitable/organization/service/impl/MemberServiceImpl.java index 9aa8f868dd..2eaab5eab0 100644 --- a/backend-server/application/src/main/java/com/apitable/organization/service/impl/MemberServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/organization/service/impl/MemberServiceImpl.java @@ -39,15 +39,17 @@ import com.apitable.core.exception.BusinessException; import com.apitable.core.util.ExceptionUtil; import com.apitable.core.util.SqlTool; -import com.apitable.interfaces.billing.facade.EntitlementServiceFacade; import com.apitable.interfaces.billing.model.SubscriptionInfo; import com.apitable.interfaces.social.enums.SocialNameModified; import com.apitable.interfaces.user.facade.InvitationServiceFacade; import com.apitable.interfaces.user.model.MultiInvitationMetadata; import com.apitable.organization.dto.MemberBaseInfoDTO; import com.apitable.organization.dto.MemberDTO; +import com.apitable.organization.dto.RoleMemberDTO; import com.apitable.organization.dto.TeamBaseInfoDTO; import com.apitable.organization.dto.TenantMemberDto; +import com.apitable.organization.dto.UnitBaseInfoDTO; +import com.apitable.organization.dto.UnitMemberTeamDTO; import com.apitable.organization.dto.UploadDataDTO; import com.apitable.organization.entity.AuditUploadParseRecordEntity; import com.apitable.organization.entity.MemberEntity; @@ -71,6 +73,7 @@ import com.apitable.organization.service.IMemberService; import com.apitable.organization.service.IRoleMemberService; import com.apitable.organization.service.IRoleService; +import com.apitable.organization.service.ITagMemberRelService; import com.apitable.organization.service.ITeamMemberRelService; import com.apitable.organization.service.ITeamService; import com.apitable.organization.service.IUnitService; @@ -89,6 +92,7 @@ import com.apitable.shared.component.notification.NotifyMailFactory; import com.apitable.shared.component.notification.NotifyMailFactory.MailWithLang; import com.apitable.shared.config.properties.ConstProperties; +import com.apitable.shared.config.properties.LimitProperties; import com.apitable.shared.constants.MailPropConstants; import com.apitable.shared.context.LoginContext; import com.apitable.shared.context.SessionContext; @@ -109,11 +113,13 @@ import com.apitable.user.entity.UserEntity; import com.apitable.user.service.IUserService; import com.apitable.workspace.enums.PermissionException; +import com.apitable.workspace.service.INodeService; import com.apitable.workspace.vo.NodeRoleMemberVo; import com.baomidou.mybatisplus.core.toolkit.IdWorker; import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; import jakarta.annotation.Resource; import java.io.IOException; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -155,6 +161,9 @@ public class MemberServiceImpl extends ExpandServiceImpl getByUserIdsAndSpaceId(List userIds, String spaceId) { return baseMapper.selectByUserIdsAndSpaceId(userIds, spaceId); @@ -300,9 +317,14 @@ public List getUnitsByMember(Long memberId) { if (!teamIds.isEmpty()) { List allParentTeamIds = teamFacade.getAllParentTeamIds(teamIds); unitRefIds.addAll(allParentTeamIds); + List refRoles = + iRoleMemberService.getByUnitRefIdsAndUnitType(allParentTeamIds, UnitType.TEAM); + refRoles.stream().map(RoleMemberDTO::getRoleId).forEach(unitRefIds::add); } List roleIds = iRoleMemberService.getRoleIdsByRoleMemberId(memberId); + List tagIds = iTagMemberRelService.getTagIdsByTagMemberId(memberId); unitRefIds.addAll(roleIds); + unitRefIds.addAll(tagIds); return iUnitService.getUnitIdsByRefIds(unitRefIds); } @@ -404,11 +426,6 @@ public List getSpaceIdWithoutNameModifiedByUserId(Long userId) { .collect(Collectors.toList()); } - @Override - public List getInactiveMemberByEmails(String email) { - return baseMapper.selectInactiveMemberByEmail(email); - } - @Override public void updateMemberNameByUserId(Long userId, String memberName) { baseMapper.updateMemberNameByUserId(userId, memberName); @@ -508,13 +525,8 @@ public void restoreMember(MemberEntity member) { @Override @Transactional(rollbackFor = Exception.class) - public List emailInvitation(Long inviteUserId, String spaceId, List emails) { - // remove empty string or null element in collection, then make it distinct - final List distinctEmails = - CollectionUtil.distinctIgnoreCase(CollUtil.removeBlank(emails)); - if (distinctEmails.isEmpty()) { - return new ArrayList<>(); - } + public void createInvitationMember(Long inviteUserId, String spaceId, + List distinctEmails) { // find email in users List userEntities = iUserService.getByEmails(distinctEmails); Map emailUserMap = userEntities.stream() @@ -576,13 +588,8 @@ public List emailInvitation(Long inviteUserId, String spaceId, List sendInviteNotification(inviteUserId, shouldSendInvitationNotify, spaceId, false)); - return memberIds; } private void createInactiveMember(MemberEntity member, String spaceId, String inviteEmail) { @@ -598,10 +605,11 @@ private void createInactiveMember(MemberEntity member, String spaceId, String in } @Override - public void sendInviteEmail(String lang, String spaceId, Long fromMemberId, String email) { + public String sendInviteEmail(String lang, String spaceId, Long fromMemberId, String email) { log.info("send Invite email"); // Other invitation links of the mailbox corresponding to the current space are invalid - spaceInviteRecordMapper.expireBySpaceIdAndEmail(Collections.singletonList(spaceId), email); + spaceInviteRecordMapper.expireBySpaceIdAndEmails(spaceId, + Collections.singletonList(email), "Resend"); // create user invitation link String inviteToken = IdUtil.fastSimpleUUID(); String inviteUrl = @@ -621,6 +629,7 @@ public void sendInviteEmail(String lang, String spaceId, Long fromMemberId, Stri log.info("End Send User Invitation Email :{}", DateUtil.now()); // record success spaceInviteRecordMapper.insert(record.setSendStatus(true).setStatusDesc("Success")); + return inviteToken; } catch (Exception e) { log.error("Send invitation email {} fail", email, e); // record fail @@ -904,8 +913,12 @@ public void batchDeleteMemberFromTeam(String spaceId, List memberIds, Long @Transactional(rollbackFor = Exception.class) public void removeByMemberIds(List memberIds) { baseMapper.deleteBatchByIds(memberIds); + // remove member's private workspace nodes + List unitIds = iUnitService.getUnitIdsByRefIds(memberIds); + iNodeService.deleteMembersNodes(unitIds); // Logically deletes a member unit from an organizational unit iUnitService.removeByMemberId(memberIds); + } @Override @@ -937,18 +950,25 @@ public void batchDeleteMemberFromSpace(String spaceId, List memberIds, } } List memberEntities = baseMapper.selectBatchIds(memberIds); + List needSendEmailMemberIds = new ArrayList<>(); // The invitation link is invalid and the public link it created is deleted if (CollUtil.isNotEmpty(memberEntities)) { List deleteMails = new ArrayList<>(); for (MemberEntity filter : memberEntities) { + if (filter.getIsActive()) { + needSendEmailMemberIds.add(filter.getId()); + } if (StrUtil.isNotBlank(filter.getEmail())) { deleteMails.add(filter.getEmail()); } } if (CollUtil.isNotEmpty(deleteMails)) { - spaceInviteRecordMapper.expireBySpaceIdAndEmails(spaceId, deleteMails); + spaceInviteRecordMapper.expireBySpaceIdAndEmails(spaceId, + deleteMails, "Removed from space"); } } + spaceInviteRecordMapper.expireBySpaceIdAndInviteMemberId(spaceId, + memberIds, "Invitor to leave the space"); spaceInviteLinkMapper.updateByCreators(memberIds); // The associated department of a member is deleted iTeamMemberRelService.removeByMemberIds(memberIds); @@ -962,8 +982,11 @@ public void batchDeleteMemberFromSpace(String spaceId, List memberIds, if (!mailNotify) { return; } + if (needSendEmailMemberIds.isEmpty()) { + return; + } String spaceName = iSpaceService.getNameBySpaceId(spaceId); - final List emails = this.getEmailsByMemberIds(memberIds); + final List emails = this.getEmailsByMemberIds(needSendEmailMemberIds); Dict dict = Dict.create(); dict.set("SPACE_NAME", spaceName); Dict mapDict = Dict.create(); @@ -1011,61 +1034,24 @@ public void preDelBySpaceId(String spaceId, Long userId) { @Override @Transactional(rollbackFor = Exception.class) - public UploadParseResultVO parseExcelFile(String spaceId, MultipartFile multipartFile) { - // subscribe to the limit - // iSubscriptionService.checkSeat(spaceId); - // manipulate user information in space - UserSpaceDto userSpaceDto = LoginContext.me().getUserSpaceDto(spaceId); - UploadParseResultVO resultVo = new UploadParseResultVO(); - try { - // obtaining statistics - int currentMemberCount = - (int) SqlTool.retCount(staticsMapper.countMemberBySpaceId(spaceId)); - SubscriptionInfo subscriptionInfo = - entitlementServiceFacade.getSpaceSubscription(spaceId); - long maxSeatNums = subscriptionInfo.getFeature().getSeat().getValue(); - // long defaultMaxMemberCount = iSubscriptionService.getPlanSeats(spaceId); - // Use the object to read data row by row, - // set the number of rows in the table header, - // and start reading data at line 4, asynchronous reading. - UploadDataListener listener = - new UploadDataListener(spaceId, this, maxSeatNums, currentMemberCount) - .resources(userSpaceDto.getResourceCodes()); - EasyExcel.read(multipartFile.getInputStream(), listener).sheet().headRowNumber(3) - .doRead(); - // gets the parse store record - resultVo.setRowCount(listener.getRowCount()); - resultVo.setSuccessCount(listener.getSuccessCount()); - resultVo.setErrorCount(listener.getErrorCount()); - resultVo.setErrorList(listener.getErrorList()); - // save the error message to the database - AuditUploadParseRecordEntity record = new AuditUploadParseRecordEntity(); - record.setSpaceId(spaceId); - record.setRowSize(listener.getRowCount()); - record.setSuccessCount(listener.getSuccessCount()); - record.setErrorCount(listener.getErrorCount()); - record.setErrorMsg(JSONUtil.toJsonStr(listener.getErrorList())); - auditUploadParseRecordMapper.insert(record); - // send an invitation email - this.batchSendInviteEmailOnUpload(spaceId, userSpaceDto.getMemberId(), - listener.getSendInviteEmails()); - this.batchSendInviteNotifyEmailOnUpload(spaceId, userSpaceDto.getMemberId(), - listener.getSendNotifyEmails()); - Long userId = userSpaceDto.getUserId(); - TaskManager.me().execute( - () -> this.sendInviteNotification(userId, listener.getMemberIds(), spaceId, false)); - } catch (IOException e) { - log.error("file cannot be read", e); - throw new BusinessException(OrganizationException.EXCEL_CAN_READ_ERROR); - } catch (BusinessException e) { - log.error("exceed over limit"); - throw new BusinessException(LimitException.SEATS_OVER_LIMIT); - } catch (Exception e) { - log.error("fail to parse file", e); - throw new BusinessException( - "Failed to parse the file. Download the template and import it"); + public List emailInvitation(Long inviteUserId, String spaceId, List emails) { + // remove empty string or null element in collection, then make it distinct + final List distinctEmails = + CollectionUtil.distinctIgnoreCase(CollUtil.removeBlank(emails)); + if (distinctEmails.isEmpty()) { + return new ArrayList<>(); } - return resultVo; + List emailsInSpace = memberMapper.selectEmailBySpaceIdAndEmails(spaceId, emails); + List emailsNotInSpace = CollUtil.subtractToList(distinctEmails, emailsInSpace); + if (emailsNotInSpace.isEmpty()) { + return new ArrayList<>(); + } + // create member + this.createInvitationMember(inviteUserId, spaceId, emailsNotInSpace); + // send email + invitationServiceFacade.sendInvitationEmail( + new MultiInvitationMetadata(inviteUserId, spaceId, emailsNotInSpace)); + return emailsNotInSpace; } /** @@ -1145,7 +1131,7 @@ public Long saveUploadData(String spaceId, UploadDataDTO uploadData, List getInactiveMemberDtoByMobile(String mobile) { } @Override - public List getInactiveMemberDtoByEmail(String email) { + public List getInactiveMemberByEmail(String email) { return baseMapper.selectInactiveMemberByEmail(email); } @@ -1472,4 +1458,114 @@ public Long getMemberIdByUnitId(String spaceId, String unitId) { public List getUserOwnSpaceIds(Long userId) { return baseMapper.selectSpaceIdsByUserIdAndIsAdmin(userId, true); } + + @Override + @Transactional(rollbackFor = Exception.class) + public UploadParseResultVO parseExcelFile(String spaceId, MultipartFile multipartFile) { + // subscribe to the limit + // iSubscriptionService.checkSeat(spaceId); + // manipulate user information in space + UserSpaceDto userSpaceDto = LoginContext.me().getUserSpaceDto(spaceId); + UploadParseResultVO resultVo = new UploadParseResultVO(); + try { + // obtaining statistics + int currentMemberCount = + (int) SqlTool.retCount(staticsMapper.countMemberBySpaceId(spaceId)); + SubscriptionInfo subscriptionInfo = iSpaceService.getSpaceSubscription(spaceId); + long maxSeatNums = subscriptionInfo.getFeature().getSeat().getValue(); + // long defaultMaxMemberCount = iSubscriptionService.getPlanSeats(spaceId); + // Use the object to read data row by row, + // set the number of rows in the table header, + // and start reading data at line 4, asynchronous reading. + UploadDataListener listener = + new UploadDataListener(spaceId, this, maxSeatNums, currentMemberCount) + .resources(userSpaceDto.getResourceCodes()); + EasyExcel.read(multipartFile.getInputStream(), listener).sheet().headRowNumber(3) + .doRead(); + // gets the parse store record + resultVo.setRowCount(listener.getRowCount()); + resultVo.setSuccessCount(listener.getSuccessCount()); + resultVo.setErrorCount(listener.getErrorCount()); + resultVo.setErrorList(listener.getErrorList()); + // save the error message to the database + AuditUploadParseRecordEntity record = new AuditUploadParseRecordEntity(); + record.setSpaceId(spaceId); + record.setRowSize(listener.getRowCount()); + record.setSuccessCount(listener.getSuccessCount()); + record.setErrorCount(listener.getErrorCount()); + record.setErrorMsg(JSONUtil.toJsonStr(listener.getErrorList())); + auditUploadParseRecordMapper.insert(record); + // send an invitation email + this.batchSendInviteEmailOnUpload(spaceId, userSpaceDto.getMemberId(), + listener.getSendInviteEmails()); + this.batchSendInviteNotifyEmailOnUpload(spaceId, userSpaceDto.getMemberId(), + listener.getSendNotifyEmails()); + Long userId = userSpaceDto.getUserId(); + TaskManager.me().execute( + () -> this.sendInviteNotification(userId, listener.getMemberIds(), spaceId, false)); + } catch (IOException e) { + log.error("file cannot be read", e); + throw new BusinessException(OrganizationException.EXCEL_CAN_READ_ERROR); + } catch (BusinessException e) { + log.error("exceed over limit"); + throw new BusinessException(LimitException.SEATS_OVER_LIMIT); + } catch (Exception e) { + log.error("fail to parse file", e); + throw new BusinessException( + "Failed to parse the file. Download the template and import it"); + } + return resultVo; + } + + /** + * check space invited record. + * + * @param spaceId space id + * @return boolean + */ + @Override + public boolean shouldPreventInvitation(String spaceId) { + LocalDateTime startAt = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0); + LocalDateTime endAt = + LocalDateTime.now().plusDays(1).withHour(0).withMinute(0).withSecond(0); + Integer count = + spaceInviteRecordMapper.selectCountBySpaceIdAndBetween(spaceId, startAt, endAt); + return count >= limitProperties.getMaxInviteCountForFree(); + } + + @Override + public List getMemberBySpaceIdAndUserIds(String spaceId, + List userIds) { + List unitMembers = new ArrayList<>(); + List members = baseMapper.selectDtoBySpaceIdAndUserIds(spaceId, userIds); + List memberIds = members.stream().map(MemberDTO::getId).toList(); + Map> memberTeamMap = iTeamService.getMembersTeamName(memberIds); + Map users = iUserService.getByIds(userIds).stream() + .collect(Collectors.toMap(UserEntity::getId, i -> i)); + Map memberUnitMap = + iUnitService.getUnitBaseInfoByRefIds(memberIds).stream().collect( + Collectors.toMap(UnitBaseInfoDTO::getUnitRefId, UnitBaseInfoDTO::getId)); + Map userMemberMap = + members.stream().collect(Collectors.toMap(MemberDTO::getUserId, i -> i)); + // maybe member doesn't bind any user. + for (Long userId : userIds) { + UnitMemberTeamDTO unitMember = new UnitMemberTeamDTO(); + MemberDTO member = userMemberMap.get(userId); + if (null != member) { + unitMember.setOpenId(member.getOpenId()); + unitMember.setDeleted(member.getIsDeleted()); + unitMember.setMemberId(member.getId()); + unitMember.setMemberName(member.getMemberName()); + unitMember.setUnitId(memberUnitMap.get(member.getId())); + String teamName = StrUtil.join(" & ", memberTeamMap.get(member.getId())); + unitMember.setTeamName(teamName); + } + UserEntity user = users.get(userId); + unitMember.setUserId(userId); + unitMember.setAvatar(user.getAvatar()); + unitMember.setAvatarColor(user.getColor()); + unitMembers.add(unitMember); + } + return unitMembers; + } } diff --git a/backend-server/application/src/main/java/com/apitable/organization/service/impl/OrganizationServiceImpl.java b/backend-server/application/src/main/java/com/apitable/organization/service/impl/OrganizationServiceImpl.java index ec707ea9bd..657ad1f7f0 100644 --- a/backend-server/application/src/main/java/com/apitable/organization/service/impl/OrganizationServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/organization/service/impl/OrganizationServiceImpl.java @@ -44,7 +44,7 @@ import com.apitable.shared.config.properties.LimitProperties; import com.apitable.shared.util.DBUtil; import com.apitable.shared.util.information.InformationUtil; -import com.apitable.workspace.service.impl.NodeRoleServiceImpl; +import com.apitable.workspace.service.INodeRoleService; import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; import jakarta.annotation.Resource; import java.util.ArrayList; @@ -99,7 +99,7 @@ public class OrganizationServiceImpl implements IOrganizationService { private IRoleService iRoleService; @Resource - private NodeRoleServiceImpl nodeRoleService; + private INodeRoleService nodeRoleService; @Resource private SocialServiceFacade socialServiceFacade; diff --git a/backend-server/application/src/main/java/com/apitable/organization/service/impl/RoleMemberServiceImpl.java b/backend-server/application/src/main/java/com/apitable/organization/service/impl/RoleMemberServiceImpl.java index d9fbfe4e7b..2e6f9481d5 100644 --- a/backend-server/application/src/main/java/com/apitable/organization/service/impl/RoleMemberServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/organization/service/impl/RoleMemberServiceImpl.java @@ -75,13 +75,13 @@ public class RoleMemberServiceImpl extends ServiceImpl consumer) @Override public List getRoleIdsByUnitIds(String spaceId, List unitIds) { - if (unitIds.isEmpty()) { + if (CollUtil.isEmpty(unitIds)) { return new ArrayList<>(); } return iUnitService.getUnitBaseInfoBySpaceIdAndUnitTypeAndUnitIds(spaceId, UnitType.ROLE, diff --git a/backend-server/application/src/main/java/com/apitable/organization/service/impl/TagMemberRelServiceImpl.java b/backend-server/application/src/main/java/com/apitable/organization/service/impl/TagMemberRelServiceImpl.java new file mode 100644 index 0000000000..98dc0c7493 --- /dev/null +++ b/backend-server/application/src/main/java/com/apitable/organization/service/impl/TagMemberRelServiceImpl.java @@ -0,0 +1,68 @@ +package com.apitable.organization.service.impl; + +import cn.hutool.core.collection.CollUtil; +import com.apitable.organization.entity.TagMemberRelEntity; +import com.apitable.organization.mapper.TagMemberRelMapper; +import com.apitable.organization.service.ITagMemberRelService; +import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import jakarta.annotation.Resource; +import java.util.List; +import java.util.stream.Collectors; +import org.springframework.stereotype.Service; + +/** + * Tag member rel service. + */ +@Service +public class TagMemberRelServiceImpl extends ServiceImpl + implements ITagMemberRelService { + + @Resource + private TagMemberRelMapper tagGroupMemberRelMapper; + + + @Override + public List getByTagIds(List tagIds) { + return tagGroupMemberRelMapper.selectByTagIds(tagIds); + } + + @Override + public List getMemberIdByTagIds(List tagIds) { + if (CollUtil.isEmpty(tagIds)) { + return CollUtil.newArrayList(); + } + return tagGroupMemberRelMapper.selectMemberIdsByTag(tagIds); + } + + @Override + public void removeMembers(Long tagId, List memberIds) { + if (CollUtil.isEmpty(memberIds)) { + return; + } + tagGroupMemberRelMapper.deleteByMemberIdAndTagId(tagId, memberIds); + } + + @Override + public void addMembers(Long tagId, List memberIds) { + List tagMemberRelEntityList = memberIds.stream().map(m -> { + return TagMemberRelEntity.builder() + .id(IdWorker.getId()) + .tagId(tagId) + .memberId(m) + .build(); + }).collect(Collectors.toList()); + tagGroupMemberRelMapper.insertBatch(tagMemberRelEntityList); + } + + @Override + public void deleteMembersByTagId(Long tagId) { + tagGroupMemberRelMapper.deleteMembersByTagId(tagId); + } + + @Override + public List getTagIdsByTagMemberId(Long memberId) { + return tagGroupMemberRelMapper.selectTagIdsByMemberId(memberId); + } + +} diff --git a/backend-server/application/src/main/java/com/apitable/organization/service/impl/TagServiceImpl.java b/backend-server/application/src/main/java/com/apitable/organization/service/impl/TagServiceImpl.java new file mode 100644 index 0000000000..1bf7f0be3b --- /dev/null +++ b/backend-server/application/src/main/java/com/apitable/organization/service/impl/TagServiceImpl.java @@ -0,0 +1,109 @@ +package com.apitable.organization.service.impl; + +import cn.hutool.core.collection.CollUtil; +import com.apitable.base.enums.DatabaseException; +import com.apitable.core.util.ExceptionUtil; +import com.apitable.organization.dto.TagInfoDto; +import com.apitable.organization.entity.TagEntity; +import com.apitable.organization.entity.TagMemberRelEntity; +import com.apitable.organization.enums.UnitType; +import com.apitable.organization.mapper.TagMapper; +import com.apitable.organization.mapper.TagMemberRelMapper; +import com.apitable.organization.service.ITagService; +import com.apitable.organization.service.IUnitService; +import com.apitable.organization.vo.TagInfoVo; +import com.baomidou.mybatisplus.core.toolkit.IdWorker; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import jakarta.annotation.Resource; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +/** + * Tag service. + */ +@Slf4j +@Service +public class TagServiceImpl extends ServiceImpl implements ITagService { + + @Resource + IUnitService iUnitService; + + @Resource + private TagMapper tagMapper; + + @Resource + private TagMemberRelMapper tagGroupMemberRelMapper; + + @Override + public Long createTag(Long groupId, String spaceId, String tagName) { + log.info("create tag: {} , spaceId: {}", tagName, spaceId); + TagEntity tagEntity = TagEntity.builder() + .id(IdWorker.getId()) + .spaceId(spaceId) + .tagName(tagName) + .build(); + boolean ret = save(tagEntity); + ExceptionUtil.isTrue(ret, DatabaseException.INSERT_ERROR); + // add ref unit. + iUnitService.create(spaceId, UnitType.TAG, tagEntity.getId()); + return tagEntity.getId(); + } + + @Override + public void updateTagName(Long tagId, String tagName) { + tagMapper.updateName(tagId, tagName); + } + + @Override + public void delete(Long tagId) { + // clear tag's member + tagGroupMemberRelMapper.deleteMembersByTagId(tagId); + // delete the ref unit and control role. + iUnitService.removeByRefId(tagId); + // delete the tag. + boolean ret = removeById(tagId); + ExceptionUtil.isTrue(ret, DatabaseException.DELETE_ERROR); + } + + @Override + public List getTagVos(String spaceId, List tagIds) { + + if (CollUtil.isEmpty(tagIds)) { + return CollUtil.newArrayList(); + } + // query the space's tag. + List tagInfoVoList = new ArrayList<>(); + List tagMemberRelEntityList = + tagGroupMemberRelMapper.selectByTagIds(tagIds); + Map tagCountMap = tagMemberRelEntityList.stream() + .collect(Collectors.groupingBy(TagMemberRelEntity::getTagId, Collectors.counting())); + List tagInfoDtos = tagMapper.selectTagInfoDtoByIdsAndSpaceId(tagIds, spaceId); + //calc member count + tagInfoDtos.stream().forEach(t -> { + Long memberCount = tagCountMap.getOrDefault(t.getId(), 0L); + tagInfoVoList.add(TagInfoVo.builder() + .unitId(t.getUnitId()) + .tagId(t.getId()) + .tagName(t.getTagName()) + .memberCount(memberCount) + .build()); + }); + return tagInfoVoList; + } + + @Override + public List getMemberIdsByTagIds(List tagIds) { + if (CollUtil.isEmpty(tagIds)) { + return CollUtil.newArrayList(); + } + List tagMemberRelEntityList = + tagGroupMemberRelMapper.selectByTagIds(tagIds); + + return tagMemberRelEntityList.stream().map(m -> m.getMemberId()).distinct().collect( + Collectors.toList()); + } +} diff --git a/backend-server/application/src/main/java/com/apitable/organization/service/impl/TeamMemberRelServiceImpl.java b/backend-server/application/src/main/java/com/apitable/organization/service/impl/TeamMemberRelServiceImpl.java index ad1c12ed2b..5848f33d2a 100644 --- a/backend-server/application/src/main/java/com/apitable/organization/service/impl/TeamMemberRelServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/organization/service/impl/TeamMemberRelServiceImpl.java @@ -116,4 +116,9 @@ public void removeByTeamIds(Collection teamIds) { public void removeByTeamIdsAndMemberId(Long memberId, List teamIds) { baseMapper.deleteByTeamIdsAndMemberId(memberId, teamIds); } + + @Override + public List getByMemberIds(List memberIds) { + return baseMapper.selectByMemberIds(memberIds); + } } diff --git a/backend-server/application/src/main/java/com/apitable/organization/service/impl/TeamServiceImpl.java b/backend-server/application/src/main/java/com/apitable/organization/service/impl/TeamServiceImpl.java index 9d2663f945..ce1801d944 100644 --- a/backend-server/application/src/main/java/com/apitable/organization/service/impl/TeamServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/organization/service/impl/TeamServiceImpl.java @@ -20,6 +20,8 @@ import static com.apitable.organization.enums.OrganizationException.DUPLICATION_TEAM_NAME; import static com.apitable.organization.enums.OrganizationException.GET_TEAM_ERROR; +import static java.util.stream.Collectors.mapping; +import static java.util.stream.Collectors.toList; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.BooleanUtil; @@ -36,6 +38,7 @@ import com.apitable.organization.dto.TeamPathInfo; import com.apitable.organization.dto.UnitBaseInfoDTO; import com.apitable.organization.entity.TeamEntity; +import com.apitable.organization.entity.TeamMemberRelEntity; import com.apitable.organization.entity.UnitEntity; import com.apitable.organization.enums.OrganizationException; import com.apitable.organization.enums.UnitType; @@ -261,8 +264,7 @@ public MemberIsolatedInfo checkMemberIsolatedBySpaceId(String spaceId, Long memb public boolean checkHasSubUnitByTeamId(String spaceId, Long teamId) { log.info("Check whether the team has members or teams"); List subTeamIds = baseMapper.selectTeamIdsByParentId(spaceId, teamId); - long subMemberCount = - SqlTool.retCount(teamMemberRelMapper.countByTeamId(Collections.singletonList(teamId))); + long subMemberCount = this.getMemberCount(Collections.singletonList(teamId)); return CollUtil.isNotEmpty(subTeamIds) || subMemberCount > 0; } @@ -270,14 +272,21 @@ public boolean checkHasSubUnitByTeamId(String spaceId, Long teamId) { public long countMemberCountByParentId(Long teamId) { log.info("count the team's members, includes the sub teams' members."); List allSubTeamIds = this.getAllTeamIdsInTeamTree(teamId); - return CollUtil.isNotEmpty(allSubTeamIds) - ? SqlTool.retCount(teamMemberRelMapper.countByTeamId(allSubTeamIds)) : 0; + return this.getMemberCount(allSubTeamIds); } @Override public long getMemberCount(List teamIds) { - // obtain the number of all members in a department - return SqlTool.retCount(teamMemberRelMapper.countByTeamId(teamIds)); + if (CollUtil.isEmpty(teamIds)) { + return 0; + } + // obtain the count of all members in departments + List teamMemberRelEntities = + DBUtil.batchSelectByFieldIn(teamIds, teamMemberRelMapper::selectByTeamIds, 100); + // deduplication + Set memberIds = teamMemberRelEntities.stream() + .map(TeamMemberRelEntity::getMemberId).collect(Collectors.toSet()); + return memberIds.size(); } @Override @@ -501,7 +510,7 @@ public TeamInfoVo getTeamInfoById(Long teamId) { } teamInfo.setTeamId(teamId); List teamIds = this.getAllTeamIdsInTeamTree(teamId); - Long memberCount = SqlHelper.retCount(teamMemberRelMapper.countByTeamId(teamIds)); + Long memberCount = this.getMemberCount(teamIds); teamInfo.setMemberCount(memberCount); return teamInfo; } @@ -656,7 +665,7 @@ public Map> batchGetFullHierarchyTeamNames(List> memberTeamMap = memberTeamInfoList.stream() .collect(Collectors.groupingBy(MemberTeamInfoDTO::getMemberId, - Collectors.mapping(MemberTeamInfoDTO::getTeamId, Collectors.toList()))); + mapping(MemberTeamInfoDTO::getTeamId, Collectors.toList()))); // get member's each full hierarchy team name Map> teamIdToPathMap = this.getMemberEachTeamPathName(memberTeamMap, spaceId); @@ -725,6 +734,32 @@ public TeamEntity getTeamByUnitId(String spaceId, String unitId) { return department; } + @Override + public Map> getMembersTeamName(List memberIds) { + List memberTeamRel = iTeamMemberRelService.getByMemberIds(memberIds); + if (memberTeamRel.isEmpty()) { + return new HashMap<>(0); + } + List teamIds = + memberTeamRel.stream().map(TeamMemberRelEntity::getTeamId).distinct().toList(); + Map> memberTeamIdMap = memberTeamRel.stream().collect( + Collectors.groupingBy(TeamMemberRelEntity::getMemberId, + mapping(TeamMemberRelEntity::getTeamId, toList()))); + Map teamNameMap = baseMapper.selectBaseInfoDTOByIds(teamIds) + .stream() + .collect(Collectors.toMap(TeamBaseInfoDTO::getId, TeamBaseInfoDTO::getTeamName)); + Map> memberTeamMap = new HashMap<>(); + for (Long memberId : memberIds) { + if (!memberTeamIdMap.containsKey(memberId)) { + continue; + } + List teamNames = + memberTeamIdMap.get(memberId).stream().map(teamNameMap::get).toList(); + memberTeamMap.put(memberId, teamNames); + } + return memberTeamMap; + } + @Override public Map> getMemberEachTeamPathName(Map> memberTeamMap, String spaceId) { diff --git a/backend-server/application/src/main/java/com/apitable/organization/service/impl/UnitServiceImpl.java b/backend-server/application/src/main/java/com/apitable/organization/service/impl/UnitServiceImpl.java index c07a2d2071..3fb6eb3c9d 100644 --- a/backend-server/application/src/main/java/com/apitable/organization/service/impl/UnitServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/organization/service/impl/UnitServiceImpl.java @@ -23,6 +23,7 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.IdUtil; +import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.StrUtil; import com.apitable.base.enums.DatabaseException; import com.apitable.control.service.IControlRoleService; @@ -42,6 +43,7 @@ import com.apitable.organization.entity.TeamMemberRelEntity; import com.apitable.organization.entity.UnitEntity; import com.apitable.organization.enums.MemberType; +import com.apitable.organization.enums.OrganizationException; import com.apitable.organization.enums.UnitType; import com.apitable.organization.mapper.MemberMapper; import com.apitable.organization.mapper.RoleMapper; @@ -64,6 +66,7 @@ import com.apitable.user.dto.UserSensitiveDTO; import com.apitable.user.service.IUserService; import com.apitable.workspace.enums.PermissionException; +import com.apitable.workspace.service.INodeService; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.toolkit.IdWorker; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -116,6 +119,9 @@ public class UnitServiceImpl extends ExpandServiceImpl @Resource private IUserService iUserService; + @Resource + private INodeService iNodeService; + @Override public Long getUnitRefIdById(Long id) { return baseMapper.selectRefIdById(id); @@ -177,6 +183,8 @@ public void restoreMemberUnit(String spaceId, Collection memberIds) { if (CollUtil.isNotEmpty(restores)) { baseMapper.batchRestoreByIds(restores); + // restore private nodes + iNodeService.restoreMembersNodes(restores); } } @@ -581,12 +589,12 @@ public PageInfo getUnitSubTeamsWithPage(String spaceId, Long par IPage teamIds = teamMapper.selectTeamIdsBySpaceIdAndParentIdAndPage(page, spaceId, parentTeamId); if (teamIds.getSize() == 0) { - return PageHelper.build((int) teamIds.getCurrent(), (int) teamIds.getSize(), - (int) teamIds.getTotal(), new ArrayList<>()); + return PageHelper.build(teamIds.getCurrent(), teamIds.getSize(), + teamIds.getTotal(), new ArrayList<>()); } List units = getUnitTeamByTeamIds(teamIds.getRecords()); - return PageHelper.build((int) teamIds.getCurrent(), (int) teamIds.getSize(), - (int) teamIds.getTotal(), units); + return PageHelper.build(teamIds.getCurrent(), teamIds.getSize(), + teamIds.getTotal(), units); } @Override @@ -594,8 +602,8 @@ public PageInfo getUnitRolesWithPage(String spaceId, Page page) { IPage roles = roleMapper.selectBySpaceIdAndPage(page, spaceId); if (roles.getSize() == 0) { - return PageHelper.build((int) roles.getCurrent(), (int) roles.getSize(), - (int) roles.getTotal(), new ArrayList<>()); + return PageHelper.build(roles.getCurrent(), roles.getSize(), + roles.getTotal(), new ArrayList<>()); } List roleIds = roles.getRecords().stream().map(RoleBaseInfoDto::getId).collect(Collectors.toList()); @@ -603,8 +611,8 @@ public PageInfo getUnitRolesWithPage(String spaceId, .collect(Collectors.toMap(UnitBaseInfoDTO::getUnitRefId, UnitBaseInfoDTO::getUnitId)); if (roleUnits.keySet().isEmpty()) { - return PageHelper.build((int) roles.getCurrent(), (int) roles.getSize(), - (int) roles.getTotal(), new ArrayList<>()); + return PageHelper.build(roles.getCurrent(), roles.getSize(), + roles.getTotal(), new ArrayList<>()); } List units = new ArrayList<>(); roles.getRecords().forEach(r -> { @@ -614,8 +622,8 @@ public PageInfo getUnitRolesWithPage(String spaceId, .build(); units.add(unit); }); - return PageHelper.build((int) roles.getCurrent(), (int) roles.getSize(), - (int) roles.getTotal(), units); + return PageHelper.build(roles.getCurrent(), roles.getSize(), + roles.getTotal(), units); } @Override @@ -624,13 +632,13 @@ public PageInfo getMembersByTeamId(String spaceId, Long parent IPage memberIds = teamMemberRelMapper.selectMemberIdsByTeamIdAndPage(page, parentTeamId); if (memberIds.getRecords().isEmpty()) { - return PageHelper.build((int) memberIds.getCurrent(), (int) memberIds.getSize(), - (int) memberIds.getTotal(), new ArrayList<>()); + return PageHelper.build(memberIds.getCurrent(), memberIds.getSize(), + memberIds.getTotal(), new ArrayList<>()); } List members = getUnitMemberByMemberIds(memberIds.getRecords(), sensitiveData); - return PageHelper.build((int) memberIds.getCurrent(), (int) memberIds.getSize(), - (int) memberIds.getTotal(), members); + return PageHelper.build(memberIds.getCurrent(), memberIds.getSize(), + memberIds.getTotal(), members); } @Override @@ -652,6 +660,24 @@ public UnitRoleMemberVo getRoleMembers(String spaceId, Long roleId, } return vo; } + + @Override + public void checkUnit(Long memberId, String unitId) { + if (null == unitId) { + return; + } + UnitEntity unit = baseMapper.selectById(NumberUtil.parseLong(unitId)); + ExceptionUtil.isFalse(null == unit, OrganizationException.ILLEGAL_UNIT_ID); + if (unit.getUnitType().equals(UnitType.MEMBER.getType())) { + ExceptionUtil.isTrue(unit.getUnitRefId().equals(memberId), + OrganizationException.ILLEGAL_UNIT_ID); + } + if (unit.getUnitType().equals(UnitType.TEAM.getType())) { + List memberIds = teamMemberRelMapper.selectMemberIdsByTeamId(unit.getUnitRefId()); + ExceptionUtil.isTrue(memberIds.contains(memberId), + OrganizationException.ILLEGAL_UNIT_ID); + } + } } diff --git a/backend-server/application/src/main/java/com/apitable/organization/vo/TagInfoVo.java b/backend-server/application/src/main/java/com/apitable/organization/vo/TagInfoVo.java new file mode 100644 index 0000000000..ada871d969 --- /dev/null +++ b/backend-server/application/src/main/java/com/apitable/organization/vo/TagInfoVo.java @@ -0,0 +1,35 @@ +package com.apitable.organization.vo; + +import com.apitable.shared.support.serializer.NullNumberSerializer; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Builder; +import lombok.Data; + +/** + *

+ * tag's info. + *

+ */ +@Data +@Builder +@Schema(description = "tag's info") +public class TagInfoVo { + + @Schema(description = "unit id", example = "1") + @JsonSerialize(using = ToStringSerializer.class) + private Long unitId; + + @Schema(description = "tag id", example = "1") + @JsonSerialize(using = ToStringSerializer.class) + private Long tagId; + + @Schema(description = "tag name", example = "1") + @JsonSerialize(using = ToStringSerializer.class) + private String tagName; + + @Schema(description = "Number of tag members", example = "3") + @JsonSerialize(nullsUsing = NullNumberSerializer.class) + private Long memberCount; +} diff --git a/backend-server/application/src/main/java/com/apitable/player/config/properties/NotificationProperties.java b/backend-server/application/src/main/java/com/apitable/player/config/properties/NotificationProperties.java new file mode 100644 index 0000000000..404e53e71b --- /dev/null +++ b/backend-server/application/src/main/java/com/apitable/player/config/properties/NotificationProperties.java @@ -0,0 +1,31 @@ +/* + * APITable Ltd. + * Copyright (C) 2022 APITable Ltd. + * + * This code file is part of APITable Enterprise Edition. + * + * It is subject to the APITable Commercial License and conditional on having a fully paid-up license from APITable. + * + * Access to this code file or other code files in this `enterprise` directory and its subdirectories does not constitute permission to use this code or APITable Enterprise Edition features. + * + * Unless otherwise noted, all files Copyright © 2022 APITable Ltd. + * + * For purchase of APITable Enterprise Edition license, please contact . + */ + +package com.apitable.player.config.properties; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; + +/** + * notification properties. + */ +@Data +@ConfigurationProperties(prefix = "notification") +public class NotificationProperties { + private String callbackUrl; + + private String templateIds; +} + diff --git a/backend-server/application/src/main/java/com/apitable/player/service/impl/PlayerNotificationServiceImpl.java b/backend-server/application/src/main/java/com/apitable/player/service/impl/PlayerNotificationServiceImpl.java index 06e7a8209a..2fa7bcac9b 100644 --- a/backend-server/application/src/main/java/com/apitable/player/service/impl/PlayerNotificationServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/player/service/impl/PlayerNotificationServiceImpl.java @@ -72,6 +72,7 @@ import com.apitable.shared.component.TaskManager; import com.apitable.shared.component.notification.INotificationFactory; import com.apitable.shared.component.notification.NotificationHelper; +import com.apitable.shared.component.notification.NotificationManager; import com.apitable.shared.component.notification.NotificationRenderMap; import com.apitable.shared.component.notification.NotificationTemplateId; import com.apitable.shared.component.notification.NotificationToTag; @@ -552,6 +553,7 @@ public boolean setDeletedIsTrue(String[] ids) { return baseMapper.deleteNotificationByIds(ids); } + @Override public boolean createBatch(List notifyEntities, List createEntities) { @@ -562,7 +564,10 @@ public boolean createBatch(List notifyEntities, // Therefore, if there is a key, no message will be sent, but the number of messages will be increased. } if (CollUtil.isNotEmpty(createEntities)) { - return SqlHelper.retBool(baseMapper.insertBatch(createEntities)); + boolean result = SqlHelper.retBool(baseMapper.insertBatch(createEntities)); + TaskManager.me().execute(() -> NotificationManager.me().doCallback(notifyEntities)); + return result; + } return true; } @@ -681,13 +686,12 @@ private Dict formatEmailDetailVo(NotificationCreateRo ro) { dict.set(EMAIL_SPACE_NAME, StrUtil.blankToDefault(iSpaceService.getNameBySpaceId(ro.getSpaceId()), "")); } - long fromUserId = Long.parseLong(ro.getFromUserId()); - if (fromUserId > 0) { - String memberName = - StrUtil.blankToDefault(iMemberService.getMemberNameByUserIdAndSpaceId(fromUserId, - ro.getSpaceId()), I18nStringsUtil.t("unnamed")); - dict.set(EMAIL_MEMBER_NAME, memberName); - } + String memberName = null != ro.getFromUserId() + ? StrUtil.blankToDefault( + iMemberService.getMemberNameByUserIdAndSpaceId(Long.parseLong(ro.getFromUserId()), + ro.getSpaceId()), I18nStringsUtil.t("unnamed")) + : I18nStringsUtil.t("unnamed"); + dict.set(EMAIL_MEMBER_NAME, memberName); if (ObjectUtil.isNotNull(ro.getBody())) { JSONObject extras = NotificationHelper.getExtrasFromNotifyBody(ro.getBody()); if (extras != null) { @@ -741,4 +745,4 @@ private Dict formatEmailDetailVo(NotificationCreateRo ro) { } return dict; } -} +} \ No newline at end of file diff --git a/backend-server/application/src/main/java/com/apitable/shared/component/notification/NotificationFactory.java b/backend-server/application/src/main/java/com/apitable/shared/component/notification/NotificationFactory.java index 76a5d6c6b4..07142907cf 100644 --- a/backend-server/application/src/main/java/com/apitable/shared/component/notification/NotificationFactory.java +++ b/backend-server/application/src/main/java/com/apitable/shared/component/notification/NotificationFactory.java @@ -24,7 +24,6 @@ import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.ListUtil; import cn.hutool.core.convert.Convert; -import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.LocalDateTimeUtil; import cn.hutool.core.map.MapUtil; import cn.hutool.core.text.CharSequenceUtil; @@ -41,6 +40,7 @@ import com.apitable.player.ro.NotificationCreateRo; import com.apitable.player.vo.NotificationDetailVo; import com.apitable.player.vo.PlayerBaseVo; +import com.apitable.shared.clock.spring.ClockManager; import com.apitable.shared.sysconfig.notification.NotificationConfigLoader; import com.apitable.shared.sysconfig.notification.NotificationTemplate; import com.apitable.space.dto.BaseSpaceInfoDTO; @@ -57,7 +57,6 @@ import java.time.LocalDateTime; import java.time.temporal.ChronoUnit; import java.util.ArrayList; -import java.util.Date; import java.util.List; import java.util.Map; import java.util.Objects; @@ -205,7 +204,7 @@ public NotificationRenderMap getRenderList(List dtos) { nodeIds.add(dto.getNodeId()); if (dto.getFromUser() != 0) { Long memberId = - memberMapper.selectMemberIdByUserIdAndSpaceIdExcludeDelete(dto.getFromUser(), + memberMapper.selectMemberIdByUserIdAndSpaceIdIncludeDeleted(dto.getFromUser(), dto.getSpaceId()); if (ObjectUtil.isNotNull(memberId)) { memberIds.add(memberId); @@ -337,7 +336,7 @@ public void addUserNotifyFrequency(Long userId, NotificationTemplate template, S if (Boolean.TRUE.equals(redisTemplate.hasKey(key))) { redisTemplate.opsForValue().increment(key); } else { - LocalDateTime now = DateUtil.toLocalDateTime(new Date()); + LocalDateTime now = ClockManager.me().getLocalDateTimeNow(); LocalDateTime endOfDay = LocalDateTimeUtil.endOfDay(now); long between = LocalDateTimeUtil.between(now, endOfDay, ChronoUnit.SECONDS); redisTemplate.opsForValue().set(key, Long.valueOf("1"), between, TimeUnit.SECONDS); diff --git a/backend-server/application/src/main/java/com/apitable/shared/component/notification/NotificationManager.java b/backend-server/application/src/main/java/com/apitable/shared/component/notification/NotificationManager.java index f5f3d2e0ad..22f0099962 100644 --- a/backend-server/application/src/main/java/com/apitable/shared/component/notification/NotificationManager.java +++ b/backend-server/application/src/main/java/com/apitable/shared/component/notification/NotificationManager.java @@ -22,8 +22,12 @@ import cn.hutool.core.convert.Convert; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; +import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.apitable.core.util.SpringContextHolder; +import com.apitable.interfaces.social.facade.SocialServiceFacade; +import com.apitable.player.config.properties.NotificationProperties; +import com.apitable.player.entity.PlayerNotificationEntity; import com.apitable.player.ro.NotificationCreateRo; import com.apitable.player.service.impl.PlayerNotificationServiceImpl; import com.apitable.shared.cache.service.LoginUserCacheService; @@ -32,10 +36,15 @@ import com.apitable.shared.constants.NotificationConstants; import com.apitable.starter.socketio.core.SocketClientTemplate; import jakarta.annotation.Resource; +import java.util.Arrays; +import java.util.HashMap; import java.util.List; import java.util.Map; import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; import org.springframework.stereotype.Component; +import org.springframework.web.client.RestClient; /** * notification manager. @@ -59,6 +68,15 @@ public class NotificationManager { @Resource private MessagingCenterNotifyObserver messagingCenterNotifyObserver; + @Resource + private NotificationProperties notificationProperties; + + @Resource + private RestClient restClient; + + @Resource + private SocialServiceFacade socialServiceFacade; + public static NotificationManager me() { return SpringContextHolder.getBean(NotificationManager.class); } @@ -144,4 +162,61 @@ public void centerNotify(NotificationCreateRo ro) { centerSub.addObserver(messagingCenterNotifyObserver); centerSub.send(ro); } + + /** + * notification call back. + */ + public void doCallback(List entities) { + String callbackUrl = notificationProperties.getCallbackUrl(); + if (StrUtil.isBlank(callbackUrl)) { + return; + } + List filterTemplateIds = + Arrays.stream(notificationProperties.getTemplateIds().split(",")).toList(); + List fromUserIds = ListUtil.toList(); + List toUserIds = ListUtil.toList(); + entities.forEach(i -> { + if (!i.getFromUser().equals(0L)) { + fromUserIds.add(i.getFromUser()); + } + toUserIds.add(i.getToUser()); + }); + Map fromUserMap = socialServiceFacade.getUnionIdMap(fromUserIds); + Map toUserMap = socialServiceFacade.getUnionIdMap(toUserIds); + List> dataList = ListUtil.toList(); + entities.forEach(entity -> { + if (!filterTemplateIds.contains(entity.getTemplateId())) { + return; + } + JSONObject body = JSONUtil.parseObj(entity.getNotifyBody()); + // remove null fields + Map data = new HashMap<>(); + data.put("spaceId", entity.getSpaceId()); + data.put("nodeId", entity.getNodeId()); + data.put("embedId", body.getByPath("extras.linkId")); + data.put("templateId", entity.getTemplateId()); + data.put("fromUserId", entity.getFromUser()); + data.put("fromUserUnionId", fromUserMap.get(entity.getFromUser())); + data.put("toUserId", entity.getToUser()); + data.put("toUserUnionId", toUserMap.get(entity.getToUser())); + data.put("notifyBody", body); // json string + dataList.add(data); + }); + if (dataList.isEmpty()) { + return; + } + Map paramMap = new HashMap<>(); + paramMap.put("data", dataList); + + HttpHeaders header = new HttpHeaders(); + header.setContentType(MediaType.APPLICATION_JSON); + // post request needs to be set contentType + RestClient.ResponseSpec res = restClient + .post() + .uri(callbackUrl) + .headers(headers -> headers.addAll(header)) + .body(paramMap) + .retrieve(); + log.info("doCallback:{}", res); + } } diff --git a/backend-server/application/src/main/java/com/apitable/shared/component/notification/observer/AbstractNotifyObserver.java b/backend-server/application/src/main/java/com/apitable/shared/component/notification/observer/AbstractNotifyObserver.java index 927a6fd9b8..b5165a2c81 100644 --- a/backend-server/application/src/main/java/com/apitable/shared/component/notification/observer/AbstractNotifyObserver.java +++ b/backend-server/application/src/main/java/com/apitable/shared/component/notification/observer/AbstractNotifyObserver.java @@ -29,12 +29,12 @@ import cn.hutool.json.JSONUtil; import com.apitable.organization.service.IMemberService; import com.apitable.player.ro.NotificationCreateRo; +import com.apitable.shared.clock.spring.ClockManager; import com.apitable.shared.component.notification.NotificationHelper; import com.apitable.shared.sysconfig.i18n.I18nStringsUtil; import com.apitable.space.service.ISpaceService; import com.apitable.workspace.service.INodeService; import jakarta.annotation.Resource; -import java.time.Instant; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.HashMap; @@ -43,9 +43,7 @@ import java.util.Objects; /** - *

* base notify observer. - *

* * @author zoe zheng */ @@ -92,8 +90,8 @@ public Map bindingMap(NotificationCreateRo ro) { if (extras != null) { extras.forEach((k, v) -> { if (StrUtil.endWith(k, "At")) { - LocalDateTime dateTime = DateUtil.toLocalDateTime( - Instant.ofEpochMilli(Long.parseLong(v.toString()))); + LocalDateTime dateTime = + ClockManager.me().convertMillis(Long.parseLong(v.toString())); bindingMap.put(k, DateUtil.format(dateTime, NORM_DATETIME_MINUTE_PATTERN)); } else if (Objects.equals(k, INVOLVE_RECORD_IDS)) { bindingMap.put(StrUtil.toCamelCase(EMAIL_RECORD_ID), diff --git a/backend-server/application/src/main/java/com/apitable/shared/component/notification/queue/QueueConfig.java b/backend-server/application/src/main/java/com/apitable/shared/component/notification/queue/QueueConfig.java index e04a60c511..a715685dd2 100644 --- a/backend-server/application/src/main/java/com/apitable/shared/component/notification/queue/QueueConfig.java +++ b/backend-server/application/src/main/java/com/apitable/shared/component/notification/queue/QueueConfig.java @@ -26,7 +26,7 @@ public class QueueConfig { /** * notification exchange. */ - private static final String NOTIFICATION_EXCHANGE = "apitable.notification.exchange"; + public static final String NOTIFICATION_EXCHANGE = "apitable.notification.exchange"; /** * notification queue. diff --git a/backend-server/application/src/main/java/com/apitable/shared/component/sentry/SentryBeforeSendCallback.java b/backend-server/application/src/main/java/com/apitable/shared/component/sentry/SentryBeforeSendCallback.java deleted file mode 100644 index fd651c952a..0000000000 --- a/backend-server/application/src/main/java/com/apitable/shared/component/sentry/SentryBeforeSendCallback.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * APITable - * Copyright (C) 2022 APITable Ltd. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package com.apitable.shared.component.sentry; - -import cn.hutool.core.map.MapUtil; -import com.apitable.shared.cache.bean.LoginUserDto; -import com.apitable.shared.cache.bean.UserSpaceDto; -import com.apitable.shared.context.LoginContext; -import io.sentry.SentryEvent; -import io.sentry.SentryOptions; -import io.sentry.protocol.User; -import io.sentry.spring.SentryUserProvider; -import java.util.HashMap; -import java.util.Map; -import lombok.extern.slf4j.Slf4j; -import org.slf4j.MDC; -import org.springframework.context.annotation.Bean; -import org.springframework.stereotype.Component; - -/** - * sentry before send callback. - */ -@Component -@Slf4j -public class SentryBeforeSendCallback implements SentryOptions.BeforeSendCallback { - - @Override - public SentryEvent execute(SentryEvent event, Object hint) { - event.setTag("zipkin.span.id", MDC.get("spanId")); - event.setTag("zipkin.trace.id", MDC.get("traceId")); - return event; - } -} diff --git a/backend-server/application/src/main/java/com/apitable/shared/config/JacksonConfig.java b/backend-server/application/src/main/java/com/apitable/shared/config/JacksonConfig.java index 798ab6cef2..90eaa1d321 100644 --- a/backend-server/application/src/main/java/com/apitable/shared/config/JacksonConfig.java +++ b/backend-server/application/src/main/java/com/apitable/shared/config/JacksonConfig.java @@ -18,7 +18,8 @@ package com.apitable.shared.config; -import com.fasterxml.jackson.core.JsonParser; +import static com.fasterxml.jackson.core.json.JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS; + import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -43,7 +44,7 @@ public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomiz return builder -> { builder.failOnEmptyBeans(false); builder.failOnUnknownProperties(false); - builder.featuresToEnable(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS); + builder.featuresToEnable(ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature()); }; } } diff --git a/backend-server/application/src/main/java/com/apitable/shared/config/RestClientConfig.java b/backend-server/application/src/main/java/com/apitable/shared/config/RestClientConfig.java new file mode 100644 index 0000000000..3c6523e8fe --- /dev/null +++ b/backend-server/application/src/main/java/com/apitable/shared/config/RestClientConfig.java @@ -0,0 +1,35 @@ +package com.apitable.shared.config; + +import org.springframework.boot.web.client.RestClientCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.web.client.RestClient; + +/** + * Rest client config. + */ +@Configuration(proxyBeanMethods = false) +public class RestClientConfig { + + /** + * rest client customizer. + * + * @return RestClientCustomizer + */ + @Bean + RestClientCustomizer restClientCustomizer() { + return builder -> builder.requestFactory(new HttpComponentsClientHttpRequestFactory()); + } + + /** + * rest client. + * + * @param builder builder + * @return RestClient + */ + @Bean + RestClient restClient(RestClient.Builder builder) { + return builder.build(); + } +} diff --git a/backend-server/application/src/main/java/com/apitable/shared/config/RestTemplateConfig.java b/backend-server/application/src/main/java/com/apitable/shared/config/RestTemplateConfig.java deleted file mode 100644 index 06c4bb2481..0000000000 --- a/backend-server/application/src/main/java/com/apitable/shared/config/RestTemplateConfig.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * APITable - * Copyright (C) 2022 APITable Ltd. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package com.apitable.shared.config; - -import java.time.Duration; -import org.springframework.boot.web.client.RestTemplateBuilder; -import org.springframework.boot.web.client.RestTemplateCustomizer; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; -import org.springframework.web.client.RestTemplate; - -/** - *

- * RestTemplate config. - *

- * - * @author Chambers - */ -@Configuration(proxyBeanMethods = false) -public class RestTemplateConfig { - - /** - * rest template customizer. - * - * @return RestTemplateCustomizer - */ - @Bean - public RestTemplateCustomizer restTemplateCustomizer() { - return restTemplate -> restTemplate.setRequestFactory( - new HttpComponentsClientHttpRequestFactory()); - } - - /** - * rest template. - * - * @param builder builder - * @return RestTemplate - */ - @Bean - public RestTemplate restTemplate(RestTemplateBuilder builder) { - return builder - .setConnectTimeout(Duration.ofMinutes(1)) - .setReadTimeout(Duration.ofMinutes(3)) - .build(); - } -} diff --git a/backend-server/application/src/main/java/com/apitable/shared/config/SentryConfig.java b/backend-server/application/src/main/java/com/apitable/shared/config/SentryConfig.java index 328b5d1467..5d0e35b9a9 100644 --- a/backend-server/application/src/main/java/com/apitable/shared/config/SentryConfig.java +++ b/backend-server/application/src/main/java/com/apitable/shared/config/SentryConfig.java @@ -5,7 +5,7 @@ import com.apitable.shared.cache.bean.UserSpaceDto; import com.apitable.shared.context.LoginContext; import io.sentry.protocol.User; -import io.sentry.spring.SentryUserProvider; +import io.sentry.spring.jakarta.SentryUserProvider; import java.util.HashMap; import java.util.Map; import org.springframework.context.annotation.Bean; @@ -36,9 +36,8 @@ public SentryUserProvider sentryUserProvider() { userOthers.put("memberName", userSpaceDto.getMemberName()); userOthers.put("spaceName", userSpaceDto.getSpaceName()); userOthers.put("uuid", loginUserDto.getUuid()); - MapUtil.removeNullValue(userOthers); - user.setOthers(userOthers); + user.setData(userOthers); } } catch (Exception ignored) { // don't bother if not log in diff --git a/backend-server/application/src/main/java/com/apitable/shared/config/SessionSerializerConfig.java b/backend-server/application/src/main/java/com/apitable/shared/config/SessionSerializerConfig.java index 6486580d77..1909a4e003 100644 --- a/backend-server/application/src/main/java/com/apitable/shared/config/SessionSerializerConfig.java +++ b/backend-server/application/src/main/java/com/apitable/shared/config/SessionSerializerConfig.java @@ -18,6 +18,7 @@ package com.apitable.shared.config; +import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.ObjectMapper; import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.BeanClassLoaderAware; @@ -40,6 +41,17 @@ public class SessionSerializerConfig implements BeanClassLoaderAware { private ClassLoader classLoader; + /** + * Long Mixin. + */ + public abstract static class LongMixin { + + @SuppressWarnings("unused") + @JsonProperty("long") + Long value; + } + + /** * config spring session redis serializer. * @@ -47,9 +59,10 @@ public class SessionSerializerConfig implements BeanClassLoaderAware { */ @Bean("springSessionDefaultRedisSerializer") public RedisSerializer springSessionDefaultRedisSerializer() { - return new GenericJackson2JsonRedisSerializer( - new ObjectMapper().registerModules(SecurityJackson2Modules.getModules(this.classLoader)) - ); + var mapper = new ObjectMapper(); + mapper.addMixIn(Long.class, LongMixin.class); + mapper.registerModules(SecurityJackson2Modules.getModules(this.classLoader)); + return new GenericJackson2JsonRedisSerializer(mapper); } @Bean diff --git a/backend-server/application/src/main/java/com/apitable/shared/config/WebSecurityConfig.java b/backend-server/application/src/main/java/com/apitable/shared/config/WebSecurityConfig.java index 79dc759f1d..44110e355b 100644 --- a/backend-server/application/src/main/java/com/apitable/shared/config/WebSecurityConfig.java +++ b/backend-server/application/src/main/java/com/apitable/shared/config/WebSecurityConfig.java @@ -76,6 +76,9 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { CookieCsrfTokenRepository cookieCsrfTokenRepository = new CookieCsrfTokenRepository(); cookieCsrfTokenRepository.setCookieCustomizer((cookie) -> cookie.httpOnly(false)); cookieCsrfTokenRepository.setCookiePath("/"); + // opt-out of deferred csrf tokens + CsrfTokenRequestAttributeHandler requestHandler = new CsrfTokenRequestAttributeHandler(); + requestHandler.setCsrfRequestAttributeName(null); http .cors(withDefaults()) .sessionManagement((sessionManagement) -> sessionManagement @@ -91,7 +94,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { (headers) -> headers.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable)) .csrf((csrf) -> csrf.csrfTokenRepository(cookieCsrfTokenRepository) - .csrfTokenRequestHandler(new CsrfTokenRequestAttributeHandler()) + .csrfTokenRequestHandler(requestHandler) .ignoringRequestMatchers( ArrayUtil.toArray(IgnorePathHelper.getInstant().iterator(), String.class) ) @@ -109,7 +112,8 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { "/idaas/**", "/ai/**", "/airagent/**", - "/appsumo/**" + "/appsumo/**", + "/invitation/**" ) ) .addFilterBefore(new CsrfBeforeFilter(), CsrfFilter.class); diff --git a/backend-server/application/src/main/java/com/apitable/shared/config/properties/ConstProperties.java b/backend-server/application/src/main/java/com/apitable/shared/config/properties/ConstProperties.java index 7bc31fa99d..52fd0facd1 100644 --- a/backend-server/application/src/main/java/com/apitable/shared/config/properties/ConstProperties.java +++ b/backend-server/application/src/main/java/com/apitable/shared/config/properties/ConstProperties.java @@ -74,6 +74,11 @@ public class ConstProperties { */ private String quoteEnTemplateId = "tpll8mltwrZMT"; + /** + * List of templates referenced by new registered users. + */ + private String registerQuoteTemplates; + /** * dingtalk subscription information table id. */ @@ -87,6 +92,7 @@ public class ConstProperties { private String emailVerificationUrl = "/user/email_verification"; + public OssBucketInfo getOssBucketByAsset() { return Optional.ofNullable(ossBuckets).orElseGet(HashMap::new) .getOrDefault(BucketKey.ASSETS, new OssBucketInfo()); diff --git a/backend-server/application/src/main/java/com/apitable/shared/config/properties/LimitProperties.java b/backend-server/application/src/main/java/com/apitable/shared/config/properties/LimitProperties.java index c0edc85af4..16bd3bb6d5 100644 --- a/backend-server/application/src/main/java/com/apitable/shared/config/properties/LimitProperties.java +++ b/backend-server/application/src/main/java/com/apitable/shared/config/properties/LimitProperties.java @@ -128,4 +128,9 @@ public class LimitProperties { * max limit of action count. */ private Integer automationActionCount = 9; + + /** + * max invited record for a single day. + */ + private Integer maxInviteCountForFree = 10; } diff --git a/backend-server/application/src/main/java/com/apitable/shared/constants/NodeExtraConstants.java b/backend-server/application/src/main/java/com/apitable/shared/constants/NodeExtraConstants.java index 1e0ff264b2..85e105478f 100644 --- a/backend-server/application/src/main/java/com/apitable/shared/constants/NodeExtraConstants.java +++ b/backend-server/application/src/main/java/com/apitable/shared/constants/NodeExtraConstants.java @@ -48,4 +48,9 @@ public class NodeExtraConstants { * source template id. */ public static final String SOURCE_TEMPLATE_ID = "sourceTemplateId"; + + /** + * node extra embedPage. + */ + public static final String EMBED_PAGE = "embedPage"; } diff --git a/backend-server/application/src/main/java/com/apitable/shared/exception/LimitException.java b/backend-server/application/src/main/java/com/apitable/shared/exception/LimitException.java index 68b0c599c3..4e67937bd1 100644 --- a/backend-server/application/src/main/java/com/apitable/shared/exception/LimitException.java +++ b/backend-server/application/src/main/java/com/apitable/shared/exception/LimitException.java @@ -21,6 +21,8 @@ public enum LimitException implements BaseException { SEATS_OVER_LIMIT(1503, "seat nums over limit"), + CHAT_BOT_OVER_LIMIT(1503, "chat bot nums over limit"), + CREDIT_OVER_LIMIT(1504, "credit over limit"), FILE_NUMS_OVER_LIMIT(1505, "file nums over limit"); diff --git a/backend-server/application/src/main/java/com/apitable/shared/interceptor/I18nInterceptor.java b/backend-server/application/src/main/java/com/apitable/shared/interceptor/I18nInterceptor.java index 70f888d76c..d1f9924ac3 100644 --- a/backend-server/application/src/main/java/com/apitable/shared/interceptor/I18nInterceptor.java +++ b/backend-server/application/src/main/java/com/apitable/shared/interceptor/I18nInterceptor.java @@ -20,7 +20,6 @@ import com.apitable.shared.context.LoginContext; import com.google.common.collect.Sets; -import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.util.Locale; @@ -45,7 +44,7 @@ public class I18nInterceptor extends AbstractServletSupport implements HandlerIn @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, - Object handler) throws ServletException { + Object handler) { try { String requestPath = resolveServletPath(request); if (INCLUDE_SERVLET_PATH.contains(requestPath)) { diff --git a/backend-server/application/src/main/java/com/apitable/shared/security/FrequencyLimitServiceImpl.java b/backend-server/application/src/main/java/com/apitable/shared/security/FrequencyLimitServiceImpl.java new file mode 100644 index 0000000000..aea6ebfa83 --- /dev/null +++ b/backend-server/application/src/main/java/com/apitable/shared/security/FrequencyLimitServiceImpl.java @@ -0,0 +1,52 @@ +package com.apitable.shared.security; + +import cn.hutool.core.date.DateUnit; +import cn.hutool.core.date.DateUtil; +import com.apitable.core.constants.RedisConstants; +import com.apitable.core.exception.BusinessException; +import com.apitable.interfaces.billing.facade.EntitlementServiceFacade; +import com.apitable.interfaces.billing.model.SubscriptionInfo; +import com.apitable.shared.config.properties.LimitProperties; +import jakarta.annotation.Resource; +import java.util.Objects; +import java.util.concurrent.TimeUnit; +import org.springframework.data.redis.core.BoundSetOperations; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.stereotype.Service; + +/** + * Frequency Limit Service Implementation. + */ +@Service +public class FrequencyLimitServiceImpl implements IFrequencyLimitService { + + @Resource + private EntitlementServiceFacade entitlementServiceFacade; + + @Resource + private LimitProperties limitProperties; + + @Resource + private RedisTemplate redisTemplate; + + @Override + public void spaceInviteFrequency(String spaceId) { + SubscriptionInfo subscriptionInfo = + entitlementServiceFacade.getSpaceSubscription(spaceId); + var seatNums = subscriptionInfo.getFeature().getSeat(); + if (!subscriptionInfo.isFree() || seatNums.isUnlimited()) { + return; + } + String repeatKey = RedisConstants.getGeneralFrequencyRecordOfInvite(spaceId); + BoundSetOperations ops = redisTemplate.boundSetOps(repeatKey); + ops.add(DateUtil.current()); + ops.expire(1, TimeUnit.DAYS); + + long repeatNum = Objects.requireNonNull(ops.members()).stream() + .filter(val -> DateUtil.between(DateUtil.date(), DateUtil.date(val), DateUnit.DAY) < 1) + .count(); + if (repeatNum > limitProperties.getMaxInviteCountForFree()) { + throw new BusinessException("Frequent operation"); + } + } +} diff --git a/backend-server/application/src/main/java/com/apitable/shared/security/IFrequencyLimitService.java b/backend-server/application/src/main/java/com/apitable/shared/security/IFrequencyLimitService.java new file mode 100644 index 0000000000..bb5377e65d --- /dev/null +++ b/backend-server/application/src/main/java/com/apitable/shared/security/IFrequencyLimitService.java @@ -0,0 +1,8 @@ +package com.apitable.shared.security; + +/** + * Frequency Limit Service. + */ +public interface IFrequencyLimitService { + void spaceInviteFrequency(String spaceId); +} diff --git a/backend-server/application/src/main/java/com/apitable/shared/util/DateHelper.java b/backend-server/application/src/main/java/com/apitable/shared/util/DateHelper.java index aaf3f9ddde..e20c1ea0a9 100644 --- a/backend-server/application/src/main/java/com/apitable/shared/util/DateHelper.java +++ b/backend-server/application/src/main/java/com/apitable/shared/util/DateHelper.java @@ -18,9 +18,11 @@ package com.apitable.shared.util; +import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.time.temporal.ChronoUnit; +import java.time.temporal.TemporalAdjusters; /** *

@@ -31,6 +33,16 @@ */ public class DateHelper { + /** + * simple date formatter: yyyy-MM-dd. + */ + public static final DateTimeFormatter SIMPLE_DATE = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + /** + * simple date formatter: yyyy-MM. + */ + public static final DateTimeFormatter SIMPLE_MONTH = DateTimeFormatter.ofPattern("yyyy-MM"); + /** * get the time remaining for today(unit:second). */ @@ -40,15 +52,29 @@ public static long todayTimeLeft() { return ChronoUnit.SECONDS.between(LocalDateTime.now(), midnight); } + /** + * Safely sets the specified day of the month for the given LocalDate object. + * It checks the last day of the month for the given date and sets the day of the month + * based on the maximum valid day of the month. + * + * @param current The current LocalDate object to set the day of the month. + * @param dayOfMonth The desired day of the month to set. + * @return A new LocalDate object with the safely set day of the month. + */ + public static LocalDate safeSetDayOfMonth(LocalDate current, int dayOfMonth) { + LocalDate lastDayOfMonth = current.with(TemporalAdjusters.lastDayOfMonth()); + return current.withDayOfMonth(Math.min(dayOfMonth, lastDayOfMonth.getDayOfMonth())); + } + /** * format the time according to the incoming format. * - * @param localDateTime LocalDateTime - * @param format formatter + * @param date date + * @param format formatter * @return formatted string */ - public static String formatFullTime(LocalDateTime localDateTime, String format) { + public static String formatFullTime(LocalDate date, String format) { DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(format); - return localDateTime.format(dateTimeFormatter); + return date.format(dateTimeFormatter); } } diff --git a/backend-server/application/src/main/java/com/apitable/shared/util/IdUtil.java b/backend-server/application/src/main/java/com/apitable/shared/util/IdUtil.java index 8fd2e447b5..b2d81acb05 100644 --- a/backend-server/application/src/main/java/com/apitable/shared/util/IdUtil.java +++ b/backend-server/application/src/main/java/com/apitable/shared/util/IdUtil.java @@ -68,6 +68,8 @@ public static String createNodeId(NodeType nodeType) { + RandomExtendUtil.randomString(DATASHEET_ID_FIXED_LENGTH); case AIRAGENT -> IdRulePrefixEnum.AIRAGENT.getIdRulePrefixEnum() + RandomExtendUtil.randomString(DATASHEET_ID_FIXED_LENGTH); + case CUSTOM_PAGE -> IdRulePrefixEnum.CUSTOM_PAGE.getIdRulePrefixEnum() + + RandomExtendUtil.randomString(DATASHEET_ID_FIXED_LENGTH); default -> IdRulePrefixEnum.FOD.getIdRulePrefixEnum() + RandomExtendUtil.randomString(ID_FIXED_LENGTH); }; diff --git a/backend-server/application/src/main/java/com/apitable/shared/util/PdfToImageUtil.java b/backend-server/application/src/main/java/com/apitable/shared/util/PdfToImageUtil.java index 86ffced33c..74a5eb9d61 100644 --- a/backend-server/application/src/main/java/com/apitable/shared/util/PdfToImageUtil.java +++ b/backend-server/application/src/main/java/com/apitable/shared/util/PdfToImageUtil.java @@ -24,6 +24,8 @@ import java.io.IOException; import java.io.InputStream; import javax.imageio.ImageIO; +import org.apache.pdfbox.Loader; +import org.apache.pdfbox.io.RandomAccessReadBuffer; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.rendering.PDFRenderer; import org.slf4j.Logger; @@ -51,13 +53,13 @@ public class PdfToImageUtil { public static InputStream convert(InputStream pdfIn) { PDDocument document = null; try { - document = PDDocument.load(pdfIn); + document = Loader.loadPDF(new RandomAccessReadBuffer(pdfIn)); PDFRenderer renderer = new PDFRenderer(document); BufferedImage image = renderer.renderImage(0, 0.5f); ByteArrayOutputStream os = new ByteArrayOutputStream(); ImageIO.write(image, "JPEG", os); return new ByteArrayInputStream(os.toByteArray()); - } catch (Exception e) { + } catch (IOException e) { LOG.error("unable to load pdf", e); return null; } finally { diff --git a/backend-server/application/src/main/java/com/apitable/shared/util/SubscriptionDateRange.java b/backend-server/application/src/main/java/com/apitable/shared/util/SubscriptionDateRange.java new file mode 100644 index 0000000000..cb0841ae63 --- /dev/null +++ b/backend-server/application/src/main/java/com/apitable/shared/util/SubscriptionDateRange.java @@ -0,0 +1,54 @@ +package com.apitable.shared.util; + +import static com.apitable.shared.util.DateHelper.safeSetDayOfMonth; + +import com.apitable.interfaces.billing.model.CycleDateRange; +import com.apitable.interfaces.billing.model.SubscriptionInfo; +import java.time.LocalDate; +import java.time.temporal.TemporalAdjusters; + +/** + * subscription util. + */ +public class SubscriptionDateRange { + + /** + * Date range rule: + * If it's a free version, the start date is set to the first day of the current month, and the end date is set to the current day. + * If today's date is before the billing date, the start date is set to the same day of the previous month as the billing date, and the end date is today. + * If today's date is after the billing date, the start date is the billing date of the current month, and the end date is today. + * If today's date is the same as the billing date, the start date is the same day of the previous month as the billing date, and the end date is today. + * + * @param subscriptionInfo subscription info + * @param now now date + * @return cycle date range + */ + public static CycleDateRange calculateCycleDate(SubscriptionInfo subscriptionInfo, + LocalDate now) { + LocalDate cycleStartDate; + LocalDate cycleEndDate; + if (subscriptionInfo.isFree()) { + // free + cycleStartDate = now.with(TemporalAdjusters.firstDayOfMonth()); + cycleEndDate = now; + } else if (subscriptionInfo.onTrial()) { + // trial + cycleStartDate = subscriptionInfo.getStartDate(); + cycleEndDate = subscriptionInfo.getEndDate(); + } else { + // paid + int dayOfCurrentMonth = now.getDayOfMonth(); + int cycleDayOfMonth = subscriptionInfo.cycleDayOfMonth(dayOfCurrentMonth); + if (dayOfCurrentMonth <= cycleDayOfMonth) { + // before cycle day + cycleStartDate = safeSetDayOfMonth(now, cycleDayOfMonth).minusMonths(1); + } else { + // after cycle day + cycleStartDate = safeSetDayOfMonth(now, cycleDayOfMonth); + } + cycleEndDate = now; + } + + return new CycleDateRange(cycleStartDate, cycleEndDate); + } +} diff --git a/backend-server/application/src/main/java/com/apitable/shared/util/page/PageHelper.java b/backend-server/application/src/main/java/com/apitable/shared/util/page/PageHelper.java index 9787e84b1d..298068734f 100644 --- a/backend-server/application/src/main/java/com/apitable/shared/util/page/PageHelper.java +++ b/backend-server/application/src/main/java/com/apitable/shared/util/page/PageHelper.java @@ -125,11 +125,11 @@ public static Page convert(String stringObjectParams) { } public static PageInfo build(IPage page) { - return new PageInfo<>((int) page.getCurrent(), (int) page.getSize(), (int) page.getTotal(), + return new PageInfo<>(page.getCurrent(), page.getSize(), page.getTotal(), page.getRecords()); } - public static PageInfo build(int pageNum, int pageSize, int total, List records) { + public static PageInfo build(long pageNum, long pageSize, long total, List records) { return new PageInfo<>(pageNum, pageSize, total, records); } } diff --git a/backend-server/application/src/main/java/com/apitable/shared/util/page/PageInfo.java b/backend-server/application/src/main/java/com/apitable/shared/util/page/PageInfo.java index 224863ace8..533c30ec5a 100644 --- a/backend-server/application/src/main/java/com/apitable/shared/util/page/PageInfo.java +++ b/backend-server/application/src/main/java/com/apitable/shared/util/page/PageInfo.java @@ -33,23 +33,23 @@ @Data public class PageInfo { - private int pageNum; + private long pageNum; - private int pageSize; + private long pageSize; - private int size; + private long size; - private int total; + private long total; - private int pages; + private long pages; - private int startRow; + private long startRow; - private int endRow; + private long endRow; - private int prePage; + private long prePage; - private int nextPage; + private long nextPage; private Boolean firstPage = false; @@ -73,7 +73,7 @@ public PageInfo() { * @param total total records * @param records records */ - public PageInfo(int pageNum, int pageSize, int total, List records) { + public PageInfo(long pageNum, long pageSize, long total, List records) { this.pageNum = pageNum; this.pageSize = pageSize; this.total = total; @@ -91,7 +91,7 @@ private void calculateSize(List records) { this.size = 0; return; } - int sub = this.total - ((this.pageNum - 1) * this.pageSize); + long sub = this.total - ((this.pageNum - 1) * this.pageSize); if (sub <= 0) { this.size = 0; return; @@ -101,7 +101,7 @@ private void calculateSize(List records) { this.size = records.size(); return; } - this.records = records.subList(0, sub); + this.records = records.subList(0, (int) sub); this.size = sub; } @@ -109,7 +109,7 @@ private void calculatePages() { if (getPageSize() == 0) { this.pages = 0; } - int pages = getTotal() / getPageSize(); + long pages = getTotal() / getPageSize(); if (getTotal() % getPageSize() != 0) { pages++; } diff --git a/backend-server/application/src/main/java/com/apitable/space/assembler/SubscribeAssembler.java b/backend-server/application/src/main/java/com/apitable/space/assembler/SubscribeAssembler.java index c8e3056f4d..9d76b455b0 100644 --- a/backend-server/application/src/main/java/com/apitable/space/assembler/SubscribeAssembler.java +++ b/backend-server/application/src/main/java/com/apitable/space/assembler/SubscribeAssembler.java @@ -18,11 +18,15 @@ package com.apitable.space.assembler; +import static java.time.temporal.TemporalAdjusters.lastDayOfMonth; + import cn.hutool.core.collection.CollUtil; import com.apitable.core.util.DateTimeUtil; import com.apitable.interfaces.billing.model.SubscriptionFeature; import com.apitable.interfaces.billing.model.SubscriptionInfo; +import com.apitable.shared.clock.spring.ClockManager; import com.apitable.space.vo.SpaceSubscribeVo; +import java.time.LocalDate; import java.time.ZoneOffset; /** @@ -50,6 +54,9 @@ public SpaceSubscribeVo toVo(SubscriptionInfo subscriptionInfo) { if (CollUtil.isNotEmpty(subscriptionInfo.getAddOnPlans())) { result.setAddOnPlans(subscriptionInfo.getAddOnPlans()); } + LocalDate now = ClockManager.me().getLocalDateNow(); + int defaultCycleDayOfMonth = now.with(lastDayOfMonth()).getDayOfMonth(); + result.setCycleDayOfMonth(subscriptionInfo.cycleDayOfMonth(defaultCycleDayOfMonth)); SubscriptionFeature feature = subscriptionInfo.getFeature(); result.setMaxSeats(feature.getSeat().getValue()); result.setMaxCapacitySizeInBytes(feature.getCapacitySize().getValue().toBytes()); @@ -59,6 +66,7 @@ public SpaceSubscribeVo toVo(SubscriptionInfo subscriptionInfo) { result.setMaxAdminNums(feature.getAdminNums().getValue()); result.setMaxMirrorNums(feature.getMirrorNums().getValue()); result.setMaxApiCall(feature.getApiCallNumsPerMonth().getValue()); + result.setApiCallNumsPerMonth(feature.getApiCallNumsPerMonth().getValue()); result.setMaxGalleryViewsInSpace(feature.getGalleryViewNums().getValue()); result.setMaxKanbanViewsInSpace(feature.getKanbanViewNums().getValue()); result.setMaxFormViewsInSpace(feature.getFormNums().getValue()); @@ -69,6 +77,7 @@ public SpaceSubscribeVo toVo(SubscriptionInfo subscriptionInfo) { result.setMaxMessageCredits(feature.getMessageCreditNums().getValue()); result.setMaxAutomationRunNums(feature.getAutomationRunNumsPerMonth().getValue()); result.setMaxWidgetNums(feature.getWidgetNums().getValue()); + result.setControlFormBrandLogo(feature.getControlFormBrandLogo().getValue()); result.setIntegrationFeishu(feature.getSocialConnect().getValue()); result.setIntegrationDingtalk(feature.getSocialConnect().getValue()); @@ -90,6 +99,7 @@ public SpaceSubscribeVo toVo(SubscriptionInfo subscriptionInfo) { result.setMaxRemainTrashDays(feature.getRemainTrashDays().getValue()); result.setMaxRemainRecordActivityDays(feature.getRemainRecordActivityDays().getValue()); result.setMaxAuditQueryDays(feature.getAuditQueryDays().getValue()); + result.setAuditQuery(feature.getAuditQuery().getValue()); result.setUnExpireGiftCapacity(subscriptionInfo.getGiftCapacity().getValue().toBytes()); result.setSubscriptionCapacity(subscriptionInfo.getTotalCapacity().getValue().toBytes() diff --git a/backend-server/application/src/main/java/com/apitable/space/controller/SpaceController.java b/backend-server/application/src/main/java/com/apitable/space/controller/SpaceController.java index 365bdb0b81..c20d60054f 100644 --- a/backend-server/application/src/main/java/com/apitable/space/controller/SpaceController.java +++ b/backend-server/application/src/main/java/com/apitable/space/controller/SpaceController.java @@ -18,6 +18,8 @@ package com.apitable.space.controller; +import static com.apitable.shared.constants.PageConstants.PAGE_PARAM; +import static com.apitable.shared.constants.PageConstants.PAGE_SIMPLE_EXAMPLE; import static com.apitable.space.enums.SpaceException.DELETE_SPACE_ERROR; import cn.hutool.core.bean.BeanUtil; @@ -55,6 +57,8 @@ import com.apitable.shared.listener.event.AuditSpaceEvent.AuditSpaceArg; import com.apitable.shared.util.information.ClientOriginInfo; import com.apitable.shared.util.information.InformationUtil; +import com.apitable.shared.util.page.PageInfo; +import com.apitable.shared.util.page.PageObjectParam; import com.apitable.space.dto.GetSpaceListFilterCondition; import com.apitable.space.entity.SpaceEntity; import com.apitable.space.enums.AuditSpaceAction; @@ -66,8 +70,11 @@ import com.apitable.space.ro.SpaceOpRo; import com.apitable.space.ro.SpaceSecuritySettingRo; import com.apitable.space.ro.SpaceUpdateOpRo; +import com.apitable.space.service.ILabsApplicantService; import com.apitable.space.service.ISpaceService; +import com.apitable.space.service.IStaticsService; import com.apitable.space.vo.CreateSpaceResultVo; +import com.apitable.space.vo.LabsFeatureVo; import com.apitable.space.vo.SpaceCapacityVO; import com.apitable.space.vo.SpaceGlobalFeature; import com.apitable.space.vo.SpaceInfoVO; @@ -76,13 +83,17 @@ import com.apitable.space.vo.UserSpaceVo; import com.apitable.user.entity.UserEntity; import com.apitable.user.service.IUserService; +import com.apitable.workspace.vo.NodeStatisticsVo; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; import io.swagger.v3.oas.annotations.enums.ParameterIn; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; import jakarta.validation.Valid; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import lombok.extern.slf4j.Slf4j; @@ -119,6 +130,12 @@ public class SpaceController { @Resource private SocialServiceFacade socialServiceFacade; + @Resource + private ILabsApplicantService iLabsApplicantService; + + @Resource + private IStaticsService iStaticsService; + /** * Get space capacity info. */ @@ -372,6 +389,13 @@ public ResponseData info(@PathVariable("spaceId") String spaceId) { UserSpaceVo userSpaceVo = iSpaceService.getUserSpaceResource(userId, spaceId); spaceInfo.setUserResource(userSpaceVo); + // get the enabled experimental functions + List applicants = new ArrayList<>(); + applicants.add(spaceId); + applicants.add(Long.toString(userId)); + LabsFeatureVo labsFeatureVo = iLabsApplicantService.getUserCurrentFeatureApplicants(applicants); + spaceInfo.setLabsKeys(labsFeatureVo.getKeys()); + return ResponseData.success(spaceInfo); } @@ -436,4 +460,16 @@ public ResponseData getCreditUsages(@PathVariable("spaceId") Strin iSpaceService.getCreditUsagesChart(spaceId, timeDimensionOfChart); return ResponseData.success(creditUsages); } + + @GetResource(path = "/space/{spaceId}/node/statistics", requiredPermission = false) + @Operation(summary = "Gets statistics for node") + @Parameters({ + @Parameter(name = "spaceId", description = "space id", required = true, schema = @Schema(type = "string"), in = ParameterIn.PATH, example = "spc8mXUeiXyVo"), + @Parameter(name = PAGE_PARAM, description = "page's parameter", required = true, schema = @Schema(type = "string"), in = ParameterIn.QUERY, example = PAGE_SIMPLE_EXAMPLE) + }) + public ResponseData> getNodeStatistics( + @PathVariable("spaceId") String spaceId, + @PageObjectParam Page page) { + return ResponseData.success(iStaticsService.getNodeStatistics(spaceId, page)); + } } diff --git a/backend-server/application/src/main/java/com/apitable/space/controller/SpaceInvitationController.java b/backend-server/application/src/main/java/com/apitable/space/controller/SpaceInvitationController.java new file mode 100644 index 0000000000..6bc480c831 --- /dev/null +++ b/backend-server/application/src/main/java/com/apitable/space/controller/SpaceInvitationController.java @@ -0,0 +1,237 @@ +/* + * APITable + * Copyright (C) 2022 APITable Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.apitable.space.controller; + +import static com.apitable.core.constants.RedisConstants.GENERAL_LOCKED; +import static com.apitable.organization.enums.OrganizationException.INVITE_EMAIL_HAS_ACTIVE; +import static com.apitable.organization.enums.OrganizationException.INVITE_EMAIL_NOT_FOUND; +import static com.apitable.organization.enums.OrganizationException.INVITE_TOO_OFTEN; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.util.StrUtil; +import com.apitable.core.support.ResponseData; +import com.apitable.core.util.ExceptionUtil; +import com.apitable.interfaces.billing.facade.EntitlementServiceFacade; +import com.apitable.interfaces.billing.model.SubscriptionInfo; +import com.apitable.interfaces.security.facade.BlackListServiceFacade; +import com.apitable.interfaces.security.facade.HumanVerificationServiceFacade; +import com.apitable.interfaces.security.model.NonRobotMetadata; +import com.apitable.interfaces.user.facade.InvitationServiceFacade; +import com.apitable.interfaces.user.model.InvitationMetadata; +import com.apitable.organization.entity.MemberEntity; +import com.apitable.organization.service.IMemberService; +import com.apitable.shared.component.scanner.annotation.ApiResource; +import com.apitable.shared.component.scanner.annotation.GetResource; +import com.apitable.shared.component.scanner.annotation.PostResource; +import com.apitable.shared.constants.ParamsConstants; +import com.apitable.shared.context.LoginContext; +import com.apitable.shared.context.SessionContext; +import com.apitable.shared.security.IFrequencyLimitService; +import com.apitable.space.ro.EmailInvitationMemberRo; +import com.apitable.space.ro.EmailInvitationResendRo; +import com.apitable.space.ro.EmailInvitationRo; +import com.apitable.space.service.ISpaceInvitationService; +import com.apitable.space.service.ISpaceService; +import com.apitable.space.vo.EmailInvitationResultVO; +import com.apitable.space.vo.EmailInvitationValidateVO; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.enums.ParameterIn; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; +import java.util.List; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; +import org.springframework.data.redis.core.BoundValueOperations; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RestController; + +/** + * Space - Invitation API. + */ +@RestController +@Tag(name = "Space - Invitation API") +@ApiResource(path = "/") +public class SpaceInvitationController { + + @Resource + private ISpaceService iSpaceService; + + @Resource + private ISpaceInvitationService iSpaceInvitationService; + + @Resource + private InvitationServiceFacade invitationServiceFacade; + + @Resource + private IMemberService iMemberService; + + @Resource + private BlackListServiceFacade blackListServiceFacade; + + @Resource + private IFrequencyLimitService iFrequencyLimitService; + + @Resource + private HumanVerificationServiceFacade humanVerificationServiceFacade; + + @Resource + private RedisTemplate redisTemplate; + + @Resource + private EntitlementServiceFacade entitlementServiceFacade; + + /** + * Valid email invitation. + */ + @GetResource(path = "/email-invitations/{inviteToken}/valid", requiredLogin = false) + @Operation(summary = "Valid Email Invitation") + @Parameter(name = "inviteToken", description = "Invite Token", required = true, + schema = @Schema(type = "string"), in = ParameterIn.PATH, example = "0c7eb51617d34fa4b") + public ResponseData validEmailInvitation( + @PathVariable("inviteToken") String inviteToken + ) { + return ResponseData.success(iSpaceInvitationService.validEmailInvitation(inviteToken)); + } + + /** + * Accept email invitation. + */ + @PostResource(path = "spaces/{spaceId}/email-invitations/{inviteToken}/accept", + requiredPermission = false) + @Operation(summary = "Accept Email Invitation") + @Parameters({ + @Parameter(name = "spaceId", description = "Space ID", required = true, + schema = @Schema(type = "string"), in = ParameterIn.PATH, example = "spczJrh2i3tLW"), + @Parameter(name = "inviteToken", description = "Invite Token", required = true, + schema = @Schema(type = "string"), in = ParameterIn.PATH, example = "0c7eb51617d34fa4b") + }) + public ResponseData acceptEmailInvitation( + @PathVariable("spaceId") String spaceId, + @PathVariable("inviteToken") String inviteToken + ) { + iSpaceService.checkCanOperateSpaceUpdate(spaceId); + Long userId = SessionContext.getUserId(); + iSpaceInvitationService.acceptEmailInvitation(userId, inviteToken); + return ResponseData.success(); + } + + /** + * Send email invitation. + * todo: remove '/org/member/sendInvite' path after v1.9.0 + */ + @PostResource(path = {"spaces/{spaceId}/email-invitations", "/org/member/sendInvite"}, + tags = "INVITE_MEMBER") + @Operation(summary = "Send an email to invite members", + description = "The user opens the link in the invitation email" + + " and will officially join the space station after confirmation.") + @Parameters({ + @Parameter(name = ParamsConstants.SPACE_ID, description = "space id", required = true, + schema = @Schema(type = "string"), in = ParameterIn.HEADER, example = "spczJrh2i3tLW"), + @Parameter(name = "spaceId", description = "Space ID", required = true, + schema = @Schema(type = "string"), in = ParameterIn.PATH, example = "spczJrh2i3tLW") + }) + @Parameter(name = "spaceId", description = "Space ID", required = true, + schema = @Schema(type = "string"), in = ParameterIn.PATH, example = "spcyQkKp9XJEl") + public ResponseData sendEmailInvitation( + @PathVariable(value = "spaceId", required = false) String spaceId, + @RequestBody @Valid EmailInvitationRo data + ) { + if (StrUtil.isBlank(spaceId)) { + spaceId = LoginContext.me().getSpaceId(); + } + // whether in black list + blackListServiceFacade.checkSpace(spaceId); + iFrequencyLimitService.spaceInviteFrequency(spaceId); + iSpaceService.checkSeatOverLimit(spaceId, data.getInvite().size()); + // check whether space can invite user + iSpaceService.checkCanOperateSpaceUpdate(spaceId); + // human verification + humanVerificationServiceFacade.verifyNonRobot(new NonRobotMetadata(data.getData())); + List inviteMembers = data.getInvite(); + EmailInvitationResultVO view = EmailInvitationResultVO.builder().build(); + // get invited emails + List inviteEmails = inviteMembers.stream() + .map(EmailInvitationMemberRo::getEmail) + .filter(StrUtil::isNotBlank).collect(Collectors.toList()); + if (CollUtil.isEmpty(inviteEmails)) { + // without email, response success directly + return ResponseData.success(view); + } + SubscriptionInfo subscriptionInfo = + entitlementServiceFacade.getSpaceSubscription(spaceId); + if (subscriptionInfo.isFree() && iMemberService.shouldPreventInvitation(spaceId)) { + return ResponseData.success(view); + } + // invite new members + Long userId = SessionContext.getUserId(); + List emails = iMemberService.emailInvitation(userId, spaceId, inviteEmails); + view.setEmails(emails); + return ResponseData.success(view); + } + + /** + * Resend email invitation. + * todo: remove '/org/member/sendInviteSingle' path after v1.9.0 + */ + @PostResource(path = {"spaces/{spaceId}/email-invitation/resend", + "/org/member/sendInviteSingle"}, tags = "INVITE_MEMBER") + @Operation(summary = "Resend an email to invite members", + description = "If a member is not activated, it can send an invitation again" + + " regardless of whether the invitation has expired." + + " After the invitation is successfully sent," + + " the invitation link sent last time will be invalid.") + @Parameters({ + @Parameter(name = ParamsConstants.SPACE_ID, description = "space id", required = true, + schema = @Schema(type = "string"), in = ParameterIn.HEADER, example = "spczJrh2i3tLW"), + @Parameter(name = "spaceId", description = "Space ID", required = true, + schema = @Schema(type = "string"), in = ParameterIn.PATH, example = "spczJrh2i3tLW") + }) + public ResponseData resendEmailInvitation( + @PathVariable(value = "spaceId", required = false) String spaceId, + @RequestBody @Valid EmailInvitationResendRo data + ) { + if (StrUtil.isBlank(spaceId)) { + spaceId = LoginContext.me().getSpaceId(); + } + // check black space + blackListServiceFacade.checkSpace(spaceId); + iFrequencyLimitService.spaceInviteFrequency(spaceId); + iSpaceService.checkSeatOverLimit(spaceId); + iSpaceService.checkCanOperateSpaceUpdate(spaceId); + // Again email invite members + MemberEntity member = iMemberService.getBySpaceIdAndEmail(spaceId, data.getEmail()); + ExceptionUtil.isNotNull(member, INVITE_EMAIL_NOT_FOUND); + ExceptionUtil.isFalse(member.getIsActive(), INVITE_EMAIL_HAS_ACTIVE); + // Limit the frequency for 10 minutes + String lockKey = StrUtil.format(GENERAL_LOCKED, "invite:email", data.getEmail()); + BoundValueOperations ops = redisTemplate.boundValueOps(lockKey); + ExceptionUtil.isNull(ops.get(), INVITE_TOO_OFTEN); + ops.set("", 10, TimeUnit.MINUTES); + Long userId = SessionContext.getUserId(); + invitationServiceFacade.sendInvitationEmail( + new InvitationMetadata(userId, spaceId, data.getEmail())); + return ResponseData.success(); + } +} diff --git a/backend-server/application/src/main/java/com/apitable/space/enums/LabsFeatureException.java b/backend-server/application/src/main/java/com/apitable/space/enums/LabsFeatureException.java index 6346d9ddf9..37e422c077 100644 --- a/backend-server/application/src/main/java/com/apitable/space/enums/LabsFeatureException.java +++ b/backend-server/application/src/main/java/com/apitable/space/enums/LabsFeatureException.java @@ -37,7 +37,13 @@ public enum LabsFeatureException implements BaseException { FEATURE_TYPE_IS_NOT_EXIST(955, "feature type does not exist"), - FEATURE_ATTRIBUTE_AT_LEAST_ONE(956, "feature attribute at least one"); + FEATURE_ATTRIBUTE_AT_LEAST_ONE(956, "feature attribute at least one"), + + LAB_FEATURE_HAVE_BEEN_EXIST(956, "Lab feature have been existed"), + + LAB_FEATURE_NOT_EXIST(956, "Lab feature not exists"), + + ; private final Integer code; diff --git a/backend-server/application/src/main/java/com/apitable/space/mapper/LabsApplicantMapper.java b/backend-server/application/src/main/java/com/apitable/space/mapper/LabsApplicantMapper.java index b8c13c9b58..1f78328578 100644 --- a/backend-server/application/src/main/java/com/apitable/space/mapper/LabsApplicantMapper.java +++ b/backend-server/application/src/main/java/com/apitable/space/mapper/LabsApplicantMapper.java @@ -55,13 +55,4 @@ public interface LabsApplicantMapper extends BaseMapper { */ LabsApplicantEntity selectApplicantAndFeatureKey(@Param("applicant") String applicant, @Param("featureKey") String featureKey); - - /** - * Soft deletion of experimental function application record. - * - * @param id ID of the experimental function application form - * @param isDeleted Delete Record - * @return Number of affected record lines - */ - int updateIsDeletedById(@Param("id") Long id, @Param("isDeleted") Boolean isDeleted); } diff --git a/backend-server/application/src/main/java/com/apitable/space/mapper/SpaceInviteRecordMapper.java b/backend-server/application/src/main/java/com/apitable/space/mapper/SpaceInviteRecordMapper.java index b220ff0001..087fbd9a64 100644 --- a/backend-server/application/src/main/java/com/apitable/space/mapper/SpaceInviteRecordMapper.java +++ b/backend-server/application/src/main/java/com/apitable/space/mapper/SpaceInviteRecordMapper.java @@ -20,8 +20,8 @@ import com.apitable.space.entity.SpaceInviteRecordEntity; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import java.time.LocalDateTime; import java.util.Collection; -import java.util.List; import org.apache.ibatis.annotations.Param; /** @@ -30,24 +30,39 @@ public interface SpaceInviteRecordMapper extends BaseMapper { /** - * All the specified invitation email links in the spaces have expired. + * All the specified invitation email links in the space have expired. * - * @param spaceIds space ids - * @param email email + * @param spaceId space id + * @param emails emails + * @param statusDesc status description * @return affected rows */ - int expireBySpaceIdAndEmail(@Param("spaceIds") List spaceIds, - @Param("email") String email); + int expireBySpaceIdAndEmails(@Param("spaceId") String spaceId, + @Param("emails") Collection emails, + @Param("statusDesc") String statusDesc); /** - * All the specified invitation email links in the space have expired. + * Expire by space id and invite member ids. * - * @param spaceId space id - * @param emails emails + * @param spaceId space id + * @param memberIds invite member ids + * @param statusDesc status description * @return affected rows */ - int expireBySpaceIdAndEmails(@Param("spaceId") String spaceId, - @Param("emails") Collection emails); + int expireBySpaceIdAndInviteMemberId(@Param("spaceId") String spaceId, + @Param("memberIds") Collection memberIds, + @Param("statusDesc") String statusDesc); + + /** + * Expire by invite token. + * + * @param inviteToken invite token + * @param statusDesc status description + * @return affected rows + * @author Chambers + */ + int expireByInviteToken(@Param("inviteToken") String inviteToken, + @Param("statusDesc") String statusDesc); /** * Query invite record. @@ -57,4 +72,16 @@ int expireBySpaceIdAndEmails(@Param("spaceId") String spaceId, */ SpaceInviteRecordEntity selectByInviteToken(@Param("inviteToken") String inviteToken); + /** + * query space invite record within the specified time. + * + * @param spaceId space id + * @param startAt start time + * @param endAt end time + * @return count + */ + Integer selectCountBySpaceIdAndBetween(@Param("spaceId") String spaceId, + @Param("startAt") LocalDateTime startAt, + @Param("endAt") LocalDateTime endAt); + } diff --git a/backend-server/application/src/main/java/com/apitable/space/mapper/SpaceMapper.java b/backend-server/application/src/main/java/com/apitable/space/mapper/SpaceMapper.java index e30ef841c1..25707a0ac4 100644 --- a/backend-server/application/src/main/java/com/apitable/space/mapper/SpaceMapper.java +++ b/backend-server/application/src/main/java/com/apitable/space/mapper/SpaceMapper.java @@ -194,4 +194,12 @@ int updatePreDeletionTimeBySpaceId(@Param("time") LocalDateTime time, */ @InterceptorIgnore(illegalSql = "true") List selectByUserId(@Param("userId") Long userId); + + /** + * query space ids by created_by. + * + * @param userId user id + * @return space ids + */ + List selectSpaceIdsByUserId(@Param("userId") Long userId); } diff --git a/backend-server/application/src/main/java/com/apitable/space/mapper/StaticsMapper.java b/backend-server/application/src/main/java/com/apitable/space/mapper/StaticsMapper.java index f3b542d8ea..fbdbcd80b5 100644 --- a/backend-server/application/src/main/java/com/apitable/space/mapper/StaticsMapper.java +++ b/backend-server/application/src/main/java/com/apitable/space/mapper/StaticsMapper.java @@ -70,7 +70,7 @@ public interface StaticsMapper { * @param spaceId space id * @return total */ - Long countRecordsBySpaceId(@Param("spaceId") String spaceId); + List countRecordsBySpaceId(@Param("spaceId") String spaceId); /** * Count the rows of all tables in the space. @@ -149,27 +149,31 @@ Long selectApiUsageMinIdByCreatedAt(@Param("minId") Long minId, /** * Query the view statistics of all tables in the space. * - * @param spaceId space id + * @param dstIds dst ids * @return number */ - List selectDstViewStaticsBySpaceId(@Param("spaceId") String spaceId); + List selectDstViewStaticsByDstIds(@Param("dstIds") List dstIds); /** - * Query the maximum API usage table ID of a day. + * Query the API usage of the space station one day. * - * @param time time - * @return id datasheet id + * @param id datasheet id + * @param spaceId space id + * @return number */ - Long selectMaxIdByTime(@Param("time") String time); + Long countByIdGreaterThanAndSpaceId(@Param("id") Long id, @Param("spaceId") String spaceId); /** * Query the API usage of the space station one day. * * @param id datasheet id * @param spaceId space id + * @param startTime start time - yesterday * @return number */ - Long countByIdGreaterThanAndSpaceId(@Param("id") Long id, @Param("spaceId") String spaceId); + Long countByIdGreaterThanAndSpaceIdAndCreatedAt(@Param("id") Long id, + @Param("spaceId") String spaceId, + @Param("startTime") String startTime); /** * Query the API usage of the space station for a certain period of time. diff --git a/backend-server/application/src/main/java/com/apitable/organization/ro/InviteMemberRo.java b/backend-server/application/src/main/java/com/apitable/space/ro/EmailInvitationMemberRo.java similarity index 90% rename from backend-server/application/src/main/java/com/apitable/organization/ro/InviteMemberRo.java rename to backend-server/application/src/main/java/com/apitable/space/ro/EmailInvitationMemberRo.java index b8635d0c93..b26ca6b24f 100644 --- a/backend-server/application/src/main/java/com/apitable/organization/ro/InviteMemberRo.java +++ b/backend-server/application/src/main/java/com/apitable/space/ro/EmailInvitationMemberRo.java @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package com.apitable.organization.ro; +package com.apitable.space.ro; import com.apitable.core.support.deserializer.StringToLongDeserializer; import com.apitable.shared.constants.PatternConstants; @@ -28,12 +28,12 @@ /** *

- * Invite Member Parameters. + * Email Invitation Member Request Parameters. *

*/ @Data -@Schema(description = "Invite Member Parameters") -public class InviteMemberRo { +@Schema(description = "Email Invitation Member Request Parameters") +public class EmailInvitationMemberRo { @Schema(description = "Email address, strictly checked", requiredMode = RequiredMode.REQUIRED, example = "123456@qq.com") diff --git a/backend-server/application/src/main/java/com/apitable/organization/ro/InviteMemberAgainRo.java b/backend-server/application/src/main/java/com/apitable/space/ro/EmailInvitationResendRo.java similarity index 87% rename from backend-server/application/src/main/java/com/apitable/organization/ro/InviteMemberAgainRo.java rename to backend-server/application/src/main/java/com/apitable/space/ro/EmailInvitationResendRo.java index 5fcdb8534e..1c26652d65 100644 --- a/backend-server/application/src/main/java/com/apitable/organization/ro/InviteMemberAgainRo.java +++ b/backend-server/application/src/main/java/com/apitable/space/ro/EmailInvitationResendRo.java @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package com.apitable.organization.ro; +package com.apitable.space.ro; import com.apitable.shared.constants.PatternConstants; import io.swagger.v3.oas.annotations.media.Schema; @@ -27,12 +27,12 @@ /** *

- * Send an email again to invite member request parameters. + * Email Invitation Resend request parameters. *

*/ @Data -@Schema(description = "Send an email again to invite member request parameters") -public class InviteMemberAgainRo { +@Schema(description = "Email Invitation Resend request parameters") +public class EmailInvitationResendRo { @NotNull(message = "The mailbox does not exist, and the invitation cannot be sent again") @Schema(description = "Email address, strictly checked", diff --git a/backend-server/application/src/main/java/com/apitable/organization/ro/InviteRo.java b/backend-server/application/src/main/java/com/apitable/space/ro/EmailInvitationRo.java similarity index 87% rename from backend-server/application/src/main/java/com/apitable/organization/ro/InviteRo.java rename to backend-server/application/src/main/java/com/apitable/space/ro/EmailInvitationRo.java index 6b3f4d7f62..299bb3f572 100644 --- a/backend-server/application/src/main/java/com/apitable/organization/ro/InviteRo.java +++ b/backend-server/application/src/main/java/com/apitable/space/ro/EmailInvitationRo.java @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package com.apitable.organization.ro; +package com.apitable.space.ro; import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; @@ -28,18 +28,18 @@ /** *

- * Email invitation member request parameters. + * Email Invitation Request Parameters. *

*/ @Data -@Schema(description = "Email invitation member request parameters") -public class InviteRo { +@Schema(description = "Email Invitation Request Parameters") +public class EmailInvitationRo { @Valid @NotEmpty @Size(max = 50, message = "Invite up to 50 members") @Schema(description = "Invite Member List", requiredMode = RequiredMode.REQUIRED) - private List invite; + private List invite; @Schema(description = "Password login for human-machine verification, and the front end " + "obtains the value of get NVC Val function (human-machine verification will be " diff --git a/backend-server/application/src/main/java/com/apitable/space/service/ISpaceInvitationService.java b/backend-server/application/src/main/java/com/apitable/space/service/ISpaceInvitationService.java new file mode 100644 index 0000000000..5faefe4075 --- /dev/null +++ b/backend-server/application/src/main/java/com/apitable/space/service/ISpaceInvitationService.java @@ -0,0 +1,45 @@ +/* + * APITable + * Copyright (C) 2022 APITable Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.apitable.space.service; + +import com.apitable.space.vo.EmailInvitationValidateVO; + +/** + * Space Invitation Service. + */ +public interface ISpaceInvitationService { + + /** + * Valid Email Invitation. + * + * @param inviteToken invitation token + * @return Invitation related information view + */ + EmailInvitationValidateVO validEmailInvitation(String inviteToken); + + /** + * Accept Email Invitation. + * + * @param userId user id + * @param inviteToken invitation token + * @return member id + * @author Chambers + */ + Long acceptEmailInvitation(Long userId, String inviteToken); +} diff --git a/backend-server/application/src/main/java/com/apitable/space/service/ISpaceService.java b/backend-server/application/src/main/java/com/apitable/space/service/ISpaceService.java index b348f95e17..365158dfe3 100644 --- a/backend-server/application/src/main/java/com/apitable/space/service/ISpaceService.java +++ b/backend-server/application/src/main/java/com/apitable/space/service/ISpaceService.java @@ -20,6 +20,8 @@ import com.apitable.interfaces.ai.model.ChartTimeDimension; import com.apitable.interfaces.ai.model.CreditInfo; +import com.apitable.interfaces.billing.model.SubscriptionInfo; +import com.apitable.interfaces.social.model.SocialConnectInfo; import com.apitable.internal.vo.InternalSpaceCapacityVo; import com.apitable.internal.vo.InternalSpaceUsageVo; import com.apitable.space.dto.GetSpaceListFilterCondition; @@ -178,6 +180,21 @@ CreditUsages getCreditUsagesChart( */ SeatUsage getSeatUsage(String spaceId); + /** + * check whether chatBot nums of the space is over limit. + * + * @param spaceId space id + */ + void checkChatBotNumsOverLimit(String spaceId); + + /** + * check whether chatBot nums of the space is over limit. + * + * @param spaceId space id + * @param addedNums added chatBot nums + */ + void checkChatBotNumsOverLimit(String spaceId, int addedNums); + /** * check whether seat nums of the space is over limit. * @@ -435,4 +452,52 @@ boolean checkSeatOverLimitAndSendNotify(List userIds, String spaceId, long * @author Chambers */ boolean getSpaceSeatAvailableStatus(String spaceId); + + /** + * get space ids by created by. + * + * @param userId user id + * @return space ids + */ + List getSpaceIdsByCreatedBy(Long userId); + + /** + * check widget whether over limit. + * + * @param spaceId space id + */ + void checkWidgetOverLimit(String spaceId); + + /** + * get space subscription. + * + * @param spaceId space id + * @return SubscriptionInfo + */ + SubscriptionInfo getSpaceSubscription(String spaceId); + + /** + * get social connection info. + * + * @param spaceId space id + * @return SocialConnectInfo + */ + SocialConnectInfo getSocialConnectInfo(String spaceId); + + /** + * get social suite key. + * + * @param appId app id + * @return social suite key + */ + String getSocialSuiteKeyByAppId(String appId); + + /** + * check whether the space bind with a social connector. + * + * @param spaceId space id + * @return boolean + */ + boolean checkSocialBind(String spaceId); + } diff --git a/backend-server/application/src/main/java/com/apitable/space/service/IStaticsService.java b/backend-server/application/src/main/java/com/apitable/space/service/IStaticsService.java index 9154ee8834..0b63883132 100644 --- a/backend-server/application/src/main/java/com/apitable/space/service/IStaticsService.java +++ b/backend-server/application/src/main/java/com/apitable/space/service/IStaticsService.java @@ -18,10 +18,14 @@ package com.apitable.space.service; +import com.apitable.shared.util.page.PageInfo; import com.apitable.space.dto.ControlStaticsDTO; import com.apitable.space.dto.DatasheetStaticsDTO; import com.apitable.space.dto.NodeStaticsDTO; import com.apitable.space.dto.NodeTypeStaticsDTO; +import com.apitable.workspace.vo.NodeStatisticsVo; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import java.time.LocalDate; import java.util.List; import java.util.Map; @@ -36,25 +40,10 @@ public interface IStaticsService { * Get the current month's API usage. * * @param spaceId space id + * @param currentMonth current month * @return amount */ - long getCurrentMonthApiUsage(String spaceId); - - /** - * Get today's API usage and update the cache. - * - * @param spaceId space id - * @return amount - */ - Long getTodayApiUsage(String spaceId); - - /** - * Get the API usage from this month to yesterday, and update the cache. - * - * @param spaceId space id - * @return amount - */ - Long getCurrentMonthApiUsageUntilYesterday(String spaceId); + long getCurrentMonthApiUsage(String spaceId, LocalDate currentMonth); /** * Total number of people obtaining space. @@ -184,4 +173,13 @@ void updateDatasheetViewCountStaticsBySpaceId(String spaceId, * @param spaceId space id. */ void deleteDatasheetRecordCountStatistics(String spaceId); + + /** + * get node statistics. + * + * @param spaceId space id + * @param page query page + * @return IPage MemberPageVo + */ + PageInfo getNodeStatistics(String spaceId, Page page); } diff --git a/backend-server/application/src/main/java/com/apitable/space/service/impl/SpaceApplyServiceImpl.java b/backend-server/application/src/main/java/com/apitable/space/service/impl/SpaceApplyServiceImpl.java index 2026312360..b1a3483045 100644 --- a/backend-server/application/src/main/java/com/apitable/space/service/impl/SpaceApplyServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/space/service/impl/SpaceApplyServiceImpl.java @@ -227,7 +227,7 @@ private void updateApplyStatus(Long userId, Boolean agree, SpaceApplyDTO apply, if (BooleanUtil.isTrue(agree)) { status = SpaceApplyStatus.APPROVE.getStatus(); // Agree to apply and determine whether the number of people invited to the space has reached the maximum - iSpaceService.checkSeatOverLimit(apply.getSpaceId(), 1); + iSpaceService.checkSeatOverLimit(apply.getSpaceId()); // Create member iMemberService.createMember(apply.getCreatedBy(), apply.getSpaceId(), null); } diff --git a/backend-server/application/src/main/java/com/apitable/space/service/impl/SpaceInvitationServiceImpl.java b/backend-server/application/src/main/java/com/apitable/space/service/impl/SpaceInvitationServiceImpl.java new file mode 100644 index 0000000000..c729bc3ad1 --- /dev/null +++ b/backend-server/application/src/main/java/com/apitable/space/service/impl/SpaceInvitationServiceImpl.java @@ -0,0 +1,150 @@ +/* + * APITable + * Copyright (C) 2022 APITable Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.apitable.space.service.impl; + +import static com.apitable.organization.enums.OrganizationException.INVITE_EMAIL_NOT_MATCH; +import static com.apitable.organization.enums.OrganizationException.INVITE_EXPIRE; +import static com.apitable.organization.enums.OrganizationException.INVITE_URL_ERROR; + +import cn.hutool.core.collection.ListUtil; +import cn.hutool.core.util.StrUtil; +import com.apitable.core.exception.BusinessException; +import com.apitable.core.util.ExceptionUtil; +import com.apitable.core.util.HttpContextUtil; +import com.apitable.interfaces.user.facade.UserServiceFacade; +import com.apitable.organization.entity.MemberEntity; +import com.apitable.organization.service.IMemberService; +import com.apitable.shared.component.TaskManager; +import com.apitable.shared.context.LoginContext; +import com.apitable.space.entity.SpaceEntity; +import com.apitable.space.entity.SpaceInviteRecordEntity; +import com.apitable.space.mapper.SpaceInviteRecordMapper; +import com.apitable.space.service.ISpaceInvitationService; +import com.apitable.space.service.ISpaceService; +import com.apitable.space.vo.EmailInvitationValidateVO; +import com.apitable.user.service.IUserService; +import jakarta.annotation.Resource; +import java.util.concurrent.locks.Lock; +import org.springframework.integration.redis.util.RedisLockRegistry; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * Space Invitation Service Implement Class. + */ +@Service +public class SpaceInvitationServiceImpl implements ISpaceInvitationService { + + @Resource + private IUserService iUserService; + + @Resource + private UserServiceFacade userServiceFacade; + + @Resource + private ISpaceService iSpaceService; + + @Resource + private SpaceInviteRecordMapper spaceInviteRecordMapper; + + @Resource + private IMemberService iMemberService; + + @Resource + private RedisLockRegistry redisLockRegistry; + + @Override + public EmailInvitationValidateVO validEmailInvitation(String inviteToken) { + // is it a illegal link + SpaceInviteRecordEntity record = this.getSpaceInviteRecord(inviteToken); + String inviteSpaceId = record.getInviteSpaceId(); + MemberEntity member = iMemberService.getById(record.getInviteMemberId()); + ExceptionUtil.isNotNull(member, INVITE_URL_ERROR); + EmailInvitationValidateVO vo = new EmailInvitationValidateVO(); + vo.setSpaceId(inviteSpaceId); + SpaceEntity spaceEntity = iSpaceService.isSpaceAvailable(inviteSpaceId); + vo.setSpaceName(spaceEntity.getName()); + vo.setInviter(member.getMemberName()); + String inviteEmail = record.getInviteEmail(); + vo.setInviteEmail(inviteEmail); + // Whether the binding is bound to the mailbox + boolean inviteBindUser = iUserService.getByEmail(inviteEmail) != null; + vo.setIsBound(inviteBindUser); + boolean isLogin = HttpContextUtil.getSession(false) != null; + vo.setIsLogin(isLogin); + if (isLogin) { + vo.setIsMatch(inviteEmail.equals(LoginContext.me().getLoginUser().getEmail())); + } + // get the link creator's personal invitation code + String inviteCode = userServiceFacade.getUserInvitationCode(member.getUserId()).getCode(); + vo.setInviteCode(inviteCode); + return vo; + } + + @Override + @Transactional(rollbackFor = Exception.class) + public Long acceptEmailInvitation(Long userId, String inviteToken) { + SpaceInviteRecordEntity inviteRecord = this.getSpaceInviteRecord(inviteToken); + String email = iUserService.getEmailByUserId(userId); + ExceptionUtil.isTrue(inviteRecord.getInviteEmail().equals(email), INVITE_EMAIL_NOT_MATCH); + Long invitorUserId = iMemberService.getUserIdByMemberId(inviteRecord.getInviteMemberId()); + ExceptionUtil.isNotNull(invitorUserId, INVITE_URL_ERROR); + + String spaceId = inviteRecord.getInviteSpaceId(); + MemberEntity member = + iMemberService.getByUserIdAndSpaceIdIncludeDeleted(userId, spaceId); + // The user already exists in the space + if (member != null && !member.getIsDeleted()) { + return member.getId(); + } + iSpaceService.checkSeatOverLimit(spaceId); + String key = StrUtil.format("space:email-invitations:{}", inviteToken); + Lock lock = redisLockRegistry.obtain(key); + boolean locked = false; + try { + locked = lock.tryLock(); + if (locked) { + // create member + Long memberId = iMemberService.createMember(userId, spaceId, null); + spaceInviteRecordMapper.expireByInviteToken(inviteToken, "Accept Invitation"); + TaskManager.me().execute( + () -> iMemberService.sendInviteNotification(invitorUserId, + ListUtil.toList(memberId), spaceId, false)); + return memberId; + } else { + throw new BusinessException("Frequent operations"); + } + } finally { + if (locked) { + lock.unlock(); + } + } + } + + private SpaceInviteRecordEntity getSpaceInviteRecord(String inviteToken) { + // is it a illegal link + SpaceInviteRecordEntity record = + spaceInviteRecordMapper.selectByInviteToken(inviteToken); + // determine whether it is illegal + ExceptionUtil.isNotNull(record, INVITE_URL_ERROR); + // determine whether it expired + ExceptionUtil.isFalse(record.getIsExpired(), INVITE_EXPIRE); + return record; + } +} diff --git a/backend-server/application/src/main/java/com/apitable/space/service/impl/SpaceInviteLinkServiceImpl.java b/backend-server/application/src/main/java/com/apitable/space/service/impl/SpaceInviteLinkServiceImpl.java index 0defbc1168..4f7e44a73a 100644 --- a/backend-server/application/src/main/java/com/apitable/space/service/impl/SpaceInviteLinkServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/space/service/impl/SpaceInviteLinkServiceImpl.java @@ -32,7 +32,6 @@ import com.apitable.core.exception.BusinessException; import com.apitable.core.util.ExceptionUtil; import com.apitable.core.util.HttpContextUtil; -import com.apitable.interfaces.social.facade.SocialServiceFacade; import com.apitable.interfaces.user.facade.UserServiceFacade; import com.apitable.organization.mapper.TeamMemberRelMapper; import com.apitable.organization.service.IMemberService; @@ -104,9 +103,6 @@ public class SpaceInviteLinkServiceImpl @Resource private RedisLockRegistry redisLockRegistry; - @Resource - private SocialServiceFacade socialServiceFacade; - @Resource private IInvitationService invitationService; @@ -118,7 +114,7 @@ public List getSpaceLinkVos(Long memberId) { @Override public String saveOrUpdate(String spaceId, Long teamId, Long memberId) { // whether a space can create an invitation link - boolean isBindSocial = socialServiceFacade.checkSocialBind(spaceId); + boolean isBindSocial = iSpaceService.checkSocialBind(spaceId); ExceptionUtil.isFalse(isBindSocial, NO_ALLOW_OPERATE); String teamSpaceId = iTeamService.getSpaceIdByTeamId(teamId); // Verify that the department exists and is in the same space @@ -231,7 +227,7 @@ public InvitationUserDTO invitedUserJoinSpaceByToken(Long userId, String token) INVITE_EXPIRE); iSpaceService.checkSeatOverLimit(dto.getSpaceId()); // Determine whether the space has a third party enabled - boolean isBoundSocial = socialServiceFacade.checkSocialBind(dto.getSpaceId()); + boolean isBoundSocial = iSpaceService.checkSocialBind(dto.getSpaceId()); ExceptionUtil.isFalse(isBoundSocial, INVITE_EXPIRE); // If the user has historical members in the space, the previous member ID can be reused directly; when the user is in the space but not in the designated department, he/she joins the department boolean isExist = this.joinTeamIfInSpace(userId, dto.getSpaceId(), dto.getTeamId()); diff --git a/backend-server/application/src/main/java/com/apitable/space/service/impl/SpaceServiceImpl.java b/backend-server/application/src/main/java/com/apitable/space/service/impl/SpaceServiceImpl.java index 42a48075b6..157086f5a5 100644 --- a/backend-server/application/src/main/java/com/apitable/space/service/impl/SpaceServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/space/service/impl/SpaceServiceImpl.java @@ -48,6 +48,7 @@ import com.apitable.interfaces.ai.model.CreditInfo; import com.apitable.interfaces.ai.model.CreditTransactionChartData; import com.apitable.interfaces.billing.facade.EntitlementServiceFacade; +import com.apitable.interfaces.billing.model.CycleDateRange; import com.apitable.interfaces.billing.model.DefaultSubscriptionInfo; import com.apitable.interfaces.billing.model.SubscriptionFeature; import com.apitable.interfaces.billing.model.SubscriptionFeatures; @@ -75,6 +76,7 @@ import com.apitable.shared.captcha.ValidateCodeProcessorManage; import com.apitable.shared.captcha.ValidateCodeType; import com.apitable.shared.captcha.ValidateTarget; +import com.apitable.shared.clock.spring.ClockManager; import com.apitable.shared.component.TaskManager; import com.apitable.shared.component.notification.NotificationManager; import com.apitable.shared.component.notification.NotificationRenderField; @@ -90,6 +92,7 @@ import com.apitable.shared.listener.event.AuditSpaceEvent; import com.apitable.shared.listener.event.AuditSpaceEvent.AuditSpaceArg; import com.apitable.shared.util.IdUtil; +import com.apitable.shared.util.SubscriptionDateRange; import com.apitable.shared.util.information.ClientOriginInfo; import com.apitable.shared.util.information.InformationUtil; import com.apitable.space.assembler.SpaceAssembler; @@ -138,6 +141,7 @@ import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; import jakarta.annotation.Resource; import java.math.BigDecimal; +import java.time.LocalDate; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Collections; @@ -241,12 +245,12 @@ public class SpaceServiceImpl extends ServiceImpl @Resource private InternalSpaceService internalSpaceService; - @Value("${BILLING_APITABLE_ENABLED:false}") - private Boolean billingApitableEnabled; - @Value("${SKIP_USAGE_VERIFICATION:false}") private Boolean skipUsageVerification; + @Value("${SKIP_API_USAGE_VERIFICATION:false}") + private Boolean skipApiUsageVerification; + @Override public SpaceEntity getEntityBySpaceId(String spaceId) { return baseMapper.selectBySpaceId(spaceId); @@ -583,9 +587,12 @@ public CreditInfo getCredit(String spaceId) { subscriptionInfo = entitlementServiceFacade.getSpaceSubscription(spaceId); } + LocalDate now = ClockManager.me().getLocalDateNow(); + CycleDateRange dateRange = SubscriptionDateRange.calculateCycleDate(subscriptionInfo, now); return new CreditInfo(subscriptionInfo.getConfig().isAllowCreditOverLimit(), subscriptionInfo.getFeature().getMessageCreditNums().getValue(), - aiServiceFacade.getUsedCreditCount(spaceId)); + aiServiceFacade.getUsedCreditCount(spaceId, dateRange.getCycleStartDate(), + dateRange.getCycleEndDate())); } @Override @@ -600,37 +607,48 @@ public CreditUsages getCreditUsagesChart( public SeatUsage getSeatUsage(String spaceId) { long memberCount = iMemberService.getTotalActiveMemberCountBySpaceId(spaceId); - long chatBotCount = iStaticsService.getTotalChatbotNodesfromCache(spaceId); - return new SeatUsage(chatBotCount, memberCount); + return new SeatUsage(0L, memberCount); } @Override - public void checkSeatOverLimit(String spaceId) { - // get subscription max seat nums - SubscriptionInfo subscriptionInfo = + public void checkChatBotNumsOverLimit(String spaceId) { + checkChatBotNumsOverLimit(spaceId, 1); + } + + @Override + public void checkChatBotNumsOverLimit(String spaceId, int addedNums) { + var subscriptionInfo = entitlementServiceFacade.getSpaceSubscription(spaceId); - // only free space has validation, or paid space in apitable mode can skip validation. - if (!subscriptionInfo.isFree() && billingApitableEnabled) { + var aiAgentNums = subscriptionInfo.getFeature().getAiAgentNums(); + if (!subscriptionInfo.isFree() && aiAgentNums.isUnlimited()) { return; } - SeatUsage seatUsage = getSeatUsage(spaceId); - SubscriptionFeatures.ConsumeFeatures.Seat seat = subscriptionInfo.getFeature().getSeat(); - if (seat.isUnlimited() && (seatUsage.getTotal() >= seat.getValue())) { - throw new BusinessException(LimitException.SEATS_OVER_LIMIT); + if (aiAgentNums.isUnlimited()) { + return; + } + long chatBotCount = iStaticsService.getTotalChatbotNodesfromCache(spaceId); + if (chatBotCount + addedNums > aiAgentNums.getValue()) { + throw new BusinessException(LimitException.CHAT_BOT_OVER_LIMIT); } } + @Override + public void checkSeatOverLimit(String spaceId) { + checkSeatOverLimit(spaceId, 1); + } + @Override public void checkSeatOverLimit(String spaceId, long addedSeatNums) { // get subscription max seat nums - SubscriptionInfo subscriptionInfo = + var subscriptionInfo = entitlementServiceFacade.getSpaceSubscription(spaceId); - if (!subscriptionInfo.isFree() && billingApitableEnabled) { + var seatNums = subscriptionInfo.getFeature().getSeat(); + if (!subscriptionInfo.isFree() && seatNums.isUnlimited()) { return; } - SeatUsage seatUsage = getSeatUsage(spaceId); - SubscriptionFeatures.ConsumeFeatures.Seat seat = subscriptionInfo.getFeature().getSeat(); - if (!seat.isUnlimited() && (seatUsage.getTotal() + addedSeatNums > seat.getValue())) { + var seatUsage = getSeatUsage(spaceId); + var total = seatUsage.getTotal(); + if (total + addedSeatNums > seatNums.getValue()) { throw new BusinessException(LimitException.SEATS_OVER_LIMIT); } } @@ -643,15 +661,15 @@ public void checkFileNumOverLimit(String spaceId) { @Override public void checkFileNumOverLimit(String spaceId, long addFileNums) { // get subscription max sheet nums - SubscriptionInfo subscriptionInfo = + var subscriptionInfo = entitlementServiceFacade.getSpaceSubscription(spaceId); if (!subscriptionInfo.isFree()) { return; } - SubscriptionFeatures.ConsumeFeatures.FileNodeNums fileNodeNums = + var fileNodeNums = subscriptionInfo.getFeature().getFileNodeNums(); - long currentSheetNums = getNodeCountBySpaceId(spaceId, NodeType::isFolder); - if (fileNodeNums.isUnlimited() + var currentSheetNums = getNodeCountBySpaceId(spaceId, NodeType::isFolder); + if (!fileNodeNums.isUnlimited() && (currentSheetNums + addFileNums > fileNodeNums.getValue())) { throw new BusinessException(LimitException.FILE_NUMS_OVER_LIMIT); } @@ -662,19 +680,20 @@ public boolean checkSeatOverLimitAndSendNotify(List userIds, String spaceI long addedSeatNums, boolean isAllMember, boolean sendNotify) { // get subscription max seat nums - SubscriptionInfo subscriptionInfo = - entitlementServiceFacade.getSpaceSubscription(spaceId); - if (!subscriptionInfo.isFree() && billingApitableEnabled) { + SubscriptionInfo subscriptionInfo = entitlementServiceFacade.getSpaceSubscription(spaceId); + var seat = subscriptionInfo.getFeature().getSeat(); + if (!subscriptionInfo.isFree() && seat.isUnlimited()) { // apitable billing mode, paid space,skip validation return true; } - SubscriptionFeatures.ConsumeFeatures.Seat seat = subscriptionInfo.getFeature().getSeat(); SeatUsage seatUsage = getSeatUsageForIM(spaceId); long totalSeatNums = seatUsage.getTotal() + addedSeatNums; if (isAllMember) { totalSeatNums = addedSeatNums; } if (!seat.isUnlimited() && (totalSeatNums > seat.getValue())) { + log.info("spaceId:{}, current num:{}, max seats:{}", spaceId, totalSeatNums, + seat.getValue()); if (sendNotify) { // Send space station notifications try { @@ -682,16 +701,15 @@ public boolean checkSeatOverLimitAndSendNotify(List userIds, String spaceI long finalTotalSeatNums = totalSeatNums; TaskManager.me().execute(() -> NotificationManager.me() .playerNotify(NotificationTemplateId.SPACE_REFRESH_CONTACT_SEATS_LIMIT, - userIds, 0L, spaceId, - Dict.create().set("spaceName", spaceName) + userIds, 0L, spaceId, Dict.create().set("spaceName", spaceName) .set("specification", seat.getValue()) .set("usage", finalTotalSeatNums))); } catch (Exception e) { log.error("send space station notifications error", e); } } - log.warn("seats over limit"); - return false; + log.warn("{} seats over limit", spaceId); + return true; } return true; } @@ -701,8 +719,7 @@ public boolean checkSeatOverLimitAndSendNotify(List userIds, String spaceI public SeatUsage getSeatUsageForIM(String spaceId) { long memberCount = iMemberService.getTotalMemberCountBySpaceId(spaceId); - long chatBotCount = iStaticsService.getTotalChatbotNodesfromCache(spaceId); - return new SeatUsage(chatBotCount, memberCount); + return new SeatUsage(0L, memberCount); } /** @@ -715,11 +732,31 @@ public SeatUsage getSeatUsageForIM(String spaceId) { public SpaceInfoVO getSpaceInfo(final String spaceId) { SpaceEntity entity = getBySpaceId(spaceId); SpaceInfoVO spaceInfoVO = this.transform(entity); + // obtain third party information + SocialConnectInfo socialConnectInfo = + socialServiceFacade.getConnectInfo(spaceId); + SpaceSocialConfig bindInfo = new SpaceSocialConfig(); + if (ObjectUtil.isNotNull(socialConnectInfo) && socialConnectInfo.isEnabled()) { + bindInfo.setEnabled(true); + bindInfo.setPlatform(socialConnectInfo.getPlatform()); + bindInfo.setAppType(socialConnectInfo.getAppType()); + bindInfo.setAuthMode(socialConnectInfo.getAuthMode()); + // is it synchronizing the contact + bindInfo.setContactSyncing(socialConnectInfo.contactSyncing()); + } + spaceInfoVO.setSocial(bindInfo); + // chat bot status + CommonCacheService cacheService = SpringContextHolder.getBean(CommonCacheService.class); + boolean isEnableChatbot = cacheService.checkIfSpaceEnabledChatbot(spaceId); + spaceInfoVO.setIsEnableChatbot(isEnableChatbot); if (Boolean.TRUE.equals(skipUsageVerification)) { spaceInfoVO.setSocial(new SpaceSocialConfig()); spaceInfoVO.setSeatUsage(new SeatUsage()); return spaceInfoVO; } + SubscriptionInfo subscriptionInfo = entitlementServiceFacade.getSpaceSubscription(spaceId); + LocalDate now = ClockManager.me().getLocalDateNow(); + CycleDateRange dateRange = SubscriptionDateRange.calculateCycleDate(subscriptionInfo, now); SeatUsage seatUsage = getSeatUsage(spaceId); spaceInfoVO.setSeatUsage(seatUsage); spaceInfoVO.setSeats(seatUsage.getMemberCount()); @@ -745,7 +782,8 @@ public SpaceInfoVO getSpaceInfo(final String spaceId) { spaceCapacityCacheService.getSpaceCapacity(spaceId); spaceInfoVO.setCapacityUsedSizes(capacityUsedSize); // API usage statistics - long apiUsage = iStaticsService.getCurrentMonthApiUsage(spaceId); + long apiUsage = + iStaticsService.getCurrentMonthApiUsage(spaceId, dateRange.getCycleEndDate()); spaceInfoVO.setApiRequestCountUsage(apiUsage); // file control amount ControlStaticsDTO controlStaticsDTO = @@ -787,27 +825,11 @@ public SpaceInfoVO getSpaceInfo(final String spaceId) { spaceCapacityUsedInfo.getCurrentBundleCapacityUsedSizes()); spaceInfoVO.setGiftCapacityUsedSizes( spaceCapacityUsedInfo.getGiftCapacityUsedSizes()); - - // obtain third party information - SocialConnectInfo socialConnectInfo = - socialServiceFacade.getConnectInfo(spaceId); - SpaceSocialConfig bindInfo = new SpaceSocialConfig(); - if (ObjectUtil.isNotNull(socialConnectInfo) && socialConnectInfo.isEnabled()) { - bindInfo.setEnabled(true); - bindInfo.setPlatform(socialConnectInfo.getPlatform()); - bindInfo.setAppType(socialConnectInfo.getAppType()); - bindInfo.setAuthMode(socialConnectInfo.getAuthMode()); - // is it synchronizing the contact - bindInfo.setContactSyncing(socialConnectInfo.contactSyncing()); - } - spaceInfoVO.setSocial(bindInfo); // credit - BigDecimal usedCredit = aiServiceFacade.getUsedCreditCount(spaceId); + BigDecimal usedCredit = + aiServiceFacade.getUsedCreditCount(spaceId, dateRange.getCycleStartDate(), + dateRange.getCycleEndDate()); spaceInfoVO.setUsedCredit(usedCredit); - // chat bot status - CommonCacheService cacheService = SpringContextHolder.getBean(CommonCacheService.class); - boolean isEnableChatbot = cacheService.checkIfSpaceEnabledChatbot(spaceId); - spaceInfoVO.setIsEnableChatbot(isEnableChatbot); return spaceInfoVO; } @@ -918,8 +940,6 @@ public InternalSpaceUsageVo getInternalSpaceUsageVo(final String spaceId) { vo.setKanbanViewNums(viewVO.getKanbanViews()); vo.setGanttViewNums(viewVO.getGanttViews()); vo.setCalendarViewNums(viewVO.getCalendarViews()); - BigDecimal usedCredit = aiServiceFacade.getUsedCreditCount(spaceId); - vo.setUsedCredit(usedCredit); return vo; } @@ -1225,4 +1245,46 @@ public boolean getSpaceSeatAvailableStatus(String spaceId) { iStaticsService.getActiveMemberTotalCountFromCache(spaceId); return seat - activeMemberTotalCount > 0; } + + @Override + public List getSpaceIdsByCreatedBy(Long userId) { + return baseMapper.selectSpaceIdsByUserId(userId); + } + + @Override + public void checkWidgetOverLimit(String spaceId) { + // get subscription max widget nums + SubscriptionInfo subscriptionInfo = getSpaceSubscription(spaceId); + // Only the free version requires verification + if (!subscriptionInfo.isFree()) { + return; + } + SubscriptionFeatures.ConsumeFeatures.WidgetNums widgetNums = + subscriptionInfo.getFeature().getWidgetNums(); + // check the number of components in the space + Long count = iWidgetService.getSpaceWidgetCount(spaceId); + if (!widgetNums.isUnlimited() && count >= widgetNums.getValue()) { + throw new BusinessException(LimitException.WIDGET_OVER_LIMIT); + } + } + + @Override + public SubscriptionInfo getSpaceSubscription(String spaceId) { + return entitlementServiceFacade.getSpaceSubscription(spaceId); + } + + @Override + public SocialConnectInfo getSocialConnectInfo(String spaceId) { + return socialServiceFacade.getConnectInfo(spaceId); + } + + @Override + public String getSocialSuiteKeyByAppId(String appId) { + return socialServiceFacade.getSuiteKeyByDingtalkSuiteId(appId); + } + + @Override + public boolean checkSocialBind(String spaceId) { + return socialServiceFacade.checkSocialBind(spaceId); + } } diff --git a/backend-server/application/src/main/java/com/apitable/space/service/impl/StaticsServiceImpl.java b/backend-server/application/src/main/java/com/apitable/space/service/impl/StaticsServiceImpl.java index 1f6f502efc..c3f0eaf047 100644 --- a/backend-server/application/src/main/java/com/apitable/space/service/impl/StaticsServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/space/service/impl/StaticsServiceImpl.java @@ -19,11 +19,13 @@ package com.apitable.space.service.impl; import static com.apitable.core.constants.RedisConstants.GENERAL_STATICS; +import static com.apitable.core.constants.RedisConstants.getApiUsageTableDayMindIdCacheKey; import static com.apitable.shared.constants.DateFormatConstants.YEARS_MONTH_PATTERN; -import static java.time.temporal.TemporalAdjusters.firstDayOfMonth; +import static com.apitable.shared.util.DateHelper.SIMPLE_DATE; +import static com.apitable.shared.util.DateHelper.SIMPLE_MONTH; import cn.hutool.core.collection.CollUtil; -import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; @@ -33,22 +35,30 @@ import com.apitable.control.model.ControlTypeDTO; import com.apitable.core.constants.RedisConstants; import com.apitable.core.util.SqlTool; +import com.apitable.organization.dto.UnitMemberTeamDTO; import com.apitable.organization.service.IMemberService; +import com.apitable.shared.clock.spring.ClockManager; import com.apitable.shared.util.DateHelper; +import com.apitable.shared.util.page.PageHelper; +import com.apitable.shared.util.page.PageInfo; import com.apitable.space.dto.ControlStaticsDTO; import com.apitable.space.dto.DatasheetStaticsDTO; import com.apitable.space.dto.NodeStaticsDTO; import com.apitable.space.dto.NodeTypeStaticsDTO; import com.apitable.space.mapper.StaticsMapper; import com.apitable.space.service.IStaticsService; +import com.apitable.workspace.dto.NodeStatisticsDTO; +import com.apitable.workspace.enums.NodeType; import com.apitable.workspace.enums.ViewType; -import com.apitable.workspace.mapper.DatasheetMapper; import com.apitable.workspace.mapper.NodeMapper; +import com.apitable.workspace.service.INodeService; +import com.apitable.workspace.vo.NodeStatisticsVo; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; import jakarta.annotation.Resource; -import java.text.SimpleDateFormat; -import java.time.LocalDateTime; -import java.util.Date; +import java.time.LocalDate; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -82,72 +92,63 @@ public class StaticsServiceImpl implements IStaticsService { private StaticsMapper staticsMapper; @Resource - private DatasheetMapper datasheetMapper; + private RedisTemplate redisTemplate; @Resource - private RedisTemplate redisTemplate; + private INodeService iNodeService; @Value("${SKIP_USAGE_VERIFICATION:false}") private Boolean skipUsageVerification; + @Value("${SKIP_API_USAGE_VERIFICATION:false}") + private Boolean skipApiUsageVerification; + @Value("${SPACE_STATISTICS_CACHE_HOURS:1}") private Integer cacheHours; @Override - public long getCurrentMonthApiUsage(String spaceId) { + public long getCurrentMonthApiUsage(String spaceId, LocalDate currentMonth) { if (Boolean.TRUE.equals(skipUsageVerification)) { return 0; } + if (Boolean.TRUE.equals(skipApiUsageVerification)) { + return 0; + } // Get the API usage of this month up to yesterday - Long apiUsageUntilYesterday = this.getCurrentMonthApiUsageUntilYesterday(spaceId); + Long apiUsageUntilYesterday = + this.getCurrentMonthApiUsageUntilYesterday(spaceId, currentMonth); // If it is NULL, it indicates that the daily API usage statistics table is empty, and the old method is adopted - if (apiUsageUntilYesterday == null) { - return this.getCurrentMonthApiUsageWithCache(spaceId); + if (null == apiUsageUntilYesterday) { + return this.getCurrentMonthApiUsageWithCache(spaceId, currentMonth); } else { return apiUsageUntilYesterday + this.getTodayApiUsage(spaceId); } } - @Override - public Long getTodayApiUsage(String spaceId) { - // Get today's API usage cache - SimpleDateFormat today = new SimpleDateFormat("yyyy-MM-dd"); - String todayKey = - StrUtil.format(GENERAL_STATICS, "api" + today.format(new Date()), spaceId); - Object apiUsageToday = redisTemplate.opsForValue().get(todayKey); - if (apiUsageToday == null) { - // Maximum table ID of yesterday's API usage record - Long yesterdayMaxId = - staticsMapper.selectMaxIdByTime(today.format(DateUtil.yesterday())); - // Get today's API usage - apiUsageToday = staticsMapper.countByIdGreaterThanAndSpaceId(yesterdayMaxId, spaceId); - // Update today's api usage cache - redisTemplate.opsForValue() - .set(todayKey, Long.valueOf(apiUsageToday.toString()), 2, TimeUnit.HOURS); - } - // Return to the space station today's API usage - return Long.valueOf(apiUsageToday.toString()); - } - - @Override - public Long getCurrentMonthApiUsageUntilYesterday(String spaceId) { + /** + * Get the API usage from this month to yesterday, and update the cache. + * + * @param spaceId space id + * @return amount + */ + private Long getCurrentMonthApiUsageUntilYesterday(String spaceId, LocalDate currentMonth) { // If it is the first day of this month, 0 will be returned directly - if (ObjectUtil.equals(LocalDateTime.now().getDayOfMonth(), 1)) { + if (ObjectUtil.equals(currentMonth.getDayOfMonth(), 1)) { return 0L; } else { // Get the API usage cache of this month before today - SimpleDateFormat month = new SimpleDateFormat("yyyy-MM"); String monthKey = - StrUtil.format(GENERAL_STATICS, "api" + month.format(new Date()), spaceId); + StrUtil.format(GENERAL_STATICS, "api" + currentMonth.format(SIMPLE_MONTH), spaceId); Object apiUsageBeforeToday = redisTemplate.opsForValue().get(monthKey); if (apiUsageBeforeToday != null) { return Long.valueOf(apiUsageBeforeToday.toString()); } // No cache. Query the API usage in this month before today - SimpleDateFormat today = new SimpleDateFormat("yyyy-MM-dd"); + LocalDate startDayOfMonth = currentMonth.withDayOfMonth(1); + LocalDate yesterday = currentMonth.minusDays(1); Long totalSum = staticsMapper.selectTotalSumBySpaceIdAndTimeBetween(spaceId, - today.format(DateUtil.beginOfMonth(new Date())), - today.format(DateUtil.yesterday())); + startDayOfMonth.format(SIMPLE_DATE), + yesterday.format(SIMPLE_DATE)); if (totalSum == null) { return null; } @@ -158,16 +159,15 @@ public Long getCurrentMonthApiUsageUntilYesterday(String spaceId) { } } - private Long getCurrentMonthApiUsageWithCache(String spaceId) { - Long minId = this.getApiUsageTableMinId(); + private Long getCurrentMonthApiUsageWithCache(String spaceId, LocalDate currentMonth) { + Long minId = this.getApiUsageTableMinId(currentMonth); // The minimum table ID of this month does not exist, that is, there is no call record if (minId == null) { return 0L; } // Get today's API usage cache - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); String cacheKey = - StrUtil.format(GENERAL_STATICS, "api-" + format.format(new Date()), spaceId); + StrUtil.format(GENERAL_STATICS, "api-" + currentMonth.format(SIMPLE_DATE), spaceId); Object apiUsageToday = redisTemplate.opsForValue().get(cacheKey); if (apiUsageToday == null) { apiUsageToday = staticsMapper.countApiUsageBySpaceId(spaceId, minId); @@ -177,28 +177,53 @@ private Long getCurrentMonthApiUsageWithCache(String spaceId) { return Long.valueOf(apiUsageToday.toString()); } - private Long getApiUsageTableMinId() { + /** + * Get today's API usage and update the cache. + * + * @param spaceId space id + * @return amount + */ + private Long getTodayApiUsage(String spaceId) { + // Get today's API usage cache + LocalDate now = ClockManager.me().getLocalDateNow(); + String todayKey = + StrUtil.format(GENERAL_STATICS, "api" + now.format(SIMPLE_DATE), spaceId); + Object apiUsageToday = redisTemplate.opsForValue().get(todayKey); + if (null == apiUsageToday) { + // The created at field is not queried based on the created at field + // reducing the number of table returns + Long currentDayMinId = getApiUsageTableMinIdByDay(); + if (null != currentDayMinId) { + apiUsageToday = staticsMapper.countApiUsageBySpaceId(spaceId, currentDayMinId); + } else { + Long currentMonthMindId = getApiUsageTableMinId(now); + if (null == currentMonthMindId) { + return 0L; + } + // Get today's API usage + apiUsageToday = + staticsMapper.countByIdGreaterThanAndSpaceIdAndCreatedAt(currentMonthMindId, + spaceId, + now.format(SIMPLE_DATE)); + } + // Update today's api usage cache + redisTemplate.opsForValue() + .set(todayKey, Long.valueOf(apiUsageToday.toString()), 2, TimeUnit.HOURS); + } + // Return to the space station today's API usage + return Long.valueOf(apiUsageToday.toString()); + } + + private Long getApiUsageTableMinId(LocalDate now) { // Get the minimum ID of the API consumption table this month - LocalDateTime now = LocalDateTime.now(); String key = StrUtil.format(GENERAL_STATICS, "api-usage-min-id", DateHelper.formatFullTime(now, YEARS_MONTH_PATTERN)); Long id = redisTemplate.opsForValue().get(key); - if (id != null) { - return id; - } - // The minimum ID of this month does not exist. Query the minimum ID of last month to reduce the query volume - String lastMonthKey = StrUtil.format(GENERAL_STATICS, "api-usage-min-id", - DateHelper.formatFullTime(now.plusMonths(-1), YEARS_MONTH_PATTERN)); - Long lastMonthMinId = redisTemplate.opsForValue().get(lastMonthKey); - // If the minimum table ID of last month does not exist, query the maximum table ID directly - if (lastMonthMinId == null) { + if (null == id) { id = staticsMapper.selectApiUsageMaxId(); - } else { - LocalDateTime startDayOfMonth = now.with(firstDayOfMonth()); - id = staticsMapper.selectApiUsageMinIdByCreatedAt(lastMonthMinId, startDayOfMonth); + // Keep the cache of the month + redisTemplate.opsForValue().set(key, id, 33, TimeUnit.DAYS); } - // Keep the cache of the month - redisTemplate.opsForValue().set(key, id, 33, TimeUnit.DAYS); return id; } @@ -242,14 +267,13 @@ public long getDatasheetRecordTotalCountBySpaceId(String spaceId) { if (null != recordCount) { return recordCount; } - List dstIds = datasheetMapper.selectDstIdBySpaceId(spaceId); - if (CollUtil.isEmpty(dstIds)) { + List recordIds = staticsMapper.countRecordsBySpaceId(spaceId); + if (CollUtil.isEmpty(recordIds)) { return 0L; } recordCount = 0L; - List> dstIdList = CollUtil.split(dstIds, 1000); - for (List item : dstIdList) { - recordCount += SqlTool.retCount(staticsMapper.countRecordsByDstIds(item)); + for (String item : recordIds) { + recordCount += JSONUtil.parseArray(item).size(); } // save in cache redisTemplate.opsForValue() @@ -342,7 +366,12 @@ public DatasheetStaticsDTO getDatasheetStaticsBySpaceId(String spaceId) { return viewCacheVo; } DatasheetStaticsDTO viewVO = new DatasheetStaticsDTO(); - List objects = staticsMapper.selectDstViewStaticsBySpaceId(spaceId); + List dstIds = + nodeMapper.selectNodeIdBySpaceIdAndType(spaceId, NodeType.DATASHEET.getNodeType()); + if (CollUtil.isEmpty(dstIds)) { + return viewVO; + } + List objects = staticsMapper.selectDstViewStaticsByDstIds(dstIds); if (CollUtil.isNotEmpty(objects)) { objects.stream() .flatMap(o -> JSONUtil.parseArray(o).stream()) @@ -437,4 +466,46 @@ public void deleteDatasheetRecordCountStatistics(String spaceId) { redisTemplate.delete(key); } } + + @Override + public PageInfo getNodeStatistics(String spaceId, Page page) { + List records = new ArrayList<>(); + IPage nodes = nodeMapper.selectCountBySpaceIdWithPage(spaceId, page); + if (nodes.getRecords().isEmpty()) { + return PageHelper.build(nodes.getCurrent(), nodes.getSize(), nodes.getTotal(), records); + } + List userIds = nodes.getRecords().stream().map( + NodeStatisticsDTO::getCreatedBy).filter(userId -> !userId.equals(0L)).distinct() + .toList(); + List members = + iMemberService.getMemberBySpaceIdAndUserIds(spaceId, userIds); + Map memberMap = members.stream() + .collect(Collectors.toMap(UnitMemberTeamDTO::getUserId, i -> i)); + // get private node count + List unitIds = + members.stream().map(UnitMemberTeamDTO::getUnitId).collect(Collectors.toList()); + Map privateNodeCountMap = iNodeService.getCountByUnitIds(unitIds); + for (NodeStatisticsDTO node : nodes.getRecords()) { + NodeStatisticsVo vo = new NodeStatisticsVo(); + UnitMemberTeamDTO member = memberMap.get(node.getCreatedBy()); + vo.setMemberId(StrUtil.toStringOrNull(member.getMemberId())); + vo.setMemberName(member.getMemberName()); + vo.setAvatar(member.getAvatar()); + vo.setAvatarColor(member.getAvatarColor()); + vo.setTeamName(member.getTeamName()); + vo.setTotalNodeCount(node.getNodeCount()); + vo.setPrivateNodeCount( + NumberUtil.nullToZero(privateNodeCountMap.get(member.getUnitId()))); + vo.setTeamNodeCount(vo.getTotalNodeCount() - vo.getPrivateNodeCount()); + records.add(vo); + } + return PageHelper.build(nodes.getCurrent(), nodes.getSize(), nodes.getTotal(), records); + } + + private Long getApiUsageTableMinIdByDay() { + // Get the minimum ID of theAPI consumption table today, input in at 0 o'clock in everyday + // see ApiUsageTask + String key = getApiUsageTableDayMindIdCacheKey(LocalDate.now().format(SIMPLE_DATE)); + return redisTemplate.opsForValue().get(key); + } } diff --git a/backend-server/application/src/main/java/com/apitable/space/task/ApiUsageTask.java b/backend-server/application/src/main/java/com/apitable/space/task/ApiUsageTask.java new file mode 100644 index 0000000000..2c510da889 --- /dev/null +++ b/backend-server/application/src/main/java/com/apitable/space/task/ApiUsageTask.java @@ -0,0 +1,44 @@ +package com.apitable.space.task; + +import static com.apitable.core.constants.RedisConstants.getApiUsageTableDayMindIdCacheKey; +import static com.apitable.shared.util.DateHelper.SIMPLE_DATE; +import static net.javacrumbs.shedlock.core.LockAssert.assertLocked; + +import com.apitable.space.mapper.StaticsMapper; +import jakarta.annotation.Resource; +import java.time.LocalDate; +import java.util.concurrent.TimeUnit; +import lombok.extern.slf4j.Slf4j; +import net.javacrumbs.shedlock.spring.annotation.SchedulerLock; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.scheduling.annotation.Scheduled; + +/** + * api usage task. + */ +@Configuration(proxyBeanMethods = false) +@ConditionalOnProperty(value = "system.test-enabled", havingValue = "false", matchIfMissing = true) +@Slf4j +public class ApiUsageTask { + @Resource + private RedisTemplate redisTemplate; + + @Resource + private StaticsMapper staticsMapper; + + /** + * get api usage table min id at beginning of every day. + * cron: 0 0 0 * * ? + */ + @Scheduled(cron = "0 0 0 * * ?") + @SchedulerLock(name = "setEveryDayApiUsageMindId", lockAtMostFor = "1h", lockAtLeastFor = "30m") + public void setEveryDayApiUsageMindId() { + assertLocked(); + String key = getApiUsageTableDayMindIdCacheKey(LocalDate.now().format(SIMPLE_DATE)); + Long maxId = staticsMapper.selectApiUsageMaxId(); + redisTemplate.opsForValue().setIfAbsent(key, maxId, 2, TimeUnit.DAYS); + log.info("setEveryDayApiUsageMindId:{}", maxId); + } +} diff --git a/backend-server/application/src/main/java/com/apitable/automation/model/TriggerTypeEditRO.java b/backend-server/application/src/main/java/com/apitable/space/vo/EmailInvitationResultVO.java similarity index 59% rename from backend-server/application/src/main/java/com/apitable/automation/model/TriggerTypeEditRO.java rename to backend-server/application/src/main/java/com/apitable/space/vo/EmailInvitationResultVO.java index 299f7c53ae..18aab5bf38 100644 --- a/backend-server/application/src/main/java/com/apitable/automation/model/TriggerTypeEditRO.java +++ b/backend-server/application/src/main/java/com/apitable/space/vo/EmailInvitationResultVO.java @@ -16,34 +16,26 @@ * along with this program. If not, see . */ -package com.apitable.automation.model; +package com.apitable.space.vo; +import com.apitable.shared.support.serializer.NullArraySerializer; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; +import lombok.Builder; import lombok.Data; /** - * TriggerTypeEditRO. + *

+ * Email Invitation Result View. + *

*/ @Data -@Schema(description = "TriggerTypeEditRO") -public class TriggerTypeEditRO { - - @Schema(description = "name") - private String name; - - @Schema(description = "description") - private String description; - - @Schema(description = "input JSON format") - private String inputJsonSchema; - - @Schema(description = "output JSON format") - private String outputJsonSchema; - - @Schema(description = "trigger prototype endpoint") - private String endpoint; - - @Schema(description = "i18n package") - private String i18n; +@Builder(toBuilder = true) +@Schema(description = "Email Invitation Result View") +public class EmailInvitationResultVO { + @Schema(description = "Email for successful invitation", example = "[\"aaa\", \"bbb\"]") + @JsonSerialize(nullsUsing = NullArraySerializer.class) + private List emails; } diff --git a/backend-server/application/src/main/java/com/apitable/organization/vo/InviteInfoVo.java b/backend-server/application/src/main/java/com/apitable/space/vo/EmailInvitationValidateVO.java similarity index 84% rename from backend-server/application/src/main/java/com/apitable/organization/vo/InviteInfoVo.java rename to backend-server/application/src/main/java/com/apitable/space/vo/EmailInvitationValidateVO.java index 928fcc262d..cc8d8e14b6 100644 --- a/backend-server/application/src/main/java/com/apitable/organization/vo/InviteInfoVo.java +++ b/backend-server/application/src/main/java/com/apitable/space/vo/EmailInvitationValidateVO.java @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package com.apitable.organization.vo; +package com.apitable.space.vo; import com.apitable.shared.support.serializer.NullBooleanSerializer; import com.fasterxml.jackson.databind.annotation.JsonSerialize; @@ -25,12 +25,12 @@ /** *

- * Invitation Information View. + * Email Invitation Validate View. *

*/ @Data -@Schema(description = "Invitation Information View") -public class InviteInfoVo { +@Schema(description = "Email Invitation Validate View") +public class EmailInvitationValidateVO { @Schema(description = "Space ID", example = "spcyQkKp9XJEl") private String spaceId; @@ -48,6 +48,10 @@ public class InviteInfoVo { @JsonSerialize(nullsUsing = NullBooleanSerializer.class) private Boolean isLogin; + @Schema(description = "Whether the user's email matches the invitation email", example = "true") + @JsonSerialize(nullsUsing = NullBooleanSerializer.class) + private Boolean isMatch; + @Schema(description = "Whether the invited mailbox has an account bound", example = "true") @JsonSerialize(nullsUsing = NullBooleanSerializer.class) private Boolean isBound; diff --git a/backend-server/application/src/main/java/com/apitable/space/vo/SeatUsage.java b/backend-server/application/src/main/java/com/apitable/space/vo/SeatUsage.java index 9db5ecdda2..57d29cef4a 100644 --- a/backend-server/application/src/main/java/com/apitable/space/vo/SeatUsage.java +++ b/backend-server/application/src/main/java/com/apitable/space/vo/SeatUsage.java @@ -22,6 +22,7 @@ public class SeatUsage { private Long memberCount; public SeatUsage() { + this(0L, 0L); } /** diff --git a/backend-server/application/src/main/java/com/apitable/space/vo/SpaceInfoVO.java b/backend-server/application/src/main/java/com/apitable/space/vo/SpaceInfoVO.java index 95fce87085..6c1bb84db6 100644 --- a/backend-server/application/src/main/java/com/apitable/space/vo/SpaceInfoVO.java +++ b/backend-server/application/src/main/java/com/apitable/space/vo/SpaceInfoVO.java @@ -28,6 +28,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import java.math.BigDecimal; import java.time.LocalDateTime; +import java.util.List; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -180,5 +181,9 @@ public class SpaceInfoVO { @Schema(description = "User's resource information view in the space") private UserSpaceVo userResource; + @Schema(description = "List of experimental functions", + type = "java.util.List", example = "[\"RENDER_PROMPT\", \"ASYNC_COMPUTE\", \"ROBOT\"]") + private List labsKeys; + } diff --git a/backend-server/application/src/main/java/com/apitable/space/vo/SpaceSubscribeVo.java b/backend-server/application/src/main/java/com/apitable/space/vo/SpaceSubscribeVo.java index f7ce92dc99..ca9f3723e5 100644 --- a/backend-server/application/src/main/java/com/apitable/space/vo/SpaceSubscribeVo.java +++ b/backend-server/application/src/main/java/com/apitable/space/vo/SpaceSubscribeVo.java @@ -59,14 +59,19 @@ public class SpaceSubscribeVo { @JsonSerialize(nullsUsing = NullArraySerializer.class) private List addOnPlans; + @Schema(description = "expire unix timestamp", example = "1703234649") private Long expireAt; @Schema(description = "subscription expiration time. if free, it is null.", - example = "2019-01-01") + example = "2019-01-01", deprecated = true) @JsonFormat(pattern = DatePattern.NORM_DATE_PATTERN) @JsonSerialize(using = LocalDateSerializer.class) private LocalDate deadline; + @Schema(description = "cycle day of month", example = "21") + @JsonSerialize(nullsUsing = NullNumberSerializer.class) + private Integer cycleDayOfMonth; + @Schema(description = "seat(unit: people)", example = "10") @JsonSerialize(nullsUsing = NullNumberSerializer.class) private Long maxSeats; @@ -87,10 +92,15 @@ public class SpaceSubscribeVo { @JsonSerialize(nullsUsing = NullNumberSerializer.class) private Long maxRowsInSpace; - @Schema(description = "api usage limit(unit: count)", example = "10") + @Schema(description = "api usage limit(unit: count)", example = "10", deprecated = true) @JsonSerialize(nullsUsing = NullNumberSerializer.class) + @Deprecated(since = "1.8.0", forRemoval = true) private Long maxApiCall; + @Schema(description = "api call number per month", example = "10") + @JsonSerialize(nullsUsing = NullNumberSerializer.class) + private Long apiCallNumsPerMonth; + @Schema(description = "admin nums(unit: person)", example = "10") @JsonSerialize(nullsUsing = NullNumberSerializer.class) private Long maxAdminNums; @@ -200,6 +210,11 @@ public class SpaceSubscribeVo { @JsonSerialize(nullsUsing = NullNumberSerializer.class) private Long maxAuditQueryDays; + @Schema(description = "Advance - whether to use audit log query", + example = "false") + @JsonSerialize(nullsUsing = NullBooleanSerializer.class) + private Boolean auditQuery; + @Schema(description = "the maximum credit number for ai query(unit: int)", example = "1000") @JsonSerialize(nullsUsing = NullNumberSerializer.class) private Long maxMessageCredits; @@ -233,4 +248,8 @@ public class SpaceSubscribeVo { @Schema(description = "max mirror nums(unit: mirror)", example = "5") @JsonSerialize(nullsUsing = NullNumberSerializer.class) private Long maxMirrorNums; + + @Schema(description = "whether can control form brand log", example = "false") + @JsonSerialize(nullsUsing = NullBooleanSerializer.class) + private Boolean controlFormBrandLogo; } diff --git a/backend-server/application/src/main/java/com/apitable/template/controller/TemplateController.java b/backend-server/application/src/main/java/com/apitable/template/controller/TemplateController.java index 6038fa958e..7bd3c78f5f 100644 --- a/backend-server/application/src/main/java/com/apitable/template/controller/TemplateController.java +++ b/backend-server/application/src/main/java/com/apitable/template/controller/TemplateController.java @@ -260,7 +260,8 @@ public ResponseData quote(@RequestBody @Valid QuoteTemplateRo ro) { String nodeId = iNodeService.copyNodeToSpace(userId, spaceId, ro.getParentId(), info.getNodeId(), NodeCopyOptions.builder().copyData(BooleanUtil.isTrue(ro.getData())) - .verifyNodeCount(true).sourceTemplateId(ro.getTemplateId()).build()); + .verifyNodeCount(true).sourceTemplateId(ro.getTemplateId()) + .unitId(ro.getUnitId()).build()); // Cumulative template usage times TaskManager.me() .execute(() -> templateMapper.updateUsedTimesByTempId(ro.getTemplateId(), 1)); diff --git a/backend-server/application/src/main/java/com/apitable/template/mapper/TemplateMapper.java b/backend-server/application/src/main/java/com/apitable/template/mapper/TemplateMapper.java index 56c950829b..b2dac0c03c 100644 --- a/backend-server/application/src/main/java/com/apitable/template/mapper/TemplateMapper.java +++ b/backend-server/application/src/main/java/com/apitable/template/mapper/TemplateMapper.java @@ -76,6 +76,17 @@ int updateUsedTimesByTempId(@Param("templateId") String templateId, */ int updateIsDeletedByTempId(@Param("templateId") String templateId); + /** + * Query template information. + * + * @param typeId type id + * @param templateIds template ids + * @return List of TemplateInfo + * @author Chambers + */ + List selectInfoByTypeIdAndTemplateIds(@Param("typeId") String typeId, + @Param("templateIds") List templateIds); + /** * Query dto by type id. */ diff --git a/backend-server/application/src/main/java/com/apitable/template/ro/QuoteTemplateRo.java b/backend-server/application/src/main/java/com/apitable/template/ro/QuoteTemplateRo.java index 249a1edf19..2c20a6d6bb 100644 --- a/backend-server/application/src/main/java/com/apitable/template/ro/QuoteTemplateRo.java +++ b/backend-server/application/src/main/java/com/apitable/template/ro/QuoteTemplateRo.java @@ -43,4 +43,8 @@ public class QuoteTemplateRo { @Schema(description = "Whether to retain data", example = "true") private Boolean data = true; + + @Schema(description = "where to quote", example = "23445") + private String unitId; + } diff --git a/backend-server/application/src/main/java/com/apitable/template/ro/TemplateCenterConfigRo.java b/backend-server/application/src/main/java/com/apitable/template/ro/TemplateCenterConfigRo.java deleted file mode 100644 index 1d75f021b5..0000000000 --- a/backend-server/application/src/main/java/com/apitable/template/ro/TemplateCenterConfigRo.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * APITable - * Copyright (C) 2022 APITable Ltd. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -package com.apitable.template.ro; - -import io.swagger.v3.oas.annotations.media.Schema; -import io.swagger.v3.oas.annotations.media.Schema.RequiredMode; -import lombok.Data; - -/** - *

- * Template Center Config Ro. - *

- */ -@Data -@Schema(description = "Template Center Config Request Object") -public class TemplateCenterConfigRo { - - @Schema(description = "Request Host", example = "https://api.com") - private String host; - - @Schema(description = "Request Bearer Token", example = "uskxx") - private String token; - - @Schema(description = "Recommend Datasheet ID", - requiredMode = RequiredMode.REQUIRED, example = "dstxxx") - private String recommendDatasheetId; - - @Schema(description = "Recommend View ID", example = "viwxxx") - private String recommendViewId; - - @Schema(description = "Template Category Datasheet ID", - requiredMode = RequiredMode.REQUIRED, example = "dstxxx") - private String categoryDatasheetId; - - @Schema(description = "Template Category View ID", example = "viwxxx") - private String categoryViewId; - - @Schema(description = "Template Album Datasheet ID", - requiredMode = RequiredMode.REQUIRED, example = "dstxxx") - private String albumDatasheetId; - - @Schema(description = "Template Album View ID", example = "viwxxx") - private String albumViewId; - - @Schema(description = "Template Datasheet ID", - requiredMode = RequiredMode.REQUIRED, example = "dstxxx") - private String templateDatasheetId; - - @Schema(description = "Template View ID", example = "viwxxx") - private String templateViewId; -} diff --git a/backend-server/application/src/main/java/com/apitable/template/service/ITemplateService.java b/backend-server/application/src/main/java/com/apitable/template/service/ITemplateService.java index ff661b3ecd..452002bfb5 100644 --- a/backend-server/application/src/main/java/com/apitable/template/service/ITemplateService.java +++ b/backend-server/application/src/main/java/com/apitable/template/service/ITemplateService.java @@ -125,6 +125,16 @@ TemplateDirectoryVo getDirectoryVo(String categoryCode, String templateId, Boole */ String getDefaultTemplateNodeId(); + /** + * Get template node ids. + * + * @param spaceId space id + * @param templateIds template ids + * @return node ids + * @author Chambers + */ + List getTemplateNodeIds(String spaceId, List templateIds); + /** * fuzzy search template related content. */ diff --git a/backend-server/application/src/main/java/com/apitable/template/service/impl/TemplateAlbumServiceImpl.java b/backend-server/application/src/main/java/com/apitable/template/service/impl/TemplateAlbumServiceImpl.java index 124ff24bed..e3f60cc92a 100644 --- a/backend-server/application/src/main/java/com/apitable/template/service/impl/TemplateAlbumServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/template/service/impl/TemplateAlbumServiceImpl.java @@ -56,6 +56,9 @@ public class TemplateAlbumServiceImpl extends ServiceImpl getAlbumVosByAlbumIds(List albumIds) { + if (albumIds.isEmpty()) { + return new ArrayList<>(); + } return baseMapper.selectAlbumVosByAlbumIds(albumIds); } diff --git a/backend-server/application/src/main/java/com/apitable/template/service/impl/TemplateServiceImpl.java b/backend-server/application/src/main/java/com/apitable/template/service/impl/TemplateServiceImpl.java index c1b53b6541..64e061b4aa 100644 --- a/backend-server/application/src/main/java/com/apitable/template/service/impl/TemplateServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/template/service/impl/TemplateServiceImpl.java @@ -213,6 +213,8 @@ public void checkTemplateForeignNode(final Long memberId, iAutomationRobotService.checkAutomationReference(singletonNodeIds, singletonNodeIds); break; + case CUSTOM_PAGE: + break; default: throw new BusinessException(NOT_ALLOW); } @@ -748,14 +750,30 @@ public TemplateDirectoryVo getDirectoryVo(final String categoryCode, */ @Override public String getDefaultTemplateNodeId() { - if (Locale.US.equals(LocaleContextHolder.getLocale())) { - String quoteEnTemplateId = constProperties.getQuoteEnTemplateId(); - return baseMapper.selectNodeIdByTempId(quoteEnTemplateId); - } String quoteTemplateId = constProperties.getQuoteTemplateId(); + try { + if (Locale.US.equals(LocaleContextHolder.getLocale())) { + quoteTemplateId = constProperties.getQuoteEnTemplateId(); + } + } catch (Exception e) { + log.error("Get default en template id error", e); + } return baseMapper.selectNodeIdByTempId(quoteTemplateId); } + @Override + public List getTemplateNodeIds(String spaceId, List templateIds) { + List templates = + baseMapper.selectInfoByTypeIdAndTemplateIds(spaceId, templateIds); + if (templates.isEmpty()) { + return new ArrayList<>(); + } + CollectionUtil.customSequenceSort(templates, TemplateInfo::getTemplateId, templateIds); + return templates.stream() + .map(TemplateInfo::getNodeId) + .collect(Collectors.toList()); + } + private List searchTemplate(final String keyword, final String rawLang) { log.info("Fuzzy Search Template. keyword:{},lang:{}", keyword, rawLang); diff --git a/backend-server/application/src/main/java/com/apitable/user/controller/UserController.java b/backend-server/application/src/main/java/com/apitable/user/controller/UserController.java index e37d61b6c0..b591a6604a 100644 --- a/backend-server/application/src/main/java/com/apitable/user/controller/UserController.java +++ b/backend-server/application/src/main/java/com/apitable/user/controller/UserController.java @@ -116,7 +116,7 @@ */ @Slf4j @RestController -@Tag(name = "Account Center Module_User Management Interface") +@Tag(name = "User") @ApiResource(path = "/user") public class UserController { @@ -343,6 +343,7 @@ public ResponseData validBindEmail() { * @param data CheckUserEmailRo * @return {@link ResponseData} */ + @Deprecated(since = "v1.10.0") @PostResource(path = "/validate/email", requiredPermission = false) @Operation(summary = "Query whether the user is consistent with the " + "specified mail", description = "Query whether the user is consistent " @@ -394,7 +395,8 @@ public ResponseData bindEmail( boolean exist = iUserService.checkByEmail(param.getEmail()); ExceptionUtil.isFalse(exist, EMAIL_HAS_BIND); Long userId = SessionContext.getUserId(); - iUserService.updateEmailByUserId(userId, param.getEmail()); + String oldEmail = LoginContext.me().getLoginUser().getEmail(); + iUserService.updateEmailByUserId(userId, param.getEmail(), oldEmail); return ResponseData.success(); } diff --git a/backend-server/application/src/main/java/com/apitable/user/service/IUserService.java b/backend-server/application/src/main/java/com/apitable/user/service/IUserService.java index 101c25651f..b88aa262d3 100644 --- a/backend-server/application/src/main/java/com/apitable/user/service/IUserService.java +++ b/backend-server/application/src/main/java/com/apitable/user/service/IUserService.java @@ -167,6 +167,16 @@ UserEntity createUserByMobilePhone(String areaCode, String mobile, */ UserEntity createUserByEmail(String email, String password); + /** + * Create an account by email. + * + * @param email email + * @param password password + * @param lang lang + * @return UserEntity + */ + UserEntity createUserByEmail(String email, String password, String lang); + /** * initial new space for new user. * @@ -196,8 +206,9 @@ UserEntity createUserByMobilePhone(String areaCode, String mobile, * * @param userId User ID * @param email email + * @param oldEmail old email */ - void updateEmailByUserId(Long userId, String email); + void updateEmailByUserId(Long userId, String email, String oldEmail); /** * User Unbind Email. @@ -396,4 +407,12 @@ List getLangAndEmailByIds(List userIds, * @return a map with userId as key */ Map getUserSimpleInfoMap(String spaceId, List userIds); + + /** + * get user simple info. + * + * @param userIds user id list + * @return list UserEntity + */ + List getByIds(List userIds); } diff --git a/backend-server/application/src/main/java/com/apitable/user/service/impl/UserHistoryServiceImpl.java b/backend-server/application/src/main/java/com/apitable/user/service/impl/UserHistoryServiceImpl.java index 01b3d156b9..cf81cefcf9 100644 --- a/backend-server/application/src/main/java/com/apitable/user/service/impl/UserHistoryServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/user/service/impl/UserHistoryServiceImpl.java @@ -32,11 +32,11 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import jakarta.annotation.Resource; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.stream.Collectors; -import org.apache.commons.compress.utils.Lists; import org.springframework.stereotype.Service; /** @@ -126,7 +126,7 @@ private UserHistoryEntity transferDataFromUser(UserEntity user) { public List getUserHistoryDtos(LocalDateTime createdAtBefore, LocalDateTime createdAtAfter, UserOperationType userOperationType) { - List userLatestHistoryDtos = Lists.newArrayList(); + List userLatestHistoryDtos = new ArrayList<>(); List historyDtos = userHistoryMapper.selectUserHistoryDtos(createdAtBefore, createdAtAfter, userOperationType.getStatusCode()); diff --git a/backend-server/application/src/main/java/com/apitable/user/service/impl/UserServiceImpl.java b/backend-server/application/src/main/java/com/apitable/user/service/impl/UserServiceImpl.java index 0148827e58..2a6ffa0881 100644 --- a/backend-server/application/src/main/java/com/apitable/user/service/impl/UserServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/user/service/impl/UserServiceImpl.java @@ -336,7 +336,7 @@ public Long createByExternalSystem( // and has not been bound to other accounts, // activate the space members of the invited mail List inactiveMembers = - iMemberService.getInactiveMemberByEmails(email); + iMemberService.getInactiveMemberByEmail(email); inactiveMemberProcess(user.getId(), inactiveMembers); } else { String spaceName = user.getNickName(); @@ -417,7 +417,7 @@ public Long create( // and has not been bound to other accounts, // activate the space members of the invited mailbox List inactiveMembers = - iMemberService.getInactiveMemberByEmails(email); + iMemberService.getInactiveMemberByEmail(email); hasSpace = this.inactiveMemberProcess(entity.getId(), inactiveMembers); } @@ -486,11 +486,17 @@ public UserEntity createUserByEmail(final String email) { @Override @Transactional(rollbackFor = Exception.class) public UserEntity createUserByEmail(final String email, final String password) { + return createUserByEmail(email, password, languageManager.getDefaultLanguageTag()); + } + + @Override + @Transactional(rollbackFor = Exception.class) + public UserEntity createUserByEmail(final String email, final String password, String lang) { UserEntity entity = UserEntity.builder() .uuid(IdUtil.fastSimpleUUID()) .email(email) .nickName(StringUtils.substringBefore(email, "@")) - .locale(languageManager.getDefaultLanguageTag()) + .locale(lang) .color(RandomUtil.randomInt(0, USER_AVATAR_COLOR_MAX_VALUE)) .lastLoginTime(LocalDateTime.now()) .build(); @@ -543,12 +549,12 @@ public void bindMemberByEmail(final Long userId, final String spaceId, ExceptionUtil.isBlank(userEmail, LINK_EMAIL_ERROR); // Bind as user email, and the email // will be activated by invited space members together - updateEmailByUserId(userId, email); + updateEmailByUserId(userId, email, null); } @Override @Transactional(rollbackFor = Exception.class) - public void updateEmailByUserId(final Long userId, final String email) { + public void updateEmailByUserId(final Long userId, final String email, final String oldEmail) { log.info("Modify User [{}] email [{}]", userId, email); UserEntity updateUser = new UserEntity(); updateUser.setId(userId); @@ -561,11 +567,11 @@ public void updateEmailByUserId(final Long userId, final String email) { // and has not been bound to other accounts, // activate the space members of the invited email List inactiveMembers = - iMemberService.getInactiveMemberByEmails(email); + iMemberService.getInactiveMemberByEmail(email); this.inactiveMemberProcess(userId, inactiveMembers); // Delete Cache loginUserCacheService.delete(userId); - userServiceFacade.onUserChangeEmailAction(userId, email); + userServiceFacade.onUserChangeEmailAction(userId, email, oldEmail); } @Override @@ -600,7 +606,7 @@ public void updateMobileByUserId(final Long userId, final String code, // and no other account has been bound, // activate the invited space member List inactiveMembers = - iMemberService.getInactiveMemberByEmails(mobile); + iMemberService.getInactiveMemberDtoByMobile(mobile); this.inactiveMemberProcess(userId, inactiveMembers); // Delete Cache @@ -1199,4 +1205,9 @@ public Map getUserSimpleInfoMap(String spaceId, List u return vo; })); } + + @Override + public List getByIds(List userIds) { + return baseMapper.selectByIds(userIds); + } } diff --git a/backend-server/application/src/main/java/com/apitable/widget/controller/WidgetController.java b/backend-server/application/src/main/java/com/apitable/widget/controller/WidgetController.java index 3ee563cc3e..0e482cc185 100644 --- a/backend-server/application/src/main/java/com/apitable/widget/controller/WidgetController.java +++ b/backend-server/application/src/main/java/com/apitable/widget/controller/WidgetController.java @@ -27,6 +27,7 @@ import com.apitable.control.infrastructure.permission.NodePermission; import com.apitable.core.support.ResponseData; import com.apitable.core.util.ExceptionUtil; +import com.apitable.organization.enums.UnitType; import com.apitable.organization.service.IMemberService; import com.apitable.shared.cache.service.UserSpaceCacheService; import com.apitable.shared.component.scanner.annotation.ApiResource; @@ -130,15 +131,24 @@ public ResponseData> widgetStoreList( schema = @Schema(type = "string"), in = ParameterIn.PATH, example = "spczJrh2i3tLW"), @Parameter(name = "count", description = "load quantity", - schema = @Schema(type = "integer"), in = ParameterIn.QUERY, example = "10") + schema = @Schema(type = "integer"), in = ParameterIn.QUERY, example = "10"), + @Parameter(name = "unitType", description = "unitType, 3: member(private), 1: team", + schema = @Schema(type = "integer"), example = "3", in = ParameterIn.QUERY) }) public ResponseData> findWidgetInfoBySpaceId( @PathVariable("spaceId") final String spaceId, - @RequestParam(value = "count", required = false, defaultValue = "10") final Integer count) { + @RequestParam(value = "count", required = false, defaultValue = "10") final Integer count, + @RequestParam(name = "unitType", required = false) Integer unitType) { Long userId = SessionContext.getUserId(); Long memberId = userSpaceCacheService.getMemberId(userId, spaceId); List infos = iWidgetService.getWidgetInfoList(spaceId, memberId, count); + if (UnitType.MEMBER.getType().equals(unitType)) { + infos = infos.stream().filter(WidgetInfo::getNodePrivate).toList(); + } + if (UnitType.TEAM.getType().equals(unitType)) { + infos = infos.stream().filter(i -> !i.getNodePrivate()).toList(); + } return ResponseData.success(infos); } @@ -265,7 +275,7 @@ public ResponseData createWidget( NodePermission.MANAGE_NODE, status -> ExceptionUtil.isTrue(status, NODE_OPERATION_DENIED)); // Check the number of running installations - iWidgetService.checkWidgetOverLimit(spaceId); + iSpaceService.checkWidgetOverLimit(spaceId); // create widget String widgetId = iWidgetService.create(userId, spaceId, widget); return ResponseData.success(iWidgetService.getWidgetPack(widgetId)); @@ -292,7 +302,7 @@ public ResponseData> copyWidget( NodePermission.MANAGE_NODE, status -> ExceptionUtil.isTrue(status, NODE_OPERATION_DENIED)); // Check the number of running installations - iWidgetService.checkWidgetOverLimit(spaceId); + iSpaceService.checkWidgetOverLimit(spaceId); // copy widget Collection widgetIds = iWidgetService.copyWidget(userId, spaceId, nodeId, widgetRo.getWidgetIds()); diff --git a/backend-server/application/src/main/java/com/apitable/widget/mapper/WidgetMapper.java b/backend-server/application/src/main/java/com/apitable/widget/mapper/WidgetMapper.java index e48d06b5c9..90468d2d58 100644 --- a/backend-server/application/src/main/java/com/apitable/widget/mapper/WidgetMapper.java +++ b/backend-server/application/src/main/java/com/apitable/widget/mapper/WidgetMapper.java @@ -133,4 +133,12 @@ List selectInfoBySpaceIdAndNodeType(@Param("spaceId") String spaceId * @return count */ Long selectCountBySpaceId(@Param("spaceId") String spaceId); + + /** + * select node id by widget ids. + * + * @param widgetIds widget id list + * @return list of node ids + */ + List selectNodeIdsByWidgetIds(@Param("widgetIds") List widgetIds); } diff --git a/backend-server/application/src/main/java/com/apitable/widget/service/IWidgetService.java b/backend-server/application/src/main/java/com/apitable/widget/service/IWidgetService.java index 67fa251b45..e1943293f9 100644 --- a/backend-server/application/src/main/java/com/apitable/widget/service/IWidgetService.java +++ b/backend-server/application/src/main/java/com/apitable/widget/service/IWidgetService.java @@ -139,9 +139,18 @@ void copyBatch(Long userId, String destSpaceId, Map newNodeMap, void checkWidgetReference(List subNodeIds, List widgetIds); /** - * check widget whether over limit. + * get widget resources. * - * @param spaceId space id + * @param widgetIds widget id list + * @return node ids + */ + List getWidgetNodeIds(List widgetIds); + + /** + * get node widgets. + * + * @param nodeIds node id. + * @return list of widget id */ - void checkWidgetOverLimit(String spaceId); + List getNodeWidgetIds(List nodeIds); } diff --git a/backend-server/application/src/main/java/com/apitable/widget/service/impl/WidgetServiceImpl.java b/backend-server/application/src/main/java/com/apitable/widget/service/impl/WidgetServiceImpl.java index 48f3ebd7f9..ee9e7c1214 100644 --- a/backend-server/application/src/main/java/com/apitable/widget/service/impl/WidgetServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/widget/service/impl/WidgetServiceImpl.java @@ -29,14 +29,10 @@ import com.apitable.core.exception.BusinessException; import com.apitable.core.util.ExceptionUtil; import com.apitable.core.util.SqlTool; -import com.apitable.interfaces.billing.facade.EntitlementServiceFacade; -import com.apitable.interfaces.billing.model.SubscriptionFeatures; -import com.apitable.interfaces.billing.model.SubscriptionInfo; import com.apitable.interfaces.widget.facade.WidgetServiceAuditFacade; import com.apitable.shared.component.TaskManager; import com.apitable.shared.config.properties.LimitProperties; import com.apitable.shared.context.LoginContext; -import com.apitable.shared.exception.LimitException; import com.apitable.shared.util.IdUtil; import com.apitable.template.enums.TemplateException; import com.apitable.widget.dto.NodeWidgetDto; @@ -128,9 +124,6 @@ public class WidgetServiceImpl implements IWidgetService { @Resource private ObjectMapper objectMapper; - @Resource - private EntitlementServiceFacade entitlementServiceFacade; - @Override public Long getSpaceWidgetCount(String spaceId) { return widgetMapper.selectCountBySpaceId(spaceId); @@ -493,20 +486,12 @@ public void checkWidgetReference(List subNodeIds, List widgetIds } @Override - public void checkWidgetOverLimit(String spaceId) { - // get subscription max widget nums - SubscriptionInfo subscriptionInfo = - entitlementServiceFacade.getSpaceSubscription(spaceId); - // Only the free version requires verification - if (!subscriptionInfo.isFree()) { - return; - } - SubscriptionFeatures.ConsumeFeatures.WidgetNums widgetNums = - subscriptionInfo.getFeature().getWidgetNums(); - // check the number of components in the space - Long count = this.getSpaceWidgetCount(spaceId); - if (!widgetNums.isUnlimited() && count >= widgetNums.getValue()) { - throw new BusinessException(LimitException.WIDGET_OVER_LIMIT); - } + public List getWidgetNodeIds(List widgetIds) { + return widgetMapper.selectNodeIdsByWidgetIds(widgetIds); + } + + @Override + public List getNodeWidgetIds(List nodeIds) { + return datasheetWidgetMapper.selectWidgetIdByDstIds(nodeIds); } } diff --git a/backend-server/application/src/main/java/com/apitable/widget/vo/WidgetInfo.java b/backend-server/application/src/main/java/com/apitable/widget/vo/WidgetInfo.java index c2ee8cea63..3cc7878420 100644 --- a/backend-server/application/src/main/java/com/apitable/widget/vo/WidgetInfo.java +++ b/backend-server/application/src/main/java/com/apitable/widget/vo/WidgetInfo.java @@ -19,6 +19,7 @@ package com.apitable.widget.vo; import com.apitable.shared.support.serializer.ImageSerializer; +import com.apitable.shared.support.serializer.NullBooleanSerializer; import com.apitable.shared.support.serializer.NullStringSerializer; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import io.swagger.v3.oas.annotations.media.Schema; @@ -61,4 +62,8 @@ public class WidgetInfo { @Schema(description = "Package Icon", example = "https://apitable.com/space/2020/12/23/aqa") @JsonSerialize(nullsUsing = NullStringSerializer.class, using = ImageSerializer.class) private String widgetPackageIcon; + + @Schema(description = "Whether it belongs to the private area") + @JsonSerialize(nullsUsing = NullBooleanSerializer.class) + private Boolean nodePrivate; } diff --git a/backend-server/application/src/main/java/com/apitable/widget/vo/WidgetReleaseListVo.java b/backend-server/application/src/main/java/com/apitable/widget/vo/WidgetReleaseListVo.java index 4d5fae4a35..7ef933d599 100644 --- a/backend-server/application/src/main/java/com/apitable/widget/vo/WidgetReleaseListVo.java +++ b/backend-server/application/src/main/java/com/apitable/widget/vo/WidgetReleaseListVo.java @@ -42,11 +42,11 @@ public class WidgetReleaseListVo { @Schema(description = "Status (0: to be approved, 1: approved, 2: rejected)", example = "1") private Integer status; - @Schema(description = "Code Address", example = "https://s1.vika.cn/code/2020/12/23/aqa") + @Schema(description = "Code Address", example = "https://aitable.ai/code/2020/12/23/aqa") @JsonSerialize(using = ImageSerializer.class) private String releaseCodeBundle; - @Schema(description = "Source code address", example = "https://s1.vika.cn/code/2020/12/23/aqa") + @Schema(description = "Source code address", example = "https://aitable.ai/code/2020/12/23/aqa") @JsonSerialize(using = ImageSerializer.class) private String sourceCodeBundle; diff --git a/backend-server/application/src/main/java/com/apitable/workspace/controller/NodeController.java b/backend-server/application/src/main/java/com/apitable/workspace/controller/NodeController.java index 6cffa84c6a..b78f314bfe 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/controller/NodeController.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/controller/NodeController.java @@ -19,9 +19,11 @@ package com.apitable.workspace.controller; import static com.apitable.workspace.enums.NodeException.DUPLICATE_NODE_NAME; +import static com.apitable.workspace.enums.PermissionException.NODE_ACCESS_DENIED; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.ListUtil; +import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; @@ -40,6 +42,7 @@ import com.apitable.core.util.SpringContextHolder; import com.apitable.core.util.SqlTool; import com.apitable.organization.dto.MemberDTO; +import com.apitable.organization.enums.UnitType; import com.apitable.organization.mapper.MemberMapper; import com.apitable.organization.service.IMemberService; import com.apitable.organization.service.IUnitService; @@ -63,10 +66,12 @@ import com.apitable.shared.holder.SpaceHolder; import com.apitable.shared.listener.event.AuditSpaceEvent; import com.apitable.shared.listener.event.AuditSpaceEvent.AuditSpaceArg; +import com.apitable.shared.util.IdUtil; import com.apitable.shared.util.information.ClientOriginInfo; import com.apitable.shared.util.information.InformationUtil; import com.apitable.space.enums.AuditSpaceAction; import com.apitable.space.enums.SpaceException; +import com.apitable.template.service.ITemplateService; import com.apitable.user.mapper.UserMapper; import com.apitable.workspace.dto.NodeCopyEffectDTO; import com.apitable.workspace.entity.NodeEntity; @@ -119,6 +124,7 @@ import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; +import java.util.stream.Stream; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.IOUtils; import org.springframework.validation.annotation.Validated; @@ -188,6 +194,12 @@ public class NodeController { @Resource private UserActiveSpaceCacheService userActiveSpaceCacheService; + @Resource + private ITemplateService iTemplateService; + + @Resource + private IUnitService iUnitService; + private static final String ROLE_DESC = "
Role Type:
" + "1.owner can add, edit, move, sort, delete, copy folders in the specified working " + "directory。
" @@ -209,15 +221,24 @@ public class NodeController { @Parameter(name = "className", description = "highlight style", schema = @Schema(type = "string"), in = ParameterIn.QUERY, example = "highLight"), @Parameter(name = "keyword", description = "keyword", required = true, - schema = @Schema(type = "string"), in = ParameterIn.QUERY, example = "datasheet") + schema = @Schema(type = "string"), in = ParameterIn.QUERY, example = "datasheet"), + @Parameter(name = "unitType", description = "unitType, 1: team, 3: member(private)", + in = ParameterIn.QUERY, schema = @Schema(type = "integer"), example = "1"), }) public ResponseData> searchNode( @RequestParam(name = "keyword") String keyword, @RequestParam(value = "className", required = false, defaultValue = "keyword") - String className) { + String className, + @RequestParam(name = "unitType", required = false) Integer unitType) { String spaceId = LoginContext.me().getSpaceId(); Long memberId = LoginContext.me().getMemberId(); List nodeInfos = iNodeService.searchNode(spaceId, memberId, keyword); + if (UnitType.TEAM.getType().equals(unitType)) { + nodeInfos = nodeInfos.stream().filter(i -> !i.getNodePrivate()).toList(); + } + if (UnitType.MEMBER.getType().equals(unitType)) { + nodeInfos = nodeInfos.stream().filter(NodeInfoVo::getNodePrivate).toList(); + } nodeInfos.forEach(info -> info.setNodeName( InformationUtil.keywordHighlight(info.getNodeName(), keyword, className))); return ResponseData.success(nodeInfos); @@ -234,14 +255,21 @@ public ResponseData> searchNode( schema = @Schema(type = "string"), in = ParameterIn.HEADER, example = "spcyQkKp9XJEl"), @Parameter(name = "depth", in = ParameterIn.QUERY, description = "tree depth, we can specify the query depth, maximum 2 layers depth.", - schema = @Schema(type = "integer"), example = "2") + schema = @Schema(type = "integer"), example = "2"), + @Parameter(name = "unitType", in = ParameterIn.QUERY, + description = "unitType, 1: team, 3: member(private)", + schema = @Schema(type = "integer"), example = "3"), }) public ResponseData getTree( - @RequestParam(name = "depth", defaultValue = "2") @Valid @Min(0) @Max(2) Integer depth) { + @RequestParam(name = "depth", defaultValue = "2") @Valid @Min(0) @Max(2) Integer depth, + @RequestParam(name = "unitType", required = false) Integer unitType) { String spaceId = LoginContext.me().getSpaceId(); Long memberId = LoginContext.me().getMemberId(); String rootNodeId = iNodeService.getRootNodeIdBySpaceId(spaceId); - NodeInfoTreeVo tree = iNodeService.getNodeTree(spaceId, rootNodeId, memberId, depth); + NodeInfoTreeVo tree = + null != unitType ? iNodeService.getNodeTree(spaceId, rootNodeId, memberId, depth, + UnitType.toEnum(unitType)) : + iNodeService.getNodeTree(spaceId, rootNodeId, memberId, depth); return ResponseData.success(tree); } @@ -419,11 +447,15 @@ public ResponseData> getParentNodes( @Parameter(name = "nodeId", description = "node id", required = true, schema = @Schema(type = "string"), in = ParameterIn.QUERY, example = "nodRTGSy43DJ9"), @Parameter(name = "nodeType", description = "node type 1:folder,2:datasheet", - schema = @Schema(type = "integer"), in = ParameterIn.QUERY, example = "1") + schema = @Schema(type = "integer"), in = ParameterIn.QUERY, example = "1"), + @Parameter(name = "unitType", in = ParameterIn.QUERY, + description = "unitType, 3: member(private)", + schema = @Schema(type = "integer"), example = "3") }) public ResponseData> getNodeChildrenList( @RequestParam(name = "nodeId") String nodeId, - @RequestParam(name = "nodeType", required = false) Integer nodeType) { + @RequestParam(name = "nodeType", required = false) Integer nodeType, + @RequestParam(name = "unitType", required = false) Integer unitType) { // get the space ID, the method includes judging whether the node exists String spaceId = iNodeService.getSpaceIdByNodeId(nodeId); NodeType nodeTypeEnum = null; @@ -434,6 +466,15 @@ public ResponseData> getNodeChildrenList( Long memberId = LoginContext.me().getUserSpaceDto(spaceId).getMemberId(); List nodeInfos = iNodeService.getChildNodesByNodeId(spaceId, memberId, nodeId, nodeTypeEnum); + nodeInfos = nodeInfos.stream() + .filter(i -> { + if (UnitType.MEMBER.getType().equals(unitType)) { + return i.getNodePrivate(); + } else { + return !i.getNodePrivate(); + } + }) + .collect(Collectors.toList()); return ResponseData.success(nodeInfos); } @@ -452,6 +493,8 @@ public ResponseData position(@PathVariable("nodeId") String node // check node permissions controlTemplate.checkNodePermission(memberId, nodeId, NodePermission.READ_NODE, status -> ExceptionUtil.isTrue(status, PermissionException.NODE_OPERATION_DENIED)); + Long userId = SessionContext.getUserId(); + ExceptionUtil.isTrue(iNodeService.privateNodeOperation(userId, nodeId), NODE_ACCESS_DENIED); NodeInfoTreeVo treeVo = iNodeService.position(spaceId, memberId, nodeId); return ResponseData.success(treeVo); } @@ -481,7 +524,7 @@ public ResponseData create(@RequestBody @Valid NodeOpRo nodeOpRo) { // Check whether the source tables of form and mirror exist and whether they have the // specified operation permissions. iNodeService.checkSourceDatasheet(spaceId, memberId, nodeOpRo.getType(), - nodeOpRo.getExtra()); + nodeOpRo.getUnitId(), nodeOpRo.getExtra()); if (Boolean.TRUE.equals(nodeOpRo.getCheckDuplicateName()) && StrUtil.isNotBlank(nodeOpRo.getNodeName())) { Optional nodeOptional = iNodeService.findSameNameInSameLevel( @@ -493,6 +536,7 @@ public ResponseData create(@RequestBody @Valid NodeOpRo nodeOpRo) { role)); } } + iUnitService.checkUnit(memberId, nodeOpRo.getUnitId()); String nodeId = iNodeService.createNode(userId, spaceId, nodeOpRo); // publish space audit events ClientOriginInfo clientOriginInfo = InformationUtil @@ -525,16 +569,21 @@ public ResponseData update(@PathVariable("nodeId") String nodeId, @RequestBody @Valid NodeUpdateOpRo nodeOpRo) { ExceptionUtil.isTrue( StrUtil.isNotBlank(nodeOpRo.getNodeName()) || ObjectUtil.isNotNull(nodeOpRo.getIcon()) - || ObjectUtil.isNotNull(nodeOpRo.getCover()) || ObjectUtil.isNotNull( - nodeOpRo.getShowRecordHistory()), ParameterException.NO_ARG); + || ObjectUtil.isNotNull(nodeOpRo.getCover()) + || ObjectUtil.isNotNull(nodeOpRo.getShowRecordHistory()) + || ObjectUtil.isNotNull(nodeOpRo.getEmbedPage()), ParameterException.NO_ARG); Long userId = SessionContext.getUserId(); // The method includes determining whether a node exists. String spaceId = iNodeService.getSpaceIdByNodeId(nodeId); SpaceHolder.set(spaceId); // The method includes determining whether the user is in this space. Long memberId = LoginContext.me().getMemberId(userId, spaceId); + NodePermission nodePermission = + NodeType.CUSTOM_PAGE.equals(iNodeService.getTypeByNodeId(nodeId)) + ? NodePermission.EDIT_CELL + : NodePermission.MANAGE_NODE; // check whether the node has the specified operation permission - controlTemplate.checkNodePermission(memberId, nodeId, NodePermission.MANAGE_NODE, + controlTemplate.checkNodePermission(memberId, nodeId, nodePermission, status -> ExceptionUtil.isTrue(status, PermissionException.NODE_OPERATION_DENIED)); iNodeService.edit(userId, nodeId, nodeOpRo); return ResponseData.success( @@ -615,8 +664,19 @@ public ResponseData> move(@RequestBody @Valid NodeMoveOpRo node status -> ExceptionUtil.isTrue(status, PermissionException.NODE_OPERATION_DENIED)); } Long userId = SessionContext.getUserId(); + // if node is private check foreign link + if (iNodeService.nodePrivate(nodeOpRo.getNodeId()) && null == nodeOpRo.getUnitId()) { + iNodeService.linkByOutsideResource(nodeOpRo.getNodeId()); + iTemplateService.checkTemplateForeignNode(memberId, nodeOpRo.getNodeId()); + } List nodeIds = iNodeService.move(userId, nodeOpRo); - return ResponseData.success(iNodeService.getNodeInfoByNodeIds(spaceId, memberId, nodeIds)); + List nodes = iNodeService.getNodeInfoByNodeIds(spaceId, memberId, nodeIds); + if (null != nodeOpRo.getUnitId()) { + nodes = nodes.stream().filter(NodeInfoVo::getNodePrivate).toList(); + } else { + nodes = nodes.stream().filter(i -> !i.getNodePrivate()).toList(); + } + return ResponseData.success(nodes); } /** @@ -750,8 +810,9 @@ public ResponseData analyzeBundle(@Valid NodeBundleOpRo opRo) { if (StrUtil.isBlank(parentId) && StrUtil.isBlank(opRo.getPreNodeId())) { parentId = iNodeService.getRootNodeIdBySpaceId(spaceId); } + iUnitService.checkUnit(memberId, opRo.getUnitId()); nodeBundleService.analyze(opRo.getFile(), opRo.getPassword(), parentId, opRo.getPreNodeId(), - userId); + userId, NumberUtil.parseLong(opRo.getUnitId())); return ResponseData.success(); } @@ -786,13 +847,14 @@ public ResponseData importExcel(@Valid ImportExcelOpRo data) throws } mainName = iNodeService.duplicateNameModify(data.getParentId(), NodeType.DATASHEET.getNodeType(), - mainName, null); + mainName, null, NumberUtil.parseLong(data.getUnitId())); // file type suffix String fileSuffix = cn.hutool.core.io.FileUtil.extName(data.getFile().getOriginalFilename()); if (StrUtil.isBlank(fileSuffix)) { throw new BusinessException("file name suffix must not be empty"); } + iUnitService.checkUnit(memberId, data.getUnitId()); String createNodeId; if (FileSuffixConstants.CSV.equals(fileSuffix)) { // identification file code @@ -803,12 +865,15 @@ public ResponseData importExcel(@Valid ImportExcelOpRo data) throws IOUtils.toString(data.getFile().getInputStream(), encoding).getBytes()); createNodeId = iNodeService.parseCsv(userId, uuid, spaceId, memberId, data.getParentId(), - data.getViewName(), mainName, targetInputStream); + NumberUtil.parseLong(data.getUnitId()), data.getViewName(), mainName, + targetInputStream); } else if (fileSuffix.equals(FileSuffixConstants.XLS) || fileSuffix.equals(FileSuffixConstants.XLSX)) { createNodeId = iNodeService.parseExcel(userId, uuid, spaceId, memberId, data.getParentId(), - data.getViewName(), mainName, fileSuffix, data.getFile().getInputStream()); + NumberUtil.parseLong(data.getUnitId()), data.getViewName(), mainName, + fileSuffix, + data.getFile().getInputStream()); } else { throw new BusinessException(ActionException.FILE_ERROR_FORMAT); } @@ -867,9 +932,14 @@ public ResponseData remind(@RequestBody @Valid RemindMemberRo ro) { LoginContext.me().getUserSpaceDto(spaceId); } else { // node sharing - String shareSpaceId = nodeShareSettingMapper.selectSpaceIdByShareId(ro.getLinkId()); - ExceptionUtil.isNotNull(shareSpaceId, NodeException.SHARE_EXPIRE); - ExceptionUtil.isTrue(shareSpaceId.equals(spaceId), SpaceException.NOT_IN_SPACE); + if (!IdUtil.isEmbed(ro.getLinkId())) { + String shareSpaceId = nodeShareSettingMapper.selectSpaceIdByShareId(ro.getLinkId()); + ExceptionUtil.isNotNull(shareSpaceId, NodeException.SHARE_EXPIRE); + ExceptionUtil.isTrue(shareSpaceId.equals(spaceId), SpaceException.NOT_IN_SPACE); + } + } + if (iNodeService.nodePrivate(ro.getNodeId())) { + return ResponseData.success(); } datasheetService.remindMemberRecOp(userId, spaceId, ro); return ResponseData.success(); @@ -969,4 +1039,21 @@ public ResponseData> recentList() { return ResponseData.success(nodeInfos); } + + /** + * get node description. + */ + @GetResource(path = "/{nodeId}/description", requiredPermission = false) + @Operation(summary = "Get node description") + @Parameter(name = "nodeId", description = "node id", required = true, + schema = @Schema(type = "string"), in = ParameterIn.PATH, example = "nodRTGSy43DJ9") + public ResponseData getNodeDescription(@PathVariable("nodeId") String nodeId) { + // The method includes determining whether a node exists. + String desc = + iNodeDescService.getNodeIdToDescMap(Stream.of(nodeId).toList()) + .getOrDefault(nodeId, ""); + + return ResponseData.success(desc); + } + } diff --git a/backend-server/application/src/main/java/com/apitable/workspace/dto/CreateNodeDto.java b/backend-server/application/src/main/java/com/apitable/workspace/dto/CreateNodeDto.java index ebed5ce196..0bee99b05b 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/dto/CreateNodeDto.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/dto/CreateNodeDto.java @@ -49,4 +49,6 @@ public class CreateNodeDto { private String cover; private String extra; + + private Long unitId; } diff --git a/backend-server/application/src/main/java/com/apitable/organization/dto/SpaceMemberIdDTO.java b/backend-server/application/src/main/java/com/apitable/workspace/dto/DatasheetMetaColumnDTO.java similarity index 83% rename from backend-server/application/src/main/java/com/apitable/organization/dto/SpaceMemberIdDTO.java rename to backend-server/application/src/main/java/com/apitable/workspace/dto/DatasheetMetaColumnDTO.java index 0e6cef6117..49a3c27c52 100644 --- a/backend-server/application/src/main/java/com/apitable/organization/dto/SpaceMemberIdDTO.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/dto/DatasheetMetaColumnDTO.java @@ -16,17 +16,17 @@ * along with this program. If not, see . */ -package com.apitable.organization.dto; +package com.apitable.workspace.dto; import lombok.Data; /** - * space member id dto. + * Datasheet Meta Column DTO. */ @Data -public class SpaceMemberIdDTO { +public class DatasheetMetaColumnDTO { - private Long id; + private String dstId; - private String spaceId; + private Integer mdFieldMapSize; } diff --git a/backend-server/application/src/main/java/com/apitable/workspace/dto/NodeCopyOptions.java b/backend-server/application/src/main/java/com/apitable/workspace/dto/NodeCopyOptions.java index 2cff9b1c2e..62f1eab33f 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/dto/NodeCopyOptions.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/dto/NodeCopyOptions.java @@ -104,6 +104,11 @@ public class NodeCopyOptions implements Serializable { */ private Map newTriggerMap = new HashMap<>(); + /** + * unit id. + */ + private String unitId; + public NodeCopyOptions() { this.copyData = true; } diff --git a/backend-server/application/src/main/java/com/apitable/workspace/dto/NodeShareDTO.java b/backend-server/application/src/main/java/com/apitable/workspace/dto/NodeShareDTO.java index 086811f4e4..d9dcf10c68 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/dto/NodeShareDTO.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/dto/NodeShareDTO.java @@ -33,4 +33,6 @@ public class NodeShareDTO { private String spaceId; private Long operator; + + private Boolean isEnabled; } diff --git a/packages/datasheet/src/pc/components/calendar_view/utils.ts b/backend-server/application/src/main/java/com/apitable/workspace/dto/NodeStatisticsDTO.java similarity index 70% rename from packages/datasheet/src/pc/components/calendar_view/utils.ts rename to backend-server/application/src/main/java/com/apitable/workspace/dto/NodeStatisticsDTO.java index 2e9feb3ee8..0141a5923e 100644 --- a/packages/datasheet/src/pc/components/calendar_view/utils.ts +++ b/backend-server/application/src/main/java/com/apitable/workspace/dto/NodeStatisticsDTO.java @@ -1,4 +1,4 @@ -/** +/* * APITable * Copyright (C) 2022 APITable Ltd. * @@ -16,10 +16,23 @@ * along with this program. If not, see . */ -export const formatString2Date = (value: string) => { - const str = value.replace(/年| /, '-').replace(/月/, ''); - const parts = str.split('-'); - const year = parts[0]; - const month = parts[1].padStart(2, '0'); - return `${year}-${month}`; -}; +package com.apitable.workspace.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * node statistics dto. + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class NodeStatisticsDTO { + + private Integer nodeCount; + + private Long createdBy; + + private Long unitId; +} diff --git a/backend-server/application/src/main/java/com/apitable/workspace/entity/DatasheetRecordAlarmEntity.java b/backend-server/application/src/main/java/com/apitable/workspace/entity/DatasheetRecordAlarmEntity.java index f31ee5b1ad..0b57d0768e 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/entity/DatasheetRecordAlarmEntity.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/entity/DatasheetRecordAlarmEntity.java @@ -72,6 +72,11 @@ public class DatasheetRecordAlarmEntity implements Serializable { */ private String dstId; + /** + * Resource ID(link#node#node_id). + */ + private String resourceId; + /** * Record ID(link#datasheet_record#record_id). */ diff --git a/backend-server/application/src/main/java/com/apitable/workspace/entity/NodeEntity.java b/backend-server/application/src/main/java/com/apitable/workspace/entity/NodeEntity.java index 56e23ca459..bc01adcdc3 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/entity/NodeEntity.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/entity/NodeEntity.java @@ -62,6 +62,11 @@ public class NodeEntity implements Serializable { */ private String spaceId; + /** + * unit id(link#xxxx_unit#id). + */ + private Long unitId; + /** * Parent Node Id. */ diff --git a/backend-server/application/src/main/java/com/apitable/workspace/enums/IdRulePrefixEnum.java b/backend-server/application/src/main/java/com/apitable/workspace/enums/IdRulePrefixEnum.java index 395f35b20e..afa82b50d0 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/enums/IdRulePrefixEnum.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/enums/IdRulePrefixEnum.java @@ -81,6 +81,7 @@ public enum IdRulePrefixEnum { AIRAGENT("ag_"), + CUSTOM_PAGE("cup"), ; diff --git a/backend-server/application/src/main/java/com/apitable/workspace/enums/NodeType.java b/backend-server/application/src/main/java/com/apitable/workspace/enums/NodeType.java index b24d3115fd..d05e53b521 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/enums/NodeType.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/enums/NodeType.java @@ -83,6 +83,11 @@ public enum NodeType { */ AIRAGENT(11), + /** + * custom page. + */ + CUSTOM_PAGE(12), + /** * static resource file. */ diff --git a/backend-server/application/src/main/java/com/apitable/workspace/listener/CsvReadListener.java b/backend-server/application/src/main/java/com/apitable/workspace/listener/CsvReadListener.java index ac512d7e0c..79899e15de 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/listener/CsvReadListener.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/listener/CsvReadListener.java @@ -87,6 +87,8 @@ public class CsvReadListener extends AnalysisEventListener> private final String fileName; + private final Long unitId; + /** * constructor. * @@ -98,9 +100,10 @@ public class CsvReadListener extends AnalysisEventListener> * @param parentNodeId parent node id * @param viewName view name * @param fileName file name + * @param unitId unit id */ - public CsvReadListener(INodeService nodeService, Long userId, String uuid, - String spaceId, Long memberId, String parentNodeId, String viewName, + public CsvReadListener(INodeService nodeService, Long userId, String uuid, String spaceId, + Long memberId, String parentNodeId, Long unitId, String viewName, String fileName) { this.iNodeService = nodeService; this.userId = userId; @@ -109,7 +112,7 @@ public CsvReadListener(INodeService nodeService, Long userId, String uuid, this.parentNodeId = parentNodeId; this.viewName = viewName; this.fileName = fileName; - + this.unitId = unitId; this.retNodeId = IdUtil.createDstId(); fieldUpdatedInfo.set("createdAt", @@ -266,6 +269,7 @@ public void doAfterAllAnalysed(AnalysisContext context) { .nodeName(fileName) .type(NodeType.DATASHEET.getNodeType()) .isTemplate(false) + .unitId(unitId) .creator(memberId) .createdBy(userId) .updatedBy(userId).build()); diff --git a/backend-server/application/src/main/java/com/apitable/workspace/listener/MultiSheetReadListener.java b/backend-server/application/src/main/java/com/apitable/workspace/listener/MultiSheetReadListener.java index 267d0d9f15..024df79214 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/listener/MultiSheetReadListener.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/listener/MultiSheetReadListener.java @@ -98,6 +98,8 @@ public class MultiSheetReadListener extends AnalysisEventListener readSheetList) { .isTemplate(false) .creator(memberId) .createdBy(userId) + .unitId(unitId) .updatedBy(userId).build()); } @@ -378,6 +382,7 @@ private void saveData(List readSheetList) { .isTemplate(false) .creator(memberId) .createdBy(userId) + .unitId(unitId) .updatedBy(userId).build()); DatasheetEntity datasheet = DatasheetEntity.builder() diff --git a/backend-server/application/src/main/java/com/apitable/workspace/mapper/DatasheetMetaMapper.java b/backend-server/application/src/main/java/com/apitable/workspace/mapper/DatasheetMetaMapper.java index 66f7656f61..8a233999f2 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/mapper/DatasheetMetaMapper.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/mapper/DatasheetMetaMapper.java @@ -19,6 +19,7 @@ package com.apitable.workspace.mapper; import com.apitable.internal.dto.SimpleDatasheetMetaDTO; +import com.apitable.workspace.dto.DatasheetMetaColumnDTO; import com.apitable.workspace.dto.DatasheetMetaDTO; import com.apitable.workspace.dto.DatasheetSnapshot; import com.apitable.workspace.entity.DatasheetMetaEntity; @@ -57,7 +58,15 @@ public interface DatasheetMetaMapper extends BaseMapper { SimpleDatasheetMetaDTO selectByNodeId(@Param("dstId") String dstId); /** - * quert DTO by datasheet ids. + * query meta column DTO. + * + * @param dstIds datasheet ids + * @return DatasheetMetaColumnDTO + */ + List selectMetaColumnDtoByDstIds(@Param("dstIds") Collection dstIds); + + /** + * query DTO by datasheet ids. * * @param dstIdList datasheet ids * @return DatasheetMetaDTO diff --git a/backend-server/application/src/main/java/com/apitable/workspace/mapper/DatasheetWidgetMapper.java b/backend-server/application/src/main/java/com/apitable/workspace/mapper/DatasheetWidgetMapper.java index 4d94dd3dc5..a6370c3989 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/mapper/DatasheetWidgetMapper.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/mapper/DatasheetWidgetMapper.java @@ -61,4 +61,12 @@ public interface DatasheetWidgetMapper extends BaseMapper * @return affected rows */ int insertBatch(@Param("entities") List entities); + + /** + * query by dst id. + * + * @param dstIds dst id + * @return list of widget id + */ + List selectWidgetIdByDstIds(@Param("dstIds") List dstIds); } diff --git a/backend-server/application/src/main/java/com/apitable/workspace/mapper/NodeMapper.java b/backend-server/application/src/main/java/com/apitable/workspace/mapper/NodeMapper.java index 9c3dc72eae..afc69bf24b 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/mapper/NodeMapper.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/mapper/NodeMapper.java @@ -19,6 +19,7 @@ package com.apitable.workspace.mapper; import com.apitable.workspace.dto.NodeBaseInfoDTO; +import com.apitable.workspace.dto.NodeStatisticsDTO; import com.apitable.workspace.dto.NodeTreeDTO; import com.apitable.workspace.dto.SimpleNodeInfo; import com.apitable.workspace.dto.UrlNodeInfoDTO; @@ -30,6 +31,8 @@ import com.apitable.workspace.vo.NodeShareTree; import com.apitable.workspace.vo.RubbishNodeVo; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import java.time.LocalDateTime; import java.util.Collection; import java.util.List; @@ -114,20 +117,25 @@ List selectNodeIdsBySpaceIdAndTypeAndKeyword(@Param("spaceId") String sp * Query first node id. * * @param parentId parent id + * @param preNodeId pre node id + * @param unitId unit id * @return node id * @author Chambers */ - String selectNodeIdByParentIdAndPreNodeId(@Param("parentId") String parentId, - @Param("preNodeId") String preNodeId); + String selectNodeIdByParentIdAndPreNodeIdAndUnitId(@Param("parentId") String parentId, + @Param("preNodeId") String preNodeId, + @Param("unitId") Long unitId); /** * Fuzzy search node, return node ID the root node cannot be searched. * * @param spaceId space id + * @param unitIds unit id * @param likeName keyword * @return node ids */ List selectLikeNodeName(@Param("spaceId") String spaceId, + @Param("unitIds") List unitIds, @Param("likeName") String likeName); /** @@ -147,6 +155,7 @@ List selectNodeIdBySpaceIdAndNodeNameLikeIncludeDeleted( * @param memberId member id * @return NodeInfoVos */ + @Deprecated List selectNodeInfoByNodeIds(@Param("nodeIds") Collection nodeIds, @Param("memberId") Long memberId); @@ -157,6 +166,7 @@ List selectNodeInfoByNodeIds(@Param("nodeIds") Collection no * @param memberId member id * @return NodeInfoTreeVo */ + @Deprecated List selectNodeInfoTreeByNodeIds(@Param("nodeIds") Collection nodeIds, @Param("memberId") Long memberId); @@ -207,10 +217,20 @@ List selectNodeInfo(@Param("nodeIds") Collection nodeIds, * * @param parentIds parent node ids * @param isRubbish rubbish status + * @param unitIds unit ids * @return List of NodeTreeDTO */ List selectNodeTreeDTOByParentIdIn( - @Param("parentIds") Collection parentIds, @Param("isRubbish") Boolean isRubbish); + @Param("parentIds") Collection parentIds, @Param("isRubbish") Boolean isRubbish, + @Param("unitIds") List unitIds); + + /** + * Query parent id with children nodes. + * + * @param parentIds parent node ids + * @return parent node ids + */ + List selectParentIdWithChildren(@Param("parentIds") Collection parentIds); /** * Query the ID of the direct child node. @@ -242,11 +262,13 @@ List selectNodeTreeDTOByParentIdIn( * @param parentId parent node id * @param nodeType node type * @param nodeId retired nodes (itself when modified) + * @param unitId unit id * @return node names */ List selectNameList(@Param("parentId") String parentId, @Param("nodeType") Integer nodeType, - @Param("nodeId") String nodeId); + @Param("nodeId") String nodeId, + @Param("unitId") Long unitId); /** * Query the number of non-root nodes and non-logically deleted nodes. @@ -264,6 +286,15 @@ List selectNameList(@Param("parentId") String parentId, */ String selectSpaceIdByNodeId(@Param("nodeId") String nodeId); + + /** + * query space id. + * + * @param nodeId node id + * @return space id + */ + NodeEntity selectSpaceIdAndUnitIdByNodeId(@Param("nodeId") String nodeId); + /** * query space id list. * @@ -529,15 +560,25 @@ List selectRubbishNodeInfo(@Param("spaceId") String spaceId, int updateExtraShowRecordHistoryByNodeId(@Param("nodeId") String nodeId, @Param("showRecordHistory") int showRecordHistory); + /** * update node extra. * * @param nodeId node id - * @param extra node's extra + * @param extra embed page * @return affected rows */ int updateExtraByNodeId(@Param("nodeId") String nodeId, @Param("extra") String extra); + /** + * update node extra. + * + * @param nodeId node id + * @param extra node's extra + * @return affected rows + */ + int insertExtraByNodeId(@Param("nodeId") String nodeId, @Param("extra") String extra); + /** * modify node --The DingTalk status of the template transfer. * @@ -613,4 +654,49 @@ String selectNodeIdByParentIdAndNodeName(@Param("parentId") String parentId, * @return NodeEntity List */ List selectByParentId(@Param("parentId") String parentId); + + /** + * update is deleted. + * + * @param unitIds unit id list + * @return affected rows + */ + int updateIsDeletedByUnitIds(@Param("unitIds") List unitIds, + @Param("isDeleted") boolean isDeleted); + + /** + * query count by space id. + * + * @param spaceId space id + * @param page page + * @return IPage NodeStatisticsDTO + */ + IPage selectCountBySpaceIdWithPage(@Param("spaceId") String spaceId, + Page page); + + /** + * query count by unitRefIds. + * + * @param unitIds unit id list + * @return List NodeStatisticsDTO + */ + List selectCountByUnitIds(@Param("unitIds") List unitIds); + + /** + * query unitId. + * + * @param nodeId node id + * @return unit id + */ + Long selectUnitIdByNodeId(@Param("nodeId") String nodeId); + + /** + * update unit id. + * + * @param nodeIds node id + * @param unitId unit id + * @return rows + */ + int updateUnitIdByNodeIds(@Param("nodeIds") List nodeIds, @Param("unitId") Long unitId); + } diff --git a/backend-server/application/src/main/java/com/apitable/workspace/mapper/NodeRelMapper.java b/backend-server/application/src/main/java/com/apitable/workspace/mapper/NodeRelMapper.java index fa0f52ffd8..687b0a07e9 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/mapper/NodeRelMapper.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/mapper/NodeRelMapper.java @@ -69,4 +69,12 @@ public interface NodeRelMapper extends BaseMapper { * @return affected rows */ int insertBatch(@Param("entities") List entities); + + /** + * get count by main node id. + * + * @param mainNodeIds main node id + * @return total amount + */ + List selectRelNodeIdsByMainNodeIds(@Param("mainNodeIds") List mainNodeIds); } diff --git a/backend-server/application/src/main/java/com/apitable/workspace/mapper/NodeShareSettingMapper.java b/backend-server/application/src/main/java/com/apitable/workspace/mapper/NodeShareSettingMapper.java index ddfde95fa9..103f1e8311 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/mapper/NodeShareSettingMapper.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/mapper/NodeShareSettingMapper.java @@ -21,6 +21,7 @@ import com.apitable.workspace.dto.NodeShareDTO; import com.apitable.workspace.entity.NodeShareSettingEntity; import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import java.util.Collection; import java.util.List; import org.apache.ibatis.annotations.Param; @@ -107,7 +108,7 @@ public interface NodeShareSettingMapper extends BaseMapper selectDtoByNodeIds(@Param("nodeIds") List nodeIds); + List selectDtoByNodeIds(@Param("nodeIds") Collection nodeIds); /** * Find the list of shared node IDs last modified by the specified member. diff --git a/backend-server/application/src/main/java/com/apitable/workspace/ro/ImportExcelOpRo.java b/backend-server/application/src/main/java/com/apitable/workspace/ro/ImportExcelOpRo.java index e28a312561..339aa64d2c 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/ro/ImportExcelOpRo.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/ro/ImportExcelOpRo.java @@ -46,4 +46,7 @@ public class ImportExcelOpRo { @Schema(description = "View Name", example = "nod10") private String viewName; + + @Schema(description = "Unit id", example = "234566") + private String unitId; } diff --git a/backend-server/application/src/main/java/com/apitable/workspace/ro/NodeBundleOpRo.java b/backend-server/application/src/main/java/com/apitable/workspace/ro/NodeBundleOpRo.java index 3dcfab4e6e..13fd15b2fc 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/ro/NodeBundleOpRo.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/ro/NodeBundleOpRo.java @@ -44,4 +44,7 @@ public class NodeBundleOpRo { @Schema(description = "Password", example = "***") private String password; + + @Schema(description = "unit id", example = "111") + private String unitId; } diff --git a/backend-server/application/src/main/java/com/apitable/automation/model/AutomationServiceEditRO.java b/backend-server/application/src/main/java/com/apitable/workspace/ro/NodeEmbedPageRo.java similarity index 63% rename from backend-server/application/src/main/java/com/apitable/automation/model/AutomationServiceEditRO.java rename to backend-server/application/src/main/java/com/apitable/workspace/ro/NodeEmbedPageRo.java index 1373a3057f..c4910b5ae9 100644 --- a/backend-server/application/src/main/java/com/apitable/automation/model/AutomationServiceEditRO.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/ro/NodeEmbedPageRo.java @@ -16,31 +16,25 @@ * along with this program. If not, see . */ -package com.apitable.automation.model; +package com.apitable.workspace.ro; import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; import lombok.Data; +import lombok.NoArgsConstructor; /** - * Automation Service Edit RO. + * Node embed page parameters. */ @Data -@Schema(description = "Automation Service Edit RO") -public class AutomationServiceEditRO { +@NoArgsConstructor +@AllArgsConstructor +@Schema(description = "Node embed page parameters") +public class NodeEmbedPageRo { - @Schema(description = "name") - private String name; - - @Schema(description = "description") - private String description; - - @Schema(description = "input JSON format") - private String logo; - - @Schema(description = "output JSON format") - private String baseUrl; - - @Schema(description = "i18n package") - private String i18n; + @Schema(description = "url", requiredMode = Schema.RequiredMode.REQUIRED) + private String url; + @Schema(description = "Embed page type, figma et.") + private String type; } diff --git a/backend-server/application/src/main/java/com/apitable/workspace/ro/NodeMoveOpRo.java b/backend-server/application/src/main/java/com/apitable/workspace/ro/NodeMoveOpRo.java index dbcae32db5..606d12012b 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/ro/NodeMoveOpRo.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/ro/NodeMoveOpRo.java @@ -42,4 +42,7 @@ public class NodeMoveOpRo { @Schema(description = "The previous node of the target position moves to the first position " + "when it is empty", example = "nod10") private String preNodeId; + + @Schema(description = "unit id, if is null means move to space workspace") + private String unitId; } diff --git a/backend-server/application/src/main/java/com/apitable/workspace/ro/NodeOpRo.java b/backend-server/application/src/main/java/com/apitable/workspace/ro/NodeOpRo.java index da4af118a3..c73b5dc69d 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/ro/NodeOpRo.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/ro/NodeOpRo.java @@ -51,10 +51,10 @@ public class NodeOpRo { @Size(max = 100, message = "The name length cannot exceed 100 bits") private String nodeName; - @Schema(description = "Type. 1: folder; 2: DataSheet; 3: Form; 4: Dashboard; 5: Mirror, 10: Automation", example = "1", requiredMode = Schema.RequiredMode.REQUIRED) + @Schema(description = "Type. 1: folder; 2: DataSheet; 3: Form; 4: Dashboard; 5: Mirror, 10: Automation, 12: embed page, ", example = "1", requiredMode = Schema.RequiredMode.REQUIRED) @NotNull(message = "Type cannot be empty") @Min(value = 1, message = "Error in type") - @Max(value = 10, message = "Error in type") + @Max(value = 12, message = "Error in type") private Integer type; @Schema(description = "The previous node of the target position moves to the first position " @@ -67,6 +67,9 @@ public class NodeOpRo { @Schema(description = "Whether to detect duplicate node names", example = "true") private Boolean checkDuplicateName; + @Schema(description = "unit id", example = "1234567") + private String unitId; + /** * Get Node Name. */ @@ -76,7 +79,7 @@ public String getNodeName() { } NodeType nodeType = NodeType.toEnum(type); return switch (nodeType) { // The name of the magic form is transmitted from the front end - case FOLDER, DATASHEET, FORM, DASHBOARD, MIRROR, AI_CHAT_BOT, AUTOMATION -> + case FOLDER, DATASHEET, FORM, DASHBOARD, MIRROR, AI_CHAT_BOT, AUTOMATION, CUSTOM_PAGE -> // The image name is transmitted from the front end // default_create_'key' Configure in the strings table I18nStringsUtil.t("default_create_" + nodeType.name().toLowerCase()); diff --git a/backend-server/application/src/main/java/com/apitable/workspace/ro/NodeRelRo.java b/backend-server/application/src/main/java/com/apitable/workspace/ro/NodeRelRo.java index 898a96995e..2e707efe6f 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/ro/NodeRelRo.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/ro/NodeRelRo.java @@ -43,6 +43,9 @@ public class NodeRelRo { @Schema(description = "View Name") private String viewName; + @Schema(description = "Embed page info", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private NodeEmbedPageRo embedPage; + public NodeRelRo(String viewId) { this.viewId = viewId; } diff --git a/backend-server/application/src/main/java/com/apitable/workspace/ro/NodeUpdateOpRo.java b/backend-server/application/src/main/java/com/apitable/workspace/ro/NodeUpdateOpRo.java index 45856e2956..b6c1e0c91c 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/ro/NodeUpdateOpRo.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/ro/NodeUpdateOpRo.java @@ -43,4 +43,7 @@ public class NodeUpdateOpRo { @Schema(description = "Whether to display the recorded history", example = "1") @Range(min = 0, max = 1, message = "Display record history can only be 0/1") private Integer showRecordHistory; + + @Schema(description = "Embed page info", requiredMode = Schema.RequiredMode.NOT_REQUIRED) + private NodeEmbedPageRo embedPage; } diff --git a/backend-server/application/src/main/java/com/apitable/workspace/service/IDatasheetMetaService.java b/backend-server/application/src/main/java/com/apitable/workspace/service/IDatasheetMetaService.java index 190507d201..97fb7fd694 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/service/IDatasheetMetaService.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/service/IDatasheetMetaService.java @@ -19,12 +19,12 @@ package com.apitable.workspace.service; import com.apitable.internal.dto.SimpleDatasheetMetaDTO; +import com.apitable.workspace.dto.DatasheetMetaColumnDTO; import com.apitable.workspace.dto.DatasheetMetaDTO; import com.apitable.workspace.dto.DatasheetSnapshot; import com.apitable.workspace.entity.DatasheetMetaEntity; import com.apitable.workspace.ro.MetaOpRo; import java.util.List; -import org.apache.ibatis.annotations.Param; /** * datasheet meta service. @@ -46,13 +46,22 @@ public interface IDatasheetMetaService { */ SimpleDatasheetMetaDTO findByDstId(String dstId); + /** + * get meta column dto list. + * + * @param dstIds datasheet ids + * @return DatasheetMetaColumnDTO List + */ + List findMetaColumnDTOs(List dstIds); + + /** * get dto by datasheet id list. * * @param dstIds datasheet ids * @return DatasheetMetaDTO */ - List findMetaDtoByDstIds(@Param("list") List dstIds); + List findMetaDtoByDstIds(List dstIds); /** * create. diff --git a/backend-server/application/src/main/java/com/apitable/workspace/service/INodeRelService.java b/backend-server/application/src/main/java/com/apitable/workspace/service/INodeRelService.java index 7606ae0815..4a5839c081 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/service/INodeRelService.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/service/INodeRelService.java @@ -84,4 +84,12 @@ List getRelationNodeInfoByNodeId(String nodeId, String viewId, Long me * @return NodeRelEntity */ NodeRelEntity getByRelNodeId(String relNodeId); + + /** + * check the rel. + * + * @param mainNodeIds main node id + * @return boolean + */ + boolean relInTheSameFolder(List mainNodeIds); } diff --git a/backend-server/application/src/main/java/com/apitable/workspace/service/INodeService.java b/backend-server/application/src/main/java/com/apitable/workspace/service/INodeService.java index 55ce1f8ebc..34d6014411 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/service/INodeService.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/service/INodeService.java @@ -19,6 +19,7 @@ package com.apitable.workspace.service; import com.apitable.control.infrastructure.role.ControlRole; +import com.apitable.organization.enums.UnitType; import com.apitable.workspace.dto.CreateNodeDto; import com.apitable.workspace.dto.NodeBaseInfoDTO; import com.apitable.workspace.dto.NodeCopyEffectDTO; @@ -50,6 +51,7 @@ import java.io.InputStream; import java.util.Collection; import java.util.List; +import java.util.Map; import java.util.Optional; /** @@ -228,6 +230,17 @@ public interface INodeService extends IService { */ String checkNodeIfExist(String spaceId, String nodeId); + + /** + * whether node exist on the specific space. + * + * @param spaceId space id + * @param nodeId node id + * @param unitId unit id + * @return spaceId + */ + String checkNodeIfExist(String spaceId, String nodeId, String unitId); + /** * check the source table. * @@ -235,8 +248,11 @@ public interface INodeService extends IService { * @param memberId member id * @param type node type * @param extra node correlation parameters + * @param unitId unit id */ - void checkSourceDatasheet(String spaceId, Long memberId, Integer type, NodeRelRo extra); + void checkSourceDatasheet(String spaceId, Long memberId, Integer type, String unitId, + NodeRelRo extra + ); /** * get member id by user id and node id. @@ -268,6 +284,19 @@ public interface INodeService extends IService { */ NodeInfoTreeVo getNodeTree(String spaceId, String nodeId, Long memberId, int depth); + /** + * query node tree. + * + * @param spaceId space id + * @param memberId member id + * @param nodeId node id + * @param depth recursive depth, min 1 + * @param unitType unit type + * @return NodeInfoTreeVo + */ + NodeInfoTreeVo getNodeTree(String spaceId, String nodeId, Long memberId, int depth, + UnitType unitType); + /** * Get sub nodes. * @@ -293,10 +322,12 @@ public interface INodeService extends IService { * @param nodeId node id * @param depth recursive depth starting with 1 * @param isRubbish rubbish status + * @param unitIds list of unit ids * @return NodeInfoTreeVo * @author Chambers */ - List getNodeIdsInNodeTree(String nodeId, Integer depth, Boolean isRubbish); + List getNodeIdsInNodeTree(String nodeId, Integer depth, Boolean isRubbish, + List unitIds); /** * Sort node. @@ -369,6 +400,7 @@ List getChildNodesByNodeId(String spaceId, Long memberId, String nod */ String createNode(Long userId, String spaceId, NodeOpRo nodeOpRo); + /** * Create forms and add pictures (if needed). * @@ -469,9 +501,11 @@ String copyNodeToSpace(Long userId, String destSpaceId, String destParentId, * @param nodeType nodeType * @param nodeName original node name * @param nodeId eliminate nodes(when modifying itself) + * @param unitId unit id * @return modified name */ - String duplicateNameModify(String parentId, int nodeType, String nodeName, String nodeId); + String duplicateNameModify(String parentId, int nodeType, String nodeName, String nodeId, + Long unitId); /** * Verify the permissions of all child and descendant nodes. @@ -507,6 +541,7 @@ String copyNodeToSpace(Long userId, String destSpaceId, String destParentId, * @param spaceId space id * @param memberId member id * @param parentNodeId parentNodeId + * @param unitId unit id * @param viewName view name * @param fileName filename * @param fileSuffix file name suffix @@ -514,7 +549,8 @@ String copyNodeToSpace(Long userId, String destSpaceId, String destParentId, * @return node id */ String parseExcel(Long userId, String uuid, String spaceId, Long memberId, String parentNodeId, - String viewName, String fileName, String fileSuffix, InputStream inputStream); + Long unitId, String viewName, String fileName, String fileSuffix, + InputStream inputStream); /** * parse csv. @@ -524,13 +560,14 @@ String parseExcel(Long userId, String uuid, String spaceId, Long memberId, Strin * @param spaceId space id * @param memberId member id * @param parentNodeId parentNodeId + * @param unitId unit id * @param viewName view name * @param fileName file name * @param inputStream file * @return node id */ String parseCsv(Long userId, String uuid, String spaceId, Long memberId, String parentNodeId, - String viewName, String fileName, InputStream inputStream); + Long unitId, String viewName, String fileName, InputStream inputStream); /** * special batch save operation @@ -643,4 +680,65 @@ void batchCreateDataSheet(NodeData data, List nodeEntities, */ Optional findSameNameInSameLevel(String parentNodeId, String nodeName); + /** + * delete member's private node. + * + * @param unitIds unit id list + */ + void deleteMembersNodes(List unitIds); + + /** + * restore member's private node. + * + * @param unitIds unit id list + */ + void restoreMembersNodes(List unitIds); + + /** + * get units node count. + * + * @param unitIds unit id list + * @return Map String, Integer + */ + Map getCountByUnitIds(List unitIds); + + /** + * get unit id by node id. + * + * @param nodeId node id + * @return unit id + */ + Long getUnitIdByNodeId(String nodeId); + + /** + * check node is private. + * + * @param nodeId node id + * @return boolean + */ + boolean nodePrivate(String nodeId); + + /** + * whether the user can operate specified node. + * + * @param userId user id + * @param nodeId node id + * @return boolean + */ + boolean privateNodeOperation(Long userId, String nodeId); + + /** + * whether the node linked by outside widget. + * + * @param nodeIds node id node + * @return boolean + */ + boolean linkByOutsideWidgets(List nodeIds); + + /** + * whether the node linked by outside resource. + * + * @param nodeId node id node + */ + void linkByOutsideResource(String nodeId); } diff --git a/backend-server/application/src/main/java/com/apitable/workspace/service/NodeBundleService.java b/backend-server/application/src/main/java/com/apitable/workspace/service/NodeBundleService.java index c9189f368e..711b1d0b8f 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/service/NodeBundleService.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/service/NodeBundleService.java @@ -42,7 +42,8 @@ public interface NodeBundleService { * @param parentId parentId * @param preNodeId preNodeId * @param userId user id + * @param unitId unitId */ void analyze(MultipartFile file, String password, String parentId, String preNodeId, - Long userId); + Long userId, Long unitId); } diff --git a/backend-server/application/src/main/java/com/apitable/workspace/service/impl/ControlMemberServiceImpl.java b/backend-server/application/src/main/java/com/apitable/workspace/service/impl/ControlMemberServiceImpl.java index 83d154abe2..2e766d972c 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/service/impl/ControlMemberServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/service/impl/ControlMemberServiceImpl.java @@ -35,6 +35,8 @@ import com.apitable.organization.enums.UnitType; import com.apitable.organization.service.IMemberService; import com.apitable.organization.service.IRoleMemberService; +import com.apitable.organization.service.ITagMemberRelService; +import com.apitable.organization.service.ITagService; import com.apitable.organization.service.ITeamService; import com.apitable.organization.service.IUnitService; import com.apitable.shared.util.page.PageHelper; @@ -86,6 +88,9 @@ public class ControlMemberServiceImpl implements IControlMemberService { @Resource private IControlRoleService iControlRoleService; + @Resource + private ITagService iTagService; + @Override public PageInfo getControlRoleMemberPageInfo( Page page, String spaceId, ControlId controlId, Class clz @@ -93,16 +98,16 @@ public PageInfo getControlRoleMemberPageInfo( Map memberControlRoleMap = this.getMemberControlRoleMap(spaceId, controlId); // calculate position - int sub = (int) (page.getCurrent() - 1) * (int) page.getSize(); + long sub = (page.getCurrent() - 1) * page.getSize(); if (sub > memberControlRoleMap.size()) { - return PageHelper.build((int) page.getCurrent(), (int) page.getSize(), + return PageHelper.build(page.getCurrent(), page.getSize(), memberControlRoleMap.size(), new ArrayList<>()); } - int end = (sub + page.getSize()) > memberControlRoleMap.size() - ? memberControlRoleMap.size() : sub + (int) page.getSize(); + long end = (sub + page.getSize()) > memberControlRoleMap.size() + ? memberControlRoleMap.size() : sub + page.getSize(); List memberIds = - new ArrayList<>(memberControlRoleMap.keySet()).subList(sub, end); + new ArrayList<>(memberControlRoleMap.keySet()).subList((int) sub, (int) end); List records = new ArrayList<>(memberIds.size()); List results = iMemberService.getNodeRoleMemberWithSort(memberIds); // Give permission value @@ -113,7 +118,7 @@ public PageInfo getControlRoleMemberPageInfo( result.setIsControlOwner(controlMemberDTO.getIsControlOwner()); records.add(BeanUtil.toBean(result, clz)); }); - return PageHelper.build((int) page.getCurrent(), (int) page.getSize(), + return PageHelper.build(page.getCurrent(), page.getSize(), memberControlRoleMap.size(), records); } @@ -143,6 +148,7 @@ public Map getMemberControlRoleMap(String spaceId, List memberIds = new ArrayList<>(); List teamIds = new ArrayList<>(); List roleIds = new ArrayList<>(); + List tagIds = new ArrayList<>(); for (ControlRoleUnitDTO control : entry.getValue()) { UnitType unitType = UnitType.toEnum(control.getUnitType()); switch (unitType) { @@ -155,6 +161,9 @@ public Map getMemberControlRoleMap(String spaceId, case ROLE: roleIds.add(control.getUnitRefId()); break; + case TAG: + tagIds.add(control.getUnitRefId()); + break; default: break; } @@ -170,12 +179,17 @@ public Map getMemberControlRoleMap(String spaceId, List roleMemberIds = iRoleMemberService.getMemberIdsByRoleIds(roleIds); memberIds.addAll(roleMemberIds); } + if (CollUtil.isNotEmpty(tagIds)) { + List tagMemberIds = iTagService.getMemberIdsByTagIds(tagIds); + memberIds.addAll(tagMemberIds); + } for (Long memberId : memberIds) { if (memberRoleMap.containsKey(memberId)) { continue; } memberRoleMap.put(memberId, new ControlMemberDTO(memberId, entry.getKey())); } + } return memberRoleMap; } diff --git a/backend-server/application/src/main/java/com/apitable/workspace/service/impl/DatasheetMetaServiceImpl.java b/backend-server/application/src/main/java/com/apitable/workspace/service/impl/DatasheetMetaServiceImpl.java index 819bfb10c1..0cc3f128d4 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/service/impl/DatasheetMetaServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/service/impl/DatasheetMetaServiceImpl.java @@ -24,6 +24,8 @@ import com.apitable.core.util.ExceptionUtil; import com.apitable.core.util.SqlTool; import com.apitable.internal.dto.SimpleDatasheetMetaDTO; +import com.apitable.shared.util.DBUtil; +import com.apitable.workspace.dto.DatasheetMetaColumnDTO; import com.apitable.workspace.dto.DatasheetMetaDTO; import com.apitable.workspace.dto.DatasheetSnapshot; import com.apitable.workspace.dto.DatasheetSnapshot.View; @@ -68,6 +70,12 @@ public SimpleDatasheetMetaDTO findByDstId(String dstId) { return meta; } + @Override + public List findMetaColumnDTOs(List dstIds) { + return DBUtil.batchSelectByFieldIn(dstIds, + datasheetMetaMapper::selectMetaColumnDtoByDstIds, 100); + } + @Override public List findMetaDtoByDstIds(List dstIds) { List dtoList = new ArrayList<>(); diff --git a/backend-server/application/src/main/java/com/apitable/workspace/service/impl/DatasheetServiceImpl.java b/backend-server/application/src/main/java/com/apitable/workspace/service/impl/DatasheetServiceImpl.java index cd92a3f3af..e47c2d19d9 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/service/impl/DatasheetServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/service/impl/DatasheetServiceImpl.java @@ -18,13 +18,13 @@ package com.apitable.workspace.service.impl; +import static com.apitable.shared.component.notification.queue.QueueConfig.NOTIFICATION_EXCHANGE; import static com.apitable.shared.constants.NotificationConstants.BODY_EXTRAS; import static java.util.stream.Collectors.toList; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.ListUtil; import cn.hutool.core.convert.Convert; -import cn.hutool.core.date.DatePattern; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.BooleanUtil; import cn.hutool.core.util.ObjectUtil; @@ -39,10 +39,6 @@ import com.apitable.control.infrastructure.permission.NodePermission; import com.apitable.core.exception.BusinessException; import com.apitable.core.util.ExceptionUtil; -import com.apitable.core.util.SpringContextHolder; -import com.apitable.interfaces.social.event.NotificationEvent; -import com.apitable.interfaces.social.facade.SocialServiceFacade; -import com.apitable.interfaces.social.model.SocialConnectInfo; import com.apitable.internal.dto.SimpleDatasheetMetaDTO; import com.apitable.organization.entity.TeamMemberRelEntity; import com.apitable.organization.entity.UnitEntity; @@ -55,11 +51,11 @@ import com.apitable.player.service.IPlayerNotificationService; import com.apitable.shared.cache.service.UserSpaceRemindRecordCacheService; import com.apitable.shared.component.notification.NotificationTemplateId; -import com.apitable.shared.config.properties.ConstProperties; import com.apitable.shared.config.properties.LimitProperties; import com.apitable.shared.context.LoginContext; import com.apitable.shared.sysconfig.i18n.I18nStringsUtil; import com.apitable.shared.util.IdUtil; +import com.apitable.starter.amqp.core.RabbitSenderService; import com.apitable.starter.beetl.autoconfigure.BeetlTemplate; import com.apitable.user.mapper.UserMapper; import com.apitable.widget.service.IWidgetService; @@ -78,9 +74,6 @@ import com.apitable.workspace.mapper.NodeMapper; import com.apitable.workspace.model.DatasheetObject; import com.apitable.workspace.observer.DatasheetRemindObserver; -import com.apitable.workspace.observer.RemindMemberOpSubject; -import com.apitable.workspace.observer.remind.MailRemind; -import com.apitable.workspace.observer.remind.NotifyDataSheetMeta; import com.apitable.workspace.observer.remind.RemindType; import com.apitable.workspace.ro.ButtonFieldProperty; import com.apitable.workspace.ro.FieldMapRo; @@ -100,8 +93,6 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.toolkit.SqlHelper; import jakarta.annotation.Resource; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -115,6 +106,7 @@ import java.util.function.Predicate; import java.util.stream.Collectors; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -169,8 +161,8 @@ public class DatasheetServiceImpl extends ServiceImpl replaceFieldDstId(Long userId, boolean sameSpace, MetaMapRo for (Object field : metaMapRo.getFieldMap().values()) { FieldMapRo fieldMapRo = JSONUtil.parseObj(field).toBean(FieldMapRo.class); FieldType type = FieldType.create(fieldMapRo.getType()); - Object originDstId = fieldMapRo.getProperty().get("datasheetId"); + String originDstId = fieldMapRo.getProperty() != null + ? fieldMapRo.getProperty().getStr("datasheetId") : null; switch (type) { case ONE_WAY_LINK: case LINK: + assert fieldMapRo.getProperty() != null; LinkFieldProperty property = fieldMapRo.getProperty().toBean(LinkFieldProperty.class); String foreignDstId = property.getForeignDatasheetId(); @@ -839,22 +833,23 @@ public List replaceFieldDstId(Long userId, boolean sameSpace, MetaMapRo case LAST_MODIFIED_TIME: if (originDstId != null) { fieldMapRo.getProperty() - .set("datasheetId", newNodeIdMap.get(originDstId.toString())); + .set("datasheetId", newNodeIdMap.get(originDstId)); } break; case MEMBER: if (!sameSpace) { + assert fieldMapRo.getProperty() != null; fieldMapRo.getProperty().set("unitIds", new ArrayList<>()); delFieldIds.add(fieldMapRo.getId()); } break; case CREATED_BY: case LAST_MODIFIED_BY: - originDstId = fieldMapRo.getProperty().get("datasheetId"); if (originDstId != null) { fieldMapRo.getProperty() - .set("datasheetId", newNodeIdMap.get(originDstId.toString())); + .set("datasheetId", newNodeIdMap.get(originDstId)); } + assert fieldMapRo.getProperty() != null; fieldMapRo.getProperty().set("uuids", Collections.singletonList(uuid)); break; default: @@ -895,7 +890,7 @@ public void remindMemberRecOp(Long userId, String spaceId, RemindMemberRo ro) { Map> roleUnitIdToRoleMemberUnitIds = getRoleMemberUnits(units); // self don't need to send notifications, filter Long memberId = - userId == null ? -2L : iMemberService.getMemberIdByUserIdAndSpaceId(userId, spaceId); + null == userId ? null : iMemberService.getMemberIdByUserIdAndSpaceId(userId, spaceId); // Gets the organizational unit of the member type, the corresponding member. Map unitIdToMemberIdMap = units.stream() .filter(unit -> unit.getUnitType().equals(UnitType.MEMBER.getType()) @@ -969,6 +964,7 @@ public void remindMemberRecOp(Long userId, String spaceId, RemindMemberRo ro) { .set("fieldName", remindUnitRecRo.getFieldName()) .set("recordTitle", recordTitle) .set("viewId", ro.getViewId()) + .set("linkId", ro.getLinkId()) .set("recordIds", remindUnitRecRo.getRecordIds()); if (null != ro.getExtra() && null != ro.getExtra().getContent()) { // comments @@ -979,63 +975,20 @@ public void remindMemberRecOp(Long userId, String spaceId, RemindMemberRo ro) { // send notification NotificationCreateRo notifyRo = new NotificationCreateRo(); notifyRo.setToMemberId(ListUtil.toList(Convert.toStrArray(toMemberIds))); - notifyRo.setFromUserId(userId == null ? "-2" : userId.toString()); + if (null != userId) { + notifyRo.setFromUserId(userId.toString()); + } notifyRo.setNodeId(ro.getNodeId()); notifyRo.setSpaceId(spaceId); // used to mark message jump read String notifyId = cn.hutool.core.util.IdUtil.simpleUUID(); notifyRo.setNotifyId(notifyId); - String templateId; - if (RemindType.MEMBER.getRemindType() == ro.getType() - && remindUnitRecRo.getRecordIds().size() == 1) { - templateId = NotificationTemplateId.SINGLE_RECORD_MEMBER_MENTION.getValue(); - } else if (RemindType.MEMBER.getRemindType() == ro.getType()) { - templateId = NotificationTemplateId.USER_FIELD.getValue(); - } else { - templateId = - NotificationTemplateId.SINGLE_RECORD_COMMENT_MENTIONED.getValue(); - } + String templateId = RemindType.MEMBER.getRemindType() == ro.getType() + ? NotificationTemplateId.SINGLE_RECORD_MEMBER_MENTION.getValue() + : NotificationTemplateId.SINGLE_RECORD_COMMENT_MENTIONED.getValue(); notifyRo.setTemplateId(templateId); notifyRo.setBody(body); - // save notification record - playerNotificationService.batchCreateNotify(CollUtil.newArrayList(notifyRo)); - NotifyDataSheetMeta meta = new NotifyDataSheetMeta() - .setRemindType(RemindType.of(ro.getType())) - .setSpaceId(spaceId) - .setNodeId(ro.getNodeId()) - .setViewId(ro.getViewId()) - .setRecordId(remindUnitRecRo.getRecordIds().get(0)) - .setFieldName(remindUnitRecRo.getFieldName()) - .setCreatedAt(LocalDateTime.now().format( - DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_MINUTE_PATTERN))) - .setExtra(ro.getExtra()) - .setFromMemberId(memberId) - .setToMemberIds(toMemberIds) - .setNotifyId(notifyId) - .setFromUserId(ObjectUtil.defaultIfNull(userId, -2L)) - .setRecordTitle(recordTitle); - if (userId != null) { - String avatar = SpringContextHolder.getBean(ConstProperties.class) - .spliceAssetUrl(userMapper.selectAvatarById(userId)); - meta.setFromUserAvatar(avatar); - } - - RemindMemberOpSubject remindMemberOpSubject = new RemindMemberOpSubject(); - // Default-Subscribe to Mail Notifications - if (!templateId.equals( - NotificationTemplateId.SINGLE_RECORD_MEMBER_MENTION.getValue())) { - remindMemberOpSubject.registerObserver(datasheetRemindObservers.get( - StrUtil.lowerFirst(MailRemind.class.getSimpleName()))); - } - // Check whether the space is bound to third-party integration - SocialConnectInfo connectInfo = socialServiceFacade.getConnectInfo(spaceId); - if (connectInfo != null && connectInfo.isEnabled() - && StrUtil.isNotBlank(connectInfo.getAppId())) { - // transform social connect app type, register remind observer - socialServiceFacade.eventCall(new NotificationEvent(notifyRo)); - } - // message pushed to observer - remindMemberOpSubject.sendNotify(meta); + rabbitSenderService.topicSend(NOTIFICATION_EXCHANGE, "notification.#", notifyRo); } } diff --git a/backend-server/application/src/main/java/com/apitable/workspace/service/impl/FieldRoleServiceImpl.java b/backend-server/application/src/main/java/com/apitable/workspace/service/impl/FieldRoleServiceImpl.java index 5a030b5d72..38a6446c65 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/service/impl/FieldRoleServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/service/impl/FieldRoleServiceImpl.java @@ -54,11 +54,14 @@ import com.apitable.organization.service.IOrganizationService; import com.apitable.organization.service.IRoleMemberService; import com.apitable.organization.service.IRoleService; +import com.apitable.organization.service.ITagService; import com.apitable.organization.service.ITeamService; import com.apitable.organization.vo.MemberTeamPathInfo; import com.apitable.organization.vo.RoleInfoVo; +import com.apitable.organization.vo.TagInfoVo; import com.apitable.organization.vo.UnitMemberVo; import com.apitable.organization.vo.UnitTeamVo; +import com.apitable.shared.util.IdUtil; import com.apitable.shared.util.page.PageInfo; import com.apitable.space.service.ISpaceRoleService; import com.apitable.workspace.dto.ControlRoleInfo; @@ -84,6 +87,7 @@ import com.apitable.workspace.vo.FieldRoleMemberVo; import com.apitable.workspace.vo.FieldRoleSetting; import com.apitable.workspace.vo.NodeRoleMemberVo; +import com.apitable.workspace.vo.NodeRoleUnit; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; @@ -169,6 +173,9 @@ public class FieldRoleServiceImpl implements IFieldRoleService { @Resource private IRoleMemberService iRoleMemberService; + @Resource + private ITagService iTagService; + @Override public boolean getFieldRoleEnabledStatus(String dstId, String fieldId) { ControlId controlId = ControlIdBuilder.fieldId(dstId, fieldId); @@ -313,6 +320,7 @@ public FieldCollaboratorVO getFieldRoles(String datasheetId, String fieldId) { List teamIds = new ArrayList<>(); List memberIds = new ArrayList<>(); List roleIds = new ArrayList<>(); + List tagIds = new ArrayList<>(); for (ControlRoleUnitDTO control : entry.getValue()) { if (unitIdToFieldRoleMap.containsKey(control.getUnitId())) { unitIdToFieldRoleMap.get(control.getUnitId()).setPermissionExtend(false); @@ -329,6 +337,8 @@ public FieldCollaboratorVO getFieldRoles(String datasheetId, String fieldId) { memberIds.add(control.getUnitRefId()); } else if (unitType == UnitType.ROLE) { roleIds.add(control.getUnitRefId()); + } else if (unitType == UnitType.TAG) { + tagIds.add(control.getUnitRefId()); } role.setCanRead(true); role.setCanEdit(true); @@ -363,6 +373,15 @@ public FieldCollaboratorVO getFieldRoles(String datasheetId, String fieldId) { role.setUnitRefId(roleVo.getRoleId()); } } + if (!tagIds.isEmpty()) { + List tags = iTagService.getTagVos(spaceId, tagIds); + for (TagInfoVo tag : tags) { + FieldRole role = unitIdToFieldRoleMap.get(tag.getUnitId()); + role.setUnitRefId(tag.getTagId()); + role.setUnitName(tag.getTagName()); + role.setMemberCount(tag.getMemberCount()); + } + } } fieldCollaboratorVO.setRoles(ListUtil.toList(unitIdToFieldRoleMap.values())); return fieldCollaboratorVO; @@ -511,13 +530,11 @@ public FieldPermissionView getFieldPermissionView(Long memberId, String nodeId, .collect(Collectors.toMap(String::toString, controlId -> controlId.substring(controlId.indexOf(ControlIdBuilder.SYMBOL) + 1))); // load field permissions in sharing - if (StrUtil.isNotBlank(shareId)) { + if ((StrUtil.isNotBlank(shareId) && !IdUtil.isEmbed(shareId)) || null == memberId) { // If the datasheet is not collected, directly return the field with the permission set. if (type != NodeType.FORM) { - Map permissionInfoMap = - controlIdToFieldIdMap.values().stream() - .collect(Collectors.toMap(String::toString, - fieldId -> FieldPermissionInfo.builder() + Map permissionInfoMap = controlIdToFieldIdMap.values().stream() + .collect(Collectors.toMap(String::toString, fieldId -> FieldPermissionInfo.builder() .fieldId(fieldId) .permission(new FieldPermission()) .build())); @@ -743,6 +760,14 @@ private void populateFieldRoles(Map unitIdToFieldRoleMap, fieldRole.setMemberCount(role.getMemberCount()); fieldRole.setUnitRefId(role.getRoleId()); }); + } else if (key == UnitType.TAG) { + List tagVos = iTagService.getTagVos(spcId, unitRefIds); + tagVos.forEach(tag -> { + FieldRole fieldRole = unitIdToFieldRoleMap.get(tag.getUnitId()); + fieldRole.setUnitRefId(tag.getTagId()); + fieldRole.setUnitName(tag.getTagName()); + fieldRole.setMemberCount(tag.getMemberCount()); + }); } }); } diff --git a/backend-server/application/src/main/java/com/apitable/workspace/service/impl/NodeBundleServiceImpl.java b/backend-server/application/src/main/java/com/apitable/workspace/service/impl/NodeBundleServiceImpl.java index 624f60ccd4..69fb4e62eb 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/service/impl/NodeBundleServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/service/impl/NodeBundleServiceImpl.java @@ -225,7 +225,7 @@ public void generate(String nodeId, boolean saveData, String password) { @Override @Transactional(rollbackFor = Exception.class) public void analyze(MultipartFile file, String password, String parentId, String preNodeId, - Long userId) { + Long userId, Long unitId) { log.info("parse bundle file"); ExceptionUtil.isNotNull(file, ActionException.FILE_EMPTY); ExceptionUtil.isTrue(StrUtil.isNotBlank(parentId) || StrUtil.isNotBlank(preNodeId), @@ -289,10 +289,10 @@ public void analyze(MultipartFile file, String password, String parentId, String // duplicate name modification at the same level String name = iNodeService.duplicateNameModify(parentId, root.getType(), root.getNodeName(), - null); + null, unitId); root.setNodeName(name); - this.processNode(userId, spaceId, parentId, preNodeId, root, nodeList, newNodeIdMap, - fileNameToNodeMap); + this.processNode(userId, spaceId, parentId, preNodeId, unitId, root, nodeList, + newNodeIdMap, fileNameToNodeMap); // processing data files if (MapUtil.isNotEmpty(fileNameToNodeMap)) { ExceptionUtil.isTrue(fileNameToNodeMap.size() == fileNameToContentMap.size(), @@ -348,7 +348,7 @@ public void analyze(MultipartFile file, String password, String parentId, String } private void processNode(Long userId, String spaceId, String parentId, String preNodeId, - NodeFileTree node, List nodeList, + Long unitId, NodeFileTree node, List nodeList, Map newNodeIdMap, Map> fileNameToNodeMap) { boolean isDst = node.getType() == NodeType.DATASHEET.getNodeType(); @@ -366,6 +366,7 @@ private void processNode(Long userId, String spaceId, String parentId, String pr .cover(node.getCover()) .createdBy(userId) .updatedBy(userId) + .unitId(unitId) .build(); nodeList.add(nodeEntity); newNodeIdMap.put(node.getNodeId(), nodeId); @@ -383,19 +384,19 @@ private void processNode(Long userId, String spaceId, String parentId, String pr } if (!isDst && CollUtil.isNotEmpty(node.getChild())) { // processing child nodes - this.processChildList(userId, spaceId, nodeId, node.getChild(), nodeList, newNodeIdMap, - fileNameToNodeMap); + this.processChildList(userId, spaceId, nodeId, unitId, node.getChild(), nodeList, + newNodeIdMap, fileNameToNodeMap); } } - private void processChildList(Long userId, String spaceId, String parentId, + private void processChildList(Long userId, String spaceId, String parentId, Long unitId, List child, List nodeList, Map newNodeIdMap, Map> fileNameToNodeMap) { String preNodeId = null; for (NodeFileTree node : child) { - this.processNode(userId, spaceId, parentId, preNodeId, node, nodeList, newNodeIdMap, - fileNameToNodeMap); + this.processNode(userId, spaceId, parentId, preNodeId, unitId, node, nodeList, + newNodeIdMap, fileNameToNodeMap); preNodeId = newNodeIdMap.get(node.getNodeId()); } } diff --git a/backend-server/application/src/main/java/com/apitable/workspace/service/impl/NodeFavoriteServiceImpl.java b/backend-server/application/src/main/java/com/apitable/workspace/service/impl/NodeFavoriteServiceImpl.java index 6e9d174d01..5aa05cdf5c 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/service/impl/NodeFavoriteServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/service/impl/NodeFavoriteServiceImpl.java @@ -143,8 +143,10 @@ public void updateFavoriteStatus(String spaceId, Long memberId, String nodeId) { ExceptionUtil.isTrue(flag, DatabaseException.EDIT_ERROR); return; } + // check whether the node exists - iNodeService.checkNodeIfExist(spaceId, nodeId); + iNodeService.checkNodeIfExist(spaceId, nodeId, + StrUtil.toString(iNodeService.getUnitIdByNodeId(nodeId))); // Check whether the node has the specified operation permission controlTemplate.checkNodePermission(memberId, nodeId, NodePermission.READ_NODE, status -> ExceptionUtil.isTrue(status, PermissionException.NODE_OPERATION_DENIED)); diff --git a/backend-server/application/src/main/java/com/apitable/workspace/service/impl/NodeRelServiceImpl.java b/backend-server/application/src/main/java/com/apitable/workspace/service/impl/NodeRelServiceImpl.java index 1e54608b7c..948183a2c7 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/service/impl/NodeRelServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/service/impl/NodeRelServiceImpl.java @@ -26,6 +26,7 @@ import com.apitable.core.util.ExceptionUtil; import com.apitable.workspace.dto.NodeRelDTO; import com.apitable.workspace.entity.NodeRelEntity; +import com.apitable.workspace.enums.IdRulePrefixEnum; import com.apitable.workspace.mapper.NodeMapper; import com.apitable.workspace.mapper.NodeRelMapper; import com.apitable.workspace.service.INodeRelService; @@ -36,6 +37,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; @@ -156,4 +158,19 @@ public NodeRelEntity getByRelNodeId(String relNodeId) { log.info("Gets the node association relationship with the associated node [{}]", relNodeId); return nodeRelMapper.selectByRelNodeId(relNodeId); } + + @Override + public boolean relInTheSameFolder(List nodeIds) { + List mainNodeIds = + nodeIds.stream().filter(i -> i.startsWith(IdRulePrefixEnum.DST.getIdRulePrefixEnum())) + .toList(); + if (!mainNodeIds.isEmpty()) { + List relNodeIds = nodeRelMapper.selectRelNodeIdsByMainNodeIds(mainNodeIds); + if (!relNodeIds.isEmpty()) { + relNodeIds = nodeMapper.selectNodeIdByNodeIdIn(relNodeIds); + return new HashSet<>(nodeIds).containsAll(relNodeIds); + } + } + return true; + } } diff --git a/backend-server/application/src/main/java/com/apitable/workspace/service/impl/NodeRoleServiceImpl.java b/backend-server/application/src/main/java/com/apitable/workspace/service/impl/NodeRoleServiceImpl.java index b13f1ad8de..f0f60f154d 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/service/impl/NodeRoleServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/service/impl/NodeRoleServiceImpl.java @@ -46,10 +46,12 @@ import com.apitable.organization.service.IMemberService; import com.apitable.organization.service.IOrganizationService; import com.apitable.organization.service.IRoleService; +import com.apitable.organization.service.ITagService; import com.apitable.organization.service.ITeamService; import com.apitable.organization.service.IUnitService; import com.apitable.organization.vo.MemberTeamPathInfo; import com.apitable.organization.vo.RoleInfoVo; +import com.apitable.organization.vo.TagInfoVo; import com.apitable.organization.vo.UnitMemberVo; import com.apitable.organization.vo.UnitTeamVo; import com.apitable.shared.cache.service.UserSpaceCacheService; @@ -144,6 +146,9 @@ public class NodeRoleServiceImpl implements INodeRoleService { @Resource private IRoleService iRoleService; + @Resource + private ITagService iTagService; + @Override @Transactional(rollbackFor = Exception.class) public void enableNodeRole(Long userId, String spaceId, String nodeId, boolean includeExtend) { @@ -413,6 +418,7 @@ public List getNodeRoleUnitList(String nodeId) { List teamIds = new ArrayList<>(); List memberIds = new ArrayList<>(); List roleIds = new ArrayList<>(); + List tagIds = new ArrayList<>(); for (ControlRoleUnitDTO nodeRoleDto : entry.getValue()) { NodeRoleUnit unit = new NodeRoleUnit(); unit.setRole(nodeRoleDto.getRole()); @@ -427,6 +433,8 @@ public List getNodeRoleUnitList(String nodeId) { memberIds.add(nodeRoleDto.getUnitRefId()); } else if (unitType == UnitType.ROLE) { roleIds.add(nodeRoleDto.getUnitRefId()); + } else if (unitType == UnitType.TAG) { + tagIds.add(nodeRoleDto.getUnitRefId()); } } // Batch query supplementary organizational unit information @@ -469,6 +477,16 @@ public List getNodeRoleUnitList(String nodeId) { roleUnits.add(unit); } } + if (!tagIds.isEmpty()) { + List tags = iTagService.getTagVos(spaceId, tagIds); + for (TagInfoVo tag : tags) { + NodeRoleUnit unit = unitIdToFieldRoleMap.get(tag.getUnitId()); + unit.setUnitRefId(tag.getTagId()); + unit.setUnitName(tag.getTagName()); + unit.setMemberCount(tag.getMemberCount()); + roleUnits.add(unit); + } + } } return roleUnits; } diff --git a/backend-server/application/src/main/java/com/apitable/workspace/service/impl/NodeRubbishServiceImpl.java b/backend-server/application/src/main/java/com/apitable/workspace/service/impl/NodeRubbishServiceImpl.java index 29f64db0b9..aa96e5a9f8 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/service/impl/NodeRubbishServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/service/impl/NodeRubbishServiceImpl.java @@ -31,12 +31,12 @@ import com.apitable.control.infrastructure.role.RoleConstants.Node; import com.apitable.control.service.IControlService; import com.apitable.core.util.ExceptionUtil; -import com.apitable.interfaces.billing.facade.EntitlementServiceFacade; import com.apitable.interfaces.billing.model.SubscriptionInfo; import com.apitable.interfaces.document.facade.DocumentServiceFacade; import com.apitable.shared.clock.spring.ClockManager; import com.apitable.shared.component.TaskManager; import com.apitable.space.service.ISpaceAssetService; +import com.apitable.space.service.ISpaceService; import com.apitable.workspace.dto.NodeBaseInfoDTO; import com.apitable.workspace.enums.NodeType; import com.apitable.workspace.enums.PermissionException; @@ -96,7 +96,7 @@ public class NodeRubbishServiceImpl implements INodeRubbishService { private INodeRoleService iNodeRoleService; @Resource - private EntitlementServiceFacade entitlementServiceFacade; + private ISpaceService iSpaceService; @Override @@ -107,7 +107,7 @@ public List getRubbishNodeList(String spaceId, Long memberId, Int memberId, spaceId, lastNodeId); // Obtain the maximum storage days of the rubbish corresponding to the space subscription plan. - SubscriptionInfo subscriptionInfo = entitlementServiceFacade.getSpaceSubscription(spaceId); + SubscriptionInfo subscriptionInfo = iSpaceService.getSpaceSubscription(spaceId); long retainDay = subscriptionInfo.getFeature().getRemainTrashDays().getValue(); // Push back start time (not included) LocalDate dateNow = ClockManager.me().getLocalDateNow(); @@ -171,7 +171,7 @@ public void recoverRubbishNode(Long userId, String nodeId, String parentId) { userId, nodeId, parentId); // Obtain the node ID of the node and its child descendants. List subNodeIds = - iNodeService.getNodeIdsInNodeTree(nodeId, -1, true); + iNodeService.getNodeIdsInNodeTree(nodeId, -1, true, new ArrayList<>()); if (CollUtil.isNotEmpty(subNodeIds)) { // recovery datasheet iDatasheetService.updateIsDeletedStatus(userId, subNodeIds, false); @@ -193,7 +193,7 @@ public void recoverRubbishNode(Long userId, String nodeId, String parentId) { BaseNodeInfo nodeInfo = nodeMapper.selectBaseNodeInfoByNodeId(nodeId); String name = iNodeService.duplicateNameModify(parentId, nodeInfo.getType(), nodeInfo.getNodeName(), - null); + null, null); // modify the information of the recovery node boolean flag = SqlHelper.retBool(nodeMapper.updateInfoByNodeId(nodeId, parentId, null, name)); @@ -205,7 +205,7 @@ public void delRubbishNode(Long userId, String nodeId) { log.info("User [{}] completely delete the node of the rubbish [{}]", userId, nodeId); // Obtain the node ID of the node and its child descendants. List subNodeIds = - iNodeService.getNodeIdsInNodeTree(nodeId, -1, true); + iNodeService.getNodeIdsInNodeTree(nodeId, -1, true, new ArrayList<>()); // logical delete node boolean flag = SqlHelper.retBool(nodeMapper.updateIsDeletedByNodeId(userId, nodeId)); ExceptionUtil.isTrue(flag, DatabaseException.DELETE_ERROR); @@ -242,7 +242,7 @@ public void checkRubbishNode(String spaceId, Long memberId, String nodeId) { ExceptionUtil.isNotNull(rubbishUpdatedAt, RUBBISH_NODE_NOT_EXIST); // Obtain the maximum storage days of the rubbish corresponding to the space subscription plan. - long retainDay = entitlementServiceFacade.getSpaceSubscription(spaceId) + long retainDay = iSpaceService.getSpaceSubscription(spaceId) .getFeature().getRemainTrashDays().getValue(); // Subscription function restriction check ExceptionUtil.isTrue(retainDay < 0 diff --git a/backend-server/application/src/main/java/com/apitable/workspace/service/impl/NodeServiceImpl.java b/backend-server/application/src/main/java/com/apitable/workspace/service/impl/NodeServiceImpl.java index b0cf90015b..3e87ba987b 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/service/impl/NodeServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/service/impl/NodeServiceImpl.java @@ -20,13 +20,16 @@ import static com.apitable.core.constants.RedisConstants.getTemplateQuoteKey; import static com.apitable.shared.constants.AssetsPublicConstants.SPACE_PREFIX; +import static com.apitable.template.enums.TemplateException.NODE_LINK_FOREIGN_NODE; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Dict; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.BooleanUtil; +import cn.hutool.core.util.NumberUtil; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; @@ -45,6 +48,7 @@ import com.apitable.control.infrastructure.ControlTemplate; import com.apitable.control.infrastructure.permission.NodePermission; import com.apitable.control.infrastructure.role.ControlRole; +import com.apitable.control.service.IControlService; import com.apitable.core.exception.BusinessException; import com.apitable.core.support.tree.DefaultTreeBuildFactory; import com.apitable.core.util.ExceptionUtil; @@ -56,11 +60,12 @@ import com.apitable.interfaces.ai.model.AiCreateParam; import com.apitable.interfaces.ai.model.AiUpdateParam; import com.apitable.interfaces.document.facade.DocumentServiceFacade; -import com.apitable.interfaces.social.facade.SocialServiceFacade; import com.apitable.interfaces.social.model.SocialConnectInfo; import com.apitable.organization.dto.MemberDTO; +import com.apitable.organization.enums.UnitType; import com.apitable.organization.mapper.MemberMapper; import com.apitable.organization.service.IMemberService; +import com.apitable.organization.service.IUnitService; import com.apitable.shared.cache.bean.LoginUserDto; import com.apitable.shared.component.adapter.MultiDatasourceAdapterTemplate; import com.apitable.shared.constants.AuditConstants; @@ -73,6 +78,7 @@ import com.apitable.shared.listener.event.AuditSpaceEvent.AuditSpaceArg; import com.apitable.shared.sysconfig.i18n.I18nStringsUtil; import com.apitable.shared.util.CollectionUtil; +import com.apitable.shared.util.DBUtil; import com.apitable.shared.util.IdUtil; import com.apitable.shared.util.StringUtil; import com.apitable.shared.util.information.ClientOriginInfo; @@ -87,11 +93,14 @@ import com.apitable.template.enums.TemplateException; import com.apitable.widget.service.IWidgetService; import com.apitable.workspace.dto.CreateNodeDto; +import com.apitable.workspace.dto.DatasheetMetaColumnDTO; import com.apitable.workspace.dto.NodeBaseInfoDTO; import com.apitable.workspace.dto.NodeCopyEffectDTO; import com.apitable.workspace.dto.NodeCopyOptions; import com.apitable.workspace.dto.NodeData; import com.apitable.workspace.dto.NodeExtraDTO; +import com.apitable.workspace.dto.NodeShareDTO; +import com.apitable.workspace.dto.NodeStatisticsDTO; import com.apitable.workspace.dto.NodeTreeDTO; import com.apitable.workspace.dto.UrlNodeInfoDTO; import com.apitable.workspace.entity.DatasheetEntity; @@ -112,6 +121,7 @@ import com.apitable.workspace.model.DatasheetCreateObject; import com.apitable.workspace.ro.CreateDatasheetRo; import com.apitable.workspace.ro.NodeCopyOpRo; +import com.apitable.workspace.ro.NodeEmbedPageRo; import com.apitable.workspace.ro.NodeMoveOpRo; import com.apitable.workspace.ro.NodeOpRo; import com.apitable.workspace.ro.NodeRelRo; @@ -121,6 +131,7 @@ import com.apitable.workspace.service.IDatasheetService; import com.apitable.workspace.service.IFieldRoleService; import com.apitable.workspace.service.INodeDescService; +import com.apitable.workspace.service.INodeFavoriteService; import com.apitable.workspace.service.INodeRelService; import com.apitable.workspace.service.INodeRoleService; import com.apitable.workspace.service.INodeService; @@ -175,6 +186,9 @@ public class NodeServiceImpl extends ServiceImpl impleme @Resource private NodeFacade nodeFacade; + @Resource + private INodeFavoriteService iNodeFavoriteService; + @Resource private INodeDescService iNodeDescService; @@ -202,6 +216,9 @@ public class NodeServiceImpl extends ServiceImpl impleme @Resource private ControlTemplate controlTemplate; + @Resource + private IControlService iControlService; + @Resource private INodeRoleService iNodeRoleService; @@ -220,9 +237,6 @@ public class NodeServiceImpl extends ServiceImpl impleme @Resource private IGrpcClientService grpcClientService; - @Resource - private SocialServiceFacade socialServiceFacade; - @Resource private RedisTemplate redisTemplate; @@ -253,6 +267,9 @@ public class NodeServiceImpl extends ServiceImpl impleme @Resource private DocumentServiceFacade documentServiceFacade; + @Resource + private IUnitService iUnitService; + @Override public String getRootNodeIdBySpaceId(String spaceId) { log.info("The root node ID of the query space [{}]", spaceId); @@ -400,7 +417,9 @@ public List getNodeInfoByNodeIds(String spaceId, Long memberId, return new ArrayList<>(); } // Batch query node information - List infos = baseMapper.selectNodeInfoByNodeIds(roleDict.keySet(), memberId); + List infos = + this.buildNodeInfos(spaceId, roleDict.keySet(), memberId, NodeInfoVo.class); + // baseMapper.selectNodeInfoByNodeIds(roleDict.keySet(), memberId); // Node switches to memory custom sorting CollectionUtil.customSequenceSort(infos, NodeInfoVo::getNodeId, new ArrayList<>(roleDict.keySet())); @@ -409,19 +428,102 @@ public List getNodeInfoByNodeIds(String spaceId, Long memberId, return infos; } + private List buildNodeInfos(String spaceId, + Set nodeIds, + Long memberId, Class targetType) { + List nodeInfoVOs = new ArrayList<>(); + List nodes = this.getByNodeIds(nodeIds); + if (nodes.isEmpty()) { + return nodeInfoVOs; + } + + // get star node id + List favoriteNodeIds = iNodeFavoriteService.getFavoriteNodeIdsByMemberId(memberId); + // get share node id + List shareDTOList = + DBUtil.batchSelectByFieldIn(nodeIds, nodeShareSettingMapper::selectDtoByNodeIds); + List shareNodeIds = shareDTOList.stream() + .filter(s -> s.getIsEnabled().equals(Boolean.TRUE)) + .map(NodeShareDTO::getNodeId).toList(); + // get control node id + List existedControlIds = + DBUtil.batchSelectByFieldIn(nodeIds, iControlService::getExistedControlId); + + // query folder ids with child nodes + List folderIdsWithChildren = new ArrayList<>(); + List folderNodeIds = nodes.stream() + .filter(n -> NodeType.toEnum(n.getType()).isFolder()) + .map(NodeEntity::getNodeId).toList(); + if (folderNodeIds.size() > 0) { + folderIdsWithChildren = + DBUtil.batchSelectByFieldIn(folderNodeIds, baseMapper::selectParentIdWithChildren); + } + // query datasheet column count + Map dstIdToColumnCountMap = new HashMap<>(); + List datasheetNodeIds = nodes.stream() + .filter(n -> n.getType().equals(NodeType.DATASHEET.getNodeType())) + .map(NodeEntity::getNodeId).toList(); + if (datasheetNodeIds.size() > 0) { + List metaColumnDTOs = + iDatasheetMetaService.findMetaColumnDTOs(datasheetNodeIds); + dstIdToColumnCountMap = metaColumnDTOs.stream().collect( + Collectors.toMap(DatasheetMetaColumnDTO::getDstId, + DatasheetMetaColumnDTO::getMdFieldMapSize)); + } + + for (NodeEntity node : nodes) { + String nodeId = node.getNodeId(); + T nodeInfo = ReflectUtil.newInstanceIfPossible(targetType); + BeanUtil.copyProperties(node, nodeInfo); + nodeInfo.setNodeFavorite(favoriteNodeIds.contains(nodeId)); + nodeInfo.setNodeShared(shareNodeIds.contains(nodeId)); + nodeInfo.setNodePermitSet(existedControlIds.contains(nodeId)); + nodeInfo.setNodePrivate(!node.getUnitId().equals(0L)); + + NodeType nodeType = NodeType.toEnum(node.getType()); + if (nodeType.isRoot()) { + // replace node name if type is root node + String spaceName = iSpaceService.getNameBySpaceId(spaceId); + nodeInfo.setNodeName(spaceName); + nodeInfo.setHasChildren(nodes.size() > 1); + } else if (nodeType.isFolder()) { + nodeInfo.setHasChildren(folderIdsWithChildren.contains(nodeId)); + } else if (nodeType.equals(NodeType.DATASHEET)) { + nodeInfo.setMdFieldMapSize(dstIdToColumnCountMap.get(nodeId)); + } + + nodeInfoVOs.add(nodeInfo); + } + return nodeInfoVOs; + } + @Override public String checkNodeIfExist(String spaceId, String nodeId) { log.info("Check if the node exists"); - String nodeSpaceId = baseMapper.selectSpaceIdByNodeId(nodeId); - ExceptionUtil.isNotNull(nodeSpaceId, PermissionException.NODE_NOT_EXIST); + return checkNodeIfExist(spaceId, nodeId, null); + } + + @Override + public String checkNodeIfExist(String spaceId, String nodeId, String unitId) { + log.info("Check if the node exists"); + if (nodeId.equals(getRootNodeIdBySpaceId(spaceId))) { + return spaceId; + } + // validate not root node + NodeEntity node = baseMapper.selectSpaceIdAndUnitIdByNodeId(nodeId); + ExceptionUtil.isNotNull(node, PermissionException.NODE_NOT_EXIST); + ExceptionUtil.isFalse( + null != unitId && !node.getUnitId().equals(NumberUtil.parseLong(unitId)), + PermissionException.NODE_NOT_EXIST); // When the space id is not empty, check whether the space is cross-space. - ExceptionUtil.isTrue(StrUtil.isBlank(spaceId) || nodeSpaceId.equals(spaceId), + ExceptionUtil.isTrue(StrUtil.isBlank(spaceId) || node.getSpaceId().equals(spaceId), SpaceException.NOT_IN_SPACE); - return nodeSpaceId; + return node.getNodeId(); } @Override - public void checkSourceDatasheet(String spaceId, Long memberId, Integer type, NodeRelRo extra) { + public void checkSourceDatasheet(String spaceId, Long memberId, Integer type, String unitId, + NodeRelRo extra) { NodeType nodeType = NodeType.toEnum(type); switch (nodeType) { case FORM: @@ -429,7 +531,7 @@ public void checkSourceDatasheet(String spaceId, Long memberId, Integer type, No ExceptionUtil.isTrue(extra != null && StrUtil.isNotBlank(extra.getDatasheetId()) && StrUtil.isNotBlank(extra.getViewId()), ParameterException.INCORRECT_ARG); // Determine whether the datasheet does not exist or is accessed across space. - this.checkNodeIfExist(spaceId, extra.getDatasheetId()); + this.checkNodeIfExist(spaceId, extra.getDatasheetId(), unitId); // Check whether the specified view of the datasheet exists. iDatasheetMetaService.checkViewIfExist(extra.getDatasheetId(), extra.getViewId()); // The form requires the editable permission of the source datasheet and the @@ -463,8 +565,11 @@ public List searchNode(String spaceId, Long memberId, String k if (StrUtil.isBlank(StrUtil.trim(keyword))) { return new ArrayList<>(); } + Long unitId = iUnitService.getUnitIdByRefId(memberId); + List unitIds = CollUtil.list(false, 0L, unitId); // fuzzy search results - List nodeIds = baseMapper.selectLikeNodeName(spaceId, StrUtil.trim(keyword)); + List nodeIds = + baseMapper.selectLikeNodeName(spaceId, unitIds, StrUtil.trim(keyword)); List nodeInfos = this.getNodeInfoByNodeIds(spaceId, memberId, nodeIds); return formatNodeSearchResults(nodeInfos); } @@ -472,10 +577,33 @@ public List searchNode(String spaceId, Long memberId, String k @Override public NodeInfoTreeVo getNodeTree(String spaceId, String nodeId, Long memberId, int depth) { log.info("Query node tree "); - List nodeIds = this.getNodeIdsInNodeTree(nodeId, depth); + // filter private workspace + List nodeIds = + this.getNodeIdsInNodeTree(nodeId, depth, false, Collections.singletonList(0L)); return this.getNodeInfoTreeByNodeIds(spaceId, memberId, nodeIds); } + @Override + public NodeInfoTreeVo getNodeTree(String spaceId, String nodeId, Long memberId, int depth, + UnitType unitType) { + log.info("Query node tree "); + List unitIds = new ArrayList<>(); + if (UnitType.MEMBER.equals(unitType)) { + unitIds.add(iUnitService.getUnitIdByRefId(memberId)); + } + List nodeIds = this.getNodeIdsInNodeTree(nodeId, depth, false, unitIds); + if (UnitType.MEMBER.equals(unitType)) { + // get space active member count + long memberCount = iMemberService.getTotalActiveMemberCountBySpaceId(spaceId); + // haven't private node + if (memberCount < 2 && nodeIds.size() == 1) { + return null; + } + } + return getNodeInfoTreeByNodeIds(spaceId, memberId, nodeIds); + } + + @Override public List getSubNodes(String nodeId) { List subNodeIds = this.getNodeIdsInNodeTree(nodeId, -1); @@ -491,23 +619,25 @@ public List getSubNodes(String nodeId) { @Override public List getNodeIdsInNodeTree(String nodeId, Integer depth) { - return this.getNodeIdsInNodeTree(nodeId, depth, false); + return this.getNodeIdsInNodeTree(nodeId, depth, false, new ArrayList<>()); } @Override - public List getNodeIdsInNodeTree(String nodeId, Integer depth, Boolean isRubbish) { - return this.getNodeIdsInNodeTree(Collections.singletonList(nodeId), depth, isRubbish); + public List getNodeIdsInNodeTree(String nodeId, Integer depth, Boolean isRubbish, + List unitIds) { + return this.getNodeIdsInNodeTree(Collections.singletonList(nodeId), depth, isRubbish, + unitIds); } private List getNodeIdsInNodeTree(List nodeIds, Integer depth, - Boolean isRubbish) { + Boolean isRubbish, List unitIds) { Set nodeIdSet = new LinkedHashSet<>(nodeIds); List parentIds = nodeIds.stream() .filter(i -> i.startsWith(IdRulePrefixEnum.FOD.getIdRulePrefixEnum())) .collect(Collectors.toList()); while (!parentIds.isEmpty() && depth != 0) { List subNode = - baseMapper.selectNodeTreeDTOByParentIdIn(parentIds, isRubbish); + baseMapper.selectNodeTreeDTOByParentIdIn(parentIds, isRubbish, unitIds); if (subNode.isEmpty()) { break; } @@ -576,10 +706,12 @@ private void sufNodeRecurrence(List nodes, NodeType nodeType, @Override public List getChildNodesByNodeId(String spaceId, Long memberId, String nodeId, NodeType nodeType) { + List unitIds = CollUtil.newArrayList(0L, iUnitService.getUnitIdByRefId(memberId)); log.info("Query the list of child nodes "); // Get a direct child node List subNode = - baseMapper.selectNodeTreeDTOByParentIdIn(Collections.singleton(nodeId), false); + baseMapper.selectNodeTreeDTOByParentIdIn(Collections.singleton(nodeId), false, + unitIds); if (subNode.isEmpty()) { return new ArrayList<>(); } @@ -611,9 +743,11 @@ public NodeInfoTreeVo position(String spaceId, Long memberId, String nodeId) { String rootNodeId = getRootNodeIdBySpaceId(spaceId); parentNodeIds.add(0, rootNodeId); parentNodeIds.remove(nodeId); + Long unitId = baseMapper.selectUnitIdByNodeId(nodeId); // The parent node supplements the tree node load. List subNode = - baseMapper.selectNodeTreeDTOByParentIdIn(parentNodeIds, false); + baseMapper.selectNodeTreeDTOByParentIdIn(parentNodeIds, false, + Collections.singletonList(unitId)); Map> parentIdToSubNodeMap = subNode.stream().collect(Collectors.groupingBy(NodeTreeDTO::getParentId)); List viewNodeIds = new ArrayList<>(); @@ -644,11 +778,13 @@ public NodeInfoTreeVo getNodeInfoTreeByNodeIds(String spaceId, Long memberId, ControlRoleDict roleDict = controlTemplate.fetchNodeTreeNode(memberId, nodeIds); ExceptionUtil.isFalse(roleDict.isEmpty(), PermissionException.NODE_ACCESS_DENIED); List treeList = - CollUtil.split(roleDict.keySet(), 1000).stream() + CollUtil.split(roleDict.keySet(), 1).stream() .reduce(new ArrayList<>(), (nodes, item) -> { List childNodes = - baseMapper.selectNodeInfoTreeByNodeIds(item, memberId); + this.buildNodeInfos(spaceId, new HashSet<>(item), memberId, + NodeInfoTreeVo.class); + // baseMapper.selectNodeInfoTreeByNodeIds(item, memberId); nodes.addAll(childNodes); return nodes; }, @@ -708,10 +844,10 @@ public String createNode(Long userId, String spaceId, NodeOpRo nodeOpRo) { log.info("create children node"); // The parent id and space id must match. // The parent node belongs to this space to prevent cross-space and cross-node operations. - this.checkNodeIfExist(spaceId, nodeOpRo.getParentId()); + this.checkNodeIfExist(spaceId, nodeOpRo.getParentId(), nodeOpRo.getUnitId()); String name = duplicateNameModify(nodeOpRo.getParentId(), nodeOpRo.getType(), nodeOpRo.getNodeName(), - null); + null, NumberUtil.parseLong(nodeOpRo.getUnitId())); NodeType nodeType = NodeType.toEnum(nodeOpRo.getType()); if (!nodeType.isFolder()) { iSpaceService.checkFileNumOverLimit(spaceId); @@ -728,7 +864,9 @@ public String createNode(Long userId, String spaceId, NodeOpRo nodeOpRo) { .preNodeId(preNodeId) .nodeName(name) .type(nodeOpRo.getType()) + .extra(JSONUtil.toJsonStr(nodeOpRo.getExtra())) .nodeId(nodeId) + .unitId(NumberUtil.parseLong(nodeOpRo.getUnitId())) .build(); // Change the front node ID of the next node to the new node ID(A <- C => B <- C) baseMapper.updatePreNodeIdBySelf(nodeId, preNodeId, nodeOpRo.getParentId()); @@ -768,6 +906,7 @@ public String createChildNode(Long userId, CreateNodeDto dto) { .extra(dto.getExtra()) .createdBy(userId) .updatedBy(userId) + .unitId(dto.getUnitId()) .build(); boolean flag = save(nodeEntity); @@ -811,19 +950,8 @@ public void edit(Long userId, String nodeId, NodeUpdateOpRo opRo) { this.updateNodeCover(userId, nodeId, opRo.getCover(), nodeEntity.getCover()); // Modify whether to display the history of the record - if (ObjectUtil.isNotNull(opRo.getShowRecordHistory()) - && nodeEntity.getType() == NodeType.DATASHEET.getNodeType()) { - boolean flag; - String newValue = JSONUtil.toJsonStr(Dict.create() - .set(NodeExtraConstants.SHOW_RECORD_HISTORY, opRo.getShowRecordHistory())); - if (ObjectUtil.isNotNull(nodeEntity.getExtra())) { - flag = SqlHelper.retBool(baseMapper.updateExtraShowRecordHistoryByNodeId(nodeId, - opRo.getShowRecordHistory())); - } else { - flag = SqlHelper.retBool(baseMapper.updateExtraByNodeId(nodeId, newValue)); - } - ExceptionUtil.isTrue(flag, DatabaseException.EDIT_ERROR); - } + this.updateExtra(nodeId, NodeType.toEnum(nodeEntity.getType()), nodeEntity.getExtra(), + opRo.getShowRecordHistory(), opRo.getEmbedPage()); } private void updateNodeName(Long userId, String nodeId, String name, NodeEntity entity) { @@ -831,7 +959,8 @@ private void updateNodeName(Long userId, String nodeId, String name, NodeEntity return; } // Prevent peer directory, duplicate name modification - String nodeName = duplicateNameModify(entity.getParentId(), entity.getType(), name, nodeId); + String nodeName = duplicateNameModify(entity.getParentId(), entity.getType(), name, nodeId, + entity.getUnitId()); boolean flag = SqlHelper.retBool(baseMapper.updateNameByNodeId(nodeId, nodeName)); ExceptionUtil.isTrue(flag, DatabaseException.EDIT_ERROR); // Correspondingly modify the name. @@ -940,14 +1069,15 @@ public List move(Long userId, NodeMoveOpRo opRo) { String parentId = nodeEntity.getParentId(); // Nodes that record changes in data (front-end requirements) List nodeIds = CollUtil.newArrayList(nodeEntity.getNodeId()); - if (!nodeEntity.getParentId().equals(opRo.getParentId())) { + if (!nodeEntity.getParentId().equals(opRo.getParentId()) + || !nodeEntity.getUnitId().equals(NumberUtil.parseLong(opRo.getUnitId()))) { // move across folders parentId = opRo.getParentId(); // Check whether the new parent node exists and is in the same space - this.checkNodeIfExist(nodeEntity.getSpaceId(), parentId); + this.checkNodeIfExist(nodeEntity.getSpaceId(), parentId, opRo.getUnitId()); name = this.duplicateNameModify(parentId, nodeEntity.getType(), nodeEntity.getNodeName(), - null); + null, NumberUtil.parseLong(opRo.getUnitId())); // The node is a datasheet, and the name changes corresponding to the modification. if (nodeEntity.getType() == NodeType.DATASHEET.getNodeType() && !nodeEntity.getNodeName().equals(name)) { @@ -983,7 +1113,8 @@ public List move(Long userId, NodeMoveOpRo opRo) { // Update the sequence relationship of nodes before // and after the move (D <- E => D <- X <- E) String sufNodeId = - baseMapper.selectNodeIdByParentIdAndPreNodeId(parentId, preNodeId); + baseMapper.selectNodeIdByParentIdAndPreNodeIdAndUnitId(parentId, preNodeId, + nodeEntity.getUnitId()); if (sufNodeId != null) { nodeIds.add(sufNodeId); baseMapper.updatePreNodeIdByNodeId(nodeEntity.getNodeId(), sufNodeId); @@ -991,6 +1122,11 @@ public List move(Long userId, NodeMoveOpRo opRo) { // Update the information of this node (the ID of the previous // node may be updated to null, so update By id is not used) baseMapper.updateInfoByNodeId(nodeEntity.getNodeId(), parentId, preNodeId, name); + List subNodeIds = getNodeIdsInNodeTree(nodeEntity.getNodeId(), -1); + if (!subNodeIds.isEmpty()) { + baseMapper.updateUnitIdByNodeIds(subNodeIds, + NumberUtil.parseLong(opRo.getUnitId())); + } } else { throw new BusinessException("Frequent operations"); } @@ -1033,7 +1169,7 @@ public void deleteById(String spaceId, Long memberId, String... ids) { new HashSet<>(idList)); // Obtain the node ID and the corresponding datasheet ID set of the node // and its child descendants. - List nodeIds = this.getNodeIdsInNodeTree(idList, -1, false); + List nodeIds = this.getNodeIdsInNodeTree(idList, -1, false, new ArrayList<>()); // delete all nodes and child descendants if (CollUtil.isNotEmpty(nodeIds)) { this.nodeDeleteChangeset(nodeIds); @@ -1129,7 +1265,8 @@ public NodeCopyEffectDTO copy(Long userId, NodeCopyOpRo opRo) { String nodeName = StringUtil.format(I18nStringsUtil.t("default_file_copy"), param); String name = - duplicateNameModify(copyNode.getParentId(), copyNode.getType(), nodeName, null); + duplicateNameModify(copyNode.getParentId(), copyNode.getType(), nodeName, null, + copyNode.getUnitId()); CreateNodeDto createNodeDto = CreateNodeDto.builder() .spaceId(copyNode.getSpaceId()) .parentId(copyNode.getParentId()) @@ -1140,6 +1277,7 @@ public NodeCopyEffectDTO copy(Long userId, NodeCopyOpRo opRo) { .icon(copyNode.getIcon()) .cover(copyNode.getCover()) .extra(copyNode.getExtra()) + .unitId(copyNode.getUnitId()) .build(); // Update the former node of the latter node to the copied node (A <- B => A <- A' <- B) baseMapper.updatePreNodeIdBySelf(createNodeDto.getNewNodeId(), opRo.getNodeId(), @@ -1179,6 +1317,8 @@ public NodeCopyEffectDTO copy(Long userId, NodeCopyOpRo opRo) { Collections.singletonList(opRo.getNodeId()), automationCopyOptions, newNodeMap); return copyEffect; + case CUSTOM_PAGE: + return copyEffect; default: break; } @@ -1248,7 +1388,8 @@ private String saveDumpedNode(Long userId, String spaceId, String destParentId, ? options.getNodeId() : IdUtil.createNodeId(nodeType); if (!options.isTemplate()) { // check for the same name - name = duplicateNameModify(destParentId, shareNode.getType(), name, null); + name = duplicateNameModify(destParentId, shareNode.getType(), name, null, + NumberUtil.parseLong(options.getUnitId())); // update the original first node, and move the position one bit later, // that is, the pre-node is the shared node that is transferred. baseMapper.updatePreNodeIdBySelf(toSaveNodeId, null, destParentId); @@ -1305,6 +1446,7 @@ private String saveDumpedNode(Long userId, String spaceId, String destParentId, toSaveNode.setType(shareNode.getType()); toSaveNode.setIcon(shareNode.getIcon()); toSaveNode.setIsTemplate(options.isTemplate()); + toSaveNode.setUnitId(NumberUtil.parseLong(options.getUnitId())); JSONObject extraObj = JSONUtil.parseObj(shareNode.getExtra()); if (StrUtil.isNotBlank(options.getSourceTemplateId())) { extraObj.set(NodeExtraConstants.SOURCE_TEMPLATE_ID, options.getSourceTemplateId()); @@ -1372,9 +1514,13 @@ private void copyFolderProcess(Long userId, String spaceId, String folderId, NodeEntity node = new NodeEntity(); node.setId(IdWorker.getId()); node.setSpaceId(spaceId); + node.setUnitId(NumberUtil.parseLong(options.getUnitId())); node.setParentId(newNodeMap.get(shareTree.getParentId())); node.setNodeId(newNodeMap.get(shareTree.getNodeId())); node.setNodeName(shareTree.getNodeName()); + if (StrUtil.isNotBlank(shareTree.getExtra())) { + node.setExtra(shareTree.getExtra()); + } if (shareTree.getPreNodeId() != null) { // The original pre-node ID, if it is in the filter column, // recursively until the transferred node is found or ends in the first place. @@ -1539,8 +1685,8 @@ public void updateNodeBanStatus(String nodeId, Integer status) { */ @Override public String duplicateNameModify(String parentId, int nodeType, String nodeName, - String nodeId) { - List nameList = baseMapper.selectNameList(parentId, nodeType, nodeId); + String nodeId, Long unitId) { + List nameList = baseMapper.selectNameList(parentId, nodeType, nodeId, unitId); int i = 2; String name = nodeName; while (nameList.contains(name)) { @@ -1648,7 +1794,7 @@ private void createFileMeta(Long userId, String spaceId, String nodeId, Integer JSONUtil.createObj().toString()); break; case AI_CHAT_BOT: - iSpaceService.checkSeatOverLimit(spaceId, 1); + iSpaceService.checkChatBotNumsOverLimit(spaceId); aiServiceFacade.createAi(AiCreateParam.builder() .spaceId(spaceId) .aiId(nodeId) @@ -1719,11 +1865,11 @@ private Map getSuperiorPathByParentIds(List parentIds) { @Override @Transactional(rollbackFor = Exception.class) public String parseExcel(Long userId, String uuid, String spaceId, - Long memberId, String parentNodeId, String viewName, String fileName, - String fileSuffix, InputStream inputStream) { + Long memberId, String parentNodeId, Long unitId, String viewName, + String fileName, String fileSuffix, InputStream inputStream) { MultiSheetReadListener readListener = new MultiSheetReadListener(this, userId, uuid, spaceId, memberId, - parentNodeId, viewName, fileName); + parentNodeId, unitId, viewName, fileName); ExcelTypeEnum excelType = FileSuffixConstants.XLS.equals(fileSuffix) ? ExcelTypeEnum.XLS : ExcelTypeEnum.XLSX; ExcelReaderBuilder readerBuilder = EasyExcel.read(inputStream) @@ -1739,11 +1885,11 @@ public String parseExcel(Long userId, String uuid, String spaceId, @Override @Transactional(rollbackFor = Exception.class) public String parseCsv(Long userId, String uuid, String spaceId, Long memberId, - String parentNodeId, String viewName, String fileName, + String parentNodeId, Long unitId, String viewName, String fileName, InputStream inputStream) { CsvReadListener readListener = new CsvReadListener(this, userId, uuid, spaceId, memberId, - parentNodeId, viewName, fileName); + parentNodeId, unitId, viewName, fileName); try (ExcelReader excelReader = EasyExcel.read(inputStream).excelType(ExcelTypeEnum.CSV) .registerReadListener(readListener).build()) { excelReader.readAll(); @@ -1784,11 +1930,10 @@ public NodeExtra getNodeExtras(String nodeId, String spaceId, String extras) { extras = baseMapper.selectExtraByNodeId(nodeId); } NodeExtraDTO nodeExtraDTO = JSONUtil.toBean(extras, NodeExtraDTO.class); - SocialConnectInfo connectInfo = socialServiceFacade.getConnectInfo(spaceId); + SocialConnectInfo connectInfo = iSpaceService.getSocialConnectInfo(spaceId); if (connectInfo != null && connectInfo.getAppId() != null) { if (connectInfo.isEnabled()) { - String suiteKey = - socialServiceFacade.getSuiteKeyByDingtalkSuiteId(connectInfo.getAppId()); + String suiteKey = iSpaceService.getSocialSuiteKeyByAppId(connectInfo.getAppId()); if (suiteKey != null) { extraVo.setDingTalkSuiteKey(suiteKey); extraVo.setDingTalkDaStatus(nodeExtraDTO.getDingTalkDaStatus()); @@ -1909,7 +2054,8 @@ public boolean isNodeBelongRootFolder(String spaceId, String nodeId) { public List recentList(String spaceId, Long memberId) { List nodeIds = multiDatasourceAdapterTemplate.getRecentlyVisitNodeIds(memberId, NodeType.FOLDER); - List nodeInfos = this.getNodeInfoByNodeIds(spaceId, memberId, nodeIds); + List nodeInfos = this.getNodeInfoByNodeIds(spaceId, memberId, nodeIds).stream() + .filter(i -> !i.getNodePrivate()).toList(); return formatNodeSearchResults(nodeInfos); } @@ -1932,6 +2078,90 @@ public Optional findSameNameInSameLevel(String parentNodeId, .findFirst(); } + @Override + public void deleteMembersNodes(List unitIds) { + if (unitIds.isEmpty()) { + return; + } + baseMapper.updateIsDeletedByUnitIds(unitIds, true); + } + + @Override + public void restoreMembersNodes(List unitIds) { + if (unitIds.isEmpty()) { + return; + } + baseMapper.updateIsDeletedByUnitIds(unitIds, false); + } + + @Override + public Map getCountByUnitIds(List unitIds) { + if (unitIds.isEmpty()) { + return new HashMap<>(0); + } + List privateNodes = baseMapper.selectCountByUnitIds(unitIds); + return privateNodes.stream().collect( + Collectors.toMap(NodeStatisticsDTO::getUnitId, NodeStatisticsDTO::getNodeCount)); + } + + @Override + public Long getUnitIdByNodeId(String nodeId) { + return baseMapper.selectUnitIdByNodeId(nodeId); + } + + @Override + public boolean nodePrivate(String nodeId) { + Long unitId = getUnitIdByNodeId(nodeId); + return !unitId.equals(0L); + } + + @Override + public boolean privateNodeOperation(Long userId, String nodeId) { + Long nodeUnit = getUnitIdByNodeId(nodeId); + // not private node + if (nodeUnit.equals(0L)) { + return true; + } + // check private user equals + Long memberId = getMemberIdByUserIdAndNodeId(userId, nodeId); + Long unitId = iUnitService.getUnitIdByRefId(memberId); + return nodeUnit.equals(unitId); + } + + @Override + public boolean linkByOutsideWidgets(List nodeIds) { + List widgetIds = iWidgetService.getNodeWidgetIds(nodeIds); + if (!widgetIds.isEmpty()) { + List resourceIds = iWidgetService.getWidgetNodeIds(widgetIds); + if (!resourceIds.isEmpty()) { + resourceIds = getExistNodeIdsBySelf(resourceIds); + return !new HashSet<>(nodeIds).containsAll(resourceIds); + } + } + return false; + } + + @Override + public void linkByOutsideResource(String nodeId) { + List nodeIds = new ArrayList<>(); + if (nodeId.startsWith(IdRulePrefixEnum.FOD.getIdRulePrefixEnum())) { + nodeIds = getNodeIdsInNodeTree(nodeId, -1); + } + if (nodeId.startsWith(IdRulePrefixEnum.DST.getIdRulePrefixEnum())) { + nodeIds.add(nodeId); + } + if (nodeIds.isEmpty()) { + return; + } + // check mirror + ExceptionUtil.isTrue(iNodeRelService.relInTheSameFolder(nodeIds), NODE_LINK_FOREIGN_NODE); + // check widgets + ExceptionUtil.isFalse(linkByOutsideWidgets(nodeIds), NODE_LINK_FOREIGN_NODE); + // check automation + ExceptionUtil.isFalse(iAutomationRobotService.linkByOutsideAutomation(nodeIds), + NODE_LINK_FOREIGN_NODE); + } + private List formatNodeSearchResults(List nodeInfoList) { if (CollUtil.isEmpty(nodeInfoList)) { return new ArrayList<>(); @@ -1952,4 +2182,29 @@ private List formatNodeSearchResults(List nodeInfo return results; } + private boolean updateExtra(String nodeId, NodeType nodeType, String oldExtra, + Integer showRecordHistory, + NodeEmbedPageRo embedPage) { + if (null == showRecordHistory && null == embedPage) { + // dont need to update + return true; + } + Dict extra = Dict.create(); + // Modify whether to display the history of the record + if (ObjectUtil.isNotNull(showRecordHistory) && NodeType.DATASHEET.equals(nodeType)) { + extra.set(NodeExtraConstants.SHOW_RECORD_HISTORY, showRecordHistory); + } + // embed page info + if (ObjectUtil.isNotNull(embedPage) && NodeType.CUSTOM_PAGE.equals(nodeType)) { + extra.set(NodeExtraConstants.EMBED_PAGE, embedPage); + } + if (null == oldExtra) { + return SqlHelper.retBool( + baseMapper.insertExtraByNodeId(nodeId, JSONUtil.toJsonStr(extra))); + } else { + return SqlHelper.retBool( + baseMapper.updateExtraByNodeId(nodeId, JSONUtil.toJsonStr(extra))); + } + } + } diff --git a/backend-server/application/src/main/java/com/apitable/workspace/service/impl/NodeShareServiceImpl.java b/backend-server/application/src/main/java/com/apitable/workspace/service/impl/NodeShareServiceImpl.java index 27093e8755..f087a0967e 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/service/impl/NodeShareServiceImpl.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/service/impl/NodeShareServiceImpl.java @@ -37,8 +37,8 @@ import com.apitable.core.util.ExceptionUtil; import com.apitable.core.util.HttpContextUtil; import com.apitable.core.util.SpringContextHolder; -import com.apitable.organization.dto.MemberDTO; -import com.apitable.organization.mapper.MemberMapper; +import com.apitable.organization.entity.MemberEntity; +import com.apitable.organization.service.IMemberService; import com.apitable.organization.service.ITeamService; import com.apitable.shared.constants.AuditConstants; import com.apitable.shared.listener.event.AuditSpaceEvent; @@ -52,10 +52,11 @@ import com.apitable.space.entity.SpaceEntity; import com.apitable.space.enums.AuditSpaceAction; import com.apitable.space.enums.LabsFeatureEnum; -import com.apitable.space.mapper.SpaceMapper; import com.apitable.space.service.ILabsApplicantService; +import com.apitable.space.service.ISpaceService; import com.apitable.space.vo.SpaceGlobalFeature; -import com.apitable.workspace.dto.MemberInfoDTO; +import com.apitable.user.entity.UserEntity; +import com.apitable.user.service.IUserService; import com.apitable.workspace.dto.NodeBaseInfoDTO; import com.apitable.workspace.dto.NodeCopyOptions; import com.apitable.workspace.dto.NodeSharePropsDTO; @@ -100,10 +101,16 @@ public class NodeShareServiceImpl implements INodeShareService { @Resource - private SpaceMapper spaceMapper; + private IUserService iUserService; @Resource - private MemberMapper memberMapper; + private ISpaceService iSpaceService; + + @Resource + private ITeamService iTeamService; + + @Resource + private IMemberService iMemberService; @Resource private NodeMapper nodeMapper; @@ -129,9 +136,6 @@ public class NodeShareServiceImpl implements INodeShareService { @Resource private ControlTemplate controlTemplate; - @Resource - private ITeamService iTeamService; - @Resource private RedisTemplate redisTemplate; @@ -151,17 +155,17 @@ public NodeShareSettingInfoVO getNodeShareSettings(String nodeId) { JSONUtil.toBean(setting.getProps(), NodeShareSettingPropsVO.class)); // turn on sharers String spaceId = nodeMapper.selectSpaceIdByNodeIdIncludeDeleted(nodeId); - MemberDTO dto = - memberMapper.selectDtoByUserIdAndSpaceId(setting.getUpdatedBy(), spaceId); + MemberEntity member = + iMemberService.getByUserIdAndSpaceId(setting.getUpdatedBy(), spaceId); // compatible member no longer in space station - if (dto == null) { + if (member == null) { settingInfoVO.setOperatorHasPermission(false); return settingInfoVO; } - settingInfoVO.setShareOpenOperator(dto.getMemberName()); + settingInfoVO.setShareOpenOperator(member.getMemberName()); // Obtain the node permissions of the sharer ControlRoleDict roleDict = - controlTemplate.fetchNodeRole(dto.getId(), Collections.singletonList(nodeId)); + controlTemplate.fetchNodeRole(member.getId(), Collections.singletonList(nodeId)); if (roleDict.isEmpty()) { settingInfoVO.setOperatorHasPermission(false); } else { @@ -284,7 +288,7 @@ public NodeShareInfoVO getNodeShareInfo(String shareId) { // settings nodeShareInfoVo.setSpaceId(node.getSpaceId()); // Check whether the space has been deleted - SpaceEntity space = spaceMapper.selectBySpaceId(node.getSpaceId()); + SpaceEntity space = iSpaceService.getBySpaceId(node.getSpaceId()); ExceptionUtil.isFalse(Objects.isNull(space) || !Objects.isNull(space.getPreDeletionTime()), NodeException.SHARE_EXPIRE); SpaceGlobalFeature feature = JSONUtil.toBean(space.getProps(), SpaceGlobalFeature.class); @@ -315,14 +319,16 @@ public NodeShareInfoVO getNodeShareInfo(String shareId) { nodeShareInfoVo.setAllowEdit(props.getBool("canBeEdited", false)); } // Get the last operator info - MemberInfoDTO memberInfo = - memberMapper.selectIdByUserIdAndSpaceIdExcludeDelete(setting.getUpdatedBy(), + MemberEntity member = + iMemberService.getByUserIdAndSpaceIdIncludeDeleted(setting.getUpdatedBy(), node.getSpaceId()); - ExceptionUtil.isNotNull(memberInfo, NodeException.SHARE_EXPIRE); - nodeShareInfoVo.setIsDeleted(memberInfo.getIsDeleted()); - MemberDTO member = memberMapper.selectDtoByMemberId(memberInfo.getId()); + ExceptionUtil.isNotNull(member, NodeException.SHARE_EXPIRE); + nodeShareInfoVo.setIsDeleted(member.getIsDeleted()); nodeShareInfoVo.setLastModifiedBy(member.getMemberName()); - nodeShareInfoVo.setLastModifiedAvatar(member.getAvatar()); + UserEntity updatedBy = iUserService.getById(setting.getUpdatedBy()); + if (updatedBy != null) { + nodeShareInfoVo.setLastModifiedAvatar(updatedBy.getAvatar()); + } nodeShareInfoVo.setHasLogin(HttpContextUtil.hasSession()); // If it is a directory node, query the permissions of the sharer and exclude child nodes without permissions. List nodeIds = CollUtil.newArrayList(node.getNodeId()); @@ -335,8 +341,8 @@ public NodeShareInfoVO getNodeShareInfo(String shareId) { } } - ControlRoleDict roleDict = controlTemplate.fetchNodeRole(memberInfo.getId(), nodeIds); - if (roleDict.isEmpty() && memberInfo.getIsDeleted()) { + ControlRoleDict roleDict = controlTemplate.fetchNodeRole(member.getId(), nodeIds); + if (roleDict.isEmpty() && member.getIsDeleted()) { Long rootTeamId = iTeamService.getRootTeamId(node.getSpaceId()); roleDict = controlTemplate.fetchNodeRoleByTeamId(rootTeamId, nodeIds); } @@ -361,6 +367,8 @@ public NodeShareInfoVO getNodeShareInfo(String shareId) { nodeTree.setType(node.getType()); nodeTree.setIcon(node.getIcon()); nodeTree.setChildren(treeList); + nodeTree.setNodePrivate(!node.getUnitId().equals(0L)); + nodeTree.setExtra(node.getExtra()); nodeShareInfoVo.setShareNodeTree(nodeTree); return nodeShareInfoVo; } @@ -468,8 +476,8 @@ public String storeShareData(Long userId, String spaceId, String shareId) { String nodeSpaceId = nodeMapper.selectSpaceIdByNodeId(nodeSetting.getNodeId()); ExceptionUtil.isNotNull(nodeSpaceId, NodeException.SHARE_EXPIRE); // Get the last operator to determine if it does not exist. - MemberInfoDTO member = - memberMapper.selectIdByUserIdAndSpaceIdExcludeDelete(nodeSetting.getUpdatedBy(), + MemberEntity member = + iMemberService.getByUserIdAndSpaceIdIncludeDeleted(nodeSetting.getUpdatedBy(), nodeSpaceId); ExceptionUtil.isNotNull(member.getId(), NodeException.SHARE_EXPIRE); // Obtain the node ID of the node and its child descendants. diff --git a/backend-server/application/src/main/java/com/apitable/workspace/vo/NodeInfoVo.java b/backend-server/application/src/main/java/com/apitable/workspace/vo/NodeInfoVo.java index df5b6b316b..eb5c4e3163 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/vo/NodeInfoVo.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/vo/NodeInfoVo.java @@ -60,6 +60,10 @@ public class NodeInfoVo extends BaseNodeInfo { @JsonIgnore private Boolean isTemplate; + @Schema(description = "Whether it belongs to the private area") + @JsonSerialize(nullsUsing = NullBooleanSerializer.class) + private Boolean nodePrivate; + @Schema(description = "Whether the node is shared") private Boolean nodeShared; @@ -94,6 +98,10 @@ public class NodeInfoVo extends BaseNodeInfo { @Schema(description = "Node Permissions") private NodePermissionView permissions; + + @Schema(description = "Node extra") + private String extra; + /** * Get Column Limit. */ diff --git a/backend-server/application/src/main/java/com/apitable/workspace/vo/NodeShareTree.java b/backend-server/application/src/main/java/com/apitable/workspace/vo/NodeShareTree.java index 9ee252fe16..ed288db6a6 100644 --- a/backend-server/application/src/main/java/com/apitable/workspace/vo/NodeShareTree.java +++ b/backend-server/application/src/main/java/com/apitable/workspace/vo/NodeShareTree.java @@ -20,6 +20,7 @@ import com.apitable.core.support.tree.Tree; import com.apitable.shared.support.serializer.NullArraySerializer; +import com.apitable.shared.support.serializer.NullBooleanSerializer; import com.apitable.shared.support.serializer.NullStringSerializer; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.annotation.JsonSerialize; @@ -55,12 +56,16 @@ public class NodeShareTree implements Tree { @JsonIgnore private String cover; - @JsonIgnore + @Schema(description = "Node extra") private String extra; @Schema(description = "Node Type[1:Folder,2:Datasheet]", example = "1") private Integer type; + @Schema(description = "node private", example = "false") + @JsonSerialize(nullsUsing = NullBooleanSerializer.class) + private Boolean nodePrivate; + @Schema(description = "Child node") @JsonSerialize(nullsUsing = NullArraySerializer.class) private List children; @@ -78,7 +83,7 @@ public String getNodeParentId() { @JsonIgnore @Override - public List getChildrenNodes() { + public List getChildrenNodes() { return this.children; } diff --git a/backend-server/application/src/main/java/com/apitable/workspace/vo/NodeStatisticsVo.java b/backend-server/application/src/main/java/com/apitable/workspace/vo/NodeStatisticsVo.java new file mode 100644 index 0000000000..5eb91096d2 --- /dev/null +++ b/backend-server/application/src/main/java/com/apitable/workspace/vo/NodeStatisticsVo.java @@ -0,0 +1,65 @@ +/* + * APITable + * Copyright (C) 2022 APITable Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.apitable.workspace.vo; + +import com.apitable.shared.support.serializer.NullNumberSerializer; +import com.apitable.shared.support.serializer.NullStringSerializer; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** + * Node Statistics View. + */ +@Data +@Schema(description = "Node Statistics View") +public class NodeStatisticsVo { + + @Schema(description = "Member name") + @JsonSerialize(nullsUsing = NullStringSerializer.class) + private String memberName; + + @Schema(description = "Member id") + @JsonSerialize(nullsUsing = NullStringSerializer.class) + private String memberId; + + @Schema(description = "avatar") + @JsonSerialize(nullsUsing = NullStringSerializer.class) + private String avatar; + + @Schema(description = "avatar color, used for empty avatar") + @JsonSerialize(nullsUsing = NullStringSerializer.class) + private Integer avatarColor; + + @Schema(description = "team name, contact with & ") + @JsonSerialize(nullsUsing = NullStringSerializer.class) + private String teamName; + + @Schema(description = "user's total Node counts") + @JsonSerialize(nullsUsing = NullNumberSerializer.class) + private Integer totalNodeCount; + + @Schema(description = "user's private node counts") + @JsonSerialize(nullsUsing = NullNumberSerializer.class) + private Integer privateNodeCount; + + @Schema(description = "team node counts, teamNodeCount = totalNodeCount - privateNodeCount") + @JsonSerialize(nullsUsing = NullNumberSerializer.class) + private Integer teamNodeCount; +} diff --git a/backend-server/application/src/main/resources/application.yml b/backend-server/application/src/main/resources/application.yml index 2308d061af..de0c58e163 100644 --- a/backend-server/application/src/main/resources/application.yml +++ b/backend-server/application/src/main/resources/application.yml @@ -40,6 +40,10 @@ spring: simple: acknowledge-mode: manual prefetch: 5 + auto-startup: true + retry: + enabled: true + virtual-host: ${RABBITMQ_VHOST:/} mail: host: ${MAIL_HOST:smtp.apitable.com} @@ -75,6 +79,7 @@ const: template-space: ${TEMPLATE_SPACE:spcNTxlv8Drra} quote-template-id: ${QUOTE_TEMPLATE_ID:tpll8mltwrZMT} quoteEn-template-id: ${QUOTE_EN_TEMPLATE_ID:spcNA5eN3Sj6Q} + register-quote-templates: ${REGISTER_QUOTE_TEMPLATES:tplZYaYZqaPLE,tplED3FVnX8U6} ding-talk-order-datasheet: ${DING_TALK_ORDER_DATASHEET:dstbPAnKDwnPpliqg4} cooling-off-period: ${COOLING_OFF_PERIOD:30} close-paused-user-cron: ${CLOSE_PAUSED_USER_CRON:0 0 0 * * ?} @@ -86,6 +91,7 @@ limit: template-max-count: ${TEMPLATE_MAX_COUNT:20} dsb-widget-max-count: ${DSB_WIDGET_MAX_COUNT:30} dst-robot-max-count: ${DST_ROBOT_MAX_COUNT:10} + max-invite-count-for-free: ${MAX_INVITE_COUNT_FOR_FREE:10} socket: domain: ${SOCKET_DOMAIN:http://127.0.0.1:3333/socket} @@ -116,7 +122,7 @@ starter: access-key: ${QINIU_ACCESS_KEY:' '} secret-key: ${QINIU_SECRET_KEY:' '} region: ${QINIU_REGION:z2} - download-domain: ${QINIU_DOWNLOAD_DOMAIN:s1.vika.cn} + download-domain: ${QINIU_DOWNLOAD_DOMAIN:aitable.ai} upload-url: ${QINIU_UPLOAD_URL:https://up-z2.qiniup.com} callback: enabled: ${QINIU_CALLBACK_ENABLED:false} @@ -166,6 +172,7 @@ sentry: environment: ${ENV} use-git-commit-id-as-release: false max-breadcrumbs: 150 + enable-tracing: true traces-sample-rate: 1.0 logging: minimum-breadcrumb-level: debug @@ -196,3 +203,7 @@ system: databus: client: host: ${DATABUS_SERVER_BASE_URL:http://127.0.0.1:8625} + +notification: + callback-url: ${NOTIFICATION_CALLBACK_URL:} + template-ids: ${NOTIFICATION_TEMPLATE_IDS:single_record_member_mention,single_record_comment_mentioned,task_reminder} diff --git a/backend-server/application/src/main/resources/default.properties b/backend-server/application/src/main/resources/default.properties index e50dbdcda4..9afb51fbd4 100644 --- a/backend-server/application/src/main/resources/default.properties +++ b/backend-server/application/src/main/resources/default.properties @@ -20,10 +20,10 @@ spring.datasource.hikari.connection-test-query=SELECT 1 spring.datasource.hikari.auto-commit=true spring.datasource.hikari.pool-name=DatebookHikariCP # lettuce -spring.redis.lettuce.pool.max-idle=8 -spring.redis.lettuce.pool.min-idle=0 -spring.redis.lettuce.pool.max-active=8 -spring.redis.lettuce.pool.max-wait=-1ms +spring.data.redis.lettuce.pool.max-idle=8 +spring.data.redis.lettuce.pool.min-idle=0 +spring.data.redis.lettuce.pool.max-active=8 +spring.data.redis.lettuce.pool.max-wait=-1ms # actuator management.health.mail.enabled=false management.endpoint.health.enabled=true diff --git a/backend-server/application/src/main/resources/mapper/automation/AutomationActionMapper.xml b/backend-server/application/src/main/resources/mapper/automation/AutomationActionMapper.xml index c728ec3771..77434005d8 100644 --- a/backend-server/application/src/main/resources/mapper/automation/AutomationActionMapper.xml +++ b/backend-server/application/src/main/resources/mapper/automation/AutomationActionMapper.xml @@ -52,4 +52,10 @@ `input` = #{updatedInput} WHERE robot_id = #{robotId} + + diff --git a/backend-server/application/src/main/resources/mapper/automation/AutomationActionTypeMapper.xml b/backend-server/application/src/main/resources/mapper/automation/AutomationActionTypeMapper.xml new file mode 100644 index 0000000000..61c67ae330 --- /dev/null +++ b/backend-server/application/src/main/resources/mapper/automation/AutomationActionTypeMapper.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + diff --git a/backend-server/application/src/main/resources/mapper/automation/AutomationRobotMapper.xml b/backend-server/application/src/main/resources/mapper/automation/AutomationRobotMapper.xml index 85dceb4dcd..01f3839f6d 100644 --- a/backend-server/application/src/main/resources/mapper/automation/AutomationRobotMapper.xml +++ b/backend-server/application/src/main/resources/mapper/automation/AutomationRobotMapper.xml @@ -104,4 +104,28 @@ AND rbt.seq_id = #{seqId} AND rbt.is_active = 1 + + + + + UPDATE ${tablePrefix}automation_robot + SET updated_by = #{updatedBy}, updated_at = CURRENT_TIMESTAMP() + WHERE `robot_id` = #{robotId} + AND is_deleted = 0 + + + diff --git a/backend-server/application/src/main/resources/mapper/automation/AutomationRunHistoryMapper.xml b/backend-server/application/src/main/resources/mapper/automation/AutomationRunHistoryMapper.xml new file mode 100644 index 0000000000..64a2d33643 --- /dev/null +++ b/backend-server/application/src/main/resources/mapper/automation/AutomationRunHistoryMapper.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + diff --git a/backend-server/application/src/main/resources/mapper/automation/AutomationTriggerMapper.xml b/backend-server/application/src/main/resources/mapper/automation/AutomationTriggerMapper.xml index 1b53064b8b..0d707830aa 100644 --- a/backend-server/application/src/main/resources/mapper/automation/AutomationTriggerMapper.xml +++ b/backend-server/application/src/main/resources/mapper/automation/AutomationTriggerMapper.xml @@ -79,4 +79,35 @@ AND trigger_type_id = #{triggerTypeId} AND is_deleted = 0 + + + + + + + + diff --git a/backend-server/application/src/main/resources/mapper/organization/MemberMapper.xml b/backend-server/application/src/main/resources/mapper/organization/MemberMapper.xml index 1b3b387268..664f0c3cf2 100644 --- a/backend-server/application/src/main/resources/mapper/organization/MemberMapper.xml +++ b/backend-server/application/src/main/resources/mapper/organization/MemberMapper.xml @@ -249,12 +249,56 @@ where id = #{id} - + SELECT id + FROM ${tablePrefix}unit_member + WHERE user_id = #{userId} + AND space_id = #{spaceId} + AND is_deleted = 0 + ORDER BY id DESC + LIMIT 1 + + + + + + + + + - - - - - - - + SELECT email FROM ${tablePrefix}unit_member WHERE space_id = #{spaceId} - AND email IN - + AND email IN + #{item} AND is_deleted = 0 + - - - - - - - - + SELECT vut.id as id, + vu.id as unitId, + vut.tag_name as tag_name + FROM ${tablePrefix}unit_tag vut + JOIN ${tablePrefix}unit vu ON vut.id = vu.unit_ref_id + WHERE vut.id in + + #{id} + + AND vut.space_id = #{spaceId} + AND vu.is_deleted = 0 + + + \ No newline at end of file diff --git a/backend-server/application/src/main/resources/mapper/organization/TagMemberRelMapper.xml b/backend-server/application/src/main/resources/mapper/organization/TagMemberRelMapper.xml new file mode 100644 index 0000000000..6a5af2a5f1 --- /dev/null +++ b/backend-server/application/src/main/resources/mapper/organization/TagMemberRelMapper.xml @@ -0,0 +1,76 @@ + + + + + + + + INSERT INTO ${tablePrefix}unit_tag_member_rel(id, tag_id, member_id) + VALUES + + + #{item.id},#{item.tagId}, #{item.memberId} + + + + + + + + + + + DELETE FROM ${tablePrefix}unit_tag_member_rel vodmr + WHERE vodmr.tag_id = #{tagId} + AND vodmr.member_id in + + #{item} + + + + + DELETE FROM ${tablePrefix}unit_tag_member_rel vodmr + WHERE vodmr.tag_id = #{tagId} + + + + + + \ No newline at end of file diff --git a/backend-server/application/src/main/resources/mapper/organization/UnitMapper.xml b/backend-server/application/src/main/resources/mapper/organization/UnitMapper.xml index 05c47d7e1e..eb42a2b9e1 100644 --- a/backend-server/application/src/main/resources/mapper/organization/UnitMapper.xml +++ b/backend-server/application/src/main/resources/mapper/organization/UnitMapper.xml @@ -172,13 +172,12 @@ - SELECT feature_key FROM ${tablePrefix}labs_applicant vla - WHERE vla.applicant IN - + SELECT feature_key + FROM ${tablePrefix}labs_applicant + WHERE applicant IN + #{item} - AND vla.is_deleted = 0 + AND is_deleted = 0 - + SELECT * + FROM ${tablePrefix}labs_applicant + WHERE applicant = #{applicant} + AND feature_key = #{featureKey} + AND is_deleted = 0 - - - UPDATE ${tablePrefix}labs_applicant vla SET vla.is_deleted = #{isDeleted} - WHERE vla.id = #{id} - diff --git a/backend-server/application/src/main/resources/mapper/space/SpaceInviteRecordMapper.xml b/backend-server/application/src/main/resources/mapper/space/SpaceInviteRecordMapper.xml index cfb30ed991..784f9f0c36 100644 --- a/backend-server/application/src/main/resources/mapper/space/SpaceInviteRecordMapper.xml +++ b/backend-server/application/src/main/resources/mapper/space/SpaceInviteRecordMapper.xml @@ -19,23 +19,37 @@ - - - update ${tablePrefix}space_invite_record vir - set vir.is_expired = 1 - where vir.invite_email = #{email} and vir.invite_space_id IN - + + UPDATE ${tablePrefix}space_invite_record vir + SET vir.is_expired = 1, + vir.status_desc = #{statusDesc} + WHERE vir.invite_space_id = #{spaceId} + AND vir.invite_email IN + #{item} - + AND vir.is_expired = 0 - - update ${tablePrefix}space_invite_record vir - set vir.is_expired = 1 - where vir.invite_space_id = #{spaceId} and vir.invite_email IN - + + UPDATE ${tablePrefix}space_invite_record vir + SET is_expired = 1, + status_desc = #{statusDesc} + WHERE invite_space_id = #{spaceId} + AND invite_member_id IN + #{item} + AND is_expired = 0 + + + + UPDATE ${tablePrefix}space_invite_record + SET is_expired = 1, + status_desc = #{statusDesc} + WHERE invite_token = #{inviteToken} + AND is_expired = 0 + + diff --git a/backend-server/application/src/main/resources/mapper/space/SpaceMapper.xml b/backend-server/application/src/main/resources/mapper/space/SpaceMapper.xml index 2cf785c480..61c46191ab 100644 --- a/backend-server/application/src/main/resources/mapper/space/SpaceMapper.xml +++ b/backend-server/application/src/main/resources/mapper/space/SpaceMapper.xml @@ -195,4 +195,9 @@ ORDER BY m.updated_at DESC, `status` DESC + diff --git a/backend-server/application/src/main/resources/mapper/space/StaticsMapper.xml b/backend-server/application/src/main/resources/mapper/space/StaticsMapper.xml index 8b7abf1d47..a3b7a9faf6 100644 --- a/backend-server/application/src/main/resources/mapper/space/StaticsMapper.xml +++ b/backend-server/application/src/main/resources/mapper/space/StaticsMapper.xml @@ -50,14 +50,11 @@ and is_rubbish = 0 - + SELECT meta_data -> '$.views[0].rows[*].recordId' + FROM ${tablePrefix}datasheet_meta vdm + WHERE exists(SELECT 1 FROM ${tablePrefix}datasheet vd WHERE vd.dst_id = vdm.dst_id AND vd.space_id = #{spaceId} + AND vd.is_deleted = 0) - - - + SELECT JSON_EXTRACT(meta_data, '$.views[*].type') AS types + FROM ${tablePrefix}datasheet_meta + WHERE dst_id IN + + #{item} + + AND is_deleted = 0 + + + diff --git a/backend-server/application/src/main/resources/mapper/template/TemplateMapper.xml b/backend-server/application/src/main/resources/mapper/template/TemplateMapper.xml index 83406cbc72..5442afed72 100644 --- a/backend-server/application/src/main/resources/mapper/template/TemplateMapper.xml +++ b/backend-server/application/src/main/resources/mapper/template/TemplateMapper.xml @@ -84,6 +84,19 @@ WHERE template_id = #{templateId} AND is_deleted = 0 + + SELECT vw.widget_id, - vw.name AS widgetName, - vwp.cover AS widgetPackageCover, - vwp.icon AS widgetPackageIcon, - vdw.dst_id AS datasheetId, - vn.node_name AS datasheetName + vw.name AS widgetName, + vwp.cover AS widgetPackageCover, + vwp.icon AS widgetPackageIcon, + vdw.dst_id AS datasheetId, + vn.node_name AS datasheetName, + IF(vn.unit_id = 0, 0, 1) node_private FROM ${tablePrefix}widget vw JOIN ${tablePrefix}widget_package vwp ON vw.package_id = vwp.package_id @@ -179,4 +180,14 @@ AND n.is_rubbish = 0 + + diff --git a/backend-server/application/src/main/resources/mapper/workspace/DatasheetMetaMapper.xml b/backend-server/application/src/main/resources/mapper/workspace/DatasheetMetaMapper.xml index f17091fd39..6af060624f 100755 --- a/backend-server/application/src/main/resources/mapper/workspace/DatasheetMetaMapper.xml +++ b/backend-server/application/src/main/resources/mapper/workspace/DatasheetMetaMapper.xml @@ -40,6 +40,16 @@ WHERE dst_id = #{dstId} AND is_deleted = 0 + + + SELECT DISTINCT widget_id + FROM ${tablePrefix}datasheet_widget + WHERE dst_id IN + + #{item} + + diff --git a/backend-server/application/src/main/resources/mapper/workspace/NodeMapper.xml b/backend-server/application/src/main/resources/mapper/workspace/NodeMapper.xml index a0a8d04978..155ec123dc 100644 --- a/backend-server/application/src/main/resources/mapper/workspace/NodeMapper.xml +++ b/backend-server/application/src/main/resources/mapper/workspace/NodeMapper.xml @@ -21,12 +21,13 @@ INSERT INTO ${tablePrefix}node(id, space_id, parent_id, pre_node_id, node_id, node_name, icon, type, cover, is_template, - created_by, updated_by) + created_by, updated_by, extra,unit_id) VALUES #{item.id},#{item.spaceId},#{item.parentId},#{item.preNodeId},#{item.nodeId},#{item.nodeName}, - #{item.icon},#{item.type},#{item.cover},#{item.isTemplate},#{item.createdBy},#{item.updatedBy} + #{item.icon},#{item.type},#{item.cover},#{item.isTemplate},#{item.createdBy},#{item.updatedBy}, + #{item.extra},#{item.unitId} @@ -50,13 +51,16 @@ and node_id != #{nodeId} + + and unit_id = #{unitId} + - @@ -141,7 +146,28 @@ separator="," close=")"> #{item} + + AND unit_id in + + #{item} + + AND is_rubbish = #{isRubbish} + AND is_deleted = 0 + + + @@ -274,7 +307,8 @@ IF(vnss.id IS NULL, 0, 1) node_shared, IF(vc.id IS NULL, 0, 1) node_permit_set, vn.created_at, - vn.updated_at + vn.updated_at, + vn.extra FROM ${tablePrefix}node vn JOIN ${tablePrefix}space vs on vn.space_id = vs.space_id LEFT JOIN ${tablePrefix}node leaf on leaf.parent_id = vn.node_id and leaf.is_rubbish = 0 @@ -286,8 +320,8 @@ WITH RECURSIVE parent_view ( node_id, parent_id, `type`, node_name, - icon, lvl ) AS ( - SELECT node_id, parent_id, `type`, node_name, icon, 0 lvl + icon, lvl, unit_id ) AS ( + SELECT node_id, parent_id, `type`, node_name, icon, 0 lvl, unit_id FROM ${tablePrefix}node WHERE node_id IN AND is_rubbish = 0 UNION ALL - SELECT n.node_id, n.parent_id, n.type, n.node_name, n.icon, pv.lvl + 1 + SELECT n.node_id, n.parent_id, n.type, n.node_name, n.icon, pv.lvl + 1, pv.unit_id FROM parent_view AS pv - JOIN ${tablePrefix}node AS n ON pv.parent_id = n.node_id + JOIN ${tablePrefix}node AS n ON pv.parent_id = n.node_id AND pv.unit_id = n.unit_id AND n.is_rubbish = 0 ) SELECT DISTINCTROW node_id, parent_id, `type`, node_name, icon @@ -545,9 +581,10 @@ SELECT node_id FROM ${tablePrefix}node WHERE space_id = #{spaceId} - AND parent_id = '-1' - AND is_rubbish = 1 - AND is_deleted = 0 + AND parent_id = '-1' + AND unit_id = 0 + AND is_rubbish = 1 + AND is_deleted = 0 AND updated_at > #{beginTime} @@ -581,7 +618,7 @@ WHERE node_id = #{nodeId} AND is_rubbish = 0 - + UPDATE ${tablePrefix}node SET extra = #{extra} WHERE node_id = #{nodeId} AND is_rubbish = 0 @@ -654,4 +691,69 @@ SELECT * FROM ${tablePrefix}node WHERE parent_id = #{parentId} AND is_deleted = 0 + + + UPDATE ${tablePrefix}node + SET extra = JSON_MERGE_PATCH(`extra`, #{extra}) + WHERE node_id = #{nodeId} AND is_rubbish = 0 + + + + UPDATE ${tablePrefix}node + SET is_deleted = #{isDeleted} + WHERE unit_id IN + + #{unitId} + + AND is_rubbish = 0 + + + + + + + + + + + + UPDATE ${tablePrefix}node + SET unit_id = #{unitId} + WHERE node_id IN + + #{unitId} + + AND is_rubbish = 0 + AND is_deleted = 0 + diff --git a/backend-server/application/src/main/resources/mapper/workspace/NodeRelMapper.xml b/backend-server/application/src/main/resources/mapper/workspace/NodeRelMapper.xml index a8c8c3d898..9c5539f00b 100644 --- a/backend-server/application/src/main/resources/mapper/workspace/NodeRelMapper.xml +++ b/backend-server/application/src/main/resources/mapper/workspace/NodeRelMapper.xml @@ -61,4 +61,13 @@ + + diff --git a/backend-server/application/src/main/resources/mapper/workspace/NodeShareSettingMapper.xml b/backend-server/application/src/main/resources/mapper/workspace/NodeShareSettingMapper.xml index cbf603edd1..83bf73b29d 100644 --- a/backend-server/application/src/main/resources/mapper/workspace/NodeShareSettingMapper.xml +++ b/backend-server/application/src/main/resources/mapper/workspace/NodeShareSettingMapper.xml @@ -90,7 +90,7 @@ - SELECT id - FROM ${tablePrefix}automation_service - WHERE service_id = #{serviceId} - AND is_deleted = 0 LIMIT 1 - + - - + + diff --git a/init-db/src/main/resources/db/changelog/1.13/20250116_changeset.xml b/init-db/src/main/resources/db/changelog/1.13/20250116_changeset.xml new file mode 100644 index 0000000000..fa8eee691e --- /dev/null +++ b/init-db/src/main/resources/db/changelog/1.13/20250116_changeset.xml @@ -0,0 +1,31 @@ + + + + + + Add resource id to alarm + + ALTER TABLE `${table.prefix}datasheet_record_alarm` ADD COLUMN `resource_id` varchar(50) CHARACTER SET utf8mb4 COLLATE + utf8mb4_unicode_ci DEFAULT NULL COMMENT 'Resource ID(node_id/..)' AFTER `dst_id`; + + + diff --git a/init-db/src/main/resources/db/changelog/1.13/master.xml b/init-db/src/main/resources/db/changelog/1.13/master.xml new file mode 100644 index 0000000000..fc0506117c --- /dev/null +++ b/init-db/src/main/resources/db/changelog/1.13/master.xml @@ -0,0 +1,26 @@ + + + + + + + diff --git a/init-db/src/main/resources/db/changelog/db.changelog-master.xml b/init-db/src/main/resources/db/changelog/db.changelog-master.xml index 48f8226e46..1dffc07a41 100644 --- a/init-db/src/main/resources/db/changelog/db.changelog-master.xml +++ b/init-db/src/main/resources/db/changelog/db.changelog-master.xml @@ -41,4 +41,6 @@ + + diff --git a/package.json b/package.json index ce7ede5e5f..a09f9a9784 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "root", - "version": "1.6.0", + "version": "1.13.0", "private": true, "scripts": { "preinstall": "npx only-allow pnpm", @@ -13,6 +13,7 @@ "start:i18n": "nx start @apitable/i18n-lang", "start:datasheet": "cd packages/datasheet && pnpm run dev", "lint:datasheet": "nx check:lint @apitable/datasheet", + "storybook:components": "nx storybook @apitable/components", "start:widget-sdk": "nx start @apitable/widget-sdk", "start:room-server": "nx start:dev @apitable/room-server ", "start:socket-server": "nx start:socket:dev @apitable/room-server", @@ -22,7 +23,6 @@ "build:room-server": "nx run @apitable/room-server:build", "build:datasheet": "nx run @apitable/datasheet:build", "build:api-client": "nx run @apitable/api-client:build", - "build:ai-components": "node build.js", "build:dst:pre": "nx run-many -t build -p @apitable/i18n-lang @apitable/core @apitable/icons @apitable/components @apitable/ai @apitable/widget-sdk --parallel=5 && pnpm build:api-client", "build:dst": "nx run --verbose @apitable/datasheet:build", "build:air-agent:pre": "nx run-many -t build -p @apitable/i18n-lang @apitable/icons @apitable/core @apitable/components @apitable/ai --parallel=5", @@ -65,7 +65,6 @@ "pnpm": "^8" }, "devDependencies": { - "git-format-staged": "^3.0.0", "@babel/core": "7.22.20", "@commitlint/cli": "17.7.1", "@commitlint/config-conventional": "17.7.0", @@ -73,6 +72,7 @@ "@swc/core": "^1.3.86", "@swc/jest": "^0.2.29", "@types/dot-object": "^2.1.2", + "@types/jest": "^29.5.11", "@types/lru-cache": "^7.10.9", "@types/node": "^20.6.2", "@typescript-eslint/eslint-plugin": "^6.7.2", @@ -85,6 +85,7 @@ "dotenv": "16.3.1", "dotenv-expand": "10.0.0", "eslint": "^8.49.0", + "eslint-config-prettier": "^8", "eslint-config-react-app": "7.0.1", "eslint-plugin-flowtype": "8.0.3", "eslint-plugin-import": "2.28.1", @@ -92,17 +93,18 @@ "eslint-plugin-react": "^7.33.2", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-vika": "0.0.1", + "git-format-staged": "^3.0.0", "husky": "8.0.3", "lint-staged": "14.0.1", "lodash": "^4.17.21", - "nx": "latest", + "nx": "16.10.0", "prettier": "^3.0.3", "pretty-quick": "^3.1.3", "quicktype": "^23.0.75", "svgo": "^3.0.2", "ts-node": "^10.9.1", - "typescript": "4.8.2", - "ts-pnp": "1.2.0" + "ts-pnp": "1.2.0", + "typescript": "4.8.2" }, "resolutions": { "node-gyp": "9.3.1", @@ -130,7 +132,11 @@ "node-gyp": "*" } } - } + }, + "patchedDependencies": { + "mysql2@3.9.7": "patches/mysql2@3.9.7.patch" + }, + "allowNonAppliedPatches": true }, "dependencies": { "glob-parent": "5.1.2", diff --git a/packages/ai-components/.eslintrc b/packages/ai-components/.eslintrc new file mode 100644 index 0000000000..7ab0e10e37 --- /dev/null +++ b/packages/ai-components/.eslintrc @@ -0,0 +1,122 @@ +{ + "extends": [ + "../../.eslintrc" + ], + "plugins": ["import"], + // "parserOptions": { + // "project": "./tsconfig.json" + // }, + "rules": { + "import/no-duplicates": [ + "warn", + { + "considerQueryString": true + } + ], + "import/order": [ + "warn", + { + "groups": [ + "builtin", + "external", + "internal", + "parent", + "sibling", + "index" + ], + "pathGroups": [ + { + "pattern": "@apitable/**", + "group": "external", + "position": "after" + }, + { + "pattern": "pc/**", + "group": "internal", + "position": "after" + }, + { + "pattern": "static/**", + "group": "internal", + "position": "after" + }, + { + "pattern": "enterprise/**", + "group": "sibling", + "position": "after" + }, + { + "pattern": "./*.less", + "group": "index", + "position": "after" + }, + { + "pattern": "./*.module.less", + "group": "index", + "position": "after" + } + ], + "pathGroupsExcludedImportTypes": [ + "builtin" + ], + "alphabetize": { + "order": "asc", + "caseInsensitive": true + } + } + ], + "comma-spacing": [ + "warn", + { + "before": false, + "after": true + } + ], + "react/display-name": 0, + "react/no-find-dom-node": 0, + "react/no-unknown-property": 1, + "no-restricted-imports": [ + "error", + { + "paths": [ + { + "name": "@apitable/components", + "importNames": [ + "Select" + ], + "message": "Please use tooltip DropdownSelect from '@apitable/components instead ." + }, + { + "name": "pc/components/common/tooltip", + "importNames": [ + "Tooltip" + ], + "message": "Please use tooltip FloatUiTooltip from '@apitable/components instead ." + }, + { + "name": "pc/components/common", + "importNames": [ + "Tooltip" + ], + "message": "Please use tooltip FloatUiTooltip from '@apitable/components instead ." + }, + { + "name": "react-custom-scrollbars", + "importNames": [ + "Scrollbars" + ], + "message": "Please use ScrollBar from pc/components/scroll_bar instead." + } + ] + } + ], + "@typescript-eslint/no-unused-vars": [ + "warn", + { + "argsIgnorePattern": "^_" + } + ] + // "@typescript-eslint/no-misused-promises": 1, + // "@typescript-eslint/no-floating-promises": 1 + } +} diff --git a/packages/ai-components/.gitignore b/packages/ai-components/.gitignore new file mode 100644 index 0000000000..196982123d --- /dev/null +++ b/packages/ai-components/.gitignore @@ -0,0 +1,6 @@ +node_modules +dist +.DS_Store +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/packages/ai-components/.npmignore b/packages/ai-components/.npmignore new file mode 100644 index 0000000000..faaede70a4 --- /dev/null +++ b/packages/ai-components/.npmignore @@ -0,0 +1,20 @@ +# The current package will be released to npm, +# and only d.ts will be kept in npm without source code, +# and all unnecessary sensitive information will be discharged in +.yarn +src +dist/**/*.d.ts.map +tsconfig*.json +docs/ +READ.dev.md +setup.ts +styleguide/ +styleguide.config.js +typings.json +typings/ +.storybook +.env +.gitignore +jest.config.js +sonar-project.properties +README.md diff --git a/packages/ai-components/README.md b/packages/ai-components/README.md new file mode 100644 index 0000000000..85520dde05 --- /dev/null +++ b/packages/ai-components/README.md @@ -0,0 +1,17 @@ +# APITable Components + +A Design System with React、styled-components and Typescript. + +## Install + +```bash +yarn add @apitable/components +``` + +## Usage + +```javascript +import { Select } from '@apitable/components'; +``` + + diff --git a/packages/ai-components/build.js b/packages/ai-components/build.js index cbbf460018..7dfe6a4876 100644 --- a/packages/ai-components/build.js +++ b/packages/ai-components/build.js @@ -1,12 +1,12 @@ const { exec } = require('child_process'); const fs = require('fs'); -const configFile = 'rollup.config.js'; +const dir = 'src'; // Check if the file exists -fs.access(configFile, fs.constants.F_OK, (err) => { +fs.access(dir, fs.constants.F_OK, (err) => { if (err) { - console.error(`${configFile} does not exist, no compilation will be performed.`); + console.error(`${dir} does not exist, no compilation will be performed.`); } else { // File exists, execute the rollup -c command exec('rm -rf ./dist && rollup -c --bundleConfigAsCjs && tsc-alias', (error, stdout, stderr) => { diff --git a/packages/ai-components/package.json b/packages/ai-components/package.json index 0eca2afa4b..0c163f0884 100644 --- a/packages/ai-components/package.json +++ b/packages/ai-components/package.json @@ -1,6 +1,6 @@ { "name": "@apitable/ai", - "version": "1.6.0", + "version": "1.13.0", "main": "dist/index.js", "typings": "dist/index.d.ts", "author": "APITable Ltd. ", @@ -11,9 +11,9 @@ "access": "public" }, "dependencies": { - "@apitable/components": "*", - "@apitable/core": "*", - "@apitable/icons": "*" + "@apitable/components": "workspace:*", + "@apitable/core": "workspace:*", + "@apitable/icons": "workspace:*" }, "devDependencies": { "@rollup/plugin-alias": "^5.0.1", @@ -28,7 +28,7 @@ "@types/react": "18.0.2", "@types/react-dom": "^18.0.2", "concurrently": "^7.2.2", - "eslint": "^7.21.0", + "eslint": "^8.49.0", "eslint-config-next": "^12.2.2", "eslint-plugin-import": "2.28.1", "less": "4.1.3", @@ -45,6 +45,7 @@ "@rjsf5/core": "npm:@rjsf/core@^5.13.2", "@rjsf5/utils": "npm:@rjsf/utils@^5.13.2", "@rjsf5/validator-ajv8": "npm:@rjsf/validator-ajv8@^5.13.2", + "antd-mobile": "5.32.4", "ahooks": "^3.5.0", "ajv-i18n": "^4.2.0", "antd": "4.23.5", diff --git a/packages/ai-components/prettier.config.js b/packages/ai-components/prettier.config.js new file mode 100644 index 0000000000..bd66771777 --- /dev/null +++ b/packages/ai-components/prettier.config.js @@ -0,0 +1,10 @@ +/** @type {import("prettier").Config} */ +module.exports = { + bracketSpacing: true, + printWidth: 150, + semi: true, + singleQuote: true, + tabWidth: 2, + trailingComma: 'all', + useTabs: false, +}; diff --git a/packages/ai-components/rollup.config.js b/packages/ai-components/rollup.config.js new file mode 100644 index 0000000000..ee33e409a8 --- /dev/null +++ b/packages/ai-components/rollup.config.js @@ -0,0 +1,39 @@ +import * as path from 'path'; +import alias from '@rollup/plugin-alias'; +import commonjs from '@rollup/plugin-commonjs'; +import image from '@rollup/plugin-image'; +import json from '@rollup/plugin-json'; +import typescript from '@rollup/plugin-typescript'; +import postcss from 'rollup-plugin-postcss'; +import tailwindcss from 'tailwindcss'; + +export default { + input: 'src/index.ts', + output: { + // file: 'dist/index.esm.js', + format: 'es', + dir: 'dist', + preserveModules: true, + preserveModulesRoot: 'src' + }, + plugins: [ + commonjs(), + typescript({ + noEmitOnError: false, + }), + json(), + image(), + postcss({ + // extract: false, + extensions: ['.css', '.less'], + plugins: [tailwindcss], + modules: { + localsConvention: 'camelCase', + }, + }), + alias({ + entries: [{ find: 'static', replacement: path.resolve(path.resolve(__dirname), 'src/static') }], + }), + ], + external: ['tslib'] +}; diff --git a/packages/ai-components/tailwind.config.js b/packages/ai-components/tailwind.config.js new file mode 100644 index 0000000000..879893da6e --- /dev/null +++ b/packages/ai-components/tailwind.config.js @@ -0,0 +1,13 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + prefix: 'vk-', + darkMode: ['class'], + content: ['./src/**/*.{js,ts,jsx,tsx,mdx}'], + theme: { + extend: {}, + }, + corePlugins: { + preflight: false, + }, + plugins: [], +}; diff --git a/packages/ai-components/tsconfig.json b/packages/ai-components/tsconfig.json new file mode 100644 index 0000000000..26df2f9a76 --- /dev/null +++ b/packages/ai-components/tsconfig.json @@ -0,0 +1,47 @@ +{ + "extends": "../../common-tsconfig.json", + "compilerOptions": { + "baseUrl": ".", + "target": "ES2017", + "allowJs": true, + "strict": true, + "isolatedModules": true, + "noEmit": true, + "incremental": false, + "noImplicitThis": true, + "noImplicitAny": false, + "declaration": true, + "declarationMap": true, + "alwaysStrict": true, + "strictNullChecks": false, + "noUnusedLocals": false, + "noImplicitReturns": true, + "noImplicitOverride": true, + "noFallthroughCasesInSwitch": true, + "useUnknownInCatchVariables": false, + "noUnusedParameters": false, + "strictBindCallApply": true, + "strictFunctionTypes": true, + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "module": "ESNext", + "jsx": "react-jsx", + "outDir": "dist", + "paths": { + "@/*": [ + "src/*" + ] + } + }, + "include": [ + "src/*", + "dist/*" + ], + "exclude": [ + "node_modules", + "dist" + ] +} \ No newline at end of file diff --git a/packages/components/package.json b/packages/components/package.json index f630463249..ebc607b30c 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,6 +1,6 @@ { "name": "@apitable/components", - "version": "1.6.0", + "version": "1.13.0", "main": "dist/index.js", "typings": "dist/index.d.ts", "author": "APITable Ltd. ", @@ -11,13 +11,15 @@ "access": "public" }, "dependencies": { - "@apitable/core": "*", - "@apitable/icons": "*", + "@apitable/core": "workspace:*", + "cron-time-generator": "^2.0.1", + "@apitable/icons": "workspace:*", "@apitable/react-contexify": "^5.0.7", - "@floating-ui/dom": "^1.5.1", - "@floating-ui/react": "0.24.5", + "@floating-ui/dom": "^1.5.3", + "@floating-ui/react": "^0.26.4", "@rjsf/core": "^4.2.3", "ahooks": "^3.5.0", + "purify-ts": "^2.0.1", "antd": "4.23.5", "classnames": "2.2.6", "color": "^3.1.3", @@ -28,6 +30,7 @@ "rc-trigger": "^5.3.3", "rc-util": "^5.24.4", "react-color": "^2.19.3", + "cron-parser": "^4.9.0", "react-dnd": "^16.0.1", "react-dnd-html5-backend": "^11.1.3", "react-draggable": "^4.0.3", @@ -39,7 +42,6 @@ "styled-system": "^5.1.5" }, "devDependencies": { - "@jest/types": "^29.6.1", "@mdx-js/react": "^1.6.22", "@storybook/addon-a11y": "^6.3.8", "@storybook/addon-actions": "^6.3.6", @@ -55,7 +57,8 @@ "@testing-library/react": "^12.0.0", "@types/classnames": "^2.2.10", "@types/color": "^3.0.1", - "@types/jest": "^29.2.1", + "@jest/types": "^29.6.3", + "@types/jest": "^29.5.11", "@types/lodash": "^4.14.197", "@types/mdx-js__react": "^1", "@types/node": "^14.14.34", @@ -66,17 +69,18 @@ "@types/react-is": "^17.0.0", "@types/react-window": "^1.8.1", "@types/resize-observer-browser": "^0.1.5", - "@types/styled-components": "^5.1.26", + "@types/styled-components": "5.1.26", "@types/styled-system": "^5.1.11", "babel-jest": "^26.6.0", + "dayjs": "1.11.10", "chromatic": "^5.10.1", "concurrently": "^7.2.2", - "jest": "^29.6.2", - "jest-environment-jsdom": "^29.2.2", + "jest": "^29.7.0", + "jest-environment-jsdom": "^29.7.0", "react-dom": "18.2.0", "storybook-addon-designs": "^6.1.0", "styled-components": "5.3.6", - "ts-jest": "28.0.3", + "ts-jest": "^29.1.1", "tsc-alias": "^1.6.11", "tsconfig-paths-webpack-plugin": "^3.5.1", "typescript": "4.8.2" @@ -89,6 +93,7 @@ "build": "rm -rf ./dist && tsc && tsc-alias", "start": "concurrently \"tsc -w\" \"tsc-alias -w\"", "test": "jest", + "test:util": "jest timing", "test:cov": "jest --coverage", "storybook": "start-storybook -p 6006", "storybook-docs": "start-storybook --docs --no-manager-cache", diff --git a/packages/components/src/colors/dark.ts b/packages/components/src/colors/dark.ts index 6bbb14747e..cc97062ca9 100644 --- a/packages/components/src/colors/dark.ts +++ b/packages/components/src/colors/dark.ts @@ -1,4 +1,3 @@ - export const rc07 = '#FFAB00'; export const rc11 = '#6E382D'; export const rc00 = '#B35FF5'; @@ -11,8 +10,8 @@ export const rc10 = '#E33E38'; export const rc03 = '#55CDFF'; export const rc01 = '#7B67EE'; export const rc04 = '#30C28B'; -export const bgBglessSolidActive = 'rgba(62, 62, 62, 1)'; -export const bgBglessSolidHover = 'rgba(43, 43, 43, 1)'; +export const bgBglessActiveSolid = 'rgba(62, 62, 62, 1)'; +export const bgBglessHoverSolid = 'rgba(43, 43, 43, 1)'; export const bgStaticLightDisabled = 'rgba(255, 255, 255, 0.5)'; export const bgStaticLightActive = 'rgba(255, 255, 255, 0.68)'; export const bgStaticLightHover = 'rgba(255, 255, 255, 0.84)'; @@ -21,9 +20,9 @@ export const bgControlsDegradeDefault = 'rgba(0, 0, 0, 0.12)'; export const bgControlsDefaultSolid = 'rgba(43, 43, 43, 1)'; export const bgControlsHoverSolid = 'rgba(62, 62, 62, 1)'; export const bgControlsActiveSolid = 'rgba(80, 80, 80, 1)'; -export const bgBrandLightActiveSolid = 'rgba(63, 58, 94, 1)'; -export const bgBrandLightHoverSolid = 'rgba(54, 49, 77, 1)'; -export const bgBrandLightDefaultSolid = 'rgba(44, 41, 59, 1)'; +export const bgBrandLightActiveSolid = 'rgba(120, 107, 197, 1)'; +export const bgBrandLightHoverSolid = 'rgba(97, 87, 154, 1)'; +export const bgBrandLightDefaultSolid = 'rgba(73, 66, 111, 1)'; export const bgLogoText = 'rgba(255, 255, 255, 0.85)'; export const bgLogoIcon = 'rgba(255, 255, 255, 0.85)'; export const rainbowGray4 = 'rgba(181, 181, 181, 0.8)'; @@ -146,8 +145,8 @@ export const bgTagDefault = 'rgba(255, 255, 255, 0.16)'; export const bgTagHover = 'rgba(255, 255, 255, 0.24)'; export const bgTagActive = 'rgba(255, 255, 255, 0.32)'; export const bgTagDisabled = 'rgba(255, 255, 255, 0.08)'; -export const bgScrollbarDefault = 'rgba(255, 255, 255, 0.16)'; -export const bgScrollbarHover = 'rgba(255, 255, 255, 0.24)'; +export const bgScrollbarDefault = 'rgba(88, 89, 89, 1)'; +export const bgScrollbarHover = 'rgba(114,114,115,1)'; export const bgScrollbarActive = 'rgba(255, 255, 255, 0.32)'; export const bgMaskDefault = 'rgba(0, 0, 0, 0.72)'; export const bgBrandDefault = 'rgba(144, 127, 240, 1)'; diff --git a/packages/components/src/colors/light.ts b/packages/components/src/colors/light.ts index 33591d8d37..486a661689 100644 --- a/packages/components/src/colors/light.ts +++ b/packages/components/src/colors/light.ts @@ -17,8 +17,8 @@ export const rc10 = '#E33E38'; export const rc03 = '#55CDFF'; export const rc01 = '#7B67EE'; export const rc04 = '#30C28B'; -export const bgBglessSolidActive = 'rgba(230, 230, 230, 1)'; -export const bgBglessSolidHover = 'rgba(243, 243, 243, 1)'; +export const bgBglessActiveSolid = 'rgba(230, 230, 230, 1)'; +export const bgBglessHoverSolid = 'rgba(243, 243, 243, 1)'; export const bgStaticLightDisabled = 'rgba(255, 255, 255, 0.5)'; export const bgStaticLightActive = 'rgba(255, 255, 255, 0.68)'; export const bgStaticLightHover = 'rgba(255, 255, 255, 0.84)'; @@ -27,9 +27,9 @@ export const bgControlsDegradeDefault = 'rgba(51, 51, 51, 0.04)'; export const bgControlsDefaultSolid = 'rgba(245, 245, 245, 1)'; export const bgControlsHoverSolid = 'rgba(232, 232, 232, 1)'; export const bgControlsActiveSolid = 'rgba(219, 219, 219, 1)'; -export const bgBrandLightActiveSolid = 'rgba(197, 188, 247, 1)'; -export const bgBrandLightHoverSolid = 'rgba(225, 220, 252, 1)'; -export const bgBrandLightDefaultSolid = 'rgba(244, 242, 255, 1)'; +export const bgBrandLightActiveSolid = 'rgba(144, 127, 240, 1)'; +export const bgBrandLightHoverSolid = 'rgba(168, 154, 245, 1)'; +export const bgBrandLightDefaultSolid = 'rgba(216, 210, 252, 1)'; export const bgLogoText = 'rgba(0, 6, 80, 1)'; export const bgLogoIcon = 'rgba(123, 103, 238, 1)'; export const rainbowGray4 = 'rgba(194, 194, 194, 1)'; @@ -152,8 +152,8 @@ export const bgTagDefault = 'rgba(51, 51, 51, 0.12)'; export const bgTagHover = 'rgba(51, 51, 51, 0.18)'; export const bgTagActive = 'rgba(51, 51, 51, 0.24)'; export const bgTagDisabled = 'rgba(51, 51, 51, 0.06)'; -export const bgScrollbarDefault = 'rgba(219, 219, 219, 1)'; -export const bgScrollbarHover = 'rgba(207, 207, 207, 1)'; +export const bgScrollbarDefault = 'rgba(192, 193,194, 1)'; +export const bgScrollbarHover = 'rgba(172, 173,173, 1)'; export const bgScrollbarActive = 'rgba(194, 194, 194, 1)'; export const bgMaskDefault = 'rgba(0, 0, 0, 0.5)'; export const bgBrandDefault = 'rgba(123, 103, 238, 1)'; diff --git a/packages/components/src/components/avatar/avatar.tsx b/packages/components/src/components/avatar/avatar.tsx index 9fb407538e..76a8f31c02 100644 --- a/packages/components/src/components/avatar/avatar.tsx +++ b/packages/components/src/components/avatar/avatar.tsx @@ -28,7 +28,8 @@ export const Avatar: FC> = ({ alt, children, style, - shape = 'circle' + shape = 'circle', + onClick }) => { const avatarNodeRef = useRef(null); const avatarChildrenRef = useRef(null); @@ -76,7 +77,7 @@ export const Avatar: FC> = ({ setScale(scale()); }, [src, icon, size]); - const wrapperProps = { size, src, shape, icon, style }; + const wrapperProps = { size, src, shape, icon, style, onClick }; return ( diff --git a/packages/components/src/components/avatar/avatar_group/avatar_group.tsx b/packages/components/src/components/avatar/avatar_group/avatar_group.tsx index b93fea61ae..cf44cb2a3a 100644 --- a/packages/components/src/components/avatar/avatar_group/avatar_group.tsx +++ b/packages/components/src/components/avatar/avatar_group/avatar_group.tsx @@ -17,26 +17,33 @@ */ import React, { cloneElement, FC, ReactElement } from 'react'; -import { IAvatarGroup } from './intarface'; +import { IAvatarGroup } from './interface'; import { AvatarGroupStyled } from './styled'; import { Avatar } from '../index'; +import { Popover } from 'antd'; -export const AvatarGroup: FC> = ({ - max = 5, children, maxStyle, size -}) => { +export const AvatarGroup: FC> = ({ max = 5, children, maxStyle, size, popoverContent }) => { const childrenArr = (Array.isArray(children) ? children : [children]).map((child, index) => - cloneElement((child as ReactElement), { + cloneElement(child as ReactElement, { key: `avatar-key-${index}`, size, - }), + }) ); + const numOfChildren = childrenArr.length; - const isHidden = numOfChildren > max; - const childrenShow = isHidden ? childrenArr.slice(0, max) : children; + const isOverMax = numOfChildren > max; + const childrenShow = isOverMax ? childrenArr.slice(0, max) : children; + return ( {childrenShow} - {isHidden && +{numOfChildren - max}} + {isOverMax && ( + + + +{numOfChildren - max} + + + )} ); -}; \ No newline at end of file +}; diff --git a/packages/components/src/components/avatar/avatar_group/intarface.ts b/packages/components/src/components/avatar/avatar_group/interface.ts similarity index 94% rename from packages/components/src/components/avatar/avatar_group/intarface.ts rename to packages/components/src/components/avatar/avatar_group/interface.ts index 1ee08c55cd..96ab8e2990 100644 --- a/packages/components/src/components/avatar/avatar_group/intarface.ts +++ b/packages/components/src/components/avatar/avatar_group/interface.ts @@ -27,4 +27,8 @@ export interface IAvatarGroup { * avatar inline style */ maxStyle?: React.CSSProperties; -} \ No newline at end of file + /** + * popover + */ + popoverContent?: React.ReactNode; +} diff --git a/packages/components/src/components/avatar/avatar_group/styled.ts b/packages/components/src/components/avatar/avatar_group/styled.ts index eeb5b5e2ec..00ebb44adb 100644 --- a/packages/components/src/components/avatar/avatar_group/styled.ts +++ b/packages/components/src/components/avatar/avatar_group/styled.ts @@ -18,7 +18,7 @@ import styled, { css } from 'styled-components'; import { AvatarSizeConfig } from '../styled'; -import { IAvatarGroup } from './intarface'; +import { IAvatarGroup } from './interface'; export const AvatarGroupStyled = styled.div>` display: inline-flex; @@ -29,12 +29,11 @@ export const AvatarGroupStyled = styled.div>` } box-sizing: content-box; ${(props) => { - const sizeKey = props.size || 'm'; - const { size, borderWidth } = AvatarSizeConfig[sizeKey]; - return css` + const sizeKey = props.size || 'm'; + const { size, borderWidth } = AvatarSizeConfig[sizeKey]; + return css` margin-left: -${size / 4}px; border: ${borderWidth}px solid #fff; - `; - } -} -`; \ No newline at end of file + `; + }} +`; diff --git a/packages/components/src/components/avatar/interface.ts b/packages/components/src/components/avatar/interface.ts index 299d9e6873..570847ab57 100644 --- a/packages/components/src/components/avatar/interface.ts +++ b/packages/components/src/components/avatar/interface.ts @@ -35,4 +35,5 @@ export interface IAvatarProps { className?: string; /** avatar image alt attribute */ alt?: string; + onClick?: (e: React.MouseEvent) => void; } \ No newline at end of file diff --git a/packages/components/src/components/box/box.tsx b/packages/components/src/components/box/box.tsx index 5e9de57505..b485c4bbcf 100644 --- a/packages/components/src/components/box/box.tsx +++ b/packages/components/src/components/box/box.tsx @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -import styled from 'styled-components'; +import styled from 'styled-components'; import { space, SpaceProps, color, ColorProps, @@ -32,7 +32,9 @@ import { } from 'styled-system'; type IBoxProps = SpaceProps & LayoutProps & ColorProps & FlexboxProps & TypographyProps - & GridProps & BackgroundProps & BorderProps & PositionProps & ShadowProps; + & GridProps & BackgroundProps & BorderProps & PositionProps & ShadowProps & { + gap?: string | number; +}; export const Box: any = styled.div( compose( @@ -46,5 +48,5 @@ export const Box: any = styled.div( border, position, shadow, - ) -); \ No newline at end of file + ), +); diff --git a/packages/components/src/components/calendar/calendar.tsx b/packages/components/src/components/calendar/calendar.tsx index 5db2abb172..175f0be64e 100644 --- a/packages/components/src/components/calendar/calendar.tsx +++ b/packages/components/src/components/calendar/calendar.tsx @@ -32,8 +32,9 @@ import classNames from 'classnames'; import { configResponsive, useResponsive } from 'ahooks'; import { useTouch, Direction } from '../../hooks/use-touch'; import format from 'date-fns/format'; +import { isValid } from 'date-fns'; -export const Calendar:FC> = props => { +export const Calendar: FC> = (props) => { const { defaultDate, monthPicker, ...rest } = props; configResponsive({ middle: 768, @@ -41,19 +42,16 @@ export const Calendar:FC> = props => { const responsive = useResponsive(); const isMobile = !responsive.middle; const [step, setStep] = useState(0); - const defaultDate2Month = defaultDate && format(defaultDate, FORMAT_MONTH); + const defaultDate2Month = defaultDate && isValid(defaultDate) ? format(defaultDate, FORMAT_MONTH) : ''; // Update of annual and monthly changes useEffect(() => { if (defaultDate2Month) { - const currStep = differenceInMonths(date2Month(defaultDate), date2Month(new Date())); + const currStep = differenceInMonths(date2Month(defaultDate!), date2Month(new Date())); setStep(currStep); } - // eslint-disable-next-line + // eslint-disable-next-line }, [defaultDate2Month]); - const { year, month } = useMemo(() => - getPanelData(step), - [step] - ); + const { year, month } = useMemo(() => getPanelData(step), [step]); const touch = useTouch(); const [isChangeMonth, setChangeMonth] = useState(false); @@ -74,13 +72,21 @@ export const Calendar:FC> = props => { - {isMobile ? : + {isMobile ? ( - } - {monthPicker ? monthPicker(formatDate(year, month, lang)) : {formatDate(year, month, lang)}} - {isMobile ? : + ) : ( + + + + )} + {monthPicker ? monthPicker(`${year}-${month}`) : {formatDate(year, month, lang)}} + {isMobile ? ( - } + ) : ( + + + + )} @@ -185,6 +296,61 @@ export const DropdownSelectDisabled = () => { ); }; +export const DropdownSelectMaxContent = () => { + const data: { + label: string; + value: string; + }[] = []; + for (let i = 0; i < 20; i++) { + data.push({ + label: + 'Test dataTest dataTest dataTest dataTest dataTest dataTest dataTest dataTest dataTest dataTest dataTest dataTest dataTest dataTest dataTest dataTest data' + + i, + value: 'opt' + i, + }); + } + const data1: { + label: string; + value: string; + }[] = []; + for (let i = 0; i < 20; i++) { + data1.push({ label: 'Test ' + i, value: 'opt' + i }); + } + const [value, setValue] = React.useState('opt15'); + return ( + + { + setValue(option.value as string); + }} + /> + { + setValue(option.value as string); + }} + /> + + ); +}; + export const DropdownSelectItem = () => { const [value, setValue] = React.useState('opt15'); return ( @@ -233,7 +399,7 @@ export const NotMatchWidth = () => { options={[ { label: 'Neither snow, nor rain, nor heat, nor gloom of night keeps these hackers from the swift completion of their code.', - value: 'opt' + value: 'opt', }, ...data, ]} @@ -345,14 +511,17 @@ export const DisabledSelect = () => { options={[ { // eslint-disable-next-line max-len - label: 'The back still says the name of a different technology company, one that came before us,left as a reminder that if we fail, someday someone might replace us.', + label: + 'The back still says the name of a different technology company, one that came before us,left as a reminder that if we fail, someday someone might replace us.', value: 'opt', prefixIcon: , - suffixIcon: - - - - , + suffixIcon: ( + + + + + + ), }, ]} value="opt" @@ -417,7 +586,7 @@ export const SearchCustomHighlightStyle = () => { }} highlightStyle={{ backgroundColor: '#7B67EE', - color: '#fff' + color: '#fff', }} dropdownMatchSelectWidth triggerStyle={{ width: 100 }} @@ -479,11 +648,7 @@ export const SelectOption = () => { > {options.map((option, index) => { return ( - + {option.label} ); @@ -491,4 +656,3 @@ export const SelectOption = () => { ); }; - diff --git a/packages/components/src/components/select/select_item.tsx b/packages/components/src/components/select/select_item.tsx index 37a0e124a1..701071dc5b 100644 --- a/packages/components/src/components/select/select_item.tsx +++ b/packages/components/src/components/select/select_item.tsx @@ -20,61 +20,65 @@ import classNames from 'classnames'; import { IOption, ISelectProps } from 'components/select/interface'; import { Typography } from 'components/typography'; import React from 'react'; +import EllipsisText from '../ellipsis_text'; type IRenderValue = Pick; -export const SelectItem: React.FC>> = (props) => { - const { item, iconClassName, children, renderValue, isChecked } = props; +export const SelectItem: React.FC< + React.PropsWithChildren< + { + iconClassName?: string; + item: IOption; + isChecked?: boolean; + } & Required + > +> = (props) => { + const { item, iconClassName, children, renderValue, isChecked } = props; - const getEllipsisConfig = () => { - /** - * If the disabled tip is directly masked, the reason for the disabled cannot be displayed, so the disabled is judged first. - */ - if (!item.disabled) { - return { tooltip: '' }; - } - // Need to prompt disabled tips - if (item.disabled && item.disabledTip) { - return { tooltip: item.disabledTip }; - } - - // Show search results - if (children) { - return { rows: 1, tooltip: item.label }; - } - - return true; - }; - - return <> + return ( + <> - { - item.prefixIcon - } + {item.prefixIcon} - - { - children || renderValue(item) - } - + {item.disabled ? ( + + {children || renderValue(item)} + + ) : ( + + + {children || renderValue(item)} + + + )} - - { - item.suffixIcon - } - - ; - }; + {item.suffixIcon} + + ); +}; diff --git a/packages/components/src/components/select/styled.ts b/packages/components/src/components/select/styled.ts index bde69a7327..acef46b02c 100644 --- a/packages/components/src/components/select/styled.ts +++ b/packages/components/src/components/select/styled.ts @@ -25,12 +25,13 @@ const CssItem = css>` position: relative; height: 40px; - ${props => { + ${(props) => { if (props.disabled) { return css` cursor: not-allowed; - .prefixIcon, .optionLabel { + .prefixIcon, + .optionLabel { opacity: 0.5; } `; @@ -38,14 +39,14 @@ const CssItem = css>` return; }} - padding-left: ${props => { + padding-left: ${(props) => { if (props.prefixIcon) { return '20px'; } return ''; }}; - padding-right: ${props => { + padding-right: ${(props) => { if (props.suffixIcon) { return '20px'; } @@ -56,7 +57,6 @@ const CssItem = css>` vertical-align: -0.225em; } - .suffixIcon, .prefixIcon { height: 100%; @@ -75,12 +75,11 @@ const CssItem = css>` &.isChecked { svg { - fill: ${props => { - return props.theme.color.primaryColor; - }}; + fill: ${(props) => { + return props.theme.color.primaryColor; + }}; } } - } .optionLabel { @@ -91,14 +90,14 @@ const CssItem = css>` line-height: 40px; &.isChecked { - color: ${props => { - return props.theme.color.primaryColor; - }}; + color: ${(props) => { + return props.theme.color.primaryColor; + }}; } } `; -export const StyledSelectTrigger = styled.div.attrs(applyDefaultTheme) <{ disabled: boolean; focus: boolean }>` +export const StyledSelectTrigger = styled.div.attrs(applyDefaultTheme)<{ disabled: boolean; focus: boolean }>` cursor: pointer; border-radius: 4px; border: 1px solid transparent; @@ -109,7 +108,7 @@ export const StyledSelectTrigger = styled.div.attrs(applyDefaultTheme) <{ disabl height: 40px; user-select: none; outline: none; - transition: all .3s; + transition: all 0.3s; ${(props) => { const { fc5 } = props.theme.color; @@ -118,21 +117,23 @@ export const StyledSelectTrigger = styled.div.attrs(applyDefaultTheme) <{ disabl cursor: not-allowed; `; } - return !props.disabled && css` - &:hover { - border-color: ${fc5}; - } - `; + return ( + !props.disabled && + css` + &:hover { + border-color: ${fc5}; + } + ` + ); }}; ${(props) => { - const { fc6 } = props.theme.color; return css` - background-color: ${fc6}; + background-color: ${props.theme.color.fc6}; `; - }}; + }} - ${props => { + ${(props) => { const { fc0 } = props.theme.color; if (props.focus) { return css` @@ -140,11 +141,14 @@ export const StyledSelectTrigger = styled.div.attrs(applyDefaultTheme) <{ disabl `; } - return !props.disabled && css` - &:focus-within { - border-color: ${fc0} !important; - } - `; + return ( + !props.disabled && + css` + &:focus-within { + border-color: ${fc0} !important; + } + ` + ); }} `; @@ -163,11 +167,11 @@ export const StyledSelectedContainer = styled.div.attrs(applyDefaultTheme)` display: inline-block; font-size: 13px; ${(props) => { - const { blackBlue } = props.theme.color; - return css` + const { blackBlue } = props.theme.color; + return css` color: ${blackBlue[500]}; `; - }} + }} } ${CssItem}; @@ -181,13 +185,17 @@ export const PrefixIcon = styled.span` padding-right: 4px; `; -export const StyledArrowIcon = styled(PrefixIcon) <{ rotated: boolean }>` +export const StyledArrowIcon = styled(PrefixIcon)<{ rotated: boolean }>` position: absolute; right: 8px; display: flex; align-items: center; transition: transform 0.3s; - ${props => props.rotated && css` transform: rotate(180deg); `} + ${(props) => + props.rotated && + css` + transform: rotate(180deg); + `} height: auto; transform-origin: 40%; `; @@ -206,11 +214,12 @@ export const hightLightCls = styled.div.attrs(applyDefaultTheme)` padding: 0; `; -export const StyledListContainer = styled.div.attrs(applyDefaultTheme) <{ width: string; minWidth: string }>` +export const StyledListContainer = styled.div.attrs(applyDefaultTheme)<{ width: string; minWidth?: string; maxWidth?: string }>` width: ${(props) => props.width}; min-width: ${(props) => props.minWidth}; + max-width: ${(props) => props.maxWidth}; padding: 4px 0; - ${props => css` + ${(props) => css` background-color: ${props.theme.color.highestBg}; box-shadow: ${props.theme.color.shadowCommonHighest}; `} @@ -219,14 +228,14 @@ export const StyledListContainer = styled.div.attrs(applyDefaultTheme) <{ width: export const OptionOutside = styled(ListDeprecate.Item).attrs(applyDefaultTheme)` ${CssItem}; - padding-left: ${props => { + padding-left: ${(props) => { if (props.prefixIcon) { return '28px'; } return ''; }}; - padding-right: ${props => { + padding-right: ${(props) => { if (props.suffixIcon) { return '28px'; } diff --git a/packages/components/src/components/text_input/text_input.tsx b/packages/components/src/components/text_input/text_input.tsx index 9222523dd1..6535e62fe5 100644 --- a/packages/components/src/components/text_input/text_input.tsx +++ b/packages/components/src/components/text_input/text_input.tsx @@ -169,6 +169,8 @@ export const TextInput = React.forwardRef(({ e.stopPropagation(); e.nativeEvent.stopPropagation(); setFocus(true); + // @ts-ignore + onFocus?.(e); }; const handleBlur = (e: React.FocusEvent) => { diff --git a/packages/components/src/components/time/ScheduleOptions.ts b/packages/components/src/components/time/ScheduleOptions.ts new file mode 100644 index 0000000000..328cafab58 --- /dev/null +++ b/packages/components/src/components/time/ScheduleOptions.ts @@ -0,0 +1,51 @@ +import dayjs from 'dayjs'; +import { t, Strings } from '@apitable/core'; +import advancedFormat from 'dayjs/plugin/advancedFormat'; +dayjs.extend(advancedFormat); + +import 'dayjs/locale/zh'; +import 'dayjs/locale/zh-cn'; +import 'dayjs/locale/zh-hk'; +import 'dayjs/locale/zh-tw'; +import { Maybe } from 'purify-ts/index'; + +export const ScheduleOptions = { + getDayIntervalOptions: () => { + const dayIntervalOptions = Array.from({ length: 30 }, (_, i) => { + return i + 1; + }).map((num) => ({ + label: String(num), + value: String(num), + })); + return dayIntervalOptions; + }, + getWeekOptions: () => { + const weekOptions = Array.from({ length: 7 }, (_, i) => i) + .map((item) => dayjs().day(item)) + .map((num) => ({ + label: num.format('dddd'), + value: num.day().toString(), + })); + return weekOptions; + }, + getHourIntervalOptions: () => { + const hourOptions = Array.from({ length: 24 }, (_, i) => i + 1).map((num) => ({ + label: String(num), + value: num.toString(), + })); + return hourOptions; + }, + getDayOptions: () => { + const dayOptions = Array.from({ length: 31 }, (_, i) => { + return dayjs().set('date', i + 1); + }).map((num) => ({ + label: num.format('Do'), + value: num.date().toString(), + })); + const dayOptionsWithLastDay = dayOptions.concat({ + label: Maybe.encase(() => t(Strings.last_day)).orDefault('最后一天'), + value: '1L', + }); + return dayOptionsWithLastDay; + }, +}; diff --git a/packages/components/src/components/time/index.ts b/packages/components/src/components/time/index.ts new file mode 100644 index 0000000000..b6def85e9d --- /dev/null +++ b/packages/components/src/components/time/index.ts @@ -0,0 +1,6 @@ +import { Timing } from './timing'; +import { TimeTips } from './tips'; +import { NextTimePreview } from './preview'; +import { CronConverter } from './utils'; +import { ICronSchema } from './types'; +export { Timing, NextTimePreview, CronConverter, ICronSchema, TimeTips }; diff --git a/packages/components/src/components/time/preview.tsx b/packages/components/src/components/time/preview.tsx new file mode 100644 index 0000000000..c9965e72c8 --- /dev/null +++ b/packages/components/src/components/time/preview.tsx @@ -0,0 +1,77 @@ +/** + * APITable + * Copyright (C) 2022 APITable Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import React, { FC } from 'react'; +import { useCssColors } from '../../hooks/use_css_colors'; +import { Box } from '../box'; +import { Typography } from '../typography'; +import dayjs from 'dayjs'; +import timezone from 'dayjs/plugin/timezone'; +import { CronConverter } from './utils'; +import styled, { css } from 'styled-components'; +dayjs.extend(timezone); + +const GapBox = styled(Box)<{ gap: string }>` + ${(props) => + props.gap && + css` + gap: ${props.gap}; + `} +`; + +export const NextTimePreview: FC<{ + cron: string; + title: string; + tz?: string; + options: { + userTimezone: string; + }; +}> = ({ title, cron, tz = 'Asia/Shanghai', options }) => { + const colors = useCssColors(); + + return ( + + + {title} + + + + {CronConverter.getHumanReadableInformation(cron, tz, options).map((time, index) => { + return ( + + {time} + + ); + })} + + + ); +}; diff --git a/packages/components/src/components/time/time.stories.tsx b/packages/components/src/components/time/time.stories.tsx new file mode 100644 index 0000000000..280f80d7b9 --- /dev/null +++ b/packages/components/src/components/time/time.stories.tsx @@ -0,0 +1,127 @@ +/** + * APITable + * Copyright (C) 2022 APITable Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import React, { FC, useState } from 'react'; +import { StoryType } from '../../stories/constants'; +import { Box } from '../box'; +import { NextTimePreview } from './preview'; +import { Timing } from './timing'; +import { ICronSchema } from './types'; +import { CronConverter } from './utils'; +import { TimeTips } from './tips'; + +const COMPONENT_NAME = 'Time'; + +const TITLE = `${StoryType.BaseComponent}/${COMPONENT_NAME}`; + +export default { + title: TITLE, + parameters: { + design: { + type: 'figma', + url: 'https://www.figma.com/file/VjmhroWol6uCMqhDcJVrxV/LightMode?node-id=247%3A0', + }, + }, + args: { + content: 'Scanner for decks of cards with bar codes printed on card edges', + }, +}; + +export const TimeTipsView: FC = () => ( + <> + + +); + +export const NextTime: FC = () => ( + <> + + +); + +export const TimingHour: FC = () => { + const [state, setState] = useState(CronConverter.extractCron(CronConverter.getDefaultValue('hour'))!); + + return ( + <> + <>{JSON.stringify(state)} + + + ); +}; + +export const TimingDay: FC = () => { + const [state, setState] = useState(CronConverter.extractCron(CronConverter.getDefaultValue('day'))!); + + return ( + <> + <>{JSON.stringify(state)} + + + ); +}; + +export const TimingHourDisabled: FC = () => { + const [state, setState] = useState(CronConverter.extractCron(CronConverter.getDefaultValue('hour'))!); + return ( + <> + <>{JSON.stringify(state)} + + + ); +}; + +export const TimingWeek: FC = () => { + const [state, setState] = useState(CronConverter.extractCron(CronConverter.getDefaultValue('week'))!); + + return ( + <> + <>{JSON.stringify(state)} + + + ); +}; + +export const TimingMonth: FC = () => { + const [state, setState] = useState(CronConverter.extractCron(CronConverter.getDefaultValue('month'))!); + + return ( + <> + <>{JSON.stringify(state)} + + + ); +}; + +export const TimingDisabled: FC = () => { + const [state, setState] = useState(CronConverter.extractCron(CronConverter.getDefaultValue('month'))!); + + return ( + + <>{JSON.stringify(state)} + + + + + + ); +}; + +// export const TimingMonth : FC = () => ; +// export const TimingDay : FC = () => ; +// export const TimingWeek : FC = () => ; diff --git a/packages/components/src/components/time/time_input/index.tsx b/packages/components/src/components/time/time_input/index.tsx new file mode 100644 index 0000000000..718aa05639 --- /dev/null +++ b/packages/components/src/components/time/time_input/index.tsx @@ -0,0 +1,256 @@ +/** + * APITable + * Copyright (C) 2022 APITable Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import React, { FC, memo, useMemo, useState } from 'react'; +import { ListDropdown } from '../../select/dropdown/list_dropdown'; +import { stopPropagation } from '../../../helper'; +import { OptionItem, StyledListContainer } from '../../select'; +import { ListDeprecate } from '../../list_deprecate'; +import styled, { css } from 'styled-components'; +import { CronConverter } from '../utils'; +import { applyDefaultTheme } from '../../../theme'; + +export const getDefaultHourArray = () => { + const CONST_DEFAULT_HOUR_ARRAY = [ + '00:00', + '00:30', + '01:00', + '01:30', + '02:00', + '02:30', + '03:00', + '03:30', + '04:00', + '04:30', + '05:00', + '05:30', + '06:00', + '06:30', + '07:00', + '07:30', + '08:00', + '08:30', + '09:00', + '09:30', + '10:00', + '10:30', + '11:00', + '11:30', + '12:00', + '12:30', + '13:00', + '13:30', + '14:00', + '14:30', + '15:00', + '15:30', + '16:00', + '16:30', + '17:00', + '17:30', + '18:00', + '18:30', + '19:00', + '19:30', + '20:00', + '20:30', + '21:00', + '21:30', + '22:00', + '22:30', + '23:00', + '23:30', + ]; + return CONST_DEFAULT_HOUR_ARRAY; +}; + +const regex = /^([01]\d|2[0-3]):([0-5]\d)$/; + +const StyledSelectTrigger = styled.div.attrs(applyDefaultTheme)<{ disabled: boolean; focus: boolean }>` + cursor: pointer; + border-radius: 4px; + border: 1px solid transparent; + display: flex; + align-items: center; + height: 40px; + position: relative; + user-select: none; + outline: none; + transition: all 0.3s; + + color: ${(props) => props.theme.color.textCommonPrimary}; + + ${(props) => { + const { fc5 } = props.theme.color; + if (props.disabled) { + return css` + cursor: not-allowed; + color: ${props.theme.color.textCommonDisabled} + `; + } + return ( + !props.disabled && + css` + &:hover { + border-color: ${fc5}; + } + ` + ); + }}; + + ${(props) => { + return css` + background-color: ${props.theme.color.bgControlsDefault}; + `; + }}; + + ${(props) => { + const { borderBrandDefault } = props.theme.color; + if (props.focus) { + return css` + border-color: ${borderBrandDefault} !important; + `; + } + + return ( + !props.disabled && + css` + &:focus-within { + border-color: ${borderBrandDefault} !important; + } + ` + ); + }} +`; + +const StyledInput = styled.input.attrs(applyDefaultTheme)<{ disabled: boolean }>` + cursor: pointer; + border-radius: 4px; + padding: 0 8px 0 8px; + display: flex; + align-items: center; + position: relative; + height: 100%; + user-select: none; + outline: none; + transition: all 0.3s; + width: 64px; + border: none; + + ${(props) => { + return css` + background-color: ${props.theme.color.fc6}; + `; + }}; + + ${(props) => + props.disabled && + ` + user-select: none; + outline: none; + cursor: not-allowed; + border: none; + `} +`; + +const TimeInputComp: FC<{ + time: string; + readonly?: boolean; + onChange?: (value: string) => void; +}> = ({ time, onChange, readonly = false }) => { + const [input, setInput] = useState(time || '00:00'); + + const CONST_DEFAULT_HOUR_ARRAY = useMemo(() => getDefaultHourArray(), []); + return ( + + { + if (readonly) { + return; + } + const input = e.target.value; + if (!regex.test(input)) { + const inputText = CronConverter.getHourTime(time ?? ''); + onChange?.(inputText); + setInput(inputText); + } + // const inputText = CronConverter.getHourTime(time ?? ''); + // setInput(inputText); + // } + }} + onChange={(e) => { + if (readonly) { + return; + } + const input = e.target.value; + if (regex.test(input)) { + onChange?.(e.target.value); + } + setInput(e.target.value); + }} + /> + + } + > + {({ toggle }) => ( + + { + toggle(); + const item = CONST_DEFAULT_HOUR_ARRAY[index]; + if (item) { + setInput(item); + onChange?.(item); + } + }} + > + {CONST_DEFAULT_HOUR_ARRAY.map((item, index) => ( + { + setInput(item); + onChange?.(item); + toggle(); + }} + value={null} + item={{ + value: item, + label: item, + }} + /> + ))} + + + )} + + ); +}; + +export const TimeInput = memo(TimeInputComp); diff --git a/packages/components/src/components/time/timing.test.ts b/packages/components/src/components/time/timing.test.ts new file mode 100644 index 0000000000..13d889460b --- /dev/null +++ b/packages/components/src/components/time/timing.test.ts @@ -0,0 +1,117 @@ +import { CronConverter } from './utils'; +import CronTime from 'cron-time-generator'; +import dayjs from 'dayjs'; + +import 'dayjs/locale/zh'; +import 'dayjs/locale/zh-cn'; +import 'dayjs/locale/zh-hk'; +import 'dayjs/locale/zh-tw'; + +describe('timing test', () => { + it('default get default value', () => { + expect(CronConverter.getDefaultValue('week')).toBe('0 0 * * 6'); // At 00:00 on Saturday + expect(CronConverter.getDefaultValue('month')).toBe('0 0 1 * *'); // At 00:00 on day-of-month 1. + }); + + it('default render validate', () => { + // At minute 0 past every 5th hour. + const cron = '0 */5 *'; + expect(CronConverter.extractCron(cron) == null).toBe(true); + }); + + it('default render 1', () => { + // At minute 0 past every 5th hour. + const cron = '0 */5 * * 1L'; + expect(CronConverter.extractCron(cron) == null).toBe(false); + }); + + it('check every hour', () => { + const every2Day = CronTime.every(Number(2)).days(); + + expect(every2Day).toBe('0 0 */2 * *'); + expect(CronConverter.extractCron(every2Day)).toBeDefined(); + expect(CronConverter.getEveryProps(CronConverter.extractCron(every2Day)!, 'dayOfMonth', 0)).toBe(2); + }); + + it('check mutiple day', () => { + const every2Day = CronTime.onSpecificDays([2, 3]); //At 00:00 on Tuesday and Wednesday. + expect(every2Day).toBe('0 0 * * 2,3'); + }); + + it('check mutiple day of month', () => { + const everyDay = CronTime.everyDay(); + // https://crontab.guru/#0_0_1,3_*_* + // At 00:00 on day-of-month 1 and 3. + expect(CronConverter.convertCronPropsString(CronConverter.setDaysOfMonth(CronConverter.extractCron(everyDay)!, [1, 2, 3]))).toBe('0 0 1,2,3 * *'); + }); + + it('check every hour', () => { + const every2Day = CronTime.every(Number(2)).days(); + expect(every2Day).toBe('0 0 */2 * *'); + + const every3Day = CronTime.everyHour(); + + const newCon = CronConverter.updateCronProps('hour', { + previous: CronConverter.extractCron(every2Day)!, + next: every3Day, + }); + + // https://crontab.guru/#0_*_*/2_*_* + expect(CronConverter.convertCronPropsString(newCon)).toBe('0 * */2 * *'); //“At minute 0 on every 2nd day-of-month + }); + + it('check get interval hour', () => { + expect(dayjs.locale()).toBe('en'); + }); + + it('check get interval hour', () => { + expect(dayjs().locale('zh-cn').format('Do')).toContain('日'); + expect(dayjs().locale('zh-cn').format('dddd')).toContain('星期'); + }); + + it('check get interval hour', () => { + expect( + CronConverter.getEveryProps( + { + hour: '*/3', + }, + 'hour', + 0 + ) + ).toBe(3); + }); + + it('read human timezone info', () => { + expect( + CronConverter.getHumanReadableInformation('0 */5 * * *', 'Europe/London', { + userTimezone: 'Asia/Shanghai', + }).length + ).toBe(10); + }); + + it('check every hour', () => { + // At minute 0 past every 5th hour. + const d = '0 */5 * * *'; + expect(CronConverter.extractCron(d) == null).toBe(false); + + const r = CronConverter.extractCron(d); + if (r != undefined) { + expect(CronConverter.getEveryProps(r, 'hour', 0)).toBe(5); + } + }); + + it('default convertCronPropsString', () => { + const data = CronConverter.convertCronPropsString({ + minute: '5', + hour: '*/5', + month: '*', + dayOfWeek: '*', + dayOfMonth: '*', + }); + expect(data).toBe('5 */5 * * *'); + }); + + it('check get interval Utc ', () => { + expect(dayjs().tz('Asia/Shanghai').utcOffset() / 60).toBe(8); + }); +}); diff --git a/packages/components/src/components/time/timing.tsx b/packages/components/src/components/time/timing.tsx new file mode 100644 index 0000000000..efe9521669 --- /dev/null +++ b/packages/components/src/components/time/timing.tsx @@ -0,0 +1,370 @@ +/** + * APITable + * Copyright (C) 2022 APITable Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import React, { FC, useCallback, useMemo } from 'react'; +import { DropdownSelect } from '../select'; +import advancedFormat from 'dayjs/plugin/advancedFormat'; +import dayjs from 'dayjs'; +import { TimeInput } from './time_input'; +import CronTime from 'cron-time-generator'; +import { ICronSchema } from './types'; +import { CronConverter } from './utils'; +import { MultipleSelect } from '../select/dropdown/multiple'; +import { ScheduleOptions } from './ScheduleOptions'; +import { Box } from 'components/box'; +import { Maybe } from 'purify-ts/index'; +import { Strings, t } from '@apitable/core'; +import { Typography } from 'components/typography'; +import styled, { css } from 'styled-components'; +import { useCssColors } from '../../hooks/use_css_colors'; + +dayjs.extend(advancedFormat); +export const CONST_EMTPTY = '__DANGER_EMPTY__'; + +interface Props { + interval: 'day' | 'month' | 'week' | 'hour'; + readonly?: boolean; + value: ICronSchema; + onUpdate?: (value: Props['value']) => void; +} + +const GapBox = styled(Box)<{ gap: string; columnGap?: string; rowGap?: string }>` + flex-wrap: wrap; + white-space: pre; + ${(props) => + props.rowGap && + css` + row-gap: ${props.rowGap}; + `} + ${(props) => + props.columnGap && + css` + column-gap: ${props.columnGap}; + `} + ${(props) => + props.gap && + css` + gap: ${props.gap}; + `} +`; + +export const monthOptions = Array.from({ length: 12 }, (_, i) => i + 1).map((num) => ({ + label: String(num), + value: num.toString(), +})); + +export const minuteOptions = Array.from({ length: 60 }, (_, i) => i).map((num) => ({ + label: num < 10 ? `0${num}` : String(num), + value: num.toString(), +})); + +export const Timing: FC = ({ interval, readonly = false, value, onUpdate }) => { + const handleUpdateItem = useCallback( + (cron: ICronSchema) => { + console.info('new cron', cron); + onUpdate?.(cron); + }, + [onUpdate] + ); + + const dayOptionsWithLastDay = useMemo(() => ScheduleOptions.getDayOptions(), []); + const weekOptions = useMemo(() => ScheduleOptions.getWeekOptions(), []); + + const dayOptions = useMemo(() => ScheduleOptions.getHourIntervalOptions(), []); + const dayIntervalOptions = useMemo(() => ScheduleOptions.getDayIntervalOptions(), []); + const colors = useCssColors(); + + switch (interval) { + case 'hour': { + const hourInterval = CronConverter.getEveryProps(value, 'hour', 1); + const minutes = CronConverter.getNumericProps(value, 'minute', 0); + + return ( + + + {Maybe.encase(() => t(Strings.starting_from_midnight)).orDefault('从每天 0 点起,')} + + + + + {Maybe.encase(() => t(Strings.by_every)).orDefault('每隔')} + + t(Strings.datasource_selector_search_placeholder)).orDefault('Search')} + value={String(hourInterval)} + options={dayOptions} + onSelected={(node) => { + const everyHour = CronTime.every(Number(node.value)).hours(); + handleUpdateItem( + CronConverter.updateCronProps('hour', { + previous: value, + next: everyHour, + }) + ); + }} + /> + + + {Maybe.encase(() => t(Strings.every_hour_at)).orDefault('小时')} + + + + + + {Maybe.encase(() => t(Strings.by_in)).orDefault('的')} + + + t(Strings.datasource_selector_search_placeholder)).orDefault('Search')} + hiddenArrow + value={String(minutes)} + disabled={readonly} + options={minuteOptions} + onSelected={(node) => { + const miniute = Number(node.value); + + const everyHour = CronTime.everyHourAt(miniute); + handleUpdateItem( + CronConverter.updateCronProps('minute', { + previous: value, + next: everyHour, + }) + ); + }} + /> + + {Maybe.encase(() => t(Strings.by_min)).orDefault('minute(s)')} + + + + ); + } + case 'week': { + const dayInMonths = CronConverter.getLists(value, 'dayOfWeek'); + return ( + + + + {Maybe.encase(() => t(Strings.every_week_at)).orDefault('Every weekday on')} + + + + + { + handleUpdateItem(new CronConverter(value).setLists('dayOfWeek', list)); + }} + /> + + + + + + {Maybe.encase(() => t(Strings.by_at)).orDefault('at')} + + + + + { + const newCro = new CronConverter(value).setHourTime(v); + handleUpdateItem(newCro); + }} + /> + + + + ); + } + + case 'month': { + const monthInterval = CronConverter.getEveryProps(value, 'month', 1); + const dayInMonths = CronConverter.getLists(value, 'dayOfMonth'); + return ( + + + + {Maybe.encase(() => t(Strings.schedule_start_month)).orDefault('从每年 1 月份起,')} + + + + + + {Maybe.encase(() => t(Strings.by_every)).orDefault('每隔')} + + + t(Strings.datasource_selector_search_placeholder)).orDefault('Search')} + listStyle={{ + width: '120px', + }} + options={monthOptions} + onSelected={(node) => { + const v = new CronConverter(value).setInterval('month', Number(node.value)); + handleUpdateItem(v); + }} + /> + + {Maybe.encase(() => t(Strings.every_month_at)).orDefault('month(s)')} + + + + + + + {Maybe.encase(() => t(Strings.by_on)).orDefault(' on the')} + + + t(Strings.datasource_selector_search_placeholder)).orDefault('Search')} + openSearch + value={dayInMonths} + disabled={readonly} + options={dayOptionsWithLastDay} + onChange={(list) => { + handleUpdateItem(new CronConverter(value).setLists('dayOfMonth', list)); + }} + /> + + + + + + {Maybe.encase(() => t(Strings.by_at)).orDefault('at')} + + + + + { + const a = new CronConverter(value).setHourTime(v); + handleUpdateItem(a); + }} + /> + + + + ); + } + case 'day': { + const dayInterval = CronConverter.getEveryProps(value, 'dayOfMonth', 1); + return ( + + + {Maybe.encase(() => t(Strings.schedule_start_day)).orDefault('从每月 1 日起,')} + + + + {Maybe.encase(() => t(Strings.by_every)).orDefault('every')} + + t(Strings.datasource_selector_search_placeholder)).orDefault('Search')} + listStyle={{ + width: '120px', + }} + disabled={readonly} + value={String(dayInterval)} + options={dayIntervalOptions} + onSelected={(node) => { + const everyHour = CronTime.every(Number(node.value)).days(); + handleUpdateItem( + CronConverter.updateCronProps('dayOfMonth', { + previous: value, + next: everyHour, + }) + ); + }} + /> + + {Maybe.encase(() => t(Strings.every_day_at)).orDefault('天')} + + + + + + {Maybe.encase(() => t(Strings.by_in)).orDefault(' at')} + + + { + const a = new CronConverter(value).setHourTime(v); + handleUpdateItem(a); + }} + /> + + + ); + } + + default: { + return <>; + } + } +}; diff --git a/packages/components/src/components/time/tips/index.tsx b/packages/components/src/components/time/tips/index.tsx new file mode 100644 index 0000000000..76e9291213 --- /dev/null +++ b/packages/components/src/components/time/tips/index.tsx @@ -0,0 +1,45 @@ +import { Strings, t } from '@apitable/core'; +import React, { FC } from 'react'; +import { Box } from '../../box'; +import { Typography } from '../../typography'; +import { useCssColors } from '../../../hooks/use_css_colors'; +import { InfoCircleOutlined } from '@apitable/icons'; +import { Maybe } from 'purify-ts/index'; + +export const TimeTips: FC<{ + interval: 'day' | 'month' | 'week' | 'hour'; +}> = ({ interval }) => { + const colors = useCssColors(); + if (interval === 'week') { + return null; + } + + let tips: string = ''; + if (interval === 'month') { + tips = Maybe.encase(() => t(Strings.schedule_year_tips)).orDefault( + '周期计算从每年的 1 月份开始算,假设设置为每隔 3 个月的 1 日,则每年的 1 月,4 月,7 月,10 月的第一天会触发' + ); + } else if (interval === 'day') { + tips = Maybe.encase(() => t(Strings.schedule_day_tips)).orDefault( + '周期计算从每个月的 1 日开始算,假设设置为每隔 10 天,则每月的 1 日,11 日,21 日,31 日会触发' + ); + } else if (interval === 'hour') { + tips = Maybe.encase(() => t(Strings.schedule_hour_tips)).orDefault( + '周期计算从每天的 0 点开始算,假设设置为每隔 3 个小时的 0 分,则每天的 0 点,3 点,6 点,9 点,12 点,15 点,18 点,21 点会触发' + ); + } + + return ( + + + + + + + + {tips} + + + + ); +}; diff --git a/packages/components/src/components/time/types.tsx b/packages/components/src/components/time/types.tsx new file mode 100644 index 0000000000..1f71224e49 --- /dev/null +++ b/packages/components/src/components/time/types.tsx @@ -0,0 +1,52 @@ +/** + * APITable + * Copyright (C) 2022 APITable Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +/** + * dayOfMonth + * : + * {type: ["string", "number"], oneOf: [{type: "string", title: "multi days of month"},…],…} + * dayOfWeek + * : + * {type: "string", oneOf: [{type: "string", title: "multi days of week"},…],…} + * hour + * : + * {type: "integer", comment: "hour (0 - 23)"} + * minute + * : + * {type: "integer", comment: "minute (0 - 59)"} + * month + * : + * {type: "integer", comment: "month (1 - 12)"} + * second + * : + * {type: "integer", comment: "second (0 - 59, optional)"} + * + * @param interval + * @param value + * @param onUpdate + * @constructor + */ + +export interface ICronSchema { + dayOfMonth?: string; // | number; + dayOfWeek?: string; // | number; + hour?: string; + minute?: string; + month?: string; //every x month + second?: string; +} diff --git a/packages/components/src/components/time/utils.ts b/packages/components/src/components/time/utils.ts new file mode 100644 index 0000000000..50305c94d6 --- /dev/null +++ b/packages/components/src/components/time/utils.ts @@ -0,0 +1,301 @@ +/** + * APITable + * Copyright (C) 2022 APITable Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import { ICronSchema } from './types'; + +import { Just, Maybe, Nothing } from 'purify-ts/index'; +import parser from 'cron-parser'; +import dayjs from 'dayjs'; +import advancedFormat from 'dayjs/plugin/advancedFormat'; +import utc from 'dayjs/plugin/utc'; +import timezone from 'dayjs/plugin/timezone'; +import CronTime from 'cron-time-generator'; + +dayjs.extend(advancedFormat); +dayjs.extend(utc); +dayjs.extend(timezone); + +const integratedMinitue = (value: number) => { + return String(value < 10 ? `0${value}` : value); +}; + +export type AutomationInterval = 'day' | 'month' | 'week' | 'hour'; +type AutomationCron = string; + +export const getUTCOffset = (time: Date, timezone: string): string => { + // dayjs(time).tz(options.userTimezone).utcOffset() / 60 + try { + const utcOffset = dayjs(time).tz(timezone).utcOffset(); + const r = utcOffset / 60; + return r < 0 ? `${r}` : `+${r}`; + } catch { + const utcOffset = dayjs().utcOffset(); + const r = utcOffset / 60; + return r < 0 ? `${r}` : `+${r}`; + } +}; +export class CronConverter { + cron: ICronSchema; + + static setDaysOfMonth = (test: ICronSchema, list: IDayOption[]): ICronSchema => { + const REPLACEMENTS = '1-30'; + + const sorted = list.sort((a, b) => String(a).localeCompare(String(b))); + const text = sorted.join(','); + + const every2Day = CronTime.between(1, 30).days().replace(REPLACEMENTS, text); + const newCon = CronConverter.updateCronProps('dayOfMonth', { + previous: test, + next: every2Day, + }); + return newCon; + }; + + static extractCron = (cronExpression: string): undefined | ICronSchema => { + try { + parser.parseExpression(cronExpression); + } catch (e) { + return undefined; + } + const matches = cronExpression.split(/\s/); + if (matches.length !== 5) { + return undefined; + } + + const minute = matches[0]; + const hour = matches[1]; + const dayOfMonth = matches[2]; + const month = matches[3]; + const dayOfWeek = matches[4]; + if (minute && hour && dayOfMonth && hour && dayOfMonth) { + return { + minute, + hour, + dayOfWeek, + month, + dayOfMonth, + }; + } + return undefined; + }; + + static getHumanReadableInformation = ( + cron: string, + tz: string, + options: { + userTimezone: string; + } + ): string[] => { + return Maybe.encase(() => { + const interval = parser.parseExpression(cron, { + startDate: new Date(), + currentDate: new Date(), + iterator: true, + tz: tz, + }); + + const newTimes = [ + interval.next().value.toDate(), + interval.next().value.toDate(), + interval.next().value.toDate(), + interval.next().value.toDate(), + interval.next().value.toDate(), + interval.next().value.toDate(), + interval.next().value.toDate(), + interval.next().value.toDate(), + interval.next().value.toDate(), + interval.next().value.toDate(), + ]; + + return newTimes.map( + (time) => + `${dayjs(time).tz(options.userTimezone).format(CONST_FORMAT_AUTOMATION_TIME)} UTC${getUTCOffset(time, options.userTimezone)} (${ + options.userTimezone + })` + ); + }).orDefault([]); + }; + + static convertCronPropsString = (cron: ICronSchema): string => { + return [cron.minute, cron.hour, cron.dayOfMonth, cron.month, cron.dayOfWeek].join(' '); + }; + constructor(cron: ICronSchema | string) { + if (typeof cron === 'string') { + const resp = CronConverter.extractCron(cron); + if (resp != null) { + this.cron = resp; + } else { + this.cron = CronConverter.extractCron(CronTime.everyDay())!; + } + } else { + this.cron = cron; + } + } + + static getHourTime = (text: string) => { + const arry = text.split(':'); + const hour = Maybe.fromPredicate((x: number) => !isNaN(x))(Number(arry[0])).orDefault(0); + + const minute = Maybe.fromPredicate((x: number) => !isNaN(x))(Number(arry[1])).orDefault(0); + return `${integratedMinitue(hour)}:${integratedMinitue(minute)}`; + }; + + public setHourTime = (text: string) => { + const arry = text.split(':'); + const hour = Maybe.fromPredicate((x: number) => !isNaN(x))(Number(arry[0])).orDefault(0); + + const minute = Maybe.fromPredicate((x: number) => !isNaN(x))(Number(arry[1])).orDefault(0); + + const newInfo = CronTime.everyDayAt(hour, minute); + + const newCon = CronConverter.updateCronProps('hour', { + previous: this.cron, + next: newInfo, + }); + return CronConverter.updateCronProps('minute', { + previous: newCon, + next: newInfo, + }); + }; + + public getHourTime = () => { + const hour = this.cron.hour; + const minute = this.cron.minute; + + const hourText = Maybe.fromPredicate((x: number) => !isNaN(x))(Number(hour)).orDefault(0); + const hourMiniute = Maybe.fromPredicate((x: number) => !isNaN(x))(Number(minute)).orDefault(0); // TODO + return `${integratedMinitue(hourText)}:${integratedMinitue(hourMiniute)}`; + }; + + static getDefaultValue = (interval: AutomationInterval): AutomationCron => { + switch (interval) { + case 'hour': { + return CronTime.everyHourAt(0); + } + case 'day': { + return CronTime.everyDayAt(0, 0); + } + case 'week': { + return CronTime.onSpecificDaysAt([6], 0, 0); + } + case 'month': { + return CronTime.everyMonthOn(1, 0, 0); + } + default: { + return CronTime.everyHourAt(0); + } + } + }; + + static minuteFormatter = (value: number) => { + return String(value < 10 ? `0${value}` : value); + }; + + static updateCronProps = ( + name: T, + option: { + previous: ICronSchema; + next: string; + } + ): ICronSchema => { + const { previous, next } = option; + const data = CronConverter.extractCron(next); + if (!data) { + return previous; + } + return { + ...previous, + [name]: data[name], + }; + }; + + static getEveryPropsOption1 = (item: ICronSchema, name: K): Maybe => { + const cronExpression = item[name]; + if (!cronExpression) { + return Nothing; + } + + const regex = /^\*\/(\d+)$/; + const matches = String(cronExpression).match(regex); + const mayOption = Maybe.fromNullable(matches) + .map((r) => r[1]) + .map((r) => Number(r)); + return mayOption; + }; + + public setLists = (name: K, list: (string | number)[]): ICronSchema => { + if (list.length === 0) { + return this.cron; + } + const sorted = list.sort((a, b) => String(a).localeCompare(String(b))).join(','); + + return { + ...this.cron, + [name]: sorted, + }; + }; + + static getLists = (item: ICronSchema, name: K): string[] => { + const cronExpression = item[name]; + if (!cronExpression) { + return []; + } + return Maybe.encase(() => String(cronExpression).split(',')).orDefault([]); + }; + + public setInterval = (name: K, interval: number) => { + if (Number.isNaN(interval)) { + return this.cron; + } + return { + ...this.cron, + [name]: `*/${interval}`, + }; + }; + + static getEveryProps = (item: ICronSchema, name: K, defaultValue: number) => { + const cronExpression = item[name]; + if (!cronExpression) { + return defaultValue; + } + + const regex = /^\*\/(\d+)$/; + const matches = String(cronExpression).match(regex); + const mayOption = Maybe.fromNullable(matches) + .map((r) => r[1]) + .map((r) => Number(r)); + return mayOption.orDefault(defaultValue); + }; + + static getNumericProps = (item: ICronSchema, name: K, defaultValue: number) => { + const cronExpression = item[name]; + if (!cronExpression) { + return defaultValue; + } + + const mayOption = Maybe.fromNullable(cronExpression) + .map((r) => Number(r)) + .chain((x) => (isNaN(x) ? Nothing : Just(x))); + return mayOption.orDefault(defaultValue); + }; +} + +export const CONST_FORMAT_AUTOMATION = 'YYYY-MM-DD HH:mm zzz z'; +export const CONST_FORMAT_AUTOMATION_TIME = 'YYYY-MM-DD HH:mm'; + +type IDayOption = string | number; diff --git a/packages/components/src/components/tooltip/float_ui/index.tsx b/packages/components/src/components/tooltip/float_ui/index.tsx index ecce8b6b21..29f26423e3 100644 --- a/packages/components/src/components/tooltip/float_ui/index.tsx +++ b/packages/components/src/components/tooltip/float_ui/index.tsx @@ -1,6 +1,7 @@ import React, { cloneElement, FunctionComponent, ReactElement, useRef, useState } from 'react'; import { - FloatingArrow, arrow, + FloatingArrow, + arrow, useFloating, autoUpdate, offset, @@ -12,59 +13,56 @@ import { useRole, useInteractions, FloatingPortal, - Placement + Placement, } from '@floating-ui/react'; import { Typography } from '../../typography'; import { TooltipBase } from '../tooltip'; import { useThemeColors } from '../../../hooks'; import { setIndex } from '../../dropdown'; +import { CONST_INITIAL_DROPDOWN_INDEX } from '../../dropdown/float_ui/useFloatUiDropdown'; + +const CONST_ARROW_HEIGHT = 7; +const CONST_GAP = 2; + interface IProps { - content: ReactElement | string - children: ReactElement, - placement?: Placement, - className?: string, - options?: { - zIndex?: number, - offset?: number, - initialVisible?: boolean - }, - arrow?: boolean + content: ReactElement | string; + children: ReactElement; + placement?: Placement; + className?: string; + options?: { + zIndex?: number; + offset?: number; + initialVisible?: boolean; + }; + arrow?: boolean; } -const FloatUiTooltip: FunctionComponent = ({ - content, - className, - placement = 'bottom', - children, - options, - arrow: hasArrow = true -}) => { +const FloatUiTooltip: FunctionComponent = ({ content, className, placement = 'bottom', children, options, arrow: hasArrow = true }) => { const [isOpen, setIsOpen] = useState(options?.initialVisible ?? false); const arrowRef = useRef(null); + const offsetOrDefault = options?.offset ?? CONST_GAP; const { refs, floatingStyles, context } = useFloating({ open: isOpen, onOpenChange: setIsOpen, placement, whileElementsMounted: autoUpdate, middleware: [ - setIndex(options?.zIndex ?? 1002), - offset(options?.offset ?? 16), - ...( - hasArrow ? ( - [ + offset(hasArrow ? offsetOrDefault + CONST_ARROW_HEIGHT : offsetOrDefault), + setIndex(options?.zIndex ?? CONST_INITIAL_DROPDOWN_INDEX), + ...(hasArrow + ? [ arrow({ element: arrowRef, - }) + }), ] - ) : [] - ), + : []), flip({ - fallbackAxisSideDirection: 'start' + fallbackAxisSideDirection: 'start', }), - shift() - ] + shift(), + ], }); const hover = useHover(context, { move: false }); @@ -72,42 +70,27 @@ const FloatUiTooltip: FunctionComponent = ({ const dismiss = useDismiss(context); const role = useRole(context, { role: 'tooltip' }); - const { getReferenceProps, getFloatingProps } = useInteractions([ - hover, - focus, - dismiss, - role - ]); + const { getReferenceProps, getFloatingProps } = useInteractions([hover, focus, dismiss, role]); const theme = useThemeColors(); return ( <> - { - cloneElement(children, { - ref: refs.setReference, - ...getReferenceProps() - }) - } + {cloneElement(children, { + ref: refs.setReference, + ...getReferenceProps(), + })} {isOpen && ( <> - { - hasArrow && ( -
- -
- ) - } - - {content} - +
+ + + {content} + + + {hasArrow && } +
)}
@@ -115,4 +98,4 @@ const FloatUiTooltip: FunctionComponent = ({ ); }; -export { FloatUiTooltip }; +export { FloatUiTooltip, TooltipBase }; diff --git a/packages/components/src/components/tooltip/tooltip.tsx b/packages/components/src/components/tooltip/tooltip.tsx index a7e1676433..a60995dc58 100644 --- a/packages/components/src/components/tooltip/tooltip.tsx +++ b/packages/components/src/components/tooltip/tooltip.tsx @@ -27,7 +27,7 @@ export interface ITooltipProps { /** * Tooltip content */ - content: string| ReactElement; + content: string | ReactElement; /** * Display position */ @@ -72,7 +72,7 @@ const GlobalStyle: any = createGlobalStyle` `; export const TooltipBase = styled.div.attrs(applyDefaultTheme)` - ${props => { + ${(props) => { const color = props.theme.color; return css` z-index: ${CONST_TOOLTIP_INDEX}; @@ -91,31 +91,29 @@ function isReactText(children: React.ReactNode) { return ['string', 'number'].includes(typeof children); } -export const Tooltip: FC> = ( - { - children, - content, - placement = 'top-center', - color, - visible, - arrow = true, - trigger = 'hover', - zIndex, - onVisibleChange, - getPopupContainer = () => document.body, - style, - } -) => { +export const Tooltip: FC> = ({ + children, + content, + placement = 'top-center', + color, + visible, + arrow = true, + trigger = 'hover', + zIndex, + onVisibleChange, + getPopupContainer = () => document.body, + style, +}) => { const theme = useProviderTheme(); const [isOver, hoverProps] = useHover(); const [clickState, setClickState] = useState(false); - const isOpen = visible != null ? visible : ((trigger === 'hover' && isOver) || (trigger === 'click' && clickState)); + const isOpen = visible != null ? visible : (trigger === 'hover' && isOver) || (trigger === 'click' && clickState); const { triggerProps, layerProps, arrowProps, renderLayer } = useLayer({ isOpen, triggerOffset: 12, auto: true, placement: placement as Placement, - container: getPopupContainer + container: getPopupContainer, }); useEffect(() => { @@ -125,7 +123,7 @@ export const Tooltip: FC> = ( let triggerEle; if (isReactText(children)) { triggerEle = ( - setClickState(!clickState)}> + setClickState(!clickState)}> {children} ); @@ -137,22 +135,18 @@ export const Tooltip: FC> = ( }); } - const tooltipBaseProps = { ...layerProps, style: { ...layerProps.style, zIndex, ...style }}; + const tooltipBaseProps = { ...layerProps, style: { ...layerProps.style, zIndex, ...style } }; return ( <> {triggerEle} {isOpen && renderLayer( - - {content} - {arrow && - - } + + + {content} + + {arrow && } )} diff --git a/packages/components/src/components/typography/typography.tsx b/packages/components/src/components/typography/typography.tsx index c108f3336d..1530a6f38d 100644 --- a/packages/components/src/components/typography/typography.tsx +++ b/packages/components/src/components/typography/typography.tsx @@ -46,7 +46,6 @@ export const Typography: FC> = (props) color = '', children, ellipsis = false, - tooltipsZIndex, ...rest } = props; const typographyRef = useRef(); diff --git a/packages/components/src/hooks/use_css_colors.ts b/packages/components/src/hooks/use_css_colors.ts new file mode 100644 index 0000000000..b349c0d598 --- /dev/null +++ b/packages/components/src/hooks/use_css_colors.ts @@ -0,0 +1,33 @@ +/** + * APITable + * Copyright (C) 2022 APITable Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import { useThemeColors } from './use_theme_colors'; +import { useMemo } from 'react'; + +export const useCssColors = () => { + const colors = useThemeColors(); + const newColors = useMemo(() => { + return new Proxy(colors, { + get: function (_, prop) { + return `var(--${String(prop)})`; + }, + }); + }, [colors]); + + return newColors; +}; diff --git a/packages/components/src/hooks/use_responsive.ts b/packages/components/src/hooks/use_responsive.ts index 355c49610a..2146c962a6 100644 --- a/packages/components/src/hooks/use_responsive.ts +++ b/packages/components/src/hooks/use_responsive.ts @@ -17,7 +17,6 @@ */ import { useSize } from 'ahooks'; -import { useEffect, useState } from 'react'; import { ScreenWidth } from '@apitable/core'; export type Orientation = 'landscape' | 'portrait'; @@ -69,21 +68,7 @@ export const getScreen = (width: number, height: number): IScreen<{ [name: strin }; export const useResponsive = (): IScreen => { - const [bodySize, setBodySize] = useState(() => { - const el = isRenderServer() ? null : document.body; - return { - width: el?.clientWidth, - height: el?.clientHeight, - }; - }); - - const size = useSize(isRenderServer() ? undefined : document.body); - - useEffect(() => { - if (size) { - setBodySize(size); - } - }, [size, setBodySize]); + const bodySize = useSize(isRenderServer() ? undefined : document.body); // @ts-ignore if (sizes[sizes.length - 1][1] !== 0) { @@ -93,12 +78,5 @@ export const useResponsive = (): IScreen { - setScreen(getScreen(bodySize?.width!, bodySize?.height!)); - // eslint-disable-next-line - }, [bodySize, setScreen]); - - return screen; + return getScreen(bodySize?.width!, bodySize?.height!); }; diff --git a/packages/core/package.json b/packages/core/package.json index af4c9cd49d..820b7d6ab2 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@apitable/core", - "version": "1.6.0", + "version": "1.13.0", "description": "datasheet core", "main": "dist/index.js", "types": "dist/index.d.ts", @@ -24,10 +24,10 @@ "node": ">=8.x" }, "dependencies": { - "@apitable/databus-wasm-nodejs": "*", - "@apitable/databus-wasm-web": "*", + "@apitable/databus-wasm-nodejs": "workspace:*", + "@apitable/databus-wasm-web": "workspace:*", "@apitable/i18n": "^1.0.4", - "@apitable/i18n-lang": "*", + "@apitable/i18n-lang": "workspace:*", "@types/lodash": "^4.14.197", "@types/socket.io-client": "^1.4.36", "apphook": "1.0.6", diff --git a/packages/core/src/automation_manager/interface/expression.interface.ts b/packages/core/src/automation_manager/interface/expression.interface.ts index 2aff1aa1e0..1b1e19114e 100644 --- a/packages/core/src/automation_manager/interface/expression.interface.ts +++ b/packages/core/src/automation_manager/interface/expression.interface.ts @@ -33,6 +33,7 @@ export enum OperatorEnums { GreaterThan = 'greaterThan', GreaterThanOrEqual = 'greaterThanOrEqual', Contains = 'contains', + DoesNotContain = 'doesNotContain', // built-in functions GetNodeOutput = 'getNodeOutput', diff --git a/packages/core/src/automation_manager/magic_variable/sys_functions/context_base.ts b/packages/core/src/automation_manager/magic_variable/sys_functions/context_base.ts index 17a3c42e13..9fad1a641d 100644 --- a/packages/core/src/automation_manager/magic_variable/sys_functions/context_base.ts +++ b/packages/core/src/automation_manager/magic_variable/sys_functions/context_base.ts @@ -17,8 +17,8 @@ */ import { IRobotTaskRuntimeContext, OperatorEnums } from 'automation_manager/interface'; -import { Field } from 'model/field'; import type { IReduxState } from 'exports/store/interfaces'; +import { Field } from 'model/field'; import { FOperator } from 'types/view_types'; /** @@ -26,10 +26,10 @@ import { FOperator } from 'types/view_types'; */ export function getNodeOutput(_context: IRobotTaskRuntimeContext, nodeId: string) { - if (!_context.executedNodeIds.includes(nodeId)) { + if (!_context.executedNodeIds.includes(nodeId) && !_context.executedNodeIds.includes(_context.robot.triggerId)) { throw Error(`${nodeId} Does Not Executed!`); } - return _context.context[nodeId]!.output; + return _context.context[nodeId]?.output || _context.context[_context.robot.triggerId]?.output; } // for now we have 3 trigger of apitable, their output will be like this: diff --git a/packages/core/src/cell_format_checker/cell_format_checker.ts b/packages/core/src/cell_format_checker/cell_format_checker.ts index c1847ef732..c70f1d8c86 100644 --- a/packages/core/src/cell_format_checker/cell_format_checker.ts +++ b/packages/core/src/cell_format_checker/cell_format_checker.ts @@ -25,14 +25,20 @@ import { Field } from 'model/field'; import { ICellValue } from 'model/record'; import produce from 'immer'; import { FieldType, IField } from 'types'; +import { OneWayLinkField } from '../model/field/one_way_link_field'; export class CellFormatChecker { constructor(private store: Store) {} static checkValueValid(cellValue: any, field: IField, state: IReduxState) { - if (Field.bindContext(field, state).validate(cellValue)) { + const isValid = Field.bindContext(field, state).validate(cellValue); + if (isValid) { return cellValue; } + // One-way link invalid data needs to be filtered out + if (field.type === FieldType.OneWayLink) { + return (Field.bindContext(field, state) as OneWayLinkField).filterRecordIds(cellValue); + } return null; } diff --git a/packages/core/src/command_manager/command.ts b/packages/core/src/command_manager/command.ts index f55b38b2f8..b8b885611b 100644 --- a/packages/core/src/command_manager/command.ts +++ b/packages/core/src/command_manager/command.ts @@ -36,7 +36,7 @@ export interface ICollaCommandDefExecuteSuccessResult extends ICollaCom /** * @description This property exists if the action of the current command contains changes to cell data */ - fieldMapSnapshot?: IFieldMap + fieldMapSnapshot?: IFieldMap; } export interface ICollaCommandDefExecuteFailResult extends ICollaCommandExecuteResultBase { @@ -44,8 +44,7 @@ export interface ICollaCommandDefExecuteFailResult extends ICollaCommandExecuteR reason: ExecuteFailReason; } -export type ICollaCommandDefExecuteResult = ICollaCommandDefExecuteSuccessResult | - ICollaCommandDefExecuteFailResult; +export type ICollaCommandDefExecuteResult = ICollaCommandDefExecuteSuccessResult | ICollaCommandDefExecuteFailResult; /** * Collaborative Command definition @@ -59,8 +58,7 @@ export interface ICollaCommandDef { /** * Actions are generated if the execution is successful, and the reason is returned if it fails. No need to deal with returning null. */ - readonly execute: (context: ICollaCommandExecuteContext, options: T) => - ICollaCommandDefExecuteResult | null; + readonly execute: (context: ICollaCommandExecuteContext, options: T) => ICollaCommandDefExecuteResult | null; /** * Determine whether the current undo can be undone, if not, it can be undo by default @@ -80,9 +78,10 @@ export interface ICommandOptionBase { } export class CollaCommand { - - constructor(private _cmdDef: ICollaCommandDef, public name: string) { - } + constructor( + private _cmdDef: ICollaCommandDef, + public name: string + ) {} undoable(): boolean { return this._cmdDef.undoable; diff --git a/packages/core/src/commands/datasheet/archive_record.ts b/packages/core/src/commands/datasheet/archive_record.ts index c3c11bca5c..daeec024b8 100644 --- a/packages/core/src/commands/datasheet/archive_record.ts +++ b/packages/core/src/commands/datasheet/archive_record.ts @@ -1,10 +1,6 @@ import { ICollaCommandDef, ExecuteResult } from 'command_manager'; import { CollaCommandName } from 'commands/enum'; -import { - getActiveDatasheetId, - getSnapshot, - getField, -} from 'modules/database/store/selectors/resource/datasheet/base'; +import { getActiveDatasheetId, getSnapshot, getField } from 'modules/database/store/selectors/resource/datasheet/base'; import { FieldType, ILinkField, ResourceType } from 'types'; import { DatasheetActions } from 'commands_actions/datasheet'; @@ -19,7 +15,7 @@ export const archiveRecord: ICollaCommandDef = { undoable: false, execute: (context, options) => { - const { state: state, ldcMaintainer } = context; + const { state: state } = context; const { data } = options; const datasheetId = options.datasheetId || getActiveDatasheetId(state)!; const snapshot = getSnapshot(state, datasheetId); @@ -45,32 +41,41 @@ export const archiveRecord: ICollaCommandDef = { state, }); + const addArchivedRecordIdsActions = DatasheetActions.addArchiveRecordIdsToAction(snapshot, { recordIds: data }); + if(addArchivedRecordIdsActions) { + addArchivedRecordIdsActions.forEach(action => { + actions.push(action); + }); + + } /** * According to the self-association field, generate a map, the key is recordId, * and the value is the id array of those records associated with this recordId. * Multiple self-associated fields will have multiple such maps */ const fieldRelinkMap: { [fieldId: string]: { [recordId: string]: string[] } } = {}; - linkField.filter(field => { - // Filter out the associated field of the word table - return !field.property.brotherFieldId; - }).forEach(field => { - const reLinkRecords: { [recordId: string]: string[] } = {}; - Object.values(snapshot.recordMap).forEach(v => { - const linkRecords = v.data[field.id] as string[] | undefined; - if (linkRecords) { - linkRecords.forEach(id => { - if (!reLinkRecords[id]) { - reLinkRecords[id] = []; - } - reLinkRecords[id]!.push(v.id); - }); - } + linkField + .filter((field) => { + // Filter out the associated field of the word table + return !field.property.brotherFieldId; + }) + .forEach((field) => { + const reLinkRecords: { [recordId: string]: string[] } = {}; + Object.values(snapshot.recordMap).forEach((v) => { + const linkRecords = v.data[field.id] as string[] | undefined; + if (linkRecords) { + linkRecords.forEach((id) => { + if (!reLinkRecords[id]) { + reLinkRecords[id] = []; + } + reLinkRecords[id]!.push(v.id); + }); + } + }); + fieldRelinkMap[field.id] = reLinkRecords; }); - fieldRelinkMap[field.id] = reLinkRecords; - }); - data.forEach(recordId => { + data.forEach((recordId) => { const record = snapshot.recordMap[recordId]; if (!record) { return; @@ -84,7 +89,7 @@ export const archiveRecord: ICollaCommandDef = { // self-association oldValue = fieldRelinkMap[field.id]![record.id] || undefined; // LinkedActions are not generated when the self-table is associated and the associated record contains the deleted record itself - oldValue = oldValue?.filter(item => !data.includes(item)); + oldValue = oldValue?.filter((item) => !data.includes(item)); } const linkedSnapshot = getSnapshot(state, field.property.foreignDatasheetId)!; @@ -99,10 +104,9 @@ export const archiveRecord: ICollaCommandDef = { metaData: { foreignDatasheetId: field.property.foreignDatasheetId }, }); } - ldcMaintainer.insert(state, linkedSnapshot, record.id, field, null, oldValue); }); }, []); - + return { result: ExecuteResult.Success, resourceId: datasheetId, diff --git a/packages/core/src/commands/datasheet/delete_archived_record.ts b/packages/core/src/commands/datasheet/delete_archived_record.ts index 5c8b567c0a..7c3efa5d4d 100644 --- a/packages/core/src/commands/datasheet/delete_archived_record.ts +++ b/packages/core/src/commands/datasheet/delete_archived_record.ts @@ -1,13 +1,15 @@ -import { ICollaCommandDef, ExecuteResult } from 'command_manager'; +import { ICollaCommandDef, ExecuteResult, ILinkedActions } from 'command_manager'; import { CollaCommandName } from 'commands/enum'; import { getActiveDatasheetId, getSnapshot, } from 'modules/database/store/selectors/resource/datasheet/base'; import { DatasheetActions } from 'commands_actions/datasheet'; -import { IJOTAction } from 'engine/ot'; -import { ResourceType } from 'types'; +import { IJOTAction, OTActionName } from 'engine/ot'; +import { FieldType, ResourceType } from 'types'; +import { getCellValue } from '../../modules/database/store/selectors/resource'; +import { isEqual } from 'lodash'; export interface IDeleteArchivedRecordsOptions { cmd: CollaCommandName.DeleteArchivedRecords; @@ -28,6 +30,46 @@ export const deleteArchivedRecords: ICollaCommandDef { + const recordId = record.id; + const value = record.data[fieldId] as string[] | null; + if (value) { + value.forEach(id => { + const oldValue = getCellValue(state, linkedSnapshot, id, field.property.brotherFieldId!) as string[] | null; + const value = oldValue ? oldValue.filter(v => v !== recordId) : null; + if (isEqual(value, oldValue)) { + return; + } + const path = ['recordMap', id, 'data', field.property.brotherFieldId!]; + const samePathIndex = _linkedActions.findIndex(action => isEqual(action.p, path)); + if (samePathIndex > -1) { + // @ts-ignore + _linkedActions[samePathIndex].oi = _linkedActions[samePathIndex].oi.filter(v => v !== recordId); + } else { + _linkedActions.push({ + n: OTActionName.ObjectReplace, + p: path, + oi: value, + od: oldValue, + }); + } + }); + } + }); + linkedActions.push({ + datasheetId: field.property.foreignDatasheetId, + actions: _linkedActions, + }); + } + } const unarchiveRecordsActions = DatasheetActions.deleteArchivedRecords2Action(snapshot, { recordsData: data }); @@ -42,6 +84,7 @@ export const deleteArchivedRecords: ICollaCommandDef = { }; }, }; - -/* - - declare module 'command_manager/command_manager' { - interface CollaCommandManager { - execute(options: ISetRecordsOptions & { cmd: 'SetRecords' }); - } - } - - */ diff --git a/packages/core/src/commands/datasheet/unarchive_records.ts b/packages/core/src/commands/datasheet/unarchive_records.ts index f81edb04f5..37fa2808c1 100644 --- a/packages/core/src/commands/datasheet/unarchive_records.ts +++ b/packages/core/src/commands/datasheet/unarchive_records.ts @@ -8,6 +8,8 @@ import { import { DatasheetActions } from 'commands_actions/datasheet'; import { IJOTAction } from 'engine/ot'; import { FieldType, ResourceType } from 'types'; +import { getCellValue } from 'modules/database/store/selectors/resource'; +import { IDPrefix } from 'utils'; export interface IUnarchiveRecordsOptions { cmd: CollaCommandName.UnarchiveRecords; @@ -18,7 +20,7 @@ export interface IUnarchiveRecordsOptions { export const unarchiveRecords: ICollaCommandDef = { undoable: false, execute: (context, options) => { - const { state: state } = context; + const { state: state, ldcMaintainer } = context; const { data } = options; const datasheetId = options.datasheetId || getActiveDatasheetId(state)!; const snapshot = getSnapshot(state, datasheetId); @@ -32,8 +34,25 @@ export const unarchiveRecords: ICollaCommandDef = { const linkFieldIds: string[] = []; for (const fieldId in snapshot.meta.fieldMap) { const field = snapshot.meta.fieldMap[fieldId]!; - if (field.type === FieldType.Link) { - linkFieldIds.push(fieldId); + if (field.type === FieldType.Link && field.property.brotherFieldId && field.property.foreignDatasheetId !== datasheetId) { + data.forEach(record => { + const recordId = record.id; + const value = record.data[fieldId]; + const oldValue = getCellValue(state, snapshot, recordId, fieldId) as string[] | null; + const linkedSnapshot = getSnapshot(state, field.property.foreignDatasheetId)!; + const isValueValid = value ? Array.isArray(value) && value.every(v => v.startsWith(IDPrefix.Record)) : true; + const isOldValueValid = oldValue ? Array.isArray(oldValue) && oldValue.every(v => v.startsWith(IDPrefix.Record)) : true; + if (isValueValid && isOldValueValid) { + ldcMaintainer.insert( + state, + linkedSnapshot, + recordId, + field, + value as string[] | null, + oldValue, + ); + } + }); } } diff --git a/packages/core/src/commands_actions/datasheet.ts b/packages/core/src/commands_actions/datasheet.ts index 0aecd5fc05..04c0372f7c 100644 --- a/packages/core/src/commands_actions/datasheet.ts +++ b/packages/core/src/commands_actions/datasheet.ts @@ -21,15 +21,7 @@ import { IJOTAction, IObjectInsertAction, IObjectReplaceAction, OTActionName } f import { ViewPropertyFilter } from 'engine/view_property_filter'; import { findIndex, isEqual, omit, unionWith } from 'lodash'; import { getMaxViewCountPerSheet } from 'model/utils'; -import { - IComments, - IMirrorSnapshot, - IRecordAlarm, - IReduxState, - ITemporaryView, - IUserInfo, - IViewLockInfo, -} from '../exports/store/interfaces'; +import { IComments, IMirrorSnapshot, IRecordAlarm, IReduxState, ITemporaryView, IUserInfo, IViewLockInfo } from '../exports/store/interfaces'; import { RowHeightLevel } from 'modules/shared/store/constants'; import { ViewType } from 'modules/shared/store/constants'; import { getDateTimeCellAlarm } from 'modules/database/store/selectors/resource/datasheet/calc'; @@ -48,11 +40,8 @@ import { import { getCellValue } from 'modules/database/store/selectors/resource/datasheet/cell_calc'; import { getViewById } from 'modules/database/store/selectors/resource/datasheet/base'; -import { getFilterInfo,sortRowsBySortInfo } from 'modules/database/store/selectors/resource/datasheet/rows_calc'; -import { - getResourceActiveWidgetPanel, - getResourceWidgetPanels, -} from 'modules/database/store/selectors/resource'; +import { getFilterInfo, sortRowsBySortInfo } from 'modules/database/store/selectors/resource/datasheet/rows_calc'; +import { getResourceActiveWidgetPanel, getResourceWidgetPanels } from 'modules/database/store/selectors/resource'; import { getActiveViewGroupInfo, getFieldMap, @@ -105,7 +94,7 @@ function getDefaultNewRecordDataByFilter( datasheetId: string, filterInfo: IFilterInfo, fieldMap: { [id: string]: IField }, - userInfo?: IUserInfo, + userInfo?: IUserInfo ): { [fieldId: string]: ICellValue } { const { conditions } = filterInfo; const recordData: { [fieldId: string]: ICellValue } = {}; @@ -119,15 +108,18 @@ function getDefaultNewRecordDataByFilter( // And combination // 1. Group filter conditions by fieldId - const conditionGroups = conditions.reduce((prev, condition) => { - const { fieldId } = condition; - let group = prev[fieldId]; - if (!group) { - group = prev[fieldId] = []; - } - group.push(condition); - return prev; - }, {} as { [fieldId: string]: IFilterCondition[] }); + const conditionGroups = conditions.reduce( + (prev, condition) => { + const { fieldId } = condition; + let group = prev[fieldId]; + if (!group) { + group = prev[fieldId] = []; + } + group.push(condition); + return prev; + }, + {} as { [fieldId: string]: IFilterCondition[] } + ); // 2. Determine the final `And` fill value, for each field corresponding to the filter condition for (const fieldId in conditionGroups) { @@ -158,7 +150,7 @@ function getDefaultNewRecordDataByFilter( // TODO: currently multi-value type field is basic type, so use "Set". // In the future, if reference type, optimize this if (isMultiValueField && Array.isArray(currentValue)) { - currentValue.forEach(v => { + currentValue.forEach((v) => { if (field.type === FieldType.Member && v === OtherTypeUnitId.Self) { userInfo && candidate.add(userInfo!.unitId); return; @@ -194,7 +186,7 @@ function getDefaultNewRecordDataByFilter( * and 1 cannot pass =1 and <0, default fill in this value does not meet user expectations. */ const viewFilterDerivate = new ViewFilterDerivate(state, datasheetId); - const pass = conditionGroup.every(condition => viewFilterDerivate.doFilter(condition, field, result)); + const pass = conditionGroup.every((condition) => viewFilterDerivate.doFilter(condition, field, result)); if (pass) { // different fields of `And`, only need to assign the values that have values to them. recordData[fieldId] = result; @@ -215,7 +207,7 @@ export class DatasheetActions { return null; } - if (!views.every(viw => viw.id !== view.id)) { + if (!views.every((viw) => viw.id !== view.id)) { return null; } @@ -285,7 +277,7 @@ export class DatasheetActions { const views = snapshot.meta.views; const viewId = payload.viewId; // check whether current is activeView - const viewIndex = findIndex(views, viw => viw.id === viewId); + const viewIndex = findIndex(views, (viw) => viw.id === viewId); if (viewIndex < 0) { return null; } @@ -303,24 +295,24 @@ export class DatasheetActions { */ static modifyView2Action( snapshot: ISnapshot, - payload: { viewId: string; key: 'name' | 'description' | 'columns' | 'displayHiddenColumnWithinMirror'; value: string | IViewColumn[] | boolean }, + payload: { viewId: string; key: 'name' | 'description' | 'columns' | 'displayHiddenColumnWithinMirror'; value: string | IViewColumn[] | boolean } ): IJOTAction[] | null { const views = snapshot.meta.views; const { viewId, key, value } = payload; // check whether current is activeView - const viewIndex = findIndex(views, viw => viw.id === viewId); + const viewIndex = findIndex(views, (viw) => viw.id === viewId); if (viewIndex < 0) { return null; } if (key === 'columns' && Array.isArray(value)) { const rlt: IJOTAction[] = []; - value.forEach(item => { + value.forEach((item) => { const fieldId = item.fieldId; const view = views[viewIndex]!; const columns = view['columns']; - const modifyColumnIndex = columns.findIndex(column => column.fieldId === fieldId); + const modifyColumnIndex = columns.findIndex((column) => column.fieldId === fieldId); const oldItem = columns[modifyColumnIndex]; if (!isEqual(oldItem, item)) { rlt.push({ @@ -349,7 +341,15 @@ export class DatasheetActions { */ static addField2Action( snapshot: ISnapshot, - payload: { field: IField; viewId?: string; index?: number; fieldId?: string; offset?: number; hiddenColumn?: boolean, forceColumnVisible?:boolean }, + payload: { + field: IField; + viewId?: string; + index?: number; + fieldId?: string; + offset?: number; + hiddenColumn?: boolean; + forceColumnVisible?: boolean; + } ): IJOTAction[] | null { const fieldMap = snapshot.meta.fieldMap; const views = snapshot.meta.views; @@ -357,7 +357,7 @@ export class DatasheetActions { const actions = views.reduce((pre, cur, viewIndex) => { let columnIndex = cur.columns.length; - if (cur.columns.some(column => column.fieldId === field.id)) { + if (cur.columns.some((column) => column.fieldId === field.id)) { return pre; } // as new columns with duplicate operation, pass in `index` to take precedence @@ -367,7 +367,7 @@ export class DatasheetActions { // only under specified view, if fieldId exists, calc index by every view's fieldId if (fieldId) { - const fieldIdIndex = cur.columns.findIndex(column => column.fieldId === fieldId); + const fieldIdIndex = cur.columns.findIndex((column) => column.fieldId === fieldId); columnIndex = fieldIdIndex + (offset ?? 0); } @@ -380,8 +380,8 @@ export class DatasheetActions { // handler of new column in view function viewColumnHandler() { - if(payload.forceColumnVisible != null) { - newColumn.hidden = payload.forceColumnVisible===true; + if (payload.forceColumnVisible != null) { + newColumn.hidden = !payload.forceColumnVisible; return; } let hiddenKey = 'hidden'; @@ -397,7 +397,7 @@ export class DatasheetActions { break; default: // current view default display or view has no hidden column - if ((viewId && viewId === cur.id) || cur.columns.every(column => !column.hidden)) { + if ((viewId && viewId === cur.id) || cur.columns.every((column) => !column.hidden)) { newColumn.hidden = Boolean(hiddenColumn); return; } @@ -440,7 +440,7 @@ export class DatasheetActions { // delete all columns related attributes in all view const actions = views.reduce((action, view, index) => { - const columnIndex = view.columns.findIndex(column => column.fieldId === fieldId); + const columnIndex = view.columns.findIndex((column) => column.fieldId === fieldId); if (columnIndex < 0) { return action; @@ -449,7 +449,7 @@ export class DatasheetActions { const deleteGroupOrSortInfo = (type: 'groupInfo' | 'sortInfo') => { const info = type === 'groupInfo' ? view.groupInfo : view.sortInfo?.rules; if (info) { - const infoIndex = info.findIndex(gp => gp.fieldId === fieldId); + const infoIndex = info.findIndex((gp) => gp.fieldId === fieldId); if (infoIndex > -1 && info.length > 1) { if (type === 'groupInfo') { action.push({ @@ -530,7 +530,7 @@ export class DatasheetActions { // the dependencies in filter's field, also need to be deleted if (view.filterInfo) { - const newConditions = view.filterInfo.conditions.filter(condition => { + const newConditions = view.filterInfo.conditions.filter((condition) => { if (condition.fieldId === fieldId) { return false; } @@ -573,7 +573,7 @@ export class DatasheetActions { if (field) { // when delete date column, remove alarm const recordMap = snapshot.recordMap; - Object.keys(recordMap).forEach(recordId => { + Object.keys(recordMap).forEach((recordId) => { const alarm = getDateTimeCellAlarm(snapshot, recordId, field.id); if (alarm) { const alarmActions = DatasheetActions.setDateTimeCellAlarm(snapshot, { @@ -605,7 +605,7 @@ export class DatasheetActions { } const view = snapshot.meta.views[viewIndex] as IGridViewProperty; - const columnIndex = view.columns.findIndex(column => column.fieldId === fieldId); + const columnIndex = view.columns.findIndex((column) => column.fieldId === fieldId); const column = view.columns[columnIndex]!; if (columnIndex < 0 || ![ViewType.Grid, ViewType.Gantt].includes(view.type) || column.width === width) { return null; @@ -628,7 +628,7 @@ export class DatasheetActions { } const view = snapshot.meta.views[viewIndex]!; - const columnIndex = view.columns.findIndex(column => column.fieldId === fieldId); + const columnIndex = view.columns.findIndex((column) => column.fieldId === fieldId); if (columnIndex < 0 || columnIndex === target) { return null; } @@ -645,7 +645,7 @@ export class DatasheetActions { */ static setColumnStatType2Action = ( snapshot: ISnapshot, - payload: { viewId: string; fieldId: string; statType?: StatType | null }, + payload: { viewId: string; fieldId: string; statType?: StatType | null } ): IJOTAction | null => { const { fieldId, statType, viewId } = payload; @@ -655,7 +655,7 @@ export class DatasheetActions { } const view = snapshot.meta.views[viewIndex] as IGridViewProperty; - const columnIndex = view.columns.findIndex(column => column.fieldId === fieldId); + const columnIndex = view.columns.findIndex((column) => column.fieldId === fieldId); const column = view.columns[columnIndex]!; if (columnIndex < 0 || ![ViewType.Grid, ViewType.Gantt].includes(view.type) || column.statType === statType) { return null; @@ -748,7 +748,10 @@ export class DatasheetActions { /** * add record to table */ - static addRecord2Action(snapshot: ISnapshot, payload: { viewId: string; record: IRecord; index: number, newRecordIndex: number }): IJOTAction[] | null { + static addRecord2Action( + snapshot: ISnapshot, + payload: { viewId: string; record: IRecord; index: number; newRecordIndex: number } + ): IJOTAction[] | null { const recordMap = snapshot.recordMap; const views = snapshot.meta.views; const { record, index, viewId, newRecordIndex } = payload; @@ -756,7 +759,7 @@ export class DatasheetActions { const actions = views.reduce((pre, cur, viewIndex) => { // multi add rows length no change let rowIndex = cur.rows.length + newRecordIndex; - if (cur.rows.some(row => row.recordId === record.id)) { + if (cur.rows.some((row) => row.recordId === record.id)) { return pre; } @@ -794,7 +797,7 @@ export class DatasheetActions { recordId: string; fieldId: string; value: ICellValue; - }, + } ): IJOTAction | null { const { recordId, fieldId, value } = payload; @@ -848,7 +851,7 @@ export class DatasheetActions { recordIds: string[]; getFieldByFieldId(fieldId: string): IField; state: IReduxState; - }, + } ): IJOTAction[] { const recordMap = snapshot.recordMap; const recordSize = Object.keys(recordMap).length; @@ -917,7 +920,7 @@ export class DatasheetActions { }, []); } - recordIds.forEach(recordId => { + recordIds.forEach((recordId) => { const record = recordMap[recordId]; if (record) { const data = {}; @@ -934,7 +937,7 @@ export class DatasheetActions { // when delete date, remove alarm // TODO(kailang) ObjectDelete has did this - Object.keys(fieldMap).forEach(fieldId => { + Object.keys(fieldMap).forEach((fieldId) => { if (fieldMap[fieldId]!.type === FieldType.DateTime) { const alarm = getDateTimeCellAlarm(snapshot, recordId, fieldId); if (alarm) { @@ -970,7 +973,7 @@ export class DatasheetActions { recordId: string; fieldId: string; alarm: IRecordAlarm | null; - }, + } ): IJOTAction[] | null { const { recordId, fieldId, alarm } = payload; const oldAlarm = getDateTimeCellAlarm(snapshot, recordId, fieldId); @@ -1045,7 +1048,7 @@ export class DatasheetActions { } const view = snapshot.meta.views[viewIndex]!; - const recordIndex = view.rows.findIndex(row => row.recordId === recordId); + const recordIndex = view.rows.findIndex((row) => row.recordId === recordId); if (recordIndex < 0) { return null; } @@ -1060,7 +1063,7 @@ export class DatasheetActions { static setViewSort2Action( state: IReduxState, snapshot: ISnapshot, - payload: { viewId: string; sortInfo?: ISortInfo; applySort?: boolean }, + payload: { viewId: string; sortInfo?: ISortInfo; applySort?: boolean } ): IJOTAction[] | null { const { viewId, sortInfo, applySort } = payload; const viewIndex = getViewIndex(snapshot, viewId); @@ -1235,7 +1238,7 @@ export class DatasheetActions { static getNewViewId(views: IViewProperty[]): string { return getNewId( IDPrefix.View, - views.map(view => view.id), + views.map((view) => view.id) ); } @@ -1266,7 +1269,7 @@ export class DatasheetActions { recordId: string, viewId?: string, groupCellValues?: ICellValue[], - userInfo?: IUserInfo, + userInfo?: IUserInfo ): IRecord { const fieldMap = getFieldMap(state, snapshot.datasheetId); const record: IRecord = { @@ -1380,7 +1383,7 @@ export class DatasheetActions { } return getUniqName( prefix, - views.map(view => view.name), + views.map((view) => view.name) ); } @@ -1414,7 +1417,7 @@ export class DatasheetActions { switch (view.type) { case ViewType.Grid: case ViewType.Gantt: { - recordIds = view.rows.map(view => view.recordId); + recordIds = view.rows.map((view) => view.recordId); } } } @@ -1436,7 +1439,7 @@ export class DatasheetActions { datasheetId: string; recordId: string; insertComments?: Omit[]; - }, + } ): IJOTAction[] | null { const { recordId, datasheetId, insertComments } = options; const recordMap = getSnapshot(state, datasheetId)!.recordMap; @@ -1504,7 +1507,7 @@ export class DatasheetActions { n: OTActionName.NumberAdd, p: ['recordMap', recordId, 'commentCount'], na: -1, - }, + } ); return actions; @@ -1514,13 +1517,13 @@ export class DatasheetActions { _state: IReduxState, panelId: string, widgetPanels: IWidgetPanel[], - resourceType: ResourceType.Mirror | ResourceType.Datasheet, + resourceType: ResourceType.Mirror | ResourceType.Datasheet ): IJOTAction[] | null { if (!widgetPanels) { return null; } - const index = widgetPanels.findIndex(item => { + const index = widgetPanels.findIndex((item) => { return item.id === panelId; }); @@ -1614,13 +1617,13 @@ export class DatasheetActions { _state: IReduxState, newPanel: IWidgetPanel, widgetPanels: IWidgetPanel[], - resourceType: ResourceType.Mirror | ResourceType.Datasheet, + resourceType: ResourceType.Mirror | ResourceType.Datasheet ): IJOTAction[] | null { if (!widgetPanels) { return null; } - const index = widgetPanels.findIndex(item => { + const index = widgetPanels.findIndex((item) => { return item.id === newPanel.id; }); @@ -1651,7 +1654,7 @@ export class DatasheetActions { static addWidgetToPanel2Action( _state: IReduxState, - { installationIndex, panelIndex, widgetId }: { installationIndex: number; panelIndex: number; widgetId: string }, + { installationIndex, panelIndex, widgetId }: { installationIndex: number; panelIndex: number; widgetId: string } ): IJOTAction[] | null { const newWidget = { id: widgetId, @@ -1670,7 +1673,7 @@ export class DatasheetActions { static addWidgetToPanelWithMirror2Action( _state: IReduxState, - { installationIndex, panelIndex, widgetId }: { installationIndex: number; panelIndex: number; widgetId: string }, + { installationIndex, panelIndex, widgetId }: { installationIndex: number; panelIndex: number; widgetId: string } ): IJOTAction[] | null { const newWidget = { id: widgetId, @@ -1693,7 +1696,7 @@ export class DatasheetActions { widgetPanelIndex: number; widget: IWidgetInPanel; widgetIndex: number; - }, + } ): IJOTAction[] { const { widgetPanelIndex, widgetIndex, widget } = options; return [ @@ -1711,7 +1714,7 @@ export class DatasheetActions { widgetPanelIndex: number; widget: IWidgetInPanel; widgetIndex: number; - }, + } ): IJOTAction[] { const { widgetPanelIndex, widgetIndex, widget } = options; return [ @@ -1737,7 +1740,7 @@ export class DatasheetActions { widgetHeight: number; resourceId: string; resourceType: ResourceType; - }, + } ): IJOTAction[] | null { const activeWidgetPanel = getResourceActiveWidgetPanel(state, resourceId, resourceType)!; const widget = activeWidgetPanel.widgets[widgetIndex]!; @@ -1762,7 +1765,7 @@ export class DatasheetActions { layout, resourceType, resourceId, - }: { widgetPanelIndex: number; layout: any[]; resourceType: ResourceType; resourceId: string }, + }: { widgetPanelIndex: number; layout: any[]; resourceType: ResourceType; resourceId: string } ): IJOTAction[] | null { const widgetPanel = getResourceWidgetPanels(state, resourceId, resourceType); const oldLayout = widgetPanel?.[widgetPanelIndex]?.widgets; @@ -1805,7 +1808,7 @@ export class DatasheetActions { static manualSaveView2Action(snapshot: ISnapshot, payload: { viewId: string; viewProperty: ITemporaryView }): IJOTAction[] | null { const { viewId, viewProperty: serverView } = payload; - const viewIndex = snapshot.meta.views.findIndex(view => view.id === viewId); + const viewIndex = snapshot.meta.views.findIndex((view) => view.id === viewId); if (viewIndex == null) { return null; @@ -1848,7 +1851,7 @@ export class DatasheetActions { static resetView2Action(snapshot: ISnapshot, payload: { viewId: string; viewProperty: ITemporaryView }): IJOTAction[] | null { const { viewId, viewProperty: serverView } = payload; - const viewIndex = snapshot.meta.views.findIndex(view => view.id === viewId); + const viewIndex = snapshot.meta.views.findIndex((view) => view.id === viewId); if (viewIndex == null) { return null; @@ -1890,7 +1893,7 @@ export class DatasheetActions { static setViewAutoSave2Action(snapshot: ISnapshot, { viewId, autoSave }: { viewId: string; autoSave: boolean }): IJOTAction | null { const views = snapshot.meta.views; - const viewIndex = views.findIndex(view => view.id === viewId); + const viewIndex = views.findIndex((view) => view.id === viewId); if (viewIndex == null) { return null; @@ -1940,7 +1943,7 @@ export class DatasheetActions { * @param payload */ - static unarchivedRecords2Action(snapshot: ISnapshot, payload: { recordsData: any, linkFields: string[] }): IJOTAction[] | null { + static unarchivedRecords2Action(snapshot: ISnapshot, payload: { recordsData: any; linkFields: string[] }): IJOTAction[] | null { const { recordsData, linkFields } = payload; if (!recordsData || !recordsData.length || !snapshot) return null; @@ -1949,8 +1952,7 @@ export class DatasheetActions { const rlt: IJOTAction[] = []; for (let i = 0; i < recordsData.length; i++) { - - for(let j = 0; j < views.length; j++) { + for (let j = 0; j < views.length; j++) { rlt.push({ n: OTActionName.ListInsert, p: ['meta', 'views', j, 'rows', rows.length], @@ -1959,24 +1961,58 @@ export class DatasheetActions { } const newRecord = produce(recordsData[i], (draft: any) => { - Object.keys(draft.data).forEach(key => { - if(linkFields.includes(key)) { + Object.keys(draft.data).forEach((key) => { + if (linkFields.includes(key)) { draft.data[key] = []; } }); }); + const archivedRecordIds = snapshot.meta.archivedRecordIds || []; + recordsData.forEach((record: any) => { + const index = archivedRecordIds.findIndex((id) => id === record.id); + if (index >= 0) { + rlt.push({ + n: OTActionName.ListDelete, + p: ['meta', 'archivedRecordIds', index], + ld: record.id, + }); + } + }); + rlt.push({ n: OTActionName.ObjectInsert, p: ['recordMap', recordsData[i].id], oi: newRecord, }); - } return rlt; } + /** + * add archieve RecordIds + * @param snapshot + * @param payload + */ + static addArchiveRecordIdsToAction(snapshot: ISnapshot, payload: { recordIds: string[] }): IJOTAction[] | null { + const { recordIds } = payload; + const archivedRecordIds = snapshot.meta.archivedRecordIds || []; + + if (!recordIds || !recordIds.length) return null; + + const rlt: IJOTAction[] = []; + recordIds.forEach((recordId, index) => { + if (archivedRecordIds.includes(recordId)) return; + rlt.push({ + n: OTActionName.ListInsert, + p: ['meta', 'archivedRecordIds', archivedRecordIds.length + index], + li: recordId, + }); + }); + return rlt; + } + /** * Delete archieve recordIds */ @@ -1994,6 +2030,18 @@ export class DatasheetActions { }); } + const archivedRecordIds = snapshot.meta.archivedRecordIds || []; + recordsData.forEach((record: any) => { + const index = archivedRecordIds.findIndex((id) => id === record.id); + if (index >= 0) { + rlt.push({ + n: OTActionName.ListDelete, + p: ['meta', 'archivedRecordIds', index], + ld: record.id, + }); + } + }); + return rlt; } } diff --git a/packages/core/src/config/constant.ts b/packages/core/src/config/constant.ts index f6e93216bc..052132e101 100644 --- a/packages/core/src/config/constant.ts +++ b/packages/core/src/config/constant.ts @@ -49,6 +49,7 @@ export enum NodeType { AI = 9, AUTOMATION = 10, VIEW = 11, + CUSTOM_PAGE = 12, ASSET_FILE = 98, TRASH = 99, } @@ -95,8 +96,19 @@ export enum NodeTypeReg { AUTOMATION = 'aut', MIRROR = 'mir', WIDGET = 'wdt', + AI = 'ai_', } +export const nodePrefixNameMap = new Map([ + [NodeTypeReg.FOLDER, t(Strings.folder)], + [NodeTypeReg.DATASHEET, t(Strings.datasheet)], + [NodeTypeReg.FORM, t(Strings.form)], + [NodeTypeReg.AUTOMATION, t(Strings.automation)], + [NodeTypeReg.MIRROR, t(Strings.mirror)], + [NodeTypeReg.DASHBOARD, t(Strings.dashboard)], + [NodeTypeReg.AI, t(Strings.ai_chat)], +]); + export enum SocialType { WECOM = 1, DINGTALK = 2, @@ -206,6 +218,15 @@ export const nodePermissionMap = new Map([ [permission.updater]: '在「只可阅读」基础上,还可以编辑小程序和分享仪表盘', }, ], + [ + NodeType.CUSTOM_PAGE, + { + [permission.manager]: t(Strings.embed_page_node_permission_manager), + [permission.editor]: t(Strings.embed_page_node_permission_editor), + [permission.reader]: t(Strings.embed_page_node_permission_reader), + [permission.updater]: t(Strings.embed_page_node_permission_updater), + }, + ], ]); export const permissionText = { @@ -278,6 +299,7 @@ export enum Modules { CATALOG = 'CATALOG', SHARE = 'SHARE', TEAM_TREE = 'TEAM_TREE', + PRIVATE = 'PRIVATE', } /** Indicates the type of menu, each different type of menu corresponds to a different menu list */ @@ -293,7 +315,8 @@ export enum ContextMenuType { MIRROR = 'MIRROR', // Action menu for view tab bar FORM_FIELD_OP = 'FORM_FIELD_OP', // Magical form field operation menu EXPAND_RECORD_FIELD = 'EXPAND_RECORD_FIELD', // Expand the operation field configuration in the card - AI = 'AI' + AI = 'AI', + CUSTOM_PAGE = 'CUSTOM_PAGE', } export const NODE_DESCRIPTION_EDITOR_ID = 'folderDescribeEditor'; @@ -371,7 +394,7 @@ export enum ScanQrType { export enum ImproveType { Phone = 'phone', - Email = 'email' + Email = 'email', } export const IDENTIFY_CODE_LOGIN = 'identify_code_login'; // login verify code @@ -502,7 +525,9 @@ export enum WizardIdConstant { PERMISSION_SETTING_EXTEND = 95, // Open permission settings, inherit state PERMISSION_SETTING_OPENED = 96, // Open permission settings, non-inherited state - CREATE_MIRROR_TIP = 106 + CREATE_MIRROR_TIP = 106, + PRICE_MODAL = 104, + AI_TABLE_VIDEO = 115, } export const WIDGET_PANEL_MAX_WIDGET_COUNT = 30; diff --git a/packages/core/src/config/dom_id/datasheet_id.ts b/packages/core/src/config/dom_id/datasheet_id.ts index b14a333e9e..6dc71b7595 100644 --- a/packages/core/src/config/dom_id/datasheet_id.ts +++ b/packages/core/src/config/dom_id/datasheet_id.ts @@ -38,6 +38,7 @@ export const API_BTN = PREFIX + 'API_BTN'; // view tab bar - api panel export const FORM_BTN = PREFIX + 'FORM_BTN'; // View Tab Bar - Magic Form export const WIDGET_BTN = PREFIX + 'WIDGET_BTN'; // View Tab Bar - Widget export const ROBOT_BTN = PREFIX + 'ROBOT_BTN'; // View Tab Bar - Robot +export const COPILOT_BTN = PREFIX + 'COPILOT_BTN'; // View Tab Bar - Copilot export const FORM_LIST_PANEL = PREFIX + 'FORM_LIST_PANEL'; // view tab bar - magic form list export const TIME_MACHINE_BTN = PREFIX + 'TIME_MACHINE_BTN'; // View Tab Bar - Time Machine export const ARCHIVED_RECORDS_BTN = PREFIX + 'ARCHIVED_RECORDS_BTN'; // View Tab Bar - Archived Records diff --git a/packages/core/src/config/dom_id/workbench_side_id.ts b/packages/core/src/config/dom_id/workbench_side_id.ts index 1d723ffa61..9f610a07a6 100644 --- a/packages/core/src/config/dom_id/workbench_side_id.ts +++ b/packages/core/src/config/dom_id/workbench_side_id.ts @@ -58,3 +58,4 @@ export const NEW_CHAT_BOT = PREFIX + 'NEW_CHAT_BOT'; export const NEW_FORM_TEMPLATE = PREFIX + 'NEW_FORM_TEMPLATE'; export const NEW_DASHBOARD = PREFIX + 'NEW_DASHBOARD'; export const NODE_INFO = PREFIX + 'NODE_INFO'; +export const NEW_EMBED = PREFIX + 'NEW_EMBED'; diff --git a/packages/core/src/config/stringkeys.interface.ts b/packages/core/src/config/stringkeys.interface.ts index b206124bf3..3add7e0cb3 100644 --- a/packages/core/src/config/stringkeys.interface.ts +++ b/packages/core/src/config/stringkeys.interface.ts @@ -147,6 +147,15 @@ export type StringKeysMapType = { 'agreed': 'agreed', 'ai_advanced_mode_desc': 'ai_advanced_mode_desc', 'ai_advanced_mode_title': 'ai_advanced_mode_title', + 'ai_agent_anonymous': 'ai_agent_anonymous', + 'ai_agent_conversation_continue_not_supported': 'ai_agent_conversation_continue_not_supported', + 'ai_agent_conversation_list': 'ai_agent_conversation_list', + 'ai_agent_conversation_log': 'ai_agent_conversation_log', + 'ai_agent_conversation_title': 'ai_agent_conversation_title', + 'ai_agent_feedback': 'ai_agent_feedback', + 'ai_agent_historical_message': 'ai_agent_historical_message', + 'ai_agent_history': 'ai_agent_history', + 'ai_agent_message_consumed': 'ai_agent_message_consumed', 'ai_api_curl_template': 'ai_api_curl_template', 'ai_api_footer_desc': 'ai_api_footer_desc', 'ai_api_javascript_template': 'ai_api_javascript_template', @@ -162,6 +171,9 @@ export type StringKeysMapType = { 'ai_chat_unit': 'ai_chat_unit', 'ai_close_setting_tip_content': 'ai_close_setting_tip_content', 'ai_close_setting_tip_title': 'ai_close_setting_tip_title', + 'ai_copilot_generate_response': 'ai_copilot_generate_response', + 'ai_copilot_processs': 'ai_copilot_processs', + 'ai_copilot_start_process_request': 'ai_copilot_start_process_request', 'ai_create_guide_btn_text': 'ai_create_guide_btn_text', 'ai_create_guide_content': 'ai_create_guide_content', 'ai_credit_cost_chart_title': 'ai_credit_cost_chart_title', @@ -686,7 +698,8 @@ export type StringKeysMapType = { 'audit_add_field_role': 'audit_add_field_role', 'audit_add_field_role_detail': 'audit_add_field_role_detail', 'audit_add_node_role': 'audit_add_node_role', - 'audit_add_node_role_detail': 'audit_add_node_role_detail', + 'audit_add_node_role_detail_end': 'audit_add_node_role_detail_end', + 'audit_add_node_role_detail_start': 'audit_add_node_role_detail_start', 'audit_admin_permission_change_event': 'audit_admin_permission_change_event', 'audit_create_template': 'audit_create_template', 'audit_create_template_detail': 'audit_create_template_detail', @@ -694,21 +707,26 @@ export type StringKeysMapType = { 'audit_delete_field_role': 'audit_delete_field_role', 'audit_delete_field_role_detail': 'audit_delete_field_role_detail', 'audit_delete_node_role': 'audit_delete_node_role', - 'audit_delete_node_role_detail': 'audit_delete_node_role_detail', + 'audit_delete_node_role_detail_end': 'audit_delete_node_role_detail_end', + 'audit_delete_node_role_detail_start': 'audit_delete_node_role_detail_start', 'audit_delete_template': 'audit_delete_template', 'audit_delete_template_detail': 'audit_delete_template_detail', 'audit_disable_field_role': 'audit_disable_field_role', 'audit_disable_field_role_detail': 'audit_disable_field_role_detail', 'audit_disable_node_role': 'audit_disable_node_role', - 'audit_disable_node_role_detail': 'audit_disable_node_role_detail', + 'audit_disable_node_role_detail_end': 'audit_disable_node_role_detail_end', + 'audit_disable_node_role_detail_start': 'audit_disable_node_role_detail_start', 'audit_disable_node_share': 'audit_disable_node_share', - 'audit_disable_node_share_detail': 'audit_disable_node_share_detail', + 'audit_disable_node_share_detail_end': 'audit_disable_node_share_detail_end', + 'audit_disable_node_share_detail_start': 'audit_disable_node_share_detail_start', 'audit_enable_field_role': 'audit_enable_field_role', 'audit_enable_field_role_detail': 'audit_enable_field_role_detail', 'audit_enable_node_role': 'audit_enable_node_role', - 'audit_enable_node_role_detail': 'audit_enable_node_role_detail', + 'audit_enable_node_role_detail_end': 'audit_enable_node_role_detail_end', + 'audit_enable_node_role_detail_start': 'audit_enable_node_role_detail_start', 'audit_enable_node_share': 'audit_enable_node_share', - 'audit_enable_node_share_detail': 'audit_enable_node_share_detail', + 'audit_enable_node_share_detail_end': 'audit_enable_node_share_detail_end', + 'audit_enable_node_share_detail_start': 'audit_enable_node_share_detail_start', 'audit_login_event': 'audit_login_event', 'audit_logout_event': 'audit_logout_event', 'audit_organization_change_event': 'audit_organization_change_event', @@ -728,19 +746,20 @@ export type StringKeysMapType = { 'audit_space_invite_user': 'audit_space_invite_user', 'audit_space_invite_user_detail': 'audit_space_invite_user_detail', 'audit_space_node_copy': 'audit_space_node_copy', - 'audit_space_node_copy_detail': 'audit_space_node_copy_detail', + 'audit_space_node_copy_detail_start': 'audit_space_node_copy_detail_start', 'audit_space_node_create': 'audit_space_node_create', - 'audit_space_node_create_detail': 'audit_space_node_create_detail', + 'audit_space_node_create_detail_start': 'audit_space_node_create_detail_start', 'audit_space_node_delete': 'audit_space_node_delete', - 'audit_space_node_delete_detail': 'audit_space_node_delete_detail', + 'audit_space_node_delete_detail_start': 'audit_space_node_delete_detail_start', 'audit_space_node_export': 'audit_space_node_export', 'audit_space_node_export_detail': 'audit_space_node_export_detail', 'audit_space_node_import': 'audit_space_node_import', - 'audit_space_node_import_detail': 'audit_space_node_import_detail', + 'audit_space_node_import_detail_start': 'audit_space_node_import_detail_start', 'audit_space_node_move': 'audit_space_node_move', - 'audit_space_node_move_detail': 'audit_space_node_move_detail', + 'audit_space_node_move_detail_end': 'audit_space_node_move_detail_end', + 'audit_space_node_move_detail_start': 'audit_space_node_move_detail_start', 'audit_space_node_rename': 'audit_space_node_rename', - 'audit_space_node_rename_detail': 'audit_space_node_rename_detail', + 'audit_space_node_rename_detail_start': 'audit_space_node_rename_detail_start', 'audit_space_node_sort': 'audit_space_node_sort', 'audit_space_node_sort_detail': 'audit_space_node_sort_detail', 'audit_space_node_update_cover': 'audit_space_node_update_cover', @@ -754,18 +773,21 @@ export type StringKeysMapType = { 'audit_space_rubbish_node_delete': 'audit_space_rubbish_node_delete', 'audit_space_rubbish_node_delete_detail': 'audit_space_rubbish_node_delete_detail', 'audit_space_rubbish_node_recover': 'audit_space_rubbish_node_recover', - 'audit_space_rubbish_node_recover_detail': 'audit_space_rubbish_node_recover_detail', + 'audit_space_rubbish_node_recover_detail_end': 'audit_space_rubbish_node_recover_detail_end', + 'audit_space_rubbish_node_recover_detail_start': 'audit_space_rubbish_node_recover_detail_start', 'audit_space_template_event': 'audit_space_template_event', 'audit_space_update_logo': 'audit_space_update_logo', 'audit_space_update_logo_detail': 'audit_space_update_logo_detail', 'audit_store_share_node': 'audit_store_share_node', - 'audit_store_share_node_detail': 'audit_store_share_node_detail', + 'audit_store_share_node_detail_start': 'audit_store_share_node_detail_start', 'audit_update_field_role': 'audit_update_field_role', 'audit_update_field_role_detail': 'audit_update_field_role_detail', 'audit_update_node_role': 'audit_update_node_role', - 'audit_update_node_role_detail': 'audit_update_node_role_detail', + 'audit_update_node_role_detail_end': 'audit_update_node_role_detail_end', + 'audit_update_node_role_detail_start': 'audit_update_node_role_detail_start', 'audit_update_node_share_setting': 'audit_update_node_share_setting', - 'audit_update_node_share_setting_detail': 'audit_update_node_share_setting_detail', + 'audit_update_node_share_setting_detail_end': 'audit_update_node_share_setting_detail_end', + 'audit_update_node_share_setting_detail_start': 'audit_update_node_share_setting_detail_start', 'audit_user_login': 'audit_user_login', 'audit_user_login_detail': 'audit_user_login_detail', 'audit_user_logout': 'audit_user_logout', @@ -807,6 +829,7 @@ export type StringKeysMapType = { 'automation_enabled_return_via_related_files': 'automation_enabled_return_via_related_files', 'automation_field': 'automation_field', 'automation_import_variables_from_pre_tep': 'automation_import_variables_from_pre_tep', + 'automation_is_not_yet_enabled': 'automation_is_not_yet_enabled', 'automation_last_edited_by': 'automation_last_edited_by', 'automation_last_edited_time': 'automation_last_edited_time', 'automation_manager_label': 'automation_manager_label', @@ -928,10 +951,19 @@ export type StringKeysMapType = { 'button_text': 'button_text', 'button_text_click_start': 'button_text_click_start', 'button_type': 'button_type', + 'by_at': 'by_at', + 'by_days': 'by_days', + 'by_every': 'by_every', 'by_field_id': 'by_field_id', + 'by_hours': 'by_hours', + 'by_in': 'by_in', + 'by_min': 'by_min', + 'by_months': 'by_months', + 'by_on': 'by_on', 'by_the_day': 'by_the_day', 'by_the_month': 'by_the_month', 'by_the_year': 'by_the_year', + 'by_weeks': 'by_weeks', 'calendar_add_date_time_field': 'calendar_add_date_time_field', 'calendar_color_more': 'calendar_color_more', 'calendar_const_detail_weeks': 'calendar_const_detail_weeks', @@ -995,6 +1027,14 @@ export type StringKeysMapType = { 'cannot_activate_space_by_space_limit': 'cannot_activate_space_by_space_limit', 'cannot_join_space': 'cannot_join_space', 'cannot_switch_field_permission': 'cannot_switch_field_permission', + 'capacity_file_detail_desc': 'capacity_file_detail_desc', + 'capacity_file_detail_title': 'capacity_file_detail_title', + 'capacity_file_member': 'capacity_file_member', + 'capacity_file_member_private_node_count': 'capacity_file_member_private_node_count', + 'capacity_file_member_private_percent': 'capacity_file_member_private_percent', + 'capacity_file_member_team': 'capacity_file_member_team', + 'capacity_file_member_team_node_count': 'capacity_file_member_team_node_count', + 'capacity_file_upgrade': 'capacity_file_upgrade', 'capacity_from_official_gift': 'capacity_from_official_gift', 'capacity_from_participation': 'capacity_from_participation', 'capacity_from_purchase': 'capacity_from_purchase', @@ -1031,6 +1071,8 @@ export type StringKeysMapType = { 'catalog': 'catalog', 'catalog_add_from_template_btn_title': 'catalog_add_from_template_btn_title', 'catalog_empty_tips': 'catalog_empty_tips', + 'catalog_private': 'catalog_private', + 'catalog_team': 'catalog_team', 'category_blank': 'category_blank', 'catering': 'catering', 'cayman_islands': 'cayman_islands', @@ -1099,6 +1141,7 @@ export type StringKeysMapType = { 'choose_type_of_vika_field': 'choose_type_of_vika_field', 'choose_your_own_space': 'choose_your_own_space', 'chose_new_primary_admin_button': 'chose_new_primary_admin_button', + 'chunk_stopping_title': 'chunk_stopping_title', 'claim_special_offer': 'claim_special_offer', 'clear': 'clear', 'clear_all_fields': 'clear_all_fields', @@ -1229,6 +1272,7 @@ export type StringKeysMapType = { 'confirm_del_current_team': 'confirm_del_current_team', 'confirm_delete': 'confirm_delete', 'confirm_delete_node_name_as': 'confirm_delete_node_name_as', + 'confirm_delete_private_node_name_as': 'confirm_delete_private_node_name_as', 'confirm_delete_space_btn': 'confirm_delete_space_btn', 'confirm_exit': 'confirm_exit', 'confirm_exit_space_with_name': 'confirm_exit_space_with_name', @@ -1266,6 +1310,14 @@ export type StringKeysMapType = { 'convert': 'convert', 'convert_tip': 'convert_tip', 'cook_islands': 'cook_islands', + 'copilot_auto_agent_desc': 'copilot_auto_agent_desc', + 'copilot_auto_agent_name': 'copilot_auto_agent_name', + 'copilot_data_agent_desc': 'copilot_data_agent_desc', + 'copilot_data_agent_name': 'copilot_data_agent_name', + 'copilot_data_agent_policy': 'copilot_data_agent_policy', + 'copilot_data_agent_policy_button': 'copilot_data_agent_policy_button', + 'copilot_help_agent_desc': 'copilot_help_agent_desc', + 'copilot_help_agent_name': 'copilot_help_agent_name', 'copy': 'copy', 'copy_automation_url': 'copy_automation_url', 'copy_card_link': 'copy_card_link', @@ -1310,6 +1362,7 @@ export type StringKeysMapType = { 'create_mirror_guide_content': 'create_mirror_guide_content', 'create_mirror_guide_title': 'create_mirror_guide_title', 'create_new_button_field': 'create_new_button_field', + 'create_private_node_tip': 'create_private_node_tip', 'create_public_invitation_link': 'create_public_invitation_link', 'create_space_sub_title': 'create_space_sub_title', 'create_team_fail': 'create_team_fail', @@ -1373,10 +1426,12 @@ export type StringKeysMapType = { 'custom_enterprise': 'custom_enterprise', 'custom_function_development': 'custom_function_development', 'custom_grade_desc': 'custom_grade_desc', + 'custom_page_setting_title': 'custom_page_setting_title', 'custom_picture': 'custom_picture', 'custom_style': 'custom_style', 'custom_upload': 'custom_upload', 'custom_upload_tip': 'custom_upload_tip', + 'custome_page_title': 'custome_page_title', 'cut_cell_data': 'cut_cell_data', 'cyprus': 'cyprus', 'czech': 'czech', @@ -1428,6 +1483,7 @@ export type StringKeysMapType = { 'default': 'default', 'default_create_ai_chat_bot': 'default_create_ai_chat_bot', 'default_create_automation': 'default_create_automation', + 'default_create_custom_page': 'default_create_custom_page', 'default_create_dashboard': 'default_create_dashboard', 'default_create_datasheet': 'default_create_datasheet', 'default_create_file': 'default_create_file', @@ -1449,6 +1505,7 @@ export type StringKeysMapType = { 'del_invitation_link': 'del_invitation_link', 'del_invitation_link_desc': 'del_invitation_link_desc', 'del_space_now': 'del_space_now', + 'del_space_now_confirm_tip': 'del_space_now_confirm_tip', 'del_space_now_tip': 'del_space_now_tip', 'del_space_res_tip': 'del_space_res_tip', 'del_team_success': 'del_team_success', @@ -1644,6 +1701,61 @@ export type StringKeysMapType = { 'embed_error_page_help': 'embed_error_page_help', 'embed_fail_og_description_content': 'embed_fail_og_description_content', 'embed_failed': 'embed_failed', + 'embed_link_bilibili': 'embed_link_bilibili', + 'embed_link_bilibili_desc': 'embed_link_bilibili_desc', + 'embed_link_bilibili_link_text': 'embed_link_bilibili_link_text', + 'embed_link_bilibili_link_url': 'embed_link_bilibili_link_url', + 'embed_link_default': 'embed_link_default', + 'embed_link_default_desc': 'embed_link_default_desc', + 'embed_link_default_link_text': 'embed_link_default_link_text', + 'embed_link_default_link_url': 'embed_link_default_link_url', + 'embed_link_figma': 'embed_link_figma', + 'embed_link_figma_desc': 'embed_link_figma_desc', + 'embed_link_figma_link_text': 'embed_link_figma_link_text', + 'embed_link_figma_link_url': 'embed_link_figma_link_url', + 'embed_link_google_docs': 'embed_link_google_docs', + 'embed_link_google_docs_desc': 'embed_link_google_docs_desc', + 'embed_link_google_docs_link_text': 'embed_link_google_docs_link_text', + 'embed_link_google_docs_link_url': 'embed_link_google_docs_link_url', + 'embed_link_google_sheets': 'embed_link_google_sheets', + 'embed_link_google_sheets_desc': 'embed_link_google_sheets_desc', + 'embed_link_google_sheets_link_text': 'embed_link_google_sheets_link_text', + 'embed_link_google_sheets_link_url': 'embed_link_google_sheets_link_url', + 'embed_link_jishi_design': 'embed_link_jishi_design', + 'embed_link_jishi_design_desc': 'embed_link_jishi_design_desc', + 'embed_link_jishi_design_link_text': 'embed_link_jishi_design_link_text', + 'embed_link_jishi_design_link_url': 'embed_link_jishi_design_link_url', + 'embed_link_tencent_docs': 'embed_link_tencent_docs', + 'embed_link_tencent_docs_desc': 'embed_link_tencent_docs_desc', + 'embed_link_tencent_docs_link_text': 'embed_link_tencent_docs_link_text', + 'embed_link_tencent_docs_link_url': 'embed_link_tencent_docs_link_url', + 'embed_link_wps': 'embed_link_wps', + 'embed_link_wps_desc': 'embed_link_wps_desc', + 'embed_link_wps_link_text': 'embed_link_wps_link_text', + 'embed_link_wps_link_url': 'embed_link_wps_link_url', + 'embed_link_youtube': 'embed_link_youtube', + 'embed_link_youtube_desc': 'embed_link_youtube_desc', + 'embed_link_youtube_link_text': 'embed_link_youtube_link_text', + 'embed_link_youtube_link_url': 'embed_link_youtube_link_url', + 'embed_page': 'embed_page', + 'embed_page_add_url': 'embed_page_add_url', + 'embed_page_doc_url': 'embed_page_doc_url', + 'embed_page_function_desc': 'embed_page_function_desc', + 'embed_page_node_permission_editor': 'embed_page_node_permission_editor', + 'embed_page_node_permission_manager': 'embed_page_node_permission_manager', + 'embed_page_node_permission_reader': 'embed_page_node_permission_reader', + 'embed_page_node_permission_updater': 'embed_page_node_permission_updater', + 'embed_page_url_invalid': 'embed_page_url_invalid', + 'embed_paste_link_bilibili_placeholder': 'embed_paste_link_bilibili_placeholder', + 'embed_paste_link_default_placeholder': 'embed_paste_link_default_placeholder', + 'embed_paste_link_figma_placeholder': 'embed_paste_link_figma_placeholder', + 'embed_paste_link_google_docs_placeholder': 'embed_paste_link_google_docs_placeholder', + 'embed_paste_link_google_sheets_placeholder': 'embed_paste_link_google_sheets_placeholder', + 'embed_paste_link_jsdesign_placeholder': 'embed_paste_link_jsdesign_placeholder', + 'embed_paste_link_tencent_docs_placeholder': 'embed_paste_link_tencent_docs_placeholder', + 'embed_paste_link_wps_placeholder': 'embed_paste_link_wps_placeholder', + 'embed_paste_link_youtube_placeholder': 'embed_paste_link_youtube_placeholder', + 'embed_success': 'embed_success', 'emoji_activity': 'emoji_activity', 'emoji_custom': 'emoji_custom', 'emoji_flags': 'emoji_flags', @@ -1750,6 +1862,11 @@ export type StringKeysMapType = { 'estonia': 'estonia', 'ethiopia': 'ethiopia', 'event_planning': 'event_planning', + 'every': 'every', + 'every_day_at': 'every_day_at', + 'every_hour_at': 'every_hour_at', + 'every_month_at': 'every_month_at', + 'every_week_at': 'every_week_at', 'everyday_life': 'everyday_life', 'everyone_visible': 'everyone_visible', 'exact_date': 'exact_date', @@ -1760,6 +1877,7 @@ export type StringKeysMapType = { 'exchange': 'exchange', 'exchange_code_times_tip': 'exchange_code_times_tip', 'exclusive_consultant': 'exclusive_consultant', + 'exclusive_limit_plan_desc': 'exclusive_limit_plan_desc', 'exist_experience': 'exist_experience', 'exits_space': 'exits_space', 'expand': 'expand', @@ -2458,6 +2576,7 @@ export type StringKeysMapType = { 'gold_grade': 'gold_grade', 'gold_grade_desc': 'gold_grade_desc', 'gold_seat_200_desc': 'gold_seat_200_desc', + 'gold_seat_300_desc': 'gold_seat_300_desc', 'golden_grade': 'golden_grade', 'got_it': 'got_it', 'got_v_coins': 'got_v_coins', @@ -2491,6 +2610,8 @@ export type StringKeysMapType = { 'guests_per_space': 'guests_per_space', 'guide_1': 'guide_1', 'guide_2': 'guide_2', + 'guide_flow_modal_contact_sales': 'guide_flow_modal_contact_sales', + 'guide_flow_modal_get_started': 'guide_flow_modal_get_started', 'guide_flow_of_catalog_step1': 'guide_flow_of_catalog_step1', 'guide_flow_of_catalog_step2': 'guide_flow_of_catalog_step2', 'guide_flow_of_click_add_view_step1': 'guide_flow_of_click_add_view_step1', @@ -2669,6 +2790,7 @@ export type StringKeysMapType = { 'intro_widget_tips': 'intro_widget_tips', 'introduction': 'introduction', 'invalid_action_sort_tip': 'invalid_action_sort_tip', + 'invalid_automation_configuration': 'invalid_automation_configuration', 'invalid_field_type': 'invalid_field_type', 'invalid_option_sort_tip': 'invalid_option_sort_tip', 'invalid_redemption_code_entered': 'invalid_redemption_code_entered', @@ -2799,6 +2921,9 @@ export type StringKeysMapType = { 'label_format_day_month_and_year_split_by_slash': 'label_format_day_month_and_year_split_by_slash', 'label_format_month': 'label_format_month', 'label_format_month_and_day_split_by_dash': 'label_format_month_and_day_split_by_dash', + 'label_format_month_day_year_split_by_dash': 'label_format_month_day_year_split_by_dash', + 'label_format_month_day_year_split_by_slash': 'label_format_month_day_year_split_by_slash', + 'label_format_month_day_year_two_digit_year_split_by_slash': 'label_format_month_day_year_two_digit_year_split_by_slash', 'label_format_year': 'label_format_year', 'label_format_year_and_month_split_by_dash': 'label_format_year_and_month_split_by_dash', 'label_format_year_month_and_day_split_by_dash': 'label_format_year_month_and_day_split_by_dash', @@ -2877,6 +3002,7 @@ export type StringKeysMapType = { 'lark_version_enterprise': 'lark_version_enterprise', 'lark_version_standard': 'lark_version_standard', 'lark_versions_free': 'lark_versions_free', + 'last_day': 'last_day', 'last_modified_by_select_modal_desc': 'last_modified_by_select_modal_desc', 'last_modified_time_select_modal_desc': 'last_modified_time_select_modal_desc', 'last_step': 'last_step', @@ -3241,8 +3367,12 @@ export type StringKeysMapType = { 'more_widget': 'more_widget', 'morocco': 'morocco', 'move': 'move', + 'move_datasheet_link_warn': 'move_datasheet_link_warn', 'move_favorite_node_fail': 'move_favorite_node_fail', + 'move_folder_link_warn': 'move_folder_link_warn', 'move_node_modal_content': 'move_node_modal_content', + 'move_other_link_no_permission': 'move_other_link_no_permission', + 'move_other_link_warn': 'move_other_link_warn', 'move_to': 'move_to', 'move_to_error_equal_parent': 'move_to_error_equal_parent', 'move_to_modal_title': 'move_to_modal_title', @@ -3273,6 +3403,7 @@ export type StringKeysMapType = { 'new_a_line': 'new_a_line', 'new_automation': 'new_automation', 'new_caledonia': 'new_caledonia', + 'new_custom_page': 'new_custom_page', 'new_datasheet': 'new_datasheet', 'new_folder': 'new_folder', 'new_folder_btn_title': 'new_folder_btn_title', @@ -3479,6 +3610,7 @@ export type StringKeysMapType = { 'open_auto_save_success': 'open_auto_save_success', 'open_auto_save_warn_content': 'open_auto_save_warn_content', 'open_auto_save_warn_title': 'open_auto_save_warn_title', + 'open_automation_time_arrival': 'open_automation_time_arrival', 'open_failed': 'open_failed', 'open_in_new_tab': 'open_in_new_tab', 'open_invite_after_operate': 'open_invite_after_operate', @@ -3625,6 +3757,8 @@ export type StringKeysMapType = { 'payment_record': 'payment_record', 'payment_reminder': 'payment_reminder', 'payment_reminder_content': 'payment_reminder_content', + 'payment_reminder_modal_content': 'payment_reminder_modal_content', + 'payment_reminder_modal_title': 'payment_reminder_modal_title', 'pending_invite': 'pending_invite', 'people': 'people', 'per_person_per_year': 'per_person_per_year', @@ -3927,6 +4061,7 @@ export type StringKeysMapType = { 'preview_guide_click_to_restart': 'preview_guide_click_to_restart', 'preview_guide_enable_it': 'preview_guide_enable_it', 'preview_guide_open_office_preview': 'preview_guide_open_office_preview', + 'preview_next_automation_execution_time': 'preview_next_automation_execution_time', 'preview_not_support_video_codecs': 'preview_not_support_video_codecs', 'preview_revision': 'preview_revision', 'preview_see_more': 'preview_see_more', @@ -3962,6 +4097,7 @@ export type StringKeysMapType = { 'privacy_protection': 'privacy_protection', 'private_cloud': 'private_cloud', 'private_external_person_only': 'private_external_person_only', + 'private_help_link': 'private_help_link', 'private_internal_person_only': 'private_internal_person_only', 'private_product_point': 'private_product_point', 'privatized_deployment': 'privatized_deployment', @@ -4032,6 +4168,8 @@ export type StringKeysMapType = { 'reconciled_data': 'reconciled_data', 'record': 'record', 'record_activity_experience_tips': 'record_activity_experience_tips', + 'record_archived_data': 'record_archived_data', + 'record_chunk_text': 'record_chunk_text', 'record_comment': 'record_comment', 'record_comments': 'record_comments', 'record_fail_data': 'record_fail_data', @@ -4478,6 +4616,12 @@ export type StringKeysMapType = { 'scan_to_login': 'scan_to_login', 'scan_to_login_by_method': 'scan_to_login_by_method', 'scatter_chart': 'scatter_chart', + 'schedule_day_tips': 'schedule_day_tips', + 'schedule_hour_tips': 'schedule_hour_tips', + 'schedule_start_day': 'schedule_start_day', + 'schedule_start_month': 'schedule_start_month', + 'schedule_type': 'schedule_type', + 'schedule_year_tips': 'schedule_year_tips', 'science_and_technology': 'science_and_technology', 'scroll_screen_down': 'scroll_screen_down', 'scroll_screen_left': 'scroll_screen_left', @@ -4491,6 +4635,7 @@ export type StringKeysMapType = { 'search_folder_or_sheet': 'search_folder_or_sheet', 'search_new_admin': 'search_new_admin', 'search_node_pleaseholder': 'search_node_pleaseholder', + 'search_node_tip': 'search_node_tip', 'search_or_add': 'search_or_add', 'search_role_placeholder': 'search_role_placeholder', 'seats': 'seats', @@ -4894,6 +5039,7 @@ export type StringKeysMapType = { 'space_info': 'space_info', 'space_info_del_confirm1': 'space_info_del_confirm1', 'space_info_del_confirm2': 'space_info_del_confirm2', + 'space_info_del_confirm3': 'space_info_del_confirm3', 'space_info_feishu_desc': 'space_info_feishu_desc', 'space_info_feishu_label': 'space_info_feishu_label', 'space_join_apply': 'space_join_apply', @@ -4980,6 +5126,7 @@ export type StringKeysMapType = { 'start_onfiguration': 'start_onfiguration', 'start_time': 'start_time', 'start_use': 'start_use', + 'starting_from_midnight': 'starting_from_midnight', 'startup': 'startup', 'startup_company_support_program': 'startup_company_support_program', 'stat_average': 'stat_average', @@ -5013,6 +5160,8 @@ export type StringKeysMapType = { 'stay_tuned_for_more_features': 'stay_tuned_for_more_features', 'steps_choose_reset_mode': 'steps_choose_reset_mode', 'steps_validate_identities': 'steps_validate_identities', + 'stop_chunk_content': 'stop_chunk_content', + 'stop_chunk_title': 'stop_chunk_title', 'stop_dingtalk_h5_modal_content': 'stop_dingtalk_h5_modal_content', 'storage_per_seats': 'storage_per_seats', 'storage_per_space': 'storage_per_space', @@ -5043,9 +5192,11 @@ export type StringKeysMapType = { 'subscribe_credit_usage_over_limit': 'subscribe_credit_usage_over_limit', 'subscribe_demonstrate': 'subscribe_demonstrate', 'subscribe_disabled_seat': 'subscribe_disabled_seat', + 'subscribe_grade_business': 'subscribe_grade_business', 'subscribe_grade_free': 'subscribe_grade_free', 'subscribe_grade_plus': 'subscribe_grade_plus', 'subscribe_grade_pro': 'subscribe_grade_pro', + 'subscribe_grade_starter': 'subscribe_grade_starter', 'subscribe_label_tooltip': 'subscribe_label_tooltip', 'subscribe_new_choose_member': 'subscribe_new_choose_member', 'subscribe_new_choose_member_tips': 'subscribe_new_choose_member_tips', @@ -5226,6 +5377,7 @@ export type StringKeysMapType = { 'text_editor_tip_end': 'text_editor_tip_end', 'text_functions': 'text_functions', 'thailand': 'thailand', + 'the_button_field_is_misconfigured': 'the_button_field_is_misconfigured', 'the_current_automation_workflow_has_no_related_files_you_can_establish_a_link_by_adding_trigger_conditions_and_actions_on_the_left_side': 'the_current_automation_workflow_has_no_related_files_you_can_establish_a_link_by_adding_trigger_conditions_and_actions_on_the_left_side', 'the_current_button_column_has_expired_please_reselect': 'the_current_button_column_has_expired_please_reselect', 'the_last_7_days': 'the_last_7_days', @@ -5328,6 +5480,7 @@ export type StringKeysMapType = { 'timemachine_update_comment': 'timemachine_update_comment', 'times_per_month_unit': 'times_per_month_unit', 'times_unit': 'times_unit', + 'timing_rules': 'timing_rules', 'timor_leste': 'timor_leste', 'tip_del_success': 'tip_del_success', 'tip_do_you_want_to_know_about_field_permission': 'tip_do_you_want_to_know_about_field_permission', @@ -5515,6 +5668,7 @@ export type StringKeysMapType = { 'verify_account_title': 'verify_account_title', 'verify_via_email': 'verify_via_email', 'verify_via_phone': 'verify_via_phone', + 'video': 'video', 'video_not_support_play': 'video_not_support_play', 'vietnam': 'vietnam', 'view': 'view', @@ -5863,7 +6017,7 @@ export type StringKeysMapType = { 'workdoc_color_title': 'workdoc_color_title', 'workdoc_create': 'workdoc_create', 'workdoc_expanded': 'workdoc_expanded', - 'workdoc_image_max_10mb': 'workdoc_image_max_10mb', + 'workdoc_image_max_size': 'workdoc_image_max_size', 'workdoc_info': 'workdoc_info', 'workdoc_info_create_time': 'workdoc_info_create_time', 'workdoc_info_creator': 'workdoc_info_creator', @@ -5871,6 +6025,7 @@ export type StringKeysMapType = { 'workdoc_info_last_modify_time': 'workdoc_info_last_modify_time', 'workdoc_link_placeholder': 'workdoc_link_placeholder', 'workdoc_only_image': 'workdoc_only_image', + 'workdoc_only_video': 'workdoc_only_video', 'workdoc_text_placeholder': 'workdoc_text_placeholder', 'workdoc_title_placeholder': 'workdoc_title_placeholder', 'workdoc_unnamed': 'workdoc_unnamed', @@ -5879,9 +6034,11 @@ export type StringKeysMapType = { 'workdoc_unsave_ok': 'workdoc_unsave_ok', 'workdoc_unsave_title': 'workdoc_unsave_title', 'workdoc_upload_failed': 'workdoc_upload_failed', + 'workdoc_video_max_size': 'workdoc_video_max_size', 'workdoc_ws_connected': 'workdoc_ws_connected', 'workdoc_ws_connecting': 'workdoc_ws_connecting', 'workdoc_ws_disconnected': 'workdoc_ws_disconnected', + 'workdoc_ws_reconnecting': 'workdoc_ws_reconnecting', 'workflow_execute_failed_notify': 'workflow_execute_failed_notify', 'workspace_data': 'workspace_data', 'workspace_files': 'workspace_files', diff --git a/packages/core/src/config/system_config.interface.ts b/packages/core/src/config/system_config.interface.ts index 277b52c3c1..255f6121b2 100644 --- a/packages/core/src/config/system_config.interface.ts +++ b/packages/core/src/config/system_config.interface.ts @@ -1,117 +1,118 @@ export interface SystemConfigInterface { + environment: Environment; + settings: Settings; + shortcut_keys: ShortcutKey[]; + country_code_and_phone_code: { [key: string]: CountryCodeAndPhoneCode }; api_panel: { [key: string]: APIPanel }; audit: Audit; - country_code_and_phone_code: { [key: string]: CountryCodeAndPhoneCode }; - environment: Environment; - guide: SystemConfigInterfaceGuide; - integral: Integral; locales: Locale[]; marketplace: SystemConfigInterfaceMarketplace; - notifications: Notifications; - player: SystemConfigInterfacePlayer; - settings: Settings; - shortcut_keys: ShortcutKey[]; test_function: TestFunction; + player: SystemConfigInterfacePlayer; + guide: SystemConfigInterfaceGuide; + notifications: Notifications; + integral: Integral; } export interface APIPanel { - defaultExample: string; defaultExampleId: string; description: string; descriptionId: string; + defaultExample: string; valueType: string; } export interface Audit { - actual_delete_space: ActualDeleteSpace; - add_field_role: ActualDeleteSpace; - add_node_role: AddNodeRole; - add_sub_admin: AddTeamToMemberClass; - add_team_to_member: AddTeamToMemberClass; - agree_user_apply: AddTeamToMemberClass; - cancel_delete_space: ActualDeleteSpace; - change_main_admin: AddTeamToMemberClass; - copy_node: AddNodeRole; - create_node: AddNodeRole; - create_space: ActualDeleteSpace; - create_team: AddTeamToMemberClass; - create_template: ActualDeleteSpace; - delete_field_role: ActualDeleteSpace; - delete_node: AddNodeRole; - delete_node_role: AddNodeRole; - delete_rubbish_node: ActualDeleteSpace; - delete_space: ActualDeleteSpace; - delete_sub_admin: AddTeamToMemberClass; - delete_team: AddTeamToMemberClass; - delete_template: ActualDeleteSpace; - disable_field_role: ActualDeleteSpace; - disable_node_role: AddNodeRole; - disable_node_share: AddNodeRole; - enable_field_role: ActualDeleteSpace; - enable_node_role: AddNodeRole; - enable_node_share: AddNodeRole; - export_node: ActualDeleteSpace; - import_node: AddNodeRole; - invite_user_join_by_email: ActualDeleteSpace; - move_node: AddNodeRole; - quote_template: ActualDeleteSpace; - recover_rubbish_node: AddNodeRole; - remove_member_from_team: AddTeamToMemberClass; - remove_user: AddTeamToMemberClass; - rename_node: AddNodeRole; - rename_space: ActualDeleteSpace; - sort_node: ActualDeleteSpace; - store_share_node: AddNodeRole; - update_field_role: ActualDeleteSpace; - update_field_role_setting: AddTeamToMemberClass; - update_member_property: AddTeamToMemberClass; - update_member_team: AddTeamToMemberClass; - update_node_cover: ActualDeleteSpace; - update_node_desc: ActualDeleteSpace; - update_node_icon: ActualDeleteSpace; - update_node_role: AddNodeRole; - update_node_share_setting: AddNodeRole; - update_space_logo: ActualDeleteSpace; - update_sub_admin_role: AddTeamToMemberClass; - update_team_property: AddTeamToMemberClass; - user_leave_space: ActualDeleteSpace; - user_login: ActualDeleteSpace; - user_logout: ActualDeleteSpace; + actual_delete_space: ActualDeleteSpace; + add_field_role: ActualDeleteSpace; + add_node_role: AddNodeRole; + add_sub_admin: AddSubAdmin; + add_team_to_member: AddSubAdmin; + agree_user_apply: AddSubAdmin; + cancel_delete_space: ActualDeleteSpace; + change_main_admin: AddSubAdmin; + copy_node: AddNodeRole; + create_node: AddNodeRole; + create_space: ActualDeleteSpace; + create_team: AddSubAdmin; + create_template: ActualDeleteSpace; + delete_field_role: ActualDeleteSpace; + delete_node: AddNodeRole; + delete_node_role: AddNodeRole; + delete_rubbish_node: ActualDeleteSpace; + delete_space: ActualDeleteSpace; + delete_sub_admin: AddSubAdmin; + delete_team: AddSubAdmin; + delete_template: ActualDeleteSpace; + disable_field_role: ActualDeleteSpace; + disable_node_role: AddNodeRole; + disable_node_share: AddNodeRole; + enable_field_role: ActualDeleteSpace; + enable_node_role: AddNodeRole; + enable_node_share: AddNodeRole; + export_node: ActualDeleteSpace; + import_node: AddNodeRole; + invite_user_join_by_email: ActualDeleteSpace; + move_node: AddNodeRole; + quote_template: ActualDeleteSpace; + recover_rubbish_node: AddNodeRole; + remove_member_from_team: AddSubAdmin; + remove_user: AddSubAdmin; + rename_node: AddNodeRole; + rename_space: ActualDeleteSpace; + sort_node: ActualDeleteSpace; + store_share_node: StoreShareNode; + update_field_role: ActualDeleteSpace; + update_field_role_setting: AddSubAdmin; + update_member_name_property: ActualDeleteSpace; + update_member_property: ActualDeleteSpace; + update_member_team: AddSubAdmin; + update_node_cover: ActualDeleteSpace; + update_node_desc: ActualDeleteSpace; + update_node_icon: ActualDeleteSpace; + update_node_role: AddNodeRole; + update_node_share_setting: AddNodeRole; + update_space_logo: ActualDeleteSpace; + update_sub_admin_role: AddSubAdmin; + update_team_property: AddSubAdmin; + user_leave_space: ActualDeleteSpace; + user_login: ActualDeleteSpace; + user_logout: ActualDeleteSpace; } export interface ActualDeleteSpace { + content?: string; + online?: boolean; + type: NotificationsTypeElement; category: string; - content: string; name: string; - online?: boolean; - type: NotificationsTypeEnum; } -export enum NotificationsTypeEnum { +export enum NotificationsTypeElement { Member = "member", Space = "space", System = "system", } export interface AddNodeRole { - category: AddNodeRoleCategory; content: string; - name: string; online: boolean; - show_in_audit_log: boolean; + type: NotificationsTypeElement; sort: string; - type: NotificationsTypeEnum; + show_in_audit_log: boolean; + category: CategoryElement; + name: string; } -export enum AddNodeRoleCategory { +export enum CategoryElement { WorkCatalogChangeEvent = "work_catalog_change_event", WorkCatalogPermissionChangeEvent = "work_catalog_permission_change_event", WorkCatalogShareEvent = "work_catalog_share_event", } -export interface AddTeamToMemberClass { +export interface AddSubAdmin { + type: NotificationsTypeElement; category: AddSubAdminCategory; - type: NotificationsTypeEnum; } export enum AddSubAdminCategory { @@ -120,6 +121,16 @@ export enum AddSubAdminCategory { OrganizationChangeEvent = "organization_change_event", } +export interface StoreShareNode { + content: string; + online: boolean; + type: NotificationsTypeElement[]; + sort: string; + show_in_audit_log: boolean; + category: CategoryElement[]; + name: string; +} + export interface CountryCodeAndPhoneCode { phoneCode: string; } @@ -135,28 +146,27 @@ export interface Integration { } export interface SystemConfigInterfaceGuide { - step: { [key: string]: Step }; wizard: { [key: string]: Wizard }; + step: { [key: string]: Step }; } export interface Step { - backdrop?: Backdrop; - next?: Next; - nextId?: NextID; - onClose?: string[]; - onNext?: On[]; - onPlay?: string[]; - onPrev?: On[]; - onSkip?: On[]; - onTarget?: On[]; - prev?: string; - uiConfig: string; - uiConfigId: string; - uiType: string; - skipId?: string; - byEvent?: string[]; - skip?: string; - description?: string; + uiConfigId: string; + uiType: string; + prev?: string; + backdrop?: Backdrop; + onPlay?: string[]; + onNext?: On[]; + next?: Next; + onPrev?: On[]; + nextId?: NextID; + onSkip?: On[]; + uiConfig: string; + onClose?: string[]; + onTarget?: On[]; + skipId?: string; + byEvent?: string[]; + skip?: string; } export enum Backdrop { @@ -203,13 +213,12 @@ export interface Wizard { completeIndex?: number; player?: WizardPlayer; steps?: string; + manualActions?: string[]; repeat?: boolean; endTime?: number; startTime?: number; freeVCount?: number; integral_action?: string; - manualActions?: string[]; - description?: string; } export interface WizardPlayer { @@ -237,20 +246,20 @@ export interface IntegralRule { export interface BeInvitedToReward { action_code: string; - action_name: string; day_max_integral_value: number; - display_name: string[]; + display_name: any[]; + online?: boolean; integral_value: number; notify?: boolean; - online?: boolean; + action_name: string; } export interface FissionReward { action_code: string; - action_name: string; - display_name: string[]; - notify?: boolean; + display_name: any[]; online: boolean; + notify?: boolean; + action_name: string; } export interface Locale { @@ -264,49 +273,49 @@ export interface Locale { export interface SystemConfigInterfaceMarketplace { cli_9f3930dd7d7ad00c: CLI; - cli_9f614b454434500e: CLI; cli_a08120b120fad00e: CLI; + cli_9f614b454434500e: CLI; ina5200279359980055: Ina; - ina5645957505507647: Ina; ina9134969049653777: Ina; + ina5645957505507647: Ina; } export interface CLI { - app_description: string; - app_id: string; + logo: Image; + env: string[]; + disable: boolean; app_info: string; + note: string; app_name: string; - app_type: string; - btn_card: BtnCard; - disable: boolean; - display_order: number; - env: string[]; + type: string; + app_description: string; id: string; + display_order: number; image: Image; + app_id: string; link_to_cms: string; - logo: Image; + app_type: string; + btn_card: BtnCard; modal: CLI9F3930Dd7D7Ad00CModal; - note: string; - type: string; } export interface BtnCard { - apps_btn_text: string; - btn_action?: string; - btn_close_action?: string; btn_text: string; + btn_action?: string; btn_type: string; + btn_close_action?: string; + apps_btn_text: string; } export interface Image { - height: number; id: string; - mimeType: MIMEType; name: string; size: number; + mimeType: MIMEType; token: string; - url: string; width: number; + height: number; + url: string; } export enum MIMEType { @@ -315,34 +324,34 @@ export enum MIMEType { } export interface CLI9F3930Dd7D7Ad00CModal { - app_description: string; - btn_action?: string; btn_text: string; + btn_action?: string; + app_description: string; btn_type: string; help_link: string; } export interface Ina { - app_description: string; - app_id: string; + logo: Image; + env: string[]; app_info: string; + note: string; app_name: string; - app_type: string; - btn_card: BtnCard; - display_order: number; - env: string[]; + type: string; + app_description: string; id: string; + display_order: number; image: Image; + app_id: string; link_to_cms: string; - logo: Image; + app_type: string; + btn_card: BtnCard; modal: CLI9F3930Dd7D7Ad00CModal; - note: string; - type: string; } export interface Notifications { - templates: Templates; types: Types; + templates: Templates; } export interface Templates { @@ -350,87 +359,98 @@ export interface Templates { activity_integral_income_toadmin: ActivityIntegralIncomeNotify; add_record_out_of_limit: AddRecordOutOfLimit; add_record_soon_to_be_limit: AddRecordOutOfLimit; - add_sub_admin: AssignedToGroupClass; - admin_transfer_space_widget_notify: AdminTransferSpaceWidgetNotify; - admin_unpublish_space_widget_notify: AdminTransferSpaceWidgetNotify; + add_sub_admin: AddRecordOutOfLimit; + admin_transfer_space_widget_notify: Notify; + admin_unpublish_space_widget_notify: Notify; apply_space_beta_feature_success_notify_all: ActivityIntegralIncomeNotify; apply_space_beta_feature_success_notify_me: ActivityIntegralIncomeNotify; - assigned_to_group: AssignedToGroupClass; - assigned_to_role: AssignedToGroupClass; - auto_cancel_record_subscription: AutoCancelRecordSubscription; - auto_create_record_subscription: AutoCancelRecordSubscription; + assigned_to_group: AddRecordOutOfLimit; + assigned_to_role: AddRecordOutOfLimit; + auto_cancel_record_subscription: AutoCRecordSubscription; + auto_create_record_subscription: AutoCRecordSubscription; + "automation-fail": AutomationFail; capacity_limit: AddRecordOutOfLimit; - changed_ordinary_user: AdminTransferSpaceWidgetNotify; - comment_mentioned: AutoCancelRecordSubscription; - common_system_notify: AdminTransferSpaceWidgetNotify; - common_system_notify_web: ActivityIntegralIncomeNotify; + changed_ordinary_user: AddRecordOutOfLimit; + comment_mentioned: CommentMentioned; + common_system_notify: Notify; + common_system_notify_web: CommonSystemNotifyWeb; datasheet_limit: AddRecordOutOfLimit; datasheet_record_limit: AddRecordOutOfLimit; integral_income_notify: ActivityIntegralIncomeNotify; - invite_member_toadmin: AdminTransferSpaceWidgetNotify; - invite_member_tomyself: AdminTransferSpaceWidgetNotify; - invite_member_touser: AdminTransferSpaceWidgetNotify; - member_applied_to_close_account: AdminTransferSpaceWidgetNotify; - new_space_widget_notify: AdminTransferSpaceWidgetNotify; - new_user_welcome_notify: AdminTransferSpaceWidgetNotify; - quit_space: AdminTransferSpaceWidgetNotify; - remove_from_group: AdminTransferSpaceWidgetNotify; - remove_from_role: AdminTransferSpaceWidgetNotify; - removed_from_space_toadmin: AdminTransferSpaceWidgetNotify; - removed_from_space_touser: AdminTransferSpaceWidgetNotify; - removed_member_tomyself: AdminTransferSpaceWidgetNotify; - server_pre_publish: AdminTransferSpaceWidgetNotify; - single_record_comment_mentioned: AutoCancelRecordSubscription; - single_record_member_mention: AutoCancelRecordSubscription; - space_add_primary_admin: AdminTransferSpaceWidgetNotify; + invite_member_toadmin: AddRecordOutOfLimit; + invite_member_tomyself: AddRecordOutOfLimit; + invite_member_touser: AddRecordOutOfLimit; + member_applied_to_close_account: AddRecordOutOfLimit; + new_space_widget_notify: AddRecordOutOfLimit; + new_user_welcome_notify: AddRecordOutOfLimit; + quit_space: AddRecordOutOfLimit; + remove_from_group: AddRecordOutOfLimit; + remove_from_role: AddRecordOutOfLimit; + removed_from_space_toadmin: AddRecordOutOfLimit; + removed_from_space_touser: AddRecordOutOfLimit; + removed_member_tomyself: AddRecordOutOfLimit; + server_pre_publish: AddRecordOutOfLimit; + single_record_comment_mentioned: CommentMentioned; + single_record_member_mention: CommentMentioned; + space_add_primary_admin: AddRecordOutOfLimit; space_admin_limit: AddRecordOutOfLimit; space_api_limit: AddRecordOutOfLimit; space_calendar_limit: AddRecordOutOfLimit; - space_certification_fail_notify: AdminTransferSpaceWidgetNotify; - space_certification_notify: AdminTransferSpaceWidgetNotify; - space_deleted: AdminTransferSpaceWidgetNotify; - space_dingtalk_notify: AdminTransferSpaceWidgetNotify; - space_field_permission_limit: AdminTransferSpaceWidgetNotify; - space_file_permission_limit: AdminTransferSpaceWidgetNotify; - space_form_limit: AdminTransferSpaceWidgetNotify; - space_gantt_limit: AdminTransferSpaceWidgetNotify; - space_join_apply: AdminTransferSpaceWidgetNotify; - space_join_apply_approved: AdminTransferSpaceWidgetNotify; - space_join_apply_refused: AdminTransferSpaceWidgetNotify; - space_lark_notify: AdminTransferSpaceWidgetNotify; - space_members_limit: AdminTransferSpaceWidgetNotify; - space_mirror_limit: AdminTransferSpaceWidgetNotify; - space_name_change: AdminTransferSpaceWidgetNotify; - space_paid_notify: AdminTransferSpaceWidgetNotify; - space_rainbow_label_limit: AdminTransferSpaceWidgetNotify; - space_record_limit: AdminTransferSpaceWidgetNotify; - space_recover: AdminTransferSpaceWidgetNotify; - space_seats_limit: AdminTransferSpaceWidgetNotify; - space_subscription_end_notify: AdminTransferSpaceWidgetNotify; - space_subscription_notify: AdminTransferSpaceWidgetNotify; - space_time_machine_limit: AdminTransferSpaceWidgetNotify; - space_trash_limit: AdminTransferSpaceWidgetNotify; - space_trial: AdminTransferSpaceWidgetNotify; - space_vika_paid_notify: AdminTransferSpaceWidgetNotify; - space_watermark_notify: AdminTransferSpaceWidgetNotify; - space_wecom_api_trial_end: AdminTransferSpaceWidgetNotify; - space_wecom_notify: AdminTransferSpaceWidgetNotify; - space_yozooffice_notify: AdminTransferSpaceWidgetNotify; - subscribed_record_cell_updated: AutoCancelRecordSubscription; - subscribed_record_commented: AutoCancelRecordSubscription; + space_certification_fail_notify: AddRecordOutOfLimit; + space_certification_notify: AddRecordOutOfLimit; + space_deleted: AddRecordOutOfLimit; + space_dingtalk_notify: AddRecordOutOfLimit; + space_field_permission_limit: AddRecordOutOfLimit; + space_file_permission_limit: AddRecordOutOfLimit; + space_form_limit: AddRecordOutOfLimit; + space_gantt_limit: AddRecordOutOfLimit; + space_join_apply: AddRecordOutOfLimit; + space_join_apply_approved: AddRecordOutOfLimit; + space_join_apply_refused: AddRecordOutOfLimit; + space_lark_notify: AddRecordOutOfLimit; + space_members_limit: AddRecordOutOfLimit; + space_mirror_limit: AddRecordOutOfLimit; + space_name_change: AddRecordOutOfLimit; + space_paid_notify: AddRecordOutOfLimit; + space_rainbow_label_limit: AddRecordOutOfLimit; + space_record_limit: AddRecordOutOfLimit; + space_recover: AddRecordOutOfLimit; + space_seats_limit: AddRecordOutOfLimit; + space_subscription_end_notify: AddRecordOutOfLimit; + space_subscription_notify: AddRecordOutOfLimit; + space_time_machine_limit: AddRecordOutOfLimit; + space_trash_limit: AddRecordOutOfLimit; + space_trial: AddRecordOutOfLimit; + space_watermark_notify: AddRecordOutOfLimit; + space_wecom_api_trial_end: AddRecordOutOfLimit; + space_wecom_notify: AddRecordOutOfLimit; + space_yozooffice_notify: AddRecordOutOfLimit; + subscribed_record_cell_updated: CommentMentioned; + subscribed_record_commented: CommentMentioned; + "subscribed-record-archived": AddRecordOutOfLimit; + "subscribed-record-unarchived": AddRecordOutOfLimit; task_reminder: AddRecordOutOfLimit; - user_field: AutoCancelRecordSubscription; - web_publish: AdminTransferSpaceWidgetNotify; - workflow_execute_failed_notify: AdminTransferSpaceWidgetNotify; + user_field: CommentMentioned; + web_publish: CommonSystemNotifyWeb; + workflow_execute_failed_notify: AddRecordOutOfLimit; } export interface ActivityIntegralIncomeNotify { - format_string: string; - is_component?: boolean; - is_notification?: boolean; - notifications_type: NotificationsTypeEnum; - to_tag: ToTag; - can_jump?: boolean; + to_tag: ToTag; + notifications_type: NotificationsTypeElement; + is_notification: boolean; + format_string: string; + notification_type: NotificationType; + is_component?: boolean; + can_jump?: boolean; + is_mail?: boolean; + mail_template_subject?: string; +} + +export enum NotificationType { + 事务型消息TransactionalNotify = "事务型消息(transactional notify)", + 营销型消息MarketingNotify = "营销型消息(marketing notify)", + 通知型消息NotificationNotify = "通知型消息(notification notify)", } export enum ToTag { @@ -445,19 +465,22 @@ export enum ToTag { } export interface AddRecordOutOfLimit { - can_jump: boolean; - format_string: string; - frequency?: number; - is_component: boolean; - is_mail: boolean; - is_notification: boolean; - mail_template_subject: string; - notifications_type: NotificationsTypeEnum; - to_tag: ToTag; - url: URL; - billing_notify?: string; - is_browser?: boolean; - is_mobile?: boolean; + can_jump?: boolean; + to_tag: ToTag; + notifications_type: NotificationsTypeElement; + is_notification: boolean; + is_mail?: boolean; + mail_template_subject?: string; + format_string?: string; + url?: URL; + frequency?: number; + is_component?: boolean; + is_mobile?: boolean; + is_browser?: boolean; + notification_type?: NotificationType; + billing_notify?: string; + redirect_url?: string; + id?: string; } export enum URL { @@ -465,50 +488,51 @@ export enum URL { Workbench = "/workbench", } -export interface AssignedToGroupClass { - can_jump: boolean; - format_string: string; +export interface Notify { + to_tag: ToTag; + notifications_type: NotificationsTypeElement; + is_notification: boolean; + is_mail?: boolean; is_browser: boolean; + format_string: string; is_component: boolean; - is_mobile: boolean; - is_notification: boolean; - notifications_type: NotificationsTypeEnum; +} + +export interface AutoCRecordSubscription { + can_jump: boolean; to_tag: ToTag; + notifications_type: any[]; + is_notification: boolean; + is_browser: boolean; + format_string: string; url: URL; } -export interface AdminTransferSpaceWidgetNotify { - format_string?: string; - is_browser?: boolean; - is_component?: boolean; - is_mail?: boolean; - is_notification?: boolean; - notifications_type: NotificationsTypeEnum; - to_tag: ToTag; - can_jump?: boolean; - is_mobile?: boolean; - url?: URL; - redirect_url?: string; - billing_notify?: string; - frequency?: number; - mail_template_subject?: string; - id?: string; +export interface AutomationFail { } -export interface AutoCancelRecordSubscription { +export interface CommentMentioned { can_jump: boolean; - format_string: string; - is_browser: boolean; - is_mail: boolean; - is_mobile: boolean; - is_notification: boolean; - notifications_type: any[]; to_tag: ToTag; + notifications_type: any[]; + is_notification: boolean; + is_mobile: boolean; + is_mail: boolean; + is_browser: boolean; + format_string: string; url: URL; is_component?: boolean; mail_template_subject?: string; } +export interface CommonSystemNotifyWeb { + to_tag: ToTag; + notifications_type: NotificationsTypeElement; + format_string: string; + is_component: boolean; + is_mobile?: boolean; +} + export interface Types { member: Member; record: Member; @@ -522,20 +546,19 @@ export interface Member { } export interface SystemConfigInterfacePlayer { - action: Action[]; + trigger: Trigger[]; events: Events; - jobs: Jobs; rule: RuleElement[]; + jobs: Jobs; + action: Action[]; tips: Tips; - trigger: Trigger[]; } export interface Action { + guide?: ActionGuide; id: string; command: string; - guide?: ActionGuide; commandArgs?: string; - description?: string; } export interface ActionGuide { @@ -543,38 +566,38 @@ export interface ActionGuide { } export interface Events { - _: Empty; + _: AutomationFail; address_shown: AddressShown; + ai_create_ai_node: AICreateAINode; app_error_logger: AddressShown; - guide_use_automation_first_time: AddressShown; - guide_use_button_column_first_time: AddressShown; app_modal_confirm: AddressShown; app_set_user_id: AddressShown; app_tracker: AddressShown; datasheet_add_new_view: AddressShown; - datasheet_create_mirror_tip: DatasheetCreateMirrorTip; + datasheet_create_mirror_tip: AICreateAINode; datasheet_dashboard_panel_shown: AddressShown; datasheet_delete_record: AddressShown; datasheet_field_context_hidden: AddressShown; datasheet_field_context_shown: AddressShown; - datasheet_field_setting_hidden: DatasheetCreateMirrorTip; + datasheet_field_setting_hidden: AICreateAINode; datasheet_field_setting_shown: AddressShown; datasheet_gantt_view_shown: AddressShown; - datasheet_grid_view_shown: DatasheetCreateMirrorTip; + datasheet_grid_view_shown: AICreateAINode; datasheet_org_has_link_field: AddressShown; datasheet_org_view_add_first_node: AddressShown; datasheet_org_view_drag_to_unhandled_list: AddressShown; datasheet_org_view_right_panel_shown: AddressShown; - datasheet_search_panel_hidden: DatasheetCreateMirrorTip; - datasheet_search_panel_shown: DatasheetCreateMirrorTip; + datasheet_search_panel_hidden: AICreateAINode; + datasheet_search_panel_shown: AICreateAINode; datasheet_shown: AddressShown; datasheet_user_menu: AddressShown; - datasheet_widget_center_modal_shown: DatasheetCreateMirrorTip; + datasheet_widget_center_modal_shown: AICreateAINode; datasheet_wigdet_empty_panel_shown: AddressShown; get_context_menu_file_more: AddressShown; get_context_menu_folder_more: AddressShown; get_context_menu_root_add: AddressShown; get_nav_list: AddressShown; + guide_use_automation_first_time: AddressShown; invite_entrance_modal_shown: AddressShown; questionnaire_shown: AddressShown; questionnaire_shown_after_sign: AddressShown; @@ -593,7 +616,7 @@ export interface Events { viewset_manual_save_tip: AddressShown; workbench_create_form_bth_clicked: AddressShown; workbench_create_form_panel_shown: AddressShown; - workbench_create_form_previewer_shown: DatasheetCreateMirrorTip; + workbench_create_form_previewer_shown: AICreateAINode; workbench_entry: AddressShown; workbench_folder_from_template_showcase_shown: AddressShown; workbench_folder_showcase_shown: AddressShown; @@ -605,17 +628,14 @@ export interface Events { workbench_space_list_shown: AddressShown; } -export interface Empty { -} - export interface AddressShown { module: string; name: string; } -export interface DatasheetCreateMirrorTip { - guide: ActionGuide; +export interface AICreateAINode { module: string; + guide: ActionGuide; name: string; } @@ -642,14 +662,14 @@ export interface Tips { } export interface FirstNodeTips { - desc: string; description: string; title: string; + desc: string; } export interface Trigger { actions: string[]; - rules: string[]; + rules?: string[]; id: string; event: string[]; eventState?: string; @@ -823,8 +843,8 @@ export interface BuildBranch { } export interface IntegrationHelpURL { - marketplace: IntegrationDingtalkHelpURLMarketplace; value: string; + marketplace: IntegrationDingtalkHelpURLMarketplace; } export interface IntegrationDingtalkHelpURLMarketplace { @@ -840,10 +860,10 @@ export interface ShortcutKey { id: string; command: string; description?: string; - type?: TypeElement[]; + type?: ShortcutKeyType[]; } -export enum TypeElement { +export enum ShortcutKeyType { GalleryViewShortcuts = "gallery_view_shortcuts", GirdViewShortcuts = "gird_view_shortcuts", GlobalShortcuts = "global_shortcuts", @@ -852,37 +872,37 @@ export enum TypeElement { export interface TestFunction { async_compute: AsyncCompute; - render_normal: AsyncCompute; render_prompt: AsyncCompute; robot: AsyncCompute; - view_manual_save: AsyncCompute; widget_center: AsyncCompute; + render_normal: AsyncCompute; + view_manual_save: AsyncCompute; } export interface AsyncCompute { - card: Card; - feature_key: string; feature_name: string; - id: string; logo: string; - modal: AsyncComputeModal; + id: string; note: string; + feature_key: string; + modal: AsyncComputeModal; + card: Card; } export interface Card { - btn_close_action: string; btn_open_action: string; - btn_text: string; - btn_type: string; info: string; info的副本: string; + btn_close_action: string; + btn_text: string; + btn_type: string; } export interface AsyncComputeModal { - btn_action?: string; btn_text: string; - btn_type: string; info: string; - info_image: string; + btn_action?: string; + btn_type: string; info的副本: string; + info_image: string; } diff --git a/packages/core/src/config/system_config.source.json b/packages/core/src/config/system_config.source.json index 2e125d5445..d1699c2504 100644 --- a/packages/core/src/config/system_config.source.json +++ b/packages/core/src/config/system_config.source.json @@ -1,1136 +1,1721 @@ { - "api_panel": { - "Attachment": { - "defaultExample": "[\n {\n \"id\": \"atcPtxnvqti5M\",\n \"name\": \"6.gif\",\n \"size\": 33914,\n \"mimeType\": \"image/gif\",\n \"token\": \"space/2020/09/22/01ee7202922d48688f61e34f12da5abc\",\n \"width\": 240,\n \"height\": 240,\n \"url\": \"__host__/space/2020/09/22/01ee7202922d48688f61e34f12da5abc\"\n }\n]", - "defaultExampleId": "api_panel_type_default_example_attachment", - "description": "由若干“附件对象”组成的数组 每一个附件对象应该包含下列属性: mimeType (string) : 附件的媒体类型 name (string) : 附件的名称 size (number) : 附件的大小,单位为字节 width (number) : 如果附件是图片格式,表示图片的宽度,单位为px height (number) : 如果附件是图片格式,表示图片的高度,单位为px token (string) : 附件的访问路径 preview (string) : 如果附件是PDF格式,将会生成一个预览图,用户可以通过此网址访问", - "descriptionId": "api_panel_type_desc_attachment", - "valueType": "array of attachment objects" + "environment": { + "integration": { + "env": "integration" }, - "AutoNumber": { - "defaultExample": "10001", - "defaultExampleId": "api_panel_type_default_example_auto_number", - "description": "数值,正整数 创建记录时自动生成,不支持手动写入", - "descriptionId": "api_panel_type_desc_autonumber", - "valueType": "number" + "production": { + "env": "production" }, - "Cascader": { - "defaultExample": "多级联动,适合作为有层级关系选项的文本,例如省区市的选择。", - "defaultExampleId": "api_panel_type_desc_cascader", - "description": "多级联动,适合作为有层级关系选项的文本,例如省区市的选择。", - "descriptionId": "api_panel_type_desc_cascader", - "valueType": "string" + "staging": { + "env": "staging" + } + }, + "settings": { + "_build_branch": { + "value": "local" }, - "Checkbox": { - "defaultExample": "true", - "defaultExampleId": "api_panel_type_default_example_checkbox", - "description": "布尔类型的true 或 空 当此字段被勾选时返回“true”。除此以外,记录中不返回此字段!", - "descriptionId": "api_panel_type_desc_checkbox", - "valueType": "boolean" + "_build_id": { + "value": "0" }, - "CreatedBy": { - "defaultExample": "{\n \"uuid\": \"aa3e6af7041c4907ba03889acc0b0cd1\",\n \"name\": \"Kelvin\",\n \"avatar\": \"__host__/public/2020/08/03/574bcee4cfc54f6fbb7d686bb237f6f3\"\n}", - "defaultExampleId": "api_panel_type_default_example_created_by", - "description": "创建此记录的成员(unit),以数组形式返回 「组织单元」是维格表中描述“空间站”与“成员”之间的关系的一个抽象概念。成员(member)、小组(team)都是一种组织单元。 *创建人必须为成员(member) unitId (string) : 组织单元的ID unitType (number) : 组织单元的类型,1是小组,3是成员 unitName (string) : 组织单元的名称,如果unitType是1,此值为小组名称;如果unitType是3,此值为成员站内昵称", - "descriptionId": "api_panel_type_desc_created_by", - "valueType": "array of unit objects" + "_version_type": { + "value": "local" }, - "CreatedTime": { - "defaultExample": "1600777860000", - "defaultExampleId": "api_panel_type_default_example_created_time", - "description": "日期和时间,以毫秒(ms)为单位返回时间戳", - "descriptionId": "api_panel_type_desc_created_time", - "valueType": "number | string" + "activity_center_end_time": { + "value": "2021-05-30 19:30" }, - "Currency": { - "defaultExample": "8.88", - "defaultExampleId": "api_panel_type_default_example_currency", - "description": "数值,支持负值 通过api调用返回的值,不受列配置里指定的精度影响,只会原样返回。", - "descriptionId": "api_panel_type_desc_currency", - "valueType": "number" + "activity_center_url": { + "value": "https://mp.weixin.qq.com/s/s2IRoAMHzsGq697TP0CCrQ" }, - "DateTime": { - "defaultExample": "1600777860000", - "defaultExampleId": "api_panel_type_default_example_date_time", - "description": "日期和时间,以毫秒(ms)为单位返回时间戳", - "descriptionId": "api_panel_type_desc_date_time", - "valueType": "number | string" + "activity_train_camp_end_time": { + "value": "2022-08-31 23:59" }, - "Email": { - "defaultExample": "support@vikadata.com", - "defaultExampleId": "api_panel_type_default_example_email", - "description": "邮箱地址(字符串)", - "descriptionId": "api_panel_type_desc_email", - "valueType": "string" + "activity_train_camp_start_time": { + "value": "2022-03-31 00:00" }, - "Formula": { - "defaultExample": "在第一行完整填写数据,就可以查看示例了", - "defaultExampleId": "api_panel_type_default_example_formula", - "description": "经过公式和函数运算后的结果,数据类型可能是数字、字符串、布尔值 此字段是运算值,创建/更新记录时不支持写入", - "descriptionId": "api_panel_type_desc_formula", - "valueType": "number | string | boolean" + "agree_terms_of_service": { + "value": "75" }, - "LastModifiedBy": { - "defaultExample": "{\n \"uuid\": \"aa3e6af7041c4907ba03889acc0b0cd1\",\n \"name\": \"Kelvin\",\n \"avatar\": \"__host__/public/2020/08/03/574bcee4cfc54f6fbb7d686bb237f6f3\"\n}", - "defaultExampleId": "api_panel_type_default_example_last_modified_by", - "description": "最近一次编辑记录/指定字段的成员(unit),以数组形式返回 「组织单元」是维格表中描述“空间站”与“成员”之间的关系的一个抽象概念。成员(member)、小组(team)都是一种组织单元。 *修改人必须为成员(member) unitId (string) : 组织单元的ID unitType (number) : 组织单元的类型,1是小组,3是成员 unitName (string) : 组织单元的名称,如果unitType是1,此值为小组名称;如果unitType是3,此值为成员站内昵称", - "descriptionId": "api_panel_type_desc_last_modified_by", - "valueType": "array of unit objects" + "api_apiffox_patch_url": { + "value": "https://www.apifox.cn/apidoc/project-613370/api-13867672-run?path[datasheetId]=${datasheetId}&query[viewId]=${viewId}&environment[token]=${token}&environment[body]=${body}" }, - "LastModifiedTime": { - "defaultExample": "1600777860000", - "defaultExampleId": "api_panel_type_default_example_last_modified_time", - "description": "日期和时间,以毫秒 (ms) 为单位返回时间戳", - "descriptionId": "api_panel_type_desc_last_modified_time", - "valueType": "number | string" + "api_apiffox_post_url": { + "value": "https://www.apifox.cn/apidoc/project-613370/api-13867671-run?path[datasheetId]=${datasheetId}&query[viewId]=${viewId}&environment[token]=${token}&environment[body]=${body}" }, - "OneWayLink": { - "defaultExample": "[\n \"rec8116cdd76088af\",\n \"rec245db9343f55e8\",\n \"rec4f3bade67ff565\"\n]", - "defaultExampleId": "api_panel_type_default_example_one_way_link", - "description": "由多条已关联记录的ID组成的数组 ", - "descriptionId": "api_panel_type_desc_one_way_link", - "valueType": "array of record IDs (strings)" + "api_apifox_delete_url": { + "value": "https://www.apifox.cn/apidoc/project-613370/api-13867673-run?path[datasheetId]=${datasheetId}&query[viewId]=${viewId}&query[recordIds]=${recordId}&environment[token]=${token}" }, - "Link": { - "defaultExample": "[\n \"rec8116cdd76088af\",\n \"rec245db9343f55e8\",\n \"rec4f3bade67ff565\"\n]", - "defaultExampleId": "api_panel_type_default_example_link", - "description": "由多条已关联记录的ID组成的数组 ", - "descriptionId": "api_panel_type_desc_link", - "valueType": "array of record IDs (strings)" + "api_apifox_get_url": { + "value": "https://www.apifox.cn/apidoc/project-613370/api-13867447-run?path[datasheetId]=${datasheetId}&query[viewId]=${viewId}&environment[token]=${token}" }, - "LookUp": { - "defaultExample": "在第一行完整填写数据,就可以查看示例了", - "defaultExampleId": "api_panel_type_default_example_look_up", - "description": "A表与B表通过双向关联字段进行表关联后,可使用此字段对B表的任意字段进行引用,视乎引用方式的不同,而返回不同数据类型的运算值。 如果引用方式选择了「原样引用」,则运算结果的数据类型保持与B表源字段一致; 其他引用方式皆返回数字类型的运算值", - "descriptionId": "api_panel_type_desc_look_up", - "valueType": "any" + "api_apifox_upload_url": { + "value": "https://www.apifox.cn/apidoc/project-613370/api-13867674-run?path[datasheetId]=${datasheetId}&environment[token]=${token}" }, - "Member": { - "defaultExample": "[\n {\n \"id\": \"1291258301781176321\",\n \"type\": 3,\n \"name\": \"小葵\",\n \"avatar\": \"https://s1.vika.cn/default/avatar004.jpg\"\n }\n]", - "defaultExampleId": "api_panel_type_default_example_member", - "description": "由若干「组织单元(unit)」组成的数组 「组织单元」是维格表中描述“空间站”与“成员”之间的关系的一个抽象概念。成员(member)、小组(team)都是一种组织单元。 id (string) : 组织单元的ID type (number) : 组织单元的类型,1是小组,3是成员 name (string) : 组织单元的名称,如果 type 是1,此值为小组名称;如果 type 是3,此值为成员站内昵称", - "descriptionId": "api_panel_type_desc_member", - "valueType": "array of unit objects" + "api_times_per_day": { + "value": "1000000" }, - "MultiSelect": { - "defaultExample": "[\n \"选项 A\",\n \"选项 B\"\n]", - "defaultExampleId": "api_panel_type_default_example_multi_select", - "description": "可能有多个选项,返回已选上的若干个选项值构成的字符串数组 当创建/更新记录时,提交的选项值并不存在于选项列表,则会返回错误码400,提示“参数错误”", - "descriptionId": "api_panel_type_desc_multi_select", - "valueType": "array of strings" + "api_times_per_hour": { + "value": "0" }, - "Number": { - "defaultExample": "8", - "defaultExampleId": "api_panel_type_default_example_number", - "description": "数值,支持负值 通过api调用返回的值,不受列配置里指定的精度影响,只会原样返回。", - "descriptionId": "api_panel_type_desc_number", - "valueType": "number" + "api_times_per_minute": { + "value": "100" }, - "Percent": { - "defaultExample": "0.88", - "defaultExampleId": "api_panel_type_default_example_percent", - "description": "数值,支持负值 通过API调用返回的值,不受列配置里指定的精度影响,只会原样返回。", - "descriptionId": "api_panel_type_desc_percent", - "valueType": "number" + "api_times_per_second": { + "value": "10" }, - "Phone": { - "defaultExample": "138xxxx7240", - "defaultExampleId": "api_panel_type_default_example_phone", - "description": "电话号码(字符串)", - "descriptionId": "api_panel_type_desc_phone", - "valueType": "string" + "apitable_login_logo": { + "value": "space/2022/12/05/1e36972963f64c85a7ce998c6abc075d" }, - "Rating": { - "defaultExample": "1", - "defaultExampleId": "api_panel_type_default_example_rating", - "description": "评分值是 1-9 之间的一个正整数 如果单元格为空或者撤销评分,则记录中不返回此字段!", - "descriptionId": "api_panel_type_desc_rating", - "valueType": "number" + "assistant": { + "value": "true" }, - "SingleSelect": { - "defaultExample": "选项 A", - "defaultExampleId": "api_panel_type_default_example_single_select", - "description": "可能有多个选项,返回已选上的一个选项值(字符串) 当创建/更新记录时,提交的选项值并不存在于选项列表,则会返回错误码400,提示“参数错误”", - "descriptionId": "api_panel_type_desc_single_select", - "valueType": "string" + "assistant_activity_train_camp_end_time": { + "value": "2022-08-31 23:59" }, - "SingleText": { - "defaultExample": "单行文本内容", - "defaultExampleId": "api_panel_type_default_example_single_text", - "description": "单行文本,适合保存不带换行符的文本,例如文章的标题。", - "descriptionId": "api_panel_type_desc_single_text", - "valueType": "string" + "assistant_activity_train_camp_start_time": { + "value": "2022-03-31 00:00" }, - "Text": { - "defaultExample": "多行\n文本内容", - "defaultExampleId": "api_panel_type_default_example_text", - "description": "多行文本,可用于存放较长的文本内容,例如一篇学术论文。", - "descriptionId": "api_panel_type_desc_text", - "valueType": "string" + "assistant_ai_course_url": { + "value": "https://vika.cn/ai-course/" }, - "Workdoc": { - "defaultExample": "文档内容", - "defaultExampleId": "api_panel_type_default_example_workdoc", - "description": "文档,可用于存放文档。", - "descriptionId": "api_panel_type_desc_workdoc", - "valueType": "array" + "assistant_release_history_url": { + "value": "https://bbs.vika.cn/column/details/13" }, - "URL": { - "defaultExample": "{\"title\":\"vika\",\"text\":\"https://vika.cn\", \"favicon\":\"https://s1.vika.cn/space/2022/12/20/73456950217f4f79b20c7ef1a49acf6e\"}", - "defaultExampleId": "api_panel_type_default_example_url", - "description": "URL 地址(字符串)", - "descriptionId": "api_panel_type_desc_url", - "valueType": "string" + "automation_action_send_msg_to_dingtalk": { + "value": "true" }, - "Button": { - "defaultExample": "Click Start", - "defaultExampleId": "click_start", - "description": "按钮列", - "descriptionId": "field_desc_button", - "valueType": "string" - } - }, - "audit": { - "actual_delete_space": { - "category": "space_change_event", - "content": "audit_space_complete_delete_detail", - "name": "audit_space_complete_delete", - "online": true, - "type": "space" + "automation_action_send_msg_to_feishu": { + "value": "true" }, - "add_field_role": { - "category": "datasheet_field_permission_change_event", - "content": "audit_add_field_role_detail", - "name": "audit_add_field_role", - "type": "space" + "automation_action_send_msg_to_wecom": { + "value": "true" }, - "add_node_role": { - "category": "work_catalog_permission_change_event", - "content": "audit_add_node_role_detail", - "name": "audit_add_node_role", - "online": true, - "show_in_audit_log": true, - "sort": "11", - "type": "space" + "billing_default_billing_period": { + "value": "annual" }, - "add_sub_admin": { - "category": "admin_permission_change_event", - "type": "space" + "billing_default_grade": { + "value": "silver" }, - "add_team_to_member": { - "category": "organization_change_event", - "type": "space" + "billing_default_seats": { + "value": "50" }, - "agree_user_apply": { - "category": "organization_change_event", - "type": "space" + "billing_enterprise_qr_code": { + "value": "space/2022/02/16/cf2f386d300142a19268c487b351d6bb" }, - "cancel_delete_space": { - "category": "space_change_event", - "content": "audit_space_cancel_delete_detail", - "name": "audit_space_cancel_delete", - "online": true, - "type": "space" + "billing_pay_contact_us": { + "value": "space/2022/02/17/b32ecd3a5dcb43a1add4d320632c6d2a" }, - "change_main_admin": { - "category": "admin_permission_change_event", - "type": "space" + "billing_pay_success_qr_code": { + "value": "space/2022/02/17/b7cd077fca35444aa02fba4d11f2c1ba" }, - "copy_node": { - "category": "work_catalog_change_event", - "content": "audit_space_node_copy_detail", - "name": "audit_space_node_copy", - "online": true, - "show_in_audit_log": true, - "sort": "4", - "type": "space" + "datasheet_max_view_count_per_sheet": { + "value": "60" }, - "create_node": { - "category": "work_catalog_change_event", - "content": "audit_space_node_create_detail", - "name": "audit_space_node_create", - "online": true, - "show_in_audit_log": true, - "sort": "1", - "type": "space" + "datasheet_unlogin_user_avatar": { + "value": "space/2020/09/11/744b39b7ed5240e1b257553f683ed6cd" }, - "create_space": { - "category": "space_change_event", - "content": "audit_space_create_detail", - "name": "audit_space_create", - "online": true, - "type": "space" + "delete_account_step1_cover": { + "value": "space/2022/01/11/05fb6ad3c03b4b4da95156313b5d7777" }, - "create_team": { - "category": "organization_change_event", - "type": "space" + "delete_account_step2_email_icon": { + "value": "space/2022/01/11/b0d06adfb14d457b9db266349edbf656" }, - "create_template": { - "category": "space_template_event", - "content": "audit_create_template_detail", - "name": "audit_create_template", - "online": true, - "type": "space" + "delete_account_step2_mobile_icon": { + "value": "space/2022/01/11/ba4572da263c46ccb94843046a2a8e6c" }, - "delete_field_role": { - "category": "datasheet_field_permission_change_event", - "content": "audit_delete_field_role_detail", - "name": "audit_delete_field_role", - "type": "space" + "education_url": { + "value": "https://edu.vika.cn" }, - "delete_node": { - "category": "work_catalog_change_event", - "content": "audit_space_node_delete_detail", - "name": "audit_space_node_delete", - "online": true, - "show_in_audit_log": true, - "sort": "6", - "type": "space" + "email_icon": { + "value": "space/2022/12/05/0d3881bd9d3c4be59845739090d06051" }, - "delete_node_role": { - "category": "work_catalog_permission_change_event", - "content": "audit_delete_node_role_detail", - "name": "audit_delete_node_role", - "online": true, - "show_in_audit_log": true, - "sort": "13", - "type": "space" + "emoji_apple_32": { + "value": "space/2021/03/23/6972f73d8bfe4539b67a4d3e264771e0" }, - "delete_rubbish_node": { - "category": "work_catalog_change_event", - "content": "audit_space_rubbish_node_delete_detail", - "name": "audit_space_rubbish_node_delete", - "online": true, - "type": "space" + "emoji_apple_64": { + "value": "space/2021/03/23/c88653f7b7424d10bef058c345f6df6d" }, - "delete_space": { - "category": "space_change_event", - "content": "audit_space_delete_detail", - "name": "audit_space_delete", - "online": true, - "type": "space" + "experimental_features_unsynchronized_view_intro_img": { + "value": "space/2021/11/30/854742d76eaa46bba848d80f358f9cdf" }, - "delete_sub_admin": { - "category": "admin_permission_change_event", - "type": "space" + "field_cascade": { + "value": "true" }, - "delete_team": { - "category": "organization_change_event", - "type": "space" + "github_icon": { + "value": "space/2022/12/14/08393af8ffc84039a75f99b8ff01b61f" }, - "delete_template": { - "category": "space_template_event", - "content": "audit_delete_template_detail", - "name": "audit_delete_template", - "online": true, - "type": "space" + "grades_info": { + "value": "/pricing/" }, - "disable_field_role": { - "category": "datasheet_field_permission_change_event", - "content": "audit_disable_field_role_detail", - "name": "audit_disable_field_role", - "type": "space" + "help_assistant": { + "value": "true" }, - "disable_node_role": { - "category": "work_catalog_permission_change_event", - "content": "audit_disable_node_role_detail", - "name": "audit_disable_node_role", - "online": true, - "show_in_audit_log": true, - "sort": "10", - "type": "space" + "help_contact_us_type": { + "value": "qrcode" }, - "disable_node_share": { - "category": "work_catalog_share_event", - "content": "audit_disable_node_share_detail", - "name": "audit_disable_node_share", - "online": true, - "show_in_audit_log": true, - "sort": "16", - "type": "space" + "help_developers_center_url": { + "value": "https://vika.cn/developers" }, - "enable_field_role": { - "category": "datasheet_field_permission_change_event", - "content": "audit_enable_field_role_detail", - "name": "audit_enable_field_role", - "type": "space" + "help_download_app": { + "value": "true" }, - "enable_node_role": { - "category": "work_catalog_permission_change_event", - "content": "audit_enable_node_role_detail", - "name": "audit_enable_node_role", - "online": true, - "show_in_audit_log": true, - "sort": "9", - "type": "space" + "help_join_chatgroup_url": { + "value": "https://vika.cn/chatgroup/" }, - "enable_node_share": { - "category": "work_catalog_share_event", - "content": "audit_enable_node_share_detail", - "name": "audit_enable_node_share", - "online": true, - "show_in_audit_log": true, - "sort": "14", - "type": "space" + "help_official_website_url": { + "value": "vika.cn?home=1" }, - "export_node": { - "category": "work_catalog_change_event", - "content": "audit_space_node_export_detail", - "name": "audit_space_node_export", - "type": "space" + "help_product_roadmap_url": { + "value": "https://bbs.vika.cn/page/product_roadmap" }, - "import_node": { - "category": "work_catalog_change_event", - "content": "audit_space_node_import_detail", - "name": "audit_space_node_import", - "online": true, - "show_in_audit_log": true, - "sort": "3", - "type": "space" + "help_solution_url": { + "value": "https://vika.cn/solutions/" }, - "invite_user_join_by_email": { - "category": "organization_change_event", - "content": "audit_space_invite_user_detail", - "name": "audit_space_invite_user", - "type": "space" + "help_subscribe_demonstrate_form_url": { + "value": "https://vika.cn/share/shrFVCtHXQwYm3DVgNn91" }, - "move_node": { - "category": "work_catalog_change_event", - "content": "audit_space_node_move_detail", - "name": "audit_space_node_move", - "online": true, - "show_in_audit_log": true, - "sort": "5", - "type": "space" + "help_user_community_url": { + "value": "{\"dev\":\"https://bbs.vika.cn\",\"prod\":\"https://bbs.vika.cn\"}" }, - "quote_template": { - "category": "work_catalog_change_event", - "content": "audit_quote_template_detail", - "name": "audit_quote_template", - "online": true, - "type": "space" + "help_user_community_url_dev": { + "value": "https://bbs.vika.cn" }, - "recover_rubbish_node": { - "category": "work_catalog_change_event", - "content": "audit_space_rubbish_node_recover_detail", - "name": "audit_space_rubbish_node_recover", - "online": true, - "show_in_audit_log": true, - "sort": "7", - "type": "space" + "help_user_community_url_prod": { + "value": "https://bbs.vika.cn" }, - "remove_member_from_team": { - "category": "organization_change_event", - "type": "space" + "help_user_feedback_url": { + "value": "https://vika.cn/share/shrCvbFC53xc3kl00B4Pg" }, - "remove_user": { - "category": "organization_change_event", - "type": "space" + "help_video_tutorials_url": { + "value": "https://edu.vika.cn" }, - "rename_node": { - "category": "work_catalog_change_event", - "content": "audit_space_node_rename_detail", - "name": "audit_space_node_rename", - "online": true, - "show_in_audit_log": true, - "sort": "2", - "type": "space" + "integration_apifox_url": { + "value": "https://www.apifox.cn/apidoc/project-613370/doc-806641" }, - "rename_space": { - "category": "space_change_event", - "content": "audit_space_rename_detail", - "name": "audit_space_rename", - "online": true, - "type": "space" + "integration_dingtalk_da": { + "value": "https://h5.dingtalk.com/dingtalk-da/index.html" }, - "sort_node": { - "category": "work_catalog_change_event", - "content": "audit_space_node_sort_detail", - "name": "audit_space_node_sort", - "online": true, - "type": "space" + "integration_dingtalk_help_url": { + "value": "https://help.vika.cn/docs/guide/integration-dingtalk", + "marketplace": { + "integration": "ina9134969049653777" + } }, - "store_share_node": { - "category": "work_catalog_change_event", - "content": "audit_store_share_node_detail", - "name": "audit_store_share_node", - "online": true, - "show_in_audit_log": true, - "sort": "8", - "type": "space" + "integration_dingtalk_upgrade_url": { + "value": "http://h5.dingtalk.com/open-purchase/mobileUrl.html?redirectUrl=https%3A%2F%2Fh5.dingtalk.com%2Fopen-market%2Fshare.html%3FshareGoodsCode%3DD34E5A30A9AC7FC6CA73DEEEDFCEC860C2F97D997C85C521B71035D4F4F2DADF5E69AE3825326C7F%26token%3D65482d6a78796151887e033769bebfd8%26shareUid%3DBCB170692B0B56DA0C22819901B68B80&dtaction=os" }, - "update_field_role": { - "category": "datasheet_field_permission_change_event", - "content": "audit_update_field_role_detail", - "name": "audit_update_field_role", - "type": "space" + "integration_feishu_help": { + "value": "vika维格表 使用指南" }, - "update_field_role_setting": { - "category": "datasheet_field_permission_change_event", - "type": "space" + "integration_feishu_help_url": { + "value": "https://help.vika.cn/docs/guide/integration-lark", + "marketplace": { + "integration": "cli_9f3930dd7d7ad00c, cli_a08120b120fad00e, cli_9f614b454434500e" + } }, - "update_member_property": { - "category": "organization_change_event", - "type": "space" + "integration_feishu_manage_open_url": { + "value": "https://applink.feishu.cn/client/bot/open" }, - "update_member_team": { - "category": "organization_change_event", - "type": "space" + "integration_feishu_seats_form_url": { + "value": "https://u.vika.cn/pb7cj" }, - "update_node_cover": { - "category": "work_catalog_change_event", - "content": "audit_space_node_update_cover_detail", - "name": "audit_space_node_update_cover", - "online": true, - "type": "space" + "integration_feishu_upgrade_url": { + "value": "https://feishu.cn/admin/appCenter/manage/cli_9f614b454434500e" }, - "update_node_desc": { - "category": "work_catalog_change_event", - "content": "audit_space_node_update_desc_detail", - "name": "audit_space_node_update_desc", - "online": true, - "type": "space" + "integration_feishu_upgrade_url_dev": { + "value": "https://feishu.cn/admin/appCenter/manage/cli_a28611a8b9e2900d" }, - "update_node_icon": { - "category": "work_catalog_change_event", - "content": "audit_space_node_update_icon_detail", - "name": "audit_space_node_update_icon", - "online": true, - "type": "space" + "integration_feisu_register_now_url": { + "value": "https://u.vika.cn/qmdp3" }, - "update_node_role": { - "category": "work_catalog_permission_change_event", - "content": "audit_update_node_role_detail", - "name": "audit_update_node_role", - "online": true, - "show_in_audit_log": true, - "sort": "12", - "type": "space" + "integration_wecom_bind_help_center": { + "value": "/help" }, - "update_node_share_setting": { - "category": "work_catalog_share_event", - "content": "audit_update_node_share_setting_detail", - "name": "audit_update_node_share_setting", - "online": true, - "show_in_audit_log": true, - "sort": "15", - "type": "space" + "integration_wecom_bind_help_center_url": { + "value": "/help" }, - "update_space_logo": { - "category": "space_change_event", - "content": "audit_space_update_logo_detail", - "name": "audit_space_update_logo", - "online": true, - "type": "space" + "integration_wecom_bind_success_icon_img": { + "value": "/space/2021/09/16/124e249b651f4934949ae39839e3ee77" }, - "update_sub_admin_role": { - "category": "admin_permission_change_event", - "type": "space" + "integration_wecom_custom_subdomain_help_url": { + "value": "https://help.vika.cn/docs/guide/intro_custom_subdomain" }, - "update_team_property": { - "category": "organization_change_event", - "type": "space" + "integration_wecom_help_url": { + "value": "https://help.vika.cn/docs/guide/integration-wecom", + "marketplace": { + "integration": "ina5200279359980055" + } }, - "user_leave_space": { - "category": "organization_change_event", - "content": "audit_user_quit_space_detail", - "name": "audit_user_quit_space", - "type": "space" + "integration_wecom_login_qrcode_js": { + "value": "http://wwcdn.weixin.qq.com/node/wework/wwopen/js/wwLogin-1.2.4.js" }, - "user_login": { - "category": "account_event", - "content": "audit_user_login_detail", - "name": "audit_user_login", - "online": true, - "type": "system" + "integration_wecom_qrcode_css": { + "value": "/space/2021/08/02/6b5374b4b3ba42aba69022ae2b13a577" }, - "user_logout": { - "category": "account_event", - "content": "audit_user_logout_detail", - "name": "audit_user_logout", - "online": true, - "type": "system" - } - }, - "country_code_and_phone_code": { - "afghanistan": { - "phoneCode": "93" + "integration_wecom_shop_cms": { + "value": "https://help.vika.cn/docs/guide/integration-wecom" }, - "albania": { - "phoneCode": "355" + "integration_wecom_shop_corpid_dev": { + "value": "ww11761d11177ae10b" }, - "algeria": { - "phoneCode": "213" + "integration_wecom_shop_corpid_prod": { + "value": "ww11761d11177ae10b" }, - "american_samoa": { - "phoneCode": "1684" + "integration_wecom_shop_corpid_staging": { + "value": "ww11761d11177ae10b" }, - "andorra": { - "phoneCode": "376" + "integration_wecom_shop_corpid_test": { + "value": "ww11761d11177ae10b" }, - "angola": { - "phoneCode": "244" + "integration_wecom_shop_suiteid_dev": { + "value": "wwc98ec5fc01dfdaeb" }, - "anguilla": { - "phoneCode": "1264" + "integration_wecom_shop_suiteid_prod": { + "value": "ww0506baa4d734acb9" }, - "antigua_and_barbuda": { - "phoneCode": "1268" + "integration_wecom_shop_suiteid_staging": { + "value": "ww514bd11dfd0f294f" }, - "argentina": { - "phoneCode": "54" + "integration_wecom_shop_suiteid_test": { + "value": "ww3dd616a360b3ce97" }, - "armenia": { - "phoneCode": "374" + "integration_wecom_upgrade_guide_url": { + "value": "/wecom-integration/#upgrade" }, - "aruba": { - "phoneCode": "297" + "integration_yozosoft_help_url": { + "value": "https://help.vika.cn/docs/guide/integration-yozosoft", + "marketplace": { + "integration": "ina5645957505507647" + } }, - "australia": { - "phoneCode": "61" + "introduction_video": { + "value": "space/2022/04/14/aff988f37b6849b1bf438a73d8721ae2" }, - "austria": { - "phoneCode": "43" + "linkedin_icon": { + "value": "space/2022/12/05/762594b3353141f6a7a83d10a3e47ea4" }, - "azerbaijan": { - "phoneCode": "994" + "login_agree_terms_of_service": { + "value": "75" }, - "bahamas": { - "phoneCode": "1242" + "login_icp1_url": { + "value": "https://beian.miit.gov.cn/" }, - "bahrain": { - "phoneCode": "973" + "login_icp2_url": { + "value": "http://www.beian.gov.cn/portal/registerSystemInfo" }, - "bangladesh": { - "phoneCode": "880" + "login_introduction_video": { + "value": "space/2022/04/14/aff988f37b6849b1bf438a73d8721ae2" }, - "barbados": { - "phoneCode": "1246" + "login_join_chatgroup_url": { + "value": "https://vika.cn/chatgroup/" }, - "belarus": { - "phoneCode": "375" + "login_privacy_policy": { + "value": "维格隐私政策" }, - "belgium": { - "phoneCode": "32" + "login_private_deployment_form_url": { + "value": "https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL" }, - "belize": { - "phoneCode": "501" + "login_service_agreement": { + "value": "维格服务协议" }, - "benin": { - "phoneCode": "229" + "official_avatar": { + "value": "space/2021/12/07/aaac193704834e9a9e4af27a1535826a" }, - "bermuda": { - "phoneCode": "1441" + "page_apply_logout": { + "value": "space/2022/01/11/5bb30117e4934522af081a05eb4fd903" }, - "bhutan": { - "phoneCode": "975" + "page_apply_logout_bg": { + "value": "space/2022/01/11/35106645c2614d11bea689a540d13787" }, - "bolivia": { - "phoneCode": "591" + "permission_config_in_workbench_page": { + "value": "[{\"key\":0,\"title\":\"表格内的操作权限\",\"detail\":[{\"title\":\"编辑视图工具栏\",\"permissions\":[0,1,2]},{\"title\":\"编辑视图列表\",\"permissions\":[0,1,2]},{\"title\":\"导出视图数据\",\"permissions\":[0,1]},{\"title\":\"增删维格列\",\"permissions\":[0,1]},{\"title\":\"编辑维格列属性(列名/类型/描述)\",\"permissions\":[0,1]},{\"title\":\"编辑维格列样式(列宽/统计栏)\",\"permissions\":[0,1]},{\"title\":\"编辑行(增删/拖动)\",\"permissions\":[0,1,2]},{\"title\":\"编辑单元格(增删改数据)\",\"permissions\":[0,1,2]},{\"title\":\" 撤销,重做\",\"permissions\":[0,1,2]}]},{\"key\":1,\"title\":\"对文件(夹)的操作权限\",\"detail\":[{\"title\":\"设置文件(夹)权限\",\"permissions\":[0,1]},{\"title\":\"将继承切换为指定权限\",\"permissions\":[0,1]},{\"title\":\"将指定切换为继承权限\",\"permissions\":[0]},{\"title\":\"新建文件(夹)\",\"permissions\":[0,1]},{\"title\":\"导入文件\",\"permissions\":[0,1]},{\"title\":\"导出文件\",\"permissions\":[0,1]},{\"title\":\"复制文件(当前文件&上级文件夹权限)\",\"permissions\":[0,1]},{\"title\":\"移动文件(当前文件&目标文件夹权限)\",\"permissions\":[0,1]},{\"title\":\"重命名文件(夹)\",\"permissions\":[0,1]},{\"title\":\"删除文件(夹)\",\"permissions\":[0,1]},{\"title\":\"分享文件(夹)\",\"permissions\":[0,1,2]},{\"title\":\"保存为模板\",\"permissions\":[0,1]}]}]" }, - "bosnia_and_herzegovina": { - "phoneCode": "387" + "quick_search_default_dark": { + "value": "space/2023/03/15/42dc46843161478fb56d27efb43a50b8" }, - "botswana": { - "phoneCode": "267" + "quick_search_default_light": { + "value": "space/2023/03/15/0fd81978a8c04d96a483f4c785736b62" }, - "brazil": { - "phoneCode": "55" + "server_error_page_bg": { + "value": "/space/2022/09/07/cbaf2ee93be24f6bbe361a85db0efba7?attname=theserverisundermaintenance.%402x.png" }, - "brunei": { - "phoneCode": "673" + "share_iframe_brand": { + "value": "space/2021/12/09/3b09b857cee04a12b6b02cd63bb90a81?attname=%E7%BB%B4%E6%A0%BC%E8%A1%A8logo.svg" }, - "bulgaria": { - "phoneCode": "359" + "share_iframe_brand_dark": { + "value": "space/2022/11/28/94e87bd1fd25472e99556c9b5f72c62e?attname=logo-reverse.svg" }, - "burkina_faso": { - "phoneCode": "226" + "space_setting_integrations_dingtalk": { + "value": "true" }, - "burundi": { - "phoneCode": "257" + "space_setting_integrations_feishu": { + "value": "true" }, - "cambodia": { - "phoneCode": "855" + "space_setting_integrations_preview_office_file": { + "value": "true" }, - "cameroon": { - "phoneCode": "237" + "space_setting_integrations_wecom": { + "value": "true" }, - "canada": { - "phoneCode": "1" + "space_setting_invite_user_to_get_v_coins": { + "value": "true" }, - "cape_verde": { - "phoneCode": "238" + "space_setting_list_of_enable_all_lab_features": { + "value": "[\"spcXXXXX\"]" }, - "cayman_islands": { - "phoneCode": "1345" + "space_setting_role_empty_img": { + "value": "space/2022/08/03/3fbdff65d66547a8ab796e1b808d45b0" }, - "central_african_republic": { - "phoneCode": "236" + "space_setting_upgrade": { + "value": "true" }, - "chad": { - "phoneCode": "235" + "system_configuration_logo_with_name_white_font": { + "value": "/space/2021/09/17/5c69f63932da4be7aa0965d3b0e543c4" }, - "chile": { - "phoneCode": "56" + "system_configuration_minmum_version_require": { + "value": "0.5.0" }, - "china": { - "phoneCode": "86" + "system_configuration_server_error_bg_img": { + "value": "/space/2022/09/07/cbaf2ee93be24f6bbe361a85db0efba7?attname=theserverisundermaintenance.%402x.png" }, - "colombia": { - "phoneCode": "57" + "system_configuration_version": { + "value": "0.5.0" }, - "comoros": { - "phoneCode": "269" + "twitter_icon": { + "value": "space/2022/12/05/09cc01ee1f894fb2923bd08b715226b6" }, - "cook_islands": { - "phoneCode": "682" + "user_account_deleted_bg_img": { + "value": "space/2022/01/11/35106645c2614d11bea689a540d13787" }, - "costa_rica": { - "phoneCode": "506" + "user_account_deleted_img": { + "value": "space/2022/01/11/5bb30117e4934522af081a05eb4fd903" }, - "croatia": { - "phoneCode": "385" + "user_guide_welcome_developer_center_url": { + "value": "/help/developers/" }, - "cuba": { - "phoneCode": "53" + "user_guide_welcome_introduction_video": { + "value": "{ \"title\":\"玩转一张维格表\", \"video\":\"space/2020/12/21/cb7bdf6fe22146068111d46915587fb2\", \"autoPlay\":true }" }, - "curacao": { - "phoneCode": "599" + "user_guide_welcome_quick_start_video": { + "value": "{\"title\":\"一分钟快速入门\", \"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\", \"autoPlay\":true}" }, - "cyprus": { - "phoneCode": "357" + "user_guide_welcome_template1_icon": { + "value": "现有的 icon 链接" }, - "czech": { - "phoneCode": "420" + "user_guide_welcome_template1_url": { + "value": "/template/tpchFkNFaaJMC/tplDYzZqqwpRQ" }, - "democratic_republic_of_the_congo": { - "phoneCode": "243" + "user_guide_welcome_template2_icon": { + "value": "现有的 icon 链接" }, - "denmark": { - "phoneCode": "45" + "user_guide_welcome_template2_url": { + "value": "/template/tpc76og2J6D8p/tplDBUKmXFo7c" }, - "djibouti": { - "phoneCode": "253" + "user_guide_welcome_template3_icon": { + "value": "现有的 icon 链接" }, - "dominica": { - "phoneCode": "1767" + "user_guide_welcome_template3_url": { + "value": "/template/tpcMixDKM5f3s/tplaglc40487X" }, - "dominican_republic": { - "phoneCode": "1809" + "user_guide_welcome_what_is_datasheet_video": { + "value": "{ \"title\":\"什么是维格表\", \"video\":\"space/2022/02/21/94cb82f9ffd84a5499c8931a224ad234\", \"autoPlay\":true }" }, - "ecuador": { - "phoneCode": "593" + "user_setting_account_bind": { + "value": "true" }, - "egypt": { - "phoneCode": "20" + "user_setting_account_bind_dingtalk": { + "value": "true" }, - "el_salvador": { - "phoneCode": "503" + "user_setting_account_bind_qq": { + "value": "true" }, - "equatorial_guinea": { - "phoneCode": "240" + "user_setting_account_bind_wechat": { + "value": "true" }, - "eritrea": { - "phoneCode": "291" - }, - "estonia": { - "phoneCode": "372" + "user_setting_default_avatar": { + "value": "space/2020/09/11/e6aa3037a38f45acb65324ea314aea58,space/2021/03/10/61a8aae11da2439ebb4df35b9075587d,space/2020/09/11/41e723917dc742d2974e41abab8cf60b,space/2020/09/11/4dce50e4ec4649b9a408a494aca28183,space/2020/09/11/e4d073b1fa674bc884a8c194e9248ecf,space/2020/09/11/31a1acb4734c4dd3ae9538299282b39e" }, - "ethiopia": { - "phoneCode": "251" + "view_architecture_empty_graphics_img": { + "value": "space/2021/11/19/b1c660a317fb4068bd312d16671308a1" }, - "faroe_islands": { - "phoneCode": "298" + "view_architecture_empty_record_list_img": { + "value": "space/2021/11/19/73c1cda56b3d4d448416d9b69c757598" }, - "fiji": { - "phoneCode": "679" + "view_architecture_guide_video": { + "value": "space/2021/11/18/428b94bb262845afabf46efff8e082b5" }, - "finland": { - "phoneCode": "358" + "view_calendar_guide_create": { + "value": "space/2021/08/16/bda3a4c51ebc444ea9f26d4573987257" }, - "france": { - "phoneCode": "33" + "view_calendar_guide_no_permission": { + "value": "space/2022/05/23/4206adbf0aaa43bf90342fd0e568dc73" }, - "french_guiana": { - "phoneCode": "594" + "view_calendar_guide_video": { + "value": "space/2021/08/06/e3a4e480768c4b4d8d01ea4a269bf2bb" }, - "french_polynesia": { - "phoneCode": "689" + "view_form_guide_video": { + "value": "space/2020/12/25/f0ecc536d7324df888d165cb73cd22c6" }, - "gabon": { - "phoneCode": "241" + "view_gallery_guide_video": { + "value": "space/2020/09/15/4383ec2f8eb041599396df0f18d99f5a" }, - "gambia": { - "phoneCode": "220" + "view_gantt_guide_video": { + "value": "space/2021/06/02/8bd6c5263ba444aabc138ed051b83c8c" }, - "georgia": { - "phoneCode": "995" + "view_grid_guide_video": { + "value": "space/2020/09/16/77e941353d8141b69f684e2592350ec7" }, - "germany": { - "phoneCode": "49" + "view_kanban_guide_video": { + "value": "space/2020/09/11/c964bcf3ec48458dae7fbdc55a59856b" }, - "ghana": { - "phoneCode": "233" + "view_mirror_list_empty_img": { + "value": "space/2022/05/23/d880e95a4a204492b20d8725c61c998c" }, - "gibraltar": { - "phoneCode": "350" + "widget_center_feature_not_unturned_on_img": { + "value": "/space/2021/12/27/cc7c3d706c8e4443a0e9b79673a078e0" }, - "greece": { - "phoneCode": "30" + "widget_center_help_link": { + "value": "#" }, - "greenland": { - "phoneCode": "299" + "widget_center_space_widget_empty_img": { + "value": "/space/2021/10/08/18343b0891a74bdb9ca0b36b6c543e3b" }, - "grenada": { - "phoneCode": "1473" + "widget_cli_miumum_version": { + "value": "0.0.1" }, - "guadeloupe": { - "phoneCode": "590" + "widget_custom_widget_empty_img": { + "value": "/space/2021/10/08/18343b0891a74bdb9ca0b36b6c543e3b" }, - "guam": { - "phoneCode": "1671" + "widget_default_cover_img": { + "value": "/space/2021/11/09/f82a5c9cb6c74452b824e17b03f20f67" }, - "guatemala": { - "phoneCode": "502" + "widget_panel_empty_img": { + "value": "space/2022/05/23/c5096fdb5d674985a49725e23f72cdc7" }, - "guinea": { - "phoneCode": "224" + "workbench_folder_default_cover_list": { + "value": "space/2021/12/29/7306be86fc6d4cac9d8de9b4a787b1fa,space/2021/12/29/58073bbfe0f64dc7bd2f5f44a123c172,space/2021/12/29/e36e93966aa049e1ba7fd53907c2265f,space/2021/12/29/ebd570b6ee3b429f8c2e51e1b1df6657,space/2021/12/29/7eb38331f61240dcb74b1fce3a90c6bc,space/2021/12/29/a8c5df5eba2e4c07a78bdca6b9613579" }, - "guinea_bissau": { - "phoneCode": "245" + "workbench_max_node_number_show_invite_and_new_node": { + "value": "13" }, - "guyana": { - "phoneCode": "592" + "workbench_no_permission_img": { + "value": "/space/2022/09/07/6e95e804d5f44fe4a0dec81d228b0286?attname=filecannotbeaccessed%402x.png" + } + }, + "shortcut_keys": [ + { + "show": true, + "key": "cmd+z", + "winKey": "ctrl+z", + "name": [ + "undo" + ], + "when": "!isGlobalEditing", + "id": "cmd+z", + "command": "Undo", + "description": "撤销", + "type": [ + "global_shortcuts" + ] }, - "haiti": { - "phoneCode": "509" + { + "show": true, + "key": "cmd+shift+z", + "winKey": "ctrl+shift+z", + "name": [ + "redo" + ], + "when": "!isGlobalEditing", + "id": "cmd+shift+z", + "command": "Redo", + "description": "重做", + "type": [ + "global_shortcuts" + ] }, - "honduras": { - "phoneCode": "504" + { + "show": true, + "key": "cmd+y", + "winKey": "ctrl+y", + "name": [ + "redo" + ], + "when": "!isGlobalEditing", + "id": "cmd+y", + "command": "Redo", + "description": "重做", + "type": [ + "global_shortcuts" + ] }, - "hong_kong": { - "phoneCode": "852" + { + "show": true, + "key": "cmd+f", + "winKey": "ctrl+f", + "name": [ + "find" + ], + "when": "!isRecordExpanding && !isWorkdocOpen", + "id": "cmd+f", + "command": "ToggleFindPanel", + "description": "查找", + "type": [ + "global_shortcuts" + ] }, - "hungary": { - "phoneCode": "36" + { + "show": true, + "key": "cmd+shift+p", + "winKey": "ctrl+shift+p", + "name": [ + "open_api_panel" + ], + "when": "true ", + "id": "cmd+shift+p", + "command": "ToggleApiPanel", + "description": "打开 API 示例面板", + "type": [ + "global_shortcuts" + ] }, - "iceland": { - "phoneCode": "354" + { + "show": true, + "key": "cmd+/", + "winKey": "ctrl+/", + "name": [ + "open_keyboard_shortcuts_panel" + ], + "when": "!isGlobalEditing && !isRecordExpanding", + "id": "cmd+/", + "command": "Help", + "description": "打开快捷键面板", + "type": [ + "global_shortcuts" + ] }, - "india": { - "phoneCode": "91" + { + "show": true, + "key": "cmd+up", + "winKey": "ctrl+up", + "name": [ + "previous_record" + ], + "when": "isRecordExpanding", + "id": "cmd+up", + "command": "PreviousRecord", + "description": "卡片翻到上一条记录", + "type": [ + "global_shortcuts" + ] }, - "indonesia": { - "phoneCode": "62" + { + "show": true, + "key": "cmd+shift+,", + "winKey": "ctrl+shift+,", + "name": [ + "previous_record" + ], + "when": "isRecordExpanding", + "id": "cmd+shift+,", + "command": "PreviousRecord", + "description": "卡片翻到上一条记录", + "type": [ + "global_shortcuts" + ] }, - "iran": { - "phoneCode": "98" + { + "show": true, + "key": "cmd+down", + "winKey": "ctrl+down", + "name": [ + "next_record" + ], + "when": "isRecordExpanding", + "id": "cmd+down", + "command": "NextRecord", + "description": "卡片翻到下一条记录", + "type": [ + "global_shortcuts" + ] }, - "iraq": { - "phoneCode": "964" + { + "show": true, + "key": "cmd+shift+.", + "winKey": "ctrl+shift+.", + "name": [ + "next_record" + ], + "when": "isRecordExpanding", + "id": "cmd+shift+.", + "command": "NextRecord", + "description": "卡片翻到下一条记录", + "type": [ + "global_shortcuts" + ] }, - "ireland": { - "phoneCode": "353" + { + "show": true, + "key": "cmd+shift+,", + "winKey": "ctrl+shift+,", + "name": [ + "switch_view_prev" + ], + "when": "!isRecordExpanding", + "id": "cmd+shift+,", + "command": "ViewPrev", + "description": "视图标签向前切换视图", + "type": [ + "global_shortcuts" + ] }, - "israel": { - "phoneCode": "972" + { + "show": true, + "key": "cmd+shift+.", + "winKey": "ctrl+shift+.", + "name": [ + "switch_view_next" + ], + "when": "!isRecordExpanding", + "id": "cmd+shift+.", + "command": "ViewNext", + "description": "视图标签向后切换视图", + "type": [ + "global_shortcuts" + ] }, - "italy": { - "phoneCode": "39" + { + "show": true, + "key": "cmd+c", + "winKey": "ctrl+c", + "name": [ + "duplicate_cell_data" + ], + "when": "hasActiveCell", + "id": "cmd+c", + "command": "Copy", + "description": "复制", + "type": [ + "gird_view_shortcuts" + ] }, - "ivory_coast": { - "phoneCode": "225" + { + "show": true, + "key": "cmd+v", + "winKey": "ctrl+v", + "name": [ + "paste_cell_data" + ], + "when": "hasActiveCell", + "id": "cmd+v", + "command": "Paste", + "description": "粘贴", + "type": [ + "gird_view_shortcuts" + ] }, - "jamaica": { - "phoneCode": "1876" + { + "show": true, + "key": "cmd+x", + "winKey": "ctrl+x", + "name": [ + "cut_cell_data" + ], + "id": "cmd+x", + "command": "None", + "description": "剪切", + "type": [ + "gird_view_shortcuts" + ] }, - "japan": { - "phoneCode": "81" + { + "show": true, + "key": "space", + "winKey": "space", + "name": [ + "expand_record" + ], + "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding && !isEditing", + "id": "space", + "command": "ExpandRecord", + "description": "展开行", + "type": [ + "gird_view_shortcuts" + ] }, - "jordan": { - "phoneCode": "962" + { + "show": true, + "key": "escape", + "winKey": "escape", + "name": [ + "escape" + ], + "when": "isEditing", + "id": "escape", + "command": "ExitEditing", + "description": "退出编辑或关闭窗口", + "type": [ + "gird_view_shortcuts" + ] }, - "kazakhstan": { - "phoneCode": "7" + { + "show": true, + "key": "shift+enter", + "winKey": "shift+enter", + "name": [ + "insert_record_below" + ], + "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding && recordEditable", + "id": "shift+enter", + "command": "AppendRow", + "description": "向下插入行", + "type": [ + "gird_view_shortcuts" + ] }, - "kenya": { - "phoneCode": "254" + { + "show": true, + "key": "cmd+shift+enter", + "winKey": "ctrl+shift+enter", + "name": [ + "insert_record_above" + ], + "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding && recordEditable", + "id": "cmd+shift+enter", + "command": "PrependRow", + "description": "向上插入行", + "type": [ + "gird_view_shortcuts" + ] }, - "kiribati": { - "phoneCode": "686" + { + "show": true, + "key": "enter", + "winKey": "enter", + "name": [ + "edit_cell_data" + ], + "when": "isFocusing && !isRecordExpanding", + "id": "enter", + "command": "ToggleNextEditing", + "description": "激活单元格编辑状态", + "type": [ + "gird_view_shortcuts" + ] }, - "kuwait": { - "phoneCode": "965" + { + "show": true, + "key": "F2", + "winKey": "F2", + "name": [ + "edit_cell_data" + ], + "when": "isFocusing && !isRecordExpanding", + "id": "F2", + "command": "ToggleNextEditing", + "description": "激活单元格编辑状态", + "type": [ + "gird_view_shortcuts" + ] }, - "kyrgyzstan": { - "phoneCode": "996" + { + "show": true, + "key": "backspace", + "winKey": "backspace", + "name": [ + "clear_record" + ], + "when": "!isGlobalEditing && !isRecordExpanding", + "id": "backspace", + "command": "Clear", + "description": "清除单元格内容", + "type": [ + "gird_view_shortcuts" + ] }, - "laos": { - "phoneCode": "856" + { + "show": true, + "key": "delete", + "winKey": "delete", + "name": [ + "clear_record" + ], + "when": "!isGlobalEditing && !isRecordExpanding", + "id": "delete", + "command": "Clear", + "description": "清除单元格内容", + "type": [ + "gird_view_shortcuts" + ] }, - "latvia": { - "phoneCode": "371" + { + "show": true, + "key": "tab", + "winKey": "tab", + "name": [ + "finish_editing_cell_right" + ], + "when": "(isEditing || hasActiveCell) && !isRecordExpanding && !isMenuOpening", + "id": "tab", + "command": "CellTab", + "description": "完成编辑并向右一个单元格", + "type": [ + "gird_view_shortcuts" + ] }, - "lebanon": { - "phoneCode": "961" + { + "show": true, + "key": "shift+tab", + "winKey": "shift+tab", + "name": [ + "finish_editing_cell_left" + ], + "when": "(isEditing || hasActiveCell) && !isRecordExpanding&& !isMenuOpening", + "id": "shift+tab", + "command": "CellShiftTab", + "description": "完成编辑并向左一个单元格", + "type": [ + "gird_view_shortcuts" + ] }, - "lesotho": { - "phoneCode": "266" + { + "show": true, + "key": "up", + "winKey": "up", + "name": [ + "up" + ], + "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening && !modalVisible", + "id": "up", + "command": "CellUp", + "description": "向上移动一个单元格", + "type": [ + "gird_view_shortcuts" + ] }, - "liberia": { - "phoneCode": "231" + { + "show": true, + "key": "down", + "winKey": "down", + "name": [ + "down" + ], + "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening && !modalVisible", + "id": "down", + "command": "CellDown", + "description": "向下移动一个单元格", + "type": [ + "gird_view_shortcuts" + ] }, - "libya": { - "phoneCode": "218" + { + "show": true, + "key": "left", + "winKey": "left", + "name": [ + "left" + ], + "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding && !isMenuOpening && !modalVisible", + "id": "left", + "command": "CellLeft", + "description": "向左移动一个单元格", + "type": [ + "gird_view_shortcuts" + ] }, - "liechtenstein": { - "phoneCode": "423" + { + "show": true, + "key": "right", + "winKey": "right", + "name": [ + "right" + ], + "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening && !modalVisible", + "id": "right", + "command": "CellRight", + "description": "向右移动一个单元格", + "type": [ + "gird_view_shortcuts" + ] }, - "lithuania": { - "phoneCode": "370" + { + "show": true, + "key": "cmd+up", + "winKey": "ctrl+up", + "name": [ + "cell_to_up_edge" + ], + "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", + "id": "cmd+up", + "command": "CellUpEdge", + "description": "移动到顶部单元格", + "type": [ + "gird_view_shortcuts" + ] }, - "luxembourg": { - "phoneCode": "352" + { + "show": true, + "key": "cmd+down", + "winKey": "ctrl+down", + "name": [ + "cell_to_down_edge" + ], + "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", + "id": "cmd+down", + "command": "CellDownEdge", + "description": "移动到底部单元格", + "type": [ + "gird_view_shortcuts" + ] }, - "macau": { - "phoneCode": "853" + { + "show": true, + "key": "cmd+left", + "winKey": "ctrl+left", + "name": [ + "cell_to_left_edge" + ], + "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", + "id": "cmd+left", + "command": "CellLeftEdge", + "description": "移动到最左侧单元格", + "type": [ + "gird_view_shortcuts" + ] }, - "macedonia": { - "phoneCode": "389" + { + "show": true, + "key": "cmd+right", + "winKey": "ctrl+right", + "name": [ + "cell_to_right_edge" + ], + "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", + "id": "cmd+right", + "command": "CellRightEdge", + "description": "移动到最右侧单元格", + "type": [ + "gird_view_shortcuts" + ] }, - "madagascar": { - "phoneCode": "261" + { + "show": true, + "key": "fn+↑", + "winKey": "fn+↑", + "name": [ + "scroll_screen_up" + ], + "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", + "id": "fn+↑", + "command": "None", + "description": "向上滚动一屏", + "type": [ + "gird_view_shortcuts" + ] }, - "malawi": { - "phoneCode": "265" + { + "show": true, + "key": "pageup", + "winKey": "pageup", + "name": [ + "scroll_screen_up" + ], + "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", + "id": "pageup", + "command": "PageUp", + "description": "向上滚动一屏", + "type": [ + "gird_view_shortcuts" + ] }, - "malaysia": { - "phoneCode": "60" + { + "show": true, + "key": "fn+↓", + "winKey": "fn+↓", + "name": [ + "scroll_screen_down" + ], + "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", + "id": "fn+↓", + "command": "None", + "description": "向下滚动一屏", + "type": [ + "gird_view_shortcuts" + ] }, - "maldives": { - "phoneCode": "960" + { + "show": true, + "key": "pagedown", + "winKey": "pagedown", + "name": [ + "scroll_screen_down" + ], + "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", + "id": "pagedown", + "command": "PageDown", + "description": "向下滚动一屏", + "type": [ + "gird_view_shortcuts" + ] }, - "mali": { - "phoneCode": "223" + { + "show": true, + "key": "fn+←", + "winKey": "fn+←", + "name": [ + "scroll_screen_left" + ], + "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", + "id": "fn+←", + "command": "None", + "description": "向左滚动一屏", + "type": [ + "gird_view_shortcuts" + ] }, - "malta": { - "phoneCode": "356" + { + "show": true, + "key": "home", + "winKey": "home", + "name": [ + "scroll_screen_left" + ], + "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", + "id": "home", + "command": "PageLeft", + "description": "向左滚动一屏", + "type": [ + "gird_view_shortcuts" + ] }, - "martinique": { - "phoneCode": "596" + { + "show": true, + "key": "fn+→", + "winKey": "fn+→", + "name": [ + "scroll_screen_right" + ], + "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", + "id": "fn+→", + "command": "None", + "description": "向右滚动一屏", + "type": [ + "gird_view_shortcuts" + ] }, - "mauritania": { - "phoneCode": "222" + { + "show": true, + "key": "end", + "winKey": "end", + "name": [ + "scroll_screen_right" + ], + "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", + "id": "end", + "command": "PageRight", + "description": "向右滚动一屏", + "type": [ + "gird_view_shortcuts" + ] }, - "mauritius": { - "phoneCode": "230" + { + "show": true, + "key": "cmd+a", + "winKey": "ctrl+a", + "name": [ + "select_all" + ], + "when": "!isGlobalEditing && !isRecordExpanding", + "id": "cmd+a", + "command": "SelectionAll", + "description": "全选", + "type": [ + "gird_view_shortcuts" + ] }, - "mayotte": { - "phoneCode": "269" - }, - "mexico": { - "phoneCode": "52" + { + "show": true, + "key": "shift+up", + "winKey": "shift+up", + "name": [ + "selection_to_up" + ], + "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", + "id": "shift+up", + "command": "SelectionUp", + "description": "单元格选区向上", + "type": [ + "gird_view_shortcuts" + ] }, - "moldova": { - "phoneCode": "373" + { + "show": true, + "key": "shift+down", + "winKey": "shift+down", + "name": [ + "selection_to_down" + ], + "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", + "id": "shift+down", + "command": "SelectionDown", + "description": "单元格选区向下", + "type": [ + "gird_view_shortcuts" + ] }, - "monaco": { - "phoneCode": "377" + { + "show": true, + "key": "shift+left", + "winKey": "shift+left", + "name": [ + "selection_to_left" + ], + "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", + "id": "shift+left", + "command": "SelectionLeft", + "description": "单元格选区向左", + "type": [ + "gird_view_shortcuts" + ] }, - "mongolia": { - "phoneCode": "976" + { + "show": true, + "key": "shift+right", + "winKey": "shift+right", + "name": [ + "selection_to_right" + ], + "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", + "id": "shift+right", + "command": "SelectionRight", + "description": "单元格选区向右", + "type": [ + "gird_view_shortcuts" + ] }, - "montenegro": { - "phoneCode": "382" + { + "show": true, + "key": "cmd+shift+up", + "winKey": "ctrl+shift+up", + "name": [ + "selection_to_up_edge" + ], + "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", + "id": "cmd+shift+up", + "command": "SelectionUpEdge", + "description": "单元格选区向上至顶部", + "type": [ + "gird_view_shortcuts" + ] }, - "montserrat": { - "phoneCode": "1664" + { + "show": true, + "key": "cmd+shift+down", + "winKey": "ctrl+shift+down", + "name": [ + "selection_to_down_edge" + ], + "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", + "id": "cmd+shift+down", + "command": "SelectionDownEdge", + "description": "单元格选区向下至底部", + "type": [ + "gird_view_shortcuts" + ] }, - "morocco": { - "phoneCode": "212" + { + "show": true, + "key": "cmd+shift+left", + "winKey": "ctrl+shift+left", + "name": [ + "selection_to_left_edge" + ], + "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", + "id": "cmd+shift+left", + "command": "SelectionLeftEdge", + "description": "单元格选区向左到边缘", + "type": [ + "gird_view_shortcuts" + ] }, - "mozambique": { - "phoneCode": "258" + { + "show": true, + "key": "cmd+shift+right", + "winKey": "ctrl+shift+right", + "name": [ + "selection_to_right_edge" + ], + "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", + "id": "cmd+shift+right", + "command": "SelectionRightEdge", + "description": "单元格选区向右至边缘", + "type": [ + "gird_view_shortcuts" + ] }, - "myanmar": { - "phoneCode": "95" + { + "show": true, + "key": "fn+↑", + "winKey": "fn+↑", + "name": [ + "scroll_screen_up" + ], + "when": "!isRecordExpanding", + "id": "fn+↑", + "command": "None", + "description": "向上滚动一屏", + "type": [ + "gallery_view_shortcuts" + ] }, - "namibia": { - "phoneCode": "264" + { + "show": true, + "key": "pageup", + "winKey": "pageup", + "name": [ + "scroll_screen_up" + ], + "when": "!isRecordExpanding", + "id": "pageup", + "command": "PageUp", + "description": "向上滚动一屏", + "type": [ + "gallery_view_shortcuts" + ] }, - "nepal": { - "phoneCode": "977" + { + "show": true, + "key": "fn+↓", + "winKey": "fn+↓", + "name": [ + "scroll_screen_down" + ], + "when": "!isRecordExpanding", + "id": "fn+↓", + "command": "None", + "description": "向下滚动一屏", + "type": [ + "gallery_view_shortcuts" + ] }, - "netherlands": { - "phoneCode": "31" + { + "show": true, + "key": "pagedown", + "winKey": "pagedown", + "name": [ + "scroll_screen_down" + ], + "when": "!isRecordExpanding", + "id": "pagedown", + "command": "PageDown", + "description": "向下滚动一屏", + "type": [ + "gallery_view_shortcuts" + ] }, - "new_caledonia": { - "phoneCode": "687" + { + "show": true, + "key": "cmd+up", + "winKey": "ctrl+up", + "name": [ + "page_to_up_edge" + ], + "when": "!isRecordExpanding", + "id": "cmd+up", + "command": "PageUpEdge", + "description": "滚动到页面顶部", + "type": [ + "gallery_view_shortcuts" + ] }, - "new_zealand": { - "phoneCode": "64" + { + "show": true, + "key": "cmd+down", + "winKey": "ctrl+down", + "name": [ + "page_to_down_edge" + ], + "when": "!isRecordExpanding", + "id": "cmd+down", + "command": "PageDownEdge", + "description": "滚动到页面底部", + "type": [ + "gallery_view_shortcuts" + ] }, - "nicaragua": { - "phoneCode": "505" + { + "key": "cmd+s", + "winKey": "ctrl+s", + "name": [ + "toast_ctrl_s" + ], + "when": "true", + "id": "cmd+s", + "command": "ToastForSave", + "description": "你的修改数据会实时保存到云端,无需手动保存", + "type": [ + "gallery_view_shortcuts" + ] }, - "niger": { - "phoneCode": "227" + { + "show": true, + "key": "cmd+k", + "winKey": "ctrl+k", + "name": [ + "open_quickgo_panel" + ], + "when": "!isRecordExpanding", + "id": "cmd+k", + "command": "SearchNode", + "description": "打开工作台的搜索栏", + "type": [ + "workbenck_shortcuts" + ] }, - "nigeria": { - "phoneCode": "234" + { + "show": true, + "key": "ctrl+n", + "winKey": "alt+n", + "name": [ + "new_datasheet" + ], + "when": "!isRecordExpanding", + "id": "ctrl+n", + "command": "NewDatasheet", + "description": "新建维格表", + "type": [ + "workbenck_shortcuts" + ] }, - "norway": { - "phoneCode": "47" + { + "show": true, + "key": "ctrl+shift+n", + "winKey": "alt+shift+n", + "name": [ + "new_folder" + ], + "when": "!isRecordExpanding", + "id": "ctrl+shift+n", + "command": "NewFolder", + "description": "新建文件夹", + "type": [ + "workbenck_shortcuts" + ] }, - "oman": { - "phoneCode": "968" + { + "show": true, + "key": "f2", + "winKey": "f2 ", + "name": [ + "rename" + ], + "when": "!isRecordExpanding", + "id": "f2", + "command": "RenameNode", + "description": "重命名", + "type": [ + "workbenck_shortcuts" + ] }, - "pakistan": { - "phoneCode": "92" + { + "show": true, + "key": "ctrl+s", + "winKey": "alt+s", + "name": [ + "share" + ], + "when": "!isRecordExpanding", + "id": "ctrl+s", + "command": "Share", + "description": "分享", + "type": [ + "workbenck_shortcuts" + ] }, - "palau": { - "phoneCode": "680" + { + "show": true, + "key": "ctrl+p", + "winKey": "alt+p", + "name": [ + "permission_setting" + ], + "when": "!isRecordExpanding", + "id": "ctrl+p", + "command": "Permission", + "description": "设置权限", + "type": [ + "workbenck_shortcuts" + ] }, - "palestine": { - "phoneCode": "970" + { + "show": true, + "key": "cmd+shift+s", + "winKey": "ctrl+shift+s", + "name": [ + "backup_create" + ], + "when": "!isRecordExpanding", + "id": "cmd+shift+S", + "command": "CreateBackup", + "description": "创建历史备份", + "type": [ + "workbenck_shortcuts" + ] }, - "panama": { - "phoneCode": "507" + { + "show": true, + "key": "ctrl+t", + "winKey": "alt+t", + "name": [ + "save_as_template" + ], + "when": "!isRecordExpanding", + "id": "ctrl+t", + "command": "SaveAsTemplate", + "description": "保存为模板", + "type": [ + "workbenck_shortcuts" + ] }, - "papua_new_guinea": { - "phoneCode": "675" + { + "show": true, + "key": "cmd+b", + "winKey": "ctrl+b", + "name": [ + "toggle_catalog_panel" + ], + "when": "!isRecordExpanding && !modalVisible", + "id": "cmd+b", + "command": "ToggleCatalogPanel", + "description": "展开折叠目录面板", + "type": [ + "workbenck_shortcuts" + ] }, - "paraguay": { - "phoneCode": "595" + { + "key": "space", + "winKey": "space", + "when": "!isGlobalEditing && isRecordExpanding && !isEditing", + "id": "space", + "command": "CloseExpandRecord" }, - "peru": { - "phoneCode": "51" + { + "key": "shift+tab", + "winKey": "shift+tab", + "when": "isRecordExpanding", + "id": "shift+tab", + "command": "RecordShiftTab" }, - "philippines": { - "phoneCode": "63" + { + "key": "tab", + "winKey": "tab", + "when": "isRecordExpanding", + "id": "tab", + "command": "RecordTab" }, - "poland": { - "phoneCode": "48" + { + "show": true, + "key": "cmd+shift+o", + "winKey": "ctrl+shift+o", + "name": [ + "toggle_widget_panel" + ], + "when": "!isRecordExpanding", + "id": "cmd+shift+o", + "command": "ToggleWidgetPanel", + "description": "展开小程序", + "type": [ + "global_shortcuts" + ] }, - "portugal": { - "phoneCode": "351" + { + "key": "cmd+shift+d", + "winKey": "ctrl+shift+d", + "when": "!isRecordExpanding", + "id": "cmd+shift+d", + "command": "ToggleDevPanel" }, - "puerto_rico": { - "phoneCode": "1787" + { + "key": "cmd+alt+d", + "winKey": "ctrl+alt+d", + "when": "!isRecordExpanding", + "id": "cmd+alt+d", + "command": "ToggleDevPanel" }, - "qatar": { - "phoneCode": "974" + { + "key": "up", + "winKey": "up", + "when": "isQuickSearchExpanding", + "id": "up", + "command": "QuickSearchUp" }, - "republic_of_the_congo": { - "phoneCode": "242" + { + "key": "down", + "winKey": "down", + "when": "isQuickSearchExpanding", + "id": "down", + "command": "QuickSearchDown" }, - "reunion_island": { - "phoneCode": "262" + { + "key": "tab", + "winKey": "tab", + "when": "isQuickSearchExpanding", + "id": "tab", + "command": "QuickSearchTab" }, - "romania": { - "phoneCode": "40" + { + "key": "enter", + "winKey": "enter", + "when": "isQuickSearchExpanding", + "id": "enter", + "command": "QuickSearchEnter" + } + ], + "country_code_and_phone_code": { + "china": { + "phoneCode": "86" }, - "russia": { - "phoneCode": "7" + "hong_kong": { + "phoneCode": "852" }, - "rwanda": { - "phoneCode": "250" + "macau": { + "phoneCode": "853" }, - "saint_kitts_and_nevis": { - "phoneCode": "1869" + "taiwan": { + "phoneCode": "886" }, - "saint_lucia": { - "phoneCode": "1758" + "albania": { + "phoneCode": "355" }, - "saint_maarten_dutch_part": { - "phoneCode": "1721" + "algeria": { + "phoneCode": "213" }, - "saint_pierre_and_miquelon": { - "phoneCode": "508" + "afghanistan": { + "phoneCode": "93" }, - "saint_vincent_and_the_grenadines": { - "phoneCode": "1784" + "argentina": { + "phoneCode": "54" }, - "samoa": { - "phoneCode": "685" + "united_arab_emirates": { + "phoneCode": "971" }, - "san_marino": { - "phoneCode": "378" + "aruba": { + "phoneCode": "297" }, - "sao_tome_and_principe": { - "phoneCode": "239" + "oman": { + "phoneCode": "968" }, - "saudi_arabia": { - "phoneCode": "966" + "azerbaijan": { + "phoneCode": "994" }, - "senegal": { - "phoneCode": "221" + "egypt": { + "phoneCode": "20" }, - "serbia": { - "phoneCode": "381" + "ethiopia": { + "phoneCode": "251" }, - "seychelles": { - "phoneCode": "248" + "ireland": { + "phoneCode": "353" }, - "sierra_leone": { - "phoneCode": "232" + "estonia": { + "phoneCode": "372" }, - "singapore": { - "phoneCode": "65" + "andorra": { + "phoneCode": "376" }, - "slovakia": { - "phoneCode": "421" + "angola": { + "phoneCode": "244" }, - "slovenia": { - "phoneCode": "386" + "anguilla": { + "phoneCode": "1264" }, - "solomon_islands": { - "phoneCode": "677" + "antigua_and_barbuda": { + "phoneCode": "1268" }, - "somalia": { - "phoneCode": "252" + "austria": { + "phoneCode": "43" }, - "south_africa": { - "phoneCode": "27" + "australia": { + "phoneCode": "61" }, - "south_korea": { - "phoneCode": "82" + "barbados": { + "phoneCode": "1246" }, - "spain": { - "phoneCode": "34" + "papua_new_guinea": { + "phoneCode": "675" }, - "sri_lanka": { - "phoneCode": "94" + "bahamas": { + "phoneCode": "1242" }, - "sudan": { - "phoneCode": "249" + "pakistan": { + "phoneCode": "92" }, - "suriname": { - "phoneCode": "597" + "paraguay": { + "phoneCode": "595" }, - "swaziland": { - "phoneCode": "268" + "palestine": { + "phoneCode": "970" }, - "sweden": { - "phoneCode": "46" + "bahrain": { + "phoneCode": "973" }, - "switzerland": { - "phoneCode": "41" + "panama": { + "phoneCode": "507" }, - "syria": { - "phoneCode": "963" + "brazil": { + "phoneCode": "55" }, - "taiwan": { - "phoneCode": "886" + "belarus": { + "phoneCode": "375" }, - "tajikistan": { - "phoneCode": "992" + "bermuda": { + "phoneCode": "1441" }, - "tanzania": { - "phoneCode": "255" + "bulgaria": { + "phoneCode": "359" }, - "thailand": { - "phoneCode": "66" + "benin": { + "phoneCode": "229" + }, + "belgium": { + "phoneCode": "32" + }, + "iceland": { + "phoneCode": "354" + }, + "puerto_rico": { + "phoneCode": "1787" + }, + "poland": { + "phoneCode": "48" + }, + "bosnia_and_herzegovina": { + "phoneCode": "387" + }, + "bolivia": { + "phoneCode": "591" + }, + "belize": { + "phoneCode": "501" + }, + "botswana": { + "phoneCode": "267" + }, + "bhutan": { + "phoneCode": "975" + }, + "burkina_faso": { + "phoneCode": "226" + }, + "burundi": { + "phoneCode": "257" + }, + "equatorial_guinea": { + "phoneCode": "240" + }, + "denmark": { + "phoneCode": "45" + }, + "germany": { + "phoneCode": "49" }, "timor_leste": { "phoneCode": "670" @@ -1138,6673 +1723,6186 @@ "togo": { "phoneCode": "228" }, - "tonga": { - "phoneCode": "676" + "dominica": { + "phoneCode": "1767" }, - "trinidad_and_tobago": { - "phoneCode": "1868" + "dominican_republic": { + "phoneCode": "1809" }, - "tunisia": { - "phoneCode": "216" + "russia": { + "phoneCode": "7" }, - "turkey": { - "phoneCode": "90" + "ecuador": { + "phoneCode": "593" }, - "turkmenistan": { - "phoneCode": "993" + "eritrea": { + "phoneCode": "291" }, - "turks_and_caicos_islands": { - "phoneCode": "1649" + "france": { + "phoneCode": "33" }, - "uganda": { - "phoneCode": "256" + "faroe_islands": { + "phoneCode": "298" }, - "ukraine": { - "phoneCode": "380" + "french_polynesia": { + "phoneCode": "689" }, - "united_arab_emirates": { - "phoneCode": "971" + "french_guiana": { + "phoneCode": "594" }, - "united_kingdom": { - "phoneCode": "44" + "philippines": { + "phoneCode": "63" }, - "united_states": { - "phoneCode": "1" + "fiji": { + "phoneCode": "679" }, - "uruguay": { - "phoneCode": "598" + "finland": { + "phoneCode": "358" }, - "uzbekistan": { - "phoneCode": "998" + "gambia": { + "phoneCode": "220" }, - "vanuatu": { - "phoneCode": "678" + "republic_of_the_congo": { + "phoneCode": "242" }, - "venezuela": { - "phoneCode": "58" + "democratic_republic_of_the_congo": { + "phoneCode": "243" }, - "vietnam": { - "phoneCode": "84" + "colombia": { + "phoneCode": "57" }, - "virgin_islands_british": { - "phoneCode": "1340" + "costa_rica": { + "phoneCode": "506" }, - "virgin_islands_us": { - "phoneCode": "1284" + "grenada": { + "phoneCode": "1473" }, - "yemen": { - "phoneCode": "967" + "greenland": { + "phoneCode": "299" }, - "zambia": { - "phoneCode": "260" + "georgia": { + "phoneCode": "995" }, - "zimbabwe": { - "phoneCode": "263" - } - }, - "environment": { - "integration": { - "env": "integration" + "cuba": { + "phoneCode": "53" }, - "production": { - "env": "production" + "guadeloupe": { + "phoneCode": "590" }, - "staging": { - "env": "staging" - } - }, - "guide": { - "step": { - "1": { - "backdrop": "around_mask", - "next": "确定", - "nextId": "confirm", - "onClose": [ - "skip_current_wizard()" - ], - "onNext": [ - "skip_all_wizards()" - ], - "onPlay": [ - "clear_guide_all_ui()" - ], - "onPrev": [ - "clear_guide_all_ui()" - ], - "onSkip": [ - "clear_guide_all_ui()" - ], - "onTarget": [ - "skip_current_wizard({\"curWizardCompleted\": true})" - ], - "prev": "-", - "uiConfig": "{}", - "uiConfigId": "player_step_ui_config_1", - "uiType": "notice" - }, - "2": { - "backdrop": "around_mask", - "next": "确定", - "nextId": "confirm", - "onClose": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"config\": [\n {\n \"key\": 1,\n \"name\": \"answer1\",\n \"title\": \"您希望通过维格表解决哪些问题?\",\n \"type\": \"checkbox\",\n \"answers\": [\n \"工作规划\",\n \"客户服务\",\n \"项目管理\",\n \"采购供应\",\n \"内容生产\",\n \"电商运营\",\n \"活动策划\",\n \"人力资源\",\n \"行政管理\",\n \"财务管理\",\n \"网络直播\",\n \"高校管理\",\n \"其它\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 2,\n \"name\": \"answer2\",\n \"title\": \"您的工作岗位是?\",\n \"type\": \"radio\",\n \"answers\": [\n \"管理者\",\n \"项目经理\",\n \"产品经理\",\n \"设计师\",\n \"研发、工程师\",\n \"运营、编辑\",\n \"销售、客服\",\n \"人事、行政\",\n \"财务、会计\",\n \"律师、法务\",\n \"市场\",\n \"教师\",\n \"学生\",\n \"其它\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 3,\n \"name\": \"answer3\",\n \"title\": \"您的公司名称是?\",\n \"type\": \"input\",\n \"submit\": false\n },\n {\n \"key\": 4,\n \"name\": \"answer4\",\n \"title\": \"请留下你的邮箱/手机/微信号,以便我们及时提供帮助。\",\n \"type\": \"input\",\n \"submit\": true\n },\n {\n \"key\": 5,\n \"title\": \"感谢你的填写,请加一下客服号以备不时之需\",\n \"platform\": {\n \"website\": \"https://s1.vika.cn/space/2023/03/02/b34e3205a9154463be16f497524f1327\",\n \"dingtalk\": \"https://s1.vika.cn/space/2023/03/02/4b16cef6602a4586a21d6346bf25d300\",\n \"wecom\": \"https://s1.vika.cn/space/2023/03/02/60119b1b69b64aa887bd1be6a2928bec\",\n \"feishu\": \"https://u.vika.cn/z9ygm\"\n },\n \"type\": \"contactUs\",\n \"next\": true\n }\n ]\n}\n", - "uiConfigId": "player_step_ui_config_2", - "uiType": "questionnaire" - }, - "3": { - "next": "确定", - "nextId": "confirm", - "onClose": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"title\": \"更新公告\",\n \"children\": \"

✨ Hello, 星球居民们~

伴随12月的前奏,维格星球又迎来了一波更新,动动手指探索下最新的资源吧 🎉

🎊 播报 News

  • 手机端支持编辑啦,现在你可以直接在手机上探索维格表
  • 维格表API 增加Golang语言的SDK
  • 新增记录的「动态评论」,你和小伙伴可以在维格表内展开深入的讨论
  • 「空间站管理-普通成员」页面新增全局开关,可以控制是否在分享页面展示「申请加入空间站」的入口

🍜 优化 Enhancement

  • 分享模态窗改版,可以更清晰地选择自己的协作方式
  • 权限模态窗改版,设置权限变成独立的页面
  • 看板视图可以在卡片上切换封面图片,高清无码大图如此性感
  • 单选/多选/成员的选项列表支持键盘快捷键上下选择选项,解放互联网冲浪达人的双手
\"\n }", - "uiConfigId": "player_step_ui_config_3", - "uiType": "notice" - }, - "4": { - "onClose": [ - "open_guide_next_step({\"clearAllPrevUi\":true})", - "open_vikaby({\n\"visible\":true,\n\"defaultExpandTodo\": true,\n\"defaultExpandMenu\": false\n})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onPlay": [ - "set_wizard_completed({\"curWizard\": true})" - ], - "uiConfig": "{\n\"title\":\"什么是维格表\",\n\"video\":\"space/2022/02/21/94cb82f9ffd84a5499c8931a224ad234\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_1\",\n\"autoPlay\":true\n}", - "uiConfigId": "player_step_ui_config_4", - "uiType": "modal" - }, - "5": { - "onClose": [ - "open_guide_next_step({\"clearAllPrevUi\":true})", - "open_vikaby({\n\"visible\":true,\n\"defaultExpandTodo\": true,\n\"defaultExpandMenu\": false\n})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onPlay": [ - "set_wizard_completed({\"curWizard\": true})" - ], - "uiConfig": "{\n\"title\":\"一分钟快速入门\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}\n", - "uiConfigId": "player_step_ui_config_5", - "uiType": "modal" - }, - "6": { - "onClose": [ - "open_guide_next_step({\"clearAllPrevUi\":true})", - "open_vikaby({\n\"visible\":true,\n\"defaultExpandTodo\": true,\n\"defaultExpandMenu\": false\n})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onPlay": [ - "set_wizard_completed({\"curWizard\": true})" - ], - "uiConfig": "{\n\"title\":\"玩转一张维格表\",\n\"video\":\"space/2020/12/21/cb7bdf6fe22146068111d46915587fb2\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_3\",\n\"autoPlay\":true\n}", - "uiConfigId": "player_step_ui_config_6", - "uiType": "modal" - }, - "7": { - "onClose": [ - "open_guide_next_step({\"clearAllPrevUi\":true})", - "open_vikaby({\n\"visible\":true,\n\"defaultExpandTodo\": true,\n\"defaultExpandMenu\": false\n})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onPlay": [ - "set_wizard_completed({\"curWizard\": true})" - ], - "uiConfig": "{\n\"title\":\"分享和邀请成员\",\n\"video\":\"space/2020/12/21/b8fa92ba4c7d41c6acbd7f24469e15fc\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_4\",\n\"autoPlay\":true\n}", - "uiConfigId": "player_step_ui_config_7", - "uiType": "modal" - }, - "8": { - "onNext": [ - "clear_guide_uis([\"popover\"])" - ], - "onSkip": [ - "skip_current_wizard({\"curWizardCompleted\": true})" - ], - "uiConfig": "{\n \"element\": \"#ADDRESS_INVITE_BTN\", \n\"placement\": \"bottomLeft\",\n \"title\": \"邀请方式\", \n\"description\": \"当前空间站支持链接、邮箱、导入三种方式邀请成员\", \"children\":\"\" \n} ", - "uiConfigId": "player_step_ui_config_8", - "uiType": "popover" - }, - "9": { - "backdrop": "around_mask", - "onTarget": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \"#ADDRESS_INVITE_BTN\"\n} ", - "uiConfigId": "player_step_ui_config_9", - "uiType": "breath" - }, - "10": { - "onNext": [ - "clear_guide_uis([\"popover\"])" - ], - "onSkip": [ - "skip_current_wizard({\"curWizardCompleted\": true})" - ], - "uiConfig": "{\n \"element\": \".style_linkWrapper__12Kgi .style_urlWrapper__2IVlG button\", \n\"placement\": \"bottomRight\",\n \"title\": \"复制并分享\",\n\"description\": \"点击复制链接并分享给成员,即可完成邀请\", \"children\":\"\" \n} ", - "uiConfigId": "player_step_ui_config_10", - "uiType": "popover" - }, - "11": { - "backdrop": "around_mask", - "onTarget": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\"element\": \".style_linkWrapper__12Kgi .style_urlWrapper__2IVlG button\",\n\"shadowDirection\": \"none\"} ", - "uiConfigId": "player_step_ui_config_11", - "uiType": "breath" - }, - "12": { - "backdrop": "around_mask", - "onNext": [ - "clear_guide_uis([\"popover\"])" - ], - "onSkip": [ - "skip_current_wizard({\"curWizardCompleted\": true})" - ], - "uiConfig": "{\n \"element\": \".style_addNewLink__3ALup>button\", \n\"placement\": \"bottomRight\",\n \"title\": \"创建邀请链接\", \n\"description\": \"创建链接邀请成员加入空间站或站内指定小组\", \"children\":\"\" \n} ", - "uiConfigId": "player_step_ui_config_12", - "uiType": "popover" - }, - "13": { - "onTarget": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \".style_addNewLink__3ALup>button\"\n} ", - "uiConfigId": "player_step_ui_config_13", - "uiType": "breath" - }, - "14": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "clear_guide_all_ui()", - "open_guide_next_step()" - ], - "onSkip": [ - "skip_current_wizard({\"curWizardCompleted\": true})" - ], - "skip": "不用了,谢谢", - "skipId": "no_and_thanks", - "uiConfig": "{\n \"placement\": \"bottomRight\",\n \"description\": \"欢迎来到维格模板中心,这里有丰富的模板,让我来给你介绍一下如何使用一个模板吧\"\n}", - "uiConfigId": "player_step_ui_config_14", - "uiType": "slideout" - }, - "15": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "clear_guide_uis([\"popover\"])" - ], - "onSkip": [ - "skip_current_wizard({\"curWizardCompleted\": true})" - ], - "skip": "跳过", - "skipId": "skip", - "uiConfig": "{\n \"element\": \".style_templateItem__1UDe0\", \n\"placement\": \"bottom\",\n \"title\": \"使用模板教程\", \n\"description\": \"我们先选择一个模板,点击进入它的预览页\", \"children\":\"\" \n}\n", - "uiConfigId": "player_step_ui_config_15", - "uiType": "popover" - }, - "16": { - "backdrop": "around_mask", - "onTarget": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \".style_templateItem__1UDe0\"\n}\n", - "uiConfigId": "player_step_ui_config_16", - "uiType": "breath" - }, - "17": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "clear_guide_uis([\"popover\"])" - ], - "onSkip": [ - "skip_current_wizard({\"curWizardCompleted\": true})" - ], - "onTarget": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "skip": "跳过", - "skipId": "skip", - "uiConfig": "{\n \"element\": \"#TEMPLATE_CENTER_USE_TEMPLATE_BTN>button\", \n\"placement\": \"rightBottom\",\n\"offsetY\": 20,\n \"title\": \"使用模板教程\", \n\"description\": \"点击左侧按钮使用模板\", \"children\":\"\" \n}", - "uiConfigId": "player_step_ui_config_17", - "uiType": "popover" - }, - "18": { - "next": "下一步", - "nextId": "next_step", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onSkip": [ - "skip_current_wizard({\"curWizardCompleted\": true})" - ], - "skip": "跳过", - "skipId": "skip", - "uiConfig": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select>.ant-select-selector\", \n\"placement\": \"bottomLeft\",\n \"title\": \"使用模板教程\", \n\"description\": \"选择模板要存放的位置\", \"children\":\"\" \n}", - "uiConfigId": "player_step_ui_config_18", - "uiType": "popover" - }, - "19": { - "onTarget": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select .ant-select-selector\"\n}", - "uiConfigId": "player_step_ui_config_19", - "uiType": "breath" - }, - "20": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "clear_guide_uis([\"popover\"])" - ], - "onSkip": [ - "skip_current_wizard({\"curWizardCompleted\": true})" - ], - "onTarget": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "skip": "跳过", - "skipId": "skip", - "uiConfig": "{\n \"element\": \"#TEMPLATE_CENTER_CONFIRM_BTN_IN_TEMPLATE_MODAL\", \n\"placement\": \"bottomLeft\",\n \"title\": \"使用模板教程\", \n\"description\": \"在确定了要存放的位置后,点击确定,模板才会使用生效哦\", \"children\":\"\" \n}", - "uiConfigId": "player_step_ui_config_20", - "uiType": "popover" - }, - "21": { - "onTarget": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \"#TEMPLATE_CENTER_CONFIRM_BTN_IN_TEMPLATE_MODAL\" \n}", - "uiConfigId": "player_step_ui_config_21", - "uiType": "breath" - }, - "22": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "open_guide_next_step()" - ], - "onSkip": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"placement\": \"bottomLeft\",\n \"description\": \"恭喜你学会了如何使用一个模板,维格表还有更多功能等待你的探索哦~\"\n}", - "uiConfigId": "player_step_ui_config_22", - "uiType": "slideout" - }, - "23": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "clear_guide_all_ui()" - ], - "uiConfig": "{\n \"element\": \".style_searchPanelContainer__1_iOe\", \n\"placement\": \"leftTop\",\n \"title\": \"如何生成神奇表单\", \n\"description\": \"首先,需要选择一张维格表来存放收集的数据\", \"children\":\"\" \n}", - "uiConfigId": "player_step_ui_config_23", - "uiType": "popover" - }, - "24": { - "byEvent": [ - "workbench_create_form_previewer_shown" - ], - "next": "好的", - "nextId": "okay", - "onNext": [ - "clear_guide_all_ui()" - ], - "onTarget": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \".style_formPreviewer__2Au6g\", \n\"placement\": \"leftTop\",\n \"title\": \"如何生成神奇表单\", \n\"description\": \"神奇表单的字段数量以及顺序,会与所选视图的配置保持一致。基于你选择的视图,右侧为自动生成的预览效果。\", \"children\":\"\" \n}", - "uiConfigId": "player_step_ui_config_24", - "uiType": "popover" - }, - "25": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "clear_guide_all_ui()" - ], - "uiConfig": "{\n \"element\": \"#WORKBENCH_SIDE_FORM_USE_GUIDE_BTN\", \n\"placement\": \"bottomRight\",\n \"title\": \"收集表教程\", \n\"description\": \"如果需要更加详细的收集表教程,可以点击上方的入口查看哦\", \"children\":\"\" \n}", - "uiConfigId": "player_step_ui_config_25", - "uiType": "popover" - }, - "26": { - "onNext": [ - "clear_guide_uis([\"popover\"])" - ], - "onSkip": [ - "skip_current_wizard()" - ], - "uiConfig": "{\n \"element\": \"#WORKBENCH_SIDE_ADD_NODE_BTN\", \n\"placement\": \"bottom\",\n \"title\": \"智能引导\", \n\"description\": \"让我们新建一张空白的维格表试一试\", \"children\":\"\" \n}", - "uiConfigId": "player_step_ui_config_26", - "uiType": "popover" - }, - "27": { - "onTarget": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \"#WORKBENCH_SIDE_ADD_NODE_BTN\"\n}", - "uiConfigId": "player_step_ui_config_27", - "uiType": "breath" - }, - "28": { - "onSkip": [ - "skip_current_wizard()" - ], - "uiConfig": "{\n \"element\": \"#NODE_CONTEXT_MENU_ID .react-contexify__item:nth-of-type(1)\", \n\"placement\": \"rightCenter\",\n \"title\": \"智能引导\", \n\"description\": \"接着,选择“新建空白维格表”\", \"children\":\"\" \n}", - "uiConfigId": "player_step_ui_config_28", - "uiType": "popover" - }, - "29": { - "uiConfig": "{\n \"element\": \"#NODE_CONTEXT_MENU_ID > .react-contexify__item:nth-of-type(1) .react-contexify__item__content > div:nth-of-type(1)\",\n\"shadowDirection\":\"inset\"\n} ", - "uiConfigId": "player_step_ui_config_29", - "uiType": "breath" - }, - "30": { - "backdrop": "around_mask", - "byEvent": [ - "datasheet_grid_view_shown" - ], - "onNext": [ - "clear_guide_uis([\"popover\"])" - ], - "onSkip": [ - "skip_current_wizard()" - ], - "onTarget": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \"#DATASHEET_ADD_COLUMN_BTN\", \n\"placement\": \"leftTop\",\n \"title\": \"智能引导\", \n\"description\": \"一张空白的维格表创建好啦,接下来我们来尝试一下新建一个维格列吧\", \"children\":\"\" \n}", - "uiConfigId": "player_step_ui_config_30", - "uiType": "popover" - }, - "31": { - "onTarget": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \"#WORKBENCH_SIDE_FORM_USE_GUIDE_BTN\"\n}", - "uiConfigId": "player_step_ui_config_31", - "uiType": "breath" - }, - "32": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "open_guide_next_step()" - ], - "onSkip": [ - "skip_current_wizard()" - ], - "uiConfig": "{\n \"element\": \"#DATASHEET_GRID_CUR_COLUMN_TYPE\", \n\"placement\": \"bottom\",\n \"title\": \"智能引导\", \n\"description\": \"维格表提供了丰富的维格列类型以匹配各种使用场景,鼠标悬浮在这里即可查看\", \"children\":\"\" \n}", - "uiConfigId": "player_step_ui_config_32", - "uiType": "popover" - }, - "33": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onSkip": [ - "skip_current_wizard()" - ], - "uiConfig": "{\n \"element\": \"#DATASHEET_VIEW_TAB_BAR .style_viewBarWrapper__AJlc-\", \n\"placement\": \"bottom\",\n \"title\": \"智能引导\", \n\"description\": \"同一张维格表可提供多种视图模式,通过“分组、筛选、排序”等功能来自定义视图的展示数据。但是要注意,一张维格表下所有的视图用的都是同一份数据源,只是展示的样式各有不同,所以不要把视图当作excel的工作簿用哦!\", \"children\":\"\" \n}", - "uiConfigId": "player_step_ui_config_33", - "uiType": "popover" - }, - "34": { - "uiConfig": "{\n \"element\": \"#DATASHEET_VIEW_TAB_BAR .style_viewBarWrapper__AJlc-\"\n}", - "uiConfigId": "player_step_ui_config_34", - "uiType": "breath" - }, - "35": { - "byEvent": [ - "datasheet_field_setting_hidden" - ], - "next": "下一步", - "nextId": "next_step", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onSkip": [ - "skip_current_wizard()" - ], - "onTarget": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \"#DATASHEET_ADD_VIEW_BTN\", \n\"placement\": \"bottom\",\n \"title\": \"智能引导\", \n\"description\": \"维格表除了标准表格形式的“维格视图”外,还支持变换“相册视图”“看板视图””甘特视图“”日历视图“”架构视图“,分别对应管理丰富的图像化数据和任务化数据,让你事半功倍,还是得要提醒一次,视图只是展示的样式不同,但是数据源是同一份哦!\", \"children\":\"\" \n}", - "uiConfigId": "player_step_ui_config_35", - "uiType": "popover" - }, - "36": { - "onTarget": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \"#DATASHEET_ADD_VIEW_BTN\",\n\"shadowDirection\":\"inset\"\n}", - "uiConfigId": "player_step_ui_config_36", - "uiType": "breath" - }, - "37": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "clear_guide_uis([\"popover\"])" - ], - "onSkip": [ - "skip_current_wizard()" - ], - "uiConfig": "{\n \"element\": \"#DATASHEET_TOOL_BAR .style_toolbarMiddle__2kxTf>button:nth-of-type(7)\", \n\"placement\": \"bottom\",\n \"title\": \"智能引导\", \n\"description\": \"如果要将内容分享给空间站外的人员,你可以通过这个功能创建一条链接分享出去\", \"children\":\"\" \n}", - "uiConfigId": "player_step_ui_config_37", - "uiType": "popover" - }, - "38": { - "onTarget": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \"#DATASHEET_TOOL_BAR .style_toolbarMiddle__2kxTf>button:nth-of-type(7)\"\n}", - "uiConfigId": "player_step_ui_config_38", - "uiType": "breath" - }, - "39": { - "next": "知道啦", - "nextId": "known", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"placement\": \"bottomLeft\",\n \"description\": \"智能引导就到这里啦,如果想要查看维格表更加详细的教程,你可以点击左下角的帮助中心去查看我们的产品手册哦\"\n}", - "uiConfigId": "player_step_ui_config_39", - "uiType": "slideout" - }, - "40": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "clear_guide_uis([\"popover\"])" - ], - "uiConfig": "{\n \"element\": \"#DATASHEET_FORM_BTN\",\n\"placement\": \"bottomRight\",\n \"title\": \"新功能\", \n\"description\": \"可以通过神奇表单来录入数据了,赶紧体验一下吧~\", \"children\":\"\" \n}", - "uiConfigId": "player_step_ui_config_40", - "uiType": "popover" - }, - "41": { - "onTarget": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \"#DATASHEET_FORM_BTN\"\n}", - "uiConfigId": "player_step_ui_config_41", - "uiType": "breath" - }, - "42": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \"#DATASHEET_FORM_LIST_PANEL\", \n\"placement\": \"leftTop\",\n \"title\": \"神奇表单\", \n\"description\": \"在这里可以快速生成当前视图的神奇表单,神奇表单的字段是依照视图的维格列数量以及顺序来生成的哦\", \"children\":\"\" \n}", - "uiConfigId": "player_step_ui_config_42", - "uiType": "popover" - }, - "43": { - "backdrop": "around_mask", - "next": "知道啦", - "nextId": "known", - "onNext": [ - "skip_current_wizard()" - ], - "onSkip": [ - "skip_current_wizard({\"curWizardCompleted\": true})" - ], - "skip": "不再提醒", - "skipId": "remind_never_again", - "uiConfig": "{\n \"element\": \".style_navigation__1U5cR .style_help__1sXEA\", \n\"placement\": \"rightBottom\",\n \"title\": \"小提示\", \n\"offsetY\":5,\n\"description\": \"你可以在左侧的「帮助中心」找回你的维格小助手\", \"children\":\"\" \n}", - "uiConfigId": "player_step_ui_config_43", - "uiType": "popover" - }, - "44": { - "onClose": [ - "open_guide_next_step({\"clearAllPrevUi\":true})", - "open_guide_wizard(18)" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onPlay": [ - "set_wizard_completed({\"wizardId\": 14})" - ], - "uiConfig": "{\n\"title\":\"一分钟快速入门\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", - "uiConfigId": "player_step_ui_config_44", - "uiType": "modal" - }, - "45": { - "next": "知道啦", - "nextId": "known", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"title\": \"更新公告\",\n \"children\": \"

✨ Hello, 星球居民们~

在2020年的尾声,维格星球迎来了一波更新,新年新气象,一起来探索2021年的新玩法吧~

🎉 播报 News

  • 「收集表」正式上线,全新玩法让数据收集、内部协作更加轻松自如
  • 「移动端」支持编辑列配置,距离理想的「躺在沙滩上办公」更近啦!
  • 记录将提供「预排序」交互效果,修改后的记录不会马上飞走了,多一步的停留让改动更有深度
  • 维格列配置菜单支持搜索维格列类型——咦,你看出我们的野心了?

🍜 优化 Enhancement

  • 重新设计的新手引导,拥有「魔力」的维格小助手带你轻松上手维格表
  • 维格表支持邮箱注册了
  • 还有许多小优化,欢迎探索体验。
\"\n }", - "uiConfigId": "player_step_ui_config_45", - "uiType": "notice" - }, - "46": { - "next": "知道啦", - "nextId": "known", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"title\": \"更新公告\",\n \"children\": \"

✨ Hello 星球居民们~

牛年新气象,维格表值此新春之际上新啦。若干重磅功能闪亮登场,让你的工作效率再上一个台阶 🔥。

🕤 仪表盘

全新文件类型,举手之间轻松搭建图表驾驶舱,清晰呈现每个指标,汇聚工作焦点。

📈 图表

简洁灵活的数据可视化图表,支持柱状图、折线图、饼状图等多种类型。
添加即查看,一键切换维度和数值计算,10s 完成制作。

💯 统计与指标

指定统计字段并选择求和、平均值等指标,将自动计算并快速呈现关键结果。
支持自定义统计说明和对比目标,提升阅读体验。

🎉 飞书集成

打通飞书,智能同步通讯录和组织架构,员工账号管理更轻松。
在维格表中,如有成员提及和评论 @ 等都可以在飞书中收到同步通知。

提示:目前飞书登录仍处于官方审核阶段,暂无法使用飞书扫码登录,请谅解。

💻 维格表桌面端

全新的桌面级客户端,支持 Windows 和 macOS,让您随时随地维格一下。

👬 邀请码

优化邀请码分享机制,复制后自动转化为邀请链接,以便他人更快完成注册和使用,双方还将获得 1000 V 币奖励。

\"\n }", - "uiConfigId": "player_step_ui_config_46", - "uiType": "notice" - }, - "47": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "clear_guide_uis([\"popover\"])" - ], - "uiConfig": "{\n \"element\": \"#DATASHEET_WIDGET_BTN\",\n\"placement\": \"bottomRight\",\n \"title\": \"新功能\", \n\"description\": \"小程序上线!想要让沉淀下来的数据得到更好的运用吗?那就赶紧来体验一下吧\", \"children\":\"\" \n}", - "uiConfigId": "player_step_ui_config_47", - "uiType": "popover" - }, - "48": { - "onTarget": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \"#DATASHEET_WIDGET_BTN\",\n\"shadowDirection\": \"inset\"\n}", - "uiConfigId": "player_step_ui_config_48", - "uiType": "breath" - }, - "49": { - "backdrop": "around_mask", - "next": "好的", - "nextId": "okay", - "onNext": [ - "clear_guide_uis([\"popover\"])" - ], - "uiConfig": "{\n \"element\": \".style_widgetPanelContainer__1l2ZV\",\n\"placement\": \"leftCenter\",\n \"title\": \"什么是小程序\", \n\"description\": \"维格小程序是维格表的一种扩展应用,可实现数据可视化、数据传输、数据清洗等等额外功能。通过在小程序面板安装适合团队的小程序,可以让工作事半功倍\", \"children\":\"\" \n}", - "uiConfigId": "player_step_ui_config_49", - "uiType": "popover" - }, - "50": { - "byEvent": [ - "datasheet_widget_center_modal_shown" - ], - "next": "好的", - "nextId": "okay", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \".style_widgetModal__eXmdB\",\n\"placement\": \"leftTop\",\n \"title\": \"小程序中心\", \n\"description\": \"官方推荐和空间站自建的小程序会发布到这里。你可以根据场景,在这里挑选合适的小程序放置到仪表盘或小程序面板里\", \"children\":\"\" \n}", - "uiConfigId": "player_step_ui_config_50", - "uiType": "popover" - }, - "51": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "clear_guide_uis([\"popover\"])" - ], - "uiConfig": "{\n \"element\": \".style_widgetModal__eXmdB .style_widgetItem__3Pl-1 button\",\n\"placement\": \"rightBottom\",\n \"title\": \"安装小程序\", \n\"description\": \"我们安装这个「图表」小程序看看吧\", \"children\":\"\" \n}", - "uiConfigId": "player_step_ui_config_51", - "uiType": "popover" - }, - "52": { - "onTarget": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \".style_widgetModal__eXmdB .style_widgetItem__3Pl-1 button\",\n\"shadowDirection\":\"none\"\n}", - "uiConfigId": "player_step_ui_config_52", - "uiType": "breath" - }, - "53": { - "backdrop": "around_mask", - "next": "好的", - "nextId": "okay", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \".style_widgetPanelContainer__1l2ZV\",\n\"placement\": \"leftCenter\",\n\"description\": \"安装成功,同时我们也为你创建了一个小程序面板,一个维格表的所有小程序都会放置在这个区域\", \"children\":\"\" \n}", - "uiConfigId": "player_step_ui_config_53", - "uiType": "popover" - }, - "54": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \".style_widgetPanelContainer__1l2ZV .style_panelHeader__3X0pG\",\n\"placement\": \"bottom\",\n \"title\": \"小程序面板\", \n\"description\": \"小程序面板是用于装载小程序的容器,可以通过创建多个小程序面板来给你的小程序进行分类\", \"children\":\"\" \n}", - "uiConfigId": "player_step_ui_config_54", - "uiType": "popover" - }, - "55": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"placement\": \"bottomLeft\",\n \"description\": \"仪表盘作为维格表的一种文件类型,添加/导入小程序后,可视化能力提升。你可以通过数据统计和图表分析,更好地进行判断和决策\"\n}", - "uiConfigId": "player_step_ui_config_55", - "uiType": "slideout" - }, - "56": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "clear_guide_uis([\"popover\"])" - ], - "uiConfig": "{\n \"element\": \"#DASHBOARD_PANEL_ID .style_tabRight__4YAkM button:nth-of-type(1)\",\n\"placement\": \"bottom\",\n \"title\": \"添加小程序\", \n\"description\": \"在这里有两种方法添加小程序,一种是从小程序中心添加,一种是从已有的小程序中导入进去\", \"children\":\"\" \n}", - "uiConfigId": "player_step_ui_config_56", - "uiType": "popover" - }, - "57": { - "onTarget": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \"#DASHBOARD_PANEL_ID .style_tabRight__4YAkM button:nth-of-type(1)\",\n \"shadowDirection\":\"inset\"\n}", - "uiConfigId": "player_step_ui_config_57", - "uiType": "breath" - }, - "58": { - "next": "好的", - "nextId": "okay", - "uiConfig": "{\n \"element\": \".style_addWidgetMenu__29bIe .style_menuItem__3Ugjz:nth-of-type(1)\",\n\"placement\": \"bottom\",\n \"title\": \"添加小程序\", \n\"description\": \"让我们来尝试一下,添加一个小程序到仪表盘吧\", \"children\":\"\" \n}", - "uiConfigId": "player_step_ui_config_58", - "uiType": "popover" - }, - "59": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "clear_guide_uis([\"popover\"])" - ], - "uiConfig": "{\n \"element\": \"#DASHBOARD_PANEL_ID .style_widgetContainer__2HwEf\",\n\"placement\": \"rightTop\",\n \"title\": \"关联维格表\", \n\"description\": \"由于部分小程序需要依赖维格表的数据,所以安装小程序之后还需要选择一个维格表进行关联\", \"children\":\"\" \n}", - "uiConfigId": "player_step_ui_config_59", - "uiType": "popover" - }, - "60": { - "byEvent": [ - "datasheet_search_panel_shown" - ], - "next": "好的", - "nextId": "okay", - "onNext": [ - "clear_guide_uis([\"popover\"])" - ], - "uiConfig": "{\n \"element\": \".style_searchPanelContainer__1_iOe\",\n\"placement\": \"rightTop\",\n \"title\": \"关联维格表\", \n\"description\": \"在这里选择你需要关联的维格表,以供小程序访问数据\", \"children\":\"\" \n}", - "uiConfigId": "player_step_ui_config_60", - "uiType": "popover" - }, - "61": { - "byEvent": [ - "datasheet_search_panel_hidden" - ], - "next": "好的", - "nextId": "okay", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"placement\": \"bottomLeft\",\n \"description\": \"恭喜你,已掌握了仪表盘和添加小程序的基本使用方法。接下来,你可以根据业务场景去搭建专属的仪表盘了\"\n}", - "uiConfigId": "player_step_ui_config_61", - "uiType": "slideout" - }, - "62": { - "next": "知道啦", - "nextId": "known", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"title\": \"✨ 星球居民们,好久不见~\",\n\"children\": \"

在过去的 2 个月里,维格表一直有在悄悄更新,改善使用体验。
这次新增了不少显性功能点,先来了解一下再上手吧~

📈  图表组件增强可视化

自动识别日期维度,开启格式化日期后可选择按周/月/季度/年展示,清晰呈现数据走势

wegist1

新增 10+ 款单色渐变主题,适合在多个数据系列的图表中应用,增强审视,突出焦点

wegist2

📎  office 文件在线预览

附件字段上传文件后可在线预览,提升协作效率,支持文档、表格、PPT 多种格式
路径:空间站设置-第三方应用集成-office 文件预览,授权后才能生效哦

wegist1

🔍  神奇引用列支持筛选

在神奇引用列中,对引用的数据进行筛选,以便在海量数据中快速、精准地展示某类数据

wegist1

📅  日期格式更丰富

日期字段新增年、月、日三种日期格式

wegist1

➕  其他

优化页面刷新逻辑,删除、复制文件后无需重载,保持当前操作不被打断

\"\n }", - "uiConfigId": "player_step_ui_config_62", - "uiType": "notice" - }, - "63": { - "next": "知道啦", - "nextId": "known", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"title\": \"🌟星球居民们🌟\",\n\"children\": \"

vika 维格表又双叒更新啦,千呼万唤的列权限、甘特图已上线,快来点亮 vika 的魔法棒吧~

🔒  精细化权限管理

列权限上线,保护敏感数据。开启列权限后,可限制成员查看或编辑表格内的某列数据。
路径:设置列权限前,需先开启文件权限

wegist1

⏳  项目跟进,张弛有度

超强甘特图,助力项目管理。以时间为轴,展示每一个任务的时间节点以及关键信息,全面把控进度。

wegist1

📋  记录修改,有迹可循

追溯修改历史,以防数据丢失。最近 90 天的修改记录,包括修改人、修改内容等完整信息都能被找回。
路径:展开行-点击弹窗右上角评论-显示本表的修改历史-修改历史

wegist1

🔜   畅享输入,轻松排版

文件详情页改版,文本编辑很清爽。支持 markdown 语法,输入“/”展开菜单栏,内容排版快人一步。

wegist1

📎  附件下载,一步完成

单行记录中,附件列的多个文件可一键下载。下载文件将以压缩包的形式存储在本地设备中。

wegist1

☎️  成员手机,可控显示

显示成员手机号码,紧急事项及时沟通。开启选项后,通讯录成员的手机号码将完整展示。
路径:空间站管理-普通成员-成员信息-显示成员手机号

wegist1

⌨️  快捷操作指南

  • 双击表格头部的表名,快速完成重命名。
  • 点击右上角的协同成员头像,快速设置成员在当前表格的权限。
  • 批量隐藏、拖动或删除维格列,选中一列后,按住 shift 并鼠标点击其他列可快速形成选区并进行操作。
  • 批量操作连续的记录时,鼠标勾选一行后按住 shift 并点击最后一行前的复选框,即可快速形成选区。

\"\n }", - "uiConfigId": "player_step_ui_config_63", - "uiType": "notice" - }, - "64": { - "onClose": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n\"title\":\"甘特图教学视频\",\n\"video\":\"space/2021/05/26/baddaa8b7d0c4b0390b03ef9a5549c6e\"\n}", - "uiConfigId": "player_step_ui_config_64", - "uiType": "modal" - }, - "65": { - "next": "知道啦", - "nextId": "known", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"title\": \"🌟星球居民们🌟\",\n\"children\": \"

7月份的尾巴,是热情洋溢的狮子座,也是魔法神奇的维格表,快来康康这次更新了哪些功能吧~

🧙‍  神奇表单更神奇

未提交表单内容时退出页面,重新进入自动保留上次填写内容,减少重复输入
支持智能公式列、神奇引用列的内容显示,表单填写智能化

wegist1

🌈  字段设置很贴心

显示双向关联列在对应关联表中的列名称,帮助使用者快速理解、一一对应

wegist1

数字列类型格式增强,贴合业务场景自定义单位名称,多种千分位格式设置,数据记录更直观

wegist1

⏳  筛选查重新技能

数据录入和表单提交时可能导致的重复记录,都可以通过筛选器快速查找,以便及时更正

wegist1

🎉   第三方集成:钉钉

在钉钉中创建自建应用「维格表」,平台间的组织架构和消息通知即时同步,清除协作障碍

wegist1

🔓  其他功能优化

相册视图布局调整,平铺状态下最少可展示一列,移动端查看更加舒适

wegist1

首列列名称增加小提示,数据结构化以「记录标题」为主键,不支持拖动、隐藏和删除

wegist1

当维格表的列数量较多需要横向拖动进行查看时,可按住 Shift 后滚动鼠标上的滚轮来实现

wegist1\"\n }", - "uiConfigId": "player_step_ui_config_65", - "uiType": "notice" - }, - "66": { - "onClose": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n\"title\":\"日历视图教学视频\",\n\"video\":\"space/2022/04/26/ab9d17db76064e9d8fd228889e30f1ad\"\n} ", - "uiConfigId": "player_step_ui_config_66", - "uiType": "modal" - }, - "67": { - "next": "知道啦", - "nextId": "known", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n\t\"title\": \"🌟星球居民们🌟\",\n\t\"children\": \"

十月更新第二弹,维格机器人来喽,打通 IM 工具,消息通知使命必达,还有满屏细节更新,快来体验吧~

🤖️  维格机器人

维格机器人 (Vika Robot) 是工作流或系统对接的自动化方案,将帮助企业/个人减少机械劳动,释放生产力。当前,维格机器人已实现与 IM 工具的信息连接,只需简单配置即可将维格表记录推送至飞书、钉钉、企业微信。更多可能,敬请期待~
尝鲜体验需先申请内测资格,路径:左下角头像-用户中心-实验性功能-机器人-去申请内测

wegist1

📅  日期统计更通用

优化 WEEKNUM()、WORKDAY()、WORKDAY_DIFF() 三个日期公式计算逻辑,使统计结果更符合预期。

  • WEEKNUM(),日期参数默认将每年的 1 月 1 日作为第一周,且周日为每周的第一天如: WEEKNUM('2021-11-11'), 输出值: 46
  • WORKDAY()、WORKDAY_DIFF(),修复参数影响导致的计算结果异常现象

🌟  评分更便捷

在满意度调研表单中,评分字段的使用尤为频繁, 使用鼠标点击并不便捷。现在,你可以选中评分单元格后,从键盘输入数字来完成( 支持 PC 端和网页端)。

↕️  分组更友好

双向关联作为维格表的明星功能,细节体验十分突出,将双向关联字段作为分组条件后,点击分组标题展开记录详情,轻松掌握更多信息。

🛎️  通知更细腻

< p class='body3'> 镜像用得好,权限无烦恼,在镜像视图下@相关成员,成员查看通知记录将打开对应的镜像视图, 避免原表无访问权限的尴尬。

\"\n}", - "uiConfigId": "player_step_ui_config_67", - "uiType": "notice" - }, - "68": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \"div[data-guide-id=WIDGET_ITEM_WRAPPER]:last-child\",\n\"placement\": \"leftCenter\",\n \"title\": \"开发模式\", \n\"description\": \"开发模式下,你可以预览小程序的最新本地改动\", \"children\":\"\" \n}", - "uiConfigId": "player_step_ui_config_68", - "uiType": "popover" - }, - "69": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \"div[data-guide-id=WIDGET_ITEM_WRAPPER]:last-child [data-guide-id=WIDGET_ITEM_REFRESH]\",\n\"placement\": \"topRight\",\n \"title\": \"刷新\", \n\"description\": \"每次本地改动代码后,都需要点击刷新来预览\", \"children\":\"\"\n}", - "uiConfigId": "player_step_ui_config_69", - "uiType": "popover" - }, - "70": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "clear_guide_uis([\"popover\"])" - ], - "uiConfig": "{\n \"element\": \"div[data-guide-id=WIDGET_ITEM_WRAPPER]:last-child [data-guide-id=WIDGET_ITEM_MORE]\",\n\"placement\": \"topRight\",\n \"title\": \"退出开发模式\", \n\"description\": \"点击此处选择「退出开发模式」,将断开与本地服务的连接,恢复至上一个版本的小程序状态\", \"children\":\"\"\n}", - "uiConfigId": "player_step_ui_config_70", - "uiType": "popover" - }, - "71": { - "uiConfig": "{}", - "uiConfigId": "player_step_ui_config_71", - "uiType": "customQuestionnaire" - }, - "72": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"title\": \"🌟星球居民们🌟\",\n\"children\": \"

维格表 10 月上旬更新来了,日期筛选大幅优化,满足全方位使用需求,智能公式优化,数据统计更加精准便捷。

📅  日期筛选更自由

运营人员每周分析广告投放效果,财务人员月末整理对账数据,这些场景与日期筛选密不可分,动态查询将让数据统计分析工作愈加轻松。

新增本周/本月/上周/上月/今年 5 个常用日期条件,一次设置长期可用,再也不用每次手动调整啦~

wegist1

项目回顾、工单处理等场景下需要聚焦某个周期内的数据,支持自定义时间范围,操作更友好

wegist1

数据分析中有时只需关注近期数据变化,筛选早于/晚于当前多少天的数据,结合仪表盘还能轻松实现可视化大屏效果

wegist1

🆒  智能公式优化

优化 DATETIME_DIFF()、AVERAGE()、FIND() 三个智能公式计算逻辑:

  • DATETIME_DIFF()输出结果调整为浮点数,更精确地计算两个日期间的差值
  • AVERAGE()所统计字段带有空值时,空值将不纳入计算
  • FIND()新增支持从文本末端往前查找,如:FIND('a','vikadata',-1),输出结果 8
\"\n }", - "uiConfigId": "player_step_ui_config_72", - "uiType": "notice" - }, - "73": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"title\": \"🌟星球居民们🌟\",\n\"children\": \"

十月更新第二弹,维格机器人 (Vika Robot) 来喽,打通 IM 工具,消息通知使命必达。还有满屏细节更新,快来体验吧~

🛰️  维格机器人

维格机器人 (Vika Robot) 是工作流或系统对接的自动化方案,将帮助企业/个人减少机械劳动,释放生产力。当前,维格机器人已实现与 IM 工具的信息连接,只需简单配置即可将维格表记录推送至飞书、钉钉、企业微信。更多可能,敬请期待~

尝鲜体验需先申请内测资格,路径:左下角头像-用户中心-实验性功能-机器人-去申请内测

wegist1

📅  日期统计更通用

优化 WEEKNUM()、WORKDAY()、WORKDAY_DIFF() 三个日期公式计算逻辑,使统计结果更符合预期。

  • WEEKNUM(),日期参数默认将每年的 1 月 1 日作为第一周,且周日为每周的第一天。如:WEEKNUM('2021-11-11'),输出值:46
  • WORKDAY()、WORKDAY_DIFF(),修复参数影响导致的计算结果异常现象

🌟  评分更便捷

在满意度调研表单中,评分字段的使用尤为频繁,使用鼠标点击并不便捷。现在,你可以选中评分单元格后,从键盘输入数字来完成(支持 PC 端和网页端)。

↕️  分组更友好

双向关联作为维格表的明星功能,细节体验十分突出,将双向关联字段作为分组条件后,点击分组标题展开记录详情,轻松掌握更多信息。

🛎️  通知更细腻

镜像用得好,权限无烦恼,在镜像视图下 @ 相关成员,成员查看通知记录将打开对应的镜像视图,避免源表无访问权限的尴尬。

\"\n }", - "uiConfigId": "player_step_ui_config_73", - "uiType": "notice" - }, - "74": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onTarget": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \".style_formSpace__1_szP .style_right__DRofa #DATASHEET_FORM_CONTAINER_SETTING\",\n\"placement\": \"bottomRight\",\n \"title\": \"收纳单多选的选项\",\n \"arrowStyle\": { \"right\": \"40px\" },\n\"description\": \"选项过多导致页面太长?试试把它们收纳起来吧\" \n}", - "uiConfigId": "player_step_ui_config_74", - "uiType": "popover" - }, - "75": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "clear_guide_uis([\"popover\"])" - ], - "uiConfig": "{\n \"element\": \"div[data-guide-id=WIDGET_ITEM_WRAPPER]:last-child\",\n\"placement\": \"leftCenter\",\n \"title\": \"未发布的小程序\", \n\"description\": \"当前小程序未发布到空间站,只能在开发模式下预览小程序效果\", \"children\":\"\" \n}", - "uiConfigId": "player_step_ui_config_75", - "uiType": "popover" - }, - "76": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"title\": \"🌟星球居民们🌟\",\n \"children\": \"

这可能是史上最硬核的 Q4,继 Vika Robot 维格机器人后,本次更新再次推出自建小组件,实现更丰富的数据可视化效果,数据流转、协作更智能。

🧙‍♀️  表单显示更紧凑

使用神奇表单进行数据收集,单选/多选的选项较多时,页面会不断拉长,影响填写体验。对此,神奇表单进行了样式优化,开启「收纳单多选的选项」,再多的选项都可以完美兼容。

路径:神奇表单-设置-收纳单多选的选项

wegist1

🔐  安全与权限升级

空间站新增「安全设置」,企业/团队负责人可更加精细化地进行安全管控,包括维格表/视图是否可导出和分享、是否可邀请他人加入协作,是否开启全局水印等,进一步规避数据泄漏风险。

路径:设置-驾驶舱-安全设置

wegist1

🧰  自建小组件内测啦~

维格表自建小组件登场,为企业团队特定的工作场景和协作流程提供更多延展可能,内测申请通过后即可体验~

路径:用户中心-实验性功能-自建小组件-申请内测

wegist1

🛰️  优化机器人

支持发送消息至企业微信群,同时新增查看运行历史详情,以便快速定位异常,确保消息及时触达。

路径:用户中心-实验性功能-机器人-申请内测

\"\n}", - "uiConfigId": "player_step_ui_config_76", - "uiType": "notice" - }, - "77": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"children\": \"

关于 11 月 17 日服务器维护导致不可访问的致歉说明


11 月 17 日 23:02-23:30 期间,因 vika.cn 服务器在升级维护过程出现异常,维格表出现了 28 分钟服务不可使用状态,我们为此深感抱歉。vika维格表本应助力深夜仍在辛勤工作的用户,更舒适快速地结束工作,在这里,向所有受影响的用户再次表达我们的歉意!


问题出现后,产研团队第一时间上线解决。11 月 18 日,vika维格表团队组织了问题复盘会,总结教训的同时,我们向每一位用户做出如下承诺:

  1. 每次服务器升级维护,我们将至少提前 36 小时给您推送邮件通知、站内通知;
  2. 服务器常规升级维护的作业时间固定调整至凌晨 4 点开始;

再次为我们造成的不便致以诚挚歉意。如果有任何问题,请随时联系我们:


vika维格表全体成员将竭诚为您服务。

vika维格表产研团队

2021 年 11 月 18 日

\"\n}", - "uiConfigId": "player_step_ui_config_77", - "uiType": "notice" - }, - "78": { - "next": "我知道了", - "nextId": "i_knew_it", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \"#DATASHEET_TOOL_BAR .style_toolbarMiddle__2kxTf\",\n\"placement\": \"bottomRight\",\n \"arrowStyle\": { \"display\": \"none\" },\n \"title\": \"视图配置不协同\",\n\"description\": \"现在,临时的筛选、分组、排序等配置在未保存的情况下,不会同步给其他人,你的临时配置也将在刷新后失效。\" \n}", - "uiConfigId": "player_step_ui_config_78", - "uiType": "popover" - }, - "79": { - "next": "我知道了", - "nextId": "i_knew_it", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \"#DATASHEET_VIEW_TAB_BAR #view_item_sync_icon\",\n\"placement\": \"bottomLeft\",\n \"arrowStyle\": { \"left\": \"6px\" },\n \"title\": \"当前视图配置未保存\",\n\"description\": \"你刚修改了某些视图配置(筛选、分组、排序...),它们现在还没有保存哦。这意味着它们仅对你自己临时生效。你可以点击此处保存并同步给其他人\" \n}", - "uiConfigId": "player_step_ui_config_79", - "uiType": "popover" - }, - "80": { - "next": "我知道了", - "nextId": "i_knew_it", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \"#AUTO_SAVE_SVG_ID\",\n\"placement\": \"bottomLeft\",\n \"arrowStyle\": { \"left\": \"6px\" },\n \"title\": \"当前视图已开启自动保存\",\n\"description\": \"你现在进行筛选、分组、排序等视图配置操作会自动保存并同步给其他人\" \n}", - "uiConfigId": "player_step_ui_config_80", - "uiType": "popover" - }, - "81": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"title\": \"🌟星球居民们🌟\",\n \"children\": \"

你们反馈的每个需求和场景,我们都记在小本本上,快来康康本期更新,有你想要的吗?

🛸 全新驾驶舱

细分功能模块,空间站管理员可清晰地查看套餐总量和可用余量,了解团队协作情况。

https://s1.vika.cn/space/2021/11/25/6675a9ee262242bd98d17dc375220dfb

↕️  批量粘贴记录的优化

小明在维格视图的分组状态下,批量粘贴记录后发现覆盖了下一分组中的数据。因此他只能撤销粘贴操作,在当前分组下新增足够的行数再进行粘贴。

对此,维格表进行优化,分组下批量粘贴记录时询问是否新增行,避免覆盖原有记录。

https://s1.vika.cn/space/2021/11/25/f0c66d4656b947f1a3f6a85df7a5fe99

🛰️ 维格机器人

维格机器人选择变量时支持插入公式列,发送至钉钉/飞书/企业微信群的消息内容中将展示公式计算结果。比如:小明在维格表中创建智能公式列,用于计算任务到期天数

https://s1.vika.cn/space/2021/11/25/295938afe27d44b095beabb5fad254e7

维格列设置权限或删除,维格机器人中与之相关的匹配条件和变量值也将实时同步异常状态。

https://s1.vika.cn/space/2021/11/25/5aba8bf2c5864d8aaf15b805aee6e740

💡 功能优化

工作目录树新增自动折叠和悬浮效果,为工作台腾出更多操作空间

https://s1.vika.cn/space/2021/11/25/11a92b3dc9074f2589f0c8f20361d08e

优化视图标签栏,支持显示文件描述,多视图下自动进行收纳

https://s1.vika.cn/space/2021/11/25/0d49558ebbae4f3cb9368fe1c588c9d5

\"\n}", - "uiConfigId": "player_step_ui_config_81", - "uiType": "notice" - }, - "82": { - "onClose": [ - "clear_guide_all_ui()" - ], - "onNext": [ - "clear_guide_all_ui()" - ], - "uiConfig": "{\n\"title\":\"架构视图教学视频\",\n\"video\":\"space/2022/04/26/bebe4536c330427c81e6b26627263904\"\n}", - "uiConfigId": "player_step_ui_config_82", - "uiType": "modal" - }, - "83": { - "onTarget": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \"#DATASHEET_CREATOR_ORG_CHART\",\n\"shadowDirection\": \"none\"\n}", - "uiConfigId": "player_step_ui_config_83", - "uiType": "breath" - }, - "84": { - "backdrop": "around_mask", - "onNext": [ - "clear_guide_uis([\"popover\"])" - ], - "onTarget": [ - "clear_guide_all_ui()" - ], - "uiConfig": "{\n \"element\": \"#DATASHEET_CREATOR_ORG_CHART\",\n\"placement\": \"right\",\n \"title\": \"架构视图上线\", \n\"description\": \"赶紧来体验一下吧\", \n\"children\": \"\"\n}", - "uiConfigId": "player_step_ui_config_84", - "uiType": "popover" - }, - "85": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})", - "clear_guide_uis([\"popover\"])" - ], - "uiConfig": "{\n \"element\": \"#DATASHEET_ORG_CHART_RECORD_LIST\",\n\"placement\": \"left\",\n \"title\": \"为它创建一个子级\", \n\"description\": \"你可以将记录拖至左侧的记录卡片中,自动成为卡片的子级\",\n\"offsetY\": 144\n}", - "uiConfigId": "player_step_ui_config_85", - "uiType": "popover" - }, - "86": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \"#DATASHEET_ORG_CHART_RECORD_LIST\",\n\"placement\": \"left\",\n \"title\": \"清除子级\", \n\"description\": \"你可以将记录拖至右侧的待处理记录区,清除其关联关系\",\n\"offsetY\": 144\n}", - "uiConfigId": "player_step_ui_config_86", - "uiType": "popover" - }, - "87": { - "uiConfig": "{\n \"element\": \"#DATASHEET_ORG_CHART_RECORD_LIST\"\n}", - "uiConfigId": "player_step_ui_config_87", - "uiType": "breath" - }, - "88": { - "uiConfig": "{\n \"element\": \"#toolHideField\"\n}", - "uiConfigId": "player_step_ui_config_88", - "uiType": "breath" - }, - "89": { - "next": "我知道了", - "nextId": "i_knew_it", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onTarget": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \"#toolHideField\",\n\"placement\": \"bottom\",\n \"title\": \"设置卡片样式\", \n\"description\": \"自定义卡片显示的字段和封面图效果\" \n}", - "uiConfigId": "player_step_ui_config_89", - "uiType": "popover" - }, - "90": { - "uiConfig": "{\n \"element\": \"#DATASHEET_TOOL_BAR_VIEW_SETTING\"\n}", - "uiConfigId": "player_step_ui_config_90", - "uiType": "breath" - }, - "91": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})", - "clear_guide_uis([\"popover\"])" - ], - "uiConfig": "{\n \"element\": \"#DATASHEET_TOOL_BAR_VIEW_SETTING\",\n\"placement\": \"bottom\",\n \"title\": \"重新查看教学视频\", \n\"description\": \"你可以点击「设置」,在里面找到「架构视图」的教学视频重新观看噢~\" \n}", - "uiConfigId": "player_step_ui_config_91", - "uiType": "popover" - }, - "92": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\"title\":\"🌟星球居民们🌟\",\"children\":\"

架构视图来袭,拖动完成绘制,视图配置不协同,数据呈现千人千面,快来体验吧~

\\n

🙋‍♂️ 架构视图

\\n

架构视图用于呈现本表每条记录间的层级关系,只需将记录卡片拖动至图形区建立关联,即可轻松绘制组织架构图、软件架构图等效果,省时又高效

\\n

\\\"https://s1.vika.cn/space/2021/12/09/8e2aa90c2fa44641a59141b3a040ce55\\\"

\\n

🙅‍♂️ 视图配置不协同

\\n

多成员在同一视图下协作时,希望通过筛选/分组/排序等操作快速展示符合自身需求的记录并且不受其他成员的操作干扰,通过「视图配置不协同」,可实现视图效果仅当前生效。

\\n

路径:空间站 > 空间站管理 > 管理员的实验性功能 > 视图配置不协同

\\n

\\\"https://s1.vika.cn/space/2021/12/09/8aa52753ff5342eaa8a05dbf20bd0efc\\\"

\\n

🛰️ 维格机器人

\\n

维格机器人选择变量时支持插入神奇引用列类型的值,所有引用类型都可在消息通知中展示。

\\n

\\\"https://s1.vika.cn/space/2021/12/09/d58e4863b0aa4a47b0fe32e416ad6289\\\"

\\n

🧣 细节体验优化

\\n

神奇引用列和智能公式列中的网址点击可跳转,数字支持设置千分位。

\\n

相册视图优化封面图尤其是长图的适配效果,记录卡片支持跨组拖动。

\"}", - "uiConfigId": "player_step_ui_config_92", - "uiType": "notice" - }, - "93": { - "next": "好的", - "nextId": "okay", - "onClose": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onNext": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"title\": \"维格隐私政策\",\n \"children\": \"

1. 我们如何收集并使用您的信息

\\n

在您使用维格表提供的以下服务或功能过程中,我们将基于以下基本功能收集您的相关必要个人信息。

\\n

1.1 账号的注册及使用

\\n

您首先需要注册一个维格表账号成为维格表的注册用户。当您注册时,您需要向我们提供您本人的手机号码或者电子邮箱,我们将通过发送短信验证码或者邮件验证码的方式来验证您的身份是否有效。如果您不提供该信息,您也可以通过第三方平台(微信、钉钉、飞书、企业微信)授权的形式快速完成注册,此方式需要您授权维格表获得您在第三方平台的头像、昵称。

\\n

1.2 基本业务使用

\\n

1.2.1 空间站的通讯录

\\n

空间站的通讯录中可能会展示您在此空间站的昵称、头像、电话号码以及邮箱。注:非本空间站的成员将不会看到您的个人信息。

\\n

1.2.2 发布记录评论

\\n

您可以对表格中的记录进行评论,评论的信息将会带上您的昵称以及头像。注:非本空间站的成员将不会看到您的个人信息。

\\n

1.2.3 带有成员相关信息的字段

\\n

在表格中使用成员字段的相关功能,将会带上您的昵称以及头像信息。

\\n

1.2.4 文件的公开链接

\\n

利用文件的公开链接能力进行分享,在分享的页面上将会带上您的昵称、头像以及空间站的名称信息。

\\n

1.2.5 “维格社区”公开发布功能

\\n

您可通过“维格社区”的问题、文章、活动、评论功能公开发布信息,相关页面将显示您的昵称和头像。您公开发布的信息中可能会涉及您或他人的个人信息甚至个人敏感信息,请您谨慎地考虑,是否在使用我们的服务时公开发布相关信息。若您公开发布的信息中涉及他人个人信息的,您需在发布前征得他人的同意。

\\n

1.3 客户服务

\\n

为了更好为您排查使用中的问题,我们会收集以下信息来帮助工程师定位问题。

\\n

1.3.1 设备信息

\\n

我们会根据您在具体使用维格表时的操作,收集您所使用的设备相关信息:包括设备型号、操作系统版本、设备设置、 MAC 地址及 IMEI 等相关信息。

\\n

1.3.2 服务日志

\\n

我们会收集您在使用维格表服务时的操作日志进行保存,包括:浏览记录、点击事件、浏览器类型、电信运营商、IP 地址、访问时长、访问日期及时间。

\\n

1.4 授权同意之外

\\n

根据法律法规的规定,在以下情形中,我们可未经您授权的情况下收集并使用以下信息:

\\n
    \\n
  1. \\n

    与国家安全、国防安全直接相关的;

    \\n
  2. \\n
  3. \\n

    与公共安全、公共卫生、重大公共利益直接相关的;

    \\n
  4. \\n
  5. \\n

    与犯罪侦查、起诉、审判和判决执行等直接相关的;

    \\n
  6. \\n
  7. \\n

    依照《中华人民共和国个人信息保护法》规定在合理的范围内处理您自行公开或者其他已经合法公开的个人信息;

    \\n
  8. \\n
  9. \\n

    从合法公开披露的信息中收集到您的个人信息,如从合法的新闻报道、政府信息公开等渠道;

    \\n
  10. \\n
  11. \\n

    根据您的要求签订和履行合同所必需的;

    \\n
  12. \\n
  13. \\n

    用于维护维格表的产品和/或服务的安全稳定运行所必需的;

    \\n
  14. \\n
  15. \\n

    法律法规规定的其他情形。

    \\n
  16. \\n
\\n

2. 我们保证信息的安全性

\\n

维格表为保障用户的数据安全不遗余力。我们始终以软件行业最高安全标准保护用户数据,所使用的安全模型和策略全部基于国际标准和行业最佳实践。

\\n

我们将严格保护您的信息的安全。使用各种安全技术和程序来保护您的信息不被未经授权的访问、使用或泄漏。如果您对隐私保护有任何置疑,请发送邮件至 devops@vikadata.com

\\n

2.1 技术措施

\\n

2.1.1 数据位置

\\n

维格表的数据全部托管在亚马逊中国(AWS)宁夏区域、北京区域、阿里云的多个数据中心的可用区中,采用多副本冗余存储。他们是中国最顶尖的云服务提供商,数据托管在他们的基础设施上,避免了硬盘被盗或失效、甚至整个区域故障导致的数据丢失风险。

\\n

2.1.2 数据灾备与恢复

\\n

维格表每天都会对数据进行备份,备份数据也存储在多个数据中心的可用区中,并使用 AES-256 算法进行加密, 所有备份都会定期追踪其完整性并进行验证检查,以确保故障发生时,我们可以迅速启动恢复流程并立即修复数据。

\\n

2.1.3 服务器安全

\\n

网络安全

\\n

维格表采用亚马逊云中国(AWS)云提供的、具有多层保护和防御机制的网络安全技术,通过防火墙阻挡未经授权的访问,同时还采用多个交换机和安全网关来确保网络冗余,防止内部网络的单点故障。

\\n

DDoS 防御

\\n

维格表使用新一代Amazon WAF(Web 应用防护系统)技术来防止对服务器的 DDoS 攻击,只允许正常的流量通过,防止恶意流量攻击造成的业务中断,使网站和 API 保持高可用性和高性能。

\\n

服务器强化

\\n

维格表所有服务器未使用的端口和帐户都被禁用,我们定期对云服务器进行安全扫描和补丁升级。

\\n

服务灾难恢复和业务连续性

\\n

维格表的服务均采用多副本冗余机制,分布在多个不同区域内,在单个区域发生故障的情况下,其他区域会接管并平稳地进行切换操作。除此之外,我们还制定了业务连续性计划并对基础架构进行持续监控,确保维格表的各项服务能够正常运行。

\\n

管理权限

\\n

维格表采用访问控制技术严格管理服务器的访问权限。基于最小特权和基于角色的权限控制原则,最大程度地减少数据泄露的风险。登录服务器被要求使用受密码保护的 SSH 密钥和双因素身份验证,并记录所有的服务器操作,日常审核。

\\n

2.1.4 软件服务安全

\\n

代码安全

\\n

维格表的所有代码在部署到服务器之前均经过严格的安全检验,包括威胁建模、自动化测试、自动扫描和代码审核。同时我们的开发人员会进行安全培训,以保证他们掌握最新、最佳的安全开发实践,防止隐患产生。

\\n

通信加密

\\n

当用户执行访问网站或上传附件等操作时,数据会在他的设备和我们的数据中心之间加密传输。我们设置了多重安全防护来保护用户数据的传输:要求所有与服务器的连接均使用 TLS 1.2 / TLS 1.3 和现代密码算法对流量进行加密;启用了 HTTPS 安全协议,要求浏览器仅能通过加密连接与我们建立连接。

\\n

数据鉴权和隔离

\\n

为了确保数据的合法访问,维格表使用国际标准的鉴权体系,提供身份管理、认证管理和角色授权三位一体的用户业务鉴权服务。通过用户身份标识、用户授权检查、业务身份标识形成端对端的鉴权体系,防止非授权的数据访问发生。以鉴权的安全性为基础,维格表依照 SaaS 服务多租户的最佳实践,设计实现了用户团队之间数据的隔离性。

\\n

网站安全加固

\\n

维格表定期进行专业漏洞扫描, 通过Web漏洞扫描、操作系统漏洞扫描、资产内容合规检测、配置基线扫描、弱密码检测五大方面,自动发现网站或服务器暴露在网络中的安全风险,为云上业务提供多维度的安全检测服务,满足合规要求,让安全弱点无所遁形。

\\n

2.2 安全认证

\\n

2.2.1 网络安全等级保护 2.0

\\n

依据网络安全等级保护 2.0 的标准及相关条例规定,维格表对整个系统进行安全加固,正在申请认证机关的审核,将于 2022 年内完成此项认证。

\\n

中国网络安全等级保护 2.0(简称等保 2.0)于 2019 年 12 月 1 日起正式实施。等保 2.0 更加注重主动防御,从被动防御到事前、事中、事后全流程的安全可信、动态感知和全面审计,实现了对传统信息系统、基础信息网络、云计算、移动互联、物联网、大数据和工业控制系统等级保护对象的全覆盖。

\\n

2.2.2 ISO/IEC 27001:2013 信息安全管理体系

\\n

维格表按照 ISO 27001 的各项标准及相关条例规定,维格表对整个系统进行安全加固,正在申请认证机关的审核,将于2022年内完成此项认证。

\\n

通过 ISO 27001 认证,能体现企业对安全的承诺,表明企业信息安全管理已建立起一套科学有效的管理体系,能够为用户提供可靠的信息服务。目前国内外许多政府机构、银行、证券、保险公司、电信运营商、网络公司及许多跨国公司均采用了此项 ISO 标准对自己的信息安全进行系统的管理。

\\n

3. 我们如何使用 cookie 和同类技术

\\n

为确保网站正常运转,我们会在您的计算机或移动设备上存储名为 cookie 的数据文件。cookie 通常包含用户身份标识符、城市名称以及一些字符。cookie 主要的功能是便于您使用网站产品和服务,以及帮助网站统计独立访客数量等。运用 cookie 技术,我们能够为您提供更加周到的服务。我们不会将 cookie 用于本政策所述目的之外的任何用途。您可根据自己的偏好管理或删除 cookie。您可以清除计算机上保存的所有 cookie,大部分网络浏览器都设有阻止 cookie 的功能。但如果您这么做,则需要在每一次访问我们的网站时亲自更改用户设置,但您可能因为该等修改,无法登录或使用依赖于 cookie 的维格表提供的服务或功能。您可以通过更改您的浏览器设置限制维格表对 cookie 的使用。以 Chrome 浏览器为例,您可以在 Chrome 浏览器右上方的下拉菜单的“浏览器设置”中,通过“设置-高级-清除浏览数据”,选择清除您的 cookie。

\\n

4. 我们如何共享、转让、披露收集到的信息

\\n

4.1 共享您的个人信息

\\n

我们在获得您的明确同意后,会在以下地方或与授权的第三方合作伙伴共享您的个人信息。共享的个人信息的用途限制:提供基础的业务服务、协助我们向您提供服务。

\\n
    \\n
  1. \\n

    我们在法律法规及您本人的允许下,根据申请方的请求对外共享您的个人信息。

    \\n
  2. \\n
  3. \\n

    与授权的第三方合作伙伴共享:我们与我们授权过的第三方共享您的个人信息,但仅会出于本隐私权政策声明的合法、正当、必要、特定、明确的目的共享您的信息,比如您使用的设备信息、操作的时间、访问页面时长等来收集您功能的使用情况,以此帮助我们改进功能的设计。我们会审慎选择第三方和第三方服务,督促相关第三方在按照本政策或另行与您达成的约定收集和使用您的个人信息,并采取适当的安全技术和管理措施保障您的个人信息安全。

    \\n
  4. \\n
\\n

4.2 转让及披露您的个人信息

\\n

除非获取您明确的同意,否则我们不会公开转让、披露您的个人信息。

\\n

但在以下情形中,我们可以在不征求您的授权同意下,共享、转让、披露您的个人信息:

\\n
    \\n
  1. \\n

    与国家安全相关;

    \\n
  2. \\n
  3. \\n

    与犯罪侦查、起诉、审批和判决执行等有关;

    \\n
  4. \\n
  5. \\n

    行政、司法机关依法提出的要求;

    \\n
  6. \\n
  7. \\n

    为了维护您所属维格表团队的财产安全或出于其他企业主提出的合法权益合理且必要的用途

    \\n
  8. \\n
  9. \\n

    您主动公开的个人信息;

    \\n
  10. \\n
  11. \\n

    从合法渠道收集到的个人信息;

    \\n
  12. \\n
  13. \\n

    法律法规的其他情形。

    \\n
  14. \\n
\\n

如您主动公开、共享个人信息,不受本协议限制。

\\n

5. 有害信息处理

\\n

根据法律法规,我们禁止用户写入并存储一切有害信息,包括:

\\n
    \\n
  1. \\n

    违反宪法的基本原则的内容;

    \\n
  2. \\n
  3. \\n

    危害国家安全,泄露国家秘密的内容;

    \\n
  4. \\n
  5. \\n

    一切反动、破坏国家统一的言论;

    \\n
  6. \\n
  7. \\n

    破坏国家关系、民族和谐统一的内容;

    \\n
  8. \\n
  9. \\n

    封建迷信的内容;

    \\n
  10. \\n
  11. \\n

    散布谣言或不实消息扰乱社会秩序、破坏社会稳定的内容;

    \\n
  12. \\n
  13. \\n

    侵犯他人名誉、隐私等合法权益的内容;

    \\n
  14. \\n
  15. \\n

    散布淫秽、色情、赌博、暴力恐怖犯罪信息的内容;

    \\n
  16. \\n
  17. \\n

    违反国家法律、行政法规禁止的其他内容;

    \\n
  18. \\n
\\n

我们将对以上信息进行屏蔽处理。如果后续的举报中发现,我们有权对违反政策的内容进行删除,并对违反政策的用户进行封号处理,同时保留依法追究当事人的法律责任的权利。

\\n

6. 您的权利

\\n

我们根据法律法规支持并保护您个人的隐私,您对自己的个人信息拥有访问、修改、删除以及撤回的权利。

\\n
    \\n
  1. \\n

    管理账号信息:您可在【用户中心】中修改您的昵称、头像、手机号、邮箱以及密码。

    \\n
  2. \\n
  3. \\n

    账号注销:您可在【个人中心】中点击【注销】,根据页面具体提示来提交您的账号注销申请,并在您符合注销条件的情况下,我们将在30个工作日后完成注销。注销申请可在操作成功后的30日内撤回。在您主动注销账号之后,我们将停止为您提供产品或服务,并根据法律的要求删除您的个人信息,或对其进行匿名化处理,因法律规定需要留存个人信息的,我们不会再将其用于日常业务活动中。

    \\n
  4. \\n
\\n

在以下情形中,您可以通过与客服沟通向我们提出删除个人信息的请求,我们会对应做出删除响应:

\\n
    \\n
  1. \\n

    我们收集并使用了您的信息但未经过您的允许或同意;

    \\n
  2. \\n
  3. \\n

    在您同意我们收集并使用的情况下,我们使用您的个人信息时严重违反了与您的约定;

    \\n
  4. \\n
  5. \\n

    我们使用您的信息时,违反了法律法规。

    \\n
  6. \\n
\\n

在以下情形中,我们不能响应您删除的请求:

\\n
    \\n
  1. \\n

    国家安全相关;

    \\n
  2. \\n
  3. \\n

    有证据表明您存在侵权行为;

    \\n
  4. \\n
  5. \\n

    与犯罪侦查、起诉、审批和判决执行相关;

    \\n
  6. \\n
  7. \\n

    行政、司法机关依法提出的要求;

    \\n
  8. \\n
  9. \\n

    响应您的请求将损害他人或企业的合法权益。

    \\n
  10. \\n
\\n

7. 面对未成年人的的隐私策略

\\n

我们非常重视对未成年人个人信息的保护。根据相关法律法规的规定,若您是 18 周岁以下的未成年人,在使用维格表服务前,应事先取得您的家长或法定监护人的书面同意。若您是未成年人的监护人,当您对您所监护的未成年人的个人信息有相关疑问时,请通过邮件support@vikadata.com向我们告知。

\\n

8. 免责说明

\\n

就下列相关事宜的发生,我们不承担任何法律责任:

\\n
    \\n
  1. \\n

    根据法律规定或相关政府的要求提供您的企业或个人信息。

    \\n
  2. \\n
  3. \\n

    由于您将用户密码告知他人或与他人共享账户,由此导致的任何企业或个人信息的泄漏,或其他非因服务原因导致的个人信息的泄漏。

    \\n
  4. \\n
  5. \\n

    在各服务条款及声明中列明的使用方式或免责情形。

    \\n
  6. \\n
  7. \\n

    因不可抗力导致的任何后果。

    \\n
  8. \\n
\\n

9. 联系我们

\\n

有关本隐私政策或相关的隐私措施的问题,请发送邮件至 support@vikadata.com

\\n

10. 附录

\\n

第三方SDK共享信息

\\n
    \\n
  1. \\n

    为保障维格表的稳定运行、功能实现,使您能够使用和体验更丰富的服务及功能,我们的应用中会嵌入授权合作伙伴的 SDK。

    \\n
  2. \\n
  3. \\n

    我们会对软件工具开发包(SDK)进行严格的安全检测,并约定严格的数据保护措施。

    \\n
  4. \\n
  5. \\n

    此外,当您使用本平台接入的第三方服务时,您的信息将适用该第三方的隐私政策,建议您在接受相关服务前阅读并确认理解相关协议。

    \\n
  6. \\n
\\n

对我们与之共享用户信息的公司、组织和个人,我们会与其签署严格的保密协议以及信息保护约定,要求他们严格遵守我们关于数据隐私保护的说明、本隐私政策以及其他任何相关的保密和安全措施来处理用户个人信息。

\\n

\\\"在这里插入图片描述\\\"

\"\n}", - "uiConfigId": "player_step_ui_config_93", - "uiType": "privacyModal" - }, - "94": { - "uiConfig": "{\n \"title\": \"选择任务,开启探索之旅吧\",\n \"description\": \"移动鼠标来选择任务,跟随页面提示开启旅程吧~\",\n \"data\": [\n {\n \"text\": \"重命名文件,目录索引更直观\",\n \"stopEvents\": [\n \"onMouseDown\"\n ],\n \"actions\": [\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \"#FOLDER_SHOWCASE_TITLE\",\n \"emitEvent\": \"click\",\n \"nextActions\": [\n {\n \"uiType\": \"popover\",\n \"uiConfig\": \"{\\\"element\\\":\\\"#FOLDER_SHOWCASE_TITLE_INPUT\\\",\\\"placement\\\":\\\"bottom\\\",\\\"title\\\":\\\"智能引导\\\",\\\"description\\\":\\\"点击这里可以修改名称 👆\\\"}\",\n \"backdrop\": \"around_mask\"\n },\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \"#FOLDER_SHOWCASE_TITLE_INPUT\",\n \"emitEvent\": \"focus\",\n \"finishTodoWhen\": [\n \"blur\"\n ]\n }\n }\n ]\n }\n }\n ]\n },\n {\n \"text\": \"查看/修改文件夹说明,以便其他协作者理解\",\n \"actions\": [\n {\n \"uiType\": \"breath\",\n \"uiConfig\": \"{\\\"element\\\":\\\"#FOLDER_SHOWCASE_DESCRIPTION\\\"}\",\n \"backdrop\": \"around_mask\"\n },\n {\n \"uiType\": \"popover\",\n \"uiConfig\": \"{\\\"element\\\":\\\"#FOLDER_SHOWCASE_DESCRIPTION\\\",\\\"placement\\\":\\\"left\\\",\\\"title\\\":\\\"智能引导\\\",\\\"description\\\":\\\"点击这里查看/修改说明\\\"}\"\n },\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \"#FOLDER_SHOWCASE_DESCRIPTION\",\n \"finishTodoWhen\": [\n \"click\"\n ]\n }\n }\n ]\n },\n {\n \"text\": \"为避免数据泄露或误删,设置文件访问权限\",\n \"actions\": [\n {\n \"uiType\": \"breath\",\n \"uiConfig\": \"{\\\"element\\\":\\\"#FOLDER_SHOWCASE_BTN_MORE\\\"}\"\n },\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \"#FOLDER_SHOWCASE_BTN_MORE\",\n \"nextActions\": [\n {\n \"uiType\": \"breath\",\n \"uiConfig\": \"{\\\"element\\\":\\\".sc-eFehXo div:nth-of-type(1)\\\",\\\"shadowDirection\\\":\\\"inset\\\"}\"\n },\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \".sc-eFehXo div:nth-of-type(1)\",\n \"finishTodoWhen\": [\n \"click\"\n ]\n }\n }\n ]\n }\n }\n ]\n },\n {\n \"text\": \"点击任一文件节点,开始进行数据协作吧\",\n \"actions\": [\n {\n \"uiType\": \"breath\",\n \"uiConfig\": \"{\\\"element\\\":\\\"#FOLDER_SHOWCASE_FIRST_NODE\\\"}\"\n },\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \"#FOLDER_SHOWCASE_NODES_CONTAINER > div\",\n \"finishTodoWhen\": [\n \"click\"\n ]\n }\n }\n ]\n }\n ]\n}", - "uiConfigId": "player_step_ui_config_94", - "uiType": "taskList" - }, - "95": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\"title\":\"🌟星球居民们🌟\",\"children\":\"

🔒 视图锁

\\n

在视图标签栏中开启「视图锁」,其他协作者将无权对视图进行筛选、分组、排序等操作,稳稳保住数据呈现效果。

\\n

\\\"https://s1.vika.cn/space/2021/12/23/831976472d6c491599ff92076045bb89\\\"

\\n

💬 记录评论

\\n

记录评论不仅支持引用指定评论进行回复,还可以用表情 👌 和 👍 表示知会和认可,让工作琐碎事事有响应。

\\n

\\\"https://s1.vika.cn/space/2021/12/23/694dcfc45bb94cbb91437cd8119d4af2\\\"

\\n

其他优化

\\n

支持只读权限成员进行视图配置,可随心进行筛选、排序等操作,不用担心影响到其他人。

\\n

维格小组件全面更名为「维格小程序」,组件板和组件中心同步更名为「小程序面板」、「小程序中心」。

\"}", - "uiConfigId": "player_step_ui_config_95", - "uiType": "notice" - }, - "97": { - "next": "已完成添加", - "nextId": "player_contact_us_confirm_btn", - "onClose": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onNext": [ - "clear_guide_all_ui()", - "set_wizard_completed({\"curWizard\": true})", - "open_vikaby({\"defaultExpandMenu\": true, \"visible\": true})" - ], - "uiConfig": "{\n\t\"vikaby\": {\n\t\t\"title\": \"你好\",\n\t\t\"description\": \"如果在使用过程中遇到问题,请扫描右侧二维码联系我解决\",\n\t\t\"list\": \"
  • 刚注册维格表,不知道怎么用
  • 维格表可以实现我想要的效果吗
  • 使用过程出现异常问题
  • 后续支持的功能有哪些
  • 获取官方邀请码
\",\n\t\t\"tip\": \"扫码添加客服\"\n\t},\n\t\"questionnaire\": {\n\t\t\"title\": \"您好,我是维格表数字化顾问\",\n\t\t\"list\": \"[{\\\"title\\\": \\\"Bug 吐槽\\\", \\\"icon\\\": \\\"BugOutlined\\\"}, {\\\"title\\\": \\\"需求反馈\\\", \\\"icon\\\": \\\"AdviseSmallOutlined\\\"}, {\\\"title\\\": \\\"服务支持\\\", \\\"icon\\\": \\\"ServeOutlined\\\"}, {\\\"title\\\": \\\"案例推荐\\\", \\\"icon\\\": \\\"ZanOutlined\\\"}, {\\\"title\\\": \\\"解决方案\\\", \\\"icon\\\": \\\"SolutionSmallOutlined\\\"}, {\\\"title\\\": \\\"产品答疑\\\", \\\"icon\\\": \\\"InformationLargeOutlined\\\"}]\",\n\t\t\"tip\": \"扫码添加微信,获得更多专属服务\"\n\t},\n\t\"website\": {\n\t\t\"questionnaire\": \"https://s1.vika.cn/space/2023/03/02/59f4cc8e0b2b4395bf0fcd133d208e63\",\n\t\t\"vikaby\": \"https://s1.vika.cn/space/2023/03/02/defbf55d1e9646eb929f9f5d11d5c119\"\n\t},\n\t\"dingtalk\": {\n\t\t\"questionnaire\": \"https://s1.vika.cn/space/2023/03/02/964be5e3217b4fa8bfa74ef47a980093?attname=dingtalk-questionnaire.png\",\n\t\t\"vikaby\": \"https://s1.vika.cn/space/2023/03/02/964be5e3217b4fa8bfa74ef47a980093?attname=dingtalk-vikaby.png\",\n\"tip\": \"请使用钉钉扫码,加入交流群\"\n\t},\n\t\"wecom\": {\n\t\t\"questionnaire\": \"https://s1.vika.cn/space/2023/03/02/1346d5efbd5043efb2bfcba0075c0ee9\",\n\t\t\"vikaby\": \"https://s1.vika.cn/space/2023/03/02/09401a8f2d8e491a9097b9bac8b5a4e4\"\n\t},\n\t\"feishu\": {\n\t\t\"title\": \"扫码添加客服\",\n\t\t\"tip\": \"请使用飞书扫码,添加客服号备用\",\n\t\t\"description\": \"以便使用过程中遇到问题,可以随时获得服务和解答\",\n\t\t\"originUrl\": \"https://u.vika.cn/z9ygm\"\n\t}\n}", - "uiConfigId": "player_step_ui_config_97", - "uiType": "contactUs" - }, - "98": { - "next": "查看更多", - "nextId": "see_more", - "onClose": [ - "clear_guide_all_ui()", - "set_wizard_completed({\"curWizard\": true})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2022/01/21/fe33887f388649579947379203ece53b\",\n \"readMoreTxt\": \"查看更多\",\n \"readMoreUrl\": \"https://cn.bing.com\",\n \"children\": \"

2022年1月更新:第二弹

\\n
    \\n
  • 维格表功能界面支持英文语言,点亮 Hello World
  • \\n
  • 新增文件信息窗展示创建人和创建时间,管理更有序
  • \\n
  • 回收舱取消「彻底删除」,避免其他成员误删除导致无法恢复
  • \\n
  • 小助手增加「历史更新」,游历社区挖掘更多功能使用小技巧
  • \\n
\"\n}", - "uiConfigId": "player_step_ui_config_notice_0_10_5", - "uiType": "notice" - }, - "99": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"title\": \"🌟星球居民们🌟\",\n \"children\": \"

2022 年首版更新已送达,希望每个细节体验都能在「辞旧迎新」中为你提供更多便利与舒心。

\\n

📅 日期输入更包容

\\n

日期字段体验优化,单元格输入 1-14、1/14 后智能补全为 2022/01/14,想你所想

\\n

\\\"\\\"

\\n

📅 日历展示更清晰

\\n

优化日历视图展示效果,同一日期中的记录超出 5 条时自动折叠,保持页面简洁

\\n

\\\"\\\"

\\n

🎮 小程序能力拓展

\\n

小程序能力进一步开放,vika 实验室实力出道,本期练习生:抽奖幸运儿、word 文档生成器

\\n

由 Liam 研发的「抽奖幸运儿」在 2022 维格年会上首次亮相,界面简约、操作简单,出场即是焦点,承担 5 万行数据不在话下,关键还免费

\\n

\\\"\\\"

\\n

由 Kelvin 研发的「Word 文档生成器」,一键即可批量填充字段并合成新的 Word 文档,减少大量重复性工作,为职场工具人的效率而生

\\n

\\\"\\\"

\\n

*两款小程序由 vika 实验室发布,欢迎前往维格社区与开发者互动交流

\\n

👉 https://bbs.vika.cn/topic/7

\"\n}", - "uiConfigId": "player_step_ui_config_99", - "uiType": "notice" - }, - "100": { - "uiConfig": "{\n \"element\": \"#VIKABY_UPDATE_LOGS_HISTORY\",\n \"shadowDirection\":\"inset\"\n}", - "uiConfigId": "player_step_ui_config_100", - "uiType": "breath" - }, - "101": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onTarget": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \"#VIKABY_UPDATE_LOGS_HISTORY\",\n \"offsetY\": 23,\n \"placement\": \"leftCenter\",\n \"title\": \"智能引导\",\n \"description\": \"来不及查看的本期更新和历史更新记录,都可以在这里找回哦\"\n}", - "uiConfigId": "player_step_ui_config_101", - "uiType": "popover" - }, - "103": { - "next": "查看更多", - "nextId": "see_more", - "onClose": [ - "clear_guide_all_ui()", - "set_wizard_completed({\"curWizard\": true})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2022/01/21/0c57f86937e941289aae077071fc4338\",\n \"readMoreUrl\": \"https://u.vika.cn/0c85m\",\n \"children\": \"

2022年1月更新|第二弹

  • 维格表功能界面支持英文语言,点亮 Hello World
  • 回收舱取消「彻底删除」,避免其他成员误删除导致无法恢复
  • 小助手增加「历史更新」,游历社区挖掘更多功能使用小技巧
\"\n}", - "uiConfigId": "player_step_ui_config_103", - "uiType": "notice" - }, - "105": { - "onSkip": [ - "skip_current_wizard()" - ], - "uiConfig": "{\n \"element\": \".sc-jmpzUR:nth-last-of-type(2)\",\n\"placement\": \"rightCenter\",\n \"title\": \"智能引导\", \n\"description\": \"模板中心提供了 1000+ 业务自动化解决方案,可免费安装应用\", \"children\":\"\" \n}", - "uiConfigId": "player_step_ui_config_105", - "uiType": "popover" - }, - "106": { - "uiConfig": "{\n \"element\": \".sc-jmpzUR:nth-last-of-type(2)\",\n\"shadowDirection\":\"inset\"\n} ", - "uiConfigId": "player_step_ui_config_106", - "uiType": "breath" - }, - "107": { - "onNext": [ - "clear_guide_uis([\"popover\"])" - ], - "onSkip": [ - "skip_current_wizard()" - ], - "uiConfig": "{ \n\"element\": \"#WORKBENCH_SIDE_ADD_NODE_BTN\", \"placement\": \"bottom\", \"title\": \"智能引导\", \"description\": \"还没想好怎么搭建业务场景?那就先从模板开始吧~\", \"children\":\"\" }", - "uiConfigId": "player_step_ui_config_107", - "uiType": "popover" - }, - "108": { - "onTarget": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \"#WORKBENCH_SIDE_ADD_NODE_BTN\"\n}", - "uiConfigId": "player_step_ui_config_108", - "uiType": "breath" - }, - "109": { - "next": "查看更多", - "nextId": "see_more", - "onClose": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2022/02/21/d9519262565a4a96a7b838ad0bd44522\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/127\",\n \"children\": \"
  • 数据录入有窍门,日期、数字按序列自动填充,又快又稳
  • 文件信息用处多,查看创建人和创建时间,避免信息断层
  • 数据关联一步到位,基于现有架构层级轻松创建记录卡片
  • 协作空间按需采购,管理员可自主完成升级,避免创作受限
  • 打通企业微信,无需复杂配置,扫码集成后将自动同步通讯录
\"\n}", - "uiConfigId": "player_step_ui_config_109", - "uiType": "notice" - }, - "111": { - "next": "查看更多", - "nextId": "see_more", - "onClose": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2022/03/02/38faa635d13f4c158f0e91c3659af653?attname=Update_cover%402x.png\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/136\",\n \"children\": \"
  • 透视表小程序来啦,多维度的数据分析更简单
  • 单/多选列支持设置默认值,数据录入更工整规范
  • 仪表盘的小程序拖动更加丝滑流畅,排列组合更便捷
  • API创建记录和更新记录接口支持指定 viewId 参数
\"\n}", - "uiConfigId": "player_step_ui_config_111", - "uiType": "notice" - }, - "177": { - "next": "下一步", - "onClose": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onTarget": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onNext": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \"#NODE_FORM_ACTIVE\"\n} ", - "uiConfigId": "player_step_ui_config_automation_1", - "uiType": "breath" - }, - - "178": { - "description": "ui dialog for use button field first time and active node ", - "next": "下一步", - "nextId": "next_step", - "onClose": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onSkip": [ - "clear_guide_all_ui()" - ], - "onTarget": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "skip": "跳过", - "skipId": "skip", - "uiConfig": "{\n \"element\": \".TREE_NODE_ACTIVE_ONE\", \"description\": \"description\", \"title\": \"title\"\n} ", - "uiConfigId": "player_step_ui_config_button_field_node", - "uiType": "popover" - }, - - "179": { - "description": "ui dialog for use button field first time for node actived status ", - "next": "下一步", - "nextId": "next_step", - "onClose": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onSkip": [ - "clear_guide_all_ui()" - ], - "onTarget": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "skip": "跳过", - "skipId": "skip", - "uiConfig": "{\n \"element\": \"#NODE_FORM_ACTIVE\"\n} ", - "uiConfigId": "player_step_ui_config_button_field_node_form_active", - "uiType": "popover" - }, - - - "180": { - "description": "ui dialog for use button field first time active bind datasheeet ", - "nextId": "next_step", - "next": "下一步", - "onSkip": [ - "clear_guide_all_ui()" - ], - "onClose": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "skip": "跳过", - "skipId": "skip", - "onTarget": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \"#AUTOMATION_BOUND_DATASHEET\"\n} ", - "uiConfigId": "player_step_ui_config_button_field_bound_datasheet", - "uiType": "popover" - }, - - "181": { - "description": "ui dialog for use button field first time active create action ", - "next": "好的", - "nextId": "okay", - "onClose": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onSkip": [ - "clear_guide_all_ui()" - ], - "onTarget": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onNext": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \"#CONST_ROBOT_ACTION_CREATE\"\n} ", - "uiConfigId": "player_step_ui_config_button_field_action_create", - "uiType": "popover" - }, - - "124": { - "next": "下一步", - "nextId": "next_step", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \".styles_controls__3Uc0- > div\",\n\"placement\": \"left\",\n \"title\": \"展开/隐藏记录\", \n\"description\": \"待处理的记录收纳在这里,点击可设置展开或隐藏\", \n\"children\": \"\"\n}", - "uiConfigId": "player_step_ui_config_124", - "uiType": "popover" - }, - "125": { - "onTarget": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \".styles_controls__3Uc0- > div\"\n}", - "uiConfigId": "player_step_ui_config_125", - "uiType": "breath" - }, - "126": { - "uiConfig": "{\n \"element\": \"#DATASHEET_ORG_CHART_RECORD_LIST\",\n\"placement\": \"left\",\n \"title\": \"创建卡片\", \n\"description\": \"选择一条记录,拖动至左侧图形区\",\n\"offsetY\": 144\n}", - "uiConfigId": "player_step_ui_config_126", - "uiType": "popover" - }, - "127": { - "uiConfig": "{\n \"element\": \"#DATASHEET_ORG_CHART_RECORD_LIST\"\n}", - "uiConfigId": "player_step_ui_config_127", - "uiType": "breath" - }, - "128": { - "onTarget": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n\"element\": \".react-flow__node\"\n}", - "uiConfigId": "player_step_ui_config_128", - "uiType": "breath" - }, - "129": { - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \".react-flow__node\",\n\"placement\": \"bottom\",\n \"title\": \"建立卡片关系\", \n\"description\": \"再选择一条记录并拖动至卡片中,建立记录的层级关系\", \n\"children\": \"\"\n}", - "uiConfigId": "player_step_ui_config_129", - "uiType": "popover" - }, - "131": { - "next": "查看更多", - "nextId": "see_more", - "onClose": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n\"headerImg\":\"https://s1.vika.cn/space/2022/03/17/f85104a4c8c145acb83379e13cfea0dd?attname=Update_cover%402x%202.png\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/151\",\n \"children\": \"

🚀 本次更新内容

  • 小程序新品上架,支持 Excel 追加导入数据和网址字段快速预览
  • 架构视图新增横向布局,竖向和横向布局自由选择
  • 小程序 SDK 更新,支持创建/删除字段
  • 维格表安卓客户端上线,支持安卓系统手机安装使用
\"\n}", - "uiConfigId": "player_step_ui_config_131", - "uiType": "notice" - }, - "132": { - "next": "查看更多", - "nextId": "see_more", - "onClose": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n\"headerImg\":\"https://s1.vika.cn/space/2022/03/31/bb9cf7f3453e457c9473def81b081080?attname=%E4%BB%BB%E5%8A%A1%E5%88%B0%E6%9C%9F%E6%8F%90%E9%86%92.png\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/153\",\n \"children\": \"

🚀 本次更新内容

\\n
    \\n
  • 在日期单元格里轻轻一点,即可开启到期提醒
  • \\n
  • 维格视图支持冻结多列
  • \\n
  • 镜像支持导出 Excel 文件
  • \\n
  • 新增 API 接口,可创建新的维格表
  • \\n
  • 开发者自建小程序可申请上架「官方推荐」
  • \\n
\"\n}", - "uiConfigId": "player_step_ui_config_132", - "uiType": "notice" - }, - "133": { - "onTarget": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n\"element\": \".style_name__29FFH\",\n\"color\": \"orange\"\n}", - "uiConfigId": "player_step_ui_config_133", - "uiType": "breath" - }, - "134": { - "uiConfig": "{\n\"element\": \".style_editNameButton__34aL4\"\n}", - "uiConfigId": "player_step_ui_config_134", - "uiType": "breath" - }, - "135": { - "uiConfig": "{\n\"element\": \".style_topRight__2hxKm\",\n\"title\": \"设置昵称\",\n\"description\": \"希望大家怎么称呼你呢?\",\n\"placement\": \"topCenter\",\n\"posInfo\": {\n\"bottom\": \"420px\",\n\"left\": \"100px\",\n\"right\": \"\",\n\"tipNodeClasses\": [\"bottom\", \"position-center\"]\n}\n}", - "uiConfigId": "player_step_ui_config_135", - "uiType": "popover" - }, - "136": { - "uiConfig": "{}", - "uiConfigId": "player_step_ui_config_136", - "uiType": "afterSignNPS" - }, - "137": { - "next": "查看更多", - "nextId": "see_more", - "onClose": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n\"headerImg\":\"https://s1.vika.cn/space/2022/04/15/5769ab6bf20943fc8119f74f498a7cfe?attname=%E8%A1%8C%E6%95%B0%E6%8D%AE%E6%94%AF%E6%8C%81%E5%85%B3%E6%B3%A8%E6%8F%90%E9%86%92.png\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/156\",\n \"children\": \"

🚀 本次更新内容

\\n
    \\n
  • 主动关注行数据,发生变化时立即提醒
  • \\n
  • 小程序支持全屏显示,还可以URL分享同事好友
  • \\n
  • 新增两个 API 接口,创建字段和删除字段
  • \\n
  • 若干模板更新升级,支持更多新功能特性
  • \\n
  • 福利来了,完成空间站认证送免费附件容量
\"\n}", - "uiConfigId": "player_step_ui_config_137", - "uiType": "notice" - }, - "138": { - "next": "查看更多", - "nextId": "see_more", - "onClose": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2022/04/27/6a2167ddd8074078a6b13f04fa6a3f1c?attname=v0.12.7Update_cover%402x.png\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/158\",\n \"children\": \"

🚀 本次更新内容

\\n
    \\n
  • 甘特图支持设置工作日,日期和星期可同时显示
  • \\n
  • 转化分析好帮手,漏斗图小程序上架
  • \\n
  • 统计栏数据支持复制,右键即可获取数据
  • \\n
  • 优化新增行的操作体验,防止误增空白行
  • \\n
  • 日期字段支持指定接收提醒的成员或小组
  • \\n
  • 维格表已上架苹果App Store 和各大安卓应用商店
  • \\n
\"\n}", - "uiConfigId": "player_step_ui_config_138", - "uiType": "notice" - }, - "139": { - "uiConfig": "{\n\"element\": \"#toolHideField\"\n}", - "uiConfigId": "player_step_ui_config_139", - "uiType": "breath" - }, - "140": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onTarget": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \"#toolHideField\",\n\"placement\": \"bottom\",\n \"title\": \"隐藏列\", \n\"description\": \"点击即可自定义左侧列表区的显示字段\", \n\"children\": \"\"\n}", - "uiConfigId": "player_step_ui_config_140", - "uiType": "popover" - }, - "141": { - "uiConfig": "{\n\"element\": \"#toolHideExclusiveField\"\n}", - "uiConfigId": "player_step_ui_config_141", - "uiType": "breath" - }, - "143": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onTarget": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"element\": \"#toolHideExclusiveField\",\n\"placement\": \"bottom\",\n \"title\": \"隐藏图示\", \n\"description\": \"点击即可自定义右侧图形区任务条上的显示字段\", \n\"children\": \"\"\n}", - "uiConfigId": "player_step_ui_config_143", - "uiType": "popover" - }, - "144": { - "next": "查看详情", - "nextId": "check_detail", - "onClose": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2022/05/12/988aad1e382d49f88119873473c2ffe9\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/180\",\n \"children\": \"

🚀 本次更新内容

\\n
    \\n
  • 腾讯云HiFlow场景连接器,办公自动化流程小程序上线
  • \\n
  • 甘特图自定义显示字段数量,任务条更清爽
  • 神奇表单支持修改配置信息,提升表单编辑效率
  • 镜像功能再升级,镜像也可以对外分享
\"\n}", - "uiConfigId": "player_step_ui_config_144", - "uiType": "notice" - }, - "145": { - "next": "查看详情", - "nextId": "check_detail", - "onClose": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2022/05/26/620822443f6244c4ba665bcc8e056135\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/185\",\n \"children\": \"

🚀 本次更新内容

\\n
    \\n
  • 暗黑模式正式上线,给你全新的视觉体验
  • \\n
  • 看板视图支持隐藏分组,分组信息显示更自由
  • 维格列名称支持换行,名称再长也能显示
  • 安全设置升级,可按权限角色限制导出文件
  • 空间站成员管理,支持筛选已加入和未加入的成员
  • 若干模板上新,覆盖更多行业场景
\"\n}", - "uiConfigId": "player_step_ui_config_145", - "uiType": "notice" - }, - "152": { - "next": "查看详情", - "nextId": "check_detail", - "onClose": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2022/06/13/0cea3e8831a94518b2c9e546b1ccbb8e\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/194\",\n \"children\": \"

🚀 本次更新内容

\\n
    \\n
  • 甘特视图、维格视图导出功能升级,可生成图片
  • \\n
  • 安全设置权限升级,可设置显示成员和小组的范围
  • 日历视图交互优化,年份月份切换更便捷
  • 安全设置升级,可按权限角色限制导出文件
  • 7个模板上新,覆盖更多行业场景
\"\n}", - "uiConfigId": "player_step_ui_config_152", - "uiType": "notice" - }, - "153": { - "next": "查看详情", - "nextId": "check_detail", - "onClose": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2022/06/23/6aa909506bba4e30aa9f3c57c9d07364\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/200\",\n \"children\": \"

🚀 本次更新内容

\\n
  • 空间站操作日志上线,成员操作明细一个不漏
  • 移动端管理功能升级,支持空间站的增删改查
  • 电商节拼单攻略等7个模板上架,覆盖更多使用场景
\"\n}", - "uiConfigId": "player_step_ui_config_153", - "uiType": "notice" - }, - "154": { - "next": "查看详情", - "nextId": "check_detail", - "onClose": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2022/07/23/ad9d1b758e7f46e6839b0e6791a8fb31\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/209\",\n \"children\": \"

🚀 本次更新内容

\\n
  • 网址字段升级,可自动获取网页标题
  • 「隐藏列」列名称支持点击快速在表格里高亮定位
  • 管理员可禁止成员在根目录下创建文件
  • 手机端支持查看和使用表格里的小程序
  • 「坐标地图」、「Airtable 导入」两款小程序上架
\"\n}", - "uiConfigId": "player_step_ui_config_154", - "uiType": "notice" - }, - "155": { - "next": "查看详情", - "nextId": "check_detail", - "onClose": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2022/08/04/0712f98ea50943f08e2213a3f1ebe601\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/220\",\n \"children\": \"

🚀 本次更新内容

\\n
  • 新增「只可更新」权限,协作更精细化
  • 记录卡片新增“侧边栏”和“全屏”两种布局
  • 记录卡片支持修改列配置,操作更轻便
  • 12个模板上新,覆盖更多行业和使用场景
  • API 面板新增调试入口
\"\n}", - "uiConfigId": "player_step_ui_config_155", - "uiType": "notice" - }, - "156": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "clear_guide_all_ui()" - ], - "uiConfig": "{\n \"element\": \".permission_setting_class\",\n \"placement\": \"leftCenter\",\n \"title\": \"默认权限\",\n \"description\": \"未指定权限时会显示默认的权限角色,你可以在这里直接给成员或小组指定权限\",\n \"children\":\"\" \n }", - "uiConfigId": "player_step_ui_config_156", - "uiType": "popover" - }, - "157": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "clear_guide_all_ui()" - ], - "uiConfig": "{\n \"element\": \"#resetPermissionButton\",\n \"placement\": \"topCenter\",\n \"title\": \"权限已限制\",\n \"offsetY\": -15,\n \"description\": \"因为已经设置过权限,所以仅下方列表中的成员对此可见。你可以点击这里,恢复到默认权限。\",\n \"children\":\"\" \n}", - "uiConfigId": "player_step_ui_config_157", - "uiType": "popover" - }, - "158": { - "next": "好的", - "nextId": "okay", - "onNext": [ - "clear_guide_all_ui()" - ], - "uiConfig": "{\n \"element\": \"#resetPermissionButton\",\n \"placement\": \"topCenter\",\n \"title\": \"指定权限角色\",\n \"offsetY\": -15,\n \"description\": \"你已经重新修改了该文件的权限角色,这意味着该文件仅你指定的成员可见。你可以点击“恢复默认”,撤销刚才的设置。\",\n \"children\":\"\" \n}", - "uiConfigId": "player_step_ui_config_158", - "uiType": "popover" - }, - "159": { - "next": "查看详情", - "nextId": "check_detail", - "onClose": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2022/08/19/bca3cedf0783402b953e02b83463e8f4\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/227\",\n \"children\": \"

🚀 本次更新内容

\\n
  • 日历视图支持筛选后新增记录
  • 工作目录可根据右侧面板状态自动回弹
  • 新能源车配件管理和食材配送等7 个模板上新
\"\n}", - "uiConfigId": "player_step_ui_config_159", - "uiType": "notice" - }, - "160": { - "uiConfig": "{\n \"element\": \".permission_setting_class\"\n }", - "uiConfigId": "player_step_ui_config_160", - "uiType": "breath" - }, - "161": { - "next": "查看详情", - "nextId": "check_detail", - "onClose": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2022/09/02/3ec8ee88a8c64ee2875cc24e3650a0b3\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/242\",\n \"children\": \"

🚀 本次更新内容

\\n
  • 甘特图新增任务依赖和自动编排功能
  • 简化权限设置界面,提升操作体验
  • 右键菜单可批量插入新行,助力效率提升
  • 模板中心新增中秋专题、开学季两大板块
  • 邀请好友注册并加入空间站,可获赠更多附件容量
\"\n}", - "uiConfigId": "player_step_ui_config_161", - "uiType": "notice" - }, - "162": { - "next": "查看详情", - "nextId": "check_detail", - "onClose": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2022/09/15/6eab2470b79a4ab1a6ced0fd555342a3?attname=Update_cover%402x.png\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/244\",\n \"children\": \"

🚀 本次更新内容

\\n
  • 「只可更新」权限范围调整,协作者也能新增记录
  • 空间站「安全设置」结束免费体验,正式按空间站等级提供服务
  • 5 个模板上新,覆盖财务预算、翻译项目、汽车零部件管理等场景
\"\n}", - "uiConfigId": "player_step_ui_config_162", - "uiType": "notice" - }, - "163": { - "next": "查看详情", - "nextId": "check_detail", - "onClose": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2022/09/30/74b29d31dbc44eb48949acd6dff3bd65?attname=Update_cover%402x%203.png\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/246\",\n \"children\": \"

🚀 本次更新内容

\\n
  • 新增「角色」功能,权限分配与任务指派更灵活
  • 「成员」选择框增加悬浮式信息卡片
  • 右键菜单新增「移动至」选项,文件分类归纳更快捷
  • 模板中心新增假期旅游攻略、自卷指南和复盘规划三大专题
\"\n}", - "uiConfigId": "player_step_ui_config_163", - "uiType": "notice" - }, - "164": { - "next": "查看详情", - "nextId": "check_detail", - "onClose": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2022/10/20/1dc32d8aa47b4863a97ea84ce11ecc60?attname=Update_cover%402x.png\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/252\",\n \"children\": \"

🚀 本次更新内容

\\n
  • 模板中心新增「专题」板块,更多元化的模板介绍
  • 全新帮助中心上线,提供更丰富的内容
  • 部分功能结束免费体验,正式按空间站等级提供服务
\"\n}", - "uiConfigId": "player_step_ui_config_164", - "uiType": "notice" - }, - "166": { - "backdrop": "around_mask", - "next": "获取特殊优惠", - "nextId": "claim_special_offer", - "onClose": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "skipId": "maybe_later", - "uiConfig": "{\n \"title\": \"恭喜你!获得试用权益\",\n \"description\": \"你获得了14天Pro版本的试用权益,你可以点击按钮查看详情\",\n \"listHeader\": \"试用权益:\",\n \"listContent\": [\n \"空间站记录总数上限提高至 2,000,000 行\",\n \"空间站附件容量数提高至 140 GB\",\n \"支持调用所有高级 API\"\n ],\n \"listFooter\": \"更多权益\",\n \"url\": \"https://apitable.com/management/upgrade\n}", - "uiConfigId": "player_step_ui_config_166", - "uiType": "billingStrip" - }, - "167": { - "backdrop": "around_mask", - "next": "确定", - "nextId": "confirm", - "onClose": [ - "open_guide_next_step({\"clearAllPrevUi\":true})", - "open_guide_wizard(18)" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"config\": [\n {\n \"key\": 1,\n \"name\": \"answer1\",\n \"title\": \"您希望通过 APITable 解决哪些问题?\",\n \"type\": \"multiButton\",\n \"answers\": [\n \"IT 运维支持\",\n \"教育\",\n \"项目管理\",\n \"市场营销\",\n \"产品管理\",\n \"招聘管理\",\n \"运营\",\n \"金融财务\",\n \"销售 & 客户管理\",\n \"软件开发\",\n \"人力资源 & 合规\",\n \"设计 & 创意\",\n \"非盈利组织\",\n \"制造业\",\n \"其他\"\n ],\n \"lastAllowInput\": false\n },\n {\n \"key\": 2,\n \"name\": \"answer2\",\n \"title\": \"您的工作岗位是?\",\n \"type\": \"radio\",\n \"answers\": [\n \"企业主\",\n \"团队负责人\",\n \"团队成员\",\n \"自由职业者\",\n \"主管\",\n \"高管层\",\n \"副总裁\"\n ],\n \"lastAllowInput\": false\n },\n {\n \"key\": 3,\n \"name\": \"answer3\",\n \"title\": \"您的团队规模是?\",\n \"type\": \"radio\",\n \"answers\": [\n \"只有我\",\n \"2-5\",\n \"6-10\",\n \"11-15\",\n \"16-25\",\n \"25-50\",\n \"51-100\",\n \"101-500\"\n ],\n \"lastAllowInput\": false\n },\n {\n \"key\": 4,\n \"name\": \"answer4\",\n \"title\": \"您的公司规模是?\",\n \"type\": \"radio\",\n \"answers\": [\n \"1-19\",\n \"20-49\",\n \"50-99\",\n \"100-250\",\n \"251-500\",\n \"501-1500\",\n \"1500+\"\n ],\n \"lastAllowInput\": false\n },\n {\n \"key\": 5,\n \"name\": \"answer5\",\n \"title\": \"您从哪种途径了解到我们?\",\n \"type\": \"checkbox\",\n \"answers\": [\n \"搜索引擎\",\n \"YouTube\",\n \"Product Hunt\",\n \"Github\",\n \"推特\",\n \"领英\",\n \"朋友推荐\"\n ],\n \"lastAllowInput\": false\n },\n {\n \"key\": 6,\n \"name\": \"answer6\",\n \"title\": \"加入我们的Discord社区,和全世界 APITable 的使用者一起讨论使用心得吧!在使用过程中如果遇到任何问题,可以随时在社区获得解答和帮助。\",\n \"type\": \"joinUs\",\n \"url\": \"https://discord.gg/2UXAbDTJTX\",\n \"confirmText\": \"加入社区\",\n \"skipText\": \"跳过\",\n \"submit\": true\n }\n ]\n}", - "uiConfigId": "player_step_ui_config_167", - "uiType": "questionnaire" - }, - "168": { - "byEvent": [ - "datasheet_create_mirror_tip" - ], - "next": "我知道了", - "nextId": "i_knew_it", - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n\"templateKey\":\"createMirrorTip\"\n}", - "uiConfigId": "player_step_ui_config_168", - "uiType": "customTemplate" - }, - "169": { - "next": "查看详情", - "nextId": "check_detail", - "onClose": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2023/03/16/8374ca1295664675bd1155b077555113\",\n \"readMoreUrl\": \"https://help.vika.cn/changelog/23-03-16-updates\",\n \"children\": \"

🚀 新功能介绍

\\n
  • 镜像功能再次升级,可禁止查看已隐藏的字段
  • 个人设置追加时区信息,日期字段可指定时区
  • 「全局搜索」优化,新增搜索结果分类
  • 神奇表单支持隐藏官方标识
  • API 性能优化,大幅提高请求速度
\"\n}", - "uiConfigId": "player_step_ui_config_165", - "uiType": "notice" - }, - "170": { - "next": "查看详情", - "nextId": "check_detail", - "onClose": [ - "set_wizard_completed({\"curWizard\": true})", - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "onNext": [ - "open_guide_next_step({\"clearAllPrevUi\":true})" - ], - "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2023/04/04/bcf0695cf35840e6b85e032a8e5ea0a1\",\n \"readMoreUrl\": \"https://help.vika.cn/changelog/23-04-06-updates\",\n \"children\": \"

🚀 新功能介绍

\\n
  • 推出新字段类型「多级联动」,神奇表单支持多级选项
  • 脚本小程序上架,少少代码满足多多定制化
  • 维格表机器人支持「发送邮件」
  • 维格表机器人支持「发送到Slack」
\"\n}", - "uiConfigId": "player_step_ui_config_169", - "uiType": "notice" - }, - "176": { - "onClose": [ - "set_wizard_completed({\"curWizard\": true})", - "clear_guide_all_ui()" - ], - "uiConfig": "{\n\"\"title\"\":\"\"AI 功能介绍\"\",\n\"\"video\"\":\"\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\"\",\n\"\"videoId\"\":\"\"VIKA_GUIDE_VIDEO_FOR_AI\"\",\n\"\"autoPlay\"\":true\n}", - "uiConfigId": "player_step_ui_config_176", - "uiType": "modal" - } - }, - "wizard": { - "1": { - "completeIndex": -1, - "player": { - "action": [ - "recH5upxLpgTD" - ] - }, - "steps": "[[2]]" - }, - "2": { - "completeIndex": 0 - }, - "3": { - "completeIndex": -1, - "repeat": true - }, - "4": { - "completeIndex": 0, - "player": { - "action": [ - "recSciFoQEPTM" - ] - }, - "steps": "[[8,9],[12,13],[10,11]]" - }, - "5": { - "completeIndex": -1, - "repeat": true - }, - "6": { - "completeIndex": 0 - }, - "7": { - "completeIndex": 0 - }, - "8": { - "completeIndex": 0 - }, - "9": { - "completeIndex": 0 - }, - "10": { - "completeIndex": 0 - }, - "11": { - "completeIndex": 0, - "endTime": 1620628680000, - "startTime": 1620023880000 - }, - "12": { - "completeIndex": 0 - }, - "13": { - "completeIndex": 0, - "steps": "[[3]]" - }, - "14": { - "completeIndex": -1, - "freeVCount": 200, - "integral_action": "wizard_video_reward", - "repeat": true, - "steps": "[[4]]" - }, - "15": { - "completeIndex": -1, - "freeVCount": 200, - "integral_action": "wizard_video_reward", - "repeat": true, - "steps": "[[5]]" - }, - "16": { - "completeIndex": -1, - "freeVCount": 200, - "integral_action": "wizard_video_reward", - "repeat": true, - "steps": "[[6]]" - }, - "17": { - "completeIndex": -1, - "freeVCount": 200, - "integral_action": "wizard_video_reward", - "repeat": true, - "steps": "[[7]]" - }, - "18": { - "completeIndex": 1, - "player": { - "action": [ - "recMKNK2u3tkA" - ] - }, - "repeat": true, - "steps": "[[107,108],[105,106]]" - }, - "19": { - "completeIndex": 0, - "player": { - "action": [ - "recl36N2sBDBe" - ] - }, - "steps": "[[14],[15,16],[17],[18],[20,21],[22]]" - }, - "20": { - "completeIndex": -1, - "freeVCount": 1000, - "integral_action": "complete_bind_email" - }, - "21": { - "completeIndex": -1, - "manualActions": [ - "open_vikaby({\n\"visible\": true,\n\"defaultExpandDialog\": true,\n\"dialogConfig\": {\n\"title\": \"维格表首届模板征集大赛\",\n\"description\":\"分享你的模板,免费获得200G空间赠礼,并有机会获得20人版6个月白银空间站!\",\n\"btnText\":\"查看详情\",\n\"btnUrl\": \"https://u.vika.cn/3pkza\",\n\"wizardId\": 21\n}\n}\n )" - ], - "player": { - "action": [ - "recCrcOjScQhC", - "rec2I8ZbLDFGw" - ] - } - }, - "22": { - "completeIndex": 0, - "player": { - "action": [ - "recbAdanWwVvE" - ] - }, - "steps": "[[23],[24]]" - }, - "23": { - "completeIndex": 0, - "steps": "[[40,41],[42]]" - }, - "24": { - "completeIndex": 0, - "player": { - "action": [ - "recH5upxLpgTD" - ] - }, - "steps": "[[44]]" - }, - "25": { - "completeIndex": -1, - "player": { - "action": [ - "recpp069I2Fvi" - ] - }, - "steps": "[[43]]" - }, - "26": { - "completeIndex": 0, - "manualActions": [ - "open_vikaby({\n\"visible\":true,\n\"defaultExpandTodo\": true,\n\"defaultExpandMenu\": false\n})" - ] - }, - "27": { - "completeIndex": 0, - "steps": "[[45]]" - }, - "28": { - "completeIndex": 0, - "steps": "[[46]]" - }, - "29": { - "completeIndex": 0, - "player": { - "action": [ - "recBtbbzXDolQ" - ] - }, - "steps": "[[47,48],[49],[50],[51,52],[53],[54]]" - }, - "30": { - "completeIndex": 0, - "player": { - "action": [ - "recnbU7bovh9p" - ] - }, - "steps": "[[55],[56,57],[58],[50],[51,52],[59],[60],[61]]" - }, - "31": { - "completeIndex": 0, - "player": { - "action": [ - "recH7YVXq8ev2" - ] - }, - "steps": "[[49],[50],[51,52],[53],[54]]" - }, - "32": { - "completeIndex": 0, - "steps": "[[62]]" - }, - "33": { - "completeIndex": 0, - "steps": "[[63]]" - }, - "34": { - "completeIndex": -1, - "repeat": true, - "steps": "[[64]]" - }, - "35": { - "completeIndex": 0, - "player": { - "action": [ - "recWzFTYL5aqi" - ] - }, - "steps": "[[64]]" - }, - "36": { - "completeIndex": 0, - "steps": "[[65]]" - }, - "37": { - "completeIndex": -1, - "repeat": true, - "steps": "[[66]]" - }, - "38": { - "completeIndex": 0, - "player": { - "action": [ - "recUsJf5WI1XK" - ] - }, - "steps": "[[66]]" - }, - "39": { - "completeIndex": 0, - "steps": "[[67]]" - }, - "40": { - "completeIndex": 0, - "player": { - "action": [ - "rec3Wfcm2vUu4" - ] - }, - "steps": "[[70],[68],[69]]" - }, - "41": { - "completeIndex": 0, - "player": { - "action": [ - "recksrkgpIWGA" - ] - }, - "repeat": true, - "steps": "[[71]]" - }, - "42": {}, - "43": {}, - "44": { - "completeIndex": 0, - "steps": "[[72]]" - }, - "45": { - "completeIndex": 0, - "steps": "[[76],[73]]" - }, - "46": { - "completeIndex": 0, - "player": { - "action": [ - "reczvbPaxSPAU" - ] - }, - "steps": "[[74]]" - }, - "47": { - "completeIndex": 0, - "player": { - "action": [ - "recV5500IVb6G" - ] - }, - "steps": "[[75]]" - }, - "48": { - "completeIndex": 0, - "steps": "[[76]]" - }, - "49": { - "completeIndex": 0, - "steps": "[[77]]" - }, - "50": { - "completeIndex": 0, - "manualActions": [ - "open_guide_wizard(50)" - ], - "player": { - "action": [ - "recepgn7o0mNn" - ] - }, - "steps": "[[78]]" - }, - "51": { - "completeIndex": 0, - "manualActions": [ - "open_guide_wizard(51)" - ], - "player": { - "action": [ - "recnv8Qb15HQI" - ] - }, - "steps": "[[79]]" - }, - "52": { - "completeIndex": 0, - "manualActions": [ - "open_guide_wizard(52)" - ], - "player": { - "action": [ - "recoiIMY1gIXm" - ] - }, - "steps": "[[80]]" - }, - "53": { - "completeIndex": 0, - "steps": "[[81]]" - }, - "54": { - "completeIndex": -1, - "repeat": true, - "steps": "[[82]]" - }, - "55": { - "completeIndex": 0, - "player": { - "action": [ - "rech73EZuut4l" - ] - }, - "steps": "[[82]]" - }, - "56": { - "completeIndex": 0, - "steps": "[[83, 84]]" - }, - "57": { - "completeIndex": 0, - "player": { - "action": [ - "rec7Y8opYoPK5" - ] - }, - "steps": "[[85]]" - }, - "58": { - "completeIndex": 0, - "player": { - "action": [ - "recNjTOtE8kzG" - ] - }, - "steps": "[[86,87],[88,89],[90,91]]" - }, - "59": { - "completeIndex": 0, - "steps": "[[92]]" - }, - "60": { - "completeIndex": 0 - }, - "61": { - "completeIndex": -1, - "player": { - "action": [ - "recWziPefmN7N" - ] - }, - "steps": "[[94]]" - }, - "62": { - "completeIndex": 0, - "steps": "[[95]]" - }, - "63": { - "completeIndex": 0, - "steps": "[[97]]" - }, - "64": { - "completeIndex": -1, - "repeat": true, - "steps": "[[97]]" - }, - "65": { - "completeIndex": -1, - "steps": "[[98]]" - }, - "66": { - "completeIndex": 0, - "steps": "[[99]]" - }, - "67": { - "completeIndex": 0, - "repeat": true, - "steps": "[[100,101]]" - }, - "68": { - "completeIndex": -1, - "steps": "[[93]]" - }, - "69": { - "completeIndex": -1, - "repeat": true, - "steps": "[[103]]" - }, - "70": { - "completeIndex": 1, - "repeat": true, - "steps": "[[26,27],[28,29],[30],[32],[35],[37,38],[39]]" - }, - "71": { - "completeIndex": -1, - "steps": "[[109]]" - }, - "72": { - "steps": "[[93]]" - }, - "73": { - "steps": "[[93]]" - }, - "74": { - "steps": "[[93]]" - }, - "75": { - "steps": "[[93]]" - }, - "76": { - "player": { - "action": [ - "recBtbbzXDolQ", - "recEIcl9v4jzr", - "recZmyGfgUNR6" - ] - }, - "steps": "[[93]]" - }, - "77": { - "steps": "[[111]]" - }, - "78": { - "completeIndex": 1, - "player": { - "action": [ - "recBEBtlrHNqc" - ] - }, - "steps": "[[83]]" - }, - "79": { - "completeIndex": 0, - "steps": "[[126,127]]" - }, - "80": { - "completeIndex": 0, - "steps": "[[128,129]]" - }, - "81": { - "completeIndex": 0, - "steps": "[[124,125],[88,89]]" - }, - "82": { - "completeIndex": -1, - "steps": "[[131]]" - }, - "83": { - "completeIndex": -1, - "steps": "[[132],[137]]" - }, - "84": { - "completeIndex": 0, - "player": { - "action": [ - "rec5MG0Q07sgC" - ] - }, - "steps": "[[135,133]]" - }, - "85": { - "player": { - "action": [ - "recpiCI64j675" - ] - }, - "repeat": true, - "steps": "[[136]]" - }, - "86": { - "steps": "[[137]]" - }, - "87": { - "player": { - "action": [ - "recZmyGfgUNR6" - ] - }, - "steps": "[[138]]" - }, - "88": { - "completeIndex": 0, - "player": { - "action": [ - "recGMkwh9WpxC" - ] - }, - "steps": "[[139,140],[141,143]]" - }, - "89": { - "completeIndex": -1, - "steps": "[[144]]" - }, - "90": { - "completeIndex": -1, - "steps": "[[145]]" - }, - "91": { - "completeIndex": -1, - "steps": "[[152]]" - }, - "92": { - "completeIndex": -1, - "steps": "[[153]]" - }, - "93": { - "completeIndex": -1, - "steps": "[[154]]" - }, - "94": { - "completeIndex": -1, - "steps": "[[155]]" - }, - "95": { - "completeIndex": 0, - "steps": "[[156,160]]" - }, - "96": { - "completeIndex": 0, - "steps": "[[157]]" - }, - "97": { - "completeIndex": 0, - "steps": "[[158]]" - }, - "98": { - "completeIndex": -1, - "steps": "[[159]]" - }, - "99": { - "completeIndex": -1, - "steps": "[[161]]" - }, - "100": { - "completeIndex": -1, - "steps": "[[162]]" - }, - "101": { - "completeIndex": -1, - "steps": "[[163]]" - }, - "102": { - "completeIndex": -1, - "steps": "[[164]]" - }, - "104": { - "completeIndex": 0, - "player": { - "action": [ - "recRyoECYFqBv" - ] - }, - "steps": "[[166]]" - }, - "105": { - "completeIndex": -1, - "player": { - "action": [ - "recRyoECYFqBv" - ] - }, - "steps": "[[167]]" - }, - "106": { - "manualActions": [ - "open_guide_wizard(106)" - ], - "player": { - "action": [ - "recO09HUv27dd" - ] - }, - "steps": "[[168]]" - }, - "107": { - "completeIndex": -1, - "steps": "[[169]]" - }, - "108": { - "completeIndex": -1, - "endTime": 1677677940000 - }, - "109": { - "completeIndex": -1, - "player": { - "action": [ - "recEIcl9v4jzr", - "recBtbbzXDolQ" - ] - }, - "steps": "[[170]]" - }, - - "118": { - "description": "steps for automation button", - "completeIndex": 0, - "player": { - "action": [ - "rec4kT7UZkdww" - ] - }, - "repeat": false, - "steps": "[[178], [179], [180], [181]]" - }, - - "117": { - "completeIndex": -1, - "player": { - "action": [ - "rec4kT7UZkdww" - ] - }, - "steps": "[[177]]" - }, - "115": { - "completeIndex": -1, - "player": { - "action": [ - "recIPTZiGHiIK" - ] - }, - "steps": "[[176]]" - } - } - }, - "integral": { - "rule": { - "be_invited_to_reward": { - "action_code": "be_invited_to_reward", - "action_name": "被邀请奖励", - "day_max_integral_value": 0, - "display_name": [ - "be_invited_to_reward" - ], - "integral_value": 1000, - "notify": true, - "online": true - }, - "complete_bind_email": { - "action_code": "complete_bind_email", - "action_name": "完成绑定邮箱奖励", - "day_max_integral_value": 0, - "display_name": [ - "complete_bind_email" - ], - "integral_value": 1000, - "online": true - }, - "first_bind_email": { - "action_code": "first_bind_email", - "action_name": "首次绑定邮箱奖励", - "day_max_integral_value": 0, - "display_name": [ - "first_bind_email" - ], - "integral_value": 1000 - }, - "first_bind_phone": { - "action_code": "first_bind_phone", - "action_name": "首次绑定手机奖励", - "day_max_integral_value": 0, - "display_name": [ - "first_bind_phone" - ], - "integral_value": 1000 - }, - "fission_reward": { - "action_code": "fission_reward", - "action_name": "「“友”福同享」活动 - XX空间", - "display_name": [ - "fission_reward" - ], - "notify": true, - "online": true - }, - "invitation_reward": { - "action_code": "invitation_reward", - "action_name": "邀请奖励", - "day_max_integral_value": 0, - "display_name": [ - "invitation_reward" - ], - "integral_value": 1000, - "notify": true, - "online": true - }, - "official_adjustment": { - "action_code": "official_adjustment", - "action_name": "官方调整", - "display_name": [ - "official_adjustment" - ], - "online": true - }, - "official_invitation_reward": { - "action_code": "official_invitation_reward", - "action_name": "官方邀请奖励", - "day_max_integral_value": 0, - "display_name": [ - "official_invitation_reward" - ], - "integral_value": 500, - "notify": true, - "online": true - }, - "redemption_code": { - "action_code": "redemption_code", - "action_name": "兑换码", - "day_max_integral_value": 0, - "display_name": [ - "redemption_code" - ], - "integral_value": 0, - "online": true - }, - "wallet_activity_reward": { - "action_code": "wallet_activity_reward", - "action_name": "XXX 活动奖励", - "display_name": [ - "wallet_activity_reward" - ], - "online": true - }, - "wizard_reward": { - "action_code": "wizard_reward", - "action_name": "智能引导奖励", - "day_max_integral_value": 0, - "display_name": [ - "wizard_reward" - ], - "integral_value": 200, - "online": true - }, - "wizard_video_reward": { - "action_code": "wizard_video_reward", - "action_name": "观看引导视频奖励", - "day_max_integral_value": 0, - "display_name": [ - "wizard_video_reward" - ], - "integral_value": 200, - "online": true - } - } - }, - "locales": [ - { - "currency_name": "Pounds", - "currency_symbol": "$", - "id": "en_GB", - "strings_language": "en_US", - "currency_code": "GBD", - "name": "English(United Kingdom)" - }, - { - "currency_name": "US Dollar", - "currency_symbol": "$", - "id": "en_US", - "strings_language": "en_US", - "currency_code": "USD", - "name": "English(USA)" - }, - { - "currency_name": "日元", - "currency_symbol": "¥", - "id": "ja_JP", - "strings_language": "ja_JP", - "currency_code": "JPY", - "name": "Japan" - }, - { - "currency_name": "人民币", - "currency_symbol": "¥", - "id": "zh_CN", - "strings_language": "zh_CN", - "currency_code": "RMB", - "name": "简体中文\n" - }, - { - "currency_name": "港币", - "currency_symbol": "$", - "id": "zh_HK", - "strings_language": "zh_HK", - "currency_code": "HKD", - "name": "繁体中文(中国香港)" - }, - { - "currency_name": "新币", - "currency_symbol": "$", - "id": "zh_SG", - "strings_language": "zh_HK", - "currency_code": "SGD", - "name": "繁体中文(新加坡)" - }, - { - "currency_name": "台币", - "currency_symbol": "$", - "id": "zh_TW", - "strings_language": "zh_HK", - "currency_code": "HKD", - "name": "繁体中文(台湾)" - } - ], - "marketplace": { - "cli_9f3930dd7d7ad00c": { - "app_description": "marketplace_integration_app_dec_feishu", - "app_id": "cli_9f3930dd7d7ad00c", - "app_info": "marketplace_integration_app_info_fesihu", - "app_name": "marketplace_integration_app_name_feishu", - "app_type": "LARK_STORE", - "btn_card": { - "apps_btn_text": "marketplace_integration_btncard_appsbtntext_read_more", - "btn_action": "https://app.feishu.cn/app/cli_9f3930dd7d7ad00c", - "btn_close_action": "https://www.feishu.cn/admin/#/appCenter/manage/cli_9f3930dd7d7ad00c?lang=zh-CN", - "btn_text": "marketplace_integration_btncard_btntext_open", - "btn_type": "primary" - }, - "disable": true, - "display_order": 10, - "env": [ - "integration" - ], - "id": "cli_9f3930dd7d7ad00c", - "image": { - "height": 1072, - "id": "atcnIol43SAeV", - "mimeType": "image/png", - "name": "飞书集成.png", - "size": 362548, - "token": "space/2021/12/08/8742173785d34efc905ba1fd23227cc0", - "url": "https://s1.vika.cn/space/2021/12/08/8742173785d34efc905ba1fd23227cc0", - "width": 1600 - }, - "link_to_cms": "integration_feishu_help_url", - "logo": { - "height": 0, - "id": "atcEEp5gDuMWu", - "mimeType": "image/svg+xml", - "name": "feishu.svg", - "size": 1059, - "token": "space/2021/04/28/4c4be697b9e94672a7c65d979b60ab95", - "url": "https://s1.vika.cn/space/2021/04/28/4c4be697b9e94672a7c65d979b60ab95", - "width": 0 - }, - "modal": { - "app_description": "marketplace_integration_app_dec_feishu", - "btn_action": "https://app.feishu.cn/app/cli_9f3930dd7d7ad00c", - "btn_text": "marketplace_integration_btncard_appsbtntext_read_more", - "btn_type": "primary", - "help_link": "integration_feishu_help_url" - }, - "note": "marketplace_integration_app_note_feishu", - "type": "integration" - }, - "cli_9f614b454434500e": { - "app_description": "marketplace_integration_app_dec_feishu", - "app_id": "cli_9f614b454434500e", - "app_info": "marketplace_integration_app_info_fesihu", - "app_name": "marketplace_integration_app_name_feishu", - "app_type": "LARK_STORE", - "btn_card": { - "apps_btn_text": "marketplace_integration_btncard_appsbtntext_read_more", - "btn_action": "https://app.feishu.cn/app/cli_9f614b454434500e", - "btn_close_action": "https://www.feishu.cn/admin/#/appCenter/manage/cli_9f614b454434500e?lang=zh-CN", - "btn_text": "marketplace_integration_btncard_btntext_open", - "btn_type": "primary" - }, - "disable": true, - "display_order": 10, - "env": [ - "production" - ], - "id": "cli_9f614b454434500e", - "image": { - "height": 1072, - "id": "atcLNS2l4KYxV", - "mimeType": "image/png", - "name": "飞书集成.png", - "size": 362548, - "token": "space/2021/12/08/8742173785d34efc905ba1fd23227cc0", - "url": "https://s1.vika.cn/space/2021/12/08/8742173785d34efc905ba1fd23227cc0", - "width": 1600 - }, - "link_to_cms": "integration_feishu_help_url", - "logo": { - "height": 0, - "id": "atckEWR2o3EgR", - "mimeType": "image/svg+xml", - "name": "feishu.svg", - "size": 1059, - "token": "space/2021/04/28/4c4be697b9e94672a7c65d979b60ab95", - "url": "https://s1.vika.cn/space/2021/04/28/4c4be697b9e94672a7c65d979b60ab95", - "width": 0 - }, - "modal": { - "app_description": "marketplace_integration_app_dec_feishu", - "btn_action": "https://app.feishu.cn/app/cli_9f614b454434500e", - "btn_text": "marketplace_integration_btncard_appsbtntext_read_more", - "btn_type": "primary", - "help_link": "integration_feishu_help_url" - }, - "note": "marketplace_integration_app_note_feishu", - "type": "integration" - }, - "cli_a08120b120fad00e": { - "app_description": "marketplace_integration_app_dec_feishu", - "app_id": "cli_a08120b120fad00e", - "app_info": "marketplace_integration_app_info_fesihu", - "app_name": "marketplace_integration_app_name_feishu", - "app_type": "LARK_STORE", - "btn_card": { - "apps_btn_text": "marketplace_integration_btncard_appsbtntext_read_more", - "btn_action": "https://app.feishu.cn/app/cli_a08120b120fad00e", - "btn_close_action": "https://www.feishu.cn/admin/#/appCenter/manage/cli_a08120b120fad00e?lang=zh-CN", - "btn_text": "marketplace_integration_btncard_btntext_open", - "btn_type": "primary" - }, - "disable": true, - "display_order": 10, - "env": [ - "staging" - ], - "id": "cli_a08120b120fad00e", - "image": { - "height": 1072, - "id": "atcEedAZX3ufL", - "mimeType": "image/png", - "name": "飞书集成.png", - "size": 362548, - "token": "space/2021/12/08/8742173785d34efc905ba1fd23227cc0", - "url": "https://s1.vika.cn/space/2021/12/08/8742173785d34efc905ba1fd23227cc0", - "width": 1600 - }, - "link_to_cms": "integration_feishu_help_url", - "logo": { - "height": 0, - "id": "atc8qT4qak5kW", - "mimeType": "image/svg+xml", - "name": "feishu.svg", - "size": 1059, - "token": "space/2021/04/28/4c4be697b9e94672a7c65d979b60ab95", - "url": "https://s1.vika.cn/space/2021/04/28/4c4be697b9e94672a7c65d979b60ab95", - "width": 0 - }, - "modal": { - "app_description": "marketplace_integration_app_dec_feishu", - "btn_action": "https://app.feishu.cn/app/cli_a08120b120fad00e", - "btn_text": "marketplace_integration_btncard_appsbtntext_read_more", - "btn_type": "primary", - "help_link": "integration_feishu_help_url" - }, - "note": "marketplace_integration_app_note_feishu", - "type": "integration" - }, - "ina5200279359980055": { - "app_description": "marketplace_integration_app_dec_wechatcp", - "app_id": "ina5200279359980055", - "app_info": "marketplace_integration_app_info_wecahtcp", - "app_name": "marketplace_integration_app_name_wechatcp", - "app_type": "WECOM_STORE", - "btn_card": { - "apps_btn_text": "marketplace_integration_btncard_appsbtntext_read_more", - "btn_action": "/user/wecom/integration/bind", - "btn_text": "marketplace_integration_btncard_btntext_open", - "btn_type": "primary" - }, - "display_order": 30, - "env": [ - "integration", - "staging", - "production" - ], - "id": "ina5200279359980055", - "image": { - "height": 1072, - "id": "atcuiGRXDfIoT", - "mimeType": "image/png", - "name": "企业微信集成.png", - "size": 599396, - "token": "space/2021/12/08/772be217f729479985295ae30dc63291", - "url": "https://s1.vika.cn/space/2021/12/08/772be217f729479985295ae30dc63291", - "width": 1600 - }, - "link_to_cms": "integration_wecom_help_url", - "logo": { - "height": 0, - "id": "atcPfGUqrcZ5j", - "mimeType": "image/svg+xml", - "name": "企业微信.svg", - "size": 5878, - "token": "space/2021/04/28/e043014e0af54bf58c6bb78e92b00b60", - "url": "https://s1.vika.cn/space/2021/04/28/e043014e0af54bf58c6bb78e92b00b60", - "width": 0 - }, - "modal": { - "app_description": "marketplace_integration_app_dec_wechatcp", - "btn_text": "0", - "btn_type": "primary", - "help_link": "integration_wecom_help_url" - }, - "note": "marketplace_integration_app_note_wechatcp", - "type": "integration" - }, - "ina5645957505507647": { - "app_description": "marketplace_integration_app_dec_office_preview", - "app_id": "ina5645957505507647", - "app_info": "marketplace_integration_app_info_office_preview", - "app_name": "marketplace_integration_app_name_officepreview", - "app_type": "OFFICE_PREVIEW", - "btn_card": { - "apps_btn_text": "marketplace_integration_btncard_appsbtntext_read_more", - "btn_text": "marketplace_integration_btncard_btntext_authorize", - "btn_type": "primary" - }, - "display_order": 20, - "env": [ - "integration", - "staging", - "production" - ], - "id": "ina5645957505507647", - "image": { - "height": 1072, - "id": "atczaIPjTBq8F", - "mimeType": "image/png", - "name": "永中集成.png", - "size": 473712, - "token": "space/2021/12/08/18efb2fce9a64dc08262fc5cc8f0eac1", - "url": "https://s1.vika.cn/space/2021/12/08/18efb2fce9a64dc08262fc5cc8f0eac1", - "width": 1600 - }, - "link_to_cms": "integration_yozosoft_help_url", - "logo": { - "height": 0, - "id": "atclqW8EjJIFz", - "mimeType": "image/svg+xml", - "name": "Frame.svg", - "size": 575, - "token": "space/2021/04/28/0c070534ccda4b4dbae3f4c7c303d02e", - "url": "https://s1.vika.cn/space/2021/04/28/0c070534ccda4b4dbae3f4c7c303d02e", - "width": 0 - }, - "modal": { - "app_description": "marketplace_integration_app_dec_office_preview", - "btn_text": "marketplace_integration_btncard_appsbtntext_read_more", - "btn_type": "primary", - "help_link": "integration_yozosoft_help_url" - }, - "note": "marketplace_integration_app_note_office_preview", - "type": "integration" - }, - "ina9134969049653777": { - "app_description": "marketplace_integration_app_dec_dingtalk", - "app_id": "ina9134969049653777", - "app_info": "marketplace_integration_app_info_dingtalk", - "app_name": "marketplace_integration_app_name_dingtalk", - "app_type": "DINGTALK_STORE", - "btn_card": { - "apps_btn_text": "marketplace_integration_btncard_appsbtntext_read_more", - "btn_action": "/help/integration-dingtalk/", - "btn_text": "marketplace_integration_btncard_btntext_open", - "btn_type": "primary" - }, - "display_order": 20, - "env": [ - "integration", - "staging", - "production" - ], - "id": "ina9134969049653777", - "image": { - "height": 1072, - "id": "atcOhMLdK4DOv", - "mimeType": "image/png", - "name": "钉钉集成.png", - "size": 124923, - "token": "space/2021/12/08/46a769fdf74d4c0f8676f3ccca358643", - "url": "https://s1.vika.cn/space/2021/12/08/46a769fdf74d4c0f8676f3ccca358643", - "width": 1600 - }, - "link_to_cms": "integration_dingtalk_help_url", - "logo": { - "height": 0, - "id": "atcpH3rGddayo", - "mimeType": "image/svg+xml", - "name": "ding.svg", - "size": 1831, - "token": "space/2021/04/28/7af742cdbb3c4ae3a76e30e68bf471cb", - "url": "https://s1.vika.cn/space/2021/04/28/7af742cdbb3c4ae3a76e30e68bf471cb", - "width": 0 - }, - "modal": { - "app_description": "marketplace_integration_app_dec_dingtalk", - "btn_action": "/help/integration-dingtalk/", - "btn_text": "marketplace_integration_btncard_appsbtntext_read_more", - "btn_type": "primary", - "help_link": "integration_dingtalk_help_url" - }, - "note": "marketplace_integration_app_note_dingtalk", - "type": "integration" - } - }, - "notifications": { - "templates": { - "activity_integral_income_notify": { - "format_string": "activity_integral_income_notify", - "is_component": true, - "is_notification": true, - "notifications_type": "system", - "to_tag": "users" - }, - "activity_integral_income_toadmin": { - "format_string": "activity_integral_income_toadmin", - "is_component": true, - "is_notification": true, - "notifications_type": "system", - "to_tag": "space_main_admin" - }, - "add_record_out_of_limit": { - "can_jump": true, - "format_string": "add_record_out_of_limit_by_api_notify", - "frequency": 1, - "is_component": true, - "is_mail": true, - "is_notification": true, - "mail_template_subject": "addRecordReachedLimited", - "notifications_type": "system", - "to_tag": "users", - "url": "/workbench" - }, - "add_record_soon_to_be_limit": { - "can_jump": true, - "format_string": "add_record_soon_to_be_limit_by_api_notify", - "frequency": 1, - "is_component": true, - "is_mail": true, - "is_notification": true, - "mail_template_subject": "addRecordReachingLimited", - "notifications_type": "system", - "to_tag": "users", - "url": "/workbench" - }, - "add_sub_admin": { - "can_jump": true, - "format_string": "space_add_sub_admin", - "is_browser": true, - "is_component": true, - "is_mobile": true, - "is_notification": true, - "notifications_type": "member", - "to_tag": "members", - "url": "/management" - }, - "admin_transfer_space_widget_notify": { - "format_string": "admin_transfer_space_widget_notify", - "is_browser": true, - "is_component": true, - "is_mail": true, - "is_notification": true, - "notifications_type": "system", - "to_tag": "users" - }, - "admin_unpublish_space_widget_notify": { - "format_string": "admin_unpublish_space_widget_notify", - "is_browser": true, - "is_component": true, - "is_mail": true, - "is_notification": true, - "notifications_type": "system", - "to_tag": "users" - }, - "apply_space_beta_feature_success_notify_all": { - "can_jump": true, - "format_string": "apply_space_beta_feature_success_notify_all", - "is_notification": true, - "notifications_type": "space", - "to_tag": "all_members" - }, - "apply_space_beta_feature_success_notify_me": { - "can_jump": true, - "format_string": "apply_space_beta_feature_success_notify_me", - "is_notification": true, - "notifications_type": "space", - "to_tag": "myself" - }, - "assigned_to_group": { - "can_jump": true, - "format_string": "space_assigned_to_group", - "is_browser": true, - "is_component": true, - "is_mobile": true, - "is_notification": true, - "notifications_type": "member", - "to_tag": "members", - "url": "/management" - }, - "assigned_to_role": { - "can_jump": true, - "format_string": "space_assigned_to_role", - "is_browser": true, - "is_component": true, - "is_mobile": true, - "is_notification": true, - "notifications_type": "member", - "to_tag": "members", - "url": "/management" - }, - "auto_cancel_record_subscription": { - "can_jump": true, - "format_string": "auto_cancel_record_subscription", - "is_browser": true, - "is_mail": false, - "is_mobile": false, - "is_notification": true, - "notifications_type": [], - "to_tag": "members", - "url": "/workbench" - }, - "auto_create_record_subscription": { - "can_jump": true, - "format_string": "auto_create_record_subscription", - "is_browser": true, - "is_mail": false, - "is_mobile": false, - "is_notification": true, - "notifications_type": [], - "to_tag": "members", - "url": "/workbench" - }, - "capacity_limit": { - "billing_notify": "max_capacity_size_in_bytes", - "can_jump": true, - "format_string": "capacity_limit", - "frequency": 1, - "is_browser": true, - "is_component": true, - "is_mail": true, - "is_notification": true, - "mail_template_subject": "subscribedCapacityLimit", - "notifications_type": "space", - "to_tag": "space_admins", - "url": "/management" - }, - "changed_ordinary_user": { - "can_jump": true, - "format_string": "space_changed_ordinary_user", - "is_browser": true, - "is_component": true, - "is_mobile": true, - "is_notification": true, - "notifications_type": "member", - "to_tag": "members" - }, - "comment_mentioned": { - "can_jump": true, - "format_string": "comment_mentioned", - "is_browser": true, - "is_component": true, - "is_mail": true, - "is_mobile": true, - "is_notification": true, - "notifications_type": [], - "to_tag": "members", - "url": "/workbench" - }, - "common_system_notify": { - "format_string": "common_system_notify", - "is_browser": true, - "is_component": true, - "is_notification": true, - "notifications_type": "system", - "to_tag": "users" - }, - "common_system_notify_web": { - "format_string": "common_system_notify_web", - "is_component": true, - "notifications_type": "system", - "to_tag": "users" - }, - "datasheet_limit": { - "billing_notify": "max_sheet_nums", - "can_jump": true, - "format_string": "datasheet_limit", - "frequency": 1, - "is_browser": true, - "is_component": true, - "is_mail": true, - "is_notification": true, - "mail_template_subject": "subscribedDatasheetLimit", - "notifications_type": "space", - "to_tag": "space_admins", - "url": "/management" - }, - "datasheet_record_limit": { - "billing_notify": "max_rows_per_sheet", - "can_jump": true, - "format_string": "datasheet_record_limit", - "frequency": 1, - "is_browser": true, - "is_component": true, - "is_mail": true, - "is_notification": true, - "mail_template_subject": "subscribedDatasheetRecordLimit", - "notifications_type": "space", - "to_tag": "space_admins", - "url": "/management" - }, - "integral_income_notify": { - "format_string": "integral_income_notify", - "is_component": true, - "is_notification": true, - "notifications_type": "system", - "to_tag": "users" - }, - "invite_member_toadmin": { - "can_jump": true, - "format_string": "invite_member_toadmin", - "is_browser": true, - "is_component": true, - "is_mobile": true, - "is_notification": true, - "notifications_type": "member", - "to_tag": "space_member_admins", - "url": "/management" - }, - "invite_member_tomyself": { - "can_jump": true, - "format_string": "invite_member_tomyself", - "is_browser": true, - "is_component": true, - "is_mobile": true, - "is_notification": true, - "notifications_type": "member", - "to_tag": "myself" - }, - "invite_member_touser": { - "can_jump": true, - "format_string": "invite_member_touser", - "is_browser": true, - "is_component": true, - "is_mobile": true, - "is_notification": true, - "notifications_type": "member", - "to_tag": "members", - "url": "/workbench" - }, - "member_applied_to_close_account": { - "format_string": "member_applied_to_close_account", - "is_browser": true, - "is_component": true, - "is_notification": true, - "notifications_type": "member", - "to_tag": "space_member_admins" - }, - "new_space_widget_notify": { - "format_string": "new_space_widget_notify", - "is_browser": true, - "is_component": true, - "is_notification": true, - "notifications_type": "system", - "to_tag": "users" - }, - "new_user_welcome_notify": { - "can_jump": true, - "format_string": "new_user_welcome_notify", - "is_component": true, - "is_notification": true, - "notifications_type": "system", - "redirect_url": "new_user_welcome_notify_url", - "to_tag": "users" - }, - "quit_space": { - "can_jump": true, - "format_string": "member_quit_space", - "is_browser": true, - "is_component": true, - "is_mobile": true, - "is_notification": true, - "notifications_type": "member", - "to_tag": "space_member_admins", - "url": "/management" - }, - "remove_from_group": { - "can_jump": true, - "format_string": "remove_from_group", - "is_browser": true, - "is_component": true, - "is_mobile": true, - "is_notification": true, - "notifications_type": "member", - "to_tag": "members", - "url": "/management" - }, - "remove_from_role": { - "can_jump": true, - "format_string": "remove_from_role", - "is_browser": true, - "is_component": true, - "is_mobile": true, - "is_notification": true, - "notifications_type": "member", - "to_tag": "members", - "url": "/management" - }, - "removed_from_space_toadmin": { - "can_jump": true, - "format_string": "user_removed_by_space_toadmin", - "is_browser": true, - "is_component": true, - "is_mobile": true, - "is_notification": true, - "notifications_type": "member", - "to_tag": "space_member_admins" - }, - "removed_from_space_touser": { - "format_string": "user_removed_by_space_touser", - "is_browser": true, - "is_component": true, - "is_mobile": true, - "is_notification": true, - "notifications_type": "member", - "to_tag": "members", - "url": "/management" - }, - "removed_member_tomyself": { - "can_jump": true, - "format_string": "removed_member_tomyself", - "is_browser": true, - "is_component": true, - "is_mobile": true, - "is_notification": true, - "notifications_type": "member", - "to_tag": "myself" - }, - "server_pre_publish": { - "format_string": "server_pre_publish", - "is_browser": true, - "is_component": true, - "is_mobile": true, - "is_notification": true, - "notifications_type": "system", - "to_tag": "all_users" - }, - "single_record_comment_mentioned": { - "can_jump": true, - "format_string": "single_record_comment_mentioned", - "is_browser": true, - "is_component": true, - "is_mail": true, - "is_mobile": true, - "is_notification": true, - "notifications_type": [], - "to_tag": "members", - "url": "/workbench" - }, - "single_record_member_mention": { - "can_jump": true, - "format_string": "single_record_member_mention", - "is_browser": true, - "is_component": true, - "is_mail": true, - "is_mobile": true, - "is_notification": true, - "mail_template_subject": "remindMember", - "notifications_type": [], - "to_tag": "members", - "url": "/workbench" - }, - "space_add_primary_admin": { - "can_jump": true, - "format_string": "space_add_primary_admin", - "is_browser": true, - "is_component": true, - "is_mobile": true, - "is_notification": true, - "notifications_type": "member", - "to_tag": "members" - }, - "space_admin_limit": { - "billing_notify": "max_admin_nums", - "can_jump": true, - "format_string": "space_admin_limit", - "frequency": 1, - "is_browser": true, - "is_component": true, - "is_mail": true, - "is_notification": true, - "mail_template_subject": "subscribedAdminLimit", - "notifications_type": "space", - "to_tag": "space_admins", - "url": "/management" - }, - "space_api_limit": { - "billing_notify": "max_api_call", - "can_jump": true, - "format_string": "space_api_limit", - "frequency": 1, - "is_browser": true, - "is_component": true, - "is_mail": true, - "is_notification": true, - "mail_template_subject": "subscribedApiLimit", - "notifications_type": "space", - "to_tag": "space_admins", - "url": "/management" - }, - "space_calendar_limit": { - "billing_notify": "max_calendar_views_in_space", - "can_jump": true, - "format_string": "space_calendar_limit", - "frequency": 1, - "is_browser": true, - "is_component": true, - "is_mail": true, - "is_notification": true, - "mail_template_subject": "subscribedCalendarLimit", - "notifications_type": "space", - "to_tag": "space_admins", - "url": "/management" - }, - "space_certification_fail_notify": { - "can_jump": true, - "format_string": "space_certification_fail_notify", - "is_browser": true, - "is_component": true, - "is_notification": true, - "notifications_type": "space", - "to_tag": "users", - "url": "/management" - }, - "space_certification_notify": { - "can_jump": true, - "format_string": "space_certification_notify", - "is_browser": true, - "is_component": true, - "is_notification": true, - "notifications_type": "space", - "to_tag": "users", - "url": "/management" - }, - "space_deleted": { - "format_string": "space_has_been_deleted", - "is_browser": true, - "is_component": true, - "is_notification": true, - "notifications_type": "space", - "to_tag": "all_members" - }, - "space_dingtalk_notify": { - "billing_notify": "integration_dingtalk", - "can_jump": true, - "format_string": "space_dingtalk_notify", - "is_browser": true, - "is_component": true, - "is_mail": true, - "is_notification": true, - "notifications_type": "space", - "to_tag": "space_admins", - "url": "/management" - }, - "space_field_permission_limit": { - "billing_notify": "field_permission_nums", - "can_jump": true, - "format_string": "space_field_permission_limit", - "frequency": 1, - "is_browser": true, - "is_component": true, - "is_mail": true, - "is_notification": true, - "mail_template_subject": "subscribedFieldPermissionLimit", - "notifications_type": "space", - "to_tag": "space_admins", - "url": "/management" - }, - "space_file_permission_limit": { - "billing_notify": "file_permission_nums", - "can_jump": true, - "format_string": "space_file_permission_limit", - "frequency": 1, - "is_browser": true, - "is_component": true, - "is_mail": true, - "is_notification": true, - "mail_template_subject": "subscribedFilePermissionLimit", - "notifications_type": "space", - "to_tag": "space_admins", - "url": "/management" - }, - "space_form_limit": { - "billing_notify": "max_form_views_in_space", - "can_jump": true, - "format_string": "space_form_limit", - "frequency": 1, - "is_browser": true, - "is_component": true, - "is_mail": true, - "is_notification": true, - "mail_template_subject": "subscribedFormLimit", - "notifications_type": "space", - "to_tag": "space_admins", - "url": "/management" - }, - "space_gantt_limit": { - "billing_notify": "max_gantt_views_in_space", - "can_jump": true, - "format_string": "space_gantt_limit", - "frequency": 1, - "is_browser": true, - "is_component": true, - "is_mail": true, - "is_notification": true, - "mail_template_subject": "SubscribedGanntLimit", - "notifications_type": "space", - "to_tag": "space_admins", - "url": "/management" - }, - "space_join_apply": { - "format_string": "space_join_apply", - "is_component": true, - "is_mail": true, - "is_notification": true, - "notifications_type": "member", - "to_tag": "space_member_admins" - }, - "space_join_apply_approved": { - "can_jump": true, - "format_string": "space_join_apply_approved", - "is_component": true, - "is_notification": true, - "notifications_type": "member", - "to_tag": "users", - "url": "/workbench" - }, - "space_join_apply_refused": { - "format_string": "space_join_apply_refused", - "is_component": true, - "is_notification": true, - "notifications_type": "member", - "to_tag": "users" - }, - "space_lark_notify": { - "billing_notify": "integration_feishu", - "can_jump": true, - "format_string": "space_lark_notify", - "is_browser": true, - "is_component": true, - "is_mail": true, - "is_notification": true, - "notifications_type": "space", - "to_tag": "space_admins", - "url": "/management" - }, - "space_members_limit": { - "can_jump": true, - "format_string": "space_members_limit", - "is_browser": true, - "is_component": true, - "is_mail": true, - "is_notification": true, - "notifications_type": "space", - "to_tag": "space_admins", - "url": "/management" - }, - "space_mirror_limit": { - "billing_notify": "max_mirror_views_in_space", - "can_jump": true, - "format_string": "space_mirror_limit", - "frequency": 1, - "is_browser": true, - "is_component": true, - "is_mail": true, - "is_notification": true, - "mail_template_subject": "subscribedMirrorLimit", - "notifications_type": "space", - "to_tag": "space_admins", - "url": "/management" - }, - "space_name_change": { - "can_jump": true, - "format_string": "notification_space_name_changed", - "is_browser": true, - "is_component": true, - "is_notification": true, - "notifications_type": "space", - "to_tag": "all_members", - "url": "/workbench" - }, - "space_paid_notify": { - "format_string": "space_paid_notify", - "is_component": true, - "is_notification": true, - "notifications_type": "space", - "to_tag": "users" - }, - "space_rainbow_label_limit": { - "billing_notify": "rainbow_label", - "can_jump": true, - "format_string": "space_rainbow_label_limit", - "frequency": 1, - "is_browser": true, - "is_component": true, - "is_mail": true, - "is_notification": true, - "mail_template_subject": "subject.subscribed.rainbow.label.limit", - "notifications_type": "space", - "to_tag": "space_admins", - "url": "/management" - }, - "space_record_limit": { - "billing_notify": "max_rows_in_space", - "can_jump": true, - "format_string": "space_record_limit", - "frequency": 1, - "is_browser": true, - "is_component": true, - "is_mail": true, - "is_notification": true, - "mail_template_subject": "subscribedRecordLimit", - "notifications_type": "space", - "to_tag": "space_admins", - "url": "/management" - }, - "space_recover": { - "can_jump": true, - "format_string": "space_has_been_recover", - "is_browser": true, - "is_component": true, - "is_notification": true, - "notifications_type": "space", - "to_tag": "all_members" - }, - "space_seats_limit": { - "billing_notify": "max_seats", - "can_jump": true, - "format_string": "space_seats_limit", - "frequency": 1, - "is_browser": true, - "is_component": true, - "is_mail": true, - "is_notification": true, - "mail_template_subject": "subscribedSeatsLimit", - "notifications_type": "space", - "to_tag": "space_admins", - "url": "/management" - }, - "space_subscription_end_notify": { - "can_jump": true, - "is_browser": true, - "is_component": true, - "is_mail": true, - "is_notification": true, - "notifications_type": "space", - "to_tag": "space_admins", - "url": "/management" - }, - "space_subscription_notify": { - "can_jump": true, - "format_string": "space_subscription_notify", - "is_browser": true, - "is_component": true, - "is_notification": true, - "notifications_type": "space", - "to_tag": "space_admins", - "url": "/management" - }, - "space_time_machine_limit": { - "billing_notify": "max_remain_timemachine_days", - "can_jump": true, - "format_string": "space_time_machine_limit", - "frequency": 1, - "is_browser": true, - "is_component": true, - "is_mail": true, - "is_notification": true, - "mail_template_subject": "subject.subscribed.time.machine.limit", - "notifications_type": "space", - "to_tag": "space_admins", - "url": "/management" - }, - "space_trash_limit": { - "billing_notify": "max_remain_trash_days", - "can_jump": true, - "format_string": "space_trash_limit", - "frequency": 1, - "is_browser": true, - "is_component": true, - "is_mail": true, - "is_notification": true, - "mail_template_subject": "subject.subscribed.trash.limit", - "notifications_type": "space", - "to_tag": "space_admins", - "url": "/management" - }, - "space_trial": { - "can_jump": true, - "format_string": "space_trial", - "is_browser": true, - "is_component": true, - "is_mail": true, - "is_notification": true, - "notifications_type": "space", - "to_tag": "space_admins", - "url": "/management" - }, - "space_vika_paid_notify": { - "can_jump": true, - "is_component": true, - "is_notification": true, - "notifications_type": "space", - "to_tag": "users", - "url": "/management" - }, - "space_watermark_notify": { - "billing_notify": "watermark", - "can_jump": true, - "format_string": "space_watermark_notify", - "is_browser": true, - "is_component": true, - "is_mail": true, - "is_notification": true, - "notifications_type": "space", - "to_tag": "space_admins", - "url": "/management" - }, - "space_wecom_api_trial_end": { - "format_string": "space_wecom_api_trial_end", - "is_browser": true, - "is_notification": true, - "notifications_type": "space", - "to_tag": "all_members" - }, - "space_wecom_notify": { - "billing_notify": "integration_we_com", - "can_jump": true, - "format_string": "space_wecom_notify", - "is_browser": true, - "is_component": true, - "is_mail": true, - "is_notification": true, - "notifications_type": "space", - "to_tag": "space_admins", - "url": "/management" - }, - "space_yozooffice_notify": { - "billing_notify": "integration_yozo_office", - "can_jump": true, - "format_string": "space_yozooffice_notify", - "is_browser": true, - "is_component": true, - "is_mail": true, - "is_notification": true, - "notifications_type": "space", - "to_tag": "space_admins", - "url": "/management" - }, - "subscribed_record_cell_updated": { - "can_jump": true, - "format_string": "subscribed_record_cell_updated", - "is_browser": true, - "is_mail": true, - "is_mobile": true, - "is_notification": true, - "mail_template_subject": "subscribedRecordCellUpdated", - "notifications_type": [], - "to_tag": "members", - "url": "/workbench" - }, - "subscribed_record_commented": { - "can_jump": true, - "format_string": "subscribed_record_commented", - "is_browser": true, - "is_mail": true, - "is_mobile": true, - "is_notification": true, - "mail_template_subject": "subscribedRecordCommented", - "notifications_type": [], - "to_tag": "members", - "url": "/workbench" - }, - "task_reminder": { - "can_jump": true, - "format_string": "task_reminder", - "is_browser": true, - "is_component": true, - "is_mail": true, - "is_mobile": true, - "is_notification": true, - "mail_template_subject": "taskReminder", - "notifications_type": "space", - "to_tag": "members", - "url": "/workbench" - }, - "user_field": { - "can_jump": true, - "format_string": "field_set_you_by_user", - "is_browser": true, - "is_component": true, - "is_mail": true, - "is_mobile": true, - "is_notification": true, - "notifications_type": [], - "to_tag": "members", - "url": "/workbench" - }, - "web_publish": { - "format_string": "web_publish", - "is_component": true, - "is_mobile": true, - "notifications_type": "system", - "to_tag": "all_users" - }, - "workflow_execute_failed_notify": { - "can_jump": true, - "format_string": "workflow_execute_failed_notify", - "id": "workflow_execute_failed_notify", - "is_browser": true, - "is_mail": true, - "is_mobile": false, - "is_notification": true, - "mail_template_subject": "automationError", - "notifications_type": "space", - "to_tag": "users", - "url": "/workbench" - } - }, - "types": { - "member": { - "format_string": "notify_type_member", - "tag": "member" - }, - "record": { - "format_string": "notify_type_datasheet", - "tag": "record" - }, - "space": { - "format_string": "notify_type_space", - "tag": "space" - }, - "system": { - "format_string": "notify_type_system", - "tag": "system" - } - } - }, - "player": { - "action": [ - { - "id": "clear_guide_all_ui()", - "command": "clear_guide_all_ui", - "guide": { - "step": [ - "recsHUjGVAb1E" - ] - } - }, - { - "id": "clear_guide_uis([\"popover\"])", - "command": "clear_guide_uis", - "commandArgs": "[\"popover\"]" - }, - { - "id": "open_guide_next_step()", - "command": "open_guide_next_step" - }, - { - "id": "open_guide_next_step({\"clearAllPrevUi\":true})", - "command": "open_guide_next_step", - "commandArgs": "{\"clearAllPrevUi\":true}" - }, - { - "id": "open_guide_wizard(118)", - "description": "打开引导向导 首次Button列", - "command": "open_guide_wizard", - "commandArgs": "118" - }, - { - "id": "open_guide_wizard(117)", - "command": "open_guide_wizard", - "commandArgs": "117" - }, - { - "id": "open_guide_wizard(106)", - "command": "open_guide_wizard", - "commandArgs": "106" - }, - { - "id": "open_guide_wizard(18)", - "command": "open_guide_wizard", - "commandArgs": "18" - }, - { - "id": "open_guide_wizard(21)", - "command": "open_guide_wizard", - "commandArgs": "21" - }, - { - "id": "open_guide_wizard(22)", - "command": "open_guide_wizard", - "commandArgs": "22" - }, - { - "id": "open_guide_wizard(25)", - "command": "open_guide_wizard", - "commandArgs": "25" - }, - { - "id": "open_guide_wizard(29)", - "command": "open_guide_wizard", - "commandArgs": "29" - }, - { - "id": "open_guide_wizard(30)", - "command": "open_guide_wizard", - "commandArgs": "30" - }, - { - "id": "open_guide_wizard(35)", - "command": "open_guide_wizard", - "commandArgs": "35" - }, - { - "id": "open_guide_wizard(38)", - "command": "open_guide_wizard", - "commandArgs": "38" - }, - { - "id": "open_guide_wizard(40)", - "command": "open_guide_wizard", - "commandArgs": "40" - }, - { - "id": "open_guide_wizard(41)", - "command": "open_guide_wizard", - "commandArgs": "41" - }, - { - "id": "open_guide_wizard(46)", - "command": "open_guide_wizard", - "commandArgs": "46" - }, - { - "id": "open_guide_wizard(50)", - "command": "open_guide_wizard", - "commandArgs": "50" - }, - { - "id": "open_guide_wizard(51)", - "command": "open_guide_wizard", - "commandArgs": "51" - }, - { - "id": "open_guide_wizard(52)", - "command": "open_guide_wizard", - "commandArgs": "52" - }, - { - "id": "open_guide_wizard(55)", - "command": "open_guide_wizard", - "commandArgs": "55" - }, - { - "id": "open_guide_wizard(57)", - "command": "open_guide_wizard", - "commandArgs": "57" - }, - { - "id": "open_guide_wizard(58)", - "command": "open_guide_wizard", - "commandArgs": "58" - }, - { - "id": "open_guide_wizard(61)", - "command": "open_guide_wizard", - "commandArgs": "61" - }, - { - "id": "open_guide_wizard(78)", - "command": "open_guide_wizard", - "commandArgs": "78" - }, - { - "id": "open_guide_wizard(84)", - "command": "open_guide_wizard", - "commandArgs": "84" - }, - { - "id": "open_guide_wizard(85)", - "command": "open_guide_wizard", - "commandArgs": "85" - }, - { - "id": "open_guide_wizard(88)", - "command": "open_guide_wizard", - "commandArgs": "88" - }, - { - "id": "open_guide_wizards([105, 104])", - "command": "open_guide_wizards", - "commandArgs": "[105, 104]" - }, - { - "id": "open_guide_wizards([105, 104, 115])", - "command": "open_guide_wizards", - "commandArgs": "[105, 104, 115]" - }, - { - "id": "open_guide_wizards([19])", - "command": "open_guide_wizards", - "commandArgs": "[19]" - }, - { - "id": "open_guide_wizards([21])", - "command": "open_guide_wizards", - "commandArgs": "[21]" - }, - { - "id": "open_guide_wizards([1, 24])", - "command": "open_guide_wizards", - "commandArgs": "[1, 24]" - }, - { - "id": "open_guide_wizards([29, 76, 109])", - "command": "open_guide_wizards", - "commandArgs": "[29, 76, 109]" - }, - { - "id": "open_guide_wizards([31])", - "command": "open_guide_wizards", - "commandArgs": "[31]" - }, - { - "id": "open_guide_wizards([4])", - "command": "open_guide_wizards", - "commandArgs": "[4]" - }, - { - "id": "open_guide_wizards([76, 109])", - "command": "open_guide_wizards", - "commandArgs": "[76, 109]" - }, - { - "id": "open_guide_wizards([76, 87])", - "command": "open_guide_wizards", - "commandArgs": "[76, 87]" - }, - { - "id": "open_guide_wizards(47)", - "command": "open_guide_wizards", - "commandArgs": "47" - }, - { - "id": "open_vikaby({\n\"visible\": true,\n\"defaultExpandDialog\": true,\n\"dialogConfig\": {\n\"title\": \"维格表首届模板征集大赛\",\n\"description\":\"分享你的模板,免费获得200G空间赠礼,并有机会获得20人版6个月白银空间站!\",\n\"btnText\":\"查看详情\",\n\"btnUrl\": \"https://u.vika.cn/3pkza\",\n\"wizardId\": 21\n}\n}\n )", - "command": "open_vikaby", - "commandArgs": "{\n\"visible\": true,\n\"defaultExpandDialog\": true,\n\"dialogConfig\": {\n\"title\": \"维格表首届模板征集大赛\",\n\"description\":\"分享你的模板,免费获得200G空间赠礼,并有机会获得20人版6个月白银空间站!\",\n\"btnText\":\"查看详情\",\n\"btnUrl\": \"https://u.vika.cn/3pkza\",\n\"wizardId\": 21\n}\n}\n " - }, - { - "id": "open_vikaby({\n\"visible\":true,\n\"defaultExpandTodo\": true,\n\"defaultExpandMenu\": false\n})", - "command": "open_vikaby", - "commandArgs": "{\n\"visible\":true,\n\"defaultExpandTodo\": true,\n\"defaultExpandMenu\": false\n}" - }, - { - "id": "open_vikaby({\"defaultExpandMenu\": true, \"visible\": true})", - "command": "open_vikaby", - "commandArgs": "{\"defaultExpandMenu\": true, \"visible\": true}" - }, - { - "id": "set_wizard_completed({\"curWizard\": true})", - "command": "set_wizard_completed", - "commandArgs": "{\"curWizard\": true}", - "guide": { - "step": [ - "recQExamygtJd", - "recgn9PAJNAtX", - "recE9LnXquMPZ", - "recSkdfQ9C4uM" - ] - } - }, - { - "id": "set_wizard_completed({\"wizardId\": 14})", - "command": "set_wizard_completed", - "commandArgs": "{\"wizardId\": 14}", - "guide": { - "step": [ - "recLftzTSNtNZ" - ] - } - }, - { - "id": "skip_all_wizards()", - "command": "skip_all_wizards" - }, - { - "id": "skip_current_wizard()", - "command": "skip_current_wizard" - }, - { - "id": "skip_current_wizard({\"curWizardCompleted\": true})", - "command": "skip_current_wizard", - "commandArgs": "{\"curWizardCompleted\": true}" - } - ], - "events": { - "_": {}, - "address_shown": { - "module": "address", - "name": "shown" - }, - "app_error_logger": { - "module": "app", - "name": "error_logger" - }, - - "guide_use_automation_first_time": { - "module": "guide", - "name": "use_automation_first_time" - }, - - "guide_use_button_column_first_time": { - "module": "guide", - "name": "guide_use_button_column_first_time" - }, - - "app_modal_confirm": { - "module": "app", - "name": "modal_confirm" - }, - "app_set_user_id": { - "module": "app", - "name": "set_user_id" - }, - "app_tracker": { - "module": "app", - "name": "tracker" - }, - "datasheet_add_new_view": { - "module": "datasheet", - "name": "add_new_view" - }, - "datasheet_create_mirror_tip": { - "guide": { - "step": [ - "recixOMO4Roib" - ] - }, - "module": "datasheet", - "name": "create_mirror_tip" - }, - "datasheet_dashboard_panel_shown": { - "module": "datasheet", - "name": "dashboard_panel_shown" - }, - "datasheet_delete_record": { - "module": "datasheet", - "name": "delete_record" - }, - "datasheet_field_context_hidden": { - "module": "datasheet", - "name": "field_context_hidden" - }, - "datasheet_field_context_shown": { - "module": "datasheet", - "name": "field_context_shown" - }, - "datasheet_field_setting_hidden": { - "guide": { - "step": [ - "recMyeQyjTId0" - ] - }, - "module": "datasheet", - "name": "field_setting_hidden" - }, - "datasheet_field_setting_shown": { - "module": "datasheet", - "name": "field_setting_shown" - }, - "datasheet_gantt_view_shown": { - "module": "datasheet", - "name": "gantt_view_shown" - }, - "datasheet_grid_view_shown": { - "guide": { - "step": [ - "recYXMUXd8Rv8" - ] - }, - "module": "datasheet", - "name": "grid_view_shown" - }, - "datasheet_org_has_link_field": { - "module": "datasheet", - "name": "org_has_link_field" - }, - "datasheet_org_view_add_first_node": { - "module": "datasheet", - "name": "org_view_add_first_node" - }, - "datasheet_org_view_drag_to_unhandled_list": { - "module": "datasheet", - "name": "org_view_drag_to_unhandled_list" - }, - "datasheet_org_view_right_panel_shown": { - "module": "datasheet", - "name": "org_view_right_panel_shown" - }, - "datasheet_search_panel_hidden": { - "guide": { - "step": [ - "recnHGTjyU7Jw" - ] - }, - "module": "datasheet", - "name": "search_panel_hidden" - }, - "datasheet_search_panel_shown": { - "guide": { - "step": [ - "reczmcUK1NLK4" - ] - }, - "module": "datasheet", - "name": "search_panel_shown" - }, - "datasheet_shown": { - "module": "datasheet", - "name": "shown" - }, - "datasheet_user_menu": { - "module": "datasheet", - "name": "user_menu" - }, - "datasheet_widget_center_modal_shown": { - "guide": { - "step": [ - "reciAEMbU27Q0" - ] - }, - "module": "datasheet", - "name": "widget_center_modal_shown" - }, - "datasheet_wigdet_empty_panel_shown": { - "module": "datasheet", - "name": "wigdet_empty_panel_shown" - }, - "get_context_menu_file_more": { - "module": "get_context_menu", - "name": "file_more" - }, - "get_context_menu_folder_more": { - "module": "get_context_menu", - "name": "folder_more" - }, - "get_context_menu_root_add": { - "module": "get_context_menu", - "name": "root_add" - }, - "get_nav_list": { - "module": "get_nav", - "name": "list" - }, - "invite_entrance_modal_shown": { - "module": "invite", - "name": "entrance_modal_shown" - }, - "questionnaire_shown": { - "module": "questionnaire", - "name": "shown" - }, - "questionnaire_shown_after_sign": { - "module": "questionnaire", - "name": "shown_after_sign" - }, - "space_setting_main_admin_shown": { - "module": "space_setting", - "name": "main_admin_shown" - }, - "space_setting_member_manage_shown": { - "module": "space_setting", - "name": "member_manage_shown" - }, - "space_setting_overview_shown": { - "module": "space_setting", - "name": "overview_shown" - }, - "space_setting_sub_admin_shown": { - "module": "space_setting", - "name": "sub_admin_shown" - }, - "space_setting_workbench_shown": { - "module": "space_setting", - "name": "workbench_shown" - }, - "template_center_shown": { - "module": "template", - "name": "center_shown" - }, - "template_detail_shown": { - "module": "template", - "name": "detail_shown" - }, - "template_use_confirm_modal_shown": { - "module": "template", - "name": "use_confirm_modal_shown" - }, - "view_add_panel_shown": { - "module": "view", - "name": "add_panel_shown" - }, - "view_convert_gallery": { - "module": "view", - "name": "convert_gallery" - }, - "view_notice_auto_save_true": { - "module": "view", - "name": "notice_auto_save_true" - }, - "view_notice_view_auto_false": { - "module": "view", - "name": "notice_view_auto_false" - }, - "viewset_manual_save_tip": { - "module": "viewset", - "name": "manual_save_tip" - }, - "workbench_create_form_bth_clicked": { - "module": "workbench", - "name": "create_form_bth_clicked" - }, - "workbench_create_form_panel_shown": { - "module": "workbench", - "name": "create_form_panel_shown" - }, - "workbench_create_form_previewer_shown": { - "guide": { - "step": [ - "recZFoBGGlEJ5" - ] - }, - "module": "workbench", - "name": "create_form_previewer_shown" - }, - "workbench_entry": { - "module": "workbench", - "name": "entry" - }, - "workbench_folder_from_template_showcase_shown": { - "module": "workbench", - "name": "folder_from_template_showcase_shown" - }, - "workbench_folder_showcase_shown": { - "module": "workbench", - "name": "folder_showcase_shown" - }, - "workbench_form_container_shown": { - "module": "workbench", - "name": "form_container_shown" - }, - "workbench_hidden_vikaby_btn_clicked": { - "module": "workbench", - "name": "hidden_vikaby_btn_clicked" - }, - "workbench_no_emit": { - "module": "workbench", - "name": "no_emit" - }, - "workbench_show_trial_tip": { - "module": "workbench", - "name": "show_trial_tip" - }, - "workbench_shown": { - "module": "workbench", - "name": "shown" - }, - "workbench_space_list_shown": { - "module": "workbench", - "name": "space_list_shown" - } - }, - "jobs": { - "15_days_recall": { - "actions": [], - "cron": "0 7 * * *" - }, - "3_days_recall": { - "actions": [], - "cron": "0 7 * * *" - }, - "7_days_recall": { - "actions": [], - "cron": "0 7 * * *" - } - }, - "rule": [ - { - "operator": "IS", - "condition": "device", - "id": "device_IS_app", - "conditionArgs": "app" - }, - { - "operator": "IS", - "condition": "device", - "id": "device_IS_mobile", - "conditionArgs": "mobile" - }, - { - "operator": "IS", - "condition": "device", - "id": "device_IS_pc", - "conditionArgs": "pc" - }, - { - "operator": "IS", - "condition": "edition", - "id": "edition_IS_apitable", - "conditionArgs": "apitable" - }, - { - "operator": "IS", - "condition": "edition", - "id": "edition_IS_vika", - "conditionArgs": "vika" - }, - { - "operator": "ALL_OF_FALSE", - "condition": "identity", - "id": "identity_ALL_OF_FALSE_['sub_admin', 'main_admin', 'member']", - "conditionArgs": "['sub_admin', 'main_admin', 'member']" - }, - { - "operator": "ALL_OF_TRUE", - "condition": "identity", - "id": "identity_ALL_OF_TRUE_['main_admin']", - "conditionArgs": "['main_admin']" - }, - { - "operator": "ALL_OF_TRUE", - "condition": "identity", - "id": "identity_ALL_OF_TRUE_['sub_admin']", - "conditionArgs": "['sub_admin']" - }, - { - "operator": "ONE_OF_TRUE", - "condition": "identity", - "id": "identity_ONE_OF_TRUE_['member']", - "conditionArgs": "['member']" - }, - { - "operator": "ONE_OF_TRUE", - "condition": "identity", - "id": "identity_ONE_OF_TRUE_['sub_admin,'member']", - "conditionArgs": "['sub_admin,'member']" - }, - { - "operator": "ONE_OF_TRUE", - "condition": "labs", - "id": "labs_ONE_OF_TRUE_['view_manual_save']", - "conditionArgs": "['view_manual_save']" - }, - { - "operator": "IS_AFTER", - "condition": "sign_up_time", - "id": "sign_up_time_IS_AFTER_2022-04-10 00:00", - "conditionArgs": "2022-04-10 00:00" - }, - { - "operator": "IS_AFTER", - "condition": "sign_up_time", - "id": "sign_up_time_IS_AFTER_2023-04-06 20:00", - "conditionArgs": "2023-04-06 20:00" - }, - { - "operator": "IS_BEFORE", - "condition": "sign_up_time", - "id": "sign_up_time_IS_BEFORE_2023-04-06 20:00", - "conditionArgs": "2023-04-06 20:00" - }, - { - "operator": "EXCLUDES", - "condition": "url", - "id": "url_EXCLUDES_shareId", - "conditionArgs": "shareId" - }, - { - "operator": "EXCLUDES", - "condition": "url", - "id": "url_EXCLUDES_templateId", - "conditionArgs": "templateId" - }, - { - "operator": "GREATER_THAN", - "condition": "wizard[1].count", - "id": "wizard[1].count_GREATER_THAN_0", - "conditionArgs": "0" - }, - { - "operator": "EQUAL", - "condition": "wizard[12].count", - "id": "wizard[12].count_EQUAL_0", - "conditionArgs": "0" - }, - { - "operator": "GREATER_THAN", - "condition": "wizard[12].count", - "id": "wizard[12].count_GREATER_THAN_0", - "conditionArgs": "0" - }, - { - "operator": "EQUAL", - "condition": "wizard[14].count", - "id": "wizard[14].count_EQUAL_0", - "conditionArgs": "0" - }, - { - "operator": "GREATER_THAN", - "condition": "wizard[14].count", - "id": "wizard[14].count_GREATER_THAN_0", - "conditionArgs": "0" - }, - { - "operator": "EQUAL", - "condition": "wizard[21].count", - "id": "wizard[21].count_EQUAL_0", - "conditionArgs": "0" - }, - { - "operator": "GREATER_THAN", - "condition": "wizard[21].count", - "id": "wizard[21].count_GREATER_THAN_0", - "conditionArgs": "0" - }, - { - "operator": "GREATER_THAN", - "condition": "wizard[24].count", - "id": "wizard[24].count_GREATER_THAN_0", - "conditionArgs": "0" - }, - { - "operator": "GREATER_THAN", - "condition": "wizard[27].count", - "id": "wizard[27].count_GREATER_THAN_0", - "conditionArgs": "0" - }, - { - "operator": "GREATER_THAN", - "condition": "wizard[42].count", - "id": "wizard[42].count_GREATER_THAN_1000", - "conditionArgs": "1000" - }, - { - "operator": "GREATER_THAN", - "condition": "wizard[42].count", - "id": "wizard[42].count_GREATER_THAN_300", - "conditionArgs": "300" - }, - { - "operator": "GREATER_THAN", - "condition": "wizard[42].count", - "id": "wizard[42].count_GREATER_THAN_6000", - "conditionArgs": "6000" - }, - { - "operator": "GREATER_THAN", - "condition": "wizard[43].count", - "id": "wizard[43].count_GREATER_THAN_100", - "conditionArgs": "100" - }, - { - "operator": "GREATER_THAN", - "condition": "wizard[43].count", - "id": "wizard[43].count_GREATER_THAN_200", - "conditionArgs": "200" - }, - { - "operator": "INCLUDES", - "condition": "url", - "id": "url_INCLUDES_ai_onboarding", - "conditionArgs": "ai_onboarding" - }, - { - "operator": "EXCLUDES", - "condition": "url", - "id": "url_EXCLUDES_ai_onboarding", - "conditionArgs": "ai_onboarding" - } - ], - "tips": { - "first_node_tips": { - "desc": "保存至本地,即可编辑和下载哦!~", - "description": "你可以xxxxx哦", - "title": "亲爱的" - } - }, - "trigger": [ - { - "actions": [ - "open_guide_wizards([4])" - ], - "rules": [ - "identity_ALL_OF_TRUE_['main_admin']", - "device_IS_pc", - "sign_up_time_IS_AFTER_2023-04-06 20:00" - ], - "id": "address_shown,[identity_ALL_OF_TRUE_['main_admin'], device_IS_pc, sign_up_time_IS_AFTER_2023-04-06 20:00],[open_guide_wizards([4])]", - "event": [ - "address_shown" - ] - }, - { - "actions": [ - "open_guide_wizard(35)" - ], - "rules": [ - "device_IS_pc", - "url_EXCLUDES_templateId", - "url_EXCLUDES_shareId", - "edition_IS_vika" - ], - "id": "datasheet_add_new_view,[device_IS_pc, url_EXCLUDES_templateId, url_EXCLUDES_shareId, edition_IS_vika],[open_guide_wizard(35)]", - "event": [ - "datasheet_add_new_view" - ], - "eventState": "{\"viewType\":6}" - }, - { - "actions": [ - "open_guide_wizard(38)" - ], - "rules": [ - "device_IS_pc", - "url_EXCLUDES_templateId", - "url_EXCLUDES_shareId", - "edition_IS_vika" - ], - "id": "datasheet_add_new_view,[device_IS_pc, url_EXCLUDES_templateId, url_EXCLUDES_shareId, edition_IS_vika],[open_guide_wizard(38)]", - "event": [ - "datasheet_add_new_view" - ], - "eventState": "{\"viewType\":5}" - }, - { - "actions": [ - "open_guide_wizard(55)" - ], - "rules": [ - "device_IS_pc", - "url_EXCLUDES_templateId", - "url_EXCLUDES_shareId", - "edition_IS_vika" - ], - "id": "datasheet_add_new_view,[device_IS_pc, url_EXCLUDES_templateId, url_EXCLUDES_shareId, edition_IS_vika],[open_guide_wizard(55)]", - "event": [ - "datasheet_add_new_view" - ], - "eventState": "{\"viewType\":7}" - }, - { - "actions": [ - "open_guide_wizard(106)" - ], - "rules": [ - "device_IS_pc" - ], - "id": "datasheet_create_mirror_tip,[device_IS_pc],[open_guide_wizard(106)]", - "event": [ - "datasheet_create_mirror_tip" - ] - }, - { - "actions": [ - "open_guide_wizard(30)" - ], - "rules": [ - "device_IS_pc", - "url_EXCLUDES_templateId", - "url_EXCLUDES_shareId" - ], - "id": "datasheet_dashboard_panel_shown,[device_IS_pc, url_EXCLUDES_templateId, url_EXCLUDES_shareId],[open_guide_wizard(30)]", - "event": [ - "datasheet_dashboard_panel_shown" - ] - }, - { - "actions": [ - "open_guide_wizard(118)" - ], - "rules": [ - "device_IS_pc", - "url_EXCLUDES_templateId", - "url_EXCLUDES_shareId" - ], - "id": "guide_use_button_column_first_time,[device_IS_pc, url_EXCLUDES_templateId, url_EXCLUDES_shareId],[open_guide_wizard(118)]", - "event": [ - "guide_use_button_column_first_time" - ] - }, - { - "actions": [ - "open_guide_wizard(117)" - ], - "rules": [ - "device_IS_pc", - "url_EXCLUDES_templateId", - "url_EXCLUDES_shareId" - ], - "id": "guide_use_automation_first_time,[device_IS_pc, url_EXCLUDES_templateId, url_EXCLUDES_shareId],[open_guide_wizard(117)]", - "event": [ - "guide_use_automation_first_time" - ] - }, - { - "actions": [ - "open_guide_wizard(88)" - ], - "rules": [ - "device_IS_pc", - "url_EXCLUDES_templateId", - "url_EXCLUDES_shareId" - ], - "id": "datasheet_gantt_view_shown,[device_IS_pc, url_EXCLUDES_templateId, url_EXCLUDES_shareId],[open_guide_wizard(88)]", - "event": [ - "datasheet_gantt_view_shown" - ] - }, - { - "actions": [ - "open_guide_wizard(84)" - ], - "rules": [ - "device_IS_pc" - ], - "id": "datasheet_user_menu,[device_IS_pc],[open_guide_wizard(84)]", - "event": [ - "datasheet_user_menu" - ] - }, - { - "actions": [ - "open_guide_wizards([31])" - ], - "rules": [ - "device_IS_pc", - "sign_up_time_IS_AFTER_2023-04-06 20:00", - "url_EXCLUDES_templateId", - "url_EXCLUDES_shareId" - ], - "id": "datasheet_wigdet_empty_panel_shown,[device_IS_pc, sign_up_time_IS_AFTER_2023-04-06 20:00, url_EXCLUDES_templateId, url_EXCLUDES_shareId],[open_guide_wizards([31])]", - "event": [ - "datasheet_wigdet_empty_panel_shown" - ] - }, - { - "actions": [ - "open_guide_wizard(85)" - ], - "rules": [ - "device_IS_pc", - "sign_up_time_IS_AFTER_2022-04-10 00:00" - ], - "id": "questionnaire_shown_after_sign,[device_IS_pc, sign_up_time_IS_AFTER_2022-04-10 00:00],[open_guide_wizard(85)]", - "event": [ - "questionnaire_shown_after_sign" - ] - }, - { - "actions": [ - "open_guide_wizard(41)" - ], - "rules": [ - "device_IS_pc", - "url_EXCLUDES_shareId", - "wizard[42].count_GREATER_THAN_300", - "wizard[43].count_GREATER_THAN_100" - ], - "id": "questionnaire_shown,[device_IS_pc, url_EXCLUDES_shareId, wizard[42].count_GREATER_THAN_300, wizard[43].count_GREATER_THAN_100],[open_guide_wizard(41)]", - "event": [ - "questionnaire_shown" - ] - }, - { - "actions": [ - "open_guide_wizard(41)" - ], - "rules": [ - "wizard[42].count_GREATER_THAN_1000", - "device_IS_pc", - "url_EXCLUDES_shareId", - "wizard[43].count_GREATER_THAN_200" - ], - "id": "questionnaire_shown,[wizard[42].count_GREATER_THAN_1000, device_IS_pc, url_EXCLUDES_shareId, wizard[43].count_GREATER_THAN_200],[open_guide_wizard(41)]", - "event": [ - "questionnaire_shown" - ] - }, - { - "actions": [ - "open_guide_wizard(41)" - ], - "rules": [ - "wizard[42].count_GREATER_THAN_6000", - "identity_ALL_OF_TRUE_['main_admin']", - "device_IS_pc", - "url_EXCLUDES_shareId" - ], - "id": "questionnaire_shown,[wizard[42].count_GREATER_THAN_6000, identity_ALL_OF_TRUE_['main_admin'], device_IS_pc, url_EXCLUDES_shareId],[open_guide_wizard(41)]", - "event": [ - "questionnaire_shown" - ] - }, - { - "actions": [ - "open_guide_wizards([19])" - ], - "rules": [ - "device_IS_pc", - "identity_ALL_OF_TRUE_['main_admin']", - "sign_up_time_IS_AFTER_2023-04-06 20:00", - "url_EXCLUDES_templateId", - "url_EXCLUDES_shareId" - ], - "id": "template_center_shown,[device_IS_pc, identity_ALL_OF_TRUE_['main_admin'], sign_up_time_IS_AFTER_2023-04-06 20:00, url_EXCLUDES_templateId, url_EXCLUDES_shareId],[open_guide_wizards([19])]", - "event": [ - "template_center_shown" - ] - }, - { - "actions": [ - "open_guide_wizard(78)" - ], - "rules": [ - "device_IS_pc", - "url_EXCLUDES_templateId", - "url_EXCLUDES_shareId" - ], - "id": "view_add_panel_shown,[device_IS_pc, url_EXCLUDES_templateId, url_EXCLUDES_shareId],[open_guide_wizard(78)]", - "event": [ - "view_add_panel_shown" - ] - }, - { - "actions": [ - "open_guide_wizard(52)" - ], - "rules": [ - "labs_ONE_OF_TRUE_['view_manual_save']" - ], - "id": "view_notice_auto_save_true,[labs_ONE_OF_TRUE_['view_manual_save']],[open_guide_wizard(52)]", - "event": [ - "view_notice_auto_save_true" - ] - }, - { - "actions": [ - "open_guide_wizard(51)" - ], - "rules": [ - "labs_ONE_OF_TRUE_['view_manual_save']" - ], - "id": "view_notice_view_auto_false,[labs_ONE_OF_TRUE_['view_manual_save']],[open_guide_wizard(51)]", - "event": [ - "view_notice_view_auto_false" - ] - }, - { - "actions": [ - "open_guide_wizard(50)" - ], - "rules": [ - "labs_ONE_OF_TRUE_['view_manual_save']" - ], - "id": "viewset_manual_save_tip,[labs_ONE_OF_TRUE_['view_manual_save']],[open_guide_wizard(50)]", - "event": [ - "viewset_manual_save_tip" - ] - }, - { - "actions": [ - "open_guide_wizard(22)" - ], - "rules": [ - "device_IS_pc", - "url_EXCLUDES_templateId", - "url_EXCLUDES_shareId" - ], - "id": "workbench_create_form_bth_clicked,[device_IS_pc, url_EXCLUDES_templateId, url_EXCLUDES_shareId],[open_guide_wizard(22)]", - "event": [ - "workbench_create_form_bth_clicked" - ], - "suspended": true - }, - { - "actions": [ - "open_guide_wizard(61)" - ], - "rules": [ - "device_IS_pc", - "url_EXCLUDES_shareId" - ], - "id": "workbench_folder_from_template_showcase_shown,[device_IS_pc, url_EXCLUDES_shareId],[open_guide_wizard(61)]", - "event": [ - "workbench_folder_from_template_showcase_shown" - ] - }, - { - "actions": [ - "open_guide_wizard(46)" - ], - "rules": [ - "device_IS_pc", - "url_EXCLUDES_templateId", - "url_EXCLUDES_shareId" - ], - "id": "workbench_form_container_shown,[device_IS_pc, url_EXCLUDES_templateId, url_EXCLUDES_shareId],[open_guide_wizard(46)]", - "event": [ - "workbench_form_container_shown" - ] - }, - { - "actions": [ - "open_guide_wizard(25)" - ], - "rules": [ - "device_IS_pc", - "url_EXCLUDES_templateId", - "url_EXCLUDES_shareId" - ], - "id": "workbench_hidden_vikaby_btn_clicked,[device_IS_pc, url_EXCLUDES_templateId, url_EXCLUDES_shareId],[open_guide_wizard(25)]", - "event": [ - "workbench_hidden_vikaby_btn_clicked" - ] - }, - { - "actions": [ - "open_guide_wizards([105, 104])" - ], - "rules": [ - "device_IS_pc", - "url_EXCLUDES_templateId", - "url_EXCLUDES_shareId", - "edition_IS_apitable" - ], - "id": "workbench_show_trial_tip,[device_IS_pc, url_EXCLUDES_templateId, url_EXCLUDES_shareId, edition_IS_apitable],[open_guide_wizards([105, 104])]", - "event": [ - "workbench_show_trial_tip" - ] - }, - { - "actions": [ - "open_guide_wizards([105, 104])" - ], - "rules": [ - "device_IS_pc", - "sign_up_time_IS_AFTER_2023-04-06 20:00", - "url_EXCLUDES_templateId", - "url_EXCLUDES_shareId", - "edition_IS_apitable", - "url_EXCLUDES_ai_onboarding" - ], - "id": "workbench_shown,[device_IS_pc, sign_up_time_IS_AFTER_2023-08-23 20:00, url_EXCLUDES_templateId, url_EXCLUDES_shareId, edition_IS_apitable, url_EXCLUDES_ai_onboarding],[open_guide_wizards([105, 104])]", - "event": [ - "workbench_shown" - ] - }, - { - "actions": [ - "open_guide_wizards([105, 104, 115])" - ], - "rules": [ - "device_IS_pc", - "url_EXCLUDES_templateId", - "url_EXCLUDES_shareId", - "edition_IS_apitable", - "url_INCLUDES_ai_onboarding" - ], - "id": "workbench_shown,[device_IS_pc, url_EXCLUDES_templateId, url_EXCLUDES_shareId,edition_IS_apitable, url_INCLUDES_ai_onboarding],[open_guide_wizards([105, 104, 115])]", - "event": [ - "workbench_shown" - ] - }, - { - "actions": [ - "open_guide_wizards([1, 24])" - ], - "rules": [ - "device_IS_pc", - "sign_up_time_IS_AFTER_2023-04-06 20:00", - "url_EXCLUDES_templateId", - "url_EXCLUDES_shareId", - "edition_IS_vika" - ], - "id": "workbench_shown,[device_IS_pc, sign_up_time_IS_AFTER_2023-04-06 20:00, url_EXCLUDES_templateId, url_EXCLUDES_shareId, edition_IS_vika],[open_guide_wizards([1, 24])]", - "event": [ - "workbench_shown" - ] - }, - { - "actions": [ - "open_guide_wizards([29, 76, 109])" - ], - "rules": [ - "device_IS_pc", - "sign_up_time_IS_BEFORE_2023-04-06 20:00", - "url_EXCLUDES_templateId", - "url_EXCLUDES_shareId", - "edition_IS_vika" - ], - "id": "workbench_shown,[device_IS_pc, sign_up_time_IS_BEFORE_2023-04-06 20:00, url_EXCLUDES_templateId, url_EXCLUDES_shareId, edition_IS_vika],[open_guide_wizards([29, 76, 109])]", - "event": [ - "workbench_shown" - ] - }, - { - "actions": [ - "open_guide_wizards([76, 109])" - ], - "rules": [ - "sign_up_time_IS_BEFORE_2023-04-06 20:00", - "device_IS_mobile", - "url_EXCLUDES_templateId", - "url_EXCLUDES_shareId", - "edition_IS_vika" - ], - "id": "workbench_shown,[sign_up_time_IS_BEFORE_2023-04-06 20:00, device_IS_mobile, url_EXCLUDES_templateId, url_EXCLUDES_shareId, edition_IS_vika],[open_guide_wizards([76, 109])]", - "event": [ - "workbench_shown" - ] - }, - { - "actions": [ - "open_guide_wizards([76, 87])" - ], - "rules": [ - "sign_up_time_IS_BEFORE_2023-04-06 20:00", - "url_EXCLUDES_templateId", - "url_EXCLUDES_shareId", - "device_IS_app", - "edition_IS_vika" - ], - "id": "workbench_shown,[sign_up_time_IS_BEFORE_2023-04-06 20:00, url_EXCLUDES_templateId, url_EXCLUDES_shareId, device_IS_app, edition_IS_vika],[open_guide_wizards([76, 87])]", - "event": [ - "workbench_shown" - ] - } - ] - }, - "settings": { - "_build_branch": { - "value": "local" - }, - "_build_id": { - "value": "0" - }, - "_version_type": { - "value": "local" + "guatemala": { + "phoneCode": "502" }, - "activity_center_end_time": { - "value": "2021-05-30 19:30" + "guam": { + "phoneCode": "1671" }, - "activity_center_url": { - "value": "https://mp.weixin.qq.com/s/s2IRoAMHzsGq697TP0CCrQ" + "guyana": { + "phoneCode": "592" }, - "activity_train_camp_end_time": { - "value": "2022-08-31 23:59" + "kazakhstan": { + "phoneCode": "7" }, - "activity_train_camp_start_time": { - "value": "2022-03-31 00:00" + "haiti": { + "phoneCode": "509" }, - "agree_terms_of_service": { - "value": "75" + "south_korea": { + "phoneCode": "82" }, - "api_apiffox_patch_url": { - "value": "https://www.apifox.cn/apidoc/project-613370/api-13867672-run?path[datasheetId]=${datasheetId}&query[viewId]=${viewId}&environment[token]=${token}&environment[body]=${body}" + "netherlands": { + "phoneCode": "31" }, - "api_apiffox_post_url": { - "value": "https://www.apifox.cn/apidoc/project-613370/api-13867671-run?path[datasheetId]=${datasheetId}&query[viewId]=${viewId}&environment[token]=${token}&environment[body]=${body}" + "montenegro": { + "phoneCode": "382" }, - "api_apifox_delete_url": { - "value": "https://www.apifox.cn/apidoc/project-613370/api-13867673-run?path[datasheetId]=${datasheetId}&query[viewId]=${viewId}&query[recordIds]=${recordId}&environment[token]=${token}" + "honduras": { + "phoneCode": "504" }, - "api_apifox_get_url": { - "value": "https://www.apifox.cn/apidoc/project-613370/api-13867447-run?path[datasheetId]=${datasheetId}&query[viewId]=${viewId}&environment[token]=${token}" + "kiribati": { + "phoneCode": "686" }, - "api_apifox_upload_url": { - "value": "https://www.apifox.cn/apidoc/project-613370/api-13867674-run?path[datasheetId]=${datasheetId}&environment[token]=${token}" + "djibouti": { + "phoneCode": "253" }, - "api_times_per_day": { - "value": "1000000" + "kyrgyzstan": { + "phoneCode": "996" }, - "api_times_per_hour": { - "value": "0" + "guinea": { + "phoneCode": "224" }, - "api_times_per_minute": { - "value": "100" + "guinea_bissau": { + "phoneCode": "245" }, - "api_times_per_second": { - "value": "10" + "canada": { + "phoneCode": "1" }, - "apitable_login_logo": { - "value": "space/2022/12/05/1e36972963f64c85a7ce998c6abc075d" + "ghana": { + "phoneCode": "233" }, - "assistant": { - "value": "true" + "gabon": { + "phoneCode": "241" }, - "assistant_activity_train_camp_end_time": { - "value": "2022-08-31 23:59" + "cambodia": { + "phoneCode": "855" }, - "assistant_activity_train_camp_start_time": { - "value": "2022-03-31 00:00" + "czech": { + "phoneCode": "420" }, - "assistant_ai_course_url": { - "value": "https://vika.cn/ai-course/" + "zimbabwe": { + "phoneCode": "263" }, - "assistant_release_history_url": { - "value": "https://bbs.vika.cn/column/details/13" + "cameroon": { + "phoneCode": "237" }, - "automation_action_send_msg_to_dingtalk": { - "value": "true" + "qatar": { + "phoneCode": "974" }, - "automation_action_send_msg_to_feishu": { - "value": "true" + "cayman_islands": { + "phoneCode": "1345" }, - "automation_action_send_msg_to_wecom": { - "value": "true" + "cape_verde": { + "phoneCode": "238" }, - "billing_default_billing_period": { - "value": "annual" + "comoros": { + "phoneCode": "269" }, - "billing_default_grade": { - "value": "silver" + "kuwait": { + "phoneCode": "965" }, - "billing_default_seats": { - "value": "50" + "croatia": { + "phoneCode": "385" }, - "billing_enterprise_qr_code": { - "value": "space/2022/02/16/cf2f386d300142a19268c487b351d6bb" + "kenya": { + "phoneCode": "254" }, - "billing_pay_contact_us": { - "value": "space/2022/02/17/b32ecd3a5dcb43a1add4d320632c6d2a" + "cook_islands": { + "phoneCode": "682" }, - "billing_pay_success_qr_code": { - "value": "space/2022/02/17/b7cd077fca35444aa02fba4d11f2c1ba" + "curacao": { + "phoneCode": "599" }, - "datasheet_max_view_count_per_sheet": { - "value": "60" + "latvia": { + "phoneCode": "371" }, - "datasheet_unlogin_user_avatar": { - "value": "space/2020/09/11/744b39b7ed5240e1b257553f683ed6cd" + "lesotho": { + "phoneCode": "266" }, - "delete_account_step1_cover": { - "value": "space/2022/01/11/05fb6ad3c03b4b4da95156313b5d7777" + "laos": { + "phoneCode": "856" }, - "delete_account_step2_email_icon": { - "value": "space/2022/01/11/b0d06adfb14d457b9db266349edbf656" + "lebanon": { + "phoneCode": "961" }, - "delete_account_step2_mobile_icon": { - "value": "space/2022/01/11/ba4572da263c46ccb94843046a2a8e6c" + "lithuania": { + "phoneCode": "370" }, - "education_url": { - "value": "https://edu.vika.cn" + "liberia": { + "phoneCode": "231" }, - "email_icon": { - "value": "space/2022/12/05/0d3881bd9d3c4be59845739090d06051" + "libya": { + "phoneCode": "218" }, - "emoji_apple_32": { - "value": "space/2021/03/23/6972f73d8bfe4539b67a4d3e264771e0" + "liechtenstein": { + "phoneCode": "423" }, - "emoji_apple_64": { - "value": "space/2021/03/23/c88653f7b7424d10bef058c345f6df6d" + "reunion_island": { + "phoneCode": "262" }, - "experimental_features_unsynchronized_view_intro_img": { - "value": "space/2021/11/30/854742d76eaa46bba848d80f358f9cdf" + "luxembourg": { + "phoneCode": "352" }, - "field_cascade": { - "value": "true" + "rwanda": { + "phoneCode": "250" }, - "github_icon": { - "value": "space/2022/12/14/08393af8ffc84039a75f99b8ff01b61f" + "romania": { + "phoneCode": "40" }, - "grades_info": { - "value": "/pricing/" + "madagascar": { + "phoneCode": "261" }, - "help_assistant": { - "value": "true" + "maldives": { + "phoneCode": "960" }, - "help_contact_us_type": { - "value": "qrcode" + "malta": { + "phoneCode": "356" }, - "help_developers_center_url": { - "value": "https://vika.cn/developers" + "malawi": { + "phoneCode": "265" }, - "help_download_app": { - "value": "true" + "malaysia": { + "phoneCode": "60" }, - "help_join_chatgroup_url": { - "value": "https://vika.cn/chatgroup/" + "mali": { + "phoneCode": "223" }, - "help_official_website_url": { - "value": "vika.cn?home=1" + "macedonia": { + "phoneCode": "389" }, - "help_product_roadmap_url": { - "value": "https://bbs.vika.cn/page/product_roadmap" + "martinique": { + "phoneCode": "596" }, - "help_solution_url": { - "value": "https://vika.cn/solutions/" + "mayotte": { + "phoneCode": "269" }, - "help_subscribe_demonstrate_form_url": { - "value": "https://vika.cn/share/shrFVCtHXQwYm3DVgNn91" + "mauritius": { + "phoneCode": "230" }, - "help_user_community_url": { - "value": "{\"dev\":\"https://bbs.vika.cn\",\"prod\":\"https://bbs.vika.cn\"}" + "mauritania": { + "phoneCode": "222" }, - "help_user_community_url_dev": { - "value": "https://bbs.vika.cn" + "united_states": { + "phoneCode": "1" }, - "help_user_community_url_prod": { - "value": "https://bbs.vika.cn" + "american_samoa": { + "phoneCode": "1684" }, - "help_user_feedback_url": { - "value": "https://vika.cn/share/shrzw0miJVmSkJ7eBBa9k/fomx5qPX0JGPFvfEEP" + "virgin_islands_us": { + "phoneCode": "1284" }, - "help_video_tutorials_url": { - "value": "https://edu.vika.cn" + "mongolia": { + "phoneCode": "976" }, - "integration_apifox_url": { - "value": "https://www.apifox.cn/apidoc/project-613370/doc-806641" + "montserrat": { + "phoneCode": "1664" }, - "integration_dingtalk_da": { - "value": "https://h5.dingtalk.com/dingtalk-da/index.html" + "bangladesh": { + "phoneCode": "880" }, - "integration_dingtalk_help_url": { - "marketplace": { - "integration": "ina9134969049653777" - }, - "value": "https://help.vika.cn/docs/guide/integration-dingtalk" + "peru": { + "phoneCode": "51" }, - "integration_dingtalk_upgrade_url": { - "value": "http://h5.dingtalk.com/open-purchase/mobileUrl.html?redirectUrl=https%3A%2F%2Fh5.dingtalk.com%2Fopen-market%2Fshare.html%3FshareGoodsCode%3DD34E5A30A9AC7FC6CA73DEEEDFCEC860C2F97D997C85C521BD4178D2ECD66BA4F839F9305FA49577%26token%3Dc9073ae902dcadcc4e9fc9af6c8fe5b8%26shareUid%3D704244F72EEF24B56571C55DCF2818F9&dtaction=os" + "myanmar": { + "phoneCode": "95" }, - "integration_feishu_help": { - "value": "vika维格表 使用指南" + "moldova": { + "phoneCode": "373" }, - "integration_feishu_help_url": { - "marketplace": { - "integration": "cli_9f3930dd7d7ad00c, cli_a08120b120fad00e, cli_9f614b454434500e" - }, - "value": "https://help.vika.cn/docs/guide/integration-lark" + "morocco": { + "phoneCode": "212" }, - "integration_feishu_manage_open_url": { - "value": "https://applink.feishu.cn/client/bot/open" + "monaco": { + "phoneCode": "377" }, - "integration_feishu_seats_form_url": { - "value": "https://u.vika.cn/pb7cj" + "mozambique": { + "phoneCode": "258" }, - "integration_feishu_upgrade_url": { - "value": "https://feishu.cn/admin/appCenter/manage/cli_9f614b454434500e" + "mexico": { + "phoneCode": "52" }, - "integration_feishu_upgrade_url_dev": { - "value": "https://feishu.cn/admin/appCenter/manage/cli_a28611a8b9e2900d" + "namibia": { + "phoneCode": "264" }, - "integration_feisu_register_now_url": { - "value": "https://u.vika.cn/qmdp3" + "south_africa": { + "phoneCode": "27" }, - "integration_wecom_bind_help_center": { - "value": "/help" + "nicaragua": { + "phoneCode": "505" }, - "integration_wecom_bind_help_center_url": { - "value": "/help" + "nepal": { + "phoneCode": "977" }, - "integration_wecom_bind_success_icon_img": { - "value": "/space/2021/09/16/124e249b651f4934949ae39839e3ee77" + "niger": { + "phoneCode": "227" }, - "integration_wecom_custom_subdomain_help_url": { - "value": "https://help.vika.cn/docs/guide/intro_custom_subdomain" + "nigeria": { + "phoneCode": "234" }, - "integration_wecom_help_url": { - "marketplace": { - "integration": "ina5200279359980055" - }, - "value": "https://help.vika.cn/docs/guide/integration-wecom" + "norway": { + "phoneCode": "47" }, - "integration_wecom_login_qrcode_js": { - "value": "http://wwcdn.weixin.qq.com/node/wework/wwopen/js/wwLogin-1.2.4.js" + "palau": { + "phoneCode": "680" }, - "integration_wecom_qrcode_css": { - "value": "/space/2021/08/02/6b5374b4b3ba42aba69022ae2b13a577" + "portugal": { + "phoneCode": "351" }, - "integration_wecom_shop_cms": { - "value": "https://help.vika.cn/docs/guide/integration-wecom" + "japan": { + "phoneCode": "81" }, - "integration_wecom_shop_corpid_dev": { - "value": "ww11761d11177ae10b" + "sweden": { + "phoneCode": "46" }, - "integration_wecom_shop_corpid_prod": { - "value": "ww11761d11177ae10b" + "switzerland": { + "phoneCode": "41" }, - "integration_wecom_shop_corpid_staging": { - "value": "ww11761d11177ae10b" + "el_salvador": { + "phoneCode": "503" }, - "integration_wecom_shop_corpid_test": { - "value": "ww11761d11177ae10b" + "samoa": { + "phoneCode": "685" }, - "integration_wecom_shop_suiteid_dev": { - "value": "wwc98ec5fc01dfdaeb" + "serbia": { + "phoneCode": "381" }, - "integration_wecom_shop_suiteid_prod": { - "value": "ww0506baa4d734acb9" + "sierra_leone": { + "phoneCode": "232" }, - "integration_wecom_shop_suiteid_staging": { - "value": "ww514bd11dfd0f294f" + "senegal": { + "phoneCode": "221" }, - "integration_wecom_shop_suiteid_test": { - "value": "ww3dd616a360b3ce97" + "cyprus": { + "phoneCode": "357" }, - "integration_wecom_upgrade_guide_url": { - "value": "/wecom-integration/#upgrade" + "seychelles": { + "phoneCode": "248" }, - "integration_yozosoft_help_url": { - "marketplace": { - "integration": "ina5645957505507647" - }, - "value": "https://help.vika.cn/docs/guide/integration-yozosoft" + "saudi_arabia": { + "phoneCode": "966" }, - "introduction_video": { - "value": "space/2022/04/14/aff988f37b6849b1bf438a73d8721ae2" + "saint_pierre_and_miquelon": { + "phoneCode": "508" }, - "linkedin_icon": { - "value": "space/2022/12/05/762594b3353141f6a7a83d10a3e47ea4" + "sao_tome_and_principe": { + "phoneCode": "239" }, - "login_agree_terms_of_service": { - "value": "75" + "saint_kitts_and_nevis": { + "phoneCode": "1869" }, - "login_icp1_url": { - "value": "https://beian.miit.gov.cn/" + "saint_lucia": { + "phoneCode": "1758" }, - "login_icp2_url": { - "value": "http://www.beian.gov.cn/portal/registerSystemInfo" + "saint_maarten_dutch_part": { + "phoneCode": "1721" }, - "login_introduction_video": { - "value": "space/2022/04/14/aff988f37b6849b1bf438a73d8721ae2" + "san_marino": { + "phoneCode": "378" }, - "login_join_chatgroup_url": { - "value": "https://vika.cn/chatgroup/" + "saint_vincent_and_the_grenadines": { + "phoneCode": "1784" }, - "login_privacy_policy": { - "value": "维格隐私政策" + "sri_lanka": { + "phoneCode": "94" }, - "login_private_deployment_form_url": { - "value": "https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL" + "slovakia": { + "phoneCode": "421" }, - "login_service_agreement": { - "value": "维格服务协议" + "slovenia": { + "phoneCode": "386" }, - "official_avatar": { - "value": "space/2021/12/07/aaac193704834e9a9e4af27a1535826a" + "swaziland": { + "phoneCode": "268" }, - "page_apply_logout": { - "value": "space/2022/01/11/5bb30117e4934522af081a05eb4fd903" + "sudan": { + "phoneCode": "249" }, - "page_apply_logout_bg": { - "value": "space/2022/01/11/35106645c2614d11bea689a540d13787" + "suriname": { + "phoneCode": "597" }, - "permission_config_in_workbench_page": { - "value": "[{\"key\":0,\"title\":\"表格内的操作权限\",\"detail\":[{\"title\":\"编辑视图工具栏\",\"permissions\":[0,1,2]},{\"title\":\"编辑视图列表\",\"permissions\":[0,1,2]},{\"title\":\"导出视图数据\",\"permissions\":[0,1]},{\"title\":\"增删维格列\",\"permissions\":[0,1]},{\"title\":\"编辑维格列属性(列名/类型/描述)\",\"permissions\":[0,1]},{\"title\":\"编辑维格列样式(列宽/统计栏)\",\"permissions\":[0,1]},{\"title\":\"编辑行(增删/拖动)\",\"permissions\":[0,1,2]},{\"title\":\"编辑单元格(增删改数据)\",\"permissions\":[0,1,2]},{\"title\":\" 撤销,重做\",\"permissions\":[0,1,2]}]},{\"key\":1,\"title\":\"对文件(夹)的操作权限\",\"detail\":[{\"title\":\"设置文件(夹)权限\",\"permissions\":[0,1]},{\"title\":\"将继承切换为指定权限\",\"permissions\":[0,1]},{\"title\":\"将指定切换为继承权限\",\"permissions\":[0]},{\"title\":\"新建文件(夹)\",\"permissions\":[0,1]},{\"title\":\"导入文件\",\"permissions\":[0,1]},{\"title\":\"导出文件\",\"permissions\":[0,1]},{\"title\":\"复制文件(当前文件&上级文件夹权限)\",\"permissions\":[0,1]},{\"title\":\"移动文件(当前文件&目标文件夹权限)\",\"permissions\":[0,1]},{\"title\":\"重命名文件(夹)\",\"permissions\":[0,1]},{\"title\":\"删除文件(夹)\",\"permissions\":[0,1]},{\"title\":\"分享文件(夹)\",\"permissions\":[0,1,2]},{\"title\":\"保存为模板\",\"permissions\":[0,1]}]}]" + "solomon_islands": { + "phoneCode": "677" }, - "quick_search_default_dark": { - "value": "space/2023/03/15/42dc46843161478fb56d27efb43a50b8" + "somalia": { + "phoneCode": "252" }, - "quick_search_default_light": { - "value": "space/2023/03/15/0fd81978a8c04d96a483f4c785736b62" + "tajikistan": { + "phoneCode": "992" }, - "server_error_page_bg": { - "value": "/space/2022/09/07/cbaf2ee93be24f6bbe361a85db0efba7?attname=theserverisundermaintenance.%402x.png" + "thailand": { + "phoneCode": "66" }, - "share_iframe_brand": { - "value": "space/2021/12/09/3b09b857cee04a12b6b02cd63bb90a81?attname=%E7%BB%B4%E6%A0%BC%E8%A1%A8logo.svg" + "tanzania": { + "phoneCode": "255" }, - "share_iframe_brand_dark": { - "value": "space/2022/11/28/94e87bd1fd25472e99556c9b5f72c62e?attname=logo-reverse.svg" + "tonga": { + "phoneCode": "676" }, - "space_setting_integrations_dingtalk": { - "value": "true" + "turks_and_caicos_islands": { + "phoneCode": "1649" }, - "space_setting_integrations_feishu": { - "value": "true" + "trinidad_and_tobago": { + "phoneCode": "1868" }, - "space_setting_integrations_preview_office_file": { - "value": "true" + "tunisia": { + "phoneCode": "216" }, - "space_setting_integrations_wecom": { - "value": "true" + "turkey": { + "phoneCode": "90" }, - "space_setting_invite_user_to_get_v_coins": { - "value": "true" + "turkmenistan": { + "phoneCode": "993" }, - "space_setting_list_of_enable_all_lab_features": { - "value": "[\"spcXXXXX\"]" + "vanuatu": { + "phoneCode": "678" }, - "space_setting_role_empty_img": { - "value": "space/2022/08/03/3fbdff65d66547a8ab796e1b808d45b0" + "venezuela": { + "phoneCode": "58" }, - "space_setting_upgrade": { - "value": "true" + "brunei": { + "phoneCode": "673" }, - "system_configuration_logo_with_name_white_font": { - "value": "/space/2021/09/17/5c69f63932da4be7aa0965d3b0e543c4" + "uganda": { + "phoneCode": "256" }, - "system_configuration_minmum_version_require": { - "value": "0.5.0" + "ukraine": { + "phoneCode": "380" }, - "system_configuration_server_error_bg_img": { - "value": "/space/2022/09/07/cbaf2ee93be24f6bbe361a85db0efba7?attname=theserverisundermaintenance.%402x.png" + "uruguay": { + "phoneCode": "598" }, - "system_configuration_version": { - "value": "0.5.0" + "uzbekistan": { + "phoneCode": "998" }, - "twitter_icon": { - "value": "space/2022/12/05/09cc01ee1f894fb2923bd08b715226b6" + "spain": { + "phoneCode": "34" }, - "user_account_deleted_bg_img": { - "value": "space/2022/01/11/35106645c2614d11bea689a540d13787" + "greece": { + "phoneCode": "30" }, - "user_account_deleted_img": { - "value": "space/2022/01/11/5bb30117e4934522af081a05eb4fd903" + "ivory_coast": { + "phoneCode": "225" }, - "user_guide_welcome_developer_center_url": { - "value": "/help/developers/" + "singapore": { + "phoneCode": "65" }, - "user_guide_welcome_introduction_video": { - "value": "{ \"title\":\"玩转一张维格表\", \"video\":\"space/2020/12/21/cb7bdf6fe22146068111d46915587fb2\", \"autoPlay\":true }" + "new_caledonia": { + "phoneCode": "687" }, - "user_guide_welcome_quick_start_video": { - "value": "{\"title\":\"一分钟快速入门\", \"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\", \"autoPlay\":true}" + "new_zealand": { + "phoneCode": "64" }, - "user_guide_welcome_template1_icon": { - "value": "现有的 icon 链接" + "hungary": { + "phoneCode": "36" }, - "user_guide_welcome_template1_url": { - "value": "/template/tpchFkNFaaJMC/tplDYzZqqwpRQ" + "syria": { + "phoneCode": "963" }, - "user_guide_welcome_template2_icon": { - "value": "现有的 icon 链接" + "jamaica": { + "phoneCode": "1876" }, - "user_guide_welcome_template2_url": { - "value": "/template/tpc76og2J6D8p/tplDBUKmXFo7c" + "armenia": { + "phoneCode": "374" }, - "user_guide_welcome_template3_icon": { - "value": "现有的 icon 链接" + "yemen": { + "phoneCode": "967" }, - "user_guide_welcome_template3_url": { - "value": "/template/tpcMixDKM5f3s/tplaglc40487X" + "iraq": { + "phoneCode": "964" }, - "user_guide_welcome_what_is_datasheet_video": { - "value": "{ \"title\":\"什么是维格表\", \"video\":\"space/2022/02/21/94cb82f9ffd84a5499c8931a224ad234\", \"autoPlay\":true }" + "iran": { + "phoneCode": "98" }, - "user_setting_account_bind": { - "value": "true" + "israel": { + "phoneCode": "972" }, - "user_setting_account_bind_dingtalk": { - "value": "true" + "italy": { + "phoneCode": "39" }, - "user_setting_account_bind_qq": { - "value": "true" + "india": { + "phoneCode": "91" }, - "user_setting_account_bind_wechat": { - "value": "true" + "indonesia": { + "phoneCode": "62" }, - "user_setting_default_avatar": { - "value": "space/2020/09/11/e6aa3037a38f45acb65324ea314aea58,space/2021/03/10/61a8aae11da2439ebb4df35b9075587d,space/2020/09/11/41e723917dc742d2974e41abab8cf60b,space/2020/09/11/4dce50e4ec4649b9a408a494aca28183,space/2020/09/11/e4d073b1fa674bc884a8c194e9248ecf,space/2020/09/11/31a1acb4734c4dd3ae9538299282b39e" + "united_kingdom": { + "phoneCode": "44" }, - "view_architecture_empty_graphics_img": { - "value": "space/2021/11/19/b1c660a317fb4068bd312d16671308a1" + "virgin_islands_british": { + "phoneCode": "1340" }, - "view_architecture_empty_record_list_img": { - "value": "space/2021/11/19/73c1cda56b3d4d448416d9b69c757598" + "jordan": { + "phoneCode": "962" }, - "view_architecture_guide_video": { - "value": "space/2021/11/18/428b94bb262845afabf46efff8e082b5" + "vietnam": { + "phoneCode": "84" }, - "view_calendar_guide_create": { - "value": "space/2021/08/16/bda3a4c51ebc444ea9f26d4573987257" + "zambia": { + "phoneCode": "260" }, - "view_calendar_guide_no_permission": { - "value": "space/2022/05/23/4206adbf0aaa43bf90342fd0e568dc73" + "chad": { + "phoneCode": "235" }, - "view_calendar_guide_video": { - "value": "space/2021/08/06/e3a4e480768c4b4d8d01ea4a269bf2bb" + "gibraltar": { + "phoneCode": "350" }, - "view_form_guide_video": { - "value": "space/2020/12/25/f0ecc536d7324df888d165cb73cd22c6" + "chile": { + "phoneCode": "56" }, - "view_gallery_guide_video": { - "value": "space/2020/09/15/4383ec2f8eb041599396df0f18d99f5a" + "central_african_republic": { + "phoneCode": "236" + } + }, + "api_panel": { + "Attachment": { + "defaultExampleId": "api_panel_type_default_example_attachment", + "description": "由若干“附件对象”组成的数组 每一个附件对象应该包含下列属性: mimeType (string) : 附件的媒体类型 name (string) : 附件的名称 size (number) : 附件的大小,单位为字节 width (number) : 如果附件是图片格式,表示图片的宽度,单位为px height (number) : 如果附件是图片格式,表示图片的高度,单位为px token (string) : 附件的访问路径 preview (string) : 如果附件是PDF格式,将会生成一个预览图,用户可以通过此网址访问", + "descriptionId": "api_panel_type_desc_attachment", + "defaultExample": "[\n {\n \"id\": \"atcPtxnvqti5M\",\n \"name\": \"6.gif\",\n \"size\": 33914,\n \"mimeType\": \"image/gif\",\n \"token\": \"space/2020/09/22/01ee7202922d48688f61e34f12da5abc\",\n \"width\": 240,\n \"height\": 240,\n \"url\": \"__host__/space/2020/09/22/01ee7202922d48688f61e34f12da5abc\"\n }\n]", + "valueType": "array of attachment objects" }, - "view_gantt_guide_video": { - "value": "space/2021/06/02/8bd6c5263ba444aabc138ed051b83c8c" + "AutoNumber": { + "defaultExampleId": "api_panel_type_default_example_auto_number", + "description": "数值,正整数 创建记录时自动生成,不支持手动写入", + "descriptionId": "api_panel_type_desc_autonumber", + "defaultExample": "10001", + "valueType": "number" }, - "view_grid_guide_video": { - "value": "space/2020/09/16/77e941353d8141b69f684e2592350ec7" + "Cascader": { + "defaultExampleId": "api_panel_type_desc_cascader", + "description": "多级联动,适合作为有层级关系选项的文本,例如省区市的选择。", + "descriptionId": "api_panel_type_desc_cascader", + "defaultExample": "多级联动,适合作为有层级关系选项的文本,例如省区市的选择。", + "valueType": "string" }, - "view_kanban_guide_video": { - "value": "space/2020/09/11/c964bcf3ec48458dae7fbdc55a59856b" + "Checkbox": { + "defaultExampleId": "api_panel_type_default_example_checkbox", + "description": "布尔类型的true 或 空 当此字段被勾选时返回“true”。除此以外,记录中不返回此字段!", + "descriptionId": "api_panel_type_desc_checkbox", + "defaultExample": "true", + "valueType": "boolean" }, - "view_mirror_list_empty_img": { - "value": "space/2022/05/23/d880e95a4a204492b20d8725c61c998c" + "CreatedBy": { + "defaultExampleId": "api_panel_type_default_example_created_by", + "description": "创建此记录的成员(unit),以数组形式返回 「组织单元」是维格表中描述“空间站”与“成员”之间的关系的一个抽象概念。成员(member)、小组(team)都是一种组织单元。 *创建人必须为成员(member) unitId (string) : 组织单元的ID unitType (number) : 组织单元的类型,1是小组,3是成员 unitName (string) : 组织单元的名称,如果unitType是1,此值为小组名称;如果unitType是3,此值为成员站内昵称", + "descriptionId": "api_panel_type_desc_created_by", + "defaultExample": "{\n \"uuid\": \"aa3e6af7041c4907ba03889acc0b0cd1\",\n \"name\": \"Kelvin\",\n \"avatar\": \"__host__/public/2020/08/03/574bcee4cfc54f6fbb7d686bb237f6f3\"\n}", + "valueType": "array of unit objects" + }, + "CreatedTime": { + "defaultExampleId": "api_panel_type_default_example_created_time", + "description": "日期和时间,以毫秒(ms)为单位返回时间戳", + "descriptionId": "api_panel_type_desc_created_time", + "defaultExample": "1600777860000", + "valueType": "number | string" }, - "widget_center_feature_not_unturned_on_img": { - "value": "/space/2021/12/27/cc7c3d706c8e4443a0e9b79673a078e0" + "Currency": { + "defaultExampleId": "api_panel_type_default_example_currency", + "description": "数值,支持负值 通过api调用返回的值,不受列配置里指定的精度影响,只会原样返回。", + "descriptionId": "api_panel_type_desc_currency", + "defaultExample": "8.88", + "valueType": "number" }, - "widget_center_help_link": { - "value": "#" + "DateTime": { + "defaultExampleId": "api_panel_type_default_example_date_time", + "description": "日期和时间,以毫秒(ms)为单位返回时间戳", + "descriptionId": "api_panel_type_desc_date_time", + "defaultExample": "1600777860000", + "valueType": "number | string" }, - "widget_center_space_widget_empty_img": { - "value": "/space/2021/10/08/18343b0891a74bdb9ca0b36b6c543e3b" + "Email": { + "defaultExampleId": "api_panel_type_default_example_email", + "description": "邮箱地址(字符串)", + "descriptionId": "api_panel_type_desc_email", + "defaultExample": "support@vikadata.com", + "valueType": "string" }, - "widget_cli_miumum_version": { - "value": "0.0.1" + "Formula": { + "defaultExampleId": "api_panel_type_default_example_formula", + "description": "经过公式和函数运算后的结果,数据类型可能是数字、字符串、布尔值 此字段是运算值,创建/更新记录时不支持写入", + "descriptionId": "api_panel_type_desc_formula", + "defaultExample": "在第一行完整填写数据,就可以查看示例了", + "valueType": "number | string | boolean" }, - "widget_custom_widget_empty_img": { - "value": "/space/2021/10/08/18343b0891a74bdb9ca0b36b6c543e3b" + "LastModifiedBy": { + "defaultExampleId": "api_panel_type_default_example_last_modified_by", + "description": "最近一次编辑记录/指定字段的成员(unit),以数组形式返回 「组织单元」是维格表中描述“空间站”与“成员”之间的关系的一个抽象概念。成员(member)、小组(team)都是一种组织单元。 *修改人必须为成员(member) unitId (string) : 组织单元的ID unitType (number) : 组织单元的类型,1是小组,3是成员 unitName (string) : 组织单元的名称,如果unitType是1,此值为小组名称;如果unitType是3,此值为成员站内昵称", + "descriptionId": "api_panel_type_desc_last_modified_by", + "defaultExample": "{\n \"uuid\": \"aa3e6af7041c4907ba03889acc0b0cd1\",\n \"name\": \"Kelvin\",\n \"avatar\": \"__host__/public/2020/08/03/574bcee4cfc54f6fbb7d686bb237f6f3\"\n}", + "valueType": "array of unit objects" }, - "widget_default_cover_img": { - "value": "/space/2021/11/09/f82a5c9cb6c74452b824e17b03f20f67" + "LastModifiedTime": { + "defaultExampleId": "api_panel_type_default_example_last_modified_time", + "description": "日期和时间,以毫秒 (ms) 为单位返回时间戳", + "descriptionId": "api_panel_type_desc_last_modified_time", + "defaultExample": "1600777860000", + "valueType": "number | string" }, - "widget_panel_empty_img": { - "value": "space/2022/05/23/c5096fdb5d674985a49725e23f72cdc7" + "Link": { + "defaultExampleId": "api_panel_type_default_example_link", + "description": "由多条已关联记录的ID组成的数组 ", + "descriptionId": "api_panel_type_desc_link", + "defaultExample": "[\n \"rec8116cdd76088af\",\n \"rec245db9343f55e8\",\n \"rec4f3bade67ff565\"\n]", + "valueType": "array of record IDs (strings)" }, - "workbench_folder_default_cover_list": { - "value": "space/2021/12/29/7306be86fc6d4cac9d8de9b4a787b1fa,space/2021/12/29/58073bbfe0f64dc7bd2f5f44a123c172,space/2021/12/29/e36e93966aa049e1ba7fd53907c2265f,space/2021/12/29/ebd570b6ee3b429f8c2e51e1b1df6657,space/2021/12/29/7eb38331f61240dcb74b1fce3a90c6bc,space/2021/12/29/a8c5df5eba2e4c07a78bdca6b9613579" + "LookUp": { + "defaultExampleId": "api_panel_type_default_example_look_up", + "description": "A表与B表通过神奇关联字段进行表关联后,可使用此字段对B表的任意字段进行引用,视乎引用方式的不同,而返回不同数据类型的运算值。 如果引用方式选择了「原样引用」,则运算结果的数据类型保持与B表源字段一致; 其他引用方式皆返回数字类型的运算值", + "descriptionId": "api_panel_type_desc_look_up", + "defaultExample": "在第一行完整填写数据,就可以查看示例了", + "valueType": "any" }, - "workbench_max_node_number_show_invite_and_new_node": { - "value": "13" + "Member": { + "defaultExampleId": "api_panel_type_default_example_member", + "description": "由若干「组织单元(unit)」组成的数组 「组织单元」是维格表中描述“空间站”与“成员”之间的关系的一个抽象概念。成员(member)、小组(team)都是一种组织单元。 id (string) : 组织单元的ID type (number) : 组织单元的类型,1是小组,3是成员 name (string) : 组织单元的名称,如果 type 是1,此值为小组名称;如果 type 是3,此值为成员站内昵称", + "descriptionId": "api_panel_type_desc_member", + "defaultExample": "[\n {\n \"id\": \"1291258301781176321\",\n \"type\": 3,\n \"name\": \"小葵\",\n \"avatar\": \"https://s1.vika.cn/default/avatar004.jpg\"\n }\n]", + "valueType": "array of unit objects" }, - "workbench_no_permission_img": { - "value": "/space/2022/09/07/6e95e804d5f44fe4a0dec81d228b0286?attname=filecannotbeaccessed%402x.png" - } - }, - "shortcut_keys": [ - { - "show": true, - "key": "cmd+z", - "winKey": "ctrl+z", - "name": [ - "undo" - ], - "when": "!isGlobalEditing", - "id": "cmd+z", - "command": "Undo", - "description": "撤销", - "type": [ - "global_shortcuts" - ] + "MultiSelect": { + "defaultExampleId": "api_panel_type_default_example_multi_select", + "description": "可能有多个选项,返回已选上的若干个选项值构成的字符串数组 当创建/更新记录时,提交的选项值并不存在于选项列表,则会返回错误码400,提示“参数错误”", + "descriptionId": "api_panel_type_desc_multi_select", + "defaultExample": "[\n \"选项 A\",\n \"选项 B\"\n]", + "valueType": "array of strings" }, - { - "show": true, - "key": "cmd+shift+z", - "winKey": "ctrl+shift+z", - "name": [ - "redo" - ], - "when": "!isGlobalEditing", - "id": "cmd+shift+z", - "command": "Redo", - "description": "重做", - "type": [ - "global_shortcuts" - ] + "Number": { + "defaultExampleId": "api_panel_type_default_example_number", + "description": "数值,支持负值 通过api调用返回的值,不受列配置里指定的精度影响,只会原样返回。", + "descriptionId": "api_panel_type_desc_number", + "defaultExample": "8", + "valueType": "number" }, - { - "show": true, - "key": "cmd+y", - "winKey": "ctrl+y", - "name": [ - "redo" - ], - "when": "!isGlobalEditing", - "id": "cmd+y", - "command": "Redo", - "description": "重做", - "type": [ - "global_shortcuts" - ] + "Percent": { + "defaultExampleId": "api_panel_type_default_example_percent", + "description": "数值,支持负值 通过API调用返回的值,不受列配置里指定的精度影响,只会原样返回。", + "descriptionId": "api_panel_type_desc_percent", + "defaultExample": "0.88", + "valueType": "number" }, - { - "show": true, - "key": "cmd+f", - "winKey": "ctrl+f", - "name": [ - "find" - ], - "when": "!isRecordExpanding", - "id": "cmd+f", - "command": "ToggleFindPanel", - "description": "查找", - "type": [ - "global_shortcuts" - ] + "Phone": { + "defaultExampleId": "api_panel_type_default_example_phone", + "description": "电话号码(字符串)", + "descriptionId": "api_panel_type_desc_phone", + "defaultExample": "138xxxx7240", + "valueType": "string" }, - { - "show": true, - "key": "cmd+shift+p", - "winKey": "ctrl+shift+p", - "name": [ - "open_api_panel" - ], - "when": "true ", - "id": "cmd+shift+p", - "command": "ToggleApiPanel", - "description": "打开 API 示例面板", - "type": [ - "global_shortcuts" - ] + "Rating": { + "defaultExampleId": "api_panel_type_default_example_rating", + "description": "评分值是 1-9 之间的一个正整数 如果单元格为空或者撤销评分,则记录中不返回此字段!", + "descriptionId": "api_panel_type_desc_rating", + "defaultExample": "1", + "valueType": "number" }, - { - "show": true, - "key": "cmd+/", - "winKey": "ctrl+/", - "name": [ - "open_keyboard_shortcuts_panel" - ], - "when": "!isGlobalEditing && !isRecordExpanding", - "id": "cmd+/", - "command": "Help", - "description": "打开快捷键面板", - "type": [ - "global_shortcuts" - ] + "SingleSelect": { + "defaultExampleId": "api_panel_type_default_example_single_select", + "description": "可能有多个选项,返回已选上的一个选项值(字符串) 当创建/更新记录时,提交的选项值并不存在于选项列表,则会返回错误码400,提示“参数错误”", + "descriptionId": "api_panel_type_desc_single_select", + "defaultExample": "选项 A", + "valueType": "string" }, - { - "show": true, - "key": "cmd+up", - "winKey": "ctrl+up", - "name": [ - "previous_record" - ], - "when": "isRecordExpanding", - "id": "cmd+up", - "command": "PreviousRecord", - "description": "卡片翻到上一条记录", - "type": [ - "global_shortcuts" - ] + "SingleText": { + "defaultExampleId": "api_panel_type_default_example_single_text", + "description": "单行文本,适合保存不带换行符的文本,例如文章的标题。", + "descriptionId": "api_panel_type_desc_single_text", + "defaultExample": "单行文本内容", + "valueType": "string" }, - { - "show": true, - "key": "cmd+shift+,", - "winKey": "ctrl+shift+,", - "name": [ - "previous_record" - ], - "when": "isRecordExpanding", - "id": "cmd+shift+,", - "command": "PreviousRecord", - "description": "卡片翻到上一条记录", - "type": [ - "global_shortcuts" - ] + "Text": { + "defaultExampleId": "api_panel_type_default_example_text", + "description": "多行文本,可用于存放较长的文本内容,例如一篇学术论文。", + "descriptionId": "api_panel_type_desc_text", + "defaultExample": "多行\n文本内容", + "valueType": "string" }, - { - "show": true, - "key": "cmd+down", - "winKey": "ctrl+down", - "name": [ - "next_record" - ], - "when": "isRecordExpanding", - "id": "cmd+down", - "command": "NextRecord", - "description": "卡片翻到下一条记录", - "type": [ - "global_shortcuts" - ] + "URL": { + "defaultExampleId": "api_panel_type_default_example_url", + "description": "URL 地址(字符串)", + "descriptionId": "api_panel_type_desc_url", + "defaultExample": "{\"title\":\"vika\",\"text\":\"https://vika.cn\", \"favicon\":\"https://s1.vika.cn/space/2022/12/20/73456950217f4f79b20c7ef1a49acf6e\"}", + "valueType": "string" + } + }, + "audit": { + "actual_delete_space": { + "content": "audit_space_complete_delete_detail", + "online": true, + "type": "space", + "category": "space_change_event", + "name": "audit_space_complete_delete" }, - { - "show": true, - "key": "cmd+shift+.", - "winKey": "ctrl+shift+.", - "name": [ - "next_record" - ], - "when": "isRecordExpanding", - "id": "cmd+shift+.", - "command": "NextRecord", - "description": "卡片翻到下一条记录", - "type": [ - "global_shortcuts" - ] + "add_field_role": { + "content": "audit_add_field_role_detail", + "type": "space", + "category": "datasheet_field_permission_change_event", + "name": "audit_add_field_role" }, - { - "show": true, - "key": "cmd+shift+,", - "winKey": "ctrl+shift+,", - "name": [ - "switch_view_prev" - ], - "when": "!isRecordExpanding", - "id": "cmd+shift+,", - "command": "ViewPrev", - "description": "视图标签向前切换视图", - "type": [ - "global_shortcuts" - ] + "add_node_role": { + "content": "audit_add_node_role_detail", + "online": true, + "type": "space", + "sort": "11", + "show_in_audit_log": true, + "category": "work_catalog_permission_change_event", + "name": "audit_add_node_role" }, - { - "show": true, - "key": "cmd+shift+.", - "winKey": "ctrl+shift+.", - "name": [ - "switch_view_next" - ], - "when": "!isRecordExpanding", - "id": "cmd+shift+.", - "command": "ViewNext", - "description": "视图标签向后切换视图", - "type": [ - "global_shortcuts" - ] + "add_sub_admin": { + "type": "space", + "category": "admin_permission_change_event" }, - { - "show": true, - "key": "cmd+c", - "winKey": "ctrl+c", - "name": [ - "duplicate_cell_data" - ], - "when": "hasActiveCell", - "id": "cmd+c", - "command": "Copy", - "description": "复制", - "type": [ - "gird_view_shortcuts" - ] + "add_team_to_member": { + "type": "space", + "category": "organization_change_event" }, - { - "show": true, - "key": "cmd+v", - "winKey": "ctrl+v", - "name": [ - "paste_cell_data" - ], - "when": "hasActiveCell", - "id": "cmd+v", - "command": "Paste", - "description": "粘贴", - "type": [ - "gird_view_shortcuts" - ] + "agree_user_apply": { + "type": "space", + "category": "organization_change_event" }, - { - "show": true, - "key": "cmd+x", - "winKey": "ctrl+x", - "name": [ - "cut_cell_data" - ], - "id": "cmd+x", - "command": "None", - "description": "剪切", - "type": [ - "gird_view_shortcuts" - ] + "cancel_delete_space": { + "content": "audit_space_cancel_delete_detail", + "online": true, + "type": "space", + "category": "space_change_event", + "name": "audit_space_cancel_delete" }, - { - "show": true, - "key": "space", - "winKey": "space", - "name": [ - "expand_record" - ], - "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding && !isEditing", - "id": "space", - "command": "ExpandRecord", - "description": "展开行", - "type": [ - "gird_view_shortcuts" - ] + "change_main_admin": { + "type": "space", + "category": "admin_permission_change_event" }, - { - "show": true, - "key": "escape", - "winKey": "escape", - "name": [ - "escape" - ], - "when": "isEditing", - "id": "escape", - "command": "ExitEditing", - "description": "退出编辑或关闭窗口", - "type": [ - "gird_view_shortcuts" - ] + "copy_node": { + "content": "audit_space_node_copy_detail", + "online": true, + "type": "space", + "sort": "4", + "show_in_audit_log": true, + "category": "work_catalog_change_event", + "name": "audit_space_node_copy" }, - { - "show": true, - "key": "shift+enter", - "winKey": "shift+enter", - "name": [ - "insert_record_below" - ], - "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding && recordEditable", - "id": "shift+enter", - "command": "AppendRow", - "description": "向下插入行", - "type": [ - "gird_view_shortcuts" - ] + "create_node": { + "content": "audit_space_node_create_detail", + "online": true, + "type": "space", + "sort": "1", + "show_in_audit_log": true, + "category": "work_catalog_change_event", + "name": "audit_space_node_create" }, - { - "show": true, - "key": "cmd+shift+enter", - "winKey": "ctrl+shift+enter", - "name": [ - "insert_record_above" - ], - "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding && recordEditable", - "id": "cmd+shift+enter", - "command": "PrependRow", - "description": "向上插入行", - "type": [ - "gird_view_shortcuts" - ] + "create_space": { + "content": "audit_space_create_detail", + "online": true, + "type": "space", + "category": "space_change_event", + "name": "audit_space_create" }, - { - "show": true, - "key": "enter", - "winKey": "enter", - "name": [ - "edit_cell_data" - ], - "when": "isFocusing && !isRecordExpanding", - "id": "enter", - "command": "ToggleNextEditing", - "description": "激活单元格编辑状态", - "type": [ - "gird_view_shortcuts" - ] + "create_team": { + "type": "space", + "category": "organization_change_event" }, - { - "show": true, - "key": "F2", - "winKey": "F2", - "name": [ - "edit_cell_data" - ], - "when": "isFocusing && !isRecordExpanding", - "id": "F2", - "command": "ToggleNextEditing", - "description": "激活单元格编辑状态", - "type": [ - "gird_view_shortcuts" - ] + "create_template": { + "content": "audit_create_template_detail", + "online": true, + "type": "space", + "category": "space_template_event", + "name": "audit_create_template" }, - { - "show": true, - "key": "backspace", - "winKey": "backspace", - "name": [ - "clear_record" - ], - "when": "!isGlobalEditing && !isRecordExpanding", - "id": "backspace", - "command": "Clear", - "description": "清除单元格内容", - "type": [ - "gird_view_shortcuts" - ] + "delete_field_role": { + "content": "audit_delete_field_role_detail", + "type": "space", + "category": "datasheet_field_permission_change_event", + "name": "audit_delete_field_role" }, - { - "show": true, - "key": "delete", - "winKey": "delete", - "name": [ - "clear_record" - ], - "when": "!isGlobalEditing && !isRecordExpanding", - "id": "delete", - "command": "Clear", - "description": "清除单元格内容", - "type": [ - "gird_view_shortcuts" - ] + "delete_node": { + "content": "audit_space_node_delete_detail", + "online": true, + "type": "space", + "sort": "6", + "show_in_audit_log": true, + "category": "work_catalog_change_event", + "name": "audit_space_node_delete" + }, + "delete_node_role": { + "content": "audit_delete_node_role_detail", + "online": true, + "type": "space", + "sort": "13", + "show_in_audit_log": true, + "category": "work_catalog_permission_change_event", + "name": "audit_delete_node_role" }, - { - "show": true, - "key": "tab", - "winKey": "tab", - "name": [ - "finish_editing_cell_right" - ], - "when": "(isEditing || hasActiveCell) && !isRecordExpanding && !isMenuOpening", - "id": "tab", - "command": "CellTab", - "description": "完成编辑并向右一个单元格", - "type": [ - "gird_view_shortcuts" - ] + "delete_rubbish_node": { + "content": "audit_space_rubbish_node_delete_detail", + "online": true, + "type": "space", + "category": "work_catalog_change_event", + "name": "audit_space_rubbish_node_delete" }, - { - "show": true, - "key": "shift+tab", - "winKey": "shift+tab", - "name": [ - "finish_editing_cell_left" - ], - "when": "(isEditing || hasActiveCell) && !isRecordExpanding&& !isMenuOpening", - "id": "shift+tab", - "command": "CellShiftTab", - "description": "完成编辑并向左一个单元格", - "type": [ - "gird_view_shortcuts" - ] + "delete_space": { + "content": "audit_space_delete_detail", + "online": true, + "type": "space", + "category": "space_change_event", + "name": "audit_space_delete" }, - { - "show": true, - "key": "up", - "winKey": "up", - "name": [ - "up" - ], - "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening && !modalVisible", - "id": "up", - "command": "CellUp", - "description": "向上移动一个单元格", - "type": [ - "gird_view_shortcuts" - ] + "delete_sub_admin": { + "type": "space", + "category": "admin_permission_change_event" }, - { - "show": true, - "key": "down", - "winKey": "down", - "name": [ - "down" - ], - "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening && !modalVisible", - "id": "down", - "command": "CellDown", - "description": "向下移动一个单元格", - "type": [ - "gird_view_shortcuts" - ] + "delete_team": { + "type": "space", + "category": "organization_change_event" }, - { - "show": true, - "key": "left", - "winKey": "left", - "name": [ - "left" - ], - "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding && !isMenuOpening && !modalVisible", - "id": "left", - "command": "CellLeft", - "description": "向左移动一个单元格", - "type": [ - "gird_view_shortcuts" - ] + "delete_template": { + "content": "audit_delete_template_detail", + "online": true, + "type": "space", + "category": "space_template_event", + "name": "audit_delete_template" }, - { - "show": true, - "key": "right", - "winKey": "right", - "name": [ - "right" - ], - "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening && !modalVisible", - "id": "right", - "command": "CellRight", - "description": "向右移动一个单元格", - "type": [ - "gird_view_shortcuts" - ] + "disable_field_role": { + "content": "audit_disable_field_role_detail", + "type": "space", + "category": "datasheet_field_permission_change_event", + "name": "audit_disable_field_role" }, - { - "show": true, - "key": "cmd+up", - "winKey": "ctrl+up", - "name": [ - "cell_to_up_edge" - ], - "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", - "id": "cmd+up", - "command": "CellUpEdge", - "description": "移动到顶部单元格", - "type": [ - "gird_view_shortcuts" - ] + "disable_node_role": { + "content": "audit_disable_node_role_detail", + "online": true, + "type": "space", + "sort": "10", + "show_in_audit_log": true, + "category": "work_catalog_permission_change_event", + "name": "audit_disable_node_role" }, - { - "show": true, - "key": "cmd+down", - "winKey": "ctrl+down", - "name": [ - "cell_to_down_edge" - ], - "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", - "id": "cmd+down", - "command": "CellDownEdge", - "description": "移动到底部单元格", - "type": [ - "gird_view_shortcuts" - ] + "disable_node_share": { + "content": "audit_disable_node_share_detail", + "online": true, + "type": "space", + "sort": "16", + "show_in_audit_log": true, + "category": "work_catalog_share_event", + "name": "audit_disable_node_share" }, - { - "show": true, - "key": "cmd+left", - "winKey": "ctrl+left", - "name": [ - "cell_to_left_edge" - ], - "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", - "id": "cmd+left", - "command": "CellLeftEdge", - "description": "移动到最左侧单元格", - "type": [ - "gird_view_shortcuts" - ] + "enable_field_role": { + "content": "audit_enable_field_role_detail", + "type": "space", + "category": "datasheet_field_permission_change_event", + "name": "audit_enable_field_role" }, - { - "show": true, - "key": "cmd+right", - "winKey": "ctrl+right", - "name": [ - "cell_to_right_edge" - ], - "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", - "id": "cmd+right", - "command": "CellRightEdge", - "description": "移动到最右侧单元格", - "type": [ - "gird_view_shortcuts" - ] + "enable_node_role": { + "content": "audit_enable_node_role_detail", + "online": true, + "type": "space", + "sort": "9", + "show_in_audit_log": true, + "category": "work_catalog_permission_change_event", + "name": "audit_enable_node_role" }, - { - "show": true, - "key": "fn+↑", - "winKey": "fn+↑", - "name": [ - "scroll_screen_up" - ], - "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", - "id": "fn+↑", - "command": "None", - "description": "向上滚动一屏", - "type": [ - "gird_view_shortcuts" - ] + "enable_node_share": { + "content": "audit_enable_node_share_detail", + "online": true, + "type": "space", + "sort": "14", + "show_in_audit_log": true, + "category": "work_catalog_share_event", + "name": "audit_enable_node_share" }, - { - "show": true, - "key": "pageup", - "winKey": "pageup", - "name": [ - "scroll_screen_up" - ], - "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", - "id": "pageup", - "command": "PageUp", - "description": "向上滚动一屏", - "type": [ - "gird_view_shortcuts" - ] + "export_node": { + "content": "audit_space_node_export_detail", + "type": "space", + "category": "work_catalog_change_event", + "name": "audit_space_node_export" }, - { - "show": true, - "key": "fn+↓", - "winKey": "fn+↓", - "name": [ - "scroll_screen_down" - ], - "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", - "id": "fn+↓", - "command": "None", - "description": "向下滚动一屏", - "type": [ - "gird_view_shortcuts" - ] + "import_node": { + "content": "audit_space_node_import_detail", + "online": true, + "type": "space", + "sort": "3", + "show_in_audit_log": true, + "category": "work_catalog_change_event", + "name": "audit_space_node_import" + }, + "invite_user_join_by_email": { + "content": "audit_space_invite_user_detail", + "type": "space", + "category": "organization_change_event", + "name": "audit_space_invite_user" + }, + "move_node": { + "content": "audit_space_node_move_detail", + "online": true, + "type": "space", + "sort": "5", + "show_in_audit_log": true, + "category": "work_catalog_change_event", + "name": "audit_space_node_move" + }, + "quote_template": { + "content": "audit_quote_template_detail", + "online": true, + "type": "space", + "category": "work_catalog_change_event", + "name": "audit_quote_template" + }, + "recover_rubbish_node": { + "content": "audit_space_rubbish_node_recover_detail", + "online": true, + "type": "space", + "sort": "7", + "show_in_audit_log": true, + "category": "work_catalog_change_event", + "name": "audit_space_rubbish_node_recover" }, - { - "show": true, - "key": "pagedown", - "winKey": "pagedown", - "name": [ - "scroll_screen_down" - ], - "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", - "id": "pagedown", - "command": "PageDown", - "description": "向下滚动一屏", - "type": [ - "gird_view_shortcuts" - ] + "remove_member_from_team": { + "type": "space", + "category": "organization_change_event" }, - { - "show": true, - "key": "fn+←", - "winKey": "fn+←", - "name": [ - "scroll_screen_left" - ], - "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", - "id": "fn+←", - "command": "None", - "description": "向左滚动一屏", - "type": [ - "gird_view_shortcuts" - ] + "remove_user": { + "type": "space", + "category": "organization_change_event" }, - { - "show": true, - "key": "home", - "winKey": "home", - "name": [ - "scroll_screen_left" - ], - "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", - "id": "home", - "command": "PageLeft", - "description": "向左滚动一屏", - "type": [ - "gird_view_shortcuts" - ] + "rename_node": { + "content": "audit_space_node_rename_detail", + "online": true, + "type": "space", + "sort": "2", + "show_in_audit_log": true, + "category": "work_catalog_change_event", + "name": "audit_space_node_rename" }, - { - "show": true, - "key": "fn+→", - "winKey": "fn+→", - "name": [ - "scroll_screen_right" - ], - "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", - "id": "fn+→", - "command": "None", - "description": "向右滚动一屏", - "type": [ - "gird_view_shortcuts" - ] + "rename_space": { + "content": "audit_space_rename_detail", + "online": true, + "type": "space", + "category": "space_change_event", + "name": "audit_space_rename" }, - { - "show": true, - "key": "end", - "winKey": "end", - "name": [ - "scroll_screen_right" - ], - "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", - "id": "end", - "command": "PageRight", - "description": "向右滚动一屏", - "type": [ - "gird_view_shortcuts" - ] + "sort_node": { + "content": "audit_space_node_sort_detail", + "online": true, + "type": "space", + "category": "work_catalog_change_event", + "name": "audit_space_node_sort" }, - { - "show": true, - "key": "cmd+a", - "winKey": "ctrl+a", - "name": [ - "select_all" - ], - "when": "!isGlobalEditing && !isRecordExpanding", - "id": "cmd+a", - "command": "SelectionAll", - "description": "全选", + "store_share_node": { + "content": "audit_store_share_node_detail", + "online": true, "type": [ - "gird_view_shortcuts" - ] - }, - { - "show": true, - "key": "shift+up", - "winKey": "shift+up", - "name": [ - "selection_to_up" + "space", + "space" ], - "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", - "id": "shift+up", - "command": "SelectionUp", - "description": "单元格选区向上", - "type": [ - "gird_view_shortcuts" - ] - }, - { - "show": true, - "key": "shift+down", - "winKey": "shift+down", - "name": [ - "selection_to_down" + "sort": "8", + "show_in_audit_log": true, + "category": [ + "work_catalog_change_event", + "work_catalog_share_event" ], - "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", - "id": "shift+down", - "command": "SelectionDown", - "description": "单元格选区向下", - "type": [ - "gird_view_shortcuts" - ] + "name": "audit_store_share_node" }, - { - "show": true, - "key": "shift+left", - "winKey": "shift+left", - "name": [ - "selection_to_left" - ], - "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", - "id": "shift+left", - "command": "SelectionLeft", - "description": "单元格选区向左", - "type": [ - "gird_view_shortcuts" - ] + "update_field_role": { + "content": "audit_update_field_role_detail", + "type": "space", + "category": "datasheet_field_permission_change_event", + "name": "audit_update_field_role" }, - { - "show": true, - "key": "shift+right", - "winKey": "shift+right", - "name": [ - "selection_to_right" - ], - "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", - "id": "shift+right", - "command": "SelectionRight", - "description": "单元格选区向右", - "type": [ - "gird_view_shortcuts" - ] + "update_field_role_setting": { + "type": "space", + "category": "datasheet_field_permission_change_event" }, - { - "show": true, - "key": "cmd+shift+up", - "winKey": "ctrl+shift+up", - "name": [ - "selection_to_up_edge" - ], - "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", - "id": "cmd+shift+up", - "command": "SelectionUpEdge", - "description": "单元格选区向上至顶部", - "type": [ - "gird_view_shortcuts" - ] + "update_member_name_property": { + "content": "audit_update_member_property_detail", + "type": "space", + "category": "organization_change_event", + "name": "audit_update_member_property" }, - { - "show": true, - "key": "cmd+shift+down", - "winKey": "ctrl+shift+down", - "name": [ - "selection_to_down_edge" - ], - "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", - "id": "cmd+shift+down", - "command": "SelectionDownEdge", - "description": "单元格选区向下至底部", - "type": [ - "gird_view_shortcuts" - ] + "update_member_property": { + "type": "space", + "category": "organization_change_event", + "name": "audit_update_member_property" }, - { - "show": true, - "key": "cmd+shift+left", - "winKey": "ctrl+shift+left", - "name": [ - "selection_to_left_edge" - ], - "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", - "id": "cmd+shift+left", - "command": "SelectionLeftEdge", - "description": "单元格选区向左到边缘", - "type": [ - "gird_view_shortcuts" - ] + "update_member_team": { + "type": "space", + "category": "organization_change_event" }, - { - "show": true, - "key": "cmd+shift+right", - "winKey": "ctrl+shift+right", - "name": [ - "selection_to_right_edge" - ], - "when": "hasActiveCell && !isGlobalEditing && !isRecordExpanding&& !isMenuOpening", - "id": "cmd+shift+right", - "command": "SelectionRightEdge", - "description": "单元格选区向右至边缘", - "type": [ - "gird_view_shortcuts" - ] + "update_node_cover": { + "content": "audit_space_node_update_cover_detail", + "online": true, + "type": "space", + "category": "work_catalog_change_event", + "name": "audit_space_node_update_cover" }, - { - "show": true, - "key": "fn+↑", - "winKey": "fn+↑", - "name": [ - "scroll_screen_up" - ], - "when": "!isRecordExpanding", - "id": "fn+↑", - "command": "None", - "description": "向上滚动一屏", - "type": [ - "gallery_view_shortcuts" - ] + "update_node_desc": { + "content": "audit_space_node_update_desc_detail", + "online": true, + "type": "space", + "category": "work_catalog_change_event", + "name": "audit_space_node_update_desc" + }, + "update_node_icon": { + "content": "audit_space_node_update_icon_detail", + "online": true, + "type": "space", + "category": "work_catalog_change_event", + "name": "audit_space_node_update_icon" + }, + "update_node_role": { + "content": "audit_update_node_role_detail", + "online": true, + "type": "space", + "sort": "12", + "show_in_audit_log": true, + "category": "work_catalog_permission_change_event", + "name": "audit_update_node_role" }, - { - "show": true, - "key": "pageup", - "winKey": "pageup", - "name": [ - "scroll_screen_up" - ], - "when": "!isRecordExpanding", - "id": "pageup", - "command": "PageUp", - "description": "向上滚动一屏", - "type": [ - "gallery_view_shortcuts" - ] + "update_node_share_setting": { + "content": "audit_update_node_share_setting_detail", + "online": true, + "type": "space", + "sort": "15", + "show_in_audit_log": true, + "category": "work_catalog_share_event", + "name": "audit_update_node_share_setting" }, - { - "show": true, - "key": "fn+↓", - "winKey": "fn+↓", - "name": [ - "scroll_screen_down" - ], - "when": "!isRecordExpanding", - "id": "fn+↓", - "command": "None", - "description": "向下滚动一屏", - "type": [ - "gallery_view_shortcuts" - ] + "update_space_logo": { + "content": "audit_space_update_logo_detail", + "online": true, + "type": "space", + "category": "space_change_event", + "name": "audit_space_update_logo" }, - { - "show": true, - "key": "pagedown", - "winKey": "pagedown", - "name": [ - "scroll_screen_down" - ], - "when": "!isRecordExpanding", - "id": "pagedown", - "command": "PageDown", - "description": "向下滚动一屏", - "type": [ - "gallery_view_shortcuts" - ] + "update_sub_admin_role": { + "type": "space", + "category": "admin_permission_change_event" }, - { - "show": true, - "key": "cmd+up", - "winKey": "ctrl+up", - "name": [ - "page_to_up_edge" - ], - "when": "!isRecordExpanding", - "id": "cmd+up", - "command": "PageUpEdge", - "description": "滚动到页面顶部", - "type": [ - "gallery_view_shortcuts" - ] + "update_team_property": { + "type": "space", + "category": "organization_change_event" + }, + "user_leave_space": { + "content": "audit_user_quit_space_detail", + "type": "space", + "category": "organization_change_event", + "name": "audit_user_quit_space" + }, + "user_login": { + "content": "audit_user_login_detail", + "online": true, + "type": "system", + "category": "account_event", + "name": "audit_user_login" }, + "user_logout": { + "content": "audit_user_logout_detail", + "online": true, + "type": "system", + "category": "account_event", + "name": "audit_user_logout" + } + }, + "locales": [ { - "show": true, - "key": "cmd+down", - "winKey": "ctrl+down", - "name": [ - "page_to_down_edge" - ], - "when": "!isRecordExpanding", - "id": "cmd+down", - "command": "PageDownEdge", - "description": "滚动到页面底部", - "type": [ - "gallery_view_shortcuts" - ] + "currency_name": "Pounds", + "currency_symbol": "$", + "id": "en_GB", + "strings_language": "en_US", + "currency_code": "GBD", + "name": "English(United Kingdom)" }, { - "key": "cmd+s", - "winKey": "ctrl+s", - "name": [ - "toast_ctrl_s" - ], - "when": "true", - "id": "cmd+s", - "command": "ToastForSave", - "description": "你的修改数据会实时保存到云端,无需手动保存", - "type": [ - "gallery_view_shortcuts" - ] + "currency_name": "US Dollar", + "currency_symbol": "$", + "id": "en_US", + "strings_language": "en_US", + "currency_code": "USD", + "name": "English(USA)" }, { - "show": true, - "key": "cmd+k", - "winKey": "ctrl+k", - "name": [ - "open_quickgo_panel" - ], - "when": "!isRecordExpanding", - "id": "cmd+k", - "command": "SearchNode", - "description": "打开工作台的搜索栏", - "type": [ - "workbenck_shortcuts" - ] + "currency_name": "日元", + "currency_symbol": "¥", + "id": "ja_JP", + "strings_language": "ja_JP", + "currency_code": "JPY", + "name": "Japan" }, { - "show": true, - "key": "ctrl+n", - "winKey": "alt+n", - "name": [ - "new_datasheet" - ], - "when": "!isRecordExpanding", - "id": "ctrl+n", - "command": "NewDatasheet", - "description": "新建维格表", - "type": [ - "workbenck_shortcuts" - ] + "currency_name": "人民币", + "currency_symbol": "¥", + "id": "zh_CN", + "strings_language": "zh_CN", + "currency_code": "RMB", + "name": "简体中文\n" }, { - "show": true, - "key": "ctrl+shift+n", - "winKey": "alt+shift+n", - "name": [ - "new_folder" - ], - "when": "!isRecordExpanding", - "id": "ctrl+shift+n", - "command": "NewFolder", - "description": "新建文件夹", - "type": [ - "workbenck_shortcuts" - ] + "currency_name": "港币", + "currency_symbol": "$", + "id": "zh_HK", + "strings_language": "zh_HK", + "currency_code": "HKD", + "name": "繁体中文(中国香港)" }, { - "show": true, - "key": "f2", - "winKey": "f2 ", - "name": [ - "rename" - ], - "when": "!isRecordExpanding", - "id": "f2", - "command": "RenameNode", - "description": "重命名", - "type": [ - "workbenck_shortcuts" - ] + "currency_name": "新币", + "currency_symbol": "$", + "id": "zh_SG", + "strings_language": "zh_HK", + "currency_code": "SGD", + "name": "繁体中文(新加坡)" }, { - "show": true, - "key": "ctrl+s", - "winKey": "alt+s", - "name": [ - "share" + "currency_name": "台币", + "currency_symbol": "$", + "id": "zh_TW", + "strings_language": "zh_HK", + "currency_code": "HKD", + "name": "繁体中文(台湾)" + } + ], + "marketplace": { + "cli_9f3930dd7d7ad00c": { + "logo": { + "id": "atcEEp5gDuMWu", + "name": "feishu.svg", + "size": 1059, + "mimeType": "image/svg+xml", + "token": "space/2021/04/28/4c4be697b9e94672a7c65d979b60ab95", + "width": 0, + "height": 0, + "url": "https://s1.vika.cn/space/2021/04/28/4c4be697b9e94672a7c65d979b60ab95" + }, + "env": [ + "integration" ], - "when": "!isRecordExpanding", - "id": "ctrl+s", - "command": "Share", - "description": "分享", - "type": [ - "workbenck_shortcuts" - ] + "disable": true, + "app_info": "marketplace_integration_app_info_fesihu", + "note": "marketplace_integration_app_note_feishu", + "app_name": "marketplace_integration_app_name_feishu", + "type": "integration", + "app_description": "marketplace_integration_app_dec_feishu", + "id": "cli_9f3930dd7d7ad00c", + "display_order": 10, + "image": { + "id": "atcnIol43SAeV", + "name": "飞书集成.png", + "size": 362548, + "mimeType": "image/png", + "token": "space/2021/12/08/8742173785d34efc905ba1fd23227cc0", + "width": 1600, + "height": 1072, + "url": "https://s1.vika.cn/space/2021/12/08/8742173785d34efc905ba1fd23227cc0" + }, + "app_id": "cli_9f3930dd7d7ad00c", + "link_to_cms": "integration_feishu_help_url", + "app_type": "LARK_STORE", + "btn_card": { + "btn_text": "marketplace_integration_btncard_btntext_open", + "btn_action": "https://app.feishu.cn/app/cli_9f3930dd7d7ad00c", + "btn_type": "primary", + "btn_close_action": "https://www.feishu.cn/admin/#/appCenter/manage/cli_9f3930dd7d7ad00c?lang=zh-CN", + "apps_btn_text": "marketplace_integration_btncard_appsbtntext_read_more" + }, + "modal": { + "btn_text": "marketplace_integration_btncard_appsbtntext_read_more", + "btn_action": "https://app.feishu.cn/app/cli_9f3930dd7d7ad00c", + "app_description": "marketplace_integration_app_dec_feishu", + "btn_type": "primary", + "help_link": "integration_feishu_help_url" + } }, - { - "show": true, - "key": "ctrl+p", - "winKey": "alt+p", - "name": [ - "permission_setting" + "cli_a08120b120fad00e": { + "logo": { + "id": "atc8qT4qak5kW", + "name": "feishu.svg", + "size": 1059, + "mimeType": "image/svg+xml", + "token": "space/2021/04/28/4c4be697b9e94672a7c65d979b60ab95", + "width": 0, + "height": 0, + "url": "https://s1.vika.cn/space/2021/04/28/4c4be697b9e94672a7c65d979b60ab95" + }, + "env": [ + "staging" ], - "when": "!isRecordExpanding", - "id": "ctrl+p", - "command": "Permission", - "description": "设置权限", - "type": [ - "workbenck_shortcuts" - ] + "disable": true, + "app_info": "marketplace_integration_app_info_fesihu", + "note": "marketplace_integration_app_note_feishu", + "app_name": "marketplace_integration_app_name_feishu", + "type": "integration", + "app_description": "marketplace_integration_app_dec_feishu", + "id": "cli_a08120b120fad00e", + "display_order": 10, + "image": { + "id": "atcEedAZX3ufL", + "name": "飞书集成.png", + "size": 362548, + "mimeType": "image/png", + "token": "space/2021/12/08/8742173785d34efc905ba1fd23227cc0", + "width": 1600, + "height": 1072, + "url": "https://s1.vika.cn/space/2021/12/08/8742173785d34efc905ba1fd23227cc0" + }, + "app_id": "cli_a08120b120fad00e", + "link_to_cms": "integration_feishu_help_url", + "app_type": "LARK_STORE", + "btn_card": { + "btn_text": "marketplace_integration_btncard_btntext_open", + "btn_action": "https://app.feishu.cn/app/cli_a08120b120fad00e", + "btn_type": "primary", + "btn_close_action": "https://www.feishu.cn/admin/#/appCenter/manage/cli_a08120b120fad00e?lang=zh-CN", + "apps_btn_text": "marketplace_integration_btncard_appsbtntext_read_more" + }, + "modal": { + "btn_text": "marketplace_integration_btncard_appsbtntext_read_more", + "btn_action": "https://app.feishu.cn/app/cli_a08120b120fad00e", + "app_description": "marketplace_integration_app_dec_feishu", + "btn_type": "primary", + "help_link": "integration_feishu_help_url" + } }, - { - "show": true, - "key": "cmd+shift+s", - "winKey": "ctrl+shift+s", - "name": [ - "create_backup" + "cli_9f614b454434500e": { + "logo": { + "id": "atckEWR2o3EgR", + "name": "feishu.svg", + "size": 1059, + "mimeType": "image/svg+xml", + "token": "space/2021/04/28/4c4be697b9e94672a7c65d979b60ab95", + "width": 0, + "height": 0, + "url": "https://s1.vika.cn/space/2021/04/28/4c4be697b9e94672a7c65d979b60ab95" + }, + "env": [ + "production" ], - "when": "!isRecordExpanding", - "id": "cmd+shift+S", - "command": "CreateBackup", - "description": "创建历史备份", - "type": [ - "workbenck_shortcuts" - ] + "disable": true, + "app_info": "marketplace_integration_app_info_fesihu", + "note": "marketplace_integration_app_note_feishu", + "app_name": "marketplace_integration_app_name_feishu", + "type": "integration", + "app_description": "marketplace_integration_app_dec_feishu", + "id": "cli_9f614b454434500e", + "display_order": 10, + "image": { + "id": "atcLNS2l4KYxV", + "name": "飞书集成.png", + "size": 362548, + "mimeType": "image/png", + "token": "space/2021/12/08/8742173785d34efc905ba1fd23227cc0", + "width": 1600, + "height": 1072, + "url": "https://s1.vika.cn/space/2021/12/08/8742173785d34efc905ba1fd23227cc0" + }, + "app_id": "cli_9f614b454434500e", + "link_to_cms": "integration_feishu_help_url", + "app_type": "LARK_STORE", + "btn_card": { + "btn_text": "marketplace_integration_btncard_btntext_open", + "btn_action": "https://app.feishu.cn/app/cli_9f614b454434500e", + "btn_type": "primary", + "btn_close_action": "https://www.feishu.cn/admin/#/appCenter/manage/cli_9f614b454434500e?lang=zh-CN", + "apps_btn_text": "marketplace_integration_btncard_appsbtntext_read_more" + }, + "modal": { + "btn_text": "marketplace_integration_btncard_appsbtntext_read_more", + "btn_action": "https://app.feishu.cn/app/cli_9f614b454434500e", + "app_description": "marketplace_integration_app_dec_feishu", + "btn_type": "primary", + "help_link": "integration_feishu_help_url" + } }, - { - "show": true, - "key": "ctrl+t", - "winKey": "alt+t", - "name": [ - "save_as_template" + "ina5200279359980055": { + "logo": { + "id": "atcPfGUqrcZ5j", + "name": "企业微信.svg", + "size": 5878, + "mimeType": "image/svg+xml", + "token": "space/2021/04/28/e043014e0af54bf58c6bb78e92b00b60", + "width": 0, + "height": 0, + "url": "https://s1.vika.cn/space/2021/04/28/e043014e0af54bf58c6bb78e92b00b60" + }, + "env": [ + "integration", + "staging", + "production" ], - "when": "!isRecordExpanding", - "id": "ctrl+t", - "command": "SaveAsTemplate", - "description": "保存为模板", - "type": [ - "workbenck_shortcuts" - ] + "app_info": "marketplace_integration_app_info_wecahtcp", + "note": "marketplace_integration_app_note_wechatcp", + "app_name": "marketplace_integration_app_name_wechatcp", + "type": "integration", + "app_description": "marketplace_integration_app_dec_wechatcp", + "id": "ina5200279359980055", + "display_order": 30, + "image": { + "id": "atcuiGRXDfIoT", + "name": "企业微信集成.png", + "size": 599396, + "mimeType": "image/png", + "token": "space/2021/12/08/772be217f729479985295ae30dc63291", + "width": 1600, + "height": 1072, + "url": "https://s1.vika.cn/space/2021/12/08/772be217f729479985295ae30dc63291" + }, + "app_id": "ina5200279359980055", + "link_to_cms": "integration_wecom_help_url", + "app_type": "WECOM_STORE", + "btn_card": { + "btn_text": "marketplace_integration_btncard_btntext_open", + "btn_action": "/user/wecom/integration/bind", + "btn_type": "primary", + "apps_btn_text": "marketplace_integration_btncard_appsbtntext_read_more" + }, + "modal": { + "btn_text": "0", + "app_description": "marketplace_integration_app_dec_wechatcp", + "btn_type": "primary", + "help_link": "integration_wecom_help_url" + } }, - { - "show": true, - "key": "cmd+b", - "winKey": "ctrl+b", - "name": [ - "toggle_catalog_panel" + "ina9134969049653777": { + "logo": { + "id": "atcpH3rGddayo", + "name": "ding.svg", + "size": 1831, + "mimeType": "image/svg+xml", + "token": "space/2021/04/28/7af742cdbb3c4ae3a76e30e68bf471cb", + "width": 0, + "height": 0, + "url": "https://s1.vika.cn/space/2021/04/28/7af742cdbb3c4ae3a76e30e68bf471cb" + }, + "env": [ + "integration", + "staging", + "production" ], - "when": "!isRecordExpanding && !modalVisible", - "id": "cmd+b", - "command": "ToggleCatalogPanel", - "description": "展开折叠目录面板", - "type": [ - "workbenck_shortcuts" - ] - }, - { - "key": "space", - "winKey": "space", - "when": "!isGlobalEditing && isRecordExpanding && !isEditing", - "id": "space", - "command": "CloseExpandRecord" + "app_info": "marketplace_integration_app_info_dingtalk", + "note": "marketplace_integration_app_note_dingtalk", + "app_name": "marketplace_integration_app_name_dingtalk", + "type": "integration", + "app_description": "marketplace_integration_app_dec_dingtalk", + "id": "ina9134969049653777", + "display_order": 20, + "image": { + "id": "atcOhMLdK4DOv", + "name": "钉钉集成.png", + "size": 124923, + "mimeType": "image/png", + "token": "space/2021/12/08/46a769fdf74d4c0f8676f3ccca358643", + "width": 1600, + "height": 1072, + "url": "https://s1.vika.cn/space/2021/12/08/46a769fdf74d4c0f8676f3ccca358643" + }, + "app_id": "ina9134969049653777", + "link_to_cms": "integration_dingtalk_help_url", + "app_type": "DINGTALK_STORE", + "btn_card": { + "btn_text": "marketplace_integration_btncard_btntext_open", + "btn_action": "/help/integration-dingtalk/", + "btn_type": "primary", + "apps_btn_text": "marketplace_integration_btncard_appsbtntext_read_more" + }, + "modal": { + "btn_text": "marketplace_integration_btncard_appsbtntext_read_more", + "btn_action": "/help/integration-dingtalk/", + "app_description": "marketplace_integration_app_dec_dingtalk", + "btn_type": "primary", + "help_link": "integration_dingtalk_help_url" + } }, - { - "key": "shift+tab", - "winKey": "shift+tab", - "when": "isRecordExpanding", - "id": "shift+tab", - "command": "RecordShiftTab" + "ina5645957505507647": { + "logo": { + "id": "atclqW8EjJIFz", + "name": "Frame.svg", + "size": 575, + "mimeType": "image/svg+xml", + "token": "space/2021/04/28/0c070534ccda4b4dbae3f4c7c303d02e", + "width": 0, + "height": 0, + "url": "https://s1.vika.cn/space/2021/04/28/0c070534ccda4b4dbae3f4c7c303d02e" + }, + "env": [ + "integration", + "staging", + "production" + ], + "app_info": "marketplace_integration_app_info_office_preview", + "note": "marketplace_integration_app_note_office_preview", + "app_name": "marketplace_integration_app_name_officepreview", + "type": "integration", + "app_description": "marketplace_integration_app_dec_office_preview", + "id": "ina5645957505507647", + "display_order": 20, + "image": { + "id": "atczaIPjTBq8F", + "name": "永中集成.png", + "size": 473712, + "mimeType": "image/png", + "token": "space/2021/12/08/18efb2fce9a64dc08262fc5cc8f0eac1", + "width": 1600, + "height": 1072, + "url": "https://s1.vika.cn/space/2021/12/08/18efb2fce9a64dc08262fc5cc8f0eac1" + }, + "app_id": "ina5645957505507647", + "link_to_cms": "integration_yozosoft_help_url", + "app_type": "OFFICE_PREVIEW", + "btn_card": { + "btn_text": "marketplace_integration_btncard_btntext_authorize", + "btn_type": "primary", + "apps_btn_text": "marketplace_integration_btncard_appsbtntext_read_more" + }, + "modal": { + "btn_text": "marketplace_integration_btncard_appsbtntext_read_more", + "app_description": "marketplace_integration_app_dec_office_preview", + "btn_type": "primary", + "help_link": "integration_yozosoft_help_url" + } + } + }, + "test_function": { + "async_compute": { + "feature_name": "async_compute", + "logo": "space/2022/01/25/bef8c76826c540c8a14c7f10938a60f9", + "id": "async_compute", + "note": "test_function_note_async_compute", + "feature_key": "async_compute", + "modal": { + "btn_text": "enable", + "info": "test_function_modal_info_async_compute", + "btn_action": "https://app.feishu.cn/app/cli_9f3930dd7d7ad00c", + "btn_type": "primary", + "info的副本": "test_function_card_info_async_compute", + "info_image": "ASYNC_COMPUTE_INFO_IMAGE" + }, + "card": { + "btn_open_action": "/", + "info": "test_function_card_info_async_compute", + "info的副本": "test_function_card_info_async_compute", + "btn_close_action": "/", + "btn_text": "test_function_btncard_btntext_open", + "btn_type": "primary" + } }, - { - "key": "tab", - "winKey": "tab", - "when": "isRecordExpanding", - "id": "tab", - "command": "RecordTab" + "render_prompt": { + "feature_name": "render_prompt", + "logo": "space/2022/01/25/387465f4e3eb40b4a53a44fea624cd02", + "id": "render_prompt", + "note": "test_function_note_render_prompt", + "feature_key": "render_prompt", + "modal": { + "btn_text": "enable", + "info": "test_function_modal_info_render_prompt", + "btn_action": "https://app.feishu.cn/app/cli_a08120b120fad00e", + "btn_type": "primary", + "info的副本": "test_function_card_info_render_prompt", + "info_image": "RENDER_PROMPT_INFO_IMAGE" + }, + "card": { + "btn_open_action": "/", + "info": "test_function_card_info_render_prompt", + "info的副本": "test_function_card_info_render_prompt", + "btn_close_action": "/", + "btn_text": "test_function_btncard_btntext_open", + "btn_type": "primary" + } }, - { - "show": true, - "key": "cmd+shift+o", - "winKey": "ctrl+shift+o", - "name": [ - "toggle_widget_panel" - ], - "when": "!isRecordExpanding", - "id": "cmd+shift+o", - "command": "ToggleWidgetPanel", - "description": "展开小程序", - "type": [ - "global_shortcuts" - ] + "robot": { + "feature_name": "robot", + "logo": "space/2022/01/25/4a36a62cf12c47a0bf29b4808f5fcbb8", + "id": "robot", + "note": "test_function_note_robot", + "feature_key": "robot", + "modal": { + "btn_text": "test_function_btnmodal_btntext", + "info": "test_function_modal_info_robot", + "btn_action": "https://vika.cn/share/shrL1BVlA2ZhkSE7nYEgt", + "btn_type": "primary", + "info的副本": "test_function_card_info_robot", + "info_image": "ROBOT_INFO_IMAGE" + }, + "card": { + "btn_open_action": "/", + "info": "test_function_card_info_robot", + "info的副本": "test_function_card_info_robot", + "btn_close_action": "/", + "btn_text": "test_function_btncard_btntext_apply", + "btn_type": "primary" + } }, - { - "key": "cmd+shift+d", - "winKey": "ctrl+shift+d", - "when": "!isRecordExpanding", - "id": "cmd+shift+d", - "command": "ToggleDevPanel" + "widget_center": { + "feature_name": "widget_name", + "logo": "space/2022/01/25/ff9091547ee84a6c87c3bc7ec1640f25", + "id": "widget_center", + "note": "test_function_note_widget", + "feature_key": "widget_center", + "modal": { + "btn_text": "test_function_btnmodal_btntext", + "info": "test_function_modal_info_widget", + "btn_action": "https://vika.cn/share/shrL1BVlA2ZhkSE7nYEgt", + "btn_type": "primary", + "info的副本": "test_function_card_info_widget", + "info_image": "WIDGET_CENTER_INFO_IMAGE" + }, + "card": { + "btn_open_action": "/", + "info": "test_function_card_info_widget", + "info的副本": "test_function_card_info_widget", + "btn_close_action": "/", + "btn_text": "test_function_btncard_btntext_apply", + "btn_type": "primary" + } }, - { - "key": "cmd+alt+d", - "winKey": "ctrl+alt+d", - "when": "!isRecordExpanding", - "id": "cmd+alt+d", - "command": "ToggleDevPanel" + "render_normal": { + "feature_name": "render_normal", + "logo": "space/2022/01/25/52f1fe2f1be34a2fb1227fc36d8861fc", + "id": "render_normal", + "note": "test_function_note_render_normal", + "feature_key": "render_normal", + "modal": { + "btn_text": "enable", + "info": "test_function_modal_info_render_normal", + "btn_type": "primary", + "info的副本": "test_function_card_info_render_normal", + "info_image": "RENDER_NORMAL_INFO_IMAGE" + }, + "card": { + "btn_open_action": "/", + "info": "test_function_card_info_render_normal", + "info的副本": "test_function_card_info_render_normal", + "btn_close_action": "/", + "btn_text": "test_function_btncard_btntext_open", + "btn_type": "primary" + } }, - { - "key": "up", - "winKey": "up", - "when": "isQuickSearchExpanding", - "id": "up", - "command": "QuickSearchUp" + "view_manual_save": { + "feature_name": "view_manual_save", + "logo": "space/2022/01/25/4aa6c029188645cebd8c31f3def205d9", + "id": "view_manual_save", + "note": "test_function_note_view_manual_save", + "feature_key": "view_manual_save", + "modal": { + "btn_text": "enable", + "info": "test_function_modal_info_view_manual_save", + "btn_type": "primary", + "info的副本": "test_function_card_info_view_manual_save", + "info_image": "VIEW_MANUAL_SAVE_INFO_IMAGE" + }, + "card": { + "btn_open_action": "/", + "info": "test_function_card_info_view_manual_save", + "info的副本": "test_function_card_info_view_manual_save", + "btn_close_action": "/", + "btn_text": "test_function_btncard_btntext_open", + "btn_type": "primary" + } + } + }, + "player": { + "trigger": [ + { + "actions": [ + "open_guide_wizards([4])" + ], + "rules": [ + "identity_ALL_OF_TRUE_['main_admin']", + "device_IS_pc", + "sign_up_time_IS_AFTER_2023-11-23 20:00" + ], + "id": "address_shown,[identity_ALL_OF_TRUE_['main_admin'], device_IS_pc, sign_up_time_IS_AFTER_2023-11-23 20:00],[open_guide_wizards([4])]", + "event": [ + "address_shown" + ] + }, + { + "actions": [ + "open_guide_wizard(113)" + ], + "rules": [ + "device_IS_pc", + "url_EXCLUDES_templateId", + "url_EXCLUDES_shareId" + ], + "id": "ai_create_ai_node,[device_IS_pc, url_EXCLUDES_templateId, url_EXCLUDES_shareId],[open_guide_wizard(113)]", + "event": [ + "ai_create_ai_node" + ] + }, + { + "actions": [ + "open_guide_wizard(35)" + ], + "rules": [ + "device_IS_pc", + "url_EXCLUDES_templateId", + "url_EXCLUDES_shareId", + "edition_IS_vika" + ], + "id": "datasheet_add_new_view,[device_IS_pc, url_EXCLUDES_templateId, url_EXCLUDES_shareId, edition_IS_vika],[open_guide_wizard(35)]", + "event": [ + "datasheet_add_new_view" + ], + "eventState": "{\"viewType\":6}" + }, + { + "actions": [ + "open_guide_wizard(38)" + ], + "rules": [ + "device_IS_pc", + "url_EXCLUDES_templateId", + "url_EXCLUDES_shareId", + "edition_IS_vika" + ], + "id": "datasheet_add_new_view,[device_IS_pc, url_EXCLUDES_templateId, url_EXCLUDES_shareId, edition_IS_vika],[open_guide_wizard(38)]", + "event": [ + "datasheet_add_new_view" + ], + "eventState": "{\"viewType\":5}" + }, + { + "actions": [ + "open_guide_wizard(55)" + ], + "rules": [ + "device_IS_pc", + "url_EXCLUDES_templateId", + "url_EXCLUDES_shareId", + "edition_IS_vika" + ], + "id": "datasheet_add_new_view,[device_IS_pc, url_EXCLUDES_templateId, url_EXCLUDES_shareId, edition_IS_vika],[open_guide_wizard(55)]", + "event": [ + "datasheet_add_new_view" + ], + "eventState": "{\"viewType\":7}" + }, + { + "actions": [ + "open_guide_wizard(106)" + ], + "rules": [ + "device_IS_pc" + ], + "id": "datasheet_create_mirror_tip,[device_IS_pc],[open_guide_wizard(106)]", + "event": [ + "datasheet_create_mirror_tip" + ] + }, + { + "actions": [ + "open_guide_wizard(30)" + ], + "rules": [ + "device_IS_pc", + "url_EXCLUDES_templateId", + "url_EXCLUDES_shareId" + ], + "id": "datasheet_dashboard_panel_shown,[device_IS_pc, url_EXCLUDES_templateId, url_EXCLUDES_shareId],[open_guide_wizard(30)]", + "event": [ + "datasheet_dashboard_panel_shown" + ] + }, + { + "actions": [ + "open_guide_wizard(88)" + ], + "rules": [ + "device_IS_pc", + "url_EXCLUDES_templateId", + "url_EXCLUDES_shareId" + ], + "id": "datasheet_gantt_view_shown,[device_IS_pc, url_EXCLUDES_templateId, url_EXCLUDES_shareId],[open_guide_wizard(88)]", + "event": [ + "datasheet_gantt_view_shown" + ] + }, + { + "actions": [ + "open_guide_wizard(84)" + ], + "rules": [ + "device_IS_pc" + ], + "id": "datasheet_user_menu,[device_IS_pc],[open_guide_wizard(84)]", + "event": [ + "datasheet_user_menu" + ] + }, + { + "actions": [ + "open_guide_wizards([31])" + ], + "rules": [ + "device_IS_pc", + "sign_up_time_IS_AFTER_2023-11-23 20:00", + "url_EXCLUDES_templateId", + "url_EXCLUDES_shareId" + ], + "id": "datasheet_wigdet_empty_panel_shown,[device_IS_pc, sign_up_time_IS_AFTER_2023-11-23 20:00, url_EXCLUDES_templateId, url_EXCLUDES_shareId],[open_guide_wizards([31])]", + "event": [ + "datasheet_wigdet_empty_panel_shown" + ] + }, + { + "actions": [ + "open_guide_wizard([117])" + ], + "rules": [ + "device_IS_pc", + "url_EXCLUDES_templateId", + "url_EXCLUDES_shareId" + ], + "id": "guide_use_automation_first_time,[device_IS_pc, url_EXCLUDES_templateId, url_EXCLUDES_shareId],[open_guide_wizard([117])]", + "event": [ + "guide_use_automation_first_time" + ] + }, + { + "actions": [ + "open_guide_wizard(85)" + ], + "rules": [ + "device_IS_pc", + "sign_up_time_IS_AFTER_2022-04-10 00:00" + ], + "id": "questionnaire_shown_after_sign,[device_IS_pc, sign_up_time_IS_AFTER_2022-04-10 00:00],[open_guide_wizard(85)]", + "event": [ + "questionnaire_shown_after_sign" + ] + }, + { + "actions": [ + "open_guide_wizard(41)" + ], + "rules": [ + "device_IS_pc", + "url_EXCLUDES_shareId", + "wizard[42].count_GREATER_THAN_300", + "wizard[43].count_GREATER_THAN_100" + ], + "id": "questionnaire_shown,[device_IS_pc, url_EXCLUDES_shareId, wizard[42].count_GREATER_THAN_300, wizard[43].count_GREATER_THAN_100],[open_guide_wizard(41)]", + "event": [ + "questionnaire_shown" + ] + }, + { + "actions": [ + "open_guide_wizard(41)" + ], + "rules": [ + "wizard[42].count_GREATER_THAN_1000", + "device_IS_pc", + "url_EXCLUDES_shareId", + "wizard[43].count_GREATER_THAN_200" + ], + "id": "questionnaire_shown,[wizard[42].count_GREATER_THAN_1000, device_IS_pc, url_EXCLUDES_shareId, wizard[43].count_GREATER_THAN_200],[open_guide_wizard(41)]", + "event": [ + "questionnaire_shown" + ] + }, + { + "actions": [ + "open_guide_wizard(41)" + ], + "rules": [ + "wizard[42].count_GREATER_THAN_6000", + "identity_ALL_OF_TRUE_['main_admin']", + "device_IS_pc", + "url_EXCLUDES_shareId" + ], + "id": "questionnaire_shown,[wizard[42].count_GREATER_THAN_6000, identity_ALL_OF_TRUE_['main_admin'], device_IS_pc, url_EXCLUDES_shareId],[open_guide_wizard(41)]", + "event": [ + "questionnaire_shown" + ] + }, + { + "actions": [ + "open_guide_wizards([19])" + ], + "rules": [ + "device_IS_pc", + "identity_ALL_OF_TRUE_['main_admin']", + "sign_up_time_IS_AFTER_2023-11-23 20:00", + "url_EXCLUDES_templateId", + "url_EXCLUDES_shareId" + ], + "id": "template_center_shown,[device_IS_pc, identity_ALL_OF_TRUE_['main_admin'], sign_up_time_IS_AFTER_2023-11-23 20:00, url_EXCLUDES_templateId, url_EXCLUDES_shareId],[open_guide_wizards([19])]", + "event": [ + "template_center_shown" + ] + }, + { + "actions": [ + "open_guide_wizard(78)" + ], + "rules": [ + "device_IS_pc", + "url_EXCLUDES_templateId", + "url_EXCLUDES_shareId" + ], + "id": "view_add_panel_shown,[device_IS_pc, url_EXCLUDES_templateId, url_EXCLUDES_shareId],[open_guide_wizard(78)]", + "event": [ + "view_add_panel_shown" + ] + }, + { + "actions": [ + "open_guide_wizard(52)" + ], + "id": "view_notice_auto_save_true,[],[open_guide_wizard(52)]", + "event": [ + "view_notice_auto_save_true" + ] + }, + { + "actions": [ + "open_guide_wizard(51)" + ], + "rules": [ + "labs_ONE_OF_TRUE_['view_manual_save']" + ], + "id": "view_notice_view_auto_false,[labs_ONE_OF_TRUE_['view_manual_save']],[open_guide_wizard(51)]", + "event": [ + "view_notice_view_auto_false" + ] + }, + { + "actions": [ + "open_guide_wizard(50)" + ], + "rules": [ + "labs_ONE_OF_TRUE_['view_manual_save']" + ], + "id": "viewset_manual_save_tip,[labs_ONE_OF_TRUE_['view_manual_save']],[open_guide_wizard(50)]", + "event": [ + "viewset_manual_save_tip" + ] + }, + { + "actions": [ + "open_guide_wizard(22)" + ], + "rules": [ + "device_IS_pc", + "url_EXCLUDES_templateId", + "url_EXCLUDES_shareId" + ], + "id": "workbench_create_form_bth_clicked,[device_IS_pc, url_EXCLUDES_templateId, url_EXCLUDES_shareId],[open_guide_wizard(22)]", + "event": [ + "workbench_create_form_bth_clicked" + ], + "suspended": true + }, + { + "actions": [ + "open_guide_wizard(61)" + ], + "rules": [ + "device_IS_pc", + "url_EXCLUDES_shareId" + ], + "id": "workbench_folder_from_template_showcase_shown,[device_IS_pc, url_EXCLUDES_shareId],[open_guide_wizard(61)]", + "event": [ + "workbench_folder_from_template_showcase_shown" + ] + }, + { + "actions": [ + "open_guide_wizard(46)" + ], + "rules": [ + "device_IS_pc", + "url_EXCLUDES_templateId", + "url_EXCLUDES_shareId" + ], + "id": "workbench_form_container_shown,[device_IS_pc, url_EXCLUDES_templateId, url_EXCLUDES_shareId],[open_guide_wizard(46)]", + "event": [ + "workbench_form_container_shown" + ] + }, + { + "actions": [ + "open_guide_wizard(25)" + ], + "rules": [ + "device_IS_pc", + "url_EXCLUDES_templateId", + "url_EXCLUDES_shareId" + ], + "id": "workbench_hidden_vikaby_btn_clicked,[device_IS_pc, url_EXCLUDES_templateId, url_EXCLUDES_shareId],[open_guide_wizard(25)]", + "event": [ + "workbench_hidden_vikaby_btn_clicked" + ] + }, + { + "actions": [ + "open_guide_wizards([105, 104])" + ], + "rules": [ + "device_IS_pc", + "url_EXCLUDES_templateId", + "url_EXCLUDES_shareId", + "edition_IS_apitable" + ], + "id": "workbench_show_trial_tip,[device_IS_pc, url_EXCLUDES_templateId, url_EXCLUDES_shareId, edition_IS_apitable],[open_guide_wizards([105, 104])]", + "event": [ + "workbench_show_trial_tip" + ] + }, + { + "actions": [ + "open_guide_wizards([29, 76, 138])" + ], + "rules": [ + "device_IS_pc", + "sign_up_time_IS_BEFORE_2024-12-31 23:59", + "url_EXCLUDES_templateId", + "url_EXCLUDES_shareId", + "edition_IS_vika" + ], + "id": "workbench_shown,[device_IS_pc, sign_up_time_IS_BEFORE_2024-12-31 23:59, url_EXCLUDES_templateId, url_EXCLUDES_shareId, edition_IS_vika],[open_guide_wizards([29, 76, 138])]", + "event": [ + "workbench_shown" + ] + }, + { + "actions": [ + "open_guide_wizards([105, 115])" + ], + "rules": [ + "device_IS_pc", + "url_EXCLUDES_templateId", + "url_EXCLUDES_shareId", + "edition_IS_apitable" + ], + "id": "workbench_shown,[device_IS_pc, url_EXCLUDES_templateId, url_EXCLUDES_shareId, edition_IS_apitable],[open_guide_wizards([105, 115])]", + "event": [ + "workbench_shown" + ] + }, + { + "actions": [ + "open_guide_wizards([1, 24, 104])" + ], + "rules": [ + "device_IS_pc", + "url_EXCLUDES_templateId", + "url_EXCLUDES_shareId", + "edition_IS_vika", + "sign_up_time_IS_AFTER_2023-12-28 20:00" + ], + "id": "workbench_shown,[device_IS_pc, url_EXCLUDES_templateId, url_EXCLUDES_shareId, edition_IS_vika, sign_up_time_IS_AFTER_2023-12-28 20:00],[open_guide_wizards([1, 24, 104])]", + "event": [ + "workbench_shown" + ] + }, + { + "actions": [ + "open_guide_wizards([76, 138])" + ], + "rules": [ + "sign_up_time_IS_BEFORE_2024-12-31 23:59", + "device_IS_mobile", + "url_EXCLUDES_templateId", + "url_EXCLUDES_shareId", + "edition_IS_vika" + ], + "id": "workbench_shown,[sign_up_time_IS_BEFORE_2024-12-31 23:59, device_IS_mobile, url_EXCLUDES_templateId, url_EXCLUDES_shareId, edition_IS_vika],[open_guide_wizards([76, 138])]", + "event": [ + "workbench_shown" + ] + }, + { + "actions": [ + "open_guide_wizards([76])" + ], + "rules": [ + "sign_up_time_IS_BEFORE_2024-12-31 23:59", + "url_EXCLUDES_templateId", + "url_EXCLUDES_shareId", + "device_IS_app", + "edition_IS_vika" + ], + "id": "workbench_shown,[sign_up_time_IS_BEFORE_2024-12-31 23:59, url_EXCLUDES_templateId, url_EXCLUDES_shareId, device_IS_app, edition_IS_vika],[open_guide_wizards([76])]", + "event": [ + "workbench_shown" + ] + } + ], + "events": { + "_": {}, + "address_shown": { + "module": "address", + "name": "shown" + }, + "ai_create_ai_node": { + "module": "ai", + "guide": { + "step": [ + "recn59RPV1b8Q" + ] + }, + "name": "create_ai_node" + }, + "app_error_logger": { + "module": "app", + "name": "error_logger" + }, + "app_modal_confirm": { + "module": "app", + "name": "modal_confirm" + }, + "app_set_user_id": { + "module": "app", + "name": "set_user_id" + }, + "app_tracker": { + "module": "app", + "name": "tracker" + }, + "datasheet_add_new_view": { + "module": "datasheet", + "name": "add_new_view" + }, + "datasheet_create_mirror_tip": { + "module": "datasheet", + "guide": { + "step": [ + "recixOMO4Roib" + ] + }, + "name": "create_mirror_tip" + }, + "datasheet_dashboard_panel_shown": { + "module": "datasheet", + "name": "dashboard_panel_shown" + }, + "datasheet_delete_record": { + "module": "datasheet", + "name": "delete_record" + }, + "datasheet_field_context_hidden": { + "module": "datasheet", + "name": "field_context_hidden" + }, + "datasheet_field_context_shown": { + "module": "datasheet", + "name": "field_context_shown" + }, + "datasheet_field_setting_hidden": { + "module": "datasheet", + "guide": { + "step": [ + "recMyeQyjTId0" + ] + }, + "name": "field_setting_hidden" + }, + "datasheet_field_setting_shown": { + "module": "datasheet", + "name": "field_setting_shown" + }, + "datasheet_gantt_view_shown": { + "module": "datasheet", + "name": "gantt_view_shown" + }, + "datasheet_grid_view_shown": { + "module": "datasheet", + "guide": { + "step": [ + "recYXMUXd8Rv8" + ] + }, + "name": "grid_view_shown" + }, + "datasheet_org_has_link_field": { + "module": "datasheet", + "name": "org_has_link_field" + }, + "datasheet_org_view_add_first_node": { + "module": "datasheet", + "name": "org_view_add_first_node" + }, + "datasheet_org_view_drag_to_unhandled_list": { + "module": "datasheet", + "name": "org_view_drag_to_unhandled_list" + }, + "datasheet_org_view_right_panel_shown": { + "module": "datasheet", + "name": "org_view_right_panel_shown" + }, + "datasheet_search_panel_hidden": { + "module": "datasheet", + "guide": { + "step": [ + "recnHGTjyU7Jw" + ] + }, + "name": "search_panel_hidden" + }, + "datasheet_search_panel_shown": { + "module": "datasheet", + "guide": { + "step": [ + "reczmcUK1NLK4" + ] + }, + "name": "search_panel_shown" + }, + "datasheet_shown": { + "module": "datasheet", + "name": "shown" + }, + "datasheet_user_menu": { + "module": "datasheet", + "name": "user_menu" + }, + "datasheet_widget_center_modal_shown": { + "module": "datasheet", + "guide": { + "step": [ + "reciAEMbU27Q0" + ] + }, + "name": "widget_center_modal_shown" + }, + "datasheet_wigdet_empty_panel_shown": { + "module": "datasheet", + "name": "wigdet_empty_panel_shown" + }, + "get_context_menu_file_more": { + "module": "get_context_menu", + "name": "file_more" + }, + "get_context_menu_folder_more": { + "module": "get_context_menu", + "name": "folder_more" + }, + "get_context_menu_root_add": { + "module": "get_context_menu", + "name": "root_add" + }, + "get_nav_list": { + "module": "get_nav", + "name": "list" + }, + "guide_use_automation_first_time": { + "module": "guide", + "name": "use_automation_first_time" + }, + "invite_entrance_modal_shown": { + "module": "invite", + "name": "entrance_modal_shown" + }, + "questionnaire_shown": { + "module": "questionnaire", + "name": "shown" + }, + "questionnaire_shown_after_sign": { + "module": "questionnaire", + "name": "shown_after_sign" + }, + "space_setting_main_admin_shown": { + "module": "space_setting", + "name": "main_admin_shown" + }, + "space_setting_member_manage_shown": { + "module": "space_setting", + "name": "member_manage_shown" + }, + "space_setting_overview_shown": { + "module": "space_setting", + "name": "overview_shown" + }, + "space_setting_sub_admin_shown": { + "module": "space_setting", + "name": "sub_admin_shown" + }, + "space_setting_workbench_shown": { + "module": "space_setting", + "name": "workbench_shown" + }, + "template_center_shown": { + "module": "template", + "name": "center_shown" + }, + "template_detail_shown": { + "module": "template", + "name": "detail_shown" + }, + "template_use_confirm_modal_shown": { + "module": "template", + "name": "use_confirm_modal_shown" + }, + "view_add_panel_shown": { + "module": "view", + "name": "add_panel_shown" + }, + "view_convert_gallery": { + "module": "view", + "name": "convert_gallery" + }, + "view_notice_auto_save_true": { + "module": "view", + "name": "notice_auto_save_true" + }, + "view_notice_view_auto_false": { + "module": "view", + "name": "notice_view_auto_false" + }, + "viewset_manual_save_tip": { + "module": "viewset", + "name": "manual_save_tip" + }, + "workbench_create_form_bth_clicked": { + "module": "workbench", + "name": "create_form_bth_clicked" + }, + "workbench_create_form_panel_shown": { + "module": "workbench", + "name": "create_form_panel_shown" + }, + "workbench_create_form_previewer_shown": { + "module": "workbench", + "guide": { + "step": [ + "recZFoBGGlEJ5" + ] + }, + "name": "create_form_previewer_shown" + }, + "workbench_entry": { + "module": "workbench", + "name": "entry" + }, + "workbench_folder_from_template_showcase_shown": { + "module": "workbench", + "name": "folder_from_template_showcase_shown" + }, + "workbench_folder_showcase_shown": { + "module": "workbench", + "name": "folder_showcase_shown" + }, + "workbench_form_container_shown": { + "module": "workbench", + "name": "form_container_shown" + }, + "workbench_hidden_vikaby_btn_clicked": { + "module": "workbench", + "name": "hidden_vikaby_btn_clicked" + }, + "workbench_no_emit": { + "module": "workbench", + "name": "no_emit" + }, + "workbench_show_trial_tip": { + "module": "workbench", + "name": "show_trial_tip" + }, + "workbench_shown": { + "module": "workbench", + "name": "shown" + }, + "workbench_space_list_shown": { + "module": "workbench", + "name": "space_list_shown" + } }, - { - "key": "down", - "winKey": "down", - "when": "isQuickSearchExpanding", - "id": "down", - "command": "QuickSearchDown" + "rule": [ + { + "operator": "IS", + "condition": "device", + "id": "device_IS_app", + "conditionArgs": "app" + }, + { + "operator": "IS", + "condition": "device", + "id": "device_IS_mobile", + "conditionArgs": "mobile" + }, + { + "operator": "IS", + "condition": "device", + "id": "device_IS_pc", + "conditionArgs": "pc" + }, + { + "operator": "IS", + "condition": "edition", + "id": "edition_IS_apitable", + "conditionArgs": "apitable" + }, + { + "operator": "IS", + "condition": "edition", + "id": "edition_IS_vika", + "conditionArgs": "vika" + }, + { + "operator": "ALL_OF_FALSE", + "condition": "identity", + "id": "identity_ALL_OF_FALSE_['sub_admin', 'main_admin', 'member']", + "conditionArgs": "['sub_admin', 'main_admin', 'member']" + }, + { + "operator": "ALL_OF_TRUE", + "condition": "identity", + "id": "identity_ALL_OF_TRUE_['main_admin']", + "conditionArgs": "['main_admin']" + }, + { + "operator": "ALL_OF_TRUE", + "condition": "identity", + "id": "identity_ALL_OF_TRUE_['sub_admin']", + "conditionArgs": "['sub_admin']" + }, + { + "operator": "ONE_OF_TRUE", + "condition": "identity", + "id": "identity_ONE_OF_TRUE_['member']", + "conditionArgs": "['member']" + }, + { + "operator": "ONE_OF_TRUE", + "condition": "identity", + "id": "identity_ONE_OF_TRUE_['sub_admin,'member']", + "conditionArgs": "['sub_admin,'member']" + }, + { + "operator": "ONE_OF_TRUE", + "condition": "labs", + "id": "labs_ONE_OF_TRUE_['view_manual_save']", + "conditionArgs": "['view_manual_save']" + }, + { + "operator": "IS_AFTER", + "condition": "sign_up_time", + "id": "sign_up_time_IS_AFTER_2022-04-10 00:00", + "conditionArgs": "2022-04-10 00:00" + }, + { + "operator": "IS_AFTER", + "condition": "sign_up_time", + "id": "sign_up_time_IS_AFTER_2023-11-23 20:00", + "conditionArgs": "2023-11-23 20:00" + }, + { + "operator": "IS_AFTER", + "condition": "sign_up_time", + "id": "sign_up_time_IS_AFTER_2023-12-28 20:00", + "conditionArgs": "2023-12-28 20:00" + }, + { + "operator": "IS_BEFORE", + "condition": "sign_up_time", + "id": "sign_up_time_IS_BEFORE_2024-12-31 23:59", + "conditionArgs": "2024-12-31 23:59" + }, + { + "operator": "EXCLUDES", + "condition": "url", + "id": "url_EXCLUDES_ai_onboarding", + "conditionArgs": "ai_onboarding" + }, + { + "operator": "EXCLUDES", + "condition": "url", + "id": "url_EXCLUDES_shareId", + "conditionArgs": "shareId" + }, + { + "operator": "EXCLUDES", + "condition": "url", + "id": "url_EXCLUDES_templateId", + "conditionArgs": "templateId" + }, + { + "operator": "INCLUDES", + "condition": "url", + "id": "url_INCLUDES_ai_onboarding", + "conditionArgs": "ai_onboarding" + }, + { + "operator": "GREATER_THAN", + "condition": "wizard[1].count", + "id": "wizard[1].count_GREATER_THAN_0", + "conditionArgs": "0" + }, + { + "operator": "EQUAL", + "condition": "wizard[12].count", + "id": "wizard[12].count_EQUAL_0", + "conditionArgs": "0" + }, + { + "operator": "GREATER_THAN", + "condition": "wizard[12].count", + "id": "wizard[12].count_GREATER_THAN_0", + "conditionArgs": "0" + }, + { + "operator": "EQUAL", + "condition": "wizard[14].count", + "id": "wizard[14].count_EQUAL_0", + "conditionArgs": "0" + }, + { + "operator": "GREATER_THAN", + "condition": "wizard[14].count", + "id": "wizard[14].count_GREATER_THAN_0", + "conditionArgs": "0" + }, + { + "operator": "EQUAL", + "condition": "wizard[21].count", + "id": "wizard[21].count_EQUAL_0", + "conditionArgs": "0" + }, + { + "operator": "GREATER_THAN", + "condition": "wizard[21].count", + "id": "wizard[21].count_GREATER_THAN_0", + "conditionArgs": "0" + }, + { + "operator": "GREATER_THAN", + "condition": "wizard[24].count", + "id": "wizard[24].count_GREATER_THAN_0", + "conditionArgs": "0" + }, + { + "operator": "GREATER_THAN", + "condition": "wizard[27].count", + "id": "wizard[27].count_GREATER_THAN_0", + "conditionArgs": "0" + }, + { + "operator": "GREATER_THAN", + "condition": "wizard[42].count", + "id": "wizard[42].count_GREATER_THAN_1000", + "conditionArgs": "1000" + }, + { + "operator": "GREATER_THAN", + "condition": "wizard[42].count", + "id": "wizard[42].count_GREATER_THAN_300", + "conditionArgs": "300" + }, + { + "operator": "GREATER_THAN", + "condition": "wizard[42].count", + "id": "wizard[42].count_GREATER_THAN_6000", + "conditionArgs": "6000" + }, + { + "operator": "GREATER_THAN", + "condition": "wizard[43].count", + "id": "wizard[43].count_GREATER_THAN_100", + "conditionArgs": "100" + }, + { + "operator": "GREATER_THAN", + "condition": "wizard[43].count", + "id": "wizard[43].count_GREATER_THAN_200", + "conditionArgs": "200" + } + ], + "jobs": { + "15_days_recall": { + "actions": [], + "cron": "0 7 * * *" + }, + "3_days_recall": { + "actions": [], + "cron": "0 7 * * *" + }, + "7_days_recall": { + "actions": [], + "cron": "0 7 * * *" + } }, - { - "key": "tab", - "winKey": "tab", - "when": "isQuickSearchExpanding", - "id": "tab", - "command": "QuickSearchTab" + "action": [ + { + "guide": { + "step": [ + "recsHUjGVAb1E" + ] + }, + "id": "clear_guide_all_ui()", + "command": "clear_guide_all_ui" + }, + { + "id": "clear_guide_uis([\"popover\"])", + "command": "clear_guide_uis", + "commandArgs": "[\"popover\"]" + }, + { + "id": "open_guide_next_step()", + "command": "open_guide_next_step" + }, + { + "id": "open_guide_next_step({\"clearAllPrevUi\":true})", + "command": "open_guide_next_step", + "commandArgs": "{\"clearAllPrevUi\":true}" + }, + { + "id": "open_guide_wizard([117])", + "command": "open_guide_wizard", + "commandArgs": "[117]" + }, + { + "id": "open_guide_wizard(106)", + "command": "open_guide_wizard", + "commandArgs": "106" + }, + { + "id": "open_guide_wizard(113)", + "command": "open_guide_wizard", + "commandArgs": "113" + }, + { + "id": "open_guide_wizard(18)", + "command": "open_guide_wizard", + "commandArgs": "18" + }, + { + "id": "open_guide_wizard(21)", + "command": "open_guide_wizard", + "commandArgs": "21" + }, + { + "id": "open_guide_wizard(22)", + "command": "open_guide_wizard", + "commandArgs": "22" + }, + { + "id": "open_guide_wizard(25)", + "command": "open_guide_wizard", + "commandArgs": "25" + }, + { + "id": "open_guide_wizard(29)", + "command": "open_guide_wizard", + "commandArgs": "29" + }, + { + "id": "open_guide_wizard(30)", + "command": "open_guide_wizard", + "commandArgs": "30" + }, + { + "id": "open_guide_wizard(35)", + "command": "open_guide_wizard", + "commandArgs": "35" + }, + { + "id": "open_guide_wizard(38)", + "command": "open_guide_wizard", + "commandArgs": "38" + }, + { + "id": "open_guide_wizard(40)", + "command": "open_guide_wizard", + "commandArgs": "40" + }, + { + "id": "open_guide_wizard(41)", + "command": "open_guide_wizard", + "commandArgs": "41" + }, + { + "id": "open_guide_wizard(46)", + "command": "open_guide_wizard", + "commandArgs": "46" + }, + { + "id": "open_guide_wizard(50)", + "command": "open_guide_wizard", + "commandArgs": "50" + }, + { + "id": "open_guide_wizard(51)", + "command": "open_guide_wizard", + "commandArgs": "51" + }, + { + "id": "open_guide_wizard(52)", + "command": "open_guide_wizard", + "commandArgs": "52" + }, + { + "id": "open_guide_wizard(55)", + "command": "open_guide_wizard", + "commandArgs": "55" + }, + { + "id": "open_guide_wizard(57)", + "command": "open_guide_wizard", + "commandArgs": "57" + }, + { + "id": "open_guide_wizard(58)", + "command": "open_guide_wizard", + "commandArgs": "58" + }, + { + "id": "open_guide_wizard(61)", + "command": "open_guide_wizard", + "commandArgs": "61" + }, + { + "id": "open_guide_wizard(78)", + "command": "open_guide_wizard", + "commandArgs": "78" + }, + { + "id": "open_guide_wizard(84)", + "command": "open_guide_wizard", + "commandArgs": "84" + }, + { + "id": "open_guide_wizard(85)", + "command": "open_guide_wizard", + "commandArgs": "85" + }, + { + "id": "open_guide_wizard(88)", + "command": "open_guide_wizard", + "commandArgs": "88" + }, + { + "id": "open_guide_wizards([1, 24, 104])", + "command": "open_guide_wizards", + "commandArgs": "[1, 24, 104]" + }, + { + "id": "open_guide_wizards([105, 104])", + "command": "open_guide_wizards", + "commandArgs": "[105, 104]" + }, + { + "id": "open_guide_wizards([105, 115])", + "command": "open_guide_wizards", + "commandArgs": "[105, 115]" + }, + { + "id": "open_guide_wizards([19])", + "command": "open_guide_wizards", + "commandArgs": "[19]" + }, + { + "id": "open_guide_wizards([21])", + "command": "open_guide_wizards", + "commandArgs": "[21]" + }, + { + "id": "open_guide_wizards([29, 76, 138])", + "command": "open_guide_wizards", + "commandArgs": "[29, 76, 138]" + }, + { + "id": "open_guide_wizards([31])", + "command": "open_guide_wizards", + "commandArgs": "[31]" + }, + { + "id": "open_guide_wizards([4])", + "command": "open_guide_wizards", + "commandArgs": "[4]" + }, + { + "id": "open_guide_wizards([76, 138])", + "command": "open_guide_wizards", + "commandArgs": "[76, 138]" + }, + { + "id": "open_guide_wizards([76])", + "command": "open_guide_wizards", + "commandArgs": "[76]" + }, + { + "id": "open_guide_wizards(47)", + "command": "open_guide_wizards", + "commandArgs": "47" + }, + { + "id": "open_vikaby({\n\"visible\": true,\n\"defaultExpandDialog\": true,\n\"dialogConfig\": {\n\"title\": \"维格表首届模板征集大赛\",\n\"description\":\"分享你的模板,免费获得200G空间赠礼,并有机会获得20人版6个月白银空间站!\",\n\"btnText\":\"查看详情\",\n\"btnUrl\": \"https://u.vika.cn/3pkza\",\n\"wizardId\": 21\n}\n}\n )", + "command": "open_vikaby", + "commandArgs": "{\n\"visible\": true,\n\"defaultExpandDialog\": true,\n\"dialogConfig\": {\n\"title\": \"维格表首届模板征集大赛\",\n\"description\":\"分享你的模板,免费获得200G空间赠礼,并有机会获得20人版6个月白银空间站!\",\n\"btnText\":\"查看详情\",\n\"btnUrl\": \"https://u.vika.cn/3pkza\",\n\"wizardId\": 21\n}\n}\n " + }, + { + "id": "open_vikaby({\n\"visible\":true,\n\"defaultExpandTodo\": true,\n\"defaultExpandMenu\": false\n})", + "command": "open_vikaby", + "commandArgs": "{\n\"visible\":true,\n\"defaultExpandTodo\": true,\n\"defaultExpandMenu\": false\n}" + }, + { + "id": "open_vikaby({\"defaultExpandMenu\": true, \"visible\": true})", + "command": "open_vikaby", + "commandArgs": "{\"defaultExpandMenu\": true, \"visible\": true}" + }, + { + "guide": { + "step": [ + "recQExamygtJd", + "recgn9PAJNAtX", + "recE9LnXquMPZ", + "recSkdfQ9C4uM" + ] + }, + "id": "set_wizard_completed({\"curWizard\": true})", + "command": "set_wizard_completed", + "commandArgs": "{\"curWizard\": true}" + }, + { + "guide": { + "step": [ + "rec6yMTEJEjgF" + ] + }, + "id": "set_wizard_completed({\"wizardId\": 115})", + "command": "set_wizard_completed", + "commandArgs": "{\"wizardId\": 115}" + }, + { + "guide": { + "step": [ + "recLftzTSNtNZ" + ] + }, + "id": "set_wizard_completed({\"wizardId\": 14})", + "command": "set_wizard_completed", + "commandArgs": "{\"wizardId\": 14}" + }, + { + "id": "skip_all_wizards()", + "command": "skip_all_wizards" + }, + { + "id": "skip_current_wizard()", + "command": "skip_current_wizard" + }, + { + "id": "skip_current_wizard({\"curWizardCompleted\": true})", + "command": "skip_current_wizard", + "commandArgs": "{\"curWizardCompleted\": true}" + } + ], + "tips": { + "first_node_tips": { + "description": "你可以xxxxx哦", + "title": "亲爱的", + "desc": "保存至本地,即可编辑和下载哦!~" + } + } + }, + "guide": { + "wizard": { + "1": { + "completeIndex": -1, + "player": { + "action": [ + "recH5upxLpgTD" + ] + }, + "steps": "[[2]]" + }, + "2": { + "completeIndex": 0 + }, + "3": { + "completeIndex": -1 + }, + "4": { + "completeIndex": 0, + "player": { + "action": [ + "recSciFoQEPTM" + ] + }, + "steps": "[[8,9],[12,13],[10,11]]" + }, + "5": { + "repeat": true, + "completeIndex": -1 + }, + "6": { + "completeIndex": 0 + }, + "7": { + "completeIndex": 0 + }, + "8": { + "completeIndex": 0 + }, + "9": { + "completeIndex": 0 + }, + "10": { + "completeIndex": 0 + }, + "11": { + "completeIndex": 0, + "endTime": 1620628680000, + "startTime": 1620023880000 + }, + "12": { + "completeIndex": 0 + }, + "13": { + "completeIndex": 0, + "steps": "[[3]]" + }, + "14": { + "repeat": true, + "completeIndex": -1, + "steps": "[[4]]", + "freeVCount": 200, + "integral_action": "wizard_video_reward" + }, + "15": { + "repeat": true, + "completeIndex": -1, + "steps": "[[5]]", + "freeVCount": 200, + "integral_action": "wizard_video_reward" + }, + "16": { + "repeat": true, + "completeIndex": -1, + "steps": "[[6]]", + "freeVCount": 200, + "integral_action": "wizard_video_reward" + }, + "17": { + "repeat": true, + "completeIndex": -1, + "steps": "[[7]]", + "freeVCount": 200, + "integral_action": "wizard_video_reward" + }, + "18": { + "repeat": true, + "completeIndex": 1, + "player": { + "action": [ + "recMKNK2u3tkA" + ] + }, + "steps": "[[107,108],[105,106]]" + }, + "19": { + "completeIndex": 0, + "player": { + "action": [ + "recl36N2sBDBe" + ] + }, + "steps": "[[14],[15,16],[17],[18],[20,21],[22]]" + }, + "20": { + "completeIndex": -1, + "freeVCount": 1000, + "integral_action": "complete_bind_email" + }, + "21": { + "completeIndex": -1, + "player": { + "action": [ + "recCrcOjScQhC", + "rec2I8ZbLDFGw" + ] + }, + "manualActions": [ + "open_vikaby({\n\"visible\": true,\n\"defaultExpandDialog\": true,\n\"dialogConfig\": {\n\"title\": \"维格表首届模板征集大赛\",\n\"description\":\"分享你的模板,免费获得200G空间赠礼,并有机会获得20人版6个月白银空间站!\",\n\"btnText\":\"查看详情\",\n\"btnUrl\": \"https://u.vika.cn/3pkza\",\n\"wizardId\": 21\n}\n}\n )" + ] + }, + "22": { + "completeIndex": 0, + "player": { + "action": [ + "recbAdanWwVvE" + ] + }, + "steps": "[[23],[24]]" + }, + "23": { + "completeIndex": 0, + "steps": "[[40,41],[42]]" + }, + "24": { + "completeIndex": 0, + "player": { + "action": [ + "recH5upxLpgTD" + ] + }, + "steps": "[[44]]" + }, + "25": { + "completeIndex": -1, + "player": { + "action": [ + "recpp069I2Fvi" + ] + }, + "steps": "[[43]]" + }, + "26": { + "completeIndex": 0, + "manualActions": [ + "open_vikaby({\n\"visible\":true,\n\"defaultExpandTodo\": true,\n\"defaultExpandMenu\": false\n})" + ] + }, + "27": { + "completeIndex": 0, + "steps": "[[45]]" + }, + "28": { + "completeIndex": 0, + "steps": "[[46]]" + }, + "29": { + "completeIndex": 0, + "player": { + "action": [ + "recBtbbzXDolQ" + ] + }, + "steps": "[[47,48],[49],[50],[51,52],[53],[54]]" + }, + "30": { + "completeIndex": 0, + "player": { + "action": [ + "recnbU7bovh9p" + ] + }, + "steps": "[[55],[56,57],[58],[50],[51,52],[59],[60],[61]]" + }, + "31": { + "completeIndex": 0, + "player": { + "action": [ + "recH7YVXq8ev2" + ] + }, + "steps": "[[49],[50],[51,52],[53],[54]]" + }, + "32": { + "completeIndex": 0, + "steps": "[[62]]" + }, + "33": { + "completeIndex": 0, + "steps": "[[63]]" + }, + "34": { + "repeat": true, + "completeIndex": -1, + "steps": "[[64]]" + }, + "35": { + "completeIndex": 0, + "player": { + "action": [ + "recWzFTYL5aqi" + ] + }, + "steps": "[[64]]" + }, + "36": { + "completeIndex": 0, + "steps": "[[65]]" + }, + "37": { + "repeat": true, + "completeIndex": -1, + "steps": "[[66]]" + }, + "38": { + "completeIndex": 0, + "player": { + "action": [ + "recUsJf5WI1XK" + ] + }, + "steps": "[[66]]" + }, + "39": { + "completeIndex": 0, + "steps": "[[67]]" + }, + "40": { + "completeIndex": 0, + "player": { + "action": [ + "rec3Wfcm2vUu4" + ] + }, + "steps": "[[70],[68],[69]]" + }, + "41": { + "repeat": true, + "completeIndex": 0, + "player": { + "action": [ + "recksrkgpIWGA" + ] + }, + "steps": "[[71]]" + }, + "42": {}, + "43": {}, + "44": { + "completeIndex": 0, + "steps": "[[72]]" + }, + "45": { + "completeIndex": 0, + "steps": "[[76],[73]]" + }, + "46": { + "completeIndex": 0, + "player": { + "action": [ + "reczvbPaxSPAU" + ] + }, + "steps": "[[74]]" + }, + "47": { + "completeIndex": 0, + "player": { + "action": [ + "recV5500IVb6G" + ] + }, + "steps": "[[75]]" + }, + "48": { + "completeIndex": 0, + "steps": "[[76]]" + }, + "49": { + "completeIndex": 0, + "steps": "[[77]]" + }, + "50": { + "completeIndex": 0, + "player": { + "action": [ + "recepgn7o0mNn" + ] + }, + "manualActions": [ + "open_guide_wizard(50)" + ], + "steps": "[[78]]" + }, + "51": { + "completeIndex": 0, + "player": { + "action": [ + "recnv8Qb15HQI" + ] + }, + "manualActions": [ + "open_guide_wizard(51)" + ], + "steps": "[[79]]" + }, + "52": { + "completeIndex": 0, + "player": { + "action": [ + "recoiIMY1gIXm" + ] + }, + "manualActions": [ + "open_guide_wizard(52)" + ], + "steps": "[[80]]" + }, + "53": { + "completeIndex": 0, + "steps": "[[81]]" + }, + "54": { + "completeIndex": -1, + "steps": "[[82]]" + }, + "55": { + "completeIndex": 0, + "player": { + "action": [ + "rech73EZuut4l" + ] + }, + "steps": "[[82]]" + }, + "56": { + "completeIndex": 0, + "steps": "[[83, 84]]" + }, + "57": { + "completeIndex": 0, + "player": { + "action": [ + "rec7Y8opYoPK5" + ] + }, + "steps": "[[85]]" + }, + "58": { + "completeIndex": 0, + "player": { + "action": [ + "recNjTOtE8kzG" + ] + }, + "steps": "[[86,87],[88,89],[90,91]]" + }, + "59": { + "completeIndex": 0, + "steps": "[[92]]" + }, + "60": { + "completeIndex": 0 + }, + "61": { + "completeIndex": -1, + "player": { + "action": [ + "recWziPefmN7N" + ] + }, + "steps": "[[94]]" + }, + "62": { + "completeIndex": 0, + "steps": "[[95]]" + }, + "63": { + "completeIndex": 0 + }, + "64": { + "repeat": true, + "completeIndex": -1, + "steps": "[[198]]" + }, + "65": { + "completeIndex": -1, + "steps": "[[98]]" + }, + "66": { + "completeIndex": 0, + "steps": "[[99]]" + }, + "67": { + "repeat": true, + "completeIndex": 0, + "steps": "[[100,101]]" + }, + "68": { + "completeIndex": -1, + "steps": "[[93]]" + }, + "69": { + "repeat": true, + "completeIndex": -1, + "steps": "[[103]]" + }, + "70": { + "repeat": true, + "completeIndex": 1, + "steps": "[[26,27],[28,29],[30],[32],[35],[37,38],[39]]" + }, + "71": { + "completeIndex": -1, + "steps": "[[109]]" + }, + "72": { + "steps": "[[93]]" + }, + "73": { + "steps": "[[93]]" + }, + "74": { + "steps": "[[93]]" + }, + "75": { + "steps": "[[93]]" + }, + "76": { + "player": { + "action": [ + "recZmyGfgUNR6", + "recEIcl9v4jzr", + "recBtbbzXDolQ" + ] + }, + "steps": "[[93]]" + }, + "77": { + "steps": "[[111]]" + }, + "78": { + "completeIndex": 1, + "player": { + "action": [ + "recBEBtlrHNqc" + ] + }, + "steps": "[[83]]" + }, + "79": { + "completeIndex": 0, + "steps": "[[126,127]]" + }, + "80": { + "completeIndex": 0, + "steps": "[[128,129]]" + }, + "81": { + "completeIndex": 0, + "steps": "[[124,125],[88,89]]" + }, + "82": { + "completeIndex": -1, + "steps": "[[131]]" + }, + "83": { + "completeIndex": -1, + "steps": "[[132],[137]]" + }, + "84": { + "completeIndex": 0, + "player": { + "action": [ + "rec5MG0Q07sgC" + ] + }, + "steps": "[[135,133]]" + }, + "85": { + "repeat": true, + "player": { + "action": [ + "recpiCI64j675" + ] + }, + "steps": "[[136]]" + }, + "86": { + "steps": "[[137]]" + }, + "87": { + "steps": "[[138]]" + }, + "88": { + "completeIndex": 0, + "player": { + "action": [ + "recGMkwh9WpxC" + ] + }, + "steps": "[[139,140],[141,143]]" + }, + "89": { + "completeIndex": -1, + "steps": "[[144]]" + }, + "90": { + "completeIndex": -1, + "steps": "[[145]]" + }, + "91": { + "completeIndex": -1, + "steps": "[[152]]" + }, + "92": { + "completeIndex": -1, + "steps": "[[153]]" + }, + "93": { + "completeIndex": -1, + "steps": "[[154]]" + }, + "94": { + "completeIndex": -1, + "steps": "[[155]]" + }, + "95": { + "completeIndex": 0, + "steps": "[[156,160]]" + }, + "96": { + "completeIndex": 0, + "steps": "[[157]]" + }, + "97": { + "completeIndex": 0, + "steps": "[[158]]" + }, + "98": { + "completeIndex": -1, + "steps": "[[159]]" + }, + "99": { + "completeIndex": -1, + "steps": "[[161]]" + }, + "100": { + "completeIndex": -1, + "steps": "[[162]]" + }, + "101": { + "completeIndex": -1, + "steps": "[[163]]" + }, + "102": { + "completeIndex": -1, + "steps": "[[164]]" + }, + "104": { + "completeIndex": 0, + "player": { + "action": [ + "recRyoECYFqBv", + "recH5upxLpgTD" + ] + }, + "steps": "[[166]]" + }, + "105": { + "completeIndex": -1, + "player": { + "action": [ + "recRyoECYFqBv", + "recIPTZiGHiIK" + ] + }, + "steps": "[[167]]" + }, + "106": { + "player": { + "action": [ + "recO09HUv27dd" + ] + }, + "manualActions": [ + "open_guide_wizard(106)" + ], + "steps": "[[168]]" + }, + "107": { + "completeIndex": -1, + "steps": "[[169]]" + }, + "108": { + "completeIndex": -1, + "endTime": 1677677940000 + }, + "109": { + "completeIndex": -1, + "endTime": 1683814200000, + "steps": "[[170]]" + }, + "110": { + "completeIndex": -1, + "endTime": 1687075920000, + "steps": "[[171]]" + }, + "111": { + "completeIndex": -1, + "endTime": 1690273320000, + "steps": "[[172]]" + }, + "112": { + "completeIndex": -1, + "endTime": 1692846180000, + "steps": "[[173]]" + }, + "113": { + "completeIndex": -1, + "player": { + "action": [ + "recS412alvczx" + ] + }, + "manualActions": [ + "open_guide_wizard(113)" + ], + "steps": "[[174]]" + }, + "114": { + "completeIndex": -1, + "endTime": 1699951800000, + "steps": "[[175]]" + }, + "115": { + "completeIndex": -1, + "player": { + "action": [ + "recIPTZiGHiIK" + ] + }, + "steps": "[[176]]" + }, + "117": { + "repeat": true, + "player": { + "action": [ + "reca04Hhjjn7B" + ] + }, + "manualActions": [ + "open_guide_wizard([117])" + ], + "steps": "[[177]]" + }, + "118": { + "completeIndex": -1, + "endTime": 1701158400000, + "steps": "[[178]]" + }, + "119": { + "completeIndex": -1, + "steps": "[[179]]" + }, + "131": { + "completeIndex": -1, + "endTime": 1703487600000, + "steps": "[[192]]" + }, + "136": { + "completeIndex": -1, + "endTime": 1704420420000, + "steps": "[[196]]" + }, + "138": { + "completeIndex": -1, + "player": { + "action": [ + "recEIcl9v4jzr", + "recBtbbzXDolQ" + ] + }, + "endTime": 1708596000000, + "steps": "[[199]]" + } }, - { - "key": "enter", - "winKey": "enter", - "when": "isQuickSearchExpanding", - "id": "enter", - "command": "QuickSearchEnter" + "step": { + "1": { + "uiConfigId": "player_step_ui_config_1", + "uiType": "notice", + "prev": "-", + "backdrop": "around_mask", + "onPlay": [ + "clear_guide_all_ui()" + ], + "onNext": [ + "skip_all_wizards()" + ], + "next": "确定", + "onPrev": [ + "clear_guide_all_ui()" + ], + "nextId": "confirm", + "onSkip": [ + "clear_guide_all_ui()" + ], + "uiConfig": "{}", + "onClose": [ + "skip_current_wizard()" + ], + "onTarget": [ + "skip_current_wizard({\"curWizardCompleted\": true})" + ] + }, + "2": { + "uiConfigId": "player_step_ui_config_2", + "uiType": "questionnaire", + "backdrop": "around_mask", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "确定", + "nextId": "confirm", + "uiConfig": "{\n \"config\": [\n {\n \"key\": 1,\n \"name\": \"answer1\",\n \"title\": \"您希望通过维格表解决哪些问题?\",\n \"type\": \"checkbox\",\n \"answers\": [\n \"工作规划\",\n \"客户服务\",\n \"项目管理\",\n \"采购供应\",\n \"内容生产\",\n \"电商运营\",\n \"活动策划\",\n \"人力资源\",\n \"行政管理\",\n \"财务管理\",\n \"网络直播\",\n \"高校管理\",\n \"其它\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 2,\n \"name\": \"answer2\",\n \"title\": \"您的工作岗位是?\",\n \"type\": \"radio\",\n \"answers\": [\n \"管理者\",\n \"项目经理\",\n \"产品经理\",\n \"设计师\",\n \"研发、工程师\",\n \"运营、编辑\",\n \"销售、客服\",\n \"人事、行政\",\n \"财务、会计\",\n \"律师、法务\",\n \"市场\",\n \"教师\",\n \"学生\",\n \"其它\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 3,\n \"name\": \"answer3\",\n \"title\": \"您的公司名称是?\",\n \"type\": \"input\",\n \"submit\": false\n },\n {\n \"key\": 4,\n \"name\": \"answer4\",\n \"title\": \"请留下你的邮箱/手机/微信号,以便我们及时提供帮助。\",\n \"type\": \"input\",\n \"submit\": true\n },\n {\n \"key\": 5,\n \"title\": \"感谢你的填写,请加一下客服号以备不时之需\",\n \"platform\": {\n \"website\": \"https://s1.vika.cn/space/2023/03/02/b34e3205a9154463be16f497524f1327\",\n \"dingtalk\": \"https://s1.vika.cn/space/2023/03/02/4b16cef6602a4586a21d6346bf25d300\",\n \"wecom\": \"https://s1.vika.cn/space/2023/03/02/60119b1b69b64aa887bd1be6a2928bec\",\n \"feishu\": \"https://u.vika.cn/z9ygm\"\n },\n \"type\": \"contactUs\",\n \"next\": true\n }\n ]\n}\n", + "onClose": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "3": { + "uiConfigId": "player_step_ui_config_3", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "确定", + "nextId": "confirm", + "uiConfig": "{\n \"title\": \"更新公告\",\n \"children\": \"

✨ Hello, 星球居民们~

伴随12月的前奏,维格星球又迎来了一波更新,动动手指探索下最新的资源吧 🎉

🎊 播报 News

  • 手机端支持编辑啦,现在你可以直接在手机上探索维格表
  • 维格表API 增加Golang语言的SDK
  • 新增记录的「动态评论」,你和小伙伴可以在维格表内展开深入的讨论
  • 「空间站管理-普通成员」页面新增全局开关,可以控制是否在分享页面展示「申请加入空间站」的入口

🍜 优化 Enhancement

  • 分享模态窗改版,可以更清晰地选择自己的协作方式
  • 权限模态窗改版,设置权限变成独立的页面
  • 看板视图可以在卡片上切换封面图片,高清无码大图如此性感
  • 单选/多选/成员的选项列表支持键盘快捷键上下选择选项,解放互联网冲浪达人的双手
\"\n }", + "onClose": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "4": { + "uiConfigId": "player_step_ui_config_4", + "uiType": "modal", + "onPlay": [ + "set_wizard_completed({\"curWizard\": true})" + ], + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "uiConfig": "{\n\"title\":\"什么是维格表\",\n\"video\":\"space/2022/02/21/94cb82f9ffd84a5499c8931a224ad234\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_1\",\n\"autoPlay\":true\n}", + "onClose": [ + "open_guide_next_step({\"clearAllPrevUi\":true})", + "open_vikaby({\n\"visible\":true,\n\"defaultExpandTodo\": true,\n\"defaultExpandMenu\": false\n})" + ] + }, + "5": { + "uiConfigId": "player_step_ui_config_5", + "uiType": "modal", + "onPlay": [ + "set_wizard_completed({\"curWizard\": true})" + ], + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "uiConfig": "{\n\"title\":\"一分钟快速入门\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}\n", + "onClose": [ + "open_guide_next_step({\"clearAllPrevUi\":true})", + "open_vikaby({\n\"visible\":true,\n\"defaultExpandTodo\": true,\n\"defaultExpandMenu\": false\n})" + ] + }, + "6": { + "uiConfigId": "player_step_ui_config_6", + "uiType": "modal", + "onPlay": [ + "set_wizard_completed({\"curWizard\": true})" + ], + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "uiConfig": "{\n\"title\":\"玩转一张维格表\",\n\"video\":\"space/2020/12/21/cb7bdf6fe22146068111d46915587fb2\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_3\",\n\"autoPlay\":true\n}", + "onClose": [ + "open_guide_next_step({\"clearAllPrevUi\":true})", + "open_vikaby({\n\"visible\":true,\n\"defaultExpandTodo\": true,\n\"defaultExpandMenu\": false\n})" + ] + }, + "7": { + "uiConfigId": "player_step_ui_config_7", + "uiType": "modal", + "onPlay": [ + "set_wizard_completed({\"curWizard\": true})" + ], + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "uiConfig": "{\n\"title\":\"分享和邀请成员\",\n\"video\":\"space/2020/12/21/b8fa92ba4c7d41c6acbd7f24469e15fc\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_4\",\n\"autoPlay\":true\n}", + "onClose": [ + "open_guide_next_step({\"clearAllPrevUi\":true})", + "open_vikaby({\n\"visible\":true,\n\"defaultExpandTodo\": true,\n\"defaultExpandMenu\": false\n})" + ] + }, + "8": { + "uiConfigId": "player_step_ui_config_8", + "uiType": "popover", + "onNext": [ + "clear_guide_uis([\"popover\"])" + ], + "onSkip": [ + "skip_current_wizard({\"curWizardCompleted\": true})" + ], + "uiConfig": "{\n \"element\": \"#ADDRESS_INVITE_BTN\", \n\"placement\": \"bottomLeft\",\n \"title\": \"邀请方式\", \n\"description\": \"当前空间站支持链接、邮箱、导入三种方式邀请成员\", \"children\":\"\" \n} " + }, + "9": { + "uiConfigId": "player_step_ui_config_9", + "uiType": "breath", + "backdrop": "around_mask", + "uiConfig": "{\n \"element\": \"#ADDRESS_INVITE_BTN\"\n} ", + "onTarget": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "10": { + "uiConfigId": "player_step_ui_config_10", + "uiType": "popover", + "onNext": [ + "clear_guide_uis([\"popover\"])" + ], + "onSkip": [ + "skip_current_wizard({\"curWizardCompleted\": true})" + ], + "uiConfig": "{\n \"element\": \".style_linkWrapper__12Kgi .style_urlWrapper__2IVlG button\", \n\"placement\": \"bottomRight\",\n \"title\": \"复制并分享\",\n\"description\": \"点击复制链接并分享给成员,即可完成邀请\", \"children\":\"\" \n} " + }, + "11": { + "uiConfigId": "player_step_ui_config_11", + "uiType": "breath", + "backdrop": "around_mask", + "uiConfig": "{\"element\": \".style_linkWrapper__12Kgi .style_urlWrapper__2IVlG button\",\n\"shadowDirection\": \"none\"} ", + "onTarget": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "12": { + "uiConfigId": "player_step_ui_config_12", + "uiType": "popover", + "backdrop": "around_mask", + "onNext": [ + "clear_guide_uis([\"popover\"])" + ], + "onSkip": [ + "skip_current_wizard({\"curWizardCompleted\": true})" + ], + "uiConfig": "{\n \"element\": \".style_addNewLink__3ALup>button\", \n\"placement\": \"bottomRight\",\n \"title\": \"创建邀请链接\", \n\"description\": \"创建链接邀请成员加入空间站或站内指定小组\", \"children\":\"\" \n} " + }, + "13": { + "uiConfigId": "player_step_ui_config_13", + "uiType": "breath", + "uiConfig": "{\n \"element\": \".style_addNewLink__3ALup>button\"\n} ", + "onTarget": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "14": { + "skipId": "no_and_thanks", + "uiConfigId": "player_step_ui_config_14", + "uiType": "slideout", + "onNext": [ + "clear_guide_all_ui()", + "open_guide_next_step()" + ], + "next": "好的", + "skip": "不用了,谢谢", + "nextId": "okay", + "onSkip": [ + "skip_current_wizard({\"curWizardCompleted\": true})" + ], + "uiConfig": "{\n \"placement\": \"bottomRight\",\n \"description\": \"欢迎来到维格模板中心,这里有丰富的模板,让我来给你介绍一下如何使用一个模板吧\"\n}" + }, + "15": { + "skipId": "skip", + "uiConfigId": "player_step_ui_config_15", + "uiType": "popover", + "onNext": [ + "clear_guide_uis([\"popover\"])" + ], + "next": "好的", + "skip": "跳过", + "nextId": "okay", + "onSkip": [ + "skip_current_wizard({\"curWizardCompleted\": true})" + ], + "uiConfig": "{\n \"element\": \".style_templateItem__1UDe0\", \n\"placement\": \"bottom\",\n \"title\": \"使用模板教程\", \n\"description\": \"我们先选择一个模板,点击进入它的预览页\", \"children\":\"\" \n}\n" + }, + "16": { + "uiConfigId": "player_step_ui_config_16", + "uiType": "breath", + "backdrop": "around_mask", + "uiConfig": "{\n \"element\": \".style_templateItem__1UDe0\"\n}\n", + "onTarget": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "17": { + "skipId": "skip", + "uiConfigId": "player_step_ui_config_17", + "uiType": "popover", + "onNext": [ + "clear_guide_uis([\"popover\"])" + ], + "next": "好的", + "skip": "跳过", + "nextId": "okay", + "onSkip": [ + "skip_current_wizard({\"curWizardCompleted\": true})" + ], + "uiConfig": "{\n \"element\": \"#TEMPLATE_CENTER_USE_TEMPLATE_BTN>button\", \n\"placement\": \"rightBottom\",\n\"offsetY\": 20,\n \"title\": \"使用模板教程\", \n\"description\": \"点击左侧按钮使用模板\", \"children\":\"\" \n}", + "onTarget": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "18": { + "skipId": "skip", + "uiConfigId": "player_step_ui_config_18", + "uiType": "popover", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "下一步", + "skip": "跳过", + "nextId": "next_step", + "onSkip": [ + "skip_current_wizard({\"curWizardCompleted\": true})" + ], + "uiConfig": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select>.ant-select-selector\", \n\"placement\": \"bottomLeft\",\n \"title\": \"使用模板教程\", \n\"description\": \"选择模板要存放的位置\", \"children\":\"\" \n}" + }, + "19": { + "uiConfigId": "player_step_ui_config_19", + "uiType": "breath", + "uiConfig": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select .ant-select-selector\"\n}", + "onTarget": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "20": { + "skipId": "skip", + "uiConfigId": "player_step_ui_config_20", + "uiType": "popover", + "onNext": [ + "clear_guide_uis([\"popover\"])" + ], + "next": "好的", + "skip": "跳过", + "nextId": "okay", + "onSkip": [ + "skip_current_wizard({\"curWizardCompleted\": true})" + ], + "uiConfig": "{\n \"element\": \"#TEMPLATE_CENTER_CONFIRM_BTN_IN_TEMPLATE_MODAL\", \n\"placement\": \"bottomLeft\",\n \"title\": \"使用模板教程\", \n\"description\": \"在确定了要存放的位置后,点击确定,模板才会使用生效哦\", \"children\":\"\" \n}", + "onTarget": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "21": { + "uiConfigId": "player_step_ui_config_21", + "uiType": "breath", + "uiConfig": "{\n \"element\": \"#TEMPLATE_CENTER_CONFIRM_BTN_IN_TEMPLATE_MODAL\" \n}", + "onTarget": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "22": { + "uiConfigId": "player_step_ui_config_22", + "uiType": "slideout", + "onNext": [ + "open_guide_next_step()" + ], + "next": "好的", + "nextId": "okay", + "onSkip": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "uiConfig": "{\n \"placement\": \"bottomLeft\",\n \"description\": \"恭喜你学会了如何使用一个模板,维格表还有更多功能等待你的探索哦~\"\n}" + }, + "23": { + "uiConfigId": "player_step_ui_config_23", + "uiType": "popover", + "onNext": [ + "clear_guide_all_ui()" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"element\": \".style_searchPanelContainer__1_iOe\", \n\"placement\": \"leftTop\",\n \"title\": \"如何生成神奇表单\", \n\"description\": \"首先,需要选择一张维格表来存放收集的数据\", \"children\":\"\" \n}" + }, + "24": { + "uiConfigId": "player_step_ui_config_24", + "uiType": "popover", + "onNext": [ + "clear_guide_all_ui()" + ], + "next": "好的", + "nextId": "okay", + "byEvent": [ + "workbench_create_form_previewer_shown" + ], + "uiConfig": "{\n \"element\": \".style_formPreviewer__2Au6g\", \n\"placement\": \"leftTop\",\n \"title\": \"如何生成神奇表单\", \n\"description\": \"神奇表单的字段数量以及顺序,会与所选视图的配置保持一致。基于你选择的视图,右侧为自动生成的预览效果。\", \"children\":\"\" \n}", + "onTarget": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "25": { + "uiConfigId": "player_step_ui_config_25", + "uiType": "popover", + "onNext": [ + "clear_guide_all_ui()" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"element\": \"#WORKBENCH_SIDE_FORM_USE_GUIDE_BTN\", \n\"placement\": \"bottomRight\",\n \"title\": \"收集表教程\", \n\"description\": \"如果需要更加详细的收集表教程,可以点击上方的入口查看哦\", \"children\":\"\" \n}" + }, + "26": { + "uiConfigId": "player_step_ui_config_26", + "uiType": "popover", + "onNext": [ + "clear_guide_uis([\"popover\"])" + ], + "onSkip": [ + "skip_current_wizard()" + ], + "uiConfig": "{\n \"element\": \"#WORKBENCH_SIDE_ADD_NODE_BTN\", \n\"placement\": \"bottom\",\n \"title\": \"智能引导\", \n\"description\": \"让我们新建一张空白的维格表试一试\", \"children\":\"\" \n}" + }, + "27": { + "uiConfigId": "player_step_ui_config_27", + "uiType": "breath", + "uiConfig": "{\n \"element\": \"#WORKBENCH_SIDE_ADD_NODE_BTN\"\n}", + "onTarget": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "28": { + "uiConfigId": "player_step_ui_config_28", + "uiType": "popover", + "onSkip": [ + "skip_current_wizard()" + ], + "uiConfig": "{\n \"element\": \"#NODE_CONTEXT_MENU_ID .react-contexify__item:nth-of-type(1)\", \n\"placement\": \"rightCenter\",\n \"title\": \"智能引导\", \n\"description\": \"接着,选择“新建空白维格表”\", \"children\":\"\" \n}" + }, + "29": { + "uiConfigId": "player_step_ui_config_29", + "uiType": "breath", + "uiConfig": "{\n \"element\": \"#NODE_CONTEXT_MENU_ID > .react-contexify__item:nth-of-type(1) .react-contexify__item__content > div:nth-of-type(1)\",\n\"shadowDirection\":\"inset\"\n} " + }, + "30": { + "uiConfigId": "player_step_ui_config_30", + "uiType": "popover", + "backdrop": "around_mask", + "onNext": [ + "clear_guide_uis([\"popover\"])" + ], + "byEvent": [ + "datasheet_grid_view_shown" + ], + "onSkip": [ + "skip_current_wizard()" + ], + "uiConfig": "{\n \"element\": \"#DATASHEET_ADD_COLUMN_BTN\", \n\"placement\": \"leftTop\",\n \"title\": \"智能引导\", \n\"description\": \"一张空白的维格表创建好啦,接下来我们来尝试一下新建一个维格列吧\", \"children\":\"\" \n}", + "onTarget": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "31": { + "uiConfigId": "player_step_ui_config_31", + "uiType": "breath", + "uiConfig": "{\n \"element\": \"#WORKBENCH_SIDE_FORM_USE_GUIDE_BTN\"\n}", + "onTarget": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "32": { + "uiConfigId": "player_step_ui_config_32", + "uiType": "popover", + "onNext": [ + "open_guide_next_step()" + ], + "next": "好的", + "nextId": "okay", + "onSkip": [ + "skip_current_wizard()" + ], + "uiConfig": "{\n \"element\": \"#DATASHEET_GRID_CUR_COLUMN_TYPE\", \n\"placement\": \"bottom\",\n \"title\": \"智能引导\", \n\"description\": \"维格表提供了丰富的维格列类型以匹配各种使用场景,鼠标悬浮在这里即可查看\", \"children\":\"\" \n}" + }, + "33": { + "uiConfigId": "player_step_ui_config_33", + "uiType": "popover", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "好的", + "nextId": "okay", + "onSkip": [ + "skip_current_wizard()" + ], + "uiConfig": "{\n \"element\": \"#DATASHEET_VIEW_TAB_BAR .style_viewBarWrapper__AJlc-\", \n\"placement\": \"bottom\",\n \"title\": \"智能引导\", \n\"description\": \"同一张维格表可提供多种视图模式,通过“分组、筛选、排序”等功能来自定义视图的展示数据。但是要注意,一张维格表下所有的视图用的都是同一份数据源,只是展示的样式各有不同,所以不要把视图当作excel的工作簿用哦!\", \"children\":\"\" \n}" + }, + "34": { + "uiConfigId": "player_step_ui_config_34", + "uiType": "breath", + "uiConfig": "{\n \"element\": \"#DATASHEET_VIEW_TAB_BAR .style_viewBarWrapper__AJlc-\"\n}" + }, + "35": { + "uiConfigId": "player_step_ui_config_35", + "uiType": "popover", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "下一步", + "nextId": "next_step", + "byEvent": [ + "datasheet_field_setting_hidden" + ], + "onSkip": [ + "skip_current_wizard()" + ], + "uiConfig": "{\n \"element\": \"#DATASHEET_ADD_VIEW_BTN\", \n\"placement\": \"bottom\",\n \"title\": \"智能引导\", \n\"description\": \"维格表除了标准表格形式的“维格视图”外,还支持变换“相册视图”“看板视图””甘特视图“”日历视图“”架构视图“,分别对应管理丰富的图像化数据和任务化数据,让你事半功倍,还是得要提醒一次,视图只是展示的样式不同,但是数据源是同一份哦!\", \"children\":\"\" \n}", + "onTarget": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "36": { + "uiConfigId": "player_step_ui_config_36", + "uiType": "breath", + "uiConfig": "{\n \"element\": \"#DATASHEET_ADD_VIEW_BTN\",\n\"shadowDirection\":\"inset\"\n}", + "onTarget": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "37": { + "uiConfigId": "player_step_ui_config_37", + "uiType": "popover", + "onNext": [ + "clear_guide_uis([\"popover\"])" + ], + "next": "好的", + "nextId": "okay", + "onSkip": [ + "skip_current_wizard()" + ], + "uiConfig": "{\n \"element\": \"#DATASHEET_TOOL_BAR .style_toolbarMiddle__2kxTf>button:nth-of-type(7)\", \n\"placement\": \"bottom\",\n \"title\": \"智能引导\", \n\"description\": \"如果要将内容分享给空间站外的人员,你可以通过这个功能创建一条链接分享出去\", \"children\":\"\" \n}" + }, + "38": { + "uiConfigId": "player_step_ui_config_38", + "uiType": "breath", + "uiConfig": "{\n \"element\": \"#DATASHEET_TOOL_BAR .style_toolbarMiddle__2kxTf>button:nth-of-type(7)\"\n}", + "onTarget": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "39": { + "uiConfigId": "player_step_ui_config_39", + "uiType": "slideout", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "知道啦", + "nextId": "known", + "uiConfig": "{\n \"placement\": \"bottomLeft\",\n \"description\": \"智能引导就到这里啦,如果想要查看维格表更加详细的教程,你可以点击左下角的帮助中心去查看我们的产品手册哦\"\n}" + }, + "40": { + "uiConfigId": "player_step_ui_config_40", + "uiType": "popover", + "onNext": [ + "clear_guide_uis([\"popover\"])" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"element\": \"#DATASHEET_FORM_BTN\",\n\"placement\": \"bottomRight\",\n \"title\": \"新功能\", \n\"description\": \"可以通过神奇表单来录入数据了,赶紧体验一下吧~\", \"children\":\"\" \n}" + }, + "41": { + "uiConfigId": "player_step_ui_config_41", + "uiType": "breath", + "uiConfig": "{\n \"element\": \"#DATASHEET_FORM_BTN\"\n}", + "onTarget": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "42": { + "uiConfigId": "player_step_ui_config_42", + "uiType": "popover", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"element\": \"#DATASHEET_FORM_LIST_PANEL\", \n\"placement\": \"leftTop\",\n \"title\": \"神奇表单\", \n\"description\": \"在这里可以快速生成当前视图的神奇表单,神奇表单的字段是依照视图的维格列数量以及顺序来生成的哦\", \"children\":\"\" \n}" + }, + "43": { + "skipId": "remind_never_again", + "uiConfigId": "player_step_ui_config_43", + "uiType": "popover", + "backdrop": "around_mask", + "onNext": [ + "skip_current_wizard()" + ], + "next": "知道啦", + "skip": "不再提醒", + "nextId": "known", + "onSkip": [ + "skip_current_wizard({\"curWizardCompleted\": true})" + ], + "uiConfig": "{\n \"element\": \".style_navigation__1U5cR .style_help__1sXEA\", \n\"placement\": \"rightBottom\",\n \"title\": \"小提示\", \n\"offsetY\":5,\n\"description\": \"你可以在左侧的「帮助中心」找回你的维格小助手\", \"children\":\"\" \n}" + }, + "44": { + "uiConfigId": "player_step_ui_config_44", + "uiType": "modal", + "onPlay": [ + "set_wizard_completed({\"wizardId\": 14})" + ], + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "uiConfig": "{\n\"title\":\"一分钟快速入门\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", + "onClose": [ + "open_guide_next_step({\"clearAllPrevUi\":true})", + "open_guide_wizard(18)" + ] + }, + "45": { + "uiConfigId": "player_step_ui_config_45", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "知道啦", + "nextId": "known", + "uiConfig": "{\n \"title\": \"更新公告\",\n \"children\": \"

✨ Hello, 星球居民们~

在2020年的尾声,维格星球迎来了一波更新,新年新气象,一起来探索2021年的新玩法吧~

🎉 播报 News

  • 「收集表」正式上线,全新玩法让数据收集、内部协作更加轻松自如
  • 「移动端」支持编辑列配置,距离理想的「躺在沙滩上办公」更近啦!
  • 记录将提供「预排序」交互效果,修改后的记录不会马上飞走了,多一步的停留让改动更有深度
  • 维格列配置菜单支持搜索维格列类型——咦,你看出我们的野心了?

🍜 优化 Enhancement

  • 重新设计的新手引导,拥有「魔力」的维格小助手带你轻松上手维格表
  • 维格表支持邮箱注册了
  • 还有许多小优化,欢迎探索体验。
\"\n }" + }, + "46": { + "uiConfigId": "player_step_ui_config_46", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "知道啦", + "nextId": "known", + "uiConfig": "{\n \"title\": \"更新公告\",\n \"children\": \"

✨ Hello 星球居民们~

牛年新气象,维格表值此新春之际上新啦。若干重磅功能闪亮登场,让你的工作效率再上一个台阶 🔥。

🕤 仪表盘

全新文件类型,举手之间轻松搭建图表驾驶舱,清晰呈现每个指标,汇聚工作焦点。

📈 图表

简洁灵活的数据可视化图表,支持柱状图、折线图、饼状图等多种类型。
添加即查看,一键切换维度和数值计算,10s 完成制作。

💯 统计与指标

指定统计字段并选择求和、平均值等指标,将自动计算并快速呈现关键结果。
支持自定义统计说明和对比目标,提升阅读体验。

🎉 飞书集成

打通飞书,智能同步通讯录和组织架构,员工账号管理更轻松。
在维格表中,如有成员提及和评论 @ 等都可以在飞书中收到同步通知。

提示:目前飞书登录仍处于官方审核阶段,暂无法使用飞书扫码登录,请谅解。

💻 维格表桌面端

全新的桌面级客户端,支持 Windows 和 macOS,让您随时随地维格一下。

👬 邀请码

优化邀请码分享机制,复制后自动转化为邀请链接,以便他人更快完成注册和使用,双方还将获得 1000 V 币奖励。

\"\n }" + }, + "47": { + "uiConfigId": "player_step_ui_config_47", + "uiType": "popover", + "onNext": [ + "clear_guide_uis([\"popover\"])" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"element\": \"#DATASHEET_WIDGET_BTN\",\n\"placement\": \"bottomRight\",\n \"title\": \"新功能\", \n\"description\": \"小程序上线!想要让沉淀下来的数据得到更好的运用吗?那就赶紧来体验一下吧\", \"children\":\"\" \n}" + }, + "48": { + "uiConfigId": "player_step_ui_config_48", + "uiType": "breath", + "uiConfig": "{\n \"element\": \"#DATASHEET_WIDGET_BTN\",\n\"shadowDirection\": \"inset\"\n}", + "onTarget": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "49": { + "uiConfigId": "player_step_ui_config_49", + "uiType": "popover", + "backdrop": "around_mask", + "onNext": [ + "clear_guide_uis([\"popover\"])" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"element\": \".style_widgetPanelContainer__1l2ZV\",\n\"placement\": \"leftCenter\",\n \"title\": \"什么是小程序\", \n\"description\": \"维格小程序是维格表的一种扩展应用,可实现数据可视化、数据传输、数据清洗等等额外功能。通过在小程序面板安装适合团队的小程序,可以让工作事半功倍\", \"children\":\"\" \n}" + }, + "50": { + "uiConfigId": "player_step_ui_config_50", + "uiType": "popover", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "好的", + "nextId": "okay", + "byEvent": [ + "datasheet_widget_center_modal_shown" + ], + "uiConfig": "{\n \"element\": \".style_widgetModal__eXmdB\",\n\"placement\": \"leftTop\",\n \"title\": \"小程序中心\", \n\"description\": \"官方推荐和空间站自建的小程序会发布到这里。你可以根据场景,在这里挑选合适的小程序放置到仪表盘或小程序面板里\", \"children\":\"\" \n}" + }, + "51": { + "uiConfigId": "player_step_ui_config_51", + "uiType": "popover", + "onNext": [ + "clear_guide_uis([\"popover\"])" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"element\": \".style_widgetModal__eXmdB .style_widgetItem__3Pl-1 button\",\n\"placement\": \"rightBottom\",\n \"title\": \"安装小程序\", \n\"description\": \"我们安装这个「图表」小程序看看吧\", \"children\":\"\" \n}" + }, + "52": { + "uiConfigId": "player_step_ui_config_52", + "uiType": "breath", + "uiConfig": "{\n \"element\": \".style_widgetModal__eXmdB .style_widgetItem__3Pl-1 button\",\n\"shadowDirection\":\"none\"\n}", + "onTarget": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "53": { + "uiConfigId": "player_step_ui_config_53", + "uiType": "popover", + "backdrop": "around_mask", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"element\": \".style_widgetPanelContainer__1l2ZV\",\n\"placement\": \"leftCenter\",\n\"description\": \"安装成功,同时我们也为你创建了一个小程序面板,一个维格表的所有小程序都会放置在这个区域\", \"children\":\"\" \n}" + }, + "54": { + "uiConfigId": "player_step_ui_config_54", + "uiType": "popover", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"element\": \".style_widgetPanelContainer__1l2ZV .style_panelHeader__3X0pG\",\n\"placement\": \"bottom\",\n \"title\": \"小程序面板\", \n\"description\": \"小程序面板是用于装载小程序的容器,可以通过创建多个小程序面板来给你的小程序进行分类\", \"children\":\"\" \n}" + }, + "55": { + "uiConfigId": "player_step_ui_config_55", + "uiType": "slideout", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"placement\": \"bottomLeft\",\n \"description\": \"仪表盘作为维格表的一种文件类型,添加/导入小程序后,可视化能力提升。你可以通过数据统计和图表分析,更好地进行判断和决策\"\n}" + }, + "56": { + "uiConfigId": "player_step_ui_config_56", + "uiType": "popover", + "onNext": [ + "clear_guide_uis([\"popover\"])" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"element\": \"#DASHBOARD_PANEL_ID .style_tabRight__4YAkM button:nth-of-type(1)\",\n\"placement\": \"bottom\",\n \"title\": \"添加小程序\", \n\"description\": \"在这里有两种方法添加小程序,一种是从小程序中心添加,一种是从已有的小程序中导入进去\", \"children\":\"\" \n}" + }, + "57": { + "uiConfigId": "player_step_ui_config_57", + "uiType": "breath", + "uiConfig": "{\n \"element\": \"#DASHBOARD_PANEL_ID .style_tabRight__4YAkM button:nth-of-type(1)\",\n \"shadowDirection\":\"inset\"\n}", + "onTarget": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "58": { + "uiConfigId": "player_step_ui_config_58", + "uiType": "popover", + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"element\": \".style_addWidgetMenu__29bIe .style_menuItem__3Ugjz:nth-of-type(1)\",\n\"placement\": \"bottom\",\n \"title\": \"添加小程序\", \n\"description\": \"让我们来尝试一下,添加一个小程序到仪表盘吧\", \"children\":\"\" \n}" + }, + "59": { + "uiConfigId": "player_step_ui_config_59", + "uiType": "popover", + "onNext": [ + "clear_guide_uis([\"popover\"])" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"element\": \"#DASHBOARD_PANEL_ID .style_widgetContainer__2HwEf\",\n\"placement\": \"rightTop\",\n \"title\": \"关联维格表\", \n\"description\": \"由于部分小程序需要依赖维格表的数据,所以安装小程序之后还需要选择一个维格表进行关联\", \"children\":\"\" \n}" + }, + "60": { + "uiConfigId": "player_step_ui_config_60", + "uiType": "popover", + "onNext": [ + "clear_guide_uis([\"popover\"])" + ], + "next": "好的", + "nextId": "okay", + "byEvent": [ + "datasheet_search_panel_shown" + ], + "uiConfig": "{\n \"element\": \".style_searchPanelContainer__1_iOe\",\n\"placement\": \"rightTop\",\n \"title\": \"关联维格表\", \n\"description\": \"在这里选择你需要关联的维格表,以供小程序访问数据\", \"children\":\"\" \n}" + }, + "61": { + "uiConfigId": "player_step_ui_config_61", + "uiType": "slideout", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "好的", + "nextId": "okay", + "byEvent": [ + "datasheet_search_panel_hidden" + ], + "uiConfig": "{\n \"placement\": \"bottomLeft\",\n \"description\": \"恭喜你,已掌握了仪表盘和添加小程序的基本使用方法。接下来,你可以根据业务场景去搭建专属的仪表盘了\"\n}" + }, + "62": { + "uiConfigId": "player_step_ui_config_62", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "知道啦", + "nextId": "known", + "uiConfig": "{\n \"title\": \"✨ 星球居民们,好久不见~\",\n\"children\": \"

在过去的 2 个月里,维格表一直有在悄悄更新,改善使用体验。
这次新增了不少显性功能点,先来了解一下再上手吧~

📈  图表组件增强可视化

自动识别日期维度,开启格式化日期后可选择按周/月/季度/年展示,清晰呈现数据走势

wegist1

新增 10+ 款单色渐变主题,适合在多个数据系列的图表中应用,增强审视,突出焦点

wegist2

📎  office 文件在线预览

附件字段上传文件后可在线预览,提升协作效率,支持文档、表格、PPT 多种格式
路径:空间站设置-第三方应用集成-office 文件预览,授权后才能生效哦

wegist1

🔍  神奇引用列支持筛选

在神奇引用列中,对引用的数据进行筛选,以便在海量数据中快速、精准地展示某类数据

wegist1

📅  日期格式更丰富

日期字段新增年、月、日三种日期格式

wegist1

➕  其他

优化页面刷新逻辑,删除、复制文件后无需重载,保持当前操作不被打断

\"\n }" + }, + "63": { + "uiConfigId": "player_step_ui_config_63", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "知道啦", + "nextId": "known", + "uiConfig": "{\n \"title\": \"🌟星球居民们🌟\",\n\"children\": \"

vika 维格表又双叒更新啦,千呼万唤的列权限、甘特图已上线,快来点亮 vika 的魔法棒吧~

🔒  精细化权限管理

列权限上线,保护敏感数据。开启列权限后,可限制成员查看或编辑表格内的某列数据。
路径:设置列权限前,需先开启文件权限

wegist1

⏳  项目跟进,张弛有度

超强甘特图,助力项目管理。以时间为轴,展示每一个任务的时间节点以及关键信息,全面把控进度。

wegist1

📋  记录修改,有迹可循

追溯修改历史,以防数据丢失。最近 90 天的修改记录,包括修改人、修改内容等完整信息都能被找回。
路径:展开行-点击弹窗右上角评论-显示本表的修改历史-修改历史

wegist1

🔜   畅享输入,轻松排版

文件详情页改版,文本编辑很清爽。支持 markdown 语法,输入“/”展开菜单栏,内容排版快人一步。

wegist1

📎  附件下载,一步完成

单行记录中,附件列的多个文件可一键下载。下载文件将以压缩包的形式存储在本地设备中。

wegist1

☎️  成员手机,可控显示

显示成员手机号码,紧急事项及时沟通。开启选项后,通讯录成员的手机号码将完整展示。
路径:空间站管理-普通成员-成员信息-显示成员手机号

wegist1

⌨️  快捷操作指南

  • 双击表格头部的表名,快速完成重命名。
  • 点击右上角的协同成员头像,快速设置成员在当前表格的权限。
  • 批量隐藏、拖动或删除维格列,选中一列后,按住 shift 并鼠标点击其他列可快速形成选区并进行操作。
  • 批量操作连续的记录时,鼠标勾选一行后按住 shift 并点击最后一行前的复选框,即可快速形成选区。

\"\n }" + }, + "64": { + "uiConfigId": "player_step_ui_config_64", + "uiType": "modal", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "uiConfig": "{\n\"title\":\"甘特图教学视频\",\n\"video\":\"space/2021/05/26/baddaa8b7d0c4b0390b03ef9a5549c6e\"\n}", + "onClose": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "65": { + "uiConfigId": "player_step_ui_config_65", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "知道啦", + "nextId": "known", + "uiConfig": "{\n \"title\": \"🌟星球居民们🌟\",\n\"children\": \"

7月份的尾巴,是热情洋溢的狮子座,也是魔法神奇的维格表,快来康康这次更新了哪些功能吧~

🧙‍  神奇表单更神奇

未提交表单内容时退出页面,重新进入自动保留上次填写内容,减少重复输入
支持智能公式列、神奇引用列的内容显示,表单填写智能化

wegist1

🌈  字段设置很贴心

显示神奇关联列在对应关联表中的列名称,帮助使用者快速理解、一一对应

wegist1

数字列类型格式增强,贴合业务场景自定义单位名称,多种千分位格式设置,数据记录更直观

wegist1

⏳  筛选查重新技能

数据录入和表单提交时可能导致的重复记录,都可以通过筛选器快速查找,以便及时更正

wegist1

🎉   第三方集成:钉钉

在钉钉中创建自建应用「维格表」,平台间的组织架构和消息通知即时同步,清除协作障碍

wegist1

🔓  其他功能优化

相册视图布局调整,平铺状态下最少可展示一列,移动端查看更加舒适

wegist1

首列列名称增加小提示,数据结构化以「记录标题」为主键,不支持拖动、隐藏和删除

wegist1

当维格表的列数量较多需要横向拖动进行查看时,可按住 Shift 后滚动鼠标上的滚轮来实现

wegist1\"\n }" + }, + "66": { + "uiConfigId": "player_step_ui_config_66", + "uiType": "modal", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "uiConfig": "{\n\"title\":\"日历视图教学视频\",\n\"video\":\"space/2022/04/26/ab9d17db76064e9d8fd228889e30f1ad\"\n} ", + "onClose": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "67": { + "uiConfigId": "player_step_ui_config_67", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "知道啦", + "nextId": "known", + "uiConfig": "{\n\t\"title\": \"🌟星球居民们🌟\",\n\t\"children\": \"

十月更新第二弹,维格机器人来喽,打通 IM 工具,消息通知使命必达,还有满屏细节更新,快来体验吧~

🤖️  维格机器人

维格机器人 (Vika Robot) 是工作流或系统对接的自动化方案,将帮助企业/个人减少机械劳动,释放生产力。当前,维格机器人已实现与 IM 工具的信息连接,只需简单配置即可将维格表记录推送至飞书、钉钉、企业微信。更多可能,敬请期待~
尝鲜体验需先申请内测资格,路径:左下角头像-用户中心-实验性功能-机器人-去申请内测

wegist1

📅  日期统计更通用

优化 WEEKNUM()、WORKDAY()、WORKDAY_DIFF() 三个日期公式计算逻辑,使统计结果更符合预期。

  • WEEKNUM(),日期参数默认将每年的 1 月 1 日作为第一周,且周日为每周的第一天如: WEEKNUM('2021-11-11'), 输出值: 46
  • WORKDAY()、WORKDAY_DIFF(),修复参数影响导致的计算结果异常现象

🌟  评分更便捷

在满意度调研表单中,评分字段的使用尤为频繁, 使用鼠标点击并不便捷。现在,你可以选中评分单元格后,从键盘输入数字来完成( 支持 PC 端和网页端)。

↕️  分组更友好

神奇关联作为维格表的明星功能,细节体验十分突出,将神奇关联字段作为分组条件后,点击分组标题展开记录详情,轻松掌握更多信息。

🛎️  通知更细腻

< p class='body3'> 镜像用得好,权限无烦恼,在镜像视图下@相关成员,成员查看通知记录将打开对应的镜像视图, 避免原表无访问权限的尴尬。

\"\n}" + }, + "68": { + "uiConfigId": "player_step_ui_config_68", + "uiType": "popover", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"element\": \"div[data-guide-id=WIDGET_ITEM_WRAPPER]:last-child\",\n\"placement\": \"leftCenter\",\n \"title\": \"开发模式\", \n\"description\": \"开发模式下,你可以预览小程序的最新本地改动\", \"children\":\"\" \n}" + }, + "69": { + "uiConfigId": "player_step_ui_config_69", + "uiType": "popover", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"element\": \"div[data-guide-id=WIDGET_ITEM_WRAPPER]:last-child [data-guide-id=WIDGET_ITEM_REFRESH]\",\n\"placement\": \"topRight\",\n \"title\": \"刷新\", \n\"description\": \"每次本地改动代码后,都需要点击刷新来预览\", \"children\":\"\"\n}" + }, + "70": { + "uiConfigId": "player_step_ui_config_70", + "uiType": "popover", + "onNext": [ + "clear_guide_uis([\"popover\"])" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"element\": \"div[data-guide-id=WIDGET_ITEM_WRAPPER]:last-child [data-guide-id=WIDGET_ITEM_MORE]\",\n\"placement\": \"topRight\",\n \"title\": \"退出开发模式\", \n\"description\": \"点击此处选择「退出开发模式」,将断开与本地服务的连接,恢复至上一个版本的小程序状态\", \"children\":\"\"\n}" + }, + "71": { + "uiConfigId": "player_step_ui_config_71", + "uiType": "customQuestionnaire", + "uiConfig": "{}" + }, + "72": { + "uiConfigId": "player_step_ui_config_72", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"title\": \"🌟星球居民们🌟\",\n\"children\": \"

维格表 10 月上旬更新来了,日期筛选大幅优化,满足全方位使用需求,智能公式优化,数据统计更加精准便捷。

📅  日期筛选更自由

运营人员每周分析广告投放效果,财务人员月末整理对账数据,这些场景与日期筛选密不可分,动态查询将让数据统计分析工作愈加轻松。

新增本周/本月/上周/上月/今年 5 个常用日期条件,一次设置长期可用,再也不用每次手动调整啦~

wegist1

项目回顾、工单处理等场景下需要聚焦某个周期内的数据,支持自定义时间范围,操作更友好

wegist1

数据分析中有时只需关注近期数据变化,筛选早于/晚于当前多少天的数据,结合仪表盘还能轻松实现可视化大屏效果

wegist1

🆒  智能公式优化

优化 DATETIME_DIFF()、AVERAGE()、FIND() 三个智能公式计算逻辑:

  • DATETIME_DIFF()输出结果调整为浮点数,更精确地计算两个日期间的差值
  • AVERAGE()所统计字段带有空值时,空值将不纳入计算
  • FIND()新增支持从文本末端往前查找,如:FIND('a','vikadata',-1),输出结果 8
\"\n }" + }, + "73": { + "uiConfigId": "player_step_ui_config_73", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"title\": \"🌟星球居民们🌟\",\n\"children\": \"

十月更新第二弹,维格机器人 (Vika Robot) 来喽,打通 IM 工具,消息通知使命必达。还有满屏细节更新,快来体验吧~

🛰️  维格机器人

维格机器人 (Vika Robot) 是工作流或系统对接的自动化方案,将帮助企业/个人减少机械劳动,释放生产力。当前,维格机器人已实现与 IM 工具的信息连接,只需简单配置即可将维格表记录推送至飞书、钉钉、企业微信。更多可能,敬请期待~

尝鲜体验需先申请内测资格,路径:左下角头像-用户中心-实验性功能-机器人-去申请内测

wegist1

📅  日期统计更通用

优化 WEEKNUM()、WORKDAY()、WORKDAY_DIFF() 三个日期公式计算逻辑,使统计结果更符合预期。

  • WEEKNUM(),日期参数默认将每年的 1 月 1 日作为第一周,且周日为每周的第一天。如:WEEKNUM('2021-11-11'),输出值:46
  • WORKDAY()、WORKDAY_DIFF(),修复参数影响导致的计算结果异常现象

🌟  评分更便捷

在满意度调研表单中,评分字段的使用尤为频繁,使用鼠标点击并不便捷。现在,你可以选中评分单元格后,从键盘输入数字来完成(支持 PC 端和网页端)。

↕️  分组更友好

神奇关联作为维格表的明星功能,细节体验十分突出,将神奇关联字段作为分组条件后,点击分组标题展开记录详情,轻松掌握更多信息。

🛎️  通知更细腻

镜像用得好,权限无烦恼,在镜像视图下 @ 相关成员,成员查看通知记录将打开对应的镜像视图,避免源表无访问权限的尴尬。

\"\n }" + }, + "74": { + "uiConfigId": "player_step_ui_config_74", + "uiType": "popover", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"element\": \".style_formSpace__1_szP .style_right__DRofa #DATASHEET_FORM_CONTAINER_SETTING\",\n\"placement\": \"bottomRight\",\n \"title\": \"收纳单多选的选项\",\n \"arrowStyle\": { \"right\": \"40px\" },\n\"description\": \"选项过多导致页面太长?试试把它们收纳起来吧\" \n}", + "onTarget": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "75": { + "uiConfigId": "player_step_ui_config_75", + "uiType": "popover", + "onNext": [ + "clear_guide_uis([\"popover\"])" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"element\": \"div[data-guide-id=WIDGET_ITEM_WRAPPER]:last-child\",\n\"placement\": \"leftCenter\",\n \"title\": \"未发布的小程序\", \n\"description\": \"当前小程序未发布到空间站,只能在开发模式下预览小程序效果\", \"children\":\"\" \n}" + }, + "76": { + "uiConfigId": "player_step_ui_config_76", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"title\": \"🌟星球居民们🌟\",\n \"children\": \"

这可能是史上最硬核的 Q4,继 Vika Robot 维格机器人后,本次更新再次推出自建小组件,实现更丰富的数据可视化效果,数据流转、协作更智能。

🧙‍♀️  表单显示更紧凑

使用神奇表单进行数据收集,单选/多选的选项较多时,页面会不断拉长,影响填写体验。对此,神奇表单进行了样式优化,开启「收纳单多选的选项」,再多的选项都可以完美兼容。

路径:神奇表单-设置-收纳单多选的选项

wegist1

🔐  安全与权限升级

空间站新增「安全设置」,企业/团队负责人可更加精细化地进行安全管控,包括维格表/视图是否可导出和分享、是否可邀请他人加入协作,是否开启全局水印等,进一步规避数据泄漏风险。

路径:设置-驾驶舱-安全设置

wegist1

🧰  自建小组件内测啦~

维格表自建小组件登场,为企业团队特定的工作场景和协作流程提供更多延展可能,内测申请通过后即可体验~

路径:用户中心-实验性功能-自建小组件-申请内测

wegist1

🛰️  优化机器人

支持发送消息至企业微信群,同时新增查看运行历史详情,以便快速定位异常,确保消息及时触达。

路径:用户中心-实验性功能-机器人-申请内测

\"\n}" + }, + "77": { + "uiConfigId": "player_step_ui_config_77", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"children\": \"

关于 11 月 17 日服务器维护导致不可访问的致歉说明


11 月 17 日 23:02-23:30 期间,因 vika.cn 服务器在升级维护过程出现异常,维格表出现了 28 分钟服务不可使用状态,我们为此深感抱歉。vika维格表本应助力深夜仍在辛勤工作的用户,更舒适快速地结束工作,在这里,向所有受影响的用户再次表达我们的歉意!


问题出现后,产研团队第一时间上线解决。11 月 18 日,vika维格表团队组织了问题复盘会,总结教训的同时,我们向每一位用户做出如下承诺:

  1. 每次服务器升级维护,我们将至少提前 36 小时给您推送邮件通知、站内通知;
  2. 服务器常规升级维护的作业时间固定调整至凌晨 4 点开始;

再次为我们造成的不便致以诚挚歉意。如果有任何问题,请随时联系我们:


vika维格表全体成员将竭诚为您服务。

vika维格表产研团队

2021 年 11 月 18 日

\"\n}" + }, + "78": { + "uiConfigId": "player_step_ui_config_78", + "uiType": "popover", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "我知道了", + "nextId": "i_knew_it", + "uiConfig": "{\n \"element\": \"#DATASHEET_TOOL_BAR .style_toolbarMiddle__2kxTf\",\n\"placement\": \"bottomRight\",\n \"arrowStyle\": { \"display\": \"none\" },\n \"title\": \"视图配置不协同\",\n\"description\": \"现在,临时的筛选、分组、排序等配置在未保存的情况下,不会同步给其他人,你的临时配置也将在刷新后失效。\" \n}" + }, + "79": { + "uiConfigId": "player_step_ui_config_79", + "uiType": "popover", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "我知道了", + "nextId": "i_knew_it", + "uiConfig": "{\n \"element\": \"#DATASHEET_VIEW_TAB_BAR #view_item_sync_icon\",\n\"placement\": \"bottomLeft\",\n \"arrowStyle\": { \"left\": \"6px\" },\n \"title\": \"当前视图配置未保存\",\n\"description\": \"你刚修改了某些视图配置(筛选、分组、排序...),它们现在还没有保存哦。这意味着它们仅对你自己临时生效。你可以点击此处保存并同步给其他人\" \n}" + }, + "80": { + "uiConfigId": "player_step_ui_config_80", + "uiType": "popover", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "我知道了", + "nextId": "i_knew_it", + "uiConfig": "{\n \"element\": \"#AUTO_SAVE_SVG_ID\",\n\"placement\": \"bottomLeft\",\n \"arrowStyle\": { \"left\": \"6px\" },\n \"title\": \"当前视图已开启自动保存\",\n\"description\": \"你现在进行筛选、分组、排序等视图配置操作会自动保存并同步给其他人\" \n}" + }, + "81": { + "uiConfigId": "player_step_ui_config_81", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"title\": \"🌟星球居民们🌟\",\n \"children\": \"

你们反馈的每个需求和场景,我们都记在小本本上,快来康康本期更新,有你想要的吗?

🛸 全新驾驶舱

细分功能模块,空间站管理员可清晰地查看套餐总量和可用余量,了解团队协作情况。

https://s1.vika.cn/space/2021/11/25/6675a9ee262242bd98d17dc375220dfb

↕️  批量粘贴记录的优化

小明在维格视图的分组状态下,批量粘贴记录后发现覆盖了下一分组中的数据。因此他只能撤销粘贴操作,在当前分组下新增足够的行数再进行粘贴。

对此,维格表进行优化,分组下批量粘贴记录时询问是否新增行,避免覆盖原有记录。

https://s1.vika.cn/space/2021/11/25/f0c66d4656b947f1a3f6a85df7a5fe99

🛰️ 维格机器人

维格机器人选择变量时支持插入公式列,发送至钉钉/飞书/企业微信群的消息内容中将展示公式计算结果。比如:小明在维格表中创建智能公式列,用于计算任务到期天数

https://s1.vika.cn/space/2021/11/25/295938afe27d44b095beabb5fad254e7

维格列设置权限或删除,维格机器人中与之相关的匹配条件和变量值也将实时同步异常状态。

https://s1.vika.cn/space/2021/11/25/5aba8bf2c5864d8aaf15b805aee6e740

💡 功能优化

工作目录树新增自动折叠和悬浮效果,为工作台腾出更多操作空间

https://s1.vika.cn/space/2021/11/25/11a92b3dc9074f2589f0c8f20361d08e

优化视图标签栏,支持显示文件描述,多视图下自动进行收纳

https://s1.vika.cn/space/2021/11/25/0d49558ebbae4f3cb9368fe1c588c9d5

\"\n}" + }, + "82": { + "uiConfigId": "player_step_ui_config_82", + "uiType": "modal", + "onNext": [ + "clear_guide_all_ui()" + ], + "uiConfig": "{\n\"title\":\"架构视图教学视频\",\n\"video\":\"space/2022/04/26/bebe4536c330427c81e6b26627263904\"\n}", + "onClose": [ + "clear_guide_all_ui()" + ] + }, + "83": { + "uiConfigId": "player_step_ui_config_83", + "uiType": "breath", + "uiConfig": "{\n \"element\": \"#DATASHEET_CREATOR_ORG_CHART\",\n\"shadowDirection\": \"none\"\n}", + "onTarget": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "84": { + "uiConfigId": "player_step_ui_config_84", + "uiType": "popover", + "backdrop": "around_mask", + "onNext": [ + "clear_guide_uis([\"popover\"])" + ], + "uiConfig": "{\n \"element\": \"#DATASHEET_CREATOR_ORG_CHART\",\n\"placement\": \"right\",\n \"title\": \"架构视图上线\", \n\"description\": \"赶紧来体验一下吧\", \n\"children\": \"\"\n}", + "onTarget": [ + "clear_guide_all_ui()" + ] + }, + "85": { + "uiConfigId": "player_step_ui_config_85", + "uiType": "popover", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})", + "clear_guide_uis([\"popover\"])" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"element\": \"#DATASHEET_ORG_CHART_RECORD_LIST\",\n\"placement\": \"left\",\n \"title\": \"为它创建一个子级\", \n\"description\": \"你可以将记录拖至左侧的记录卡片中,自动成为卡片的子级\",\n\"offsetY\": 144\n}" + }, + "86": { + "uiConfigId": "player_step_ui_config_86", + "uiType": "popover", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"element\": \"#DATASHEET_ORG_CHART_RECORD_LIST\",\n\"placement\": \"left\",\n \"title\": \"清除子级\", \n\"description\": \"你可以将记录拖至右侧的待处理记录区,清除其关联关系\",\n\"offsetY\": 144\n}" + }, + "87": { + "uiConfigId": "player_step_ui_config_87", + "uiType": "breath", + "uiConfig": "{\n \"element\": \"#DATASHEET_ORG_CHART_RECORD_LIST\"\n}" + }, + "88": { + "uiConfigId": "player_step_ui_config_88", + "uiType": "breath", + "uiConfig": "{\n \"element\": \"#toolHideField\"\n}" + }, + "89": { + "uiConfigId": "player_step_ui_config_89", + "uiType": "popover", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "我知道了", + "nextId": "i_knew_it", + "uiConfig": "{\n \"element\": \"#toolHideField\",\n\"placement\": \"bottom\",\n \"title\": \"设置卡片样式\", \n\"description\": \"自定义卡片显示的字段和封面图效果\" \n}", + "onTarget": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "90": { + "uiConfigId": "player_step_ui_config_90", + "uiType": "breath", + "uiConfig": "{\n \"element\": \"#DATASHEET_TOOL_BAR_VIEW_SETTING\"\n}" + }, + "91": { + "uiConfigId": "player_step_ui_config_91", + "uiType": "popover", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})", + "clear_guide_uis([\"popover\"])" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"element\": \"#DATASHEET_TOOL_BAR_VIEW_SETTING\",\n\"placement\": \"bottom\",\n \"title\": \"重新查看教学视频\", \n\"description\": \"你可以点击「设置」,在里面找到「架构视图」的教学视频重新观看噢~\" \n}" + }, + "92": { + "uiConfigId": "player_step_ui_config_92", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\"title\":\"🌟星球居民们🌟\",\"children\":\"

架构视图来袭,拖动完成绘制,视图配置不协同,数据呈现千人千面,快来体验吧~

\\n

🙋‍♂️ 架构视图

\\n

架构视图用于呈现本表每条记录间的层级关系,只需将记录卡片拖动至图形区建立关联,即可轻松绘制组织架构图、软件架构图等效果,省时又高效

\\n

\\\"https://s1.vika.cn/space/2021/12/09/8e2aa90c2fa44641a59141b3a040ce55\\\"

\\n

🙅‍♂️ 视图配置不协同

\\n

多成员在同一视图下协作时,希望通过筛选/分组/排序等操作快速展示符合自身需求的记录并且不受其他成员的操作干扰,通过「视图配置不协同」,可实现视图效果仅当前生效。

\\n

路径:空间站 > 空间站管理 > 管理员的实验性功能 > 视图配置不协同

\\n

\\\"https://s1.vika.cn/space/2021/12/09/8aa52753ff5342eaa8a05dbf20bd0efc\\\"

\\n

🛰️ 维格机器人

\\n

维格机器人选择变量时支持插入神奇引用列类型的值,所有引用类型都可在消息通知中展示。

\\n

\\\"https://s1.vika.cn/space/2021/12/09/d58e4863b0aa4a47b0fe32e416ad6289\\\"

\\n

🧣 细节体验优化

\\n

神奇引用列和智能公式列中的网址点击可跳转,数字支持设置千分位。

\\n

相册视图优化封面图尤其是长图的适配效果,记录卡片支持跨组拖动。

\"}" + }, + "93": { + "uiConfigId": "player_step_ui_config_93", + "uiType": "privacyModal", + "onNext": [ + "set_wizard_completed({\"curWizard\": true})", + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"title\": \"维格隐私政策\",\n \"children\": \"

1. 我们如何收集并使用您的信息

\\n

在您使用维格表提供的以下服务或功能过程中,我们将基于以下基本功能收集您的相关必要个人信息。

\\n

1.1 账号的注册及使用

\\n

您首先需要注册一个维格表账号成为维格表的注册用户。当您注册时,您需要向我们提供您本人的手机号码或者电子邮箱,我们将通过发送短信验证码或者邮件验证码的方式来验证您的身份是否有效。如果您不提供该信息,您也可以通过第三方平台(微信、钉钉、飞书、企业微信)授权的形式快速完成注册,此方式需要您授权维格表获得您在第三方平台的头像、昵称。

\\n

1.2 基本业务使用

\\n

1.2.1 空间站的通讯录

\\n

空间站的通讯录中可能会展示您在此空间站的昵称、头像、电话号码以及邮箱。注:非本空间站的成员将不会看到您的个人信息。

\\n

1.2.2 发布记录评论

\\n

您可以对表格中的记录进行评论,评论的信息将会带上您的昵称以及头像。注:非本空间站的成员将不会看到您的个人信息。

\\n

1.2.3 带有成员相关信息的字段

\\n

在表格中使用成员字段的相关功能,将会带上您的昵称以及头像信息。

\\n

1.2.4 文件的公开链接

\\n

利用文件的公开链接能力进行分享,在分享的页面上将会带上您的昵称、头像以及空间站的名称信息。

\\n

1.2.5 “维格社区”公开发布功能

\\n

您可通过“维格社区”的问题、文章、活动、评论功能公开发布信息,相关页面将显示您的昵称和头像。您公开发布的信息中可能会涉及您或他人的个人信息甚至个人敏感信息,请您谨慎地考虑,是否在使用我们的服务时公开发布相关信息。若您公开发布的信息中涉及他人个人信息的,您需在发布前征得他人的同意。

\\n

1.3 客户服务

\\n

为了更好为您排查使用中的问题,我们会收集以下信息来帮助工程师定位问题。

\\n

1.3.1 设备信息

\\n

我们会根据您在具体使用维格表时的操作,收集您所使用的设备相关信息:包括设备型号、操作系统版本、设备设置、 MAC 地址及 IMEI 等相关信息。

\\n

1.3.2 服务日志

\\n

我们会收集您在使用维格表服务时的操作日志进行保存,包括:浏览记录、点击事件、浏览器类型、电信运营商、IP 地址、访问时长、访问日期及时间。

\\n

1.4 授权同意之外

\\n

根据法律法规的规定,在以下情形中,我们可未经您授权的情况下收集并使用以下信息:

\\n
    \\n
  1. \\n

    与国家安全、国防安全直接相关的;

    \\n
  2. \\n
  3. \\n

    与公共安全、公共卫生、重大公共利益直接相关的;

    \\n
  4. \\n
  5. \\n

    与犯罪侦查、起诉、审判和判决执行等直接相关的;

    \\n
  6. \\n
  7. \\n

    依照《中华人民共和国个人信息保护法》规定在合理的范围内处理您自行公开或者其他已经合法公开的个人信息;

    \\n
  8. \\n
  9. \\n

    从合法公开披露的信息中收集到您的个人信息,如从合法的新闻报道、政府信息公开等渠道;

    \\n
  10. \\n
  11. \\n

    根据您的要求签订和履行合同所必需的;

    \\n
  12. \\n
  13. \\n

    用于维护维格表的产品和/或服务的安全稳定运行所必需的;

    \\n
  14. \\n
  15. \\n

    法律法规规定的其他情形。

    \\n
  16. \\n
\\n

2. 我们保证信息的安全性

\\n

维格表为保障用户的数据安全不遗余力。我们始终以软件行业最高安全标准保护用户数据,所使用的安全模型和策略全部基于国际标准和行业最佳实践。

\\n

我们将严格保护您的信息的安全。使用各种安全技术和程序来保护您的信息不被未经授权的访问、使用或泄漏。如果您对隐私保护有任何置疑,请发送邮件至 devops@vikadata.com

\\n

2.1 技术措施

\\n

2.1.1 数据位置

\\n

维格表的数据全部托管在亚马逊中国(AWS)宁夏区域、北京区域、阿里云的多个数据中心的可用区中,采用多副本冗余存储。他们是中国最顶尖的云服务提供商,数据托管在他们的基础设施上,避免了硬盘被盗或失效、甚至整个区域故障导致的数据丢失风险。

\\n

2.1.2 数据灾备与恢复

\\n

维格表每天都会对数据进行备份,备份数据也存储在多个数据中心的可用区中,并使用 AES-256 算法进行加密, 所有备份都会定期追踪其完整性并进行验证检查,以确保故障发生时,我们可以迅速启动恢复流程并立即修复数据。

\\n

2.1.3 服务器安全

\\n

网络安全

\\n

维格表采用亚马逊云中国(AWS)云提供的、具有多层保护和防御机制的网络安全技术,通过防火墙阻挡未经授权的访问,同时还采用多个交换机和安全网关来确保网络冗余,防止内部网络的单点故障。

\\n

DDoS 防御

\\n

维格表使用新一代Amazon WAF(Web 应用防护系统)技术来防止对服务器的 DDoS 攻击,只允许正常的流量通过,防止恶意流量攻击造成的业务中断,使网站和 API 保持高可用性和高性能。

\\n

服务器强化

\\n

维格表所有服务器未使用的端口和帐户都被禁用,我们定期对云服务器进行安全扫描和补丁升级。

\\n

服务灾难恢复和业务连续性

\\n

维格表的服务均采用多副本冗余机制,分布在多个不同区域内,在单个区域发生故障的情况下,其他区域会接管并平稳地进行切换操作。除此之外,我们还制定了业务连续性计划并对基础架构进行持续监控,确保维格表的各项服务能够正常运行。

\\n

管理权限

\\n

维格表采用访问控制技术严格管理服务器的访问权限。基于最小特权和基于角色的权限控制原则,最大程度地减少数据泄露的风险。登录服务器被要求使用受密码保护的 SSH 密钥和双因素身份验证,并记录所有的服务器操作,日常审核。

\\n

2.1.4 软件服务安全

\\n

代码安全

\\n

维格表的所有代码在部署到服务器之前均经过严格的安全检验,包括威胁建模、自动化测试、自动扫描和代码审核。同时我们的开发人员会进行安全培训,以保证他们掌握最新、最佳的安全开发实践,防止隐患产生。

\\n

通信加密

\\n

当用户执行访问网站或上传附件等操作时,数据会在他的设备和我们的数据中心之间加密传输。我们设置了多重安全防护来保护用户数据的传输:要求所有与服务器的连接均使用 TLS 1.2 / TLS 1.3 和现代密码算法对流量进行加密;启用了 HTTPS 安全协议,要求浏览器仅能通过加密连接与我们建立连接。

\\n

数据鉴权和隔离

\\n

为了确保数据的合法访问,维格表使用国际标准的鉴权体系,提供身份管理、认证管理和角色授权三位一体的用户业务鉴权服务。通过用户身份标识、用户授权检查、业务身份标识形成端对端的鉴权体系,防止非授权的数据访问发生。以鉴权的安全性为基础,维格表依照 SaaS 服务多租户的最佳实践,设计实现了用户团队之间数据的隔离性。

\\n

网站安全加固

\\n

维格表定期进行专业漏洞扫描, 通过Web漏洞扫描、操作系统漏洞扫描、资产内容合规检测、配置基线扫描、弱密码检测五大方面,自动发现网站或服务器暴露在网络中的安全风险,为云上业务提供多维度的安全检测服务,满足合规要求,让安全弱点无所遁形。

\\n

2.2 安全认证

\\n

2.2.1 网络安全等级保护 2.0

\\n

依据网络安全等级保护 2.0 的标准及相关条例规定,维格表对整个系统进行安全加固,正在申请认证机关的审核,将于 2022 年内完成此项认证。

\\n

中国网络安全等级保护 2.0(简称等保 2.0)于 2019 年 12 月 1 日起正式实施。等保 2.0 更加注重主动防御,从被动防御到事前、事中、事后全流程的安全可信、动态感知和全面审计,实现了对传统信息系统、基础信息网络、云计算、移动互联、物联网、大数据和工业控制系统等级保护对象的全覆盖。

\\n

2.2.2 ISO/IEC 27001:2013 信息安全管理体系

\\n

维格表按照 ISO 27001 的各项标准及相关条例规定,维格表对整个系统进行安全加固,正在申请认证机关的审核,将于2022年内完成此项认证。

\\n

通过 ISO 27001 认证,能体现企业对安全的承诺,表明企业信息安全管理已建立起一套科学有效的管理体系,能够为用户提供可靠的信息服务。目前国内外许多政府机构、银行、证券、保险公司、电信运营商、网络公司及许多跨国公司均采用了此项 ISO 标准对自己的信息安全进行系统的管理。

\\n

3. 我们如何使用 cookie 和同类技术

\\n

为确保网站正常运转,我们会在您的计算机或移动设备上存储名为 cookie 的数据文件。cookie 通常包含用户身份标识符、城市名称以及一些字符。cookie 主要的功能是便于您使用网站产品和服务,以及帮助网站统计独立访客数量等。运用 cookie 技术,我们能够为您提供更加周到的服务。我们不会将 cookie 用于本政策所述目的之外的任何用途。您可根据自己的偏好管理或删除 cookie。您可以清除计算机上保存的所有 cookie,大部分网络浏览器都设有阻止 cookie 的功能。但如果您这么做,则需要在每一次访问我们的网站时亲自更改用户设置,但您可能因为该等修改,无法登录或使用依赖于 cookie 的维格表提供的服务或功能。您可以通过更改您的浏览器设置限制维格表对 cookie 的使用。以 Chrome 浏览器为例,您可以在 Chrome 浏览器右上方的下拉菜单的“浏览器设置”中,通过“设置-高级-清除浏览数据”,选择清除您的 cookie。

\\n

4. 我们如何共享、转让、披露收集到的信息

\\n

4.1 共享您的个人信息

\\n

我们在获得您的明确同意后,会在以下地方或与授权的第三方合作伙伴共享您的个人信息。共享的个人信息的用途限制:提供基础的业务服务、协助我们向您提供服务。

\\n
    \\n
  1. \\n

    我们在法律法规及您本人的允许下,根据申请方的请求对外共享您的个人信息。

    \\n
  2. \\n
  3. \\n

    与授权的第三方合作伙伴共享:我们与我们授权过的第三方共享您的个人信息,但仅会出于本隐私权政策声明的合法、正当、必要、特定、明确的目的共享您的信息,比如您使用的设备信息、操作的时间、访问页面时长等来收集您功能的使用情况,以此帮助我们改进功能的设计。我们会审慎选择第三方和第三方服务,督促相关第三方在按照本政策或另行与您达成的约定收集和使用您的个人信息,并采取适当的安全技术和管理措施保障您的个人信息安全。

    \\n
  4. \\n
\\n

4.2 转让及披露您的个人信息

\\n

除非获取您明确的同意,否则我们不会公开转让、披露您的个人信息。

\\n

但在以下情形中,我们可以在不征求您的授权同意下,共享、转让、披露您的个人信息:

\\n
    \\n
  1. \\n

    与国家安全相关;

    \\n
  2. \\n
  3. \\n

    与犯罪侦查、起诉、审批和判决执行等有关;

    \\n
  4. \\n
  5. \\n

    行政、司法机关依法提出的要求;

    \\n
  6. \\n
  7. \\n

    为了维护您所属维格表团队的财产安全或出于其他企业主提出的合法权益合理且必要的用途

    \\n
  8. \\n
  9. \\n

    您主动公开的个人信息;

    \\n
  10. \\n
  11. \\n

    从合法渠道收集到的个人信息;

    \\n
  12. \\n
  13. \\n

    法律法规的其他情形。

    \\n
  14. \\n
\\n

如您主动公开、共享个人信息,不受本协议限制。

\\n

5. 有害信息处理

\\n

根据法律法规,我们禁止用户写入并存储一切有害信息,包括:

\\n
    \\n
  1. \\n

    违反宪法的基本原则的内容;

    \\n
  2. \\n
  3. \\n

    危害国家安全,泄露国家秘密的内容;

    \\n
  4. \\n
  5. \\n

    一切反动、破坏国家统一的言论;

    \\n
  6. \\n
  7. \\n

    破坏国家关系、民族和谐统一的内容;

    \\n
  8. \\n
  9. \\n

    封建迷信的内容;

    \\n
  10. \\n
  11. \\n

    散布谣言或不实消息扰乱社会秩序、破坏社会稳定的内容;

    \\n
  12. \\n
  13. \\n

    侵犯他人名誉、隐私等合法权益的内容;

    \\n
  14. \\n
  15. \\n

    散布淫秽、色情、赌博、暴力恐怖犯罪信息的内容;

    \\n
  16. \\n
  17. \\n

    违反国家法律、行政法规禁止的其他内容;

    \\n
  18. \\n
\\n

我们将对以上信息进行屏蔽处理。如果后续的举报中发现,我们有权对违反政策的内容进行删除,并对违反政策的用户进行封号处理,同时保留依法追究当事人的法律责任的权利。

\\n

6. 您的权利

\\n

我们根据法律法规支持并保护您个人的隐私,您对自己的个人信息拥有访问、修改、删除以及撤回的权利。

\\n
    \\n
  1. \\n

    管理账号信息:您可在【用户中心】中修改您的昵称、头像、手机号、邮箱以及密码。

    \\n
  2. \\n
  3. \\n

    账号注销:您可在【个人中心】中点击【注销】,根据页面具体提示来提交您的账号注销申请,并在您符合注销条件的情况下,我们将在30个工作日后完成注销。注销申请可在操作成功后的30日内撤回。在您主动注销账号之后,我们将停止为您提供产品或服务,并根据法律的要求删除您的个人信息,或对其进行匿名化处理,因法律规定需要留存个人信息的,我们不会再将其用于日常业务活动中。

    \\n
  4. \\n
\\n

在以下情形中,您可以通过与客服沟通向我们提出删除个人信息的请求,我们会对应做出删除响应:

\\n
    \\n
  1. \\n

    我们收集并使用了您的信息但未经过您的允许或同意;

    \\n
  2. \\n
  3. \\n

    在您同意我们收集并使用的情况下,我们使用您的个人信息时严重违反了与您的约定;

    \\n
  4. \\n
  5. \\n

    我们使用您的信息时,违反了法律法规。

    \\n
  6. \\n
\\n

在以下情形中,我们不能响应您删除的请求:

\\n
    \\n
  1. \\n

    国家安全相关;

    \\n
  2. \\n
  3. \\n

    有证据表明您存在侵权行为;

    \\n
  4. \\n
  5. \\n

    与犯罪侦查、起诉、审批和判决执行相关;

    \\n
  6. \\n
  7. \\n

    行政、司法机关依法提出的要求;

    \\n
  8. \\n
  9. \\n

    响应您的请求将损害他人或企业的合法权益。

    \\n
  10. \\n
\\n

7. 面对未成年人的的隐私策略

\\n

我们非常重视对未成年人个人信息的保护。根据相关法律法规的规定,若您是 18 周岁以下的未成年人,在使用维格表服务前,应事先取得您的家长或法定监护人的书面同意。若您是未成年人的监护人,当您对您所监护的未成年人的个人信息有相关疑问时,请通过邮件support@vikadata.com向我们告知。

\\n

8. 免责说明

\\n

就下列相关事宜的发生,我们不承担任何法律责任:

\\n
    \\n
  1. \\n

    根据法律规定或相关政府的要求提供您的企业或个人信息。

    \\n
  2. \\n
  3. \\n

    由于您将用户密码告知他人或与他人共享账户,由此导致的任何企业或个人信息的泄漏,或其他非因服务原因导致的个人信息的泄漏。

    \\n
  4. \\n
  5. \\n

    在各服务条款及声明中列明的使用方式或免责情形。

    \\n
  6. \\n
  7. \\n

    因不可抗力导致的任何后果。

    \\n
  8. \\n
\\n

9. 联系我们

\\n

有关本隐私政策或相关的隐私措施的问题,请发送邮件至 support@vikadata.com

\\n

10. 附录

\\n

第三方SDK共享信息

\\n
    \\n
  1. \\n

    为保障维格表的稳定运行、功能实现,使您能够使用和体验更丰富的服务及功能,我们的应用中会嵌入授权合作伙伴的 SDK。

    \\n
  2. \\n
  3. \\n

    我们会对软件工具开发包(SDK)进行严格的安全检测,并约定严格的数据保护措施。

    \\n
  4. \\n
  5. \\n

    此外,当您使用本平台接入的第三方服务时,您的信息将适用该第三方的隐私政策,建议您在接受相关服务前阅读并确认理解相关协议。

    \\n
  6. \\n
\\n

对我们与之共享用户信息的公司、组织和个人,我们会与其签署严格的保密协议以及信息保护约定,要求他们严格遵守我们关于数据隐私保护的说明、本隐私政策以及其他任何相关的保密和安全措施来处理用户个人信息。

\\n

\\\"在这里插入图片描述\\\"

\"\n}", + "onClose": [ + "set_wizard_completed({\"curWizard\": true})", + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "94": { + "uiConfigId": "player_step_ui_config_94", + "uiType": "taskList", + "uiConfig": "{\n \"title\": \"选择任务,开启探索之旅吧\",\n \"description\": \"移动鼠标来选择任务,跟随页面提示开启旅程吧~\",\n \"data\": [\n {\n \"text\": \"重命名文件,目录索引更直观\",\n \"stopEvents\": [\n \"onMouseDown\"\n ],\n \"actions\": [\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \"#FOLDER_SHOWCASE_TITLE\",\n \"emitEvent\": \"click\",\n \"nextActions\": [\n {\n \"uiType\": \"popover\",\n \"uiConfig\": \"{\\\"element\\\":\\\"#FOLDER_SHOWCASE_TITLE_INPUT\\\",\\\"placement\\\":\\\"bottom\\\",\\\"title\\\":\\\"智能引导\\\",\\\"description\\\":\\\"点击这里可以修改名称 👆\\\"}\",\n \"backdrop\": \"around_mask\"\n },\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \"#FOLDER_SHOWCASE_TITLE_INPUT\",\n \"emitEvent\": \"focus\",\n \"finishTodoWhen\": [\n \"blur\"\n ]\n }\n }\n ]\n }\n }\n ]\n },\n {\n \"text\": \"查看/修改文件夹说明,以便其他协作者理解\",\n \"actions\": [\n {\n \"uiType\": \"breath\",\n \"uiConfig\": \"{\\\"element\\\":\\\"#FOLDER_SHOWCASE_DESCRIPTION\\\"}\",\n \"backdrop\": \"around_mask\"\n },\n {\n \"uiType\": \"popover\",\n \"uiConfig\": \"{\\\"element\\\":\\\"#FOLDER_SHOWCASE_DESCRIPTION\\\",\\\"placement\\\":\\\"left\\\",\\\"title\\\":\\\"智能引导\\\",\\\"description\\\":\\\"点击这里查看/修改说明\\\"}\"\n },\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \"#FOLDER_SHOWCASE_DESCRIPTION\",\n \"finishTodoWhen\": [\n \"click\"\n ]\n }\n }\n ]\n },\n {\n \"text\": \"为避免数据泄露或误删,设置文件访问权限\",\n \"actions\": [\n {\n \"uiType\": \"breath\",\n \"uiConfig\": \"{\\\"element\\\":\\\"#FOLDER_SHOWCASE_BTN_MORE\\\"}\"\n },\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \"#FOLDER_SHOWCASE_BTN_MORE\",\n \"nextActions\": [\n {\n \"uiType\": \"breath\",\n \"uiConfig\": \"{\\\"element\\\":\\\".sc-eFehXo div:nth-of-type(1)\\\",\\\"shadowDirection\\\":\\\"inset\\\"}\"\n },\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \".sc-eFehXo div:nth-of-type(1)\",\n \"finishTodoWhen\": [\n \"click\"\n ]\n }\n }\n ]\n }\n }\n ]\n },\n {\n \"text\": \"点击任一文件节点,开始进行数据协作吧\",\n \"actions\": [\n {\n \"uiType\": \"breath\",\n \"uiConfig\": \"{\\\"element\\\":\\\"#FOLDER_SHOWCASE_FIRST_NODE\\\"}\"\n },\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \"#FOLDER_SHOWCASE_NODES_CONTAINER > div\",\n \"finishTodoWhen\": [\n \"click\"\n ]\n }\n }\n ]\n }\n ]\n}" + }, + "95": { + "uiConfigId": "player_step_ui_config_95", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\"title\":\"🌟星球居民们🌟\",\"children\":\"

🔒 视图锁

\\n

在视图标签栏中开启「视图锁」,其他协作者将无权对视图进行筛选、分组、排序等操作,稳稳保住数据呈现效果。

\\n

\\\"https://s1.vika.cn/space/2021/12/23/831976472d6c491599ff92076045bb89\\\"

\\n

💬 记录评论

\\n

记录评论不仅支持引用指定评论进行回复,还可以用表情 👌 和 👍 表示知会和认可,让工作琐碎事事有响应。

\\n

\\\"https://s1.vika.cn/space/2021/12/23/694dcfc45bb94cbb91437cd8119d4af2\\\"

\\n

其他优化

\\n

支持只读权限成员进行视图配置,可随心进行筛选、排序等操作,不用担心影响到其他人。

\\n

维格小组件全面更名为「维格小程序」,组件板和组件中心同步更名为「小程序面板」、「小程序中心」。

\"}" + }, + "98": { + "uiConfigId": "player_step_ui_config_notice_0_10_5", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "查看更多", + "nextId": "see_more", + "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2022/01/21/fe33887f388649579947379203ece53b\",\n \"readMoreTxt\": \"查看更多\",\n \"readMoreUrl\": \"https://cn.bing.com\",\n \"children\": \"

2022年1月更新:第二弹

\\n
    \\n
  • 维格表功能界面支持英文语言,点亮 Hello World
  • \\n
  • 新增文件信息窗展示创建人和创建时间,管理更有序
  • \\n
  • 回收舱取消「彻底删除」,避免其他成员误删除导致无法恢复
  • \\n
  • 小助手增加「历史更新」,游历社区挖掘更多功能使用小技巧
  • \\n
\"\n}", + "onClose": [ + "clear_guide_all_ui()", + "set_wizard_completed({\"curWizard\": true})" + ] + }, + "99": { + "uiConfigId": "player_step_ui_config_99", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"title\": \"🌟星球居民们🌟\",\n \"children\": \"

2022 年首版更新已送达,希望每个细节体验都能在「辞旧迎新」中为你提供更多便利与舒心。

\\n

📅 日期输入更包容

\\n

日期字段体验优化,单元格输入 1-14、1/14 后智能补全为 2022/01/14,想你所想

\\n

\\\"\\\"

\\n

📅 日历展示更清晰

\\n

优化日历视图展示效果,同一日期中的记录超出 5 条时自动折叠,保持页面简洁

\\n

\\\"\\\"

\\n

🎮 小程序能力拓展

\\n

小程序能力进一步开放,vika 实验室实力出道,本期练习生:抽奖幸运儿、word 文档生成器

\\n

由 Liam 研发的「抽奖幸运儿」在 2022 维格年会上首次亮相,界面简约、操作简单,出场即是焦点,承担 5 万行数据不在话下,关键还免费

\\n

\\\"\\\"

\\n

由 Kelvin 研发的「Word 文档生成器」,一键即可批量填充字段并合成新的 Word 文档,减少大量重复性工作,为职场工具人的效率而生

\\n

\\\"\\\"

\\n

*两款小程序由 vika 实验室发布,欢迎前往维格社区与开发者互动交流

\\n

👉 https://bbs.vika.cn/topic/7

\"\n}" + }, + "100": { + "uiConfigId": "player_step_ui_config_100", + "uiType": "breath", + "uiConfig": "{\n \"element\": \"#VIKABY_UPDATE_LOGS_HISTORY\",\n \"shadowDirection\":\"inset\"\n}" + }, + "101": { + "uiConfigId": "player_step_ui_config_101", + "uiType": "popover", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"element\": \"#VIKABY_UPDATE_LOGS_HISTORY\",\n \"offsetY\": 23,\n \"placement\": \"leftCenter\",\n \"title\": \"智能引导\",\n \"description\": \"来不及查看的本期更新和历史更新记录,都可以在这里找回哦\"\n}", + "onTarget": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "103": { + "uiConfigId": "player_step_ui_config_103", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "查看更多", + "nextId": "see_more", + "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2022/01/21/0c57f86937e941289aae077071fc4338\",\n \"readMoreUrl\": \"https://u.vika.cn/0c85m\",\n \"children\": \"

2022年1月更新|第二弹

  • 维格表功能界面支持英文语言,点亮 Hello World
  • 回收舱取消「彻底删除」,避免其他成员误删除导致无法恢复
  • 小助手增加「历史更新」,游历社区挖掘更多功能使用小技巧
\"\n}", + "onClose": [ + "clear_guide_all_ui()", + "set_wizard_completed({\"curWizard\": true})" + ] + }, + "105": { + "uiConfigId": "player_step_ui_config_105", + "uiType": "popover", + "onSkip": [ + "skip_current_wizard()" + ], + "uiConfig": "{\n \"element\": \".sc-jmpzUR:nth-last-of-type(2)\",\n\"placement\": \"rightCenter\",\n \"title\": \"智能引导\", \n\"description\": \"模板中心提供了 1000+ 业务自动化解决方案,可免费安装应用\", \"children\":\"\" \n}" + }, + "106": { + "uiConfigId": "player_step_ui_config_106", + "uiType": "breath", + "uiConfig": "{\n \"element\": \".sc-jmpzUR:nth-last-of-type(2)\",\n\"shadowDirection\":\"inset\"\n} " + }, + "107": { + "uiConfigId": "player_step_ui_config_107", + "uiType": "popover", + "onNext": [ + "clear_guide_uis([\"popover\"])" + ], + "onSkip": [ + "skip_current_wizard()" + ], + "uiConfig": "{ \n\"element\": \"#WORKBENCH_SIDE_ADD_NODE_BTN\", \"placement\": \"bottom\", \"title\": \"智能引导\", \"description\": \"还没想好怎么搭建业务场景?那就先从模板开始吧~\", \"children\":\"\" }" + }, + "108": { + "uiConfigId": "player_step_ui_config_108", + "uiType": "breath", + "uiConfig": "{\n \"element\": \"#WORKBENCH_SIDE_ADD_NODE_BTN\"\n}", + "onTarget": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "109": { + "uiConfigId": "player_step_ui_config_109", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "查看更多", + "nextId": "see_more", + "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2022/02/21/d9519262565a4a96a7b838ad0bd44522\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/127\",\n \"children\": \"
  • 数据录入有窍门,日期、数字按序列自动填充,又快又稳
  • 文件信息用处多,查看创建人和创建时间,避免信息断层
  • 数据关联一步到位,基于现有架构层级轻松创建记录卡片
  • 协作空间按需采购,管理员可自主完成升级,避免创作受限
  • 打通企业微信,无需复杂配置,扫码集成后将自动同步通讯录
\"\n}", + "onClose": [ + "set_wizard_completed({\"curWizard\": true})", + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "111": { + "uiConfigId": "player_step_ui_config_111", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "查看更多", + "nextId": "see_more", + "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2022/03/02/38faa635d13f4c158f0e91c3659af653?attname=Update_cover%402x.png\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/136\",\n \"children\": \"
  • 透视表小程序来啦,多维度的数据分析更简单
  • 单/多选列支持设置默认值,数据录入更工整规范
  • 仪表盘的小程序拖动更加丝滑流畅,排列组合更便捷
  • API创建记录和更新记录接口支持指定 viewId 参数
\"\n}", + "onClose": [ + "set_wizard_completed({\"curWizard\": true})", + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "124": { + "uiConfigId": "player_step_ui_config_124", + "uiType": "popover", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "下一步", + "nextId": "next_step", + "uiConfig": "{\n \"element\": \".styles_controls__3Uc0- > div\",\n\"placement\": \"left\",\n \"title\": \"展开/隐藏记录\", \n\"description\": \"待处理的记录收纳在这里,点击可设置展开或隐藏\", \n\"children\": \"\"\n}" + }, + "125": { + "uiConfigId": "player_step_ui_config_125", + "uiType": "breath", + "uiConfig": "{\n \"element\": \".styles_controls__3Uc0- > div\"\n}", + "onTarget": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "126": { + "uiConfigId": "player_step_ui_config_126", + "uiType": "popover", + "uiConfig": "{\n \"element\": \"#DATASHEET_ORG_CHART_RECORD_LIST\",\n\"placement\": \"left\",\n \"title\": \"创建卡片\", \n\"description\": \"选择一条记录,拖动至左侧图形区\",\n\"offsetY\": 144\n}" + }, + "127": { + "uiConfigId": "player_step_ui_config_127", + "uiType": "breath", + "uiConfig": "{\n \"element\": \"#DATASHEET_ORG_CHART_RECORD_LIST\"\n}" + }, + "128": { + "uiConfigId": "player_step_ui_config_128", + "uiType": "breath", + "uiConfig": "{\n\"element\": \".react-flow__node\"\n}", + "onTarget": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "129": { + "uiConfigId": "player_step_ui_config_129", + "uiType": "popover", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "uiConfig": "{\n \"element\": \".react-flow__node\",\n\"placement\": \"bottom\",\n \"title\": \"建立卡片关系\", \n\"description\": \"再选择一条记录并拖动至卡片中,建立记录的层级关系\", \n\"children\": \"\"\n}" + }, + "131": { + "uiConfigId": "player_step_ui_config_131", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "查看更多", + "nextId": "see_more", + "uiConfig": "{\n\"headerImg\":\"https://s1.vika.cn/space/2022/03/17/f85104a4c8c145acb83379e13cfea0dd?attname=Update_cover%402x%202.png\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/151\",\n \"children\": \"

🚀 本次更新内容

  • 小程序新品上架,支持 Excel 追加导入数据和网址字段快速预览
  • 架构视图新增横向布局,竖向和横向布局自由选择
  • 小程序 SDK 更新,支持创建/删除字段
  • 维格表安卓客户端上线,支持安卓系统手机安装使用
\"\n}", + "onClose": [ + "set_wizard_completed({\"curWizard\": true})", + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "132": { + "uiConfigId": "player_step_ui_config_132", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "查看更多", + "nextId": "see_more", + "uiConfig": "{\n\"headerImg\":\"https://s1.vika.cn/space/2022/03/31/bb9cf7f3453e457c9473def81b081080?attname=%E4%BB%BB%E5%8A%A1%E5%88%B0%E6%9C%9F%E6%8F%90%E9%86%92.png\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/153\",\n \"children\": \"

🚀 本次更新内容

\\n
    \\n
  • 在日期单元格里轻轻一点,即可开启到期提醒
  • \\n
  • 维格视图支持冻结多列
  • \\n
  • 镜像支持导出 Excel 文件
  • \\n
  • 新增 API 接口,可创建新的维格表
  • \\n
  • 开发者自建小程序可申请上架「官方推荐」
  • \\n
\"\n}", + "onClose": [ + "set_wizard_completed({\"curWizard\": true})", + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "133": { + "uiConfigId": "player_step_ui_config_133", + "uiType": "breath", + "uiConfig": "{\n\"element\": \".style_name__29FFH\",\n\"color\": \"orange\"\n}", + "onTarget": [ + "set_wizard_completed({\"curWizard\": true})", + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "134": { + "uiConfigId": "player_step_ui_config_134", + "uiType": "breath", + "uiConfig": "{\n\"element\": \".style_editNameButton__34aL4\"\n}" + }, + "135": { + "uiConfigId": "player_step_ui_config_135", + "uiType": "popover", + "uiConfig": "{\n\"element\": \".style_topRight__2hxKm\",\n\"title\": \"设置昵称\",\n\"description\": \"希望大家怎么称呼你呢?\",\n\"placement\": \"topCenter\",\n\"posInfo\": {\n\"bottom\": \"420px\",\n\"left\": \"100px\",\n\"right\": \"\",\n\"tipNodeClasses\": [\"bottom\", \"position-center\"]\n}\n}" + }, + "136": { + "uiConfigId": "player_step_ui_config_136", + "uiType": "afterSignNPS", + "uiConfig": "{}" + }, + "137": { + "uiConfigId": "player_step_ui_config_137", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "查看更多", + "nextId": "see_more", + "uiConfig": "{\n\"headerImg\":\"https://s1.vika.cn/space/2022/04/15/5769ab6bf20943fc8119f74f498a7cfe?attname=%E8%A1%8C%E6%95%B0%E6%8D%AE%E6%94%AF%E6%8C%81%E5%85%B3%E6%B3%A8%E6%8F%90%E9%86%92.png\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/156\",\n \"children\": \"

🚀 本次更新内容

\\n
    \\n
  • 主动关注行数据,发生变化时立即提醒
  • \\n
  • 小程序支持全屏显示,还可以URL分享同事好友
  • \\n
  • 新增两个 API 接口,创建字段和删除字段
  • \\n
  • 若干模板更新升级,支持更多新功能特性
  • \\n
  • 福利来了,完成空间站认证送免费附件容量
\"\n}", + "onClose": [ + "set_wizard_completed({\"curWizard\": true})", + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "138": { + "uiConfigId": "player_step_ui_config_138", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "查看更多", + "nextId": "see_more", + "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2022/04/27/6a2167ddd8074078a6b13f04fa6a3f1c?attname=v0.12.7Update_cover%402x.png\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/158\",\n \"children\": \"

🚀 本次更新内容

\\n
    \\n
  • 甘特图支持设置工作日,日期和星期可同时显示
  • \\n
  • 转化分析好帮手,漏斗图小程序上架
  • \\n
  • 统计栏数据支持复制,右键即可获取数据
  • \\n
  • 优化新增行的操作体验,防止误增空白行
  • \\n
  • 日期字段支持指定接收提醒的成员或小组
  • \\n
  • 维格表已上架苹果App Store 和各大安卓应用商店
  • \\n
\"\n}", + "onClose": [ + "set_wizard_completed({\"curWizard\": true})", + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "139": { + "uiConfigId": "player_step_ui_config_139", + "uiType": "breath", + "uiConfig": "{\n\"element\": \"#toolHideField\"\n}" + }, + "140": { + "uiConfigId": "player_step_ui_config_140", + "uiType": "popover", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"element\": \"#toolHideField\",\n\"placement\": \"bottom\",\n \"title\": \"隐藏列\", \n\"description\": \"点击即可自定义左侧列表区的显示字段\", \n\"children\": \"\"\n}", + "onTarget": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "141": { + "uiConfigId": "player_step_ui_config_141", + "uiType": "breath", + "uiConfig": "{\n\"element\": \"#toolHideExclusiveField\"\n}" + }, + "143": { + "uiConfigId": "player_step_ui_config_143", + "uiType": "popover", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"element\": \"#toolHideExclusiveField\",\n\"placement\": \"bottom\",\n \"title\": \"隐藏图示\", \n\"description\": \"点击即可自定义右侧图形区任务条上的显示字段\", \n\"children\": \"\"\n}", + "onTarget": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "144": { + "uiConfigId": "player_step_ui_config_144", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "查看详情", + "nextId": "check_detail", + "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2022/05/12/988aad1e382d49f88119873473c2ffe9\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/180\",\n \"children\": \"

🚀 本次更新内容

\\n
    \\n
  • 腾讯云HiFlow场景连接器,办公自动化流程小程序上线
  • \\n
  • 甘特图自定义显示字段数量,任务条更清爽
  • 神奇表单支持修改配置信息,提升表单编辑效率
  • 镜像功能再升级,镜像也可以对外分享
\"\n}", + "onClose": [ + "set_wizard_completed({\"curWizard\": true})", + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "145": { + "uiConfigId": "player_step_ui_config_145", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "查看详情", + "nextId": "check_detail", + "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2022/05/26/620822443f6244c4ba665bcc8e056135\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/185\",\n \"children\": \"

🚀 本次更新内容

\\n
    \\n
  • 暗黑模式正式上线,给你全新的视觉体验
  • \\n
  • 看板视图支持隐藏分组,分组信息显示更自由
  • 维格列名称支持换行,名称再长也能显示
  • 安全设置升级,可按权限角色限制导出文件
  • 空间站成员管理,支持筛选已加入和未加入的成员
  • 若干模板上新,覆盖更多行业场景
\"\n}", + "onClose": [ + "set_wizard_completed({\"curWizard\": true})", + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "152": { + "uiConfigId": "player_step_ui_config_152", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "查看详情", + "nextId": "check_detail", + "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2022/06/13/0cea3e8831a94518b2c9e546b1ccbb8e\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/194\",\n \"children\": \"

🚀 本次更新内容

\\n
    \\n
  • 甘特视图、维格视图导出功能升级,可生成图片
  • \\n
  • 安全设置权限升级,可设置显示成员和小组的范围
  • 日历视图交互优化,年份月份切换更便捷
  • 安全设置升级,可按权限角色限制导出文件
  • 7个模板上新,覆盖更多行业场景
\"\n}", + "onClose": [ + "set_wizard_completed({\"curWizard\": true})", + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "153": { + "uiConfigId": "player_step_ui_config_153", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "查看详情", + "nextId": "check_detail", + "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2022/06/23/6aa909506bba4e30aa9f3c57c9d07364\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/200\",\n \"children\": \"

🚀 本次更新内容

\\n
  • 空间站操作日志上线,成员操作明细一个不漏
  • 移动端管理功能升级,支持空间站的增删改查
  • 电商节拼单攻略等7个模板上架,覆盖更多使用场景
\"\n}", + "onClose": [ + "set_wizard_completed({\"curWizard\": true})", + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "154": { + "uiConfigId": "player_step_ui_config_154", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "查看详情", + "nextId": "check_detail", + "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2022/07/23/ad9d1b758e7f46e6839b0e6791a8fb31\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/209\",\n \"children\": \"

🚀 本次更新内容

\\n
  • 网址字段升级,可自动获取网页标题
  • 「隐藏列」列名称支持点击快速在表格里高亮定位
  • 管理员可禁止成员在根目录下创建文件
  • 手机端支持查看和使用表格里的小程序
  • 「坐标地图」、「Airtable 导入」两款小程序上架
\"\n}", + "onClose": [ + "set_wizard_completed({\"curWizard\": true})", + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "155": { + "uiConfigId": "player_step_ui_config_155", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "查看详情", + "nextId": "check_detail", + "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2022/08/04/0712f98ea50943f08e2213a3f1ebe601\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/220\",\n \"children\": \"

🚀 本次更新内容

\\n
  • 新增「只可更新」权限,协作更精细化
  • 记录卡片新增“侧边栏”和“全屏”两种布局
  • 记录卡片支持修改列配置,操作更轻便
  • 12个模板上新,覆盖更多行业和使用场景
  • API 面板新增调试入口
\"\n}", + "onClose": [ + "set_wizard_completed({\"curWizard\": true})", + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "156": { + "uiConfigId": "player_step_ui_config_156", + "uiType": "popover", + "onNext": [ + "clear_guide_all_ui()" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"element\": \".permission_setting_class\",\n \"placement\": \"leftCenter\",\n \"title\": \"默认权限\",\n \"description\": \"未指定权限时会显示默认的权限角色,你可以在这里直接给成员或小组指定权限\",\n \"children\":\"\" \n }" + }, + "157": { + "uiConfigId": "player_step_ui_config_157", + "uiType": "popover", + "onNext": [ + "clear_guide_all_ui()" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"element\": \"#resetPermissionButton\",\n \"placement\": \"topCenter\",\n \"title\": \"权限已限制\",\n \"offsetY\": -15,\n \"description\": \"因为已经设置过权限,所以仅下方列表中的成员对此可见。你可以点击这里,恢复到默认权限。\",\n \"children\":\"\" \n}" + }, + "158": { + "uiConfigId": "player_step_ui_config_158", + "uiType": "popover", + "onNext": [ + "clear_guide_all_ui()" + ], + "next": "好的", + "nextId": "okay", + "uiConfig": "{\n \"element\": \"#resetPermissionButton\",\n \"placement\": \"topCenter\",\n \"title\": \"指定权限角色\",\n \"offsetY\": -15,\n \"description\": \"你已经重新修改了该文件的权限角色,这意味着该文件仅你指定的成员可见。你可以点击“恢复默认”,撤销刚才的设置。\",\n \"children\":\"\" \n}" + }, + "159": { + "uiConfigId": "player_step_ui_config_159", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "查看详情", + "nextId": "check_detail", + "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2022/08/19/bca3cedf0783402b953e02b83463e8f4\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/227\",\n \"children\": \"

🚀 本次更新内容

\\n
  • 日历视图支持筛选后新增记录
  • 工作目录可根据右侧面板状态自动回弹
  • 新能源车配件管理和食材配送等7 个模板上新
\"\n}", + "onClose": [ + "set_wizard_completed({\"curWizard\": true})", + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "160": { + "uiConfigId": "player_step_ui_config_160", + "uiType": "breath", + "uiConfig": "{\n \"element\": \".permission_setting_class\"\n }" + }, + "161": { + "uiConfigId": "player_step_ui_config_161", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "查看详情", + "nextId": "check_detail", + "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2022/09/02/3ec8ee88a8c64ee2875cc24e3650a0b3\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/242\",\n \"children\": \"

🚀 本次更新内容

\\n
  • 甘特图新增任务依赖和自动编排功能
  • 简化权限设置界面,提升操作体验
  • 右键菜单可批量插入新行,助力效率提升
  • 模板中心新增中秋专题、开学季两大板块
  • 邀请好友注册并加入空间站,可获赠更多附件容量
\"\n}", + "onClose": [ + "set_wizard_completed({\"curWizard\": true})", + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "162": { + "uiConfigId": "player_step_ui_config_162", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "查看详情", + "nextId": "check_detail", + "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2022/09/15/6eab2470b79a4ab1a6ced0fd555342a3?attname=Update_cover%402x.png\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/244\",\n \"children\": \"

🚀 本次更新内容

\\n
  • 「只可更新」权限范围调整,协作者也能新增记录
  • 空间站「安全设置」结束免费体验,正式按空间站等级提供服务
  • 5 个模板上新,覆盖财务预算、翻译项目、汽车零部件管理等场景
\"\n}", + "onClose": [ + "set_wizard_completed({\"curWizard\": true})", + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "163": { + "uiConfigId": "player_step_ui_config_163", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "查看详情", + "nextId": "check_detail", + "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2022/09/30/74b29d31dbc44eb48949acd6dff3bd65?attname=Update_cover%402x%203.png\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/246\",\n \"children\": \"

🚀 本次更新内容

\\n
  • 新增「角色」功能,权限分配与任务指派更灵活
  • 「成员」选择框增加悬浮式信息卡片
  • 右键菜单新增「移动至」选项,文件分类归纳更快捷
  • 模板中心新增假期旅游攻略、自卷指南和复盘规划三大专题
\"\n}", + "onClose": [ + "set_wizard_completed({\"curWizard\": true})", + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "164": { + "uiConfigId": "player_step_ui_config_164", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "查看详情", + "nextId": "check_detail", + "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2022/10/20/1dc32d8aa47b4863a97ea84ce11ecc60?attname=Update_cover%402x.png\",\n \"readMoreUrl\": \"https://bbs.vika.cn/article/252\",\n \"children\": \"

🚀 本次更新内容

\\n
  • 模板中心新增「专题」板块,更多元化的模板介绍
  • 全新帮助中心上线,提供更丰富的内容
  • 部分功能结束免费体验,正式按空间站等级提供服务
\"\n}", + "onClose": [ + "set_wizard_completed({\"curWizard\": true})", + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "166": { + "skipId": "maybe_later", + "uiConfigId": "player_step_ui_config_166", + "uiType": "billingStrip", + "backdrop": "around_mask", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "获取特殊优惠", + "nextId": "claim_special_offer", + "uiConfig": "{\n \"title\": \"恭喜你!获得试用权益\",\n \"description\": \"你获得了14天Enterprise版本的试用权益,你可以点击按钮查看详情\",\n \"listHeader\": \"试用权益:\",\n \"listContent\": [\n \"空间站记录总数上限提高至 500,000,000 行\",\n \"空间站附件容量数提高至 50 GB\",\n \"支持调用所有高级 API\"\n ],\n \"listFooter\": \"更多权益\",\n \"url\": \"https://apitable.com/management/upgrade\n}", + "onClose": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "167": { + "uiConfigId": "player_step_ui_config_167", + "uiType": "questionnaire", + "backdrop": "around_mask", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "确定", + "nextId": "confirm", + "uiConfig": "{\n \"config\": [\n {\n \"key\": 1,\n \"name\": \"answer1\",\n \"title\": \"您希望通过 APITable 解决哪些问题?\",\n \"type\": \"multiButton\",\n \"answers\": [\n \"IT 运维支持\",\n \"教育\",\n \"项目管理\",\n \"市场营销\",\n \"产品管理\",\n \"招聘管理\",\n \"运营\",\n \"金融财务\",\n \"销售 & 客户管理\",\n \"软件开发\",\n \"人力资源 & 合规\",\n \"设计 & 创意\",\n \"非盈利组织\",\n \"制造业\",\n \"其他\"\n ],\n \"lastAllowInput\": false\n },\n {\n \"key\": 2,\n \"name\": \"answer2\",\n \"title\": \"您的工作岗位是?\",\n \"type\": \"radio\",\n \"answers\": [\n \"企业主\",\n \"团队负责人\",\n \"团队成员\",\n \"自由职业者\",\n \"主管\",\n \"高管层\",\n \"副总裁\"\n ],\n \"lastAllowInput\": false\n },\n {\n \"key\": 3,\n \"name\": \"answer3\",\n \"title\": \"您的团队规模是?\",\n \"type\": \"radio\",\n \"answers\": [\n \"只有我\",\n \"2-5\",\n \"6-10\",\n \"11-15\",\n \"16-25\",\n \"25-50\",\n \"51-100\",\n \"101-500\"\n ],\n \"lastAllowInput\": false\n },\n {\n \"key\": 4,\n \"name\": \"answer4\",\n \"title\": \"您的公司规模是?\",\n \"type\": \"radio\",\n \"answers\": [\n \"1-19\",\n \"20-49\",\n \"50-99\",\n \"100-250\",\n \"251-500\",\n \"501-1500\",\n \"1500+\"\n ],\n \"lastAllowInput\": false\n },\n {\n \"key\": 5,\n \"name\": \"answer5\",\n \"title\": \"您从哪种途径了解到我们?\",\n \"type\": \"checkbox\",\n \"answers\": [\n \"搜索引擎\",\n \"YouTube\",\n \"Product Hunt\",\n \"Github\",\n \"推特\",\n \"领英\",\n \"朋友推荐\"\n ],\n \"lastAllowInput\": false\n },\n {\n \"key\": 6,\n \"name\": \"answer6\",\n \"title\": \"加入我们的Discord社区,和全世界 APITable 的使用者一起讨论使用心得吧!在使用过程中如果遇到任何问题,可以随时在社区获得解答和帮助。\",\n \"type\": \"joinUs\",\n \"url\": \"https://discord.gg/2UXAbDTJTX\",\n \"confirmText\": \"加入社区\",\n \"skipText\": \"跳过\",\n \"submit\": true\n }\n ]\n}", + "onClose": [ + "open_guide_next_step({\"clearAllPrevUi\":true})", + "open_guide_wizard(18)" + ] + }, + "168": { + "uiConfigId": "player_step_ui_config_168", + "uiType": "customTemplate", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "我知道了", + "nextId": "i_knew_it", + "byEvent": [ + "datasheet_create_mirror_tip" + ], + "uiConfig": "{\n\"templateKey\":\"createMirrorTip\"\n}" + }, + "169": { + "uiConfigId": "player_step_ui_config_165", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "查看详情", + "nextId": "check_detail", + "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2023/03/16/8374ca1295664675bd1155b077555113\",\n \"readMoreUrl\": \"https://help.vika.cn/changelog/23-03-16-updates\",\n \"children\": \"

🚀 新功能介绍

\\n
  • 镜像功能再次升级,可禁止查看已隐藏的字段
  • 个人设置追加时区信息,日期字段可指定时区
  • 「全局搜索」优化,新增搜索结果分类
  • 神奇表单支持隐藏官方标识
  • API 性能优化,大幅提高请求速度
\"\n}", + "onClose": [ + "set_wizard_completed({\"curWizard\": true})", + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "170": { + "uiConfigId": "player_step_ui_config_169", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "查看详情", + "nextId": "check_detail", + "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2023/04/04/bcf0695cf35840e6b85e032a8e5ea0a1\",\n \"readMoreUrl\": \"https://help.vika.cn/changelog/23-04-10-updates\",\n \"children\": \"

🚀 新功能介绍

\\n
  • 推出新字段类型「多级联动」,神奇表单支持多级选项
  • 脚本小程序上架,少少代码满足多多定制化
  • 维格表机器人支持「发送邮件」
  • 维格表机器人支持「发送到Slack」
  • 维格表的AI探索,「GPT 内容生成」小程序发布
\"\n}", + "onClose": [ + "set_wizard_completed({\"curWizard\": true})", + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "171": { + "uiConfigId": "player_step_ui_config_171", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "查看详情", + "nextId": "check_detail", + "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2023/05/11/eb7778e708ac421294ed3b137e8a50c2\",\n \"readMoreUrl\": \"https://help.vika.cn/changelog/23-05-11-updates\",\n \"children\": \"

🚀 新功能介绍

\\n
  • 优化用户体验,采用标签页切换工作目录与星标区域
  • 小程序支持数据筛选,数据分析更高效灵活
\"\n}", + "onClose": [ + "set_wizard_completed({\"curWizard\": true})", + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "172": { + "uiConfigId": "player_step_ui_config_172", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "查看详情", + "nextId": "check_detail", + "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2023/06/19/41e7087220764e86bd0020da33b00e23\",\n \"readMoreUrl\": \"https://help.vika.cn/changelog/23-06-15-updates\",\n \"children\": \"

🚀 新功能介绍

\\n
  • 自动关注被分配的任务动态,重点信息一个不落
  • 「批量图片生成器」小程序上架,三分钟出图上百张
  • 网址字段支持自定义网址标题,阅读体验更加清晰
  • 神奇引用字段升级!支持调整引用数据的排序和数量
  • 开放通讯录相关APIs,支持更多的企业自动化场景
  • API调用频率调整,黄金级以上可获得更高的并发数
\"\n}", + "onClose": [ + "set_wizard_completed({\"curWizard\": true})", + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "173": { + "uiConfigId": "player_step_ui_config_173", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "查看详情", + "nextId": "check_detail", + "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2023/07/25/1d5c36599371436f831c758daedfd4ee\",\n \"readMoreUrl\": \"https://help.vika.cn/changelog/23-07-20-updates\",\n \"children\": \"

🚀 新功能介绍

\\n
  • 表格支持创建和回溯版本历史,数据随时安全备份
  • 分享文件的窗口优化,操作更加简洁清晰
  • 视图协作的交互更新,减少多人协作冲突
\"\n}", + "onClose": [ + "set_wizard_completed({\"curWizard\": true})", + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "174": { + "uiConfigId": "player_step_ui_config_174", + "uiType": "customTemplate", + "byEvent": [ + "ai_create_ai_node" + ], + "uiConfig": "{\n\"\"templateKey\"\":\"\"createAiNode\"\"\n}" + }, + "175": { + "uiConfigId": "player_step_ui_config_175", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "查看详情", + "nextId": "check_detail", + "uiConfig": "{\n \"headerImg\": \"https://s4.vika.cn/space/2023/08/24/29de666c68b148f4a6f08bde7a450ec8\",\n \"readMoreUrl\": \"https://u.vika.cn/hsx6z\",\n \"children\": \"

🚀 内测邀请:将表格数据一键训练你专属的 AI 聊天机器人

\\n

大家好,维格云的下一个AI功能来了!
想要利用维格表里的数据,训练出私有专属的AI助理吗?
快点击下方按钮,提交申请吧!
真诚期待你的体验反馈✨

\"\n}", + "onClose": [ + "set_wizard_completed({\"curWizard\": true})", + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "176": { + "uiConfigId": "player_step_ui_config_176", + "uiType": "modal", + "onPlay": [ + "set_wizard_completed({\"wizardId\": 115})" + ], + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "uiConfig": "{\n\"title\":\"AI 功能介绍\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\n\"autoPlay\":true\n}\n", + "onClose": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "177": { + "uiConfigId": "player_step_ui_config_automation_1", + "uiType": "breath", + "backdrop": "around_mask", + "onNext": [ + "clear_guide_all_ui()" + ], + "onSkip": [ + "skip_current_wizard()" + ], + "uiConfig": "{\n \"element\": \"#AUTOMATION_ADD_TRIGGER_BTN\"\n} \n", + "onTarget": [ + "clear_guide_all_ui()" + ] + }, + "178": { + "uiConfigId": "player_step_ui_config_177", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "查看详情", + "nextId": "check_detail", + "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2023/11/14/d5e1c09b021d4434a93709fbe3200140\",\n \"readMoreUrl\": \"https://u.vika.cn/wed5h\",\n \"children\": \"

🚀 利用vika实现Al转型和工作自动化

\\n

大家好,我们将于周三上午11点举行一场特别的线上研讨会
你想了解如何利用vika维格云的多维表格能力吗?
快点击下方按钮,进行预约吧!

\"\n}", + "onClose": [ + "set_wizard_completed({\"curWizard\": true})", + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "179": { + "uiConfigId": "player_step_ui_config_178", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "查看详情", + "nextId": "check_detail", + "uiConfig": "{\n \"headerImg\": \"https://s4.vika.cn/space/2023/08/24/29de666c68b148f4a6f08bde7a450ec8\",\n \"readMoreUrl\": \"https://u.vika.cn/hsx6z\",\n \"children\": \"

🚀 内测邀请:将表格数据一键训练你专属的 AI 聊天机器人

\\n

大家好,维格云的下一个AI功能来了!
想要利用维格表里的数据,训练出私有专属的AI助理吗?
快点击下方按钮,提交申请吧!
真诚期待你的体验反馈✨

\"\n}", + "onClose": [ + "set_wizard_completed({\"curWizard\": true})", + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "192": { + "uiConfigId": "player_step_ui_config_192", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "查看详情", + "nextId": "check_detail", + "uiConfig": "{\n \"headerImg\": \"https://help.vika.cn/assets/images/update_cover@4x-dc5caa13339ad2deaea06e1db4aae0ac.png\",\n \"readMoreUrl\": \"https://help.vika.cn/changelog/23-12-01-updates\",\n \"children\": \"

🚀 本次更新内容

\\n
    \\n
  • 基于全新数据引擎的 Fusion API v3 内测启动,搭载全新数据引擎,期待您的加入
  • \\n
  • 全新「按钮」维格列上线:一键操作,简化工作流程,提升效率
  • \\n
  • 新功能「轻文档」维格列上线:一站式解决文档管理与业务管理
  • \\n
\"\n}", + "onClose": [ + "set_wizard_completed({\"curWizard\": true})", + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "196": { + "uiConfigId": "player_step_ui_config_196·", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "查看详情", + "nextId": "check_detail", + "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2023/12/28/36139bb2556a4c68b267dd5c29739087\",\n \"readMoreUrl\": \"https://meeting.tencent.com/dw/2XYzYvyVHtqH\",\n \"children\": \"

🚀 实现定时触发的自动化支持,无需担心工作提醒问题

\\n

你可以根据小时、天、周或月份设定周期性任务,满足时间条件后自动启动,例如发送邮件、提醒或调用业务接口,轻松实现。

\\n

重要通知:周三上午11点,将举办新用户产品培训会。培训旨在帮助新用户了解和使用vika维格云。如果你是新用户,请点击链接报名参加。

\"\n}", + "onClose": [ + "set_wizard_completed({\"curWizard\": true})", + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "198": { + "uiConfigId": "player_step_ui_config_97", + "uiType": "contactUs", + "onNext": [ + "clear_guide_all_ui()", + "set_wizard_completed({\"curWizard\": true})", + "open_vikaby({\"defaultExpandMenu\": true, \"visible\": true})" + ], + "next": "已完成添加", + "nextId": "player_contact_us_confirm_btn", + "uiConfig": "{\n\t\"vikaby\": {\n\t\t\"title\": \"你好\",\n\t\t\"description\": \"如果在使用过程中遇到问题,请扫描右侧二维码联系我解决\",\n\t\t\"list\": \"
  • 刚注册维格表,不知道怎么用
  • 维格表可以实现我想要的效果吗
  • 使用过程出现异常问题
  • 后续支持的功能有哪些
  • 获取官方邀请码
\",\n\t\t\"tip\": \"扫码添加客服\"\n\t},\n\t\"questionnaire\": {\n\t\t\"title\": \"您好,我是维格表数字化顾问\",\n\t\t\"list\": \"[{\\\"title\\\": \\\"Bug 吐槽\\\", \\\"icon\\\": \\\"BugOutlined\\\"}, {\\\"title\\\": \\\"需求反馈\\\", \\\"icon\\\": \\\"AdviseSmallOutlined\\\"}, {\\\"title\\\": \\\"服务支持\\\", \\\"icon\\\": \\\"ServeOutlined\\\"}, {\\\"title\\\": \\\"案例推荐\\\", \\\"icon\\\": \\\"ZanOutlined\\\"}, {\\\"title\\\": \\\"解决方案\\\", \\\"icon\\\": \\\"SolutionSmallOutlined\\\"}, {\\\"title\\\": \\\"产品答疑\\\", \\\"icon\\\": \\\"InformationLargeOutlined\\\"}]\",\n\t\t\"tip\": \"扫码添加微信,获得更多专属服务\"\n\t},\n\t\"website\": {\n\t\t\"questionnaire\": \"https://s1.vika.cn/space/2023/03/02/59f4cc8e0b2b4395bf0fcd133d208e63\",\n\t\t\"vikaby\": \"https://s1.vika.cn/space/2023/03/02/defbf55d1e9646eb929f9f5d11d5c119\"\n\t},\n\t\"dingtalk\": {\n\t\t\"questionnaire\": \"https://s1.vika.cn/space/2023/04/27/2c617a16afd9408ba48392e337fbbd7f?attname=20230427_dingtalk_questionnaire.png\",\n\t\t\"vikaby\": \"https://s1.vika.cn/space/2023/04/27/2c617a16afd9408ba48392e337fbbd7f?attname=20230427_dingtalk_vikaby.png\",\n\"tip\": \"请使用钉钉扫码,加入交流群\"\n\t},\n\t\"wecom\": {\n\t\t\"questionnaire\": \"https://s1.vika.cn/space/2023/03/02/1346d5efbd5043efb2bfcba0075c0ee9\",\n\t\t\"vikaby\": \"https://s1.vika.cn/space/2023/03/02/09401a8f2d8e491a9097b9bac8b5a4e4\"\n\t},\n\t\"feishu\": {\n\t\t\"title\": \"扫码添加客服\",\n\t\t\"tip\": \"请使用飞书扫码,添加客服号备用\",\n\t\t\"description\": \"以便使用过程中遇到问题,可以随时获得服务和解答\",\n\t\t\"originUrl\": \"https://u.vika.cn/z9ygm\"\n\t}\n}", + "onClose": [ + "set_wizard_completed({\"curWizard\": true})", + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + }, + "199": { + "uiConfigId": "player_step_ui_config_199·", + "uiType": "notice", + "onNext": [ + "open_guide_next_step({\"clearAllPrevUi\":true})" + ], + "next": "查看详情", + "nextId": "check_detail", + "uiConfig": "{\n \"headerImg\": \"https://s1.vika.cn/space/2024/01/24/3aa9d045e1504ab7a4f0d1ebb01af1c6\",\n \"readMoreUrl\": \"https://help.vika.cn/changelog/24-01-25-updates\",\n \"children\": \"

🚀 本次更新内容

  • 归档记录功能升级:归档记录后,保留双向关联关系
  • 自定义页面上线,一站式管理所有网页资源
  • 轻文档功能升级:图片组件完善、支持上传视频、导出文件到本地
\"\n}", + "onClose": [ + "set_wizard_completed({\"curWizard\": true})", + "open_guide_next_step({\"clearAllPrevUi\":true})" + ] + } } - ], - "test_function": { - "async_compute": { - "card": { - "btn_close_action": "/", - "btn_open_action": "/", - "btn_text": "test_function_btncard_btntext_open", - "btn_type": "primary", - "info": "test_function_card_info_async_compute", - "info的副本": "test_function_card_info_async_compute" + }, + "notifications": { + "types": { + "member": { + "format_string": "notify_type_member", + "tag": "member" + }, + "record": { + "format_string": "notify_type_datasheet", + "tag": "record" + }, + "space": { + "format_string": "notify_type_space", + "tag": "space" + }, + "system": { + "format_string": "notify_type_system", + "tag": "system" + } + }, + "templates": { + "activity_integral_income_notify": { + "to_tag": "users", + "notifications_type": "system", + "is_notification": true, + "format_string": "activity_integral_income_notify", + "notification_type": "事务型消息(transactional notify)", + "is_component": true + }, + "activity_integral_income_toadmin": { + "to_tag": "space_main_admin", + "notifications_type": "system", + "is_notification": true, + "format_string": "activity_integral_income_toadmin", + "notification_type": "事务型消息(transactional notify)", + "is_component": true + }, + "add_record_out_of_limit": { + "can_jump": true, + "to_tag": "users", + "notifications_type": "system", + "is_notification": true, + "is_mail": true, + "mail_template_subject": "addRecordReachedLimited", + "format_string": "add_record_out_of_limit_by_api_notify", + "url": "/workbench", + "frequency": 1, + "is_component": true + }, + "add_record_soon_to_be_limit": { + "can_jump": true, + "to_tag": "users", + "notifications_type": "system", + "is_notification": true, + "is_mail": true, + "mail_template_subject": "addRecordReachingLimited", + "format_string": "add_record_soon_to_be_limit_by_api_notify", + "url": "/workbench", + "frequency": 1, + "is_component": true + }, + "add_sub_admin": { + "can_jump": true, + "to_tag": "members", + "notifications_type": "member", + "is_notification": true, + "is_mobile": true, + "is_mail": true, + "is_browser": true, + "mail_template_subject": "addSubAdmin", + "format_string": "space_add_sub_admin", + "notification_type": "事务型消息(transactional notify)", + "url": "/management", + "is_component": true + }, + "admin_transfer_space_widget_notify": { + "to_tag": "users", + "notifications_type": "system", + "is_notification": true, + "is_mail": true, + "is_browser": true, + "format_string": "admin_transfer_space_widget_notify", + "is_component": true + }, + "admin_unpublish_space_widget_notify": { + "to_tag": "users", + "notifications_type": "system", + "is_notification": true, + "is_mail": true, + "is_browser": true, + "format_string": "admin_unpublish_space_widget_notify", + "is_component": true + }, + "apply_space_beta_feature_success_notify_all": { + "can_jump": true, + "to_tag": "all_members", + "notifications_type": "space", + "is_notification": true, + "format_string": "apply_space_beta_feature_success_notify_all", + "notification_type": "事务型消息(transactional notify)" + }, + "apply_space_beta_feature_success_notify_me": { + "can_jump": true, + "to_tag": "myself", + "notifications_type": "space", + "is_notification": true, + "is_mail": true, + "mail_template_subject": "applySpaceBetaFeatureSuccess", + "format_string": "apply_space_beta_feature_success_notify_me", + "notification_type": "事务型消息(transactional notify)" + }, + "assigned_to_group": { + "can_jump": true, + "to_tag": "members", + "notifications_type": "member", + "is_notification": true, + "is_mobile": true, + "is_mail": true, + "is_browser": true, + "mail_template_subject": "assignedToGroup", + "format_string": "space_assigned_to_group", + "notification_type": "事务型消息(transactional notify)", + "url": "/management", + "is_component": true + }, + "assigned_to_role": { + "can_jump": true, + "to_tag": "members", + "notifications_type": "member", + "is_notification": true, + "is_mobile": true, + "is_mail": true, + "is_browser": true, + "format_string": "space_assigned_to_role", + "notification_type": "事务型消息(transactional notify)", + "url": "/management", + "is_component": true + }, + "auto_cancel_record_subscription": { + "can_jump": true, + "to_tag": "members", + "notifications_type": [], + "is_notification": true, + "is_browser": true, + "format_string": "auto_cancel_record_subscription", + "url": "/workbench" + }, + "auto_create_record_subscription": { + "can_jump": true, + "to_tag": "members", + "notifications_type": [], + "is_notification": true, + "is_browser": true, + "format_string": "auto_create_record_subscription", + "url": "/workbench" + }, + "automation-fail": {}, + "capacity_limit": { + "can_jump": true, + "to_tag": "space_admins", + "notifications_type": "space", + "is_notification": true, + "is_mail": true, + "is_browser": true, + "mail_template_subject": "subscribedCapacityLimit", + "billing_notify": "max_capacity_size_in_bytes", + "format_string": "capacity_limit", + "url": "/management", + "frequency": 1, + "is_component": true + }, + "changed_ordinary_user": { + "can_jump": true, + "to_tag": "members", + "notifications_type": "member", + "is_notification": true, + "is_mobile": true, + "is_mail": true, + "is_browser": true, + "format_string": "space_changed_ordinary_user", + "notification_type": "事务型消息(transactional notify)", + "is_component": true + }, + "comment_mentioned": { + "can_jump": true, + "to_tag": "members", + "notifications_type": [], + "is_notification": true, + "is_mobile": true, + "is_mail": true, + "is_browser": true, + "format_string": "comment_mentioned", + "url": "/workbench", + "is_component": true + }, + "common_system_notify": { + "to_tag": "users", + "notifications_type": "system", + "is_notification": true, + "is_browser": true, + "format_string": "common_system_notify", + "is_component": true + }, + "common_system_notify_web": { + "to_tag": "users", + "notifications_type": "system", + "format_string": "common_system_notify_web", + "is_component": true + }, + "datasheet_limit": { + "can_jump": true, + "to_tag": "space_admins", + "notifications_type": "space", + "is_notification": true, + "is_mail": true, + "is_browser": true, + "mail_template_subject": "subscribedDatasheetLimit", + "billing_notify": "max_sheet_nums", + "format_string": "datasheet_limit", + "url": "/management", + "frequency": 1, + "is_component": true + }, + "datasheet_record_limit": { + "can_jump": true, + "to_tag": "space_admins", + "notifications_type": "space", + "is_notification": true, + "is_mail": true, + "is_browser": true, + "mail_template_subject": "subscribedDatasheetRecordLimit", + "billing_notify": "max_rows_per_sheet", + "format_string": "datasheet_record_limit", + "url": "/management", + "frequency": 1, + "is_component": true + }, + "integral_income_notify": { + "to_tag": "users", + "notifications_type": "system", + "is_notification": true, + "format_string": "integral_income_notify", + "notification_type": "事务型消息(transactional notify)", + "is_component": true + }, + "invite_member_toadmin": { + "can_jump": true, + "to_tag": "space_member_admins", + "notifications_type": "member", + "is_notification": true, + "is_mobile": true, + "is_browser": true, + "format_string": "invite_member_toadmin", + "notification_type": "事务型消息(transactional notify)", + "url": "/management", + "is_component": true + }, + "invite_member_tomyself": { + "can_jump": true, + "to_tag": "myself", + "notifications_type": "member", + "is_notification": true, + "is_mobile": true, + "is_mail": true, + "is_browser": true, + "mail_template_subject": "acceptInvite", + "format_string": "invite_member_tomyself", + "notification_type": "事务型消息(transactional notify)", + "is_component": true + }, + "invite_member_touser": { + "can_jump": true, + "to_tag": "members", + "notifications_type": "member", + "is_notification": true, + "is_mobile": true, + "is_browser": true, + "format_string": "invite_member_touser", + "notification_type": "事务型消息(transactional notify)", + "url": "/workbench", + "is_component": true + }, + "member_applied_to_close_account": { + "to_tag": "space_member_admins", + "notifications_type": "member", + "is_notification": true, + "is_mail": true, + "is_browser": true, + "format_string": "member_applied_to_close_account", + "notification_type": "事务型消息(transactional notify)", + "is_component": true + }, + "new_space_widget_notify": { + "to_tag": "users", + "notifications_type": "system", + "is_notification": true, + "is_browser": true, + "format_string": "new_space_widget_notify", + "notification_type": "事务型消息(transactional notify)", + "is_component": true + }, + "new_user_welcome_notify": { + "can_jump": true, + "to_tag": "users", + "notifications_type": "system", + "is_notification": true, + "format_string": "new_user_welcome_notify", + "notification_type": "营销型消息(marketing notify)", + "is_component": true, + "redirect_url": "new_user_welcome_notify_url" + }, + "quit_space": { + "can_jump": true, + "to_tag": "space_member_admins", + "notifications_type": "member", + "is_notification": true, + "is_mobile": true, + "is_browser": true, + "format_string": "member_quit_space", + "notification_type": "事务型消息(transactional notify)", + "url": "/management", + "is_component": true + }, + "remove_from_group": { + "can_jump": true, + "to_tag": "members", + "notifications_type": "member", + "is_notification": true, + "is_mobile": true, + "is_mail": true, + "is_browser": true, + "format_string": "remove_from_group", + "notification_type": "事务型消息(transactional notify)", + "url": "/management", + "is_component": true + }, + "remove_from_role": { + "can_jump": true, + "to_tag": "members", + "notifications_type": "member", + "is_notification": true, + "is_mobile": true, + "is_mail": true, + "is_browser": true, + "mail_template_subject": "removeFromRole", + "format_string": "remove_from_role", + "notification_type": "事务型消息(transactional notify)", + "url": "/management", + "is_component": true + }, + "removed_from_space_toadmin": { + "can_jump": true, + "to_tag": "space_member_admins", + "notifications_type": "member", + "is_notification": true, + "is_mobile": true, + "is_browser": true, + "format_string": "user_removed_by_space_toadmin", + "notification_type": "事务型消息(transactional notify)", + "is_component": true + }, + "removed_from_space_touser": { + "to_tag": "members", + "notifications_type": "member", + "is_notification": true, + "is_mobile": true, + "is_mail": true, + "is_browser": true, + "format_string": "user_removed_by_space_touser", + "url": "/management", + "is_component": true + }, + "removed_member_tomyself": { + "can_jump": true, + "to_tag": "myself", + "notifications_type": "member", + "is_notification": true, + "is_mobile": true, + "is_browser": true, + "format_string": "removed_member_tomyself", + "notification_type": "事务型消息(transactional notify)", + "is_component": true + }, + "server_pre_publish": { + "to_tag": "all_users", + "notifications_type": "system", + "is_notification": true, + "is_mobile": true, + "is_browser": true, + "format_string": "server_pre_publish", + "is_component": true + }, + "single_record_comment_mentioned": { + "can_jump": true, + "to_tag": "members", + "notifications_type": [], + "is_notification": true, + "is_mobile": true, + "is_mail": true, + "is_browser": true, + "format_string": "single_record_comment_mentioned", + "url": "/workbench", + "is_component": true + }, + "single_record_member_mention": { + "can_jump": true, + "to_tag": "members", + "notifications_type": [], + "is_notification": true, + "is_mobile": true, + "is_mail": true, + "is_browser": true, + "mail_template_subject": "remindMember", + "format_string": "single_record_member_mention", + "url": "/workbench", + "is_component": true + }, + "space_add_primary_admin": { + "can_jump": true, + "to_tag": "members", + "notifications_type": "member", + "is_notification": true, + "is_mobile": true, + "is_mail": true, + "is_browser": true, + "format_string": "space_add_primary_admin", + "is_component": true + }, + "space_admin_limit": { + "can_jump": true, + "to_tag": "space_admins", + "notifications_type": "space", + "is_notification": true, + "is_mail": true, + "is_browser": true, + "mail_template_subject": "subscribedAdminLimit", + "billing_notify": "max_admin_nums", + "format_string": "space_admin_limit", + "url": "/management", + "frequency": 1, + "is_component": true + }, + "space_api_limit": { + "can_jump": true, + "to_tag": "space_admins", + "notifications_type": "space", + "is_notification": true, + "is_mail": true, + "is_browser": true, + "mail_template_subject": "subscribedApiLimit", + "billing_notify": "max_api_call", + "format_string": "space_api_limit", + "url": "/management", + "frequency": 1, + "is_component": true + }, + "space_calendar_limit": { + "can_jump": true, + "to_tag": "space_admins", + "notifications_type": "space", + "is_notification": true, + "is_mail": true, + "is_browser": true, + "mail_template_subject": "subscribedCalendarLimit", + "billing_notify": "max_calendar_views_in_space", + "format_string": "space_calendar_limit", + "url": "/management", + "frequency": 1, + "is_component": true + }, + "space_certification_fail_notify": { + "can_jump": true, + "to_tag": "users", + "notifications_type": "space", + "is_notification": true, + "is_mail": true, + "is_browser": true, + "format_string": "space_certification_fail_notify", + "notification_type": "事务型消息(transactional notify)", + "url": "/management", + "is_component": true + }, + "space_certification_notify": { + "can_jump": true, + "to_tag": "users", + "notifications_type": "space", + "is_notification": true, + "is_mail": true, + "is_browser": true, + "format_string": "space_certification_notify", + "notification_type": "事务型消息(transactional notify)", + "url": "/management", + "is_component": true + }, + "space_deleted": { + "to_tag": "all_members", + "notifications_type": "space", + "is_notification": true, + "is_browser": true, + "format_string": "space_has_been_deleted", + "notification_type": "事务型消息(transactional notify)", + "is_component": true + }, + "space_dingtalk_notify": { + "can_jump": true, + "to_tag": "space_admins", + "notifications_type": "space", + "is_notification": true, + "is_mail": true, + "is_browser": true, + "billing_notify": "integration_dingtalk", + "format_string": "space_dingtalk_notify", + "url": "/management", + "is_component": true + }, + "space_field_permission_limit": { + "can_jump": true, + "to_tag": "space_admins", + "notifications_type": "space", + "is_notification": true, + "is_mail": true, + "is_browser": true, + "mail_template_subject": "subscribedFieldPermissionLimit", + "billing_notify": "field_permission_nums", + "format_string": "space_field_permission_limit", + "url": "/management", + "frequency": 1, + "is_component": true + }, + "space_file_permission_limit": { + "can_jump": true, + "to_tag": "space_admins", + "notifications_type": "space", + "is_notification": true, + "is_mail": true, + "is_browser": true, + "mail_template_subject": "subscribedFilePermissionLimit", + "billing_notify": "file_permission_nums", + "format_string": "space_file_permission_limit", + "url": "/management", + "frequency": 1, + "is_component": true + }, + "space_form_limit": { + "can_jump": true, + "to_tag": "space_admins", + "notifications_type": "space", + "is_notification": true, + "is_mail": true, + "is_browser": true, + "mail_template_subject": "subscribedFormLimit", + "billing_notify": "max_form_views_in_space", + "format_string": "space_form_limit", + "url": "/management", + "frequency": 1, + "is_component": true + }, + "space_gantt_limit": { + "can_jump": true, + "to_tag": "space_admins", + "notifications_type": "space", + "is_notification": true, + "is_mail": true, + "is_browser": true, + "mail_template_subject": "SubscribedGanntLimit", + "billing_notify": "max_gantt_views_in_space", + "format_string": "space_gantt_limit", + "url": "/management", + "frequency": 1, + "is_component": true + }, + "space_join_apply": { + "to_tag": "space_member_admins", + "notifications_type": "member", + "is_notification": true, + "is_mail": true, + "format_string": "space_join_apply", + "is_component": true + }, + "space_join_apply_approved": { + "can_jump": true, + "to_tag": "users", + "notifications_type": "member", + "is_notification": true, + "is_mail": true, + "mail_template_subject": "spaceApplyApproved", + "format_string": "space_join_apply_approved", + "notification_type": "事务型消息(transactional notify)", + "url": "/workbench", + "is_component": true + }, + "space_join_apply_refused": { + "to_tag": "users", + "notifications_type": "member", + "is_notification": true, + "is_mail": true, + "format_string": "space_join_apply_refused", + "notification_type": "事务型消息(transactional notify)", + "is_component": true + }, + "space_lark_notify": { + "can_jump": true, + "to_tag": "space_admins", + "notifications_type": "space", + "is_notification": true, + "is_mail": true, + "is_browser": true, + "billing_notify": "integration_feishu", + "format_string": "space_lark_notify", + "url": "/management", + "is_component": true + }, + "space_members_limit": { + "can_jump": true, + "to_tag": "space_admins", + "notifications_type": "space", + "is_notification": true, + "is_mail": true, + "is_browser": true, + "format_string": "space_members_limit", + "url": "/management", + "is_component": true + }, + "space_mirror_limit": { + "can_jump": true, + "to_tag": "space_admins", + "notifications_type": "space", + "is_notification": true, + "is_mail": true, + "is_browser": true, + "mail_template_subject": "subscribedMirrorLimit", + "billing_notify": "max_mirror_views_in_space", + "format_string": "space_mirror_limit", + "url": "/management", + "frequency": 1, + "is_component": true + }, + "space_name_change": { + "can_jump": true, + "to_tag": "all_members", + "notifications_type": "space", + "is_notification": true, + "is_browser": true, + "format_string": "notification_space_name_changed", + "notification_type": "事务型消息(transactional notify)", + "url": "/workbench", + "is_component": true + }, + "space_paid_notify": { + "to_tag": "users", + "notifications_type": "space", + "is_notification": true, + "format_string": "space_paid_notify", + "notification_type": "事务型消息(transactional notify)", + "is_component": true + }, + "space_rainbow_label_limit": { + "can_jump": true, + "to_tag": "space_admins", + "notifications_type": "space", + "is_notification": true, + "is_mail": true, + "is_browser": true, + "mail_template_subject": "subject.subscribed.rainbow.label.limit", + "billing_notify": "rainbow_label", + "format_string": "space_rainbow_label_limit", + "url": "/management", + "frequency": 1, + "is_component": true + }, + "space_record_limit": { + "can_jump": true, + "to_tag": "space_admins", + "notifications_type": "space", + "is_notification": true, + "is_mail": true, + "is_browser": true, + "mail_template_subject": "subscribedRecordLimit", + "billing_notify": "max_rows_in_space", + "format_string": "space_record_limit", + "url": "/management", + "frequency": 1, + "is_component": true + }, + "space_recover": { + "can_jump": true, + "to_tag": "all_members", + "notifications_type": "space", + "is_notification": true, + "is_browser": true, + "format_string": "space_has_been_recover", + "notification_type": "事务型消息(transactional notify)", + "is_component": true + }, + "space_seats_limit": { + "can_jump": true, + "to_tag": "space_admins", + "notifications_type": "space", + "is_notification": true, + "is_mail": true, + "is_browser": true, + "mail_template_subject": "subscribedSeatsLimit", + "billing_notify": "max_seats", + "format_string": "space_seats_limit", + "url": "/management", + "frequency": 1, + "is_component": true + }, + "space_subscription_end_notify": { + "can_jump": true, + "to_tag": "space_admins", + "notifications_type": "space", + "is_notification": true, + "is_mail": true, + "is_browser": true, + "url": "/management", + "is_component": true + }, + "space_subscription_notify": { + "can_jump": true, + "to_tag": "space_admins", + "notifications_type": "space", + "is_notification": true, + "is_browser": true, + "format_string": "space_subscription_notify", + "notification_type": "事务型消息(transactional notify)", + "url": "/management", + "is_component": true + }, + "space_time_machine_limit": { + "can_jump": true, + "to_tag": "space_admins", + "notifications_type": "space", + "is_notification": true, + "is_mail": true, + "is_browser": true, + "mail_template_subject": "subject.subscribed.time.machine.limit", + "billing_notify": "max_remain_timemachine_days", + "format_string": "space_time_machine_limit", + "url": "/management", + "frequency": 1, + "is_component": true + }, + "space_trash_limit": { + "can_jump": true, + "to_tag": "space_admins", + "notifications_type": "space", + "is_notification": true, + "is_mail": true, + "is_browser": true, + "mail_template_subject": "subject.subscribed.trash.limit", + "billing_notify": "max_remain_trash_days", + "format_string": "space_trash_limit", + "url": "/management", + "frequency": 1, + "is_component": true + }, + "space_trial": { + "can_jump": true, + "to_tag": "space_admins", + "notifications_type": "space", + "is_notification": true, + "is_mail": true, + "is_browser": true, + "format_string": "space_trial", + "url": "/management", + "is_component": true }, - "feature_key": "async_compute", - "feature_name": "async_compute", - "id": "async_compute", - "logo": "space/2022/01/25/bef8c76826c540c8a14c7f10938a60f9", - "modal": { - "btn_action": "https://app.feishu.cn/app/cli_9f3930dd7d7ad00c", - "btn_text": "enable", - "btn_type": "primary", - "info": "test_function_modal_info_async_compute", - "info_image": "ASYNC_COMPUTE_INFO_IMAGE", - "info的副本": "test_function_card_info_async_compute" + "space_watermark_notify": { + "can_jump": true, + "to_tag": "space_admins", + "notifications_type": "space", + "is_notification": true, + "is_mail": true, + "is_browser": true, + "billing_notify": "watermark", + "format_string": "space_watermark_notify", + "url": "/management", + "is_component": true }, - "note": "test_function_note_async_compute" - }, - "render_normal": { - "card": { - "btn_close_action": "/", - "btn_open_action": "/", - "btn_text": "test_function_btncard_btntext_open", - "btn_type": "primary", - "info": "test_function_card_info_render_normal", - "info的副本": "test_function_card_info_render_normal" + "space_wecom_api_trial_end": { + "to_tag": "all_members", + "notifications_type": "space", + "is_notification": true, + "is_browser": true, + "format_string": "space_wecom_api_trial_end", + "notification_type": "通知型消息(notification notify)" }, - "feature_key": "render_normal", - "feature_name": "render_normal", - "id": "render_normal", - "logo": "space/2022/01/25/52f1fe2f1be34a2fb1227fc36d8861fc", - "modal": { - "btn_text": "enable", - "btn_type": "primary", - "info": "test_function_modal_info_render_normal", - "info_image": "RENDER_NORMAL_INFO_IMAGE", - "info的副本": "test_function_card_info_render_normal" + "space_wecom_notify": { + "can_jump": true, + "to_tag": "space_admins", + "notifications_type": "space", + "is_notification": true, + "is_mail": true, + "is_browser": true, + "billing_notify": "integration_we_com", + "format_string": "space_wecom_notify", + "url": "/management", + "is_component": true }, - "note": "test_function_note_render_normal" - }, - "render_prompt": { - "card": { - "btn_close_action": "/", - "btn_open_action": "/", - "btn_text": "test_function_btncard_btntext_open", - "btn_type": "primary", - "info": "test_function_card_info_render_prompt", - "info的副本": "test_function_card_info_render_prompt" + "space_yozooffice_notify": { + "can_jump": true, + "to_tag": "space_admins", + "notifications_type": "space", + "is_notification": true, + "is_mail": true, + "is_browser": true, + "billing_notify": "integration_yozo_office", + "format_string": "space_yozooffice_notify", + "url": "/management", + "is_component": true }, - "feature_key": "render_prompt", - "feature_name": "render_prompt", - "id": "render_prompt", - "logo": "space/2022/01/25/387465f4e3eb40b4a53a44fea624cd02", - "modal": { - "btn_action": "https://app.feishu.cn/app/cli_a08120b120fad00e", - "btn_text": "enable", - "btn_type": "primary", - "info": "test_function_modal_info_render_prompt", - "info_image": "RENDER_PROMPT_INFO_IMAGE", - "info的副本": "test_function_card_info_render_prompt" + "subscribed_record_cell_updated": { + "can_jump": true, + "to_tag": "members", + "notifications_type": [], + "is_notification": true, + "is_mobile": true, + "is_mail": true, + "is_browser": true, + "mail_template_subject": "subscribedRecordCellUpdated", + "format_string": "subscribed_record_cell_updated", + "url": "/workbench" }, - "note": "test_function_note_render_prompt" - }, - "robot": { - "card": { - "btn_close_action": "/", - "btn_open_action": "/", - "btn_text": "test_function_btncard_btntext_apply", - "btn_type": "primary", - "info": "test_function_card_info_robot", - "info的副本": "test_function_card_info_robot" + "subscribed_record_commented": { + "can_jump": true, + "to_tag": "members", + "notifications_type": [], + "is_notification": true, + "is_mobile": true, + "is_mail": true, + "is_browser": true, + "mail_template_subject": "subscribedRecordCommented", + "format_string": "subscribed_record_commented", + "url": "/workbench" }, - "feature_key": "robot", - "feature_name": "robot", - "id": "robot", - "logo": "space/2022/01/25/4a36a62cf12c47a0bf29b4808f5fcbb8", - "modal": { - "btn_action": "https://vika.cn/share/shrL1BVlA2ZhkSE7nYEgt", - "btn_text": "test_function_btnmodal_btntext", - "btn_type": "primary", - "info": "test_function_modal_info_robot", - "info_image": "ROBOT_INFO_IMAGE", - "info的副本": "test_function_card_info_robot" + "subscribed-record-archived": { + "can_jump": true, + "to_tag": "myself", + "notifications_type": "space", + "is_notification": true, + "is_mail": true, + "format_string": "subscribed_record_archived" }, - "note": "test_function_note_robot" - }, - "view_manual_save": { - "card": { - "btn_close_action": "/", - "btn_open_action": "/", - "btn_text": "test_function_btncard_btntext_open", - "btn_type": "primary", - "info": "test_function_card_info_view_manual_save", - "info的副本": "test_function_card_info_view_manual_save" + "subscribed-record-unarchived": { + "to_tag": "myself", + "notifications_type": "space", + "is_notification": true, + "is_mail": true, + "format_string": "subscribed-record-archived" }, - "feature_key": "view_manual_save", - "feature_name": "view_manual_save", - "id": "view_manual_save", - "logo": "space/2022/01/25/4aa6c029188645cebd8c31f3def205d9", - "modal": { - "btn_text": "enable", - "btn_type": "primary", - "info": "test_function_modal_info_view_manual_save", - "info_image": "VIEW_MANUAL_SAVE_INFO_IMAGE", - "info的副本": "test_function_card_info_view_manual_save" + "task_reminder": { + "can_jump": true, + "to_tag": "members", + "notifications_type": "space", + "is_notification": true, + "is_mobile": true, + "is_mail": true, + "is_browser": true, + "mail_template_subject": "taskReminder", + "format_string": "task_reminder", + "url": "/workbench", + "is_component": true }, - "note": "test_function_note_view_manual_save" - }, - "widget_center": { - "card": { - "btn_close_action": "/", - "btn_open_action": "/", - "btn_text": "test_function_btncard_btntext_apply", - "btn_type": "primary", - "info": "test_function_card_info_widget", - "info的副本": "test_function_card_info_widget" + "user_field": { + "can_jump": true, + "to_tag": "members", + "notifications_type": [], + "is_notification": true, + "is_mobile": true, + "is_mail": true, + "is_browser": true, + "format_string": "field_set_you_by_user", + "url": "/workbench", + "is_component": true }, - "feature_key": "widget_center", - "feature_name": "widget_name", - "id": "widget_center", - "logo": "space/2022/01/25/ff9091547ee84a6c87c3bc7ec1640f25", - "modal": { - "btn_action": "https://vika.cn/share/shrL1BVlA2ZhkSE7nYEgt", - "btn_text": "test_function_btnmodal_btntext", - "btn_type": "primary", - "info": "test_function_modal_info_widget", - "info_image": "WIDGET_CENTER_INFO_IMAGE", - "info的副本": "test_function_card_info_widget" + "web_publish": { + "to_tag": "all_users", + "notifications_type": "system", + "is_mobile": true, + "format_string": "web_publish", + "is_component": true + }, + "workflow_execute_failed_notify": { + "can_jump": true, + "format_string": "workflow_execute_failed_notify", + "id": "workflow_execute_failed_notify", + "is_browser": true, + "is_mail": true, + "is_mobile": false, + "is_notification": true, + "mail_template_subject": "automationError", + "notifications_type": "space", + "is_component": true, + "to_tag": "users", + "url": "/workbench" + } + } + }, + "integral": { + "rule": { + "be_invited_to_reward": { + "action_code": "be_invited_to_reward", + "day_max_integral_value": 0, + "display_name": [], + "online": true, + "integral_value": 1000, + "notify": true, + "action_name": "被邀请奖励" + }, + "complete_bind_email": { + "action_code": "complete_bind_email", + "day_max_integral_value": 0, + "display_name": [], + "online": true, + "integral_value": 1000, + "action_name": "完成绑定邮箱奖励" + }, + "first_bind_email": { + "action_code": "first_bind_email", + "day_max_integral_value": 0, + "display_name": [], + "integral_value": 1000, + "action_name": "首次绑定邮箱奖励" + }, + "first_bind_phone": { + "action_code": "first_bind_phone", + "day_max_integral_value": 0, + "display_name": [], + "integral_value": 1000, + "action_name": "首次绑定手机奖励" + }, + "fission_reward": { + "action_code": "fission_reward", + "display_name": [], + "online": true, + "notify": true, + "action_name": "「“友”福同享」活动 - XX空间" + }, + "invitation_reward": { + "action_code": "invitation_reward", + "day_max_integral_value": 0, + "display_name": [], + "online": true, + "integral_value": 1000, + "notify": true, + "action_name": "邀请奖励" + }, + "official_adjustment": { + "action_code": "official_adjustment", + "display_name": [], + "online": true, + "action_name": "官方调整" + }, + "official_invitation_reward": { + "action_code": "official_invitation_reward", + "day_max_integral_value": 0, + "display_name": [], + "online": true, + "integral_value": 500, + "notify": true, + "action_name": "官方邀请奖励" + }, + "redemption_code": { + "action_code": "redemption_code", + "day_max_integral_value": 0, + "display_name": [], + "online": true, + "integral_value": 0, + "action_name": "兑换码" + }, + "wallet_activity_reward": { + "action_code": "wallet_activity_reward", + "display_name": [], + "online": true, + "action_name": "XXX 活动奖励" + }, + "wizard_reward": { + "action_code": "wizard_reward", + "day_max_integral_value": 0, + "display_name": [], + "online": true, + "integral_value": 200, + "action_name": "智能引导奖励" }, - "note": "test_function_note_widget" + "wizard_video_reward": { + "action_code": "wizard_video_reward", + "day_max_integral_value": 0, + "display_name": [], + "online": true, + "integral_value": 200, + "action_name": "观看引导视频奖励" + } } } -} +} \ No newline at end of file diff --git a/packages/core/src/config/timezones.ts b/packages/core/src/config/timezones.ts index 4242e52764..df7dd4a96b 100644 --- a/packages/core/src/config/timezones.ts +++ b/packages/core/src/config/timezones.ts @@ -17,7 +17,7 @@ export interface IUtcOption { } export const covertDayjsFormat2DateFnsFormat = (format: string) => { - return format.replace('YYYY', 'yyyy').replace('DD', 'dd'); + return format.replace('YYYY', 'yyyy').replace('YY', 'yy').replace('DD', 'dd'); }; export const isValidTimezone = (timezone: string) => { @@ -30,9 +30,10 @@ export const getTimeZone = () => { return isValidTimezone(timeZone) ? timeZone : ''; }; -export const getTimeZoneOffsetByUtc = (utc: string) => { - const currentTimeZoneData = TIMEZONES.find(tz => tz.utc.includes(utc)); - return currentTimeZoneData?.offset; +export const getTimeZoneOffsetByUtc = (utc: string, isdstDate?: boolean) => { + const currentTimeZoneData = TIMEZONES.find((tz) => tz.utc.includes(utc)); + const dstDiff = currentTimeZoneData?.isdst ? isdstDate ? 0 : -1 : 0; + return currentTimeZoneData ? currentTimeZoneData.offset + dstDiff : 0; }; export const getTimeZoneAbbrByUtc = (utc: string) => { @@ -48,16 +49,19 @@ export const getUtcOptionList = () => { let list: IUtcOption[] = []; for (let i = 0; i < TIMEZONES.length; i++) { - const { abbr, offset, utc, isdst } = TIMEZONES[i]!; - if (isdst) continue; - list = list.concat(utc.filter((tz: string) => !tz.includes('Etc/GMT')).map((tz: string) => { - return { - abbr, - offset, - label: `UTC${offset > 0 ? '+' : ''}${offset}(${tz})`, - value: tz, - }; - })); + const { abbr, offset, utc } = TIMEZONES[i]!; + list = list.concat( + utc + .filter((tz: string) => !tz.includes('Etc/GMT')) + .map((tz: string) => { + return { + abbr, + offset, + label: `UTC${offset > 0 ? '+' : ''}${offset}(${tz})`, + value: tz, + }; + }) + ); } return list; @@ -66,7 +70,7 @@ export const getUtcOptionList = () => { export const getClientTimeZone = () => { // https://github.com/iamkun/dayjs/blob/dev/src/plugin/timezone/index.js#L143 const clientTimeZone = getTimeZone(); - const currentTimeZoneData = TIMEZONES.find(tz => tz.utc.includes(clientTimeZone)); + const currentTimeZoneData = TIMEZONES.find((tz) => tz.utc.includes(clientTimeZone)); if (!currentTimeZoneData) { return ''; } @@ -74,8 +78,8 @@ export const getClientTimeZone = () => { return `UTC${offset > 0 ? '+' : ''}${offset}(${clientTimeZone})`; }; -export const formatTimeZone =(timeZone: string) => { - const currentTimeZoneData = TIMEZONES.find(tz => tz.utc.includes(timeZone)); +export const formatTimeZone = (timeZone: string) => { + const currentTimeZoneData = TIMEZONES.find((tz) => tz.utc.includes(timeZone)); if (!currentTimeZoneData) { return ''; } @@ -92,9 +96,7 @@ export const TIMEZONES = [ offset: -12, isdst: false, text: '(UTC-12:00) International Date Line West', - utc: [ - 'Etc/GMT+12' - ] + utc: ['Etc/GMT+12'], }, { value: 'UTC-11', @@ -102,12 +104,7 @@ export const TIMEZONES = [ offset: -11, isdst: false, text: '(UTC-11:00) Coordinated Universal Time-11', - utc: [ - 'Etc/GMT+11', - 'Pacific/Midway', - 'Pacific/Niue', - 'Pacific/Pago_Pago' - ] + utc: ['Etc/GMT+11', 'Pacific/Midway', 'Pacific/Niue', 'Pacific/Pago_Pago'], }, { value: 'Hawaiian Standard Time', @@ -115,13 +112,7 @@ export const TIMEZONES = [ offset: -10, isdst: false, text: '(UTC-10:00) Hawaii', - utc: [ - 'Etc/GMT+10', - 'Pacific/Honolulu', - 'Pacific/Johnston', - 'Pacific/Rarotonga', - 'Pacific/Tahiti' - ] + utc: ['Etc/GMT+10', 'Pacific/Honolulu', 'Pacific/Johnston', 'Pacific/Rarotonga', 'Pacific/Tahiti'], }, { value: 'Alaskan Standard Time', @@ -129,13 +120,7 @@ export const TIMEZONES = [ offset: -8, isdst: true, text: '(UTC-09:00) Alaska', - utc: [ - 'America/Anchorage', - 'America/Juneau', - 'America/Nome', - 'America/Sitka', - 'America/Yakutat' - ] + utc: ['America/Anchorage', 'America/Juneau', 'America/Nome', 'America/Sitka', 'America/Yakutat'], }, { value: 'Pacific Standard Time (Mexico)', @@ -143,21 +128,7 @@ export const TIMEZONES = [ offset: -7, isdst: true, text: '(UTC-08:00) Baja California', - utc: [ - 'America/Santa_Isabel' - ] - }, - { - value: 'Pacific Daylight Time', - abbr: 'PDT', - offset: -7, - isdst: true, - text: '(UTC-07:00) Pacific Daylight Time (US & Canada)', - utc: [ - 'America/Los_Angeles', - 'America/Tijuana', - 'America/Vancouver' - ] + utc: ['America/Santa_Isabel'], }, { value: 'Pacific Standard Time', @@ -165,12 +136,7 @@ export const TIMEZONES = [ offset: -8, isdst: false, text: '(UTC-08:00) Pacific Standard Time (US & Canada)', - utc: [ - 'America/Los_Angeles', - 'America/Tijuana', - 'America/Vancouver', - 'PST8PDT' - ] + utc: ['America/Los_Angeles', 'America/Tijuana', 'America/Vancouver', 'PST8PDT'], }, { value: 'US Mountain Standard Time', @@ -178,15 +144,7 @@ export const TIMEZONES = [ offset: -7, isdst: false, text: '(UTC-07:00) Arizona', - utc: [ - 'America/Creston', - 'America/Dawson', - 'America/Dawson_Creek', - 'America/Hermosillo', - 'America/Phoenix', - 'America/Whitehorse', - 'Etc/GMT+7' - ] + utc: ['America/Creston', 'America/Dawson', 'America/Dawson_Creek', 'America/Hermosillo', 'America/Phoenix', 'America/Whitehorse', 'Etc/GMT+7'], }, { value: 'Mountain Standard Time (Mexico)', @@ -194,10 +152,7 @@ export const TIMEZONES = [ offset: -6, isdst: true, text: '(UTC-07:00) Chihuahua, La Paz, Mazatlan', - utc: [ - 'America/Chihuahua', - 'America/Mazatlan' - ] + utc: ['America/Chihuahua', 'America/Mazatlan'], }, { value: 'Mountain Standard Time', @@ -213,8 +168,8 @@ export const TIMEZONES = [ 'America/Inuvik', 'America/Ojinaga', 'America/Yellowknife', - 'MST7MDT' - ] + 'MST7MDT', + ], }, { value: 'Central America Standard Time', @@ -230,16 +185,17 @@ export const TIMEZONES = [ 'America/Managua', 'America/Tegucigalpa', 'Etc/GMT+6', - 'Pacific/Galapagos' - ] + 'Pacific/Galapagos', + ], }, { value: 'Central Standard Time', abbr: 'CDT', offset: -5, - // isdst: true, + isdst: true, text: '(UTC-06:00) Central Time (US & Canada)', utc: [ + 'America/Chicago', 'America/Indiana/Knox', 'America/Indiana/Tell_City', 'America/Matamoros', @@ -251,8 +207,8 @@ export const TIMEZONES = [ 'America/Rankin_Inlet', 'America/Resolute', 'America/Winnipeg', - 'CST6CDT' - ] + 'CST6CDT', + ], }, { value: 'Central Standard Time (Mexico)', @@ -260,13 +216,7 @@ export const TIMEZONES = [ offset: -5, isdst: true, text: '(UTC-06:00) Guadalajara, Mexico City, Monterrey', - utc: [ - 'America/Bahia_Banderas', - 'America/Cancun', - 'America/Merida', - 'America/Mexico_City', - 'America/Monterrey' - ] + utc: ['America/Bahia_Banderas', 'America/Cancun', 'America/Merida', 'America/Mexico_City', 'America/Monterrey'], }, { value: 'Canada Central Standard Time', @@ -274,10 +224,7 @@ export const TIMEZONES = [ offset: -6, isdst: false, text: '(UTC-06:00) Saskatchewan', - utc: [ - 'America/Regina', - 'America/Swift_Current' - ] + utc: ['America/Regina', 'America/Swift_Current'], }, { value: 'SA Pacific Standard Time', @@ -295,14 +242,14 @@ export const TIMEZONES = [ 'America/Lima', 'America/Panama', 'America/Rio_Branco', - 'Etc/GMT+5' - ] + 'Etc/GMT+5', + ], }, { value: 'Eastern Standard Time', abbr: 'EST', offset: -5, - isdst: true, + // isdst: true, text: '(UTC-05:00) Eastern Time (US & Canada)', utc: [ 'America/Detroit', @@ -320,33 +267,8 @@ export const TIMEZONES = [ 'America/Pangnirtung', 'America/Port-au-Prince', 'America/Thunder_Bay', - 'America/Toronto' - ] - }, - { - value: 'Eastern Daylight Time', - abbr: 'EDT', - offset: -4, - isdst: false, - text: '(UTC-04:00) Eastern Daylight Time (US & Canada)', - utc: [ - 'America/Detroit', - 'America/Havana', - 'America/Indiana/Petersburg', - 'America/Indiana/Vincennes', - 'America/Indiana/Winamac', - 'America/Iqaluit', - 'America/Kentucky/Monticello', - 'America/Louisville', - 'America/Montreal', - 'America/Nassau', - 'America/New_York', - 'America/Nipigon', - 'America/Pangnirtung', - 'America/Port-au-Prince', - 'America/Thunder_Bay', - 'America/Toronto' - ] + 'America/Toronto', + ], }, { value: 'US Eastern Standard Time', @@ -354,11 +276,7 @@ export const TIMEZONES = [ offset: -5, isdst: false, text: '(UTC-05:00) Indiana (East)', - utc: [ - 'America/Indiana/Marengo', - 'America/Indiana/Vevay', - 'America/Indianapolis' - ] + utc: ['America/Indiana/Marengo', 'America/Indiana/Vevay', 'America/Indianapolis'], }, { value: 'Venezuela Standard Time', @@ -366,9 +284,7 @@ export const TIMEZONES = [ offset: -4.5, isdst: false, text: '(UTC-04:30) Caracas', - utc: [ - 'America/Caracas' - ] + utc: ['America/Caracas'], }, { value: 'Paraguay Standard Time', @@ -376,9 +292,7 @@ export const TIMEZONES = [ offset: -4, isdst: false, text: '(UTC-04:00) Asuncion', - utc: [ - 'America/Asuncion' - ] + utc: ['America/Asuncion'], }, { value: 'Atlantic Standard Time', @@ -386,14 +300,7 @@ export const TIMEZONES = [ offset: -3, isdst: true, text: '(UTC-04:00) Atlantic Time (Canada)', - utc: [ - 'America/Glace_Bay', - 'America/Goose_Bay', - 'America/Halifax', - 'America/Moncton', - 'America/Thule', - 'Atlantic/Bermuda' - ] + utc: ['America/Glace_Bay', 'America/Goose_Bay', 'America/Halifax', 'America/Moncton', 'America/Thule', 'Atlantic/Bermuda'], }, { value: 'Central Brazilian Standard Time', @@ -401,10 +308,7 @@ export const TIMEZONES = [ offset: -4, isdst: false, text: '(UTC-04:00) Cuiaba', - utc: [ - 'America/Campo_Grande', - 'America/Cuiaba' - ] + utc: ['America/Campo_Grande', 'America/Cuiaba'], }, { value: 'SA Western Standard Time', @@ -442,8 +346,8 @@ export const TIMEZONES = [ 'America/St_Thomas', 'America/St_Vincent', 'America/Tortola', - 'Etc/GMT+4' - ] + 'Etc/GMT+4', + ], }, { value: 'Pacific SA Standard Time', @@ -451,10 +355,7 @@ export const TIMEZONES = [ offset: -4, isdst: false, text: '(UTC-04:00) Santiago', - utc: [ - 'America/Santiago', - 'Antarctica/Palmer' - ] + utc: ['America/Santiago', 'Antarctica/Palmer'], }, { value: 'Newfoundland Standard Time', @@ -462,9 +363,7 @@ export const TIMEZONES = [ offset: -2.5, isdst: true, text: '(UTC-03:30) Newfoundland', - utc: [ - 'America/St_Johns' - ] + utc: ['America/St_Johns'], }, { value: 'E. South America Standard Time', @@ -472,9 +371,7 @@ export const TIMEZONES = [ offset: -3, isdst: false, text: '(UTC-03:00) Brasilia', - utc: [ - 'America/Sao_Paulo' - ] + utc: ['America/Sao_Paulo'], }, { value: 'Argentina Standard Time', @@ -494,8 +391,8 @@ export const TIMEZONES = [ 'America/Catamarca', 'America/Cordoba', 'America/Jujuy', - 'America/Mendoza' - ] + 'America/Mendoza', + ], }, { value: 'SA Eastern Standard Time', @@ -514,8 +411,8 @@ export const TIMEZONES = [ 'America/Santarem', 'Antarctica/Rothera', 'Atlantic/Stanley', - 'Etc/GMT+3' - ] + 'Etc/GMT+3', + ], }, { value: 'Greenland Standard Time', @@ -523,9 +420,7 @@ export const TIMEZONES = [ offset: -3, isdst: true, text: '(UTC-03:00) Greenland', - utc: [ - 'America/Godthab' - ] + utc: ['America/Godthab'], }, { value: 'Montevideo Standard Time', @@ -533,9 +428,7 @@ export const TIMEZONES = [ offset: -3, isdst: false, text: '(UTC-03:00) Montevideo', - utc: [ - 'America/Montevideo' - ] + utc: ['America/Montevideo'], }, { value: 'Bahia Standard Time', @@ -543,9 +436,7 @@ export const TIMEZONES = [ offset: -3, isdst: false, text: '(UTC-03:00) Salvador', - utc: [ - 'America/Bahia' - ] + utc: ['America/Bahia'], }, { value: 'UTC-02', @@ -553,11 +444,7 @@ export const TIMEZONES = [ offset: -2, isdst: false, text: '(UTC-02:00) Coordinated Universal Time-02', - utc: [ - 'America/Noronha', - 'Atlantic/South_Georgia', - 'Etc/GMT+2' - ] + utc: ['America/Noronha', 'Atlantic/South_Georgia', 'Etc/GMT+2'], }, { value: 'Mid-Atlantic Standard Time', @@ -565,7 +452,7 @@ export const TIMEZONES = [ offset: -1, isdst: true, text: '(UTC-02:00) Mid-Atlantic - Old', - utc: [] + utc: [], }, { value: 'Azores Standard Time', @@ -573,10 +460,7 @@ export const TIMEZONES = [ offset: 0, isdst: true, text: '(UTC-01:00) Azores', - utc: [ - 'America/Scoresbysund', - 'Atlantic/Azores' - ] + utc: ['America/Scoresbysund', 'Atlantic/Azores'], }, { value: 'Cape Verde Standard Time', @@ -584,10 +468,7 @@ export const TIMEZONES = [ offset: -1, isdst: false, text: '(UTC-01:00) Cape Verde Is.', - utc: [ - 'Atlantic/Cape_Verde', - 'Etc/GMT+1' - ] + utc: ['Atlantic/Cape_Verde', 'Etc/GMT+1'], }, { value: 'Morocco Standard Time', @@ -595,10 +476,7 @@ export const TIMEZONES = [ offset: 1, isdst: true, text: '(UTC) Casablanca', - utc: [ - 'Africa/Casablanca', - 'Africa/El_Aaiun' - ] + utc: ['Africa/Casablanca', 'Africa/El_Aaiun'], }, { value: 'UTC', @@ -606,10 +484,7 @@ export const TIMEZONES = [ offset: 0, isdst: false, text: '(UTC) Coordinated Universal Time', - utc: [ - 'America/Danmarkshavn', - 'Etc/GMT' - ] + utc: ['America/Danmarkshavn', 'Etc/GMT'], }, { value: 'GMT Standard Time', @@ -617,12 +492,7 @@ export const TIMEZONES = [ offset: 0, isdst: false, text: '(UTC) Edinburgh, London', - utc: [ - 'Europe/Isle_of_Man', - 'Europe/Guernsey', - 'Europe/Jersey', - 'Europe/London' - ] + utc: ['Europe/Isle_of_Man', 'Europe/Guernsey', 'Europe/Jersey', 'Europe/London'], }, { value: 'British Summer Time', @@ -630,12 +500,7 @@ export const TIMEZONES = [ offset: 1, isdst: true, text: '(UTC+01:00) Edinburgh, London', - utc: [ - 'Europe/Isle_of_Man', - 'Europe/Guernsey', - 'Europe/Jersey', - 'Europe/London' - ] + utc: ['Europe/Isle_of_Man', 'Europe/Guernsey', 'Europe/Jersey', 'Europe/London'], }, { value: 'GMT Standard Time', @@ -643,13 +508,7 @@ export const TIMEZONES = [ offset: 1, isdst: true, text: '(UTC) Dublin, Lisbon', - utc: [ - 'Atlantic/Canary', - 'Atlantic/Faeroe', - 'Atlantic/Madeira', - 'Europe/Dublin', - 'Europe/Lisbon' - ] + utc: ['Atlantic/Canary', 'Atlantic/Faeroe', 'Atlantic/Madeira', 'Europe/Dublin', 'Europe/Lisbon'], }, { value: 'Greenwich Standard Time', @@ -672,8 +531,8 @@ export const TIMEZONES = [ 'Africa/Ouagadougou', 'Africa/Sao_Tome', 'Atlantic/Reykjavik', - 'Atlantic/St_Helena' - ] + 'Atlantic/St_Helena', + ], }, { value: 'W. Europe Standard Time', @@ -698,8 +557,8 @@ export const TIMEZONES = [ 'Europe/Vaduz', 'Europe/Vatican', 'Europe/Vienna', - 'Europe/Zurich' - ] + 'Europe/Zurich', + ], }, { value: 'Central Europe Standard Time', @@ -707,15 +566,7 @@ export const TIMEZONES = [ offset: 2, isdst: true, text: '(UTC+01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague', - utc: [ - 'Europe/Belgrade', - 'Europe/Bratislava', - 'Europe/Budapest', - 'Europe/Ljubljana', - 'Europe/Podgorica', - 'Europe/Prague', - 'Europe/Tirane' - ] + utc: ['Europe/Belgrade', 'Europe/Bratislava', 'Europe/Budapest', 'Europe/Ljubljana', 'Europe/Podgorica', 'Europe/Prague', 'Europe/Tirane'], }, { value: 'Romance Standard Time', @@ -723,13 +574,7 @@ export const TIMEZONES = [ offset: 2, isdst: true, text: '(UTC+01:00) Brussels, Copenhagen, Madrid, Paris', - utc: [ - 'Africa/Ceuta', - 'Europe/Brussels', - 'Europe/Copenhagen', - 'Europe/Madrid', - 'Europe/Paris' - ] + utc: ['Africa/Ceuta', 'Europe/Brussels', 'Europe/Copenhagen', 'Europe/Madrid', 'Europe/Paris'], }, { value: 'Central European Standard Time', @@ -737,12 +582,7 @@ export const TIMEZONES = [ offset: 2, isdst: true, text: '(UTC+01:00) Sarajevo, Skopje, Warsaw, Zagreb', - utc: [ - 'Europe/Sarajevo', - 'Europe/Skopje', - 'Europe/Warsaw', - 'Europe/Zagreb' - ] + utc: ['Europe/Sarajevo', 'Europe/Skopje', 'Europe/Warsaw', 'Europe/Zagreb'], }, { value: 'W. Central Africa Standard Time', @@ -764,8 +604,8 @@ export const TIMEZONES = [ 'Africa/Niamey', 'Africa/Porto-Novo', 'Africa/Tunis', - 'Etc/GMT-1' - ] + 'Etc/GMT-1', + ], }, { value: 'Namibia Standard Time', @@ -773,9 +613,7 @@ export const TIMEZONES = [ offset: 1, isdst: false, text: '(UTC+01:00) Windhoek', - utc: [ - 'Africa/Windhoek' - ] + utc: ['Africa/Windhoek'], }, { value: 'GTB Standard Time', @@ -783,12 +621,7 @@ export const TIMEZONES = [ offset: 3, isdst: true, text: '(UTC+02:00) Athens, Bucharest', - utc: [ - 'Asia/Nicosia', - 'Europe/Athens', - 'Europe/Bucharest', - 'Europe/Chisinau' - ] + utc: ['Asia/Nicosia', 'Europe/Athens', 'Europe/Bucharest', 'Europe/Chisinau'], }, { value: 'Middle East Standard Time', @@ -796,9 +629,7 @@ export const TIMEZONES = [ offset: 3, isdst: true, text: '(UTC+02:00) Beirut', - utc: [ - 'Asia/Beirut' - ] + utc: ['Asia/Beirut'], }, { value: 'Egypt Standard Time', @@ -806,9 +637,7 @@ export const TIMEZONES = [ offset: 2, isdst: false, text: '(UTC+02:00) Cairo', - utc: [ - 'Africa/Cairo' - ] + utc: ['Africa/Cairo'], }, { value: 'Syria Standard Time', @@ -816,9 +645,7 @@ export const TIMEZONES = [ offset: 3, isdst: true, text: '(UTC+02:00) Damascus', - utc: [ - 'Asia/Damascus' - ] + utc: ['Asia/Damascus'], }, { value: 'E. Europe Standard Time', @@ -840,9 +667,8 @@ export const TIMEZONES = [ 'Europe/Tallinn', 'Europe/Uzhgorod', 'Europe/Vilnius', - 'Europe/Zaporozhye' - - ] + 'Europe/Zaporozhye', + ], }, { value: 'South Africa Standard Time', @@ -862,8 +688,8 @@ export const TIMEZONES = [ 'Africa/Maputo', 'Africa/Maseru', 'Africa/Mbabane', - 'Etc/GMT-2' - ] + 'Etc/GMT-2', + ], }, { value: 'FLE Standard Time', @@ -880,8 +706,8 @@ export const TIMEZONES = [ 'Europe/Tallinn', 'Europe/Uzhgorod', 'Europe/Vilnius', - 'Europe/Zaporozhye' - ] + 'Europe/Zaporozhye', + ], }, { value: 'Turkey Standard Time', @@ -889,9 +715,7 @@ export const TIMEZONES = [ offset: 3, isdst: false, text: '(UTC+03:00) Istanbul', - utc: [ - 'Europe/Istanbul' - ] + utc: ['Europe/Istanbul'], }, { value: 'Israel Standard Time', @@ -899,9 +723,7 @@ export const TIMEZONES = [ offset: 3, isdst: true, text: '(UTC+02:00) Jerusalem', - utc: [ - 'Asia/Jerusalem' - ] + utc: ['Asia/Jerusalem'], }, { value: 'Libya Standard Time', @@ -909,9 +731,7 @@ export const TIMEZONES = [ offset: 2, isdst: false, text: '(UTC+02:00) Tripoli', - utc: [ - 'Africa/Tripoli' - ] + utc: ['Africa/Tripoli'], }, { value: 'Jordan Standard Time', @@ -919,9 +739,7 @@ export const TIMEZONES = [ offset: 3, isdst: false, text: '(UTC+03:00) Amman', - utc: [ - 'Asia/Amman' - ] + utc: ['Asia/Amman'], }, { value: 'Arabic Standard Time', @@ -929,9 +747,7 @@ export const TIMEZONES = [ offset: 3, isdst: false, text: '(UTC+03:00) Baghdad', - utc: [ - 'Asia/Baghdad' - ] + utc: ['Asia/Baghdad'], }, { value: 'Kaliningrad Standard Time', @@ -939,9 +755,7 @@ export const TIMEZONES = [ offset: 3, isdst: false, text: '(UTC+02:00) Kaliningrad', - utc: [ - 'Europe/Kaliningrad' - ] + utc: ['Europe/Kaliningrad'], }, { value: 'Arab Standard Time', @@ -949,13 +763,7 @@ export const TIMEZONES = [ offset: 3, isdst: false, text: '(UTC+03:00) Kuwait, Riyadh', - utc: [ - 'Asia/Aden', - 'Asia/Bahrain', - 'Asia/Kuwait', - 'Asia/Qatar', - 'Asia/Riyadh' - ] + utc: ['Asia/Aden', 'Asia/Bahrain', 'Asia/Kuwait', 'Asia/Qatar', 'Asia/Riyadh'], }, { value: 'E. Africa Standard Time', @@ -977,8 +785,8 @@ export const TIMEZONES = [ 'Etc/GMT-3', 'Indian/Antananarivo', 'Indian/Comoro', - 'Indian/Mayotte' - ] + 'Indian/Mayotte', + ], }, { value: 'Moscow Standard Time', @@ -986,13 +794,7 @@ export const TIMEZONES = [ offset: 3, isdst: false, text: '(UTC+03:00) Moscow, St. Petersburg, Volgograd, Minsk', - utc: [ - 'Europe/Kirov', - 'Europe/Moscow', - 'Europe/Simferopol', - 'Europe/Volgograd', - 'Europe/Minsk' - ] + utc: ['Europe/Kirov', 'Europe/Moscow', 'Europe/Simferopol', 'Europe/Volgograd', 'Europe/Minsk'], }, { value: 'Samara Time', @@ -1000,11 +802,7 @@ export const TIMEZONES = [ offset: 4, isdst: false, text: '(UTC+04:00) Samara, Ulyanovsk, Saratov', - utc: [ - 'Europe/Astrakhan', - 'Europe/Samara', - 'Europe/Ulyanovsk' - ] + utc: ['Europe/Astrakhan', 'Europe/Samara', 'Europe/Ulyanovsk'], }, { value: 'Iran Standard Time', @@ -1012,9 +810,7 @@ export const TIMEZONES = [ offset: 4.5, isdst: true, text: '(UTC+03:30) Tehran', - utc: [ - 'Asia/Tehran' - ] + utc: ['Asia/Tehran'], }, { value: 'Arabian Standard Time', @@ -1022,11 +818,7 @@ export const TIMEZONES = [ offset: 4, isdst: false, text: '(UTC+04:00) Abu Dhabi, Muscat', - utc: [ - 'Asia/Dubai', - 'Asia/Muscat', - 'Etc/GMT-4' - ] + utc: ['Asia/Dubai', 'Asia/Muscat', 'Etc/GMT-4'], }, { value: 'Azerbaijan Standard Time', @@ -1034,9 +826,7 @@ export const TIMEZONES = [ offset: 5, isdst: true, text: '(UTC+04:00) Baku', - utc: [ - 'Asia/Baku' - ] + utc: ['Asia/Baku'], }, { value: 'Mauritius Standard Time', @@ -1044,11 +834,7 @@ export const TIMEZONES = [ offset: 4, isdst: false, text: '(UTC+04:00) Port Louis', - utc: [ - 'Indian/Mahe', - 'Indian/Mauritius', - 'Indian/Reunion' - ] + utc: ['Indian/Mahe', 'Indian/Mauritius', 'Indian/Reunion'], }, { value: 'Georgian Standard Time', @@ -1056,9 +842,7 @@ export const TIMEZONES = [ offset: 4, isdst: false, text: '(UTC+04:00) Tbilisi', - utc: [ - 'Asia/Tbilisi' - ] + utc: ['Asia/Tbilisi'], }, { value: 'Caucasus Standard Time', @@ -1066,9 +850,7 @@ export const TIMEZONES = [ offset: 4, isdst: false, text: '(UTC+04:00) Yerevan', - utc: [ - 'Asia/Yerevan' - ] + utc: ['Asia/Yerevan'], }, { value: 'Afghanistan Standard Time', @@ -1076,9 +858,7 @@ export const TIMEZONES = [ offset: 4.5, isdst: false, text: '(UTC+04:30) Kabul', - utc: [ - 'Asia/Kabul' - ] + utc: ['Asia/Kabul'], }, { value: 'West Asia Standard Time', @@ -1097,8 +877,8 @@ export const TIMEZONES = [ 'Asia/Tashkent', 'Etc/GMT-5', 'Indian/Kerguelen', - 'Indian/Maldives' - ] + 'Indian/Maldives', + ], }, { value: 'Yekaterinburg Time', @@ -1106,9 +886,7 @@ export const TIMEZONES = [ offset: 5, isdst: false, text: '(UTC+05:00) Yekaterinburg', - utc: [ - 'Asia/Yekaterinburg' - ] + utc: ['Asia/Yekaterinburg'], }, { value: 'Pakistan Standard Time', @@ -1116,9 +894,7 @@ export const TIMEZONES = [ offset: 5, isdst: false, text: '(UTC+05:00) Islamabad, Karachi', - utc: [ - 'Asia/Karachi' - ] + utc: ['Asia/Karachi'], }, { value: 'India Standard Time', @@ -1126,10 +902,7 @@ export const TIMEZONES = [ offset: 5.5, isdst: false, text: '(UTC+05:30) Chennai, Kolkata, Mumbai, New Delhi', - utc: [ - 'Asia/Kolkata', - 'Asia/Calcutta' - ] + utc: ['Asia/Kolkata', 'Asia/Calcutta'], }, { value: 'Sri Lanka Standard Time', @@ -1137,9 +910,7 @@ export const TIMEZONES = [ offset: 5.5, isdst: false, text: '(UTC+05:30) Sri Jayawardenepura', - utc: [ - 'Asia/Colombo' - ] + utc: ['Asia/Colombo'], }, { value: 'Nepal Standard Time', @@ -1147,9 +918,7 @@ export const TIMEZONES = [ offset: 5.75, isdst: false, text: '(UTC+05:45) Kathmandu', - utc: [ - 'Asia/Kathmandu' - ] + utc: ['Asia/Kathmandu'], }, { value: 'Central Asia Standard Time', @@ -1157,15 +926,7 @@ export const TIMEZONES = [ offset: 6, isdst: false, text: '(UTC+06:00) Nur-Sultan (Astana)', - utc: [ - 'Antarctica/Vostok', - 'Asia/Almaty', - 'Asia/Bishkek', - 'Asia/Qyzylorda', - 'Asia/Urumqi', - 'Etc/GMT-6', - 'Indian/Chagos' - ] + utc: ['Antarctica/Vostok', 'Asia/Almaty', 'Asia/Bishkek', 'Asia/Qyzylorda', 'Asia/Urumqi', 'Etc/GMT-6', 'Indian/Chagos'], }, { value: 'Bangladesh Standard Time', @@ -1173,11 +934,7 @@ export const TIMEZONES = [ offset: 6, isdst: false, text: '(UTC+06:00) Dhaka', - utc: [ - 'Asia/Dhaka', - 'Asia/Thimphu', - 'Asia/Omsk' - ] + utc: ['Asia/Dhaka', 'Asia/Thimphu', 'Asia/Omsk'], }, { value: 'Myanmar Standard Time', @@ -1185,10 +942,7 @@ export const TIMEZONES = [ offset: 6.5, isdst: false, text: '(UTC+06:30) Yangon (Rangoon)', - utc: [ - 'Asia/Rangoon', - 'Indian/Cocos' - ] + utc: ['Asia/Rangoon', 'Indian/Cocos'], }, { value: 'SE Asia Standard Time', @@ -1206,8 +960,8 @@ export const TIMEZONES = [ 'Asia/Saigon', 'Asia/Vientiane', 'Etc/GMT-7', - 'Indian/Christmas' - ] + 'Indian/Christmas', + ], }, { value: 'N. Central Asia Standard Time', @@ -1215,10 +969,7 @@ export const TIMEZONES = [ offset: 7, isdst: false, text: '(UTC+07:00) Novosibirsk', - utc: [ - 'Asia/Novokuznetsk', - 'Asia/Novosibirsk' - ] + utc: ['Asia/Novokuznetsk', 'Asia/Novosibirsk'], }, { value: 'China Standard Time', @@ -1226,11 +977,7 @@ export const TIMEZONES = [ offset: 8, isdst: false, text: '(UTC+08:00) Beijing, Chongqing, Hong Kong, Urumqi', - utc: [ - 'Asia/Hong_Kong', - 'Asia/Macau', - 'Asia/Shanghai' - ] + utc: ['Asia/Hong_Kong', 'Asia/Macau', 'Asia/Shanghai'], }, { value: 'North Asia Standard Time', @@ -1238,9 +985,7 @@ export const TIMEZONES = [ offset: 8, isdst: false, text: '(UTC+08:00) Krasnoyarsk', - utc: [ - 'Asia/Krasnoyarsk' - ] + utc: ['Asia/Krasnoyarsk'], }, { value: 'Singapore Standard Time', @@ -1248,15 +993,7 @@ export const TIMEZONES = [ offset: 8, isdst: false, text: '(UTC+08:00) Kuala Lumpur, Singapore', - utc: [ - 'Asia/Brunei', - 'Asia/Kuala_Lumpur', - 'Asia/Kuching', - 'Asia/Makassar', - 'Asia/Manila', - 'Asia/Singapore', - 'Etc/GMT-8' - ] + utc: ['Asia/Brunei', 'Asia/Kuala_Lumpur', 'Asia/Kuching', 'Asia/Makassar', 'Asia/Manila', 'Asia/Singapore', 'Etc/GMT-8'], }, { value: 'W. Australia Standard Time', @@ -1264,10 +1001,7 @@ export const TIMEZONES = [ offset: 8, isdst: false, text: '(UTC+08:00) Perth', - utc: [ - 'Antarctica/Casey', - 'Australia/Perth' - ] + utc: ['Antarctica/Casey', 'Australia/Perth'], }, { value: 'Taipei Standard Time', @@ -1275,9 +1009,7 @@ export const TIMEZONES = [ offset: 8, isdst: false, text: '(UTC+08:00) Taipei', - utc: [ - 'Asia/Taipei' - ] + utc: ['Asia/Taipei'], }, { value: 'Ulaanbaatar Standard Time', @@ -1285,10 +1017,7 @@ export const TIMEZONES = [ offset: 8, isdst: false, text: '(UTC+08:00) Ulaanbaatar', - utc: [ - 'Asia/Choibalsan', - 'Asia/Ulaanbaatar' - ] + utc: ['Asia/Choibalsan', 'Asia/Ulaanbaatar'], }, { value: 'North Asia East Standard Time', @@ -1296,19 +1025,7 @@ export const TIMEZONES = [ offset: 8, isdst: false, text: '(UTC+08:00) Irkutsk', - utc: [ - 'Asia/Irkutsk' - ] - }, - { - value: 'Central Standard Time', - abbr: 'CDT', - offset: 8, - isdst: false, - text: '(UTC-06:00) Central Time (US & Canada)', - utc: [ - 'America/Chicago' - ] + utc: ['Asia/Irkutsk'], }, { value: 'Japan Standard Time', @@ -1316,13 +1033,7 @@ export const TIMEZONES = [ offset: 9, isdst: false, text: '(UTC+09:00) Osaka, Sapporo, Tokyo', - utc: [ - 'Asia/Dili', - 'Asia/Jayapura', - 'Asia/Tokyo', - 'Etc/GMT-9', - 'Pacific/Palau' - ] + utc: ['Asia/Dili', 'Asia/Jayapura', 'Asia/Tokyo', 'Etc/GMT-9', 'Pacific/Palau'], }, { value: 'Korea Standard Time', @@ -1330,10 +1041,7 @@ export const TIMEZONES = [ offset: 9, isdst: false, text: '(UTC+09:00) Seoul', - utc: [ - 'Asia/Pyongyang', - 'Asia/Seoul' - ] + utc: ['Asia/Pyongyang', 'Asia/Seoul'], }, { value: 'Cen. Australia Standard Time', @@ -1341,10 +1049,7 @@ export const TIMEZONES = [ offset: 9.5, isdst: false, text: '(UTC+09:30) Adelaide', - utc: [ - 'Australia/Adelaide', - 'Australia/Broken_Hill' - ] + utc: ['Australia/Adelaide', 'Australia/Broken_Hill'], }, { value: 'AUS Central Standard Time', @@ -1352,9 +1057,7 @@ export const TIMEZONES = [ offset: 9.5, isdst: false, text: '(UTC+09:30) Darwin', - utc: [ - 'Australia/Darwin' - ] + utc: ['Australia/Darwin'], }, { value: 'E. Australia Standard Time', @@ -1362,10 +1065,7 @@ export const TIMEZONES = [ offset: 10, isdst: false, text: '(UTC+10:00) Brisbane', - utc: [ - 'Australia/Brisbane', - 'Australia/Lindeman' - ] + utc: ['Australia/Brisbane', 'Australia/Lindeman'], }, { value: 'AUS Eastern Standard Time', @@ -1373,10 +1073,7 @@ export const TIMEZONES = [ offset: 10, isdst: false, text: '(UTC+10:00) Canberra, Melbourne, Sydney', - utc: [ - 'Australia/Melbourne', - 'Australia/Sydney' - ] + utc: ['Australia/Melbourne', 'Australia/Sydney'], }, { value: 'West Pacific Standard Time', @@ -1384,14 +1081,7 @@ export const TIMEZONES = [ offset: 10, isdst: false, text: '(UTC+10:00) Guam, Port Moresby', - utc: [ - 'Antarctica/DumontDUrville', - 'Etc/GMT-10', - 'Pacific/Guam', - 'Pacific/Port_Moresby', - 'Pacific/Saipan', - 'Pacific/Truk' - ] + utc: ['Antarctica/DumontDUrville', 'Etc/GMT-10', 'Pacific/Guam', 'Pacific/Port_Moresby', 'Pacific/Saipan', 'Pacific/Truk'], }, { value: 'Tasmania Standard Time', @@ -1399,10 +1089,7 @@ export const TIMEZONES = [ offset: 10, isdst: false, text: '(UTC+10:00) Hobart', - utc: [ - 'Australia/Currie', - 'Australia/Hobart' - ] + utc: ['Australia/Currie', 'Australia/Hobart'], }, { value: 'Yakutsk Standard Time', @@ -1410,11 +1097,7 @@ export const TIMEZONES = [ offset: 9, isdst: false, text: '(UTC+09:00) Yakutsk', - utc: [ - 'Asia/Chita', - 'Asia/Khandyga', - 'Asia/Yakutsk' - ] + utc: ['Asia/Chita', 'Asia/Khandyga', 'Asia/Yakutsk'], }, { value: 'Central Pacific Standard Time', @@ -1422,15 +1105,7 @@ export const TIMEZONES = [ offset: 11, isdst: false, text: '(UTC+11:00) Solomon Is., New Caledonia', - utc: [ - 'Antarctica/Macquarie', - 'Etc/GMT-11', - 'Pacific/Efate', - 'Pacific/Guadalcanal', - 'Pacific/Kosrae', - 'Pacific/Noumea', - 'Pacific/Ponape' - ] + utc: ['Antarctica/Macquarie', 'Etc/GMT-11', 'Pacific/Efate', 'Pacific/Guadalcanal', 'Pacific/Kosrae', 'Pacific/Noumea', 'Pacific/Ponape'], }, { value: 'Vladivostok Standard Time', @@ -1438,11 +1113,7 @@ export const TIMEZONES = [ offset: 11, isdst: false, text: '(UTC+11:00) Vladivostok', - utc: [ - 'Asia/Sakhalin', - 'Asia/Ust-Nera', - 'Asia/Vladivostok' - ] + utc: ['Asia/Sakhalin', 'Asia/Ust-Nera', 'Asia/Vladivostok'], }, { value: 'New Zealand Standard Time', @@ -1450,10 +1121,7 @@ export const TIMEZONES = [ offset: 12, isdst: false, text: '(UTC+12:00) Auckland, Wellington', - utc: [ - 'Antarctica/McMurdo', - 'Pacific/Auckland' - ] + utc: ['Antarctica/McMurdo', 'Pacific/Auckland'], }, { value: 'UTC+12', @@ -1469,8 +1137,8 @@ export const TIMEZONES = [ 'Pacific/Nauru', 'Pacific/Tarawa', 'Pacific/Wake', - 'Pacific/Wallis' - ] + 'Pacific/Wallis', + ], }, { value: 'Fiji Standard Time', @@ -1478,9 +1146,7 @@ export const TIMEZONES = [ offset: 12, isdst: false, text: '(UTC+12:00) Fiji', - utc: [ - 'Pacific/Fiji' - ] + utc: ['Pacific/Fiji'], }, { value: 'Magadan Standard Time', @@ -1488,12 +1154,7 @@ export const TIMEZONES = [ offset: 12, isdst: false, text: '(UTC+12:00) Magadan', - utc: [ - 'Asia/Anadyr', - 'Asia/Kamchatka', - 'Asia/Magadan', - 'Asia/Srednekolymsk' - ] + utc: ['Asia/Anadyr', 'Asia/Kamchatka', 'Asia/Magadan', 'Asia/Srednekolymsk'], }, { value: 'Kamchatka Standard Time', @@ -1501,9 +1162,7 @@ export const TIMEZONES = [ offset: 13, isdst: true, text: '(UTC+12:00) Petropavlovsk-Kamchatsky - Old', - utc: [ - 'Asia/Kamchatka' - ] + utc: ['Asia/Kamchatka'], }, { value: 'Tonga Standard Time', @@ -1511,12 +1170,7 @@ export const TIMEZONES = [ offset: 13, isdst: false, text: "(UTC+13:00) Nuku'alofa", - utc: [ - 'Etc/GMT-13', - 'Pacific/Enderbury', - 'Pacific/Fakaofo', - 'Pacific/Tongatapu' - ] + utc: ['Etc/GMT-13', 'Pacific/Enderbury', 'Pacific/Fakaofo', 'Pacific/Tongatapu'], }, { value: 'Samoa Standard Time', @@ -1524,9 +1178,7 @@ export const TIMEZONES = [ offset: 13, isdst: false, text: '(UTC+13:00) Samoa', - utc: [ - 'Pacific/Apia' - ] + utc: ['Pacific/Apia'], }, { value: '', @@ -1534,8 +1186,6 @@ export const TIMEZONES = [ offset: 14, isdst: false, text: '(UTC+14:00) Kiritimati', - utc: [ - 'Pacific/Kiritimati' - ] - } + utc: ['Pacific/Kiritimati'], + }, ]; diff --git a/packages/core/src/databus/__tests__/databus.test.ts b/packages/core/src/databus/__tests__/databus.test.ts index 8c89bed3b5..8a2b335f38 100644 --- a/packages/core/src/databus/__tests__/databus.test.ts +++ b/packages/core/src/databus/__tests__/databus.test.ts @@ -16,12 +16,12 @@ * along with this program. If not, see . */ -import { mockRecordValues, mockRecords, mockDefaultRecord, mockRecordVoTransformer } from './mock.record'; -import { MockDataBus, resetDataLoader } from './mock.databus'; -import { IRecord } from 'exports/store/interfaces'; -import { SegmentType } from 'types'; import { ExecuteResult } from 'command_manager'; import { CollaCommandName } from 'commands/enum'; +import { IRecord } from 'exports/store/interfaces'; +import { SegmentType } from 'types'; +import { MockDataBus, resetDataLoader } from './mock.databus'; +import { mockDefaultRecord, mockRecords, mockRecordValues, mockRecordVoTransformer } from './mock.record'; const assertRecordId = (record: IRecord, newId: string): IRecord => { expect(record.id).toBeTruthy(); @@ -48,7 +48,7 @@ describe('record operations', () => { expect(dst1).toBeTruthy(); const view1 = await dst1!.getView('viw1'); expect(view1).toBeTruthy(); - const records = await view1!.getRecords({}); + const records = await view1!.getRecords(); expect(records).toBeTruthy(); expect(records.length).toBe(5); @@ -62,11 +62,11 @@ describe('record operations', () => { expect(dst1).toBeTruthy(); const view1 = await dst1!.getView('viw1'); expect(view1).toBeTruthy(); - const records = await view1!.getRecords({}); + const records = await view1!.getRecords(); expect(records).toBeTruthy(); - const recordVos = records.map(record => record.getViewObject(mockRecordVoTransformer)); + const recordVos = records.map((record) => record.getViewObject(mockRecordVoTransformer)); expect(recordVos).toStrictEqual([ { @@ -146,7 +146,7 @@ describe('record operations', () => { }, ], }, - {}, + {} ); expect(succeeded.result).toStrictEqual(ExecuteResult.Success); @@ -160,7 +160,7 @@ describe('record operations', () => { view1 = await dst1!.getView('viw1'); expect(view1).toBeTruthy(); - const records = await view1!.getRecords({}); + const records = await view1!.getRecords(); expect(records).toBeTruthy(); expect(records.length).toBe(6); @@ -179,7 +179,7 @@ describe('record operations', () => { index: 0, recordValues: [mockRecordValues[0]!], }, - {}, + {} ); expect(result.result).toStrictEqual(ExecuteResult.Success); @@ -192,7 +192,7 @@ describe('record operations', () => { view1 = await dst1!.getView('viw1'); expect(view1).toBeTruthy(); - const records = await view1!.getRecords({}); + const records = await view1!.getRecords(); expect(records).toBeTruthy(); expect(records.length).toBe(6); @@ -216,7 +216,7 @@ describe('record operations', () => { index: 1, recordValues: [mockRecordValues[0]!], }, - {}, + {} ); expect(result.result).toStrictEqual(ExecuteResult.Success); @@ -229,7 +229,7 @@ describe('record operations', () => { view1 = await dst1!.getView('viw1'); expect(view1).toBeTruthy(); - const records = await view1!.getRecords({}); + const records = await view1!.getRecords(); expect(records).toBeTruthy(); expect(records.length).toBe(6); @@ -253,7 +253,7 @@ describe('record operations', () => { index: 1, recordValues: mockRecordValues, }, - {}, + {} ); expect(result.result).toStrictEqual(ExecuteResult.Success); @@ -266,13 +266,13 @@ describe('record operations', () => { view1 = await dst1!.getView('viw1'); expect(view1).toBeTruthy(); - const records = await view1!.getRecords({}); + const records = await view1!.getRecords(); expect(records).toBeTruthy(); expect(records.length).toBe(8); - let recordVos = records.slice(1, 4).map(record => record.getViewObject(mockRecordVoTransformer)); - recordVos = assertRecordIds(recordVos, i => `rec${i + 4}`); + let recordVos = records.slice(1, 4).map((record) => record.getViewObject(mockRecordVoTransformer)); + recordVos = assertRecordIds(recordVos, (i) => `rec${i + 4}`); expect(recordVos).toStrictEqual(mockRecords); }); @@ -290,7 +290,7 @@ describe('record operations', () => { index: 1, count: 3, }, - {}, + {} ); expect(result.result).toStrictEqual(ExecuteResult.Success); @@ -303,12 +303,12 @@ describe('record operations', () => { view1 = await dst1!.getView('viw1'); expect(view1).toBeTruthy(); - const records = await view1!.getRecords({}); + const records = await view1!.getRecords(); expect(records).toBeTruthy(); expect(records.length).toBe(8); - const recordVos = records.slice(1, 4).map(record => record.getViewObject(mockRecordVoTransformer)); + const recordVos = records.slice(1, 4).map((record) => record.getViewObject(mockRecordVoTransformer)); let recordVo = assertRecordId(recordVos[0]!, 'rec4'); expect(recordVo).toStrictEqual(mockDefaultRecord); @@ -335,7 +335,7 @@ describe('record operations', () => { cellValues: [mockRecordValues[0]!], ignoreFieldPermission: true, }, - {}, + {} ); expect(result.result).toStrictEqual(ExecuteResult.Success); @@ -348,7 +348,7 @@ describe('record operations', () => { const view1 = await dst1!.getView('viw1'); expect(view1).toBeTruthy(); - const records = await view1!.getRecords({}); + const records = await view1!.getRecords(); expect(records).toBeTruthy(); expect(records.length).toBe(6); diff --git a/packages/core/src/databus/__tests__/record.test.ts b/packages/core/src/databus/__tests__/record.test.ts index 3e04821a5e..5c9b7e6ec1 100644 --- a/packages/core/src/databus/__tests__/record.test.ts +++ b/packages/core/src/databus/__tests__/record.test.ts @@ -24,7 +24,7 @@ const db = MockDataBus.getDatabase(); beforeAll(resetDataLoader); describe('record info', () => { - test('basic record info', async() => { + test('basic record info', async () => { const dst1 = await db.getDatasheet('dst1', { loadOptions: {}, storeOptions: {}, @@ -36,9 +36,9 @@ describe('record info', () => { expect(view1!.id).toStrictEqual('viw1'); - const records = await view1!.getRecords({}); + const records = await view1!.getRecords(); - const recordData = records.map(record => ({ id: record.id, comments: record.comments })); + const recordData = records.map((record) => ({ id: record.id, comments: record.comments })); expect(recordData).toStrictEqual([ { @@ -78,7 +78,7 @@ describe('record info', () => { }); describe('getViewInfo', () => { - test('verbatim', async() => { + test('verbatim', async () => { const dst1 = await db.getDatasheet('dst1', { loadOptions: {}, storeOptions: {}, @@ -90,11 +90,11 @@ describe('getViewInfo', () => { expect(view1!.id).toStrictEqual('viw1'); - const records = await view1!.getRecords({}); + const records = await view1!.getRecords(); expect(records.length).toBeGreaterThan(1); - expect(records[1]!.getViewObject(x => x)).toStrictEqual({ + expect(records[1]!.getViewObject((x) => x)).toStrictEqual({ id: 'rec2', data: { fld1: [{ type: SegmentType.Text, text: 'text 2' }], diff --git a/packages/core/src/databus/__tests__/view.test.ts b/packages/core/src/databus/__tests__/view.test.ts index 7c48017aa2..512bb980f6 100644 --- a/packages/core/src/databus/__tests__/view.test.ts +++ b/packages/core/src/databus/__tests__/view.test.ts @@ -17,13 +17,13 @@ */ import { ExecuteResult, ExecuteType, ICollaCommandExecuteSuccessResult } from 'command_manager'; -import { ICommandExecutionSuccessResult } from '../logic'; +import { CollaCommandName } from 'commands/enum'; +import { IOperation, OTActionName } from 'engine'; import { ViewType } from 'modules/shared/store/constants'; import { ResourceType, SegmentType } from 'types'; +import { ICommandExecutionSuccessResult } from '../logic'; import { MockDataBus, resetDataLoader } from './mock.databus'; import { mockOperationOfAddRecords } from './mock.record'; -import { IOperation, OTActionName } from 'engine'; -import { CollaCommandName } from 'commands/enum'; const db = MockDataBus.getDatabase(); @@ -63,7 +63,7 @@ describe('getFields', () => { const fields = await view2!.getFields({}); - const fieldIds = fields.map(field => field.id); + const fieldIds = fields.map((field) => field.id); expect(fieldIds).toStrictEqual(['fld1']); }); @@ -84,7 +84,7 @@ describe('getFields', () => { includeHidden: true, }); - const fieldIds = fields.map(field => field.id); + const fieldIds = fields.map((field) => field.id); expect(fieldIds).toStrictEqual(['fld1', 'fld2']); }); @@ -101,207 +101,12 @@ describe('getRecords', () => { const view2 = await dst1!.getView('viw2'); expect(view2).toBeTruthy(); - const records = await view2!.getRecords({}); - - const recordIds = records.map(record => record.id); - - expect(recordIds).toStrictEqual(['rec2', 'rec3', 'rec5', 'rec1', 'rec4']); - }); - - test('maxRecords limit number of records', async () => { - const dst1 = await db.getDatasheet('dst1', { - loadOptions: {}, - storeOptions: {}, - }); - expect(dst1).toBeTruthy(); - - const view2 = await dst1!.getView('viw2'); - expect(view2).toBeTruthy(); - - const records = await view2!.getRecords({ - maxRecords: 3, - }); - - const recordIds = records.map(record => record.id); - - expect(recordIds).toStrictEqual(['rec2', 'rec3', 'rec5']); - }); - - test('maxRecords > total number of records', async () => { - const dst1 = await db.getDatasheet('dst1', { - loadOptions: {}, - storeOptions: {}, - }); - expect(dst1).toBeTruthy(); - - const view2 = await dst1!.getView('viw2'); - expect(view2).toBeTruthy(); - - const records = await view2!.getRecords({ - maxRecords: 20, - }); + const records = await view2!.getRecords(); - const recordIds = records.map(record => record.id); + const recordIds = records.map((record) => record.id); expect(recordIds).toStrictEqual(['rec2', 'rec3', 'rec5', 'rec1', 'rec4']); }); - - describe('pagination', () => { - test('pageNum = 1, pageSize = 3', async () => { - const dst1 = await db.getDatasheet('dst1', { - loadOptions: {}, - storeOptions: {}, - }); - expect(dst1).toBeTruthy(); - - const view2 = await dst1!.getView('viw2'); - expect(view2).toBeTruthy(); - - const records = await view2!.getRecords({ - pagination: { - pageNum: 1, - pageSize: 3, - }, - }); - - const recordIds = records.map(record => record.id); - - expect(recordIds).toStrictEqual(['rec2', 'rec3', 'rec5']); - }); - - test('pageNum = 1, pageSize = 0', async () => { - const dst1 = await db.getDatasheet('dst1', { - loadOptions: {}, - storeOptions: {}, - }); - expect(dst1).toBeTruthy(); - - const view2 = await dst1!.getView('viw2'); - expect(view2).toBeTruthy(); - - const records = await view2!.getRecords({ - pagination: { - pageNum: 1, - pageSize: 0, - }, - }); - - const recordIds = records.map(record => record.id); - - expect(recordIds).toStrictEqual([]); - }); - - test('pageNum = 1, pageSize = 0', async () => { - const dst1 = await db.getDatasheet('dst1', { - loadOptions: {}, - storeOptions: {}, - }); - expect(dst1).toBeTruthy(); - - const view2 = await dst1!.getView('viw2'); - expect(view2).toBeTruthy(); - - const records = await view2!.getRecords({ - pagination: { - pageNum: 1, - pageSize: 0, - }, - }); - - const recordIds = records.map(record => record.id); - - expect(recordIds).toStrictEqual([]); - }); - - test('pageNum = 2, pageSize = 2', async () => { - const dst1 = await db.getDatasheet('dst1', { - loadOptions: {}, - storeOptions: {}, - }); - expect(dst1).toBeTruthy(); - - const view2 = await dst1!.getView('viw2'); - expect(view2).toBeTruthy(); - - const records = await view2!.getRecords({ - pagination: { - pageNum: 2, - pageSize: 2, - }, - }); - - const recordIds = records.map(record => record.id); - - expect(recordIds).toStrictEqual(['rec5', 'rec1']); - }); - - test('pageNum = 2, pageSize = 3', async () => { - const dst1 = await db.getDatasheet('dst1', { - loadOptions: {}, - storeOptions: {}, - }); - expect(dst1).toBeTruthy(); - - const view2 = await dst1!.getView('viw2'); - expect(view2).toBeTruthy(); - - const records = await view2!.getRecords({ - pagination: { - pageNum: 2, - pageSize: 3, - }, - }); - - const recordIds = records.map(record => record.id); - - expect(recordIds).toStrictEqual(['rec1', 'rec4']); - }); - - test('pageNum = 3, pageSize = 3', async () => { - const dst1 = await db.getDatasheet('dst1', { - loadOptions: {}, - storeOptions: {}, - }); - expect(dst1).toBeTruthy(); - - const view2 = await dst1!.getView('viw2'); - expect(view2).toBeTruthy(); - - const records = await view2!.getRecords({ - pagination: { - pageNum: 3, - pageSize: 3, - }, - }); - - const recordIds = records.map(record => record.id); - - expect(recordIds).toStrictEqual([]); - }); - }); - - test('maxRecords = 4 and pagnation: pageNum = 2, pageSize = 3', async () => { - const dst1 = await db.getDatasheet('dst1', { - loadOptions: {}, - storeOptions: {}, - }); - expect(dst1).toBeTruthy(); - - const view2 = await dst1!.getView('viw2'); - expect(view2).toBeTruthy(); - - const records = await view2!.getRecords({ - maxRecords: 4, - pagination: { - pageNum: 2, - pageSize: 3, - }, - }); - - const recordIds = records.map(record => record.id); - - expect(recordIds).toStrictEqual(['rec1']); - }); }); describe('addRecords', () => { @@ -322,7 +127,7 @@ describe('addRecords', () => { index: 3, count: 2, }, - {}, + {} ); expect(result.result).toStrictEqual(ExecuteResult.Success); @@ -407,7 +212,7 @@ describe('addRecords', () => { }, ], }, - {}, + {} ); expect(result.result).toStrictEqual(ExecuteResult.Success); @@ -495,7 +300,7 @@ describe('modify view', () => { key: 'name', value: 'VIEW_1', }, - {}, + {} ); expect(result.result).toStrictEqual(ExecuteResult.Success); @@ -560,7 +365,7 @@ describe('modify view', () => { key: 'columns', value: [{ fieldId: 'fld2', hidden: true }], }, - {}, + {} ); expect(result.result).toStrictEqual(ExecuteResult.Success); diff --git a/packages/core/src/databus/logic/view.ts b/packages/core/src/databus/logic/view.ts index 9811e4c5db..e4505add62 100644 --- a/packages/core/src/databus/logic/view.ts +++ b/packages/core/src/databus/logic/view.ts @@ -18,14 +18,12 @@ import { CollaCommandName, IModifySelfView, IMoveSelfView } from 'commands'; import { IFieldMap, IRecordCellValue, IReduxState, IViewColumn, IViewLockInfo, IViewProperty, IViewRow } from 'exports/store/interfaces'; -import { ViewType } from 'modules/shared/store/constants'; -import { - getSnapshot, -} from 'modules/database/store/selectors/resource/datasheet/base'; -import { getViewIndex } from 'modules/database/store/selectors/resource/datasheet/calc'; import { keyBy } from 'lodash'; import { ICellValue } from 'model/record'; import { getViewClass } from 'model/views'; +import { getSnapshot } from 'modules/database/store/selectors/resource/datasheet/base'; +import { getViewIndex } from 'modules/database/store/selectors/resource/datasheet/calc'; +import { ViewType } from 'modules/shared/store/constants'; import { Store } from 'redux'; import type { Datasheet, ICommandExecutionResult, ISaveOptions } from './datasheet'; import { Field } from './field'; @@ -41,7 +39,11 @@ export class View { * * @internal This constructor is not intended for public use. */ - constructor(private readonly datasheet: Datasheet, private readonly store: Store, info: IViewInfo) { + constructor( + private readonly datasheet: Datasheet, + private readonly store: Store, + info: IViewInfo + ) { const { property, fieldMap } = info; this.property = property; @@ -97,31 +99,13 @@ export class View { /** * Get records in the view. */ - public getRecords(options: IRecordsOptions): Promise { + public getRecords(): Promise { const { store, fieldMap } = this; const snapshot = getSnapshot(store.getState()); if (!snapshot) { return Promise.resolve([]); } - const { pagination, maxRecords } = options; - - // Pagination - let pageRows = this.rows; - if (maxRecords !== undefined && maxRecords < this.rows.length) { - pageRows = this.rows.slice(0, maxRecords); - } - - if (pagination !== undefined) { - const start = (pagination.pageNum - 1) * pagination.pageSize; - const end = start + pagination.pageSize; - pageRows = pagination.pageSize == -1 ? pageRows : pageRows.slice(start, end); - } - - if (pageRows.length === 0) { - return Promise.resolve([]); - } - const recordMap = snapshot.recordMap; const fieldKeys = Object.keys(this.fieldMap); const columnMap = keyBy(this.columns, 'fieldId'); @@ -133,12 +117,12 @@ export class View { }; const records: Record[] = []; - for (const row of pageRows) { + for (const row of this.rows) { if (recordMap[row.recordId]) { records.push( new Record(recordMap[row.recordId]!, { voTransformOptions, - }), + }) ); } } @@ -158,7 +142,7 @@ export class View { ...recordOptions, viewId: this.id, }, - saveOptions, + saveOptions ); } @@ -203,7 +187,7 @@ export class View { data: lockInfo, viewId: this.id, }, - saveOptions, + saveOptions ); } @@ -219,7 +203,7 @@ export class View { autoSave, viewId: this.id, }, - saveOptions, + saveOptions ); } @@ -276,42 +260,42 @@ export interface IRecordsOptions { export type IAddRecordsOptions = | { - /** - * The position where new records will be inserted. - */ - index: number; - - /** - * The number of new records. All cells of new records are set to default values, or left empty if no - * default values are set for corresponding fields. - */ - count: number; - - /** - * The cell values of the group which the new records belongs to. - */ - groupCellValues?: ICellValue[]; - - ignoreFieldPermission?: boolean; -} + /** + * The position where new records will be inserted. + */ + index: number; + + /** + * The number of new records. All cells of new records are set to default values, or left empty if no + * default values are set for corresponding fields. + */ + count: number; + + /** + * The cell values of the group which the new records belongs to. + */ + groupCellValues?: ICellValue[]; + + ignoreFieldPermission?: boolean; + } | { - /** - * The position where new records will be inserted. - */ - index: number; - - /** - * New record values. - */ - recordValues: IRecordCellValue[]; - - /** - * The cell values of the group which the new records belongs to. - */ - groupCellValues?: ICellValue[]; - - ignoreFieldPermission?: boolean; -}; + /** + * The position where new records will be inserted. + */ + index: number; + + /** + * New record values. + */ + recordValues: IRecordCellValue[]; + + /** + * The cell values of the group which the new records belongs to. + */ + groupCellValues?: ICellValue[]; + + ignoreFieldPermission?: boolean; + }; /** * The options for getting fields in a view. diff --git a/packages/core/src/engine/buffer_storage.ts b/packages/core/src/engine/buffer_storage.ts index 14ded4b788..7be39b78b6 100644 --- a/packages/core/src/engine/buffer_storage.ts +++ b/packages/core/src/engine/buffer_storage.ts @@ -20,6 +20,7 @@ import { LS_DATASHEET_NAMESPACE } from 'config/constant'; import { ResourceType } from 'types'; import { generateRandomString } from 'utils'; import { composeOperations, ILocalChangeset, IOperation } from './ot'; +import { isClient } from 'utils/env'; // Local cache processing interface export interface IStoredData { @@ -193,8 +194,14 @@ export class BufferStorage { } static ops2Changeset(ops: IOperation[], revision: number, resourceId: string, resourceType: ResourceType): ILocalChangeset { + const messageId = generateRandomString(); + if (isClient()) { + // register the messageId to event manager + new CustomEvent(messageId); + localStorage.setItem('doing_op_messageId', messageId); + } return { - messageId: generateRandomString(), + messageId, baseRevision: revision, resourceId, resourceType, diff --git a/packages/core/src/event_manager/events/datasheet/cell_updated.ts b/packages/core/src/event_manager/events/datasheet/cell_updated.ts index 7b3e1af3b6..9f7b1e1f12 100644 --- a/packages/core/src/event_manager/events/datasheet/cell_updated.ts +++ b/packages/core/src/event_manager/events/datasheet/cell_updated.ts @@ -31,6 +31,7 @@ import { ResourceType } from 'types/resource_types'; import { IAtomEventType, ICellUpdatedContext } from '../interface'; import { EventAtomTypeEnums, EventRealTypeEnums, EventSourceTypeEnums, OPEventNameEnums } from './../../enum'; import { IEventInstance, IOPBaseContext, IOPEvent, IVirtualAtomEvent } from './../../interface/event.interface'; +import { CacheManager } from 'cache_manager'; // @EventMeta(OPEventNameEnums.CellUpdated) export class OPEventCellUpdated extends IAtomEventType { @@ -109,6 +110,11 @@ export class OPEventCellUpdated extends IAtomEventType { if (!relatedLinkField) { return; } + // https://github.com/vikadata/vikadata/issues/9875 + // if relate field type is OneWayLink. clear old lookup field values + if (relatedLinkField.type === FieldType.OneWayLink) { + CacheManager.removeCellCache(_datasheetId, field.id); + } let triggerRecIds: string[] = []; // 2. The same table triggers a lookup update, which must be associated with the table. // The sibling field of the associated link field is itself @@ -131,6 +137,15 @@ export class OPEventCellUpdated extends IAtomEventType { const brotherFieldId = (relatedLinkField as ILinkField).property?.brotherFieldId!; // 3. The recordIds affected by this cell update triggerRecIds = getCellValue(state, snapshot, recordId, brotherFieldId); + if (relatedLinkField.type === FieldType.OneWayLink) { + const _snapshot = getSnapshot(state, _datasheetId)!; + const _records = Object.values(_snapshot.recordMap); + const filterRecords = _records.filter(record => { + const recordData = record?.data[relatedLinkField.id] as string[] | undefined; + return recordData && recordData.includes(recordId); + }); + triggerRecIds = filterRecords.map(record => record.id); + } } // TODO: The value of the link field cell must be null or an array. // Due to the existence of dirty data, we first judge whether it is an array type before processing it. Delete data after cleaning? diff --git a/packages/core/src/exports/api/index.ts b/packages/core/src/exports/api/index.ts index 6fe377e17f..f0839c0c44 100644 --- a/packages/core/src/exports/api/index.ts +++ b/packages/core/src/exports/api/index.ts @@ -87,7 +87,7 @@ const onResponse = (response: AxiosResponse) => { }; const createAxios = (config: AxiosRequestConfig) => { const http = axios.create(Object.assign({ - timeout: 20 * 1000, + timeout: 60 * 1000, withCredentials: true, }, config)); http.interceptors.response.use(onResponse, onResponseError); diff --git a/packages/core/src/exports/i18n/index.ts b/packages/core/src/exports/i18n/index.ts index 016bb654e1..9574f8f2fd 100644 --- a/packages/core/src/exports/i18n/index.ts +++ b/packages/core/src/exports/i18n/index.ts @@ -20,9 +20,13 @@ * read strings.auto.json, go translation */ import { I18N } from '@apitable/i18n'; +import LANGUAGE_DATA from '@apitable/i18n-lang/src/config/strings.json'; import type { StringKeysMapType, StringKeysType } from '../../config/stringkeys.interface'; -export * from '../../config/stringkeys.interface'; +export { StringKeysMapType, StringKeysType }; + +// @ts-ignore nextjs +const isBrowser = process.browser || typeof window !== 'undefined'; export const Strings = new Proxy({} as Record, { get: function (_target, key: string) { @@ -37,19 +41,59 @@ declare const window: any; declare const global: any; const _global = global || window; +const getBrowserLanguage = (): string | undefined => { + if (_global.browserLang){ + return _global.browserLang; + } + // @ts-ignore + const languageMap = _global.languageManifest; + + if (!_global.navigator || !languageMap) { + return undefined; + } + let userLanguage: string | undefined = _global.navigator.language as string; + if (userLanguage){ + userLanguage = userLanguage.replace(/-(.+)/g, (match, group1) => { + return `-${group1.toUpperCase()}`; + }); + } + if (userLanguage === 'zh-TW') { + userLanguage = 'zh-HK'; + } + if (userLanguage?.startsWith('en')) { + userLanguage = 'en-US'; + } + if (!languageMap[userLanguage]) { + userLanguage = undefined; + const langArr = Object.keys(languageMap); + if (langArr) { + for (let i = 0; i < langArr.length; i++) { + // @ts-ignore + if (langArr[i] !== undefined && langArr[i].indexOf(userLanguage) > -1) { + userLanguage = langArr[i]; + break; + } + } + } + } + _global.browserLang = userLanguage; + return userLanguage; +}; export function getLanguage() { let clientLang = null; - if (typeof window !== 'undefined') { + if (isBrowser) { try { // @ts-ignore clientLang = localStorage.getItem('client-lang'); } catch (e) {} } + const browserLang = getBrowserLanguage(); + // console.log('browser language is', browserLang); const language = typeof _global == 'object' && _global.__initialization_data__ && _global.__initialization_data__.locale != 'und' && _global.__initialization_data__.locale; const defaultLang = (typeof _global == 'object' && _global.__initialization_data__?.envVars?.SYSTEM_CONFIGURATION_DEFAULT_LANGUAGE) || 'zh-CN'; - return clientLang || language || defaultLang; + return clientLang || browserLang || language || defaultLang; } const fetchLanguagePack = (lang: string, data: any) => { @@ -76,52 +120,9 @@ const fetchLanguagePack = (lang: string, data: any) => { } }; -// get English language pack asynchronously -const fetchLanguagePackAsync = (lang: string, data: any) => { - const version = window.__initialization_data__.version; - // @ts-ignore - fetch(`/file/langs/strings.${lang}.json?version=${version}`) - .then((response: any) => { - if (!response.ok) { - throw new Error('get lang pack error: ' + response.status); - } - return response.json(); // 解析响应为JSON格式 - }) - .then((langPack: any) => { - data[lang] = langPack; - if (_global.apitable_i18n){ - _global.apitable_i18n[lang] = langPack; - } - }); -}; - -const loadLanguage = (lang: string) => { - // console.log('start load language', lang); - let data = {}; - if (typeof window !== 'undefined') { - fetchLanguagePack(lang, data); - if (lang != 'en-US') { - fetchLanguagePackAsync('en-US', data); - } - } else { - try { - // load language for room-server. suitable for docker environment - const fs = require('fs'); - const jsonData = fs.readFileSync(`${__dirname}/../../../../i18n-lang/src/config/strings.json`); - data = JSON.parse(jsonData); - } catch (_e) { - // load language for frontend - try { - const path = require('path'); - const fs = require('fs'); - const pagesDirectory = path.resolve(process.cwd(), '../i18n-lang/src/config/strings.json'); - const jsonData = fs.readFileSync(pagesDirectory); - data = JSON.parse(jsonData); - } catch (error) { - console.error('load strings.json error', error); - } - } - } +const loadClientLanguage = (lang: string) => { + const data = {}; + fetchLanguagePack(lang, data); return data; }; @@ -135,28 +136,26 @@ const rewriteI18nForEdition = () => { } } +}; + +// browser only +if (isBrowser) { + require('@apitable/i18n-lang'); + if (_global.apitable_language_list && Object.keys(_global.apitable_language_list).length > 0) { _global.languageManifest = _global.apitable_language_list; } -}; +} const currentLang = getLanguage().replace('_', '-'); _global.currentLang = currentLang; -_global.apitable_i18n = loadLanguage(currentLang); -// browser only -if (typeof window !== 'undefined') { - require('@apitable/i18n-lang'); -} +_global.apitable_i18n = isBrowser ? loadClientLanguage(currentLang) : LANGUAGE_DATA; + rewriteI18nForEdition(); const i18n = I18N.createByLanguagePacks(_global.apitable_i18n, currentLang); -let engI18n: I18N | null = null; -if (currentLang != 'en-US') { - engI18n = I18N.createByLanguagePacks(_global.apitable_i18n, 'en-US'); -} + export function t(stringKey: keyof StringKeysMapType | unknown, options: any = null, isPlural = false): string { const text = i18n.getText(stringKey as string, options, isPlural); - if (currentLang != 'en-US' && !text && engI18n != null && _global.apitable_i18n['en-US']) { - return engI18n.getText(stringKey as string, options, isPlural); - } return text; -} \ No newline at end of file +} + diff --git a/packages/core/src/formula_parser/__tests__/mock_state.ts b/packages/core/src/formula_parser/__tests__/mock_state.ts index 4c84dde7fe..85ac331910 100644 --- a/packages/core/src/formula_parser/__tests__/mock_state.ts +++ b/packages/core/src/formula_parser/__tests__/mock_state.ts @@ -282,6 +282,12 @@ export const generateMockState = (fieldMap: IFieldMap): IReduxState => ({ allVisible: false, isPermission: false, socketData: null, + privateLoading: false, + privateRootId: '', + privateEditNodeId: '', + privateDelNodeId: '', + privateTreeNodesMap: {}, + privateExpandedKeys: [], favoriteTreeNodeIds: [], favoriteLoading: false, favoriteExpandedKeys: [], diff --git a/packages/core/src/formula_parser/functions/date_time.ts b/packages/core/src/formula_parser/functions/date_time.ts index ca7d0b6483..04ebceef29 100644 --- a/packages/core/src/formula_parser/functions/date_time.ts +++ b/packages/core/src/formula_parser/functions/date_time.ts @@ -544,7 +544,7 @@ export class WorkDayDiff extends DateFunc { const isMinus = startDate.valueOf() > endDate.valueOf(); // Whether with a negative sign isMinus && ([startDate, endDate] = [endDate, startDate]); const holidayStrList = params.length > 2 ? String(params[2]!.value).split(',') : []; - const holidays = holidayStrList.filter(v => v !== 'null').map(v => getDayjs(v.trim())); + const holidays = holidayStrList.filter(v => v !== 'null').map(v => getStartOfDay(v.trim())); const weekends = [0, 6]; // specify which days are the weekends const startDay = startDate.day(); @@ -572,12 +572,10 @@ export class WorkDayDiff extends DateFunc { const holiday = holidays[i]!; const holidayDay = holiday.day(); if ( - endDate.isAfter(holiday, 'date') && - ( - startDate.isBefore(holiday, 'date') || - startDate.isSame(holiday, 'date') - ) && - !weekends.includes(holidayDay) + ((endDate.isAfter(holiday, 'date') && startDate.isBefore(holiday, 'date')) // holiday is between start and end date + || endDate.isSame(holiday, 'date') // holiday is the same as the end date + || startDate.isSame(holiday, 'date')) // holiday is the same as the start date + && !weekends.includes(holidayDay) ) { finalCount--; } diff --git a/packages/core/src/io/io.ts b/packages/core/src/io/io.ts index 1504a14da8..6ec06077aa 100644 --- a/packages/core/src/io/io.ts +++ b/packages/core/src/io/io.ts @@ -27,10 +27,14 @@ export interface IRegisterOption { export class IO { private abort = false; // abort link - callbackCache: Map any)> = new Map(); + callbackCache: Map any> = new Map(); - constructor(public roomId: string, public socket: SocketIOClient.Socket) { - } + watchRoomRetryInterval: NodeJS.Timeout | undefined; + + constructor( + public roomId: string, + public socket: SocketIOClient.Socket + ) {} async waitToConnect() { this.abort = false; @@ -52,11 +56,15 @@ export class IO { resolve(); return; } - let retryTimes = 3; + let retryTimes = 5; - const emit = (interval: NodeJS.Timeout) => { + const emit = (interval: NodeJS.Timeout | undefined) => { this.socket.emit(SyncRequestTypes.WATCH_ROOM, { ...params, roomId, shareId, embedLinkId: embedId }, (msg: T) => { - interval && clearInterval(interval as any); + clearInterval(interval); + if (interval !== this.watchRoomRetryInterval) { + resolve(); + return; + } if ('success' in msg && msg.success) { // console.log('watched in ', roomId, this.socket.id, 'msg:', msg); @@ -65,7 +73,7 @@ export class IO { Player.doTrigger(Events.app_error_logger, { error: new Error(`watchRoom failed: ${msg.message}`), metaData: { - socketConnected: this.socket.connected + socketConnected: this.socket.connected, }, }); reject(msg); @@ -76,20 +84,22 @@ export class IO { const interval = setInterval(() => { if (retryTimes < 0) { clearInterval(interval); - reject('The link with the server has not been established successfully, please refresh and try again. \ - If you have any questions, please scan the QR code on the right to add customer service, and let us help you solve'); + reject( + 'The link with the server has not been established successfully, please refresh and try again. \ + If you have any questions, please scan the QR code on the right to add customer service, and let us help you solve' + ); } retryTimes--; emit(interval); - }, 5 * 1000); - + }, 3 * 1000); + this.watchRoomRetryInterval = interval; emit(interval); }); } request(params: P): Promise { if (!this.socket) { - throw new Error('socket didn\'t prepared'); + throw new Error("socket didn't prepared"); } // console.log('Send data:', params); @@ -102,6 +112,9 @@ export class IO { unWatch() { this.abort = true; + clearInterval(this.watchRoomRetryInterval); + this.watchRoomRetryInterval = undefined; + return new Promise((resolve) => { this.socket.emit(SyncRequestTypes.LEAVE_ROOM, { roomId: this.roomId }, (msg: any) => { console.log('unwatch: ', this.roomId, 'msg:', msg); diff --git a/packages/core/src/model/color.ts b/packages/core/src/model/color.ts index 8be1f25059..13515d4cd5 100644 --- a/packages/core/src/model/color.ts +++ b/packages/core/src/model/color.ts @@ -47,7 +47,7 @@ export const getColorValue = (color: string, alpha: number) => { * 0 => deepPurple_1 * 10 => deepPurple_2 * 11 => indigo_2 - * @param index option.color + * @param index option.color */ export function getFieldOptionColor(index: number) { const hue = COLOR_INDEX_NAME[index % COLOR_INDEX_NAME.length]!; diff --git a/packages/core/src/model/constants.ts b/packages/core/src/model/constants.ts index 32f9572bb0..f882d923e7 100644 --- a/packages/core/src/model/constants.ts +++ b/packages/core/src/model/constants.ts @@ -22,7 +22,7 @@ import { isServer } from 'utils/env'; // album(gallery) view has no cover field ID export const NO_COVER_FIELD_ID = 'NO_COVER_FIELD_ID'; -export const DEFAULT_TIME_ZONE = isServer() && (process.env.TZ || process.env.TIMEZONE) || 'America/Toronto'; +export const DEFAULT_TIME_ZONE = (isServer() && (process.env.TZ || process.env.TIMEZONE)) || 'UTC'; export const ValueTypeMap = { [BasicValueType.Number]: 'number', diff --git a/packages/core/src/model/field/__tests__/open/multi_select_field.test.ts b/packages/core/src/model/field/__tests__/open/multi_select_field.test.ts index af5a64ecf4..38be4ce779 100644 --- a/packages/core/src/model/field/__tests__/open/multi_select_field.test.ts +++ b/packages/core/src/model/field/__tests__/open/multi_select_field.test.ts @@ -126,7 +126,7 @@ const writeOpenProperty: IUpdateOpenMultiSelectFieldProperty = { describe('Multiple selection fields read property format check', () => { const valid = getOpenFieldProperty(singleSelectField); - it('correct property', function() { + it('correct property', function () { const [expectValue, receiveValue] = valid(openSingleSelectField.property); expect(receiveValue).toEqual(expectValue); }); diff --git a/packages/core/src/model/field/__tests__/open/single_select_field.test.ts b/packages/core/src/model/field/__tests__/open/single_select_field.test.ts index 553eb05d95..dd31eec8c4 100644 --- a/packages/core/src/model/field/__tests__/open/single_select_field.test.ts +++ b/packages/core/src/model/field/__tests__/open/single_select_field.test.ts @@ -88,7 +88,7 @@ const writeOpenPropertyDelete: IUpdateOpenSingleSelectFieldProperty = { options: [{ id: 'opt000', name: 'Test Label 1', - color: getFieldOptionColor(1).name + color: 1 }] }; @@ -96,17 +96,17 @@ const writeOpenProperty: IUpdateOpenSingleSelectFieldProperty = { options: [{ id: 'opt000', name: 'Test Label 1', - color: getFieldOptionColor(1).name + color: 1 }, { id: 'opt001', name: 'Test Label 2', - color: getFieldOptionColor(2).name + color: 2 }] }; describe('Radio field read property format check', () => { const valid = getOpenFieldProperty(singleSelectField); - it('correct property', function() { + it('correct property', function () { const [expectValue, receiveValue] = valid(openSingleSelectField.property); expect(receiveValue).toEqual(expectValue); }); diff --git a/packages/core/src/model/field/attachment_field.ts b/packages/core/src/model/field/attachment_field.ts index 273b596b2e..ecb9478b56 100644 --- a/packages/core/src/model/field/attachment_field.ts +++ b/packages/core/src/model/field/attachment_field.ts @@ -36,7 +36,7 @@ const baseAttachmentFieldSchema = { name: Joi.string().required(), mimeType: Joi.string().required(), token: Joi.string().required(), - bucket: Joi.string().required(), + bucket: Joi.string(), size: Joi.number().required(), width: Joi.number(), height: Joi.number(), diff --git a/packages/core/src/model/field/cascader_field.ts b/packages/core/src/model/field/cascader_field.ts index 11b62e1fd6..f0dd2b169d 100644 --- a/packages/core/src/model/field/cascader_field.ts +++ b/packages/core/src/model/field/cascader_field.ts @@ -1,14 +1,14 @@ import Joi from 'joi'; -import { FieldType, IField, ICascaderField, ISegment } from 'types/field_types'; +import { FieldType, ICascaderField, IField, ISegment } from 'types/field_types'; import { DatasheetActions } from '../../commands_actions/datasheet'; -import { TextBaseField } from './text_base_field'; -import { ICellValue } from '../record'; import { Strings, t } from '../../exports/i18n'; -import { FOperator, IFilterText } from '../../types'; -import { getFieldDefaultProperty } from './const'; +import { FOperator, IAPIMetaTextBaseFieldProperty, IFilterText } from '../../types'; import { ICascaderProperty } from '../../types/field_types'; -export class CascaderField extends TextBaseField { +import { ICellValue } from '../record'; +import { getFieldDefaultProperty } from './const'; +import { TextBaseField } from './text_base_field'; +export class CascaderField extends TextBaseField { static defaultProperty() { return getFieldDefaultProperty(FieldType.Cascader) as ICascaderProperty; } @@ -17,17 +17,24 @@ export class CascaderField extends TextBaseField { showAll: Joi.bool().required(), linkedDatasheetId: Joi.string().required(), linkedViewId: Joi.string().required(), - linkedFields: Joi.array().items(Joi.object({ - id: Joi.string().required(), - name: Joi.string().required(), - type: Joi.number().required(), - })).required(), - fullLinkedFields: Joi.array().items(Joi.object({ - id: Joi.string().required(), - name: Joi.string().required(), - type: Joi.number().required(), - })).required(), - + linkedFields: Joi.array() + .items( + Joi.object({ + id: Joi.string().required(), + name: Joi.string().required(), + type: Joi.number().required(), + }), + ) + .required(), + fullLinkedFields: Joi.array() + .items( + Joi.object({ + id: Joi.string().required(), + name: Joi.string().required(), + type: Joi.number().required(), + }), + ) + .required(), }).required(); static createDefault(fieldMap: { [fieldId: string]: IField }): ICascaderField { @@ -58,13 +65,17 @@ export class CascaderField extends TextBaseField { } const showAll = this.field.property.showAll; const cv = [cellValue].flat(); - return (cv as ISegment[]).map(seg => { - if (!showAll) { - const segArr = seg.text.split('/'); - return segArr[segArr.length - 1]; - } - return seg.text; - }).join('') || null; + return ( + (cv as ISegment[]) + .map((seg) => { + if (!showAll) { + const segArr = seg.text.split('/'); + return segArr[segArr.length - 1]; + } + return seg.text; + }) + .join('') || null + ); } cellValueToFullString(cellValue: ICellValue): string | null { @@ -72,7 +83,7 @@ export class CascaderField extends TextBaseField { return null; } const cv = [cellValue].flat(); - return (cv as ISegment[]).map(seg => seg.text).join('') || null; + return (cv as ISegment[]).map((seg) => seg.text).join('') || null; } override isMeetFilter(operator: FOperator, cellValue: ISegment[] | null, conditionValue: Exclude) { @@ -80,7 +91,11 @@ export class CascaderField extends TextBaseField { return TextBaseField._isMeetFilter(operator, cellText, conditionValue, { containsFn: (filterValue: string) => cellText != null && this.stringInclude(cellText, filterValue), doesNotContainFn: (filterValue: string) => cellText == null || !this.stringInclude(cellText, filterValue), - defaultFn: () => super.isMeetFilter(operator, cellValue, conditionValue) + defaultFn: () => super.isMeetFilter(operator, cellValue, conditionValue), }); } + + override get apiMetaProperty(): IAPIMetaTextBaseFieldProperty { + return { ...this.field.property, fullLinkedFields: undefined }; + } } diff --git a/packages/core/src/model/field/const.ts b/packages/core/src/model/field/const.ts index ad07da78c1..42372cf036 100644 --- a/packages/core/src/model/field/const.ts +++ b/packages/core/src/model/field/const.ts @@ -1,14 +1,15 @@ import { IUnitValue } from '../../exports/store/interfaces'; -import { t,Strings } from '../../exports/i18n'; +import { t, Strings } from '../../exports/i18n'; import { ButtonStyleType } from 'types'; import { CollectType, SymbolAlign, IUnitIds, FieldType, DateFormat, TimeFormat } from 'types/field_types'; +import { AutomationConstant } from './button_field'; export enum OtherTypeUnitId { Self = 'Self', // used to identify the current user Alien = 'Alien', // used to identify anonymous } // scientific notation threshold -export const numberThresholdValue = 1e+16; +export const numberThresholdValue = 1e16; export function polyfillOldData(cellValue: IUnitIds | null) { if (!cellValue) { @@ -17,7 +18,7 @@ export function polyfillOldData(cellValue: IUnitIds | null) { if (!Array.isArray(cellValue)) { return null; } - return cellValue.map(item => { + return cellValue.map((item) => { if (typeof item === 'object') { // old data only returns unitId return (item as IUnitValue).unitId; @@ -42,7 +43,7 @@ export const getFieldDefaultProperty = (fieldType: FieldType) => { text: t(Strings.button_text_click_start), style: { type: ButtonStyleType.Background, - color: 50, + color: AutomationConstant.defaultColor, }, action: {}, }; @@ -75,7 +76,7 @@ export const getFieldDefaultProperty = (fieldType: FieldType) => { return { symbol: '$', precision: 2, - symbolAlign: SymbolAlign.default + symbolAlign: SymbolAlign.default, }; case FieldType.DateTime: return { @@ -89,7 +90,7 @@ export const getFieldDefaultProperty = (fieldType: FieldType) => { case FieldType.Formula: return { expression: '', - datasheetId: '' + datasheetId: '', }; case FieldType.LastModifiedBy: return { @@ -125,7 +126,7 @@ export const getFieldDefaultProperty = (fieldType: FieldType) => { case FieldType.Number: return { precision: 0, - symbolAlign: SymbolAlign.right + symbolAlign: SymbolAlign.right, }; case FieldType.Percent: return { @@ -156,4 +157,3 @@ export const getFieldDefaultProperty = (fieldType: FieldType) => { } return null; }; - diff --git a/packages/core/src/model/field/date_time_base_field.ts b/packages/core/src/model/field/date_time_base_field.ts index 702fc144a2..f7b71dc4ec 100644 --- a/packages/core/src/model/field/date_time_base_field.ts +++ b/packages/core/src/model/field/date_time_base_field.ts @@ -704,7 +704,7 @@ export abstract class DateTimeBaseField extends Field { } cellValueToOpenValue(cellValue: ICellValue): string | null { - return cellValue ? this.cellValueToString(cellValue) : null; + return cellValue ? this.cellValueToString(cellValue): null; } openWriteValueToCellValue(openWriteValue: string | Date | null) { diff --git a/packages/core/src/model/field/field.ts b/packages/core/src/model/field/field.ts index 1add47acc2..62df31af96 100644 --- a/packages/core/src/model/field/field.ts +++ b/packages/core/src/model/field/field.ts @@ -22,7 +22,6 @@ import { getColorNames } from 'model/color'; import type { IBindFieldContext, IBindFieldModel } from 'model/field'; import { getFieldTypeString } from 'model/utils'; import { getViewsList } from 'modules/database/store/selectors/resource/datasheet/base'; -// import { IReduxState } from 'exports/store/interfaces'; import { getPermissions } from 'modules/database/store/selectors/resource/datasheet/calc'; import type { IAPIMetaFieldProperty } from 'types/field_api_property_types'; import type { IAPIMetaField } from 'types/field_api_types'; diff --git a/packages/core/src/model/field/index.ts b/packages/core/src/model/field/index.ts index 3818cb60cc..967beeab64 100644 --- a/packages/core/src/model/field/index.ts +++ b/packages/core/src/model/field/index.ts @@ -1,3 +1,21 @@ +/** + * APITable + * Copyright (C) 2022 APITable Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + import { Store } from 'redux'; import { FieldType, @@ -87,6 +105,7 @@ export * from './created_by_field'; export * from './last_modified_by_field'; export * from './text_base_field'; export * from './workdoc_field'; +export * from './button_field'; export * from './utils'; export { numberThresholdValue, OtherTypeUnitId } from './const'; diff --git a/packages/core/src/model/field/link_field.ts b/packages/core/src/model/field/link_field.ts index 7589db2716..675570612d 100644 --- a/packages/core/src/model/field/link_field.ts +++ b/packages/core/src/model/field/link_field.ts @@ -157,9 +157,10 @@ export class LinkField extends ArrayValueField { if (!snapshot) { return false; } + const archivedRecordIds = snapshot.meta.archivedRecordIds || []; if (Array.isArray(value)) { return value.every(recordId => { - if (snapshot.recordMap[recordId]) { + if (snapshot.recordMap[recordId] || archivedRecordIds.includes(recordId)) { return true; } return false; @@ -303,7 +304,7 @@ export class LinkField extends ArrayValueField { data: [], }; - if (recordIds) { + if (recordIds && Array.isArray(recordIds)) { stdVal.data = recordIds.map(recordId => { const text = this.getLinkedRecordCellString(recordId) || t(Strings.record_unnamed); return { diff --git a/packages/core/src/model/field/member_base_field.ts b/packages/core/src/model/field/member_base_field.ts index a85b408570..e9230d935c 100644 --- a/packages/core/src/model/field/member_base_field.ts +++ b/packages/core/src/model/field/member_base_field.ts @@ -210,10 +210,13 @@ export abstract class MemberBaseField extends ArrayValueField { }; if (!cellValue) return stdValue; const nameValues = this.cellValueToArray(cellValue); + const isString = typeof cellValue === 'string'; if (!nameValues) return stdValue; - nameValues.forEach(item => { + nameValues.forEach((item, idx) => { stdValue.data.push({ text: item, + unitId: isString ? undefined : cellValue[idx], + uuid: isString ? cellValue : undefined, }); }); return stdValue; diff --git a/packages/core/src/model/field/member_field.ts b/packages/core/src/model/field/member_field.ts index aaaa325012..422e9fddb9 100644 --- a/packages/core/src/model/field/member_field.ts +++ b/packages/core/src/model/field/member_field.ts @@ -151,9 +151,12 @@ export class MemberField extends MemberBaseField { // it is necessary to first find the members that are activated and not deleted, so all data must be checked const unitNames = Array.from(new Set(stdValue.data.map(d => d.text.split(/, ?/)).flat())); const cvMap = new Map(); - for (const name of unitNames) { + unitNames.forEach((name, index) => { + const unitId = stdValue.data[index]?.unitId; + const uuid = stdValue.data[index]?.uuid; for (const unit of unitValue) { - if (unit.name !== name) { + const isCurrentUnit = unitId ? unit.unitId === unitId : uuid ? unit.uuid === uuid : unit.name === name; + if (!isCurrentUnit) { continue; } cvMap.set(name, unit.unitId); @@ -161,7 +164,7 @@ export class MemberField extends MemberBaseField { break; } } - } + }); return cvMap.size ? [...cvMap.values()] : null; } diff --git a/packages/core/src/model/field/one_way_link_field.ts b/packages/core/src/model/field/one_way_link_field.ts index 1a07a122be..04d4514139 100644 --- a/packages/core/src/model/field/one_way_link_field.ts +++ b/packages/core/src/model/field/one_way_link_field.ts @@ -137,8 +137,9 @@ export class OneWayLinkField extends ArrayValueField { if (!snapshot) { return []; } + const archivedRecordIds = snapshot.meta.archivedRecordIds || []; if (Array.isArray(value)) { - return value.filter(recordId => snapshot.recordMap[recordId]); + return value.filter(recordId => snapshot.recordMap[recordId] || archivedRecordIds.includes(recordId)); } return []; } @@ -148,12 +149,11 @@ export class OneWayLinkField extends ArrayValueField { if (!snapshot) { return false; } + const archivedRecordIds = snapshot.meta.archivedRecordIds || []; if (Array.isArray(value)) { return value.every(recordId => { - if (snapshot.recordMap[recordId]) { - return true; - } - return false; + return !!(snapshot.recordMap[recordId] || archivedRecordIds.includes(recordId)); + }); } return false; diff --git a/packages/core/src/model/field/select_field/common_select_field.ts b/packages/core/src/model/field/select_field/common_select_field.ts index 2fc70641ae..95906ceff5 100644 --- a/packages/core/src/model/field/select_field/common_select_field.ts +++ b/packages/core/src/model/field/select_field/common_select_field.ts @@ -18,7 +18,7 @@ import { IReduxState } from 'exports/store'; import Joi from 'joi'; -import { difference, isString, keyBy, memoize, range } from 'lodash'; +import { difference, has, isString, keyBy, memoize, range } from 'lodash'; import { getFieldOptionColor } from 'model/color'; import { IAPIMetaSingleSelectFieldProperty } from 'types/field_api_property_types'; import { FieldType, IMultiSelectedIds, ISelectField, ISelectFieldOption, ISelectFieldProperty, IStandardValue } from 'types/field_types'; @@ -271,7 +271,7 @@ export abstract class SelectField extends Field { validateWriteOpenOptionsEffect(updateProperty: IWriteOpenSelectBaseFieldProperty, effectOption?: IEffectOption): Joi.ValidationResult { // Not allowed to pass option parameter with ID but no color - if (updateProperty.options.some(option => option.id && !option.color)) { + if (updateProperty.options.some(option => option.id && !has(option, 'color'))) { return joiErrorResult('Option object is not supported. It has id but no color'); } // Check if this update removes options @@ -290,7 +290,7 @@ export abstract class SelectField extends Field { let transformedDefaultValue = defaultValue; const transformedOptions = options.map(option => { if (!option.id || !option.color) { - const color = option.color ? this.getOptionColorNumberByName(option.color) : undefined; + const color = option.color ? (typeof option.color === 'number' ? option.color : this.getOptionColorNumberByName(option.color)) : undefined; // prevent duplicate option IDs const newOption = SelectField._createNewOption({ name: option.name, color }, [...this.field.property.options, ...newOptions]); transformedDefaultValue = this.transformDefaultValue(newOption, transformedDefaultValue); @@ -300,7 +300,7 @@ export abstract class SelectField extends Field { return { id: option.id, name: option.name, - color: this.getOptionColorNumberByName(option.color)! + color: typeof option.color === 'number' ? option.color : this.getOptionColorNumberByName(option.color)!, }; }); return { diff --git a/packages/core/src/model/field/select_field/multi_select_field.ts b/packages/core/src/model/field/select_field/multi_select_field.ts index 5dc9f802a3..73f1d9fc80 100644 --- a/packages/core/src/model/field/select_field/multi_select_field.ts +++ b/packages/core/src/model/field/select_field/multi_select_field.ts @@ -338,7 +338,7 @@ export class MultiSelectField extends SelectField { options: Joi.array().items(Joi.object({ id: Joi.string(), name: Joi.string().required(), - color: Joi.string(), + color: Joi.alternatives(Joi.number(), Joi.string()) })).required(), defaultValue: Joi.array().items(Joi.string()) }).required(); diff --git a/packages/core/src/model/field/select_field/single_select_field.ts b/packages/core/src/model/field/select_field/single_select_field.ts index 68a3195e90..6a2abd092d 100644 --- a/packages/core/src/model/field/select_field/single_select_field.ts +++ b/packages/core/src/model/field/select_field/single_select_field.ts @@ -261,7 +261,7 @@ export class SingleSelectField extends SelectField { options: Joi.array().items(Joi.object({ id: Joi.string(), name: Joi.string().required(), - color: Joi.string(), + color: Joi.alternatives(Joi.number(), Joi.string()) })).required(), defaultValue: Joi.string() }).required(); diff --git a/packages/core/src/model/filter_data_structure_parse.ts b/packages/core/src/model/filter_data_structure_parse.ts index 4afbbe0994..dec42a7303 100644 --- a/packages/core/src/model/filter_data_structure_parse.ts +++ b/packages/core/src/model/filter_data_structure_parse.ts @@ -180,7 +180,8 @@ export function parseInnerFilter(filterInfo: IOpenFilterInfo, context: { const operator = Object.keys(filterValueMap)[0]; exitIds.push(conditionId); const fieldValue = filterValueMap[operator]; - const isSingleContains = field.type === FieldType.SingleSelect && operator === FOperator.Contains; + const isSingleContains = (field.type === FieldType.SingleSelect || field.type === FieldType.LookUp) && + (operator === FOperator.Contains || operator === FOperator.DoesNotContain); let value; if (isSingleContains) { value = Array.isArray(fieldValue) ? @@ -209,7 +210,10 @@ export function parseInnerFilter(filterInfo: IOpenFilterInfo, context: { function openFilterValueToFilterValueInterceptor(fieldModel: Field, fieldValue: IFilterSingleSelect, operator: OperatorEnums, fieldType: FieldType){ const ensuredArrayValue = Array.isArray(fieldValue)? fieldValue: [fieldValue]; - if (fieldType === FieldType.SingleSelect && operator === OperatorEnums.Contains) { + if ( + (fieldType === FieldType.SingleSelect || fieldType === FieldType.LookUp) && + (operator === OperatorEnums.Contains || operator === OperatorEnums.DoesNotContain) + ) { return ensuredArrayValue.map(item => fieldModel.openFilterValueToFilterValue(item)).flat(); } return fieldModel.openFilterValueToFilterValue(fieldValue); @@ -220,7 +224,10 @@ function filterValueToOpenFilterValueInterceptor(fieldModel: Field, value: IFilt return fieldModel.filterValueToOpenFilterValue(value); } const arrayValue: IFilterSingleSelect = Array.isArray(value) ? value : [value]; - if (operator === OperatorEnums.Contains && fieldType == FieldType.SingleSelect) { + if ( + (operator === OperatorEnums.Contains || operator === OperatorEnums.DoesNotContain) && + (fieldType === FieldType.SingleSelect || fieldType === FieldType.LookUp) + ) { return arrayValue.map((option: string) => fieldModel.filterValueToOpenFilterValue([option])) .filter(Boolean); } diff --git a/packages/core/src/model/linked_data_conformance_maintainer.ts b/packages/core/src/model/linked_data_conformance_maintainer.ts index 2cfb2194ed..d72a272344 100644 --- a/packages/core/src/model/linked_data_conformance_maintainer.ts +++ b/packages/core/src/model/linked_data_conformance_maintainer.ts @@ -175,7 +175,7 @@ export class LinkedDataConformanceMaintainer { // Make sure that the cell is populated only when the foreign key field is indeed the relation field type. const cellValueInLinkedCell = (fieldType === FieldType.Link || fieldType === FieldType.OneWayLink) ? getCellValue(state, snapshot, recordId, fieldId, undefined, undefined, true) as string[] || [] : []; - let newLinkedCellValue: string[] | null = without(cellValueInLinkedCell, ...changeIds.del); + let newLinkedCellValue: string[] | null = without(cellValueInLinkedCell, ...changeIds.del, ...changeIds.add); newLinkedCellValue.push(...changeIds.add); newLinkedCellValue = handleEmptyCellValue(newLinkedCellValue, BasicValueType.Array); const action = DatasheetActions.setRecord2Action( diff --git a/packages/core/src/model/utils/index.ts b/packages/core/src/model/utils/index.ts index e633d4ae5d..9589229343 100644 --- a/packages/core/src/model/utils/index.ts +++ b/packages/core/src/model/utils/index.ts @@ -212,6 +212,10 @@ export const getMaxViewCountPerSheet = () => { return getCustomConfig().MAXIMUM_VIEW_COUNT_PER_DATASHEET || 30; }; +export const getRecordChunkSize = (): number => { + return getCustomConfig().RECORD_CHUCK_SIZE || 500; +}; + export const getFieldTypeString = (fieldType: FieldType): APIMetaFieldType => { return FieldTypeStringMap[fieldType]; }; diff --git a/packages/core/src/modules/billing/store/interfaces/billing.ts b/packages/core/src/modules/billing/store/interfaces/billing.ts index 5e492d9410..4354db4fd4 100644 --- a/packages/core/src/modules/billing/store/interfaces/billing.ts +++ b/packages/core/src/modules/billing/store/interfaces/billing.ts @@ -66,7 +66,9 @@ export interface ISubscription extends ISubscribeResponseData { onTrial: boolean; // ai - maxMessageCredits: number + maxMessageCredits: number; + // form + controlFormBrandLogo?: boolean; } export interface IBillingCatalog { diff --git a/packages/core/src/modules/database/api/datasheet_api.ts b/packages/core/src/modules/database/api/datasheet_api.ts index f569b6ff67..26b943dff9 100644 --- a/packages/core/src/modules/database/api/datasheet_api.ts +++ b/packages/core/src/modules/database/api/datasheet_api.ts @@ -246,6 +246,10 @@ export function addFieldPermissionRole(dstId: string, fieldId: string, option: { return axios.post(urlcat(Url.FIELD_PERMISSION_ADD_ROLE, { dstId, fieldId }), option); } +export function addYachFieldPermissionRole(dstId: string, fieldId: string, option: { role: string; unitIds: string[] }) { + return axios.post(urlcat(Url.FIELD_PERMISSION_YACH_ADD_ROLE, { dstId, fieldId }), option); +} + /** * edit field permission role * diff --git a/packages/core/src/modules/database/api/mirror_api.ts b/packages/core/src/modules/database/api/mirror_api.ts index e6404fc901..4e2e24a1dc 100644 --- a/packages/core/src/modules/database/api/mirror_api.ts +++ b/packages/core/src/modules/database/api/mirror_api.ts @@ -28,6 +28,10 @@ export const fetchMirrorInfo = (mirrorId: string) => { return axios.get(urlcat(Url.READ_MIRROR_INFO, { mirrorId }), { baseURL }); }; +export const fetchEmbedMirrorInfo = (embedId: string, mirrorId: string) => { + return axios.get(urlcat(Url.READ_EMBED_MIRROR_INFO, { embedId, mirrorId }), { baseURL }); +}; + export const fetchMirrorDataPack = (mirrorId: string, recordIds?: string[]) => { return axios.get(urlcat(Url.READ_MIRROR_DATA_PACK, { mirrorId }), { baseURL, @@ -40,6 +44,18 @@ export const fetchMirrorDataPack = (mirrorId: string, recordIds?: string[]) => { }); }; +export const fetchEmbedMirrorDataPack = (embedId: string, mirrorId: string, recordIds?: string[]) => { + return axios.get(urlcat(Url.READ_EMBED_MIRROR_DATA_PACK, { embedId, mirrorId }), { + baseURL, + params: { + recordIds + }, + paramsSerializer: (params) => { + return Qs.stringify(params, { arrayFormat: 'repeat' }); + }, + }); +}; + export const fetchShareMirrorInfo = (shareId: string, mirrorId: string) => { return axios.get(urlcat(Url.READ_SHARE_MIRROR_INFO, { shareId, mirrorId }), { baseURL }); }; diff --git a/packages/core/src/modules/database/api/url.data.ts b/packages/core/src/modules/database/api/url.data.ts index 5eac97b5dc..367366d461 100644 --- a/packages/core/src/modules/database/api/url.data.ts +++ b/packages/core/src/modules/database/api/url.data.ts @@ -25,6 +25,7 @@ export const FETCH_EMBED_DASHBOARD = '/embedlinks/:embedId/dashboards/:dashboard // =============== Column permissions related start ======================= export const FIELD_PERMISSION_ADD_ROLE = 'datasheet/:dstId/field/:fieldId/addRole'; +export const FIELD_PERMISSION_YACH_ADD_ROLE = 'org/yach/datasheet/:dstId/field/:fieldId/addRole'; export const FIELD_PERMISSION_DELETE_ROLE = 'datasheet/:dstId/field/:fieldId/deleteRole'; export const FIELD_PERMISSION_EDIT_ROLE = 'datasheet/:dstId/field/:fieldId/editRole'; export const FIELD_PERMISSION_ROLE_LIST = 'datasheet/:dstId/field/:fieldId/listRole'; @@ -38,7 +39,9 @@ export const GET_FIELD_PERMISSION_PAGE_MEMBER_LIST = '/datasheet/:dstId/field/:f // ================ mirror related start ======================= export const READ_MIRROR_INFO = 'mirrors/:mirrorId/info'; // Request mirror data +export const READ_EMBED_MIRROR_INFO = 'embedlinks/:embedId/mirrors/:mirrorId/info'; // Request mirror data export const READ_MIRROR_DATA_PACK = 'mirrors/:mirrorId/dataPack'; // Request the data of the mirror-related table +export const READ_EMBED_MIRROR_DATA_PACK = 'embedlinks/:embedId/resources/:mirrorId/dataPack'; // Request the data of the mirror-related table export const READ_SHARE_MIRROR_INFO = 'shares/:shareId/mirrors/:mirrorId/info'; // Request the data of mirror-related tables export const READ_SHARE_MIRROR_DATA_PACK = 'shares/:shareId/mirrors/:mirrorId/dataPack'; // Request the data of the mirror-related table export const GET_MIRROR_SUBSCRIPTIONS = '/mirrors/:mirrorId/records/subscriptions'; // Get the concerned record IDs of the mirror table diff --git a/packages/core/src/modules/database/api/wasm/index.ts b/packages/core/src/modules/database/api/wasm/index.ts index 494ba02a87..c260ef2d5b 100644 --- a/packages/core/src/modules/database/api/wasm/index.ts +++ b/packages/core/src/modules/database/api/wasm/index.ts @@ -148,7 +148,9 @@ const getBrowserDatabusApiEnabled = () => { const parsedTestFunctionSettings = testFunctionSettings == null ? {} : JSON.parse(testFunctionSettings); return parsedTestFunctionSettings['dataBusWasmEnable'] != null; } catch (e) { - console.error('error getting browser databus api enabled', e); + if (isClient()) { + console.error('error getting browser databus api enabled', e); + } return false; } }; diff --git a/packages/core/src/modules/database/store/actions/resource/datasheet/datasheet.ts b/packages/core/src/modules/database/store/actions/resource/datasheet/datasheet.ts index 451a5db271..9a4c2198bd 100644 --- a/packages/core/src/modules/database/store/actions/resource/datasheet/datasheet.ts +++ b/packages/core/src/modules/database/store/actions/resource/datasheet/datasheet.ts @@ -49,7 +49,6 @@ import { ACTIVE_OPERATE_VIEW_ID, ADD_DATASHEET, CHANGE_VIEW, - CHANGE_WIDGET_PANEL_WIDTH, CLEAR_ACTIVE_ROW_INFO, CLEAR_FIELD_INFO, DATAPACK_LOADED, @@ -87,6 +86,7 @@ import { SET_ORG_CHART_GRID_WIDTH as SET_ORG_CHART_GRID_PANEL_WIDTH, SET_ORG_CHART_SETTING_PANEL_WIDTH, SET_ROBOT_PANEL_STATUS, + SET_COPILOT_PANEL_STATUS, SET_SEARCH_KEYWORD, SET_SEARCH_RESULT_CURSOR_INDEX, SET_VIEW_DERIVATION, @@ -137,7 +137,7 @@ function ensureInnerConsistency(payload: IServerDatasheetPack, getState?: () => // @su // the check of data consistency // datasheet is the only object that should be attention - // if if all the permission of datasheet is ok, no need to check more + // if all the permission of datasheet is ok, no need to check more if (!datasheet.permissions?.editable) { // when the permission of datasheet is not ok, then check other factors const pageParams = getState ? getState().pageParams : {}; @@ -789,6 +789,14 @@ export const toggleTimeMachinePanel = (datasheetId: string, visible?: boolean) = }; }; +export const setCoPilotPanelStatus = (status: boolean, datasheetId: string) => { + return { + type: SET_COPILOT_PANEL_STATUS, + payload: status, + datasheetId, + }; +}; + export const toggleArchivedRecordsPanel = (datasheetId: string, visible?: boolean) => { return { type: TOGGLE_ARCHIVED_RECORDS_PANEL, @@ -801,16 +809,6 @@ export interface IToggleWidgetPanel { type: typeof TOGGLE_WIDGET_PANEL; } -// export interface IChangeWidgetPanelWidth { -// type: typeof CHANGE_WIDGET_PANEL_WIDTH; -// payload: number; -// } - -// export interface ISwitchActivePanel { -// type: typeof SWITCH_ACTIVE_PANEL; -// payload: string; -// } - export interface ISetGridViewHoverFieldIdAction { type: typeof SET_GRID_VIEW_HOVER_FIELD_ID; payload: string | null; diff --git a/packages/core/src/modules/database/store/actions/resource/mirror/mirror.ts b/packages/core/src/modules/database/store/actions/resource/mirror/mirror.ts index 7af8aae263..91f389313b 100644 --- a/packages/core/src/modules/database/store/actions/resource/mirror/mirror.ts +++ b/packages/core/src/modules/database/store/actions/resource/mirror/mirror.ts @@ -23,7 +23,14 @@ import { deleteNode } from 'modules/space/store/actions/catalog_tree'; import { StatusCode } from 'config'; import { AxiosResponse } from 'axios'; import { Dispatch } from 'redux'; -import { fetchMirrorDataPack, fetchMirrorInfo, fetchShareMirrorDataPack, fetchShareMirrorInfo } from '../../../../api/mirror_api'; +import { + fetchEmbedMirrorDataPack, + fetchEmbedMirrorInfo, + fetchMirrorDataPack, + fetchMirrorInfo, + fetchShareMirrorDataPack, + fetchShareMirrorInfo, +} from '../../../../api/mirror_api'; import * as ActionConstants from 'modules/shared/store/action_constants'; import { batchActions } from 'redux-batched-actions'; import { CACHE_TEMPORARY_VIEW, UPDATE_MIRROR_INFO, UPDATE_MIRROR_NAME } from 'modules/shared/store/action_constants'; @@ -36,19 +43,25 @@ interface IFetchMirrorSuccess { getState: () => IReduxState; } -export const fetchMirrorInfoApi = (mirrorId: string, shareId?: string, _templateId?: string) => { +export const fetchMirrorInfoApi = (mirrorId: string, shareId?: string, _templateId?: string, embedId?: string) => { let requestMethod = fetchMirrorInfo; if (shareId) { requestMethod = () => fetchShareMirrorInfo(shareId, mirrorId); } + if (embedId) { + requestMethod = () => fetchEmbedMirrorInfo(embedId, mirrorId); + } return requestMethod(mirrorId); }; -export const fetchMirrorDataPackApi = (mirrorId: string, shareId?: string, recordIds?: string[]) => { +export const fetchMirrorDataPackApi = (mirrorId: string, shareId?: string, recordIds?: string[], embedId?: string) => { let requestMethod = fetchMirrorDataPack; if (shareId) { requestMethod = () => fetchShareMirrorDataPack(shareId, mirrorId); } + if (embedId) { + requestMethod = () => fetchEmbedMirrorDataPack(embedId, mirrorId, recordIds); + } return requestMethod(mirrorId, recordIds); }; @@ -57,31 +70,31 @@ export function fetchMirrorPack( successCb?: (props?: IFetchMirrorSuccess) => void, _overwrite?: boolean, extra?: { recordIds: string[] }, - failCb?: () => void, + failCb?: () => void ) { return (dispatch: any, getState: () => IReduxState) => { const state = getState(); const mirror = getMirror(state, mirrorId); - const { shareId, templateId } = state.pageParams; + const { shareId, templateId, embedId } = state.pageParams; const mirrorLoading = getMirrorLoading(state, mirrorId); const datasheet = getDatasheet(state, getMirrorSourceInfo(state, mirrorId)?.datasheetId); if (mirrorLoading) { return; } if (!mirror || datasheet?.isPartOfData) { - return fetchMirrorInfoApi(mirrorId, shareId, templateId) - .then(response => { + return fetchMirrorInfoApi(mirrorId, shareId, templateId, embedId) + .then((response) => { // if (!response.data.success && state.catalogTree.treeNodesMap[mirrorId]) { // // dispatch(deleteNode({ nodeId: mirrorId, parentId: state.catalogTree.treeNodesMap[mirrorId].parentId })); // // return Promise.reject(); // } return Promise.resolve({ mirrorId, response, dispatch, getState }); }) - .catch(e => { + .catch((e) => { dispatch(setMirrorErrorCode(mirrorId, StatusCode.COMMON_ERR)); throw e; }) - .then(async props => { + .then(async (props) => { const { recordIds } = extra || {}; await fetchSuccess(props, recordIds, successCb, failCb); }); @@ -103,7 +116,7 @@ const fetchSuccess = ( { dispatch, getState, response, mirrorId }: { dispatch: any; getState: () => IReduxState; response: any; mirrorId: string }, recordIds?: string[], successCb?: (props?: IFetchMirrorSuccess) => void, - failCb?: () => void, + failCb?: () => void ) => { const { data, success, code } = response.data; if (success) { @@ -114,17 +127,18 @@ const fetchSuccess = ( sourceInfo: data.sourceInfo, snapshot: data.snapshot, }, - data.mirror.id, + data.mirror.id ), ]; const state = getState(); const shareId = state.pageParams.shareId; + const embedId = state.pageParams.embedId; const sourceDatasheetId = data.sourceInfo.datasheetId; const datasheet = getDatasheet(state, sourceDatasheetId); if (!datasheet || datasheet.isPartOfData) { - fetchMirrorDataPackApi(mirrorId, shareId, recordIds) - .then(response => { + fetchMirrorDataPackApi(mirrorId, shareId, recordIds, embedId) + .then((response) => { return Promise.resolve({ datasheetId: sourceDatasheetId, responseBody: response.data, @@ -133,19 +147,22 @@ const fetchSuccess = ( isPartOfData: Boolean(recordIds), }); }) - .catch(e => { + .catch((e) => { if (state.catalogTree.treeNodesMap[sourceDatasheetId]) { dispatch(deleteNode({ nodeId: sourceDatasheetId, parentId: state.catalogTree.treeNodesMap[sourceDatasheetId]!.parentId })); } dispatch(datasheetErrorCode(sourceDatasheetId, StatusCode.COMMON_ERR)); throw e; }) - .then(props => { - fetchDatasheetPackSuccess(props as any); - props.responseBody.success ? successCb && successCb() : failCb && failCb(); - }, e => { - console.error('fetchMirrorDataPackApi error', e); - }); + .then( + (props) => { + fetchDatasheetPackSuccess(props as any); + props.responseBody.success ? successCb && successCb() : failCb && failCb(); + }, + (e) => { + console.error('fetchMirrorDataPackApi error', e); + } + ); } else { successCb && successCb(); } diff --git a/packages/core/src/modules/database/store/interfaces/resource/datasheet/datasheet.ts b/packages/core/src/modules/database/store/interfaces/resource/datasheet/datasheet.ts index 578de16f29..398eeccc8c 100644 --- a/packages/core/src/modules/database/store/interfaces/resource/datasheet/datasheet.ts +++ b/packages/core/src/modules/database/store/interfaces/resource/datasheet/datasheet.ts @@ -19,21 +19,11 @@ import { IRemoteChangeset } from 'engine/ot'; import { StatType } from 'model/field/stat'; import { ICellValue } from 'model/record'; -import { FillDirection, ICell,IFieldRanges, IRange, IRecordRanges } from 'model/view/range'; +import { FillDirection, ICell, IFieldRanges, IRange, IRecordRanges } from 'model/view/range'; import { IField, IStandardValue } from 'types/field_types'; import { IFilterInfo, IGroupInfo, ISortedField, ISortInfo } from 'types/view_types'; -import { - IUnitValue, - IUserValue, -} from 'exports/store/interfaces'; -import { - CellType, - GalleryStyleKeyType, - LayoutType, - RowHeightLevel, - ViewType, - WhyRecordMoveType, -} from 'modules/shared/store/constants'; +import { IUnitValue, IUserValue } from 'exports/store/interfaces'; +import { CellType, GalleryStyleKeyType, LayoutType, RowHeightLevel, ViewType, WhyRecordMoveType } from 'modules/shared/store/constants'; import * as actions from '../../../../../shared/store/action_constants'; import { @@ -100,6 +90,7 @@ export interface IMeta { fieldMap: IFieldMap; views: IViewProperty[]; widgetPanels?: IWidgetPanel[]; + archivedRecordIds?: string[]; } export interface IRecordCellValue { @@ -304,6 +295,7 @@ export interface INodeMeta { nodeShared: boolean; nodePermitSet: boolean; nodeFavorite?: boolean; + nodePrivate?: boolean; spaceId: string; role: Role; permissions: IPermissions; @@ -479,6 +471,7 @@ export interface IDatasheetClientState { isRobotPanelOpen?: boolean; operateViewIds?: string[] | null; isTimeMachinePanelOpen?: boolean; + isCopilotPanelOpen?: boolean; isArchivedRecordsPanelOpen?: boolean; exportViewId?: string | null; // View-derived data, all content obtained by calculation, is uniformly maintained here. @@ -828,6 +821,7 @@ export interface IPageParams { mirrorId?: string; embedId?: string; aiId?: string; + customPageId?: string; } export interface ICollaboratorParams { diff --git a/packages/core/src/modules/database/store/reducers/resource/datasheet/client.ts b/packages/core/src/modules/database/store/reducers/resource/datasheet/client.ts index cd72a5dfef..e3d1e3ff18 100644 --- a/packages/core/src/modules/database/store/reducers/resource/datasheet/client.ts +++ b/packages/core/src/modules/database/store/reducers/resource/datasheet/client.ts @@ -32,7 +32,7 @@ import { SET_ROBOT_PANEL_STATUS, SET_SEARCH_KEYWORD, SET_SEARCH_RESULT_CURSOR_INDEX, SET_WIDGET_PANEL_LOADING, SWITCH_ACTIVE_PANEL, TOGGLE_CALENDAR_GRID, TOGGLE_CALENDAR_GUIDE_STATUS, TOGGLE_CALENDAR_SETTING_PANEL, TOGGLE_GANTT_GRID, TOGGLE_GANTT_SETTING_PANEL, TOGGLE_KANBAN_GROUP_SETTING_VISIBLE, TOGGLE_ORG_CHART_GRID, TOGGLE_ORG_CHART_GUIDE_STATUS, TOGGLE_ORG_CHART_SETTING_PANEL, TOGGLE_TIME_MACHINE_PANEL, TOGGLE_WIDGET_PANEL, - DELETE_VIEW_DERIVATION, PATCH_VIEW_DERIVATION, SET_VIEW_DERIVATION + DELETE_VIEW_DERIVATION, PATCH_VIEW_DERIVATION, SET_VIEW_DERIVATION, SET_COPILOT_PANEL_STATUS } from '../../../../../shared/store/action_constants'; import { DateUnitType, WhyRecordMoveType } from '../../../../../shared/store/constants'; import { collaborators } from './collaborators'; @@ -362,6 +362,12 @@ export const client = combineReducers({ } return state; }, + isCopilotPanelOpen(state = false, action) { + if (action.type === SET_COPILOT_PANEL_STATUS) { + return action.payload; + } + return state; + }, exportViewId(state = null, action) { if (action.type === ACTIVE_EXPORT_VIEW_ID) { const viewId = action.payload; diff --git a/packages/core/src/modules/database/store/reducers/resource/datasheet/datasheet.ts b/packages/core/src/modules/database/store/reducers/resource/datasheet/datasheet.ts index 45d5e3087b..fe8633e55d 100644 --- a/packages/core/src/modules/database/store/reducers/resource/datasheet/datasheet.ts +++ b/packages/core/src/modules/database/store/reducers/resource/datasheet/datasheet.ts @@ -95,6 +95,7 @@ export const datasheet = produce(( if (state && action.payload.isPartOfData && state.isPartOfData) { if (action.payload.revision === state.revision) { state.snapshot.recordMap = Object.assign({}, action.payload.snapshot.recordMap, state.snapshot.recordMap); + state.snapshot.meta.views = action.payload.snapshot.meta.views; } else { Player.doTrigger(Events.app_error_logger, { error: new Error(t(Strings.error_the_version_is_inconsistent_while_preparing_to_merge)), diff --git a/packages/core/src/modules/database/store/selectors/resource/datasheet/base.ts b/packages/core/src/modules/database/store/selectors/resource/datasheet/base.ts index 8ab2ef41ce..367fdf8e4c 100644 --- a/packages/core/src/modules/database/store/selectors/resource/datasheet/base.ts +++ b/packages/core/src/modules/database/store/selectors/resource/datasheet/base.ts @@ -143,49 +143,51 @@ export const getFieldPermissionMapBase = (state: IReduxState, id?: string | void return datasheetPack?.fieldPermissionMap; }; -export const getFieldPermissionMap = createCachedSelector( - [ - getFieldPermissionMapBase, - state => { - const snapshot = getSnapshot(state)!; - return getViewById(snapshot, state.pageParams?.viewId || ''); - }, - state => state.pageParams?.mirrorId, - ], - - (fieldPermissionMap: IFieldPermissionMap | undefined, view: IViewProperty | undefined, mirrorId?: string | void) => { - if (!mirrorId) { - return fieldPermissionMap; - } - if (mirrorId && view && typeof view.displayHiddenColumnWithinMirror === 'boolean' && !view.displayHiddenColumnWithinMirror) { - const _fieldPermissionMap = {}; - for (const v of view.columns) { - if (!v.hidden) continue; - _fieldPermissionMap[v.fieldId] = { - role: Role.None, - setting: { - formSheetAccessible: true, - }, - permission: { - editable: false, - readable: false - }, - manageable: false - }; - } - return { - ...fieldPermissionMap, - ..._fieldPermissionMap + IFieldPermissionMap | undefined +>( + [ + getFieldPermissionMapBase, + (state) => { + const snapshot = getSnapshot(state)!; + return getViewById(snapshot, state.pageParams?.viewId || ''); + }, + (state) => state.pageParams?.mirrorId, + ], + + (fieldPermissionMap: IFieldPermissionMap | undefined, view: IViewProperty | undefined, mirrorId?: string | void) => { + if (!mirrorId) { + return fieldPermissionMap; + } + if (mirrorId && view && typeof view.displayHiddenColumnWithinMirror === 'boolean' && !view.displayHiddenColumnWithinMirror) { + const _fieldPermissionMap = {}; + for (const v of view.columns) { + if (!v.hidden) continue; + _fieldPermissionMap[v.fieldId] = { + role: Role.None, + setting: { + formSheetAccessible: true, + }, + permission: { + editable: false, + readable: false, + }, + manageable: false, }; } - return fieldPermissionMap; + return { + ...fieldPermissionMap, + ..._fieldPermissionMap, + }; } - )(defaultKeySelector); + return fieldPermissionMap; + } +)(defaultKeySelector); export const getFieldRoleByFieldId = (fieldPermissionMap: IFieldPermissionMap | undefined, fieldId: string): null | Role => { if (!fieldPermissionMap || !fieldPermissionMap[fieldId]) { @@ -276,7 +278,7 @@ export const getNodeDesc = (state: IReduxState, dsId?: string): null | INodeDesc } try { return JSON.parse(datasheet.description); - }catch (e) { + } catch (e) { return null; } }; @@ -308,30 +310,18 @@ export const getViewsList = (state: IReduxState, dsId?: string) => { }; export const getNodeId = (state: IReduxState) => { - const { datasheetId, automationId, folderId, formId, dashboardId, mirrorId,aiId } = state.pageParams; + const { mirrorId, nodeId } = state.pageParams; // mirror is special, url will contain mirrorId and datasheetId at the same time, so mirrorId need to be judged first if (mirrorId) { return mirrorId; } - if (automationId) { - return automationId; - } - if (datasheetId) { - return datasheetId; - } - if (folderId) { - return folderId; - } - if (formId) { - return formId; - } - if (dashboardId) { - return dashboardId; - } - if (aiId) { - return aiId; - } - return ''; + + return nodeId || ''; +}; + +export const getActiveNodePrivate = (state: IReduxState) => { + const nodeId = getNodeId(state); + return state.datasheetMap[nodeId]?.datasheet?.nodePrivate; }; export const getToolbarMenuCardState = (state: IReduxState) => { @@ -352,11 +342,12 @@ export const allowShowCommentPane = (state: IReduxState) => { }; export const getDatasheetParentId = (state: IReduxState, id?: string) => { - const tree = state.catalogTree.treeNodesMap; const datasheet = getDatasheet(state, id); if (!datasheet) { return; } + const nodePrivate = datasheet.nodePrivate; + const tree = state.catalogTree[nodePrivate ? 'privateTreeNodesMap' : 'treeNodesMap']; return tree[datasheet.id]?.parentId || datasheet.parentId; }; @@ -391,12 +382,25 @@ export const getActiveViewId = (state: IReduxState, id?: string | void) => { if (!views) { return pageViewId; } - if (!views.find(item => item.id === pageViewId)) { + if (!views.find((item) => item.id === pageViewId)) { return views[0]?.id; } return pageViewId; }; +export const getActiveView = (state: IReduxState, id?: string | void) => { + const datasheet = getDatasheet(state, id); + const views = datasheet?.snapshot.meta.views; + const pageViewId = state.pageParams.viewId; + if (views) { + const view = views.find((item) => item.id === pageViewId); + if (view) { + return view; + } + } + return null; +}; + export const getViewIdByNodeId = (state: IReduxState, datasheetId: string, viewId?: string, mirror?: IMirror) => { const _mirror = mirror || getMirror(state); const _viewId = viewId ?? state.pageParams.viewId; @@ -424,7 +428,7 @@ export const getViewInNode = (state: IReduxState, datasheetId: string, viewId?: }; export const getViewById = (snapshot: ISnapshot, viewId: string) => { - return snapshot?.meta.views.find(view => view.id === viewId); + return snapshot?.meta.views.find((view) => view.id === viewId); }; export const getCloseSyncViewIds = (state: IReduxState, dsId: string) => { @@ -447,14 +451,17 @@ export const getNodeViewWithoutFilterInfo = (snapshot: ISnapshot, viewId: string if (!temporaryView || mirror?.sourceInfo.datasheetId !== snapshot.datasheetId) { return originView; } + if (!originView) { + return; + } // If any view configuration is modified in the mirror, // the view configuration operation of the original table will not affect the mirror anymore, // so the cached data of the mirror is taken directly here. return { - id: originView!.id, - type: originView!.type, - rows: originView!.rows, + id: originView.id, + type: originView.type, + rows: originView.rows, ...temporaryView, - filterInfo: originView?.filterInfo + filterInfo: originView?.filterInfo, } as IViewProperty; }; diff --git a/packages/core/src/modules/database/store/selectors/resource/datasheet/calc.ts b/packages/core/src/modules/database/store/selectors/resource/datasheet/calc.ts index 82b69b3cdd..a9023496aa 100644 --- a/packages/core/src/modules/database/store/selectors/resource/datasheet/calc.ts +++ b/packages/core/src/modules/database/store/selectors/resource/datasheet/calc.ts @@ -62,13 +62,7 @@ import { import { getMirror, getMirrorNetworking } from 'modules/database/store/selectors/resource/mirror'; -import { - FieldType, - IField, - IFilterInfo, - IGroupInfo, - IMemberField, -} from 'types'; +import { FieldType, IField, IFilterInfo, IGroupInfo, IMemberField } from 'types'; import { getActiveDatasheetId, @@ -94,7 +88,7 @@ const defaultKeySelector = (state: IReduxState, datasheetId: string | undefined export const getDatasheetIds = createDeepEqualSelector( (state: IReduxState) => Object.keys(state.datasheetMap), - keys => keys, + (keys) => keys ); /** @@ -139,15 +133,16 @@ export const getVisibleColumnsBase = (view?: IViewProperty) => { export const getColumnWidth = (column: IGridViewColumn) => (!column || column.width == null ? DEFAULT_COLUMN_WIDTH : column.width); export const getView = (snapshot: ISnapshot, viewId: string) => { - return snapshot.meta.views.find(view => view.id === viewId); + return snapshot.meta.views.find((view) => view.id === viewId); }; export const getViewIndex = (snapshot: ISnapshot, viewId: string) => { - return snapshot.meta.views.findIndex(view => view.id === viewId); + return snapshot.meta.views.findIndex((view) => view.id === viewId); }; const filterColumnsByPermission = (columns: IViewColumn[], fieldPermissionMap: IFieldPermissionMap | undefined) => { - return columns.filter(column => { + return columns.filter((column) => { + if (!column) return true; // TODO: column permission delete this logic (2nd phase) const fieldRole = getFieldRoleByFieldId(fieldPermissionMap, column.fieldId); return fieldRole !== Role.None; @@ -159,7 +154,7 @@ export const getCurrentViewBase = ( viewId: string | undefined, datasheetId?: string, fieldPermissionMap?: IFieldPermissionMap | undefined, - mirror?: IMirror | null, + mirror?: IMirror | null ) => { if (!viewId) { return; @@ -173,6 +168,21 @@ export const getCurrentViewBase = ( const permissionColumns = filterColumnsByPermission(view.columns, fieldPermissionMap); if (permissionColumns.length !== view.columns.length) { + // we need to update the frozenColumnCount in mirror view when the permissionColumns is changed + if (mirror?.id && (view.type === ViewType.Grid || view.type === ViewType.Gantt)) { + let frozenColumnCount = view.frozenColumnCount; + view.columns.slice(0, view.frozenColumnCount).forEach((column) => { + const fieldRole = getFieldRoleByFieldId(fieldPermissionMap, column.fieldId); + if (fieldRole === Role.None) { + frozenColumnCount--; + } + }); + return { + ...view, + frozenColumnCount, + columns: permissionColumns, + }; + } return { ...view, columns: permissionColumns, @@ -180,26 +190,28 @@ export const getCurrentViewBase = ( } return view; }; -export const getCurrentView = createCachedSelector( - [ - getSnapshot, - getActiveViewId, - (state, datasheetId) => datasheetId || getActiveDatasheetId(state), - getFieldPermissionMap, - (state: IReduxState) => getMirror(state), - ], - getCurrentViewBase, - )({ + IViewProperty | undefined +>( + [ + getSnapshot, + getActiveViewId, + (state, datasheetId) => datasheetId || getActiveDatasheetId(state), + getFieldPermissionMap, + (state: IReduxState) => getMirror(state), + ], + getCurrentViewBase +)({ // keySelector: (state, datasheetId) => state.pageParams.mirrorId || datasheetId || getActiveDatasheetId(state), - keySelector: defaultKeySelector, - }); + keySelector: defaultKeySelector, +}); export const getViewByIdWithDefault = (state: IReduxState, datasheetId: string, viewId?: string) => { const snapshot = getSnapshot(state, datasheetId); @@ -228,12 +240,15 @@ export const getTemporaryView = (snapshot: ISnapshot | undefined, viewId: string if (!temporaryView || mirror?.sourceInfo.datasheetId !== snapshot.datasheetId) { return originView; } + if (!originView) { + return; + } // in mirror, if any view config is modified, // the original table's view config will not affect the mirror, so here directly use the mirror's cache data return { - id: originView!.id, - type: originView!.type, - rows: originView!.rows, + id: originView.id, + type: originView.type, + rows: originView.rows, ...temporaryView, } as IViewProperty; }; @@ -253,7 +268,7 @@ export const getFilterInfoExceptInvalid = (state: IReduxState, datasheetId?: str return { ...filterInfo, - conditions: filterInfo.conditions.filter(condition => { + conditions: filterInfo.conditions.filter((condition) => { const fieldMap = snapshot.meta.fieldMap; const field = fieldMap[condition.fieldId]!; @@ -283,7 +298,7 @@ export const getGroupInfoWithPermission = (state: IReduxState, groupInfo: IGroup if (!groupInfo || !fieldPermissionMap) { return groupInfo; } - return groupInfo.filter(group => { + return groupInfo.filter((group) => { const fieldRole = getFieldRoleByFieldId(fieldPermissionMap, group.fieldId); if (fieldRole === Role.None) { @@ -319,26 +334,30 @@ export const getFieldMapBase = (datasheet: IDatasheetState | null | undefined, f return _fieldMap; }; -export const getFieldMap = createCachedSelector( - [getDatasheet, getFieldPermissionMap], - getFieldMapBase, - )(defaultKeySelector); + IFieldMap | null | undefined +>( + [getDatasheet, getFieldPermissionMap], + getFieldMapBase +)(defaultKeySelector); -export const getFieldMapIgnorePermission = createCachedSelector( - [getDatasheet], - getFieldMapBase, - )(defaultKeySelector); + IFieldMap | null | undefined +>( + [getDatasheet], + getFieldMapBase +)(defaultKeySelector); export const getColumnIndexMap = createSelector( [getCurrentView], - view => { + (view) => { const columnsMap: { [id: string]: number } = {}; if (!view) { return columnsMap; @@ -347,28 +366,30 @@ export const getColumnIndexMap = createSelector([getCurrentView, getFieldPermissionMap], (view?: IViewProperty, fieldPermissionMap?) => { + IViewColumn[] +>([getCurrentView, getFieldPermissionMap], (view?: IViewProperty, fieldPermissionMap?) => { // ignore the first column as hidden - return view - ? view.columns.filter((item, i) => { - const fieldRole = getFieldRoleByFieldId(fieldPermissionMap, item.fieldId); - if (fieldRole === Role.None) { - return false; - } - return !(item.hidden && i !== 0); - }) - : []; - })(defaultKeySelector); + return view + ? view.columns.filter((item, i) => { + const fieldRole = getFieldRoleByFieldId(fieldPermissionMap, item.fieldId); + if (fieldRole === Role.None) { + return false; + } + return !(item.hidden && i !== 0); + }) + : []; +})(defaultKeySelector); -export const getVisibleColumnsMap = createSelector([getVisibleColumns], columns => { - return new Map(columns.map((item, index) => [item.fieldId, index])); +export const getVisibleColumnsMap = createSelector([getVisibleColumns], (columns) => { + return new Map(columns?.map((item, index) => [item.fieldId, index])); }); export const findColumnIndexById = (state: IReduxState, id: string): number => { @@ -378,7 +399,7 @@ export const findColumnIndexById = (state: IReduxState, id: string): number => { throw new Error( t(Strings.error_not_exist_id, { id, - }), + }) ); } return index; @@ -422,7 +443,7 @@ export const getRangeFields = (state: IReduxState, range: IRange, datasheetId: s } const columnSlice = [rangeIndex.field.min, rangeIndex.field.max + 1]; const columns = getVisibleColumns(state); - return columns.slice(...columnSlice).map(col => getField(state, col.fieldId, datasheetId)); + return columns.slice(...columnSlice).map((col) => getField(state, col.fieldId, datasheetId)); }; export const getRecordSnapshot = (state: IReduxState, datasheetId: string, recordId: string): IRecordSnapshot | null => { @@ -471,14 +492,14 @@ export const getEffectConditionCount = (state: IReduxState) => { export const getColumnByFieldId = (state: IReduxState, fieldId: string) => { const columns = getVisibleColumns(state); - return columns.find(column => column.fieldId === fieldId); + return columns.find((column) => column.fieldId === fieldId); }; export const getRowHeightFromLevel = (level?: RowHeightLevel): number => { return level == null ? RowHeight.Short : RowHeight[RowHeightLevel[level]!]; }; -export const getGroupLevel = createSelector([getActiveViewGroupInfo], groupInfo => { +export const getGroupLevel = createSelector([getActiveViewGroupInfo], (groupInfo) => { return groupInfo.length; }); @@ -491,7 +512,7 @@ export const getCurrentGalleryViewStyle = createSelector([getCurrentView], (view const getIntegratePermissionWithFieldBase = ( _state: IReduxState, - { permission, fieldId, fieldPermissionMap }: { permission: IPermissions; fieldId?: string; fieldPermissionMap?: IFieldPermissionMap }, + { permission, fieldId, fieldPermissionMap }: { permission: IPermissions; fieldId?: string; fieldPermissionMap?: IFieldPermissionMap } ) => { const fieldPermission = fieldPermissionMap && fieldId ? fieldPermissionMap[fieldId] : undefined; @@ -506,7 +527,8 @@ const getIntegratePermissionWithFieldBase = ( }; }; -const getIntegratePermissionWithField = createCachedSelector(getIntegratePermissionWithFieldBase, permission => { - return permission; - })({ - keySelector: (state, { datasheetId, mirrorId }) => mirrorId || datasheetId || getActiveDatasheetId(state), - selectorCreator: createDeepEqualSelector, - }); + IPermissions +>(getIntegratePermissionWithFieldBase, (permission) => { + return permission; +})({ + keySelector: (state, { datasheetId, mirrorId }) => mirrorId || datasheetId || getActiveDatasheetId(state), + selectorCreator: createDeepEqualSelector, +}); export const getPermissions = (state: IReduxState, datasheetId?: string, fieldId?: string, sourceMirrorId?: string): IPermissions => { const datasheet = getDatasheet(state, datasheetId); @@ -618,7 +641,7 @@ export const getFilterConditionValue = (state: IReduxState, conditionId: string) const filterInfo = getCurrentView(state)!.filterInfo; if (filterInfo) { - const result = filterInfo.conditions.find(item => { + const result = filterInfo.conditions.find((item) => { return item.conditionId === conditionId; }); return result && result.value ? result.value : null; @@ -641,27 +664,27 @@ export const getKanbanGroupMapIds = createSelector( return []; } if (field.type === FieldType.SingleSelect) { - return field.property.options.map(item => item.id); + return field.property.options.map((item) => item.id); } return (field as IMemberField).property.unitIds; - }, + } ); export const getQueryMeta = createSelector( [getVisibleColumns, getActiveDatasheetId, getActiveViewFilterInfo, getActiveViewGroupInfo, getActiveViewSortInfo], (selectFields, fromDstId, filterInfo, groupInfo, sortInfo) => { - let q = `select ${selectFields.map(field => field.fieldId).join(',')} from ${fromDstId}\n`; + let q = `select ${selectFields.map((field) => field.fieldId).join(',')} from ${fromDstId}\n`; if (filterInfo) { - q += `where ${filterInfo.conditions.map(cond => `${cond.fieldId} ${cond.operator} ${cond.value}`).join(` ${filterInfo.conjunction} `)}\n`; + q += `where ${filterInfo.conditions.map((cond) => `${cond.fieldId} ${cond.operator} ${cond.value}`).join(` ${filterInfo.conjunction} `)}\n`; } if (groupInfo && groupInfo.length) { - q += `group by ${groupInfo.map(gInfo => gInfo.fieldId).join(',')}\n`; + q += `group by ${groupInfo.map((gInfo) => gInfo.fieldId).join(',')}\n`; } if (sortInfo) { - q += `order by ${sortInfo.rules.map(rule => `${rule.fieldId} ${rule.desc ? 'desc' : ''}`).join(',')}\n`; + q += `order by ${sortInfo.rules.map((rule) => `${rule.fieldId} ${rule.desc ? 'desc' : ''}`).join(',')}\n`; } return q; - }, + } ); export const getCalendarStyle = (state: IReduxState) => { @@ -699,14 +722,14 @@ export const getCalendarVisibleColumns = createCachedSelector { return view ? (view as ICalendarViewProperty).columns.filter((item, i) => !(item.hiddenInCalendar && i !== 0)) : []; - }, + } )(defaultKeySelector); export const getOrgChartVisibleColumns = createCachedSelector( [getCurrentView], (view?: IViewProperty) => { return view ? (view as IOrgChartViewProperty).columns.filter((item: IOrgChartViewColumn, i) => !(item.hiddenInOrgChart && i !== 0)) : []; - }, + } )(defaultKeySelector); export const getCalendarVisibleColumnCount = (state: IReduxState) => { @@ -728,8 +751,8 @@ export const getGanttStyle = (state: IReduxState) => { export const getGanttVisibleColumns = createCachedSelector( [getCurrentView], (view?: IViewProperty) => { - return view ? (view as IGanttViewProperty).columns.filter(item => !item.hiddenInGantt) : []; - }, + return view ? (view as IGanttViewProperty).columns.filter((item) => !item.hiddenInGantt) : []; + } )(defaultKeySelector); export const getGanttVisibleColumnCount = (state: IReduxState) => { @@ -787,12 +810,12 @@ export const getDateTimeCellAlarmForClient = (snapshot: IRecordSnapshot, recordI return { ...alarm, target: AlarmUsersType.Field, - alarmUsers: alarm.alarmUsers.map(item => item.data).filter(fieldId => fieldMap[fieldId] && fieldMap[fieldId]!.type === FieldType.Member), + alarmUsers: alarm.alarmUsers.map((item) => item.data).filter((fieldId) => fieldMap[fieldId] && fieldMap[fieldId]!.type === FieldType.Member), }; } return { ...alarm, target: AlarmUsersType.Member, - alarmUsers: alarm.alarmUsers.map(item => item.data), + alarmUsers: alarm.alarmUsers.map((item) => item.data), }; }; diff --git a/packages/core/src/modules/database/store/selectors/resource/datasheet/cell_calc.ts b/packages/core/src/modules/database/store/selectors/resource/datasheet/cell_calc.ts index 1a7235cb77..a9dc33f73a 100644 --- a/packages/core/src/modules/database/store/selectors/resource/datasheet/cell_calc.ts +++ b/packages/core/src/modules/database/store/selectors/resource/datasheet/cell_calc.ts @@ -4,6 +4,7 @@ import { CacheManager } from 'cache_manager'; import { dataSelfHelper } from 'compute_manager/compute_cache_manager'; import { IRecord, IRecordSnapshot, IReduxState, ISnapshot, Role } from 'exports/store/interfaces'; import { evaluate } from 'formula_parser/evaluate'; +import { ButtonField } from 'model/field/button_field'; import { handleEmptyCellValue } from 'model/utils'; import { ICellValue } from 'model/record'; import { BasicValueType, FieldType, IAttachmentValue, IFormulaField } from 'types/field_types'; @@ -197,6 +198,9 @@ export const getComputeCellValue = (state: IReduxState, snapshot: IRecordSnapsho case FieldType.LookUp: { return Field.bindContext(field, state).getCellValue(recordId, withError); } + case FieldType.Button: { + return (Field.bindContext(field, state) as ButtonField).cellValueToArray(null); + } case FieldType.CreatedBy: case FieldType.LastModifiedBy: case FieldType.CreatedTime: diff --git a/packages/core/src/modules/enterprise/index.ts b/packages/core/src/modules/enterprise/index.ts index 400e1a33ab..9d9ea6ff0f 100644 --- a/packages/core/src/modules/enterprise/index.ts +++ b/packages/core/src/modules/enterprise/index.ts @@ -20,4 +20,4 @@ export {}; export type StringSaaSKeysMapType = {}; -export type StringSaaSKeysType = {}; +export type StringSaaSKeysType = {}; \ No newline at end of file diff --git a/packages/core/src/modules/org/api/api.org.ts b/packages/core/src/modules/org/api/api.org.ts index ceb25548fb..306afa9b78 100644 --- a/packages/core/src/modules/org/api/api.org.ts +++ b/packages/core/src/modules/org/api/api.org.ts @@ -18,7 +18,9 @@ import axios from 'axios'; import * as Url from '../../shared/api/url'; -import { IAddIsActivedMemberInfo, IApiWrapper, IInviteMemberList, IMemberInfoInAddressList, IUpdateMemberInfo } from '../../../exports/store/interfaces'; +import { + IAddIsActivedMemberInfo, IApiWrapper, IInviteMemberList, IMemberInfoInAddressList, IUpdateMemberInfo +} from '../../../exports/store/interfaces'; import urlcat from 'urlcat'; const CancelToken = axios.CancelToken; @@ -254,10 +256,9 @@ export function updateMemberTeam(memberIds: string[], newTeamIds: string[], preT /** * Invite members(batch available) */ -export function sendInvite(invite: IInviteMemberList[], nodeId?: string, nvcVal?: string) { - return axios.post(Url.SEND_INVITE, { +export function sendInvite(spaceId: string, invite: IInviteMemberList[], nvcVal?: string) { + return axios.post(urlcat(Url.SEND_EMAIL_INVITATION, { spaceId }), { invite, - nodeId, data: nvcVal, }); } @@ -267,21 +268,25 @@ export function sendInvite(invite: IInviteMemberList[], nodeId?: string, nvcVal? * * @param email strict email format */ -export function reSendInvite(email: string) { - return axios.post(Url.RESEND_INVITE, { +export function reSendInvite(spaceId: string, email: string) { + return axios.post(urlcat(Url.RESEND_EMAIL_INVITATION, { spaceId }), { email, }); } /** * Invite Email Verify - * @param token one-time invite token - * @param from inviter + * @param inviteToken one-time invite token */ -export function inviteEmailVerify(token: string) { - return axios.post(Url.INVITE_EMAIL_VERIFY, { - token, - }); +export function inviteEmailVerify(inviteToken: string) { + return axios.get(urlcat(Url.VALID_EMAIL_INVITATION, { inviteToken })); +} + +/** + * Accept email invitation. + */ +export function acceptEmailInvitation(spaceId: string, inviteToken: string) { + return axios.post(urlcat(Url.ACCEPT_EMAIL_INVITATION, { spaceId, inviteToken })); } /** diff --git a/packages/core/src/modules/org/api/url.org.ts b/packages/core/src/modules/org/api/url.org.ts index e4563fdeb2..5147359005 100644 --- a/packages/core/src/modules/org/api/url.org.ts +++ b/packages/core/src/modules/org/api/url.org.ts @@ -50,10 +50,6 @@ export const TEAM_ADD_MEMBER = '/org/member/addMember'; export const GET_ADD_MEMBERS = '/org/search/unit'; // Space station - determine whether member mailboxes exist in the space export const EXIST_EMAIL = '/org/member/checkEmail'; -// Space Station - Mail invites external members for the first time -export const SEND_INVITE = '/org/member/sendInvite'; -// space station-mail invites external members again -export const RESEND_INVITE = '/org/member/sendInviteSingle'; // Space station - download employee information form template export const DOWNLOAD_MEMBER_FILE = '/org/member/downloadTemplate'; // space station - upload employee information form @@ -69,6 +65,10 @@ export const MEMBER_UNITS = '/org/member/units'; export const COLLABORATOR_INFO = 'node/collaborator/info'; +export const GET_ORG_YACH_GROUP = 'org/yach/group/page'; + +export const YACH_ADD_ROLE = 'org/yach/node/addRole'; + /** * Edit Member Info */ diff --git a/packages/core/src/modules/org/store/actions/invite.ts b/packages/core/src/modules/org/store/actions/invite.ts index 29b98cf3e6..dce4d0cf98 100644 --- a/packages/core/src/modules/org/store/actions/invite.ts +++ b/packages/core/src/modules/org/store/actions/invite.ts @@ -44,15 +44,6 @@ export const updateMailToken = (token: string) => { payload: token, }; }; -export const getMailLinkData = (token: string): any => { - return async(dispatch: any) => { - const { data } = await Api.inviteEmailVerify(token); - dispatch(updateInviteEmailInfo(data)); - if (!data.success) { - dispatch(updateErrCode(data.code)); - } - }; -}; /** * invite by link - inviter @@ -78,7 +69,7 @@ export const updateLinkInviteList = (list: IInviteLink[]) => { }; }; export const getSubTeamInvite = (teamId: string): any => { - return async(dispatch: any) => { + return async (dispatch: any) => { const subTree = await Api.getSubTeams(teamId); dispatch(updateSubTeamTreeInvite(teamId, subTree.data.data)); }; @@ -86,8 +77,8 @@ export const getSubTeamInvite = (teamId: string): any => { // TODO: to be delete by yudongdong export const getLinkInviteList = (): any => { - return async(dispatch: any) => { - const { data: { success, data }} = await Api.getLinkList(); + return async (dispatch: any) => { + const { data: { success, data } } = await Api.getLinkList(); if (success) { dispatch(updateLinkInviteList(data)); } @@ -113,7 +104,7 @@ export const updateLinkToken = (token: string) => { }; export const verifyLink = (token: string): any => { - return async(dispatch: any) => { + return async (dispatch: any) => { const { data } = await Api.linkValid(token); dispatch(updateInviteLinkInfo(data)); }; diff --git a/packages/core/src/modules/org/store/actions/space_member_manage.ts b/packages/core/src/modules/org/store/actions/space_member_manage.ts index f01e6c0efb..8bade54818 100644 --- a/packages/core/src/modules/org/store/actions/space_member_manage.ts +++ b/packages/core/src/modules/org/store/actions/space_member_manage.ts @@ -115,9 +115,9 @@ export function getTeamInfo(_spaceId: string, teamId: string) { * Space - invite member by email * invite member by email */ -export function sendInviteEmail(_spaceId: string, invite: IInviteMemberList[]) { +export function sendInviteEmail(spaceId: string, invite: IInviteMemberList[]) { return (dispatch: any) => { - Api.sendInvite(invite).then(res => { + Api.sendInvite(spaceId, invite).then(res => { const { success } = res.data; dispatch(updateInviteStatus(true)); if (success) { diff --git a/packages/core/src/modules/org/store/actions/unit_info.ts b/packages/core/src/modules/org/store/actions/unit_info.ts index 98241b304f..aebd5905ba 100644 --- a/packages/core/src/modules/org/store/actions/unit_info.ts +++ b/packages/core/src/modules/org/store/actions/unit_info.ts @@ -17,7 +17,7 @@ */ import keyBy from 'lodash/keyBy'; -import { RESET_UNIT_INFO, UPDATE_UNIT_MAP, UPDATE_USER_MAP } from '../../../shared/store/action_constants'; +import { RESET_UNIT_INFO, UPDATE_UNIT_MAP, UPDATE_USER_MAP, UPDATE_GROUP_LIST } from '../../../shared/store/action_constants'; import { IUnitMap } from '../../../../exports/store/interfaces'; import { Api } from '../../../../exports/api'; @@ -26,6 +26,10 @@ export interface IUpdateUnitMapAction { payload: IUnitMap; } +export interface IUpdateGroupListAction { + type: typeof UPDATE_GROUP_LIST; + payload: any; +} export interface IUpdateUserMapAction { type: typeof UPDATE_USER_MAP; payload: IUnitMap; @@ -49,6 +53,13 @@ export const updateUserMap = (userMap: IUnitMap) => { }; }; +export const updateGroupList = (data: { groupId: string; groupName: string }) => { + return { + type: UPDATE_GROUP_LIST, + payload: data, + }; +}; + export const resetUnitInfo = () => { return { type: RESET_UNIT_INFO, @@ -62,11 +73,11 @@ export const resetUnitInfo = () => { * @returns */ export const loadLackUnitMap = (names: string, linkId?: string,) => { - return async(dispatch: any) => { + return async (dispatch: any) => { if (!names.length) { return; } - const { data: { data: resData }} = await Api.searchUnitInfoVo(names, linkId); + const { data: { data: resData } } = await Api.searchUnitInfoVo(names, linkId); if (!resData.length) { return; } diff --git a/packages/core/src/modules/org/store/interface/unit_info.ts b/packages/core/src/modules/org/store/interface/unit_info.ts index 672a7b5870..54e4554730 100644 --- a/packages/core/src/modules/org/store/interface/unit_info.ts +++ b/packages/core/src/modules/org/store/interface/unit_info.ts @@ -20,10 +20,14 @@ import { MemberType } from 'types'; import { ITeamData } from './address_list'; export interface IUnitInfo { - unitMap: IUnitMap | null, + unitMap: IUnitMap | null; userMap: { [userId: string]: string | IUserValue - } | null + } | null; + groupList?: { + groupId: string; + groupName: string; + }[]; } interface IUnitBase { diff --git a/packages/core/src/modules/org/store/reducers/unit_info.ts b/packages/core/src/modules/org/store/reducers/unit_info.ts index 2727c87219..609251af49 100644 --- a/packages/core/src/modules/org/store/reducers/unit_info.ts +++ b/packages/core/src/modules/org/store/reducers/unit_info.ts @@ -17,16 +17,16 @@ */ import { IUnitInfo } from '../../../../exports/store/interfaces'; -import { IResetUnitInfoAction, IUpdateUnitMapAction, IUpdateUserMapAction } from 'modules/org/store/actions/unit_info'; +import { IResetUnitInfoAction, IUpdateUnitMapAction, IUpdateUserMapAction, IUpdateGroupListAction } from 'modules/org/store/actions/unit_info'; import produce from 'immer'; -import { RESET_UNIT_INFO, UPDATE_UNIT_MAP, UPDATE_USER_MAP } from '../../../shared/store/action_constants'; +import { RESET_UNIT_INFO, UPDATE_GROUP_LIST, UPDATE_UNIT_MAP, UPDATE_USER_MAP } from '../../../shared/store/action_constants'; const defaultState: IUnitInfo = { unitMap: null, userMap: null, }; -type IUnitInfoAction = IUpdateUnitMapAction | IUpdateUserMapAction | IResetUnitInfoAction; +type IUnitInfoAction = IUpdateUnitMapAction | IUpdateUserMapAction | IResetUnitInfoAction | IUpdateGroupListAction; const updateUnitMap = (oldUnitMap: any, newUnitMap: any) => { return { @@ -66,6 +66,10 @@ export const unitInfo = produce( state.unitMap = unitMap; break; } + case UPDATE_GROUP_LIST: { + state.groupList = action.payload; + break; + } case RESET_UNIT_INFO: { return defaultState; } diff --git a/packages/core/src/modules/shared/api/api.interface.ts b/packages/core/src/modules/shared/api/api.interface.ts index 1af0b9035d..d01f518a4d 100644 --- a/packages/core/src/modules/shared/api/api.interface.ts +++ b/packages/core/src/modules/shared/api/api.interface.ts @@ -74,6 +74,7 @@ export interface ILoadOrSearchArg { // `linkId` use to mark the operations that off-site. Now support templateId and shareId. linkId?: string | undefined; all?: boolean; + type?: string; } export interface ISignIn { diff --git a/packages/core/src/modules/shared/api/api.ts b/packages/core/src/modules/shared/api/api.ts index abeea95935..27472e3730 100644 --- a/packages/core/src/modules/shared/api/api.ts +++ b/packages/core/src/modules/shared/api/api.ts @@ -18,7 +18,7 @@ import { IGetCommentsByIdsResponse } from '../../database/api/datasheet_api.interface'; import axios from 'axios'; -import { ConfigConstant } from 'config'; +import { ConfigConstant, getCustomConfig } from 'config'; import * as Url from './url'; import { ILocalChangeset } from 'engine'; import { IApiWrapper, IRubbishListParams } from '../../../exports/store/interfaces'; @@ -57,7 +57,7 @@ const nestBaseURL = process.env.NEXT_PUBLIC_NEXT_API; /** * Upload Attachment * - * @param formData attachment data + * @param file */ export function uploadAttach(file: any) { return axios.post(Url.UPLOAD_ATTACH, file, { @@ -68,7 +68,9 @@ export function uploadAttach(file: any) { /** * Get attachment's preview url * + * @param spaceId * @param token cloud file token + * @param attname */ export function getAttachPreviewUrl(spaceId: string, token: string, attname: string) { return axios.post(urlcat(Url.OFFICE_PREVIEW, { spaceId }), { @@ -98,8 +100,8 @@ export function getNotificationStatistics() { /** * notification list with pagination - * @param pageObjectParams pagination params * @param isRead 1:read 2:unread, if empty, get all + * @param rowNo */ export function getNotificationPage(isRead?: boolean, rowNo?: number) { return axios.get(Url.NOTIFICATION_PAGE, { @@ -282,13 +284,15 @@ export const templateDirectory = (templateId: string, isPrivate: boolean, catego * @param templateId * @param parentId * @param data + * @param unitId * @returns */ -export const useTemplate = (templateId: string, parentId: string, data?: boolean) => { +export const useTemplate = (templateId: string, parentId: string, data?: boolean, unitId?: string) => { return axios.post(Url.USE_TEMPLATE, { templateId, parentId, data, + unitId, }); }; @@ -332,6 +336,7 @@ export function loadOrSearch({ filterIds, keyword, names, unitIds, linkId, all, if (unitIds && unitIds.includes('opt')) { return Promise.reject(); } + return axios.get(Url.LOAD_OR_SEARCH, { params: { filterIds, @@ -356,6 +361,7 @@ export function loadOrSearchEmbed(embedId: string, { filterIds, keyword, names, linkId, all, searchEmail, + type: getCustomConfig().NEXT_PUBLIC_UNIT_SEARCH_TYPE }, }); } @@ -381,6 +387,10 @@ export function searchUnitInfoVo(names: string, linkId?: string) { * @returns */ export function commitRemind(data: ICommitRemind) { + // if(process.env.NEXT_PUBLIC_DISABLED_REMIND_ENDPOINT === 'true') { + // return Promise.reject(); + // } + return axios.post(Url.COMMIT_REMIND, data); } @@ -402,10 +412,12 @@ export function enableRoleExtend(nodeId: string) { */ export function disableRoleExtend(nodeId: string, includeExtend?: boolean) { const params = includeExtend ? { includeExtend } : {}; - if (getBrowserDatabusApiEnabled()){ - WasmApi.getInstance().delete_cache(nodeId).then((result) => { - console.log('delete indexDb cache', result); - }); + if (getBrowserDatabusApiEnabled()) { + WasmApi.getInstance() + .delete_cache(nodeId) + .then((result) => { + console.log('delete indexDb cache', result); + }); } return axios.post(Url.DISABLE_ROLE_EXTEND + `?nodeId=${nodeId}`, params); } @@ -836,7 +848,7 @@ export function applyResourceChangesets(changesets: ILocalChangeset[], roomId: s }, { baseURL: nestBaseURL, - }, + } ); } @@ -857,6 +869,9 @@ export function getNodeInfoWindow(nodeId: string) { * @returns */ export function getNoPermissionMember(nodeId: string, unitIds: string[]) { + // if(process.env.NEXT_PUBLIC_DISABLED_REMIND_ENDPOINT === 'true') { + // return Promise.reject(); + // } return axios.post(Url.NO_PERMISSION_MEMBER, { nodeId, unitIds }); } diff --git a/packages/core/src/modules/shared/store/action_constants.ts b/packages/core/src/modules/shared/store/action_constants.ts index 51c6696cc0..0266b90522 100644 --- a/packages/core/src/modules/shared/store/action_constants.ts +++ b/packages/core/src/modules/shared/store/action_constants.ts @@ -17,6 +17,7 @@ */ export const SET_ROBOT_PANEL_STATUS = 'SET_ROBOT_PANEL_STATUS'; +export const SET_COPILOT_PANEL_STATUS = 'SET_COPILOT_PANEL_STATUS'; export const SET_NEW_RECORD_EXPECT_INDEX = 'SET_NEW_RECORD_EXPECT_INDEX'; export const CLEAR_ACTIVE_ROW_INFO = 'CLEAR_ACTIVE_ROW_INFO'; export const SET_ACTIVE_ROW_INFO = 'SET_ACTIVE_ROW_INFO'; @@ -135,6 +136,8 @@ export const GET_NEW_MSG_FROM_WS_AND_LOOK = 'GET_NEW_MSG_FROM_WS_AND_LOOK'; export const SCROLL_OFFSET = 'SCROLL_OFFSET'; export const SET_NODE_NAME = 'SET_NODE_NAME'; +export const UPDATE_GROUP_LIST = 'UPDATE_GROUP_LIST'; + /** * if the sub-node request failed */ @@ -163,6 +166,7 @@ export const UPDATE_LINK_LIST = 'UPDATE_LINK_LIST'; export const SET_COPY_NODE_ID = 'SET_COPY_NODE_ID'; export const SET_ALL_VISIBLE = 'SET_ALL_VISIBLE'; export const TREE_LOADING = 'TREE_LOADING'; +export const SET_ACTIVE_TREE_TYPE = 'SET_ACTIVE_TREE_TYPE'; export const UPDATE_HAS_CHILDREN = 'UPDATE_HAS_CHILDREN'; export const NODE_MOVE_TO = 'NODE_MOVE_TO'; export const UPDATE_TREE_NODES_MAP = 'UPDATE_TREE_NODES_MAP'; @@ -176,6 +180,7 @@ export const UPDATE_SOCKET_DATA = 'UPDATE_SOCKET_DATA'; export const REFRESH_TREE = 'REFRESH_TREE'; export const SET_ACTIVE_NODE_ERROR = 'SET_ACTIVE_NODE_ERROR'; export const SET_TREE_ROOT_ID = 'SET_TREE_ROOT_ID'; +export const SET_PRIVATE_TREE_ROOT_ID = 'SET_PRIVATE_TREE_ROOT_ID'; export const ADD_NODE_TO_FAVORITE_LIST = 'ADD_NODE_TO_FAVORITE_LIST'; export const REMOVE_FAVORITE_NODE = 'REMOVE_FAVORITE_NODE'; diff --git a/packages/core/src/modules/space/api/api.space.interface.ts b/packages/core/src/modules/space/api/api.space.interface.ts index dfac46f46e..e4ccffb32f 100644 --- a/packages/core/src/modules/space/api/api.space.interface.ts +++ b/packages/core/src/modules/space/api/api.space.interface.ts @@ -4,6 +4,7 @@ export interface IAddNodeParams { nodeName?: string; preNodeId?: string; extra?: { [key: string]: any }; + unitId?: string; aiCreateParams?: { datasheet: { id: string; diff --git a/packages/core/src/modules/space/api/api.space.ts b/packages/core/src/modules/space/api/api.space.ts index cd7953d277..1da82cc05b 100644 --- a/packages/core/src/modules/space/api/api.space.ts +++ b/packages/core/src/modules/space/api/api.space.ts @@ -32,12 +32,15 @@ const CancelToken = axios.CancelToken; * * Query the node tree of the workbench, limit the query to two layers * + * @unitType 1: team, 3: member(private) + * @param unitType * @param depth * @returns */ -export function getNodeTree(depth?: number) { +export function getNodeTree(unitType?: number, depth?: number) { return axios.get(Url.GET_NODE_TREE, { params: { + unitType, depth, }, }); @@ -59,13 +62,15 @@ export function getRootNode() { * * @param nodeId * @param nodeType + * @param unitType * @returns */ -export function getChildNodeList(nodeId: string, nodeType?: NodeType) { +export function getChildNodeList(nodeId: string, nodeType?: NodeType, unitType?: number) { return axios.get[] }>(Url.GET_NODE_LIST, { params: { nodeId, nodeType, + unitType, }, }); } @@ -143,12 +148,14 @@ export function createSpace(name: string) { * @param nodeId the node id that will be moved. * @param parentId the parent node id that will be placed here. * @param preNodeId + * @param unitId */ -export function nodeMove(nodeId: string, parentId: string, preNodeId?: string) { +export function nodeMove(nodeId: string, parentId: string, preNodeId?: string, unitId?: string) { return axios.post(Url.MOVE_NODE, { nodeId, parentId, preNodeId, + unitId }); } @@ -164,10 +171,12 @@ export function addNode(nodeInfo: IAddNodeParams) { * @param nodeId Node Id */ export function delNode(nodeId: string) { - if (getBrowserDatabusApiEnabled()){ - WasmApi.getInstance().delete_cache(nodeId).then((result) => { - console.log('delete indexDb cache', result); - }); + if (getBrowserDatabusApiEnabled()) { + WasmApi.getInstance() + .delete_cache(nodeId) + .then((result) => { + console.log('delete indexDb cache', result); + }); } return axios.delete(Url.DELETE_NODE + nodeId); } @@ -186,12 +195,15 @@ export function getSpecifyNodeList(nodeType: NodeType) { * @param nodeId Node ID * @param data */ -export function editNode(nodeId: string, data: { - nodeName?: string; - icon?: string; - cover?: string; - showRecordHistory?: ShowRecordHistory -}) { +export function editNode( + nodeId: string, + data: { + nodeName?: string; + icon?: string; + cover?: string; + showRecordHistory?: ShowRecordHistory; + } +) { return axios.post(Url.EDIT_NODE + nodeId, data); } @@ -248,6 +260,7 @@ export function quitSpace(spaceId: string) { * Find nodes * * @param keyword the keyword to search + * @param ctx */ export function findNode(keyword: string, ctx: any) { return axios.get(Url.SEARCH_NODE, { @@ -263,13 +276,15 @@ export function findNode(keyword: string, ctx: any) { * * @param spaceId * @param keyword + * @param unitType * @returns */ -export function searchNode(spaceId: string, keyword: string) { +export function searchNode(spaceId: string, keyword: string, unitType?: number) { return axios.get(Url.SEARCH_NODE, { params: { spaceId, keyword, + unitType }, }); } @@ -382,7 +397,6 @@ export function searchSpaceSize() { /** * Get the number of nodes(folders and files) in the specified space - * @param spaceId */ export function getSpaceNodeNumber() { return axios.get(Url.NODE_NUMBER); @@ -390,7 +404,6 @@ export function getSpaceNodeNumber() { /** * Get the permissions resources of the specified space - * @param spaceId */ export function getSpaceResource() { return axios.get(Url.SPACE_RESOURCE); @@ -438,6 +451,7 @@ export function subAdminPermission(memberId: string) { * fuzzy search members * * @param keyword the keyword to search + * @param filter */ export function searchMember(keyword: string, filter: boolean) { return axios.get(Url.MEMBER_SEARCH, { @@ -451,7 +465,7 @@ export function searchMember(keyword: string, filter: boolean) { /** * add sub-admin * - * @param memberId member id + * @param memberIds * @param resourceCodes operation resources set, no orders, auto verify */ export function addSubMember(memberIds: string[], resourceCodes: string[]) { @@ -464,6 +478,7 @@ export function addSubMember(memberIds: string[], resourceCodes: string[]) { /** * edit sub-admin * + * @param id * @param memberId member id * @param resourceCodes operation resources set, no orders, auto verify */ @@ -479,6 +494,7 @@ export function editSubMember(id: string, memberId: string, resourceCodes: strin * search organization resource * * @param keyword keywords(tag/team) + * @param linkId */ export function searchUnit(keyword: string, linkId?: string) { return axios.get(Url.SEARCH_UNIT, { @@ -506,6 +522,7 @@ export function getAllVisibleStatus() { /** * get child teams and members * @param teamId Team ID + * @param linkId */ export function getSubUnitList(teamId?: string, linkId?: string) { return axios.get(Url.GET_SUB_UNIT_LIST, { @@ -516,6 +533,32 @@ export function getSubUnitList(teamId?: string, linkId?: string) { }); } +interface IGetOrgYachGroupList { + groupName?: string; + pageObjectParams: { + pageSize: number; + pageNo: number; + }; +} +export function getOrgYachGroupList({ groupName, pageObjectParams }: IGetOrgYachGroupList) { + return axios.get(Url.GET_ORG_YACH_GROUP, { + params: { + groupName, + pageObjectParams: JSON.stringify(pageObjectParams), + }, + }); +} + +interface IYachAddRole { + nodeId: string; + unitIds: string[]; + role: string; +} + +export function yachAddRole(data: IYachAddRole) { + return axios.post(Url.YACH_ADD_ROLE, data); +} + /** * Update(edit) role * @@ -568,6 +611,27 @@ export function getCapacityRewardList(isExpire: boolean, pageNo: number) { }); } +/** + * Get Space node infos + * + * @param spaceId + * @param pageNo + * @returns + */ +export function getCapacityNodeList(spaceId: string, pageNo: number) { + const pageObjectParams = JSON.stringify({ + pageSize: ConfigConstant.CAPACITY_REWARD_LIST_PAGE_SIZE, + order: 'createdAt', + sort: ConfigConstant.SORT_DESC, + pageNo, + }); + return axios.get(urlcat(Url.CAPACITY_NODE_LIST, { spaceId }), { + params: { + pageObjectParams, + }, + }); +} + /** * change node's description * @@ -646,7 +710,7 @@ export function updateShare( onlyRead?: boolean; canBeEdited?: boolean; canBeStored?: boolean; - }, + } ) { return axios.post(Url.UPDATE_SHARE + nodeId, { props: JSON.stringify(permission), @@ -657,6 +721,7 @@ export function updateShare( * folder node preview * * @param nodeId + * @param shareId */ export function nodeShowcase(nodeId: string, shareId?: string) { return axios.get(Url.NODE_SHOWCASE, { @@ -667,11 +732,12 @@ export function nodeShowcase(nodeId: string, shareId?: string) { }); } -export function checkoutOrder(spaceId: string, priceId: string, clientReferenceId: string, couponId: string) { +export function checkoutOrder(spaceId: string, priceId: string, clientReferenceId: string, couponId: string, trial?: boolean) { return axios.post(Url.CHECKOUT_ORDER, { spaceId, priceId, clientReferenceId, couponId, + trial, }); } diff --git a/packages/core/src/modules/space/api/url.space.ts b/packages/core/src/modules/space/api/url.space.ts index 8d6fe4b78e..4750d0459f 100644 --- a/packages/core/src/modules/space/api/url.space.ts +++ b/packages/core/src/modules/space/api/url.space.ts @@ -84,6 +84,13 @@ export const SPACE_RESOURCE = '/space/resource'; export const NO_PERMISSION_MEMBER = '/node/remind/units/noPermission'; // Give attachment space capacity details export const CAPACITY_REWARD_LIST = '/space/capacity/detail'; +// Give node capacity details +export const CAPACITY_NODE_LIST = '/space/:spaceId/node/statistics'; +// email invitation +export const SEND_EMAIL_INVITATION = '/spaces/:spaceId/email-invitations'; +export const RESEND_EMAIL_INVITATION = '/spaces/:spaceId/email-invitation/resend'; +export const VALID_EMAIL_INVITATION = '/email-invitations/:inviteToken/valid'; +export const ACCEPT_EMAIL_INVITATION = '/spaces/:spaceId/email-invitations/:inviteToken/accept'; // link invite export const CREATE_LINK = '/space/link/generate'; export const LINK_LIST = '/space/link/list'; diff --git a/packages/core/src/modules/space/store/actions/catalog_tree.ts b/packages/core/src/modules/space/store/actions/catalog_tree.ts index 2f10271e47..1aea7f64a2 100644 --- a/packages/core/src/modules/space/store/actions/catalog_tree.ts +++ b/packages/core/src/modules/space/store/actions/catalog_tree.ts @@ -43,6 +43,7 @@ export function setErr(err: string) { * set current edit state node ID * * @param nodeId Node ID + * @param module */ export function setEditNodeId(nodeId: string, module: ConfigConstant.Modules = ConfigConstant.Modules.CATALOG) { return { @@ -58,6 +59,7 @@ export function setEditNodeId(nodeId: string, module: ConfigConstant.Modules = C * Set the node ID to delete * * @param nodeId Node ID + * @param module */ export function setDelNodeId(nodeId: string, module: ConfigConstant.Modules = ConfigConstant.Modules.CATALOG) { return { @@ -91,6 +93,19 @@ export const setTreeRootId = (nodeId: string) => { }; }; +/** + * Set the root Node ID + * + * @param nodeId + * @returns + */ +export const setPrivateTreeRootId = (nodeId: string) => { + return { + type: actions.SET_PRIVATE_TREE_ROOT_ID, + payload: nodeId, + }; +}; + /** * Current Node that is opening permission UI window * @param nodeId Node ID @@ -141,6 +156,7 @@ export function updateImportModalNodeId(nodeId: string) { * Set the array of expanded nodes * * @param expandedKeys the keys array of expanded nodes + * @param module */ export function setExpandedKeys(expandedKeys: string[], module: ConfigConstant.Modules = ConfigConstant.Modules.CATALOG) { return { @@ -155,12 +171,18 @@ export function setExpandedKeys(expandedKeys: string[], module: ConfigConstant.M /** * add single or multiple nodes to treeNodeMap (catalog tree data source) * - * @param Node Single node or collection of nodes + * @param data + * @param isCoverChildren + * @param module */ -export const addNodeToMap = (data: (Omit & { children?: string[] })[], isCoverChildren = true) => { +export const addNodeToMap = ( + data: (Omit & { children?: string[] })[], + isCoverChildren = true, + module: ConfigConstant.Modules = ConfigConstant.Modules.CATALOG +) => { return { type: actions.ADD_NODE_TO_MAP, - payload: { data, isCoverChildren }, + payload: { data, isCoverChildren, module }, }; }; @@ -168,10 +190,14 @@ export const addNodeToMap = (data: (Omit & { children * add nodes to files tree(catalog) * * @param node the node info of new + * @param module */ -export const addNode = (node: INodesMapItem) => { +export const addNode = (node: INodesMapItem, module?: ConfigConstant.Modules) => { return (dispatch: any) => { - dispatch(batchActions([addNodeToMap([node]), setEditNodeId(node.nodeId)], 'ADD_NODE')); + dispatch(batchActions([ + addNodeToMap([node], true, module), + setEditNodeId(node.nodeId, module) + ], 'ADD_NODE')); }; }; @@ -192,23 +218,26 @@ export const updateSocketData = (data: INodeChangeSocketData) => { * * @param nodeId Node ID * @param nodeName Node Name + * @param module */ -export function setNodeName(nodeId: string, nodeName: string) { +export function setNodeName(nodeId: string, nodeName: string, module?: ConfigConstant.Modules) { return { type: actions.SET_NODE_NAME, payload: { nodeId, nodeName, + module }, }; } -export function setNodeErrorType(nodeId: string, errType: NodeErrorType | null) { +export function setNodeErrorType(nodeId: string, errType: NodeErrorType | null, module?: ConfigConstant.Modules) { return { type: actions.SET_NODE_ERROR_TYPE, payload: { nodeId, errType, + module }, }; } @@ -218,30 +247,31 @@ export function setNodeErrorType(nodeId: string, errType: NodeErrorType | null) * and attach them to files tree. * * @param nodeId Node ID + * @param module */ -export function getChildNode(nodeId: string): any { +export function getChildNode(nodeId: string, module?: ConfigConstant.Modules): any { return async (dispatch: Dispatch, getState: () => IReduxState) => { const state: IReduxState = getState(); const { loadedKeys } = state.catalogTree; - dispatch(setTreeLoading(true)); - const nodeData = await getChildNodeList(nodeId); + dispatch(setTreeLoading(true, module)); + const nodeData = await getChildNodeList(nodeId, module === ConfigConstant.Modules.PRIVATE ? 3 : undefined); if (nodeData === NodeErrorType.ChildNodes) { - dispatch(setTreeLoading(false)); - dispatch(setNodeErrorType(nodeId, NodeErrorType.ChildNodes)); + dispatch(setTreeLoading(false, module)); + dispatch(setNodeErrorType(nodeId, NodeErrorType.ChildNodes, module)); return; } if (!nodeData || (Array.isArray(nodeData) && !nodeData.length)) { - dispatch(setTreeLoading(false)); + dispatch(setTreeLoading(false, module)); dispatch(setLoadedKeys([...loadedKeys, nodeId])); - dispatch(setNodeErrorType(nodeId, null)); + dispatch(setNodeErrorType(nodeId, null, module)); return; } // update current node has child nodes - dispatch(addNodeToMap(flatNodeTree(nodeData), false)); - dispatch(updateHasChildren(nodeId)); - dispatch(setNodeErrorType(nodeId, null)); - dispatch(setTreeLoading(false)); + dispatch(addNodeToMap(flatNodeTree(nodeData), false, module)); + dispatch(updateHasChildren(nodeId, module)); + dispatch(setNodeErrorType(nodeId, null, module)); + dispatch(setTreeLoading(false, module)); }; } @@ -249,21 +279,23 @@ export function getChildNode(nodeId: string): any { * update node's hasChildren state * * @param nodeId the node that want to update + * @param module */ -export function updateHasChildren(nodeId: string) { +export function updateHasChildren(nodeId: string, module?: ConfigConstant.Modules) { return { type: actions.UPDATE_HAS_CHILDREN, - payload: nodeId, + payload: { nodeId, module }, }; } /** * get specified node's child nodes. * @param nodeId + * @param unitType * @returns */ -const getChildNodeList = (nodeId: string) => { - return Api.getChildNodeList(nodeId).then(res => { +const getChildNodeList = (nodeId: string, unitType?: number) => { + return Api.getChildNodeList(nodeId, undefined, unitType).then(res => { const { success, data } = res.data; if (success) { return data; @@ -272,6 +304,20 @@ const getChildNodeList = (nodeId: string) => { }).catch(() => NodeErrorType.ChildNodes); }; +/** + * the loading state of current files tree. + * + * @param module + * @returns + */ + +export const setActiveTreeType = (module?: ConfigConstant.Modules) => { + return { + type: actions.SET_ACTIVE_TREE_TYPE, + payload: module, + }; +}; + /** * the loading state of current files tree. * @@ -295,15 +341,17 @@ export const setTreeLoading = (loading: boolean, module: ConfigConstant.Modules * @param {string} nodeId Node ID * @param {string} targetNodeId target node ID * @param {number} pos -1: above the target node | 0:move into target node | 1:below the target node + * @param module * @returns */ -export const moveTo = (nodeId: string, targetNodeId: string, pos: number) => { +export const moveTo = (nodeId: string, targetNodeId: string, pos: number, module?: ConfigConstant.Modules) => { return { type: actions.NODE_MOVE_TO, payload: { nodeId, targetNodeId, pos, + module, }, }; }; @@ -328,7 +376,7 @@ export function initCatalogTree() { /** * remove single or multi nodes from treeNodeMap(catalog tree data source) - * @param Node single node or collection of nodes + * @param nodeId */ export const removeNodeFromMap = (nodeId: string | string[]) => { return { @@ -339,7 +387,7 @@ export const removeNodeFromMap = (nodeId: string | string[]) => { /** * remove single or multi nodes from tree - * @param data single node or collection of nodes + * @param nodeId */ export const removeNodeFromTree = (nodeId: string | string[]) => { return { @@ -374,13 +422,15 @@ export function updateIsPermission(status: boolean) { * * @param nodeId Node ID * @param data new data + * @param module */ -export const updateTreeNodesMap = (nodeId: string, data: Partial) => { +export const updateTreeNodesMap = (nodeId: string, data: Partial, module?: ConfigConstant.Modules) => { return { type: actions.UPDATE_TREE_NODES_MAP, payload: { nodeId, data, + module, }, }; }; @@ -403,11 +453,11 @@ export const refreshTree = (data: INode[]) => { * @param optNode the node info that is under operation. */ export const deleteNode = (optNode: IOptNode) => { - + const { module } = optNode; const actions = [ deleteNodeAction(optNode), deleteNodeFromFavoriteList(optNode), - setDelNodeId(''), + setDelNodeId('', module), setDelNodeId('', ConfigConstant.Modules.FAVORITE), ]; return (dispatch: any) => { @@ -419,14 +469,16 @@ export const deleteNode = (optNode: IOptNode) => { * find the path of the node by parentId, and expand all the folders on them. * * @param nodeId Node ID + * @param module */ -export const collectionNodeAndExpand = (nodeId: string) => { +export const collectionNodeAndExpand = (nodeId: string, module?: ConfigConstant.Modules) => { return (dispatch: Dispatch, getState: () => IReduxState) => { const state = getState(); - const { rootId, expandedKeys, treeNodesMap, favoriteExpandedKeys, favoriteTreeNodeIds } = state.catalogTree; - const newExpandKeys = [...(new Set([...expandedKeys, ...getExpandNodeIds(treeNodesMap, nodeId, rootId)]))]; - const newFavoriteExpandKeys = [...(new Set([...favoriteExpandedKeys, ...getExpandNodeIds(treeNodesMap, nodeId, rootId, favoriteTreeNodeIds)]))]; - dispatch(setExpandedKeys(newExpandKeys)); + const { rootId, expandedKeys, treeNodesMap, favoriteExpandedKeys, favoriteTreeNodeIds, privateTreeNodesMap } = state.catalogTree; + const nodesMap = module === ConfigConstant.Modules.PRIVATE ? privateTreeNodesMap : treeNodesMap; + const newExpandKeys = [...(new Set([...expandedKeys, ...getExpandNodeIds(nodesMap, nodeId, rootId)]))]; + const newFavoriteExpandKeys = [...(new Set([...favoriteExpandedKeys, ...getExpandNodeIds(nodesMap, nodeId, rootId, favoriteTreeNodeIds)]))]; + dispatch(setExpandedKeys(newExpandKeys, module)); dispatch(setExpandedKeys(newFavoriteExpandKeys, ConfigConstant.Modules.FAVORITE)); }; }; @@ -438,7 +490,7 @@ export const collectionNodeAndExpand = (nodeId: string) => { */ export const generateFavoriteTree = (node: INodesMapItem[]) => { return (dispatch: Dispatch) => { - dispatch(addNodeToMap(node)); + // dispatch(addNodeToMap(node, true, module)); const nodeIds = node.map(item => item.nodeId); dispatch(addNodeToFavoriteTree(nodeIds)); }; @@ -463,13 +515,16 @@ export const addNodeToFavoriteTree = (nodeIds: string[], parentId = '') => { /** * remove favorite (star) * @param nodeId + * @param nodePrivate * @returns */ -export const removeFavorite = (nodeId: string) => { +export const removeFavorite = (nodeId: string, nodePrivate?: boolean) => { return (dispatch: Dispatch, getState: () => IReduxState) => { const state = getState(); - const type = state.catalogTree.treeNodesMap[nodeId]!.type; - dispatch(updateNodeInfo(nodeId, type, { nodeFavorite: false })); + const nodeKey = nodePrivate ? 'privateTreeNodesMap' : 'treeNodesMap'; + const type = state.catalogTree[nodeKey][nodeId]!.type; + const _module = nodePrivate ? ConfigConstant.Modules.PRIVATE : undefined; + dispatch(updateNodeInfo(nodeId, type, { nodeFavorite: false }, _module)); dispatch({ type: actions.DELETE_NODE_FROM_FAVORITE_LIST, payload: { nodeId }, @@ -523,8 +578,9 @@ export const getNodeInfo = (nodeId: string) => { return (dispatch: Dispatch) => { Api.getNodeInfo(nodeId).then(res => { const { success, data } = res.data; + const isPrivate = data?.[0]?.nodePrivate; if (success) { - dispatch(addNodeToMap(data)); + dispatch(addNodeToMap(data, undefined, isPrivate ? ConfigConstant.Modules.PRIVATE : undefined)); } }, err => { console.error('API.getNodeInfo error', err); @@ -538,9 +594,10 @@ export const getNodeInfo = (nodeId: string) => { * @param nodeId * @param nodeType * @param data + * @param module * @returns */ -export const updateNodeInfo = (nodeId: string, nodeType: ConfigConstant.NodeType, data: Partial): any => { +export const updateNodeInfo = (nodeId: string, nodeType: ConfigConstant.NodeType, data: Partial, module?: ConfigConstant.Modules): any => { return (dispatch: Dispatch) => { switch (nodeType) { case ConfigConstant.NodeType.DATASHEET: { @@ -562,12 +619,12 @@ export const updateNodeInfo = (nodeId: string, nodeType: ConfigConstant.NodeType } const { name, ...info } = data; const nodeData = name ? { ...info, nodeName: name } : info; - dispatch(updateTreeNodesMap(nodeId, nodeData)); + dispatch(updateTreeNodesMap(nodeId, nodeData, module)); }; }; /** - * set permissions, whether or not to send a notification when popup window closed. + * set permissions, whether to send a notification when popup window closed. * * @param status * @returns diff --git a/packages/core/src/modules/space/store/actions/space.ts b/packages/core/src/modules/space/store/actions/space.ts index 7253aa0266..27bfa99231 100644 --- a/packages/core/src/modules/space/store/actions/space.ts +++ b/packages/core/src/modules/space/store/actions/space.ts @@ -23,7 +23,7 @@ import * as ActionConstants from 'modules/shared/store/action_constants'; import { IApp, IEnvs, IReduxState, ISpaceBasicInfo, ISpaceErr, ISpaceFeatures, ISpaceInfo } from 'exports/store/interfaces'; import { initCatalogTree } from './catalog_tree'; import { getUserMe } from '../../../user/store/actions/user'; -import { updateSpaceResource } from 'exports/store/actions'; +import { setLabs, updateSpaceResource } from 'exports/store/actions'; /** * Get Space List @@ -210,6 +210,7 @@ export const getSpaceInfo = (spaceId: string, ignoreTimeLimit: boolean = false) dispatch(setSpaceInfo({ ...data, lastUpdateTime: Date.now() })); dispatch(setSpaceFeatures(data.feature)); dispatch(updateSpaceResource(data.userResource)); + dispatch(setLabs(data.labsKeys)); } }, err => { console.log('API.spaceInfo error', err); diff --git a/packages/core/src/modules/space/store/interfaces/catalog_tree.ts b/packages/core/src/modules/space/store/interfaces/catalog_tree.ts index f7e9c007cd..a79b604edb 100644 --- a/packages/core/src/modules/space/store/interfaces/catalog_tree.ts +++ b/packages/core/src/modules/space/store/interfaces/catalog_tree.ts @@ -29,9 +29,7 @@ export interface ICatalogTree { node: INewNode | null; delNodeId: string; editNodeId: string; - favoriteEditNodeId: string; copyNodeId: string; - favoriteDelNodeId: string; isCopyAll: boolean; err: string; optNode: IOptNode | null; @@ -43,6 +41,17 @@ export interface ICatalogTree { allVisible: boolean; isPermission: boolean; socketData: INodeChangeSocketData | null; + activeType?: ConfigConstant.Modules; + // private + privateRootId: string; + privateLoading: boolean; + privateEditNodeId: string; + privateDelNodeId: string; + privateTreeNodesMap: ITreeNodesMap; + privateExpandedKeys:string[]; + // favorite + favoriteEditNodeId: string; + favoriteDelNodeId: string; favoriteTreeNodeIds: string[]; favoriteLoading: boolean; favoriteExpandedKeys: string[]; @@ -79,7 +88,7 @@ export interface IRightClickInfo { */ module: ConfigConstant.Modules; /** - * indicates which type of menu to call + * indicates which type of menu to call */ contextMenuType: ConfigConstant.ContextMenuType; // current node's level @@ -104,6 +113,8 @@ export interface INode { nodePermitSet: boolean; nodeFavorite: boolean; preFavoriteNodeId?: string; + extra?: any; + nodePrivate: boolean; } export interface INodePermissions { @@ -251,6 +262,7 @@ export interface ISetNodeNameAction { payload: { nodeId: string; nodeName: string; + module?: ConfigConstant.Modules; }; } @@ -259,12 +271,14 @@ export interface ISetNodeErrorTypeAction { payload: { nodeId: string; errType: NodeErrorType; + module?: ConfigConstant.Modules; }; } export interface IOptNode { nodeId: string; parentId: string; + module?: ConfigConstant.Modules } export interface INewNode extends INode { @@ -383,6 +397,11 @@ export type UnitItem = roleName: string; memberCount: number; position: number; + } + | { + unitId?: string; + groupId: string; + groupName: string; }; export interface IRefreshTreeAction { @@ -395,6 +414,11 @@ export interface ISetAllVisibleAction { payload: boolean; } +export interface ISetActiveTreeType { + type: typeof actions.SET_ACTIVE_TREE_TYPE; + payload: ConfigConstant.Modules; +} + // Action export interface ISetDelNodeIdAction { type: typeof actions.SET_DEL_NODE_ID; @@ -455,6 +479,7 @@ export interface IAddNodeToMapAction { * Whether to keep the old children or use the new children to replace the old children */ isCoverChildren: boolean; + module: ConfigConstant.Modules; }; } @@ -490,7 +515,10 @@ export interface ISetLoadedAction { export interface IUpdateHasChildren { type: typeof actions.UPDATE_HAS_CHILDREN; - payload: string; + payload: { + nodeId: string; + module?: ConfigConstant.Modules; + }; } export interface IMoveToAction { @@ -499,6 +527,7 @@ export interface IMoveToAction { nodeId: string; targetNodeId: string; pos: number; + module?: ConfigConstant.Modules; }; } @@ -507,6 +536,7 @@ export interface IUpdateTreeNodesMapAction { payload: { nodeId: string; data: Partial; + module?: ConfigConstant.Modules; }; } @@ -593,6 +623,11 @@ export interface ISetTreeRootIdAction { payload: string; } +export interface ISetPrivateTreeRootIdAction { + type: typeof actions.SET_PRIVATE_TREE_ROOT_ID; + payload: string; +} + export interface ISetLoadedKeysAction { type: typeof actions.SET_LOADED_KEYS; payload: string[]; @@ -610,7 +645,7 @@ export interface ISetPermissionCommitRemindParameterAction { export interface ISetNoPermissionMembersAction { type: typeof actions.SET_NO_PERMISSION_MEMBERS; - payload: string[] + payload: string[]; } export interface IUpdateMoveToNodeIdsAction { diff --git a/packages/core/src/modules/space/store/interfaces/share.ts b/packages/core/src/modules/space/store/interfaces/share.ts index 9e4d575343..42ad0296d2 100644 --- a/packages/core/src/modules/space/store/interfaces/share.ts +++ b/packages/core/src/modules/space/store/interfaces/share.ts @@ -24,6 +24,7 @@ export interface IShareNodeTree { icon: string; type: number; children: any[]; + nodePrivate: boolean; } export interface IShareInfo { diff --git a/packages/core/src/modules/space/store/interfaces/space.ts b/packages/core/src/modules/space/store/interfaces/space.ts index 3b2bebfa54..967db5dcdb 100644 --- a/packages/core/src/modules/space/store/interfaces/space.ts +++ b/packages/core/src/modules/space/store/interfaces/space.ts @@ -130,6 +130,7 @@ export interface ISpaceBasicInfo { galleryViewNums: number; ganttViewNums: number; kanbanViewNums: number; + labsKeys: string[]; calendarViewNums: number; mirrorNums: number; nodeRoleNums: number; diff --git a/packages/core/src/modules/space/store/interfaces/template_centre.ts b/packages/core/src/modules/space/store/interfaces/template_centre.ts index 0c0327f6f9..f08a501d0b 100644 --- a/packages/core/src/modules/space/store/interfaces/template_centre.ts +++ b/packages/core/src/modules/space/store/interfaces/template_centre.ts @@ -70,6 +70,7 @@ export interface ITemplateTree { nodeName: string; icon: string; type: number; + extra: string; children: ITemplateTree[]; } diff --git a/packages/core/src/modules/space/store/reducers/catalog_tree.ts b/packages/core/src/modules/space/store/reducers/catalog_tree.ts index 2790c0c1d0..b46c42868e 100644 --- a/packages/core/src/modules/space/store/reducers/catalog_tree.ts +++ b/packages/core/src/modules/space/store/reducers/catalog_tree.ts @@ -20,14 +20,53 @@ import { ConfigConstant } from 'config'; import { produce } from 'immer'; import { collectProperty, findNode, getUniqName } from 'utils'; import { - IAddNodeToFavoriteTreeAction, IAddNodeToMapAction, ICatalogTree, IClearNodeAction, ICoLayerMoveNodeAction, IDeleteNodeAction, - IDeleteNodeFromFavoriteTreeAction, IInitCatalogTreeAction, IInitFavoriteTreeNodesAction, IMoveFavoriteNodeAction, IMoveNodeToFolderAction, - IMoveToAction, INode, INodesMapItem, IOptNode, IRefreshTreeAction, IRemoveFavoriteNodeAction, ISetActiveNodeErrorAction, ISetAllVisibleAction, - ISetCopyNodeIdAction, ISetDelNodeIdAction, ISetEditNodeIdAction, ISetErrAction, ISetExpandedKeysActions, ISetIsCopyAllAction, ISetLoadedAction, - ISetLoadedKeysAction, ISetNodeErrorTypeAction, ISetNodeNameAction, ISetNoPermissionMembersAction, ISetOptNodeAction, - ISetPermissionCommitRemindParameterAction, ISetPermissionModalMessageStatusAction, ISetRootIdAction, ISetTreeRootIdAction, ITreeNode, ITreeNodesMap, - IUpdateHasChildren, IUpdateImportModalNodeIdAction, IUpdateIsPermissionAction, IUpdateMoveToNodeIdsAction, IUpdatePermissionModalNodeIdAction, - IUpdateSaveAsTemplateModalNodeIdAction, IUpdateShareModalNodeIdAction, IUpdateSocketDataAction, IUpdateTreeNodesMapAction, + IAddNodeToFavoriteTreeAction, + IAddNodeToMapAction, + ICatalogTree, + IClearNodeAction, + ICoLayerMoveNodeAction, + IDeleteNodeAction, + IDeleteNodeFromFavoriteTreeAction, + IInitCatalogTreeAction, + IInitFavoriteTreeNodesAction, + IMoveFavoriteNodeAction, + IMoveNodeToFolderAction, + IMoveToAction, + INode, + INodesMapItem, + IOptNode, + IRefreshTreeAction, + IRemoveFavoriteNodeAction, + ISetActiveNodeErrorAction, ISetActiveTreeType, + ISetAllVisibleAction, + ISetCopyNodeIdAction, + ISetDelNodeIdAction, + ISetEditNodeIdAction, + ISetErrAction, + ISetExpandedKeysActions, + ISetIsCopyAllAction, + ISetLoadedAction, + ISetLoadedKeysAction, + ISetNodeErrorTypeAction, + ISetNodeNameAction, + ISetNoPermissionMembersAction, + ISetOptNodeAction, + ISetPermissionCommitRemindParameterAction, + ISetPermissionModalMessageStatusAction, + ISetPrivateTreeRootIdAction, + ISetRootIdAction, + ISetTreeRootIdAction, + ITreeNode, + ITreeNodesMap, + IUpdateHasChildren, + IUpdateImportModalNodeIdAction, + IUpdateIsPermissionAction, + IUpdateMoveToNodeIdsAction, + IUpdatePermissionModalNodeIdAction, + IUpdateSaveAsTemplateModalNodeIdAction, + IUpdateShareModalNodeIdAction, + IUpdateSocketDataAction, + IUpdateTreeNodesMapAction, } from '../../../../exports/store/interfaces'; import * as actions from '../../../shared/store/action_constants'; import { uniq } from 'lodash'; @@ -89,12 +128,18 @@ const defaultState: ICatalogTree = { * all visible */ allVisible: false, - // whether or not to have current datasheet permission + // whether to have current datasheet permission isPermission: true, /** * the push data by socket */ socketData: null, + privateRootId: '', + privateLoading: false, + privateEditNodeId: '', + privateDelNodeId: '', + privateTreeNodesMap: {}, + privateExpandedKeys: [], // favorite tree node ids favoriteTreeNodeIds: [], // the loading state of favorite star @@ -131,17 +176,52 @@ const defaultState: ICatalogTree = { /** * the unit(member) ids that have no permission */ - noPermissionMembers: [] + noPermissionMembers: [], }; -type CatalogTreeActions = ISetNodeNameAction | ISetRootIdAction | ISetDelNodeIdAction | IDeleteNodeAction | IMoveNodeToFolderAction | - ICoLayerMoveNodeAction | ISetOptNodeAction | ISetErrAction | ISetEditNodeIdAction | IAddNodeToMapAction | ISetIsCopyAllAction | - ISetExpandedKeysActions | IInitCatalogTreeAction | ISetCopyNodeIdAction | ISetAllVisibleAction | ISetLoadedAction | IUpdateHasChildren | - IMoveToAction | IUpdateTreeNodesMapAction | IClearNodeAction | IUpdateIsPermissionAction | IUpdateSocketDataAction | IRefreshTreeAction | - IAddNodeToFavoriteTreeAction | IRemoveFavoriteNodeAction | IDeleteNodeFromFavoriteTreeAction | IMoveFavoriteNodeAction | - IInitFavoriteTreeNodesAction | ISetActiveNodeErrorAction | IUpdatePermissionModalNodeIdAction | IUpdateShareModalNodeIdAction | - IUpdateSaveAsTemplateModalNodeIdAction | IUpdateImportModalNodeIdAction | ISetTreeRootIdAction | ISetLoadedKeysAction | ISetNodeErrorTypeAction | - ISetPermissionModalMessageStatusAction | ISetPermissionCommitRemindParameterAction | ISetNoPermissionMembersAction | IUpdateMoveToNodeIdsAction; +type CatalogTreeActions = + | ISetNodeNameAction + | ISetRootIdAction + | ISetDelNodeIdAction + | IDeleteNodeAction + | IMoveNodeToFolderAction + | ICoLayerMoveNodeAction + | ISetOptNodeAction + | ISetErrAction + | ISetEditNodeIdAction + | IAddNodeToMapAction + | ISetIsCopyAllAction + | ISetExpandedKeysActions + | IInitCatalogTreeAction + | ISetCopyNodeIdAction + | ISetAllVisibleAction + | ISetLoadedAction + | IUpdateHasChildren + | IMoveToAction + | IUpdateTreeNodesMapAction + | IClearNodeAction + | IUpdateIsPermissionAction + | IUpdateSocketDataAction + | IRefreshTreeAction + | IAddNodeToFavoriteTreeAction + | IRemoveFavoriteNodeAction + | IDeleteNodeFromFavoriteTreeAction + | IMoveFavoriteNodeAction + | IInitFavoriteTreeNodesAction + | ISetActiveNodeErrorAction + | IUpdatePermissionModalNodeIdAction + | IUpdateShareModalNodeIdAction + | IUpdateSaveAsTemplateModalNodeIdAction + | IUpdateImportModalNodeIdAction + | ISetTreeRootIdAction + | ISetPrivateTreeRootIdAction + | ISetLoadedKeysAction + | ISetNodeErrorTypeAction + | ISetPermissionModalMessageStatusAction + | ISetPermissionCommitRemindParameterAction + | ISetNoPermissionMembersAction + | ISetActiveTreeType + | IUpdateMoveToNodeIdsAction; export const catalogTree = produce((draftCatalogTree: ICatalogTree = defaultState, action: CatalogTreeActions) => { switch (action.type) { @@ -156,6 +236,10 @@ export const catalogTree = produce((draftCatalogTree: ICatalogTree = defaultStat draftCatalogTree.delNodeId = nodeId; break; } + case ConfigConstant.Modules.PRIVATE: { + draftCatalogTree.privateDelNodeId = nodeId; + break; + } case ConfigConstant.Modules.FAVORITE: { draftCatalogTree.favoriteDelNodeId = nodeId; break; @@ -178,6 +262,10 @@ export const catalogTree = produce((draftCatalogTree: ICatalogTree = defaultStat draftCatalogTree.editNodeId = nodeId; break; } + case ConfigConstant.Modules.PRIVATE: { + draftCatalogTree.privateEditNodeId = nodeId; + break; + } case ConfigConstant.Modules.FAVORITE: { draftCatalogTree.favoriteEditNodeId = nodeId; break; @@ -186,22 +274,33 @@ export const catalogTree = produce((draftCatalogTree: ICatalogTree = defaultStat return draftCatalogTree; } case actions.SET_NODE_NAME: { - const { nodeId, nodeName } = action.payload; - draftCatalogTree.treeNodesMap[nodeId]!.nodeName = nodeName; + const { nodeId, nodeName, module } = action.payload; + if (module === ConfigConstant.Modules.PRIVATE) { + draftCatalogTree.privateTreeNodesMap[nodeId]!.nodeName = nodeName; + } else { + draftCatalogTree.treeNodesMap[nodeId]!.nodeName = nodeName; + } return draftCatalogTree; } case actions.SET_NODE_ERROR_TYPE: { - const { nodeId, errType } = action.payload; - draftCatalogTree.treeNodesMap[nodeId]!.errType = errType; + const { nodeId, errType, module } = action.payload; + if (module === ConfigConstant.Modules.PRIVATE) { + draftCatalogTree.privateTreeNodesMap[nodeId]!.errType = errType; + } else { + draftCatalogTree.treeNodesMap[nodeId]!.errType = errType; + } return draftCatalogTree; } case actions.ADD_NODE_TO_MAP: { - const { data, isCoverChildren } = action.payload; - addNodeToMap(draftCatalogTree, data, isCoverChildren); + const { data, isCoverChildren, module } = action.payload; + addNodeToMap(draftCatalogTree, data, isCoverChildren, module); return draftCatalogTree; } case actions.REFRESH_TREE: { - const childNodeIds = action.payload.map(item => item.nodeId); + const childNodeIds = action.payload.map((item) => item.nodeId); + if (!draftCatalogTree.treeNodesMap[action.payload[0]!.parentId]) { + return draftCatalogTree; + } draftCatalogTree.treeNodesMap[action.payload[0]!.parentId]!.children = childNodeIds; const parentNode = draftCatalogTree.treeNodesMap[action.payload[0]!.parentId]!; if (!parentNode.hasChildren && action.payload.length) { @@ -216,6 +315,10 @@ export const catalogTree = produce((draftCatalogTree: ICatalogTree = defaultStat draftCatalogTree.expandedKeys = expandedKeys; break; } + case ConfigConstant.Modules.PRIVATE: { + draftCatalogTree.privateExpandedKeys = expandedKeys; + break; + } case ConfigConstant.Modules.FAVORITE: { draftCatalogTree.favoriteExpandedKeys = expandedKeys; break; @@ -238,6 +341,10 @@ export const catalogTree = produce((draftCatalogTree: ICatalogTree = defaultStat draftCatalogTree.allVisible = action.payload; return draftCatalogTree; } + case actions.SET_ACTIVE_TREE_TYPE: { + draftCatalogTree.activeType = action.payload; + return draftCatalogTree; + } case actions.TREE_LOADING: { const { loading, module } = action.payload; switch (module) { @@ -245,6 +352,10 @@ export const catalogTree = produce((draftCatalogTree: ICatalogTree = defaultStat draftCatalogTree.loading = loading; break; } + case ConfigConstant.Modules.PRIVATE: { + draftCatalogTree.privateLoading = loading; + break; + } case ConfigConstant.Modules.FAVORITE: { draftCatalogTree.favoriteLoading = loading; break; @@ -253,24 +364,29 @@ export const catalogTree = produce((draftCatalogTree: ICatalogTree = defaultStat return draftCatalogTree; } case actions.UPDATE_HAS_CHILDREN: { - updateHasChildren(draftCatalogTree.treeNodesMap, action.payload); + const nodesMap = action.payload.module === ConfigConstant.Modules.PRIVATE ? + draftCatalogTree.privateTreeNodesMap : draftCatalogTree.treeNodesMap; + updateHasChildren(nodesMap, action.payload.nodeId); return draftCatalogTree; } case actions.NODE_MOVE_TO: { - const { nodeId, targetNodeId, pos } = action.payload; - const prevName = draftCatalogTree.treeNodesMap[nodeId]!.nodeName; - moveTo(draftCatalogTree.treeNodesMap, nodeId, targetNodeId, pos); - if (prevName !== draftCatalogTree.treeNodesMap[nodeId]!.nodeName) { - draftCatalogTree.editNodeId = nodeId; + const { nodeId, targetNodeId, pos, module } = action.payload; + const treeNodeKey = module === ConfigConstant.Modules.PRIVATE ? 'privateTreeNodesMap' : 'treeNodesMap'; + const prevName = draftCatalogTree[treeNodeKey][nodeId]!.nodeName; + moveTo(draftCatalogTree[treeNodeKey], nodeId, targetNodeId, pos); + if (prevName !== draftCatalogTree[treeNodeKey][nodeId]!.nodeName) { + const editNodeIdKey = module === ConfigConstant.Modules.PRIVATE ? 'privateEditNodeId' : 'editNodeId'; + draftCatalogTree[editNodeIdKey] = nodeId; } return draftCatalogTree; } case actions.UPDATE_TREE_NODES_MAP: { - const { nodeId, data } = action.payload; - if (!draftCatalogTree.treeNodesMap[nodeId]) { + const { nodeId, data, module } = action.payload; + const treeNodeKey = module === ConfigConstant.Modules.PRIVATE ? 'privateTreeNodesMap' : 'treeNodesMap'; + if (!draftCatalogTree[treeNodeKey][nodeId]) { return draftCatalogTree; } - draftCatalogTree.treeNodesMap[nodeId] = { ...draftCatalogTree.treeNodesMap[nodeId]!, ...data }; + draftCatalogTree[treeNodeKey][nodeId] = { ...draftCatalogTree[treeNodeKey][nodeId]!, ...data }; return draftCatalogTree; } case actions.CLEAR_NODE: { @@ -300,8 +416,8 @@ export const catalogTree = produce((draftCatalogTree: ICatalogTree = defaultStat } case actions.DELETE_NODE_FROM_FAVORITE_LIST: { const deleteNodeId = action.payload.nodeId; - if (draftCatalogTree.favoriteTreeNodeIds.findIndex(id => id === deleteNodeId) !== -1) { - draftCatalogTree.favoriteTreeNodeIds = draftCatalogTree.favoriteTreeNodeIds.filter(id => id !== deleteNodeId); + if (draftCatalogTree.favoriteTreeNodeIds.findIndex((id) => id === deleteNodeId) !== -1) { + draftCatalogTree.favoriteTreeNodeIds = draftCatalogTree.favoriteTreeNodeIds.filter((id) => id !== deleteNodeId); } return draftCatalogTree; } @@ -337,6 +453,10 @@ export const catalogTree = produce((draftCatalogTree: ICatalogTree = defaultStat draftCatalogTree.rootId = action.payload; return draftCatalogTree; } + case actions.SET_PRIVATE_TREE_ROOT_ID: { + draftCatalogTree.privateRootId = action.payload; + return draftCatalogTree; + } case actions.SET_PERMISSION_COMMIT_REMIND_STATUS: { draftCatalogTree.permissionCommitRemindStatus = action.payload; return draftCatalogTree; @@ -361,70 +481,104 @@ export const catalogTree = produce((draftCatalogTree: ICatalogTree = defaultStat /** * delete node * attention, sub nodes may be a favorite(star). - * it need to update favorite trees. - * @param tree - * @param optNode the nodes info that will deleted + * it needs to update favorite trees. + * @param catalogTree + * @param optNode the nodes info */ const deleteNode = (catalogTree: ICatalogTree, optNode: IOptNode) => { + const { nodeId, parentId, module } = optNode; const { - treeNodesMap, favoriteTreeNodeIds, delNodeId, editNodeId, favoriteEditNodeId, favoriteDelNodeId, - permissionModalNodeId, shareModalNodeId, saveAsTemplateModalNodeId, importModalNodeId, expandedKeys, loadedKeys + treeNodesMap, + privateTreeNodesMap, + favoriteTreeNodeIds, + delNodeId, + editNodeId, + privateDelNodeId, + privateEditNodeId, + favoriteEditNodeId, + favoriteDelNodeId, + permissionModalNodeId, + shareModalNodeId, + saveAsTemplateModalNodeId, + importModalNodeId, + expandedKeys, + loadedKeys, } = catalogTree; + const nodesMap = module === ConfigConstant.Modules.PRIVATE ? privateTreeNodesMap : treeNodesMap; // the nodeIDs collection that is operating - const operationsIdArr = [delNodeId, editNodeId, favoriteEditNodeId, favoriteDelNodeId, permissionModalNodeId, - shareModalNodeId, saveAsTemplateModalNodeId, importModalNodeId]; - const { nodeId, parentId } = optNode; - const parentNode = treeNodesMap[parentId]; - - const deleteIds = collectProperty(treeNodesMap, nodeId); + const operationsIdArr = module === ConfigConstant.Modules.PRIVATE ? [ + privateDelNodeId, + privateEditNodeId, + favoriteEditNodeId, + favoriteDelNodeId, + permissionModalNodeId, + shareModalNodeId, + saveAsTemplateModalNodeId, + importModalNodeId, + ] : [ + delNodeId, + editNodeId, + favoriteEditNodeId, + favoriteDelNodeId, + permissionModalNodeId, + shareModalNodeId, + saveAsTemplateModalNodeId, + importModalNodeId, + ]; + + const parentNode = nodesMap[parentId]; + + const deleteIds = collectProperty(nodesMap, nodeId); if (parentNode) { - const nextNodeId = parentNode.children[parentNode.children.findIndex(item => item === nodeId) + 1]!; - const nextNode = treeNodesMap[nextNodeId]; + const nextNodeId = parentNode.children[parentNode.children.findIndex((item) => item === nodeId) + 1]!; + const nextNode = nodesMap[nextNodeId]; if (nextNode && nextNode.preNodeId === nodeId) { - nextNode.preNodeId = treeNodesMap[nodeId]!.preNodeId; + nextNode.preNodeId = nodesMap[nodeId]!.preNodeId; } - parentNode.children = parentNode.children.filter(id => id !== nodeId); + parentNode.children = parentNode.children.filter((id) => id !== nodeId); } for (const nodeId of deleteIds) { if (operationsIdArr.includes(nodeId)) { - catalogTree.delNodeId = ''; - catalogTree.editNodeId = ''; - catalogTree.favoriteEditNodeId = ''; - catalogTree.favoriteDelNodeId = ''; - catalogTree.permissionModalNodeId = ''; - catalogTree.shareModalNodeId = ''; - catalogTree.saveAsTemplateModalNodeId = ''; - catalogTree.importModalNodeId = ''; + operationsIdArr.forEach((id) => { + catalogTree[id] = ''; + }); } if (loadedKeys.includes(nodeId)) { - catalogTree.loadedKeys = loadedKeys.filter(item => item !== nodeId); + catalogTree.loadedKeys = loadedKeys.filter((item) => item !== nodeId); } - if (favoriteTreeNodeIds.findIndex(id => id === nodeId) !== -1) { + if (favoriteTreeNodeIds.findIndex((id) => id === nodeId) !== -1) { removeFavoriteNode(catalogTree, nodeId); } // remove the deleted node from expanded collection if (expandedKeys.includes(nodeId)) { - catalogTree.expandedKeys = expandedKeys.filter(item => item !== nodeId); + catalogTree.expandedKeys = expandedKeys.filter((item) => item !== nodeId); } - delete treeNodesMap[nodeId]; + delete nodesMap[nodeId]; } }; /** * add nodes to treeNodeMap (catalog tree data source) * - * @param treeNodesMap map of tree + * @param catalogTree * @param data tree nodes info + * @param isCoverChildren + * @param module */ -const addNodeToMap = (catalogTree: ICatalogTree, data: (Omit & { children?: string[] })[], isCoverChildren: boolean) => { - const { treeNodesMap } = catalogTree; - data.forEach(node => { +const addNodeToMap = ( + catalogTree: ICatalogTree, + data: (Omit & { children?: string[] })[], + isCoverChildren: boolean, + module: ConfigConstant.Modules +) => { + const nodesMap = module === ConfigConstant.Modules.PRIVATE ? catalogTree.privateTreeNodesMap : catalogTree.treeNodesMap; + data.forEach((node) => { const { nodeId, parentId } = node; - const parentNode = treeNodesMap[parentId]; + const parentNode = nodesMap[parentId]; - // if nodes don't exist in data, and have no children property, it need to add children property - if (!treeNodesMap[nodeId] && !node?.children) { + // if nodes don't exist in data, and have no children property, it needs to add children property + if (!nodesMap[nodeId] && !node?.children) { node = { ...node, children: [] }; } // whether to put this node into the collection of loaded nodes @@ -432,10 +586,10 @@ const addNodeToMap = (catalogTree: ICatalogTree, data: (Omit { - const parentNode = treeNodesMap[parentId]; +const updateHasChildren = (nodesMap: ITreeNodesMap, parentId: string) => { + const parentNode = nodesMap[parentId]; if (!parentNode) { return; } - if (parentNode.children.length && !treeNodesMap[parentId]!.hasChildren) { - treeNodesMap[parentId]!.hasChildren = true; + if (parentNode.children.length && !nodesMap[parentId]!.hasChildren) { + nodesMap[parentId]!.hasChildren = true; return; } - if (!parentNode.children.length && treeNodesMap[parentId]!.hasChildren) { - treeNodesMap[parentId]!.hasChildren = false; + if (!parentNode.children.length && nodesMap[parentId]!.hasChildren) { + nodesMap[parentId]!.hasChildren = false; } }; -const moveTo = (treeNodesMap: ITreeNodesMap, nodeId: string, targetNodeId: string, pos: number) => { +const moveTo = (nodesMap: ITreeNodesMap, nodeId: string, targetNodeId: string, pos: number) => { if (pos === 0) { - crossLevelMove(treeNodesMap, nodeId, targetNodeId, pos); + crossLevelMove(nodesMap, nodeId, targetNodeId, pos); } // the parent node id for the dragged node - const parentNodeId = treeNodesMap[nodeId]!.parentId; - const targetParentNodeId = treeNodesMap[targetNodeId]!.parentId; + const parentNodeId = nodesMap[nodeId]!.parentId; + const targetParentNodeId = nodesMap[targetNodeId]!.parentId; // if two nodes' parents are the same, it means that they are moved in the same level if (parentNodeId === targetParentNodeId) { - sameLevelMove(treeNodesMap, nodeId, targetNodeId, pos); + sameLevelMove(nodesMap, nodeId, targetNodeId, pos); } else { - crossLevelMove(treeNodesMap, nodeId, targetNodeId, pos); + crossLevelMove(nodesMap, nodeId, targetNodeId, pos); } }; /** * move in the same level * - * @param treeNodes tree nodes - * @param treeNodesMap the map of tree nodes + * @param nodesMap the map of tree nodes * @param nodeId be moved nodes * @param targetNodeId target node * @param pos relative target node's position */ -const sameLevelMove = (treeNodesMap: ITreeNodesMap, nodeId: string, targetNodeId: string, pos: number) => { - const parentNodeId = treeNodesMap[nodeId]!.parentId; - const parentNode = treeNodesMap[parentNodeId]; - const targetParentNode = treeNodesMap[treeNodesMap[targetNodeId]!.parentId]!; - const dragNode = treeNodesMap[nodeId]; +const sameLevelMove = (nodesMap: ITreeNodesMap, nodeId: string, targetNodeId: string, pos: number) => { + const parentNodeId = nodesMap[nodeId]!.parentId; + const parentNode = nodesMap[parentNodeId]; + const targetParentNode = nodesMap[nodesMap[targetNodeId]!.parentId]!; + const dragNode = nodesMap[nodeId]; if (!parentNode || !dragNode) { return; } - const nextNodeId = parentNode.children[parentNode.children.findIndex(id => id === nodeId) + 1]; + const nextNodeId = parentNode.children[parentNode.children.findIndex((id) => id === nodeId) + 1]; // whether affect the preNodeId of the next node of the moved node - if (nextNodeId && treeNodesMap[nextNodeId]!.preNodeId === nodeId) { - treeNodesMap[nextNodeId]!.preNodeId = dragNode.preNodeId; + if (nextNodeId && nodesMap[nextNodeId]!.preNodeId === nodeId) { + nodesMap[nextNodeId]!.preNodeId = dragNode.preNodeId; } // update the node which is affected by the target position if (pos === -1) { - dragNode.preNodeId = treeNodesMap[targetNodeId]!.preNodeId; - treeNodesMap[targetNodeId]!.preNodeId = nodeId; + dragNode.preNodeId = nodesMap[targetNodeId]!.preNodeId; + nodesMap[targetNodeId]!.preNodeId = nodeId; } if (pos === 1) { dragNode.preNodeId = targetNodeId; - const nextNodeIdOfTargetNode = targetParentNode.children[targetParentNode.children.findIndex(id => id === targetNodeId) + 1]; - if (nextNodeIdOfTargetNode && treeNodesMap[nextNodeIdOfTargetNode]!.preNodeId === targetNodeId) { - treeNodesMap[nextNodeIdOfTargetNode]!.preNodeId = nodeId; + const nextNodeIdOfTargetNode = targetParentNode.children[targetParentNode.children.findIndex((id) => id === targetNodeId) + 1]; + if (nextNodeIdOfTargetNode && nodesMap[nextNodeIdOfTargetNode]!.preNodeId === targetNodeId) { + nodesMap[nextNodeIdOfTargetNode]!.preNodeId = nodeId; } } @@ -571,23 +723,23 @@ const sameLevelMove = (treeNodesMap: ITreeNodesMap, nodeId: string, targetNodeId /** * cross level move - * @param treeNodesMap the collection of catalog tree's nodes info + * @param nodesMap the collection of catalog tree's nodes info * @param nodeId moved node * @param targetNodeId target node ID * @param pos relative target node's position */ -const crossLevelMove = (treeNodesMap: ITreeNodesMap, nodeId: string, targetNodeId: string, pos: number) => { - const parentNodeId = treeNodesMap[nodeId]!.parentId; - const targetParentNodeId = pos === 0 ? targetNodeId : treeNodesMap[targetNodeId]!.parentId; - const parentNode = treeNodesMap[parentNodeId]; - const targetParentNode = treeNodesMap[targetParentNodeId]; - const dragNode = treeNodesMap[nodeId]; +const crossLevelMove = (nodesMap: ITreeNodesMap, nodeId: string, targetNodeId: string, pos: number) => { + const parentNodeId = nodesMap[nodeId]!.parentId; + const targetParentNodeId = pos === 0 ? targetNodeId : nodesMap[targetNodeId]!.parentId; + const parentNode = nodesMap[parentNodeId]; + const targetParentNode = nodesMap[targetParentNodeId]; + const dragNode = nodesMap[nodeId]; if (!parentNode || !targetParentNode || !dragNode) { return; } - parentNode.children = parentNode.children.filter(id => id !== nodeId); + parentNode.children = parentNode.children.filter((id) => id !== nodeId); if (pos === 0) { targetParentNode.children.unshift(nodeId); } else { @@ -605,39 +757,38 @@ const crossLevelMove = (treeNodesMap: ITreeNodesMap, nodeId: string, targetNodeI } // last modified the parent node of the moved node - treeNodesMap[nodeId]!.parentId = targetParentNodeId; - const names = getPropertyByTree(treeNodesMap, targetParentNodeId, [nodeId], 'nodeName'); - treeNodesMap[nodeId]!.nodeName = getUniqName(treeNodesMap[nodeId]!.nodeName, names); + nodesMap[nodeId]!.parentId = targetParentNodeId; + const names = getPropertyByTree(nodesMap, targetParentNodeId, [nodeId], 'nodeName'); + nodesMap[nodeId]!.nodeName = getUniqName(nodesMap[nodeId]!.nodeName, names); }; /** * get current node's children's property - * @param treeNodesMap data source tree of nodes - * @param treeNodes nodes tree + * @param nodesMap data source tree of nodes * @param nodeId the node id want to find * @param exceptArr the node id will remove * @param property the node attributes to get */ -export const getPropertyByTree = (treeNodesMap: ITreeNodesMap, nodeId: string, exceptArr: string[], property: string) => { - const node = treeNodesMap[nodeId]; +export const getPropertyByTree = (nodesMap: ITreeNodesMap, nodeId: string, exceptArr: string[], property: string) => { + const node = nodesMap[nodeId]; if (!node) { return []; } return node.children.reduce((names, nodeId) => { if (!exceptArr.includes(nodeId)) { - names.push(treeNodesMap[nodeId]![property]); + names.push(nodesMap[nodeId]![property]); } return names; }, [] as any[]); }; -export const mergeObj = (oldTree: ITreeNode[], newTree: ITreeNode[], treeNodesMap: ITreeNodesMap) => { - oldTree.forEach(item => { +export const mergeObj = (oldTree: ITreeNode[], newTree: ITreeNode[], nodesMap: ITreeNodesMap) => { + oldTree.forEach((item) => { const node = findNode(newTree, item.nodeId); if (item.children.length === 0 && node && node.children.length) { item.children = node.children; } else { - mergeObj(item.children, newTree, treeNodesMap); + mergeObj(item.children, newTree, nodesMap); } }); }; @@ -677,7 +828,7 @@ export const addSingleNodeToTree = (tree: ITreeNode[], newNode: INode) => { parentNode.children.unshift({ nodeId, children: [] }); return; } - const index = parentNode.children.findIndex(item => item.nodeId === preNodeId); + const index = parentNode.children.findIndex((item) => item.nodeId === preNodeId); if (index !== -1) { parentNode.children.splice(index + 1, 0, { nodeId, children: [] }); } @@ -696,11 +847,10 @@ export const addMultiNodeToTree = (tree: ITreeNode[], newNodes: INode[]) => { if (!parentNode) { return; } - const formatNodes = newNodes.map(item => ({ nodeId: item.nodeId, children: [] })); - parentNode.children = formatNodes; + parentNode.children = newNodes.map((item) => ({ nodeId: item.nodeId, children: [] })); }; -export const moveFavoriteNode = (draftCatalogTree: ICatalogTree, data: { nodeId: string, preNodeId: string }) => { +export const moveFavoriteNode = (draftCatalogTree: ICatalogTree, data: { nodeId: string; preNodeId: string }) => { const { favoriteTreeNodeIds } = draftCatalogTree; const { nodeId, preNodeId } = data; @@ -730,7 +880,7 @@ export const moveFavoriteNode = (draftCatalogTree: ICatalogTree, data: { nodeId: */ export const removeFavoriteNode = (catalogTree: ICatalogTree, removeNodeId: string) => { const { favoriteTreeNodeIds, treeNodesMap } = catalogTree; - const removeIndex = favoriteTreeNodeIds.findIndex(id => id === removeNodeId); + const removeIndex = favoriteTreeNodeIds.findIndex((id) => id === removeNodeId); if (favoriteTreeNodeIds.length > 1 && removeIndex !== favoriteTreeNodeIds.length - 1) { const nextNodeId = favoriteTreeNodeIds[removeIndex + 1]!; @@ -738,6 +888,6 @@ export const removeFavoriteNode = (catalogTree: ICatalogTree, removeNodeId: stri treeNodesMap[nextNodeId]!.preFavoriteNodeId = removeIndex === 0 ? '' : treeNodesMap[removeNodeId]!.preFavoriteNodeId; } - catalogTree.favoriteTreeNodeIds = favoriteTreeNodeIds.filter(id => id !== removeNodeId); + catalogTree.favoriteTreeNodeIds = favoriteTreeNodeIds.filter((id) => id !== removeNodeId); delete treeNodesMap[removeNodeId]!.preFavoriteNodeId; }; diff --git a/packages/core/src/modules/user/api/api.auth.ts b/packages/core/src/modules/user/api/api.auth.ts index b23b8e465a..dd1c08ada5 100644 --- a/packages/core/src/modules/user/api/api.auth.ts +++ b/packages/core/src/modules/user/api/api.auth.ts @@ -89,10 +89,11 @@ export function signUp(token?: string, inviteCode?: string) { * */ -export function register(username: string, credential: string) { +export function register(username: string, credential: string, lang = 'en-US') { return axios.post(Url.REGISTER, { username, - credential + credential, + lang }); } diff --git a/packages/core/src/modules/user/api/api.user.ts b/packages/core/src/modules/user/api/api.user.ts index dfda912d63..009cc81ad6 100644 --- a/packages/core/src/modules/user/api/api.user.ts +++ b/packages/core/src/modules/user/api/api.user.ts @@ -50,16 +50,6 @@ export function getUserCanLogout() { return axios.get(Url.USER_CAN_LOGOUT); } -/** - * - * Space - check if the user's email is the same as the specified email - * @param email - * @returns - */ -export function validateEmail(email: string) { - return axios.post(Url.EMAIL_VALIDATE, { email }); -} - /** * * Space - binding the invited email diff --git a/packages/core/src/modules/user/api/url.auth.ts b/packages/core/src/modules/user/api/url.auth.ts index 24e2777848..214d203985 100644 --- a/packages/core/src/modules/user/api/url.auth.ts +++ b/packages/core/src/modules/user/api/url.auth.ts @@ -64,10 +64,5 @@ export const VALIDATE_SMS_CODE = '/base/action/sms/code/validate'; * */ export const VALIDATE_EMAIL_CODE = '/base/action/email/code/validate'; - -/** - * Space - invite verify code validate - */ -export const INVITE_EMAIL_VERIFY = '/base/action/invite/valid'; export const REGISTER = '/register'; \ No newline at end of file diff --git a/packages/core/src/modules/widget/api/widget_api.ts b/packages/core/src/modules/widget/api/widget_api.ts index b702f90dc2..9630e626be 100644 --- a/packages/core/src/modules/widget/api/widget_api.ts +++ b/packages/core/src/modules/widget/api/widget_api.ts @@ -58,8 +58,8 @@ export const installWidget = (nodeId: string, packageId: string, name?: string) }); }; -export const getRecentInstalledWidgets = (spaceId: string) => { - return axios.get(urlcat(Url.RECENT_INSTALL_WIDGET, { spaceId })); +export const getRecentInstalledWidgets = (spaceId: string, unitType?: number) => { + return axios.get(urlcat(Url.RECENT_INSTALL_WIDGET, { spaceId, unitType })); }; export const getWidgetsInfoByNodeId = (nodeId: string) => { diff --git a/packages/core/src/sync/room.ts b/packages/core/src/sync/room.ts index dbe1525457..bd239051da 100644 --- a/packages/core/src/sync/room.ts +++ b/packages/core/src/sync/room.ts @@ -38,14 +38,31 @@ import { ErrorCode, IError, ModalType, OnOkType, ResourceType } from 'types'; import { errorCapture, numbersBetween } from 'utils'; import { socketGuard } from 'utils/socket_guard'; import { - BroadcastTypes, IClientRoomMessage, IEngagementCursorData, IFieldPermissionMessage, INewChangesData, INodeShareDisabledData, ISocketResponseData, - IWatchResponse, OtErrorCode, SyncRequestTypes, + BroadcastTypes, + IClientRoomMessage, + IEngagementCursorData, + IFieldPermissionMessage, + INewChangesData, + INodeShareDisabledData, + ISocketResponseData, + IWatchResponse, + OtErrorCode, + SyncRequestTypes, } from './types'; import { - fetchFieldPermission,cursorMove, + fetchFieldPermission, + cursorMove, deactivateCollaborator, - resetResource, activeCollaborator, changeResourceSyncingStatus, resetFieldPermissionMap, roomInfoSync, setResourceConnect, updateFieldPermissionMap, updateFieldPermissionSetting, + resetResource, + activeCollaborator, + changeResourceSyncingStatus, + resetFieldPermissionMap, + roomInfoSync, + setResourceConnect, + updateFieldPermissionMap, + updateFieldPermissionSetting, } from 'modules/database/store/actions/resource'; +import { isClient } from 'utils/env'; // The maximum number of data retransmission actions is online, beyond this value, no timeout retry operation will be performed const MAX_RETRY_LENGTH = 5000; const VIKA_OP_BACKUP = 'VIKA_OP_BACKUP'; @@ -100,7 +117,7 @@ export class RoomService { if (!collaEngineMap) { return; } - collaEngineMap.forEach(engine => { + collaEngineMap.forEach((engine) => { this.addCollaEngine(engine); }); } @@ -122,7 +139,7 @@ export class RoomService { } private async nextTick() { - await new Promise(resolve => { + await new Promise((resolve) => { setTimeout(resolve, 10); }); } @@ -137,10 +154,12 @@ export class RoomService { } while (!hasCollaEngine()); firstRoomInit && this.sendLocalChangesetWithInit(); // Initialize the collaboration engine first - await Promise.all(Array.from(this.collaEngineMap.keys()).map(resourceId => { - const collaEngine = this.collaEngineMap.get(resourceId)!; - return collaEngine.waitPrepareComplete(); - })); + await Promise.all( + Array.from(this.collaEngineMap.keys()).map((resourceId) => { + const collaEngine = this.collaEngineMap.get(resourceId)!; + return collaEngine.waitPrepareComplete(); + }) + ); await this.watch(); } @@ -168,7 +187,7 @@ export class RoomService { try { await this.backupDB.setItem(String(Date.now()), { changesetMap, - opBufferMap + opBufferMap, }); } catch (e) { if ((e as any).name === 'QuotaExceededError') { @@ -178,28 +197,29 @@ export class RoomService { } const timestamps = await this.backupDB.keys(); - await Promise.all(timestamps.map(async timestamp => { - // Clean up data whose backup time is greater than two weeks - if (dayjs().diff(Date.now(), 'day') > 14) { - await this.backupDB.removeItem(timestamp); - } - })); + await Promise.all( + timestamps.map(async (timestamp) => { + // Clean up data whose backup time is greater than two weeks + if (dayjs().diff(Date.now(), 'day') > 14) { + await this.backupDB.removeItem(timestamp); + } + }) + ); Player.doTrigger(Events.app_error_logger, { error: new Error(`Failed to initialize applyChangeset: ${(e as any).message}`), metaData: { roomId: this.roomId, changesetMap: JSON.stringify(changesetMap), - opBufferMap: JSON.stringify(opBufferMap) + opBufferMap: JSON.stringify(opBufferMap), }, }); throw new EnhanceError({ code: ErrorCode.CollaModalError, message: t(Strings.initialization_failed_message), - modalType: ModalType.Warning + modalType: ModalType.Warning, }); - } this.event.setRoomIOClear(true); @@ -232,7 +252,7 @@ export class RoomService { const resourceType = opBuffer[0]!.resourceType; const changeset = BufferStorage.ops2Changeset(opBuffer, revision as number, resourceId, resourceType as ResourceType); - if (opBuffer.every(operation => !operation.mainLinkDstId)) { + if (opBuffer.every((operation) => !operation.mainLinkDstId)) { const res = await Api.applyResourceChangesets([changeset], this.roomId); const { success, message } = res.data; if (!success) { @@ -263,15 +283,12 @@ export class RoomService { */ @errorCapture() handleNewChanges(data: INewChangesData) { - data.changesets.forEach(cs => { + data.changesets.forEach((cs) => { const resourceId = cs.resourceId; const collaEngine = this.collaEngineMap.get(resourceId); if (collaEngine) { void collaEngine.handleNewChanges(cs); - } else if ( - resourceId.startsWith(NodeTypeReg.DATASHEET) && - !getDatasheet(this.store.getState(), resourceId) - ) { + } else if (resourceId.startsWith(NodeTypeReg.DATASHEET) && !getDatasheet(this.store.getState(), resourceId)) { // The data obtained at this time is the latest version, no need to apply cs anymore void this.fetchResource(resourceId, ResourceType.Datasheet); } @@ -293,7 +310,7 @@ export class RoomService { const state = this.store.getState(); const shareId = state.pageParams.shareId; const embedId = state.pageParams.embedId; - const watchResponse = await this.io.watch(this.roomId, shareId, embedId).catch(e => { + const watchResponse = await this.io.watch(this.roomId, shareId, embedId).catch((e) => { throw new EnhanceError(e); }); @@ -314,7 +331,6 @@ export class RoomService { this.loadFieldPermissionMap(); this.bindSocketMessage(); this.setSendingWatcher(); - } /** @@ -322,7 +338,7 @@ export class RoomService { */ loadFieldPermissionMap() { const dstIds: string[] = []; - this.collaEngineMap.forEach(collaEngine => { + this.collaEngineMap.forEach((collaEngine) => { if (collaEngine.resourceType !== ResourceType.Datasheet) { return; } @@ -357,15 +373,17 @@ export class RoomService { throw new EnhanceError({ code: StatusCode.FRONT_VERSION_ERROR, message: t(Strings.changeset_diff_big_tip), - modalType: ModalType.Info + modalType: ModalType.Info, }); } missVersionEngines.push({ collaEngine, revision }); } - return await Promise.all(missVersionEngines.map>(({ collaEngine, revision }) => { - return collaEngine.prepare(revision + 1); - })); + return await Promise.all( + missVersionEngines.map>(({ collaEngine, revision }) => { + return collaEngine.prepare(revision + 1); + }) + ); } /** @@ -395,7 +413,7 @@ export class RoomService { if (this.socket.connected) { await this.unwatch(); } else { - console.log('socket has been closed, room needn\'t leave again'); + console.log("socket has been closed, room needn't leave again"); } this.clearSendingWatcher(); return this.collaEngineMap; @@ -433,10 +451,10 @@ export class RoomService { } /** - * Data sending status listener - * Regular polling to check whether user data has been sent and confirmed - * If it has not been confirmed for a long time (1 minute), execute a retry mechanism - * This situation usually occurs with an error + * Data sending status listener + * Regular polling to check whether user data has been sent and confirmed + * If it has not been confirmed for a long time (1 minute), execute a retry mechanism + * This situation usually occurs with an error */ private setSendingWatcher() { this.clearSendingWatcher(); @@ -467,9 +485,12 @@ export class RoomService { // As long as a persistent connection exists, data will be sent. private forceSend(changesets: ILocalChangeset[]) { const actionLength = changesets.reduce((pre, cur) => { - return pre + cur.operations.reduce((p, c) => { - return p + c.actions.length; - }, 0); + return ( + pre + + cur.operations.reduce((p, c) => { + return p + c.actions.length; + }, 0) + ); }, 0); // Note: In the case of pasting large data, the server may return slowly, and the data will not be re-sent at this time. @@ -495,7 +516,7 @@ export class RoomService { this.event.setRoomIOClear(false); this.event.setRoomLastSendTime(); if (!this.connected) { - console.error('room has been destroy,can\'t send anything'); + console.error("room has been destroy,can't send anything"); return; } // Load after 500ms, to prevent the icon from flashing when the network is fast @@ -506,34 +527,38 @@ export class RoomService { }, 500); const state = this.store.getState(); const shareId = state.pageParams.shareId; - return this.io.request({ - type: SyncRequestTypes.CLIENT_ROOM_CHANGE, - roomId: this.roomId, - changesets, - shareId, - }).then((data) => { - clearTimeout(timer); - this.event.setRoomIOClear(true); - if (data.success && data.data) { - this.store.dispatch(changeResourceSyncingStatus(this.roomId, resourceType, false)); - return this.handleAcceptCommit(data.data.changesets); - } - // Unsuccessful requests, divert traffic to the following catch - return Promise.reject(data); - }).catch(async e => { - this.event.setRoomIOClear(true); - let errMsg = e; - clearTimeout(timer); - if (!('success' in errMsg)) { - errMsg = { - success: false, - code: 0, - message: t(Strings.exception_network_exception), - }; - } - await this.handleRejectCommit(errMsg); - return Promise.reject(); - }); + const embedId = state.pageParams.embedId; + return this.io + .request({ + type: SyncRequestTypes.CLIENT_ROOM_CHANGE, + roomId: this.roomId, + changesets, + shareId: shareId || embedId, + }) + .then((data) => { + clearTimeout(timer); + this.event.setRoomIOClear(true); + if (data.success && data.data) { + this.store.dispatch(changeResourceSyncingStatus(this.roomId, resourceType, false)); + return this.handleAcceptCommit(data.data.changesets); + } + // Unsuccessful requests, divert traffic to the following catch + return Promise.reject(data); + }) + .catch(async (e) => { + this.event.setRoomIOClear(true); + let errMsg = e; + clearTimeout(timer); + if (!('success' in errMsg)) { + errMsg = { + success: false, + code: 0, + message: t(Strings.exception_network_exception), + }; + } + await this.handleRejectCommit(errMsg); + return Promise.reject(); + }); }; @errorCapture() @@ -547,6 +572,10 @@ export class RoomService { await collaEngine.handleAcceptCommit(cs); // TODO: There are cookies in changesets to be removed in the middle layer console.log('Data returned successfully: ', cs); + if (isClient()) { + const customEvent = new CustomEvent(cs.messageId); + window.dispatchEvent(customEvent); + } } this.nextSend(); @@ -579,7 +608,7 @@ export class RoomService { // Before clearing the data, make a local backup of the cleared data await this.backupDB.setItem(String(Date.now()), { opBufferMap: this.getBufferOperateMap(), - changesetMap: keyBy(this.getLocalPendingChangesets(), 'resourceId') + changesetMap: keyBy(this.getLocalPendingChangesets(), 'resourceId'), }); this.clearAllStorage(); } @@ -646,7 +675,7 @@ export class RoomService { this.event.setRoomLastSendTime(); void this.sendUserChanges(nextChangesets); } - }, 500); + }, 1000); /** * Push the operation into the send queue, SyncEngine will ensure that the data is sent to the server in version order @@ -658,9 +687,9 @@ export class RoomService { */ @errorCapture() syncOperations(localOperations: IResourceOpsCollect[]) { - localOperations.forEach(lop => { + localOperations.forEach((lop) => { const collaEngine = this.collaEngineMap.get(lop.resourceId); - lop.operations.forEach(op => collaEngine?.pushOpBuffer(op)); + lop.operations.forEach((op) => collaEngine?.pushOpBuffer(op)); }); this.nextSend(); @@ -705,7 +734,7 @@ export class RoomService { if (!collaEngine) { return; } - data.collaborators.forEach(item => { + data.collaborators.forEach((item) => { this.store.dispatch(activeCollaborator(item, this.roomId, collaEngine.resourceType)); }); } @@ -726,12 +755,17 @@ export class RoomService { handleCursor(data: IEngagementCursorData) { // console.log('RECEIVED IEngagementCursorData: ', { data }); const { cursorInfo } = data; - this.store.dispatch(cursorMove({ - fieldId: cursorInfo.fieldId, - recordId: cursorInfo.recordId, - time: cursorInfo.time, - socketId: data.socketId, - }, this.roomId)); + this.store.dispatch( + cursorMove( + { + fieldId: cursorInfo.fieldId, + recordId: cursorInfo.recordId, + time: cursorInfo.time, + socketId: data.socketId, + }, + this.roomId + ) + ); } @errorCapture() @@ -746,7 +780,7 @@ export class RoomService { message: t(Strings.error_please_close_sharing_page), okText: t(Strings.okay), modalType: ModalType.Warning, - onOkType: OnOkType.BackWorkBench + onOkType: OnOkType.BackWorkBench, }); } } @@ -769,7 +803,6 @@ export class RoomService { console.log('RECEIVED handleFieldPermissionEnabled: ', { data }); const fieldPermission = this.generateStdFieldPermission(data, true); this.store.dispatch(updateFieldPermissionMap(fieldPermission, data.datasheetId)); - } // change column permissions @@ -812,31 +845,31 @@ export class RoomService { this.handleCursor(data); }); - this.io.on<{ collaborators: ICollaborator[] }>(BroadcastTypes.ACTIVATE_COLLABORATORS, data => { + this.io.on<{ collaborators: ICollaborator[] }>(BroadcastTypes.ACTIVATE_COLLABORATORS, (data) => { this.handleActiveCollaborators(data); }); - this.io.on(BroadcastTypes.DEACTIVATE_COLLABORATOR, data => { + this.io.on(BroadcastTypes.DEACTIVATE_COLLABORATOR, (data) => { this.handleDeactivateCollaborator(data); }); - this.io.on(BroadcastTypes.NODE_SHARE_DISABLED, data => { + this.io.on(BroadcastTypes.NODE_SHARE_DISABLED, (data) => { this.handleNodeShareDisabled(data); }); - this.io.on(BroadcastTypes.FIELD_PERMISSION_ENABLE, data => { + this.io.on(BroadcastTypes.FIELD_PERMISSION_ENABLE, (data) => { this.handleFieldPermissionEnabled(data); }); - this.io.on(BroadcastTypes.FIELD_PERMISSION_CHANGE, data => { + this.io.on(BroadcastTypes.FIELD_PERMISSION_CHANGE, (data) => { this.handleFieldPermissionChange(data); }); - this.io.on(BroadcastTypes.FIELD_PERMISSION_DISABLE, data => { + this.io.on(BroadcastTypes.FIELD_PERMISSION_DISABLE, (data) => { this.handleFieldPermissionDisabled(data); }); - this.io.on(BroadcastTypes.FIELD_PERMISSION_SETTING_CHANGE, data => { + this.io.on(BroadcastTypes.FIELD_PERMISSION_SETTING_CHANGE, (data) => { this.handleFieldPermissionSetting(data); }); }; diff --git a/packages/core/src/types/field_types.ts b/packages/core/src/types/field_types.ts index 58318a3f00..6f1fdd64b3 100644 --- a/packages/core/src/types/field_types.ts +++ b/packages/core/src/types/field_types.ts @@ -43,9 +43,9 @@ export enum FormulaFuncType { Text = 'Text', } /** - * The underlying type of the cell value. - */ - export enum BasicValueType { + * The underlying type of the cell value. + */ +export enum BasicValueType { String = 'String', Number = 'Number', DateTime = 'DateTime', @@ -102,7 +102,7 @@ export interface ILookUpSortField { } export interface ILookUpSortInfo { - rules: ILookUpSortField[] + rules: ILookUpSortField[]; } export interface ILookUpProperty { @@ -143,6 +143,7 @@ export enum MemberType { Team = 1, Role = 2, Member = 3, + Group = 4, } export type IUnitIds = string[]; @@ -415,6 +416,12 @@ export enum DateFormat { 'MM', /** day */ 'DD', + /** month/day/year */ + 'MM/DD/YYYY', + /** month-day-year */ + 'MM-DD-YYYY', + /** month/day/year */ + 'MM/DD/YY', } export enum TimeFormat { @@ -477,7 +484,6 @@ export interface ISelectFieldOption { color: number; } - export interface ISelectFieldProperty { options: ISelectFieldOption[]; defaultValue?: string | IMultiSelectedIds; @@ -597,16 +603,16 @@ interface ILinkedFields { } export interface ICascaderProperty { - showAll: boolean, - linkedDatasheetId: string, - linkedViewId: string, - linkedFields: ILinkedFields[], - fullLinkedFields: ILinkedFields[], + showAll: boolean; + linkedDatasheetId: string; + linkedViewId: string; + linkedFields: ILinkedFields[]; + fullLinkedFields: ILinkedFields[]; } export enum ButtonStyleType { - Background= 0, - OnlyText=1 + Background = 0, + OnlyText = 1, } export enum ButtonActionType { @@ -615,8 +621,8 @@ export enum ButtonActionType { } export interface IButtonStyle { - type: ButtonStyleType, - color: number + type: ButtonStyleType; + color: number; } export enum OpenLinkType { @@ -638,16 +644,16 @@ export interface IButtonAction { export interface IButtonActionMeta { type?: ButtonActionType; - expression?: string; - automationId?: string; - triggerId?: string; + expression?: string; + automationId?: string; + triggerId?: string; } export interface IButtonProperty { datasheetId?: string; - text: string, - style: IButtonStyle - action: IButtonAction, + text: string; + style: IButtonStyle; + action: IButtonAction; } export interface IButtonField extends IBaseField { @@ -729,7 +735,7 @@ export const readonlyFields = new Set([ FieldType.LastModifiedTime, FieldType.CreatedBy, FieldType.LastModifiedBy, - FieldType.Button + FieldType.Button, ]); export interface IFieldTypeCollection { @@ -1007,6 +1013,6 @@ export const FieldTypeDescriptionMap: { fieldGroup: FieldGroup.Common, help: t(Strings.field_help_workdoc), hasOptSetting: false, - isBeta: true + isBeta: true, }, }; diff --git a/packages/core/src/types/open/open_field_write_types.ts b/packages/core/src/types/open/open_field_write_types.ts index 0aa2265356..bf3976ae84 100644 --- a/packages/core/src/types/open/open_field_write_types.ts +++ b/packages/core/src/types/open/open_field_write_types.ts @@ -95,8 +95,7 @@ export interface IWriteOpenSelectBaseFieldProperty { options: { id?: string; name: string; - /** color name */ - color?: string; + color?: string | number; }[]; } diff --git a/packages/core/src/utils/convert/other2timestamp.ts b/packages/core/src/utils/convert/other2timestamp.ts index 93676e04c8..b1f52ae970 100644 --- a/packages/core/src/utils/convert/other2timestamp.ts +++ b/packages/core/src/utils/convert/other2timestamp.ts @@ -21,17 +21,16 @@ import type { IDateTimeField, ITimestamp } from 'types/field_types'; import duration from 'dayjs/plugin/duration'; import customParseFormat from 'dayjs/plugin/customParseFormat'; import { getTimeZoneOffsetByUtc, getTimeZone } from '../../config'; +import moment from 'moment-timezone'; dayjs.extend(duration); dayjs.extend(customParseFormat); -export function str2timestamp( - value: string | null, -): ITimestamp | null { +export function str2timestamp(value: string | null, dateFormat?: string): ITimestamp | null { if (!value) { return null; } - const dateTime = dayjs(value); + const dateTime = dayjs(value, dateFormat); return dateTime.isValid() ? dateTime.valueOf() : null; } @@ -63,20 +62,29 @@ export function str2time(value: string, _field?: IDateTimeField) { if (hours < 0 || hours > 23 || minutes < 0 || minutes > 59) { return; } - return dayjs.duration({ - hours, - minutes, - // seconds: parseInt(s, 10), - // milliseconds: dateTime.millisecond(), - }).asMilliseconds(); + return dayjs + .duration({ + hours, + minutes, + // seconds: parseInt(s, 10), + // milliseconds: dateTime.millisecond(), + }) + .asMilliseconds(); } -export const diffTimeZone = (timeZone?: string) => { +export const isDstDate = (date: string, timeZone?: string) => { + if (!timeZone) return false; + return moment(date).tz(timeZone).isDST(); +}; + +export const diffTimeZone = (timeZone?: string, isdstDate?: boolean) => { if (!timeZone) return 0; - const tzOffset = getTimeZoneOffsetByUtc(timeZone)!; + const tzOffset = getTimeZoneOffsetByUtc(timeZone, isdstDate)!; const clientTimeZone = getTimeZone(); - const clientTzOffset = getTimeZoneOffsetByUtc(clientTimeZone)!; - return dayjs.duration({ - hours: clientTzOffset - tzOffset - }).asMilliseconds(); + const clientTzOffset = getTimeZoneOffsetByUtc(clientTimeZone, isdstDate)!; + return dayjs + .duration({ + hours: clientTzOffset - tzOffset, + }) + .asMilliseconds(); }; diff --git a/packages/core/src/utils/jot.ts b/packages/core/src/utils/jot.ts index 4792fbdfa6..73c50108c7 100644 --- a/packages/core/src/utils/jot.ts +++ b/packages/core/src/utils/jot.ts @@ -232,7 +232,9 @@ export const effectResourceAction = (type: ActionType): boolean => { return [ ActionType.AddField, ActionType.AddRecord, + ActionType.DelRow, ActionType.DelField, + ActionType.DelColumn, ActionType.DelRecord, ActionType.UpdateRecord, ActionType.UpdateField diff --git a/packages/core/src/utils/link_consistency.ts b/packages/core/src/utils/link_consistency.ts index aea038e2d2..7d903f91eb 100644 --- a/packages/core/src/utils/link_consistency.ts +++ b/packages/core/src/utils/link_consistency.ts @@ -26,7 +26,7 @@ export function checkLinkConsistency(state: IReduxState, _loadedForeignDstId: st // the check of data consistency // datasheet is the only object that should be attention - // if if all the permission of datasheet is ok, no need to check more + // if all the permission of datasheet is ok, no need to check more if (!datasheet.permissions?.editable) { // when the permission of datasheet is not ok, then check other factors if (!state.pageParams.mirrorId) { @@ -118,7 +118,10 @@ export function checkLinkConsistency(state: IReduxState, _loadedForeignDstId: st for (const fieldId of linkFieldIds) { const { foreignDatasheetId, brotherFieldId } = fieldMap[fieldId]!.property as ILinkFieldProperty; const { - snapshot: { recordMap: foreignRecordMap }, + snapshot: { + recordMap: foreignRecordMap, + meta: { archivedRecordIds } + }, } = getDatasheet(state, foreignDatasheetId)!; // check recordIds that are missing in link cells in foreign datasheet @@ -130,7 +133,11 @@ export function checkLinkConsistency(state: IReduxState, _loadedForeignDstId: st } for (const linkedRecordId of cellValue) { const foreignRecord = foreignRecordMap[linkedRecordId]; - + const isArchivedRecord = archivedRecordIds?.includes(linkedRecordId); + // ignore archived records + if (isArchivedRecord) { + continue; + } if (!foreignRecord) { addRedundantRecordId(mainDstId, recordId, fieldId, linkedRecordId); } else if (!(foreignRecord.data[brotherFieldId!] as ILinkIds | undefined)?.includes(recordId)) { diff --git a/packages/core/src/utils/types.ts b/packages/core/src/utils/types.ts index 66bc8f0329..834ee21b49 100644 --- a/packages/core/src/utils/types.ts +++ b/packages/core/src/utils/types.ts @@ -60,7 +60,7 @@ export function isGroupFieldValid(snapshot: ISnapshot, group: IGroupInfo, viewTy } export function isTextBaseType(type: FieldType): boolean { - return [FieldType.Text, FieldType.Phone, FieldType.Email, FieldType.URL, FieldType.SingleText].includes(type); + return [FieldType.Text, FieldType.Phone, FieldType.Email, FieldType.URL, FieldType.Button, FieldType.SingleText].includes(type); } export function isEnhanceTextType(type: FieldType): boolean { diff --git a/packages/core/src/utils/uuid.ts b/packages/core/src/utils/uuid.ts index 4c0b664008..80ac7633db 100644 --- a/packages/core/src/utils/uuid.ts +++ b/packages/core/src/utils/uuid.ts @@ -40,6 +40,8 @@ export enum IDPrefix { AutomationAction = 'aac', Document = 'doc', AutomationTrigger = 'atr', + WorkDocAonymousId = 'wda', + Mirror = "mir" } /** @@ -110,3 +112,14 @@ export function getUniqName(newName: string, names: string[]) { } return uniqName; } + +const numbers = '0123456789'; +export function generateRandomNumber(length: number): string { + let result = ''; + for (let i = 0; i < length; i++) { + const randomIndex = Math.floor(Math.random() * numbers.length); + result += numbers.charAt(randomIndex); + } + + return result; +} diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json index 8716ec8eb6..9ae893da0a 100644 --- a/packages/core/tsconfig.json +++ b/packages/core/tsconfig.json @@ -21,7 +21,7 @@ "strictBindCallApply": true, "strictFunctionTypes": true, "module": "ESNext", - "target": "ES2020", + "target": "ES2018", "outDir": "dist", "rootDir": "src", "baseUrl": "src", @@ -30,6 +30,7 @@ "*": ["*"] }, "lib": [ + "dom", "esnext", "ESNext.Array", "ES2020.String" diff --git a/packages/cypress/package.json b/packages/cypress/package.json index e46fddd569..8f9578c5ae 100644 --- a/packages/cypress/package.json +++ b/packages/cypress/package.json @@ -1,6 +1,6 @@ { "name": "@apitable/cypress", - "version": "1.6.0", + "version": "1.13.0", "description": "> TODO: description", "author": "APITable Ltd. ", "license": "AGPL-3.0", diff --git a/packages/databus-client/package.json b/packages/databus-client/package.json index 0bb031ca1d..0a435bce1a 100644 --- a/packages/databus-client/package.json +++ b/packages/databus-client/package.json @@ -1,6 +1,6 @@ { "name": "databus-client", - "version": "1.6.0", + "version": "1.13.0", "description": "OpenAPI client for databus-client", "author": "OpenAPI-Generator Contributors", "repository": { diff --git a/packages/databus-wasm-nodejs/package.json b/packages/databus-wasm-nodejs/package.json index 46d6e87206..37b61bfcac 100644 --- a/packages/databus-wasm-nodejs/package.json +++ b/packages/databus-wasm-nodejs/package.json @@ -3,7 +3,7 @@ "collaborators": [ "Kelly Peilin Chan " ], - "version": "1.6.0", + "version": "1.13.0", "files": [ "databus_wasm_bg.wasm", "databus_wasm.js", diff --git a/packages/databus-wasm-web/package.json b/packages/databus-wasm-web/package.json index b806a08b5a..e3459486c5 100644 --- a/packages/databus-wasm-web/package.json +++ b/packages/databus-wasm-web/package.json @@ -3,7 +3,7 @@ "collaborators": [ "Kelly Peilin Chan " ], - "version": "1.6.0", + "version": "1.13.0", "files": [ "databus_wasm_bg.wasm", "databus_wasm.js", diff --git a/packages/datasheet/.env b/packages/datasheet/.env index 258b7f6a7d..3d626c430a 100644 --- a/packages/datasheet/.env +++ b/packages/datasheet/.env @@ -149,4 +149,9 @@ VIEW_MANUAL_SAVE_INFO_IMAGE=space/2023/03/24/c1e29bbb60c048999a9cda1b95c52d84 IS_CANVAS_IMAGE_CROSS_ORIGIN=true TRANSLATION_FEEDBACK_HELP_URL=https://github.com/apitable/apitable/blob/develop/docs/contribute/developer-guide.md#how-to-contribute-to-translations ENABLE_DATABUS_API=false +SENTRY_ORG=sentry +SENTRY_PROJECT=web-server +SENTRY_CONFIG_DSN=https://51c44e606db14f34963bd4ba64d86410@sentry.vika.ltd/3 +SENTRY_AUTH_TOKEN=b8d7afa51f464492904b368cb17fa121e7333a2183a4425abec0e6bebd42b8bb +SENTRY_URL=https://sentry.vika.ltd/ diff --git a/packages/datasheet/.eslintrc b/packages/datasheet/.eslintrc index 6c27c3a4b1..108d008b04 100644 --- a/packages/datasheet/.eslintrc +++ b/packages/datasheet/.eslintrc @@ -17,14 +17,7 @@ "import/order": [ "warn", { - "groups": [ - "builtin", - "external", - "internal", - "parent", - "sibling", - "index" - ], + "groups": ["builtin", "external", "internal", "parent", "sibling", "index"], "pathGroups": [ { "pattern": "@apitable/**", @@ -62,9 +55,7 @@ "position": "after" } ], - "pathGroupsExcludedImportTypes": [ - "builtin" - ], + "pathGroupsExcludedImportTypes": ["builtin"], "alphabetize": { "order": "asc", "caseInsensitive": true @@ -81,10 +72,7 @@ "react/display-name": 0, "react/no-find-dom-node": 0, "react/no-unknown-property": 1, - "@next/next/no-html-link-for-pages": [ - "error", - "packages/datasheet/pages/" - ], + "@next/next/no-html-link-for-pages": ["error", "packages/datasheet/pages/"], "@next/next/no-img-element": "off", "no-restricted-imports": [ "warn", @@ -92,30 +80,22 @@ "paths": [ { "name": "@apitable/components", - "importNames": [ - "Select" - ], + "importNames": ["Select"], "message": "Please use tooltip DropdownSelect from '@apitable/components instead ." }, { "name": "pc/components/common/tooltip", - "importNames": [ - "Tooltip" - ], + "importNames": ["Tooltip"], "message": "Please use tooltip FloatUiTooltip from '@apitable/components instead ." }, { "name": "pc/components/common", - "importNames": [ - "Tooltip" - ], + "importNames": ["Tooltip"], "message": "Please use tooltip FloatUiTooltip from '@apitable/components instead ." }, { "name": "react-custom-scrollbars", - "importNames": [ - "Scrollbars" - ], + "importNames": ["Scrollbars"], "message": "Please use ScrollBar from pc/components/scroll_bar instead." } ] diff --git a/packages/datasheet/next.config.js b/packages/datasheet/next.config.js index 1ffa75feaa..d0da5e5549 100644 --- a/packages/datasheet/next.config.js +++ b/packages/datasheet/next.config.js @@ -19,32 +19,40 @@ /* eslint no-undef: 0 */ const withLess = require('next-with-less'); const path = require('path'); -const withPlugins = require('next-compose-plugins'); const withTM = require('next-transpile-modules'); const withBundleAnalyzer = require('@next/bundle-analyzer'); const isProd = process.env.NODE_ENV === 'production'; const getWebpackConfig = require('./webpack.config'); +const { withSentryConfig } = require('@sentry/nextjs'); -const plugins = [ - [ - withLess, - { - lessLoaderOptions: { - lessOptions: { - paths: [path.resolve(__dirname, './src')], - }, - }, - }, - ], - [withTM(['antd', 'antd-mobile', 'rc-util', 'rc-picker', 'rc-notification', 'rc-calendar'])], - [withBundleAnalyzer({ enabled: process.env.ANALYZE === 'true' })], -]; -/** @type {import('next').NextConfig} */ -module.exports = withPlugins(plugins, { +const sentryWebpackPluginOptions = { + disableServerWebpackPlugin: false, + widenClientFileUpload: true, + disableClientWebpackPlugin: false, + org: process.env.SENTRY_ORG ?? 'sentry', + project: process.env.SENTRY_PROJECT ?? 'web-server', + url: process.env.SENTRY_URL ?? 'https://sentry.vika.ltd', + // An auth token is required for uploading source maps. + dsn: process.env.SENTRY_CONFIG_DSN ?? 'https://51c44e606db14f34963bd4ba64d86410@sentry.vika.ltd/3', + authToken: process.env.SENTRY_AUTH_TOKEN_VIKA ?? '', + release: process.env.WEB_CLIENT_VERSION ?? '', + silent: false, // Suppresses all logs + hideSourceMaps: true, + debug: false + + // For all available options, see: + // https://github.com/getsentry/sentry-webpack-plugin#options. +}; + +const nextConfig = { // Use the CDN in production and localhost for development. assetPrefix: isProd ? process.env.NEXT_ASSET_PREFIX : '', // Possible fix for timeout error in static page generation + env: { + SENTRY_AUTH_TOKEN: process.env.SENTRY_AUTH_TOKEN_VIKA + }, staticPageGenerationTimeout: 120, + webpack: getWebpackConfig, images: { unoptimized: true, domains: ['s4.vika.cn', 's1.vika.cn', 'mp.weixin.qq.com', 'localhost', 's1.apitable.com'], @@ -52,24 +60,24 @@ module.exports = withPlugins(plugins, { { protocol: 'http', hostname: '**', - pathname: '/vk-assets-ltd/**', + pathname: '/vk-assets-ltd/**' }, { protocol: 'https', hostname: '**', - pathname: '/vk-assets-ltd/**', + pathname: '/vk-assets-ltd/**' }, { protocol: 'http', hostname: '**', - pathname: '/assets/**', + pathname: '/assets/**' }, { protocol: 'https', hostname: '**', - pathname: '/assets/**', - }, - ], + pathname: '/assets/**' + } + ] }, swcMinify: true, poweredByHeader: false, @@ -79,20 +87,37 @@ module.exports = withPlugins(plugins, { if (process.env.USE_CUSTOM_PUBLIC_FILES === 'true') return ''; return isProd ? process.env.NEXT_PUBLIC_ASSET_PREFIX : ''; - }, + } + }, + sentry: { + disableServerWebpackPlugin: false, + disableClientWebpackPlugin: false }, - webpack: getWebpackConfig, distDir: 'web_build', output: 'standalone', experimental: { + // runtime: 'nodejs', // 'node.js' (default) | experimental-edge esmExternals: true, // this includes files from the monorepo base two directories up - outputFileTracingRoot: path.join(__dirname, '../../'), - }, - // eslint: { - // ignoreDuringBuilds: true, - // }, - // typescript: { - // ignoreBuildErrors: true, - // } -}); + outputFileTracingRoot: path.join(__dirname, '../../') + } +}; + +/** @type {import('next').NextConfig} */ +const plugins = [ + (nextConfigonfig) => + withLess({ + ...nextConfigonfig, + lessLoaderOptions: { + lessOptions: { + paths: [path.resolve(__dirname, './src')] + } + } + }), + + withTM(['antd', 'antd-mobile', 'rc-util', 'rc-picker', 'rc-notification', 'rc-calendar', 'purify-ts']), + withBundleAnalyzer({ enabled: process.env.ANALYZE === 'true' }) +]; + +const config = () => plugins.reduce((acc, next) => next(acc), nextConfig); +module.exports = isProd && process.env.SENTRY_AUTH_TOKEN_VIKA ? withSentryConfig(config, sentryWebpackPluginOptions, sentryWebpackPluginOptions) : config; diff --git a/packages/datasheet/package.json b/packages/datasheet/package.json index 50324f0b5a..49f66faa46 100644 --- a/packages/datasheet/package.json +++ b/packages/datasheet/package.json @@ -1,6 +1,6 @@ { "name": "@apitable/datasheet", - "version": "1.6.0", + "version": "1.13.0", "author": "APITable Ltd. ", "license": "AGPL-3.0", "scripts": { @@ -8,7 +8,7 @@ "next:start": "next start", "next:build-again": "next build", "dev": "NODE_ENV=development node --max-old-space-size=10000 server.js", - "build": "rm -rf ./web_build && NODE_OPTIONS=--max-old-space-size=4096 next build", + "build": "rm -rf ./web_build && NODE_OPTIONS=--max-old-space-size=10240 next build", "test": "next test", "check:lint": "rm -rf ./web_build && tsc --noEmit && pnpm lint", "check": "tsc --noEmit", @@ -22,14 +22,14 @@ "node": "16.15.0" }, "dependencies": { - "@apitable/ai": "*", - "@apitable/api-client": "*", - "@apitable/components": "*", - "@apitable/core": "*", - "@apitable/i18n-lang": "*", - "@apitable/icons": "*", + "@apitable/ai": "workspace:*", + "@apitable/api-client": "workspace:*", + "@apitable/components": "workspace:*", + "@apitable/core": "workspace:*", + "@apitable/i18n-lang": "workspace:*", + "@apitable/icons": "workspace:*", "@apitable/react-flow": "^9.6.12", - "@apitable/widget-sdk": "*", + "@apitable/widget-sdk": "workspace:*", "@floating-ui/react": "0.24.5", "@futpib/dagre": "^0.8.5-pre1", "@hocuspocus/provider": "^2.5.0", @@ -42,10 +42,10 @@ "@rjsf5/core": "npm:@rjsf/core@^5.13.2", "@rjsf5/utils": "npm:@rjsf/utils@^5.13.2", "@rjsf5/validator-ajv8": "npm:@rjsf/validator-ajv8@^5.13.2", - "@sentry/browser": "^7.20.0", - "@sentry/integrations": "^7.18.0", - "@sentry/nextjs": "^7.18.0", - "@sentry/tracing": "^7.18.0", + "@sentry/browser": "7.92.0", + "@sentry/integrations": "7.92.0", + "@sentry/nextjs": "7.92.0", + "@sentry/tracing": "7.92.0", "@tanstack/query-core": "^4.36.1", "@testing-library/jest-dom": "^5.11.10", "@tiptap/core": "^2.1.8", @@ -55,7 +55,7 @@ "@tiptap/extension-color": "^2.1.8", "@tiptap/extension-document": "^2.1.8", "@tiptap/extension-highlight": "^2.1.8", - "@tiptap/extension-horizontal-rule": "^2.1.8", + "@tiptap/extension-horizontal-rule": "^2.1.11", "@tiptap/extension-image": "^2.1.8", "@tiptap/extension-link": "^2.1.8", "@tiptap/extension-placeholder": "^2.1.8", @@ -72,7 +72,7 @@ "@types/json-schema": "^7.0.12", "@types/react-highlight-words": "^0.16.1", "@types/react-window": "^1.8.1", - "@types/styled-components": "^5.1.26", + "@types/styled-components": "5.1.26", "ahooks": "^3.5.0", "ajv": "^6.12.6", "ajv-i18n": "^4.2.0", @@ -94,6 +94,7 @@ "dingtalk-design-libs": "^0.0.20", "dingtalk-jsapi": "^2.13.71", "dnd-core": "^16.0.1", + "dompurify": "^3.0.1", "dom-to-image": "^2.6.0", "dot-object": "^2.1.2", "element-closest": "^3.0.2", @@ -142,6 +143,7 @@ "posthog-js": "^1.57.2", "prettier-plugin-tailwindcss": "^0.4.1", "prismjs": "^1.29.0", + "purify-ts": "^2.0.1", "qr-image": "^3.2.0", "qrcode": "^1.4.4", "qs": "^6.9.4", @@ -153,7 +155,7 @@ "rc-picker": "^3.13.0", "rc-queue-anim": "^1.8.5", "rc-swipeout": "^2.0.11", - "rc-textarea": "^0.4.5", + "rc-textarea": "^0.3.0", "rc-trigger": "^5.3.3", "rc-util": "^5.24.4", "rc-virtual-list": "^3.4.11", @@ -170,6 +172,7 @@ "react-dropzone": "^11.2.0", "react-grid-layout": "^1.2.0", "react-highlight-words": "^0.16.0", + "react-hook-form": "^7.49.2", "react-image-crop": "^8.6.2", "react-infinite-scroll-hook": "^4.0.1", "react-is": "^17.0.2", @@ -194,14 +197,17 @@ "resize-observer-polyfill": "^1.5.1", "scroller": "^0.0.3", "semver": "^7.5.2", - "slate": "0.66.1", + "slate": "0.81.3", "slate-history": "0.66.0", "slate-hyperscript": "0.66.0", - "slate-react": "0.66.1", + "slate-react": "0.81.0", "socket.io-client": "2.2.0", "store2": "^2.12.0", "styled-components": "5.3.6", "swr": "2.2.0", + "tiptap-markdown": "^0.8.8", + "ts-pattern": "4.3.0", + "turndown": "^7.1.2", "urlcat": "^2.0.4", "use-long-press": "^1.2.0", "uuid": "^9.0.1", @@ -216,6 +222,7 @@ "@tailwindcss/typography": "^0.5.9", "@types/classnames": "2.2.10", "@types/dagre": "^0", + "@types/dompurify": "^3", "@types/dom-to-image": "^2.6.2", "@types/dot-object": "^2.1.2", "@types/element-closest": "^3", @@ -269,6 +276,7 @@ "http-proxy-middleware": "^2.0.6", "https-browserify": "^1.0.0", "is-wsl": "1.1.0", + "jest": "^29.7.0", "less": "4.1.3", "naming-style": "^1.0.1", "next": "^12.3.1", @@ -321,4 +329,4 @@ ] ] } -} +} \ No newline at end of file diff --git a/packages/datasheet/pages/_app.tsx b/packages/datasheet/pages/_app.tsx index 1b134ddbff..37dd3a1677 100644 --- a/packages/datasheet/pages/_app.tsx +++ b/packages/datasheet/pages/_app.tsx @@ -22,11 +22,12 @@ import { Scope } from '@sentry/browser'; import * as Sentry from '@sentry/nextjs'; import axios from 'axios'; import classNames from 'classnames'; +import dayjs from 'dayjs'; import elementClosest from 'element-closest'; import ErrorPage from 'error_page'; import * as immer from 'immer'; import { enableMapSet } from 'immer'; -import { merge } from 'lodash'; +import { init as initPlayer } from 'modules/shared/player/init'; import type { AppProps } from 'next/app'; import dynamic from 'next/dynamic'; import Head from 'next/head'; @@ -52,9 +53,8 @@ import { t, WasmApi, } from '@apitable/core'; -import 'antd/es/date-picker/style/index'; import { getBrowserDatabusApiEnabled } from '@apitable/core/dist/modules/database/api/wasm'; -import { init as initPlayer } from 'modules/shared/player/init'; +import 'antd/es/date-picker/style/index'; import 'normalize.css'; import { initializer } from 'pc/common/initializer'; import { Modal } from 'pc/components/common/modal/modal/modal'; @@ -84,7 +84,6 @@ import '../src/main.less'; import '../src/widget-stage/index.less'; import '../src/widget-stage/main/main.less'; import { getInitialProps } from '../utils/get_initial_props'; -import dayjs from 'dayjs'; enableMapSet(); @@ -155,7 +154,7 @@ function MyAppMain({ Component, pageProps, envVars }: AppProps & { envVars: stri const endLoading = () => { const ele = document.querySelector('.script-loading-wrap'); - // delete loading : scale logo -> vika -> wait 1000ms -> disappear + // delete loading : scale logo -> aitable -> wait 1000ms -> disappear const logoImg = document.querySelector('.script-loading-logo-img'); logoImg?.classList.remove('loading-static-animation'); setTimeout(() => ele?.classList.add('script-loading-wrap-finished'), 0); @@ -287,10 +286,14 @@ function MyAppMain({ Component, pageProps, envVars }: AppProps & { envVars: stri store.dispatch(batchActions(_batchActions, LOGIN_SUCCESS)); window.__initialization_data__.userInfo = userInfo; - window.__initialization_data__.wizards = merge(JSON.parse(res.data.wizards), { + if (userInfo?.locale) { + window.__initialization_data__.lang = userInfo.locale; + window.__initialization_data__.locale = userInfo.locale; + } + window.__initialization_data__.wizards = { guide: SystemConfig.guide, player: SystemConfig.player, - }); + }; }; getUser().then(() => { import('../src/preIndex'); @@ -387,7 +390,6 @@ function MyAppMain({ Component, pageProps, envVars }: AppProps & { envVars: stri return ( <> - {env.DEFAULT_TITLE_NAME || (env.IS_AITABLE ? 'AITable' : env.IS_APITABLE ? 'APITable' : 'vikadata')} . */ -// @ts-ignore -import { IEmbedProps } from 'enterprise/embed/embed'; import { NextPageContext } from 'next'; import dynamic from 'next/dynamic'; import React from 'react'; import { getRegResult, embedIdReg } from 'pc/hooks'; +// @ts-ignore +import { IEmbedProps } from 'enterprise/embed/embed'; const DynamicComponentWithNoSSR = dynamic( () => diff --git a/packages/datasheet/pages/user/appsumo/index.tsx b/packages/datasheet/pages/user/appsumo/index.tsx index dd50bab949..4438dbc818 100644 --- a/packages/datasheet/pages/user/appsumo/index.tsx +++ b/packages/datasheet/pages/user/appsumo/index.tsx @@ -1,12 +1,13 @@ -import {useResponsive} from "pc/hooks"; -import {ScreenSize} from "pc/components/common/component_display"; -import styles from "pc/components/home/style.module.less"; -import {PcHome} from "pc/components/home/pc_home"; -import {MobileHome} from "pc/components/home/mobile_home"; +import { ScreenSize } from 'pc/components/common/component_display'; +import { MobileHome } from 'pc/components/home/mobile_home'; +import { PcHome } from 'pc/components/home/pc_home'; +import styles from 'pc/components/home/style.module.less'; +import { useResponsive } from 'pc/hooks'; +// eslint-disable-next-line import/no-anonymous-default-export export default ()=>{ const { screenIsAtMost } = useResponsive(); const isMobile = screenIsAtMost(ScreenSize.lg); - return
{!isMobile ? : }
-} + return
{!isMobile ? : }
; +}; diff --git a/packages/datasheet/pages/user/wecom/integration/bind.tsx b/packages/datasheet/pages/user/wecom/integration/bind.tsx index 1d70b7fb72..8c0a8b1dc6 100644 --- a/packages/datasheet/pages/user/wecom/integration/bind.tsx +++ b/packages/datasheet/pages/user/wecom/integration/bind.tsx @@ -18,9 +18,9 @@ import React from 'react'; // @ts-ignore -import { WecomIntegrationBind } from 'enterprise/wecom/wecom_integration/wecom_integration_bind/wecom_integration_bind'; -// @ts-ignore import { WecomIntegration } from 'enterprise/wecom/wecom_integration/wecom_integration'; +// @ts-ignore +import { WecomIntegrationBind } from 'enterprise/wecom/wecom_integration/wecom_integration_bind/wecom_integration_bind'; const App = () => { return ( diff --git a/packages/datasheet/pages/user/wecom/integration/bind_success.tsx b/packages/datasheet/pages/user/wecom/integration/bind_success.tsx index cb705862ff..c83321acf2 100644 --- a/packages/datasheet/pages/user/wecom/integration/bind_success.tsx +++ b/packages/datasheet/pages/user/wecom/integration/bind_success.tsx @@ -20,7 +20,7 @@ import React from 'react'; // @ts-ignore import { WecomBindSuccess } from 'enterprise/wecom/wecom_integration/wecom_bind_success'; // @ts-ignore -import { WecomIntegration } from 'enterprise/wecom/wecom_integration/wecom_integration' +import { WecomIntegration } from 'enterprise/wecom/wecom_integration/wecom_integration'; const App = () => { return ( diff --git a/packages/datasheet/pages/user/wecom/integration/binding.tsx b/packages/datasheet/pages/user/wecom/integration/binding.tsx index 1f57414ce9..525b4ac46e 100644 --- a/packages/datasheet/pages/user/wecom/integration/binding.tsx +++ b/packages/datasheet/pages/user/wecom/integration/binding.tsx @@ -18,9 +18,9 @@ import React from 'react'; // @ts-ignore -import { WecomToBind } from 'enterprise/wecom/wecom_integration/wecom_to_bind'; -// @ts-ignore import { WecomIntegration } from 'enterprise/wecom/wecom_integration/wecom_integration'; +// @ts-ignore +import { WecomToBind } from 'enterprise/wecom/wecom_integration/wecom_to_bind'; const App = () => { return ( diff --git a/packages/datasheet/pages/user/wecom/integration/config.tsx b/packages/datasheet/pages/user/wecom/integration/config.tsx index db788bcd85..39c9589075 100644 --- a/packages/datasheet/pages/user/wecom/integration/config.tsx +++ b/packages/datasheet/pages/user/wecom/integration/config.tsx @@ -20,7 +20,7 @@ import React from 'react'; // @ts-ignore import { WecomConfig } from 'enterprise/wecom/wecom_integration/wecom_config'; // @ts-ignore -import { WecomIntegration } from 'enterprise/wecom/wecom_integration/wecom_integration' +import { WecomIntegration } from 'enterprise/wecom/wecom_integration/wecom_integration'; const App = () => { return ( diff --git a/packages/datasheet/public/custom/custom_config.js b/packages/datasheet/public/custom/custom_config.js index c7817d604d..debb6cae59 100644 --- a/packages/datasheet/public/custom/custom_config.js +++ b/packages/datasheet/public/custom/custom_config.js @@ -18,6 +18,7 @@ function main() { window.apitable_i18n_edition = { 'de-DE': { "account_password_incorrect": "Falsches Konto oder Passwort", + "action_execute_error": "Schrittausführungsfehler Fehlermeldung: ${value} Einzelheiten finden Sie unter https://help.vika.cn/docs/guide/manual-automation-robot#how-to-troubleshoot", "activity_login_desc": "", "add_gallery_view_success_guide": "Das Datenblatt mit Bildern wird in der Galerieansicht sehr intuitiv angezeigt. Viele interessante Funktionen sind in Vorbereitung. Bleiben Sie dran~", "all_editable_fields": "Alle bearbeitbaren Felder", @@ -42,6 +43,23 @@ function main() { "assistant_hide": "Verstecke Vikaby", "audit_add_field_role_detail": "english", "auth_server_extensions_login_description_content": "Vikadata Einheitliche Anmeldeseite", + "backup_action_delete": "Snapshot löschen", + "backup_action_recover": "Genesen", + "backup_create": "Schnappschuss erstellen", + "backup_create_success": "Snapshot erfolgreich erstellt", + "backup_create_time": "Zeit schaffen", + "backup_creating": "Erstellen", + "backup_delete_text": "Nach dem Löschen kann es nicht wiederhergestellt werden. Sind Sie sicher, dass Sie es löschen möchten?", + "backup_delete_title": "Schnappschuss löschen", + "backup_deleted": "Gelöscht", + "backup_expired_time": "Ablaufzeit", + "backup_name_success_update": "Erfolgreich geupdated", + "backup_recover_dst_name_suffix": "Genesen", + "backup_recover_modal_text": "Wählen Sie aus, wo der Schnappschuss abgelegt werden soll", + "backup_recover_success": "Erfolgreich wiederhergestellt", + "backup_recover_title": "Genesen", + "backup_success_delete": "Snapshot erfolgreich gelöscht", + "backup_title": "Schnappschuss", "bind_resource": "Wählen Sie ein Datenblatt aus, auf das Sie verlinken möchten", "bronze_grade": "Bronze", "bronze_grade_desc": "For individuals or teams who are new to APITable\n", @@ -51,7 +69,7 @@ function main() { "change_password_success": "Passwort erfolgreich zurückgesetzt", "chart_widget_setting_help_url": "https://help.vika.cn/docs/guide/intro-widget-chart", "check_link_table": "Wählen Sie ein Datenblatt aus, auf das Sie verlinken möchten", - "check_table_link_field": "Wählen Sie ein Link-Feld aus", + "check_table_link_field": "Wählen Sie ein Linkfeld aus", "choose_datasheet_to_link": "Wählen Sie ein Datenblatt aus, zu dem Sie einen Link erstellen möchten", "client_meta_label_desc": "vikadata – eine Datenproduktivitätsplattform, die Ihnen hilft, Ihre Arbeitsdaten effizienter zu verwalten", "client_meta_label_title": "vikadata – eine Datenproduktivitätsplattform", @@ -74,6 +92,7 @@ function main() { "delete_field_tips_content": "Sind Sie sicher, dass Sie das Feld „${field_title}“ löschen möchten?", "delete_field_tips_title": "Feld löschen", "edit_field_name": "Feldnamen bearbeiten", + "embed_link_default_link_url": "https://help.vika.cn/docs/guide/manual-custom-page", "empty_datasheet": "Neues Datenblatt", "err_field_group_tip": "Fehler in den Feldeinstellungen gefunden. Die Gruppierung funktioniert vorübergehend nicht.", "err_filter_field": "Dieses Feld kann aufgrund von Feldkonfigurationsfehlern nicht als Filter hinzugefügt werden", @@ -88,6 +107,7 @@ function main() { "field_had_deleted": "Dieses Feld wurde gelöscht", "field_help_attachment": "https://help.vika.cn/docs/guide/manual-field-attachment", "field_help_autonumber": "https://help.vika.cn/docs/guide/manual-autonumber", + "field_help_button": "Null", "field_help_cascader": "https://help.vika.cn/docs/guide/manual-field-cascader", "field_help_checkbox": "https://help.vika.cn/docs/guide/manual-field-checkbox", "field_help_created_by": "https://help.vika.cn/docs/guide/manual-createdby", @@ -100,12 +120,12 @@ function main() { "field_help_last_modified_by": "https://help.vika.cn/docs/guide/manual-lastmodifiedby", "field_help_last_modified_time": "https://help.vika.cn/docs/guide/manual-lastmodifiedtime", "field_help_link": "https://help.vika.cn/docs/guide/manual-field-link", - "field_help_one_way_link": "https://help.vika.cn/docs/guide/manual-field-link", "field_help_lookup": "https://help.vika.cn/docs/guide/manual-field-lookup", "field_help_member": "https://help.vika.cn/docs/guide/manual-filed-member", "field_help_member_property_subscription": "https://help.vika.cn/docs/guide/manual-filed-member", "field_help_multi_select": "https://help.vika.cn/docs/guide/manual-field-select", "field_help_number": "https://help.vika.cn/docs/guide/manual-field-number", + "field_help_one_way_link": "https://help.vika.cn/docs/guide/manual-field-link", "field_help_percent": "https://help.vika.cn/docs/guide/manual-field-percent", "field_help_phone": "https://help.vika.cn/docs/guide/manual-field-phone", "field_help_rating": "https://help.vika.cn/docs/guide/manual-field-rating", @@ -113,7 +133,7 @@ function main() { "field_help_single_text": "https://help.vika.cn/docs/guide/manual-field-single-line-text", "field_help_text": "https://help.vika.cn/docs/guide/manual-field-text", "field_help_url": "https://help.vika.cn/docs/guide/manual-field-url", - "field_help_button": "https://help.vika.cn/docs/guide/manual-field-button", + "field_help_workdoc": "https://help.vika.cn/docs/guide/manual-field-workdoc", "field_map_tips_for_python": "A field name exists that does not match the variable rules, please turn on \"Use FieldId\" or the code example below may not work! \n[Field Mapping](https://github.com/vikadata/vika.py#%E5%AD%97%E6%AE%B5%E6%98%A0%E5%B0%84) can help you to solve this problem.", "field_permission_help_url": "https://help.vika.cn/docs/guide/manual-field-permission", "field_select_modal_desc": "Wenn eines der unten ausgewählten Felder bearbeitet wird, wird das Mitglied, das zuletzt bearbeitet hat, im Feld „Zuletzt bearbeitet von“ angezeigt", @@ -268,19 +288,19 @@ function main() { "player_step_ui_config_97": "{\n\t\"vikaby\": {\n\t\t\"title\": \"Hello~\",\n\t\t\"description\": \"If you have a problem, you can contact me to help you\",\n\t\t\"list\": \"
  • Not sure how to use vikadata
  • What vikadata can do for me
  • Problems during use
  • What's new in the future
  • Get official invitation code
\",\n\t\t\"tip\": \"Scan the QR code to contact us\"\n\t},\n\t\"questionnaire\": {\n\t\t\"title\": \"Hello, I'm Vika's Digitalization Consultant\",\n\t\t\"list\": \"[{\\\"title\\\": \\\"Report bug\\\", \\\"icon\\\": \\\"BugOutlined\\\"}, {\\\"title\\\": \\\"Give feedback\\\", \\\"icon\\\": \\\"AdviseSmallOutlined\\\"}, {\\\"title\\\": \\\"Customer support\\\", \\\"icon\\\": \\\"ServeOutlined\\\"}, {\\\"title\\\": \\\"Case recommendation\\\", \\\"icon\\\": \\\"ZanOutlined\\\"}, {\\\"title\\\": \\\"Solutions\\\", \\\"icon\\\": \\\"SolutionSmallOutlined\\\"}, {\\\"title\\\": \\\"FAQs\\\", \\\"icon\\\": \\\"InformationLargeOutlined\\\"}]\",\n\t\t\"tip\": \"Please use WeChat to scan the code to add customer service to get more exclusive services\"\n\t},\n\t\"website\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/03/02/59f4cc8e0b2b4395bf0fcd133d208e63\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/03/02/defbf55d1e9646eb929f9f5d11d5c119\"\n\t},\n\t\"dingtalk\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/04/27/2c617a16afd9408ba48392e337fbbd7f?attname=20230427_dingtalk_questionnaire.png\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/04/27/2c617a16afd9408ba48392e337fbbd7f?attname=20230427_dingtalk_vikaby.png\",\n\"tip\": \"Please use DingTalk to scan the code to join our group\"\n\t},\n\t\"wecom\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/03/02/1346d5efbd5043efb2bfcba0075c0ee9\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/03/02/09401a8f2d8e491a9097b9bac8b5a4e4\"\n\t},\n\t\"feishu\": {\n\t\t\"title\": \"Scan the QR code to contact us\",\n\t\t\"tip\": \"Please use Lark to scan the code and add customer service for more help\",\n\t\t\"description\": \"So that you can get service at any time when you encounter problems during use\",\n\t\t\"originUrl\": \"https://u.vika.cn/z9ygm\"\n\t}\n}", "price_title1": "Vika", "private_product_point": "Holen Sie sich sofort Ihr eigenes APITable", - "record_history_help_url": "https://help.vika.cn/docs/guide/manual-record-history", + "record_history_help_url": "https://help.vika.cn/docs/guide/manual-record-activity", "records_per_datasheet": "Die Anzahl der Datensätze pro Datenblatt", "reset_password": "Passwort zurücksetzen", "retrieve_password": "Passwort vergessen", "robot_config_help_url": "https://help.vika.cn/docs/guide/manual-automation-robot/#how-to-config-robot", - "robot_create_name_placeholder": "Vikaby-Roboter", + "robot_create_name_placeholder": "Vikaby-Automatisierung", "robot_help_url": "https://help.vika.cn/docs/guide/manual-automation-robot", "robot_run_history_desc": "Während der öffentlichen Beta- Fehlerbehebung haben Sie Zugriff auf den gesamten Laufverlauf", "robot_run_history_old_version_tip": "Leider stammt dieser Ausführungsverlauf aus einer älteren Version von Vikadata, die das Anzeigen der Details nicht unterstützt", "robot_trigger_record_created_config_1": "Wählen Sie ein Datenblatt aus", - "robot_trigger_record_created_config_1_desc": "Geben Sie ein Datenblatt an: Wenn darin ein Datensatz erstellt wird, beginnt der Roboter zu laufen", + "robot_trigger_record_created_config_1_desc": "Geben Sie ein Datenblatt an: Wenn darin ein Datensatz erstellt wird, wird die Automatisierung gestartet", "robot_trigger_record_matches_condition_config_1": "Wählen Sie ein Datenblatt aus", - "robot_trigger_record_matches_condition_config_1_desc": "Geben Sie ein Datenblatt an: Wenn ein Datensatz darin mit der Bedingung übereinstimmt, beginnt der Roboter zu laufen", + "robot_trigger_record_matches_condition_config_1_desc": "Geben Sie ein Datenblatt an: Wenn ein Datensatz darin mit der Bedingung übereinstimmt, wird die Automatisierung gestartet", "robot_trigger_record_matches_condition_config_2_desc": "Hinweis: Das Hinzufügen eines Datums-/Formelfelds zur Auslösung zur geplanten/fälligen Zeit wird nicht unterstützt [FAQ](https://help.vika.cn/docs/guide/manual-automation-robot#robot-scene-lated-faq)", "robot_variables_datasheet_ID": "Datenblatt-ID", "robot_variables_datasheet_URL": "Datenblatt-URL", @@ -327,7 +347,7 @@ function main() { "task_reminder": "[Erinnerung] Ihre Aufgabe“ „im Datenblatt“ \" wird fällig sein", "template_center_use_to_create_datasheets": "Verwenden Sie diese Vorlage, um Datenblätter zu erstellen.", "template_centre": "Vorlagen", - "test_function_card_info_robot": "Vika Robots helfen Ihnen, sich wiederholende Aktionen in den Datenblättern zu automatisieren und die Produktivität Ihres Teams zu steigern", + "test_function_card_info_robot": "Vika Automation hilft Ihnen, sich wiederholende Aktionen in den Datenblättern zu automatisieren und die Produktivität Ihres Teams zu steigern", "these_columns_you_chose_would_be_deleted": "Ihre ausgewählten ${count}-Felder werden gelöscht", "timemachine_help_url": "https://help.vika.cn/docs/guide/manual-timemachine", "tip_setting_nickname_distribute": "„${nickname}“ ist ein zufälliger Spitzname~", @@ -459,7 +479,7 @@ function main() { "gallery_style_setting_url": "https://help.vika.cn/docs/guide/manual-gallery-view#set-style", "how_to_report_issues": "https://help.vika.cn/docs/guide/how-to-report-issues", "how_contact_service": "https://help.vika.cn/docs/guide/how-contact-service", - "record_history_help_url": "https://help.vika.cn/docs/guide/manual-record-history", + "record_history_help_url": "https://help.vika.cn/docs/guide/manual-record-activity", "field_permission_help_url": "https://help.vika.cn/docs/guide/manual-field-permission", "gantt_setting_help_url": "https://help.vika.cn/docs/guide/manual-gantt-view", "intro_widget": "https://help.vika.cn/docs/guide/intro-widget", @@ -708,6 +728,8 @@ function main() { "main_admin_page_desc": "Admin have full access to the Space, such as assigning sub-admins and transferring ownership of the Space", "backup_creating": "Creating", "backup_deleted": "Deleted", + "backup_create_time": "Create time", + "backup_expired_time": "Expire time", "backup_title": "Snapshot", "backup_create": "Create snapshot", "backup_create_success": "Snapshot created successfully", @@ -724,9 +746,13 @@ function main() { "get_ai_link_person_on_internet": "People who obtain this link on the Internet can also have a conversation with the chat assistant.", "share_tips_ai": "Easily publish your chatbot to the web and share it with a wider audience. Click the \"Publish to Web\" button, and your chatbot will be available at a unique URL.", "pre_fill_help": "https://help.vika.cn/docs/guide/faq-form-pre-fill", - "action_execute_error": "Step execute error\nError message:\n${value}\n\nFor details, please refer to https://help.vika.cn/docs/guide/manual-automation-robot#how-to-troubleshoot" + "action_execute_error": "Step execute error\nError message:\n${value}\n\nFor details, please refer to https://help.vika.cn/docs/guide/manual-automation-robot#how-to-troubleshoot", + "embed_link_default_link_url": "https://help.vika.cn/docs/guide/manual-custom-page", + "embed_page_doc_url": "https://help.vika.cn/docs/guide/manual-custom-page", + "private_help_link": "https://help.vika.cn/docs/guide/team-and-private-area#private-area" },'es-ES': { "account_password_incorrect": "Cuenta o contraseña incorrectas", + "action_execute_error": "Error de ejecución de paso Mensaje de error: ${value} Para obtener más información, consulte https://help.vika.cn/docs/guide/manual-automation-robot#how-to-troubleshoot", "activity_login_desc": "", "add_gallery_view_success_guide": "Para la hoja de datos con imágenes, la vista de galería la mostrará de manera muy intuitiva. Muchas funciones interesantes están en camino. Estén atentos ~", "all_editable_fields": "Todos los campos editables", @@ -736,7 +762,7 @@ function main() { "api_panel_md_js_example": "## Initialize SDK [![github]({{ githubIcon }})](https://github.com/vikadata/vika.js)\n\n```js\n// If es6 import does not work,use const Vika = require('@vikadata/vika').default; to replace import { Vika } from \"@vikadata/vika\";\n\nconst vika = new Vika({ token: \"{{ apiToken }}\", fieldKey: \"{{ fieldKey }}\" });\nconst datasheet = vika.datasheet(\"{{ datasheetId }}\");\n```\n\n\n\n## Get records\n\n```js\n\n// Get the records from a specific view. Returns the first page of records by default\ndatasheet.records.query({ viewId: \"{{ viewId }}\"}).then(response => {\n if (response.success) {\n console.log(response.data);\n } else {\n console.error(response);\n }\n});\n\n```\n\n### Returned data example\n\n```json\n{{ response }}\n```\n\n### Other parameters and tips\n```js\n/**\n * 全局参数配置\n */\n\new Vika({\n /**\n * (必填) string 你的 API Token,用于鉴权\n */\n token: 'YOUR_API_TOKEN',\n /**\n * (选填)全局指定 field 的查询和返回的 key。默认使用列名 'name' 。指定为 'id' 时将以 fieldId 作为查询和返回方式(使用 id 可以避免列名的修改导致代码失效问题)\n */\n fieldKey: 'name', // 默认值\n /**\n * (选填)请求失效时间\n */\n requestTimeout: 60000, // 默认 60000ms (10 秒)\n /**\n * (选填)目标服务器地址\n */\n host: 'https://api.vika.cn/fusion/v1', // 默认值\n});\n\n/*******************************/\n\n// 获取记录\ndatasheet.record.query({\n /**\n * (选填)视图ID。默认为维格表中第一个视图。请求会返回视图中经过视图中筛选/排序后的结果,可以搭配使用fields参数过滤不需要的字段数据\n */\n viewId: 'viewId1',\n /**\n * (选填)对指定维格表的记录进行排序。由多个“排序对象”组成的数组。支持顺序:'asc' 和 逆序:'desc'。注:此参数指定的排序条件将会覆盖视图里的排序条件。\n */\n sort: [{ field: 'field1': order: 'asc' }],\n /**\n * (选填)recordIds 数组。如果附带此参数,则返回参数中指定的records数组。 返回值按照传入数组的顺序排序。此时无视筛选、排序。无分页,每次最多查询 1000 条\n */\n recordIds: ['recordId1', 'recordId2'],\n /**\n * (选填)指定要返回的字段(默认为字段名, 也可以通过 fieldKey 指定为字段 Id)。如果附带此参数,则返回的记录合集将会被过滤,只有指定的字段会返回。\n */\n fields: ['标题', '详情', '引用次数'],\n /**\n * (选填)使用公式作为筛选条件,返回匹配的记录,访问 https://help.vika.cn/docs/guide/tutorial-getting-started-with-formulas 了解公式使用方式\n */\n filterByFormula: '{引用次数} > 0',\n /**\n * (选填)限制返回记录的总数量。如果该值小于表中实际的记录总数,则返回的记录总数会被限制为该值。\n */\n maxRecords: 5000,\n /**\n * (选填)单元格值类型,默认为 'json',指定为 'string' 时所有值都将被自动转换为 string 格式。\n */\n cellFormat: 'json',\n /**\n * (选填)指定 field 的查询和返回的 key。默认使用列名 'name' 。指定为 'id' 时将以 fieldId 作为查询和返回方式(使用 id 可以避免列名的修改导致代码失效问题)\n */\n fieldKey: 'name',\n});\n\n/*******************************/\n\n/**\n * 和 query 获取记录参数相同,自动处理分页。直到获取到所有数据为止。\n */\nconst allRecordsIter = datasheet.records.queryAll()\nfor await (const eachPageRecords of allRecordsIter) {\n console.log(eachPageRecords)\n}\n```\n\n\n\n## Add records\n```js\n// add 方法接收一个数组值,可以同时创建多条 record,单次请求可最多创建10条 record\ndatasheet.records.create({{ records }}).then(response => {\n if (response.success) {\n console.log(response.data);\n } else {\n console.error(response);\n }\n})\n```\n\n### Returned data example\n\n```json\n{{ response }}\n```\n\n\n### Other parameters and tips\n\nadd 接口接收一个数组值,可以同时创建多条 record,单次请求可最多创建10条 record\n\n\n\n## Update records\n```js\n/**\n * update 接收一个数组值,可以同时更新多条 record,单次请求可最多更新10条 record\n * 特别注意: update 只会更新你传入的 fields 下的数据,未传入的不会影响,如果需要清空值,请显式传入 null\n */\ndatasheet.records.update({{ records }}).then(response => {\n if (response.success) {\n console.log(response.data);\n } else {\n console.error(response);\n }\n})\n```\n### Returned data example\n```json\n{{ response }}\n```\n\n\n### Other parameters and tips\n\nupdate 接口接收一个数组值,可以同时更新多条 record,单次请求可最多更新10条 record\n特别注意: update 只会更新你传入的 fields 下的数据,未传入的不会影响,如果需要清空值,请显式传入 null\n \n\n\n## Delete records\n```js\n// del 方法接收一个数组值,可以同时删除多条 record,单次请求可最多删除10条 record\ndatasheet.records.delete({{ recordIds }}).then(response => {\n if (response.success) {\n console.log(response.data);\n } else {\n console.error(response);\n }\n})\n```\n### Returned data example\n```json\n{\n \"code\": 200,\n \"success\": true,\n \"message\": \"请求成功\"\n}\n```\n### Other parameters and tips\ndelete 接口接收一个数组值,可以同时删除多条 record,单次请求可最多删除10条 record\n\n\n\n## Upload attachments\n\n```js\n/*\n * 从 file input 中获取文件\n * \n * 或者在 NodeJs 中使用流读取文件\n * const file = fs.createReadStream(/your/file/path)\n *\n * 下方以浏览器环境作为示例\n */\nconst input = document.getElementById('input');\n\ninput.onchange = function () {\n const file = this.files[0];\n datasheet.upload(file).then(response => {\n /**\n * response 数据包括\n * success: boolean\n * code: number\n * message: string\n * data: IAttachment\n */\n if (response.success) {\n console.log(response.data);\n } else {\n console.error(response);\n }\n });\n};\n\n```\n### Returned data example\n\n*Tips:上传完毕后,请尽快写入data 中的数据到附件单元格里,否则附件链接可能失效*\n\n```json\n{\n \"code\": 200,\n \"success\": true,\n \"message\": \"请求成功\",\n \"data\": {\n \"id\": \"atcPtxnvqti5M\",\n \"name\": \"6.gif\",\n \"size\": 33914,\n \"mimeType\": \"image/gif\",\n \"token\": \"space/2020/09/22/01ee7202922d48688f61e34f12da5abc\",\n \"width\": 240,\n \"height\": 240,\n \"url\": \"https://s4.vika.cn/space/2020/09/22/01ee7202922d48688f61e34f12da5abc\"\n }\n}\n```\n\n### Other parameters and tips\ndelete 接口接收一个数组值,可以同时删除多条 record,单次请求可最多删除10条 record", "api_panel_md_python_example": "## Initialize SDK [![github]({{ githubIcon }})](https://github.com/vikadata/vika.py)\n\n```python\nfrom vika import Vika\nvika = Vika(\"{{ apiToken }}\")\ndatasheet = vika.datasheet(\"{{ datasheetId }}\", field_key=\"{{ fieldKey }}\")\n```\n\n{{ fieldNameTips }}\n\n\n## Get records\n\n```python\n# Returns all records\nrecords = datasheet.records.all()\nfor record in records:\n print(record.json())\n\n# Returns the records from a specific view\nrecords_via_view = datasheet.records.all(viewId=\"{{ viewId }}\")\n# Get one record (if there are more than one records in the result, return the first record); It's recommended to get one record by its recordId.\none_record = datasheet.records.get({{ pyGetParams }})\n# Returns the records that matches the given condition. If you don't give any condition, it returns all records.\nrecords = datasheet.records.filter({{ pyGetParams }})\n```\n\n\n## Add records\n```python\n# Add one record\nrow = datasheet.records.create({{ addParams }})\n# Add multiple records\nrecords = datasheet.records.bulk_create({{ bulkAddParams }})\n\n```\n\n\n## Update records\n```python\nrow = datasheet.records.get({{ pyGetParams }})\n\n# Update one record\nrow.{{ oneFieldKey }} = {{ oneFieldValue }}\n## row.save()\n\n# Update multiple records\nrow.update({{ updateParams }})\n\n```\n\n\n## Delete records\n```python\nrecord = datasheet.records.get({{ pyGetParams }})\n# Delete one record\nrecord.delete()\n# Delete the records that matches a specific condition\ndatasheet.records.filter({{ pyGetParams }}).delete()\n# Delete the records by recordIds\ndatasheet.delete_records({{ recordIds }})\n```\n\n\n## Upload attachments\n\n```python\n_file = datasheet.upload_file()\nrecord.{{ attachFieldName }} = [_file]\n```", "api_panel_type_default_example_email": "support@vikadata.com", - "api_panel_type_default_example_member": "[\n {\n \"id\": \"1291258301781176321\",\n \"type\": 3,\n \"name\": \"Jane\",\n \"avatar\": \"https://s4.vika.cn/default/avatar004.jpg\"\n }\n]", + "api_panel_type_default_example_member": "[ { \"id\": \"1291258301781176321\", \"tipo\": 3, \"nombre\": \"Jane\", \"avatar\": \"https://s4.vika.cn/default/avatar004.jpg\" } ]", "api_panel_type_default_example_url": "{\"title\":\"vika\",\"text\":\"https://vika.cn\", \"favicon\":\"https://s4.vika.cn/space/2022/12/20/73456950217f4f79b20c7ef1a49acf6e\"}", "api_panel_type_desc_created_by": "Devuelve una matriz que contiene un objeto de unidad. La unidad es el miembro que crea el registro.", "api_panel_type_desc_last_modified_by": "Devuelve una matriz que contiene un objeto de unidad. La unidad es la última unidad que modifica el registro o los campos especificados.", @@ -751,6 +777,23 @@ function main() { "assistant_hide": "Ocultar Vikaby", "audit_add_field_role_detail": "english", "auth_server_extensions_login_description_content": "Página de inicio de sesión unificada de Vikadata", + "backup_action_delete": "Eliminar instantánea", + "backup_action_recover": "Recuperar", + "backup_create": "Crear instantánea", + "backup_create_success": "Instantánea creada con éxito", + "backup_create_time": "crear tiempo", + "backup_creating": "Creando", + "backup_delete_text": "Después de la eliminación, no se puede restaurar. ¿Estás seguro de que quieres eliminarlo?", + "backup_delete_title": "Eliminar instantánea", + "backup_deleted": "Eliminado", + "backup_expired_time": "expirar el tiempo", + "backup_name_success_update": "Actualizado exitosamente", + "backup_recover_dst_name_suffix": "Recuperar", + "backup_recover_modal_text": "Elige dónde poner la instantánea", + "backup_recover_success": "Recuperado con éxito", + "backup_recover_title": "Recuperar", + "backup_success_delete": "Instantánea eliminada correctamente", + "backup_title": "Instantánea", "bind_resource": "Seleccione una hoja de datos para enlazar", "bronze_grade": "Bronce", "bronze_grade_desc": "For individuals or teams who are new to APITable\n", @@ -760,7 +803,7 @@ function main() { "change_password_success": "Restablecimiento de contraseña con éxito", "chart_widget_setting_help_url": "https://help.vika.cn/docs/guide/intro-widget-chart", "check_link_table": "Seleccione una hoja de datos para enlazar", - "check_table_link_field": "Seleccione un campo de enlace mágico", + "check_table_link_field": "Seleccione un campo de enlace", "choose_datasheet_to_link": "Seleccione una hoja de datos para enlazar", "client_meta_label_desc": "vikadata: una plataforma de productividad de datos que lo ayuda a administrar sus datos de trabajo de manera más eficiente", "client_meta_label_title": "vikadata: una plataforma de productividad de datos", @@ -783,6 +826,7 @@ function main() { "delete_field_tips_content": "¿Está seguro de que desea eliminar el campo \"${field_title}\"?", "delete_field_tips_title": "Eliminar campo", "edit_field_name": "Editar nombre de campo", + "embed_link_default_link_url": "https://help.vika.cn/docs/guide/manual-custom-page", "empty_datasheet": "Nueva hoja de datos", "err_field_group_tip": "Error encontrado en la configuración de campo. La agrupación no funciona temporalmente.", "err_filter_field": "No se puede agregar este campo como filtro debido a errores de configuración del campo", @@ -809,12 +853,12 @@ function main() { "field_help_last_modified_by": "https://help.vika.cn/docs/guide/manual-lastmodifiedby", "field_help_last_modified_time": "https://help.vika.cn/docs/guide/manual-lastmodifiedtime", "field_help_link": "https://help.vika.cn/docs/guide/manual-field-link", - "field_help_one_way_link": "https://help.vika.cn/docs/guide/manual-field-link", "field_help_lookup": "https://help.vika.cn/docs/guide/manual-field-lookup", "field_help_member": "https://help.vika.cn/docs/guide/manual-filed-member", "field_help_member_property_subscription": "https://help.vika.cn/docs/guide/manual-filed-member", "field_help_multi_select": "https://help.vika.cn/docs/guide/manual-field-select", "field_help_number": "https://help.vika.cn/docs/guide/manual-field-number", + "field_help_one_way_link": "https://help.vika.cn/docs/guide/manual-field-link", "field_help_percent": "https://help.vika.cn/docs/guide/manual-field-percent", "field_help_phone": "https://help.vika.cn/docs/guide/manual-field-phone", "field_help_rating": "https://help.vika.cn/docs/guide/manual-field-rating", @@ -822,6 +866,7 @@ function main() { "field_help_single_text": "https://help.vika.cn/docs/guide/manual-field-single-line-text", "field_help_text": "https://help.vika.cn/docs/guide/manual-field-text", "field_help_url": "https://help.vika.cn/docs/guide/manual-field-url", + "field_help_workdoc": "https://help.vika.cn/docs/guide/manual-field-workdoc", "field_map_tips_for_python": "A field name exists that does not match the variable rules, please turn on \"Use FieldId\" or the code example below may not work! \n[Field Mapping](https://github.com/vikadata/vika.py#%E5%AD%97%E6%AE%B5%E6%98%A0%E5%B0%84) can help you to solve this problem.", "field_permission_help_url": "https://help.vika.cn/docs/guide/manual-field-permission", "field_select_modal_desc": "Si alguno de los campos que selecciona a continuación se edita, el miembro que editó más recientemente se mostrará en el último campo editado por", @@ -916,7 +961,7 @@ function main() { "login_title": "Iniciar sesión", "long_time_no_operate": "La hoja de datos no se ha utilizado durante mucho tiempo, actualice la página para mantener los datos actualizados ~", "lookup_field": "Seleccione una fila de dimensión de ${datasheetName}", - "lookup_field_err": "Primero agregue un campo de enlace mágico", + "lookup_field_err": "Primero agregue un campo de enlace", "lookup_help": "https://help.vika.cn/docs/guide/manual-field-lookup", "lookup_not_found_search_keyword": "No hay coincidencias que contengan \"${notFoundSearchKeywordSpan}\"", "lookup_values_summary": "Devuelve los valores originales", @@ -976,19 +1021,19 @@ function main() { "player_step_ui_config_97": "{\n\t\"vikaby\": {\n\t\t\"title\": \"Hello~\",\n\t\t\"description\": \"If you have a problem, you can contact me to help you\",\n\t\t\"list\": \"
  • Not sure how to use vikadata
  • What vikadata can do for me
  • Problems during use
  • What's new in the future
  • Get official invitation code
\",\n\t\t\"tip\": \"Scan the QR code to contact us\"\n\t},\n\t\"questionnaire\": {\n\t\t\"title\": \"Hello, I'm Vika's Digitalization Consultant\",\n\t\t\"list\": \"[{\\\"title\\\": \\\"Report bug\\\", \\\"icon\\\": \\\"BugOutlined\\\"}, {\\\"title\\\": \\\"Give feedback\\\", \\\"icon\\\": \\\"AdviseSmallOutlined\\\"}, {\\\"title\\\": \\\"Customer support\\\", \\\"icon\\\": \\\"ServeOutlined\\\"}, {\\\"title\\\": \\\"Case recommendation\\\", \\\"icon\\\": \\\"ZanOutlined\\\"}, {\\\"title\\\": \\\"Solutions\\\", \\\"icon\\\": \\\"SolutionSmallOutlined\\\"}, {\\\"title\\\": \\\"FAQs\\\", \\\"icon\\\": \\\"InformationLargeOutlined\\\"}]\",\n\t\t\"tip\": \"Please use WeChat to scan the code to add customer service to get more exclusive services\"\n\t},\n\t\"website\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/03/02/59f4cc8e0b2b4395bf0fcd133d208e63\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/03/02/defbf55d1e9646eb929f9f5d11d5c119\"\n\t},\n\t\"dingtalk\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/04/27/2c617a16afd9408ba48392e337fbbd7f?attname=20230427_dingtalk_questionnaire.png\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/04/27/2c617a16afd9408ba48392e337fbbd7f?attname=20230427_dingtalk_vikaby.png\",\n\"tip\": \"Please use DingTalk to scan the code to join our group\"\n\t},\n\t\"wecom\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/03/02/1346d5efbd5043efb2bfcba0075c0ee9\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/03/02/09401a8f2d8e491a9097b9bac8b5a4e4\"\n\t},\n\t\"feishu\": {\n\t\t\"title\": \"Scan the QR code to contact us\",\n\t\t\"tip\": \"Please use Lark to scan the code and add customer service for more help\",\n\t\t\"description\": \"So that you can get service at any time when you encounter problems during use\",\n\t\t\"originUrl\": \"https://u.vika.cn/z9ygm\"\n\t}\n}", "price_title1": "Viká", "private_product_point": "Obtenga su propia APITable inmediatamente", - "record_history_help_url": "https://help.vika.cn/docs/guide/manual-record-history", + "record_history_help_url": "https://help.vika.cn/docs/guide/manual-record-activity", "records_per_datasheet": "El número de registros por hoja de datos", "reset_password": "Restablecer la contraseña", "retrieve_password": "Has olvidado tu contraseña", "robot_config_help_url": "https://help.vika.cn/docs/guide/manual-automation-robot/#how-to-config-robot", - "robot_create_name_placeholder": "Robot Vikaby", + "robot_create_name_placeholder": "Automatización Vikaby", "robot_help_url": "https://help.vika.cn/docs/guide/manual-automation-robot", "robot_run_history_desc": "Tiene acceso a todo el historial de ejecución durante la versión beta pública Solución de problemas", "robot_run_history_old_version_tip": "Lo sentimos, este historial de ejecución era de una versión anterior de vikadata, que no permite ver los detalles", "robot_trigger_record_created_config_1": "Seleccione una hoja de datos", - "robot_trigger_record_created_config_1_desc": "Especifique una hoja de datos: cuando se crea un registro en ella, el robot comienza a funcionar", + "robot_trigger_record_created_config_1_desc": "Especifique una hoja de datos: cuando se crea un registro en ella, la automatización comienza a ejecutarse", "robot_trigger_record_matches_condition_config_1": "Seleccione una hoja de datos", - "robot_trigger_record_matches_condition_config_1_desc": "Especifique una hoja de datos: cuando un registro en ella coincide con la condición, el robot comienza a funcionar", + "robot_trigger_record_matches_condition_config_1_desc": "Especifique una hoja de datos: cuando un registro coincide con la condición, la automatización comienza a ejecutarse", "robot_trigger_record_matches_condition_config_2_desc": "Nota: No se admite agregar el campo Fecha/Fórmula para activar a la hora programada/vencida [FAQ](https://help.vika.cn/docs/guide/manual-automation-robot#robot-scene-related-faq)", "robot_variables_datasheet_ID": "Identificación de la hoja de datos", "robot_variables_datasheet_URL": "URL de la hoja de datos", @@ -1031,11 +1076,11 @@ function main() { "swagger_constants_desc": "Combinación de cuadrícula y hoja de datos y API integrada, lo que lo ayuda a establecer la aplicación en un abrir y cerrar de ojos basada en este poderoso híbrido de base de datos y hoja de cálculo", "system_configuration_company_name_short": "vika", "system_configuration_product_name": "vikadata", - "table_link_err": "Primero agregue un campo de enlace mágico", + "table_link_err": "Primero agregue un campo de enlace", "task_reminder": "[Recordatorio] Tu tarea \" \"en la hoja de datos\" \"vencerá en", "template_center_use_to_create_datasheets": "Use esta plantilla para crear hojas de datos", "template_centre": "Plantillas", - "test_function_card_info_robot": "Vika Robots lo ayuda a automatizar acciones repetitivas en las hojas de datos y libera la productividad de su equipo", + "test_function_card_info_robot": "Vika Automation te ayuda a automatizar acciones repetitivas en las hojas de datos y liberar la productividad de tu equipo.", "these_columns_you_chose_would_be_deleted": "Se eliminarán los campos de ${count} seleccionados", "timemachine_help_url": "https://help.vika.cn/docs/guide/manual-timemachine", "tip_setting_nickname_distribute": "\"${nickname}\" es un apodo aleatorio~", @@ -1072,6 +1117,7 @@ function main() { "workbench_share_link_template": "De vikadata: ${nickName} ha compartido el archivo \"${nodeName}\" contigo." },'fr-FR': { "account_password_incorrect": "Mauvais compte ou mot de passe", + "action_execute_error": "Erreur d'exécution de l'étape Message d'erreur : ${value} Pour plus de détails, veuillez vous référer à https://help.vika.cn/docs/guide/manual-automation-robot#how-to-troubleshoot", "activity_login_desc": "", "add_gallery_view_success_guide": "Pour la fiche technique avec des images, la vue de la galerie l'affichera de manière très intuitive. De nombreuses fonctions intéressantes sont en route. Restez à l'écoute ~", "all_editable_fields": "Tous les champs modifiables", @@ -1081,8 +1127,8 @@ function main() { "api_panel_md_js_example": "## Initialize SDK [![github]({{ githubIcon }})](https://github.com/vikadata/vika.js)\n\n```js\n// If es6 import does not work,use const Vika = require('@vikadata/vika').default; to replace import { Vika } from \"@vikadata/vika\";\n\nconst vika = new Vika({ token: \"{{ apiToken }}\", fieldKey: \"{{ fieldKey }}\" });\nconst datasheet = vika.datasheet(\"{{ datasheetId }}\");\n```\n\n\n\n## Get records\n\n```js\n\n// Get the records from a specific view. Returns the first page of records by default\ndatasheet.records.query({ viewId: \"{{ viewId }}\"}).then(response => {\n if (response.success) {\n console.log(response.data);\n } else {\n console.error(response);\n }\n});\n\n```\n\n### Returned data example\n\n```json\n{{ response }}\n```\n\n### Other parameters and tips\n```js\n/**\n * 全局参数配置\n */\n\new Vika({\n /**\n * (必填) string 你的 API Token,用于鉴权\n */\n token: 'YOUR_API_TOKEN',\n /**\n * (选填)全局指定 field 的查询和返回的 key。默认使用列名 'name' 。指定为 'id' 时将以 fieldId 作为查询和返回方式(使用 id 可以避免列名的修改导致代码失效问题)\n */\n fieldKey: 'name', // 默认值\n /**\n * (选填)请求失效时间\n */\n requestTimeout: 60000, // 默认 60000ms (10 秒)\n /**\n * (选填)目标服务器地址\n */\n host: 'https://api.vika.cn/fusion/v1', // 默认值\n});\n\n/*******************************/\n\n// 获取记录\ndatasheet.record.query({\n /**\n * (选填)视图ID。默认为维格表中第一个视图。请求会返回视图中经过视图中筛选/排序后的结果,可以搭配使用fields参数过滤不需要的字段数据\n */\n viewId: 'viewId1',\n /**\n * (选填)对指定维格表的记录进行排序。由多个“排序对象”组成的数组。支持顺序:'asc' 和 逆序:'desc'。注:此参数指定的排序条件将会覆盖视图里的排序条件。\n */\n sort: [{ field: 'field1': order: 'asc' }],\n /**\n * (选填)recordIds 数组。如果附带此参数,则返回参数中指定的records数组。 返回值按照传入数组的顺序排序。此时无视筛选、排序。无分页,每次最多查询 1000 条\n */\n recordIds: ['recordId1', 'recordId2'],\n /**\n * (选填)指定要返回的字段(默认为字段名, 也可以通过 fieldKey 指定为字段 Id)。如果附带此参数,则返回的记录合集将会被过滤,只有指定的字段会返回。\n */\n fields: ['标题', '详情', '引用次数'],\n /**\n * (选填)使用公式作为筛选条件,返回匹配的记录,访问 https://help.vika.cn/docs/guide/tutorial-getting-started-with-formulas 了解公式使用方式\n */\n filterByFormula: '{引用次数} > 0',\n /**\n * (选填)限制返回记录的总数量。如果该值小于表中实际的记录总数,则返回的记录总数会被限制为该值。\n */\n maxRecords: 5000,\n /**\n * (选填)单元格值类型,默认为 'json',指定为 'string' 时所有值都将被自动转换为 string 格式。\n */\n cellFormat: 'json',\n /**\n * (选填)指定 field 的查询和返回的 key。默认使用列名 'name' 。指定为 'id' 时将以 fieldId 作为查询和返回方式(使用 id 可以避免列名的修改导致代码失效问题)\n */\n fieldKey: 'name',\n});\n\n/*******************************/\n\n/**\n * 和 query 获取记录参数相同,自动处理分页。直到获取到所有数据为止。\n */\nconst allRecordsIter = datasheet.records.queryAll()\nfor await (const eachPageRecords of allRecordsIter) {\n console.log(eachPageRecords)\n}\n```\n\n\n\n## Add records\n```js\n// add 方法接收一个数组值,可以同时创建多条 record,单次请求可最多创建10条 record\ndatasheet.records.create({{ records }}).then(response => {\n if (response.success) {\n console.log(response.data);\n } else {\n console.error(response);\n }\n})\n```\n\n### Returned data example\n\n```json\n{{ response }}\n```\n\n\n### Other parameters and tips\n\nadd 接口接收一个数组值,可以同时创建多条 record,单次请求可最多创建10条 record\n\n\n\n## Update records\n```js\n/**\n * update 接收一个数组值,可以同时更新多条 record,单次请求可最多更新10条 record\n * 特别注意: update 只会更新你传入的 fields 下的数据,未传入的不会影响,如果需要清空值,请显式传入 null\n */\ndatasheet.records.update({{ records }}).then(response => {\n if (response.success) {\n console.log(response.data);\n } else {\n console.error(response);\n }\n})\n```\n### Returned data example\n```json\n{{ response }}\n```\n\n\n### Other parameters and tips\n\nupdate 接口接收一个数组值,可以同时更新多条 record,单次请求可最多更新10条 record\n特别注意: update 只会更新你传入的 fields 下的数据,未传入的不会影响,如果需要清空值,请显式传入 null\n \n\n\n## Delete records\n```js\n// del 方法接收一个数组值,可以同时删除多条 record,单次请求可最多删除10条 record\ndatasheet.records.delete({{ recordIds }}).then(response => {\n if (response.success) {\n console.log(response.data);\n } else {\n console.error(response);\n }\n})\n```\n### Returned data example\n```json\n{\n \"code\": 200,\n \"success\": true,\n \"message\": \"请求成功\"\n}\n```\n### Other parameters and tips\ndelete 接口接收一个数组值,可以同时删除多条 record,单次请求可最多删除10条 record\n\n\n\n## Upload attachments\n\n```js\n/*\n * 从 file input 中获取文件\n * \n * 或者在 NodeJs 中使用流读取文件\n * const file = fs.createReadStream(/your/file/path)\n *\n * 下方以浏览器环境作为示例\n */\nconst input = document.getElementById('input');\n\ninput.onchange = function () {\n const file = this.files[0];\n datasheet.upload(file).then(response => {\n /**\n * response 数据包括\n * success: boolean\n * code: number\n * message: string\n * data: IAttachment\n */\n if (response.success) {\n console.log(response.data);\n } else {\n console.error(response);\n }\n });\n};\n\n```\n### Returned data example\n\n*Tips:上传完毕后,请尽快写入data 中的数据到附件单元格里,否则附件链接可能失效*\n\n```json\n{\n \"code\": 200,\n \"success\": true,\n \"message\": \"请求成功\",\n \"data\": {\n \"id\": \"atcPtxnvqti5M\",\n \"name\": \"6.gif\",\n \"size\": 33914,\n \"mimeType\": \"image/gif\",\n \"token\": \"space/2020/09/22/01ee7202922d48688f61e34f12da5abc\",\n \"width\": 240,\n \"height\": 240,\n \"url\": \"https://s4.vika.cn/space/2020/09/22/01ee7202922d48688f61e34f12da5abc\"\n }\n}\n```\n\n### Other parameters and tips\ndelete 接口接收一个数组值,可以同时删除多条 record,单次请求可最多删除10条 record", "api_panel_md_python_example": "## Initialize SDK [![github]({{ githubIcon }})](https://github.com/vikadata/vika.py)\n\n```python\nfrom vika import Vika\nvika = Vika(\"{{ apiToken }}\")\ndatasheet = vika.datasheet(\"{{ datasheetId }}\", field_key=\"{{ fieldKey }}\")\n```\n\n{{ fieldNameTips }}\n\n\n## Get records\n\n```python\n# Returns all records\nrecords = datasheet.records.all()\nfor record in records:\n print(record.json())\n\n# Returns the records from a specific view\nrecords_via_view = datasheet.records.all(viewId=\"{{ viewId }}\")\n# Get one record (if there are more than one records in the result, return the first record); It's recommended to get one record by its recordId.\none_record = datasheet.records.get({{ pyGetParams }})\n# Returns the records that matches the given condition. If you don't give any condition, it returns all records.\nrecords = datasheet.records.filter({{ pyGetParams }})\n```\n\n\n## Add records\n```python\n# Add one record\nrow = datasheet.records.create({{ addParams }})\n# Add multiple records\nrecords = datasheet.records.bulk_create({{ bulkAddParams }})\n\n```\n\n\n## Update records\n```python\nrow = datasheet.records.get({{ pyGetParams }})\n\n# Update one record\nrow.{{ oneFieldKey }} = {{ oneFieldValue }}\n## row.save()\n\n# Update multiple records\nrow.update({{ updateParams }})\n\n```\n\n\n## Delete records\n```python\nrecord = datasheet.records.get({{ pyGetParams }})\n# Delete one record\nrecord.delete()\n# Delete the records that matches a specific condition\ndatasheet.records.filter({{ pyGetParams }}).delete()\n# Delete the records by recordIds\ndatasheet.delete_records({{ recordIds }})\n```\n\n\n## Upload attachments\n\n```python\n_file = datasheet.upload_file()\nrecord.{{ attachFieldName }} = [_file]\n```", "api_panel_type_default_example_email": "support@vikadata.com", - "api_panel_type_default_example_member": "[\n {\n \"id\": \"1291258301781176321\",\n \"type\": 3,\n \"name\": \"Jane\",\n \"avatar\": \"https://s4.vika.cn/default/avatar004.jpg\"\n }\n]", - "api_panel_type_default_example_url": "{\"title\":\"vika\",\"text\":\"https://vika.cn\", \"favicon\":\"https://s4.vika.cn/space/2022/12/20/73456950217f4f79b20c7ef1a49acf6e\"}", + "api_panel_type_default_example_member": "[ { \"id\": \"1291258301781176321\", \"type\": 3, \"name\": \"Jane\", \"avatar\": \"https://s4.vika.cn/default/avatar004.jpg\" } ]", + "api_panel_type_default_example_url": "{\"title\": \"vika\", \"text\": \"https://vika.cn\", \"favicon\": \"https://s4.vika.cn/space/2022/12/20/73456950217f4f79b20c7ef1a49acf6e\"}", "api_panel_type_desc_created_by": "Renvoie un tableau qui contient un objet unité. L'unité est le membre qui crée l'enregistrement.", "api_panel_type_desc_last_modified_by": "Renvoie un tableau qui contient un objet unité. L'unité est la dernière unité qui modifie l'enregistrement ou le(s) champ(s) spécifié(s).", "api_panel_type_desc_member": "Renvoie un tableau d'objets unitaires. Une unité décrit les rôles dans un espace tel qu'un membre ou une équipe. \"type\" a deux valeurs : Team ou Member.", @@ -1096,6 +1142,23 @@ function main() { "assistant_hide": "Cacher Vikaby", "audit_add_field_role_detail": "english", "auth_server_extensions_login_description_content": "Page de connexion unifiée Vikadata", + "backup_action_delete": "Supprimer l'instantané", + "backup_action_recover": "Récupérer", + "backup_create": "Créer un instantané", + "backup_create_success": "Instantané créé avec succès", + "backup_create_time": "Créer du temps", + "backup_creating": "Création", + "backup_delete_text": "Après suppression, il ne peut pas être restauré. Es-tu sûr de vouloir le supprimer?", + "backup_delete_title": "Supprimer l'instantané", + "backup_deleted": "Supprimé", + "backup_expired_time": "Date d'expiration", + "backup_name_success_update": "Mis à jour avec succés", + "backup_recover_dst_name_suffix": "Récupérer", + "backup_recover_modal_text": "Choisissez où placer l'instantané", + "backup_recover_success": "Récupéré avec succès", + "backup_recover_title": "Récupérer", + "backup_success_delete": "L'instantané a été supprimé avec succès", + "backup_title": "Instantané", "bind_resource": "Sélectionnez une feuille de données à lier", "bronze_grade": "Bronze", "bronze_grade_desc": "For individuals or teams who are new to APITable\n", @@ -1105,7 +1168,7 @@ function main() { "change_password_success": "Mot de passe réinitialisé avec succès", "chart_widget_setting_help_url": "https://help.vika.cn/docs/guide/intro-widget-chart", "check_link_table": "Sélectionnez une feuille de données à lier", - "check_table_link_field": "Sélectionnez un champ Link", + "check_table_link_field": "Sélectionnez un champ Lien", "choose_datasheet_to_link": "Sélectionnez une feuille de données à lier", "client_meta_label_desc": "vikadata - une plateforme de productivité des données qui vous aide à gérer plus efficacement vos données de travail", "client_meta_label_title": "vikadata - une plateforme de productivité des données", @@ -1128,6 +1191,7 @@ function main() { "delete_field_tips_content": "Voulez-vous vraiment supprimer le champ \"${field_title}\" ?", "delete_field_tips_title": "Supprimer le champ", "edit_field_name": "Modifier le nom du champ", + "embed_link_default_link_url": "https://help.vika.cn/docs/guide/manual-custom-page", "empty_datasheet": "Nouvelle fiche technique", "err_field_group_tip": "Erreur trouvée dans les paramètres de champ. Le regroupement ne fonctionne pas temporairement.", "err_filter_field": "Impossible d'ajouter ce champ en tant que filtre en raison d'erreurs de configuration de champ", @@ -1142,6 +1206,7 @@ function main() { "field_had_deleted": "Ce champ a été supprimé", "field_help_attachment": "https://help.vika.cn/docs/guide/manual-field-attachment", "field_help_autonumber": "https://help.vika.cn/docs/guide/manual-autonumber", + "field_help_button": "nul", "field_help_cascader": "https://help.vika.cn/docs/guide/manual-field-cascader", "field_help_checkbox": "https://help.vika.cn/docs/guide/manual-field-checkbox", "field_help_created_by": "https://help.vika.cn/docs/guide/manual-createdby", @@ -1154,12 +1219,12 @@ function main() { "field_help_last_modified_by": "https://help.vika.cn/docs/guide/manual-lastmodifiedby", "field_help_last_modified_time": "https://help.vika.cn/docs/guide/manual-lastmodifiedtime", "field_help_link": "https://help.vika.cn/docs/guide/manual-field-link", - "field_help_one_way_link": "https://help.vika.cn/docs/guide/manual-field-link", "field_help_lookup": "https://help.vika.cn/docs/guide/manual-field-lookup", "field_help_member": "https://help.vika.cn/docs/guide/manual-filed-member", "field_help_member_property_subscription": "https://help.vika.cn/docs/guide/manual-filed-member", "field_help_multi_select": "https://help.vika.cn/docs/guide/manual-field-select", "field_help_number": "https://help.vika.cn/docs/guide/manual-field-number", + "field_help_one_way_link": "https://help.vika.cn/docs/guide/manual-field-link", "field_help_percent": "https://help.vika.cn/docs/guide/manual-field-percent", "field_help_phone": "https://help.vika.cn/docs/guide/manual-field-phone", "field_help_rating": "https://help.vika.cn/docs/guide/manual-field-rating", @@ -1167,7 +1232,7 @@ function main() { "field_help_single_text": "https://help.vika.cn/docs/guide/manual-field-single-line-text", "field_help_text": "https://help.vika.cn/docs/guide/manual-field-text", "field_help_url": "https://help.vika.cn/docs/guide/manual-field-url", - "field_help_button": "https://help.vika.cn/docs/guide/manual-field-button", + "field_help_workdoc": "https://help.vika.cn/docs/guide/manual-field-workdoc", "field_map_tips_for_python": "A field name exists that does not match the variable rules, please turn on \"Use FieldId\" or the code example below may not work! \n[Field Mapping](https://github.com/vikadata/vika.py#%E5%AD%97%E6%AE%B5%E6%98%A0%E5%B0%84) can help you to solve this problem.", "field_permission_help_url": "https://help.vika.cn/docs/guide/manual-field-permission", "field_select_modal_desc": "Si l'un des champs que vous sélectionnez ci-dessous est modifié, le membre qui a modifié le plus récemment s'affichera dans le dernier champ modifié par", @@ -1262,7 +1327,7 @@ function main() { "login_title": "Se connecter", "long_time_no_operate": "La fiche technique n'a pas été exploitée depuis longtemps, veuillez rafraîchir la page pour garder les données à jour ~", "lookup_field": "Sélectionnez une ligne de dimension dans ${datasheetName}", - "lookup_field_err": "Veuillez d'abord ajouter un champ Link", + "lookup_field_err": "Veuillez d'abord ajouter un champ Lien", "lookup_help": "https://help.vika.cn/docs/guide/manual-field-lookup", "lookup_not_found_search_keyword": "Aucune correspondance contenant \"${notFoundSearchKeywordSpan}\"", "lookup_values_summary": "Renvoie les valeurs d'origine", @@ -1322,19 +1387,19 @@ function main() { "player_step_ui_config_97": "{\n\t\"vikaby\": {\n\t\t\"title\": \"Hello~\",\n\t\t\"description\": \"If you have a problem, you can contact me to help you\",\n\t\t\"list\": \"
  • Not sure how to use vikadata
  • What vikadata can do for me
  • Problems during use
  • What's new in the future
  • Get official invitation code
\",\n\t\t\"tip\": \"Scan the QR code to contact us\"\n\t},\n\t\"questionnaire\": {\n\t\t\"title\": \"Hello, I'm Vika's Digitalization Consultant\",\n\t\t\"list\": \"[{\\\"title\\\": \\\"Report bug\\\", \\\"icon\\\": \\\"BugOutlined\\\"}, {\\\"title\\\": \\\"Give feedback\\\", \\\"icon\\\": \\\"AdviseSmallOutlined\\\"}, {\\\"title\\\": \\\"Customer support\\\", \\\"icon\\\": \\\"ServeOutlined\\\"}, {\\\"title\\\": \\\"Case recommendation\\\", \\\"icon\\\": \\\"ZanOutlined\\\"}, {\\\"title\\\": \\\"Solutions\\\", \\\"icon\\\": \\\"SolutionSmallOutlined\\\"}, {\\\"title\\\": \\\"FAQs\\\", \\\"icon\\\": \\\"InformationLargeOutlined\\\"}]\",\n\t\t\"tip\": \"Please use WeChat to scan the code to add customer service to get more exclusive services\"\n\t},\n\t\"website\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/03/02/59f4cc8e0b2b4395bf0fcd133d208e63\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/03/02/defbf55d1e9646eb929f9f5d11d5c119\"\n\t},\n\t\"dingtalk\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/04/27/2c617a16afd9408ba48392e337fbbd7f?attname=20230427_dingtalk_questionnaire.png\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/04/27/2c617a16afd9408ba48392e337fbbd7f?attname=20230427_dingtalk_vikaby.png\",\n\"tip\": \"Please use DingTalk to scan the code to join our group\"\n\t},\n\t\"wecom\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/03/02/1346d5efbd5043efb2bfcba0075c0ee9\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/03/02/09401a8f2d8e491a9097b9bac8b5a4e4\"\n\t},\n\t\"feishu\": {\n\t\t\"title\": \"Scan the QR code to contact us\",\n\t\t\"tip\": \"Please use Lark to scan the code and add customer service for more help\",\n\t\t\"description\": \"So that you can get service at any time when you encounter problems during use\",\n\t\t\"originUrl\": \"https://u.vika.cn/z9ygm\"\n\t}\n}", "price_title1": "Vika", "private_product_point": "Obtenez votre propre APITable immédiatement", - "record_history_help_url": "https://help.vika.cn/docs/guide/manual-record-history", + "record_history_help_url": "https://help.vika.cn/docs/guide/manual-record-activity", "records_per_datasheet": "Le nombre d'enregistrements par feuille de données", "reset_password": "Réinitialiser le mot de passe", "retrieve_password": "Mot de passe oublié", "robot_config_help_url": "https://help.vika.cn/docs/guide/manual-automation-robot/#how-to-config-robot", - "robot_create_name_placeholder": "Robot Vikaby", + "robot_create_name_placeholder": "Vikaby Automatisation", "robot_help_url": "https://help.vika.cn/docs/guide/manual-automation-robot", - "robot_run_history_desc": "Vous avez accès à tout l'historique d'exécution pendant la version bêta publique", + "robot_run_history_desc": "Vous avez accès à tout l'historique des exécutions pendant la version bêta publique . Dépannage", "robot_run_history_old_version_tip": "Désolé, cet historique d'exécution provenait d'une ancienne version de vikadata, qui ne prend pas en charge l'affichage des détails", "robot_trigger_record_created_config_1": "Sélectionnez une fiche technique", - "robot_trigger_record_created_config_1_desc": "Spécifiez une feuille de données : lorsqu'un enregistrement y est créé, le robot démarre", + "robot_trigger_record_created_config_1_desc": "Spécifiez une feuille de données : lorsqu'un enregistrement y est créé, l'automatisation commence à s'exécuter", "robot_trigger_record_matches_condition_config_1": "Sélectionnez une fiche technique", - "robot_trigger_record_matches_condition_config_1_desc": "Spécifiez une feuille de données : lorsqu'un enregistrement correspond à la condition, le robot commence à fonctionner", + "robot_trigger_record_matches_condition_config_1_desc": "Spécifiez une feuille de données : lorsqu'un enregistrement correspond à la condition, l'automatisation commence à s'exécuter", "robot_trigger_record_matches_condition_config_2_desc": "Remarque : l'ajout d'un champ Date/Formule pour déclencher à l'heure prévue/durée n'est pas pris en charge [FAQ](https://help.vika.cn/docs/guide/manual-automation-robot#robot-scene-related-faq)", "robot_variables_datasheet_ID": "ID de la feuille de données", "robot_variables_datasheet_URL": "URL de la fiche technique", @@ -1377,11 +1442,11 @@ function main() { "swagger_constants_desc": "Combinaison de grille et de feuille de données et d'API intégrée, vous aidant à établir une application en un clin d'œil basée sur ce puissant hybride de base de données et de feuille de calcul", "system_configuration_company_name_short": "vika", "system_configuration_product_name": "vikadata", - "table_link_err": "Veuillez d'abord ajouter un champ Link", + "table_link_err": "Veuillez d'abord ajouter un champ Lien", "task_reminder": "[Rappel] Votre tâche\" \" dans la fiche technique \" \" sera dû en", "template_center_use_to_create_datasheets": "Utilisez ce modèle pour créer des fiches techniques", "template_centre": "Modèles", - "test_function_card_info_robot": "Les robots Vika vous aident à automatiser les actions répétitives dans les fiches techniques et à libérer la productivité de votre équipe", + "test_function_card_info_robot": "Vika Automation vous aide à automatiser les actions répétitives dans les fiches techniques et libère la productivité de votre équipe", "these_columns_you_chose_would_be_deleted": "Vos champs ${count} sélectionnés seront supprimés", "timemachine_help_url": "https://help.vika.cn/docs/guide/manual-timemachine", "tip_setting_nickname_distribute": "\"${nickname}\" est un surnom aléatoire~", @@ -1418,6 +1483,7 @@ function main() { "workbench_share_link_template": "De vikadata : ${nickName} a partagé le fichier \"${nodeName}\" avec vous." },'it-IT': { "account_password_incorrect": "Account o password errati", + "action_execute_error": "Errore di esecuzione del passaggio Messaggio di errore: ${value} Per i dettagli, fare riferimento a https://help.vika.cn/docs/guide/manual-automation-robot#how-to-troubleshoot", "activity_login_desc": "", "add_gallery_view_success_guide": "Per la scheda tecnica con le immagini, la visualizzazione della galleria la visualizzerà in modo molto intuitivo. Molte funzioni interessanti sono in arrivo. Resta sintonizzato~", "all_editable_fields": "Tutti i campi modificabili", @@ -1427,7 +1493,7 @@ function main() { "api_panel_md_js_example": "## Initialize SDK [![github]({{ githubIcon }})](https://github.com/vikadata/vika.js)\n\n```js\n// If es6 import does not work,use const Vika = require('@vikadata/vika').default; to replace import { Vika } from \"@vikadata/vika\";\n\nconst vika = new Vika({ token: \"{{ apiToken }}\", fieldKey: \"{{ fieldKey }}\" });\nconst datasheet = vika.datasheet(\"{{ datasheetId }}\");\n```\n\n\n\n## Get records\n\n```js\n\n// Get the records from a specific view. Returns the first page of records by default\ndatasheet.records.query({ viewId: \"{{ viewId }}\"}).then(response => {\n if (response.success) {\n console.log(response.data);\n } else {\n console.error(response);\n }\n});\n\n```\n\n### Returned data example\n\n```json\n{{ response }}\n```\n\n### Other parameters and tips\n```js\n/**\n * 全局参数配置\n */\n\new Vika({\n /**\n * (必填) string 你的 API Token,用于鉴权\n */\n token: 'YOUR_API_TOKEN',\n /**\n * (选填)全局指定 field 的查询和返回的 key。默认使用列名 'name' 。指定为 'id' 时将以 fieldId 作为查询和返回方式(使用 id 可以避免列名的修改导致代码失效问题)\n */\n fieldKey: 'name', // 默认值\n /**\n * (选填)请求失效时间\n */\n requestTimeout: 60000, // 默认 60000ms (10 秒)\n /**\n * (选填)目标服务器地址\n */\n host: 'https://api.vika.cn/fusion/v1', // 默认值\n});\n\n/*******************************/\n\n// 获取记录\ndatasheet.record.query({\n /**\n * (选填)视图ID。默认为维格表中第一个视图。请求会返回视图中经过视图中筛选/排序后的结果,可以搭配使用fields参数过滤不需要的字段数据\n */\n viewId: 'viewId1',\n /**\n * (选填)对指定维格表的记录进行排序。由多个“排序对象”组成的数组。支持顺序:'asc' 和 逆序:'desc'。注:此参数指定的排序条件将会覆盖视图里的排序条件。\n */\n sort: [{ field: 'field1': order: 'asc' }],\n /**\n * (选填)recordIds 数组。如果附带此参数,则返回参数中指定的records数组。 返回值按照传入数组的顺序排序。此时无视筛选、排序。无分页,每次最多查询 1000 条\n */\n recordIds: ['recordId1', 'recordId2'],\n /**\n * (选填)指定要返回的字段(默认为字段名, 也可以通过 fieldKey 指定为字段 Id)。如果附带此参数,则返回的记录合集将会被过滤,只有指定的字段会返回。\n */\n fields: ['标题', '详情', '引用次数'],\n /**\n * (选填)使用公式作为筛选条件,返回匹配的记录,访问 https://help.vika.cn/docs/guide/tutorial-getting-started-with-formulas 了解公式使用方式\n */\n filterByFormula: '{引用次数} > 0',\n /**\n * (选填)限制返回记录的总数量。如果该值小于表中实际的记录总数,则返回的记录总数会被限制为该值。\n */\n maxRecords: 5000,\n /**\n * (选填)单元格值类型,默认为 'json',指定为 'string' 时所有值都将被自动转换为 string 格式。\n */\n cellFormat: 'json',\n /**\n * (选填)指定 field 的查询和返回的 key。默认使用列名 'name' 。指定为 'id' 时将以 fieldId 作为查询和返回方式(使用 id 可以避免列名的修改导致代码失效问题)\n */\n fieldKey: 'name',\n});\n\n/*******************************/\n\n/**\n * 和 query 获取记录参数相同,自动处理分页。直到获取到所有数据为止。\n */\nconst allRecordsIter = datasheet.records.queryAll()\nfor await (const eachPageRecords of allRecordsIter) {\n console.log(eachPageRecords)\n}\n```\n\n\n\n## Add records\n```js\n// add 方法接收一个数组值,可以同时创建多条 record,单次请求可最多创建10条 record\ndatasheet.records.create({{ records }}).then(response => {\n if (response.success) {\n console.log(response.data);\n } else {\n console.error(response);\n }\n})\n```\n\n### Returned data example\n\n```json\n{{ response }}\n```\n\n\n### Other parameters and tips\n\nadd 接口接收一个数组值,可以同时创建多条 record,单次请求可最多创建10条 record\n\n\n\n## Update records\n```js\n/**\n * update 接收一个数组值,可以同时更新多条 record,单次请求可最多更新10条 record\n * 特别注意: update 只会更新你传入的 fields 下的数据,未传入的不会影响,如果需要清空值,请显式传入 null\n */\ndatasheet.records.update({{ records }}).then(response => {\n if (response.success) {\n console.log(response.data);\n } else {\n console.error(response);\n }\n})\n```\n### Returned data example\n```json\n{{ response }}\n```\n\n\n### Other parameters and tips\n\nupdate 接口接收一个数组值,可以同时更新多条 record,单次请求可最多更新10条 record\n特别注意: update 只会更新你传入的 fields 下的数据,未传入的不会影响,如果需要清空值,请显式传入 null\n \n\n\n## Delete records\n```js\n// del 方法接收一个数组值,可以同时删除多条 record,单次请求可最多删除10条 record\ndatasheet.records.delete({{ recordIds }}).then(response => {\n if (response.success) {\n console.log(response.data);\n } else {\n console.error(response);\n }\n})\n```\n### Returned data example\n```json\n{\n \"code\": 200,\n \"success\": true,\n \"message\": \"请求成功\"\n}\n```\n### Other parameters and tips\ndelete 接口接收一个数组值,可以同时删除多条 record,单次请求可最多删除10条 record\n\n\n\n## Upload attachments\n\n```js\n/*\n * 从 file input 中获取文件\n * \n * 或者在 NodeJs 中使用流读取文件\n * const file = fs.createReadStream(/your/file/path)\n *\n * 下方以浏览器环境作为示例\n */\nconst input = document.getElementById('input');\n\ninput.onchange = function () {\n const file = this.files[0];\n datasheet.upload(file).then(response => {\n /**\n * response 数据包括\n * success: boolean\n * code: number\n * message: string\n * data: IAttachment\n */\n if (response.success) {\n console.log(response.data);\n } else {\n console.error(response);\n }\n });\n};\n\n```\n### Returned data example\n\n*Tips:上传完毕后,请尽快写入data 中的数据到附件单元格里,否则附件链接可能失效*\n\n```json\n{\n \"code\": 200,\n \"success\": true,\n \"message\": \"请求成功\",\n \"data\": {\n \"id\": \"atcPtxnvqti5M\",\n \"name\": \"6.gif\",\n \"size\": 33914,\n \"mimeType\": \"image/gif\",\n \"token\": \"space/2020/09/22/01ee7202922d48688f61e34f12da5abc\",\n \"width\": 240,\n \"height\": 240,\n \"url\": \"https://s4.vika.cn/space/2020/09/22/01ee7202922d48688f61e34f12da5abc\"\n }\n}\n```\n\n### Other parameters and tips\ndelete 接口接收一个数组值,可以同时删除多条 record,单次请求可最多删除10条 record", "api_panel_md_python_example": "## Initialize SDK [![github]({{ githubIcon }})](https://github.com/vikadata/vika.py)\n\n```python\nfrom vika import Vika\nvika = Vika(\"{{ apiToken }}\")\ndatasheet = vika.datasheet(\"{{ datasheetId }}\", field_key=\"{{ fieldKey }}\")\n```\n\n{{ fieldNameTips }}\n\n\n## Get records\n\n```python\n# Returns all records\nrecords = datasheet.records.all()\nfor record in records:\n print(record.json())\n\n# Returns the records from a specific view\nrecords_via_view = datasheet.records.all(viewId=\"{{ viewId }}\")\n# Get one record (if there are more than one records in the result, return the first record); It's recommended to get one record by its recordId.\none_record = datasheet.records.get({{ pyGetParams }})\n# Returns the records that matches the given condition. If you don't give any condition, it returns all records.\nrecords = datasheet.records.filter({{ pyGetParams }})\n```\n\n\n## Add records\n```python\n# Add one record\nrow = datasheet.records.create({{ addParams }})\n# Add multiple records\nrecords = datasheet.records.bulk_create({{ bulkAddParams }})\n\n```\n\n\n## Update records\n```python\nrow = datasheet.records.get({{ pyGetParams }})\n\n# Update one record\nrow.{{ oneFieldKey }} = {{ oneFieldValue }}\n## row.save()\n\n# Update multiple records\nrow.update({{ updateParams }})\n\n```\n\n\n## Delete records\n```python\nrecord = datasheet.records.get({{ pyGetParams }})\n# Delete one record\nrecord.delete()\n# Delete the records that matches a specific condition\ndatasheet.records.filter({{ pyGetParams }}).delete()\n# Delete the records by recordIds\ndatasheet.delete_records({{ recordIds }})\n```\n\n\n## Upload attachments\n\n```python\n_file = datasheet.upload_file()\nrecord.{{ attachFieldName }} = [_file]\n```", "api_panel_type_default_example_email": "support@vikadata.com", - "api_panel_type_default_example_member": "[\n {\n \"id\": \"1291258301781176321\",\n \"type\": 3,\n \"name\": \"Jane\",\n \"avatar\": \"https://s4.vika.cn/default/avatar004.jpg\"\n }\n]", + "api_panel_type_default_example_member": "[ { \"id\": \"1291258301781176321\", \"tipo\": 3, \"nome\": \"Jane\", \"avatar\": \"https://s4.vika.cn/default/avatar004.jpg\" } ]", "api_panel_type_default_example_url": "{\"title\":\"vika\",\"text\":\"https://vika.cn\", \"favicon\":\"https://s4.vika.cn/space/2022/12/20/73456950217f4f79b20c7ef1a49acf6e\"}", "api_panel_type_desc_created_by": "Restituisce una matrice che contiene un oggetto unità. L'unità è il membro che crea il record.", "api_panel_type_desc_last_modified_by": "Restituisce una matrice che contiene un oggetto unità. L'unità è l'ultima unità che modifica il record o il/i campo/i specificato/i.", @@ -1442,6 +1508,23 @@ function main() { "assistant_hide": "Nascondi Vikaby", "audit_add_field_role_detail": "english", "auth_server_extensions_login_description_content": "Pagina di accesso unificato Vikadata", + "backup_action_delete": "Elimina istantanea", + "backup_action_recover": "Recuperare", + "backup_create": "Crea istantanea", + "backup_create_success": "Istantanea creata correttamente", + "backup_create_time": "Crea tempo", + "backup_creating": "Creare", + "backup_delete_text": "Dopo l'eliminazione non è possibile ripristinarlo. Sei sicuro di voler cancellare?", + "backup_delete_title": "Elimina istantanea", + "backup_deleted": "Eliminato", + "backup_expired_time": "Scadenza", + "backup_name_success_update": "Aggiornato con successo", + "backup_recover_dst_name_suffix": "Recuperare", + "backup_recover_modal_text": "Scegli dove posizionare l'istantanea", + "backup_recover_success": "Recuperato con successo", + "backup_recover_title": "Recuperare", + "backup_success_delete": "Istantanea eliminata correttamente", + "backup_title": "Istantanea", "bind_resource": "Seleziona un foglio dati a cui collegarti", "bronze_grade": "Bronzo", "bronze_grade_desc": "For individuals or teams who are new to APITable\n", @@ -1451,7 +1534,7 @@ function main() { "change_password_success": "Reimpostazione password riuscita", "chart_widget_setting_help_url": "https://help.vika.cn/docs/guide/intro-widget-chart", "check_link_table": "Seleziona un foglio dati a cui collegarti", - "check_table_link_field": "Seleziona un campo Link", + "check_table_link_field": "Seleziona un campo Collegamento", "choose_datasheet_to_link": "Seleziona un foglio dati a cui collegarti", "client_meta_label_desc": "vikadata: una piattaforma di produttività dei dati che ti aiuta a gestire i tuoi dati di lavoro in modo più efficiente", "client_meta_label_title": "vikadata - una piattaforma per la produttività dei dati", @@ -1474,6 +1557,7 @@ function main() { "delete_field_tips_content": "Sei sicuro di voler eliminare il campo \"${field_title}\"?", "delete_field_tips_title": "Elimina campo", "edit_field_name": "Modifica il nome del campo", + "embed_link_default_link_url": "https://help.vika.cn/docs/guide/manual-custom-page", "empty_datasheet": "Nuova scheda tecnica", "err_field_group_tip": "Errore trovato nelle impostazioni del campo. Il raggruppamento non funziona temporaneamente.", "err_filter_field": "Impossibile aggiungere questo campo come filtro a causa di errori di configurazione del campo", @@ -1488,6 +1572,7 @@ function main() { "field_had_deleted": "Questo campo è stato eliminato", "field_help_attachment": "https://help.vika.cn/docs/guide/manual-field-attachment", "field_help_autonumber": "https://help.vika.cn/docs/guide/manual-autonumber", + "field_help_button": "nullo", "field_help_cascader": "https://help.vika.cn/docs/guide/manual-field-cascader", "field_help_checkbox": "https://help.vika.cn/docs/guide/manual-field-checkbox", "field_help_created_by": "https://help.vika.cn/docs/guide/manual-createdby", @@ -1500,12 +1585,12 @@ function main() { "field_help_last_modified_by": "https://help.vika.cn/docs/guide/manual-lastmodifiedby", "field_help_last_modified_time": "https://help.vika.cn/docs/guide/manual-lastmodifiedtime", "field_help_link": "https://help.vika.cn/docs/guide/manual-field-link", - "field_help_one_way_link": "https://help.vika.cn/docs/guide/manual-field-link", "field_help_lookup": "https://help.vika.cn/docs/guide/manual-field-lookup", "field_help_member": "https://help.vika.cn/docs/guide/manual-filed-member", "field_help_member_property_subscription": "https://help.vika.cn/docs/guide/manual-filed-member", "field_help_multi_select": "https://help.vika.cn/docs/guide/manual-field-select", "field_help_number": "https://help.vika.cn/docs/guide/manual-field-number", + "field_help_one_way_link": "https://help.vika.cn/docs/guide/manual-field-link", "field_help_percent": "https://help.vika.cn/docs/guide/manual-field-percent", "field_help_phone": "https://help.vika.cn/docs/guide/manual-field-phone", "field_help_rating": "https://help.vika.cn/docs/guide/manual-field-rating", @@ -1513,7 +1598,7 @@ function main() { "field_help_single_text": "https://help.vika.cn/docs/guide/manual-field-single-line-text", "field_help_text": "https://help.vika.cn/docs/guide/manual-field-text", "field_help_url": "https://help.vika.cn/docs/guide/manual-field-url", - "field_help_button": "https://help.vika.cn/docs/guide/manual-field-button", + "field_help_workdoc": "https://help.vika.cn/docs/guide/manual-field-workdoc", "field_map_tips_for_python": "A field name exists that does not match the variable rules, please turn on \"Use FieldId\" or the code example below may not work! \n[Field Mapping](https://github.com/vikadata/vika.py#%E5%AD%97%E6%AE%B5%E6%98%A0%E5%B0%84) can help you to solve this problem.", "field_permission_help_url": "https://help.vika.cn/docs/guide/manual-field-permission", "field_select_modal_desc": "Se uno dei campi selezionati di seguito viene modificato, il membro che ha modificato più di recente verrà visualizzato nell'ultimo campo modificato da", @@ -1608,7 +1693,7 @@ function main() { "login_title": "Accedi vikadata", "long_time_no_operate": "La scheda tecnica non è stata utilizzata per molto tempo, aggiorna la pagina per mantenere i dati aggiornati~", "lookup_field": "Seleziona una riga dimensione da ${datasheetName}", - "lookup_field_err": "Aggiungi prima un campo Link", + "lookup_field_err": "Aggiungi prima un campo Collegamento", "lookup_help": "https://help.vika.cn/docs/guide/manual-field-lookup", "lookup_not_found_search_keyword": "Nessuna corrispondenza contenente \"${notFoundSearchKeywordSpan}\"", "lookup_values_summary": "Restituisce i valori originali", @@ -1668,19 +1753,19 @@ function main() { "player_step_ui_config_97": "{\n\t\"vikaby\": {\n\t\t\"title\": \"Hello~\",\n\t\t\"description\": \"If you have a problem, you can contact me to help you\",\n\t\t\"list\": \"
  • Not sure how to use vikadata
  • What vikadata can do for me
  • Problems during use
  • What's new in the future
  • Get official invitation code
\",\n\t\t\"tip\": \"Scan the QR code to contact us\"\n\t},\n\t\"questionnaire\": {\n\t\t\"title\": \"Hello, I'm Vika's Digitalization Consultant\",\n\t\t\"list\": \"[{\\\"title\\\": \\\"Report bug\\\", \\\"icon\\\": \\\"BugOutlined\\\"}, {\\\"title\\\": \\\"Give feedback\\\", \\\"icon\\\": \\\"AdviseSmallOutlined\\\"}, {\\\"title\\\": \\\"Customer support\\\", \\\"icon\\\": \\\"ServeOutlined\\\"}, {\\\"title\\\": \\\"Case recommendation\\\", \\\"icon\\\": \\\"ZanOutlined\\\"}, {\\\"title\\\": \\\"Solutions\\\", \\\"icon\\\": \\\"SolutionSmallOutlined\\\"}, {\\\"title\\\": \\\"FAQs\\\", \\\"icon\\\": \\\"InformationLargeOutlined\\\"}]\",\n\t\t\"tip\": \"Please use WeChat to scan the code to add customer service to get more exclusive services\"\n\t},\n\t\"website\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/03/02/59f4cc8e0b2b4395bf0fcd133d208e63\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/03/02/defbf55d1e9646eb929f9f5d11d5c119\"\n\t},\n\t\"dingtalk\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/04/27/2c617a16afd9408ba48392e337fbbd7f?attname=20230427_dingtalk_questionnaire.png\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/04/27/2c617a16afd9408ba48392e337fbbd7f?attname=20230427_dingtalk_vikaby.png\",\n\"tip\": \"Please use DingTalk to scan the code to join our group\"\n\t},\n\t\"wecom\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/03/02/1346d5efbd5043efb2bfcba0075c0ee9\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/03/02/09401a8f2d8e491a9097b9bac8b5a4e4\"\n\t},\n\t\"feishu\": {\n\t\t\"title\": \"Scan the QR code to contact us\",\n\t\t\"tip\": \"Please use Lark to scan the code and add customer service for more help\",\n\t\t\"description\": \"So that you can get service at any time when you encounter problems during use\",\n\t\t\"originUrl\": \"https://u.vika.cn/z9ygm\"\n\t}\n}", "price_title1": "Vica", "private_product_point": "Ottieni subito la tua APITable", - "record_history_help_url": "https://help.vika.cn/docs/guide/manual-record-history", + "record_history_help_url": "https://help.vika.cn/docs/guide/manual-record-activity", "records_per_datasheet": "Il numero di record per foglio dati", "reset_password": "Resetta la password", "retrieve_password": "Ha dimenticato la password", "robot_config_help_url": "https://help.vika.cn/docs/guide/manual-automation-robot/#how-to-config-robot", - "robot_create_name_placeholder": "Vikaby Robot", + "robot_create_name_placeholder": "Vikaby Automazione", "robot_help_url": "https://help.vika.cn/docs/guide/manual-automation-robot", "robot_run_history_desc": "Hai accesso a tutta la cronologia delle corse durante la risoluzione dei problemi della beta pubblica", "robot_run_history_old_version_tip": "Siamo spiacenti, questa cronologia di esecuzione proveniva da una versione precedente di vikadata, che non supporta la visualizzazione dei dettagli", "robot_trigger_record_created_config_1": "Seleziona una scheda tecnica", - "robot_trigger_record_created_config_1_desc": "Specificare un foglio dati: quando viene creato un record in esso, il robot inizia a funzionare", + "robot_trigger_record_created_config_1_desc": "Specificare un foglio dati: quando viene creato un record al suo interno, l'automazione inizia a essere eseguita", "robot_trigger_record_matches_condition_config_1": "Seleziona una scheda tecnica", - "robot_trigger_record_matches_condition_config_1_desc": "Specificare un foglio dati: quando un record in esso corrisponde alla condizione, il robot inizia a funzionare", + "robot_trigger_record_matches_condition_config_1_desc": "Specificare un foglio dati: quando un record in esso contenuto corrisponde alla condizione, l'automazione inizia a essere eseguita", "robot_trigger_record_matches_condition_config_2_desc": "Nota: l'aggiunta del campo Data/Formula per l'attivazione all'ora pianificata/di scadenza non è supportata [FAQ](https://help.vika.cn/docs/guide/manual-automation-robot#robot-scene-related-faq)", "robot_variables_datasheet_ID": "ID foglio dati", "robot_variables_datasheet_URL": "URL del foglio dati", @@ -1723,11 +1808,11 @@ function main() { "swagger_constants_desc": "Combinazione di griglia e foglio dati e API integrata, che ti aiuta a stabilire un'applicazione in un batter d'occhio basata su questo potente ibrido foglio di calcolo database", "system_configuration_company_name_short": "vika", "system_configuration_product_name": "vikadata", - "table_link_err": "Aggiungi prima un campo Link", + "table_link_err": "Aggiungi prima un campo Collegamento", "task_reminder": "[Promemoria] Il tuo compito \" \" nella scheda tecnica \" \"sarà in arrivo", "template_center_use_to_create_datasheets": "Usa questo modello per creare fogli dati", "template_centre": "Modelli", - "test_function_card_info_robot": "Vika Robots ti aiuta ad automatizzare le azioni ripetitive nelle schede tecniche e a liberare la produttività del tuo team", + "test_function_card_info_robot": "Vika Automation ti aiuta ad automatizzare le azioni ripetitive nelle schede tecniche e libera la produttività del tuo team", "these_columns_you_chose_would_be_deleted": "I campi ${count} selezionati verranno eliminati", "timemachine_help_url": "https://help.vika.cn/docs/guide/manual-timemachine", "tip_setting_nickname_distribute": "\"${nickname}\" è un soprannome casuale~", @@ -1764,6 +1849,7 @@ function main() { "workbench_share_link_template": "Da vikadata: ${nickName} ha condiviso con te il file \"${nodeName}\"." },'ja-JP': { "account_password_incorrect": "アカウントまたはパスワードが間違っています", + "action_execute_error": "ステップ実行エラー エラー メッセージ: ${value} 詳細については、https://help.vika.cn/docs/guide/manual-automation-robot#how-to-troubleshoot を参照してください。", "activity_login_desc": "", "add_gallery_view_success_guide": "画像を含むデータシートの場合、ギャラリー ビューでは非常に直感的に表示されます。多くの興味深い機能が開発中です。乞うご期待~", "all_editable_fields": "すべての編集可能なフィールド", @@ -1773,8 +1859,8 @@ function main() { "api_panel_md_js_example": "## Initialize SDK [![github]({{ githubIcon }})](https://github.com/vikadata/vika.js)\n\n```js\n// If es6 import does not work,use const Vika = require('@vikadata/vika').default; to replace import { Vika } from \"@vikadata/vika\";\n\nconst vika = new Vika({ token: \"{{ apiToken }}\", fieldKey: \"{{ fieldKey }}\" });\nconst datasheet = vika.datasheet(\"{{ datasheetId }}\");\n```\n\n\n\n## Get records\n\n```js\n\n// Get the records from a specific view. Returns the first page of records by default\ndatasheet.records.query({ viewId: \"{{ viewId }}\"}).then(response => {\n if (response.success) {\n console.log(response.data);\n } else {\n console.error(response);\n }\n});\n\n```\n\n### Returned data example\n\n```json\n{{ response }}\n```\n\n### Other parameters and tips\n```js\n/**\n * 全局参数配置\n */\n\new Vika({\n /**\n * (必填) string 你的 API Token,用于鉴权\n */\n token: 'YOUR_API_TOKEN',\n /**\n * (选填)全局指定 field 的查询和返回的 key。默认使用列名 'name' 。指定为 'id' 时将以 fieldId 作为查询和返回方式(使用 id 可以避免列名的修改导致代码失效问题)\n */\n fieldKey: 'name', // 默认值\n /**\n * (选填)请求失效时间\n */\n requestTimeout: 60000, // 默认 60000ms (10 秒)\n /**\n * (选填)目标服务器地址\n */\n host: 'https://api.vika.cn/fusion/v1', // 默认值\n});\n\n/*******************************/\n\n// 获取记录\ndatasheet.record.query({\n /**\n * (选填)视图ID。默认为维格表中第一个视图。请求会返回视图中经过视图中筛选/排序后的结果,可以搭配使用fields参数过滤不需要的字段数据\n */\n viewId: 'viewId1',\n /**\n * (选填)对指定维格表的记录进行排序。由多个“排序对象”组成的数组。支持顺序:'asc' 和 逆序:'desc'。注:此参数指定的排序条件将会覆盖视图里的排序条件。\n */\n sort: [{ field: 'field1': order: 'asc' }],\n /**\n * (选填)recordIds 数组。如果附带此参数,则返回参数中指定的records数组。 返回值按照传入数组的顺序排序。此时无视筛选、排序。无分页,每次最多查询 1000 条\n */\n recordIds: ['recordId1', 'recordId2'],\n /**\n * (选填)指定要返回的字段(默认为字段名, 也可以通过 fieldKey 指定为字段 Id)。如果附带此参数,则返回的记录合集将会被过滤,只有指定的字段会返回。\n */\n fields: ['标题', '详情', '引用次数'],\n /**\n * (选填)使用公式作为筛选条件,返回匹配的记录,访问 https://help.vika.cn/docs/guide/tutorial-getting-started-with-formulas 了解公式使用方式\n */\n filterByFormula: '{引用次数} > 0',\n /**\n * (选填)限制返回记录的总数量。如果该值小于表中实际的记录总数,则返回的记录总数会被限制为该值。\n */\n maxRecords: 5000,\n /**\n * (选填)单元格值类型,默认为 'json',指定为 'string' 时所有值都将被自动转换为 string 格式。\n */\n cellFormat: 'json',\n /**\n * (选填)指定 field 的查询和返回的 key。默认使用列名 'name' 。指定为 'id' 时将以 fieldId 作为查询和返回方式(使用 id 可以避免列名的修改导致代码失效问题)\n */\n fieldKey: 'name',\n});\n\n/*******************************/\n\n/**\n * 和 query 获取记录参数相同,自动处理分页。直到获取到所有数据为止。\n */\nconst allRecordsIter = datasheet.records.queryAll()\nfor await (const eachPageRecords of allRecordsIter) {\n console.log(eachPageRecords)\n}\n```\n\n\n\n## Add records\n```js\n// add 方法接收一个数组值,可以同时创建多条 record,单次请求可最多创建10条 record\ndatasheet.records.create({{ records }}).then(response => {\n if (response.success) {\n console.log(response.data);\n } else {\n console.error(response);\n }\n})\n```\n\n### Returned data example\n\n```json\n{{ response }}\n```\n\n\n### Other parameters and tips\n\nadd 接口接收一个数组值,可以同时创建多条 record,单次请求可最多创建10条 record\n\n\n\n## Update records\n```js\n/**\n * update 接收一个数组值,可以同时更新多条 record,单次请求可最多更新10条 record\n * 特别注意: update 只会更新你传入的 fields 下的数据,未传入的不会影响,如果需要清空值,请显式传入 null\n */\ndatasheet.records.update({{ records }}).then(response => {\n if (response.success) {\n console.log(response.data);\n } else {\n console.error(response);\n }\n})\n```\n### Returned data example\n```json\n{{ response }}\n```\n\n\n### Other parameters and tips\n\nupdate 接口接收一个数组值,可以同时更新多条 record,单次请求可最多更新10条 record\n特别注意: update 只会更新你传入的 fields 下的数据,未传入的不会影响,如果需要清空值,请显式传入 null\n \n\n\n## Delete records\n```js\n// del 方法接收一个数组值,可以同时删除多条 record,单次请求可最多删除10条 record\ndatasheet.records.delete({{ recordIds }}).then(response => {\n if (response.success) {\n console.log(response.data);\n } else {\n console.error(response);\n }\n})\n```\n### Returned data example\n```json\n{\n \"code\": 200,\n \"success\": true,\n \"message\": \"请求成功\"\n}\n```\n### Other parameters and tips\ndelete 接口接收一个数组值,可以同时删除多条 record,单次请求可最多删除10条 record\n\n\n\n## Upload attachments\n\n```js\n/*\n * 从 file input 中获取文件\n * \n * 或者在 NodeJs 中使用流读取文件\n * const file = fs.createReadStream(/your/file/path)\n *\n * 下方以浏览器环境作为示例\n */\nconst input = document.getElementById('input');\n\ninput.onchange = function () {\n const file = this.files[0];\n datasheet.upload(file).then(response => {\n /**\n * response 数据包括\n * success: boolean\n * code: number\n * message: string\n * data: IAttachment\n */\n if (response.success) {\n console.log(response.data);\n } else {\n console.error(response);\n }\n });\n};\n\n```\n### Returned data example\n\n*Tips:上传完毕后,请尽快写入data 中的数据到附件单元格里,否则附件链接可能失效*\n\n```json\n{\n \"code\": 200,\n \"success\": true,\n \"message\": \"请求成功\",\n \"data\": {\n \"id\": \"atcPtxnvqti5M\",\n \"name\": \"6.gif\",\n \"size\": 33914,\n \"mimeType\": \"image/gif\",\n \"token\": \"space/2020/09/22/01ee7202922d48688f61e34f12da5abc\",\n \"width\": 240,\n \"height\": 240,\n \"url\": \"https://s4.vika.cn/space/2020/09/22/01ee7202922d48688f61e34f12da5abc\"\n }\n}\n```\n\n### Other parameters and tips\ndelete 接口接收一个数组值,可以同时删除多条 record,单次请求可最多删除10条 record", "api_panel_md_python_example": "## Initialize SDK [![github]({{ githubIcon }})](https://github.com/vikadata/vika.py)\n\n```python\nfrom vika import Vika\nvika = Vika(\"{{ apiToken }}\")\ndatasheet = vika.datasheet(\"{{ datasheetId }}\", field_key=\"{{ fieldKey }}\")\n```\n\n{{ fieldNameTips }}\n\n\n## Get records\n\n```python\n# Returns all records\nrecords = datasheet.records.all()\nfor record in records:\n print(record.json())\n\n# Returns the records from a specific view\nrecords_via_view = datasheet.records.all(viewId=\"{{ viewId }}\")\n# Get one record (if there are more than one records in the result, return the first record); It's recommended to get one record by its recordId.\none_record = datasheet.records.get({{ pyGetParams }})\n# Returns the records that matches the given condition. If you don't give any condition, it returns all records.\nrecords = datasheet.records.filter({{ pyGetParams }})\n```\n\n\n## Add records\n```python\n# Add one record\nrow = datasheet.records.create({{ addParams }})\n# Add multiple records\nrecords = datasheet.records.bulk_create({{ bulkAddParams }})\n\n```\n\n\n## Update records\n```python\nrow = datasheet.records.get({{ pyGetParams }})\n\n# Update one record\nrow.{{ oneFieldKey }} = {{ oneFieldValue }}\n## row.save()\n\n# Update multiple records\nrow.update({{ updateParams }})\n\n```\n\n\n## Delete records\n```python\nrecord = datasheet.records.get({{ pyGetParams }})\n# Delete one record\nrecord.delete()\n# Delete the records that matches a specific condition\ndatasheet.records.filter({{ pyGetParams }}).delete()\n# Delete the records by recordIds\ndatasheet.delete_records({{ recordIds }})\n```\n\n\n## Upload attachments\n\n```python\n_file = datasheet.upload_file()\nrecord.{{ attachFieldName }} = [_file]\n```", "api_panel_type_default_example_email": "support@vikadata.com", - "api_panel_type_default_example_member": "[\n {\n \"id\": \"1291258301781176321\",\n \"type\": 3,\n \"name\": \"Jane\",\n \"avatar\": \"https://s4.vika.cn/default/avatar004.jpg\"\n }\n]", - "api_panel_type_default_example_url": "{\"title\":\"vika\",\"text\":\"https://vika.cn\", \"favicon\":\"https://s4.vika.cn/space/2022/12/20/73456950217f4f79b20c7ef1a49acf6e\"}", + "api_panel_type_default_example_member": "[ { \"id\": \"1291258301781176321\"、\"タイプ\": 3、\"名前\": \"ジェーン\"、\"アバター\": \"https://s4.vika.cn/default/avatar004.jpg\" } ]", + "api_panel_type_default_example_url": "{\"タイトル\":\"ヴィカ\",\"テキスト\":\"https://vika.cn\", \"ファビコン\":\"https://s4.vika.cn/space/2022/12/20/73456950217f4f79b20c7ef1a49acf6e\"}", "api_panel_type_desc_created_by": "1 つのユニット オブジェクトを含む配列を返します。ユニットはレコードを作成するメンバーです。", "api_panel_type_desc_last_modified_by": "1 つのユニット オブジェクトを含む配列を返します。ユニットは、レコードまたは指定されたフィールドを変更する最後のユニットです。", "api_panel_type_desc_member": "ユニットオブジェクトの配列を返します。ユニットは、メンバーやチームなど、スペース内の役割を記述します。 「type」には、Team または Member の 2 つの値があります。", @@ -1788,6 +1874,23 @@ function main() { "assistant_hide": "ヴィカビを隠す", "audit_add_field_role_detail": "english", "auth_server_extensions_login_description_content": "Vikadata 統合ログイン ページ", + "backup_action_delete": "スナップショットの削除", + "backup_action_recover": "回復する", + "backup_create": "スナップショットの作成", + "backup_create_success": "スナップショットが正常に作成されました", + "backup_create_time": "時間を作る", + "backup_creating": "作成", + "backup_delete_text": "削除後は復元できません。削除してもよろしいですか?", + "backup_delete_title": "スナップショットの削除", + "backup_deleted": "削除されました", + "backup_expired_time": "有効期限", + "backup_name_success_update": "更新成功", + "backup_recover_dst_name_suffix": "回復する", + "backup_recover_modal_text": "スナップショットを配置する場所を選択します", + "backup_recover_success": "正常に回復しました", + "backup_recover_title": "回復する", + "backup_success_delete": "スナップショットが正常に削除されました", + "backup_title": "スナップショット", "bind_resource": "リンク先のデータシートを選択してください", "bronze_grade": "ブロンズ", "bronze_grade_desc": "For individuals or teams who are new to APITable\n", @@ -1797,7 +1900,7 @@ function main() { "change_password_success": "パスワードが正常にリセットされました", "chart_widget_setting_help_url": "https://help.vika.cn/docs/guide/intro-widget-chart", "check_link_table": "リンク先のデータシートを選択してください", - "check_table_link_field": "マジック リンク フィールドを選択します", + "check_table_link_field": "リンクフィールドを選択してください", "choose_datasheet_to_link": "リンク先のデータシートを選択してください", "client_meta_label_desc": "vikadata - 仕事データをより効率的に管理するのに役立つデータ生産性プラットフォーム", "client_meta_label_title": "vikadata - データ生産性プラットフォーム", @@ -1820,6 +1923,7 @@ function main() { "delete_field_tips_content": "「${field_title}」フィールドを削除してもよろしいですか?", "delete_field_tips_title": "フィールドの削除", "edit_field_name": "フィールド名の編集", + "embed_link_default_link_url": "https://help.vika.cn/docs/guide/manual-custom-page", "empty_datasheet": "新しいデータシート", "err_field_group_tip": "フィールド設定でエラーが見つかりました。グループ化は一時的に機能しません。", "err_filter_field": "フィールド構成エラーのため、このフィールドをフィルターとして追加できません", @@ -1834,6 +1938,7 @@ function main() { "field_had_deleted": "このフィールドは削除されました", "field_help_attachment": "https://help.vika.cn/docs/guide/manual-field-attachment", "field_help_autonumber": "https://help.vika.cn/docs/guide/manual-autonumber", + "field_help_button": "ヌル", "field_help_cascader": "https://help.vika.cn/docs/guide/manual-field-cascader", "field_help_checkbox": "https://help.vika.cn/docs/guide/manual-field-checkbox", "field_help_created_by": "https://help.vika.cn/docs/guide/manual-createdby", @@ -1846,12 +1951,12 @@ function main() { "field_help_last_modified_by": "https://help.vika.cn/docs/guide/manual-lastmodifiedby", "field_help_last_modified_time": "https://help.vika.cn/docs/guide/manual-lastmodifiedtime", "field_help_link": "https://help.vika.cn/docs/guide/manual-field-link", - "field_help_one_way_link": "https://help.vika.cn/docs/guide/manual-field-link", "field_help_lookup": "https://help.vika.cn/docs/guide/manual-field-lookup", "field_help_member": "https://help.vika.cn/docs/guide/manual-filed-member", "field_help_member_property_subscription": "https://help.vika.cn/docs/guide/manual-filed-member", "field_help_multi_select": "https://help.vika.cn/docs/guide/manual-field-select", "field_help_number": "https://help.vika.cn/docs/guide/manual-field-number", + "field_help_one_way_link": "https://help.vika.cn/docs/guide/manual-field-link", "field_help_percent": "https://help.vika.cn/docs/guide/manual-field-percent", "field_help_phone": "https://help.vika.cn/docs/guide/manual-field-phone", "field_help_rating": "https://help.vika.cn/docs/guide/manual-field-rating", @@ -1859,7 +1964,7 @@ function main() { "field_help_single_text": "https://help.vika.cn/docs/guide/manual-field-single-line-text", "field_help_text": "https://help.vika.cn/docs/guide/manual-field-text", "field_help_url": "https://help.vika.cn/docs/guide/manual-field-url", - "field_help_button": "https://help.vika.cn/docs/guide/manual-field-button", + "field_help_workdoc": "https://help.vika.cn/docs/guide/manual-field-workdoc", "field_map_tips_for_python": "A field name exists that does not match the variable rules, please turn on \"Use FieldId\" or the code example below may not work! \n[Field Mapping](https://github.com/vikadata/vika.py#%E5%AD%97%E6%AE%B5%E6%98%A0%E5%B0%84) can help you to solve this problem.", "field_permission_help_url": "https://help.vika.cn/docs/guide/manual-field-permission", "field_select_modal_desc": "以下で選択したフィールドのいずれかが編集されている場合、最後に編集したメンバーが「最終編集者」フィールドに表示されます。", @@ -1954,7 +2059,7 @@ function main() { "login_title": "ログイン", "long_time_no_operate": "データシートは長期間操作されていません。データを最新の状態に保つためにページを更新してください~", "lookup_field": "${datasheetName} からディメンション行を選択します", - "lookup_field_err": "最初に Link フィールドを追加してください", + "lookup_field_err": "まずリンクフィールドを追加してください", "lookup_help": "https://help.vika.cn/docs/guide/manual-field-lookup", "lookup_not_found_search_keyword": "「${notFoundSearchKeywordSpan}」を含む一致はありません", "lookup_values_summary": "元の値を返します", @@ -2014,19 +2119,19 @@ function main() { "player_step_ui_config_97": "{\n\t\"vikaby\": {\n\t\t\"title\": \"Hello~\",\n\t\t\"description\": \"If you have a problem, you can contact me to help you\",\n\t\t\"list\": \"
  • Not sure how to use vikadata
  • What vikadata can do for me
  • Problems during use
  • What's new in the future
  • Get official invitation code
\",\n\t\t\"tip\": \"Scan the QR code to contact us\"\n\t},\n\t\"questionnaire\": {\n\t\t\"title\": \"Hello, I'm Vika's Digitalization Consultant\",\n\t\t\"list\": \"[{\\\"title\\\": \\\"Report bug\\\", \\\"icon\\\": \\\"BugOutlined\\\"}, {\\\"title\\\": \\\"Give feedback\\\", \\\"icon\\\": \\\"AdviseSmallOutlined\\\"}, {\\\"title\\\": \\\"Customer support\\\", \\\"icon\\\": \\\"ServeOutlined\\\"}, {\\\"title\\\": \\\"Case recommendation\\\", \\\"icon\\\": \\\"ZanOutlined\\\"}, {\\\"title\\\": \\\"Solutions\\\", \\\"icon\\\": \\\"SolutionSmallOutlined\\\"}, {\\\"title\\\": \\\"FAQs\\\", \\\"icon\\\": \\\"InformationLargeOutlined\\\"}]\",\n\t\t\"tip\": \"Please use WeChat to scan the code to add customer service to get more exclusive services\"\n\t},\n\t\"website\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/03/02/59f4cc8e0b2b4395bf0fcd133d208e63\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/03/02/defbf55d1e9646eb929f9f5d11d5c119\"\n\t},\n\t\"dingtalk\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/04/27/2c617a16afd9408ba48392e337fbbd7f?attname=20230427_dingtalk_questionnaire.png\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/04/27/2c617a16afd9408ba48392e337fbbd7f?attname=20230427_dingtalk_vikaby.png\",\n\"tip\": \"Please use DingTalk to scan the code to join our group\"\n\t},\n\t\"wecom\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/03/02/1346d5efbd5043efb2bfcba0075c0ee9\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/03/02/09401a8f2d8e491a9097b9bac8b5a4e4\"\n\t},\n\t\"feishu\": {\n\t\t\"title\": \"Scan the QR code to contact us\",\n\t\t\"tip\": \"Please use Lark to scan the code and add customer service for more help\",\n\t\t\"description\": \"So that you can get service at any time when you encounter problems during use\",\n\t\t\"originUrl\": \"https://u.vika.cn/z9ygm\"\n\t}\n}", "price_title1": "ヴィカ", "private_product_point": "独自の APITable を今すぐ入手", - "record_history_help_url": "https://help.vika.cn/docs/guide/manual-record-history", + "record_history_help_url": "https://help.vika.cn/docs/guide/manual-record-activity", "records_per_datasheet": "データシートあたりのレコード数", "reset_password": "パスワードを再設定する", "retrieve_password": "パスワードをお忘れですか", "robot_config_help_url": "https://help.vika.cn/docs/guide/manual-automation-robot/#how-to-config-robot", - "robot_create_name_placeholder": "ヴィカビーロボット", + "robot_create_name_placeholder": "ビカビオートメーション", "robot_help_url": "https://help.vika.cn/docs/guide/manual-automation-robot", "robot_run_history_desc": "パブリックベータ期間中はすべての実行履歴にアクセスできます。 トラブルシューティング", "robot_run_history_old_version_tip": "申し訳ありませんが、この実行履歴は古いバージョンの vikadata のものであり、詳細の表示をサポートしていません。", "robot_trigger_record_created_config_1": "データシートを選択してください", - "robot_trigger_record_created_config_1_desc": "データシートを 1 つ指定します。データシートにレコードが作成されると、ロボットが実行を開始します。", + "robot_trigger_record_created_config_1_desc": "1 つのデータシートを指定します。その中にレコードが作成されると、オートメーションの実行が開始されます。", "robot_trigger_record_matches_condition_config_1": "データシートを選択してください", - "robot_trigger_record_matches_condition_config_1_desc": "データシートを 1 つ指定します。データシート内のレコードが条件に一致すると、ロボットが実行を開始します。", + "robot_trigger_record_matches_condition_config_1_desc": "データシートを 1 つ指定します。データシート内のレコードが条件に一致すると、オートメーションの実行が開始されます。", "robot_trigger_record_matches_condition_config_2_desc": "注: スケジュール/期日でトリガーする日付/式フィールドの追加はサポートされていません [FAQ](https://help.vika.cn/docs/guide/manual-automation-robot#robot-scene-popular-faq)", "robot_variables_datasheet_ID": "データシートID", "robot_variables_datasheet_URL": "データシートの URL", @@ -2069,11 +2174,11 @@ function main() { "swagger_constants_desc": "グリッド、データシート、組み込み API の組み合わせにより、この強力なデータベースとスプレッドシートのハイブリッドに基づいてアプリケーションを瞬時に構築できます。", "system_configuration_company_name_short": "vika", "system_configuration_product_name": "vikadata", - "table_link_err": "最初に Link フィールドを追加してください", + "table_link_err": "まずリンクフィールドを追加してください", "task_reminder": "[リマインダー] あなたのタスク」 「データシートにある」 \" に予定されています", "template_center_use_to_create_datasheets": "このテンプレートを使用してデータシートを作成します", "template_centre": "テンプレート", - "test_function_card_info_robot": "Vika ロボットは、データシートでの反復的なアクションを自動化し、チームの生産性を解放するのに役立ちます。", + "test_function_card_info_robot": "Vika Automation は、データシートでの反復的なアクションを自動化し、チームの生産性を解放するのに役立ちます。", "these_columns_you_chose_would_be_deleted": "選択した ${count} フィールドが削除されます", "timemachine_help_url": "https://help.vika.cn/docs/guide/manual-timemachine", "tip_setting_nickname_distribute": "「${nickname}」はランダムなニックネームです~", @@ -2110,6 +2215,7 @@ function main() { "workbench_share_link_template": "vikadata より: ${nickName} が「${nodeName}」ファイルをあなたと共有しました。" },'ko-KR': { "account_password_incorrect": "잘못된 계정 또는 비밀번호", + "action_execute_error": "단계 실행 오류 오류 메시지: ${value} 자세한 내용은 https://help.vika.cn/docs/guide/manual-automation-robot#how-to-troubleshoot를 참조하세요.", "activity_login_desc": "", "add_gallery_view_success_guide": "사진이 있는 데이터시트의 경우 갤러리 보기에 매우 직관적으로 표시됩니다. 많은 흥미로운 기능이 진행 중입니다. 기대해주세요~", "all_editable_fields": "편집 가능한 모든 필드", @@ -2119,8 +2225,8 @@ function main() { "api_panel_md_js_example": "## Initialize SDK [![github]({{ githubIcon }})](https://github.com/vikadata/vika.js)\n\n```js\n// If es6 import does not work,use const Vika = require('@vikadata/vika').default; to replace import { Vika } from \"@vikadata/vika\";\n\nconst vika = new Vika({ token: \"{{ apiToken }}\", fieldKey: \"{{ fieldKey }}\" });\nconst datasheet = vika.datasheet(\"{{ datasheetId }}\");\n```\n\n\n\n## Get records\n\n```js\n\n// Get the records from a specific view. Returns the first page of records by default\ndatasheet.records.query({ viewId: \"{{ viewId }}\"}).then(response => {\n if (response.success) {\n console.log(response.data);\n } else {\n console.error(response);\n }\n});\n\n```\n\n### Returned data example\n\n```json\n{{ response }}\n```\n\n### Other parameters and tips\n```js\n/**\n * 全局参数配置\n */\n\new Vika({\n /**\n * (必填) string 你的 API Token,用于鉴权\n */\n token: 'YOUR_API_TOKEN',\n /**\n * (选填)全局指定 field 的查询和返回的 key。默认使用列名 'name' 。指定为 'id' 时将以 fieldId 作为查询和返回方式(使用 id 可以避免列名的修改导致代码失效问题)\n */\n fieldKey: 'name', // 默认值\n /**\n * (选填)请求失效时间\n */\n requestTimeout: 60000, // 默认 60000ms (10 秒)\n /**\n * (选填)目标服务器地址\n */\n host: 'https://api.vika.cn/fusion/v1', // 默认值\n});\n\n/*******************************/\n\n// 获取记录\ndatasheet.record.query({\n /**\n * (选填)视图ID。默认为维格表中第一个视图。请求会返回视图中经过视图中筛选/排序后的结果,可以搭配使用fields参数过滤不需要的字段数据\n */\n viewId: 'viewId1',\n /**\n * (选填)对指定维格表的记录进行排序。由多个“排序对象”组成的数组。支持顺序:'asc' 和 逆序:'desc'。注:此参数指定的排序条件将会覆盖视图里的排序条件。\n */\n sort: [{ field: 'field1': order: 'asc' }],\n /**\n * (选填)recordIds 数组。如果附带此参数,则返回参数中指定的records数组。 返回值按照传入数组的顺序排序。此时无视筛选、排序。无分页,每次最多查询 1000 条\n */\n recordIds: ['recordId1', 'recordId2'],\n /**\n * (选填)指定要返回的字段(默认为字段名, 也可以通过 fieldKey 指定为字段 Id)。如果附带此参数,则返回的记录合集将会被过滤,只有指定的字段会返回。\n */\n fields: ['标题', '详情', '引用次数'],\n /**\n * (选填)使用公式作为筛选条件,返回匹配的记录,访问 https://help.vika.cn/docs/guide/tutorial-getting-started-with-formulas 了解公式使用方式\n */\n filterByFormula: '{引用次数} > 0',\n /**\n * (选填)限制返回记录的总数量。如果该值小于表中实际的记录总数,则返回的记录总数会被限制为该值。\n */\n maxRecords: 5000,\n /**\n * (选填)单元格值类型,默认为 'json',指定为 'string' 时所有值都将被自动转换为 string 格式。\n */\n cellFormat: 'json',\n /**\n * (选填)指定 field 的查询和返回的 key。默认使用列名 'name' 。指定为 'id' 时将以 fieldId 作为查询和返回方式(使用 id 可以避免列名的修改导致代码失效问题)\n */\n fieldKey: 'name',\n});\n\n/*******************************/\n\n/**\n * 和 query 获取记录参数相同,自动处理分页。直到获取到所有数据为止。\n */\nconst allRecordsIter = datasheet.records.queryAll()\nfor await (const eachPageRecords of allRecordsIter) {\n console.log(eachPageRecords)\n}\n```\n\n\n\n## Add records\n```js\n// add 方法接收一个数组值,可以同时创建多条 record,单次请求可最多创建10条 record\ndatasheet.records.create({{ records }}).then(response => {\n if (response.success) {\n console.log(response.data);\n } else {\n console.error(response);\n }\n})\n```\n\n### Returned data example\n\n```json\n{{ response }}\n```\n\n\n### Other parameters and tips\n\nadd 接口接收一个数组值,可以同时创建多条 record,单次请求可最多创建10条 record\n\n\n\n## Update records\n```js\n/**\n * update 接收一个数组值,可以同时更新多条 record,单次请求可最多更新10条 record\n * 特别注意: update 只会更新你传入的 fields 下的数据,未传入的不会影响,如果需要清空值,请显式传入 null\n */\ndatasheet.records.update({{ records }}).then(response => {\n if (response.success) {\n console.log(response.data);\n } else {\n console.error(response);\n }\n})\n```\n### Returned data example\n```json\n{{ response }}\n```\n\n\n### Other parameters and tips\n\nupdate 接口接收一个数组值,可以同时更新多条 record,单次请求可最多更新10条 record\n特别注意: update 只会更新你传入的 fields 下的数据,未传入的不会影响,如果需要清空值,请显式传入 null\n \n\n\n## Delete records\n```js\n// del 方法接收一个数组值,可以同时删除多条 record,单次请求可最多删除10条 record\ndatasheet.records.delete({{ recordIds }}).then(response => {\n if (response.success) {\n console.log(response.data);\n } else {\n console.error(response);\n }\n})\n```\n### Returned data example\n```json\n{\n \"code\": 200,\n \"success\": true,\n \"message\": \"请求成功\"\n}\n```\n### Other parameters and tips\ndelete 接口接收一个数组值,可以同时删除多条 record,单次请求可最多删除10条 record\n\n\n\n## Upload attachments\n\n```js\n/*\n * 从 file input 中获取文件\n * \n * 或者在 NodeJs 中使用流读取文件\n * const file = fs.createReadStream(/your/file/path)\n *\n * 下方以浏览器环境作为示例\n */\nconst input = document.getElementById('input');\n\ninput.onchange = function () {\n const file = this.files[0];\n datasheet.upload(file).then(response => {\n /**\n * response 数据包括\n * success: boolean\n * code: number\n * message: string\n * data: IAttachment\n */\n if (response.success) {\n console.log(response.data);\n } else {\n console.error(response);\n }\n });\n};\n\n```\n### Returned data example\n\n*Tips:上传完毕后,请尽快写入data 中的数据到附件单元格里,否则附件链接可能失效*\n\n```json\n{\n \"code\": 200,\n \"success\": true,\n \"message\": \"请求成功\",\n \"data\": {\n \"id\": \"atcPtxnvqti5M\",\n \"name\": \"6.gif\",\n \"size\": 33914,\n \"mimeType\": \"image/gif\",\n \"token\": \"space/2020/09/22/01ee7202922d48688f61e34f12da5abc\",\n \"width\": 240,\n \"height\": 240,\n \"url\": \"https://s4.vika.cn/space/2020/09/22/01ee7202922d48688f61e34f12da5abc\"\n }\n}\n```\n\n### Other parameters and tips\ndelete 接口接收一个数组值,可以同时删除多条 record,单次请求可最多删除10条 record", "api_panel_md_python_example": "## Initialize SDK [![github]({{ githubIcon }})](https://github.com/vikadata/vika.py)\n\n```python\nfrom vika import Vika\nvika = Vika(\"{{ apiToken }}\")\ndatasheet = vika.datasheet(\"{{ datasheetId }}\", field_key=\"{{ fieldKey }}\")\n```\n\n{{ fieldNameTips }}\n\n\n## Get records\n\n```python\n# Returns all records\nrecords = datasheet.records.all()\nfor record in records:\n print(record.json())\n\n# Returns the records from a specific view\nrecords_via_view = datasheet.records.all(viewId=\"{{ viewId }}\")\n# Get one record (if there are more than one records in the result, return the first record); It's recommended to get one record by its recordId.\none_record = datasheet.records.get({{ pyGetParams }})\n# Returns the records that matches the given condition. If you don't give any condition, it returns all records.\nrecords = datasheet.records.filter({{ pyGetParams }})\n```\n\n\n## Add records\n```python\n# Add one record\nrow = datasheet.records.create({{ addParams }})\n# Add multiple records\nrecords = datasheet.records.bulk_create({{ bulkAddParams }})\n\n```\n\n\n## Update records\n```python\nrow = datasheet.records.get({{ pyGetParams }})\n\n# Update one record\nrow.{{ oneFieldKey }} = {{ oneFieldValue }}\n## row.save()\n\n# Update multiple records\nrow.update({{ updateParams }})\n\n```\n\n\n## Delete records\n```python\nrecord = datasheet.records.get({{ pyGetParams }})\n# Delete one record\nrecord.delete()\n# Delete the records that matches a specific condition\ndatasheet.records.filter({{ pyGetParams }}).delete()\n# Delete the records by recordIds\ndatasheet.delete_records({{ recordIds }})\n```\n\n\n## Upload attachments\n\n```python\n_file = datasheet.upload_file()\nrecord.{{ attachFieldName }} = [_file]\n```", "api_panel_type_default_example_email": "support@vikadata.com", - "api_panel_type_default_example_member": "[\n {\n \"id\": \"1291258301781176321\",\n \"type\": 3,\n \"name\": \"Jane\",\n \"avatar\": \"https://s4.vika.cn/default/avatar004.jpg\"\n }\n]", - "api_panel_type_default_example_url": "{\"title\":\"vika\",\"text\":\"https://vika.cn\", \"favicon\":\"https://s4.vika.cn/space/2022/12/20/73456950217f4f79b20c7ef1a49acf6e\"}", + "api_panel_type_default_example_member": "[ { \"id\": \"1291258301781176321\", \"type\": 3, \"name\": \"Jane\", \"avatar\": \"https://s4.vika.cn/default/avatar004.jpg\" } ]", + "api_panel_type_default_example_url": "{\"제목\":\"vika\",\"텍스트\":\"https://vika.cn\", \"favicon\":\"https://s4.vika.cn/space/2022/12/20/73456950217f4f79b20c7ef1a49acf6e\"}", "api_panel_type_desc_created_by": "하나의 단위 개체를 포함하는 배열을 반환합니다. 단위는 레코드를 생성하는 구성원입니다.", "api_panel_type_desc_last_modified_by": "하나의 단위 개체를 포함하는 배열을 반환합니다. 단위는 레코드 또는 지정된 필드를 수정하는 마지막 단위입니다.", "api_panel_type_desc_member": "단위 개체의 배열을 반환합니다. 단위는 구성원이나 팀과 같은 공간의 역할을 설명합니다. \"유형\"에는 팀 또는 구성원의 두 가지 값이 있습니다.", @@ -2134,6 +2240,23 @@ function main() { "assistant_hide": "비카비 숨기기", "audit_add_field_role_detail": "english", "auth_server_extensions_login_description_content": "Vikadata 통합 로그인 페이지", + "backup_action_delete": "스냅샷 삭제", + "backup_action_recover": "다시 덮다", + "backup_create": "스냅샷 생성", + "backup_create_success": "스냅샷이 성공적으로 생성되었습니다.", + "backup_create_time": "시간을 창조하다", + "backup_creating": "만들기", + "backup_delete_text": "삭제 후에는 복원할 수 없습니다. 삭제하시겠습니까?", + "backup_delete_title": "스냅샷 삭제", + "backup_deleted": "삭제됨", + "backup_expired_time": "만료 시간", + "backup_name_success_update": "업데이트되었습니다.", + "backup_recover_dst_name_suffix": "다시 덮다", + "backup_recover_modal_text": "스냅샷을 저장할 위치를 선택하세요", + "backup_recover_success": "성공적으로 복구되었습니다", + "backup_recover_title": "다시 덮다", + "backup_success_delete": "스냅샷이 삭제되었습니다.", + "backup_title": "스냅 사진", "bind_resource": "연결할 데이터시트 선택", "bronze_grade": "청동", "bronze_grade_desc": "For individuals or teams who are new to APITable\n", @@ -2143,7 +2266,7 @@ function main() { "change_password_success": "비밀번호 재설정 성공", "chart_widget_setting_help_url": "https://help.vika.cn/docs/guide/intro-widget-chart", "check_link_table": "연결할 데이터시트 선택", - "check_table_link_field": "매직 링크 필드 선택", + "check_table_link_field": "링크 필드를 선택하세요", "choose_datasheet_to_link": "연결할 데이터시트 선택", "client_meta_label_desc": "vikadata - 작업 데이터를 보다 효율적으로 관리할 수 있도록 도와주는 데이터 생산성 플랫폼", "client_meta_label_title": "vikadata - 데이터 생산성 플랫폼", @@ -2166,6 +2289,7 @@ function main() { "delete_field_tips_content": "\"${field_title}\" 필드를 삭제하시겠습니까?", "delete_field_tips_title": "필드 삭제", "edit_field_name": "필드 이름 수정", + "embed_link_default_link_url": "https://help.vika.cn/docs/guide/manual-custom-page", "empty_datasheet": "새 데이터시트", "err_field_group_tip": "필드 설정에서 오류가 발견되었습니다. 그룹화는 일시적으로 작동하지 않습니다.", "err_filter_field": "필드 구성 오류로 인해 이 필드를 필터로 추가할 수 없습니다.", @@ -2180,6 +2304,7 @@ function main() { "field_had_deleted": "이 필드는 삭제되었습니다", "field_help_attachment": "https://help.vika.cn/docs/guide/manual-field-attachment", "field_help_autonumber": "https://help.vika.cn/docs/guide/manual-autonumber", + "field_help_button": "없는", "field_help_cascader": "https://help.vika.cn/docs/guide/manual-field-cascader", "field_help_checkbox": "https://help.vika.cn/docs/guide/manual-field-checkbox", "field_help_created_by": "https://help.vika.cn/docs/guide/manual-createdby", @@ -2192,12 +2317,12 @@ function main() { "field_help_last_modified_by": "https://help.vika.cn/docs/guide/manual-lastmodifiedby", "field_help_last_modified_time": "https://help.vika.cn/docs/guide/manual-lastmodifiedtime", "field_help_link": "https://help.vika.cn/docs/guide/manual-field-link", - "field_help_one_way_link": "https://help.vika.cn/docs/guide/manual-field-link", "field_help_lookup": "https://help.vika.cn/docs/guide/manual-field-lookup", "field_help_member": "https://help.vika.cn/docs/guide/manual-filed-member", "field_help_member_property_subscription": "https://help.vika.cn/docs/guide/manual-filed-member", "field_help_multi_select": "https://help.vika.cn/docs/guide/manual-field-select", "field_help_number": "https://help.vika.cn/docs/guide/manual-field-number", + "field_help_one_way_link": "https://help.vika.cn/docs/guide/manual-field-link", "field_help_percent": "https://help.vika.cn/docs/guide/manual-field-percent", "field_help_phone": "https://help.vika.cn/docs/guide/manual-field-phone", "field_help_rating": "https://help.vika.cn/docs/guide/manual-field-rating", @@ -2205,7 +2330,7 @@ function main() { "field_help_single_text": "https://help.vika.cn/docs/guide/manual-field-single-line-text", "field_help_text": "https://help.vika.cn/docs/guide/manual-field-text", "field_help_url": "https://help.vika.cn/docs/guide/manual-field-url", - "field_help_button": "https://help.vika.cn/docs/guide/manual-field-button", + "field_help_workdoc": "https://help.vika.cn/docs/guide/manual-field-workdoc", "field_map_tips_for_python": "A field name exists that does not match the variable rules, please turn on \"Use FieldId\" or the code example below may not work! \n[Field Mapping](https://github.com/vikadata/vika.py#%E5%AD%97%E6%AE%B5%E6%98%A0%E5%B0%84) can help you to solve this problem.", "field_permission_help_url": "https://help.vika.cn/docs/guide/manual-field-permission", "field_select_modal_desc": "아래에서 선택한 필드가 편집된 경우 가장 최근에 편집한 구성원이 마지막으로 편집한 필드에 표시됩니다.", @@ -2300,7 +2425,7 @@ function main() { "login_title": "로그인 vikadata", "long_time_no_operate": "오랫동안 데이터시트를 운영하지 않았습니다. 페이지를 새로고침하여 데이터를 최신 상태로 유지하세요~", "lookup_field": "${datasheetName}에서 차원 행 선택", - "lookup_field_err": "먼저 Link 필드를 추가하십시오.", + "lookup_field_err": "먼저 링크 필드를 추가하세요.", "lookup_help": "https://help.vika.cn/docs/guide/manual-field-lookup", "lookup_not_found_search_keyword": "\"${notFoundSearchKeywordSpan}\"을(를) 포함하는 일치 항목이 없습니다.", "lookup_values_summary": "원래 값을 반환합니다.", @@ -2360,19 +2485,19 @@ function main() { "player_step_ui_config_97": "{\n\t\"vikaby\": {\n\t\t\"title\": \"Hello~\",\n\t\t\"description\": \"If you have a problem, you can contact me to help you\",\n\t\t\"list\": \"
  • Not sure how to use vikadata
  • What vikadata can do for me
  • Problems during use
  • What's new in the future
  • Get official invitation code
\",\n\t\t\"tip\": \"Scan the QR code to contact us\"\n\t},\n\t\"questionnaire\": {\n\t\t\"title\": \"Hello, I'm Vika's Digitalization Consultant\",\n\t\t\"list\": \"[{\\\"title\\\": \\\"Report bug\\\", \\\"icon\\\": \\\"BugOutlined\\\"}, {\\\"title\\\": \\\"Give feedback\\\", \\\"icon\\\": \\\"AdviseSmallOutlined\\\"}, {\\\"title\\\": \\\"Customer support\\\", \\\"icon\\\": \\\"ServeOutlined\\\"}, {\\\"title\\\": \\\"Case recommendation\\\", \\\"icon\\\": \\\"ZanOutlined\\\"}, {\\\"title\\\": \\\"Solutions\\\", \\\"icon\\\": \\\"SolutionSmallOutlined\\\"}, {\\\"title\\\": \\\"FAQs\\\", \\\"icon\\\": \\\"InformationLargeOutlined\\\"}]\",\n\t\t\"tip\": \"Please use WeChat to scan the code to add customer service to get more exclusive services\"\n\t},\n\t\"website\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/03/02/59f4cc8e0b2b4395bf0fcd133d208e63\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/03/02/defbf55d1e9646eb929f9f5d11d5c119\"\n\t},\n\t\"dingtalk\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/04/27/2c617a16afd9408ba48392e337fbbd7f?attname=20230427_dingtalk_questionnaire.png\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/04/27/2c617a16afd9408ba48392e337fbbd7f?attname=20230427_dingtalk_vikaby.png\",\n\"tip\": \"Please use DingTalk to scan the code to join our group\"\n\t},\n\t\"wecom\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/03/02/1346d5efbd5043efb2bfcba0075c0ee9\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/03/02/09401a8f2d8e491a9097b9bac8b5a4e4\"\n\t},\n\t\"feishu\": {\n\t\t\"title\": \"Scan the QR code to contact us\",\n\t\t\"tip\": \"Please use Lark to scan the code and add customer service for more help\",\n\t\t\"description\": \"So that you can get service at any time when you encounter problems during use\",\n\t\t\"originUrl\": \"https://u.vika.cn/z9ygm\"\n\t}\n}", "price_title1": "비카", "private_product_point": "나만의 APITable 즉시 가져오기", - "record_history_help_url": "https://help.vika.cn/docs/guide/manual-record-history", + "record_history_help_url": "https://help.vika.cn/docs/guide/manual-record-activity", "records_per_datasheet": "데이터시트당 레코드 수", "reset_password": "암호를 재설정", "retrieve_password": "비밀번호를 잊으 셨나요", "robot_config_help_url": "https://help.vika.cn/docs/guide/manual-automation-robot/#how-to-config-robot", - "robot_create_name_placeholder": "비카비 로봇", + "robot_create_name_placeholder": "Vikaby 자동화", "robot_help_url": "https://help.vika.cn/docs/guide/manual-automation-robot", - "robot_run_history_desc": "공개 베타 기간 동안 모든 실행 기록에 액세스할 수 있습니다 . 문제 해결", + "robot_run_history_desc": "공개 베타 기간 동안 모든 실행 기록에 액세스할 수 있습니다.", "robot_run_history_old_version_tip": "죄송합니다. 이 실행 기록은 세부 정보 보기를 지원하지 않는 이전 버전의 vikadata에서 가져온 것입니다.", "robot_trigger_record_created_config_1": "데이터시트 선택", - "robot_trigger_record_created_config_1_desc": "하나의 데이터시트 지정: 레코드가 생성되면 로봇이 실행을 시작합니다.", + "robot_trigger_record_created_config_1_desc": "하나의 데이터시트 지정: 레코드가 생성되면 자동화가 실행되기 시작합니다.", "robot_trigger_record_matches_condition_config_1": "데이터시트 선택", - "robot_trigger_record_matches_condition_config_1_desc": "하나의 데이터시트 지정: 레코드가 조건과 일치하면 로봇이 실행을 시작합니다.", + "robot_trigger_record_matches_condition_config_1_desc": "하나의 데이터시트 지정: 데이터시트의 레코드가 조건과 일치하면 자동화가 실행되기 시작합니다.", "robot_trigger_record_matches_condition_config_2_desc": "참고: 예약/마감 시간에 트리거할 날짜/수식 필드 추가는 지원되지 않습니다[FAQ](https://help.vika.cn/docs/guide/manual-automation-robot#robot-scene-related-faq).", "robot_variables_datasheet_ID": "데이터시트 ID", "robot_variables_datasheet_URL": "데이터시트 URL", @@ -2415,11 +2540,11 @@ function main() { "swagger_constants_desc": "이 강력한 데이터베이스-스프레드시트 하이브리드를 기반으로 눈 깜짝할 사이에 애플리케이션을 구축할 수 있도록 지원하는 그리드와 데이터시트 및 내장 API의 조합", "system_configuration_company_name_short": "vika", "system_configuration_product_name": "vikadata", - "table_link_err": "먼저 Link 필드를 추가하십시오.", + "table_link_err": "먼저 링크 필드를 추가하세요.", "task_reminder": "[알림] 귀하의 작업 \" \" 데이터시트에서 \" \"에 예정", "template_center_use_to_create_datasheets": "이 템플릿을 사용하여 데이터시트를 만듭니다.", "template_centre": "템플릿", - "test_function_card_info_robot": "Vika Robots는 데이터시트에서 반복 작업을 자동화하고 팀의 생산성을 자유롭게 해줍니다.", + "test_function_card_info_robot": "Vika Automation을 사용하면 데이터시트에서 반복적인 작업을 자동화하고 팀의 생산성을 높일 수 있습니다.", "these_columns_you_chose_would_be_deleted": "선택한 ${count} 필드가 삭제됩니다.", "timemachine_help_url": "https://help.vika.cn/docs/guide/manual-timemachine", "tip_setting_nickname_distribute": "\"${nickname}\"은 랜덤 닉네임~", @@ -2456,6 +2581,7 @@ function main() { "workbench_share_link_template": "vikadata에서: ${nickName}님이 \"${nodeName}\" 파일을 귀하와 공유했습니다." },'ru-RU': { "account_password_incorrect": "Неверный аккаунт или пароль", + "action_execute_error": "Ошибка выполнения шага. Сообщение об ошибке: ${value}. Подробную информацию см. в https://help.vika.cn/docs/guide/manual-automation-robot#how-to-troubleshoot.", "activity_login_desc": "", "add_gallery_view_success_guide": "Для таблицы данных с изображениями вид галереи будет отображаться очень интуитивно. На подходе много интересных функций. Оставайтесь с нами~", "all_editable_fields": "Все редактируемые поля", @@ -2480,6 +2606,23 @@ function main() { "assistant_hide": "Скрыть Викаби", "audit_add_field_role_detail": "english", "auth_server_extensions_login_description_content": "Единая страница входа Vikadata", + "backup_action_delete": "Удалить снимок", + "backup_action_recover": "Восстанавливаться", + "backup_create": "Создать снимок", + "backup_create_success": "Снимок успешно создан", + "backup_create_time": "Создать время", + "backup_creating": "Создание", + "backup_delete_text": "После удаления его невозможно восстановить. Вы уверены, что хотите это удалить?", + "backup_delete_title": "Удалить снимок", + "backup_deleted": "Удалено", + "backup_expired_time": "Истекает время", + "backup_name_success_update": "Успешно Обновлено", + "backup_recover_dst_name_suffix": "Восстанавливаться", + "backup_recover_modal_text": "Выберите, куда поместить снимок", + "backup_recover_success": "Успешно восстановлено", + "backup_recover_title": "Восстанавливаться", + "backup_success_delete": "Снимок успешно удален", + "backup_title": "Снимок", "bind_resource": "Выберите таблицу для ссылки на", "bronze_grade": "Бронза", "bronze_grade_desc": "For individuals or teams who are new to APITable\n", @@ -2489,7 +2632,7 @@ function main() { "change_password_success": "Сброс пароля успешно", "chart_widget_setting_help_url": "https://help.vika.cn/docs/guide/intro-widget-chart", "check_link_table": "Выберите таблицу для ссылки на", - "check_table_link_field": "Выберите поле Link", + "check_table_link_field": "Выберите поле ссылки", "choose_datasheet_to_link": "Выберите таблицу для ссылки на", "client_meta_label_desc": "vikadata — платформа для повышения производительности данных, которая поможет вам более эффективно управлять своими рабочими данными.", "client_meta_label_title": "vikadata — платформа для продуктивной работы с данными", @@ -2512,6 +2655,7 @@ function main() { "delete_field_tips_content": "Вы уверены, что хотите удалить поле \"${field_title}\"?", "delete_field_tips_title": "Удалить поле", "edit_field_name": "Изменить имя поля", + "embed_link_default_link_url": "https://help.vika.cn/docs/guide/manual-custom-page", "empty_datasheet": "Новое техническое описание", "err_field_group_tip": "Обнаружена ошибка в настройках поля. Группировка временно не работает.", "err_filter_field": "Невозможно добавить это поле в качестве фильтра из-за ошибок конфигурации поля.", @@ -2526,6 +2670,7 @@ function main() { "field_had_deleted": "Это поле было удалено", "field_help_attachment": "https://help.vika.cn/docs/guide/manual-field-attachment", "field_help_autonumber": "https://help.vika.cn/docs/guide/manual-autonumber", + "field_help_button": "нулевой", "field_help_cascader": "https://help.vika.cn/docs/guide/manual-field-cascader", "field_help_checkbox": "https://help.vika.cn/docs/guide/manual-field-checkbox", "field_help_created_by": "https://help.vika.cn/docs/guide/manual-createdby", @@ -2538,12 +2683,12 @@ function main() { "field_help_last_modified_by": "https://help.vika.cn/docs/guide/manual-lastmodifiedby", "field_help_last_modified_time": "https://help.vika.cn/docs/guide/manual-lastmodifiedtime", "field_help_link": "https://help.vika.cn/docs/guide/manual-field-link", - "field_help_one_way_link": "https://help.vika.cn/docs/guide/manual-field-link", "field_help_lookup": "https://help.vika.cn/docs/guide/manual-field-lookup", "field_help_member": "https://help.vika.cn/docs/guide/manual-filed-member", "field_help_member_property_subscription": "https://help.vika.cn/docs/guide/manual-filed-member", "field_help_multi_select": "https://help.vika.cn/docs/guide/manual-field-select", "field_help_number": "https://help.vika.cn/docs/guide/manual-field-number", + "field_help_one_way_link": "https://help.vika.cn/docs/guide/manual-field-link", "field_help_percent": "https://help.vika.cn/docs/guide/manual-field-percent", "field_help_phone": "https://help.vika.cn/docs/guide/manual-field-phone", "field_help_rating": "https://help.vika.cn/docs/guide/manual-field-rating", @@ -2551,7 +2696,7 @@ function main() { "field_help_single_text": "https://help.vika.cn/docs/guide/manual-field-single-line-text", "field_help_text": "https://help.vika.cn/docs/guide/manual-field-text", "field_help_url": "https://help.vika.cn/docs/guide/manual-field-url", - "field_help_button": "https://help.vika.cn/docs/guide/manual-field-button", + "field_help_workdoc": "https://help.vika.cn/docs/guide/manual-field-workdoc", "field_map_tips_for_python": "A field name exists that does not match the variable rules, please turn on \"Use FieldId\" or the code example below may not work! \n[Field Mapping](https://github.com/vikadata/vika.py#%E5%AD%97%E6%AE%B5%E6%98%A0%E5%B0%84) can help you to solve this problem.", "field_permission_help_url": "https://help.vika.cn/docs/guide/manual-field-permission", "field_select_modal_desc": "Если какое-либо из полей, выбранных вами ниже, редактируется, участник, редактировавший последним, будет отображаться в поле, которое редактировалось последним.", @@ -2646,7 +2791,7 @@ function main() { "login_title": "Войти", "long_time_no_operate": "Даташит давно не эксплуатировался, пожалуйста, обновите страницу, чтобы данные были актуальными~", "lookup_field": "Выберите строку параметра из ${datasheetName}", - "lookup_field_err": "Сначала добавьте поле Link", + "lookup_field_err": "Сначала добавьте поле «Ссылка»", "lookup_help": "https://help.vika.cn/docs/guide/manual-field-lookup", "lookup_not_found_search_keyword": "Нет совпадений, содержащих \"${notFoundSearchKeywordSpan}\"", "lookup_values_summary": "Возвращает исходные значения", @@ -2706,19 +2851,19 @@ function main() { "player_step_ui_config_97": "{\n\t\"vikaby\": {\n\t\t\"title\": \"Hello~\",\n\t\t\"description\": \"If you have a problem, you can contact me to help you\",\n\t\t\"list\": \"
  • Not sure how to use vikadata
  • What vikadata can do for me
  • Problems during use
  • What's new in the future
  • Get official invitation code
\",\n\t\t\"tip\": \"Scan the QR code to contact us\"\n\t},\n\t\"questionnaire\": {\n\t\t\"title\": \"Hello, I'm Vika's Digitalization Consultant\",\n\t\t\"list\": \"[{\\\"title\\\": \\\"Report bug\\\", \\\"icon\\\": \\\"BugOutlined\\\"}, {\\\"title\\\": \\\"Give feedback\\\", \\\"icon\\\": \\\"AdviseSmallOutlined\\\"}, {\\\"title\\\": \\\"Customer support\\\", \\\"icon\\\": \\\"ServeOutlined\\\"}, {\\\"title\\\": \\\"Case recommendation\\\", \\\"icon\\\": \\\"ZanOutlined\\\"}, {\\\"title\\\": \\\"Solutions\\\", \\\"icon\\\": \\\"SolutionSmallOutlined\\\"}, {\\\"title\\\": \\\"FAQs\\\", \\\"icon\\\": \\\"InformationLargeOutlined\\\"}]\",\n\t\t\"tip\": \"Please use WeChat to scan the code to add customer service to get more exclusive services\"\n\t},\n\t\"website\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/03/02/59f4cc8e0b2b4395bf0fcd133d208e63\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/03/02/defbf55d1e9646eb929f9f5d11d5c119\"\n\t},\n\t\"dingtalk\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/04/27/2c617a16afd9408ba48392e337fbbd7f?attname=20230427_dingtalk_questionnaire.png\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/04/27/2c617a16afd9408ba48392e337fbbd7f?attname=20230427_dingtalk_vikaby.png\",\n\"tip\": \"Please use DingTalk to scan the code to join our group\"\n\t},\n\t\"wecom\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/03/02/1346d5efbd5043efb2bfcba0075c0ee9\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/03/02/09401a8f2d8e491a9097b9bac8b5a4e4\"\n\t},\n\t\"feishu\": {\n\t\t\"title\": \"Scan the QR code to contact us\",\n\t\t\"tip\": \"Please use Lark to scan the code and add customer service for more help\",\n\t\t\"description\": \"So that you can get service at any time when you encounter problems during use\",\n\t\t\"originUrl\": \"https://u.vika.cn/z9ygm\"\n\t}\n}", "price_title1": "Вика", "private_product_point": "Получите свою собственную APITable немедленно", - "record_history_help_url": "https://help.vika.cn/docs/guide/manual-record-history", + "record_history_help_url": "https://help.vika.cn/docs/guide/manual-record-activity", "records_per_datasheet": "Количество записей в таблице данных", "reset_password": "Сброс пароля", "retrieve_password": "Забыли пароль", "robot_config_help_url": "https://help.vika.cn/docs/guide/manual-automation-robot/#how-to-config-robot", - "robot_create_name_placeholder": "Викаби Робот", + "robot_create_name_placeholder": "Викаби Автоматизация", "robot_help_url": "https://help.vika.cn/docs/guide/manual-automation-robot", - "robot_run_history_desc": "У вас есть доступ ко всей истории запусков во время общедоступной бета-версии . Устранение неполадок.", + "robot_run_history_desc": "У вас есть доступ ко всей истории запусков во время публичной бета-версии . Устранение неполадок.", "robot_run_history_old_version_tip": "Извините, эта история запусков была из старой версии vikadata, которая не поддерживает просмотр сведений.", "robot_trigger_record_created_config_1": "Выберите таблицу данных", - "robot_trigger_record_created_config_1_desc": "Укажите один даташит: Когда в нем будет создана запись, робот запустится", + "robot_trigger_record_created_config_1_desc": "Укажите одну таблицу данных: при создании в ней записи запускается автоматизация.", "robot_trigger_record_matches_condition_config_1": "Выберите таблицу данных", - "robot_trigger_record_matches_condition_config_1_desc": "Укажите один лист данных: когда запись в нем соответствует условию, робот начинает работать", + "robot_trigger_record_matches_condition_config_1_desc": "Укажите одну таблицу данных: если запись в ней соответствует условию, запускается автоматизация.", "robot_trigger_record_matches_condition_config_2_desc": "Примечание. Добавление поля «Дата/формула» для срабатывания в запланированное время не поддерживается [Часто задаваемые вопросы] (https://help.vika.cn/docs/guide/manual-automation-robot#robot-scene-related-faq)", "robot_variables_datasheet_ID": "Идентификатор таблицы", "robot_variables_datasheet_URL": "URL-адрес таблицы данных", @@ -2761,11 +2906,11 @@ function main() { "swagger_constants_desc": "Сочетание сетки, таблицы данных и встроенного API, помогающее вам мгновенно создать приложение на основе этого мощного гибрида базы данных и электронной таблицы.", "system_configuration_company_name_short": "vika", "system_configuration_product_name": "vikadata", - "table_link_err": "Сначала добавьте поле Link", + "table_link_err": "Сначала добавьте поле «Ссылка»", "task_reminder": "[Напоминание] Ваша задача » \"в даташите\" \"будет в", "template_center_use_to_create_datasheets": "Используйте этот шаблон для создания таблиц данных.", "template_centre": "Шаблоны", - "test_function_card_info_robot": "Роботы Vika помогут вам автоматизировать повторяющиеся действия в таблицах данных и повысить производительность вашей команды.", + "test_function_card_info_robot": "Vika Automation поможет вам автоматизировать повторяющиеся действия в таблицах данных и повысить производительность вашей команды.", "these_columns_you_chose_would_be_deleted": "Выбранные поля (${count}) будут удалены.", "timemachine_help_url": "https://help.vika.cn/docs/guide/manual-timemachine", "tip_setting_nickname_distribute": "\"${nickname}\" — это случайное прозвище~", @@ -2819,7 +2964,7 @@ function main() { "app_launch_guide_text_1": "千人同时操作一张维格表,高效实时协同", "assistant": "维格小助手", "assistant_beginner_task_1_what_is_datasheet": "什么是维格云", - "assistant_beginner_task_2_quick_start": "一分钟快速入门", + "assistant_beginner_task_2_quick_start": "VIKA产品演示", "assistant_beginner_task_3_how_to_use_datasheet": "玩转一张维格表", "assistant_beginner_task_title1": "欢迎来到维格云", "assistant_beginner_task_title2": "跟着指引开始你的维格之旅吧~", @@ -3053,7 +3198,7 @@ function main() { "player_step_ui_config_97": "{\n\t\"vikaby\": {\n\t\t\"title\": \"你好\",\n\t\t\"description\": \"如果在使用过程中遇到问题,请扫描右侧二维码联系我解决\",\n\t\t\"list\": \"
  • 刚注册维格云,不知道怎么用
  • 维格云可以实现我想要的效果吗
  • 使用过程出现异常问题
  • 后续支持的功能有哪些
  • 获取官方邀请码
\",\n\t\t\"tip\": \"扫码添加客服\"\n\t},\n\t\"questionnaire\": {\n\t\t\"title\": \"您好,我是维格云数字化顾问\",\n\t\t\"list\": \"[{\\\"title\\\": \\\"Bug 吐槽\\\", \\\"icon\\\": \\\"BugOutlined\\\"}, {\\\"title\\\": \\\"需求反馈\\\", \\\"icon\\\": \\\"AdviseSmallOutlined\\\"}, {\\\"title\\\": \\\"服务支持\\\", \\\"icon\\\": \\\"ServeOutlined\\\"}, {\\\"title\\\": \\\"案例推荐\\\", \\\"icon\\\": \\\"ZanOutlined\\\"}, {\\\"title\\\": \\\"解决方案\\\", \\\"icon\\\": \\\"SolutionSmallOutlined\\\"}, {\\\"title\\\": \\\"产品答疑\\\", \\\"icon\\\": \\\"InformationLargeOutlined\\\"}]\",\n\t\t\"tip\": \"扫码添加微信,获得更多专属服务\"\n\t},\n\t\"website\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/03/02/59f4cc8e0b2b4395bf0fcd133d208e63\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/03/02/defbf55d1e9646eb929f9f5d11d5c119\"\n\t},\n\t\"dingtalk\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/04/27/2c617a16afd9408ba48392e337fbbd7f?attname=20230427_dingtalk_questionnaire.png\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/04/27/2c617a16afd9408ba48392e337fbbd7f?attname=20230427_dingtalk_vikaby.png\",\n\"tip\": \"请使用钉钉扫码,加入交流群\"\n\t},\n\t\"wecom\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/03/02/1346d5efbd5043efb2bfcba0075c0ee9\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/03/02/09401a8f2d8e491a9097b9bac8b5a4e4\"\n\t},\n\t\"feishu\": {\n\t\t\"title\": \"扫码添加客服\",\n\t\t\"tip\": \"请使用飞书扫码,添加客服号备用\",\n\t\t\"description\": \"以便使用过程中遇到问题,可以随时获得服务和解答\",\n\t\t\"originUrl\": \"https://u.vika.cn/z9ygm\"\n\t}\n}", "price_title1": "vika维格表", "private_product_point": "一键拥有自己的维格表平台", - "record_history_help_url": "https://help.vika.cn/docs/guide/manual-record-history", + "record_history_help_url": "https://help.vika.cn/docs/guide/manual-record-activity", "records_per_datasheet": "单维格表行数", "reset_password": "重置密码", "retrieve_password": "忘记密码", @@ -3135,7 +3280,7 @@ function main() { "vikaby_todo_menu1": "什么是维格云", "vikaby_todo_tip1": "欢迎来到维格云", "welcome_module1": "什么是维格云", - "welcome_module2": "一分钟快速入门", + "welcome_module2": "VIKA产品演示", "welcome_module3": "玩转一张维格表", "welcome_module4": "PMO项目群管理", "welcome_module5": "服装批发进销存", @@ -3149,6 +3294,8 @@ function main() { "workbench_share_link_template": "【维格云】- ${nickName}给你分享了《${nodeName}》", "backup_creating": "创建中", "backup_deleted": "已删除", + "backup_create_time": "创建时间", + "backup_expired_time": "过期时间", "backup_title": "版本历史", "backup_create": "创建版本", "backup_create_success": "已创建版本, 可以在时光机中查看", @@ -3163,9 +3310,13 @@ function main() { "backup_action_recover": "还原", "backup_action_delete": "删除版本", "pre_fill_help": "https://help.vika.cn/docs/guide/faq-form-pre-fill", - "action_execute_error": "执行失败\n错误信息:\n${value}\n\n了解详细信息可以参考:https://help.vika.cn/docs/guide/manual-automation-robot#how-to-troubleshoot" + "action_execute_error": "执行失败\n错误信息:\n${value}\n\n了解详细信息可以参考:https://help.vika.cn/docs/guide/manual-automation-robot#how-to-troubleshoot", + "embed_link_default_link_url": "https://help.vika.cn/docs/guide/manual-custom-page", + "embed_page_doc_url": "https://help.vika.cn/docs/guide/manual-custom-page", + "private_help_link": "https://help.vika.cn/docs/guide/team-and-private-area#private-area" },'zh-HK': { "account_password_incorrect": "帳號或密碼錯誤", + "action_execute_error": "步驟執行錯誤 錯誤訊息:${value} 詳情請參考https://help.vika.cn/docs/guide/manual-automation-robot#how-to-troubleshoot", "activity_login_desc": "", "add_gallery_view_success_guide": "對於帶有圖片的維格表,相冊視圖可以很直觀的展示你的數據。另外,維格表還有更多有趣的功能正在迭代,敬請期待~", "all_editable_fields": "所有可編輯的維格列", @@ -3190,6 +3341,23 @@ function main() { "assistant_hide": "取消懸浮", "audit_add_field_role_detail": "在「」維格表中,對字段 []添加 []的角色為 []", "auth_server_extensions_login_description_content": "維格統一登錄頁", + "backup_action_delete": "刪除快照", + "backup_action_recover": "恢復", + "backup_create": "建立快照", + "backup_create_success": "快照創建成功", + "backup_create_time": "創造時間", + "backup_creating": "創造", + "backup_delete_text": "刪除後,無法恢復。你確定要刪除嗎?", + "backup_delete_title": "刪除快照", + "backup_deleted": "已刪除", + "backup_expired_time": "過期時間", + "backup_name_success_update": "更新成功", + "backup_recover_dst_name_suffix": "恢復", + "backup_recover_modal_text": "選擇放置快照的位置", + "backup_recover_success": "恢復成功", + "backup_recover_title": "恢復", + "backup_success_delete": "快照刪除成功", + "backup_title": "快照", "bind_resource": "請選擇要關聯的維格表", "bronze_grade": "青銅級", "bronze_grade_desc": "適用於剛上手維格表的個人或團隊", @@ -3199,7 +3367,7 @@ function main() { "change_password_success": "修改密碼成功", "chart_widget_setting_help_url": "https://help.vika.cn/docs/guide/intro-widget-chart", "check_link_table": "請選擇要關聯的維格表", - "check_table_link_field": "請選擇「關聯」維格列", + "check_table_link_field": "選擇連結字段", "choose_datasheet_to_link": "請選擇要關聯的維格表", "client_meta_label_desc": "維格雲, 積木式多媒體數據表格, 維格表技術首創者, 數據整理神器, 讓人人都是數據設計師", "client_meta_label_title": "維格雲 - 積木式多媒體數據表格", @@ -3222,6 +3390,7 @@ function main() { "delete_field_tips_content": "確定刪除維格列「${field_title}」嗎?", "delete_field_tips_title": "刪除維格列", "edit_field_name": "編輯維格列名", + "embed_link_default_link_url": "https://help.vika.cn/docs/guide/manual-custom-page", "empty_datasheet": "新建空白維格表", "err_field_group_tip": "維格列配置錯誤,暫不支持分組", "err_filter_field": "該維格列存在配置錯誤,暫不支持設置為篩選", @@ -3236,6 +3405,7 @@ function main() { "field_had_deleted": "該維格列已被刪除", "field_help_attachment": "https://help.vika.cn/docs/guide/manual-field-attachment", "field_help_autonumber": "https://help.vika.cn/docs/guide/manual-autonumber", + "field_help_button": "無效的", "field_help_cascader": "https://help.vika.cn/docs/guide/manual-field-cascader", "field_help_checkbox": "https://help.vika.cn/docs/guide/manual-field-checkbox", "field_help_created_by": "https://help.vika.cn/docs/guide/manual-createdby", @@ -3248,12 +3418,12 @@ function main() { "field_help_last_modified_by": "https://help.vika.cn/docs/guide/manual-lastmodifiedby", "field_help_last_modified_time": "https://help.vika.cn/docs/guide/manual-lastmodifiedtime", "field_help_link": "https://help.vika.cn/docs/guide/manual-field-link", - "field_help_one_way_link": "https://help.vika.cn/docs/guide/manual-field-link", "field_help_lookup": "https://help.vika.cn/docs/guide/manual-field-lookup", "field_help_member": "https://help.vika.cn/docs/guide/manual-filed-member", "field_help_member_property_subscription": "https://help.vika.cn/docs/guide/manual-filed-member", "field_help_multi_select": "https://help.vika.cn/docs/guide/manual-field-select", "field_help_number": "https://help.vika.cn/docs/guide/manual-field-number", + "field_help_one_way_link": "https://help.vika.cn/docs/guide/manual-field-link", "field_help_percent": "https://help.vika.cn/docs/guide/manual-field-percent", "field_help_phone": "https://help.vika.cn/docs/guide/manual-field-phone", "field_help_rating": "https://help.vika.cn/docs/guide/manual-field-rating", @@ -3261,7 +3431,7 @@ function main() { "field_help_single_text": "https://help.vika.cn/docs/guide/manual-field-single-line-text", "field_help_text": "https://help.vika.cn/docs/guide/manual-field-text", "field_help_url": "https://help.vika.cn/docs/guide/manual-field-url", - "field_help_button": "https://help.vika.cn/docs/guide/manual-field-button", + "field_help_workdoc": "https://help.vika.cn/docs/guide/manual-field-workdoc", "field_map_tips_for_python": "存在與變量規則不匹配的字段名稱,請打開“使用 Field ID”,否則下面的代碼示例可能無法運行![字段映射](https://github.com/vikadata/vika.py#%E5%AD%97%E6%AE%B5%E6%98%A0%E5%B0%84)可以幫你解決這個問題。", "field_permission_help_url": "https://help.vika.cn/docs/guide/manual-field-permission", "field_select_modal_desc": "由於該維格列類型的特殊性,下方只展示可編輯的列,每當有人在指定的列進行過修改,則會更新當前的修改人", @@ -3356,7 +3526,7 @@ function main() { "login_title": "進入維格雲", "long_time_no_operate": "該維格表已經很久未操作,請刷新頁面保持數據為最新~", "lookup_field": "從下方維格表中選擇維格列", - "lookup_field_err": "請先在當前維格表添加一個「關聯」列", + "lookup_field_err": "請先加入連結字段", "lookup_help": "https://help.vika.cn/docs/guide/manual-field-lookup", "lookup_not_found_search_keyword": "沒有找到包含\"${notFoundSearchKeywordSpan}\"的維格列", "lookup_values_summary": "從關聯表中原樣引用選定維格列的數據。", @@ -3416,19 +3586,19 @@ function main() { "player_step_ui_config_97": "{\n\t\"vikaby\": {\n\t\t\"title\": \"你好\",\n\t\t\"description\": \"如果在使用過程中遇到問題,請掃描右側二維碼聯繫我解決\",\n\t\t\"list\": \"
  • 剛註冊維格雲,不知道怎麼用
  • 維格雲可以實現我想要的效果嗎
  • 使用過程出現異常問題
  • 後續支持的功能有哪些
  • 獲取官方邀請碼
\",\n\t\t\"tip\": \"掃碼添加客服\"\n\t},\n\t\"questionnaire\": {\n\t\t\"title\": \"您好,我是維格雲數字化顧問\",\n\t\t\"list\": \"[{\\\"title\\\": \\\"Bug 吐槽\\\", \\\"icon\\\": \\\"BugOutlined\\\"}, {\\\"title\\\": \\\"需求反饋\\\", \\\"icon\\\": \\\"AdviseSmallOutlined\\\"}, {\\\"title\\\": \\\"服務支持\\\", \\\"icon\\\": \\\"ServeOutlined\\\"}, {\\\"title\\\": \\\"案例推薦\\\", \\\"icon\\\": \\\"ZanOutlined\\\"}, {\\\"title\\\": \\\"解決方案\\\", \\\"icon\\\": \\\"SolutionSmallOutlined\\\"}, {\\\"title\\\": \\\"產品答疑\\\", \\\"icon\\\": \\\"InformationLargeOutlined\\\"}]\",\n\t\t\"tip\": \"掃碼添加微信,獲得更多專屬服務\"\n\t},\n\t\"website\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/03/02/59f4cc8e0b2b4395bf0fcd133d208e63\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/03/02/defbf55d1e9646eb929f9f5d11d5c119\"\n\t},\n\t\"dingtalk\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/04/27/2c617a16afd9408ba48392e337fbbd7f?attname=20230427_dingtalk_questionnaire.png\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/04/27/2c617a16afd9408ba48392e337fbbd7f?attname=20230427_dingtalk_vikaby.png\",\n\"tip\": \"請使用釘釘掃碼,加入交流群\"\n\t},\n\t\"wecom\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/03/02/1346d5efbd5043efb2bfcba0075c0ee9\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/03/02/09401a8f2d8e491a9097b9bac8b5a4e4\"\n\t},\n\t\"feishu\": {\n\t\t\"title\": \"掃碼添加客服\",\n\t\t\"tip\": \"請使用飛書掃碼,添加客服號備用\",\n\t\t\"description\": \"以便使用過程中遇到問題,可以隨時獲得服務和解答\",\n\t\t\"originUrl\": \"https://u.vika.cn/z9ygm\"\n\t}\n}", "price_title1": "vika維格表", "private_product_point": "立即獲取您自己的 APITable", - "record_history_help_url": "https://help.vika.cn/docs/guide/manual-record-history", + "record_history_help_url": "https://help.vika.cn/docs/guide/manual-record-activity", "records_per_datasheet": "單維格表行數", "reset_password": "重置密碼", "retrieve_password": "忘記密碼", "robot_config_help_url": "https://help.vika.cn/docs/guide/manual-automation-robot/#how-to-config-robot", "robot_create_name_placeholder": "維卡比·羅伯特", "robot_help_url": "https://help.vika.cn/docs/guide/manual-automation-robot", - "robot_run_history_desc": "公測期間,你可以看到該機器人所有的運行歷史 如何排查問題", + "robot_run_history_desc": "您可以在公開測試版期間存取所有運行歷史記錄 疑難排解", "robot_run_history_old_version_tip": "抱歉,此為舊版本下的運行歷史,不支持查看輸入輸出", "robot_trigger_record_created_config_1": "選擇維格表", - "robot_trigger_record_created_config_1_desc": "指定在哪張維格表有記錄創建時,觸發機器人開始運行(目前只支持選擇當前表)", + "robot_trigger_record_created_config_1_desc": "指定一個資料表:在其中建立記錄時,自動化開始運行", "robot_trigger_record_matches_condition_config_1": "選擇維格表", - "robot_trigger_record_matches_condition_config_1_desc": "指定在哪張維格表有記錄滿足條件時,觸發機器人開始運行(目前只支持選擇當前表)", + "robot_trigger_record_matches_condition_config_1_desc": "指定一個資料表:當其中的一筆記錄符合條件時,自動化開始運行", "robot_trigger_record_matches_condition_config_2_desc": "注意:不支持在匹配條件中添加日期列或者包含日期函數的公式列來實現定時觸發或到期觸發 [FAQ 參考](https://help.vika.cn/docs/guide/manual-automation-robot#robot-scene-related-faq)", "robot_variables_datasheet_ID": "維格表 ID", "robot_variables_datasheet_URL": "維格表 URL", @@ -3471,11 +3641,11 @@ function main() { "swagger_constants_desc": "格表融合開放 API 文檔,幫助你基於強大的維格表數據庫快速構建應用", "system_configuration_company_name_short": "vika", "system_configuration_product_name": "維格表", - "table_link_err": "請先在當前維格表添加一個「關聯」列", + "table_link_err": "請先加入連結字段", "task_reminder": "你在「」維格表中的事項「」的到期時間為,請及時處理", "template_center_use_to_create_datasheets": "使用模板創建維格表", "template_centre": "維格模板中心", - "test_function_card_info_robot": "使用機器人,將維格表中的重複性操作自動化,解放員工生產力", + "test_function_card_info_robot": "Vika Automation 可協助您自動執行資料表中的重複操作並釋放團隊的生產力", "these_columns_you_chose_would_be_deleted": "你所選中的 ${count} 個維格列將會被刪除", "timemachine_help_url": "https://help.vika.cn/docs/guide/manual-timemachine", "tip_setting_nickname_distribute": "「${nickname}」是我們維格星球裡面為你分配的隨機暱稱~", diff --git a/packages/datasheet/public/file/langs/strings.ar-SA.json b/packages/datasheet/public/file/langs/strings.ar-SA.json index 97dd583e95..679210d286 100644 --- a/packages/datasheet/public/file/langs/strings.ar-SA.json +++ b/packages/datasheet/public/file/langs/strings.ar-SA.json @@ -3105,7 +3105,7 @@ "nvc_start_text": "سحب شريط الرسم البياني إلى اليمين", "nvc_yes_text": "ثبت", "obtain_verification_code": "رمز التحقق لم يتم الحصول عليها أو منتهية الصلاحية", - "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrzw0miJVmSkJ7eBBa9k/fomx5qPX0JGPFvfEEP\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", + "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrCvbFC53xc3kl00B4Pg\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", "offical_website_nav_data": "[{\n \"name\": \"产品\",\n \"href\": \"/login\",\n \"children\": [\n {\n \"name\": \"vika维格表 Overview\",\n \"href\": \"/login/\"\n },\n {\n \"name\": \"应用连接 Integration\",\n \"href\": \"/connections/\"\n },\n {\n \"name\": \"客户端(Beta) Download\",\n \"href\": \"/download/\"\n }\n ]\n}, {\n \"name\": \"解决方案\",\n \"href\": \"/\",\n \"children\": [{\n \"name\": \"PMO项目群管理\",\n \"href\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"href\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"href\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"href\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"href\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"href\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"href\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"href\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"href\": \"/shop/\"\n }, {\n \"name\": \"更多解决方案 >\",\n \"href\": \"/solutions/\"\n }]\n}, {\n \"name\": \"模板/案例\",\n \"href\": \"/template\",\n \"children\": [\n {\n \"name\": \"模板中心 Tempaltes\",\n \"href\": \"/template\"\n },\n {\n \"name\": \"客户案例 Customers\",\n \"href\": \"/cases/\"\n }\n ]\n},\n {\n \"name\": \"首页\",\n \"href\": \"/?home=1\"\n },\n {\n \"name\": \"学习资源\",\n \"href\": \"https://edu.vika.cn/index\",\n \"children\": [\n {\n \"name\": \"快速入门 Tutorials\",\n \"href\": \"https://help.vika.cn/docs/guide/tutorial\"\n },\n {\n \"name\": \"产品手册 Manual\",\n \"href\": \"https://help.vika.cn/docs/guide/manual\"\n },\n {\n \"name\": \"维格课堂 Vika Education\",\n \"href\": \"https://edu.vika.cn/\"\n },\n {\n \"name\": \"维格社区 Vika BBS\",\n \"href\": \"https://bbs.vika.cn/\"\n },\n {\n \"name\": \"第三方连接 Integration\",\n \"href\": \"https://help.vika.cn/docs/guide/connection\"\n },\n {\n \"name\": \"开发者中心 Developer Center\",\n \"href\": \"/developers/\"\n },\n {\n \"name\": \"常见问题 FAQ\",\n \"href\": \"https://help.vika.cn/docs/guide/questions\"\n }\n ]\n }]", "office_preview": "معاينة الملفات المكتبية", "office_preview_app_desc": "

Smooth online preview of office files on datasheet, allowing you to view common office files such as Excel, Word, PPT, etc. on your desktop or mobile anywhere, anytime

\n\n
    \n
  • Online preview of .doc, .docx, .xls, .xlsx, .ppt, .pptx, and .pdf formatted office files
  • \n
  • Desktop and mobile both support file previews of the above formats
  • \n
\n\n

Additional notes:

\n
    \n
  • This feature is powered by \"Yoncentric Cloud Conversion\" and officially integrated
  • \n
  • Click the \"Enable\" button below to enable this integration and agree that \"Yoncentric Cloud Conversion\" reads the office files you want to preview
  • \n
  • If you no longer need the office files preview feature, the space admin can disable it on this page
  • \n
", @@ -3481,13 +3481,13 @@ "player_step_ui_config_41": "", "player_step_ui_config_42": "{\n \"element\": \"#DATASHEET_FORM_LIST_PANEL\", \n\"placement\": \"leftTop\",\n \"title\": \"Form\", \n\"description\": \"You can quickly create a form from the current view. The number and order of the fields in the form is consistent with the view.\", \"children\":\"\" \n}", "player_step_ui_config_43": "{\n \"element\": \".style_navigation__1U5cR .style_help__1sXEA\", \n\"placement\": \"rightBottom\",\n \"title\": \"Tip\", \n\"offsetY\":5,\n\"description\": \"You can find your Vikaby assistant from the \"Help\" icon on the left\", \"children\":\"\" \n}", - "player_step_ui_config_44": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", + "player_step_ui_config_44": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", "player_step_ui_config_45": "", "player_step_ui_config_46": "", "player_step_ui_config_47": "{\n \"element\": \"#DATASHEET_WIDGET_BTN\",\n\"placement\": \"bottomRight\",\n \"title\": \"Widget\", \n\"description\": \"Want to use and view your data in a richer way? Try the widget!\", \"children\":\"\" \n}", "player_step_ui_config_48": "", "player_step_ui_config_49": "{\n \"element\": \".style_widgetPanelContainer__1l2ZV\",\n\"placement\": \"leftCenter\",\n \"title\": \"What is a widget\", \n\"description\": \"Vika widgets are an extended application of vikadata that features in richer data visualization, data transfer, data cleansing, and more. By installing widgets in the widget board, you can make work a lot easier.\", \"children\":\"\" \n}", - "player_step_ui_config_5": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", + "player_step_ui_config_5": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", "player_step_ui_config_50": "{\n \"element\": \".style_widgetModal__eXmdB\",\n\"placement\": \"leftTop\",\n \"title\": \"Widget Center\", \n\"description\": \"Officially recommended and custom widgets are published here. You can install any widget you want onto a dashboard or into a widget board of any datasheet.\", \"children\":\"\" \n}", "player_step_ui_config_51": "{\n \"element\": \".style_widgetModal__eXmdB .style_widgetItem__3Pl-1 button\",\n\"placement\": \"rightBottom\",\n \"title\": \"Install widget\", \n\"description\": \"Let's install this \"Chart\" widget\", \"children\":\"\" \n}", "player_step_ui_config_52": "", @@ -3682,7 +3682,7 @@ "record_filter_tips": "تم تصفية هذا السجل", "record_functions": "وظيفة تسجيل", "record_history": "مراجعة التاريخ فقط", - "record_history_help_url": "https://help.apitable.com/docs/guide/manual-record-history", + "record_history_help_url": "https://help.apitable.com/docs/guide/manual-record-activity", "record_history_title": "سجل التاريخ", "record_pre_filtered": "هذا السجل قد تم تصفيتها ، وسوف تكون مخفية عند النقر فوق خارج السجل .", "record_pre_move": "بعد النقر فوق خارج السجل ، سيتم نقل هذا السجل إلى موقع آخر", diff --git a/packages/datasheet/public/file/langs/strings.de-DE.json b/packages/datasheet/public/file/langs/strings.de-DE.json index a09640c97a..5dff7eed2d 100644 --- a/packages/datasheet/public/file/langs/strings.de-DE.json +++ b/packages/datasheet/public/file/langs/strings.de-DE.json @@ -146,6 +146,15 @@ "agreed": "Genehmigt", "ai_advanced_mode_desc": "Der erweiterte Modus ermöglicht es Benutzern, Prognosen anzupassen, wodurch das Verhalten und die Antworten des AI-Agenten stärker kontrolliert werden kann.", "ai_advanced_mode_title": "Erweiterter Modus", + "ai_agent_anonymous": "Anonym${ID}", + "ai_agent_conversation_continue_not_supported": "Das Fortsetzen eines vorherigen Gesprächs wird derzeit nicht unterstützt", + "ai_agent_conversation_list": "Gesprächsliste", + "ai_agent_conversation_log": "Gesprächsprotokoll", + "ai_agent_conversation_title": "Gesprächstitel", + "ai_agent_feedback": "Rückmeldung", + "ai_agent_historical_message": "Das Obige ist eine historische Botschaft", + "ai_agent_history": "Geschichte", + "ai_agent_message_consumed": "Nachricht verbraucht", "ai_api_curl_template": "## Create chat completions\n\n```bash\n\ncurl -X POST \"{{apiBase}}/fusion/v1/ai/{{aiId}}/chat/completions\" \\n -H \"Content-Type: application/json\" \\n -H \"Authorization: Bearer {{token}}\" \\n -d '{\n \"model\": \"gpt-3.5-turbo\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"You are a helpful assistant.\"\n },\n {\n \"role\": \"user\",\n \"content\": \"Hello!\"\n }\n ]\n }'\n\n```\n\n## Returned data example\n\n```json\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", "ai_api_footer_desc": "AI-Agent in deine Website einbinden? Erfahren Sie mehr", "ai_api_javascript_template": "## Initialize SDK [![github]({{ githubIcon }})](https://github.com/openai/openai-node)\nAITable's chat completion API is compatible with OpenAI's Node.js SDK. You can use our service with the same SDK by simply changing the configuration as follows:\n\n\n```javascript\nconst { Configuration, OpenAIApi } = require(\"openai\");\nconst configuration = new Configuration({\n apiKey: \"{{token}}\",\n basePath: \"{{apiBase}}/fusion/v1/ai/{{aiId}}\"\n});\n```\n\n## Create chat completions\n\n```javascript\nconst openai = new OpenAIApi(configuration);\nconst chatCompletion = await openai.createChatCompletion({\n model: \"gpt-3.5-turbo\",\n messages: [{role: \"user\", content: \"Hello world\"}],\n});\n```\n\n## Returned data example\n\n```javascript\n\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", @@ -161,6 +170,9 @@ "ai_chat_unit": "KI-Bot(s)", "ai_close_setting_tip_content": "Sie haben Änderungen vorgenommen. Willst du sie wegwerfen?", "ai_close_setting_tip_title": "tip", + "ai_copilot_generate_response": "Antwort wird für Sie generiert...", + "ai_copilot_processs": "Verarbeitung läuft, bitte warten...", + "ai_copilot_start_process_request": "Ihre Anfrage wird verarbeitet...", "ai_create_guide_btn_text": "Datenblatt auswählen", "ai_create_guide_content": "Als AI-Agent kann ich Ihre Fragen basierend auf dem Wissen beantworten, das ich gelernt habe. Bevor Sie mit dem Gespräch beginnen, wählen Sie bitte ein Datenbuch als Wissensbasis aus, und ich werde alle darauffolgenden Daten zum Lernen lesen.", "ai_credit_cost_chart_title": "Kreditkosten", @@ -629,7 +641,7 @@ "apps_support": "Plattformübergreifender Kundensupport", "archive_delete_record": "Archivierte Datensätze löschen", "archive_delete_record_title": "Aufzeichnung löschen", - "archive_notice": "

Sie versuchen, bestimmte Datensätze zu archivieren. Durch die Archivierung der Datensätze ergeben sich folgende Änderungen:

1. Alle bidirektionalen Verbindungen für diesen Datensatz werden gelöscht

2. Das Bearbeiten wird nicht unterstützt

3. Funktionen wie Terminerinnerungen und Abonnementdatensätze werden nicht unterstützt

4. Beteiligen Sie sich nicht mehr an der Berechnung von Such-, Formel- und anderen Feldern

Bist du dir sicher, dass du weitermachen willst? (Sie können die Archivierung in der Archivbox unter „Erweitert“ aufheben)

", + "archive_notice": "

Sie versuchen, bestimmte Datensätze zu archivieren. Durch die Archivierung der Datensätze ergeben sich folgende Änderungen:

1. Das Bearbeiten wird nicht unterstützt

2. Funktionen wie Terminerinnerungen und Abonnementdatensätze werden nicht unterstützt

3. Beteiligen Sie sich nicht mehr an der Berechnung von Such-, Formel- und anderen Feldern

Bist du dir sicher, dass du weitermachen willst? (Sie können die Archivierung in der Archivbox unter „Erweitert“ aufheben)

", "archive_record_in_activity": "Archiviert diesen Datensatz", "archive_record_in_menu": "Datensatz archivieren", "archive_record_success": "Erfolgreich archivierte Aufzeichnungen", @@ -689,6 +701,8 @@ "audit_add_field_role_detail": "Im Datenblatt „ fügen Sie [] Rolle als [] für das Feld [] ", "audit_add_node_role": "Dateiberechtigungen hinzufügen", "audit_add_node_role_detail": "Dateiberechtigung hinzufügen,setzen Sie 「${unitNames}」auf 「${role}」von 「${currentNodeName}」", + "audit_add_node_role_detail_end": "to「${role}", + "audit_add_node_role_detail_start": "Add file node permission,set「${unitNames}」", "audit_admin_permission_change_event": "Administratorberechtigungen ändern", "audit_create_template": "Vorlage erstellen", "audit_create_template_detail": "Vorlage erstellen", @@ -697,20 +711,30 @@ "audit_delete_field_role_detail": "Prüfung", "audit_delete_node_role": "Dateiberechtigung löschen", "audit_delete_node_role_detail": "Lösche Dateiberechtigung, lösche die Rolle „${role}“ von „${unitNames}“ in „${currentNodeName}“", + "audit_delete_node_role_detail_end": "at 「${role}」role", + "audit_delete_node_role_detail_start": "Delete file node permission,delete「${unitNames}」from", "audit_delete_template": "Vorlage löschen", "audit_delete_template_detail": "Vorlage löschen", "audit_disable_field_role": "Feldberechtigungen deaktivieren", "audit_disable_field_role_detail": "Prüfung", "audit_disable_node_role": "Dateiberechtigungen deaktivieren", "audit_disable_node_role_detail": " ${nodeType} 「${currentNodeName}」 `s permission deaktivieren", + "audit_disable_node_role_detail_end": "`s permission", + "audit_disable_node_role_detail_start": "Disable ${nodeType}", "audit_disable_node_share": "Öffentlicher Link schließen", "audit_disable_node_share_detail": "Schließen ${nodeType} 「${currentNodeName}」 public link", + "audit_disable_node_share_detail_end": "public link", + "audit_disable_node_share_detail_start": "Close ${nodeType}", "audit_enable_field_role": "Feldberechtigungen aktivieren", "audit_enable_field_role_detail": "Prüfung", "audit_enable_node_role": "Dateiberechtigungen aktivieren", "audit_enable_node_role_detail": " ${nodeType} 「${currentNodeName}」 `s permission aktivieren", + "audit_enable_node_role_detail_end": "`s permission", + "audit_enable_node_role_detail_start": "Enable ${nodeType}", "audit_enable_node_share": "Öffentlicher Link öffnen", "audit_enable_node_share_detail": " ${nodeType} 「${currentNodeName}」 public link öffnen", + "audit_enable_node_share_detail_end": "public link", + "audit_enable_node_share_detail_start": "Open ${nodeType}", "audit_login_event": "Anmeldeereignis", "audit_logout_event": "englisch", "audit_organization_change_event": "Die Organisationsstruktur der Kontakte hat sich geändert", @@ -731,18 +755,25 @@ "audit_space_invite_user_detail": "Prüfung", "audit_space_node_copy": "Datei duplizieren", "audit_space_node_copy_detail": "Duplizieren Sie ${nodeType} 「${sourceNodeName}「, der Name der neuen Datei lautet 「${currentNodeName}」", + "audit_space_node_copy_detail_start": "Duplicate ${nodeType} 「${sourceNodeName}」, the new file node's name is", "audit_space_node_create": "Datei erstellen", "audit_space_node_create_detail": "Erstellen Sie einen ${nodeType} namens 「${currentNodeName}」", + "audit_space_node_create_detail_start": "Create a ${nodeType} named", "audit_space_node_delete": "Datei löschen", "audit_space_node_delete_detail": " ${nodeType} mit dem Namen 「${currentNodeName}」", + "audit_space_node_delete_detail_start": "Delete ${nodeType} named", "audit_space_node_export": "Datenblatt exportieren", "audit_space_node_export_detail": "Member ${member_name} exportiertes Datenblatt ${node_name}", "audit_space_node_import": "Datei importieren", "audit_space_node_import_detail": "Importieren Sie eine Datei mit dem Namen 「${nodeName}」", + "audit_space_node_import_detail_start": "Import a file node named", "audit_space_node_move": "Datei verschieben", "audit_space_node_move_detail": "Verschieben Sie ${nodeType} 「${currentNodeName}」in den Ordner「${parentName}」」.", + "audit_space_node_move_detail_end": "to the folder「${parentName}」", + "audit_space_node_move_detail_start": "Move ${nodeType}", "audit_space_node_rename": "Datei umbenennen", "audit_space_node_rename_detail": "${nodeType} 」${oldNodeName}」」」」」」」in 「${nodeName}」", + "audit_space_node_rename_detail_start": "Rename ${nodeType} 「${oldNodeName}」to", "audit_space_node_sort": "Prüfung", "audit_space_node_sort_detail": "Prüfung", "audit_space_node_update_cover": "Prüfung", @@ -757,17 +788,24 @@ "audit_space_rubbish_node_delete_detail": "Prüfung", "audit_space_rubbish_node_recover": "Dateien wiederherstellen", "audit_space_rubbish_node_recover_detail": " ${nodeType} 「${currentNodeName}」 aus dem Papierkorb wiederherstellen", + "audit_space_rubbish_node_recover_detail_end": "from the trash", + "audit_space_rubbish_node_recover_detail_start": "Restore ${nodeType}", "audit_space_template_event": "Vorlage ändern", "audit_space_update_logo": "Prüfung", "audit_space_update_logo_detail": "Prüfung", "audit_store_share_node": "Freigegebene Datei speichern", "audit_store_share_node_detail": " ${nodeType} in den Leerraum wiederherstellen, Name ist 「${nodeName}」", + "audit_store_share_node_detail_start": "Restore ${nodeType} to the space, name is", "audit_update_field_role": "Prüfung", "audit_update_field_role_detail": "Prüfung", "audit_update_node_role": "Dateiberechtigung ändern", "audit_update_node_role_detail": "Ändern Sie die Dateiberechtigung, ändern Sie die Rolle von „${unitNames}“ in „${role}“ von 「 ${currentNodeName}」", + "audit_update_node_role_detail_end": "to「${role}」role", + "audit_update_node_role_detail_start": "Modify file node permission,modify「${unitNames}」from", "audit_update_node_share_setting": "Einstellungen für öffentliche Links für Dateien ändern", "audit_update_node_share_setting_detail": " ${nodeType} 「${currentNodeName}」 public link ändern", + "audit_update_node_share_setting_detail_end": "public link settings", + "audit_update_node_share_setting_detail_start": "Modify ${nodeType}", "audit_user_login": "Benutzeranmeldung", "audit_user_login_detail": "Prüfung", "audit_user_logout": "Benutzer abmelden", @@ -809,6 +847,7 @@ "automation_enabled_return_via_related_files": "Die Automatisierung ist aktiviert. Bitte geben Sie die ursprüngliche Tabelle über „Verwandte Dateien“ erneut ein, um die neue Schaltfläche zu verwenden.", "automation_field": "Field", "automation_import_variables_from_pre_tep": "Holen Sie sich Daten aus dem Vorschritt", + "automation_is_not_yet_enabled": "Die Automatisierung ist noch nicht aktiviert. Bitte aktivieren Sie sie und versuchen Sie es erneut", "automation_last_edited_by": "Zuletzt bearbeitet von", "automation_last_edited_time": "Letzte Bearbeitungszeit", "automation_manager_label": "Kann alle Aktionen an der Automatisierung ausführen", @@ -834,6 +873,7 @@ "automation_runs_this_month": "Läuft diesen Monat", "automation_stay_tuned": "Bleiben Sie dran", "automation_success": "Erfolg", + "automation_tips": "Das Schaltflächenfeld ist falsch konfiguriert. Bitte überprüfen Sie es und versuchen Sie es erneut", "automation_updater_label": "Kann den Ausführungsverlauf der Automatisierung anzeigen", "automation_variabel_empty": "Es sind keine Daten vorhanden, die im Vorschritt verwendet werden können. Bitte passen Sie sie an und versuchen Sie es erneut.", "automation_variable_datasheet": "Daten von ${NODE_NAME} abrufen", @@ -869,6 +909,7 @@ "bermuda": "Bermuda", "bhutan": "Bhutan", "billing_over_limit_tip_common": "Die Nutzung des Speicherplatzes hat das Limit überschritten und Sie können nach dem Upgrade eine höhere Menge nutzen.", + "billing_over_limit_tip_forbidden": "Ihre Testdauer oder Ihr Abonnementzeitraum ist abgelaufen. Für eine Verlängerung wenden Sie sich bitte an den Verkaufsberater.", "billing_over_limit_tip_widget": "Die Anzahl der Widget-Installationen hat das Limit überschritten und Sie können ein Upgrade durchführen, um eine höhere Nutzung zu erzielen.", "billing_period": "Abrechnungszeitraum: ${period}", "billing_subscription_warning": "Feature-Erfahrung", @@ -928,10 +969,19 @@ "button_text": "Schaltflächentext", "button_text_click_start": "Klicken Sie zum Starten", "button_type": "Schaltflächentyp", + "by_at": "bei", + "by_days": "Tage", + "by_every": "jeden", "by_field_id": "Feld-ID verwenden", + "by_hours": "Std", + "by_in": "bei", + "by_min": "Protokoll)", + "by_months": "Monate", + "by_on": "auf der", "by_the_day": "Tagsüber", "by_the_month": "Monatlich", "by_the_year": "Jährlich", + "by_weeks": "Wochen", "calendar_add_date_time_field": "Datumsfeld erstellen", "calendar_color_more": "Mehr Farben", "calendar_const_detail_weeks": "[\"Montag\",\"Dienstag\",\"Mittwoch\",\"Donnerstag\",\"Freitag\",\"Samstag\",\"Sonntag\"]", @@ -995,6 +1045,14 @@ "cannot_activate_space_by_space_limit": "can_activate_space_by_space_limit", "cannot_join_space": "Sie können einer neuen Raumstation nicht beitreten, weil Sie die maximale Quote von zehn Raumstationen überschritten haben.", "cannot_switch_field_permission": "Legen Sie Feldberechtigungen fest, die nicht höher als die Dateiberechtigungen sind.", + "capacity_file_detail_desc": "The total number of file nodes within the Space is calculated by adding the file nodes from the Team to the file nodes created by each member in their Private. Not enough capacity?", + "capacity_file_detail_title": "File Capacity", + "capacity_file_member": "Member", + "capacity_file_member_private_node_count": "Private", + "capacity_file_member_private_percent": "Percent", + "capacity_file_member_team": "Team", + "capacity_file_member_team_node_count": "Team", + "capacity_file_upgrade": "Click to upgrade your Space", "capacity_from_official_gift": "Aus dem offiziellen Geschenk", "capacity_from_participation": "Von eingeladenem ${user} dem Space beitreten", "capacity_from_purchase": "Nach Kaufkapazität", @@ -1031,6 +1089,8 @@ "catalog": "Forscher", "catalog_add_from_template_btn_title": "Aus Vorlagen hinzufügen", "catalog_empty_tips": "Dieser Arbeitsbereich ist jetzt leer. Beginnen Sie mit der Verwendung von Vorlagen zum Erstellen von Dateien.", + "catalog_private": "Private", + "catalog_team": "Team", "category_blank": "[Leere]", "catering": "Verpflegung", "cayman_islands": "Kaimaninseln", @@ -1099,6 +1159,7 @@ "choose_type_of_vika_field": "Feldtyp auswählen", "choose_your_own_space": "(Unterstützt nur das Speichern auf Ihrem eigenen Speicherplatz als Ersteller)", "chose_new_primary_admin_button": "Zuweisen", + "chunk_stopping_title": "Stopping", "claim_special_offer": "Fordern Sie dieses Sonderangebot an!", "clear": "Löschen", "clear_all_fields": "Alles löschen", @@ -1229,6 +1290,7 @@ "confirm_del_current_team": "Sind Sie sicher, dass Sie das Team löschen möchten?", "confirm_delete": "Bestätigen und löschen", "confirm_delete_node_name_as": "Möchten Sie \"${nodeNameDiv}\" wirklich löschen?", + "confirm_delete_private_node_name_as": "Are you sure you want to delete \"${nodeNameDiv}\"? The file will be deleted from the Space and the trash.", "confirm_delete_space_btn": "Leerzeichen bestätigen und löschen", "confirm_exit": "Beenden bestätigen", "confirm_exit_space_with_name": "Bestätigen, ob das Leerzeichen \"${spaceNameDiv}\" beendet werden soll", @@ -1266,6 +1328,14 @@ "convert": "Konvertieren", "convert_tip": "Diese Aktion kann Daten in einigen Zellen löschen. Sie können die Aktion rückgängig machen, wenn etwas Unerwartetes passiert.", "cook_islands": "Cookinseln", + "copilot_auto_agent_desc": "Sie sind sich nicht sicher, welchen Agenten Sie wählen sollen? Versuchen Sie es mit AutoAgent.", + "copilot_auto_agent_name": "Auto-Agent", + "copilot_data_agent_desc": "Generiere Datenanalyse/Visualisierungen basierend auf Ihren Ansichten.", + "copilot_data_agent_name": "Datenagent", + "copilot_data_agent_policy": "Wenn Sie mit Copilot chatten, stimmen Sie den Nutzungsbedingungen zu", + "copilot_data_agent_policy_button": "Politik", + "copilot_help_agent_desc": "Fragen Sie alles über die Hilfezentrumsdokumente von AITable.", + "copilot_help_agent_name": "Hilfezentrum abrufen", "copy": "Kopieren", "copy_automation_url": "URL kopieren", "copy_card_link": "Datensatz-URL kopieren", @@ -1310,6 +1380,7 @@ "create_mirror_guide_content": "Die Spiegelfunktion bietet die Möglichkeit, bestimmte Daten auszublenden. Sie können in der ursprünglichen Datenblattansicht „Filterbedingungen“ und „ausgeblendete Felder“ festlegen, um zu steuern, welche Datensätze und Felder im Spiegel angezeigt werden.\n
\n
\nIn Verbindung mit der Funktion „Ansichtssperre“ kann sie andere daran hindern, Änderungen vorzunehmen.\n
\n
\nDarüber hinaus können Sie zu „Originaltabelle > Ausgeblendete Felder“ gehen, um die Konfiguration für „Alle Felder in Spiegeln anzeigen“ zu ändern.", "create_mirror_guide_title": "Spiegel blendet einige Datensätze und Felder aus", "create_new_button_field": "Erstellen Sie ein neues Schaltflächenspaltenfeld", + "create_private_node_tip": "Personal or temporary draft documents can be created here ${link}", "create_public_invitation_link": "Öffentliche Einladungslinks erstellen", "create_space_sub_title": "Hallo, bitte geben Sie Ihrem Space einen Namen~", "create_team_fail": "Team erstellen fehlgeschlagen", @@ -1373,10 +1444,12 @@ "custom_enterprise": "Passen Sie den Unternehmensraum für Sie an", "custom_function_development": "Entwicklung benutzerdefinierter Features", "custom_grade_desc": "Bietet Agenten-Bereitstellung, private Installation, Unterstützung und maßgeschneiderte professionelle Services", + "custom_page_setting_title": "Add a custom page", "custom_picture": "Individuelles Bild", "custom_style": "Stil", "custom_upload": "Benutzerdefinierter Upload", "custom_upload_tip": "Ein 1:1 quadratisches Bild wird für die bessere visuelle Erfahrung empfohlen", + "custome_page_title": "Custom Web", "cut_cell_data": "Zelle(n) ausschneiden", "cyprus": "Zypern", "czech": "Tschechisch", @@ -1428,6 +1501,7 @@ "default": "Standard", "default_create_ai_chat_bot": "Neuer AI-Agent", "default_create_automation": "Neue Automatisierung", + "default_create_custom_page": "Neue benutzerdefinierte Seite", "default_create_dashboard": "Neues Dashboard", "default_create_datasheet": "Neues Datenblatt", "default_create_file": "Neue Datei", @@ -1449,6 +1523,7 @@ "del_invitation_link": "Einladungslink löschen", "del_invitation_link_desc": "Der Link ist nach Löschung ungültig", "del_space_now": "Leerzeichen für immer löschen", + "del_space_now_confirm_tip": "For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "del_space_now_tip": "Der Speicherplatz kann nach dem Löschen nicht wiederhergestellt werden. Alle Dateien und Anhänge werden gelöscht.", "del_space_res_tip": "Das Leerzeichen gelöscht", "del_team_success": "Teamerfolg löschen", @@ -1644,6 +1719,62 @@ "embed_error_page_help": "Erfahren Sie mehr", "embed_fail_og_description_content": "Der öffentliche Link für diese Einbettung wurde deaktiviert und ist vorübergehend nicht verfügbar", "embed_failed": "Einbettungslink ist nicht verfügbar,", + "embed_link_bilibili": "bilibili", + "embed_link_bilibili_desc": "Durch das Einbetten der Bilibili-Videos können Sie Tutorials und Anleitungen ansehen oder die Kanal-Homepage in Vika anzeigen.", + "embed_link_bilibili_link_text": "So betten Sie das Bilibili-Video ein", + "embed_link_bilibili_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-bilibili-video", + "embed_link_default": "Irgendetwas", + "embed_link_default_desc": "Fügen Sie einen Link ein, um eine beliebige Website anzuzeigen.", + "embed_link_default_link_text": "Erfahren Sie mehr", + "embed_link_default_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_link_figma": "Figma", + "embed_link_figma_desc": "Durch die Einbettung von Figma-Dateien können Mitglieder Designentwürfe bequemer anzeigen und bearbeiten und so die Effizienz der Zusammenarbeit verbessern.", + "embed_link_figma_link_text": "So betten Sie Figma-Dateien ein", + "embed_link_figma_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-figma-file", + "embed_link_google_docs": "Docs", + "embed_link_google_docs_desc": "Durch die Einbettung von Google Docs können Sie Dokumente in AITable bearbeiten und anzeigen, um die Zusammenarbeit im Team zu erleichtern.", + "embed_link_google_docs_link_text": "So betten Sie Google Docs ein", + "embed_link_google_docs_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-docs-file", + "embed_link_google_sheets": "Sheets", + "embed_link_google_sheets_desc": "Durch die Einbettung von Google Sheets können Sie Tabellen in AITable bearbeiten und anzeigen, um die Zusammenarbeit im Team zu erleichtern.", + "embed_link_google_sheets_link_text": "So betten Sie Google Sheets ein", + "embed_link_google_sheets_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-sheets-file", + "embed_link_jishi_design": "JSdesign", + "embed_link_jishi_design_desc": "Durch die Einbettung von JSdesign-Dateien können Mitglieder Designentwürfe bequemer anzeigen und bearbeiten und so die Effizienz der Zusammenarbeit verbessern.", + "embed_link_jishi_design_link_text": "So betten Sie JSdesign-Dateien ein", + "embed_link_jishi_design_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-js-design-file", + "embed_link_tencent_docs": "Tencent-Dokumente", + "embed_link_tencent_docs_desc": "Durch die Einbettung von Tencent-Dokumenten können Sie Tencent-Dokumente in Vika bearbeiten und anzeigen, um die Effizienz der Zusammenarbeit zu verbessern.", + "embed_link_tencent_docs_link_text": "So betten Sie Tencent-Dokumente ein", + "embed_link_tencent_docs_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-tencent-docs", + "embed_link_wps": "WPS", + "embed_link_wps_desc": "Durch das Einbetten von WPS-Dateien können Sie WPS-Dokumente, -Tabellen und -Formulare in Vika bearbeiten und anzeigen, um die Effizienz der Zusammenarbeit zu verbessern.", + "embed_link_wps_link_text": "So betten Sie WPS-Dateien ein", + "embed_link_wps_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-wps-file", + "embed_link_youtube": "Youtube", + "embed_link_youtube_desc": "Durch das Einbetten von YouTube-Videos können Sie Tutorials und Anleitungen ansehen oder die Kanal-Homepage in AITable anzeigen.", + "embed_link_youtube_link_text": "So betten Sie YouTube-Videos ein", + "embed_link_youtube_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-youtube-video", + "embed_page": "Benutzerdefinierte Seite", + "embed_page_add_url": "URL hinzufügen", + "embed_page_doc_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_page_function_desc": "Fügen Sie Webseiten zu ${edition} hinzu, um einfachen Zugriff auf Website-Dokumente, Videos und mehr von Drittanbietern zu erhalten. Sie können empfohlene Website-Links oder beliebige benutzerdefinierte Links hinzufügen.", + "embed_page_node_permission_editor": "Auf der Basis von „Nur aktualisieren“ kann auch die öffentliche Freigabe der Datei geöffnet werden", + "embed_page_node_permission_manager": "Kann alle Aktionen für die Datei ausführen", + "embed_page_node_permission_reader": "Kann den Inhalt der benutzerdefinierten Seite und grundlegende Dateiinformationen anzeigen", + "embed_page_node_permission_updater": "Auf der Basis von „schreibgeschützt“ kann auch der Link der benutzerdefinierten Seite geändert werden", + "embed_page_setting_title": "Fügen Sie eine benutzerdefinierte Seite hinzu", + "embed_page_url_invalid": "Bitte geben Sie die richtige URL ein", + "embed_paste_link_bilibili_placeholder": "Fügen Sie den Link zum Bilibili-Video ein", + "embed_paste_link_default_placeholder": "Fügen Sie die URL ein", + "embed_paste_link_figma_placeholder": "Fügen Sie den Freigabelink der Figma-Datei ein", + "embed_paste_link_google_docs_placeholder": "Fügen Sie den Freigabelink für Google Docs ein", + "embed_paste_link_google_sheets_placeholder": "Fügen Sie den Freigabelink für Google Sheets ein", + "embed_paste_link_jsdesign_placeholder": "Fügen Sie den Freigabelink der JSdesign-Datei ein", + "embed_paste_link_tencent_docs_placeholder": "Fügen Sie den Tencent Docs-Freigabelink ein", + "embed_paste_link_wps_placeholder": "Fügen Sie den Freigabelink der WPS-Datei ein", + "embed_paste_link_youtube_placeholder": "Fügen Sie den YouTube-Videolink ein", + "embed_success": "Erfolgreich hinzufügen", "emoji_activity": "Aktivitäten", "emoji_custom": "Benutzerdefiniert", "emoji_flags": "Flaggen", @@ -1750,6 +1881,11 @@ "estonia": "Estland", "ethiopia": "Äthiopien", "event_planning": "Veranstaltungsplanung", + "every": "Jeden", + "every_day_at": "Tag(e) um", + "every_hour_at": "Stunde(n) um", + "every_month_at": "Monat(e) am", + "every_week_at": "Jede Woche weiter", "everyday_life": "Alltag", "everyone_visible": "Für alle sichtbar", "exact_date": "exaktes Datum", @@ -1760,6 +1896,7 @@ "exchange": "Einlösen", "exchange_code_times_tip": "Hinweis: Der Einlösungscode kann nur einmal verwendet werden", "exclusive_consultant": "Exklusiver V+ Berater", + "exclusive_limit_plan_desc": "Exklusive begrenzte Stufe", "exist_experience": "Exit-Erfahrung", "exits_space": "Leerzeichen verlassen", "expand": "Erweitern", @@ -1786,7 +1923,7 @@ "expired": "Abgelaufen", "export": "Exportieren...", "export_brand_desc": "Bereitgestellt von", - "export_current_preview_view_data": "", + "export_current_preview_view_data": "Export current preview view data", "export_gantt_button_tips": "Export in eine .png-Datei", "export_gantt_chart": "Gantt-Diagramm exportieren", "export_to_excel": "Daten exportieren", @@ -2358,26 +2495,26 @@ "gantt_config_color_help": "Wie man einrichtet", "gantt_config_friday": "Freitag", "gantt_config_friday_in_bar": "Fr", - "gantt_config_friday_in_select": "Fr", + "gantt_config_friday_in_select": "Freitag", "gantt_config_monday": "Montag", "gantt_config_monday_in_bar": "Mo", - "gantt_config_monday_in_select": "Mo", + "gantt_config_monday_in_select": "Montag", "gantt_config_only_count_workdays": "Die Dauer zählt nur Arbeitstage.", "gantt_config_saturday": "Samstag", "gantt_config_saturday_in_bar": "Sa", - "gantt_config_saturday_in_select": "Sa", + "gantt_config_saturday_in_select": "Samstag", "gantt_config_sunday": "Sonntag", - "gantt_config_sunday_in_bar": "Sonne", - "gantt_config_sunday_in_select": "Sonne", + "gantt_config_sunday_in_bar": "So", + "gantt_config_sunday_in_select": "Sonntag", "gantt_config_thursday": "Donnerstag", "gantt_config_thursday_in_bar": "Do", - "gantt_config_thursday_in_select": "Do", + "gantt_config_thursday_in_select": "Donnerstag", "gantt_config_tuesday": "Dienstag", "gantt_config_tuesday_in_bar": "Di", - "gantt_config_tuesday_in_select": "Di", + "gantt_config_tuesday_in_select": "Dienstag", "gantt_config_wednesday": "Mittwoch", - "gantt_config_wednesday_in_bar": "Heiraten", - "gantt_config_wednesday_in_select": "Heiraten", + "gantt_config_wednesday_in_bar": "Mi", + "gantt_config_wednesday_in_select": "Mittwoch", "gantt_config_weekdays_range": "${weekday} bis ${weekday}", "gantt_config_workdays_a_week": "Kundenspezifische Standardarbeitstage", "gantt_cycle_connection_warning": "Invalid task dependency, there is a cycle connection\n", @@ -2458,6 +2595,7 @@ "gold_grade": "Gold", "gold_grade_desc": "Für Teams mit komplexen Geschäftsprozessen", "gold_seat_200_desc": "200", + "gold_seat_300_desc": "300", "golden_grade": "Gold", "got_it": "Hab's", "got_v_coins": "V-Münzen belohnt", @@ -2491,6 +2629,8 @@ "guests_per_space": "Gäste pro Raum", "guide_1": "啊这", "guide_2": "Es dauert nur wenige Minuten, um die grundlegenden Funktionen zu erlernen. Arbeiten Sie ab diesem Moment produktiver!", + "guide_flow_modal_contact_sales": "Kontaktieren Sie den Vertrieb", + "guide_flow_modal_get_started": "Loslegen", "guide_flow_of_catalog_step1": "Hier ist der Arbeitskatalog, in dem alle Ordner und Dateien des Space gespeichert sind.", "guide_flow_of_catalog_step2": "Im Arbeitskatalog können Sie nach Bedarf ein Datenblatt oder einen Ordner erstellen.", "guide_flow_of_click_add_view_step1": "Zusätzlich zu einigen grundlegenden Ansichten wird dringend empfohlen, eine Albumansicht zu erstellen, wenn Sie Anhänge im Bildformat haben.", @@ -2669,6 +2809,7 @@ "intro_widget_tips": "Was ist Widget?", "introduction": "Einleitung", "invalid_action_sort_tip": "Als Gruppierungsfeld wurde die Sortierung festgelegt. Die Einstellung der aktuellen Bestellung wird nicht wirksam.", + "invalid_automation_configuration": "Ungültige Automatisierungskonfiguration. Bitte überprüfen Sie und versuchen Sie es erneut", "invalid_field_type": "Ungültiger Feldtyp", "invalid_option_sort_tip": "Als Gruppierungsfeld wurde die Sortierung festgelegt.", "invalid_redemption_code_entered": "Ungültiger Einlösungscode", @@ -2799,6 +2940,9 @@ "label_format_day_month_and_year_split_by_slash": "Tag/Monat/Jahr", "label_format_month": "Monat", "label_format_month_and_day_split_by_dash": "Monatstag", + "label_format_month_day_year_split_by_dash": "Month-Day-Year", + "label_format_month_day_year_split_by_slash": "Month/Day/Year", + "label_format_month_day_year_two_digit_year_split_by_slash": "Month/Day/Year (Two-digit year)", "label_format_year": "Jahr", "label_format_year_and_month_split_by_dash": "Jahr Monat", "label_format_year_month_and_day_split_by_dash": "Jahr-Monat-Tag", @@ -2877,6 +3021,7 @@ "lark_version_enterprise": "Enterprise Plan mit Lark", "lark_version_standard": "Standardplan mit Lerche", "lark_versions_free": "Grundplan mit Lerche", + "last_day": "Letzter Tag", "last_modified_by_select_modal_desc": "Wenn eines der unten ausgewählten Felder bearbeitet wird, wird das zuletzt bearbeitete Mitglied im zuletzt bearbeiteten Feld angezeigt.", "last_modified_time_select_modal_desc": "Wenn eines der unten ausgewählten Felder bearbeitet wird, wird die zuletzt bearbeitete Zeit im zuletzt bearbeiteten Zeitfeld angezeigt.", "last_step": "Zurück", @@ -3021,7 +3166,7 @@ "mail_invite_fail": "Mail einladen Erfolg.", "mail_invite_success": "Mail einladen Erfolg.", "main_admin_name": "Name des Administrators", - "main_admin_page_desc": "Administratoren haben vollen Zugriff auf den Space, z. B. Zuweisung von Unteradministratoren und Übertragung des Eigentums an dem Space", + "main_admin_page_desc": "Administratoren haben vollen Zugriff auf den Space, z. B. zum Verwalten von Mitgliedern und zum Verwalten von Space-Einstellungen.", "main_contain": "Hauptinhalte", "malawi": "Malawi", "malaysia": "Malaysia", @@ -3241,8 +3386,12 @@ "more_widget": "Weitere Widgets", "morocco": "Marokko", "move": "Bewegen", + "move_datasheet_link_warn": "Cannot be moved to Team Area alone, because there is a two-way link from the current datasheet to another datasheet, it is recommended to put them in a folder and then move them", "move_favorite_node_fail": "Knotenbewegung fehlgeschlagen. Das System aktualisiert die Liste automatisch.", + "move_folder_link_warn": "Cannot be moved to Team Area because the files in the current folder are linked to files outside the folder (may be two-way links or linked by forms, etc.) We recommend that they be placed in a folder before moving", "move_node_modal_content": "Nach dem Verschieben kann die Sichtbarkeit der Datei durch den übergeordneten Ordner beeinträchtigt werden.", + "move_other_link_no_permission": "Unable to move to the corresponding folder because you do not have administrative rights to the folder", + "move_other_link_warn": "It is not allowed to move ${node type} to Team Area alone, because it connects to the datasheet of Private Area, it is recommended to put them in a folder before moving them", "move_to": "Verschieben nach", "move_to_error_equal_parent": "Die Datei befindet sich unter dem aktuellen Ordner. Bitte wählen Sie einen anderen Ordner", "move_to_modal_title": "[${name}] verschieben", @@ -3273,7 +3422,9 @@ "new_a_line": "Umschalt+Eingabetaste: Zeilenumbruch", "new_automation": "Neue Automatisierung", "new_caledonia": "Neukaledonien", + "new_custom_page": "New custom page", "new_datasheet": "Neues Datenblatt", + "new_ebmed_page": "Neue benutzerdefinierte Seite", "new_folder": "Neuer Ordner", "new_folder_btn_title": "Ordner", "new_folder_tooltip": "Ordner erstellen", @@ -3439,7 +3590,7 @@ "nvc_start_text": "Ziehen Sie die Leiste an das rechte Ende", "nvc_yes_text": "Verifiziert", "obtain_verification_code": "Überprüfungscode nicht erhalten oder abgelaufen", - "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrzw0miJVmSkJ7eBBa9k/fomx5qPX0JGPFvfEEP\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", + "offical_website_footer_nav_data": "[{ „title“: „产品“, „lists“: [{ „name“: „快速入门“, „url“: „https://help.vika.cn/docs/guide/tutorial-1-quick- start\" }, { \"name\": \"产品指南\", \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\" }, { \"name\": „产品价格“, „url“: „/pricing/“ }, { „name“: „产品路线图“, „url“: „https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5“ }] }, { \"title\": \"关于我们\", \"lists\": [{ \"name\": \"公司介绍\", \"url\": \"/company/\" }, { \"name\": \"加入我们\", \"url \": \"/join-us/\" }, { \"name\": \"媒体报道\", \"url\": \"/press/\" }, { \"name\": \"vika维格课堂\", \"url\": \"https ://edu.vika.cn/\" }, { \"name\": \"维格合伙人\", \"url\": \"/partners/\" }] }, { \"title\": \"解决方案\", \"lists\" : [{ \"name\": \"PMO项目群管理\", \"url\": \"/business-pmo/\" }, { \"name\": \"智慧电商运营\", \"url\": \"/ecommerce/\" }, { \"name\": \"CRM客户管理\", \"url\": \"/crm/\" }, { \"name\": \"HR人力资源管理\", \"url\": \"/hr/\" }, { \"name\": „Scrum敏捷开发管理“, „url“: „/scrum/“ }, { „name“: „营销策划与市场运营“, „url“: „/marketing/“ }, { „name“: „OKR目标管理\", \"url\": \"/okr/\" }, { \"name\": \"教育培训管理\", \"url\": \"/education/\" }, { \"name\": \"智慧门 Aliexpress管理\", \"url\" : \"/shop/\" }] }, { \"title\": \"支持\", \"lists\": [{ \"name\": \"意见反馈\", \"url\": \"https://vika.cn/share/shrCvbFC53xc3kl00B4Pg \" }, { \"name\": \"帮助中心\", \"url\": \"https://help.vika.cn/\" }, { \"name\": \"开发者中心\", \"url\": \"/developers/ \" }, { \"name\": \"服务条款\", \"url\": \"/service-agreement/\" }, { \"name\": \"隐私协议\", \"url\": \"/service-agreement/\" }, { \"name\": \"安全与合规\", \"url\": \"/security/\" }] }, { \"title\": \"服务\", \"lists\": [{ \"name\": \"加入社群\", \" url\": \"/chatgroup/\" }, { \"name\": \"Github开源\", \"url\": \"https://github.com/vikadata\" }, { \"name\": \"预约演示\", \"url\" : „https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef“ }, { „name“: „专有云部署“, „url“: „https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL“ } , { \"name\": \"应用连接\", \"url\": \"/connections/\" }] }, { \"title\": \"联系我们\", \"lists\": [{ \"name\": \"地址:深圳市南山区国信投资大厦1710\", \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\" }, { \"name\": \"售前咨询:点击联系商务\", \"url\": \"https: //vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\" }, { \"name\": \"合作:bd@vikadata.com\", \"url\": \"mailto:bd@vikadata.com\" }, { \"name\": \" Adresse: pr@vikadata.com, \"url\": \"mailto:pr@vikadata.com\" }, { \"name\": \"Adresse: hr@vikadata.com\", \"url\": \"mailto:hr@vikadata. com\" }] }]", "offical_website_nav_data": "[{\n \"name\": \"产品\",\n \"href\": \"/login\",\n \"children\": [\n {\n \"name\": \"vika维格表 Overview\",\n \"href\": \"/login/\"\n },\n {\n \"name\": \"应用连接 Integration\",\n \"href\": \"/connections/\"\n },\n {\n \"name\": \"客户端(Beta) Download\",\n \"href\": \"/download/\"\n }\n ]\n}, {\n \"name\": \"解决方案\",\n \"href\": \"/\",\n \"children\": [{\n \"name\": \"PMO项目群管理\",\n \"href\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"href\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"href\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"href\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"href\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"href\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"href\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"href\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"href\": \"/shop/\"\n }, {\n \"name\": \"更多解决方案 >\",\n \"href\": \"/solutions/\"\n }]\n}, {\n \"name\": \"模板/案例\",\n \"href\": \"/template\",\n \"children\": [\n {\n \"name\": \"模板中心 Tempaltes\",\n \"href\": \"/template\"\n },\n {\n \"name\": \"客户案例 Customers\",\n \"href\": \"/cases/\"\n }\n ]\n},\n {\n \"name\": \"首页\",\n \"href\": \"/?home=1\"\n },\n {\n \"name\": \"学习资源\",\n \"href\": \"https://edu.vika.cn/index\",\n \"children\": [\n {\n \"name\": \"快速入门 Tutorials\",\n \"href\": \"https://help.vika.cn/docs/guide/tutorial\"\n },\n {\n \"name\": \"产品手册 Manual\",\n \"href\": \"https://help.vika.cn/docs/guide/manual\"\n },\n {\n \"name\": \"维格课堂 Vika Education\",\n \"href\": \"https://edu.vika.cn/\"\n },\n {\n \"name\": \"维格社区 Vika BBS\",\n \"href\": \"https://bbs.vika.cn/\"\n },\n {\n \"name\": \"第三方连接 Integration\",\n \"href\": \"https://help.vika.cn/docs/guide/connection\"\n },\n {\n \"name\": \"开发者中心 Developer Center\",\n \"href\": \"/developers/\"\n },\n {\n \"name\": \"常见问题 FAQ\",\n \"href\": \"https://help.vika.cn/docs/guide/questions\"\n }\n ]\n }]", "office_preview": "Vorschau von Office-Dateien", "office_preview_app_desc": "

Smooth online preview of office files on datasheet, allowing you to view common office files such as Excel, Word, PPT, etc. on your desktop or mobile anywhere, anytime

\n\n
    \n
  • Online preview of .doc, .docx, .xls, .xlsx, .ppt, .pptx, and .pdf formatted office files
  • \n
  • Desktop and mobile both support file previews of the above formats
  • \n
\n\n

Additional notes:

\n
    \n
  • This feature is powered by \"Yoncentric Cloud Conversion\" and officially integrated
  • \n
  • Click the \"Enable\" button below to enable this integration and agree that \"Yoncentric Cloud Conversion\" reads the office files you want to preview
  • \n
  • If you no longer need the office files preview feature, the space admin can disable it on this page
  • \n
", @@ -3479,6 +3630,7 @@ "open_auto_save_success": "Automatisches Speichern der Ansicht wurde erfolgreich aktiviert", "open_auto_save_warn_content": "Alle Änderungen unter dieser Ansicht werden automatisch gespeichert und mit anderen Mitgliedern synchronisiert.", "open_auto_save_warn_title": "Automatisches Speichern aktivieren", + "open_automation_time_arrival": "https://aitable.ai/contact-sales-open-source", "open_failed": "Öffnen fehlgeschlagen", "open_in_new_tab": "in einer neuen Registerkarte öffnen", "open_invite_after_operate": "Einmal eingeschaltet, können alle Mitglieder über das Kontaktpanel neue Mitglieder einladen", @@ -3625,6 +3777,8 @@ "payment_record": "Zahlungsbilanz", "payment_reminder": "Zahlungserinnerung", "payment_reminder_content": "Der neue Tarif, den Sie ausgewählt haben, ist stärker abzugsfähig als der zu zahlende Betrag. Es wird empfohlen, dass Sie den neuen Plan mit einer längeren Laufzeit wählen. Wenn Sie dies bestätigen, wird der überschüssige Betrag nicht zurückerstattet. ${action} im Zweifel", + "payment_reminder_modal_content": "Sie können die erweiterte Version ausprobieren, um von mehr Dateiknoten, Unternehmensberechtigungen, Anhangskapazität, Datenvolumen, KI und anderen erweiterten Funktionen und Privilegien zu profitieren.", + "payment_reminder_modal_title": "Sie verwenden derzeit die kostenlose Version", "pending_invite": "Ausstehende Einladung", "people": "Mitglied(e)", "per_person_per_year": "Pro Person pro Jahr", @@ -3794,7 +3948,7 @@ "player_step_ui_config_168": "{\n\"templateKey\":\"createMirrorTip\"\n}", "player_step_ui_config_169": "{ „headerImg“: „https://s4.vika.cn/space/2023/04/04/bcf0695cf35840e6b85e032a8e5ea0a1“, „readMoreUrl“: „https://help.vika.cn/changelog/23-04-10- Updates\", \"Kinder\": \"

🚀 Einführung neuer Funktionen

\\N
  • Der neue Feldtyp „Cascader“ wird eingeführt, der die Auswahl aus einer Hierarchie von Optionen auf Formularen erleichtert
  • Das Widget „Skript“ wird veröffentlicht, weniger Code für mehr Anpassungsmöglichkeiten
  • Lösen Sie die Automatisierung aus, um E-Mails zu senden und schnelle Benachrichtigungen zu erhalten
  • Lösen Sie die Automatisierung aus, um eine Nachricht an Slack zu senden und Ihr Team rechtzeitig zu informieren
  • KI erforschen: Widget „GPT Content Generator“ veröffentlicht
\" }", "player_step_ui_config_17": "{\n \"element\": \"#TEMPLATE_CENTER_USE_TEMPLATE_BTN>button\", \n\"placement\": \"rightBottom\",\n\"offsetY\": 20,\n \"title\": \"How to use a template\", \n\"description\": \"Click the button on the left to use the template\", \"children\":\"\" \n}", - "player_step_ui_config_176": "{\"title\":\"Einführung in den AI agent\",\"video\":\"https://www.youtube.com/embed/cjds1r_roG8?si=irKUpMhwDlOEb8Hc\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", + "player_step_ui_config_176": "{\"title\": \"AITable.ai DEMO\", \"video\": \"https://www.youtube.com/embed/kGxMyEEo3OU\", \"videoId\": \"VIKA_GUIDE_VIDEO_FOR_AI\", \"autoPlay\":true}", "player_step_ui_config_18": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select>.ant-select-selector\", \n\"placement\": \"bottomLeft\",\n \"title\": \"How to use a template\", \n\"description\": \"Select where to put the template\", \"children\":\"\" \n}", "player_step_ui_config_19": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select .ant-select-selector\"\n}", "player_step_ui_config_2": "{\n \"config\": [\n {\n \"key\": 1,\n \"name\": \"answer1\",\n \"title\": \"What kind of issues are you looking forward to solved by vikadata?\",\n \"type\": \"checkbox\",\n \"answers\": [\n \"Work Planning\",\n \"Customer Service\",\n \"Project Management\",\n \"Sourcing Supply\",\n \"Content Production\",\n \"E-commerce operation\",\n \"Event Planning\",\n \"Human Resources\",\n \"Administration\",\n \"Financial Management\",\n \"Webcast\",\n \"Educational institutes Management\",\n \"Other\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 2,\n \"name\": \"answer2\",\n \"title\": \"Your job title is______\",\n \"type\": \"radio\",\n \"answers\": [\n \"General manager \",\n \"Project manager\",\n \"Product manager\",\n \"Designer\",\n \"R&D engineer\",\n \"Operator, editor\",\n \"Sales, customer service\",\n \"Human resource, administration \",\n \"Finance, accountant\",\n \"Lawyer, legal affairs\",\n \"Marketing\",\n \"Teacher\",\n \"Student\",\n \"Other\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 3,\n \"name\": \"answer3\",\n \"title\": \"What is the name of your company?\",\n \"type\": \"input\",\n \"submit\": false\n },\n {\n \"key\": 4,\n \"name\": \"answer4\",\n \"title\": \"Please leave your email address/ phone number/ Wechat account below so we can reach you in time when you need help.\",\n \"type\": \"input\",\n \"submit\": true\n },\n {\n \"key\": 5,\n \"title\": \"Thank you for filling out the form, you can add our customer service in case of need\",\n \"platform\": {\n \"website\": \"https://s4.vika.cn/space/2023/03/02/b34e3205a9154463be16f497524f1327\",\n \"dingtalk\": \"https://s4.vika.cn/space/2023/03/02/4b16cef6602a4586a21d6346bf25d300\",\n \"wecom\": \"https://s4.vika.cn/space/2023/03/02/60119b1b69b64aa887bd1be6a2928bec\",\n \"feishu\": \"https://u.vika.cn/z9ygm\"\n },\n \"type\": \"contactUs\",\n \"next\": true\n }\n ]\n}\n", @@ -3824,13 +3978,13 @@ "player_step_ui_config_41": "", "player_step_ui_config_42": "{\n \"element\": \"#DATASHEET_FORM_LIST_PANEL\", \n\"placement\": \"leftTop\",\n \"title\": \"Form\", \n\"description\": \"You can quickly create a form from the current view. The number and order of the fields in the form is consistent with the view.\", \"children\":\"\" \n}", "player_step_ui_config_43": "{\n \"element\": \".style_navigation__1U5cR .style_help__1sXEA\", \n\"placement\": \"rightBottom\",\n \"title\": \"Tip\", \n\"offsetY\":5,\n\"description\": \"You can find your Vikaby assistant from the \"Help\" icon on the left\", \"children\":\"\" \n}", - "player_step_ui_config_44": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", + "player_step_ui_config_44": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", "player_step_ui_config_45": "", "player_step_ui_config_46": "", "player_step_ui_config_47": "{\n \"element\": \"#DATASHEET_WIDGET_BTN\",\n\"placement\": \"bottomRight\",\n \"title\": \"Widget\", \n\"description\": \"Want to use and view your data in a richer way? Try the widget!\", \"children\":\"\" \n}", "player_step_ui_config_48": "", "player_step_ui_config_49": "{\n \"element\": \".style_widgetPanelContainer__1l2ZV\",\n\"placement\": \"leftCenter\",\n \"title\": \"What is a widget\", \n\"description\": \"Vika widgets are an extended application of vikadata that features in richer data visualization, data transfer, data cleansing, and more. By installing widgets in the widget board, you can make work a lot easier.\", \"children\":\"\" \n}", - "player_step_ui_config_5": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", + "player_step_ui_config_5": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", "player_step_ui_config_50": "{\n \"element\": \".style_widgetModal__eXmdB\",\n\"placement\": \"leftTop\",\n \"title\": \"Widget Center\", \n\"description\": \"Officially recommended and custom widgets are published here. You can install any widget you want onto a dashboard or into a widget board of any datasheet.\", \"children\":\"\" \n}", "player_step_ui_config_51": "{\n \"element\": \".style_widgetModal__eXmdB .style_widgetItem__3Pl-1 button\",\n\"placement\": \"rightBottom\",\n \"title\": \"Install widget\", \n\"description\": \"Let's install this \"Chart\" widget\", \"children\":\"\" \n}", "player_step_ui_config_52": "", @@ -3927,6 +4081,7 @@ "preview_guide_click_to_restart": "Klicken Sie auf die Schaltfläche unten, um eine Vorschau erneut anzuzeigen", "preview_guide_enable_it": "Drücken Sie die Taste unten, um diese Funktion einzuschalten", "preview_guide_open_office_preview": "Um eine Vorschau dieser Datei anzuzeigen, aktivieren Sie bitte die Funktion \"Office Preview\"", + "preview_next_automation_execution_time": "Vorschau der nächsten 10 Ausführungszeiten", "preview_not_support_video_codecs": "Nur MP4-Videos mit H.264-Videocodecs können in der Vorschau angezeigt werden", "preview_revision": "Vorschau", "preview_see_more": "Möchten Sie mehr über die Funktion \"Office File Preview\" erfahren? Bitte klicken Sie hier", @@ -3962,6 +4117,7 @@ "privacy_protection": "\"Datenschutz\"", "private_cloud": "Private Wolke", "private_external_person_only": "Nur externe Personen", + "private_help_link": "https://help.aitable.ai/docs/guide/team-and-private-area#private-area", "private_internal_person_only": "Nur interne Personen", "private_product_point": "Besitzen Sie Ihre APITable-Plattform mit einem Klick", "privatized_deployment": "Selbsthosted", @@ -4032,13 +4188,15 @@ "reconciled_data": "Daten werden abgeglichen", "record": "Aufzeichnung", "record_activity_experience_tips": "Sie können Aufzeichnungsaktivitäten von ${day} Tagen anzeigen", + "record_archived_data": "archivierter Datensatz", + "record_chunk_text": "${text} rows, please wait", "record_comment": "Nur Kommentare", "record_comments": "Kommentare", "record_fail_data": "Datenfehler", "record_filter_tips": "Dieser Datensatz wurde gefiltert", "record_functions": "Aufzeichnungsfunktion", "record_history": "Nur Revisionsverlauf", - "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-history", + "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-activity", "record_history_title": "Aufzeichnungsverlauf", "record_pre_filtered": "Dieser Datensatz wurde gefiltert und wird ausgeblendet, sobald Sie außerhalb des Datensatzes klicken", "record_pre_move": "Dieser Datensatz wird an eine andere Stelle verschoben, sobald Sie außerhalb des Datensatzes klicken", @@ -4478,6 +4636,12 @@ "scan_to_login": "Scannen, um sich anzumelden", "scan_to_login_by_method": "Bitte scannen Sie ${method}, um dem offiziellen Konto zu folgen, um sich anzumelden", "scatter_chart": "Streudiagramm", + "schedule_day_tips": "Die Zyklusberechnung beginnt mit dem Zählen ab dem ersten Tag jedes Monats. Wenn wir davon ausgehen, dass es sich alle 10 Tage wiederholt, dann wird es am 1., 11., 21. und 31. Tag jedes Monats ausgelöst", + "schedule_hour_tips": "Die Zyklusberechnung beginnt jeden Tag um Mitternacht (0:00). Unter der Annahme, dass alle drei Stunden 0 Minuten wiederholt werden, geschieht dies täglich um Mitternacht (0:00), 3 Uhr, 6 Uhr, 9 Uhr, 12 Uhr (12 Uhr), 15 Uhr, 18 Uhr und schließlich bei Einbruch der Dunkelheit (21 Uhr).", + "schedule_start_day": "Ab dem 1. Tag des Monats jeden", + "schedule_start_month": "Ab Januar jedes Jahres, jeden", + "schedule_type": "Zeitplantyp", + "schedule_year_tips": "Die Zyklusberechnung beginnt mit dem Zählen ab dem ersten Monat eines jeden Jahres. Unter der Annahme eines Intervalls von drei Monaten am ersten Tag werden Auslöser jedes Jahr am ersten Tag im Januar, April, Juli und Oktober um Mitternacht aktiviert.", "science_and_technology": "Wissenschaft und Technologie", "scroll_screen_down": "Einen Bildschirm nach unten scrollen", "scroll_screen_left": "Einen Bildschirm nach links scrollen", @@ -4491,6 +4655,7 @@ "search_folder_or_sheet": "Dateien suchen", "search_new_admin": "Suche", "search_node_pleaseholder": "Nach Dateien suchen (${shortcutKey})", + "search_node_tip": "Schnellsuche (${shortcutKey})", "search_or_add": "Eine Option suchen oder hinzufügen", "search_role_placeholder": "Rollen suchen", "seats": "Sitze", @@ -4894,6 +5059,7 @@ "space_info": "Übersicht", "space_info_del_confirm1": "1. Wenn Sie diesen Bereich löschen, werden die folgenden Daten bereinigt:", "space_info_del_confirm2": "2. Der Space wird nach sieben Tagen vollständig gelöscht. Sie können den Space vorher wiederherstellen.", + "space_info_del_confirm3": "3. For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "space_info_feishu_desc": "Sie verwenden eine Drittanbieterintegration. Um den Space zu löschen, deaktivieren Sie bitte zuerst die Integration von Drittanbietern.", "space_info_feishu_label": "Integrationen", "space_join_apply": " wurde angefordert, dem \"\" Raum beizutreten.", @@ -4980,6 +5146,7 @@ "start_onfiguration": "Konfiguration starten", "start_time": "Startzeit", "start_use": "Verwendung starten", + "starting_from_midnight": "Ab Mitternacht (00:00 Uhr) jeden Tag, jeden Tag", "startup": "Inbetriebnahme", "startup_company_support_program": "Starthilfeprogramm", "stat_average": "Durchschnittlich", @@ -5013,6 +5180,8 @@ "stay_tuned_for_more_features": "Bleiben Sie dran für weitere Funktionen", "steps_choose_reset_mode": "Wählen Sie eine Reset-Methode", "steps_validate_identities": "Identität überprüfen", + "stop_chunk_content": "Are you sure you want to stop the operation?", + "stop_chunk_title": "Stop", "stop_dingtalk_h5_modal_content": "Die selbst erstellte Anwendung wird von diesem Raum entbunden. Bitte bestätigen Sie .", "storage_per_seats": "", "storage_per_space": "Speichernutzung", @@ -5043,9 +5212,11 @@ "subscribe_credit_usage_over_limit": "Die Anzahl der Guthaben, die in diesem Bereich sind, die das Limit überschreiten, werden verwendet.\n", "subscribe_demonstrate": "Demos anfordern", "subscribe_disabled_seat": "Die Anzahl der Personen darf nicht niedriger sein als das ursprüngliche Programm", + "subscribe_grade_business": "Geschäft", "subscribe_grade_free": "Frei", "subscribe_grade_plus": "Plus", "subscribe_grade_pro": "Profi", + "subscribe_grade_starter": "Anlasser", "subscribe_label_tooltip": "Erweiterte Raumfunktionen", "subscribe_new_choose_member": "Unterstützt bis zu ${member_num} Members", "subscribe_new_choose_member_tips": "Dieser Plan unterstützt 1~${member_num} Mitglieder, um den Raum zu betreten", @@ -5182,7 +5353,7 @@ "template_name_repetition_title": "\"${templateName}\" existiert bereits. Wollen Sie es ersetzen?", "template_no_template": "Keine Vorlagen", "template_not_found": "Sie können die gewünschten Vorlagen nicht finden? Sagen Sie uns", - "template_recommend_title": "Heiß", + "template_recommend_title": "🌟 Hot", "template_type": "Vorlage", "terms_of_service": "", "terms_of_service_pure_string": "Nutzungsbedingungen", @@ -5226,6 +5397,7 @@ "text_editor_tip_end": "\"Enter\" zum Beenden der Bearbeitung", "text_functions": "Zeichenfolgenfunktion", "thailand": "Thailand", + "the_button_field_is_misconfigured": "Das Schaltflächenfeld ist falsch konfiguriert. Bitte überprüfen Sie es und versuchen Sie es erneut", "the_current_automation_workflow_has_no_related_files_you_can_establish_a_link_by_adding_trigger_conditions_and_actions_on_the_left_side": "Der aktuelle Automatisierungsprozess hat keine verwandten Dokumente. Sie können eine Verbindung herstellen, indem Sie Triggerbedingungen und -Aktionen auf der linken Seite hinzufügen", "the_current_button_column_has_expired_please_reselect": "Die aktuelle Schaltflächenspalte ist abgelaufen. Bitte wählen Sie sie erneut aus", "the_last_7_days": "die letzten sieben Tage", @@ -5328,6 +5500,7 @@ "timemachine_update_comment": "aktualisierte(r) Kommentar(e)", "times_per_month_unit": "Aufruf/Monat", "times_unit": "Aufruf(e)", + "timing_rules": "Zeitliche Koordinierung", "timor_leste": "Timor-Leste", "tip_del_success": "Sie können Ihren Space innerhalb von 7 Tagen wiederherstellen", "tip_do_you_want_to_know_about_field_permission": "Möchten Sie Felddaten verschlüsseln? Erfahren Sie mehr über Feldberechtigungen", @@ -5515,6 +5688,7 @@ "verify_account_title": "Konto verifizieren", "verify_via_email": "Identitätsprüfung per E-Mail", "verify_via_phone": "Identitätsprüfung per SMS", + "video": "Video", "video_not_support_play": "Das aktuelle Videoformat unterstützt keine Online-Wiedergabe", "vietnam": "Vietnam", "view": "Ansicht", @@ -5863,7 +6037,8 @@ "workdoc_color_title": "Schriftfarbe", "workdoc_create": "Arbeitsdokument erstellen", "workdoc_expanded": "Erweitern Sie das Inhaltsverzeichnis", - "workdoc_image_max_10mb": "Die Bildgröße darf 10 MB nicht überschreiten", + "workdoc_image_max_10mb": "Null", + "workdoc_image_max_size": "Die Bildgröße darf ${size} nicht überschreiten", "workdoc_info": "WorkDoc Info", "workdoc_info_create_time": "Hergestellt in", "workdoc_info_creator": "Erstellt von", @@ -5871,6 +6046,7 @@ "workdoc_info_last_modify_time": "Zuletzt geändert um", "workdoc_link_placeholder": "Bitte geben Sie den Link ein", "workdoc_only_image": "Es ist nur ein Bild erlaubt", + "workdoc_only_video": "Es sind nur Videos erlaubt", "workdoc_text_placeholder": "Geben Sie „/“ Schnellstart ein", "workdoc_title_placeholder": "Bitte Titel eingeben", "workdoc_unnamed": "Unbenanntes Arbeitsdokument", @@ -5879,9 +6055,11 @@ "workdoc_unsave_ok": "Änderungen verwerfen", "workdoc_unsave_title": "Das WorkDoc wurde nicht gespeichert", "workdoc_upload_failed": "Upload fehlgeschlagen", + "workdoc_video_max_size": "Die Videogröße darf ${size} nicht überschreiten", "workdoc_ws_connected": "In Verbindung gebracht", "workdoc_ws_connecting": "Verbinden...", "workdoc_ws_disconnected": "Getrennt", + "workdoc_ws_reconnecting": "Verbindung wird wieder hergestellt...", "workflow_execute_failed_notify": " konnte bei nicht ausgeführt werden. Bitte überprüfen Sie den Ausführungsverlauf, um das Problem zu beheben. Wenn Sie Hilfe benötigen, wenden Sie sich bitte an unser Kundendienstteam.", "workspace_data": "Weltraumdaten", "workspace_files": "Workbench-Daten", diff --git a/packages/datasheet/public/file/langs/strings.en-US.json b/packages/datasheet/public/file/langs/strings.en-US.json index f13c435a1e..abcc70113a 100644 --- a/packages/datasheet/public/file/langs/strings.en-US.json +++ b/packages/datasheet/public/file/langs/strings.en-US.json @@ -58,7 +58,7 @@ "add_cover": "Add cover", "add_dashboard": "New dashboard", "add_datasheet_editor": "In addition to \"Update-only\", can also add or delete views and delete records", - "add_datasheet_manager": "Can perform all actions on the file", + "add_datasheet_manager": "Can perform all actions on the file node", "add_datasheet_reader": "Can read data or comment on the datasheet", "add_datasheet_updater": "Can read, add and edit records except deleting records", "add_editor": "Editor", @@ -66,9 +66,9 @@ "add_filter": "Add filter", "add_filter_condition_tips": "Pick a field to Filter", "add_filter_empty": "Pick another field to Filter", - "add_folder_editor": "In addition to \"Update-only\", can also edit and share files", - "add_folder_manager": "Can perform all actions to the file", - "add_folder_reader": "Can read files in the folder", + "add_folder_editor": "In addition to \"Update-only\", can also edit and share file nodes", + "add_folder_manager": "Can perform all actions to the file node", + "add_folder_reader": "Can read file nodes in the folder", "add_folder_updater": "Can read, add and edit records except deleting records", "add_form": "New form", "add_form_logo": "Add logo", @@ -117,7 +117,7 @@ "add_sub_admin_template_configuration": "The sub-admin can delete the Space templates", "add_sub_admin_title_member_team": "Members and teams ", "add_sub_admin_title_workbench": "Workbench", - "add_sub_admin_workbench_configuration": "The sub-admins have the highest authority of all files in \"Workbench\", and can add, delete, modify and set permissions on files", + "add_sub_admin_workbench_configuration": "The sub-admins have the highest authority of all file nodes in \"Workbench\", and can add, delete, modify and set permissions on file nodes", "add_summry_describle": "Add summary describe", "add_target_values": "Add target value", "add_team": "Add team", @@ -146,6 +146,15 @@ "agreed": "Approved", "ai_advanced_mode_desc": "Advanced mode allows users to customize prompts, providing greater control over the behavior and responses of the AI agent.", "ai_advanced_mode_title": "Advanced mode", + "ai_agent_anonymous": "Anonymous${ID}", + "ai_agent_conversation_continue_not_supported": "Continuing a previous conversation is not currently supported", + "ai_agent_conversation_list": "Conversation list", + "ai_agent_conversation_log": "Conversation Log", + "ai_agent_conversation_title": "Conversation title", + "ai_agent_feedback": "Feedback", + "ai_agent_historical_message": "The above is historical message", + "ai_agent_history": "History", + "ai_agent_message_consumed": "Message consumed", "ai_api_curl_template": "## Create chat completions\n\n```bash\n\ncurl -X POST \"{{apiBase}}/fusion/v1/ai/{{aiId}}/chat/completions\" \\\n -H \"Content-Type: application/json\" \\\n -H \"Authorization: Bearer {{token}}\" \\\n -d '{\n \"model\": \"gpt-3.5-turbo\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"You are a helpful assistant.\"\n },\n {\n \"role\": \"user\",\n \"content\": \"Hello!\"\n }\n ]\n }'\n\n```\n\n## Returned data example\n\n```json\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", "ai_api_footer_desc": "Embed the AI agent into your website? Learn more", "ai_api_javascript_template": "## Initialize SDK [![github]({{ githubIcon }})](https://github.com/openai/openai-node)\nAITable's chat completion API is compatible with OpenAI's Node.js SDK. You can use our service with the same SDK by simply changing the configuration as follows:\n\n\n```javascript\nconst { Configuration, OpenAIApi } = require(\"openai\");\nconst configuration = new Configuration({\n apiKey: \"{{token}}\",\n basePath: \"{{apiBase}}/fusion/v1/ai/{{aiId}}\"\n});\n```\n\n## Create chat completions\n\n```javascript\nconst openai = new OpenAIApi(configuration);\nconst chatCompletion = await openai.createChatCompletion({\n model: \"gpt-3.5-turbo\",\n messages: [{role: \"user\", content: \"Hello world\"}],\n});\n```\n\n## Returned data example\n\n```javascript\n\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", @@ -161,6 +170,9 @@ "ai_chat_unit": "aibot(s)", "ai_close_setting_tip_content": "You have made changes. Do you want to discard them?", "ai_close_setting_tip_title": "Unsaved changes", + "ai_copilot_generate_response": "Generating answer for you...", + "ai_copilot_processs": "Processing, please wait...", + "ai_copilot_start_process_request": "Starting to process your request...", "ai_create_guide_btn_text": "Select datasheet", "ai_create_guide_content": "As an AI agent, I can answer your questions based on the knowledge I have learned. Before starting the conversation, please select a datasheet as a knowledge base, and I will read all the data in it for learning.", "ai_credit_cost_chart_title": "Message credit", @@ -424,7 +436,7 @@ "api_param_api_btn_type_error": "the parameter apiBtn must be a boolean type", "api_param_attachment_array_type_error": "Attachment type must be array", "api_param_attachment_name_type_error": "Attachment name must be string", - "api_param_attachment_not_exists": "The file specified by the token does not exist", + "api_param_attachment_not_exists": "The attachment specified by the token does not exist", "api_param_attachment_token_type_error": "Attachment token must be string", "api_param_basic_tools_type_error": "the parameter bannerLogo must be a boolean type", "api_param_checkbox_field_type_error": "field:{field} Checkbox field value must be boolean", @@ -622,11 +634,11 @@ "apply_space_beta_feature_success_notify_all": "'s application for enabling the beta feature \"\" has been approved. For details, go to \"Account\" -> \"Experimental features\".", "apply_space_beta_feature_success_notify_me": "Your application for enabling the beta feature \"\" has been approved. For details, go to \"Account\" -> \"Beta Feature\".", "apply_template": "Use template", - "appoint_permission_tip": "Only members below have access to this file", + "appoint_permission_tip": "Only members below have access to this file node", "apps_support": "All-platform client support", "archive_delete_record": "Delete archived records", "archive_delete_record_title": "Delete record", - "archive_notice": "

You are trying to archive specific records. Archiving the records will result in the following changes:

1. All two-way link for this record will be canceled

2. Editing is not supported

3. Functions such as date reminders and subscribe records are not supported

4. No longer participate in the calculation of lookup, formula and other fields

Are you sure you want to continue? (You can unarchive in Archive Box in Advanced)

", + "archive_notice": "

You are trying to archive specific records. Archiving the records will result in the following changes:

1. Editing is not supported

2. Functions such as date reminders and subscribe records are not supported

3. No longer participate in the calculation of lookup, formula and other fields

Are you sure you want to continue? (You can unarchive in Archive Box in Advanced)

", "archive_record_in_activity": " archived this record", "archive_record_in_menu": "Archive record", "archive_record_success": "Successfully archived records", @@ -684,30 +696,36 @@ "attachment_upload_fail": "Failed to upload ${count} attachment(s)", "audit_add_field_role": "Add field permissions", "audit_add_field_role_detail": "In the \"\" datasheet , add [] role as [] for the field [] ", - "audit_add_node_role": "Add file permissions", - "audit_add_node_role_detail": "Add file permission,set「${unitNames}」to「${role}」of 「${currentNodeName}」", + "audit_add_node_role": "Add file node permissions", + "audit_add_node_role_detail_end": "to「${role}", + "audit_add_node_role_detail_start": "Add file node permission,set「${unitNames}」", "audit_admin_permission_change_event": "Change admin permissions", "audit_create_template": "Create template", "audit_create_template_detail": "Create template", "audit_datasheet_field_permission_change_event": "Field permissions changed", "audit_delete_field_role": "Delete field permissions", "audit_delete_field_role_detail": "Audit", - "audit_delete_node_role": "Delete file permission", - "audit_delete_node_role_detail": "Delete file permission,delete「${unitNames}」`s 「${role}」role of 「${currentNodeName}」", + "audit_delete_node_role": "Delete file node permission", + "audit_delete_node_role_detail_end": "at 「${role}」role", + "audit_delete_node_role_detail_start": "Delete file node permission,delete「${unitNames}」from", "audit_delete_template": "Delete template", "audit_delete_template_detail": "Delete template", "audit_disable_field_role": "Disable field permissions", "audit_disable_field_role_detail": "Audit", - "audit_disable_node_role": "Disable file permissions", - "audit_disable_node_role_detail": "Disable ${nodeType} 「${currentNodeName}」 `s permission", - "audit_disable_node_share": "Close file public link", - "audit_disable_node_share_detail": "Close ${nodeType} 「${currentNodeName}」 public link", + "audit_disable_node_role": "Disable file node permissions", + "audit_disable_node_role_detail_end": "`s permission", + "audit_disable_node_role_detail_start": "Disable ${nodeType}", + "audit_disable_node_share": "Close file node public link", + "audit_disable_node_share_detail_end": "public link", + "audit_disable_node_share_detail_start": "Close ${nodeType}", "audit_enable_field_role": "Enable field permissions", "audit_enable_field_role_detail": "Audit", - "audit_enable_node_role": "Enable file permissions", - "audit_enable_node_role_detail": "Enable ${nodeType} 「${currentNodeName}」 `s permission", - "audit_enable_node_share": "Open file public link", - "audit_enable_node_share_detail": "Open ${nodeType} 「${currentNodeName}」 public link", + "audit_enable_node_role": "Enable file node permissions", + "audit_enable_node_role_detail_end": "`s permission", + "audit_enable_node_role_detail_start": "Enable ${nodeType}", + "audit_enable_node_share": "Open file node public link", + "audit_enable_node_share_detail_end": "public link", + "audit_enable_node_share_detail_start": "Open ${nodeType}", "audit_login_event": "Login event", "audit_logout_event": "english", "audit_organization_change_event": "The organizational structure of the contacts has changed", @@ -726,20 +744,21 @@ "audit_space_entry_workbench_detail": "Member ${member_name} joined the space \n${space_name}", "audit_space_invite_user": "Audit", "audit_space_invite_user_detail": "Audit", - "audit_space_node_copy": "Duplicate file", - "audit_space_node_copy_detail": "Duplicate ${nodeType} 「${sourceNodeName}」, the new file's name is 「${currentNodeName}」", - "audit_space_node_create": "Create file", - "audit_space_node_create_detail": "Create a ${nodeType} named 「${currentNodeName}」", - "audit_space_node_delete": "Delete file", - "audit_space_node_delete_detail": "Delete ${nodeType} named 「${currentNodeName}」", + "audit_space_node_copy": "Duplicate file node", + "audit_space_node_copy_detail_start": "Duplicate ${nodeType} 「${sourceNodeName}」, the new file node's name is", + "audit_space_node_create": "Create file node", + "audit_space_node_create_detail_start": "Create a ${nodeType} named", + "audit_space_node_delete": "Delete file node", + "audit_space_node_delete_detail_start": "Delete ${nodeType} named", "audit_space_node_export": "Export datasheet", "audit_space_node_export_detail": "Member ${member_name} exported datsheet ${node_name}", - "audit_space_node_import": "Import file", - "audit_space_node_import_detail": "Import a file named 「${nodeName}」", - "audit_space_node_move": "Move file", - "audit_space_node_move_detail": "Move ${nodeType} 「${currentNodeName}」to the folder「${parentName}」", - "audit_space_node_rename": "Rename file", - "audit_space_node_rename_detail": "Rename ${nodeType} 「${oldNodeName}」to 「${nodeName}」", + "audit_space_node_import": "Import file node", + "audit_space_node_import_detail_start": "Import a file node named", + "audit_space_node_move": "Move file node", + "audit_space_node_move_detail_end": "to the folder「${parentName}」", + "audit_space_node_move_detail_start": "Move ${nodeType}", + "audit_space_node_rename": "Rename file node", + "audit_space_node_rename_detail_start": "Rename ${nodeType} 「${oldNodeName}」to", "audit_space_node_sort": "Audit", "audit_space_node_sort_detail": "Audit", "audit_space_node_update_cover": "Audit", @@ -752,19 +771,22 @@ "audit_space_rename_detail": "Audit", "audit_space_rubbish_node_delete": "Audit", "audit_space_rubbish_node_delete_detail": "Audit", - "audit_space_rubbish_node_recover": "Restore files", - "audit_space_rubbish_node_recover_detail": "Restore ${nodeType} 「${currentNodeName}」 form the trash", + "audit_space_rubbish_node_recover": "Restore file nodes", + "audit_space_rubbish_node_recover_detail_end": "from the trash", + "audit_space_rubbish_node_recover_detail_start": "Restore ${nodeType}", "audit_space_template_event": "Template change", "audit_space_update_logo": "Audit", "audit_space_update_logo_detail": "Audit", - "audit_store_share_node": "Save shared file", - "audit_store_share_node_detail": "Restore ${nodeType} to the space, name is 「${nodeName}」", + "audit_store_share_node": "Save shared file node", + "audit_store_share_node_detail_start": "Restore ${nodeType} to the space, name is", "audit_update_field_role": "Audit", "audit_update_field_role_detail": "Audit", - "audit_update_node_role": "Modify file permission", - "audit_update_node_role_detail": "Modify file permission,modify「${unitNames}」`s role to「${role}」of 「${currentNodeName}」", - "audit_update_node_share_setting": "Modify file public link settings", - "audit_update_node_share_setting_detail": "Modify ${nodeType} 「${currentNodeName}」 public link", + "audit_update_node_role": "Modify file node permission", + "audit_update_node_role_detail_end": "to「${role}」role", + "audit_update_node_role_detail_start": "Modify file node permission,modify「${unitNames}」from", + "audit_update_node_share_setting": "Modify file node public link settings", + "audit_update_node_share_setting_detail_end": "public link settings", + "audit_update_node_share_setting_detail_start": "Modify ${nodeType}", "audit_user_login": "User login", "audit_user_login_detail": "Audit", "audit_user_logout": "User logout", @@ -774,7 +796,7 @@ "audit_user_quit_space_detail": "Audit", "audit_work_catalog_change_event": "english", "audit_work_catalog_permission_change_event": "Explorer permissions changed", - "audit_work_catalog_share_event": "Sharing events of files in Explorer", + "audit_work_catalog_share_event": "Sharing events of file nodes in Explorer", "augmented_views": "Augmented Views", "australia": "Australia", "austria": "Austria", @@ -803,9 +825,10 @@ "automation_editor_label": "Can edit steps in automation and viewing the run history of the automation", "automation_empty_warning": "Automation cannot be empty", "automation_enabled": "Automation is enabled", - "automation_enabled_return_via_related_files": "Automation is enabled. Please re-enter the original table via \"Related Files\" to use the new button.", + "automation_enabled_return_via_related_files": "Automation is enabled. Please re-enter the original table via \"Related File nodes\" to use the new button.", "automation_field": "Field", "automation_import_variables_from_pre_tep": "Get data from the pre-step", + "automation_is_not_yet_enabled": "Automation is not yet enabled, please enable it and try again", "automation_last_edited_by": "Last edited by", "automation_last_edited_time": "Last edited time", "automation_manager_label": "Can perform all actions on the automation", @@ -927,10 +950,19 @@ "button_text": "Button text", "button_text_click_start": "Click to Start", "button_type": "Button Type", + "by_at": "at", + "by_days": "Days", + "by_every": "every", "by_field_id": "Use field ID", + "by_hours": "Hours", + "by_in": " at", + "by_min": "minute(s)", + "by_months": "Months", + "by_on": " on the", "by_the_day": "By day", "by_the_month": "Monthly", "by_the_year": "Yearly", + "by_weeks": "Weeks", "calendar_add_date_time_field": "Create Date field", "calendar_color_more": "More colors", "calendar_const_detail_weeks": "[\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\",\"Sunday\"]", @@ -993,7 +1025,15 @@ "cannot_access": "Can Access", "cannot_activate_space_by_space_limit": "cannot_activate_space_by_space_limit", "cannot_join_space": "You can't join a new space station because you've exceeded the maximum quota of 10 space stations.", - "cannot_switch_field_permission": "Set field permissions not higher than the file permissions. ", + "cannot_switch_field_permission": "Set field permissions not higher than the file node permissions. ", + "capacity_file_detail_desc": "The total number of file nodes within the Space is calculated by adding the file nodes from the Team to the file nodes created by each member in their Private. Not enough capacity?", + "capacity_file_detail_title": "File Capacity", + "capacity_file_member": "Member", + "capacity_file_member_private_node_count": "Private", + "capacity_file_member_private_percent": "Percent", + "capacity_file_member_team": "Team", + "capacity_file_member_team_node_count": "Team", + "capacity_file_upgrade": "Click to upgrade your Space", "capacity_from_official_gift": "From the official gift", "capacity_from_participation": "By invited ${user} join the space", "capacity_from_purchase": "By purchasing capacity", @@ -1029,7 +1069,9 @@ "cascader_undefined_field_error": "There exists unselected field. Please select the field and try again", "catalog": "Explorer", "catalog_add_from_template_btn_title": "Add from templates", - "catalog_empty_tips": "This workspace is empty now. Get started by using templates to create files.", + "catalog_empty_tips": "This workspace is empty now. Get started by using templates to create file nodes.", + "catalog_private": "Private", + "catalog_team": "Team", "category_blank": "[Blank]", "catering": "Catering", "cayman_islands": "Cayman Islands", @@ -1098,6 +1140,7 @@ "choose_type_of_vika_field": "Select field type", "choose_your_own_space": "(Only supports saving to your own space as creator)", "chose_new_primary_admin_button": "Assign", + "chunk_stopping_title": "Stopping", "claim_special_offer": "Claim This Special Offer!", "clear": "Clear", "clear_all_fields": "Clear all", @@ -1117,9 +1160,9 @@ "click_top_right_to_share": "Click on the top right to share", "click_upload_tip": "Click here to paste an attachment", "client_meta_label_desc": "APITable - a data productivity platform that helps you manage your work data more efficiently", - "client_meta_label_file_deleted_desc": "The shared file is deleted, so the public share link is invalid", - "client_meta_label_file_deleted_title": "Invalid shared file", - "client_meta_label_share_disable_desc": "The shared public link is disabled so you can't access the file", + "client_meta_label_file_deleted_desc": "The shared file node is deleted, so the public share link is invalid", + "client_meta_label_file_deleted_title": "Invalid shared file node", + "client_meta_label_share_disable_desc": "The shared public link is disabled so you can't access the file node", "client_meta_label_share_disable_title": "Can't access", "client_meta_label_template_deleted_desc": "The template does not exist or is deleted, so the share link is invalid", "client_meta_label_template_deleted_title": "Invalid shared template", @@ -1135,7 +1178,7 @@ "close_node_share_modal_content": "After disabling the sharing, the generated share link will become invalid", "close_node_share_modal_title": "Close the sharing of this node", "close_permission": "Restore default", - "close_permission_warning_content": "all members and teams will see the file, and the set permissions will be closed at the same time", + "close_permission_warning_content": "all members and teams will see the file node, and the set permissions will be closed at the same time", "close_public_link_success": "Disable public link successfully", "close_share_link": "Disable public link", "close_share_tip": "Disable sharing ${status}", @@ -1228,6 +1271,7 @@ "confirm_del_current_team": "Are you sure you want to delete the team?", "confirm_delete": "Confirm and delete", "confirm_delete_node_name_as": "Are you sure you want to delete \"${nodeNameDiv}\"?", + "confirm_delete_private_node_name_as": "Are you sure you want to delete \"${nodeNameDiv}\"? The file will be deleted from the Space and the trash.", "confirm_delete_space_btn": "Confirm and delete Space", "confirm_exit": "Confirm to exit", "confirm_exit_space_with_name": "Confirm whether to exit the \"${spaceNameDiv}\" Space", @@ -1265,6 +1309,14 @@ "convert": "Convert", "convert_tip": "This action may clear up data in some cells. You can undo the action if anything unexpected happens.", "cook_islands": "Cook Islands", + "copilot_auto_agent_desc": "Not sure which one to choose Agent? Try AutoAgent.", + "copilot_auto_agent_name": "Auto Agent", + "copilot_data_agent_desc": "generate visualizations/data analysis based on your views.", + "copilot_data_agent_name": "Data Agent", + "copilot_data_agent_policy": "When chatting with Copilot, you agree to the user terms policy", + "copilot_data_agent_policy_button": "Policy", + "copilot_help_agent_desc": "Ask anything about AITable's help center documents .", + "copilot_help_agent_name": "Retrieve Help Center", "copy": " Copy", "copy_automation_url": "Copy URL", "copy_card_link": "Copy record URL", @@ -1299,7 +1351,7 @@ "create": "Create", "create_and_save": "Create and save", "create_date": "Creation date", - "create_file_and_folder": "Create a new file or folder", + "create_file_and_folder": "Create a new file node or folder", "create_form": "Create form", "create_form_panel_title": "Select a datasheet to store form data", "create_invitation_link": "Create Invitation Link", @@ -1309,6 +1361,7 @@ "create_mirror_guide_content": "The mirror function has the ability to hide certain data. You can set \"filter conditions\" and \"hidden fields\" in the original datasheet view to control which records and fields are displayed in the mirror.\n
\n
\nIf used in conjunction with the \"view lock\" function, it can prevent others from making modifications.\n
\n
\nIn addition, you can go to \"Original Table>Hidden Fields\" to modify the configuration for \"Show all fields in Mirrors\".", "create_mirror_guide_title": "Mirror hides some records and fields", "create_new_button_field": "Create a new button column field", + "create_private_node_tip": "Personal or temporary draft documents can be created here ${link}", "create_public_invitation_link": "Create public invitation link(s)", "create_space_sub_title": "Hi, please give a name to your Space~", "create_team_fail": "Create team failed", @@ -1359,7 +1412,7 @@ "current_count_of_person": "Total Seats", "current_datasheet": "Current datasheet", "current_field_fail": "The data went wrong in this field", - "current_file_may_be_changed": "Status of current file has changed", + "current_file_may_be_changed": "Status of current file node has changed", "current_form_is_invalid": "The form is invalid because the original view has been deleted", "current_grade": "Current", "current_main_admin": "Current admin", @@ -1372,10 +1425,12 @@ "custom_enterprise": "Customize enterprise space for you", "custom_function_development": "Custom feature development", "custom_grade_desc": "Provides agent deployment, private installation, assistance support and customized professional services", + "custom_page_setting_title": "Add a custom page", "custom_picture": "Customized picture", "custom_style": "Style", "custom_upload": "Customized upload", "custom_upload_tip": "A 1:1 square size image is recommended for the better visual experience", + "custome_page_title": "Custom Web", "cut_cell_data": "Cut cell(s)", "cyprus": "Cyprus", "czech": "Czech", @@ -1392,7 +1447,7 @@ "datasheet": "Datasheet", "datasheet_1000_rows_limited_tips": "Your datasheet has the maximum number of records", "datasheet_choose_field_type": "Select field type", - "datasheet_count": "Total Files", + "datasheet_count": "Total File nodes", "datasheet_editor_label": "In addition to \"Update-only\", can also add or delete views and delete records", "datasheet_exist_widget": "The datasheet has installed these widgets:", "datasheet_experience_label": "Use the template first, then you can modify or write data", @@ -1427,9 +1482,10 @@ "default": "Default", "default_create_ai_chat_bot": "New AI agent", "default_create_automation": "New automation", + "default_create_custom_page": "New Custom Page", "default_create_dashboard": "New dashboard", "default_create_datasheet": "New datasheet", - "default_create_file": "New file", + "default_create_file": "New file node", "default_create_folder": "New folder", "default_create_form": "New form", "default_create_mirror": "New mirror", @@ -1448,7 +1504,8 @@ "del_invitation_link": "Delete invitation link", "del_invitation_link_desc": "The link will be invalid after deletion", "del_space_now": "Delete Space forever", - "del_space_now_tip": "The Space can't be restored after deletion. All files and attachments will be deleted.", + "del_space_now_confirm_tip": "For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", + "del_space_now_tip": "The Space can't be restored after deletion. All file nodes and attachments will be deleted.", "del_space_res_tip": "The Space deleted", "del_team_success": "Delete Team Success", "del_view_content": "Are you sure you want to delete the ${view_name} view?", @@ -1458,12 +1515,12 @@ "delete_comment_tip_content": "The comment can't be restored after deletion. Continue?", "delete_comment_tip_title": "Delete comment", "delete_completey": "Delete forever", - "delete_completey_fail": "Failed to delete file (folder) forever", + "delete_completey_fail": "Failed to delete file node (folder) forever", "delete_field": "Delete field", "delete_field_success": "Field deleted", "delete_field_tips_content": "Are you sure you want to delete the \"${field_title}\" field?", "delete_field_tips_title": "Delete field", - "delete_file_message_content": "The file has been deleted and you can no longer access it.", + "delete_file_message_content": "The file node has been deleted and you can no longer access it.", "delete_kanban_group": "Delete group", "delete_kanban_tip_content": "All records in this group will be moved to the uncategorized group", "delete_kanban_tip_title": "Delete group", @@ -1562,7 +1619,7 @@ "dingtalk_social_deactivate_tip": "If you need to disable the application, please go to DingTalk Admin Panel -> Applications -> 维格表.", "dingtalk_space_list_item_tag_info": "DingTalk binding", "dingtalk_standard": "Standard Plan with DingTalk", - "dingtalk_sync_address_modal_content": "After manually synchronizing the address book, you need to reassign administrators, file permissions and column permissions for members and departments. Please know", + "dingtalk_sync_address_modal_content": "After manually synchronizing the address book, you need to reassign administrators, file node permissions and column permissions for members and departments. Please know", "dingtalk_tenant_not_exist_tips": "The enterprise didn't authorized, please contact the administrator", "direction_above": "above", "direction_below": "below", @@ -1643,6 +1700,61 @@ "embed_error_page_help": "Learn more", "embed_fail_og_description_content": "The public link for this embed has been disabled and is temporarily unavailable", "embed_failed": "Embed link is unavailable, ", + "embed_link_bilibili": "bilibili", + "embed_link_bilibili_desc": "By embedding the bilibili videos, you can watch tutorials, and guides, or view the channel homepage in Vika.", + "embed_link_bilibili_link_text": "How to embed the bilibili video", + "embed_link_bilibili_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-bilibili-video", + "embed_link_default": "Anything", + "embed_link_default_desc": "Paste a link to view any website. ", + "embed_link_default_link_text": "Learn more", + "embed_link_default_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_link_figma": "Figma", + "embed_link_figma_desc": "By embedding Figma files, members can view and edit design drafts more conveniently, improving collaboration efficiency. ", + "embed_link_figma_link_text": "How to embed Figma files", + "embed_link_figma_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-figma-file", + "embed_link_google_docs": "Docs", + "embed_link_google_docs_desc": "By embedding Google Docs, you can edit and view documents in AITable to facilitate team collaboration.", + "embed_link_google_docs_link_text": "How to embed Google Docs", + "embed_link_google_docs_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-docs-file", + "embed_link_google_sheets": "Sheets", + "embed_link_google_sheets_desc": "By embedding Google Sheets, you can edit and view tables in AITable to facilitate team collaboration. ", + "embed_link_google_sheets_link_text": "How to embed Google Sheets", + "embed_link_google_sheets_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-sheets-file", + "embed_link_jishi_design": "JSdesign", + "embed_link_jishi_design_desc": "By embedding JSdesign files, members can view and edit design drafts more conveniently, improving collaboration efficiency. ", + "embed_link_jishi_design_link_text": "How to embed JSdesign files", + "embed_link_jishi_design_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-js-design-file", + "embed_link_tencent_docs": "Tencent Docs", + "embed_link_tencent_docs_desc": "By embedding Tencent Docs, you can edit and view Tencent docs in Vika to improve collaboration efficiency. ", + "embed_link_tencent_docs_link_text": "How to embed Tencent Docs", + "embed_link_tencent_docs_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-tencent-docs", + "embed_link_wps": "WPS", + "embed_link_wps_desc": "By embedding WPS files, you can edit and view WPS documents, tables, and forms in Vika to improve collaboration efficiency.", + "embed_link_wps_link_text": "How to embed WPS files", + "embed_link_wps_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-wps-file", + "embed_link_youtube": "YouTube", + "embed_link_youtube_desc": "By embedding YouTube videos, you can watch tutorials, and guides, or view the channel homepage in AITable. ", + "embed_link_youtube_link_text": "How to Embed YouTube Videos", + "embed_link_youtube_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-youtube-video", + "embed_page": "Custom Page", + "embed_page_add_url": "Add Url", + "embed_page_doc_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_page_function_desc": "Add web pages into ${edition} for easy access to third-party website documents, videos, and more. You can add recommended website links or any custom links.", + "embed_page_node_permission_editor": "On the basis of \"update only\", can also open the public sharing of the file node", + "embed_page_node_permission_manager": "Can perform all actions on the file node", + "embed_page_node_permission_reader": "Can view the content of the custom page and basic file node information", + "embed_page_node_permission_updater": "On the basis of \"read-only\", can also modify the link of the custom page", + "embed_page_url_invalid": "Please enter the correct URL", + "embed_paste_link_bilibili_placeholder": "Paste the bilibili video link", + "embed_paste_link_default_placeholder": "Paste the URL", + "embed_paste_link_figma_placeholder": "Paste the Figma file’s share link", + "embed_paste_link_google_docs_placeholder": "Paste the Google Docs share link", + "embed_paste_link_google_sheets_placeholder": "Paste the Google Sheets share link", + "embed_paste_link_jsdesign_placeholder": "Paste the JSdesign file’s share link", + "embed_paste_link_tencent_docs_placeholder": "Paste the Tencent Docs share link", + "embed_paste_link_wps_placeholder": "Paste the WPS file’s share link", + "embed_paste_link_youtube_placeholder": "Paste the YouTube video link", + "embed_success": "Add Successfully", "emoji_activity": "Activities", "emoji_custom": "Custom", "emoji_flags": "Flags", @@ -1663,7 +1775,7 @@ "empty_email_tip": "No results, invite a new member via email", "empty_nodes": "Empty", "empty_record": "No records", - "empty_trash": "No files were deleted in the past ${day} days", + "empty_trash": "No file nodes were deleted in the past ${day} days", "enable": "Enable", "enabled_view_lock_success": "View Locked", "enabled_view_lock_tip": "Once the view is locked, it can't be edited until a member who can manage the datasheet unlocks it", @@ -1749,6 +1861,11 @@ "estonia": "Estonia", "ethiopia": "Ethiopia", "event_planning": "Event Planning", + "every": "Every", + "every_day_at": "day(s)", + "every_hour_at": "hour(s)", + "every_month_at": "month(s)", + "every_week_at": "Every Week on", "everyday_life": "Everyday Life", "everyone_visible": "Visible for Everyone", "exact_date": "exact date", @@ -1759,6 +1876,7 @@ "exchange": "Redeem", "exchange_code_times_tip": "Note: The redeem code can be used once only", "exclusive_consultant": "Exclusive V+ consultant", + "exclusive_limit_plan_desc": "Exclusive Limited Tier", "exist_experience": "Exit experience", "exits_space": "Exit space", "expand": "Expand", @@ -1800,8 +1918,8 @@ "faroe_islands": "Faroe Islands", "fashion_and_style": "Fashion and style", "favorite": "Pin", - "favorite_empty_tip1": "Pin files here for quick access.", - "favorite_empty_tip2": "Pinned files are only visible to you", + "favorite_empty_tip1": "Pin file nodes here for quick access.", + "favorite_empty_tip2": "Pinned file nodes are only visible to you", "fee_unit": "yuan", "feedback": "Feedback", "feishu_activity_upgrade_guidance": "", @@ -1850,7 +1968,7 @@ "field_created_by_property_subscription_close_tip": "After closing, the members under the creator column will automatically cancel the records they have followed", "field_created_by_property_subscription_open_tip": "This option only applies to newly created records", "field_desc": "Field description", - "field_desc_attachment": "Add files such as documents, images, and videos, and preview or download them", + "field_desc_attachment": "Add attachments such as documents, images, and videos, and preview or download them", "field_desc_autonumber": "Add a unique and self-increasing number for each record", "field_desc_button": "You can trigger automation or jump to a specified web by clicking a button", "field_desc_cascader": "Using a cascading approach, select pre-options.", @@ -1982,14 +2100,14 @@ "field_title_url": "URL", "field_title_workdoc": "WorkDoc", "field_type": "Field type", - "field_type_attachment_select_cell": "Drop files here", + "field_type_attachment_select_cell": "Drop attachments here", "fiji": "Fiji", - "file": "file", - "file_limits": "${limit} file limits in one space", + "file": "file node", + "file_limits": "${limit} file node limits in one space", "file_name_with_bulk_download": "${fileName}, etc. ${count} files.zip", "file_notification": "Tips", "file_of_rest": "Remaining: ${nodeRest}", - "file_sharing": "File sharing processing...", + "file_sharing": "File node sharing processing...", "file_summary": "Description", "file_upper_bound": "Maximum: ${nodeMax}", "fill_in_completed": "Completed", @@ -2016,14 +2134,14 @@ "fission_reward": "\"Sharing Blessings\" reward from \"${name}\"", "folder": "Folder", "folder_banner_desc": "It is recommended to use pictures with a width larger than 800 px to achieve a better visual experience.", - "folder_contains": "${folders} folders and ${files} files", + "folder_contains": "${folders} folders and ${files} file nodes", "folder_content_empty": "Empty folder", "folder_desc_title_placeholder": "Enter a title", - "folder_editor_label": "In addition to \"Update-only\", can also edit and share files", + "folder_editor_label": "In addition to \"Update-only\", can also edit and share file nodes", "folder_level_2_limit_tips": "Hey, the level of your folder has reached the limit of level-2.", - "folder_manager_label": "In addition to \"Editor\", can also add or delete files", - "folder_permission": "File permissions", - "folder_reader_label": " You can only view the files under this folder and can't edit them.", + "folder_manager_label": "In addition to \"Editor\", can also add or delete file nodes", + "folder_permission": "File node permissions", + "folder_reader_label": " You can only view the file nodes under this folder and can't edit them.", "folder_with_link_share_reminder": "The current folder is associated with external datasheet. Do you want to continue sharing", "folder_with_link_share_view_reminder": "Note: The shared folder has datasheets that link to other datasheets in another folder", "folds_hidden_fields_by_count": "Collapse ${count} hidden field(s)", @@ -2357,26 +2475,26 @@ "gantt_config_color_help": "How to set up", "gantt_config_friday": "Friday", "gantt_config_friday_in_bar": "Fri", - "gantt_config_friday_in_select": "Fri", + "gantt_config_friday_in_select": "Friday", "gantt_config_monday": "Monday", "gantt_config_monday_in_bar": "Mon", - "gantt_config_monday_in_select": "Mon", + "gantt_config_monday_in_select": "Monday", "gantt_config_only_count_workdays": "Duration only counts workdays.", "gantt_config_saturday": "Saturday", "gantt_config_saturday_in_bar": "Sat", - "gantt_config_saturday_in_select": "Sat", + "gantt_config_saturday_in_select": "Saturday", "gantt_config_sunday": "Sunday", "gantt_config_sunday_in_bar": "Sun", - "gantt_config_sunday_in_select": "Sun", + "gantt_config_sunday_in_select": "Sunday", "gantt_config_thursday": "Thursday", "gantt_config_thursday_in_bar": "Thu", - "gantt_config_thursday_in_select": "Thu", + "gantt_config_thursday_in_select": "Thursday", "gantt_config_tuesday": "Tuesday", "gantt_config_tuesday_in_bar": "Tue", - "gantt_config_tuesday_in_select": "Tue", + "gantt_config_tuesday_in_select": "Tuesday", "gantt_config_wednesday": "Wednesday", "gantt_config_wednesday_in_bar": "Wed", - "gantt_config_wednesday_in_select": "Wed", + "gantt_config_wednesday_in_select": "Wednesday", "gantt_config_weekdays_range": "${weekday} to ${weekday}", "gantt_config_workdays_a_week": "Custom standard workdays", "gantt_cycle_connection_warning": "Invalid task dependency, there is a cycle connection\n", @@ -2457,6 +2575,7 @@ "gold_grade": "Gold", "gold_grade_desc": "For teams with complex business process", "gold_seat_200_desc": "200", + "gold_seat_300_desc": "300", "golden_grade": "Gold", "got_it": "Got it", "got_v_coins": "V coins rewarded", @@ -2490,7 +2609,9 @@ "guests_per_space": "Guests per Space", "guide_1": "啊这", "guide_2": "It takes only a few minutes to learn the basic functions. Work more productively from this moment on!", - "guide_flow_of_catalog_step1": "Here is working catalog where all the folders and files of the Space are stored.", + "guide_flow_modal_contact_sales": "Contact Sales", + "guide_flow_modal_get_started": "Get Started", + "guide_flow_of_catalog_step1": "Here is working catalog where all the folders and file nodes of the Space are stored.", "guide_flow_of_catalog_step2": "In the working catalog, you can create a datasheet or a folder as needed.", "guide_flow_of_click_add_view_step1": "In addition to some basic view, you are highly recommended to create an album view if you have attachments in picture format.", "guide_flow_of_datasheet_step1": "This is a list of views that are created for this datasheet. You can create new views here.", @@ -2538,12 +2659,12 @@ "hide_fields_not_go": "Can't go to the hidden field", "hide_graphic_field_tips_in_gantt": "Click to adjust the display fields in the task item", "hide_kanban_grouping": "Hide group", - "hide_node_permission_resource": "Hide no permission file", + "hide_node_permission_resource": "Hide no permission file node", "hide_one_field": "Hide field", "hide_one_graphic_field": "Hide graphic field", "hide_pane": "Hide panel", "hide_uneditable_automation_node": "Hide uneditable automation nodes", - "hide_unmanageable_files": "Hide unmanageable files", + "hide_unmanageable_files": "Hide unmanageable file nodes", "hide_unmanaged_sheet": "Hide unmanageable resource", "hide_unusable_sheet": "Hide uneditable resource", "highlight": "Highlight", @@ -2597,7 +2718,7 @@ "inform": "Report abuse", "inherit_field_permission_tip": "This field is accessible to all members or teams below", "inherit_permission_tip": "Permissons are inherited from the parent folder", - "inherit_permission_tip_root": "All members or teams below can access this file", + "inherit_permission_tip_root": "All members or teams below can access this file node", "inhert_permission_desc": "Members and teams inherit permissions from superior folder \"${nodeName}\" ", "init_roles": "Finance,Marketing,IT,HR,Legal", "initial_size": "Original size", @@ -2668,6 +2789,7 @@ "intro_widget_tips": "What is widget?", "introduction": "Introduction", "invalid_action_sort_tip": "As a grouping field, the sorting of it has been set. The setting of the current order will not take effect.", + "invalid_automation_configuration": "Invalid automation configuration, please check and try again", "invalid_field_type": "Invalid field type", "invalid_option_sort_tip": "As a grouping field, the sorting of it has been set. ", "invalid_redemption_code_entered": "Invalid redeem code", @@ -2798,6 +2920,9 @@ "label_format_day_month_and_year_split_by_slash": "Day/Month/Year", "label_format_month": "Month", "label_format_month_and_day_split_by_dash": "Month-Day", + "label_format_month_day_year_split_by_dash": "Month-Day-Year", + "label_format_month_day_year_split_by_slash": "Month/Day/Year", + "label_format_month_day_year_two_digit_year_split_by_slash": "Month/Day/Year (Two-digit year)", "label_format_year": "Year", "label_format_year_and_month_split_by_dash": "Year-Month", "label_format_year_month_and_day_split_by_dash": "Year-Month-Day", @@ -2827,7 +2952,7 @@ "lark_integration_step1_instructions": "vikadata x Lark Self-Built Application Integration Instructions", "lark_integration_step1_tips": "Tips", "lark_integration_step1_tips_content": "
    \n
  • \n In addition to the build-your-own app approach, we also offer a version of the Lark Store app that is ready to use right out of the box without configuration and binding to the space What's different?\n
  • \n
", - "lark_integration_step1_warning": "
    \n
  • \n

    \n Operators must have administrative access to both vikadata space and Lark\n

    \n

    The operator needs to be the main administrator of the space and also have the permission to create self-built applications in the Lark administration backend

    \n
  • \n
  • \n

    \n The original members of the space will be removed from the space station, and then the member information and department information will be synchronized from the Lark side in one direction\n

    \n

    After Lark integration is enabled, member and department information will be based on the Lark side, so the original member/group information cannot be retained, and related permission information (sub-administrator permission, file permission, column permission, etc.) will be lost, so please let administrators know and make preparations

    \n
  • \n
", + "lark_integration_step1_warning": "
    \n
  • \n

    \n Operators must have administrative access to both vikadata space and Lark\n

    \n

    The operator needs to be the main administrator of the space and also have the permission to create self-built applications in the Lark administration backend

    \n
  • \n
  • \n

    \n The original members of the space will be removed from the space station, and then the member information and department information will be synchronized from the Lark side in one direction\n

    \n

    After Lark integration is enabled, member and department information will be based on the Lark side, so the original member/group information cannot be retained, and related permission information (sub-administrator permission, file node permission, column permission, etc.) will be lost, so please let administrators know and make preparations

    \n
  • \n
", "lark_integration_step2": "Application Credentials", "lark_integration_step2_appid": "App ID", "lark_integration_step2_appsecret": "App Secret", @@ -2876,6 +3001,7 @@ "lark_version_enterprise": "Enterprise Plan with Lark", "lark_version_standard": "Standard Plan with Lark", "lark_versions_free": "Basic Plan with Lark", + "last_day": "Last day", "last_modified_by_select_modal_desc": "If any of the fields you select below are edited, the member who edited most recently will show in the last edited by field", "last_modified_time_select_modal_desc": "If any of the fields you select below are edited, the most recently edited time will show in the last edited time field", "last_step": "Back", @@ -2911,12 +3037,12 @@ "link_to_specific_view": "Link to records from a view", "linked_datasheet": "Linked datasheet", "list": "List", - "list_how_many_folders_and_files": "${folderNumber} Folder, ${fileNumber} files", + "list_how_many_folders_and_files": "${folderNumber} Folder, ${fileNumber} file nodes", "list_of_attachments": "Attachments", "lithuania": "Lithuania", "load_tree_failed": "Failed to load tree resources", "loading": "Loading...", - "loading_file": "Loading files, please wait...", + "loading_file": "Loading file nodes, please wait...", "local_business": "Local Business", "local_data_conflict": "Resources in the process of initialization of data errors, please refresh and retry", "local_drag_upload": "Upload local files", @@ -3020,7 +3146,7 @@ "mail_invite_fail": "Mail invite success.", "mail_invite_success": "Mail invite success.", "main_admin_name": "Admin name", - "main_admin_page_desc": "Admin have full access to the Space, such as assigning sub-admins and transferring ownership of the Space", + "main_admin_page_desc": "Admin have full access to the Space, such as managing members, managing Space settings.", "main_contain": "Main contents", "malawi": "Malawi", "malaysia": "Malaysia", @@ -3101,7 +3227,7 @@ "max_records": "Maximum: ${count}", "max_remain_record_activity_days": "This space supports viewing record activity within ${specification} days, upgrade to view more ", "max_remain_timemachine_days": "The space only shows the record activity within ${specification} days, upgrade to view more record activity.", - "max_remain_trash_days": "This space supports viewing historical files within ${specification} days, upgrade to view more historical files ", + "max_remain_trash_days": "This space supports viewing historical file nodes within ${specification} days, upgrade to view more historical file nodes ", "max_rows_in_space": "The maximum number of records in space is ${specification}. So far, ${usage} records have been created, and you can upgrade to get higher usage.", "max_rows_per_sheet": "The maximum number of records in one datasheet is ${specification}. So far, ${usage} records have been created, and you can upgrade to get higher usage.", "max_seats": "The maximum number of seats in the space is ${specification}, and ${usage} are currently invited, and you can upgrade to get higher usage.", @@ -3114,9 +3240,9 @@ "media_element": "Media Element", "member": "Member", "member_applied_to_close_account": " has requested to delete his accoun", - "member_data_desc_of_appendix": "All attachments uploaded to the Space are counted in. You can't upload any files once the storage reaches its limit.", + "member_data_desc_of_appendix": "All attachments uploaded to the Space are counted in. You can't upload any attachments once the storage reaches its limit.", "member_data_desc_of_dept_number": "Quantity statistics of all teams in the organizational structure (including sub-teams)", - "member_data_desc_of_field_number": "Numbers of all files in the catalog", + "member_data_desc_of_field_number": "Numbers of all files in the catalog & custom templates.", "member_data_desc_of_member_number": "'seats' refers to the number of members joined in the space and AI agents added in workbench.Which means:seats = members+ AI agents", "member_data_desc_of_record_number": "Quantity statistic in all datasheets of working catalog, including the blank record(s)", "member_err": "Nickname cannot exceed 32 characters", @@ -3162,8 +3288,8 @@ "message_exit_space_failed": "Failed to exit the space", "message_exit_space_successfully": "You've exited the space", "message_fields_count_up_to_bound": "The datasheet has reached the upper limit of the field. Unable to create related relations.", - "message_file_size_out_of_upperbound": "The size of a single file cannot exceed 1G", - "message_get_node_share_setting_failed": "Failed to get the sharing settings of the file", + "message_file_size_out_of_upperbound": "The size of a single attachment cannot exceed 1G", + "message_get_node_share_setting_failed": "Failed to get the sharing settings of the file node", "message_hidden_field_desc": "Field descriptions have been hidden", "message_img_size_limit": "The size of the picture should not exceed ${size}", "message_invalid_url": "Invalid address", @@ -3240,10 +3366,14 @@ "more_widget": "More widgets", "morocco": "Morocco", "move": "Move", + "move_datasheet_link_warn": "Cannot be moved to Team Area alone, because there is a two-way link from the current datasheet to another datasheet, it is recommended to put them in a folder and then move them", "move_favorite_node_fail": "Node moving failed. The system will update the list automatically. ", - "move_node_modal_content": "After moving, the visibility of the file may be affected by the parent folder.", + "move_folder_link_warn": "Cannot be moved to Team Area because the files in the current folder are linked to files outside the folder (may be two-way links or linked by forms, etc.) We recommend that they be placed in a folder before moving", + "move_node_modal_content": "After moving, the visibility of the file node may be affected by the parent folder.", + "move_other_link_no_permission": "Unable to move to the corresponding folder because you do not have administrative rights to the folder", + "move_other_link_warn": "It is not allowed to move ${node type} to Team Area alone, because it connects to the datasheet of Private Area, it is recommended to put them in a folder before moving them", "move_to": "Move to", - "move_to_error_equal_parent": "The file is under the current folder. Please select another folder", + "move_to_error_equal_parent": "The file node is under the current folder. Please select another folder", "move_to_modal_title": "Move [${name}] to", "move_to_success": "Move succeeded", "mozambique": "Mozambique", @@ -3272,6 +3402,7 @@ "new_a_line": "Shift+Enter: break line", "new_automation": "New automation", "new_caledonia": "New Caledonia", + "new_custom_page": "New custom page", "new_datasheet": "New datasheet", "new_folder": "New folder", "new_folder_btn_title": "Folder", @@ -3305,7 +3436,7 @@ "nickname_modified_successfully": "Name edited", "niger": "Niger", "nigeria": "Nigeria", - "no_access_node": "The file is hidden", + "no_access_node": "The file node is hidden", "no_access_record": "No access", "no_access_space_descirption": "Unable to access the Space. You might not have the permission or the Space does not exist.", "no_access_space_title": "Note", @@ -3318,9 +3449,9 @@ "no_datasheet_editing_right": "You do not have manageable access to the original datasheet to which the current form is linked and cannot insert fields", "no_editing_rights": "No editing permission", "no_field_role": "You have no access to the field", - "no_file_permission": "The file cannot be accessed", - "no_file_permission_content": "You do not have access to the file or the file has been deleted", - "no_file_permission_message": "The file's permissions have been changed and you cannot access it.", + "no_file_permission": "The file node cannot be accessed", + "no_file_permission_content": "You do not have access to the file node or the file node has been deleted", + "no_file_permission_message": "The file node's permissions have been changed and you cannot access it.", "no_foreignDstId": "Please link to a datasheet", "no_foreign_dst_readable": "No permission to view the related datasheet", "no_link_ds_permission": "No edit permissions for related datasheets", @@ -3359,27 +3490,27 @@ "no_support_pc_sub_desc": "These 4 browsers are recommended: Chrome, Firefox, Safari, and Microsoft Edge", "no_view_create_form": "Can't create a form without a Grid view", "no_view_find": "No results", - "node_info": "File information", + "node_info": "File node information", "node_info_created_time": "Created time:", "node_info_createdby": "Created by:", "node_info_last_modified_by": "Last modified by:", "node_info_last_modified_time": "Last modified time:", "node_name": "Node name", - "node_not_exist_content": "The file you are accessing has no permissions or has been deleted", + "node_not_exist_content": "The file node you are accessing has no permissions or has been deleted", "node_not_exist_title": "Note", - "node_number_err_content": "Your action failed because the Space has reached the maximum number of files", - "node_permission": "File permissions", + "node_number_err_content": "Your action failed because the Space has reached the maximum number of file nodes", + "node_permission": "File node permissions", "node_permission_desc": "The sub-admin will have the access to manage workbench, and to set \"manageable\", \"editable\", and \"read-only\" permissions for other members.", "node_permission_extend_desc": "Permissions inherit from the parent folder", "node_permission_has_been_changed": "Your permission has been changed to \"${nodeRoleName}\"", - "node_permission_item_tips_admin_he": "The administrator of the space who can manage this file", - "node_permission_item_tips_admin_you": "You are the administrator of the space and can manage this file", - "node_permission_item_tips_file_he": "The file manager who can manage this file", - "node_permission_item_tips_file_you": "You are the file manager and can manage this file", - "node_permission_item_tips_other_he": "The ${role} of this file", + "node_permission_item_tips_admin_he": "The administrator of the space who can manage this file node", + "node_permission_item_tips_admin_you": "You are the administrator of the space and can manage this file node", + "node_permission_item_tips_file_he": "The file node manager who can manage this file node", + "node_permission_item_tips_file_you": "You are the file node manager and can manage this file node", + "node_permission_item_tips_other_he": "The ${role} of this file node", "node_permission_item_tips_other_he_edit": ", you can click the menu on the right to modify or remove permission", - "node_permission_item_tips_other_you": "You are the ${role} of this file", - "node_permission_label_space_and_file": "Space & File Manager", + "node_permission_item_tips_other_you": "You are the ${role} of this file node", + "node_permission_label_space_and_file": "Space & File Node Manager", "node_permission_nums": "The maximum number of node permissions to be used in space is ${specification}. So far, ${usage} has been used, and you can upgrade to get higher usage.", "node_with_link_share_reminder": "The current datasheet is associated with the contents of other datasheet. Do you want to continue sharing?", "node_with_link_share_view_reminder": "Note: The shared datasheet has data linked from another datasheet", @@ -3392,7 +3523,7 @@ "not_equal": "is not...", "not_found_field_the_name_as": "Field named \"${value}\" unfound.", "not_found_record_contains_value": "No matches that contain \"${searchValueSpan}\" ", - "not_found_this_file": "The file you are searching for is unfound", + "not_found_this_file": "The file node you are searching for is unfound", "not_found_vika_field_the_name_as": "Column named \"${value}\" unfound", "not_joined_members": "Unactive members", "not_mail_invitee_page_tip": "The current login user is not invitee (${text}).
Please select the corresponding account to enter the space station.", @@ -3438,7 +3569,7 @@ "nvc_start_text": "Drag the bar to the right end", "nvc_yes_text": "Verified", "obtain_verification_code": "Verification code not obtained or expired", - "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrzw0miJVmSkJ7eBBa9k/fomx5qPX0JGPFvfEEP\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", + "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrCvbFC53xc3kl00B4Pg\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", "offical_website_nav_data": "[{\n \"name\": \"产品\",\n \"href\": \"/login\",\n \"children\": [\n {\n \"name\": \"vika维格表 Overview\",\n \"href\": \"/login/\"\n },\n {\n \"name\": \"应用连接 Integration\",\n \"href\": \"/connections/\"\n },\n {\n \"name\": \"客户端(Beta) Download\",\n \"href\": \"/download/\"\n }\n ]\n}, {\n \"name\": \"解决方案\",\n \"href\": \"/\",\n \"children\": [{\n \"name\": \"PMO项目群管理\",\n \"href\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"href\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"href\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"href\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"href\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"href\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"href\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"href\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"href\": \"/shop/\"\n }, {\n \"name\": \"更多解决方案 >\",\n \"href\": \"/solutions/\"\n }]\n}, {\n \"name\": \"模板/案例\",\n \"href\": \"/template\",\n \"children\": [\n {\n \"name\": \"模板中心 Tempaltes\",\n \"href\": \"/template\"\n },\n {\n \"name\": \"客户案例 Customers\",\n \"href\": \"/cases/\"\n }\n ]\n},\n {\n \"name\": \"首页\",\n \"href\": \"/?home=1\"\n },\n {\n \"name\": \"学习资源\",\n \"href\": \"https://edu.vika.cn/index\",\n \"children\": [\n {\n \"name\": \"快速入门 Tutorials\",\n \"href\": \"https://help.vika.cn/docs/guide/tutorial\"\n },\n {\n \"name\": \"产品手册 Manual\",\n \"href\": \"https://help.vika.cn/docs/guide/manual\"\n },\n {\n \"name\": \"维格课堂 Vika Education\",\n \"href\": \"https://edu.vika.cn/\"\n },\n {\n \"name\": \"维格社区 Vika BBS\",\n \"href\": \"https://bbs.vika.cn/\"\n },\n {\n \"name\": \"第三方连接 Integration\",\n \"href\": \"https://help.vika.cn/docs/guide/connection\"\n },\n {\n \"name\": \"开发者中心 Developer Center\",\n \"href\": \"/developers/\"\n },\n {\n \"name\": \"常见问题 FAQ\",\n \"href\": \"https://help.vika.cn/docs/guide/questions\"\n }\n ]\n }]", "office_preview": "Preview Office Files", "office_preview_app_desc": "

Smooth online preview of office files on datasheet, allowing you to view common office files such as Excel, Word, PPT, etc. on your desktop or mobile anywhere, anytime

\n\n
    \n
  • Online preview of .doc, .docx, .xls, .xlsx, .ppt, .pptx, and .pdf formatted office files
  • \n
  • Desktop and mobile both support file previews of the above formats
  • \n
\n\n

Additional notes:

\n
    \n
  • This feature is powered by \"Yoncentric Cloud Conversion\" and officially integrated
  • \n
  • Click the \"Enable\" button below to enable this integration and agree that \"Yoncentric Cloud Conversion\" reads the office files you want to preview
  • \n
  • If you no longer need the office files preview feature, the space admin can disable it on this page
  • \n
", @@ -3478,6 +3609,7 @@ "open_auto_save_success": "Autosave view is turned on successfully", "open_auto_save_warn_content": "All changes under this view are automatically saved and synchronized with other members.", "open_auto_save_warn_title": "Turn on autosave view", + "open_automation_time_arrival": "https://aitable.ai/contact-sales-open-source", "open_failed": "Open failed", "open_in_new_tab": "open in a new tab", "open_invite_after_operate": "Once switched on, all members can invite new members from the contacts panel", @@ -3507,9 +3639,9 @@ "operate_warning": "Action warning", "operated": "Operated", "operation": "Operations", - "operation_log_allow_other_save": "Others can save the file to their own Space", + "operation_log_allow_other_save": "Others can save the file node to their own Space", "operation_log_closed_share": "Sharing disabled", - "operation_log_not_allow_other_save": "Others can't save the file to their own Space", + "operation_log_not_allow_other_save": "Others can't save the file node to their own Space", "operation_log_open_share": "Sharing enabled", "operation_log_update_share": "Share link updated", "operations": "Operations", @@ -3608,8 +3740,8 @@ "password_reset_succeed": "Password reset successfully, and you will log in automatically", "password_rules": "8-24 digits with letters and numbers", "paste": "Paste", - "paste_attachment": "${keyboardShortcut} Paste files here", - "paste_attachment_error": "Please paste the file into an attachment field", + "paste_attachment": "${keyboardShortcut} Paste attachments here", + "paste_attachment_error": "Please paste the attachment into an attachment field", "paste_cell_data": "Paste cell(s)", "paste_tip_add_field": "One or more new fields will be added to this datasheet", "paste_tip_for_add_record": "One or more records will be added to this datasheet", @@ -3624,6 +3756,8 @@ "payment_record": "Payment record", "payment_reminder": "Payment Reminder", "payment_reminder_content": "The new plan you have selected is more deductible than the amount to be paid. It is recommended that you choose the new plan with a longer duration. If you confirm to do so, the excess amount will not be refundable. ${action} if in doubt", + "payment_reminder_modal_content": "You can try the advanced version to enjoy more file nodes, enterprise permissions, attachment capacity, data volume, AI and other advanced features and privileges.", + "payment_reminder_modal_title": "You are currently using the free version", "pending_invite": "Pending invite", "people": " member(s)", "per_person_per_year": "Per person per year", @@ -3644,7 +3778,7 @@ "permission_and_security_content": "Adjust the security level to prevent data leaks", "permission_bound": "Access level", "permission_change_success": "Permission changed", - "permission_config_in_workbench_page": "[{\"key\":0,\"title\":\"About Datasheets\",\"detail\":[{\"title\":\"Edit view settings\",\"permissions\":[0,1,2]},{\"title\":\"Edit view list\",\"permissions\":[0,1,2]},{\"title\":\"Export view data\",\"permissions\":[0,1]},{\"title\":\"Add/Delete/Configure fields\",\"permissions\":[0,1]},{\"title\":\"Edit field layout (width/statistics/order)\",\"permissions\":[0,1,2]},{\"title\":\"Edit records (add/edit records)\",\"permissions\":[0,1,2,3]},{\"title\":\"Delete records\",\"permissions\":[0,1,2]},{\"title\":\"Undo/Redo actions\",\"permissions\":[0,1,2,3]},{\"title\":\"Post a comment\",\"permissions\":[0,1,2,3,4]}]},{\"key\":1,\"title\":\"About Files\",\"detail\":[{\"title\":\"Edit file permissions\",\"permissions\":[0,1]},{\"title\":\"Create files\",\"permissions\":[0,1]},{\"title\":\"Import files\",\"permissions\":[0,1]},{\"title\":\"Export files\",\"permissions\":[0,1]},{\"title\":\"Duplicate files (Need full access to the file and its folder)\",\"permissions\":[0,1]},{\"title\":\"Move files (Need full access to the file and its folder)\",\"permissions\":[0,1]},{\"title\":\"Rename files\",\"permissions\":[0,1]},{\"title\":\"Delete files\",\"permissions\":[0,1]},{\"title\":\"Share files\",\"permissions\":[0,1,2]},{\"title\":\"Add files description\",\"permissions\":[0,1]},{\"title\":\"Save as template\",\"permissions\":[0,1]}]}]", + "permission_config_in_workbench_page": "[{\"key\":0,\"title\":\"About Datasheets\",\"detail\":[{\"title\":\"Edit view settings\",\"permissions\":[0,1,2]},{\"title\":\"Edit view list\",\"permissions\":[0,1,2]},{\"title\":\"Export view data\",\"permissions\":[0,1]},{\"title\":\"Add/Delete/Configure fields\",\"permissions\":[0,1]},{\"title\":\"Edit field layout (width/statistics/order)\",\"permissions\":[0,1,2]},{\"title\":\"Edit records (add/edit records)\",\"permissions\":[0,1,2,3]},{\"title\":\"Delete records\",\"permissions\":[0,1,2]},{\"title\":\"Undo/Redo actions\",\"permissions\":[0,1,2,3]},{\"title\":\"Post a comment\",\"permissions\":[0,1,2,3,4]}]},{\"key\":1,\"title\":\"About File nodes\",\"detail\":[{\"title\":\"Edit file node permissions\",\"permissions\":[0,1]},{\"title\":\"Create file nodes\",\"permissions\":[0,1]},{\"title\":\"Import files\",\"permissions\":[0,1]},{\"title\":\"Export files\",\"permissions\":[0,1]},{\"title\":\"Duplicate file nodes (Need full access to the file node and its folder)\",\"permissions\":[0,1]},{\"title\":\"Move file nodes (Need full access to the file node and its folder)\",\"permissions\":[0,1]},{\"title\":\"Rename file nodes\",\"permissions\":[0,1]},{\"title\":\"Delete file nodes\",\"permissions\":[0,1]},{\"title\":\"Share file nodes\",\"permissions\":[0,1,2]},{\"title\":\"Add file nodes description\",\"permissions\":[0,1]},{\"title\":\"Save as template\",\"permissions\":[0,1]}]}]", "permission_delete_failed": "Failed to delete member(s)/team permission", "permission_delete_success": "Member/team permissions deleted", "permission_edit_failed": "Edit failed", @@ -3656,14 +3790,14 @@ "permission_no_permission_access": "Uneditable", "permission_removed_in_curspace_tip": "Your permission on this Space changed to a member", "permission_setting": "Edit permissions", - "permission_setting_tip": "You can give permissions on this file for members or teams in the Space", + "permission_setting_tip": "You can give permissions on this file node for members or teams in the Space", "permission_settings": "Permission settings", "permission_specific_show": "Specify visibility", "permission_switch_failed": "Failed to switch permission setting mode", "permission_switch_specified": "Enable manual setting", "permission_switch_succeed": "Permission setting mode switched", "permission_switch_to_superior": "Disable manual setting", - "permission_switched_inherit_superior": "After disabled, members and teams will automatically have permission to this file as they have to the superior folder. The already specified permissions will be cleared and cancelled.", + "permission_switched_inherit_superior": "After disabled, members and teams will automatically have permission to this file node as they have to the superior folder. The already specified permissions will be cleared and cancelled.", "permission_switched_reallocate": "After enabled, you can set permissions for specific members or teams", "permission_template_visitor": "Experiencing", "permisson_model_field_owner": "Field owner", @@ -3722,8 +3856,8 @@ "placeholder_select_report_reason": "Please select the reason for the report", "placeholder_set_password": "8-24 digits with letters and numbers", "plan_model_benefits_button": "Viewing Privilege Comparison", - "plan_model_benefits_gold": "1,000 node files per space;\n20,000 records per datasheet;\n500 thousand api call per month;\n200 node files permission per space;\n6 months history to go back;\nattachment capacity increased;\nadvanced views and magic forms increased;", - "plan_model_benefits_sliver": "300 node files per space;\n10,000 records per datasheet;\n100 thousand api call per month;\n6 months history to go back;\nattachment capacity increased;\nadvanced views and magic forms increased;", + "plan_model_benefits_gold": "1,000 file nodes per space;\n20,000 records per datasheet;\n500 thousand api call per month;\n200 file nodes permission per space;\n6 months history to go back;\nattachment capacity increased;\nadvanced views and magic forms increased;", + "plan_model_benefits_sliver": "300 file nodes per space;\n10,000 records per datasheet;\n100 thousand api call per month;\n6 months history to go back;\nattachment capacity increased;\nadvanced views and magic forms increased;", "plan_model_benefits_title": "${space_level} privilege", "plan_model_button": "Pay", "plan_model_choose_members": "Choose seats", @@ -3779,7 +3913,7 @@ "player_step_ui_config_155": "", "player_step_ui_config_156": "{\n \"element\": \".permission_setting_class\",\n \"placement\": \"leftCenter\",\n \"title\": \"Default permissions\",\n \"description\": \"The default permission role is displayed when no permission is specified, and you can assign permissions to members or groups directly here.\",\n \"children\":\"\" \n }", "player_step_ui_config_157": "{\n \"element\": \"#resetPermissionButton\",\n \"placement\": \"topCenter\",\n \"title\": \"Restricted permissions\",\n \"offsetY\": -15,\n \"description\": \"Permissions have been set here, so only the members of the list below are visible. You can click here to restore the default permissions.\",\n \"children\":\"\" \n}", - "player_step_ui_config_158": "{\n \"element\": \"#resetPermissionButton\",\n \"placement\": \"topCenter\",\n \"title\": \"Specify permission role\",\n \"offsetY\": -15,\n \"description\": \"You have modified the permission role of this file again, which means that this file is only visible to the members you specified. You can click \"restore default\" to undo the previous settings.\",\n \"children\":\"\" \n}", + "player_step_ui_config_158": "{\n \"element\": \"#resetPermissionButton\",\n \"placement\": \"topCenter\",\n \"title\": \"Specify permission role\",\n \"offsetY\": -15,\n \"description\": \"You have modified the permission role of this file node again, which means that this file node is only visible to the members you specified. You can click \"restore default\" to undo the previous settings.\",\n \"children\":\"\" \n}", "player_step_ui_config_159": "", "player_step_ui_config_16": "{\n \"element\": \".style_templateItem__1UDe0\"\n}\n", "player_step_ui_config_160": "{\n \"element\": \".permission_setting_class\"\n }", @@ -3793,7 +3927,7 @@ "player_step_ui_config_168": "{\n\"templateKey\":\"createMirrorTip\"\n}", "player_step_ui_config_169": "{\n \"headerImg\": \"https://s4.vika.cn/space/2023/04/04/bcf0695cf35840e6b85e032a8e5ea0a1\",\n \"readMoreUrl\": \"https://help.vika.cn/changelog/23-04-10-updates\",\n \"children\": \"

🚀 Introduction of new functions

\\n
  • New field type \"Cascader\" is launched, making selection from a hierarchy of options on forms easier
  • \"Script\" widget is released, less code for more customization
  • Trigger Automation to send Emails, and get fast notifications
  • Trigger Automation to send a message to Slack, and inform your team in time
  • Exploring AI: \"GPT Content Generator\" Widget Released
\"\n}", "player_step_ui_config_17": "{\n \"element\": \"#TEMPLATE_CENTER_USE_TEMPLATE_BTN>button\", \n\"placement\": \"rightBottom\",\n\"offsetY\": 20,\n \"title\": \"How to use a template\", \n\"description\": \"Click the button on the left to use the template\", \"children\":\"\" \n}", - "player_step_ui_config_176": "{\"title\":\"AI Agent Introduction\",\"video\":\"https://www.youtube.com/embed/cjds1r_roG8?si=irKUpMhwDlOEb8Hc\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", + "player_step_ui_config_176": "{\"title\":\"AITable.ai DEMO\",\"video\":\"https://www.youtube.com/embed/nbqwE21X1hc?si=HYTHEboJtarOL1w8\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", "player_step_ui_config_18": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select>.ant-select-selector\", \n\"placement\": \"bottomLeft\",\n \"title\": \"How to use a template\", \n\"description\": \"Select where to put the template\", \"children\":\"\" \n}", "player_step_ui_config_19": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select .ant-select-selector\"\n}", "player_step_ui_config_2": "{\n \"config\": [\n {\n \"key\": 1,\n \"name\": \"answer1\",\n \"title\": \"What kind of issues are you looking forward to solved by vikadata?\",\n \"type\": \"checkbox\",\n \"answers\": [\n \"Work Planning\",\n \"Customer Service\",\n \"Project Management\",\n \"Sourcing Supply\",\n \"Content Production\",\n \"E-commerce operation\",\n \"Event Planning\",\n \"Human Resources\",\n \"Administration\",\n \"Financial Management\",\n \"Webcast\",\n \"Educational institutes Management\",\n \"Other\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 2,\n \"name\": \"answer2\",\n \"title\": \"Your job title is______\",\n \"type\": \"radio\",\n \"answers\": [\n \"General manager \",\n \"Project manager\",\n \"Product manager\",\n \"Designer\",\n \"R&D engineer\",\n \"Operator, editor\",\n \"Sales, customer service\",\n \"Human resource, administration \",\n \"Finance, accountant\",\n \"Lawyer, legal affairs\",\n \"Marketing\",\n \"Teacher\",\n \"Student\",\n \"Other\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 3,\n \"name\": \"answer3\",\n \"title\": \"What is the name of your company?\",\n \"type\": \"input\",\n \"submit\": false\n },\n {\n \"key\": 4,\n \"name\": \"answer4\",\n \"title\": \"Please leave your email address/ phone number/ Wechat account below so we can reach you in time when you need help.\",\n \"type\": \"input\",\n \"submit\": true\n },\n {\n \"key\": 5,\n \"title\": \"Thank you for filling out the form, you can add our customer service in case of need\",\n \"platform\": {\n \"website\": \"https://s4.vika.cn/space/2023/03/02/b34e3205a9154463be16f497524f1327\",\n \"dingtalk\": \"https://s4.vika.cn/space/2023/03/02/4b16cef6602a4586a21d6346bf25d300\",\n \"wecom\": \"https://s4.vika.cn/space/2023/03/02/60119b1b69b64aa887bd1be6a2928bec\",\n \"feishu\": \"https://u.vika.cn/z9ygm\"\n },\n \"type\": \"contactUs\",\n \"next\": true\n }\n ]\n}\n", @@ -3823,13 +3957,13 @@ "player_step_ui_config_41": "", "player_step_ui_config_42": "{\n \"element\": \"#DATASHEET_FORM_LIST_PANEL\", \n\"placement\": \"leftTop\",\n \"title\": \"Form\", \n\"description\": \"You can quickly create a form from the current view. The number and order of the fields in the form is consistent with the view.\", \"children\":\"\" \n}", "player_step_ui_config_43": "{\n \"element\": \".style_navigation__1U5cR .style_help__1sXEA\", \n\"placement\": \"rightBottom\",\n \"title\": \"Tip\", \n\"offsetY\":5,\n\"description\": \"You can find your Vikaby assistant from the \"Help\" icon on the left\", \"children\":\"\" \n}", - "player_step_ui_config_44": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", + "player_step_ui_config_44": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2023/12/29/212a38dda62f4e52a58a92bf86657705\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", "player_step_ui_config_45": "", "player_step_ui_config_46": "", "player_step_ui_config_47": "{\n \"element\": \"#DATASHEET_WIDGET_BTN\",\n\"placement\": \"bottomRight\",\n \"title\": \"Widget\", \n\"description\": \"Want to use and view your data in a richer way? Try the widget!\", \"children\":\"\" \n}", "player_step_ui_config_48": "", "player_step_ui_config_49": "{\n \"element\": \".style_widgetPanelContainer__1l2ZV\",\n\"placement\": \"leftCenter\",\n \"title\": \"What is a widget\", \n\"description\": \"Vika widgets are an extended application of vikadata that features in richer data visualization, data transfer, data cleansing, and more. By installing widgets in the widget board, you can make work a lot easier.\", \"children\":\"\" \n}", - "player_step_ui_config_5": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", + "player_step_ui_config_5": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", "player_step_ui_config_50": "{\n \"element\": \".style_widgetModal__eXmdB\",\n\"placement\": \"leftTop\",\n \"title\": \"Widget Center\", \n\"description\": \"Officially recommended and custom widgets are published here. You can install any widget you want onto a dashboard or into a widget board of any datasheet.\", \"children\":\"\" \n}", "player_step_ui_config_51": "{\n \"element\": \".style_widgetModal__eXmdB .style_widgetItem__3Pl-1 button\",\n\"placement\": \"rightBottom\",\n \"title\": \"Install widget\", \n\"description\": \"Let's install this \"Chart\" widget\", \"children\":\"\" \n}", "player_step_ui_config_52": "", @@ -3878,7 +4012,7 @@ "player_step_ui_config_91": "{\n \"element\": \"#DATASHEET_TOOL_BAR_VIEW_SETTING\",\n\"placement\": \"bottom\",\n \"title\": \"Watch videos again\", \n\"description\": \"Click \"Settings\" and you can find the tutorial video\" \n}", "player_step_ui_config_92": "", "player_step_ui_config_93": "", - "player_step_ui_config_94": "{\n \"title\": \"Let's go start your project!\",\n \"description\": \"Welcome to Vika Planet! Let's take up a task and our journey will start from here.\",\n \"data\": [\n {\n \"text\": \"Rename a file to make the index clearer\",\n \"stopEvents\": [\n \"onMouseDown\"\n ],\n \"actions\": [\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \"#FOLDER_SHOWCASE_TITLE\",\n \"emitEvent\": \"click\",\n \"nextActions\": [\n {\n \"uiType\": \"popover\",\n \"uiConfig\": \"{\\\"element\\\":\\\"#FOLDER_SHOWCASE_TITLE_INPUT\\\",\\\"placement\\\":\\\"bottom\\\",\\\"title\\\":\\\"How to use a datasheet\\\",\\\"description\\\":\\\"Click here to rename the file 👆\\\"}\",\n \"backdrop\": \"around_mask\"\n },\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \"#FOLDER_SHOWCASE_TITLE_INPUT\",\n \"emitEvent\": \"focus\",\n \"finishTodoWhen\": [\n \"blur\"\n ]\n }\n }\n ]\n }\n }\n ]\n },\n {\n \"text\": \"Modify a file's description to help others understand it better\",\n \"actions\": [\n {\n \"uiType\": \"breath\",\n \"uiConfig\": \"{\\\"element\\\":\\\"#FOLDER_SHOWCASE_DESCRIPTION\\\"}\",\n \"backdrop\": \"around_mask\"\n },\n {\n \"uiType\": \"popover\",\n \"uiConfig\": \"{\\\"element\\\":\\\"#FOLDER_SHOWCASE_DESCRIPTION\\\",\\\"placement\\\":\\\"left\\\",\\\"title\\\":\\\"How to use a datasheet\\\",\\\"description\\\":\\\"Click here to view or modify description\\\"}\"\n },\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \"#FOLDER_SHOWCASE_DESCRIPTION\",\n \"finishTodoWhen\": [\n \"click\"\n ]\n }\n }\n ]\n },\n {\n \"text\": \"Set access permission on a file to prevent data leakage or misoperation\",\n \"actions\": [\n {\n \"uiType\": \"breath\",\n \"uiConfig\": \"{\\\"element\\\":\\\"#FOLDER_SHOWCASE_BTN_MORE\\\"}\"\n },\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \"#FOLDER_SHOWCASE_BTN_MORE\",\n \"nextActions\": [\n {\n \"uiType\": \"breath\",\n \"uiConfig\": \"{\\\"element\\\":\\\".sc-eFehXo div:nth-of-type(1)\\\",\\\"shadowDirection\\\":\\\"inset\\\"}\"\n },\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \".sc-eFehXo div:nth-of-type(1)\",\n \"finishTodoWhen\": [\n \"click\"\n ]\n }\n }\n ]\n }\n }\n ]\n },\n {\n \"text\": \"Pick and enter a node to start collaborating with others\",\n \"actions\": [\n {\n \"uiType\": \"breath\",\n \"uiConfig\": \"{\\\"element\\\":\\\"#FOLDER_SHOWCASE_FIRST_NODE\\\"}\"\n },\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \"#FOLDER_SHOWCASE_NODES_CONTAINER > div\",\n \"finishTodoWhen\": [\n \"click\"\n ]\n }\n }\n ]\n }\n ]\n}", + "player_step_ui_config_94": "{\n \"title\": \"Let's go start your project!\",\n \"description\": \"Welcome to Vika Planet! Let's take up a task and our journey will start from here.\",\n \"data\": [\n {\n \"text\": \"Rename a file node to make the index clearer\",\n \"stopEvents\": [\n \"onMouseDown\"\n ],\n \"actions\": [\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \"#FOLDER_SHOWCASE_TITLE\",\n \"emitEvent\": \"click\",\n \"nextActions\": [\n {\n \"uiType\": \"popover\",\n \"uiConfig\": \"{\\\"element\\\":\\\"#FOLDER_SHOWCASE_TITLE_INPUT\\\",\\\"placement\\\":\\\"bottom\\\",\\\"title\\\":\\\"How to use a datasheet\\\",\\\"description\\\":\\\"Click here to rename the file node 👆\\\"}\",\n \"backdrop\": \"around_mask\"\n },\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \"#FOLDER_SHOWCASE_TITLE_INPUT\",\n \"emitEvent\": \"focus\",\n \"finishTodoWhen\": [\n \"blur\"\n ]\n }\n }\n ]\n }\n }\n ]\n },\n {\n \"text\": \"Modify a file node's description to help others understand it better\",\n \"actions\": [\n {\n \"uiType\": \"breath\",\n \"uiConfig\": \"{\\\"element\\\":\\\"#FOLDER_SHOWCASE_DESCRIPTION\\\"}\",\n \"backdrop\": \"around_mask\"\n },\n {\n \"uiType\": \"popover\",\n \"uiConfig\": \"{\\\"element\\\":\\\"#FOLDER_SHOWCASE_DESCRIPTION\\\",\\\"placement\\\":\\\"left\\\",\\\"title\\\":\\\"How to use a datasheet\\\",\\\"description\\\":\\\"Click here to view or modify description\\\"}\"\n },\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \"#FOLDER_SHOWCASE_DESCRIPTION\",\n \"finishTodoWhen\": [\n \"click\"\n ]\n }\n }\n ]\n },\n {\n \"text\": \"Set access permission on a file node to prevent data leakage or misoperation\",\n \"actions\": [\n {\n \"uiType\": \"breath\",\n \"uiConfig\": \"{\\\"element\\\":\\\"#FOLDER_SHOWCASE_BTN_MORE\\\"}\"\n },\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \"#FOLDER_SHOWCASE_BTN_MORE\",\n \"nextActions\": [\n {\n \"uiType\": \"breath\",\n \"uiConfig\": \"{\\\"element\\\":\\\".sc-eFehXo div:nth-of-type(1)\\\",\\\"shadowDirection\\\":\\\"inset\\\"}\"\n },\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \".sc-eFehXo div:nth-of-type(1)\",\n \"finishTodoWhen\": [\n \"click\"\n ]\n }\n }\n ]\n }\n }\n ]\n },\n {\n \"text\": \"Pick and enter a node to start collaborating with others\",\n \"actions\": [\n {\n \"uiType\": \"breath\",\n \"uiConfig\": \"{\\\"element\\\":\\\"#FOLDER_SHOWCASE_FIRST_NODE\\\"}\"\n },\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \"#FOLDER_SHOWCASE_NODES_CONTAINER > div\",\n \"finishTodoWhen\": [\n \"click\"\n ]\n }\n }\n ]\n }\n ]\n}", "player_step_ui_config_95": "", "player_step_ui_config_97": "{\n\t\"vikaby\": {\n\t\t\"title\": \"Hello~\",\n\t\t\"description\": \"If you have a problem, you can contact me to help you\",\n\t\t\"list\": \"
  • Not sure how to use vikadata
  • What vikadata can do for me
  • Problems during use
  • What's new in the future
  • Get official invitation code
\",\n\t\t\"tip\": \"Scan the QR code to contact us\"\n\t},\n\t\"questionnaire\": {\n\t\t\"title\": \"Hello, I'm Vika's Digitalization Consultant\",\n\t\t\"list\": \"[{\\\"title\\\": \\\"Report bug\\\", \\\"icon\\\": \\\"BugOutlined\\\"}, {\\\"title\\\": \\\"Give feedback\\\", \\\"icon\\\": \\\"AdviseSmallOutlined\\\"}, {\\\"title\\\": \\\"Customer support\\\", \\\"icon\\\": \\\"ServeOutlined\\\"}, {\\\"title\\\": \\\"Case recommendation\\\", \\\"icon\\\": \\\"ZanOutlined\\\"}, {\\\"title\\\": \\\"Solutions\\\", \\\"icon\\\": \\\"SolutionSmallOutlined\\\"}, {\\\"title\\\": \\\"FAQs\\\", \\\"icon\\\": \\\"InformationLargeOutlined\\\"}]\",\n\t\t\"tip\": \"Please use WeChat to scan the code to add customer service to get more exclusive services\"\n\t},\n\t\"website\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/03/02/59f4cc8e0b2b4395bf0fcd133d208e63\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/03/02/defbf55d1e9646eb929f9f5d11d5c119\"\n\t},\n\t\"dingtalk\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/03/02/964be5e3217b4fa8bfa74ef47a980093?attname=dingtalk-questionnaire.png\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/03/02/964be5e3217b4fa8bfa74ef47a980093?attname=dingtalk-vikaby.png\",\n\"tip\": \"Please use DingTalk to scan the code to join our group\"\n\t},\n\t\"wecom\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/03/02/1346d5efbd5043efb2bfcba0075c0ee9\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/03/02/09401a8f2d8e491a9097b9bac8b5a4e4\"\n\t},\n\t\"feishu\": {\n\t\t\"title\": \"Scan the QR code to contact us\",\n\t\t\"tip\": \"Please use Lark to scan the code and add customer service for more help\",\n\t\t\"description\": \"So that you can get service at any time when you encounter problems during use\",\n\t\t\"originUrl\": \"https://u.vika.cn/z9ygm\"\n\t}\n}", "player_step_ui_config_99": "", @@ -3909,7 +4043,7 @@ "pre_fill_share_copy_title": "The public link with pre-filled data", "pre_fill_title": "Form Pre-fill", "pre_fill_title_btn": "Pre-fill", - "pre_set_node_permission": "Field permissions can only be set after the file permissions of the current datasheet are enabled in the explorer", + "pre_set_node_permission": "Field permissions can only be set after the file node permissions of the current datasheet are enabled in the explorer", "precision": "Precision", "press_again_to_exit": "Press again to exit!", "preview": "Preview", @@ -3926,6 +4060,7 @@ "preview_guide_click_to_restart": "Press the button below to preview again", "preview_guide_enable_it": "Press the button below to turn on this function", "preview_guide_open_office_preview": "To preview this file, please turn on the \"office preview\" function", + "preview_next_automation_execution_time": "Preview next 10 execution times", "preview_not_support_video_codecs": "Only MP4 videos with H.264 video codecs can be preview", "preview_revision": "Preview", "preview_see_more": "Want to learn more about the \"office file preview\" feature? Please click here", @@ -3961,6 +4096,7 @@ "privacy_protection": "\"Privacy Protection\"", "private_cloud": "Private Cloud", "private_external_person_only": " External person only", + "private_help_link": "https://help.aitable.ai/docs/guide/team-and-private-area#private-area", "private_internal_person_only": " Internal person only", "private_product_point": "Own your APITable platform with one click", "privatized_deployment": "Self-Hosted", @@ -3999,10 +4135,10 @@ "quick_import_widget": "Import installed widgets", "quick_login": "Quick login options", "quick_login_bind": "<%= type %>", - "quick_search_intro": "Quickly obtain relevant search results by entering a keyword. Filter by file type (e.g. datasheet, folder, form, mirror, dashboard) using category items", + "quick_search_intro": "Quickly obtain relevant search results by entering a keyword. Filter by file node type (e.g. datasheet, folder, form, mirror, dashboard) using category items", "quick_search_loading": "Searching...", "quick_search_not_found": "We couldn't find what you were searching for", - "quick_search_placeholder": "Search for files", + "quick_search_placeholder": "Search for file nodes", "quick_search_shortcut_esc": "Close", "quick_search_shortcut_open": "Open", "quick_search_shortcut_select": "Select", @@ -4031,13 +4167,15 @@ "reconciled_data": "Data is being reconciled", "record": "Record", "record_activity_experience_tips": "You can view record activity of ${day} days", + "record_archived_data": "archived record", + "record_chunk_text": "${text} rows, please wait", "record_comment": "Comments only", "record_comments": "comments", "record_fail_data": "data error", "record_filter_tips": "This record has been filtered", "record_functions": "Record Function", "record_history": "Revision history only", - "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-history", + "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-activity", "record_history_title": "Record history", "record_pre_filtered": "This record has been filtered and will be hidden once you click outside the record", "record_pre_move": "This record will be moved elsewhere once you click outside the record", @@ -4048,9 +4186,9 @@ "records_of_count": "${count} records", "records_per_datasheet": "The number of records per datasheet", "records_per_space": "Total records of the Space", - "recover_node": "Restore file", - "recover_node_fail": "Failed to restore file", - "recover_node_success": "File restored ", + "recover_node": "Restore file node", + "recover_node_fail": "Failed to restore file node", + "recover_node_success": "File node restored ", "redemption_code": "Used redeem code", "redemption_code_button": "Redeem code", "redo": "Redo", @@ -4069,7 +4207,7 @@ "reject": "Reject", "rejected": "Rejected", "related_automations_disconnect_title": "Are you sure to disconnect this automation?", - "related_files": "Related files", + "related_files": "Related file nodes", "reload_page_later_msg": "Synchronization is done. The page will refresh in 5 seconds.", "remain": "remain:", "remain_capacity": "Remaining capacity", @@ -4083,7 +4221,7 @@ "remove_from_group": "You were removed from the \"\" team of the \"\" Space by .", "remove_from_role": "You were removed from the \"\" role of the \"\" Space by .", "remove_from_space": "Remove from Space", - "remove_from_space_confirm_tip": "Confirm to move the member out of this Space completely", + "remove_from_space_confirm_tip": "Confirm to completely remove the member from this workspace. After removal, the member's private workspace files will no longer occupy the capacity of the workspace station.", "remove_from_team": "Remove from team", "remove_from_team_confirm_tip": "Confirm to remove the member from this team", "remove_from_the_team": "Remove", @@ -4095,9 +4233,9 @@ "remove_members_button": "Remove forever", "remove_members_content": "Remove selected members from the organization?", "remove_members_title": "Remove members", - "remove_own_permissions_desc": "You are removing your own permission, which may prevent you from viewing this file after operation", + "remove_own_permissions_desc": "You are removing your own permission, which may prevent you from viewing this file node after operation", "remove_permissions": "Remove permission", - "remove_permissions_desc": "After removing permissions, the member/team may not be able to view the file", + "remove_permissions_desc": "After removing permissions, the member/team may not be able to view the file node", "remove_role": "Remove permission", "removed_member_tomyself": "You removed from the \"\" Space.", "rename": "Rename", @@ -4130,7 +4268,7 @@ "request_in_api_panel_curl": "Make a request", "request_in_api_panel_curl_warning": "Turn the jump to Apifox (including the API token), do you continue? After clicking confirm, the next time will not be reminded.", "request_tree_node_error_tips": "Request failed, please click retry", - "require_login_tip": "Editing a shared file requires login ", + "require_login_tip": "Editing a shared file node requires login ", "reselect": "Reselect", "reset": "Reset", "reset_password": "Reset password", @@ -4411,7 +4549,7 @@ "role_permission_manage_team": "Manage teams", "role_permission_manage_template": "Manage templates", "role_permission_manage_widget": "Manage Widget Center", - "role_permission_manage_workbench": "Manage file permissions", + "role_permission_manage_workbench": "Manage file node permissions", "rollback": "Rollback", "rollback_fail_content": "The current version has data conflicts and does not support rollback, Learn more", "rollback_fail_tip": "${type} Failed, please try again!", @@ -4466,7 +4604,7 @@ "sao_tome_and_principe": "Sao Tome and Principe", "saudi_arabia": "Saudi Arabia", "save": "Save", - "save_action_desc": "You can save this file as a copy", + "save_action_desc": "You can save this file node as a copy", "save_as_template": "Save as template", "save_document": "Save as copy", "save_template_disabled": "Cannot save as template", @@ -4477,6 +4615,12 @@ "scan_to_login": "Scan to login", "scan_to_login_by_method": "Please scan ${method} to follow official account to login", "scatter_chart": "Scatter Chart", + "schedule_day_tips": "The cycle calculation begins counting from the first day of each month. If we assume that it repeats every 10 days, then it will be triggered on the 1st, 11th, 21st and 31st day of each month", + "schedule_hour_tips": "The cycle calculation begins at midnight (0:00) each day. Assuming it repeats 0 minutes every three hours, it will occur at midnight (0:00), 3 AM, 6 AM, 9 AM, noon (12 PM), \n\n3 PM,6 PM, and finally at nightfall (9 PM) daily", + "schedule_start_day": "Starting from the 1st day of the month, ", + "schedule_start_month": "Starting from January each year, every", + "schedule_type": "Schedule Type", + "schedule_year_tips": "The cycle calculation begins counting from the first month of each year. Assuming an interval of first day 3 months, triggers will be activated at midnight on the first day of January, April, July, and October every year.", "science_and_technology": "Science and technology", "scroll_screen_down": "Scroll one screen down", "scroll_screen_left": "Scroll one screen left", @@ -4489,7 +4633,8 @@ "search_folder_or_form": "Find a folder or form ", "search_folder_or_sheet": "Find a folder or datasheet ", "search_new_admin": "Search", - "search_node_pleaseholder": "Search for files (${shortcutKey})", + "search_node_pleaseholder": "Search for file nodes (${shortcutKey})", + "search_node_tip": "Quick search (${shortcutKey})", "search_or_add": "Find or add an option", "search_role_placeholder": "Search roles", "seats": "Seats", @@ -4536,22 +4681,22 @@ "security_disabled_download_file": "Prevent read-only users from downloading attachments", "security_disabled_download_file_describle": "Users with \"read-Only\" permission cannot download attachments in cells, both on and off the Space", "security_disabled_download_file_modal_describle": "Users with \"read-Only\" permission can download attachments in cells, both on and off the Space", - "security_disabled_download_file_modal_title": "Allow read-only users to export files", + "security_disabled_download_file_modal_title": "Allow read-only users to export file nodes", "security_disabled_download_file_tip": "Users with \"read-Only\" permission cannot download attachments in cells", - "security_disabled_export": "Prohibition of file sharing", + "security_disabled_export": "Prohibition of file node sharing", "security_disabled_export_data": "Prevent members from exporting datasheet or view", "security_disabled_export_data_describle": "All members cannot export datasheet or view data locally", "security_disabled_export_data_modal_describle": "If members have the \"manageable\" permission to a datasheet, they can export it to a local file.", - "security_disabled_export_data_modal_title": "Allow to export files", - "security_disabled_export_tip": "Prohibit all members from sharing files outside the space", + "security_disabled_export_data_modal_title": "Allow to export file nodes", + "security_disabled_export_tip": "Prohibit all members from sharing file nodes outside the space", "security_disabled_invite_member": "Prevent members from inviting user", "security_disabled_invite_member_describle": "No one can invite users to join the Space except Space admin,and the generated invitation link will be invalid", "security_disabled_invite_member_modal_describle": "Once switched on, all members can invite new members from the contacts panel", "security_disabled_invite_member_modal_title": "Allow to invite members", - "security_disabled_share": " Disable sharing files", - "security_disabled_share_describle": "All members cannot creat the public link of the file, and the generated public link becomes invalid", - "security_disabled_share_modal_describle": "members can open the public link of the file", - "security_disabled_share_modal_title": "Allow to share files", + "security_disabled_share": " Disable sharing file nodes", + "security_disabled_share_describle": "All members cannot creat the public link of the file node, and the generated public link becomes invalid", + "security_disabled_share_modal_describle": "members can open the public link of the file node", + "security_disabled_share_modal_title": "Allow to share file nodes", "security_features": "Security", "security_setting_address_list_isolation": "You are experiencing the ${grade} space exclusive feature, which will be unlocked when you upgrade", "security_setting_apply_join_space": "You are experiencing the ${grade} space exclusive feature, which will be unlocked when you upgrade", @@ -4560,8 +4705,8 @@ "security_setting_apply_join_space_title": "Prevent users from applying to join the Space in the sharing page ", "security_setting_catalog_management": "You are experiencing the ${grade} space exclusive feature, which will be unlocked when you upgrade", "security_setting_catalog_management_describle": "Members can create new nodes to the root of the Working catalog. After the function is disabled, only Space admin can create.", - "security_setting_catalog_management_description": "Members can't create new files at the root of the catalog. After toggling this on, only space admins can create new files at the root of the catalog.", - "security_setting_catalog_management_title": "Prevent members from creating new files at the root of the catalog", + "security_setting_catalog_management_description": "Members can't create new file nodes at the root of the catalog. After toggling this on, only space admins can create new file nodes at the root of the catalog.", + "security_setting_catalog_management_title": "Prevent members from creating new file nodes at the root of the catalog", "security_setting_copy_cell_data": "You are experiencing the ${grade} space exclusive feature, which will be unlocked when you upgrade", "security_setting_copy_cell_data_describle": "After the function is disabled,users with \"read-Only\" permission cannot copy cell data, both on and off the Space", "security_setting_copy_cell_data_description": "Users with \"Read-only\" permission cannot copy data in cells", @@ -4585,8 +4730,8 @@ "security_setting_invite_member_title": "Prevent members from inviting user", "security_setting_mobile": "You are experiencing the ${grade} space exclusive feature, which will be unlocked when you upgrade", "security_setting_share": "You are experiencing the ${grade} space exclusive feature, which will be unlocked when you upgrade", - "security_setting_share_describle": "All members cannot creat the public link of the file, and the generated public link becomes invalid", - "security_setting_share_description": "All members cannot creat the public link of the file, and the generated public link becomes invalid", + "security_setting_share_describle": "All members cannot creat the public link of the file node, and the generated public link becomes invalid", + "security_setting_share_description": "All members cannot creat the public link of the file node, and the generated public link becomes invalid", "security_setting_share_title": "Prevent members from creating public links", "security_show_mobile": "Show phone numbers", "security_show_mobile_describle": "Show all members' phone numbers in contacts", @@ -4618,7 +4763,7 @@ "select_link_data_number": "Select the number of linked records", "select_link_data_number_all": "Link all records", "select_link_data_number_first": "Link the first record", - "select_local_file": "Drag and drop files or click here to upload", + "select_local_file": "Drag and drop attachments or click here to upload", "select_one_field": "Select field type", "select_phone_code": "Select country and region", "select_sort_rule": "Select sort rule", @@ -4684,7 +4829,7 @@ "set_permission_modal_help": "https://help.aitable.ai/docs/guide/faq-permission-settings", "set_permission_modal_radio_1": "Inherit superior permission", "set_permission_modal_radio_1_description": "Member and team inherit the permissions of the superior folder\"${parent_node_name}\"", - "set_permission_modal_radio_2": "File permissions", + "set_permission_modal_radio_2": "File node permissions", "set_permission_modal_radio_2_description": "Separately specify permission of member and team for the current ${node_type}", "set_permission_modal_title": "Assign permissions to members in ${name}", "set_permission_success_tips": "Permission set successfully", @@ -4711,7 +4856,7 @@ "share_configuration": "Sharing setting", "share_copy_url_link": "Copy link", "share_edit_exist_member_tip": "The current datasheet has ${content}. Confirm only if you allow others to view the organizational chart of the Space.", - "share_edit_tip": "The file is read-only before you log in. Please log in and try again.", + "share_edit_tip": "The file node is read-only before you log in. Please log in and try again.", "share_editor": "Log in to edit", "share_editor_label": "Log in to edit", "share_email_invite": "Invite collaborators into your Space", @@ -4727,17 +4872,17 @@ "share_form_title": "Fill in the form via the public link", "share_invite_no_permission": "You do not have permission to invite members", "share_link_text": "", - "share_login_tip": "Log in to edit file", + "share_login_tip": "Log in to edit file node", "share_mobile_friendly_tip": "88% of people get a better experience by editing on the computer", "share_modal_desc": "Copy the exclusive link below~
Invite friends to use APITable
Share with friends", "share_modal_title": "Share", "share_node_number_err_content": "share_node_number_err_content", - "share_only_desc": "External users outside the space can only view the file", + "share_only_desc": "External users outside the space can only view the file node", "share_only_title": "Share with others for reading-only", - "share_permisson_model_link_datasheet_label": "Related external files", - "share_permisson_model_link_datasheet_label_desc": "The current file (folder) is related with an external Datasheet", - "share_permisson_model_node_owner": "File owner", - "share_permisson_model_node_owner_desc": "The member has enabled manual permission setting for this file", + "share_permisson_model_link_datasheet_label": "Related external file nodes", + "share_permisson_model_link_datasheet_label_desc": "The current file node (folder) is related with an external Datasheet", + "share_permisson_model_node_owner": "File node owner", + "share_permisson_model_node_owner_desc": "The member has enabled manual permission setting for this file node", "share_permisson_model_open_share_false_1": "Failed to share. Someone else has enabled the sharing.", "share_permisson_model_open_share_label": "Sharing enabled", "share_permisson_model_open_share_label_desc": "${member_name} enables sharing, and external users can access the content via the public link", @@ -4753,8 +4898,8 @@ "share_save_label": "This shared content can be saved as a copy", "share_setting": "Share outside the Space", "share_settings_tip": "Sharing settings updated ${status}", - "share_succeed": "File shared", - "share_tips": "Publish a share link for this file. Users who obtain the link on the Internet can view, edit, or copy the file based on their permissions.", + "share_succeed": "File node shared", + "share_tips": "Publish a share link for this file node. Users who obtain the link on the Internet can view, edit, or copy the file node based on their permissions.", "share_tips_title": "Publish share link", "share_title": "Share \"${node}\"", "share_with_offsite_users": "Share with users outside the Space", @@ -4877,8 +5022,8 @@ "space_exist_dashboard": "Send widget to dashboard", "space_field_permission_limit": "The maximum number of field permissions to be used in the \"\" Space is . So far, has been used, and you can upgrade to get higher usage.", "space_field_permission_limit_email_title": "Usage reminders for the number of field permissions in the \"${SPACE_NAME}\" space", - "space_file_permission_limit": "The maximum number of file permissions to be used in the \"\" Space is . So far, has been used, and you can upgrade to get higher usage.", - "space_file_permission_limit_email_title": "Usage reminders for the number of file permissions in the \"${SPACE_NAME}\" space", + "space_file_permission_limit": "The maximum number of file node permissions to be used in the \"\" Space is . So far, has been used, and you can upgrade to get higher usage.", + "space_file_permission_limit_email_title": "Usage reminders for the number of file node permissions in the \"${SPACE_NAME}\" space", "space_form_limit": "The maximum number of forms to be used in the \"\" Space is . So far, has been used, and you can upgrade to get higher usage.", "space_form_limit_email_title": "Usage reminders for the number of forms in the \"${SPACE_NAME}\" space", "space_free_capacity_expansion": "Free expansion", @@ -4893,6 +5038,7 @@ "space_info": "Overview", "space_info_del_confirm1": "1. Deleting this Space will clean up the following data:", "space_info_del_confirm2": "2. The Space will be deleted completely after 7 days. You can restore the Space before then.", + "space_info_del_confirm3": "3. For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "space_info_feishu_desc": "You are using a third-party integration. To delete the Space, please disable the third-party integration first. ", "space_info_feishu_label": "Integrations", "space_join_apply": " requested to join the \"\" Space.", @@ -4906,7 +5052,7 @@ "space_log_actions": "Actions", "space_log_date_range": "Date range", "space_log_download_button": "Download logs", - "space_log_file_name": "File name", + "space_log_file_name": "File node name", "space_log_operator": "Operator", "space_log_title": "Space logs", "space_log_trial_button": "Try now", @@ -4948,7 +5094,7 @@ "space_template": "Custom", "space_time_machine_limit": "Your Space supports days of record history. You can upgrade the plan to see longer history.", "space_time_machine_limit_email_title": "", - "space_trash_limit": "Your Space supports keeping deleted files in trash within days. You can upgrade the plan to see more.", + "space_trash_limit": "Your Space supports keeping deleted file nodes in trash within days. You can upgrade the plan to see more.", "space_trash_limit_email_title": "", "space_trial": "Congrats! Your \"\" Space has upgraded to the (on trial). The plan will expire at .", "space_watermark_notify": "The Space is using the enterprise-level feature \"Global Watermarks\". Please upgrade to continue using it.", @@ -4979,6 +5125,7 @@ "start_onfiguration": "Start configuration", "start_time": "Start time", "start_use": "Start using", + "starting_from_midnight": "Starting from midnight (12:00 AM) every day, ", "startup": "Startup", "startup_company_support_program": "Startup support Program", "stat_average": "Average", @@ -5012,6 +5159,8 @@ "stay_tuned_for_more_features": "Stay tuned for more features", "steps_choose_reset_mode": "Select a reset method", "steps_validate_identities": "Verify identity", + "stop_chunk_content": "Are you sure you want to stop the operation?", + "stop_chunk_title": "Stop", "stop_dingtalk_h5_modal_content": "The self-built application will be unbound from this space. Please confirm .", "storage_per_seats": "", "storage_per_space": "Storage usage", @@ -5042,9 +5191,11 @@ "subscribe_credit_usage_over_limit": "The number of credits in the current space exceeds the limit, please upgrade your subscription.\n", "subscribe_demonstrate": "Request demos", "subscribe_disabled_seat": "The number of people cannot be lower than the original program", + "subscribe_grade_business": "Business", "subscribe_grade_free": "Free", "subscribe_grade_plus": "Plus", "subscribe_grade_pro": "Pro", + "subscribe_grade_starter": "Starter", "subscribe_label_tooltip": "Advanced space features", "subscribe_new_choose_member": "Supports up to ${member_num} members", "subscribe_new_choose_member_tips": "This plan supports 1~${member_num} members to enter the space", @@ -5060,9 +5211,9 @@ "subscribed_record_unarchived": " unarchived in ", "subscription_expire_error": "Your subscription status has expired", "subscription_fee": "Subscription fee: ${fee}", - "subscription_grades_checklist": "{\n \"Usages\": [\n {\n \"group\": \"Usages\",\n \"id\": \"member_num\",\n \"title\": \"Seats\",\n \"bronze\": \"Incl. 5 seats\",\n \"silver\": \"Incl. 5 seats\",\n \"gold\": \"Incl. 5 seats\",\n \"enterprise\": \"Incl. 5 seats\",\n \"community\":\"Unlimited\",\n \"custom\":\"Custom\"\n },\n {\n \"group\": \"Usages\",\n \"id\": \"datasheet_number\",\n \"title\": \"File nodes \",\n \"bronze\": \"30\",\n \"silver\": \"300\",\n \"gold\": \"1,000\",\n \"enterprise\": \"10,000\",\n \"community\":\"Unlimited\",\n \"custom\":\"Unlimited\"\n },\n {\n \"group\": \"Usages\",\n \"id\": \"datasheet_rows\",\n \"title\": \"Records per datasheet\",\n \"bronze\": \"5,000 \",\n \"silver\": \"10,000\",\n \"gold\": \"20,000\",\n \"enterprise\": \"50,000\",\n \"community\":\"50,000\",\n \"custom\":\"50,000\"\n },\n {\n \"group\": \"Usages\",\n \"id\": \"space_rows\",\n \"title\": \"Records per space\",\n \"bronze\": \"20,000\",\n \"silver\": \"3,000,000\",\n \"gold\": \"20,000,000\",\n \"enterprise\": \"500,000,000\",\n \"community\":\"Unlimited\",\n \"custom\":\"Unlimited\"\n },\n {\n \"group\": \"Usages\",\n \"id\": \"space_capacity\",\n \"title\": \"Attachments storage per space\",\n \"bronze\": \"1GB \",\n \"silver\": \"Seats * 5GB\",\n \"gold\": \"Seats * 7GB\",\n \"enterprise\": \"Seats * 10GB\",\n \"community\":\"Unlimited\",\n \"custom\":\"Unlimited\"\n }\n ],\n \"Features\": [\n {\n \"group\": \"Features\",\n \"id\": \"star_marker\",\n \"title\": \"Pin\",\n \"bronze\": true,\n \"silver\": true,\n \"gold\": true,\n \"enterprise\": true,\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"album_view\",\n \"title\": \"Gallery view\",\n \"bronze\": true,\n \"silver\": true,\n \"gold\": true,\n \"enterprise\": true,\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"kanban_view\",\n \"title\": \"Kanban view\",\n \"bronze\": true,\n \"silver\": true,\n \"gold\": true,\n \"enterprise\": true,\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"org_chart_view\",\n \"title\": \"Architecture view\",\n \"bronze\": true,\n \"silver\": true,\n \"gold\": true,\n \"enterprise\": true,\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"gantt_view\",\n \"title\": \"Gantt view\",\n \"bronze\": \"10 per space\",\n \"silver\": \"50 per space\",\n \"gold\": \"200 per space\",\n \"enterprise\": \"Unlimited\",\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"calendar_view\",\n \"title\": \"Calendar view\",\n \"bronze\": \"5 per space\",\n \"silver\": \"50 per space\",\n \"gold\": \"200 per space\",\n \"enterprise\": \"Unlimited\",\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"collection_table\",\n \"title\": \"Form\",\n \"bronze\": \"20 per space\",\n \"silver\": \"100 per space\",\n \"gold\": \"300 per space\",\n \"enterprise\": \"Unlimited\",\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"mirror\",\n \"title\": \"Mirror(records permission)\",\n \"bronze\": \"5 per space\",\n \"silver\": \"50 per space\",\n \"gold\": \"100 per space\",\n \"enterprise\": \"Unlimited\",\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"widget\",\n \"title\": \"Widget\",\n \"bronze\": \"Free for a limited time\",\n \"silver\": \"Free for a limited time\",\n \"gold\": \"Free for a limited time\",\n \"enterprise\": \"Free for a limited time\",\n \"community\":\"Free for a limited time\",\n \"custom\":\"Free for a limited time\"\n },\n {\n \"group\": \"Features\",\n \"id\": \"dashboard\",\n \"title\": \"Dashboard\",\n \"bronze\": \"5 per space\",\n \"silver\": \"50 per space\",\n \"gold\": \"100 per space\",\n \"enterprise\": \"Unlimited\",\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"custom_embedding\",\n \"title\": \"Custom embedding\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": true,\n \"enterprise\": true,\n \"community\":false,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"rainbow_tags\",\n \"title\": \"Rainbow tags\",\n \"bronze\": \"Basic color\",\n \"silver\": \"Advanced color\",\n \"gold\": \"Advanced color\",\n \"enterprise\": \"Advanced color\",\n \"community\":\"Basic color\",\n \"custom\":\"Advanced color\"\n },\n {\n \"group\": \"Features\",\n \"id\": \"space_capacity\",\n \"title\": \"Record activity\",\n \"bronze\": \"14 days\",\n \"silver\": \"3 months\",\n \"gold\": \"6 months\",\n \"enterprise\": \"24 months\",\n \"community\": true,\n \"custom\": true\n },\n {\n \"group\": \"Features\",\n \"id\": \"recycle_bin\",\n \"title\": \"Trash\",\n \"bronze\": \"14 days\",\n \"silver\": \"3 months\",\n \"gold\": \"6 months\",\n \"enterprise\": \"24 months\",\n \"community\": true,\n \"custom\": true\n },\n {\n \"group\": \"Features\",\n \"id\": \"api_limits\",\n \"title\": \"API\",\n \"bronze\": \"Free for a limited time\",\n \"silver\": \"Free for a limited time\",\n \"gold\": \"Free for a limited time\",\n \"enterprise\": \"Free for a limited time\",\n \"community\": true,\n \"custom\": true\n },\n {\n \"group\": \"Features\",\n \"id\": \"robot\",\n \"title\": \"Automation\",\n \"bronze\": \"Free for a limited time\",\n \"silver\": \"Free for a limited time\",\n \"gold\": \"Free for a limited time\",\n \"enterprise\": \"Free for a limited time\",\n \"community\": true,\n \"custom\": true\n }\n ],\n \"Management and security\": [\n {\n \"group\": \"Management and security\",\n \"id\": \"column_permission\",\n \"title\": \"Field permissions\",\n \"bronze\": \"10 per space\",\n \"silver\": \"50 per space\",\n \"gold\": \"200 per space\",\n \"enterprise\": \"Unlimited\",\n \"community\":false,\n \"custom\":true\n },\n {\n \"group\": \"Management and security\",\n \"id\": \"folder_permission\",\n \"title\": \"File permissions\",\n \"bronze\": \"10 per space\",\n \"silver\": \"50 per space\",\n \"gold\": \"200 per space\",\n \"enterprise\": \"Unlimited\",\n \"community\":false,\n \"custom\":true\n },\n {\n \"group\": \"Management and security\",\n \"id\": \"admin_counts\",\n \"title\": \"Space admin\",\n \"bronze\": \"3\",\n \"silver\": \"5\",\n \"gold\": \"10\",\n \"enterprise\": \"Unlimited\",\n \"community\": false,\n \"custom\": true\n },\n {\n \"group\": \"Management and security\",\n \"id\": \"watermark\",\n \"title\": \"Watermark\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": false,\n \"enterprise\": true,\n \"community\": false,\n \"custom\": true\n },\n {\n \"group\": \"Management and security\",\n \"id\": \"security_disabled_export_data\",\n \"title\": \"Disable data export\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": true,\n \"enterprise\": true,\n \"community\": false,\n \"custom\": true\n },\n {\n \"group\": \"Management and security\",\n \"id\": \"security_disabled_share\",\n \"title\": \"Disable opening public links\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": false,\n \"enterprise\": true,\n \"community\": false,\n \"custom\": true\n },\n {\n \"group\": \"Management and security\",\n \"id\": \"security_disabled_copy\",\n \"title\": \"Disable copying datas\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": false,\n \"enterprise\": true,\n \"community\": false,\n \"custom\": true\n },\n {\n \"group\": \"Management and security\",\n \"id\": \"security_disabled_download_file\",\n \"title\": \"Disable downloadimg files\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": false,\n \"enterprise\": true,\n \"community\": false,\n \"custom\": true\n },\n {\n \"group\": \"Management and security\",\n \"id\": \"security_disabled_invite_members\",\n \"title\": \"Disable inviting off-space user\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": false,\n \"enterprise\": true,\n \"community\": false,\n \"custom\": true\n }\n ,\n {\n \"group\": \"Management and security\",\n \"id\": \"space_log\",\n \"title\": \"Space log\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": false,\n \"enterprise\": true,\n \"community\": false,\n \"custom\": true\n }\n ],\n \"Professional Services\": [\n {\n \"group\": \"Professional Services\",\n \"id\": \"professional_services\",\n \"title\": \"Consultant Services\",\n \"bronze\": \"Community\",\n \"silver\": \"Community\",\n \"gold\": \"Community\",\n \"enterprise\": \"Customer Success Manager\",\n \"community\": \"Community\",\n \"custom\": \"Customer Success Manager\"\n },\n {\n \"group\": \"Professional Services\",\n \"id\": \"enterprise_consulting_training\",\n \"title\": \"Enterprise-level consulting training\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": false,\n \"enterprise\": true,\n \"community\": false,\n \"custom\": true\n }\n ]\n}", - "subscription_grades_checklist_mobile_saas": "[\n {\n \"grade\": \"free\",\n \"btnText\": \"Start Now\",\n \"btnHref\": \"/login\",\n \"primaryContent\": [\n \"30 file nodes\",\n \"5,000 records per datasheet\",\n \"1G attachments storage per sapce\"\n ],\n \"details\": [\n {\n \"name\": \"Usage\",\n \"rules\": [\n \"30 file nodes\",\n \"5,000 records per datasheet\",\n \"20,000 records per sapce\",\n \"1G attachments storage per sapce\"\n ]\n },\n {\n \"name\": \"Features\",\n \"rules\": [\n \"Pin file nodes\",\n \"Gallery view,Kanban view and Architecture view are unlimited\",\n \"10 gantt views per sapce\",\n \"5 calendar views per sapce\",\n \"20 forms per sapce\",\n \"5 mirrors per sapce\",\n \"5 dashbords per sapce\",\n \"Widget is free for a limited time\",\n \"Basic colors for rainbow tags\",\n \"Record activity goes back 14 days\",\n \"Trash goes back 14 days\",\n \"API is free for a limited time\",\n \"Automation is free for a limited time\"\n ]\n },\n {\n \"name\": \"Management and security\",\n \"rules\": [\n \"10 field permissions per sapce\",\n \"10 file permissions per sapce\",\n \"3 admins per sapce\"\n ]\n },\n {\n \"name\": \"Professional Services\",\n \"rules\": [\n \"Community\"\n ]\n }\n ]\n },\n {\n \"grade\": \"plus\",\n \"btnText\": \"Choose Plus\",\n \"btnHref\": \"/login\",\n \"primaryContent\": [\n \"300 file nodes\",\n \"10,000 records per datasheet\",\n \"5G/seats attachments storage per sapce\"\n ],\n \"details\": [\n {\n \"name\": \"Usage\",\n \"rules\": [\n \"300 file nodes\",\n \"10,000 records per datasheet\",\n \"3,0000,000 records per sapce\",\n \"5G/seats attachments storage per sapce\"\n ]\n },\n {\n \"name\": \"Features\",\n \"rules\": [\n \"Pin file nodes\",\n \"Gallery view,Kanban view and Architecture view are unlimited\",\n \"50 gantt views per sapce\",\n \"50 calendar views per sapce\",\n \"100 forms per sapce\",\n \"50 mirrors per sapce\",\n \"50 dashbords per sapce\",\n \"Widget is free for a limited time\",\n \"Advanced colors for rainbow tags\",\n \"Record activity goes back 3 months\",\n \"Trash goes back 3 months\",\n \"API is free for a limited time\",\n \"Automation is free for a limited time\"\n ]\n },\n {\n \"name\": \"Management and security\",\n \"rules\": [\n \"50 field permissions per sapce\",\n \"50 file permissions per sapce\",\n \"5 admins per sapce\"\n ]\n },\n {\n \"name\": \"Professional Services\",\n \"rules\": [\n \"Community\"\n ]\n }\n ]\n },\n {\n \"grade\": \"pro\",\n \"btnText\": \"Choose Pro\",\n \"btnHref\": \"/login\",\n \"primaryContent\": [\n \"1,000 file nodes\",\n \"20,000 records per datasheet\",\n \"7G/seats attachments storage per sapce\",\n \"Custom embedding\"\n ],\n \"details\": [\n {\n \"name\": \"Usage\",\n \"rules\": [\n \"1,000 file nodes\",\n \"20,000 records per datasheet\",\n \"20,000,000 records per sapce\",\n \"7G/seats attachments storage per sapce\"\n ]\n },\n {\n \"name\": \"Features\",\n \"rules\": [\n \"Pin file nodes\",\n \"Gallery view,Kanban view and Architecture view are unlimited\",\n \"200 gantt views per sapce\",\n \"300 calendar views per sapce\",\n \"300 forms per sapce\",\n \"100 mirrors per sapce\",\n \"100 dashbords per sapce\",\n \"Widget is free for a limited time\",\n \"Advanced colors for rainbow tags\",\n \"Custom embedding\",\n \"Record activity goes back 6 months\",\n \"Trash goes back 6 months\",\n \"API is free for a limited time\",\n \"Automation is free for a limited time\"\n ]\n },\n {\n \"name\": \"Management and security\",\n \"rules\": [\n \"200 field permissions per sapce\",\n \"200 file permissions per sapce\",\n \"10 admins per sapce\",\n \"Disable data export\"\n ]\n },\n {\n \"name\": \"Professional Services\",\n \"rules\": [\n \"Community\"\n ]\n }\n ]\n },\n {\n \"grade\": \"enterprise\",\n \"btnText\": \"Contacts us\",\n \"btnHref\": \"\",\n \"primaryContent\": [\n \"10,000 file nodes\",\n \"50,000 records per datasheet\",\n \"10G/seats attachments storage per sapce\",\n \"Unlimited permission and security settings\",\n \"Customer Success Manager\"\n ],\n \"details\": [\n {\n \"name\": \"Usage\",\n \"rules\": [\n \"10,000 file nodes\",\n \"50,000 records per datasheet\",\n \"50,0000,000 records per sapce\",\n \"10G/seats attachments storage per sapce\"\n ]\n },\n {\n \"name\": \"Features\",\n \"rules\": [\n \"Pin file nodes\",\n \"Gallery view,Kanban view and Architecture view are unlimited\",\n \"Gantt views are unlimited\",\n \"Calendar views are unlimited\",\n \"Forms are unlimited\",\n \"Mirrors are unlimited\",\n \"Dashbords are unlimited\",\n \"Widget is free for a limited time\",\n \"Advanced colors for rainbow tags\",\n \"Custom embedding\",\n \"Record activity goes back 24 months\",\n \"Trash goes back 24 months\",\n \"API is free for a limited time\",\n \"Automation is free for a limited time\"\n ]\n },\n {\n \"name\": \"Management and security\",\n \"rules\": [\n \"Field permissions are unlimited\",\n \"File permissions are unlimited\",\n \"Admins are unlimited\",\n \"Watermark\",\n \"Disable data export\",\n \"Disable opening public links\",\n \"Disable copying datas\",\n \"Disable downloadimg files\",\n \"Disable inviting off-space user\",\n \"Space log\"\n ]\n },\n {\n \"name\": \"Professional Services\",\n \"rules\": [\n \"Customer Success Manager\",\n \"Custom function development (additional cost)\",\n \"Enterprise-level consulting training\"\n ]\n }\n ]\n }\n ]", - "subscription_grades_checklist_mobile_selfhost": "[\n {\n \"grade\": \"community\",\n \"btnText\": \"Dowload\",\n \"primaryContent\": [\n \"10,000 file nodes\",\n \"50,000 records per datasheet\",\n \"Unlimitied attachments storage per sapce\"\n ],\n \"details\": [\n {\n \"name\": \"Usage\",\n \"rules\": [\n \"10,000 file nodes\",\n \"50,000 records per datasheet\",\n \"50,0000,000 records per sapce\",\n \"Unlimitied attachments storage per sapce\"\n ]\n },\n {\n \"name\": \"Features\",\n \"rules\": [\n \"Pin file nodes\",\n \"Gallery view,Kanban view and Architecture view are unlimited\",\n \"Gantt views are unlimited\",\n \"Calendar views are unlimited\",\n \"Forms are unlimited\",\n \"Mirrors are unlimited\",\n \"Dashbords are unlimited\",\n \"Widget is free for a limited time\",\n \"Basic colors for rainbow tags\",\n \"Record activity goes back 24 months\",\n \"Trash goes back 24 months\",\n \"API is free for a limited time\",\n \"Automation is free for a limited time\"\n ]\n },\n {\n \"name\": \"Management and security\",\n \"rules\": [\n \"Not supported\"\n ]\n },\n {\n \"name\": \"Professional Services\",\n \"rules\": [\n \"Community\"\n ]\n }\n ]\n },\n {\n \"grade\": \"custom\",\n \"btnText\": \"Contacts us\",\n \"primaryContent\": [\n \"10,000 file nodes\",\n \"50,000 records per datasheet\",\n \"10G/seats attachments storage per sapce\",\n \"Unlimited permission and security settings\",\n \"Customer Success Manager\"\n ],\n \"details\": [\n {\n \"name\": \"Usage\",\n \"rules\": [\n \"10,000 file nodes\",\n \"50,000 records per datasheet\",\n \"50,0000,000 records per sapce\",\n \"Unlimited attachments storage per sapce\"\n ]\n },\n {\n \"name\": \"Features\",\n \"rules\": [\n \"Pin file nodes\",\n \"Gallery view,Kanban view and Architecture view are unlimited\",\n \"Gantt views are unlimited\",\n \"Calendar views are unlimited\",\n \"Forms are unlimited\",\n \"Mirrors are unlimited\",\n \"Dashbords are unlimited\",\n \"Widget is free for a limited time\",\n \"Advanced colors for rainbow tags\",\n \"Custom embedding\",\n \"Record activity goes back 24 months\",\n \"Trash goes back 24 months\",\n \"API is free for a limited time\",\n \"Automation is free for a limited time\"\n ]\n },\n {\n \"name\": \"Management and security\",\n \"rules\": [\n \"Field permissions are unlimited\",\n \"File permissions are unlimited\",\n \"Admins are unlimited\",\n \"Watermark\",\n \"Disable data export\",\n \"Disable opening public links\",\n \"Disable copying datas\",\n \"Disable downloadimg files\",\n \"Disable inviting off-space user\",\n \"Space log\"\n ]\n },\n {\n \"name\": \"Professional Services\",\n \"rules\": [\n \"Customer Success Manager\",\n \"Custom function development (additional cost)\",\n \"Enterprise-level consulting training\"\n ]\n }\n ]\n }\n]", + "subscription_grades_checklist": "{\n \"Usages\": [\n {\n \"group\": \"Usages\",\n \"id\": \"member_num\",\n \"title\": \"Seats\",\n \"bronze\": \"Incl. 5 seats\",\n \"silver\": \"Incl. 5 seats\",\n \"gold\": \"Incl. 5 seats\",\n \"enterprise\": \"Incl. 5 seats\",\n \"community\":\"Unlimited\",\n \"custom\":\"Custom\"\n },\n {\n \"group\": \"Usages\",\n \"id\": \"datasheet_number\",\n \"title\": \"File nodes \",\n \"bronze\": \"30\",\n \"silver\": \"300\",\n \"gold\": \"1,000\",\n \"enterprise\": \"10,000\",\n \"community\":\"Unlimited\",\n \"custom\":\"Unlimited\"\n },\n {\n \"group\": \"Usages\",\n \"id\": \"datasheet_rows\",\n \"title\": \"Records per datasheet\",\n \"bronze\": \"5,000 \",\n \"silver\": \"10,000\",\n \"gold\": \"20,000\",\n \"enterprise\": \"50,000\",\n \"community\":\"50,000\",\n \"custom\":\"50,000\"\n },\n {\n \"group\": \"Usages\",\n \"id\": \"space_rows\",\n \"title\": \"Records per space\",\n \"bronze\": \"20,000\",\n \"silver\": \"3,000,000\",\n \"gold\": \"20,000,000\",\n \"enterprise\": \"500,000,000\",\n \"community\":\"Unlimited\",\n \"custom\":\"Unlimited\"\n },\n {\n \"group\": \"Usages\",\n \"id\": \"space_capacity\",\n \"title\": \"Attachments storage per space\",\n \"bronze\": \"1GB \",\n \"silver\": \"Seats * 5GB\",\n \"gold\": \"Seats * 7GB\",\n \"enterprise\": \"Seats * 10GB\",\n \"community\":\"Unlimited\",\n \"custom\":\"Unlimited\"\n }\n ],\n \"Features\": [\n {\n \"group\": \"Features\",\n \"id\": \"star_marker\",\n \"title\": \"Pin\",\n \"bronze\": true,\n \"silver\": true,\n \"gold\": true,\n \"enterprise\": true,\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"album_view\",\n \"title\": \"Gallery view\",\n \"bronze\": true,\n \"silver\": true,\n \"gold\": true,\n \"enterprise\": true,\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"kanban_view\",\n \"title\": \"Kanban view\",\n \"bronze\": true,\n \"silver\": true,\n \"gold\": true,\n \"enterprise\": true,\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"org_chart_view\",\n \"title\": \"Architecture view\",\n \"bronze\": true,\n \"silver\": true,\n \"gold\": true,\n \"enterprise\": true,\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"gantt_view\",\n \"title\": \"Gantt view\",\n \"bronze\": \"10 per space\",\n \"silver\": \"50 per space\",\n \"gold\": \"200 per space\",\n \"enterprise\": \"Unlimited\",\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"calendar_view\",\n \"title\": \"Calendar view\",\n \"bronze\": \"5 per space\",\n \"silver\": \"50 per space\",\n \"gold\": \"200 per space\",\n \"enterprise\": \"Unlimited\",\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"collection_table\",\n \"title\": \"Form\",\n \"bronze\": \"20 per space\",\n \"silver\": \"100 per space\",\n \"gold\": \"300 per space\",\n \"enterprise\": \"Unlimited\",\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"mirror\",\n \"title\": \"Mirror(records permission)\",\n \"bronze\": \"5 per space\",\n \"silver\": \"50 per space\",\n \"gold\": \"100 per space\",\n \"enterprise\": \"Unlimited\",\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"widget\",\n \"title\": \"Widget\",\n \"bronze\": \"Free for a limited time\",\n \"silver\": \"Free for a limited time\",\n \"gold\": \"Free for a limited time\",\n \"enterprise\": \"Free for a limited time\",\n \"community\":\"Free for a limited time\",\n \"custom\":\"Free for a limited time\"\n },\n {\n \"group\": \"Features\",\n \"id\": \"dashboard\",\n \"title\": \"Dashboard\",\n \"bronze\": \"5 per space\",\n \"silver\": \"50 per space\",\n \"gold\": \"100 per space\",\n \"enterprise\": \"Unlimited\",\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"custom_embedding\",\n \"title\": \"Custom embedding\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": true,\n \"enterprise\": true,\n \"community\":false,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"rainbow_tags\",\n \"title\": \"Rainbow tags\",\n \"bronze\": \"Basic color\",\n \"silver\": \"Advanced color\",\n \"gold\": \"Advanced color\",\n \"enterprise\": \"Advanced color\",\n \"community\":\"Basic color\",\n \"custom\":\"Advanced color\"\n },\n {\n \"group\": \"Features\",\n \"id\": \"space_capacity\",\n \"title\": \"Record activity\",\n \"bronze\": \"14 days\",\n \"silver\": \"3 months\",\n \"gold\": \"6 months\",\n \"enterprise\": \"24 months\",\n \"community\": true,\n \"custom\": true\n },\n {\n \"group\": \"Features\",\n \"id\": \"recycle_bin\",\n \"title\": \"Trash\",\n \"bronze\": \"14 days\",\n \"silver\": \"3 months\",\n \"gold\": \"6 months\",\n \"enterprise\": \"24 months\",\n \"community\": true,\n \"custom\": true\n },\n {\n \"group\": \"Features\",\n \"id\": \"api_limits\",\n \"title\": \"API\",\n \"bronze\": \"Free for a limited time\",\n \"silver\": \"Free for a limited time\",\n \"gold\": \"Free for a limited time\",\n \"enterprise\": \"Free for a limited time\",\n \"community\": true,\n \"custom\": true\n },\n {\n \"group\": \"Features\",\n \"id\": \"robot\",\n \"title\": \"Automation\",\n \"bronze\": \"Free for a limited time\",\n \"silver\": \"Free for a limited time\",\n \"gold\": \"Free for a limited time\",\n \"enterprise\": \"Free for a limited time\",\n \"community\": true,\n \"custom\": true\n }\n ],\n \"Management and security\": [\n {\n \"group\": \"Management and security\",\n \"id\": \"column_permission\",\n \"title\": \"Field permissions\",\n \"bronze\": \"10 per space\",\n \"silver\": \"50 per space\",\n \"gold\": \"200 per space\",\n \"enterprise\": \"Unlimited\",\n \"community\":false,\n \"custom\":true\n },\n {\n \"group\": \"Management and security\",\n \"id\": \"folder_permission\",\n \"title\": \"File node permissions\",\n \"bronze\": \"10 per space\",\n \"silver\": \"50 per space\",\n \"gold\": \"200 per space\",\n \"enterprise\": \"Unlimited\",\n \"community\":false,\n \"custom\":true\n },\n {\n \"group\": \"Management and security\",\n \"id\": \"admin_counts\",\n \"title\": \"Space admin\",\n \"bronze\": \"3\",\n \"silver\": \"5\",\n \"gold\": \"10\",\n \"enterprise\": \"Unlimited\",\n \"community\": false,\n \"custom\": true\n },\n {\n \"group\": \"Management and security\",\n \"id\": \"watermark\",\n \"title\": \"Watermark\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": false,\n \"enterprise\": true,\n \"community\": false,\n \"custom\": true\n },\n {\n \"group\": \"Management and security\",\n \"id\": \"security_disabled_export_data\",\n \"title\": \"Disable data export\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": true,\n \"enterprise\": true,\n \"community\": false,\n \"custom\": true\n },\n {\n \"group\": \"Management and security\",\n \"id\": \"security_disabled_share\",\n \"title\": \"Disable opening public links\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": false,\n \"enterprise\": true,\n \"community\": false,\n \"custom\": true\n },\n {\n \"group\": \"Management and security\",\n \"id\": \"security_disabled_copy\",\n \"title\": \"Disable copying datas\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": false,\n \"enterprise\": true,\n \"community\": false,\n \"custom\": true\n },\n {\n \"group\": \"Management and security\",\n \"id\": \"security_disabled_download_file\",\n \"title\": \"Disable downloadimg files\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": false,\n \"enterprise\": true,\n \"community\": false,\n \"custom\": true\n },\n {\n \"group\": \"Management and security\",\n \"id\": \"security_disabled_invite_members\",\n \"title\": \"Disable inviting off-space user\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": false,\n \"enterprise\": true,\n \"community\": false,\n \"custom\": true\n }\n ,\n {\n \"group\": \"Management and security\",\n \"id\": \"space_log\",\n \"title\": \"Space log\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": false,\n \"enterprise\": true,\n \"community\": false,\n \"custom\": true\n }\n ],\n \"Professional Services\": [\n {\n \"group\": \"Professional Services\",\n \"id\": \"professional_services\",\n \"title\": \"Consultant Services\",\n \"bronze\": \"Community\",\n \"silver\": \"Community\",\n \"gold\": \"Community\",\n \"enterprise\": \"Customer Success Manager\",\n \"community\": \"Community\",\n \"custom\": \"Customer Success Manager\"\n },\n {\n \"group\": \"Professional Services\",\n \"id\": \"enterprise_consulting_training\",\n \"title\": \"Enterprise-level consulting training\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": false,\n \"enterprise\": true,\n \"community\": false,\n \"custom\": true\n }\n ]\n}", + "subscription_grades_checklist_mobile_saas": "[\n {\n \"grade\": \"free\",\n \"btnText\": \"Start Now\",\n \"btnHref\": \"/login\",\n \"primaryContent\": [\n \"30 file nodes\",\n \"5,000 records per datasheet\",\n \"1G attachments storage per sapce\"\n ],\n \"details\": [\n {\n \"name\": \"Usage\",\n \"rules\": [\n \"30 file nodes\",\n \"5,000 records per datasheet\",\n \"20,000 records per sapce\",\n \"1G attachments storage per sapce\"\n ]\n },\n {\n \"name\": \"Features\",\n \"rules\": [\n \"Pin file nodes\",\n \"Gallery view,Kanban view and Architecture view are unlimited\",\n \"10 gantt views per sapce\",\n \"5 calendar views per sapce\",\n \"20 forms per sapce\",\n \"5 mirrors per sapce\",\n \"5 dashbords per sapce\",\n \"Widget is free for a limited time\",\n \"Basic colors for rainbow tags\",\n \"Record activity goes back 14 days\",\n \"Trash goes back 14 days\",\n \"API is free for a limited time\",\n \"Automation is free for a limited time\"\n ]\n },\n {\n \"name\": \"Management and security\",\n \"rules\": [\n \"10 field permissions per sapce\",\n \"10 file node permissions per sapce\",\n \"3 admins per sapce\"\n ]\n },\n {\n \"name\": \"Professional Services\",\n \"rules\": [\n \"Community\"\n ]\n }\n ]\n },\n {\n \"grade\": \"plus\",\n \"btnText\": \"Choose Plus\",\n \"btnHref\": \"/login\",\n \"primaryContent\": [\n \"300 file nodes\",\n \"10,000 records per datasheet\",\n \"5G/seats attachments storage per sapce\"\n ],\n \"details\": [\n {\n \"name\": \"Usage\",\n \"rules\": [\n \"300 file nodes\",\n \"10,000 records per datasheet\",\n \"3,0000,000 records per sapce\",\n \"5G/seats attachments storage per sapce\"\n ]\n },\n {\n \"name\": \"Features\",\n \"rules\": [\n \"Pin file nodes\",\n \"Gallery view,Kanban view and Architecture view are unlimited\",\n \"50 gantt views per sapce\",\n \"50 calendar views per sapce\",\n \"100 forms per sapce\",\n \"50 mirrors per sapce\",\n \"50 dashbords per sapce\",\n \"Widget is free for a limited time\",\n \"Advanced colors for rainbow tags\",\n \"Record activity goes back 3 months\",\n \"Trash goes back 3 months\",\n \"API is free for a limited time\",\n \"Automation is free for a limited time\"\n ]\n },\n {\n \"name\": \"Management and security\",\n \"rules\": [\n \"50 field permissions per sapce\",\n \"50 file node permissions per sapce\",\n \"5 admins per sapce\"\n ]\n },\n {\n \"name\": \"Professional Services\",\n \"rules\": [\n \"Community\"\n ]\n }\n ]\n },\n {\n \"grade\": \"pro\",\n \"btnText\": \"Choose Pro\",\n \"btnHref\": \"/login\",\n \"primaryContent\": [\n \"1,000 file nodes\",\n \"20,000 records per datasheet\",\n \"7G/seats attachments storage per sapce\",\n \"Custom embedding\"\n ],\n \"details\": [\n {\n \"name\": \"Usage\",\n \"rules\": [\n \"1,000 file nodes\",\n \"20,000 records per datasheet\",\n \"20,000,000 records per sapce\",\n \"7G/seats attachments storage per sapce\"\n ]\n },\n {\n \"name\": \"Features\",\n \"rules\": [\n \"Pin file nodes\",\n \"Gallery view,Kanban view and Architecture view are unlimited\",\n \"200 gantt views per sapce\",\n \"300 calendar views per sapce\",\n \"300 forms per sapce\",\n \"100 mirrors per sapce\",\n \"100 dashbords per sapce\",\n \"Widget is free for a limited time\",\n \"Advanced colors for rainbow tags\",\n \"Custom embedding\",\n \"Record activity goes back 6 months\",\n \"Trash goes back 6 months\",\n \"API is free for a limited time\",\n \"Automation is free for a limited time\"\n ]\n },\n {\n \"name\": \"Management and security\",\n \"rules\": [\n \"200 field permissions per sapce\",\n \"200 file node permissions per sapce\",\n \"10 admins per sapce\",\n \"Disable data export\"\n ]\n },\n {\n \"name\": \"Professional Services\",\n \"rules\": [\n \"Community\"\n ]\n }\n ]\n },\n {\n \"grade\": \"enterprise\",\n \"btnText\": \"Contacts us\",\n \"btnHref\": \"\",\n \"primaryContent\": [\n \"10,000 file nodes\",\n \"50,000 records per datasheet\",\n \"10G/seats attachments storage per sapce\",\n \"Unlimited permission and security settings\",\n \"Customer Success Manager\"\n ],\n \"details\": [\n {\n \"name\": \"Usage\",\n \"rules\": [\n \"10,000 file nodes\",\n \"50,000 records per datasheet\",\n \"50,0000,000 records per sapce\",\n \"10G/seats attachments storage per sapce\"\n ]\n },\n {\n \"name\": \"Features\",\n \"rules\": [\n \"Pin file nodes\",\n \"Gallery view,Kanban view and Architecture view are unlimited\",\n \"Gantt views are unlimited\",\n \"Calendar views are unlimited\",\n \"Forms are unlimited\",\n \"Mirrors are unlimited\",\n \"Dashbords are unlimited\",\n \"Widget is free for a limited time\",\n \"Advanced colors for rainbow tags\",\n \"Custom embedding\",\n \"Record activity goes back 24 months\",\n \"Trash goes back 24 months\",\n \"API is free for a limited time\",\n \"Automation is free for a limited time\"\n ]\n },\n {\n \"name\": \"Management and security\",\n \"rules\": [\n \"Field permissions are unlimited\",\n \"File node permissions are unlimited\",\n \"Admins are unlimited\",\n \"Watermark\",\n \"Disable data export\",\n \"Disable opening public links\",\n \"Disable copying datas\",\n \"Disable downloadimg files\",\n \"Disable inviting off-space user\",\n \"Space log\"\n ]\n },\n {\n \"name\": \"Professional Services\",\n \"rules\": [\n \"Customer Success Manager\",\n \"Custom function development (additional cost)\",\n \"Enterprise-level consulting training\"\n ]\n }\n ]\n }\n ]", + "subscription_grades_checklist_mobile_selfhost": "[\n {\n \"grade\": \"community\",\n \"btnText\": \"Dowload\",\n \"primaryContent\": [\n \"10,000 file nodes\",\n \"50,000 records per datasheet\",\n \"Unlimitied attachments storage per sapce\"\n ],\n \"details\": [\n {\n \"name\": \"Usage\",\n \"rules\": [\n \"10,000 file nodes\",\n \"50,000 records per datasheet\",\n \"50,0000,000 records per sapce\",\n \"Unlimitied attachments storage per sapce\"\n ]\n },\n {\n \"name\": \"Features\",\n \"rules\": [\n \"Pin file nodes\",\n \"Gallery view,Kanban view and Architecture view are unlimited\",\n \"Gantt views are unlimited\",\n \"Calendar views are unlimited\",\n \"Forms are unlimited\",\n \"Mirrors are unlimited\",\n \"Dashbords are unlimited\",\n \"Widget is free for a limited time\",\n \"Basic colors for rainbow tags\",\n \"Record activity goes back 24 months\",\n \"Trash goes back 24 months\",\n \"API is free for a limited time\",\n \"Automation is free for a limited time\"\n ]\n },\n {\n \"name\": \"Management and security\",\n \"rules\": [\n \"Not supported\"\n ]\n },\n {\n \"name\": \"Professional Services\",\n \"rules\": [\n \"Community\"\n ]\n }\n ]\n },\n {\n \"grade\": \"custom\",\n \"btnText\": \"Contacts us\",\n \"primaryContent\": [\n \"10,000 file nodes\",\n \"50,000 records per datasheet\",\n \"10G/seats attachments storage per sapce\",\n \"Unlimited permission and security settings\",\n \"Customer Success Manager\"\n ],\n \"details\": [\n {\n \"name\": \"Usage\",\n \"rules\": [\n \"10,000 file nodes\",\n \"50,000 records per datasheet\",\n \"50,0000,000 records per sapce\",\n \"Unlimited attachments storage per sapce\"\n ]\n },\n {\n \"name\": \"Features\",\n \"rules\": [\n \"Pin file nodes\",\n \"Gallery view,Kanban view and Architecture view are unlimited\",\n \"Gantt views are unlimited\",\n \"Calendar views are unlimited\",\n \"Forms are unlimited\",\n \"Mirrors are unlimited\",\n \"Dashbords are unlimited\",\n \"Widget is free for a limited time\",\n \"Advanced colors for rainbow tags\",\n \"Custom embedding\",\n \"Record activity goes back 24 months\",\n \"Trash goes back 24 months\",\n \"API is free for a limited time\",\n \"Automation is free for a limited time\"\n ]\n },\n {\n \"name\": \"Management and security\",\n \"rules\": [\n \"Field permissions are unlimited\",\n \"File node permissions are unlimited\",\n \"Admins are unlimited\",\n \"Watermark\",\n \"Disable data export\",\n \"Disable opening public links\",\n \"Disable copying datas\",\n \"Disable downloadimg files\",\n \"Disable inviting off-space user\",\n \"Space log\"\n ]\n },\n {\n \"name\": \"Professional Services\",\n \"rules\": [\n \"Customer Success Manager\",\n \"Custom function development (additional cost)\",\n \"Enterprise-level consulting training\"\n ]\n }\n ]\n }\n]", "subscription_information": "Subscription plan", "subscription_level": "Plan: ${level}", "subscription_product_seats": "Seat", @@ -5181,7 +5332,7 @@ "template_name_repetition_title": "\"${templateName}\" already exists. Do you want to replace it?", "template_no_template": "No templates", "template_not_found": "Can't find templates you want? Tell us", - "template_recommend_title": "Hot", + "template_recommend_title": "🌟 Hot", "template_type": "Template", "terms_of_service": "", "terms_of_service_pure_string": "Terms of service", @@ -5225,7 +5376,8 @@ "text_editor_tip_end": "\"Enter\" to end editing", "text_functions": "String Function", "thailand": "Thailand", - "the_current_automation_workflow_has_no_related_files_you_can_establish_a_link_by_adding_trigger_conditions_and_actions_on_the_left_side": "The current automation workflow has no related files. You can establish a link by adding trigger conditions and actions on the left side", + "the_button_field_is_misconfigured": "The button field is misconfigured, please check and try again", + "the_current_automation_workflow_has_no_related_files_you_can_establish_a_link_by_adding_trigger_conditions_and_actions_on_the_left_side": "The current automation workflow has no related file nodes. You can establish a link by adding trigger conditions and actions on the left side", "the_current_button_column_has_expired_please_reselect": "The current button column has expired, please reselect", "the_last_7_days": "the past 7 days", "the_last_month": "last 30 days", @@ -5327,6 +5479,7 @@ "timemachine_update_comment": "updated comment(s)", "times_per_month_unit": "call(s)/month", "times_unit": " call(s)", + "timing_rules": "Timing", "timor_leste": "Timor-Leste", "tip_del_success": "You can restore your Space within 7 days", "tip_do_you_want_to_know_about_field_permission": "Want to encrypt field data? Learn about field permissions", @@ -5385,8 +5538,8 @@ "training_data_source_title": "通过 \"dataDource\",您可以上传、导入和添加数据到数据集中。您可以将各种类型的数据文件包括图像、文本、等添加到数据集中,以满足您的训练需求。", "transfer_to_public": "Transfer ", "trash": "Trash", - "trash_over_limit_tip": "\"Silver\" space can view ${day} days of historical files, limited-time open experience", - "trash_tip": "You can restore files deleted in the past ${day} days from the Trash. You can only view files with \"manager\" permissions", + "trash_over_limit_tip": "\"Silver\" space can view ${day} days of historical file nodes, limited-time open experience", + "trash_tip": "You can restore file nodes deleted in the past ${day} days from the Trash. You can only view file nodes with \"manager\" permissions", "travel_and_outdoors": "Travel and outdoors", "tree_level": "Lv ${level}", "trial_expires": "Your free trial has expired", @@ -5514,6 +5667,7 @@ "verify_account_title": "Verify account", "verify_via_email": "Identity verification by email", "verify_via_phone": "Identity verification by SMS", + "video": "Video", "video_not_support_play": "The current video format does not support playing online", "vietnam": "Vietnam", "view": "View", @@ -5577,7 +5731,7 @@ "vika_invite_link_template": "From vikadata: You were invited to join the \"${spaceName}\" Space by ${nickName}.", "vika_official_accounts": "Official account", "vika_privacy_policy": "", - "vika_share_link_template": "From vikadata: ${nickName} has shared the \"${nodeName}\" file with you.", + "vika_share_link_template": "From vikadata: ${nickName} has shared the \"${nodeName}\" file node with you.", "vika_small_classroom": "Video tutorials", "vika_star": "Vika Planet", "vikaby_activity_train_camp": "Time-limited welfare", @@ -5744,7 +5898,7 @@ "widget_import_from_airtable_step_2_fields": "Fields", "widget_import_from_airtable_step_2_fields_type": "Field types", "widget_import_from_airtable_step_2_title": "2. Configure field type", - "widget_import_from_airtable_step_2_waring_file_upload": "The attachment column is detected. The widget currently only supports the import of files that do not exceed 10MB. Do you continue?", + "widget_import_from_airtable_step_2_waring_file_upload": "The attachment column is detected. The widget currently only supports the import of attachments that do not exceed 10MB. Do you continue?", "widget_import_from_airtable_step_3_button": "Stop", "widget_import_from_airtable_step_3_description": "Importing data ……", "widget_import_from_airtable_step_3_import_num": "Imported ${ROW_NUM} records", @@ -5845,12 +5999,12 @@ "workbench_instruction_of_all_member_setting_and_node_permission": "Controls what can do and what can't do from the workbench", "workbench_setting": "Workbench Permission", "workbench_setting_all": "Global settings", - "workbench_setting_cannot_export_datasheet_describle": "If turn on, datasheets of the workbench can be imported to local computer when member has the permission of the files.", + "workbench_setting_cannot_export_datasheet_describle": "If turn on, datasheets of the workbench can be imported to local computer when member has the permission of the file nodes.", "workbench_setting_cannot_export_datasheet_tips": "If members have the \"manageable\" permission to a datasheet, they can export it to a local file.", "workbench_setting_cannot_export_datasheet_title": "Allow exporting datasheets", "workbench_setting_show_watermark_tips": "The workbench and the contacts support watermarks to prevent members from leaking enterprise information. A watermark includes the name and phone number suffix/email prefix.", "workbench_setting_show_watermark_title": "Show watermarks", - "workbench_share_link_template": "From APITable: ${nickName} has shared the \"${nodeName}\" file with you.", + "workbench_share_link_template": "From APITable: ${nickName} has shared the \"${nodeName}\" file node with you.", "workbench_side_space_template": "Custom templates", "workbenck_shortcuts": "Workbench", "workdoc_attach_uploading": "Uploading...", @@ -5862,7 +6016,7 @@ "workdoc_color_title": "Text color", "workdoc_create": "Create WorkDoc", "workdoc_expanded": "Expand the table of contents", - "workdoc_image_max_10mb": "The image size cannot exceed 10MB", + "workdoc_image_max_size": "The image size cannot exceed ${size}", "workdoc_info": "WorkDoc Info", "workdoc_info_create_time": "Created at", "workdoc_info_creator": "Created by", @@ -5870,6 +6024,7 @@ "workdoc_info_last_modify_time": "Last modified at", "workdoc_link_placeholder": "Please enter link", "workdoc_only_image": "Only image is allowed", + "workdoc_only_video": "Only video is allowed", "workdoc_text_placeholder": "Enter \"/\" to start", "workdoc_title_placeholder": "Please enter title", "workdoc_unnamed": "Unnamed WorkDoc", @@ -5878,9 +6033,11 @@ "workdoc_unsave_ok": "Discard changes", "workdoc_unsave_title": "The WorkDoc has not been saved", "workdoc_upload_failed": "Upload failed", + "workdoc_video_max_size": "The video size cannot exceed ${size}", "workdoc_ws_connected": "Connected", "workdoc_ws_connecting": "Connecting...", "workdoc_ws_disconnected": "Disconnected", + "workdoc_ws_reconnecting": "Reconnecting...", "workflow_execute_failed_notify": " failed to execute at . Please review the execution history to troubleshoot the issue. If you need any assistance, please contact our customer service team.", "workspace_data": "Space data", "workspace_files": "Workbench data", diff --git a/packages/datasheet/public/file/langs/strings.es-ES.json b/packages/datasheet/public/file/langs/strings.es-ES.json index 894e3f291b..30c1e97e81 100644 --- a/packages/datasheet/public/file/langs/strings.es-ES.json +++ b/packages/datasheet/public/file/langs/strings.es-ES.json @@ -146,6 +146,15 @@ "agreed": "Aprobado", "ai_advanced_mode_desc": "El modo avanzado permite a los usuarios personalizar las indicaciones, proporcionando un mayor control sobre el comportamiento y las respuestas del AI agent.", "ai_advanced_mode_title": "Modelo avanzado", + "ai_agent_anonymous": "Anónimo${ID}", + "ai_agent_conversation_continue_not_supported": "Actualmente no se admite continuar una conversación anterior", + "ai_agent_conversation_list": "Lista de conversación", + "ai_agent_conversation_log": "Registro de conversación", + "ai_agent_conversation_title": "Título de la conversación", + "ai_agent_feedback": "Comentario", + "ai_agent_historical_message": "Lo anterior es un mensaje histórico.", + "ai_agent_history": "Historia", + "ai_agent_message_consumed": "Mensaje consumido", "ai_api_curl_template": "## Create chat completions\n\n```bash\n\ncurl -X POST \"{{apiBase}}/fusion/v1/ai/{{aiId}}/chat/completions\" \\n -H \"Content-Type: application/json\" \\n -H \"Authorization: Bearer {{token}}\" \\n -d '{\n \"model\": \"gpt-3.5-turbo\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"You are a helpful assistant.\"\n },\n {\n \"role\": \"user\",\n \"content\": \"Hello!\"\n }\n ]\n }'\n\n```\n\n## Returned data example\n\n```json\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", "ai_api_footer_desc": "¿Incorporar al AI agent en tu sitio web? Más información", "ai_api_javascript_template": "## Initialize SDK [![github]({{ githubIcon }})](https://github.com/openai/openai-node)\nAITable's chat completion API is compatible with OpenAI's Node.js SDK. You can use our service with the same SDK by simply changing the configuration as follows:\n\n\n```javascript\nconst { Configuration, OpenAIApi } = require(\"openai\");\nconst configuration = new Configuration({\n apiKey: \"{{token}}\",\n basePath: \"{{apiBase}}/fusion/v1/ai/{{aiId}}\"\n});\n```\n\n## Create chat completions\n\n```javascript\nconst openai = new OpenAIApi(configuration);\nconst chatCompletion = await openai.createChatCompletion({\n model: \"gpt-3.5-turbo\",\n messages: [{role: \"user\", content: \"Hello world\"}],\n});\n```\n\n## Returned data example\n\n```javascript\n\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", @@ -161,6 +170,9 @@ "ai_chat_unit": "Aibot(s)", "ai_close_setting_tip_content": "Usted ha hecho cambios. ¿ quieres descartarlos?", "ai_close_setting_tip_title": "Consejos", + "ai_copilot_generate_response": "Generando respuesta para usted...", + "ai_copilot_processs": "Procesando, por favor espere...", + "ai_copilot_start_process_request": "Iniciando el procesamiento de su solicitud...", "ai_create_guide_btn_text": "Seleccionar tabla de datos", "ai_create_guide_content": "Como AI agent, puedo responder a sus preguntas basándose en el conocimiento que he aprendido. Antes de iniciar la conversación, por favor seleccione una hoja de datos como base de conocimiento, y leeré todos los datos en ella para su aprendizaje.", "ai_credit_cost_chart_title": "Costo de crédito", @@ -221,7 +233,7 @@ "ai_prompt_title": "Promover", "ai_prompt_wrong_content": "Por favor, incluya el {context} y las {question} en el texto.", "ai_query_of_number": "Uso", - "ai_remain_credit_label": "Mensaje restante: ${crédito}", + "ai_remain_credit_label": "Mensaje restante: ${credit}", "ai_retrain": "Reciclaje", "ai_robot_data_source_title": "Colección de conjuntos de datos", "ai_robot_type_QA_desc": "Un agente de preguntas y respuestas basado en PNL y aprendizaje automático responde de forma rápida y precisa varias preguntas y proporciona información en tiempo real y consejos útiles a los usuarios.", @@ -629,7 +641,7 @@ "apps_support": "Soporte cliente de plataforma completa", "archive_delete_record": "Eliminar registros archivados", "archive_delete_record_title": "Eliminar el registro", - "archive_notice": "

Está intentando archivar registros específicos. Archivar los registros resultará en los siguientes cambios:

1. Se cancelará todo enlace bidireccional para este registro.

2. No se admite la edición

3. No se admiten funciones como recordatorios de fechas y registros de suscripción

4. Ya no participa en el cálculo de búsquedas, fórmulas y otros campos.

Estás seguro de que quieres continuar? (Puedes desarchivar en Archive Box en Avanzado)

", + "archive_notice": "

Está intentando archivar registros específicos. Archivar los registros resultará en los siguientes cambios:

1. No se admite la edición

2. No se admiten funciones como recordatorios de fechas y registros de suscripción

3. Ya no participar en el cálculo de búsquedas, fórmulas y otros campos.

Estás seguro de que quieres continuar? (Puedes desarchivar en Archive Box en Avanzado)

", "archive_record_in_activity": "Archivó este registro", "archive_record_in_menu": "Registro de archivo", "archive_record_success": "Se han archivado con éxito los registros", @@ -689,6 +701,8 @@ "audit_add_field_role_detail": "[a class = \"membername\" > en la tabla de datos \"[a class =\" nodename \"> < a > en la tabla de datos\" [a class = \"times\" > en la tabla de datos, para el campo [a class = \"field name\" > en la tabla de datos, añadir [a class = \"unitname\" > en la tabla de datos] [/ a > para el personaje ", "audit_add_node_role": "Añadir permisos de archivo", "audit_add_node_role_detail": "Agregar permiso de archivo, establecer 「${unitNames}」a「${role}」de 「${currentNodeName }」", + "audit_add_node_role_detail_end": "to「${role}", + "audit_add_node_role_detail_start": "Add file node permission,set「${unitNames}」", "audit_admin_permission_change_event": "Cambiar los permisos del Administrador", "audit_create_template": "Crear una plantilla", "audit_create_template_detail": "Crear una plantilla", @@ -697,20 +711,30 @@ "audit_delete_field_role_detail": "Auditoría", "audit_delete_node_role": "Eliminar permisos de archivo", "audit_delete_node_role_detail": "Eliminar permiso de archivo,eliminar「${unitNames}」`s 「${role}」rol de 「${currentNodeName}」", + "audit_delete_node_role_detail_end": "at 「${role}」role", + "audit_delete_node_role_detail_start": "Delete file node permission,delete「${unitNames}」from", "audit_delete_template": "Eliminar plantilla", "audit_delete_template_detail": "Eliminar plantilla", "audit_disable_field_role": "Desactivar permisos de campo", "audit_disable_field_role_detail": "Auditoría", "audit_disable_node_role": "Desactivar permisos de archivo", "audit_disable_node_role_detail": "Deshabilitar el permiso de ${nodeType} 「${currentNodeName}」", + "audit_disable_node_role_detail_end": "`s permission", + "audit_disable_node_role_detail_start": "Disable ${nodeType}", "audit_disable_node_share": "Cierre el enlace público del archivo", "audit_disable_node_share_detail": "Cierre el enlace público de ${nodeType} 「${currentNodeName}」", + "audit_disable_node_share_detail_end": "public link", + "audit_disable_node_share_detail_start": "Close ${nodeType}", "audit_enable_field_role": "Activar permisos de campo", "audit_enable_field_role_detail": "Auditoría", "audit_enable_node_role": "Activar permisos de archivo", "audit_enable_node_role_detail": "Habilitar el permiso de ${nodeType} 「${currentNodeName}」", + "audit_enable_node_role_detail_end": "`s permission", + "audit_enable_node_role_detail_start": "Enable ${nodeType}", "audit_enable_node_share": "Abrir el enlace público del archivo", "audit_enable_node_share_detail": "Abra el enlace público de ${nodeType} 「${currentNodeName}」", + "audit_enable_node_share_detail_end": "public link", + "audit_enable_node_share_detail_start": "Open ${nodeType}", "audit_login_event": "Evento de inicio de sesión", "audit_logout_event": "Inglés", "audit_organization_change_event": "La estructura organizativa de los contactos ha cambiado", @@ -731,18 +755,25 @@ "audit_space_invite_user_detail": "Auditoría", "audit_space_node_copy": "Archivos duplicados", "audit_space_node_copy_detail": "Duplique ${nodeType} 「${sourceNodeName}」, el nombre del nuevo archivo es 「${currentNodeName}」", + "audit_space_node_copy_detail_start": "Duplicate ${nodeType} 「${sourceNodeName}」, the new file node's name is", "audit_space_node_create": "Crear archivo", "audit_space_node_create_detail": "Crear ${nodeType} llamado 「${currentNodeName}」", + "audit_space_node_create_detail_start": "Create a ${nodeType} named", "audit_space_node_delete": "Eliminar archivo", "audit_space_node_delete_detail": "Eliminar ${nodeType}, el nombre es 「${currentNodeName}」", + "audit_space_node_delete_detail_start": "Delete ${nodeType} named", "audit_space_node_export": "Exportar tablas de datos", "audit_space_node_export_detail": "El miembro ${member_name} exportó la hoja de datos ${node_name}", "audit_space_node_import": "Importar archivos", "audit_space_node_import_detail": "Importe un archivo llamado 「${nodeName}」", + "audit_space_node_import_detail_start": "Import a file node named", "audit_space_node_move": "Mover Archivos", "audit_space_node_move_detail": "Mueva ${nodeType} 「${currentNodeName}」 a la carpeta 「${parentName}」", + "audit_space_node_move_detail_end": "to the folder「${parentName}」", + "audit_space_node_move_detail_start": "Move ${nodeType}", "audit_space_node_rename": "Cambiar el nombre del archivo", "audit_space_node_rename_detail": "Cambiar el nombre de ${nodeType} 「${oldNodeName}」a 「${nodeName}」", + "audit_space_node_rename_detail_start": "Rename ${nodeType} 「${oldNodeName}」to", "audit_space_node_sort": "Auditoría", "audit_space_node_sort_detail": "Auditoría", "audit_space_node_update_cover": "Auditoría", @@ -757,17 +788,24 @@ "audit_space_rubbish_node_delete_detail": "Auditoría", "audit_space_rubbish_node_recover": "Restaurar archivo", "audit_space_rubbish_node_recover_detail": "Restaure ${nodeType} del contenedor de recuperación con el nombre 「${currentNodeName}」", + "audit_space_rubbish_node_recover_detail_end": "from the trash", + "audit_space_rubbish_node_recover_detail_start": "Restore ${nodeType}", "audit_space_template_event": "Cambio de plantilla", "audit_space_update_logo": "Auditoría", "audit_space_update_logo_detail": "Auditoría", "audit_store_share_node": "Guardar archivos compartidos", "audit_store_share_node_detail": "Restaure ${nodeType} al espacio, el nombre es 「${nodeName}」", + "audit_store_share_node_detail_start": "Restore ${nodeType} to the space, name is", "audit_update_field_role": "Auditoría", "audit_update_field_role_detail": "Auditoría", "audit_update_node_role": "Modificar permisos de archivo", "audit_update_node_role_detail": "Modificar permiso de archivo, modificar el rol de ${unitNames}」 a 「${role}」de 「${currentNodeName}」", + "audit_update_node_role_detail_end": "to「${role}」role", + "audit_update_node_role_detail_start": "Modify file node permission,modify「${unitNames}」from", "audit_update_node_share_setting": "Modificar la configuración del enlace público del archivo", "audit_update_node_share_setting_detail": "Modificar ${nodeType} 「${currentNodeName}」 enlace público", + "audit_update_node_share_setting_detail_end": "public link settings", + "audit_update_node_share_setting_detail_start": "Modify ${nodeType}", "audit_user_login": "Inicio de sesión del usuario", "audit_user_login_detail": "Auditoría", "audit_user_logout": "Cancelación del usuario", @@ -809,6 +847,7 @@ "automation_enabled_return_via_related_files": "La automatización está habilitada. Vuelva a ingresar la tabla original a través de \"Archivos relacionados\" para usar el botón nuevo.", "automation_field": "Campo", "automation_import_variables_from_pre_tep": "Obtener datos del paso previo", + "automation_is_not_yet_enabled": "La automatización aún no está habilitada, habilítela e inténtelo nuevamente.", "automation_last_edited_by": "Última edición por", "automation_last_edited_time": "Hora de la última edición", "automation_manager_label": "Puede realizar todas las acciones en la automatización.", @@ -834,6 +873,7 @@ "automation_runs_this_month": "Funciona este mes", "automation_stay_tuned": "Manténganse al tanto", "automation_success": "Éxito", + "automation_tips": "El campo del botón está mal configurado, verifíquelo e inténtelo nuevamente.", "automation_updater_label": "Puede ver el historial de ejecución de la automatización.", "automation_variabel_empty": "No hay datos que puedan usarse en el paso previo, ajústelos e inténtelo nuevamente.", "automation_variable_datasheet": "Obtener datos de ${NODE_NAME}", @@ -869,6 +909,7 @@ "bermuda": "Bermudas", "bhutan": "Bhután", "billing_over_limit_tip_common": "El uso del espacio ha superado el límite y podrá disfrutar de una cantidad mayor después de la actualización.", + "billing_over_limit_tip_forbidden": "Su duración de prueba o período de suscripción ha expirado. Comuníquese con el asesor de ventas para renovar.", "billing_over_limit_tip_widget": "La cantidad de instalaciones de widgets ha excedido el límite y puede actualizar para obtener un mayor uso.", "billing_period": "Período de facturación: ${period}", "billing_subscription_warning": "Experiencia funcional", @@ -928,10 +969,19 @@ "button_text": "Botón de texto", "button_text_click_start": "Haga clic para comenzar", "button_type": "Tipo de botón", + "by_at": "en", + "by_days": "Días", + "by_every": "cada", "by_field_id": "Usar el ID de campo", + "by_hours": "Horas", + "by_in": "en", + "by_min": "minutos)", + "by_months": "Meses", + "by_on": "sobre el", "by_the_day": "Por día", "by_the_month": "Revista mensual", "by_the_year": "Anual", + "by_weeks": "Semanas", "calendar_add_date_time_field": "Crear campo de fecha", "calendar_color_more": "Más colores", "calendar_const_detail_weeks": "[\"lunes\",\"martes\",\"miércoles\",\"jueves\",\"viernes\",\"sábado\",\"domingo\"]", @@ -995,6 +1045,14 @@ "cannot_activate_space_by_space_limit": "No se puede activar el límite espacial", "cannot_join_space": "No puedes unirte a la nueva estación espacial porque ya has superado la cuota máxima de 10 estaciones espaciales.", "cannot_switch_field_permission": "Establezca los permisos de campo a no más de los permisos de archivo.", + "capacity_file_detail_desc": "The total number of file nodes within the Space is calculated by adding the file nodes from the Team to the file nodes created by each member in their Private. Not enough capacity?", + "capacity_file_detail_title": "File Capacity", + "capacity_file_member": "Member", + "capacity_file_member_private_node_count": "Private", + "capacity_file_member_private_percent": "Percent", + "capacity_file_member_team": "Team", + "capacity_file_member_team_node_count": "Team", + "capacity_file_upgrade": "Click to upgrade your Space", "capacity_from_official_gift": "De regalos oficiales", "capacity_from_participation": "Por invitación ${user} unirse al espacio", "capacity_from_purchase": "Por capacidad de compra", @@ -1031,6 +1089,8 @@ "catalog": "Explorador", "catalog_add_from_template_btn_title": "Añadir desde la plantilla", "catalog_empty_tips": "Este área de Trabajo está ahora vacía. Comienza a crear archivos con plantillas.", + "catalog_private": "Private", + "catalog_team": "Team", "category_blank": "[en blanco]", "catering": "Restauración", "cayman_islands": "Islas Caimán", @@ -1099,6 +1159,7 @@ "choose_type_of_vika_field": "Seleccionar tipo de campo", "choose_your_own_space": "(solo se admite guardar en su propio espacio como creador)", "chose_new_primary_admin_button": "Distribución", + "chunk_stopping_title": "Stopping", "claim_special_offer": "¡¡ solicite este descuento especial!", "clear": "Claro", "clear_all_fields": "Eliminar todo", @@ -1229,6 +1290,7 @@ "confirm_del_current_team": "¿Está seguro de que quiere eliminar al equipo?", "confirm_delete": "Confirmar y eliminar", "confirm_delete_node_name_as": "¿Está seguro de que desea eliminar \"${nodeNameDiv}\"?", + "confirm_delete_private_node_name_as": "Are you sure you want to delete \"${nodeNameDiv}\"? The file will be deleted from the Space and the trash.", "confirm_delete_space_btn": "Confirmar y eliminar espacios", "confirm_exit": "Confirmar salida", "confirm_exit_space_with_name": "Confirme si desea salir del espacio \"${spaceNameDiv}\"", @@ -1266,6 +1328,14 @@ "convert": "Conversión", "convert_tip": "Esta operación puede eliminar los datos en algunas células. Si se produce algún accidente, puede retirar la operación.", "cook_islands": "Islas Cook", + "copilot_auto_agent_desc": "¿No estás seguro de cuál elegir Agente? Pruebe AutoAgent.", + "copilot_auto_agent_name": "Agente automático", + "copilot_data_agent_desc": "Generar análisis de datos/visualizaciones basadas en sus vistas.", + "copilot_data_agent_name": "Agente de datos", + "copilot_data_agent_policy": "Al chatear con Copilot, aceptas la política de términos de usuario", + "copilot_data_agent_policy_button": "Política", + "copilot_help_agent_desc": "Pregunte cualquier cosa sobre los documentos del centro de ayuda de AITable.", + "copilot_help_agent_name": "Recuperar centro de ayuda", "copy": "Copiar", "copy_automation_url": "Copiar URL", "copy_card_link": "Copiar la dirección de registro", @@ -1310,6 +1380,7 @@ "create_mirror_guide_content": "La función de espejo tiene la capacidad de ocultar ciertos datos. Puede establecer \"condiciones de filtro\" y \"campos ocultos\" en la vista de hoja de datos original para controlar qué registros y campos se muestran en el espejo.\n
\n
\nSi se usa junto con la función de \"bloqueo de vista\", puede evitar que otros realicen modificaciones.\n
\n
\nAdemás, puede ir a \"Tabla original>Campos ocultos\" para modificar la configuración de \"Mostrar todos los campos en espejos\".", "create_mirror_guide_title": "El espejo esconde algunos registros y campos", "create_new_button_field": "Crear un nuevo campo de columna de botón", + "create_private_node_tip": "Personal or temporary draft documents can be created here ${link}", "create_public_invitation_link": "Crear enlaces de invitación pública", "create_space_sub_title": "Hola, por favor, nombra tu espacio compartido.", "create_team_fail": "Falló la creación del equipo", @@ -1373,10 +1444,12 @@ "custom_enterprise": "Personalizar el espacio empresarial para usted", "custom_function_development": "Desarrollo de funciones personalizadas", "custom_grade_desc": "Prestación de servicios profesionales para el despliegue de agentes, instalación privada, soporte de asistencia y personalización", + "custom_page_setting_title": "Add a custom page", "custom_picture": "Imagen personalizada", "custom_style": "Estilo", "custom_upload": "Carga personalizada", "custom_upload_tip": "Se recomienda usar imágenes de tamaño cuadrado 1: 1 para una mejor experiencia visual", + "custome_page_title": "Custom Web", "cut_cell_data": "Cortar celdas", "cyprus": "Chipre", "czech": "Checo", @@ -1428,6 +1501,7 @@ "default": "Incumplimiento de contrato", "default_create_ai_chat_bot": "Nuevo AI agent", "default_create_automation": "Nueva automatización", + "default_create_custom_page": "Nueva página personalizada", "default_create_dashboard": "Nuevo salpicadero", "default_create_datasheet": "Nouvelle fiche technique", "default_create_file": "Nuevos archivos", @@ -1449,6 +1523,7 @@ "del_invitation_link": "Eliminar el enlace de invitación", "del_invitation_link_desc": "El enlace no será válido después de la eliminación", "del_space_now": "Eliminar espacio para siempre", + "del_space_now_confirm_tip": "For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "del_space_now_tip": "No se puede restaurar el espacio después de la eliminación. Todos los archivos y archivos adjuntos serán eliminados.", "del_space_res_tip": "Espacios eliminados", "del_team_success": "El equipo de eliminación fue exitoso", @@ -1644,6 +1719,62 @@ "embed_error_page_help": "Aprende más", "embed_fail_og_description_content": "Este enlace público incrustado ha sido desactivado y no está disponible por el momento", "embed_failed": "Los enlaces incrustados no están disponibles,", + "embed_link_bilibili": "bilibili", + "embed_link_bilibili_desc": "Al insertar los videos de bilibili, puede ver tutoriales y guías, o ver la página de inicio del canal en Vika.", + "embed_link_bilibili_link_text": "Cómo insertar el vídeo de bilibili", + "embed_link_bilibili_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-bilibili-video", + "embed_link_default": "Cualquier cosa", + "embed_link_default_desc": "Pegue un enlace para ver cualquier sitio web.", + "embed_link_default_link_text": "Aprende más", + "embed_link_default_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_link_figma": "Figma", + "embed_link_figma_desc": "Al incorporar archivos Figma, los miembros pueden ver y editar borradores de diseño de manera más conveniente, mejorando la eficiencia de la colaboración.", + "embed_link_figma_link_text": "Cómo incrustar archivos Figma", + "embed_link_figma_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-figma-file", + "embed_link_google_docs": "Docs", + "embed_link_google_docs_desc": "Al incorporar Google Docs, puede editar y ver documentos en AITable para facilitar la colaboración en equipo.", + "embed_link_google_docs_link_text": "Cómo incrustar Google Docs", + "embed_link_google_docs_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-docs-file", + "embed_link_google_sheets": "Sheets", + "embed_link_google_sheets_desc": "Al incorporar Google Sheets, puede editar y ver tablas en AITable para facilitar la colaboración en equipo.", + "embed_link_google_sheets_link_text": "Cómo incrustar Hojas de cálculo de Google", + "embed_link_google_sheets_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-sheets-file", + "embed_link_jishi_design": "Diseño JS", + "embed_link_jishi_design_desc": "Al incorporar archivos JSdesign, los miembros pueden ver y editar borradores de diseño de manera más conveniente, mejorando la eficiencia de la colaboración.", + "embed_link_jishi_design_link_text": "Cómo incrustar archivos JSdesign", + "embed_link_jishi_design_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-js-design-file", + "embed_link_tencent_docs": "Documentos Tencent", + "embed_link_tencent_docs_desc": "Al incorporar Tencent Docs, puede editar y ver documentos de Tencent en Vika para mejorar la eficiencia de la colaboración.", + "embed_link_tencent_docs_link_text": "Cómo incrustar documentos Tencent", + "embed_link_tencent_docs_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-tencent-docs", + "embed_link_wps": "WPS", + "embed_link_wps_desc": "Al incorporar archivos WPS, puede editar y ver documentos, tablas y formularios WPS en Vika para mejorar la eficiencia de la colaboración.", + "embed_link_wps_link_text": "Cómo incrustar archivos WPS", + "embed_link_wps_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-wps-file", + "embed_link_youtube": "YouTube", + "embed_link_youtube_desc": "Al insertar videos de YouTube, puede ver tutoriales y guías, o ver la página de inicio del canal en AITable.", + "embed_link_youtube_link_text": "Cómo insertar vídeos de YouTube", + "embed_link_youtube_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-youtube-video", + "embed_page": "Pagina personalizada", + "embed_page_add_url": "Agregar URL", + "embed_page_doc_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_page_function_desc": "Agregue páginas web a ${edition} para acceder fácilmente a documentos, videos y más de sitios web de terceros. Puede agregar enlaces a sitios web recomendados o cualquier enlace personalizado.", + "embed_page_node_permission_editor": "Sobre la base de \"solo actualización\", también se puede abrir el intercambio público del archivo.", + "embed_page_node_permission_manager": "Puede realizar todas las acciones en el archivo.", + "embed_page_node_permission_reader": "Puede ver el contenido de la página personalizada y la información básica del archivo.", + "embed_page_node_permission_updater": "Sobre la base de \"solo lectura\", también puede modificar el enlace de la página personalizada.", + "embed_page_setting_title": "Agregar una página personalizada", + "embed_page_url_invalid": "Por favor ingresa la URL correcta", + "embed_paste_link_bilibili_placeholder": "Pegue el enlace del video bilibili", + "embed_paste_link_default_placeholder": "Pega la URL", + "embed_paste_link_figma_placeholder": "Pegue el enlace para compartir del archivo Figma", + "embed_paste_link_google_docs_placeholder": "Pegue el enlace para compartir de Google Docs", + "embed_paste_link_google_sheets_placeholder": "Pegue el enlace para compartir de Google Sheets", + "embed_paste_link_jsdesign_placeholder": "Pegue el enlace para compartir del archivo JSdesign", + "embed_paste_link_tencent_docs_placeholder": "Pegue el enlace para compartir de Tencent Docs", + "embed_paste_link_wps_placeholder": "Pegue el enlace para compartir del archivo WPS", + "embed_paste_link_youtube_placeholder": "Pega el enlace del vídeo de YouTube.", + "embed_success": "Agregar con éxito", "emoji_activity": "Actividades", "emoji_custom": "Costumbres", "emoji_flags": "Bandera", @@ -1750,6 +1881,11 @@ "estonia": "Estonia", "ethiopia": "Etiopía", "event_planning": "Planificación del evento", + "every": "Cada", + "every_day_at": "día(s) en", + "every_hour_at": "hora(s) a las", + "every_month_at": "mes(es) en el", + "every_week_at": "Cada semana en", "everyday_life": "Vida diaria", "everyone_visible": "Visible para todos", "exact_date": "Fecha exacta", @@ -1760,6 +1896,7 @@ "exchange": "Rescate", "exchange_code_times_tip": "Nota: el Código de cambio solo se puede usar una vez", "exclusive_consultant": "Consultor exclusivo V +.", + "exclusive_limit_plan_desc": "Nivel limitado exclusivo", "exist_experience": "Experiencia de salida", "exits_space": "Espacio de salida", "expand": "Ampliación", @@ -1786,7 +1923,7 @@ "expired": "Expiración", "export": "Se está exportando...", "export_brand_desc": "Soporte técnico", - "export_current_preview_view_data": "", + "export_current_preview_view_data": "Export current preview view data", "export_gantt_button_tips": "Exportar al archivo. PNG", "export_gantt_chart": "Exportar mapa de Gantt", "export_to_excel": "Exportar datos", @@ -2357,26 +2494,26 @@ "gantt_config_color_by_single_select_pleaseholder": "Seleccionar campo de selección", "gantt_config_color_help": "Cómo configurar", "gantt_config_friday": "Viernes", - "gantt_config_friday_in_bar": "Viernes", + "gantt_config_friday_in_bar": "Vie", "gantt_config_friday_in_select": "Viernes", "gantt_config_monday": "Lunes", - "gantt_config_monday_in_bar": "Lunes", + "gantt_config_monday_in_bar": "Lun", "gantt_config_monday_in_select": "Lunes", "gantt_config_only_count_workdays": "La duración solo se calcula en días hábiles.", - "gantt_config_saturday": "Hoy es sábado.", - "gantt_config_saturday_in_bar": "Hoy es sábado.", - "gantt_config_saturday_in_select": "Hoy es sábado.", + "gantt_config_saturday": "Sábado", + "gantt_config_saturday_in_bar": "Sáb", + "gantt_config_saturday_in_select": "Sábado", "gantt_config_sunday": "Domingo", - "gantt_config_sunday_in_bar": "Domingo", + "gantt_config_sunday_in_bar": "Dom", "gantt_config_sunday_in_select": "Domingo", - "gantt_config_thursday": "Hoy es jueves.", - "gantt_config_thursday_in_bar": "Universidad de Tsinghua", - "gantt_config_thursday_in_select": "Universidad de Tsinghua", + "gantt_config_thursday": "Jueves", + "gantt_config_thursday_in_bar": "Jue", + "gantt_config_thursday_in_select": "Jueves", "gantt_config_tuesday": "Martes", - "gantt_config_tuesday_in_bar": "Martes", + "gantt_config_tuesday_in_bar": "Mar", "gantt_config_tuesday_in_select": "Martes", "gantt_config_wednesday": "Miércoles", - "gantt_config_wednesday_in_bar": "Miércoles", + "gantt_config_wednesday_in_bar": "Mié", "gantt_config_wednesday_in_select": "Miércoles", "gantt_config_weekdays_range": "${weekday} a ${weekday}", "gantt_config_workdays_a_week": "Días hábiles estándar personalizados", @@ -2458,6 +2595,7 @@ "gold_grade": "Oro", "gold_grade_desc": "Adecuado para equipos con procesos de negocio complejos", "gold_seat_200_desc": "200", + "gold_seat_300_desc": "300", "golden_grade": "Oro", "got_it": "Lo Tengo.", "got_v_coins": "Recompensa V monedas", @@ -2491,6 +2629,8 @@ "guests_per_space": "Huéspedes en cada espacio", "guide_1": "啊这", "guide_2": "Solo se tarda unos minutos en aprender las funciones básicas. ¡¡ a partir de este momento, el trabajo es más eficiente!", + "guide_flow_modal_contact_sales": "Contacto Ventas", + "guide_flow_modal_get_started": "Empezar", "guide_flow_of_catalog_step1": "Este es el catálogo de trabajo en el que se almacenan todas las carpetas y archivos de space.", "guide_flow_of_catalog_step2": "En el catálogo de trabajo, puede crear una tabla de datos o una carpeta según sea necesario.", "guide_flow_of_click_add_view_step1": "Además de algunas vistas básicas, si tiene un adjunto en formato de imagen, se recomienda encarecidamente crear una vista de álbum.", @@ -2669,6 +2809,7 @@ "intro_widget_tips": "¿Qué es widget?", "introduction": "Introducción", "invalid_action_sort_tip": "Como campo de agrupación, se ha establecido su clasificación. La configuración del pedido actual no entrará en vigor.", + "invalid_automation_configuration": "Configuración de automatización no válida, verifíquela e inténtelo nuevamente.", "invalid_field_type": "Tipo de campo no válido", "invalid_option_sort_tip": "Como campo de agrupación, se ha establecido su clasificación.", "invalid_redemption_code_entered": "El Código de cambio no es válido", @@ -2799,6 +2940,9 @@ "label_format_day_month_and_year_split_by_slash": "Día / mes / año", "label_format_month": "Mes", "label_format_month_and_day_split_by_dash": "Año, mes, día", + "label_format_month_day_year_split_by_dash": "Month-Day-Year", + "label_format_month_day_year_split_by_slash": "Month/Day/Year", + "label_format_month_day_year_two_digit_year_split_by_slash": "Month/Day/Year (Two-digit year)", "label_format_year": "Año", "label_format_year_and_month_split_by_dash": "Año y mes", "label_format_year_month_and_day_split_by_dash": "Año, mes, día", @@ -2877,6 +3021,7 @@ "lark_version_enterprise": "El plan empresarial de Lark", "lark_version_standard": "Plano estándar de Lark", "lark_versions_free": "Plano básico de Lark", + "last_day": "Último día", "last_modified_by_select_modal_desc": "Si se edita alguno de los campos seleccionados a continuación, el miembro recién editado se mostrará en el campo editado por última vez.", "last_modified_time_select_modal_desc": "Si se edita alguno de los campos seleccionados a continuación, el tiempo de edición más reciente se mostrará en el campo de tiempo de la última edición.", "last_step": "Volver", @@ -3021,7 +3166,7 @@ "mail_invite_fail": "La invitación por correo fue exitosa.", "mail_invite_success": "La invitación por correo fue exitosa.", "main_admin_name": "Nombre del Administrador", - "main_admin_page_desc": "Los administradores pueden acceder completamente a los espacios, como los administradores de gametos y la propiedad de los espacios de transferencia.", + "main_admin_page_desc": "El administrador tiene acceso completo al Espacio, como administrar miembros y administrar la configuración del Espacio.", "main_contain": "Contenido principal", "malawi": "Malaui", "malaysia": "Malasia", @@ -3241,8 +3386,12 @@ "more_widget": "Más gadgets", "morocco": "Marruecos", "move": "Mover", + "move_datasheet_link_warn": "Cannot be moved to Team Area alone, because there is a two-way link from the current datasheet to another datasheet, it is recommended to put them in a folder and then move them", "move_favorite_node_fail": "El movimiento del nodo falló. El sistema actualizará automáticamente la lista.", + "move_folder_link_warn": "Cannot be moved to Team Area because the files in the current folder are linked to files outside the folder (may be two-way links or linked by forms, etc.) We recommend that they be placed in a folder before moving", "move_node_modal_content": "Después de moverse, la visibilidad del archivo puede verse afectada por la carpeta padre.", + "move_other_link_no_permission": "Unable to move to the corresponding folder because you do not have administrative rights to the folder", + "move_other_link_warn": "It is not allowed to move ${node type} to Team Area alone, because it connects to the datasheet of Private Area, it is recommended to put them in a folder before moving them", "move_to": "Mover a", "move_to_error_equal_parent": "El archivo se encuentra bajo la carpeta actual. Por favor, elija otra carpeta", "move_to_modal_title": "Mover [${name}] a", @@ -3273,7 +3422,9 @@ "new_a_line": "Tecla shift + enter: cambiar de línea", "new_automation": "Nueva automatización", "new_caledonia": "Nueva Caledonia", + "new_custom_page": "New custom page", "new_datasheet": "Nueva tabla de datos", + "new_ebmed_page": "Nueva página personalizada", "new_folder": "Nueva carpeta", "new_folder_btn_title": "Carpetas", "new_folder_tooltip": "Crear una carpeta", @@ -3439,7 +3590,7 @@ "nvc_start_text": "Arrastre la barra al extremo derecho", "nvc_yes_text": "Confirmado", "obtain_verification_code": "El Código de verificación no se ha obtenido o ha expirado", - "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrzw0miJVmSkJ7eBBa9k/fomx5qPX0JGPFvfEEP\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", + "offical_website_footer_nav_data": "[{ \"title\": \"产品\", \"lists\": [{ \"name\": \"快速入门\", \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick- inicio\" }, { \"nombre\": \"产品指南\", \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\" }, { \"nombre\": \"产品价格\", \"url\": \"/precios/\" }, { \"name\": \"产品路线图\", \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\" }] }, { \"title\": \"关于我们\", \"lists\": [{ \"name\": \"公司介绍\", \"url\": \"/company/\" }, { \"name\": \"加入我们\", \"url \": \"/únete a nosotros/\" }, { \"name\": \"媒体报道\", \"url\": \"/press/\" }, { \"name\": \"vika维格课堂\", \"url\": \"https ://edu.vika.cn/\" }, { \"name\": \"维格合伙人\", \"url\": \"/partners/\" }] }, { \"title\": \"解决方案\", \"listas\" : [{ \"name\": \"PMO项目群管理\", \"url\": \"/business-pmo/\" }, { \"name\": \"智慧电商运营\", \"url\": \"/ecommerce/\" }, { \"nombre\": \"CRM客户管理\", \"url\": \"/crm/\" }, { \"nombre\": \"HR人力资源管理\", \"url\": \"/hr/\" }, { \"nombre\": \"Scrum敏捷开发管理\", \"url\": \"/scrum/\" }, { \"name\": \"营销策划与市场运营\", \"url\": \"/marketing/\" }, { \"name\": \"OKR目标管理\", \"url\": \"/okr/\" }, { \"name\": \"教育培训管理\", \"url\": \"/education/\" }, { \"name\": \"智慧门管理\", \"url\" : \"/tienda/\" }] }, { \"title\": \"支持\", \"lists\": [{ \"name\": \"意见反馈\", \"url\": \"https://vika.cn/share/shrCvbFC53xc3kl00B4Pg \" }, { \"nombre\": \"帮助中心\", \"url\": \"https://help.vika.cn/\" }, { \"nombre\": \"开发者中心\", \"url\": \"/developers/ \" }, { \"nombre\": \"服务条款\", \"url\": \"/acuerdo-de-servicio/\" }, { \"nombre\": \"隐私协议\", \"url\": \"/acuerdo-de-servicio/\" }, { \"name\": \"安全与合规\", \"url\": \"/security/\" }] }, { \"title\": \"服务\", \"lists\": [{ \"name\": \"加入社群\", \" url\": \"/chatgroup/\" }, { \"name\": \"Github开源\", \"url\": \"https://github.com/vikadata\" }, { \"name\": \"预约演示\", \"url\" : \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\" }, { \"name\": \"专有云部署\", \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\" } , { \"name\": \"应用连接\", \"url\": \"/connections/\" }] }, { \"title\": \"联系我们\", \"lists\": [{ \"name\": \"地址:深圳市南山区国信投资大厦1710\", \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\" }, { \"name\": \"售前咨询:点击联系商务\", \"url\": \"https: //vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\" }, { \"name\": \"合作:bd@vikadata.com\", \"url\": \"mailto:bd@vikadata.com\" }, { \"name\": \"媒体:pr@vikadata.com\", \"url\": \"mailto:pr@vikadata.com\" }, { \"name\": \"招聘:hr@vikadata.com\", \"url\": \"mailto:hr@vikadata. es\" }] }]", "offical_website_nav_data": "[{\n \"name\": \"产品\",\n \"href\": \"/login\",\n \"children\": [\n {\n \"name\": \"vika维格表 Overview\",\n \"href\": \"/login/\"\n },\n {\n \"name\": \"应用连接 Integration\",\n \"href\": \"/connections/\"\n },\n {\n \"name\": \"客户端(Beta) Download\",\n \"href\": \"/download/\"\n }\n ]\n}, {\n \"name\": \"解决方案\",\n \"href\": \"/\",\n \"children\": [{\n \"name\": \"PMO项目群管理\",\n \"href\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"href\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"href\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"href\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"href\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"href\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"href\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"href\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"href\": \"/shop/\"\n }, {\n \"name\": \"更多解决方案 >\",\n \"href\": \"/solutions/\"\n }]\n}, {\n \"name\": \"模板/案例\",\n \"href\": \"/template\",\n \"children\": [\n {\n \"name\": \"模板中心 Tempaltes\",\n \"href\": \"/template\"\n },\n {\n \"name\": \"客户案例 Customers\",\n \"href\": \"/cases/\"\n }\n ]\n},\n {\n \"name\": \"首页\",\n \"href\": \"/?home=1\"\n },\n {\n \"name\": \"学习资源\",\n \"href\": \"https://edu.vika.cn/index\",\n \"children\": [\n {\n \"name\": \"快速入门 Tutorials\",\n \"href\": \"https://help.vika.cn/docs/guide/tutorial\"\n },\n {\n \"name\": \"产品手册 Manual\",\n \"href\": \"https://help.vika.cn/docs/guide/manual\"\n },\n {\n \"name\": \"维格课堂 Vika Education\",\n \"href\": \"https://edu.vika.cn/\"\n },\n {\n \"name\": \"维格社区 Vika BBS\",\n \"href\": \"https://bbs.vika.cn/\"\n },\n {\n \"name\": \"第三方连接 Integration\",\n \"href\": \"https://help.vika.cn/docs/guide/connection\"\n },\n {\n \"name\": \"开发者中心 Developer Center\",\n \"href\": \"/developers/\"\n },\n {\n \"name\": \"常见问题 FAQ\",\n \"href\": \"https://help.vika.cn/docs/guide/questions\"\n }\n ]\n }]", "office_preview": "Previsualizar archivos de Office", "office_preview_app_desc": "

Smooth online preview of office files on datasheet, allowing you to view common office files such as Excel, Word, PPT, etc. on your desktop or mobile anywhere, anytime

\n\n
    \n
  • Online preview of .doc, .docx, .xls, .xlsx, .ppt, .pptx, and .pdf formatted office files
  • \n
  • Desktop and mobile both support file previews of the above formats
  • \n
\n\n

Additional notes:

\n
    \n
  • This feature is powered by \"Yoncentric Cloud Conversion\" and officially integrated
  • \n
  • Click the \"Enable\" button below to enable this integration and agree that \"Yoncentric Cloud Conversion\" reads the office files you want to preview
  • \n
  • If you no longer need the office files preview feature, the space admin can disable it on this page
  • \n
", @@ -3479,6 +3630,7 @@ "open_auto_save_success": "La vista de guardar automáticamente se ha abierto con éxito", "open_auto_save_warn_content": "Todos los cambios bajo esta vista se guardan automáticamente y se sincronizan con otros miembros.", "open_auto_save_warn_title": "Activar guardar vista automáticamente", + "open_automation_time_arrival": "https://aitable.ai/contact-sales-open-source", "open_failed": "Abrir falló", "open_in_new_tab": "Abrir en una nueva ficha", "open_invite_after_operate": "Una vez abierto, todos los miembros pueden invitar a nuevos miembros desde el panel de contactos", @@ -3625,6 +3777,8 @@ "payment_record": "Registro de pagos", "payment_reminder": "Consejos de pago", "payment_reminder_content": "El nuevo plan que ha seleccionado es más deducible que el monto a pagar. Se recomienda elegir el nuevo plan de mayor duración. Si confirma hacerlo, el importe de la franquicia no será reembolsable. ${action} en caso de duda", + "payment_reminder_modal_content": "Puede probar la versión avanzada para disfrutar de más nodos de archivos, permisos empresariales, capacidad de archivos adjuntos, volumen de datos, IA y otras funciones y privilegios avanzados.", + "payment_reminder_modal_title": "Actualmente estás usando la versión gratuita.", "pending_invite": "Invitación pendiente", "people": "Miembros", "per_person_per_year": "Por persona y año", @@ -3794,7 +3948,7 @@ "player_step_ui_config_168": "{\n\"templateKey\":\"createMirrorTip\"\n}", "player_step_ui_config_169": "{ \"headerImg\": \"https://s4.vika.cn/space/2023/04/04/bcf0695cf35840e6b85e032a8e5ea0a1\", \"readMoreUrl\": \"https://help.vika.cn/changelog/23-04-10- actualizaciones\", \"niños\": \"

🚀 Introducción de nuevas funciones.

\\norte
  • Se lanza el nuevo tipo de campo \"Cascader\", lo que facilita la selección entre una jerarquía de opciones en los formularios.
  • Se lanza el widget \"Script\", menos código para una mayor personalización
  • Active la automatización para enviar correos electrónicos y recibir notificaciones rápidas
  • Activa la automatización para enviar un mensaje a Slack e informar a tu equipo a tiempo
  • Explorando la IA: Lanzamiento del widget \"Generador de contenido GPT\"
\" }", "player_step_ui_config_17": "{\n \"element\": \"#TEMPLATE_CENTER_USE_TEMPLATE_BTN>button\", \n\"placement\": \"rightBottom\",\n\"offsetY\": 20,\n \"title\": \"How to use a template\", \n\"description\": \"Click the button on the left to use the template\", \"children\":\"\" \n}", - "player_step_ui_config_176": "{\"title\":\"Introducción AI agent\",\"video\":\"https://www.youtube.com/embed/cjds1r_roG8?si=irKUpMhwDlOEb8Hc\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", + "player_step_ui_config_176": "{\"title\":\"AITable.ai DEMO\",\"video\":\"https://www.youtube.com/embed/kGxMyEEo3OU\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", "player_step_ui_config_18": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select>.ant-select-selector\", \n\"placement\": \"bottomLeft\",\n \"title\": \"How to use a template\", \n\"description\": \"Select where to put the template\", \"children\":\"\" \n}", "player_step_ui_config_19": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select .ant-select-selector\"\n}", "player_step_ui_config_2": "{\n \"config\": [\n {\n \"key\": 1,\n \"name\": \"answer1\",\n \"title\": \"What kind of issues are you looking forward to solved by vikadata?\",\n \"type\": \"checkbox\",\n \"answers\": [\n \"Work Planning\",\n \"Customer Service\",\n \"Project Management\",\n \"Sourcing Supply\",\n \"Content Production\",\n \"E-commerce operation\",\n \"Event Planning\",\n \"Human Resources\",\n \"Administration\",\n \"Financial Management\",\n \"Webcast\",\n \"Educational institutes Management\",\n \"Other\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 2,\n \"name\": \"answer2\",\n \"title\": \"Your job title is______\",\n \"type\": \"radio\",\n \"answers\": [\n \"General manager \",\n \"Project manager\",\n \"Product manager\",\n \"Designer\",\n \"R&D engineer\",\n \"Operator, editor\",\n \"Sales, customer service\",\n \"Human resource, administration \",\n \"Finance, accountant\",\n \"Lawyer, legal affairs\",\n \"Marketing\",\n \"Teacher\",\n \"Student\",\n \"Other\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 3,\n \"name\": \"answer3\",\n \"title\": \"What is the name of your company?\",\n \"type\": \"input\",\n \"submit\": false\n },\n {\n \"key\": 4,\n \"name\": \"answer4\",\n \"title\": \"Please leave your email address/ phone number/ Wechat account below so we can reach you in time when you need help.\",\n \"type\": \"input\",\n \"submit\": true\n },\n {\n \"key\": 5,\n \"title\": \"Thank you for filling out the form, you can add our customer service in case of need\",\n \"platform\": {\n \"website\": \"https://s4.vika.cn/space/2023/03/02/b34e3205a9154463be16f497524f1327\",\n \"dingtalk\": \"https://s4.vika.cn/space/2023/03/02/4b16cef6602a4586a21d6346bf25d300\",\n \"wecom\": \"https://s4.vika.cn/space/2023/03/02/60119b1b69b64aa887bd1be6a2928bec\",\n \"feishu\": \"https://u.vika.cn/z9ygm\"\n },\n \"type\": \"contactUs\",\n \"next\": true\n }\n ]\n}\n", @@ -3824,13 +3978,13 @@ "player_step_ui_config_41": "", "player_step_ui_config_42": "{\n \"element\": \"#DATASHEET_FORM_LIST_PANEL\", \n\"placement\": \"leftTop\",\n \"title\": \"Form\", \n\"description\": \"You can quickly create a form from the current view. The number and order of the fields in the form is consistent with the view.\", \"children\":\"\" \n}", "player_step_ui_config_43": "{\n \"element\": \".style_navigation__1U5cR .style_help__1sXEA\", \n\"placement\": \"rightBottom\",\n \"title\": \"Tip\", \n\"offsetY\":5,\n\"description\": \"You can find your Vikaby assistant from the \"Help\" icon on the left\", \"children\":\"\" \n}", - "player_step_ui_config_44": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", + "player_step_ui_config_44": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", "player_step_ui_config_45": "", "player_step_ui_config_46": "", "player_step_ui_config_47": "{\n \"element\": \"#DATASHEET_WIDGET_BTN\",\n\"placement\": \"bottomRight\",\n \"title\": \"Widget\", \n\"description\": \"Want to use and view your data in a richer way? Try the widget!\", \"children\":\"\" \n}", "player_step_ui_config_48": "", "player_step_ui_config_49": "{\n \"element\": \".style_widgetPanelContainer__1l2ZV\",\n\"placement\": \"leftCenter\",\n \"title\": \"What is a widget\", \n\"description\": \"Vika widgets are an extended application of vikadata that features in richer data visualization, data transfer, data cleansing, and more. By installing widgets in the widget board, you can make work a lot easier.\", \"children\":\"\" \n}", - "player_step_ui_config_5": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", + "player_step_ui_config_5": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", "player_step_ui_config_50": "{\n \"element\": \".style_widgetModal__eXmdB\",\n\"placement\": \"leftTop\",\n \"title\": \"Widget Center\", \n\"description\": \"Officially recommended and custom widgets are published here. You can install any widget you want onto a dashboard or into a widget board of any datasheet.\", \"children\":\"\" \n}", "player_step_ui_config_51": "{\n \"element\": \".style_widgetModal__eXmdB .style_widgetItem__3Pl-1 button\",\n\"placement\": \"rightBottom\",\n \"title\": \"Install widget\", \n\"description\": \"Let's install this \"Chart\" widget\", \"children\":\"\" \n}", "player_step_ui_config_52": "", @@ -3927,6 +4081,7 @@ "preview_guide_click_to_restart": "Presione el botón de abajo para Previsualizar de nuevo", "preview_guide_enable_it": "Presione el botón de abajo para abrir esta función", "preview_guide_open_office_preview": "Para Previsualizar este archivo, abra la función \"previsualización de la oficina\"", + "preview_next_automation_execution_time": "Vista previa de los próximos 10 tiempos de ejecución", "preview_not_support_video_codecs": "Solo se pueden Previsualizar vídeos mp4 con Códec de vídeo h.264", "preview_revision": "Vista previa", "preview_see_more": "¿Desea obtener más información sobre la función \"vista previa de archivos de Office\"? Por favor haga clic aquí", @@ -3962,6 +4117,7 @@ "privacy_protection": "\"Protección de la privacidad\"", "private_cloud": "Nube privada", "private_external_person_only": "Solo personal externo", + "private_help_link": "https://help.aitable.ai/docs/guide/team-and-private-area#private-area", "private_internal_person_only": "Solo personal interno", "private_product_point": "Sea dueño de su plataforma APITable con un solo clic", "privatized_deployment": "Autogestión", @@ -4032,13 +4188,15 @@ "reconciled_data": "Se están verificando los datos", "record": "Registro", "record_activity_experience_tips": "Puede ver la actividad de registro de ${day} días", + "record_archived_data": "registro archivado", + "record_chunk_text": "${text} rows, please wait", "record_comment": "Solo anotaciones", "record_comments": "Comentarios", "record_fail_data": "Error de datos", "record_filter_tips": "Este registro ha sido filtrado", "record_functions": "Función de registro", "record_history": "Solo se revisan los registros históricos", - "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-history", + "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-activity", "record_history_title": "Registrar registros históricos", "record_pre_filtered": "Este registro ha sido filtrado y se ocultará al hacer clic en el exterior del registro", "record_pre_move": "Después de hacer clic en el exterior del registro, este registro se moverá a otra posición", @@ -4478,6 +4636,12 @@ "scan_to_login": "Escanear inicio de sesión", "scan_to_login_by_method": "Escanea ${method} para seguir la cuenta oficial e iniciar sesión", "scatter_chart": "Mapa de dispersión", + "schedule_day_tips": "El cómputo del ciclo comienza a contar desde el primer día de cada mes. Si asumimos que se repite cada 10 días, entonces se activará los días 1, 11, 21 y 31 de cada mes.", + "schedule_hour_tips": "El cálculo del ciclo comienza a medianoche (0:00) cada día. Suponiendo que se repite 0 minutos cada tres horas, ocurrirá a medianoche (0:00), 3 a. m., 6 a. m., 9 a. m., mediodía (12 p. m.), 3 p. m., 6 p. m. y finalmente al anochecer (9 p. m.) todos los días.", + "schedule_start_day": "A partir del día 1 del mes, cada", + "schedule_start_month": "A partir de enero de cada año, cada", + "schedule_type": "Tipo de horario", + "schedule_year_tips": "El cómputo del ciclo comienza a contar desde el primer mes de cada año. Suponiendo un intervalo de tres meses durante el primer día, los activadores se activarán a la medianoche del primer día de enero, abril, julio y octubre de cada año.", "science_and_technology": "Ciencia y tecnología", "scroll_screen_down": "Desplácese hacia abajo por una pantalla", "scroll_screen_left": "Desplaza una pantalla a la izquierda", @@ -4491,6 +4655,7 @@ "search_folder_or_sheet": "Buscar archivos", "search_new_admin": "Buscar", "search_node_pleaseholder": "Buscar archivos (${shortcutKey})", + "search_node_tip": "Búsqueda rápida (${shortcutKey})", "search_or_add": "Encontrar o agregar opciones", "search_role_placeholder": "Buscar personajes", "seats": "Asientos", @@ -4894,6 +5059,7 @@ "space_info": "Resumen", "space_info_del_confirm1": "1. eliminar este espacio compartido eliminará los siguientes datos:", "space_info_del_confirm2": "2. los espacios compartidos serán eliminados por completo después de 7 días. Antes de eso, puede restaurar el espacio.", + "space_info_del_confirm3": "3. For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "space_info_feishu_desc": "Está utilizando integración de terceros. Para eliminar el espacio compartido, primero Deshabilite la integración de terceros.", "space_info_feishu_label": "Integración", "space_join_apply": "Se solicita la inclusión en el espacio \" < a class =\" spacename \"> < a > espacio.", @@ -4980,6 +5146,7 @@ "start_onfiguration": "Iniciar configuración", "start_time": "Hora de inicio", "start_use": "Empezar a usar", + "starting_from_midnight": "A partir de medianoche (12:00 a.m.) todos los días, todos", "startup": "Inicio", "startup_company_support_program": "Iniciar el plan de apoyo", "stat_average": "Promedio", @@ -5013,6 +5180,8 @@ "stay_tuned_for_more_features": "Por favor, preste atención a más funciones.", "steps_choose_reset_mode": "Seleccionar el método de reinicio", "steps_validate_identities": "Autenticación", + "stop_chunk_content": "Are you sure you want to stop the operation?", + "stop_chunk_title": "Stop", "stop_dingtalk_h5_modal_content": "La aplicación autoconstruida se desbloqueará desde este espacio. Por favor, confirme.", "storage_per_seats": "", "storage_per_space": "Uso del almacenamiento", @@ -5043,9 +5212,11 @@ "subscribe_credit_usage_over_limit": "El número de créditos en el espacio actual supera el límite, por favor actualice su suscripción.\n", "subscribe_demonstrate": "Solicitud de presentación", "subscribe_disabled_seat": "El número de personas no puede ser inferior al plan original", + "subscribe_grade_business": "Negocio", "subscribe_grade_free": "Libre", "subscribe_grade_plus": "Más", "subscribe_grade_pro": "A favor", + "subscribe_grade_starter": "Inicio", "subscribe_label_tooltip": "Función espacial avanzada", "subscribe_new_choose_member": "Admite hasta ${member_num} miembros", "subscribe_new_choose_member_tips": "Este plan admite 1~${member_num} miembros para ingresar al espacio", @@ -5182,7 +5353,7 @@ "template_name_repetition_title": "\"${templateName}\" ya existe. ¿Quieres cambiarlo?", "template_no_template": "No hay plantilla", "template_not_found": "¿No puede encontrar las plantillas que desea? Dinos", - "template_recommend_title": "Caliente", + "template_recommend_title": "🌟 Hot", "template_type": "Modelo", "terms_of_service": "[términos de servicio]", "terms_of_service_pure_string": "Cláusulas de servicio", @@ -5226,6 +5397,7 @@ "text_editor_tip_end": "\"Entrada\" para terminar la edición", "text_functions": "Función de cadena", "thailand": "Tailandia", + "the_button_field_is_misconfigured": "El campo del botón está mal configurado, verifíquelo e inténtelo nuevamente.", "the_current_automation_workflow_has_no_related_files_you_can_establish_a_link_by_adding_trigger_conditions_and_actions_on_the_left_side": "El flujo de trabajo de automatización actual no tiene archivos relacionados. Usted puede establecer un enlace añadiendo condiciones de activación y acciones en el lado izquierdo", "the_current_button_column_has_expired_please_reselect": "La columna de botones actual ha caducado, vuelva a seleccionarla", "the_last_7_days": "Los últimos 7 días", @@ -5278,8 +5450,8 @@ "time_machine_action_title": "Historial de operaciones", "time_machine_unlimited": "Historia de la máquina del tiempo infinito", "time_zone_inconsistent_tips": "Cuando la zona es inconsistente en ese momento, por defecto se utilizará la zona horaria de la hora de inicio.", - "timemachine_add": "Añadido ${nombre}", - "timemachine_add_field": "se agregaron ${nombre} columna(s)", + "timemachine_add": "Añadido ${name}", + "timemachine_add_field": "se agregaron ${name} columna(s)", "timemachine_add_record": "se agregaron ${count} filas de registros", "timemachine_add_widget": "añadido un nuevo widget", "timemachine_delete_comment": "comentarios eliminados", @@ -5328,6 +5500,7 @@ "timemachine_update_comment": "comentarios actualizados", "times_per_month_unit": "Teléfono / mes", "times_unit": "Teléfono", + "timing_rules": "Momento", "timor_leste": "Timor Oriental", "tip_del_success": "Puede recuperar su espacio compartido en 7 días", "tip_do_you_want_to_know_about_field_permission": "¿Quiere cifrar datos de campo? Más información sobre los permisos de campo", @@ -5515,6 +5688,7 @@ "verify_account_title": "Cuenta de verificación", "verify_via_email": "Autenticación por correo electrónico", "verify_via_phone": "Autenticación SMS", + "video": "Video", "video_not_support_play": "El formato de vídeo actual no admite reproducción en línea", "vietnam": "Vietnam", "view": "Puntos de vista", @@ -5863,7 +6037,8 @@ "workdoc_color_title": "Color de fuente", "workdoc_create": "Crear documento de trabajo", "workdoc_expanded": "Ampliar la tabla de contenidos", - "workdoc_image_max_10mb": "El tamaño de la imagen no puede exceder los 10 MB.", + "workdoc_image_max_10mb": "nulo", + "workdoc_image_max_size": "El tamaño de la imagen no puede exceder ${size}", "workdoc_info": "Información", "workdoc_info_create_time": "Creado en", "workdoc_info_creator": "Creado por", @@ -5871,6 +6046,7 @@ "workdoc_info_last_modify_time": "Última modificación en", "workdoc_link_placeholder": "Por favor ingrese el enlace", "workdoc_only_image": "Solo se permite imagen", + "workdoc_only_video": "Sólo se permite vídeo", "workdoc_text_placeholder": "Ingrese \"/\" inicio rápido", "workdoc_title_placeholder": "Por favor ingresa el título", "workdoc_unnamed": "Documento de trabajo sin nombre", @@ -5879,9 +6055,11 @@ "workdoc_unsave_ok": "Descartar los cambios", "workdoc_unsave_title": "El WorkDoc no ha sido guardado", "workdoc_upload_failed": "Subida fallida", + "workdoc_video_max_size": "El tamaño del video no puede exceder ${size}", "workdoc_ws_connected": "Conectado", "workdoc_ws_connecting": "Conectando...", "workdoc_ws_disconnected": "Desconectado", + "workdoc_ws_reconnecting": "Reconectando...", "workflow_execute_failed_notify": " no pudo ejecutarse en . Revise el historial de ejecución para solucionar el problema. Si necesita ayuda, comuníquese con nuestro equipo de atención al cliente.", "workspace_data": "Datos espaciales", "workspace_files": "Datos de la Mesa de trabajo", diff --git a/packages/datasheet/public/file/langs/strings.fr-FR.json b/packages/datasheet/public/file/langs/strings.fr-FR.json index 9e2a857312..4b127b86c8 100644 --- a/packages/datasheet/public/file/langs/strings.fr-FR.json +++ b/packages/datasheet/public/file/langs/strings.fr-FR.json @@ -146,6 +146,15 @@ "agreed": "Approuvé", "ai_advanced_mode_desc": "El modo avanzado permite a los usuarios personalizar las indicaciones, proporcionando un mayor control sobre el comportamiento y las respuestas del AI agent.", "ai_advanced_mode_title": "Mode avancé", + "ai_agent_anonymous": "Anonyme${ID}", + "ai_agent_conversation_continue_not_supported": "La poursuite d'une conversation précédente n'est actuellement pas prise en charge", + "ai_agent_conversation_list": "Liste de conversations", + "ai_agent_conversation_log": "Journal des conversations", + "ai_agent_conversation_title": "Titre de la conversation", + "ai_agent_feedback": "Retour", + "ai_agent_historical_message": "Ce qui précède est un message historique", + "ai_agent_history": "Histoire", + "ai_agent_message_consumed": "Message consommé", "ai_api_curl_template": "## Create chat completions\n\n```bash\n\ncurl -X POST \"{{apiBase}}/fusion/v1/ai/{{aiId}}/chat/completions\" \\n -H \"Content-Type: application/json\" \\n -H \"Authorization: Bearer {{token}}\" \\n -d '{\n \"model\": \"gpt-3.5-turbo\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"You are a helpful assistant.\"\n },\n {\n \"role\": \"user\",\n \"content\": \"Hello!\"\n }\n ]\n }'\n\n```\n\n## Returned data example\n\n```json\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", "ai_api_footer_desc": "¿Integrar AI agent en su sitio web? Aprende más", "ai_api_javascript_template": "## Initialize SDK [![github]({{ githubIcon }})](https://github.com/openai/openai-node)\nAITable's chat completion API is compatible with OpenAI's Node.js SDK. You can use our service with the same SDK by simply changing the configuration as follows:\n\n\n```javascript\nconst { Configuration, OpenAIApi } = require(\"openai\");\nconst configuration = new Configuration({\n apiKey: \"{{token}}\",\n basePath: \"{{apiBase}}/fusion/v1/ai/{{aiId}}\"\n});\n```\n\n## Create chat completions\n\n```javascript\nconst openai = new OpenAIApi(configuration);\nconst chatCompletion = await openai.createChatCompletion({\n model: \"gpt-3.5-turbo\",\n messages: [{role: \"user\", content: \"Hello world\"}],\n});\n```\n\n## Returned data example\n\n```javascript\n\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", @@ -161,6 +170,9 @@ "ai_chat_unit": "aibot(s)", "ai_close_setting_tip_content": "Vous avez apporté des modifications. Tu veux les jeter?", "ai_close_setting_tip_title": "tip", + "ai_copilot_generate_response": "Génération de la réponse pour vous...", + "ai_copilot_processs": "Traitement en cours, veuillez patienter...", + "ai_copilot_start_process_request": "Début du traitement de votre demande...", "ai_create_guide_btn_text": "Sélectionner une fiche de données", "ai_create_guide_content": "En tant qu'AI agent, je peux répondre à vos questions en fonction des connaissances que j'ai apprises. Avant de commencer la conversation, veuillez sélectionner une feuille de données comme base de connaissances, et je lirai toutes les données qu'elle contient pour l'apprentissage.", "ai_credit_cost_chart_title": "Coût du crédit", @@ -221,7 +233,7 @@ "ai_prompt_title": "Prompt", "ai_prompt_wrong_content": "Veuillez inclure {context} et {question} dans votre texte.", "ai_query_of_number": "Utilisation", - "ai_remain_credit_label": "Message laissé : ${crédit}", + "ai_remain_credit_label": "Message laissé : ${credit}", "ai_retrain": "Retrain", "ai_robot_data_source_title": "Collection d'ensembles de données", "ai_robot_type_QA_desc": "Un agent de questions-réponses basé sur le PNL et l'apprentissage automatique répond rapidement et précisément à diverses questions et fournit des informations en temps réel et des conseils utiles aux utilisateurs.", @@ -629,7 +641,7 @@ "apps_support": "Support client de toutes les plates-formes", "archive_delete_record": "Supprimer les enregistrements archivés", "archive_delete_record_title": "Supprimer l'enregistrement", - "archive_notice": "

Vous essayez d'archiver des enregistrements spécifiques. L'archivage des enregistrements entraînera les modifications suivantes :

1. Tous les liens bidirectionnels pour cet enregistrement seront annulés

2. L'édition n'est pas prise en charge

3. Les fonctions telles que les rappels de date et les enregistrements d'abonnement ne sont pas prises en charge

4. Ne participez plus au calcul des champs de recherche, de formule et autres

Es-tu sur de vouloir continuer? (Vous pouvez désarchiver dans Archive Box dans Advanced)

", + "archive_notice": "

Vous essayez d'archiver des enregistrements spécifiques. L'archivage des enregistrements entraînera les modifications suivantes :

1. L'édition n'est pas prise en charge

2. Les fonctions telles que les rappels de date et les enregistrements d'abonnement ne sont pas prises en charge

3. Ne participez plus au calcul des champs de recherche, de formule et autres

Es-tu sur de vouloir continuer? (Vous pouvez désarchiver dans Archive Box dans Advanced)

", "archive_record_in_activity": "Archivé cet enregistrement", "archive_record_in_menu": "Dossier d'archive", "archive_record_success": "Enregistrements archivés avec succès", @@ -689,6 +701,8 @@ "audit_add_field_role_detail": "Dans la \"\"feuille de données , ajouter [] le rôle comme [] pour le champ [] ", "audit_add_node_role": "Ajouter des permissions de fichier", "audit_add_node_role_detail": "Ajouter une autorisation de fichier , définir 「 ${unitNames} 」 à 「 ${role} 」 de 「 ${currentNodeName} 」", + "audit_add_node_role_detail_end": "to「${role}", + "audit_add_node_role_detail_start": "Add file node permission,set「${unitNames}」", "audit_admin_permission_change_event": "Modifier les permissions de l'administrateur", "audit_create_template": "Créer un modèle", "audit_create_template_detail": "Nommer le modèle", @@ -697,20 +711,30 @@ "audit_delete_field_role_detail": "Audit", "audit_delete_node_role": "Permission de supprimer le fichier", "audit_delete_node_role_detail": "Supprimer l'autorisation de fichier,delete「${unitNames}」`s 「${role}」rôle de 「${currentNodeName}」", + "audit_delete_node_role_detail_end": "at 「${role}」role", + "audit_delete_node_role_detail_start": "Delete file node permission,delete「${unitNames}」from", "audit_delete_template": "Supprimer ce modèle", "audit_delete_template_detail": "Supprimer ce modèle", "audit_disable_field_role": "Désactiver les autorisations de champ", "audit_disable_field_role_detail": "Audit", "audit_disable_node_role": "Désactiver les permissions de fichier", "audit_disable_node_role_detail": "Désactiver l'autorisation de ${nodeType} 「${currentNodeName}」", + "audit_disable_node_role_detail_end": "`s permission", + "audit_disable_node_role_detail_start": "Disable ${nodeType}", "audit_disable_node_share": "Fermer le lien public du fichier", "audit_disable_node_share_detail": "Fermer le lien public ${nodeType} 「${currentNodeName}」", + "audit_disable_node_share_detail_end": "public link", + "audit_disable_node_share_detail_start": "Close ${nodeType}", "audit_enable_field_role": "Activer les autorisations de champ", "audit_enable_field_role_detail": "Audit", "audit_enable_node_role": "Activer les permissions de fichier", "audit_enable_node_role_detail": "Activer l'autorisation de ${nodeType} 「${currentNodeName}」", + "audit_enable_node_role_detail_end": "`s permission", + "audit_enable_node_role_detail_start": "Enable ${nodeType}", "audit_enable_node_share": "Ouvrir le lien public du fichier", "audit_enable_node_share_detail": "Ouvrez le lien public ${nodeType} 「${currentNodeName}」", + "audit_enable_node_share_detail_end": "public link", + "audit_enable_node_share_detail_start": "Open ${nodeType}", "audit_login_event": "Événement de connexion", "audit_logout_event": "anglais", "audit_organization_change_event": "La structure organisationnelle des contacts a changé", @@ -731,18 +755,25 @@ "audit_space_invite_user_detail": "Audit", "audit_space_node_copy": "Dupliquer le fichier", "audit_space_node_copy_detail": "Dupliquer ${nodeType} 「${sourceNodeName}」, le nouveau nom de fichier est 「${currentNodeName}」", + "audit_space_node_copy_detail_start": "Duplicate ${nodeType} 「${sourceNodeName}」, the new file node's name is", "audit_space_node_create": "Créer un fichier", "audit_space_node_create_detail": "Créez un ${nodeType} nommé 「${currentNodeName}」", + "audit_space_node_create_detail_start": "Create a ${nodeType} named", "audit_space_node_delete": "Supprimer le champ", "audit_space_node_delete_detail": "Supprimer ${nodeType} nommé 「${currentNodeName}」", + "audit_space_node_delete_detail_start": "Delete ${nodeType} named", "audit_space_node_export": "Exporter la fiche technique", "audit_space_node_export_detail": "Le membre ${member_name} a exporté la feuille de données ${node_name}", "audit_space_node_import": "Importer fichier", "audit_space_node_import_detail": "Importez un fichier nommé 「${nodeName}」", + "audit_space_node_import_detail_start": "Import a file node named", "audit_space_node_move": "Déplacer le fichier", "audit_space_node_move_detail": "Déplacez ${nodeType} 「${currentNodeName}」 vers le dossier「${parentName}」", + "audit_space_node_move_detail_end": "to the folder「${parentName}」", + "audit_space_node_move_detail_start": "Move ${nodeType}", "audit_space_node_rename": "Renommer le fichier", "audit_space_node_rename_detail": "Renommez ${nodeType} 「${oldNodeName}」 en 「${nodeName}」", + "audit_space_node_rename_detail_start": "Rename ${nodeType} 「${oldNodeName}」to", "audit_space_node_sort": "Audit", "audit_space_node_sort_detail": "Audit", "audit_space_node_update_cover": "Audit", @@ -757,17 +788,24 @@ "audit_space_rubbish_node_delete_detail": "Audit", "audit_space_rubbish_node_recover": "Restaurer les fichiers", "audit_space_rubbish_node_recover_detail": "Restaurer ${nodeType} 「${currentNodeName}」 depuis la corbeille", + "audit_space_rubbish_node_recover_detail_end": "from the trash", + "audit_space_rubbish_node_recover_detail_start": "Restore ${nodeType}", "audit_space_template_event": "Changement de modèle", "audit_space_update_logo": "Audit", "audit_space_update_logo_detail": "Audit", "audit_store_share_node": "Enregistrer le fichier partagé", "audit_store_share_node_detail": "Restaurez ${nodeType} dans l'espace, le nom est 「${nodeName}」", + "audit_store_share_node_detail_start": "Restore ${nodeType} to the space, name is", "audit_update_field_role": "Audit", "audit_update_field_role_detail": "Audit", "audit_update_node_role": "Modifier l'autorisation de fichier", "audit_update_node_role_detail": "Modifier l'autorisation de fichier , modifier le rôle de 「 ${unitNames} 」 à 「 ${role} 」 de 「 ${currentNodeName} 」", + "audit_update_node_role_detail_end": "to「${role}」role", + "audit_update_node_role_detail_start": "Modify file node permission,modify「${unitNames}」from", "audit_update_node_share_setting": "Modifier les paramètres des liens publics du fichier", "audit_update_node_share_setting_detail": "Modifier le lien public ${nodeType} 「${currentNodeName}」", + "audit_update_node_share_setting_detail_end": "public link settings", + "audit_update_node_share_setting_detail_start": "Modify ${nodeType}", "audit_user_login": "Connexion de l'utilisateur", "audit_user_login_detail": "Audit", "audit_user_logout": "Déconnexion de l'utilisateur", @@ -809,6 +847,7 @@ "automation_enabled_return_via_related_files": "L'automatisation est activée. Veuillez saisir à nouveau le tableau d'origine via \"Fichiers associés\" pour utiliser le nouveau bouton.", "automation_field": "Champ d'application", "automation_import_variables_from_pre_tep": "Obtenez les données de la pré-étape", + "automation_is_not_yet_enabled": "L'automatisation n'est pas encore activée, veuillez l'activer et réessayer", "automation_last_edited_by": "Dernière édition par", "automation_last_edited_time": "Heure de la dernière modification", "automation_manager_label": "Peut effectuer toutes les actions sur l'automatisme", @@ -834,6 +873,7 @@ "automation_runs_this_month": "Fonctionne ce mois-ci", "automation_stay_tuned": "Restez à l'écoute", "automation_success": "Succès", + "automation_tips": "Le champ du bouton est mal configuré, veuillez vérifier et réessayer", "automation_updater_label": "Peut afficher l'historique d'exécution de l'automatisation", "automation_variabel_empty": "Aucune donnée ne peut être utilisée lors de l'étape préalable, veuillez ajuster et réessayer.", "automation_variable_datasheet": "Obtenir des données de ${NODE_NAME}", @@ -869,6 +909,7 @@ "bermuda": "Les îles Bermudes", "bhutan": "Bhoutan", "billing_over_limit_tip_common": "L'utilisation de l'espace a dépassé la limite et vous pouvez profiter d'un montant plus élevé après la mise à niveau.", + "billing_over_limit_tip_forbidden": "Votre durée d’essai ou votre période d’abonnement a expiré. Veuillez contacter le conseiller commercial pour renouveler.", "billing_over_limit_tip_widget": "Le nombre d'installations de widgets a dépassé la limite et vous pouvez effectuer une mise à niveau pour obtenir une utilisation plus élevée.", "billing_period": "Période de facturation : ${period}", "billing_subscription_warning": "Expérience des fonctionnalités", @@ -928,10 +969,19 @@ "button_text": "Texte du bouton", "button_text_click_start": "Cliquez pour démarrer", "button_type": "Type de bouton", + "by_at": "à", + "by_days": "Jours", + "by_every": "chaque", "by_field_id": "Utiliser l'ID du champ", + "by_hours": "Heures", + "by_in": "à", + "by_min": "minutes)", + "by_months": "Mois", + "by_on": "sur le", "by_the_day": "Par jour", "by_the_month": "Mensuel", "by_the_year": "Annuel", + "by_weeks": "Semaines", "calendar_add_date_time_field": "Créer le champ Date", "calendar_color_more": "Plus de couleurs", "calendar_const_detail_weeks": "[\"lundi\",\"mardi\",\"mercredi\",\"jeudi\",\"vendredi\",\"samedi\",\"dimanche\"]", @@ -995,6 +1045,14 @@ "cannot_activate_space_by_space_limit": "impossible d'activer l'espace de stockage par limite d'espace", "cannot_join_space": "Vous ne pouvez pas rejoindre une nouvelle station spatiale car vous avez dépassé le quota maximum de 10 stations spatiales.", "cannot_switch_field_permission": "Définir les permissions de champ ne sont pas supérieures aux permissions du fichier. ", + "capacity_file_detail_desc": "The total number of file nodes within the Space is calculated by adding the file nodes from the Team to the file nodes created by each member in their Private. Not enough capacity?", + "capacity_file_detail_title": "File Capacity", + "capacity_file_member": "Member", + "capacity_file_member_private_node_count": "Private", + "capacity_file_member_private_percent": "Percent", + "capacity_file_member_team": "Team", + "capacity_file_member_team_node_count": "Team", + "capacity_file_upgrade": "Click to upgrade your Space", "capacity_from_official_gift": "Du cadeau officiel", "capacity_from_participation": "Par invité ${user} rejoindre l'espace", "capacity_from_purchase": "Par capacité d'achat", @@ -1031,6 +1089,8 @@ "catalog": "Explorateur", "catalog_add_from_template_btn_title": "Ajouter à partir des modèles", "catalog_empty_tips": "Cet espace de travail est vide maintenant. Commencez par utiliser des modèles pour créer des fichiers.", + "catalog_private": "Private", + "catalog_team": "Team", "category_blank": "[espace vide]", "catering": "Restauration", "cayman_islands": "Iles Caïmans", @@ -1099,6 +1159,7 @@ "choose_type_of_vika_field": "Sélectionnez le type de champ", "choose_your_own_space": "(Supporte uniquement les sauvegardes dans votre propre espace en tant que créateur)", "chose_new_primary_admin_button": "Attribuer", + "chunk_stopping_title": "Stopping", "claim_special_offer": "Réclamez cette offre spéciale !", "clear": "Nettoyer", "clear_all_fields": "Effacer tout", @@ -1229,6 +1290,7 @@ "confirm_del_current_team": "Êtes-vous sûr de vouloir supprimer cette équipe?", "confirm_delete": "Confirmer et supprimer l'espace", "confirm_delete_node_name_as": "Voulez-vous vraiment supprimer \"${nodeNameDiv}\" ?", + "confirm_delete_private_node_name_as": "Are you sure you want to delete \"${nodeNameDiv}\"? The file will be deleted from the Space and the trash.", "confirm_delete_space_btn": "Confirmer et supprimer l'espace", "confirm_exit": "Confirmez pour quitter", "confirm_exit_space_with_name": "Confirmez si vous souhaitez quitter l'espace \"${spaceNameDiv}\"", @@ -1266,6 +1328,14 @@ "convert": "Convertir", "convert_tip": "Cette action peut effacer des données dans certaines cellules. Vous pouvez annuler l'action si quelque chose d'inattendu se produit.", "cook_islands": "Iles Cook", + "copilot_auto_agent_desc": "Vous ne savez pas lequel choisir Agent ? Essayez AutoAgent.", + "copilot_auto_agent_name": "Agent automobile", + "copilot_data_agent_desc": "Générer des analyses de données/visualisations basées sur vos vues.", + "copilot_data_agent_name": "Agent de données", + "copilot_data_agent_policy": "Lorsque vous discutez avec Copilot, vous acceptez la politique des conditions d'utilisation", + "copilot_data_agent_policy_button": "Politique", + "copilot_help_agent_desc": "Posez des questions sur les documents du centre d'aide d'AITable.", + "copilot_help_agent_name": "Récupérer le centre d'aide", "copy": " Copie", "copy_automation_url": "Copier l'URL", "copy_card_link": "Copier l'URL de l'enregistrement", @@ -1310,6 +1380,7 @@ "create_mirror_guide_content": "La fonction miroir a la capacité de masquer certaines données. Vous pouvez définir des \"conditions de filtre\" et des \"champs masqués\" dans la vue de feuille de données d'origine pour contrôler les enregistrements et les champs affichés dans le miroir.\n
\n
\nS'il est utilisé en conjonction avec la fonction \"verrouiller la vue\", il peut empêcher les autres d'apporter des modifications.\n
\n
\nDe plus, vous pouvez aller dans \"Table d'origine>Champs cachés\" pour modifier la configuration pour \"Afficher tous les champs dans les miroirs\".", "create_mirror_guide_title": "Le miroir masque certains enregistrements et champs", "create_new_button_field": "Créer un nouveau champ de colonne de bouton", + "create_private_node_tip": "Personal or temporary draft documents can be created here ${link}", "create_public_invitation_link": "Créer le(s) lien(s) d'invitation publique", "create_space_sub_title": "Bonjour, veuillez donner un nom à votre espace~", "create_team_fail": "La création de l'équipe a échoué", @@ -1373,10 +1444,12 @@ "custom_enterprise": "Personnaliser l'espace d'entreprise pour vous", "custom_function_development": "Développement de fonctionnalités personnalisées", "custom_grade_desc": "Fournit le déploiement d'agents, l'installation privée, l'assistance technique et des services professionnels personnalisés", + "custom_page_setting_title": "Add a custom page", "custom_picture": "Image personnalisée", "custom_style": "Style", "custom_upload": "Envoi personnalisé", "custom_upload_tip": "Une image de taille 1:1 est recommandée pour une meilleure expérience visuelle", + "custome_page_title": "Custom Web", "cut_cell_data": "Couper la (les) cellule", "cyprus": "Chypre", "czech": "Tchèque", @@ -1428,6 +1501,7 @@ "default": "Par défaut", "default_create_ai_chat_bot": "Nouvel AI agent", "default_create_automation": "Nouvelle automatisation", + "default_create_custom_page": "Nouvelle page personnalisée", "default_create_dashboard": "Nouveau tableau de bord", "default_create_datasheet": "Nouvelle fiche technique", "default_create_file": "Nouveau fichier", @@ -1449,6 +1523,7 @@ "del_invitation_link": "Supprimer le lien d'invitation", "del_invitation_link_desc": "Le lien sera invalide après suppression", "del_space_now": "Supprimer l'espace pour toujours", + "del_space_now_confirm_tip": "For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "del_space_now_tip": "L'espace ne peut pas être restauré après la suppression. Tous les fichiers et pièces jointes seront supprimés.", "del_space_res_tip": "L'espace a été supprimé", "del_team_success": "Suppression de l'équipe réussie", @@ -1644,6 +1719,62 @@ "embed_error_page_help": "En savoir plus", "embed_fail_og_description_content": "Le lien public pour cette intégration a été désactivé et est temporairement indisponible", "embed_failed": "Le lien d'intégration est indisponible ", + "embed_link_bilibili": "bilibili", + "embed_link_bilibili_desc": "En intégrant les vidéos bilibili, vous pouvez regarder des tutoriels et des guides, ou consulter la page d'accueil de la chaîne dans Vika.", + "embed_link_bilibili_link_text": "Comment intégrer la vidéo bilibili", + "embed_link_bilibili_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-bilibili-video", + "embed_link_default": "Rien", + "embed_link_default_desc": "Collez un lien pour afficher n’importe quel site Web.", + "embed_link_default_link_text": "Apprendre encore plus", + "embed_link_default_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_link_figma": "Figma", + "embed_link_figma_desc": "En intégrant des fichiers Figma, les membres peuvent visualiser et modifier les brouillons de conception plus facilement, améliorant ainsi l'efficacité de la collaboration.", + "embed_link_figma_link_text": "Comment intégrer des fichiers Figma", + "embed_link_figma_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-figma-file", + "embed_link_google_docs": "Docs", + "embed_link_google_docs_desc": "En intégrant Google Docs, vous pouvez modifier et afficher des documents dans AITable pour faciliter la collaboration en équipe.", + "embed_link_google_docs_link_text": "Comment intégrer Google Docs", + "embed_link_google_docs_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-docs-file", + "embed_link_google_sheets": "Sheets", + "embed_link_google_sheets_desc": "En intégrant Google Sheets, vous pouvez modifier et afficher des tableaux dans AITable pour faciliter la collaboration en équipe.", + "embed_link_google_sheets_link_text": "Comment intégrer Google Sheets", + "embed_link_google_sheets_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-sheets-file", + "embed_link_jishi_design": "JSconception", + "embed_link_jishi_design_desc": "En intégrant des fichiers JSdesign, les membres peuvent visualiser et modifier les brouillons de conception plus facilement, améliorant ainsi l'efficacité de la collaboration.", + "embed_link_jishi_design_link_text": "Comment intégrer des fichiers JSdesign", + "embed_link_jishi_design_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-js-design-file", + "embed_link_tencent_docs": "Documents Tencent", + "embed_link_tencent_docs_desc": "En intégrant Tencent Docs, vous pouvez modifier et afficher des documents Tencent dans Vika pour améliorer l'efficacité de la collaboration.", + "embed_link_tencent_docs_link_text": "Comment intégrer Tencent Docs", + "embed_link_tencent_docs_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-tencent-docs", + "embed_link_wps": "WPS", + "embed_link_wps_desc": "En intégrant des fichiers WPS, vous pouvez modifier et afficher des documents, des tableaux et des formulaires WPS dans Vika pour améliorer l'efficacité de la collaboration.", + "embed_link_wps_link_text": "Comment intégrer des fichiers WPS", + "embed_link_wps_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-wps-file", + "embed_link_youtube": "Youtube", + "embed_link_youtube_desc": "En intégrant des vidéos YouTube, vous pouvez regarder des didacticiels et des guides, ou afficher la page d'accueil de la chaîne dans AITable.", + "embed_link_youtube_link_text": "Comment intégrer des vidéos YouTube", + "embed_link_youtube_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-youtube-video", + "embed_page": "Page personnalisée", + "embed_page_add_url": "Ajouter l'URL", + "embed_page_doc_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_page_function_desc": "Ajoutez des pages Web dans ${edition} pour accéder facilement aux documents, vidéos et bien plus encore de sites Web tiers. Vous pouvez ajouter des liens de sites Web recommandés ou des liens personnalisés.", + "embed_page_node_permission_editor": "Sur la base de \"mise à jour uniquement\", peut également ouvrir le partage public du fichier", + "embed_page_node_permission_manager": "Peut effectuer toutes les actions sur le fichier", + "embed_page_node_permission_reader": "Peut afficher le contenu de la page personnalisée et les informations de base sur le fichier", + "embed_page_node_permission_updater": "Sur la base du \"lecture seule\", on peut également modifier le lien de la page personnalisée", + "embed_page_setting_title": "Ajouter une page personnalisée", + "embed_page_url_invalid": "Veuillez entrer l'URL correcte", + "embed_paste_link_bilibili_placeholder": "Collez le lien vidéo bilibili", + "embed_paste_link_default_placeholder": "Collez l'URL", + "embed_paste_link_figma_placeholder": "Collez le lien de partage du fichier Figma", + "embed_paste_link_google_docs_placeholder": "Collez le lien de partage Google Docs", + "embed_paste_link_google_sheets_placeholder": "Collez le lien de partage Google Sheets", + "embed_paste_link_jsdesign_placeholder": "Collez le lien de partage du fichier JSdesign", + "embed_paste_link_tencent_docs_placeholder": "Collez le lien de partage Tencent Docs", + "embed_paste_link_wps_placeholder": "Collez le lien de partage du fichier WPS", + "embed_paste_link_youtube_placeholder": "Collez le lien de la vidéo YouTube", + "embed_success": "Ajouter avec succès", "emoji_activity": "Activité", "emoji_custom": "Personnalisée", "emoji_flags": "Drapeaux", @@ -1750,6 +1881,11 @@ "estonia": "Estonie", "ethiopia": "Éthiopie", "event_planning": "Planification d'événements", + "every": "Chaque", + "every_day_at": "jour(s) à", + "every_hour_at": "heure(s) à", + "every_month_at": "mois(s) sur le", + "every_week_at": "Chaque semaine sur", "everyday_life": "Vie du quotidien", "everyone_visible": "Visible pour tous", "exact_date": "date exacte", @@ -1760,6 +1896,7 @@ "exchange": "Rédemption", "exchange_code_times_tip": "Note: Le code de rachat ne peut être utilisé qu'une seule fois", "exclusive_consultant": "Consultant exclusif V+", + "exclusive_limit_plan_desc": "Niveau limité exclusif", "exist_experience": "Quitter l'expérience", "exits_space": "Sortir de l’espace", "expand": "Agrandir", @@ -1786,7 +1923,7 @@ "expired": "Expiré", "export": "Exportation en cours...", "export_brand_desc": "Propulsé par", - "export_current_preview_view_data": "", + "export_current_preview_view_data": "Export current preview view data", "export_gantt_button_tips": "Exporter vers un fichier .png", "export_gantt_chart": "Exporter le diagramme gantt", "export_to_excel": "Exporter les données", @@ -2358,26 +2495,26 @@ "gantt_config_color_help": "Comment configurer", "gantt_config_friday": "Vendredi", "gantt_config_friday_in_bar": "Ven", - "gantt_config_friday_in_select": "Ven", + "gantt_config_friday_in_select": "Vendredi", "gantt_config_monday": "Lundi", - "gantt_config_monday_in_bar": "Lundi", + "gantt_config_monday_in_bar": "Lun", "gantt_config_monday_in_select": "Lundi", "gantt_config_only_count_workdays": "La durée ne compte que les jours ouvrables.", "gantt_config_saturday": "Samedi", "gantt_config_saturday_in_bar": "Sam", - "gantt_config_saturday_in_select": "Sam", + "gantt_config_saturday_in_select": "Samedi", "gantt_config_sunday": "Dimanche", "gantt_config_sunday_in_bar": "Dim", - "gantt_config_sunday_in_select": "Dim", + "gantt_config_sunday_in_select": "Dimanche", "gantt_config_thursday": "Jeudi", - "gantt_config_thursday_in_bar": "Université Tsinghua", - "gantt_config_thursday_in_select": "Université Tsinghua", + "gantt_config_thursday_in_bar": "Jeu", + "gantt_config_thursday_in_select": "Jeudi", "gantt_config_tuesday": "Mardi", - "gantt_config_tuesday_in_bar": "Mai", - "gantt_config_tuesday_in_select": "Mai", + "gantt_config_tuesday_in_bar": "Mar", + "gantt_config_tuesday_in_select": "Mardi", "gantt_config_wednesday": "Mercredi", "gantt_config_wednesday_in_bar": "Mer", - "gantt_config_wednesday_in_select": "Mer", + "gantt_config_wednesday_in_select": "Mercredi", "gantt_config_weekdays_range": "${weekday} à ${weekday}", "gantt_config_workdays_a_week": "Jours de travail standard personnalisés", "gantt_cycle_connection_warning": "Dépendance de tâche non valide, il y a une connexion de cycle\n", @@ -2458,6 +2595,7 @@ "gold_grade": "Or", "gold_grade_desc": "Pour les équipes avec un processus métier complexe", "gold_seat_200_desc": "200", + "gold_seat_300_desc": "300", "golden_grade": "Or", "got_it": "Compris", "got_v_coins": "V pièces récompensées", @@ -2491,6 +2629,8 @@ "guests_per_space": "Invités par Espace", "guide_1": "啊这", "guide_2": "Il ne faut que quelques minutes pour apprendre les fonctions de base. Travaillez de manière plus productive dès maintenant !", + "guide_flow_modal_contact_sales": "Contacter le service commercial", + "guide_flow_modal_get_started": "Commencer", "guide_flow_of_catalog_step1": "Voici un catalogue fonctionnel où sont stockés tous les dossiers et fichiers de l'espace.", "guide_flow_of_catalog_step2": "Dans le catalogue fonctionnel, vous pouvez créer une feuille de données ou un dossier si nécessaire.", "guide_flow_of_click_add_view_step1": "En plus d'une vue de base, il est fortement recommandé de créer une vue d'album si vous avez des pièces jointes au format image.", @@ -2669,6 +2809,7 @@ "intro_widget_tips": "Qu'est-ce que le widget ?", "introduction": "Présentation", "invalid_action_sort_tip": "En tant que champ de regroupement, le tri a été défini. Le paramétrage de l'ordre actuel ne prendra pas effet.", + "invalid_automation_configuration": "Configuration d'automatisation invalide, veuillez vérifier et réessayer", "invalid_field_type": "Type de champ invalide", "invalid_option_sort_tip": "En tant que champ de regroupement, le tri a été défini. ", "invalid_redemption_code_entered": "Code de rachat invalide", @@ -2799,6 +2940,9 @@ "label_format_day_month_and_year_split_by_slash": "Jour/mois/Année", "label_format_month": "Mois", "label_format_month_and_day_split_by_dash": "Mois du jour", + "label_format_month_day_year_split_by_dash": "Month-Day-Year", + "label_format_month_day_year_split_by_slash": "Month/Day/Year", + "label_format_month_day_year_two_digit_year_split_by_slash": "Month/Day/Year (Two-digit year)", "label_format_year": "Année", "label_format_year_and_month_split_by_dash": "Année-Mois", "label_format_year_month_and_day_split_by_dash": "Année-Moise-Jour", @@ -2877,6 +3021,7 @@ "lark_version_enterprise": "Plan d'entreprise avec Lark", "lark_version_standard": "Plan standard avec Lark", "lark_versions_free": "Plan de base avec Lark", + "last_day": "Dernier jour", "last_modified_by_select_modal_desc": "Si l'un des champs que vous sélectionnez ci-dessous est modifié, le membre qui a modifié le plus récemment sera affiché dans la dernière édition par champ", "last_modified_time_select_modal_desc": "Si l'un des champs que vous sélectionnez ci-dessous est modifié, la date de modification la plus récente s'affichera dans le dernier champ de temps modifié", "last_step": "Précédent", @@ -3021,7 +3166,7 @@ "mail_invite_fail": "Invitation par e-mail réussie.", "mail_invite_success": "Invitation par e-mail réussie.", "main_admin_name": "Nom de l'administrateur", - "main_admin_page_desc": "Les administrateurs ont un accès complet à l'espace, comme l'assignation de sous-administrateurs et le transfert de la propriété de l'espace", + "main_admin_page_desc": "L'administrateur a un accès complet à l'espace, comme la gestion des membres et la gestion des paramètres de l'espace.", "main_contain": "Contenu principal", "malawi": "Malawi", "malaysia": "Malaisie", @@ -3241,8 +3386,12 @@ "more_widget": "Plus de widgets", "morocco": "Le Maroc", "move": "Déplacer", + "move_datasheet_link_warn": "Cannot be moved to Team Area alone, because there is a two-way link from the current datasheet to another datasheet, it is recommended to put them in a folder and then move them", "move_favorite_node_fail": "Le déplacement du nœud a échoué. Le système mettra à jour la liste automatiquement. ", + "move_folder_link_warn": "Cannot be moved to Team Area because the files in the current folder are linked to files outside the folder (may be two-way links or linked by forms, etc.) We recommend that they be placed in a folder before moving", "move_node_modal_content": "Après le déplacement, la visibilité du fichier peut être affectée par le dossier parent.", + "move_other_link_no_permission": "Unable to move to the corresponding folder because you do not have administrative rights to the folder", + "move_other_link_warn": "It is not allowed to move ${node type} to Team Area alone, because it connects to the datasheet of Private Area, it is recommended to put them in a folder before moving them", "move_to": "Déplacer vers", "move_to_error_equal_parent": "Le fichier est sous le dossier actuel. Veuillez sélectionner un autre dossier", "move_to_modal_title": "Déplacez [${name}] vers", @@ -3273,7 +3422,9 @@ "new_a_line": "Maj+Entrée : ligne de rupture", "new_automation": "Nouvelle automatisation", "new_caledonia": "Nouvelle-Calédonie", + "new_custom_page": "New custom page", "new_datasheet": "Nouvelle fiche technique", + "new_ebmed_page": "Nouvelle page personnalisée", "new_folder": "Nouveau dossier", "new_folder_btn_title": "Répertoire", "new_folder_tooltip": "Créer un dossier", @@ -3439,7 +3590,7 @@ "nvc_start_text": "Faites glisser la barre vers la droite", "nvc_yes_text": "Vérifié", "obtain_verification_code": "Code de vérification non obtenu ou expiré", - "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrzw0miJVmSkJ7eBBa9k/fomx5qPX0JGPFvfEEP\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", + "offical_website_footer_nav_data": "[{ \"title\": \"产品\", \"lists\": [{ \"name\": \"快速入门\", \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick- start\" }, { \"name\": \"产品指南\", \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\" }, { \"name\": \"产品价格\", \"url\": \"/pricing/\" }, { \"name\": \"产品路线图\", \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\" }] }, { \"title\": \"关于我们\", \"lists\": [{ \"name\": \"公司介绍\", \"url\": \"/company/\" }, { \"name\": \"加入我们\", \"url \": \"/rejoignez-nous/\" }, { \"name\": \"媒体报道\", \"url\": \"/press/\" }, { \"name\": \"vika维格课堂\", \"url\": \"https ://edu.vika.cn/\" }, { \"name\": \"维格合伙人\", \"url\": \"/partners/\" }] }, { \"title\": \"解决方案\", \"lists\" : [{ \"name\": \"PMO项目群管理\", \"url\": \"/business-pmo/\" }, { \"name\": \"智慧电商运营\", \"url\": \"/ecommerce/\" }, { \"name\": \"CRM客户管理\", \"url\": \"/crm/\" }, { \"name\": \"HR人力资源管理\", \"url\": \"/hr/\" }, { \"name\": \"Scrum\"管理\", \"url\": \"/okr/\" }, { \"name\": \"教育培训管理\", \"url\": \"/education/\" }, { \"name\": \"智慧门店管理\", \"url\" : \"/shop/\" }] }, { \"title\": \"支持\", \"lists\": [{ \"name\": \"意见反馈\", \"url\": \"https://vika.cn/share/shrCvbFC53xc3kl00B4Pg \" }, { \"name\": \"帮助中心\", \"url\": \"https://help.vika.cn/\" }, { \"name\": \"开发者中心\", \"url\": \"/developers/ \" }, { \"name\": \"服务条款\", \"url\": \"/service-agreement/\" }, { \"name\": \"隐私协议\", \"url\": \"/service-agreement/\" }, { \"name\": \"安全与合规\", \"url\": \"/security/\" }] }, { \"title\": \"服务\", \"lists\": [{ \"name\": \"加入社群\", \" url\": \"/chatgroup/\" }, { \"name\": \"Github开源\", \"url\": \"https://github.com/vikadata\" }, { \"name\": \"预约演示\", \"url\" : \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\" }, { \"name\": \"专有云部署\", \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\" } , { \"name\": \"应用连接\", \"url\": \"/connections/\" }] }, { \"title\": \"联系我们\", \"lists\": [{ \"name\": \"地址:深圳市南山区国信投资大厦1710\", \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\" }, { \"name\": \"售前咨询:点击联系商务\", \"url\": \"https: //vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\" }, { \"name\": \"合作:bd@vikadata.com\", \"url\": \"mailto:bd@vikadata.com\" }, { \"name\": \"媒体:pr@vikadata.com\", \"url\": \"mailto:pr@vikadata.com\" }, { \"name\": \"招聘:hr@vikadata.com\", \"url\": \"mailto:hr@vikadata. com\" }] }]", "offical_website_nav_data": "[{\n \"name\": \"产品\",\n \"href\": \"/login\",\n \"children\": [\n {\n \"name\": \"vika维格表 Overview\",\n \"href\": \"/login/\"\n },\n {\n \"name\": \"应用连接 Integration\",\n \"href\": \"/connections/\"\n },\n {\n \"name\": \"客户端(Beta) Download\",\n \"href\": \"/download/\"\n }\n ]\n}, {\n \"name\": \"解决方案\",\n \"href\": \"/\",\n \"children\": [{\n \"name\": \"PMO项目群管理\",\n \"href\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"href\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"href\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"href\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"href\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"href\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"href\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"href\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"href\": \"/shop/\"\n }, {\n \"name\": \"更多解决方案 >\",\n \"href\": \"/solutions/\"\n }]\n}, {\n \"name\": \"模板/案例\",\n \"href\": \"/template\",\n \"children\": [\n {\n \"name\": \"模板中心 Tempaltes\",\n \"href\": \"/template\"\n },\n {\n \"name\": \"客户案例 Customers\",\n \"href\": \"/cases/\"\n }\n ]\n},\n {\n \"name\": \"首页\",\n \"href\": \"/?home=1\"\n },\n {\n \"name\": \"学习资源\",\n \"href\": \"https://edu.vika.cn/index\",\n \"children\": [\n {\n \"name\": \"快速入门 Tutorials\",\n \"href\": \"https://help.vika.cn/docs/guide/tutorial\"\n },\n {\n \"name\": \"产品手册 Manual\",\n \"href\": \"https://help.vika.cn/docs/guide/manual\"\n },\n {\n \"name\": \"维格课堂 Vika Education\",\n \"href\": \"https://edu.vika.cn/\"\n },\n {\n \"name\": \"维格社区 Vika BBS\",\n \"href\": \"https://bbs.vika.cn/\"[{\n \"name\": \"产品\",\n \"href\": \"/login\",\n \"children\": [\n {\n \"name\": \"vika维格表 Overview\",\n \"href\": \"/login/\"\n },\n {\n \"name\": \"应用连接 Integration\",\n \"href\": \"/connections/\"\n },\n {\n \"name\": \"客户端(Beta) Download\",\n \"href\": \"/download/\"\n }\n ]\n}, {\n \"name\": \"解决方案\",\n \"href\": \"/\",\n \"children\": [{\n \"name\": \"PMO项目群管理\",\n \"href\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"href\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"href\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"href\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"href\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"href\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"href\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"href\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"href\": \"/shop/\"\n }, {\n \"name\": \"更多解决方案 >\",\n \"href\": \"/solutions/\"\n }]\n}, {\n \"name\": \"模板/案例\",\n \"href\": \"/template\",\n \"children\": [\n {\n \"name\": \"模板中心 Tempaltes\",\n \"href\": \"/template\"\n },\n {\n \"name\": \"客户案例 Customers\",\n \"href\": \"/cases/\"\n }\n ]\n},\n {\n \"name\": \"首页\",\n \"href\": \"/?home=1\"\n },\n {\n \"name\": \"学习资源\",\n \"href\": \"https://edu.vika.cn/index\",\n \"children\": [\n {\n \"name\": \"快速入门 Tutorials\",\n \"href\": \"https://help.vika.cn/docs/guide/tutorial\"\n },\n {\n \"name\": \"产品手册 Manual\",\n \"href\": \"https://help.vika.cn/docs/guide/manual\"\n },\n {\n \"name\": \"维格课堂 Vika Education\",\n \"href\": \"https://edu.vika.cn/\"\n },\n {\n \"name\": \"维格社区 Vika BBS\",\n \"href\": \"https://bbs.vika.cn/\"\n },\n {\n \"name\": \"第三方连接 Integration\",\n \"href\": \"https://help.vika.cn/docs/guide/connection\"\n },\n {\n \"name\": \"开发者中心 Developer Center\",\n \"href\": \"/developers/\"\n },\n {\n \"name\": \"常见问题 FAQ\",\n \"href\": \"https://help.vika.cn/docs/guide/questions\"\n }\n ]\n }]\n },\n {\n \"name\": \"第三方连接 Integration\",\n \"href\": \"https://help.vika.cn/docs/guide/connection\"\n },\n {\n \"name\": \"开发者中心 Developer Center\",\n \"href\": \"/developers/\"\n },\n {\n \"name\": \"常见问题 FAQ\",\n \"href\": \"https://help.vika.cn/docs/guide/questions\"\n }\n ]\n }]", "office_preview": "Aperçu des fichiers Office", "office_preview_app_desc": "

Aperçu en ligne lisse des fichiers bureautiques sur la feuille de données, vous permettant de visualiser les fichiers bureautiques courants tels que Excel, Word, PPT, etc. sur votre ordinateur de bureau ou mobile n'importe où, à tout moment

\n\n
    \n
  • Aperçu en ligne de . oc, .docx, .xls, .xlsx, .ppt, .pptx, et . df fichiers bureautiques formatés
  • \n
  • Bureau et mobile supportent les aperçus de fichiers des formats ci-dessus
  • \n
\n\n

Notes supplémentaires :

\n
    \n
  • Cette fonctionnalité est alimentée par \"Conversion Cloud Yoncentrique\" et officiellement intégrée
  • \n
  • Cliquez sur le bouton \"Activer\" ci-dessous pour activer cette intégration et accepter que \"Conversion Cloud Yoncentrique\" lit les fichiers bureautiques que vous souhaitez prévisualiser
  • \n
  • Si vous n'avez plus besoin de la fonction de prévisualisation des fichiers bureautiques, l'administrateur de l'espace peut le désactiver sur cette page
  • \n
", @@ -3479,6 +3630,7 @@ "open_auto_save_success": "La vue d'enregistrement automatique est activée avec succès", "open_auto_save_warn_content": "Toutes les modifications sous cette vue sont automatiquement enregistrées et synchronisées avec d'autres membres.", "open_auto_save_warn_title": "Activer la vue de sauvegarde automatique", + "open_automation_time_arrival": "https://aitable.ai/contact-sales-open-source", "open_failed": "Échec de l'ouverture", "open_in_new_tab": "ouvrir dans un nouvel onglet", "open_invite_after_operate": "Une fois activé, tous les membres peuvent inviter de nouveaux membres depuis le panneau des contacts", @@ -3625,6 +3777,8 @@ "payment_record": "Dossier de paiement", "payment_reminder": "Rappel de paiement", "payment_reminder_content": "Le nouveau plan que vous avez sélectionné est plus déductible que le montant à payer. Il est recommandé de choisir le nouveau plan avec une durée plus longue. Si vous le confirmez, le montant excédentaire ne sera pas remboursable. ${action} en cas de doute", + "payment_reminder_modal_content": "Vous pouvez essayer la version avancée pour profiter de plus de nœuds de fichiers, d'autorisations d'entreprise, de capacité de pièces jointes, de volume de données, d'IA et d'autres fonctionnalités et privilèges avancés.", + "payment_reminder_modal_title": "Vous utilisez actuellement la version gratuite", "pending_invite": "Invitation en attente", "people": " membre(s)", "per_person_per_year": "Par personne et par an", @@ -3794,7 +3948,7 @@ "player_step_ui_config_168": "{\n\"templateKey\":\"createMirrorTip\"\n}", "player_step_ui_config_169": "{ \"headerImg\": \"https://s4.vika.cn/space/2023/04/04/bcf0695cf35840e6b85e032a8e5ea0a1\", \"readMoreUrl\": \"https://help.vika.cn/changelog/23-04-10- mises à jour\", \"enfants\": \"

🚀 Introduction de nouvelles fonctions

\\n
  • Un nouveau type de champ \"Cascader\" est lancé, facilitant la sélection parmi une hiérarchie d'options sur les formulaires.
  • Le widget \"Script\" est sorti, moins de code pour plus de personnalisation
  • Déclenchez l'automatisation pour envoyer des e-mails et recevoir des notifications rapides
  • Déclenchez l'automatisation pour envoyer un message à Slack et informer votre équipe à temps
  • Explorer l'IA : lancement du widget \"Générateur de contenu GPT\"
\" }", "player_step_ui_config_17": "{\n \"element\": \"#TEMPLATE_CENTER_USE_TEMPLATE_BTN>button\", \n\"placement\": \"rightBottom\",\n\"offsetY\": 20,\n \"title\": \"Comment utiliser un modèle\", \n\"description\": \"Cliquez sur le bouton à gauche pour utiliser le modèle\", \"children\":\"\" \n}", - "player_step_ui_config_176": "{\"title\":\"Introduction au AI agent\",\"video\":\"https://www.youtube.com/embed/cjds1r_roG8?si=irKUpMhwDlOEb8Hc\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", + "player_step_ui_config_176": "{\"title\": DEMO AITable.ai, \"video\": https://www.youtube.com/embed/kGxMyEEo3OU, \"videoId\": \"VIKA_GUIDE_VIDEO_FOR_AI\", \"autoPlay\": true}", "player_step_ui_config_18": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select>. nt-select-selector\", \n\"placement\": \"bottomLeft\",\n \"title\": \"Comment utiliser un modèle\", \n\"description\": \"Sélectionnez où mettre le modèle\", \"children\":\"\" \n}", "player_step_ui_config_19": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select .ant-select-selector\"\n}", "player_step_ui_config_2": "{\n \"config\": [\n {\n \"key\": 1,\n \"nom\": \"réponse1\",\n \"titre\": \"Quel genre de questions êtes-vous impatient de résoudre par vikadata? ,\n \"type\": \"checkbox\",\n \"réponses\": [\n \"Planification de travail\",\n \"Service client\",\n \"Gestion de projet\",\n \"Sourcing Supply\",\n \"Content Production\",\n \"Opération e-commerce\",\n \"Planification d'événement\",\n \"Ressources humaines\",\n \"Administration\",\n \"Gestion financière\",\n \"Webcast\",\n \"Gestion des instituts éducatifs\",\n \"Autre\"\n ],\n \"lastAllowInput\": vrai\n },\n {\n \"key\": 2,\n \"name\": \"answer2\",\n \"title\": \"Votre titre d'emploi est______\",\n \"type\": \"radio\",\n \"réponses\": [\n \"Directeur Général\",\n \"Chef de projet\",\n \"Gestionnaire de produits\",\n \"Designer\",\n \"Ingénieur R&D \",\n \"Opérateur, éditeur\",\n ventes, service à la clientèle\",\n \"Ressources humaines, administration \",\n \"Finance\", comptable\",\n \"Avocat, affaires juridiques\",\n \"Marketing\",\n \"Professeur\",\n \"Étudiant\",\n \"Autre\"\n ],\n \"lastAllowInput\": vrai\n },\n {\n \"key\": 3,\n \"name\": \"answer3\",\n \"title\": \"Quel est le nom de votre entreprise? ,\n \"type\": \"input\",\n \"submit\": false\n },\n {\n \"key\": 4,\n \"name\": \"answer4\",\n \"titre\": \"Veuillez laisser votre adresse e-mail/ numéro de téléphone/ compte Wechat ci-dessous afin que nous puissions vous joindre à temps lorsque vous avez besoin d'aide. ,\n \"type\": \"input\",\n \"submit\": true\n },\n {\n \"key\": 5,\n \"titre\": \"Merci d'avoir rempli le formulaire, vous pouvez ajouter notre service à la clientèle en cas de besoin\",\n \"platform\": {\n \"website\": \"https://s4.vika.cn/space/2023/03/02/b34e3205a9154463be16f497524f1327\",\n \"dingtalk\": \"https://s4.vika.cn/space/2023/03/02/4b16cef6602a4586a21d6346bf25d300\",\n \"wecom\": \"https://s4.vika.cn/space/2023/03/02/60119b1b69b64aa887bd1be6a2928bec\",\n \"feishu\": \"https://u. ika.cn/z9ygm\"\n },\n \"type\": \"contactUs\",\n \"next\": true\n }\n ]\n}\n", @@ -3824,13 +3978,13 @@ "player_step_ui_config_41": "", "player_step_ui_config_42": "{\n \"element\": \"#DATASHEET_FORM_LIST_PANEL\", \n\"placement\": \"leftTop\",\n \"title\": \"Form\", \n\"description\": \"Vous pouvez rapidement créer un formulaire à partir de la vue actuelle. Le nombre et l'ordre des champs dans le formulaire sont compatibles avec la vue.\", \"children\":\"\" \n}", "player_step_ui_config_43": "{\n \"element\": \".style_navigation__1U5cR . tyle_help__1sXEA\", \n\"placement\": \"rightBais\",\n \"title\": \"Conseil\", \n\"offsetY\":5,\n\"description\": \"Vous pouvez trouver votre assistant Vikaby à partir de l'icône \"Aide\" à gauche\", \"enfants\":\"\" \n}", - "player_step_ui_config_44": "{\n\"title\":\"hiérarchie de Vikadata\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", + "player_step_ui_config_44": "{\n\"title\":\"hiérarchie de Vikadata\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", "player_step_ui_config_45": "", "player_step_ui_config_46": "", "player_step_ui_config_47": "{\n \"element\": \"#DATASHEET_WIDGET_BTN\",\n\"placement\": \"bottomRight\",\n \"title\": \"Widget\", \n\"description\": \"Vous voulez utiliser et visualiser vos données de manière plus riche? Essayez le widget ! , \"children\":\"\" \n}", "player_step_ui_config_48": "", "player_step_ui_config_49": "{\n \"élément\": \". tyle_widgetPanelContainer__1l2ZV\",\n\"placement\": \"centre gauche\",\n \"titre\": \"Qu'est-ce qu'un widget\", \n\"description\": \"Les widgets Vika sont une application étendue de vikadonnées qui se caractérise par une visualisation de données plus riche, le transfert de données, le nettoyage de données, et plus encore. En installant des widgets dans le tableau des widgets, vous pouvez faciliter le travail.\", \"enfants\":\"\" \n}", - "player_step_ui_config_5": "{\n\"title\":\"hiérarchie de Vikadata\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", + "player_step_ui_config_5": "{\n\"title\":\"hiérarchie de Vikadata\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", "player_step_ui_config_50": "{\n \"element\": \".style_widgetModal__eXmdB\",\n\"placement\": \"leftTop\",\n \"title\": \"Widget Center\", \n\"description\": \"Officiellement recommandé et personnalisés widgets sont publiés ici. Vous pouvez installer n'importe quel widget que vous voulez sur un tableau de bord ou dans un widget de n'importe quelle feuille de données.\", \"children\":\"\" \n}", "player_step_ui_config_51": "{\n \"element\": \".style_widgetModal__eXmdB .style_widgetItem__3Pl-1 bouton\",\n\"placement\": \"rightBottom\",\n \"title\": \"Installer le widget\", \n\"description\": \"Installons ce widget \"Graphique\" widget\", \"children\":\"\" \n}", "player_step_ui_config_52": "", @@ -3927,6 +4081,7 @@ "preview_guide_click_to_restart": "Appuyez sur le bouton ci-dessous pour prévisualiser à nouveau", "preview_guide_enable_it": "Appuyez sur le bouton ci-dessous pour activer cette fonction", "preview_guide_open_office_preview": "Pour visualiser ce fichier, veuillez activer la fonction \"Prévisualisation bureautique\"", + "preview_next_automation_execution_time": "Aperçu des 10 prochaines heures d'exécution", "preview_not_support_video_codecs": "Seules les vidéos MP4 avec des codecs H.264 peuvent être prévisualisées", "preview_revision": "Aperçu", "preview_see_more": "Vous voulez en savoir plus sur la fonction \"aperçu des dossiers de bureau\" ? Veuillez cliquer ici", @@ -3962,6 +4117,7 @@ "privacy_protection": "\"Protection de la vie privée\"", "private_cloud": "Nuage privé", "private_external_person_only": " Personne externe uniquement", + "private_help_link": "https://help.aitable.ai/docs/guide/team-and-private-area#private-area", "private_internal_person_only": " Personne interne uniquement", "private_product_point": "Possédez votre plateforme APITable en un seul clic", "privatized_deployment": "Auto-hébergé", @@ -4032,13 +4188,15 @@ "reconciled_data": "Les données sont en cours de rapprochement", "record": "Enregistrements", "record_activity_experience_tips": "Vous pouvez afficher l'activité d'enregistrement de ${day} jours", + "record_archived_data": "enregistrement archivé", + "record_chunk_text": "${text} rows, please wait", "record_comment": "Commentaires uniquement", "record_comments": "commenté", "record_fail_data": "erreur de données", "record_filter_tips": "Cet enregistrement a été filtré", "record_functions": "Fonction d'enregistrement", "record_history": "Historique des révisions uniquement", - "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-history", + "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-activity", "record_history_title": "Historique des enregistrements", "record_pre_filtered": "Cet enregistrement a été filtré et sera masqué une fois que vous aurez cliqué en dehors de l'enregistrement", "record_pre_move": "Cet enregistrement sera déplacé ailleurs une fois que vous cliquerez en dehors de l'enregistrement", @@ -4478,6 +4636,12 @@ "scan_to_login": "Scanner pour se connecter", "scan_to_login_by_method": "Veuillez scanner ${method} pour suivre le compte officiel pour vous connecter", "scatter_chart": "Graphique de dispersion", + "schedule_day_tips": "Le calcul du cycle commence à compter à partir du premier jour de chaque mois. Si on suppose qu'il se répète tous les 10 jours, alors il se déclenchera les 1er, 11, 21 et 31 de chaque mois.", + "schedule_hour_tips": "Le calcul du cycle commence à minuit (0h00) chaque jour. En supposant qu'il se répète 0 minute toutes les trois heures, cela se produira quotidiennement à minuit (0h00), 3h00, 6h00, 9h00, midi (12h00), 15h00, 18h00 et enfin à la tombée de la nuit (21h00).", + "schedule_start_day": "A partir du 1er jour du mois, tous les", + "schedule_start_month": "À partir de janvier de chaque année, chaque", + "schedule_type": "Type d'horaire", + "schedule_year_tips": "Le calcul du cycle commence à compter du premier mois de chaque année. En supposant un intervalle de 3 mois le premier jour, les déclencheurs seront activés à minuit le premier jour de janvier, avril, juillet et octobre de chaque année.", "science_and_technology": "Science et technologie", "scroll_screen_down": "Faire défiler un écran vers le bas", "scroll_screen_left": "Faire défiler un écran vers la gauche", @@ -4491,6 +4655,7 @@ "search_folder_or_sheet": "Rechercher des fichiers", "search_new_admin": "Chercher", "search_node_pleaseholder": "Rechercher des fichiers (${shortcutKey})", + "search_node_tip": "Recherche rapide (${shortcutKey})", "search_or_add": "Trouver ou ajouter une option", "search_role_placeholder": "Rechercher des rôles", "seats": "Sièges", @@ -4894,6 +5059,7 @@ "space_info": "Aperçu", "space_info_del_confirm1": "1. La suppression de cet espace va nettoyer les données suivantes :", "space_info_del_confirm2": "2. L'espace sera supprimé complètement après 7 jours. Vous pouvez restaurer l'espace avant cette date.", + "space_info_del_confirm3": "3. For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "space_info_feishu_desc": "Vous utilisez une intégration de tiers. Pour supprimer l'espace, veuillez d'abord désactiver l'intégration de tiers. ", "space_info_feishu_label": "Intégrations", "space_join_apply": " a demandé à rejoindre l'espace \".", @@ -4980,6 +5146,7 @@ "start_onfiguration": "Lancer la configuration", "start_time": "Heure de début", "start_use": "Commencez à utiliser", + "starting_from_midnight": "À partir de minuit (00h00) tous les jours, tous les", "startup": "Démarrage", "startup_company_support_program": "Programme de support de démarrage", "stat_average": "Moyenne", @@ -5013,6 +5180,8 @@ "stay_tuned_for_more_features": "Restez à l'écoute pour plus de fonctions", "steps_choose_reset_mode": "Sélectionnez une méthode de réinitialisation", "steps_validate_identities": "Vérifier l'identité", + "stop_chunk_content": "Are you sure you want to stop the operation?", + "stop_chunk_title": "Stop", "stop_dingtalk_h5_modal_content": "L'application auto-construite sera dissociée de cet espace. Veuillez confirmer .", "storage_per_seats": "", "storage_per_space": "Utilisation du stockage", @@ -5043,9 +5212,11 @@ "subscribe_credit_usage_over_limit": "Le nombre de crédits dans l'espace actuel dépasse la limite, veuillez mettre à jour votre abonnement.\n", "subscribe_demonstrate": "Demander des démos", "subscribe_disabled_seat": "Le nombre de personnes ne peut pas être inférieur au programme original", + "subscribe_grade_business": "Entreprise", "subscribe_grade_free": "Gratuit", "subscribe_grade_plus": "Plus", "subscribe_grade_pro": "Approuvé", + "subscribe_grade_starter": "Entrée", "subscribe_label_tooltip": "Fonctionnalités de l'espace avancé", "subscribe_new_choose_member": "Prend en charge jusqu'à ${member_num} membres", "subscribe_new_choose_member_tips": "Ce forfait permet à 1 ~ ${member_num} membres d'accéder à l'espace", @@ -5182,7 +5353,7 @@ "template_name_repetition_title": "\"${templateName}\" existe déjà. Voulez-vous le remplacer?", "template_no_template": "Aucun modèle", "template_not_found": "Vous ne trouvez pas de modèles que vous voulez ? Dites-nous", - "template_recommend_title": "Chaud", + "template_recommend_title": "🌟 Hot", "template_type": "Gabarit", "terms_of_service": "< conditions d'utilisation >", "terms_of_service_pure_string": "Conditions d'utilisation", @@ -5226,6 +5397,7 @@ "text_editor_tip_end": "\"Entrée\" jusqu'à la fin de l'édition", "text_functions": "Fonction de chaîne de caractères", "thailand": "Thaïlande", + "the_button_field_is_misconfigured": "Le champ du bouton est mal configuré, veuillez vérifier et réessayer", "the_current_automation_workflow_has_no_related_files_you_can_establish_a_link_by_adding_trigger_conditions_and_actions_on_the_left_side": "Le flux de travail d'automatisation actuel n'a pas de fichiers connexes. Vous pouvez établir un lien en ajoutant des conditions de déclenchement et des actions sur le côté gauche", "the_current_button_column_has_expired_please_reselect": "La colonne de boutons actuelle a expiré, veuillez resélectionner", "the_last_7_days": "les 7 derniers jours", @@ -5328,6 +5500,7 @@ "timemachine_update_comment": "commentaire(s) mis à jour", "times_per_month_unit": "appel(s)/mois", "times_unit": " appel(s)", + "timing_rules": "Horaire", "timor_leste": "Timor oriental", "tip_del_success": "Vous pouvez restaurer votre Espace dans les 7 jours", "tip_do_you_want_to_know_about_field_permission": "Vous voulez chiffrer les données des champs ? En savoir plus sur les autorisations des champs", @@ -5515,6 +5688,7 @@ "verify_account_title": "Vérifier le compte", "verify_via_email": "Vérification d'identité par e-mail", "verify_via_phone": "Vérification d'identité par SMS", + "video": "Vidéo", "video_not_support_play": "Le format vidéo actuel ne prend pas en charge la lecture en ligne", "vietnam": "Viêt Nam", "view": "Voir", @@ -5863,7 +6037,8 @@ "workdoc_color_title": "Couleur de la police", "workdoc_create": "Créer un document de travail", "workdoc_expanded": "Développer la table des matières", - "workdoc_image_max_10mb": "La taille de l'image ne peut pas dépasser 10 Mo", + "workdoc_image_max_10mb": "nul", + "workdoc_image_max_size": "La taille de l'image ne peut pas dépasser ${size}", "workdoc_info": "Informations", "workdoc_info_create_time": "Créé à", "workdoc_info_creator": "Créé par", @@ -5871,6 +6046,7 @@ "workdoc_info_last_modify_time": "Dernière modification à", "workdoc_link_placeholder": "Veuillez entrer le lien", "workdoc_only_image": "Seule l'image est autorisée", + "workdoc_only_video": "Seule la vidéo est autorisée", "workdoc_text_placeholder": "Entrez \"/\" démarrage rapide", "workdoc_title_placeholder": "Veuillez entrer le titre", "workdoc_unnamed": "Document de travail sans nom", @@ -5879,9 +6055,11 @@ "workdoc_unsave_ok": "Annuler les modifications", "workdoc_unsave_title": "Le WorkDoc n'a pas été enregistré", "workdoc_upload_failed": "Échec du téléchargement", + "workdoc_video_max_size": "La taille de la vidéo ne peut pas dépasser ${size}", "workdoc_ws_connected": "Connecté", "workdoc_ws_connecting": "De liaison...", "workdoc_ws_disconnected": "Débranché", + "workdoc_ws_reconnecting": "Reconnexion...", "workflow_execute_failed_notify": " n'a pas pu s'exécuter à . Veuillez consulter l'historique d'exécution pour résoudre le problème. Si vous avez besoin d'aide, veuillez contacter notre équipe de service client.", "workspace_data": "Données de l'espace", "workspace_files": "Données de l'établi", diff --git a/packages/datasheet/public/file/langs/strings.it-IT.json b/packages/datasheet/public/file/langs/strings.it-IT.json index 75bb334758..4ec24ace3f 100644 --- a/packages/datasheet/public/file/langs/strings.it-IT.json +++ b/packages/datasheet/public/file/langs/strings.it-IT.json @@ -146,6 +146,15 @@ "agreed": "Approvato", "ai_advanced_mode_desc": "La modalità avanzata consente agli utenti di personalizzare i messaggi di richiesta, fornendo un maggiore controllo sul comportamento e le risposte dell'agente AI.", "ai_advanced_mode_title": "Modalità avanzata", + "ai_agent_anonymous": "Anonimo${ID}", + "ai_agent_conversation_continue_not_supported": "La continuazione di una conversazione precedente non è attualmente supportata", + "ai_agent_conversation_list": "Elenco conversazioni", + "ai_agent_conversation_log": "Registro delle conversazioni", + "ai_agent_conversation_title": "Titolo della conversazione", + "ai_agent_feedback": "Feedback", + "ai_agent_historical_message": "Quanto sopra è un messaggio storico", + "ai_agent_history": "Storia", + "ai_agent_message_consumed": "Messaggio consumato", "ai_api_curl_template": "## Create chat completions\n\n```bash\n\ncurl -X POST \"{{apiBase}}/fusion/v1/ai/{{aiId}}/chat/completions\" \\n -H \"Content-Type: application/json\" \\n -H \"Authorization: Bearer {{token}}\" \\n -d '{\n \"model\": \"gpt-3.5-turbo\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"You are a helpful assistant.\"\n },\n {\n \"role\": \"user\",\n \"content\": \"Hello!\"\n }\n ]\n }'\n\n```\n\n## Returned data example\n\n```json\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", "ai_api_footer_desc": "Incorpora l'agente AI nel tuo sito web? Per saperne di più", "ai_api_javascript_template": "## Initialize SDK [![github]({{ githubIcon }})](https://github.com/openai/openai-node)\nAITable's chat completion API is compatible with OpenAI's Node.js SDK. You can use our service with the same SDK by simply changing the configuration as follows:\n\n\n```javascript\nconst { Configuration, OpenAIApi } = require(\"openai\");\nconst configuration = new Configuration({\n apiKey: \"{{token}}\",\n basePath: \"{{apiBase}}/fusion/v1/ai/{{aiId}}\"\n});\n```\n\n## Create chat completions\n\n```javascript\nconst openai = new OpenAIApi(configuration);\nconst chatCompletion = await openai.createChatCompletion({\n model: \"gpt-3.5-turbo\",\n messages: [{role: \"user\", content: \"Hello world\"}],\n});\n```\n\n## Returned data example\n\n```javascript\n\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", @@ -161,6 +170,9 @@ "ai_chat_unit": "Aibot (i)", "ai_close_setting_tip_content": "Avete fatto dei cambiamenti. Vuoi buttarli via?", "ai_close_setting_tip_title": "Suggerimenti", + "ai_copilot_generate_response": "Generazione della risposta per te...", + "ai_copilot_processs": "Elaborazione in corso, attendi...", + "ai_copilot_start_process_request": "Inizio elaborazione della tua richiesta...", "ai_create_guide_btn_text": "Seleziona foglio dati", "ai_create_guide_content": "Come agente dell'AI, posso rispondere alle vostre domande in base alle conoscenze che ho imparato. Prima di iniziare la conversazione, si prega di selezionare una scheda tecnica come base di conoscenza, e leggerò tutti i dati in esso per l'apprendimento.", "ai_credit_cost_chart_title": "Costo del credito", @@ -173,7 +185,7 @@ "ai_credit_time_dimension_year": "Quest'anno", "ai_credit_usage_tooltip": "I crediti di messaggio possono essere utilizzati per le domande di agente AI. I crediti del messaggio sono proporzionali al numero di posti sul vostro spazio.", "ai_data_source_required": "nullo", - "ai_data_source_rows": "${righe} righe di dati", + "ai_data_source_rows": "${rows} righe di dati", "ai_data_source_update": "Aggiornamento disponibile", "ai_datasheet_panel_create_btn_text": "Crea AI Agent", "ai_default_idk": "Non so", @@ -629,7 +641,7 @@ "apps_support": "Supporto clienti su tutte le piattaforme", "archive_delete_record": "Elimina i record archiviati", "archive_delete_record_title": "Elimina registrazione", - "archive_notice": "

Stai tentando di archiviare record specifici. L'archiviazione dei record comporterà le seguenti modifiche:

1. Tutti i collegamenti bidirezionali per questo record verranno annullati

2. La modifica non è supportata

3. Funzioni come promemoria della data e record di abbonamento non sono supportate

4. Non partecipare più al calcolo di ricerca, formula e altri campi

Sei sicuro di voler continuare? (Puoi annullare l'archiviazione nella casella Archivio in Avanzato)

", + "archive_notice": "

Stai tentando di archiviare record specifici. L'archiviazione dei record comporterà le seguenti modifiche:

1. La modifica non è supportata

2. Funzioni come promemoria della data e record di abbonamento non sono supportate

3. Non partecipare più al calcolo di ricerca, formula e altri campi

Sei sicuro di voler continuare? (Puoi annullare l'archiviazione nella casella Archivio in Avanzato)

", "archive_record_in_activity": "Archiviato questo disco", "archive_record_in_menu": "Archivio record", "archive_record_success": "Archiviati con successo", @@ -689,6 +701,8 @@ "audit_add_field_role_detail": "Nel \" \" scheda dati , aggiungere [ ] ruolo di [ ] per il campo [ ]", "audit_add_node_role": "Aggiungi autorizzazioni file", "audit_add_node_role_detail": "Aggiungi permesso file,imposta「${unitNames}」a「${role}」di 「${currentNodeName}」", + "audit_add_node_role_detail_end": "to「${role}", + "audit_add_node_role_detail_start": "Add file node permission,set「${unitNames}」", "audit_admin_permission_change_event": "Cambia autorizzazioni di amministratore", "audit_create_template": "Crea modello", "audit_create_template_detail": "Crea modello", @@ -697,20 +711,30 @@ "audit_delete_field_role_detail": "Verifica", "audit_delete_node_role": "Elimina autorizzazione file", "audit_delete_node_role_detail": "Elimina permesso file,cancella「${unitNames}」`s 「${role}」ruolo di 「${currentNodeName}」", + "audit_delete_node_role_detail_end": "at 「${role}」role", + "audit_delete_node_role_detail_start": "Delete file node permission,delete「${unitNames}」from", "audit_delete_template": "Elimina modello", "audit_delete_template_detail": "Elimina modello", "audit_disable_field_role": "Disabilita le autorizzazioni dei campi", "audit_disable_field_role_detail": "Verifica", "audit_disable_node_role": "Disabilita le autorizzazioni dei file", "audit_disable_node_role_detail": "Disabilita l'autorizzazione `${nodeType} 「${currentNodeName}」", + "audit_disable_node_role_detail_end": "`s permission", + "audit_disable_node_role_detail_start": "Disable ${nodeType}", "audit_disable_node_share": "Chiudi il collegamento pubblico del file", "audit_disable_node_share_detail": "Chiudi il collegamento pubblico ${nodeType} 「${currentNodeName}」", + "audit_disable_node_share_detail_end": "public link", + "audit_disable_node_share_detail_start": "Close ${nodeType}", "audit_enable_field_role": "Abilita le autorizzazioni dei campi", "audit_enable_field_role_detail": "Verifica", "audit_enable_node_role": "Abilita le autorizzazioni dei file", "audit_enable_node_role_detail": "Abilita l'autorizzazione `${nodeType} 「${currentNodeName}」", + "audit_enable_node_role_detail_end": "`s permission", + "audit_enable_node_role_detail_start": "Enable ${nodeType}", "audit_enable_node_share": "Apri il collegamento pubblico del file", "audit_enable_node_share_detail": "Apri il collegamento pubblico ${nodeType} 「${currentNodeName}」", + "audit_enable_node_share_detail_end": "public link", + "audit_enable_node_share_detail_start": "Open ${nodeType}", "audit_login_event": "Evento di accesso", "audit_logout_event": "inglese", "audit_organization_change_event": "La struttura organizzativa dei contatti è cambiata", @@ -731,18 +755,25 @@ "audit_space_invite_user_detail": "Verifica", "audit_space_node_copy": "Duplica file", "audit_space_node_copy_detail": "Duplica ${nodeType} 「${sourceNodeName}」, il nuovo nome del file è 「${currentNodeName}」", + "audit_space_node_copy_detail_start": "Duplicate ${nodeType} 「${sourceNodeName}」, the new file node's name is", "audit_space_node_create": "Crea file", "audit_space_node_create_detail": "Crea un ${nodeType} chiamato 「${currentNodeName}」", + "audit_space_node_create_detail_start": "Create a ${nodeType} named", "audit_space_node_delete": "Elimina file", "audit_space_node_delete_detail": "Elimina ${nodeType} chiamato 「${currentNodeName}」", + "audit_space_node_delete_detail_start": "Delete ${nodeType} named", "audit_space_node_export": "Esporta foglio dati", "audit_space_node_export_detail": "Membro ${member_name} foglio dati esportato ${node_name}", "audit_space_node_import": "Importa file", "audit_space_node_import_detail": "Importa un file chiamato 「${nodeName}」", + "audit_space_node_import_detail_start": "Import a file node named", "audit_space_node_move": "Sposta file", "audit_space_node_move_detail": "Sposta ${nodeType} 「${currentNodeName}」 nella cartella「${parentName}」", + "audit_space_node_move_detail_end": "to the folder「${parentName}」", + "audit_space_node_move_detail_start": "Move ${nodeType}", "audit_space_node_rename": "Rinomina file", "audit_space_node_rename_detail": "Rinomina ${nodeType} 「${oldNodeName}」in 「${nodeName}」", + "audit_space_node_rename_detail_start": "Rename ${nodeType} 「${oldNodeName}」to", "audit_space_node_sort": "Verifica", "audit_space_node_sort_detail": "Verifica", "audit_space_node_update_cover": "Verifica", @@ -757,17 +788,24 @@ "audit_space_rubbish_node_delete_detail": "Verifica", "audit_space_rubbish_node_recover": "Ripristina file", "audit_space_rubbish_node_recover_detail": "Ripristina ${nodeType} 「${currentNodeName}」 dal cestino", + "audit_space_rubbish_node_recover_detail_end": "from the trash", + "audit_space_rubbish_node_recover_detail_start": "Restore ${nodeType}", "audit_space_template_event": "Modifica modello", "audit_space_update_logo": "Verifica", "audit_space_update_logo_detail": "Verifica", "audit_store_share_node": "Salva file condiviso", "audit_store_share_node_detail": "Ripristina ${nodeType} nello spazio, il nome è 「${nodeName}」", + "audit_store_share_node_detail_start": "Restore ${nodeType} to the space, name is", "audit_update_field_role": "Verifica", "audit_update_field_role_detail": "Verifica", "audit_update_node_role": "Modifica autorizzazione file", "audit_update_node_role_detail": "Modifica l'autorizzazione file , modifica il ruolo di「${unitNames}」 in「${role}」di 「${currentNodeName}」", + "audit_update_node_role_detail_end": "to「${role}」role", + "audit_update_node_role_detail_start": "Modify file node permission,modify「${unitNames}」from", "audit_update_node_share_setting": "Modifica le impostazioni del collegamento pubblico del file", "audit_update_node_share_setting_detail": "Modifica il collegamento pubblico ${nodeType} 「${currentNodeName}」", + "audit_update_node_share_setting_detail_end": "public link settings", + "audit_update_node_share_setting_detail_start": "Modify ${nodeType}", "audit_user_login": "Accesso utente", "audit_user_login_detail": "Verifica", "audit_user_logout": "Accesso utente", @@ -809,6 +847,7 @@ "automation_enabled_return_via_related_files": "L'automazione è abilitata. Inserisci nuovamente la tabella originale tramite \"File correlati\" per utilizzare il nuovo pulsante.", "automation_field": "Campo", "automation_import_variables_from_pre_tep": "Ottieni i dati dal passaggio preliminare", + "automation_is_not_yet_enabled": "L'automazione non è ancora abilitata, abilitala e riprova", "automation_last_edited_by": "Ultima modifica di", "automation_last_edited_time": "Ora dell'ultima modifica", "automation_manager_label": "Può eseguire tutte le azioni sull'automazione", @@ -834,6 +873,7 @@ "automation_runs_this_month": "Esce questo mese", "automation_stay_tuned": "Rimani sintonizzato", "automation_success": "Successo", + "automation_tips": "Il campo del pulsante non è configurato correttamente, controlla e riprova", "automation_updater_label": "Può visualizzare la cronologia di esecuzione dell'automazione", "automation_variabel_empty": "Non ci sono dati che possano essere utilizzati nel passaggio preliminare, modificali e riprova.", "automation_variable_datasheet": "Ottieni dati da ${NODE_NAME}", @@ -869,6 +909,7 @@ "bermuda": "Bermude", "bhutan": "Bhutan", "billing_over_limit_tip_common": "L'utilizzo dello spazio ha superato il limite e potrai usufruire di un importo maggiore dopo l'aggiornamento.", + "billing_over_limit_tip_forbidden": "La durata della prova o il periodo di abbonamento sono scaduti. Si prega di contattare il consulente di vendita per rinnovare.", "billing_over_limit_tip_widget": "Il numero di installazioni di widget ha superato il limite ed è possibile eseguire l'aggiornamento per ottenere un utilizzo maggiore.", "billing_period": "Periodo di fatturazione: ${period}", "billing_subscription_warning": "Esperienza caratteristica", @@ -928,10 +969,19 @@ "button_text": "Testo del pulsante", "button_text_click_start": "Fare clic per iniziare", "button_type": "Tipo di pulsante", + "by_at": "A", + "by_days": "Giorni", + "by_every": "ogni", "by_field_id": "Usa ID campo", + "by_hours": "Ore", + "by_in": "A", + "by_min": "minuti)", + "by_months": "Mesi", + "by_on": "sul", "by_the_day": "Di giorno", "by_the_month": "Mensile", "by_the_year": "Annuale", + "by_weeks": "Settimane", "calendar_add_date_time_field": "Crea campo data", "calendar_color_more": "Altri colori", "calendar_const_detail_weeks": "[\"lunedì\",\"martedì\",\"mercoledì\",\"giovedì\",\"venerdì\",\"sabato\",\"domenica\"]", @@ -995,6 +1045,14 @@ "cannot_activate_space_by_space_limit": "cannot_active_space_by_space_limit", "cannot_join_space": "Non puoi unirti a una nuova stazione spaziale perché hai superato la quota massima di 10 stazioni spaziali.", "cannot_switch_field_permission": "Impostare le autorizzazioni dei campi non superiori alle autorizzazioni dei file.", + "capacity_file_detail_desc": "The total number of file nodes within the Space is calculated by adding the file nodes from the Team to the file nodes created by each member in their Private. Not enough capacity?", + "capacity_file_detail_title": "File Capacity", + "capacity_file_member": "Member", + "capacity_file_member_private_node_count": "Private", + "capacity_file_member_private_percent": "Percent", + "capacity_file_member_team": "Team", + "capacity_file_member_team_node_count": "Team", + "capacity_file_upgrade": "Click to upgrade your Space", "capacity_from_official_gift": "Dal regalo ufficiale", "capacity_from_participation": "Su invito ${user} unisciti allo spazio", "capacity_from_purchase": "Per capacità d'acquisto", @@ -1031,6 +1089,8 @@ "catalog": "Esploratore", "catalog_add_from_template_btn_title": "Aggiungi dai modelli", "catalog_empty_tips": "Questo spazio di lavoro è vuoto ora. Inizia utilizzando modelli per creare file.", + "catalog_private": "Private", + "catalog_team": "Team", "category_blank": "[Vuoto]", "catering": "Ristorazione", "cayman_islands": "Isole Cayman", @@ -1099,6 +1159,7 @@ "choose_type_of_vika_field": "Seleziona tipo di campo", "choose_your_own_space": "(Supporta solo il salvataggio al proprio spazio come creatore)", "chose_new_primary_admin_button": "Assegna", + "chunk_stopping_title": "Stopping", "claim_special_offer": "Richiedi questa offerta speciale!", "clear": "Cancella", "clear_all_fields": "Cancella tutto", @@ -1229,6 +1290,7 @@ "confirm_del_current_team": "Sei sicuro di voler eliminare il team?", "confirm_delete": "Conferma ed elimina", "confirm_delete_node_name_as": "Sei sicuro di voler eliminare \"${nodeNameDiv}\"?", + "confirm_delete_private_node_name_as": "Are you sure you want to delete \"${nodeNameDiv}\"? The file will be deleted from the Space and the trash.", "confirm_delete_space_btn": "Conferma ed elimina spazio", "confirm_exit": "Conferma di uscire", "confirm_exit_space_with_name": "Conferma se uscire dallo spazio \"${spaceNameDiv}\".", @@ -1266,6 +1328,14 @@ "convert": "Converti", "convert_tip": "Questa azione può cancellare i dati in alcune celle. È possibile annullare l'azione se accade qualcosa di inaspettato.", "cook_islands": "Isole Cook", + "copilot_auto_agent_desc": "Non sai quale scegliere Agente? Prova l'agente automatico.", + "copilot_auto_agent_name": "Agente automatico", + "copilot_data_agent_desc": "Genera analisi dati/visualizzazioni basate sulle tue visualizzazioni.", + "copilot_data_agent_name": "Agente dati", + "copilot_data_agent_policy": "Quando chatti con Copilot, accetti la politica sui termini dell'utente", + "copilot_data_agent_policy_button": "Politica", + "copilot_help_agent_desc": "Chiedi qualsiasi cosa riguardo ai documenti del centro assistenza di AITable.", + "copilot_help_agent_name": "Recupera Centro assistenza", "copy": "Copia", "copy_automation_url": "Copia URL", "copy_card_link": "Copia URL del record", @@ -1310,6 +1380,7 @@ "create_mirror_guide_content": "La funzione mirror ha la capacità di nascondere determinati dati. È possibile impostare \"condizioni di filtro\" e \"campi nascosti\" nella visualizzazione del foglio dati originale per controllare quali record e campi vengono visualizzati nel mirror.\n
\n
\nSe utilizzato insieme alla funzione \"Visualizza blocco\", può impedire ad altri di apportare modifiche.\n
\n
\nInoltre, puoi andare su \"Tabella originale>Campi nascosti\" per modificare la configurazione per \"Mostra tutti i campi nei mirror\".", "create_mirror_guide_title": "Specchio nasconde alcuni record e campi", "create_new_button_field": "Crea un nuovo campo colonna pulsante", + "create_private_node_tip": "Personal or temporary draft documents can be created here ${link}", "create_public_invitation_link": "Crea link di invito pubblico", "create_space_sub_title": "Ciao, si prega di dare un nome al vostro spazio~", "create_team_fail": "Crea team fallito", @@ -1373,10 +1444,12 @@ "custom_enterprise": "Personalizza lo spazio aziendale per te", "custom_function_development": "Sviluppo di funzionalità personalizzate", "custom_grade_desc": "Fornisce distribuzione di agenti, installazione privata, supporto di assistenza e servizi professionali personalizzati", + "custom_page_setting_title": "Add a custom page", "custom_picture": "Immagine personalizzata", "custom_style": "Stile", "custom_upload": "Caricamento personalizzato", "custom_upload_tip": "Un'immagine di dimensione quadrata 1:1 è consigliata per una migliore esperienza visiva", + "custome_page_title": "Custom Web", "cut_cell_data": "Celle tagliate", "cyprus": "Cipro", "czech": "Ceco", @@ -1428,6 +1501,7 @@ "default": "Predefinito", "default_create_ai_chat_bot": "Nuovo agente AI", "default_create_automation": "Nuova automazione", + "default_create_custom_page": "Nuova pagina personalizzata", "default_create_dashboard": "Nuovo cruscotto", "default_create_datasheet": "Nuovo foglio dati", "default_create_file": "Nuovo file", @@ -1449,6 +1523,7 @@ "del_invitation_link": "Elimina link di invito", "del_invitation_link_desc": "Il link non sarà valido dopo la cancellazione", "del_space_now": "Elimina spazio per sempre", + "del_space_now_confirm_tip": "For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "del_space_now_tip": "Lo spazio non può essere ripristinato dopo la cancellazione. Tutti i file e gli allegati verranno eliminati.", "del_space_res_tip": "Lo spazio eliminato", "del_team_success": "Elimina team di successo", @@ -1644,6 +1719,62 @@ "embed_error_page_help": "Per saperne di più", "embed_fail_og_description_content": "Il link pubblico per questa incorporazione è stato disabilitato ed è temporaneamente non disponibile", "embed_failed": "Il collegamento incorporato non è disponibile,", + "embed_link_bilibili": "bilibili", + "embed_link_bilibili_desc": "Incorporando i video bilibili, puoi guardare tutorial e guide o visualizzare la home page del canale in Vika.", + "embed_link_bilibili_link_text": "Come incorporare il video bilibili", + "embed_link_bilibili_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-bilibili-video", + "embed_link_default": "Nulla", + "embed_link_default_desc": "Incolla un collegamento per visualizzare qualsiasi sito web.", + "embed_link_default_link_text": "Saperne di più", + "embed_link_default_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_link_figma": "Figma", + "embed_link_figma_desc": "Incorporando i file Figma, i membri possono visualizzare e modificare le bozze di progettazione in modo più conveniente, migliorando l'efficienza della collaborazione.", + "embed_link_figma_link_text": "Come incorporare file Figma", + "embed_link_figma_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-figma-file", + "embed_link_google_docs": "Docs", + "embed_link_google_docs_desc": "Incorporando Google Docs, puoi modificare e visualizzare i documenti in AITable per facilitare la collaborazione del team.", + "embed_link_google_docs_link_text": "Come incorporare Google Documenti", + "embed_link_google_docs_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-docs-file", + "embed_link_google_sheets": "Sheets", + "embed_link_google_sheets_desc": "Incorporando Fogli Google, puoi modificare e visualizzare le tabelle in AITable per facilitare la collaborazione del team.", + "embed_link_google_sheets_link_text": "Come incorporare Fogli Google", + "embed_link_google_sheets_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-sheets-file", + "embed_link_jishi_design": "JSdesign", + "embed_link_jishi_design_desc": "Incorporando file JSdesign, i membri possono visualizzare e modificare le bozze di progettazione in modo più pratico, migliorando l'efficienza della collaborazione.", + "embed_link_jishi_design_link_text": "Come incorporare file JSdesign", + "embed_link_jishi_design_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-js-design-file", + "embed_link_tencent_docs": "Documenti Tencent", + "embed_link_tencent_docs_desc": "Incorporando Tencent Docs, puoi modificare e visualizzare i documenti Tencent in Vika per migliorare l'efficienza della collaborazione.", + "embed_link_tencent_docs_link_text": "Come incorporare Tencent Docs", + "embed_link_tencent_docs_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-tencent-docs", + "embed_link_wps": "WPS", + "embed_link_wps_desc": "Incorporando file WPS, puoi modificare e visualizzare documenti, tabelle e moduli WPS in Vika per migliorare l'efficienza della collaborazione.", + "embed_link_wps_link_text": "Come incorporare file WPS", + "embed_link_wps_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-wps-file", + "embed_link_youtube": "Youtube", + "embed_link_youtube_desc": "Incorporando video di YouTube, puoi guardare tutorial e guide o visualizzare la home page del canale in AITable.", + "embed_link_youtube_link_text": "Come incorporare video di YouTube", + "embed_link_youtube_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-youtube-video", + "embed_page": "Pagina personalizzata", + "embed_page_add_url": "Aggiungi URL", + "embed_page_doc_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_page_function_desc": "Aggiungi pagine web in ${edition} per accedere facilmente a documenti, video e altro ancora di siti web di terze parti. È possibile aggiungere collegamenti a siti Web consigliati o collegamenti personalizzati.", + "embed_page_node_permission_editor": "Sulla base del \"solo aggiornamento\", è possibile anche aprire la condivisione pubblica del file", + "embed_page_node_permission_manager": "Può eseguire tutte le azioni sul file", + "embed_page_node_permission_reader": "Può visualizzare il contenuto della pagina personalizzata e le informazioni di base sul file", + "embed_page_node_permission_updater": "Sulla base della \"sola lettura\", è possibile anche modificare il collegamento della pagina personalizzata", + "embed_page_setting_title": "Aggiungi una pagina personalizzata", + "embed_page_url_invalid": "Inserisci l'URL corretto", + "embed_paste_link_bilibili_placeholder": "Incolla il collegamento del video bilibili", + "embed_paste_link_default_placeholder": "Incolla l'URL", + "embed_paste_link_figma_placeholder": "Incolla il collegamento di condivisione del file Figma", + "embed_paste_link_google_docs_placeholder": "Incolla il link di condivisione di Google Documenti", + "embed_paste_link_google_sheets_placeholder": "Incolla il link di condivisione di Fogli Google", + "embed_paste_link_jsdesign_placeholder": "Incolla il collegamento di condivisione del file JSdesign", + "embed_paste_link_tencent_docs_placeholder": "Incolla il collegamento di condivisione di Tencent Docs", + "embed_paste_link_wps_placeholder": "Incolla il collegamento di condivisione del file WPS", + "embed_paste_link_youtube_placeholder": "Incolla il collegamento del video di YouTube", + "embed_success": "Aggiungi con successo", "emoji_activity": "Attività", "emoji_custom": "Personalizzato", "emoji_flags": "Bandiere", @@ -1750,6 +1881,11 @@ "estonia": "Estonia", "ethiopia": "Etiopia", "event_planning": "Pianificazione eventi", + "every": "Ogni", + "every_day_at": "giorno(i) a", + "every_hour_at": "ora/e alle", + "every_month_at": "mese(i) del", + "every_week_at": "Ogni settimana in poi", "everyday_life": "Vita quotidiana", "everyone_visible": "Visibile per tutti", "exact_date": "data esatta", @@ -1760,6 +1896,7 @@ "exchange": "Riscatta", "exchange_code_times_tip": "Nota: Il codice di riscatto può essere utilizzato una sola volta", "exclusive_consultant": "Consulente V+ esclusivo", + "exclusive_limit_plan_desc": "Livello limitato esclusivo", "exist_experience": "Esperienza di uscita", "exits_space": "Esci dallo spazio", "expand": "Espandi", @@ -1786,7 +1923,7 @@ "expired": "Scaduto", "export": "Esportazione...", "export_brand_desc": "Offerto da", - "export_current_preview_view_data": "", + "export_current_preview_view_data": "Export current preview view data", "export_gantt_button_tips": "Esporta in un file .png", "export_gantt_chart": "Esporta il grafico gantt", "export_to_excel": "Esporta dati", @@ -2358,26 +2495,26 @@ "gantt_config_color_help": "Come impostare", "gantt_config_friday": "Venerdì", "gantt_config_friday_in_bar": "Ven", - "gantt_config_friday_in_select": "Ven", + "gantt_config_friday_in_select": "Venerdì", "gantt_config_monday": "Lunedì", "gantt_config_monday_in_bar": "Lun", - "gantt_config_monday_in_select": "Lun", + "gantt_config_monday_in_select": "Lunedi", "gantt_config_only_count_workdays": "La durata conta solo i giorni lavorativi.", "gantt_config_saturday": "Sabato", "gantt_config_saturday_in_bar": "Sab", - "gantt_config_saturday_in_select": "Sab", + "gantt_config_saturday_in_select": "Sabato", "gantt_config_sunday": "Domenica", - "gantt_config_sunday_in_bar": "Sole", - "gantt_config_sunday_in_select": "Sole", + "gantt_config_sunday_in_bar": "Dom", + "gantt_config_sunday_in_select": "Domenica", "gantt_config_thursday": "Giovedì", "gantt_config_thursday_in_bar": "Gio", - "gantt_config_thursday_in_select": "Gio", + "gantt_config_thursday_in_select": "Giovedì", "gantt_config_tuesday": "Martedì", "gantt_config_tuesday_in_bar": "Mar", - "gantt_config_tuesday_in_select": "Mar", + "gantt_config_tuesday_in_select": "Martedì", "gantt_config_wednesday": "Mercoledì", "gantt_config_wednesday_in_bar": "Mer", - "gantt_config_wednesday_in_select": "Mer", + "gantt_config_wednesday_in_select": "Mercoledì", "gantt_config_weekdays_range": "${weekday} a ${weekday}", "gantt_config_workdays_a_week": "Giorni lavorativi standard personalizzati", "gantt_cycle_connection_warning": "Invalid task dependency, there is a cycle connection\n", @@ -2458,6 +2595,7 @@ "gold_grade": "Oro", "gold_grade_desc": "Per team con processi aziendali complessi", "gold_seat_200_desc": "200", + "gold_seat_300_desc": "300", "golden_grade": "Oro", "got_it": "Ho capito", "got_v_coins": "V monete premiate", @@ -2491,6 +2629,8 @@ "guests_per_space": "Ospiti per spazio", "guide_1": "啊这", "guide_2": "Ci vogliono solo pochi minuti per imparare le funzioni di base. Lavora in modo più produttivo da questo momento in poi!", + "guide_flow_modal_contact_sales": "Contatta l'ufficio vendite", + "guide_flow_modal_get_started": "Iniziare", "guide_flow_of_catalog_step1": "Qui è il catalogo di lavoro in cui tutte le cartelle e i file dello spazio sono memorizzati.", "guide_flow_of_catalog_step2": "Nel catalogo di lavoro è possibile creare un foglio dati o una cartella a seconda delle necessità.", "guide_flow_of_click_add_view_step1": "Oltre ad alcune viste di base, si consiglia vivamente di creare una vista album se si dispone di allegati in formato immagine.", @@ -2669,6 +2809,7 @@ "intro_widget_tips": "Cos'è widget?", "introduction": "Introduzione", "invalid_action_sort_tip": "Come campo di raggruppamento, l'ordinamento di esso è stato impostato. L'impostazione dell'ordine corrente non avrà effetto.", + "invalid_automation_configuration": "Configurazione dell'automazione non valida, controlla e riprova", "invalid_field_type": "Tipo di campo non valido", "invalid_option_sort_tip": "Come campo di raggruppamento, l'ordinamento di esso è stato impostato.", "invalid_redemption_code_entered": "Codice di riscatto non valido", @@ -2799,6 +2940,9 @@ "label_format_day_month_and_year_split_by_slash": "Giorno/Mese/Anno", "label_format_month": "Mese", "label_format_month_and_day_split_by_dash": "Mese-Giorno", + "label_format_month_day_year_split_by_dash": "Month-Day-Year", + "label_format_month_day_year_split_by_slash": "Month/Day/Year", + "label_format_month_day_year_two_digit_year_split_by_slash": "Month/Day/Year (Two-digit year)", "label_format_year": "Anno", "label_format_year_and_month_split_by_dash": "Anno-Mese", "label_format_year_month_and_day_split_by_dash": "Anno-Mese-Giorno", @@ -2877,6 +3021,7 @@ "lark_version_enterprise": "Piano d'impresa con Lark", "lark_version_standard": "Piano standard con Lark", "lark_versions_free": "Piano di base con Lark", + "last_day": "Ultimo giorno", "last_modified_by_select_modal_desc": "Se uno dei campi selezionati di seguito viene modificato, il membro che ha modificato di recente verrà visualizzato nell'ultimo campo modificato", "last_modified_time_select_modal_desc": "Se uno dei campi selezionati di seguito viene modificato, l'ora modificata più recente verrà visualizzata nel campo dell'ultima modifica", "last_step": "Indietro", @@ -3021,7 +3166,7 @@ "mail_invite_fail": "La posta invita il successo.", "mail_invite_success": "La posta invita il successo.", "main_admin_name": "Nome amministratore", - "main_admin_page_desc": "L'amministratore ha pieno accesso allo Spazio, ad esempio assegnando sotto-amministratori e trasferendo la proprietà dello Spazio", + "main_admin_page_desc": "L'amministratore ha accesso completo allo spazio, ad esempio alla gestione dei membri e alle impostazioni dello spazio.", "main_contain": "Contenuti principali", "malawi": "Malawi", "malaysia": "Malaysia", @@ -3241,8 +3386,12 @@ "more_widget": "Altri widget", "morocco": "Marocco", "move": "Sposta", + "move_datasheet_link_warn": "Cannot be moved to Team Area alone, because there is a two-way link from the current datasheet to another datasheet, it is recommended to put them in a folder and then move them", "move_favorite_node_fail": "Spostamento nodo fallito. Il sistema aggiornerà automaticamente l'elenco.", + "move_folder_link_warn": "Cannot be moved to Team Area because the files in the current folder are linked to files outside the folder (may be two-way links or linked by forms, etc.) We recommend that they be placed in a folder before moving", "move_node_modal_content": "Dopo lo spostamento, la visibilità del file potrebbe essere influenzata dalla cartella principale.", + "move_other_link_no_permission": "Unable to move to the corresponding folder because you do not have administrative rights to the folder", + "move_other_link_warn": "It is not allowed to move ${node type} to Team Area alone, because it connects to the datasheet of Private Area, it is recommended to put them in a folder before moving them", "move_to": "Sposta a", "move_to_error_equal_parent": "Il file si trova sotto la cartella corrente. Seleziona un'altra cartella", "move_to_modal_title": "Sposta [${name}] in", @@ -3273,7 +3422,9 @@ "new_a_line": "Shift+Invio: linea di interruzione", "new_automation": "Nuova automazione", "new_caledonia": "Nuova Caledonia", + "new_custom_page": "New custom page", "new_datasheet": "Nuovo foglio dati", + "new_ebmed_page": "Nuova pagina personalizzata", "new_folder": "Nuova cartella", "new_folder_btn_title": "Cartella", "new_folder_tooltip": "Crea cartella", @@ -3439,7 +3590,7 @@ "nvc_start_text": "Trascina la barra verso l'estremità destra", "nvc_yes_text": "Verificato", "obtain_verification_code": "Codice di verifica non ottenuto o scaduto", - "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrzw0miJVmSkJ7eBBa9k/fomx5qPX0JGPFvfEEP\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", + "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrCvbFC53xc3kl00B4Pg\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", "offical_website_nav_data": "[{\n \"name\": \"产品\",\n \"href\": \"/login\",\n \"children\": [\n {\n \"name\": \"vika维格表 Overview\",\n \"href\": \"/login/\"\n },\n {\n \"name\": \"应用连接 Integration\",\n \"href\": \"/connections/\"\n },\n {\n \"name\": \"客户端(Beta) Download\",\n \"href\": \"/download/\"\n }\n ]\n}, {\n \"name\": \"解决方案\",\n \"href\": \"/\",\n \"children\": [{\n \"name\": \"PMO项目群管理\",\n \"href\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"href\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"href\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"href\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"href\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"href\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"href\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"href\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"href\": \"/shop/\"\n }, {\n \"name\": \"更多解决方案 >\",\n \"href\": \"/solutions/\"\n }]\n}, {\n \"name\": \"模板/案例\",\n \"href\": \"/template\",\n \"children\": [\n {\n \"name\": \"模板中心 Tempaltes\",\n \"href\": \"/template\"\n },\n {\n \"name\": \"客户案例 Customers\",\n \"href\": \"/cases/\"\n }\n ]\n},\n {\n \"name\": \"首页\",\n \"href\": \"/?home=1\"\n },\n {\n \"name\": \"学习资源\",\n \"href\": \"https://edu.vika.cn/index\",\n \"children\": [\n {\n \"name\": \"快速入门 Tutorials\",\n \"href\": \"https://help.vika.cn/docs/guide/tutorial\"\n },\n {\n \"name\": \"产品手册 Manual\",\n \"href\": \"https://help.vika.cn/docs/guide/manual\"\n },\n {\n \"name\": \"维格课堂 Vika Education\",\n \"href\": \"https://edu.vika.cn/\"\n },\n {\n \"name\": \"维格社区 Vika BBS\",\n \"href\": \"https://bbs.vika.cn/\"\n },\n {\n \"name\": \"第三方连接 Integration\",\n \"href\": \"https://help.vika.cn/docs/guide/connection\"\n },\n {\n \"name\": \"开发者中心 Developer Center\",\n \"href\": \"/developers/\"\n },\n {\n \"name\": \"常见问题 FAQ\",\n \"href\": \"https://help.vika.cn/docs/guide/questions\"\n }\n ]\n }]", "office_preview": "Anteprima file di Office", "office_preview_app_desc": "

Smooth online preview of office files on datasheet, allowing you to view common office files such as Excel, Word, PPT, etc. on your desktop or mobile anywhere, anytime

\n\n
    \n
  • Online preview of .doc, .docx, .xls, .xlsx, .ppt, .pptx, and .pdf formatted office files
  • \n
  • Desktop and mobile both support file previews of the above formats
  • \n
\n\n

Additional notes:

\n
    \n
  • This feature is powered by \"Yoncentric Cloud Conversion\" and officially integrated
  • \n
  • Click the \"Enable\" button below to enable this integration and agree that \"Yoncentric Cloud Conversion\" reads the office files you want to preview
  • \n
  • If you no longer need the office files preview feature, the space admin can disable it on this page
  • \n
", @@ -3479,6 +3630,7 @@ "open_auto_save_success": "La vista Salvataggio automatico è attivata correttamente", "open_auto_save_warn_content": "Tutte le modifiche in questa visualizzazione vengono salvate e sincronizzate automaticamente con gli altri membri.", "open_auto_save_warn_title": "Attiva la vista salvataggio automatico", + "open_automation_time_arrival": "https://aitable.ai/contact-sales-open-source", "open_failed": "Apertura non riuscita", "open_in_new_tab": "aprire in una nuova scheda", "open_invite_after_operate": "Una volta attivato, tutti i membri possono invitare nuovi membri dal pannello contatti", @@ -3625,6 +3777,8 @@ "payment_record": "Registrazione dei pagamenti", "payment_reminder": "Promemoria di pagamento", "payment_reminder_content": "Il nuovo piano che hai selezionato è più deducibile dell'importo da pagare. Si consiglia di scegliere il nuovo piano con una durata maggiore. Se confermi di farlo, l'importo in eccesso non sarà rimborsabile. ${action} in caso di dubbio", + "payment_reminder_modal_content": "Puoi provare la versione avanzata per usufruire di più nodi di file, autorizzazioni aziendali, capacità di allegati, volume di dati, intelligenza artificiale e altre funzionalità e privilegi avanzati.", + "payment_reminder_modal_title": "Attualmente stai utilizzando la versione gratuita", "pending_invite": "Invito in attesa", "people": "membro(i)", "per_person_per_year": "Per persona all'anno", @@ -3794,7 +3948,7 @@ "player_step_ui_config_168": "{\n\"templateKey\":\"createMirrorTip\"\n}", "player_step_ui_config_169": "{ \"headerImg\": \"https://s4.vika.cn/space/2023/04/04/bcf0695cf35840e6b85e032a8e5ea0a1\", \"readMoreUrl\": \"https://help.vika.cn/changelog/23-04-10- aggiornamenti\", \"bambini\": \"

🚀 Introduzione di nuove funzionalità

\\N
  • Viene lanciato il nuovo tipo di campo \"Cascader\", rendendo più semplice la selezione da una gerarchia di opzioni sui moduli
  • Viene rilasciato il widget \"Script\", meno codice per una maggiore personalizzazione
  • Attiva l'automazione per inviare e-mail e ricevere notifiche rapide
  • Attiva l'automazione per inviare un messaggio a Slack e informare il tuo team in tempo
  • Esplorando l'intelligenza artificiale: rilasciato il widget \"Generatore di contenuti GPT\".
\" }", "player_step_ui_config_17": "{\n \"element\": \"#TEMPLATE_CENTER_USE_TEMPLATE_BTN>button\", \n\"placement\": \"rightBottom\",\n\"offsetY\": 20,\n \"title\": \"How to use a template\", \n\"description\": \"Click the button on the left to use the template\", \"children\":\"\" \n}", - "player_step_ui_config_176": "{\"title\":\"Introduzione agente AI\",\"video\":\"https://www.youtube.com/embed/cjds1r_roG8?si=irKUpMhwDlOEb8Hc\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", + "player_step_ui_config_176": "{\"title\":\"AITable.ai DEMO\",\"video\":\"https://www.youtube.com/embed/kGxMyEEo3OU\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", "player_step_ui_config_18": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select>.ant-select-selector\", \n\"placement\": \"bottomLeft\",\n \"title\": \"How to use a template\", \n\"description\": \"Select where to put the template\", \"children\":\"\" \n}", "player_step_ui_config_19": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select .ant-select-selector\"\n}", "player_step_ui_config_2": "{\n \"config\": [\n {\n \"key\": 1,\n \"name\": \"answer1\",\n \"title\": \"What kind of issues are you looking forward to solved by vikadata?\",\n \"type\": \"checkbox\",\n \"answers\": [\n \"Work Planning\",\n \"Customer Service\",\n \"Project Management\",\n \"Sourcing Supply\",\n \"Content Production\",\n \"E-commerce operation\",\n \"Event Planning\",\n \"Human Resources\",\n \"Administration\",\n \"Financial Management\",\n \"Webcast\",\n \"Educational institutes Management\",\n \"Other\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 2,\n \"name\": \"answer2\",\n \"title\": \"Your job title is______\",\n \"type\": \"radio\",\n \"answers\": [\n \"General manager \",\n \"Project manager\",\n \"Product manager\",\n \"Designer\",\n \"R&D engineer\",\n \"Operator, editor\",\n \"Sales, customer service\",\n \"Human resource, administration \",\n \"Finance, accountant\",\n \"Lawyer, legal affairs\",\n \"Marketing\",\n \"Teacher\",\n \"Student\",\n \"Other\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 3,\n \"name\": \"answer3\",\n \"title\": \"What is the name of your company?\",\n \"type\": \"input\",\n \"submit\": false\n },\n {\n \"key\": 4,\n \"name\": \"answer4\",\n \"title\": \"Please leave your email address/ phone number/ Wechat account below so we can reach you in time when you need help.\",\n \"type\": \"input\",\n \"submit\": true\n },\n {\n \"key\": 5,\n \"title\": \"Thank you for filling out the form, you can add our customer service in case of need\",\n \"platform\": {\n \"website\": \"https://s4.vika.cn/space/2023/03/02/b34e3205a9154463be16f497524f1327\",\n \"dingtalk\": \"https://s4.vika.cn/space/2023/03/02/4b16cef6602a4586a21d6346bf25d300\",\n \"wecom\": \"https://s4.vika.cn/space/2023/03/02/60119b1b69b64aa887bd1be6a2928bec\",\n \"feishu\": \"https://u.vika.cn/z9ygm\"\n },\n \"type\": \"contactUs\",\n \"next\": true\n }\n ]\n}\n", @@ -3824,13 +3978,13 @@ "player_step_ui_config_41": "", "player_step_ui_config_42": "{\n \"element\": \"#DATASHEET_FORM_LIST_PANEL\", \n\"placement\": \"leftTop\",\n \"title\": \"Form\", \n\"description\": \"You can quickly create a form from the current view. The number and order of the fields in the form is consistent with the view.\", \"children\":\"\" \n}", "player_step_ui_config_43": "{\n \"element\": \".style_navigation__1U5cR .style_help__1sXEA\", \n\"placement\": \"rightBottom\",\n \"title\": \"Tip\", \n\"offsetY\":5,\n\"description\": \"You can find your Vikaby assistant from the \"Help\" icon on the left\", \"children\":\"\" \n}", - "player_step_ui_config_44": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", + "player_step_ui_config_44": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", "player_step_ui_config_45": "", "player_step_ui_config_46": "", "player_step_ui_config_47": "{\n \"element\": \"#DATASHEET_WIDGET_BTN\",\n\"placement\": \"bottomRight\",\n \"title\": \"Widget\", \n\"description\": \"Want to use and view your data in a richer way? Try the widget!\", \"children\":\"\" \n}", "player_step_ui_config_48": "", "player_step_ui_config_49": "{\n \"element\": \".style_widgetPanelContainer__1l2ZV\",\n\"placement\": \"leftCenter\",\n \"title\": \"What is a widget\", \n\"description\": \"Vika widgets are an extended application of vikadata that features in richer data visualization, data transfer, data cleansing, and more. By installing widgets in the widget board, you can make work a lot easier.\", \"children\":\"\" \n}", - "player_step_ui_config_5": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", + "player_step_ui_config_5": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", "player_step_ui_config_50": "{\n \"element\": \".style_widgetModal__eXmdB\",\n\"placement\": \"leftTop\",\n \"title\": \"Widget Center\", \n\"description\": \"Officially recommended and custom widgets are published here. You can install any widget you want onto a dashboard or into a widget board of any datasheet.\", \"children\":\"\" \n}", "player_step_ui_config_51": "{\n \"element\": \".style_widgetModal__eXmdB .style_widgetItem__3Pl-1 button\",\n\"placement\": \"rightBottom\",\n \"title\": \"Install widget\", \n\"description\": \"Let's install this \"Chart\" widget\", \"children\":\"\" \n}", "player_step_ui_config_52": "", @@ -3927,6 +4081,7 @@ "preview_guide_click_to_restart": "Premere il pulsante qui sotto per visualizzare nuovamente l'anteprima", "preview_guide_enable_it": "Premere il pulsante qui sotto per attivare questa funzione", "preview_guide_open_office_preview": "Per visualizzare l'anteprima di questo file, attivare la funzione \"anteprima ufficio\"", + "preview_next_automation_execution_time": "Anteprima dei prossimi 10 tempi di esecuzione", "preview_not_support_video_codecs": "Solo i video MP4 con codec video H.264 possono essere visualizzati in anteprima", "preview_revision": "Anteprima", "preview_see_more": "Vuoi saperne di più sulla funzione \"anteprima file di ufficio\"? Clicca qui", @@ -3962,6 +4117,7 @@ "privacy_protection": "\"Tutela della privacy\"", "private_cloud": "Cloud privato", "private_external_person_only": "Solo persona esterna", + "private_help_link": "https://help.aitable.ai/docs/guide/team-and-private-area#private-area", "private_internal_person_only": "Solo persona interna", "private_product_point": "Gestisci la tua piattaforma APITable con un clic", "privatized_deployment": "Self-ospitato", @@ -4032,13 +4188,15 @@ "reconciled_data": "I dati vengono riconciliati", "record": "Registra", "record_activity_experience_tips": "Puoi visualizzare l'attività registrata di ${day} giorni", + "record_archived_data": "registrazione archiviata", + "record_chunk_text": "${text} rows, please wait", "record_comment": "Solo osservazioni", "record_comments": "commenti", "record_fail_data": "errore dei dati", "record_filter_tips": "Questo record è stato filtrato", "record_functions": "Funzione di registrazione", "record_history": "Solo cronologia delle revisioni", - "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-history", + "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-activity", "record_history_title": "Cronologia record", "record_pre_filtered": "Questo record è stato filtrato e verrà nascosto una volta cliccato fuori dal record", "record_pre_move": "Questo record verrà spostato altrove una volta cliccato fuori dal record", @@ -4478,6 +4636,12 @@ "scan_to_login": "Scansiona per accedere", "scan_to_login_by_method": "Scansiona ${method} per seguire l'account ufficiale per accedere", "scatter_chart": "Grafico a dispersione", + "schedule_day_tips": "Il calcolo del ciclo inizia a contare dal primo giorno di ogni mese. Se assumiamo che si ripeta ogni 10 giorni, verrà attivato il 1, 11, 21 e 31 di ogni mese", + "schedule_hour_tips": "Il calcolo del ciclo inizia ogni giorno a mezzanotte (0:00). Supponendo che si ripeta 0 minuti ogni tre ore, avverrà a mezzanotte (0:00), 3:00, 6:00, 9:00, mezzogiorno (12:00), 15:00, 18:00 e infine al calare della notte (21:00) tutti i giorni", + "schedule_start_day": "A partire dal 1° giorno del mese, ogni", + "schedule_start_month": "A partire da gennaio di ogni anno, ogni", + "schedule_type": "Tipo di pianificazione", + "schedule_year_tips": "Il calcolo del ciclo inizia a contare dal primo mese di ogni anno. Supponendo un intervallo di primo giorno e 3 mesi, i trigger verranno attivati alla mezzanotte del primo giorno di gennaio, aprile, luglio e ottobre di ogni anno.", "science_and_technology": "Scienza e tecnologia", "scroll_screen_down": "Scorri uno schermo verso il basso", "scroll_screen_left": "Scorri uno schermo a sinistra", @@ -4491,6 +4655,7 @@ "search_folder_or_sheet": "Cerca file", "search_new_admin": "Cerca", "search_node_pleaseholder": "Cerca file (${shortcutKey})", + "search_node_tip": "Ricerca rapida (${shortcutKey})", "search_or_add": "Trova o aggiungi un'opzione", "search_role_placeholder": "Ricerca ruoli", "seats": "Sedili", @@ -4894,6 +5059,7 @@ "space_info": "Panoramica", "space_info_del_confirm1": "1. Eliminando questo spazio verranno eliminati i seguenti dati:", "space_info_del_confirm2": "2. Lo spazio verrà cancellato completamente dopo 7 giorni. Puoi ripristinare lo Spazio prima di allora.", + "space_info_del_confirm3": "3. For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "space_info_feishu_desc": "Stai utilizzando un'integrazione di terze parti. Per eliminare lo spazio, disattivare prima l'integrazione di terze parti.", "space_info_feishu_label": "Integrazioni", "space_join_apply": " ha richiesto di unirsi allo spazio \"\".", @@ -4980,6 +5146,7 @@ "start_onfiguration": "Avvia configurazione", "start_time": "Ora di inizio", "start_use": "Inizia a usare", + "starting_from_midnight": "A partire da mezzanotte (00:00) tutti i giorni, ogni", "startup": "Avvio", "startup_company_support_program": "Programma di supporto all'avvio", "stat_average": "Media", @@ -5013,6 +5180,8 @@ "stay_tuned_for_more_features": "Rimani sintonizzato per ulteriori funzionalità", "steps_choose_reset_mode": "Seleziona un metodo di ripristino", "steps_validate_identities": "Verifica identità", + "stop_chunk_content": "Are you sure you want to stop the operation?", + "stop_chunk_title": "Stop", "stop_dingtalk_h5_modal_content": "L'applicazione autocostruita sarà svincolata da questo spazio. Si prega di confermare .", "storage_per_seats": "", "storage_per_space": "Uso dello storage", @@ -5043,9 +5212,11 @@ "subscribe_credit_usage_over_limit": "Il numero di crediti nello spazio corrente supera il limite, si prega di aggiornare il vostro abbonamento.\n", "subscribe_demonstrate": "Richiedi demo", "subscribe_disabled_seat": "Il numero di persone non può essere inferiore al programma originale", + "subscribe_grade_business": "Attività commerciale", "subscribe_grade_free": "Gratis", "subscribe_grade_plus": "Più", "subscribe_grade_pro": "Pro", + "subscribe_grade_starter": "Antipasto", "subscribe_label_tooltip": "Caratteristiche avanzate dello spazio", "subscribe_new_choose_member": "Supporta fino a ${member_num} membri", "subscribe_new_choose_member_tips": "Questo piano supporta 1~${member_num} membri per entrare nello spazio", @@ -5182,7 +5353,7 @@ "template_name_repetition_title": "\"${templateName}\" esiste già. Vuoi sostituirlo?", "template_no_template": "Nessun modello", "template_not_found": "Non riesci a trovare i modelli che desideri? Dicci", - "template_recommend_title": "Caldo", + "template_recommend_title": "🌟 Hot", "template_type": "Modello", "terms_of_service": "", "terms_of_service_pure_string": "Condizioni di servizio", @@ -5226,6 +5397,7 @@ "text_editor_tip_end": "\"Invio\" per terminare la modifica", "text_functions": "Funzione stringa", "thailand": "Thailandia", + "the_button_field_is_misconfigured": "Il campo del pulsante non è configurato correttamente, controlla e riprova", "the_current_automation_workflow_has_no_related_files_you_can_establish_a_link_by_adding_trigger_conditions_and_actions_on_the_left_side": "Il flusso di lavoro di automazione corrente non ha file correlati. È possibile stabilire un collegamento aggiungendo le condizioni di innesco e le azioni sul lato sinistro", "the_current_button_column_has_expired_please_reselect": "La colonna del pulsante corrente è scaduta, seleziona nuovamente", "the_last_7_days": "negli ultimi 7 giorni", @@ -5278,7 +5450,7 @@ "time_machine_action_title": "Storia delle operazioni", "time_machine_unlimited": "Storia illimitata delle macchine del tempo", "time_zone_inconsistent_tips": "Quando i fusi orari sono incoerenti, il fuso orario dell'ora di inizio verrà utilizzato per impostazione predefinita", - "timemachine_add": "Aggiunto ${nome}", + "timemachine_add": "Aggiunto ${name}", "timemachine_add_field": "aggiunte colonne ${name}", "timemachine_add_record": "aggiunte ${count} righe di record", "timemachine_add_widget": "aggiunto un nuovo widget", @@ -5328,6 +5500,7 @@ "timemachine_update_comment": "commenti aggiornati", "times_per_month_unit": "invito/mese", "times_unit": "call(s)", + "timing_rules": "Tempistica", "timor_leste": "Timor-Est", "tip_del_success": "Puoi ripristinare il tuo spazio entro 7 giorni", "tip_do_you_want_to_know_about_field_permission": "Vuoi crittografare i dati del campo? Informazioni sulle autorizzazioni dei campi", @@ -5515,6 +5688,7 @@ "verify_account_title": "Verifica account", "verify_via_email": "Verifica dell'identità via e-mail", "verify_via_phone": "Verifica dell'identità tramite SMS", + "video": "video", "video_not_support_play": "Il formato video corrente non supporta la riproduzione online", "vietnam": "Vietnam", "view": "Visualizza", @@ -5863,7 +6037,8 @@ "workdoc_color_title": "Colore del carattere", "workdoc_create": "Crea documento di lavoro", "workdoc_expanded": "Espandi il sommario", - "workdoc_image_max_10mb": "La dimensione dell'immagine non può superare i 10 MB", + "workdoc_image_max_10mb": "nullo", + "workdoc_image_max_size": "La dimensione dell'immagine non può superare ${size}", "workdoc_info": "Informazioni", "workdoc_info_create_time": "Creato a", "workdoc_info_creator": "Creato da", @@ -5871,6 +6046,7 @@ "workdoc_info_last_modify_time": "Ultima modifica a", "workdoc_link_placeholder": "Inserisci il collegamento", "workdoc_only_image": "È consentita solo l'immagine", + "workdoc_only_video": "È consentito solo il video", "workdoc_text_placeholder": "Immettere \"/\" avvio rapido", "workdoc_title_placeholder": "Inserisci il titolo", "workdoc_unnamed": "Documento di lavoro senza nome", @@ -5879,9 +6055,11 @@ "workdoc_unsave_ok": "Non salvare le modifiche", "workdoc_unsave_title": "Il WorkDoc non è stato salvato", "workdoc_upload_failed": "Caricamento fallito", + "workdoc_video_max_size": "La dimensione del video non può superare ${size}", "workdoc_ws_connected": "Collegato", "workdoc_ws_connecting": "Collegamento...", "workdoc_ws_disconnected": "Disconnesso", + "workdoc_ws_reconnecting": "Riconnessione...", "workflow_execute_failed_notify": " impossibile eseguire a . Consulta la cronologia delle esecuzioni per risolvere il problema. Se hai bisogno di assistenza, contatta il nostro team di assistenza clienti.", "workspace_data": "Dati spaziali", "workspace_files": "Dati sul banco di lavoro", diff --git a/packages/datasheet/public/file/langs/strings.ja-JP.json b/packages/datasheet/public/file/langs/strings.ja-JP.json index 833d0cd7e1..8b01dee40b 100644 --- a/packages/datasheet/public/file/langs/strings.ja-JP.json +++ b/packages/datasheet/public/file/langs/strings.ja-JP.json @@ -146,6 +146,15 @@ "agreed": "承認済み", "ai_advanced_mode_desc": "高度なモデルは,ユーザが提示をカスタマイズすることを可能にし,AIエージェントの行動や応答をより良く制御する.", "ai_advanced_mode_title": "拡張モード", + "ai_agent_anonymous": "匿名${ID}", + "ai_agent_conversation_continue_not_supported": "以前の会話の継続は現在サポートされていません", + "ai_agent_conversation_list": "会話リスト", + "ai_agent_conversation_log": "会話ログ", + "ai_agent_conversation_title": "会話のタイトル", + "ai_agent_feedback": "フィードバック", + "ai_agent_historical_message": "上記は歴史的なメッセージです", + "ai_agent_history": "歴史", + "ai_agent_message_consumed": "消費されたメッセージ", "ai_api_curl_template": "## Create chat completions\n\n```bash\n\ncurl -X POST \"{{apiBase}}/fusion/v1/ai/{{aiId}}/chat/completions\" \\n -H \"Content-Type: application/json\" \\n -H \"Authorization: Bearer {{token}}\" \\n -d '{\n \"model\": \"gpt-3.5-turbo\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"You are a helpful assistant.\"\n },\n {\n \"role\": \"user\",\n \"content\": \"Hello!\"\n }\n ]\n }'\n\n```\n\n## Returned data example\n\n```json\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", "ai_api_footer_desc": "AIエージェントをあなたのサイトに埋め込みますか?もっと知っている", "ai_api_javascript_template": "## Initialize SDK [![github]({{ githubIcon }})](https://github.com/openai/openai-node)\nAITable's chat completion API is compatible with OpenAI's Node.js SDK. You can use our service with the same SDK by simply changing the configuration as follows:\n\n\n```javascript\nconst { Configuration, OpenAIApi } = require(\"openai\");\nconst configuration = new Configuration({\n apiKey: \"{{token}}\",\n basePath: \"{{apiBase}}/fusion/v1/ai/{{aiId}}\"\n});\n```\n\n## Create chat completions\n\n```javascript\nconst openai = new OpenAIApi(configuration);\nconst chatCompletion = await openai.createChatCompletion({\n model: \"gpt-3.5-turbo\",\n messages: [{role: \"user\", content: \"Hello world\"}],\n});\n```\n\n## Returned data example\n\n```javascript\n\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", @@ -161,6 +170,9 @@ "ai_chat_unit": "アルバート(S)", "ai_close_setting_tip_content": "変更されました。それらを捨てたいですか。", "ai_close_setting_tip_title": "葉の先", + "ai_copilot_generate_response": "あなたのために回答を生成しています...", + "ai_copilot_processs": "処理中、お待ちください...", + "ai_copilot_start_process_request": "リクエストの処理を開始しています...", "ai_create_guide_btn_text": "データテーブルの選択", "ai_create_guide_content": "AIエージェントとして、私は私が学んだ知識に基づいてあなたの質問に答えることができます。対話を始める前に、知識ベースとしてデータテーブルを選択してください。その中のすべてのデータを読んで学習のために読みます。", "ai_credit_cost_chart_title": "信用コスト", @@ -173,7 +185,7 @@ "ai_credit_time_dimension_year": "今年.", "ai_credit_usage_tooltip": "メッセージクレジットは、AIエージェントクエリのために使用することができます。メッセージクレジットは、あなたの空間上の座席数に比例します。", "ai_data_source_required": "ヌル", - "ai_data_source_rows": "${row}行データ", + "ai_data_source_rows": "${rows}行データ", "ai_data_source_update": "使用可能性を更新する", "ai_datasheet_panel_create_btn_text": "AIエージェントの作成", "ai_default_idk": "私は知らない", @@ -629,7 +641,7 @@ "apps_support": "フルプラットフォームクライアントサポート", "archive_delete_record": "アーカイブされたレコードを削除する", "archive_delete_record_title": "レコードの削除", - "archive_notice": "

特定のレコードをアーカイブしようとしています。レコードをアーカイブすると、次のような変更が生じます。

1. このレコードの双方向リンクはすべてキャンセルされます

2. 編集はサポートされていません

3. 日付リマインダーや購読記録などの機能はサポートされていません

4. ルックアップ、式、その他のフィールドの計算に参加しなくなりました

続行してもよろしいですか? (詳細設定のアーカイブボックスで解凍できます)

", + "archive_notice": "

特定のレコードをアーカイブしようとしています。レコードをアーカイブすると、次のような変更が生じます。

1. 編集はサポートされていません

2. 日付リマインダーや購読記録などの機能はサポートされていません

3. ルックアップ、式、その他のフィールドの計算に参加しなくなりました

続行してもよろしいですか? (詳細設定のアーカイブボックスで解凍できます)

", "archive_record_in_activity": "この記録をアーカイブしました", "archive_record_in_menu": "アーカイブレコード", "archive_record_success": "レコードは正常にアーカイブされました", @@ -689,6 +701,8 @@ "audit_add_field_role_detail": "」データシートに、[] フィールド [] の [] としての役割 ", "audit_add_node_role": "ファイル権限の追加", "audit_add_node_role_detail": "ファイル権限を追加し、「${currentNodeName}」の「${role}」に「${unitNames}」を設定します", + "audit_add_node_role_detail_end": "to「${role}", + "audit_add_node_role_detail_start": "Add file node permission,set「${unitNames}」", "audit_admin_permission_change_event": "管理者権限の変更", "audit_create_template": "テンプレートの作成", "audit_create_template_detail": "テンプレートの作成", @@ -697,20 +711,30 @@ "audit_delete_field_role_detail": "監査", "audit_delete_node_role": "ファイル権限の削除", "audit_delete_node_role_detail": "ファイル権限の削除,「$」の「${unitNames}」の「${role}」ロールを削除します 「{currentNodeName}」", + "audit_delete_node_role_detail_end": "at 「${role}」role", + "audit_delete_node_role_detail_start": "Delete file node permission,delete「${unitNames}」from", "audit_delete_template": "テンプレートの削除", "audit_delete_template_detail": "テンプレートの削除", "audit_disable_field_role": "フィールド権限の無効化", "audit_disable_field_role_detail": "監査", "audit_disable_node_role": "ファイル権限の無効化", "audit_disable_node_role_detail": "${nodeType} 「${currentNodeName}」の権限を無効にします", + "audit_disable_node_role_detail_end": "`s permission", + "audit_disable_node_role_detail_start": "Disable ${nodeType}", "audit_disable_node_share": "ファイルパブリックリンクを閉じる", "audit_disable_node_share_detail": "${nodeType} 「${currentNodeName}」パブリック リンクを閉じる", + "audit_disable_node_share_detail_end": "public link", + "audit_disable_node_share_detail_start": "Close ${nodeType}", "audit_enable_field_role": "フィールド権限の有効化", "audit_enable_field_role_detail": "監査", "audit_enable_node_role": "ファイル権限の有効化", "audit_enable_node_role_detail": "${nodeType} 「${currentNodeName}」の権限を有効にする", + "audit_enable_node_role_detail_end": "`s permission", + "audit_enable_node_role_detail_start": "Enable ${nodeType}", "audit_enable_node_share": "ファイルパブリックリンクを開く", "audit_enable_node_share_detail": "${nodeType} 「${currentNodeName}」パブリック リンクを開きます", + "audit_enable_node_share_detail_end": "public link", + "audit_enable_node_share_detail_start": "Open ${nodeType}", "audit_login_event": "ログインイベント", "audit_logout_event": "英語", "audit_organization_change_event": "連絡先の組織構造が変更されました", @@ -731,18 +755,25 @@ "audit_space_invite_user_detail": "監査", "audit_space_node_copy": "重複するファイル", "audit_space_node_copy_detail": "${nodeType} 「${sourceNodeName}」が重複しています。新しいファイルの名前は「${currentNodeName}」です。", + "audit_space_node_copy_detail_start": "Duplicate ${nodeType} 「${sourceNodeName}」, the new file node's name is", "audit_space_node_create": "ファイルの作成", "audit_space_node_create_detail": "「${currentNodeName}」という名前の ${nodeType} を作成します", + "audit_space_node_create_detail_start": "Create a ${nodeType} named", "audit_space_node_delete": "ファイルを削除", "audit_space_node_delete_detail": "「${currentNodeName}」という名前の ${nodeType} を削除します", + "audit_space_node_delete_detail_start": "Delete ${nodeType} named", "audit_space_node_export": "データテーブルのエクスポート", "audit_space_node_export_detail": "メンバー ${member_name} がデータシート ${node_name} をエクスポートしました", "audit_space_node_import": "ファイルのインポート", "audit_space_node_import_detail": "「${nodeName}」という名前のファイルをインポートします", + "audit_space_node_import_detail_start": "Import a file node named", "audit_space_node_move": "ファイルの移動", "audit_space_node_move_detail": "${nodeType} 「${currentNodeName}」をフォルダー「${parentName}」に移動します", + "audit_space_node_move_detail_end": "to the folder「${parentName}」", + "audit_space_node_move_detail_start": "Move ${nodeType}", "audit_space_node_rename": "ファイル名の変更", "audit_space_node_rename_detail": "${nodeType} の名前を「${oldNodeName}」から「${nodeName}」に変更します", + "audit_space_node_rename_detail_start": "Rename ${nodeType} 「${oldNodeName}」to", "audit_space_node_sort": "監査", "audit_space_node_sort_detail": "監査", "audit_space_node_update_cover": "監査", @@ -757,17 +788,24 @@ "audit_space_rubbish_node_delete_detail": "監査", "audit_space_rubbish_node_recover": "ファイルを復元", "audit_space_rubbish_node_recover_detail": "${nodeType} 「${currentNodeName}」をゴミ箱から復元します", + "audit_space_rubbish_node_recover_detail_end": "from the trash", + "audit_space_rubbish_node_recover_detail_start": "Restore ${nodeType}", "audit_space_template_event": "テンプレートの変更", "audit_space_update_logo": "監査", "audit_space_update_logo_detail": "監査", "audit_store_share_node": "共有ファイルの保存", "audit_store_share_node_detail": "${nodeType} をスペースに復元します。名前は「${nodeName}」です", + "audit_store_share_node_detail_start": "Restore ${nodeType} to the space, name is", "audit_update_field_role": "監査", "audit_update_field_role_detail": "監査", "audit_update_node_role": "ファイル権限の変更", "audit_update_node_role_detail": "ファイル権限を変更し、「${unitNames}」のロールを「 ${currentNodeName}」の「${role}」に変更します", + "audit_update_node_role_detail_end": "to「${role}」role", + "audit_update_node_role_detail_start": "Modify file node permission,modify「${unitNames}」from", "audit_update_node_share_setting": "ファイルパブリックリンク設定の変更", "audit_update_node_share_setting_detail": "${nodeType} 「${currentNodeName}」パブリック リンクを変更します", + "audit_update_node_share_setting_detail_end": "public link settings", + "audit_update_node_share_setting_detail_start": "Modify ${nodeType}", "audit_user_login": "ユーザーログイン", "audit_user_login_detail": "監査", "audit_user_logout": "ユーザーのログアウト", @@ -809,6 +847,7 @@ "automation_enabled_return_via_related_files": "自動化が有効になっています。新しいボタンを使用するには、「関連ファイル」から元のテーブルを再入力してください。", "automation_field": "フィールド.フィールド", "automation_import_variables_from_pre_tep": "前ステップからデータを取得する", + "automation_is_not_yet_enabled": "自動化がまだ有効になっていません。有効にしてもう一度お試しください。", "automation_last_edited_by": "最終編集者", "automation_last_edited_time": "最終編集時刻", "automation_manager_label": "オートメーションですべてのアクションを実行できます", @@ -834,6 +873,7 @@ "automation_runs_this_month": "今月の運行", "automation_stay_tuned": "乞うご期待", "automation_success": "成功", + "automation_tips": "ボタンフィールドの設定が間違っています。確認してもう一度お試しください。", "automation_updater_label": "オートメーションの実行履歴を表示できます", "automation_variabel_empty": "前段階で使用できるデータがありません。調整して再試行してください。", "automation_variable_datasheet": "${NODE_NAME} からデータを取得する", @@ -869,6 +909,7 @@ "bermuda": "バミューダ諸島", "bhutan": "ブータン", "billing_over_limit_tip_common": "容量の使用量が制限を超えているため、アップグレード後はより多くの量をお楽しみいただけます。", + "billing_over_limit_tip_forbidden": "試用期間またはサブスクリプション期間が終了しました。更新するには販売コンサルタントにご連絡ください。", "billing_over_limit_tip_widget": "ウィジェットのインストール数が制限を超えているため、アップグレードして使用量を増やすことができます。", "billing_period": "請求期間: ${period}", "billing_subscription_warning": "機能性", @@ -928,10 +969,19 @@ "button_text": "ボタンのテキスト", "button_text_click_start": "クリックして開始", "button_type": "ボタンの種類", + "by_at": "で", + "by_days": "日々", + "by_every": "毎", "by_field_id": "フィールドIDの使用", + "by_hours": "時間", + "by_in": "で", + "by_min": "分)", + "by_months": "月", + "by_on": "で", "by_the_day": "日単位", "by_the_month": "月刊誌", "by_the_year": "毎年", + "by_weeks": "週間", "calendar_add_date_time_field": "作成日フィールド", "calendar_color_more": "その他の色", "calendar_const_detail_weeks": "[\"月曜日\",\"火曜日\",\"水曜日\",\"木曜日\",\"金曜日\",\"土曜日\",\"日曜日\"]", @@ -995,6 +1045,14 @@ "cannot_activate_space_by_space_limit": "スペース境界をアクティブ化できません", "cannot_join_space": "新しいスペースに参加することはできません。10のスペースの最大クォータを超えているからです。", "cannot_switch_field_permission": "フィールド権限をファイル権限以上に設定します。", + "capacity_file_detail_desc": "The total number of file nodes within the Space is calculated by adding the file nodes from the Team to the file nodes created by each member in their Private. Not enough capacity?", + "capacity_file_detail_title": "File Capacity", + "capacity_file_member": "Member", + "capacity_file_member_private_node_count": "Private", + "capacity_file_member_private_percent": "Percent", + "capacity_file_member_team": "Team", + "capacity_file_member_team_node_count": "Team", + "capacity_file_upgrade": "Click to upgrade your Space", "capacity_from_official_gift": "公式プレゼントより", "capacity_from_participation": "招待された ${user} がスペースに参加します", "capacity_from_purchase": "購買能力別", @@ -1031,6 +1089,8 @@ "catalog": "探索者", "catalog_add_from_template_btn_title": "テンプレートから追加", "catalog_empty_tips": "このワークスペースは空になりました。テンプレートを使用したファイルの作成を開始します。", + "catalog_private": "Private", + "catalog_team": "Team", "category_blank": "[空白]", "catering": "飲食", "cayman_islands": "ケイマン諸島", @@ -1099,6 +1159,7 @@ "choose_type_of_vika_field": "フィールドタイプの選択", "choose_your_own_space": "(作成者として自分のスペースに保存することのみがサポートされています)", "chose_new_primary_admin_button": "割当て", + "chunk_stopping_title": "Stopping", "claim_special_offer": "このスペシャル特典をお申し込みください!", "clear": "はっきりした", "clear_all_fields": "すべて消去", @@ -1229,6 +1290,7 @@ "confirm_del_current_team": "本当にチームを削除しますか?", "confirm_delete": "確認して削除", "confirm_delete_node_name_as": "「${nodeNameDiv}」を削除してもよろしいですか?", + "confirm_delete_private_node_name_as": "Are you sure you want to delete \"${nodeNameDiv}\"? The file will be deleted from the Space and the trash.", "confirm_delete_space_btn": "スペースの確認と削除", "confirm_exit": "終了の確認", "confirm_exit_space_with_name": "「${spaceNameDiv}」スペースを終了するかどうかの確認", @@ -1266,6 +1328,14 @@ "convert": "へんかん", "convert_tip": "これにより、特定のセルのデータが消去される可能性があります。予期しないことが発生した場合は、操作を元に戻すことができます。", "cook_islands": "クック諸島", + "copilot_auto_agent_desc": "どのエージェントを選択すればよいかわかりませんか?オートエージェントを試してください。", + "copilot_auto_agent_name": "自動エージェント", + "copilot_data_agent_desc": "ビューに基づいてデータ分析/可視化を生成します。", + "copilot_data_agent_name": "データエージェント", + "copilot_data_agent_policy": "Copilot とチャットするときは、ユーザー規約ポリシーに同意したことになります。", + "copilot_data_agent_policy_button": "ポリシー", + "copilot_help_agent_desc": "AITableのヘルプセンタードキュメントに関する質問は何でもどうぞ。", + "copilot_help_agent_name": "ヘルプセンターを検索", "copy": "レプリケーション", "copy_automation_url": "URLをコピーする", "copy_card_link": "レコードURLのコピー", @@ -1310,6 +1380,7 @@ "create_mirror_guide_content": "ミラー機能には、特定のデータを非表示にする機能があります。 元のデータシート ビューで「フィルター条件」と「非表示フィールド」を設定して、ミラーに表示するレコードとフィールドを制御できます。\n
\n
\n「閲覧ロック」機能と併用すると、他人による改変を防ぐことができます。\n
\n
\nさらに、「元のテーブル > 非表示フィールド」に移動して、「ミラー内のすべてのフィールドを表示」の設定を変更できます。", "create_mirror_guide_title": "ミラーはいくつかのレコードとフィールドを非表示にします", "create_new_button_field": "新しいボタン列フィールドを作成する", + "create_private_node_tip": "Personal or temporary draft documents can be created here ${link}", "create_public_invitation_link": "パブリック招待リンクの作成", "create_space_sub_title": "ハイ、あなたの共有スペースに名前を付けてください~", "create_team_fail": "チームの作成に失敗しました", @@ -1373,10 +1444,12 @@ "custom_enterprise": "エンタープライズスペースをカスタマイズ", "custom_function_development": "カスタム機能の開発", "custom_grade_desc": "エージェントの導入、プライベート・インストール、サポート、カスタマイズに関するプロフェッショナル・サービスの提供", + "custom_page_setting_title": "Add a custom page", "custom_picture": "カスタム画像", "custom_style": "スタイル", "custom_upload": "アップロードのカスタマイズ", "custom_upload_tip": "1:1正方形サイズの画像を使用して、より良い視覚体験を得ることをお勧めします", + "custome_page_title": "Custom Web", "cut_cell_data": "セルの切り取り", "cyprus": "キプロス.", "czech": "チェコ人人", @@ -1428,6 +1501,7 @@ "default": "約束を破る", "default_create_ai_chat_bot": "新しいAIエージェント", "default_create_automation": "新しい自動化", + "default_create_custom_page": "新しいカスタムページ", "default_create_dashboard": "新規ダッシュボード", "default_create_datasheet": "新規データテーブル", "default_create_file": "新規ファイル", @@ -1449,6 +1523,7 @@ "del_invitation_link": "招待リンクの削除", "del_invitation_link_desc": "削除するとリンクが無効になります", "del_space_now": "スペースを永遠に削除", + "del_space_now_confirm_tip": "For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "del_space_now_tip": "削除後にスペースを復元できませんでした。すべてのファイルと添付ファイルが削除されます。", "del_space_res_tip": "削除されたスペース", "del_team_success": "チームの削除に成功しました", @@ -1644,6 +1719,62 @@ "embed_error_page_help": "詳細はこちら", "embed_fail_og_description_content": "この埋め込まれたパブリックリンクは無効になっており、一時的には使用できません", "embed_failed": "埋め込みリンクは使用できません。", + "embed_link_bilibili": "bilibili", + "embed_link_bilibili_desc": "bilibili ビデオを埋め込むことで、チュートリアルやガイドを視聴したり、Vika でチャンネルのホームページを表示したりできます。", + "embed_link_bilibili_link_text": "bilibili動画を埋め込む方法", + "embed_link_bilibili_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-bilibili-video", + "embed_link_default": "何でも", + "embed_link_default_desc": "リンクを貼り付けて Web サイトを表示します。", + "embed_link_default_link_text": "もっと詳しく知る", + "embed_link_default_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_link_figma": "Figma", + "embed_link_figma_desc": "Figma ファイルを埋め込むことで、メンバーはデザイン ドラフトをより簡単に表示および編集できるようになり、コラボレーションの効率が向上します。", + "embed_link_figma_link_text": "Figma ファイルを埋め込む方法", + "embed_link_figma_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-figma-file", + "embed_link_google_docs": "Docs", + "embed_link_google_docs_desc": "Google ドキュメントを埋め込むことで、AITable でドキュメントを編集および表示して、チームのコラボレーションを促進できます。", + "embed_link_google_docs_link_text": "Googleドキュメントを埋め込む方法", + "embed_link_google_docs_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-docs-file", + "embed_link_google_sheets": "Sheets", + "embed_link_google_sheets_desc": "Google スプレッドシートを埋め込むと、AITable でテーブルを編集および表示して、チームのコラボレーションを促進できます。", + "embed_link_google_sheets_link_text": "Googleスプレッドシートを埋め込む方法", + "embed_link_google_sheets_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-sheets-file", + "embed_link_jishi_design": "JSデザイン", + "embed_link_jishi_design_desc": "JSdesign ファイルを埋め込むことで、メンバーはデザイン ドラフトをより簡単に表示および編集できるようになり、コラボレーションの効率が向上します。", + "embed_link_jishi_design_link_text": "JSdesignファイルを埋め込む方法", + "embed_link_jishi_design_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-js-design-file", + "embed_link_tencent_docs": "テンセントのドキュメント", + "embed_link_tencent_docs_desc": "Tencent ドキュメントを埋め込むことで、Vika で Tencent ドキュメントを編集および表示できるようになり、コラボレーションの効率が向上します。", + "embed_link_tencent_docs_link_text": "Tencent ドキュメントを埋め込む方法", + "embed_link_tencent_docs_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-tencent-docs", + "embed_link_wps": "WPS", + "embed_link_wps_desc": "WPS ファイルを埋め込むことで、Vika で WPS ドキュメント、テーブル、フォームを編集および表示して、コラボレーションの効率を向上させることができます。", + "embed_link_wps_link_text": "WPSファイルを埋め込む方法", + "embed_link_wps_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-wps-file", + "embed_link_youtube": "YouTube", + "embed_link_youtube_desc": "YouTube ビデオを埋め込むことで、チュートリアルやガイドを視聴したり、AITable でチャンネルのホームページを表示したりできます。", + "embed_link_youtube_link_text": "YouTubeビデオを埋め込む方法", + "embed_link_youtube_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-youtube-video", + "embed_page": "カスタムページ", + "embed_page_add_url": "URLを追加", + "embed_page_doc_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_page_function_desc": "Web ページを ${edition} に追加すると、サードパーティの Web サイトのドキュメントやビデオなどに簡単にアクセスできます。推奨される Web サイトのリンクやカスタム リンクを追加できます。", + "embed_page_node_permission_editor": "「更新のみ」に基づいて、ファイルの公開共有を開くこともできます", + "embed_page_node_permission_manager": "ファイルに対するすべてのアクションを実行できます", + "embed_page_node_permission_reader": "カスタムページのコンテンツと基本的なファイル情報を表示できます", + "embed_page_node_permission_updater": "「読み取り専用」に基づいて、カスタムページのリンクを変更することもできます", + "embed_page_setting_title": "カスタムページを追加する", + "embed_page_url_invalid": "正しいURLを入力してください", + "embed_paste_link_bilibili_placeholder": "bilibili動画のリンクを貼り付けます", + "embed_paste_link_default_placeholder": "URLを貼り付けてください", + "embed_paste_link_figma_placeholder": "Figma ファイルの共有リンクを貼り付けます", + "embed_paste_link_google_docs_placeholder": "Google ドキュメントの共有リンクを貼り付けます", + "embed_paste_link_google_sheets_placeholder": "Google スプレッドシートの共有リンクを貼り付けます", + "embed_paste_link_jsdesign_placeholder": "JSdesign ファイルの共有リンクを貼り付けます。", + "embed_paste_link_tencent_docs_placeholder": "Tencent ドキュメントの共有リンクを貼り付けます", + "embed_paste_link_wps_placeholder": "WPS ファイルの共有リンクを貼り付けます", + "embed_paste_link_youtube_placeholder": "YouTube ビデオのリンクを貼り付けます", + "embed_success": "正常に追加されました", "emoji_activity": "アクティビティ", "emoji_custom": "風俗", "emoji_flags": "に旗を立てる", @@ -1750,6 +1881,11 @@ "estonia": "エストニア.", "ethiopia": "エチオピア.", "event_planning": "イベント企画", + "every": "毎", + "every_day_at": "日:", + "every_hour_at": "時", + "every_month_at": "の月", + "every_week_at": "毎週", "everyday_life": "日常生活", "everyone_visible": "すべての人に表示", "exact_date": "正確な日付", @@ -1760,6 +1896,7 @@ "exchange": "請け出す", "exchange_code_times_tip": "注意:為替コードは1回だけ使用できます", "exclusive_consultant": "独占V+コンサルタント", + "exclusive_limit_plan_desc": "限定限定ティア", "exist_experience": "エクスペリエンスの終了", "exits_space": "スペースを終了", "expand": "拡大", @@ -1786,7 +1923,7 @@ "expired": "期限が切れる", "export": "エクスポート中。。。", "export_brand_desc": "テクニカルサポート", - "export_current_preview_view_data": "", + "export_current_preview_view_data": "Export current preview view data", "export_gantt_button_tips": ".pngファイルにエクスポート", "export_gantt_chart": "ガントチャートのエクスポート", "export_to_excel": "データのエクスポート", @@ -2458,6 +2595,7 @@ "gold_grade": "金", "gold_grade_desc": "複雑なビジネスプロセスに対応するチーム", "gold_seat_200_desc": "200", + "gold_seat_300_desc": "300", "golden_grade": "金", "got_it": "わかりました", "got_v_coins": "ご褒美Vコイン", @@ -2491,6 +2629,8 @@ "guests_per_space": "各スペースのお客様", "guide_1": "啊这", "guide_2": "基本機能を学ぶのに数分しかかかりません。この瞬間から、仕事の効率がさらにアップ!", + "guide_flow_modal_contact_sales": "営業担当者へのお問い合わせ", + "guide_flow_modal_get_started": "始めましょう", "guide_flow_of_catalog_step1": "これは作業ディレクトリで、スペースのすべてのフォルダとファイルが格納されています。", "guide_flow_of_catalog_step2": "作業ディレクトリでは、必要に応じてデータテーブルまたはフォルダを作成できます。", "guide_flow_of_click_add_view_step1": "基本ビューのほかに、画像形式の添付ファイルがある場合は、アルバムビューを作成することを強くお勧めします。", @@ -2669,6 +2809,7 @@ "intro_widget_tips": "ウィジェットとは", "introduction": "紹介", "invalid_action_sort_tip": "グループ化フィールドとして、ソートが設定されています。現在の注文の設定は有効になりません。", + "invalid_automation_configuration": "自動化構成が無効です。確認して再試行してください。", "invalid_field_type": "無効なフィールドタイプ", "invalid_option_sort_tip": "グループ化フィールドとして、ソートが設定されています。", "invalid_redemption_code_entered": "無効な換算コード", @@ -2799,6 +2940,9 @@ "label_format_day_month_and_year_split_by_slash": "日/月/年", "label_format_month": "月", "label_format_month_and_day_split_by_dash": "年月日", + "label_format_month_day_year_split_by_dash": "Month-Day-Year", + "label_format_month_day_year_split_by_slash": "Month/Day/Year", + "label_format_month_day_year_two_digit_year_split_by_slash": "Month/Day/Year (Two-digit year)", "label_format_year": "年", "label_format_year_and_month_split_by_dash": "年月", "label_format_year_month_and_day_split_by_dash": "年月日", @@ -2877,6 +3021,7 @@ "lark_version_enterprise": "Larkのエンタープライズ計画", "lark_version_standard": "Lark標準平面図", "lark_versions_free": "Larkの基本平面図", + "last_day": "最終日", "last_modified_by_select_modal_desc": "下で選択したフィールドを編集すると、最後に編集したメンバーが最後に編集したフィールドに表示されます", "last_modified_time_select_modal_desc": "下で選択したフィールドを編集すると、最後に編集した時刻が最後に編集した時刻フィールドに表示されます", "last_step": "リターンマッチ", @@ -3021,7 +3166,7 @@ "mail_invite_fail": "メール招待に成功しました。", "mail_invite_success": "メール招待に成功しました。", "main_admin_name": "管理者名", - "main_admin_page_desc": "管理者は、サブ管理者の割り当てやスペースの所有権の移転など、スペースに完全にアクセスできます。", + "main_admin_page_desc": "管理者は、メンバーの管理、スペース設定の管理など、スペースへの完全なアクセス権を持ちます。", "main_contain": "主な内容", "malawi": "マラウイ.", "malaysia": "マレーシア.", @@ -3241,8 +3386,12 @@ "more_widget": "その他のガジェット", "morocco": "モロッコ.", "move": "移動", + "move_datasheet_link_warn": "Cannot be moved to Team Area alone, because there is a two-way link from the current datasheet to another datasheet, it is recommended to put them in a folder and then move them", "move_favorite_node_fail": "ノードの移動に失敗しました。リストが自動的に更新されます。", + "move_folder_link_warn": "Cannot be moved to Team Area because the files in the current folder are linked to files outside the folder (may be two-way links or linked by forms, etc.) We recommend that they be placed in a folder before moving", "move_node_modal_content": "移動後、ファイルの可視性は親フォルダーの影響を受ける可能性があります。", + "move_other_link_no_permission": "Unable to move to the corresponding folder because you do not have administrative rights to the folder", + "move_other_link_warn": "It is not allowed to move ${node type} to Team Area alone, because it connects to the datasheet of Private Area, it is recommended to put them in a folder before moving them", "move_to": "移動先", "move_to_error_equal_parent": "ファイルは現在のフォルダの下にあります。他のフォルダを選択してください", "move_to_modal_title": "[${name}] を次の場所に移動します", @@ -3273,7 +3422,9 @@ "new_a_line": "Shift+Enterキー:改行", "new_automation": "新しい自動化", "new_caledonia": "ニューカレドニア", + "new_custom_page": "New custom page", "new_datasheet": "新規データテーブル", + "new_ebmed_page": "新しいカスタムページ", "new_folder": "新規フォルダ", "new_folder_btn_title": "フォルダー", "new_folder_tooltip": "フォルダの作成", @@ -3439,7 +3590,7 @@ "nvc_start_text": "棒グラフを右端にドラッグ", "nvc_yes_text": "実証済み", "obtain_verification_code": "認証コードが取得されていないか期限切れです", - "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrzw0miJVmSkJ7eBBa9k/fomx5qPX0JGPFvfEEP\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", + "offical_website_footer_nav_data": "[{ \"title\": \"产品\", \"lists\": [{ \"name\": \"快速入门\", \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick- start\" }, { \"name\": \"产品指南\", \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\" }, { \"name\": \"产品价格\", \"url\": \"/pricing/\" }, { \"name\": \"产品回線图\", \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\" }] }, { \"title\": \"关に関する我们\", \"lists\": [{ \"name\": \"公司介绍\", \"url\": \"/company/\" }, { \"name\": \"添加我们\", \"url \": \"/join-us/\" }, { \"name\": \"メディア报道\", \"url\": \"/press/\" }, { \"name\": \"vika维格课堂\", \"url\": \"https ://edu.vika.cn/\" }, { \"name\": \"维格合伙人\", \"url\": \"/partners/\" }] }, { \"title\": \"解决方案\", \"lists\" : [{ \"name\": \"PMO项目群管理\", \"url\": \"/business-pmo/\" }, { \"name\": \"智慧电商运营\", \"url\": \"/ecommerce/\" }, { \"name\": \"CRM客户管理\", \"url\": \"/crm/\" }, { \"name\": \"HR人力资源管理\", \"url\": \"/hr/\" }, { \"name\": \"Scrum敏捷开発行管理\", \"url\": \"/scrum/\" }, { \"name\": \"营销策划与市场运营\", \"url\": \"/marketing/\" }, { \"name\": \"OKR目标管理\", \"url\": \"/okr/\" }, { \"name\": \"教育培训管理\", \"url\": \"/education/\" }, { \"name\": \"智慧门店管理\", \"url\" : \"/shop/\" }] }, { \"title\": \" サポート\", \"lists\": [{ \"name\": \"意见反馈\", \"url\": \"https://vika.cn/share/shrCvbFC53xc3kl00B4Pg \" }, { \"name\": \"帮助中心\", \"url\": \"https://help.vika.cn/\" }, { \"name\": \"开発行者中心\", \"url\": \"/developers/ \" }, { \"name\": \"服务条款\", \"url\": \"/service-agreement/\" }, { \"name\": \"隐私协议\", \"url\": \"/service-agreement/\" }, { \"name\": \"安全与合规\", \"url\": \"/security/\" }] }, { \"title\": \"服务\", \"lists\": [{ \"name\": \"追加社群\", \" url\": \"/chatgroup/\" }, { \"name\": \"Github开源\", \"url\": \"https://github.com/vikadata\" }, { \"name\": \"预约演示\", \"url\" : \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\" }, { \"name\": \"专有云配置\", \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\" } , { \"name\": \"应用连接\", \"url\": \"/connections/\" }] }, { \"title\": \"联系我们\", \"lists\": [{ \"name\": \"地址:深圳市南山区国信投资大厦1710\", \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\" }, { \"name\": \"售前咨询:点击联系商务\", \"url\": \"https: //vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\" }, { \"name\": \"合作:bd@vikadata.com\", \"url\": \"mailto:bd@vikadata.com\" }, { \"name\": \"メディア:pr@vikadata.com\", \"url\": \"mailto:pr@vikadata.com\" }, { \"name\": \"招聘:hr@vikadata.com\", \"url\": \"mailto:hr@vikadata. com\" }] }]", "offical_website_nav_data": "[{\n \"name\": \"产品\",\n \"href\": \"/login\",\n \"children\": [\n {\n \"name\": \"vika维格表 Overview\",\n \"href\": \"/login/\"\n },\n {\n \"name\": \"应用连接 Integration\",\n \"href\": \"/connections/\"\n },\n {\n \"name\": \"客户端(Beta) Download\",\n \"href\": \"/download/\"\n }\n ]\n}, {\n \"name\": \"解决方案\",\n \"href\": \"/\",\n \"children\": [{\n \"name\": \"PMO项目群管理\",\n \"href\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"href\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"href\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"href\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"href\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"href\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"href\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"href\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"href\": \"/shop/\"\n }, {\n \"name\": \"更多解决方案 >\",\n \"href\": \"/solutions/\"\n }]\n}, {\n \"name\": \"模板/案例\",\n \"href\": \"/template\",\n \"children\": [\n {\n \"name\": \"模板中心 Tempaltes\",\n \"href\": \"/template\"\n },\n {\n \"name\": \"客户案例 Customers\",\n \"href\": \"/cases/\"\n }\n ]\n},\n {\n \"name\": \"首页\",\n \"href\": \"/?home=1\"\n },\n {\n \"name\": \"学习资源\",\n \"href\": \"https://edu.vika.cn/index\",\n \"children\": [\n {\n \"name\": \"快速入门 Tutorials\",\n \"href\": \"https://help.vika.cn/docs/guide/tutorial\"\n },\n {\n \"name\": \"产品手册 Manual\",\n \"href\": \"https://help.vika.cn/docs/guide/manual\"\n },\n {\n \"name\": \"维格课堂 Vika Education\",\n \"href\": \"https://edu.vika.cn/\"\n },\n {\n \"name\": \"维格社区 Vika BBS\",\n \"href\": \"https://bbs.vika.cn/\"\n },\n {\n \"name\": \"第三方连接 Integration\",\n \"href\": \"https://help.vika.cn/docs/guide/connection\"\n },\n {\n \"name\": \"开发者中心 Developer Center\",\n \"href\": \"/developers/\"\n },\n {\n \"name\": \"常见问题 FAQ\",\n \"href\": \"https://help.vika.cn/docs/guide/questions\"\n }\n ]\n }]", "office_preview": "Officeファイルのプレビュー", "office_preview_app_desc": "

Smooth online preview of office files on datasheet, allowing you to view common office files such as Excel, Word, PPT, etc. on your desktop or mobile anywhere, anytime

\n\n
    \n
  • Online preview of .doc, .docx, .xls, .xlsx, .ppt, .pptx, and .pdf formatted office files
  • \n
  • Desktop and mobile both support file previews of the above formats
  • \n
\n\n

Additional notes:

\n
    \n
  • This feature is powered by \"Yoncentric Cloud Conversion\" and officially integrated
  • \n
  • Click the \"Enable\" button below to enable this integration and agree that \"Yoncentric Cloud Conversion\" reads the office files you want to preview
  • \n
  • If you no longer need the office files preview feature, the space admin can disable it on this page
  • \n
", @@ -3479,6 +3630,7 @@ "open_auto_save_success": "自動保存ビューが正常に開きました", "open_auto_save_warn_content": "このビューでの変更はすべて自動的に保存され、他のメンバーと同期されます。", "open_auto_save_warn_title": "自動保存ビューを有効にする", + "open_automation_time_arrival": "https://aitable.ai/contact-sales-open-source", "open_failed": "開けませんでした", "open_in_new_tab": "新しいタブで開く", "open_invite_after_operate": "開くと、すべてのメンバーが連絡先パネルから新しいメンバーを招待できます", @@ -3625,6 +3777,8 @@ "payment_record": "支払記録", "payment_reminder": "支払プロンプト", "payment_reminder_content": "選択した新しいプランは、支払われる金額よりも多くの控除対象となります。期間が長い新しいプランを選択することをお勧めします。確認した場合、超過金額は返金されません。疑わしい場合は ${action}", + "payment_reminder_modal_content": "上級バージョンを試して、より多くのファイル ノード、エンタープライズ権限、添付ファイル容量、データ量、AI、その他の高度な機能と権限を楽しむことができます。", + "payment_reminder_modal_title": "現在無料版を使用しています", "pending_invite": "保留中の招待", "people": "メンバー", "per_person_per_year": "一人当たり毎年", @@ -3794,7 +3948,7 @@ "player_step_ui_config_168": "{\n\"templateKey\":\"createMirrorTip\"\n}", "player_step_ui_config_169": "{ \"headerImg\": \"https://s4.vika.cn/space/2023/04/04/bcf0695cf35840e6b85e032a8e5ea0a1\", \"readMoreUrl\": \"https://help.vika.cn/changelog/23-04-10-更新\"、\"子\": \"

🚀 新機能のご紹介

\\n
  • 新しいフィールド タイプ「Cascader」がリリースされ、フォーム上のオプションの階層からの選択が容易になります。
  • 「スクリプト」ウィジェットがリリースされ、より少ないコードでよりカスタマイズ可能に
  • 自動化をトリガーして電子メールを送信し、迅速な通知を受け取ります
  • 自動化をトリガーして Slack にメッセージを送信し、時間内にチームに通知します
  • AIの探求:「GPT Content Generator」ウィジェットをリリース
\" }", "player_step_ui_config_17": "{\n \"element\": \"#TEMPLATE_CENTER_USE_TEMPLATE_BTN>button\", \n\"placement\": \"rightBottom\",\n\"offsetY\": 20,\n \"title\": \"How to use a template\", \n\"description\": \"Click the button on the left to use the template\", \"children\":\"\" \n}", - "player_step_ui_config_176": "{\"title\":\"AIエージェント入門\",\"video\":\"https://www.youtube.com/embed/cjds1r_roG8?si=irKUpMhwDlOEb8Hc\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", + "player_step_ui_config_176": "{\"title\":\"AITable.ai DEMO\",\"video\":\"https://www.youtube.com/embed/kGxMyEEo3OU\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", "player_step_ui_config_18": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select>.ant-select-selector\", \n\"placement\": \"bottomLeft\",\n \"title\": \"How to use a template\", \n\"description\": \"Select where to put the template\", \"children\":\"\" \n}", "player_step_ui_config_19": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select .ant-select-selector\"\n}", "player_step_ui_config_2": "{\n \"config\": [\n {\n \"key\": 1,\n \"name\": \"answer1\",\n \"title\": \"What kind of issues are you looking forward to solved by vikadata?\",\n \"type\": \"checkbox\",\n \"answers\": [\n \"Work Planning\",\n \"Customer Service\",\n \"Project Management\",\n \"Sourcing Supply\",\n \"Content Production\",\n \"E-commerce operation\",\n \"Event Planning\",\n \"Human Resources\",\n \"Administration\",\n \"Financial Management\",\n \"Webcast\",\n \"Educational institutes Management\",\n \"Other\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 2,\n \"name\": \"answer2\",\n \"title\": \"Your job title is______\",\n \"type\": \"radio\",\n \"answers\": [\n \"General manager \",\n \"Project manager\",\n \"Product manager\",\n \"Designer\",\n \"R&D engineer\",\n \"Operator, editor\",\n \"Sales, customer service\",\n \"Human resource, administration \",\n \"Finance, accountant\",\n \"Lawyer, legal affairs\",\n \"Marketing\",\n \"Teacher\",\n \"Student\",\n \"Other\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 3,\n \"name\": \"answer3\",\n \"title\": \"What is the name of your company?\",\n \"type\": \"input\",\n \"submit\": false\n },\n {\n \"key\": 4,\n \"name\": \"answer4\",\n \"title\": \"Please leave your email address/ phone number/ Wechat account below so we can reach you in time when you need help.\",\n \"type\": \"input\",\n \"submit\": true\n },\n {\n \"key\": 5,\n \"title\": \"Thank you for filling out the form, you can add our customer service in case of need\",\n \"platform\": {\n \"website\": \"https://s4.vika.cn/space/2023/03/02/b34e3205a9154463be16f497524f1327\",\n \"dingtalk\": \"https://s4.vika.cn/space/2023/03/02/4b16cef6602a4586a21d6346bf25d300\",\n \"wecom\": \"https://s4.vika.cn/space/2023/03/02/60119b1b69b64aa887bd1be6a2928bec\",\n \"feishu\": \"https://u.vika.cn/z9ygm\"\n },\n \"type\": \"contactUs\",\n \"next\": true\n }\n ]\n}\n", @@ -3824,13 +3978,13 @@ "player_step_ui_config_41": "", "player_step_ui_config_42": "{\n \"element\": \"#DATASHEET_FORM_LIST_PANEL\", \n\"placement\": \"leftTop\",\n \"title\": \"Form\", \n\"description\": \"You can quickly create a form from the current view. The number and order of the fields in the form is consistent with the view.\", \"children\":\"\" \n}", "player_step_ui_config_43": "{\n \"element\": \".style_navigation__1U5cR .style_help__1sXEA\", \n\"placement\": \"rightBottom\",\n \"title\": \"Tip\", \n\"offsetY\":5,\n\"description\": \"You can find your Vikaby assistant from the \"Help\" icon on the left\", \"children\":\"\" \n}", - "player_step_ui_config_44": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", + "player_step_ui_config_44": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", "player_step_ui_config_45": "", "player_step_ui_config_46": "", "player_step_ui_config_47": "{\n \"element\": \"#DATASHEET_WIDGET_BTN\",\n\"placement\": \"bottomRight\",\n \"title\": \"Widget\", \n\"description\": \"Want to use and view your data in a richer way? Try the widget!\", \"children\":\"\" \n}", "player_step_ui_config_48": "", "player_step_ui_config_49": "{\n \"element\": \".style_widgetPanelContainer__1l2ZV\",\n\"placement\": \"leftCenter\",\n \"title\": \"What is a widget\", \n\"description\": \"Vika widgets are an extended application of vikadata that features in richer data visualization, data transfer, data cleansing, and more. By installing widgets in the widget board, you can make work a lot easier.\", \"children\":\"\" \n}", - "player_step_ui_config_5": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", + "player_step_ui_config_5": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", "player_step_ui_config_50": "{\n \"element\": \".style_widgetModal__eXmdB\",\n\"placement\": \"leftTop\",\n \"title\": \"Widget Center\", \n\"description\": \"Officially recommended and custom widgets are published here. You can install any widget you want onto a dashboard or into a widget board of any datasheet.\", \"children\":\"\" \n}", "player_step_ui_config_51": "{\n \"element\": \".style_widgetModal__eXmdB .style_widgetItem__3Pl-1 button\",\n\"placement\": \"rightBottom\",\n \"title\": \"Install widget\", \n\"description\": \"Let's install this \"Chart\" widget\", \"children\":\"\" \n}", "player_step_ui_config_52": "", @@ -3927,6 +4081,7 @@ "preview_guide_click_to_restart": "下のボタンを押して再度プレビュー", "preview_guide_enable_it": "次のボタンを押してこの機能を開きます", "preview_guide_open_office_preview": "このファイルをプレビューするには、「オフィスプレビュー」機能を開きます", + "preview_next_automation_execution_time": "次の 10 回の実行時間をプレビューする", "preview_not_support_video_codecs": "H.264ビデオコーデック付きMP 4ビデオのみプレビュー可能", "preview_revision": "プレビュー", "preview_see_more": "オフィスファイルプレビュー機能の詳細について知りたいですか?ここをクリックしてください", @@ -3962,6 +4117,7 @@ "privacy_protection": "プライバシー保護", "private_cloud": "プライベートクラウド", "private_external_person_only": "社外ユーザのみ", + "private_help_link": "https://help.aitable.ai/docs/guide/team-and-private-area#private-area", "private_internal_person_only": "社内ユーザのみ", "private_product_point": "ワンクリックで APITable プラットフォームを所有", "privatized_deployment": "自己管理", @@ -4032,13 +4188,15 @@ "reconciled_data": "データの照合", "record": "レコード破り", "record_activity_experience_tips": "${day} 日間のアクティビティの記録を表示できます", + "record_archived_data": "アーカイブされた記録", + "record_chunk_text": "${text} rows, please wait", "record_comment": "コメントのみ", "record_comments": "コメント", "record_fail_data": "データエラー", "record_filter_tips": "このレコードはフィルタされました", "record_functions": "ロギング機能", "record_history": "改訂履歴のみ", - "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-history", + "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-activity", "record_history_title": "レコード履歴", "record_pre_filtered": "このレコードはフィルタされており、レコードの外部をクリックすると非表示になります", "record_pre_move": "レコードの外部をクリックすると、このレコードは別の場所に移動されます", @@ -4478,6 +4636,12 @@ "scan_to_login": "スキャンログイン", "scan_to_login_by_method": "${method} をスキャンして公式アカウントをフォローしてログインしてください", "scatter_chart": "さんぷず", + "schedule_day_tips": "周期の計算は各月の 1 日からカウントされます。 10 日ごとに繰り返すと仮定すると、毎月 1 日、11 日、21 日、31 日にトリガーされます。", + "schedule_hour_tips": "サイクルの計算は毎日午前 0 時 (0:00) に開始されます。 3 時間ごとに 0 分が繰り返されると仮定すると、毎日深夜 (0:00)、午前 3 時、午前 6 時、午前 9 時、正午 (午後 12 時)、午後 3 時、午後 6 時、そして最後に日没 (午後 9 時) に発生します。", + "schedule_start_day": "毎月1日から始まり、", + "schedule_start_month": "毎年1月から毎年、", + "schedule_type": "スケジュールの種類", + "schedule_year_tips": "周期の計算は、各年の最初の月からカウントされます。初日を 3 か月間隔として、毎年 1 月、4 月、7 月、10 月の初日の午前 0 時にトリガーがアクティブになります。", "science_and_technology": "科学と技術", "scroll_screen_down": "画面を下にスクロール", "scroll_screen_left": "画面を左にスクロール", @@ -4491,6 +4655,7 @@ "search_folder_or_sheet": "ファイルを検索する", "search_new_admin": "検索けんさく", "search_node_pleaseholder": "ファイルの検索 (${shortcutKey})", + "search_node_tip": "クイック検索 (${shortcutKey})", "search_or_add": "オプションの検索または追加", "search_role_placeholder": "ロールの検索", "seats": "座席", @@ -4894,6 +5059,7 @@ "space_info": "概要", "space_info_del_confirm1": "1.この共有スペースを削除すると、次のデータが消去されます。", "space_info_del_confirm2": "2.共有スペースは7日後に完全に削除されます。その前に、スペースを復元できます。", + "space_info_del_confirm3": "3. For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "space_info_feishu_desc": "サードパーティ統合を使用しています。共有スペースを削除するには、まずサードパーティ統合を無効にします。", "space_info_feishu_label": "統合", "space_join_apply": "「」スペースへの参加を要求します。", @@ -4980,6 +5146,7 @@ "start_onfiguration": "構成の開始", "start_time": "開始時間", "start_use": "使用開始", + "starting_from_midnight": "毎日午前 0 時 (午前 12 時) から始まり、", "startup": "スタートアップ", "startup_company_support_program": "サポート計画の開始", "stat_average": "へいきん", @@ -5013,6 +5180,8 @@ "stay_tuned_for_more_features": "詳細な機能に注目してください", "steps_choose_reset_mode": "リセット方法の選択", "steps_validate_identities": "認証", + "stop_chunk_content": "Are you sure you want to stop the operation?", + "stop_chunk_title": "Stop", "stop_dingtalk_h5_modal_content": "カスタムアプリケーションは、このスペースからバインドを解除します。確認してください。", "storage_per_seats": "", "storage_per_space": "ストレージの使用状況", @@ -5043,9 +5212,11 @@ "subscribe_credit_usage_over_limit": "現在の空間のポイント数が制限を超えていますので、購読をアップグレードしてください。\n", "subscribe_demonstrate": "デモンストレーションのリクエスト", "subscribe_disabled_seat": "人数は当初の計画を下回ってはならない", + "subscribe_grade_business": "仕事", "subscribe_grade_free": "フリー", "subscribe_grade_plus": "プラス", "subscribe_grade_pro": "プロ", + "subscribe_grade_starter": "スターター", "subscribe_label_tooltip": "高度なスペース機能", "subscribe_new_choose_member": "最大 ${member_num} 人のメンバーをサポート", "subscribe_new_choose_member_tips": "このプランでは 1~${member_num} 名のメンバーがスペースに入場できます", @@ -5182,7 +5353,7 @@ "template_name_repetition_title": "「${templateName}」はすでに存在します。取り替えたいですか?", "template_no_template": "テンプレートなし", "template_not_found": "希望するテンプレートが見つかりませんでしたか?教えて", - "template_recommend_title": "あつい", + "template_recommend_title": "🌟 Hot", "template_type": "テンプレート", "terms_of_service": "<サービス約款>", "terms_of_service_pure_string": "サービス条件", @@ -5226,6 +5397,7 @@ "text_editor_tip_end": "入力(Input)編集の終了", "text_functions": "文字列関数", "thailand": "タイ", + "the_button_field_is_misconfigured": "ボタンフィールドの設定が間違っています。確認してもう一度お試しください。", "the_current_automation_workflow_has_no_related_files_you_can_establish_a_link_by_adding_trigger_conditions_and_actions_on_the_left_side": "現在の自動ワークフローには関連ファイルはありません。左側にトリガ条件と操作を追加することでリンクを確立することができます", "the_current_button_column_has_expired_please_reselect": "現在のボタン列の有効期限が切れています。再選択してください", "the_last_7_days": "過去7日間", @@ -5328,6 +5500,7 @@ "timemachine_update_comment": "コメントを更新しました", "times_per_month_unit": "コール/月", "times_unit": "コール数", + "timing_rules": "タイミング", "timor_leste": "東ティモール", "tip_del_success": "7日以内に共有スペースをリカバリできます", "tip_do_you_want_to_know_about_field_permission": "フィールドデータを暗号化しますか?フィールド権限の理解", @@ -5515,6 +5688,7 @@ "verify_account_title": "アカウントの検証", "verify_via_email": "電子メールによる認証", "verify_via_phone": "SMS認証", + "video": "ビデオ", "video_not_support_play": "現在のビデオフォーマットはオンライン再生をサポートしていません", "vietnam": "ベトナム.", "view": "見方", @@ -5863,7 +6037,8 @@ "workdoc_color_title": "文字の色", "workdoc_create": "ワークドキュメントの作成", "workdoc_expanded": "目次を展開する", - "workdoc_image_max_10mb": "画像サイズは10MBを超えることはできません", + "workdoc_image_max_10mb": "ヌル", + "workdoc_image_max_size": "画像サイズは ${size} を超えることはできません", "workdoc_info": "ワークドキュメント情報", "workdoc_info_create_time": "で作成されました", "workdoc_info_creator": "によって作成された", @@ -5871,6 +6046,7 @@ "workdoc_info_last_modify_time": "最終更新日時", "workdoc_link_placeholder": "リンクを入力してください", "workdoc_only_image": "画像のみ許可されています", + "workdoc_only_video": "動画のみ許可されています", "workdoc_text_placeholder": "「/」を入力してクイックスタート", "workdoc_title_placeholder": "タイトルを入力してください", "workdoc_unnamed": "名前のないワークドキュメント", @@ -5879,9 +6055,11 @@ "workdoc_unsave_ok": "変更を破棄", "workdoc_unsave_title": "WorkDoc は保存されていません", "workdoc_upload_failed": "アップロードに失敗しました", + "workdoc_video_max_size": "動画のサイズは ${size} を超えることはできません", "workdoc_ws_connected": "接続済み", "workdoc_ws_connecting": "接続中...", "workdoc_ws_disconnected": "切断されました", + "workdoc_ws_reconnecting": "再接続中...", "workflow_execute_failed_notify": " で実行できませんでした . 問題のトラブルシューティングを行うには、実行履歴を確認してください。 サポートが必要な場合は、カスタマーサービスチームまでご連絡ください。", "workspace_data": "くうかんデータ", "workspace_files": "ワークベンチデータ", diff --git a/packages/datasheet/public/file/langs/strings.json b/packages/datasheet/public/file/langs/strings.json index 39db71db06..f28c329aa1 100644 --- a/packages/datasheet/public/file/langs/strings.json +++ b/packages/datasheet/public/file/langs/strings.json @@ -147,6 +147,15 @@ "agreed": "Genehmigt", "ai_advanced_mode_desc": "Der erweiterte Modus ermöglicht es Benutzern, Prognosen anzupassen, wodurch das Verhalten und die Antworten des AI-Agenten stärker kontrolliert werden kann.", "ai_advanced_mode_title": "Erweiterter Modus", + "ai_agent_anonymous": "Anonym${ID}", + "ai_agent_conversation_continue_not_supported": "Das Fortsetzen eines vorherigen Gesprächs wird derzeit nicht unterstützt", + "ai_agent_conversation_list": "Gesprächsliste", + "ai_agent_conversation_log": "Gesprächsprotokoll", + "ai_agent_conversation_title": "Gesprächstitel", + "ai_agent_feedback": "Rückmeldung", + "ai_agent_historical_message": "Das Obige ist eine historische Botschaft", + "ai_agent_history": "Geschichte", + "ai_agent_message_consumed": "Nachricht verbraucht", "ai_api_curl_template": "## Create chat completions\n\n```bash\n\ncurl -X POST \"{{apiBase}}/fusion/v1/ai/{{aiId}}/chat/completions\" \\n -H \"Content-Type: application/json\" \\n -H \"Authorization: Bearer {{token}}\" \\n -d '{\n \"model\": \"gpt-3.5-turbo\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"You are a helpful assistant.\"\n },\n {\n \"role\": \"user\",\n \"content\": \"Hello!\"\n }\n ]\n }'\n\n```\n\n## Returned data example\n\n```json\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", "ai_api_footer_desc": "AI-Agent in deine Website einbinden? Erfahren Sie mehr", "ai_api_javascript_template": "## Initialize SDK [![github]({{ githubIcon }})](https://github.com/openai/openai-node)\nAITable's chat completion API is compatible with OpenAI's Node.js SDK. You can use our service with the same SDK by simply changing the configuration as follows:\n\n\n```javascript\nconst { Configuration, OpenAIApi } = require(\"openai\");\nconst configuration = new Configuration({\n apiKey: \"{{token}}\",\n basePath: \"{{apiBase}}/fusion/v1/ai/{{aiId}}\"\n});\n```\n\n## Create chat completions\n\n```javascript\nconst openai = new OpenAIApi(configuration);\nconst chatCompletion = await openai.createChatCompletion({\n model: \"gpt-3.5-turbo\",\n messages: [{role: \"user\", content: \"Hello world\"}],\n});\n```\n\n## Returned data example\n\n```javascript\n\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", @@ -162,6 +171,9 @@ "ai_chat_unit": "KI-Bot(s)", "ai_close_setting_tip_content": "Sie haben Änderungen vorgenommen. Willst du sie wegwerfen?", "ai_close_setting_tip_title": "tip", + "ai_copilot_generate_response": "Antwort wird für Sie generiert...", + "ai_copilot_processs": "Verarbeitung läuft, bitte warten...", + "ai_copilot_start_process_request": "Ihre Anfrage wird verarbeitet...", "ai_create_guide_btn_text": "Datenblatt auswählen", "ai_create_guide_content": "Als AI-Agent kann ich Ihre Fragen basierend auf dem Wissen beantworten, das ich gelernt habe. Bevor Sie mit dem Gespräch beginnen, wählen Sie bitte ein Datenbuch als Wissensbasis aus, und ich werde alle darauffolgenden Daten zum Lernen lesen.", "ai_credit_cost_chart_title": "Kreditkosten", @@ -630,7 +642,7 @@ "apps_support": "Plattformübergreifender Kundensupport", "archive_delete_record": "Archivierte Datensätze löschen", "archive_delete_record_title": "Aufzeichnung löschen", - "archive_notice": "

Sie versuchen, bestimmte Datensätze zu archivieren. Durch die Archivierung der Datensätze ergeben sich folgende Änderungen:

1. Alle bidirektionalen Verbindungen für diesen Datensatz werden gelöscht

2. Das Bearbeiten wird nicht unterstützt

3. Funktionen wie Terminerinnerungen und Abonnementdatensätze werden nicht unterstützt

4. Beteiligen Sie sich nicht mehr an der Berechnung von Such-, Formel- und anderen Feldern

Bist du dir sicher, dass du weitermachen willst? (Sie können die Archivierung in der Archivbox unter „Erweitert“ aufheben)

", + "archive_notice": "

Sie versuchen, bestimmte Datensätze zu archivieren. Durch die Archivierung der Datensätze ergeben sich folgende Änderungen:

1. Das Bearbeiten wird nicht unterstützt

2. Funktionen wie Terminerinnerungen und Abonnementdatensätze werden nicht unterstützt

3. Beteiligen Sie sich nicht mehr an der Berechnung von Such-, Formel- und anderen Feldern

Bist du dir sicher, dass du weitermachen willst? (Sie können die Archivierung in der Archivbox unter „Erweitert“ aufheben)

", "archive_record_in_activity": "Archiviert diesen Datensatz", "archive_record_in_menu": "Datensatz archivieren", "archive_record_success": "Erfolgreich archivierte Aufzeichnungen", @@ -690,6 +702,8 @@ "audit_add_field_role_detail": "Im Datenblatt „ fügen Sie [] Rolle als [] für das Feld [] ", "audit_add_node_role": "Dateiberechtigungen hinzufügen", "audit_add_node_role_detail": "Dateiberechtigung hinzufügen,setzen Sie 「${unitNames}」auf 「${role}」von 「${currentNodeName}」", + "audit_add_node_role_detail_end": "to「${role}", + "audit_add_node_role_detail_start": "Add file node permission,set「${unitNames}」", "audit_admin_permission_change_event": "Administratorberechtigungen ändern", "audit_create_template": "Vorlage erstellen", "audit_create_template_detail": "Vorlage erstellen", @@ -698,20 +712,30 @@ "audit_delete_field_role_detail": "Prüfung", "audit_delete_node_role": "Dateiberechtigung löschen", "audit_delete_node_role_detail": "Lösche Dateiberechtigung, lösche die Rolle „${role}“ von „${unitNames}“ in „${currentNodeName}“", + "audit_delete_node_role_detail_end": "at 「${role}」role", + "audit_delete_node_role_detail_start": "Delete file node permission,delete「${unitNames}」from", "audit_delete_template": "Vorlage löschen", "audit_delete_template_detail": "Vorlage löschen", "audit_disable_field_role": "Feldberechtigungen deaktivieren", "audit_disable_field_role_detail": "Prüfung", "audit_disable_node_role": "Dateiberechtigungen deaktivieren", "audit_disable_node_role_detail": " ${nodeType} 「${currentNodeName}」 `s permission deaktivieren", + "audit_disable_node_role_detail_end": "`s permission", + "audit_disable_node_role_detail_start": "Disable ${nodeType}", "audit_disable_node_share": "Öffentlicher Link schließen", "audit_disable_node_share_detail": "Schließen ${nodeType} 「${currentNodeName}」 public link", + "audit_disable_node_share_detail_end": "public link", + "audit_disable_node_share_detail_start": "Close ${nodeType}", "audit_enable_field_role": "Feldberechtigungen aktivieren", "audit_enable_field_role_detail": "Prüfung", "audit_enable_node_role": "Dateiberechtigungen aktivieren", "audit_enable_node_role_detail": " ${nodeType} 「${currentNodeName}」 `s permission aktivieren", + "audit_enable_node_role_detail_end": "`s permission", + "audit_enable_node_role_detail_start": "Enable ${nodeType}", "audit_enable_node_share": "Öffentlicher Link öffnen", "audit_enable_node_share_detail": " ${nodeType} 「${currentNodeName}」 public link öffnen", + "audit_enable_node_share_detail_end": "public link", + "audit_enable_node_share_detail_start": "Open ${nodeType}", "audit_login_event": "Anmeldeereignis", "audit_logout_event": "englisch", "audit_organization_change_event": "Die Organisationsstruktur der Kontakte hat sich geändert", @@ -732,18 +756,25 @@ "audit_space_invite_user_detail": "Prüfung", "audit_space_node_copy": "Datei duplizieren", "audit_space_node_copy_detail": "Duplizieren Sie ${nodeType} 「${sourceNodeName}「, der Name der neuen Datei lautet 「${currentNodeName}」", + "audit_space_node_copy_detail_start": "Duplicate ${nodeType} 「${sourceNodeName}」, the new file node's name is", "audit_space_node_create": "Datei erstellen", "audit_space_node_create_detail": "Erstellen Sie einen ${nodeType} namens 「${currentNodeName}」", + "audit_space_node_create_detail_start": "Create a ${nodeType} named", "audit_space_node_delete": "Datei löschen", "audit_space_node_delete_detail": " ${nodeType} mit dem Namen 「${currentNodeName}」", + "audit_space_node_delete_detail_start": "Delete ${nodeType} named", "audit_space_node_export": "Datenblatt exportieren", "audit_space_node_export_detail": "Member ${member_name} exportiertes Datenblatt ${node_name}", "audit_space_node_import": "Datei importieren", "audit_space_node_import_detail": "Importieren Sie eine Datei mit dem Namen 「${nodeName}」", + "audit_space_node_import_detail_start": "Import a file node named", "audit_space_node_move": "Datei verschieben", "audit_space_node_move_detail": "Verschieben Sie ${nodeType} 「${currentNodeName}」in den Ordner「${parentName}」」.", + "audit_space_node_move_detail_end": "to the folder「${parentName}」", + "audit_space_node_move_detail_start": "Move ${nodeType}", "audit_space_node_rename": "Datei umbenennen", "audit_space_node_rename_detail": "${nodeType} 」${oldNodeName}」」」」」」」in 「${nodeName}」", + "audit_space_node_rename_detail_start": "Rename ${nodeType} 「${oldNodeName}」to", "audit_space_node_sort": "Prüfung", "audit_space_node_sort_detail": "Prüfung", "audit_space_node_update_cover": "Prüfung", @@ -758,17 +789,24 @@ "audit_space_rubbish_node_delete_detail": "Prüfung", "audit_space_rubbish_node_recover": "Dateien wiederherstellen", "audit_space_rubbish_node_recover_detail": " ${nodeType} 「${currentNodeName}」 aus dem Papierkorb wiederherstellen", + "audit_space_rubbish_node_recover_detail_end": "from the trash", + "audit_space_rubbish_node_recover_detail_start": "Restore ${nodeType}", "audit_space_template_event": "Vorlage ändern", "audit_space_update_logo": "Prüfung", "audit_space_update_logo_detail": "Prüfung", "audit_store_share_node": "Freigegebene Datei speichern", "audit_store_share_node_detail": " ${nodeType} in den Leerraum wiederherstellen, Name ist 「${nodeName}」", + "audit_store_share_node_detail_start": "Restore ${nodeType} to the space, name is", "audit_update_field_role": "Prüfung", "audit_update_field_role_detail": "Prüfung", "audit_update_node_role": "Dateiberechtigung ändern", "audit_update_node_role_detail": "Ändern Sie die Dateiberechtigung, ändern Sie die Rolle von „${unitNames}“ in „${role}“ von 「 ${currentNodeName}」", + "audit_update_node_role_detail_end": "to「${role}」role", + "audit_update_node_role_detail_start": "Modify file node permission,modify「${unitNames}」from", "audit_update_node_share_setting": "Einstellungen für öffentliche Links für Dateien ändern", "audit_update_node_share_setting_detail": " ${nodeType} 「${currentNodeName}」 public link ändern", + "audit_update_node_share_setting_detail_end": "public link settings", + "audit_update_node_share_setting_detail_start": "Modify ${nodeType}", "audit_user_login": "Benutzeranmeldung", "audit_user_login_detail": "Prüfung", "audit_user_logout": "Benutzer abmelden", @@ -810,6 +848,7 @@ "automation_enabled_return_via_related_files": "Die Automatisierung ist aktiviert. Bitte geben Sie die ursprüngliche Tabelle über „Verwandte Dateien“ erneut ein, um die neue Schaltfläche zu verwenden.", "automation_field": "Field", "automation_import_variables_from_pre_tep": "Holen Sie sich Daten aus dem Vorschritt", + "automation_is_not_yet_enabled": "Die Automatisierung ist noch nicht aktiviert. Bitte aktivieren Sie sie und versuchen Sie es erneut", "automation_last_edited_by": "Zuletzt bearbeitet von", "automation_last_edited_time": "Letzte Bearbeitungszeit", "automation_manager_label": "Kann alle Aktionen an der Automatisierung ausführen", @@ -835,6 +874,7 @@ "automation_runs_this_month": "Läuft diesen Monat", "automation_stay_tuned": "Bleiben Sie dran", "automation_success": "Erfolg", + "automation_tips": "Das Schaltflächenfeld ist falsch konfiguriert. Bitte überprüfen Sie es und versuchen Sie es erneut", "automation_updater_label": "Kann den Ausführungsverlauf der Automatisierung anzeigen", "automation_variabel_empty": "Es sind keine Daten vorhanden, die im Vorschritt verwendet werden können. Bitte passen Sie sie an und versuchen Sie es erneut.", "automation_variable_datasheet": "Daten von ${NODE_NAME} abrufen", @@ -870,6 +910,7 @@ "bermuda": "Bermuda", "bhutan": "Bhutan", "billing_over_limit_tip_common": "Die Nutzung des Speicherplatzes hat das Limit überschritten und Sie können nach dem Upgrade eine höhere Menge nutzen.", + "billing_over_limit_tip_forbidden": "Ihre Testdauer oder Ihr Abonnementzeitraum ist abgelaufen. Für eine Verlängerung wenden Sie sich bitte an den Verkaufsberater.", "billing_over_limit_tip_widget": "Die Anzahl der Widget-Installationen hat das Limit überschritten und Sie können ein Upgrade durchführen, um eine höhere Nutzung zu erzielen.", "billing_period": "Abrechnungszeitraum: ${period}", "billing_subscription_warning": "Feature-Erfahrung", @@ -929,10 +970,19 @@ "button_text": "Schaltflächentext", "button_text_click_start": "Klicken Sie zum Starten", "button_type": "Schaltflächentyp", + "by_at": "bei", + "by_days": "Tage", + "by_every": "jeden", "by_field_id": "Feld-ID verwenden", + "by_hours": "Std", + "by_in": "bei", + "by_min": "Protokoll)", + "by_months": "Monate", + "by_on": "auf der", "by_the_day": "Tagsüber", "by_the_month": "Monatlich", "by_the_year": "Jährlich", + "by_weeks": "Wochen", "calendar_add_date_time_field": "Datumsfeld erstellen", "calendar_color_more": "Mehr Farben", "calendar_const_detail_weeks": "[\"Montag\",\"Dienstag\",\"Mittwoch\",\"Donnerstag\",\"Freitag\",\"Samstag\",\"Sonntag\"]", @@ -996,6 +1046,14 @@ "cannot_activate_space_by_space_limit": "can_activate_space_by_space_limit", "cannot_join_space": "Sie können einer neuen Raumstation nicht beitreten, weil Sie die maximale Quote von zehn Raumstationen überschritten haben.", "cannot_switch_field_permission": "Legen Sie Feldberechtigungen fest, die nicht höher als die Dateiberechtigungen sind.", + "capacity_file_detail_desc": "The total number of file nodes within the Space is calculated by adding the file nodes from the Team to the file nodes created by each member in their Private. Not enough capacity?", + "capacity_file_detail_title": "File Capacity", + "capacity_file_member": "Member", + "capacity_file_member_private_node_count": "Private", + "capacity_file_member_private_percent": "Percent", + "capacity_file_member_team": "Team", + "capacity_file_member_team_node_count": "Team", + "capacity_file_upgrade": "Click to upgrade your Space", "capacity_from_official_gift": "Aus dem offiziellen Geschenk", "capacity_from_participation": "Von eingeladenem ${user} dem Space beitreten", "capacity_from_purchase": "Nach Kaufkapazität", @@ -1032,6 +1090,8 @@ "catalog": "Forscher", "catalog_add_from_template_btn_title": "Aus Vorlagen hinzufügen", "catalog_empty_tips": "Dieser Arbeitsbereich ist jetzt leer. Beginnen Sie mit der Verwendung von Vorlagen zum Erstellen von Dateien.", + "catalog_private": "Private", + "catalog_team": "Team", "category_blank": "[Leere]", "catering": "Verpflegung", "cayman_islands": "Kaimaninseln", @@ -1100,6 +1160,7 @@ "choose_type_of_vika_field": "Feldtyp auswählen", "choose_your_own_space": "(Unterstützt nur das Speichern auf Ihrem eigenen Speicherplatz als Ersteller)", "chose_new_primary_admin_button": "Zuweisen", + "chunk_stopping_title": "Stopping", "claim_special_offer": "Fordern Sie dieses Sonderangebot an!", "clear": "Löschen", "clear_all_fields": "Alles löschen", @@ -1230,6 +1291,7 @@ "confirm_del_current_team": "Sind Sie sicher, dass Sie das Team löschen möchten?", "confirm_delete": "Bestätigen und löschen", "confirm_delete_node_name_as": "Möchten Sie \"${nodeNameDiv}\" wirklich löschen?", + "confirm_delete_private_node_name_as": "Are you sure you want to delete \"${nodeNameDiv}\"? The file will be deleted from the Space and the trash.", "confirm_delete_space_btn": "Leerzeichen bestätigen und löschen", "confirm_exit": "Beenden bestätigen", "confirm_exit_space_with_name": "Bestätigen, ob das Leerzeichen \"${spaceNameDiv}\" beendet werden soll", @@ -1267,6 +1329,14 @@ "convert": "Konvertieren", "convert_tip": "Diese Aktion kann Daten in einigen Zellen löschen. Sie können die Aktion rückgängig machen, wenn etwas Unerwartetes passiert.", "cook_islands": "Cookinseln", + "copilot_auto_agent_desc": "Sie sind sich nicht sicher, welchen Agenten Sie wählen sollen? Versuchen Sie es mit AutoAgent.", + "copilot_auto_agent_name": "Auto-Agent", + "copilot_data_agent_desc": "Generiere Datenanalyse/Visualisierungen basierend auf Ihren Ansichten.", + "copilot_data_agent_name": "Datenagent", + "copilot_data_agent_policy": "Wenn Sie mit Copilot chatten, stimmen Sie den Nutzungsbedingungen zu", + "copilot_data_agent_policy_button": "Politik", + "copilot_help_agent_desc": "Fragen Sie alles über die Hilfezentrumsdokumente von AITable.", + "copilot_help_agent_name": "Hilfezentrum abrufen", "copy": "Kopieren", "copy_automation_url": "URL kopieren", "copy_card_link": "Datensatz-URL kopieren", @@ -1311,6 +1381,7 @@ "create_mirror_guide_content": "Die Spiegelfunktion bietet die Möglichkeit, bestimmte Daten auszublenden. Sie können in der ursprünglichen Datenblattansicht „Filterbedingungen“ und „ausgeblendete Felder“ festlegen, um zu steuern, welche Datensätze und Felder im Spiegel angezeigt werden.\n
\n
\nIn Verbindung mit der Funktion „Ansichtssperre“ kann sie andere daran hindern, Änderungen vorzunehmen.\n
\n
\nDarüber hinaus können Sie zu „Originaltabelle > Ausgeblendete Felder“ gehen, um die Konfiguration für „Alle Felder in Spiegeln anzeigen“ zu ändern.", "create_mirror_guide_title": "Spiegel blendet einige Datensätze und Felder aus", "create_new_button_field": "Erstellen Sie ein neues Schaltflächenspaltenfeld", + "create_private_node_tip": "Personal or temporary draft documents can be created here ${link}", "create_public_invitation_link": "Öffentliche Einladungslinks erstellen", "create_space_sub_title": "Hallo, bitte geben Sie Ihrem Space einen Namen~", "create_team_fail": "Team erstellen fehlgeschlagen", @@ -1374,10 +1445,12 @@ "custom_enterprise": "Passen Sie den Unternehmensraum für Sie an", "custom_function_development": "Entwicklung benutzerdefinierter Features", "custom_grade_desc": "Bietet Agenten-Bereitstellung, private Installation, Unterstützung und maßgeschneiderte professionelle Services", + "custom_page_setting_title": "Add a custom page", "custom_picture": "Individuelles Bild", "custom_style": "Stil", "custom_upload": "Benutzerdefinierter Upload", "custom_upload_tip": "Ein 1:1 quadratisches Bild wird für die bessere visuelle Erfahrung empfohlen", + "custome_page_title": "Custom Web", "cut_cell_data": "Zelle(n) ausschneiden", "cyprus": "Zypern", "czech": "Tschechisch", @@ -1429,6 +1502,7 @@ "default": "Standard", "default_create_ai_chat_bot": "Neuer AI-Agent", "default_create_automation": "Neue Automatisierung", + "default_create_custom_page": "Neue benutzerdefinierte Seite", "default_create_dashboard": "Neues Dashboard", "default_create_datasheet": "Neues Datenblatt", "default_create_file": "Neue Datei", @@ -1450,6 +1524,7 @@ "del_invitation_link": "Einladungslink löschen", "del_invitation_link_desc": "Der Link ist nach Löschung ungültig", "del_space_now": "Leerzeichen für immer löschen", + "del_space_now_confirm_tip": "For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "del_space_now_tip": "Der Speicherplatz kann nach dem Löschen nicht wiederhergestellt werden. Alle Dateien und Anhänge werden gelöscht.", "del_space_res_tip": "Das Leerzeichen gelöscht", "del_team_success": "Teamerfolg löschen", @@ -1645,6 +1720,62 @@ "embed_error_page_help": "Erfahren Sie mehr", "embed_fail_og_description_content": "Der öffentliche Link für diese Einbettung wurde deaktiviert und ist vorübergehend nicht verfügbar", "embed_failed": "Einbettungslink ist nicht verfügbar,", + "embed_link_bilibili": "bilibili", + "embed_link_bilibili_desc": "Durch das Einbetten der Bilibili-Videos können Sie Tutorials und Anleitungen ansehen oder die Kanal-Homepage in Vika anzeigen.", + "embed_link_bilibili_link_text": "So betten Sie das Bilibili-Video ein", + "embed_link_bilibili_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-bilibili-video", + "embed_link_default": "Irgendetwas", + "embed_link_default_desc": "Fügen Sie einen Link ein, um eine beliebige Website anzuzeigen.", + "embed_link_default_link_text": "Erfahren Sie mehr", + "embed_link_default_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_link_figma": "Figma", + "embed_link_figma_desc": "Durch die Einbettung von Figma-Dateien können Mitglieder Designentwürfe bequemer anzeigen und bearbeiten und so die Effizienz der Zusammenarbeit verbessern.", + "embed_link_figma_link_text": "So betten Sie Figma-Dateien ein", + "embed_link_figma_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-figma-file", + "embed_link_google_docs": "Docs", + "embed_link_google_docs_desc": "Durch die Einbettung von Google Docs können Sie Dokumente in AITable bearbeiten und anzeigen, um die Zusammenarbeit im Team zu erleichtern.", + "embed_link_google_docs_link_text": "So betten Sie Google Docs ein", + "embed_link_google_docs_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-docs-file", + "embed_link_google_sheets": "Sheets", + "embed_link_google_sheets_desc": "Durch die Einbettung von Google Sheets können Sie Tabellen in AITable bearbeiten und anzeigen, um die Zusammenarbeit im Team zu erleichtern.", + "embed_link_google_sheets_link_text": "So betten Sie Google Sheets ein", + "embed_link_google_sheets_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-sheets-file", + "embed_link_jishi_design": "JSdesign", + "embed_link_jishi_design_desc": "Durch die Einbettung von JSdesign-Dateien können Mitglieder Designentwürfe bequemer anzeigen und bearbeiten und so die Effizienz der Zusammenarbeit verbessern.", + "embed_link_jishi_design_link_text": "So betten Sie JSdesign-Dateien ein", + "embed_link_jishi_design_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-js-design-file", + "embed_link_tencent_docs": "Tencent-Dokumente", + "embed_link_tencent_docs_desc": "Durch die Einbettung von Tencent-Dokumenten können Sie Tencent-Dokumente in Vika bearbeiten und anzeigen, um die Effizienz der Zusammenarbeit zu verbessern.", + "embed_link_tencent_docs_link_text": "So betten Sie Tencent-Dokumente ein", + "embed_link_tencent_docs_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-tencent-docs", + "embed_link_wps": "WPS", + "embed_link_wps_desc": "Durch das Einbetten von WPS-Dateien können Sie WPS-Dokumente, -Tabellen und -Formulare in Vika bearbeiten und anzeigen, um die Effizienz der Zusammenarbeit zu verbessern.", + "embed_link_wps_link_text": "So betten Sie WPS-Dateien ein", + "embed_link_wps_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-wps-file", + "embed_link_youtube": "Youtube", + "embed_link_youtube_desc": "Durch das Einbetten von YouTube-Videos können Sie Tutorials und Anleitungen ansehen oder die Kanal-Homepage in AITable anzeigen.", + "embed_link_youtube_link_text": "So betten Sie YouTube-Videos ein", + "embed_link_youtube_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-youtube-video", + "embed_page": "Benutzerdefinierte Seite", + "embed_page_add_url": "URL hinzufügen", + "embed_page_doc_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_page_function_desc": "Fügen Sie Webseiten zu ${edition} hinzu, um einfachen Zugriff auf Website-Dokumente, Videos und mehr von Drittanbietern zu erhalten. Sie können empfohlene Website-Links oder beliebige benutzerdefinierte Links hinzufügen.", + "embed_page_node_permission_editor": "Auf der Basis von „Nur aktualisieren“ kann auch die öffentliche Freigabe der Datei geöffnet werden", + "embed_page_node_permission_manager": "Kann alle Aktionen für die Datei ausführen", + "embed_page_node_permission_reader": "Kann den Inhalt der benutzerdefinierten Seite und grundlegende Dateiinformationen anzeigen", + "embed_page_node_permission_updater": "Auf der Basis von „schreibgeschützt“ kann auch der Link der benutzerdefinierten Seite geändert werden", + "embed_page_setting_title": "Fügen Sie eine benutzerdefinierte Seite hinzu", + "embed_page_url_invalid": "Bitte geben Sie die richtige URL ein", + "embed_paste_link_bilibili_placeholder": "Fügen Sie den Link zum Bilibili-Video ein", + "embed_paste_link_default_placeholder": "Fügen Sie die URL ein", + "embed_paste_link_figma_placeholder": "Fügen Sie den Freigabelink der Figma-Datei ein", + "embed_paste_link_google_docs_placeholder": "Fügen Sie den Freigabelink für Google Docs ein", + "embed_paste_link_google_sheets_placeholder": "Fügen Sie den Freigabelink für Google Sheets ein", + "embed_paste_link_jsdesign_placeholder": "Fügen Sie den Freigabelink der JSdesign-Datei ein", + "embed_paste_link_tencent_docs_placeholder": "Fügen Sie den Tencent Docs-Freigabelink ein", + "embed_paste_link_wps_placeholder": "Fügen Sie den Freigabelink der WPS-Datei ein", + "embed_paste_link_youtube_placeholder": "Fügen Sie den YouTube-Videolink ein", + "embed_success": "Erfolgreich hinzufügen", "emoji_activity": "Aktivitäten", "emoji_custom": "Benutzerdefiniert", "emoji_flags": "Flaggen", @@ -1751,6 +1882,11 @@ "estonia": "Estland", "ethiopia": "Äthiopien", "event_planning": "Veranstaltungsplanung", + "every": "Jeden", + "every_day_at": "Tag(e) um", + "every_hour_at": "Stunde(n) um", + "every_month_at": "Monat(e) am", + "every_week_at": "Jede Woche weiter", "everyday_life": "Alltag", "everyone_visible": "Für alle sichtbar", "exact_date": "exaktes Datum", @@ -1761,6 +1897,7 @@ "exchange": "Einlösen", "exchange_code_times_tip": "Hinweis: Der Einlösungscode kann nur einmal verwendet werden", "exclusive_consultant": "Exklusiver V+ Berater", + "exclusive_limit_plan_desc": "Exklusive begrenzte Stufe", "exist_experience": "Exit-Erfahrung", "exits_space": "Leerzeichen verlassen", "expand": "Erweitern", @@ -1787,7 +1924,7 @@ "expired": "Abgelaufen", "export": "Exportieren...", "export_brand_desc": "Bereitgestellt von", - "export_current_preview_view_data": "", + "export_current_preview_view_data": "Export current preview view data", "export_gantt_button_tips": "Export in eine .png-Datei", "export_gantt_chart": "Gantt-Diagramm exportieren", "export_to_excel": "Daten exportieren", @@ -2359,26 +2496,26 @@ "gantt_config_color_help": "Wie man einrichtet", "gantt_config_friday": "Freitag", "gantt_config_friday_in_bar": "Fr", - "gantt_config_friday_in_select": "Fr", + "gantt_config_friday_in_select": "Freitag", "gantt_config_monday": "Montag", "gantt_config_monday_in_bar": "Mo", - "gantt_config_monday_in_select": "Mo", + "gantt_config_monday_in_select": "Montag", "gantt_config_only_count_workdays": "Die Dauer zählt nur Arbeitstage.", "gantt_config_saturday": "Samstag", "gantt_config_saturday_in_bar": "Sa", - "gantt_config_saturday_in_select": "Sa", + "gantt_config_saturday_in_select": "Samstag", "gantt_config_sunday": "Sonntag", - "gantt_config_sunday_in_bar": "Sonne", - "gantt_config_sunday_in_select": "Sonne", + "gantt_config_sunday_in_bar": "So", + "gantt_config_sunday_in_select": "Sonntag", "gantt_config_thursday": "Donnerstag", "gantt_config_thursday_in_bar": "Do", - "gantt_config_thursday_in_select": "Do", + "gantt_config_thursday_in_select": "Donnerstag", "gantt_config_tuesday": "Dienstag", "gantt_config_tuesday_in_bar": "Di", - "gantt_config_tuesday_in_select": "Di", + "gantt_config_tuesday_in_select": "Dienstag", "gantt_config_wednesday": "Mittwoch", - "gantt_config_wednesday_in_bar": "Heiraten", - "gantt_config_wednesday_in_select": "Heiraten", + "gantt_config_wednesday_in_bar": "Mi", + "gantt_config_wednesday_in_select": "Mittwoch", "gantt_config_weekdays_range": "${weekday} bis ${weekday}", "gantt_config_workdays_a_week": "Kundenspezifische Standardarbeitstage", "gantt_cycle_connection_warning": "Invalid task dependency, there is a cycle connection\n", @@ -2459,6 +2596,7 @@ "gold_grade": "Gold", "gold_grade_desc": "Für Teams mit komplexen Geschäftsprozessen", "gold_seat_200_desc": "200", + "gold_seat_300_desc": "300", "golden_grade": "Gold", "got_it": "Hab's", "got_v_coins": "V-Münzen belohnt", @@ -2492,6 +2630,8 @@ "guests_per_space": "Gäste pro Raum", "guide_1": "啊这", "guide_2": "Es dauert nur wenige Minuten, um die grundlegenden Funktionen zu erlernen. Arbeiten Sie ab diesem Moment produktiver!", + "guide_flow_modal_contact_sales": "Kontaktieren Sie den Vertrieb", + "guide_flow_modal_get_started": "Loslegen", "guide_flow_of_catalog_step1": "Hier ist der Arbeitskatalog, in dem alle Ordner und Dateien des Space gespeichert sind.", "guide_flow_of_catalog_step2": "Im Arbeitskatalog können Sie nach Bedarf ein Datenblatt oder einen Ordner erstellen.", "guide_flow_of_click_add_view_step1": "Zusätzlich zu einigen grundlegenden Ansichten wird dringend empfohlen, eine Albumansicht zu erstellen, wenn Sie Anhänge im Bildformat haben.", @@ -2670,6 +2810,7 @@ "intro_widget_tips": "Was ist Widget?", "introduction": "Einleitung", "invalid_action_sort_tip": "Als Gruppierungsfeld wurde die Sortierung festgelegt. Die Einstellung der aktuellen Bestellung wird nicht wirksam.", + "invalid_automation_configuration": "Ungültige Automatisierungskonfiguration. Bitte überprüfen Sie und versuchen Sie es erneut", "invalid_field_type": "Ungültiger Feldtyp", "invalid_option_sort_tip": "Als Gruppierungsfeld wurde die Sortierung festgelegt.", "invalid_redemption_code_entered": "Ungültiger Einlösungscode", @@ -2800,6 +2941,9 @@ "label_format_day_month_and_year_split_by_slash": "Tag/Monat/Jahr", "label_format_month": "Monat", "label_format_month_and_day_split_by_dash": "Monatstag", + "label_format_month_day_year_split_by_dash": "Month-Day-Year", + "label_format_month_day_year_split_by_slash": "Month/Day/Year", + "label_format_month_day_year_two_digit_year_split_by_slash": "Month/Day/Year (Two-digit year)", "label_format_year": "Jahr", "label_format_year_and_month_split_by_dash": "Jahr Monat", "label_format_year_month_and_day_split_by_dash": "Jahr-Monat-Tag", @@ -2878,6 +3022,7 @@ "lark_version_enterprise": "Enterprise Plan mit Lark", "lark_version_standard": "Standardplan mit Lerche", "lark_versions_free": "Grundplan mit Lerche", + "last_day": "Letzter Tag", "last_modified_by_select_modal_desc": "Wenn eines der unten ausgewählten Felder bearbeitet wird, wird das zuletzt bearbeitete Mitglied im zuletzt bearbeiteten Feld angezeigt.", "last_modified_time_select_modal_desc": "Wenn eines der unten ausgewählten Felder bearbeitet wird, wird die zuletzt bearbeitete Zeit im zuletzt bearbeiteten Zeitfeld angezeigt.", "last_step": "Zurück", @@ -3022,7 +3167,7 @@ "mail_invite_fail": "Mail einladen Erfolg.", "mail_invite_success": "Mail einladen Erfolg.", "main_admin_name": "Name des Administrators", - "main_admin_page_desc": "Administratoren haben vollen Zugriff auf den Space, z. B. Zuweisung von Unteradministratoren und Übertragung des Eigentums an dem Space", + "main_admin_page_desc": "Administratoren haben vollen Zugriff auf den Space, z. B. zum Verwalten von Mitgliedern und zum Verwalten von Space-Einstellungen.", "main_contain": "Hauptinhalte", "malawi": "Malawi", "malaysia": "Malaysia", @@ -3242,8 +3387,12 @@ "more_widget": "Weitere Widgets", "morocco": "Marokko", "move": "Bewegen", + "move_datasheet_link_warn": "Cannot be moved to Team Area alone, because there is a two-way link from the current datasheet to another datasheet, it is recommended to put them in a folder and then move them", "move_favorite_node_fail": "Knotenbewegung fehlgeschlagen. Das System aktualisiert die Liste automatisch.", + "move_folder_link_warn": "Cannot be moved to Team Area because the files in the current folder are linked to files outside the folder (may be two-way links or linked by forms, etc.) We recommend that they be placed in a folder before moving", "move_node_modal_content": "Nach dem Verschieben kann die Sichtbarkeit der Datei durch den übergeordneten Ordner beeinträchtigt werden.", + "move_other_link_no_permission": "Unable to move to the corresponding folder because you do not have administrative rights to the folder", + "move_other_link_warn": "It is not allowed to move ${node type} to Team Area alone, because it connects to the datasheet of Private Area, it is recommended to put them in a folder before moving them", "move_to": "Verschieben nach", "move_to_error_equal_parent": "Die Datei befindet sich unter dem aktuellen Ordner. Bitte wählen Sie einen anderen Ordner", "move_to_modal_title": "[${name}] verschieben", @@ -3274,7 +3423,9 @@ "new_a_line": "Umschalt+Eingabetaste: Zeilenumbruch", "new_automation": "Neue Automatisierung", "new_caledonia": "Neukaledonien", + "new_custom_page": "New custom page", "new_datasheet": "Neues Datenblatt", + "new_ebmed_page": "Neue benutzerdefinierte Seite", "new_folder": "Neuer Ordner", "new_folder_btn_title": "Ordner", "new_folder_tooltip": "Ordner erstellen", @@ -3440,7 +3591,7 @@ "nvc_start_text": "Ziehen Sie die Leiste an das rechte Ende", "nvc_yes_text": "Verifiziert", "obtain_verification_code": "Überprüfungscode nicht erhalten oder abgelaufen", - "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrzw0miJVmSkJ7eBBa9k/fomx5qPX0JGPFvfEEP\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", + "offical_website_footer_nav_data": "[{ „title“: „产品“, „lists“: [{ „name“: „快速入门“, „url“: „https://help.vika.cn/docs/guide/tutorial-1-quick- start\" }, { \"name\": \"产品指南\", \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\" }, { \"name\": „产品价格“, „url“: „/pricing/“ }, { „name“: „产品路线图“, „url“: „https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5“ }] }, { \"title\": \"关于我们\", \"lists\": [{ \"name\": \"公司介绍\", \"url\": \"/company/\" }, { \"name\": \"加入我们\", \"url \": \"/join-us/\" }, { \"name\": \"媒体报道\", \"url\": \"/press/\" }, { \"name\": \"vika维格课堂\", \"url\": \"https ://edu.vika.cn/\" }, { \"name\": \"维格合伙人\", \"url\": \"/partners/\" }] }, { \"title\": \"解决方案\", \"lists\" : [{ \"name\": \"PMO项目群管理\", \"url\": \"/business-pmo/\" }, { \"name\": \"智慧电商运营\", \"url\": \"/ecommerce/\" }, { \"name\": \"CRM客户管理\", \"url\": \"/crm/\" }, { \"name\": \"HR人力资源管理\", \"url\": \"/hr/\" }, { \"name\": „Scrum敏捷开发管理“, „url“: „/scrum/“ }, { „name“: „营销策划与市场运营“, „url“: „/marketing/“ }, { „name“: „OKR目标管理\", \"url\": \"/okr/\" }, { \"name\": \"教育培训管理\", \"url\": \"/education/\" }, { \"name\": \"智慧门 Aliexpress管理\", \"url\" : \"/shop/\" }] }, { \"title\": \"支持\", \"lists\": [{ \"name\": \"意见反馈\", \"url\": \"https://vika.cn/share/shrCvbFC53xc3kl00B4Pg \" }, { \"name\": \"帮助中心\", \"url\": \"https://help.vika.cn/\" }, { \"name\": \"开发者中心\", \"url\": \"/developers/ \" }, { \"name\": \"服务条款\", \"url\": \"/service-agreement/\" }, { \"name\": \"隐私协议\", \"url\": \"/service-agreement/\" }, { \"name\": \"安全与合规\", \"url\": \"/security/\" }] }, { \"title\": \"服务\", \"lists\": [{ \"name\": \"加入社群\", \" url\": \"/chatgroup/\" }, { \"name\": \"Github开源\", \"url\": \"https://github.com/vikadata\" }, { \"name\": \"预约演示\", \"url\" : „https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef“ }, { „name“: „专有云部署“, „url“: „https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL“ } , { \"name\": \"应用连接\", \"url\": \"/connections/\" }] }, { \"title\": \"联系我们\", \"lists\": [{ \"name\": \"地址:深圳市南山区国信投资大厦1710\", \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\" }, { \"name\": \"售前咨询:点击联系商务\", \"url\": \"https: //vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\" }, { \"name\": \"合作:bd@vikadata.com\", \"url\": \"mailto:bd@vikadata.com\" }, { \"name\": \" Adresse: pr@vikadata.com, \"url\": \"mailto:pr@vikadata.com\" }, { \"name\": \"Adresse: hr@vikadata.com\", \"url\": \"mailto:hr@vikadata. com\" }] }]", "offical_website_nav_data": "[{\n \"name\": \"产品\",\n \"href\": \"/login\",\n \"children\": [\n {\n \"name\": \"vika维格表 Overview\",\n \"href\": \"/login/\"\n },\n {\n \"name\": \"应用连接 Integration\",\n \"href\": \"/connections/\"\n },\n {\n \"name\": \"客户端(Beta) Download\",\n \"href\": \"/download/\"\n }\n ]\n}, {\n \"name\": \"解决方案\",\n \"href\": \"/\",\n \"children\": [{\n \"name\": \"PMO项目群管理\",\n \"href\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"href\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"href\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"href\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"href\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"href\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"href\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"href\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"href\": \"/shop/\"\n }, {\n \"name\": \"更多解决方案 >\",\n \"href\": \"/solutions/\"\n }]\n}, {\n \"name\": \"模板/案例\",\n \"href\": \"/template\",\n \"children\": [\n {\n \"name\": \"模板中心 Tempaltes\",\n \"href\": \"/template\"\n },\n {\n \"name\": \"客户案例 Customers\",\n \"href\": \"/cases/\"\n }\n ]\n},\n {\n \"name\": \"首页\",\n \"href\": \"/?home=1\"\n },\n {\n \"name\": \"学习资源\",\n \"href\": \"https://edu.vika.cn/index\",\n \"children\": [\n {\n \"name\": \"快速入门 Tutorials\",\n \"href\": \"https://help.vika.cn/docs/guide/tutorial\"\n },\n {\n \"name\": \"产品手册 Manual\",\n \"href\": \"https://help.vika.cn/docs/guide/manual\"\n },\n {\n \"name\": \"维格课堂 Vika Education\",\n \"href\": \"https://edu.vika.cn/\"\n },\n {\n \"name\": \"维格社区 Vika BBS\",\n \"href\": \"https://bbs.vika.cn/\"\n },\n {\n \"name\": \"第三方连接 Integration\",\n \"href\": \"https://help.vika.cn/docs/guide/connection\"\n },\n {\n \"name\": \"开发者中心 Developer Center\",\n \"href\": \"/developers/\"\n },\n {\n \"name\": \"常见问题 FAQ\",\n \"href\": \"https://help.vika.cn/docs/guide/questions\"\n }\n ]\n }]", "office_preview": "Vorschau von Office-Dateien", "office_preview_app_desc": "

Smooth online preview of office files on datasheet, allowing you to view common office files such as Excel, Word, PPT, etc. on your desktop or mobile anywhere, anytime

\n\n
    \n
  • Online preview of .doc, .docx, .xls, .xlsx, .ppt, .pptx, and .pdf formatted office files
  • \n
  • Desktop and mobile both support file previews of the above formats
  • \n
\n\n

Additional notes:

\n
    \n
  • This feature is powered by \"Yoncentric Cloud Conversion\" and officially integrated
  • \n
  • Click the \"Enable\" button below to enable this integration and agree that \"Yoncentric Cloud Conversion\" reads the office files you want to preview
  • \n
  • If you no longer need the office files preview feature, the space admin can disable it on this page
  • \n
", @@ -3480,6 +3631,7 @@ "open_auto_save_success": "Automatisches Speichern der Ansicht wurde erfolgreich aktiviert", "open_auto_save_warn_content": "Alle Änderungen unter dieser Ansicht werden automatisch gespeichert und mit anderen Mitgliedern synchronisiert.", "open_auto_save_warn_title": "Automatisches Speichern aktivieren", + "open_automation_time_arrival": "https://aitable.ai/contact-sales-open-source", "open_failed": "Öffnen fehlgeschlagen", "open_in_new_tab": "in einer neuen Registerkarte öffnen", "open_invite_after_operate": "Einmal eingeschaltet, können alle Mitglieder über das Kontaktpanel neue Mitglieder einladen", @@ -3626,6 +3778,8 @@ "payment_record": "Zahlungsbilanz", "payment_reminder": "Zahlungserinnerung", "payment_reminder_content": "Der neue Tarif, den Sie ausgewählt haben, ist stärker abzugsfähig als der zu zahlende Betrag. Es wird empfohlen, dass Sie den neuen Plan mit einer längeren Laufzeit wählen. Wenn Sie dies bestätigen, wird der überschüssige Betrag nicht zurückerstattet. ${action} im Zweifel", + "payment_reminder_modal_content": "Sie können die erweiterte Version ausprobieren, um von mehr Dateiknoten, Unternehmensberechtigungen, Anhangskapazität, Datenvolumen, KI und anderen erweiterten Funktionen und Privilegien zu profitieren.", + "payment_reminder_modal_title": "Sie verwenden derzeit die kostenlose Version", "pending_invite": "Ausstehende Einladung", "people": "Mitglied(e)", "per_person_per_year": "Pro Person pro Jahr", @@ -3795,7 +3949,7 @@ "player_step_ui_config_168": "{\n\"templateKey\":\"createMirrorTip\"\n}", "player_step_ui_config_169": "{ „headerImg“: „https://s4.vika.cn/space/2023/04/04/bcf0695cf35840e6b85e032a8e5ea0a1“, „readMoreUrl“: „https://help.vika.cn/changelog/23-04-10- Updates\", \"Kinder\": \"

🚀 Einführung neuer Funktionen

\\N
  • Der neue Feldtyp „Cascader“ wird eingeführt, der die Auswahl aus einer Hierarchie von Optionen auf Formularen erleichtert
  • Das Widget „Skript“ wird veröffentlicht, weniger Code für mehr Anpassungsmöglichkeiten
  • Lösen Sie die Automatisierung aus, um E-Mails zu senden und schnelle Benachrichtigungen zu erhalten
  • Lösen Sie die Automatisierung aus, um eine Nachricht an Slack zu senden und Ihr Team rechtzeitig zu informieren
  • KI erforschen: Widget „GPT Content Generator“ veröffentlicht
\" }", "player_step_ui_config_17": "{\n \"element\": \"#TEMPLATE_CENTER_USE_TEMPLATE_BTN>button\", \n\"placement\": \"rightBottom\",\n\"offsetY\": 20,\n \"title\": \"How to use a template\", \n\"description\": \"Click the button on the left to use the template\", \"children\":\"\" \n}", - "player_step_ui_config_176": "{\"title\":\"Einführung in den AI agent\",\"video\":\"https://www.youtube.com/embed/cjds1r_roG8?si=irKUpMhwDlOEb8Hc\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", + "player_step_ui_config_176": "{\"title\": \"AITable.ai DEMO\", \"video\": \"https://www.youtube.com/embed/kGxMyEEo3OU\", \"videoId\": \"VIKA_GUIDE_VIDEO_FOR_AI\", \"autoPlay\":true}", "player_step_ui_config_18": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select>.ant-select-selector\", \n\"placement\": \"bottomLeft\",\n \"title\": \"How to use a template\", \n\"description\": \"Select where to put the template\", \"children\":\"\" \n}", "player_step_ui_config_19": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select .ant-select-selector\"\n}", "player_step_ui_config_2": "{\n \"config\": [\n {\n \"key\": 1,\n \"name\": \"answer1\",\n \"title\": \"What kind of issues are you looking forward to solved by vikadata?\",\n \"type\": \"checkbox\",\n \"answers\": [\n \"Work Planning\",\n \"Customer Service\",\n \"Project Management\",\n \"Sourcing Supply\",\n \"Content Production\",\n \"E-commerce operation\",\n \"Event Planning\",\n \"Human Resources\",\n \"Administration\",\n \"Financial Management\",\n \"Webcast\",\n \"Educational institutes Management\",\n \"Other\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 2,\n \"name\": \"answer2\",\n \"title\": \"Your job title is______\",\n \"type\": \"radio\",\n \"answers\": [\n \"General manager \",\n \"Project manager\",\n \"Product manager\",\n \"Designer\",\n \"R&D engineer\",\n \"Operator, editor\",\n \"Sales, customer service\",\n \"Human resource, administration \",\n \"Finance, accountant\",\n \"Lawyer, legal affairs\",\n \"Marketing\",\n \"Teacher\",\n \"Student\",\n \"Other\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 3,\n \"name\": \"answer3\",\n \"title\": \"What is the name of your company?\",\n \"type\": \"input\",\n \"submit\": false\n },\n {\n \"key\": 4,\n \"name\": \"answer4\",\n \"title\": \"Please leave your email address/ phone number/ Wechat account below so we can reach you in time when you need help.\",\n \"type\": \"input\",\n \"submit\": true\n },\n {\n \"key\": 5,\n \"title\": \"Thank you for filling out the form, you can add our customer service in case of need\",\n \"platform\": {\n \"website\": \"https://s4.vika.cn/space/2023/03/02/b34e3205a9154463be16f497524f1327\",\n \"dingtalk\": \"https://s4.vika.cn/space/2023/03/02/4b16cef6602a4586a21d6346bf25d300\",\n \"wecom\": \"https://s4.vika.cn/space/2023/03/02/60119b1b69b64aa887bd1be6a2928bec\",\n \"feishu\": \"https://u.vika.cn/z9ygm\"\n },\n \"type\": \"contactUs\",\n \"next\": true\n }\n ]\n}\n", @@ -3825,13 +3979,13 @@ "player_step_ui_config_41": "", "player_step_ui_config_42": "{\n \"element\": \"#DATASHEET_FORM_LIST_PANEL\", \n\"placement\": \"leftTop\",\n \"title\": \"Form\", \n\"description\": \"You can quickly create a form from the current view. The number and order of the fields in the form is consistent with the view.\", \"children\":\"\" \n}", "player_step_ui_config_43": "{\n \"element\": \".style_navigation__1U5cR .style_help__1sXEA\", \n\"placement\": \"rightBottom\",\n \"title\": \"Tip\", \n\"offsetY\":5,\n\"description\": \"You can find your Vikaby assistant from the \"Help\" icon on the left\", \"children\":\"\" \n}", - "player_step_ui_config_44": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", + "player_step_ui_config_44": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", "player_step_ui_config_45": "", "player_step_ui_config_46": "", "player_step_ui_config_47": "{\n \"element\": \"#DATASHEET_WIDGET_BTN\",\n\"placement\": \"bottomRight\",\n \"title\": \"Widget\", \n\"description\": \"Want to use and view your data in a richer way? Try the widget!\", \"children\":\"\" \n}", "player_step_ui_config_48": "", "player_step_ui_config_49": "{\n \"element\": \".style_widgetPanelContainer__1l2ZV\",\n\"placement\": \"leftCenter\",\n \"title\": \"What is a widget\", \n\"description\": \"Vika widgets are an extended application of vikadata that features in richer data visualization, data transfer, data cleansing, and more. By installing widgets in the widget board, you can make work a lot easier.\", \"children\":\"\" \n}", - "player_step_ui_config_5": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", + "player_step_ui_config_5": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", "player_step_ui_config_50": "{\n \"element\": \".style_widgetModal__eXmdB\",\n\"placement\": \"leftTop\",\n \"title\": \"Widget Center\", \n\"description\": \"Officially recommended and custom widgets are published here. You can install any widget you want onto a dashboard or into a widget board of any datasheet.\", \"children\":\"\" \n}", "player_step_ui_config_51": "{\n \"element\": \".style_widgetModal__eXmdB .style_widgetItem__3Pl-1 button\",\n\"placement\": \"rightBottom\",\n \"title\": \"Install widget\", \n\"description\": \"Let's install this \"Chart\" widget\", \"children\":\"\" \n}", "player_step_ui_config_52": "", @@ -3928,6 +4082,7 @@ "preview_guide_click_to_restart": "Klicken Sie auf die Schaltfläche unten, um eine Vorschau erneut anzuzeigen", "preview_guide_enable_it": "Drücken Sie die Taste unten, um diese Funktion einzuschalten", "preview_guide_open_office_preview": "Um eine Vorschau dieser Datei anzuzeigen, aktivieren Sie bitte die Funktion \"Office Preview\"", + "preview_next_automation_execution_time": "Vorschau der nächsten 10 Ausführungszeiten", "preview_not_support_video_codecs": "Nur MP4-Videos mit H.264-Videocodecs können in der Vorschau angezeigt werden", "preview_revision": "Vorschau", "preview_see_more": "Möchten Sie mehr über die Funktion \"Office File Preview\" erfahren? Bitte klicken Sie hier", @@ -3963,6 +4118,7 @@ "privacy_protection": "\"Datenschutz\"", "private_cloud": "Private Wolke", "private_external_person_only": "Nur externe Personen", + "private_help_link": "https://help.aitable.ai/docs/guide/team-and-private-area#private-area", "private_internal_person_only": "Nur interne Personen", "private_product_point": "Besitzen Sie Ihre APITable-Plattform mit einem Klick", "privatized_deployment": "Selbsthosted", @@ -4033,13 +4189,15 @@ "reconciled_data": "Daten werden abgeglichen", "record": "Aufzeichnung", "record_activity_experience_tips": "Sie können Aufzeichnungsaktivitäten von ${day} Tagen anzeigen", + "record_archived_data": "archivierter Datensatz", + "record_chunk_text": "${text} rows, please wait", "record_comment": "Nur Kommentare", "record_comments": "Kommentare", "record_fail_data": "Datenfehler", "record_filter_tips": "Dieser Datensatz wurde gefiltert", "record_functions": "Aufzeichnungsfunktion", "record_history": "Nur Revisionsverlauf", - "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-history", + "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-activity", "record_history_title": "Aufzeichnungsverlauf", "record_pre_filtered": "Dieser Datensatz wurde gefiltert und wird ausgeblendet, sobald Sie außerhalb des Datensatzes klicken", "record_pre_move": "Dieser Datensatz wird an eine andere Stelle verschoben, sobald Sie außerhalb des Datensatzes klicken", @@ -4479,6 +4637,12 @@ "scan_to_login": "Scannen, um sich anzumelden", "scan_to_login_by_method": "Bitte scannen Sie ${method}, um dem offiziellen Konto zu folgen, um sich anzumelden", "scatter_chart": "Streudiagramm", + "schedule_day_tips": "Die Zyklusberechnung beginnt mit dem Zählen ab dem ersten Tag jedes Monats. Wenn wir davon ausgehen, dass es sich alle 10 Tage wiederholt, dann wird es am 1., 11., 21. und 31. Tag jedes Monats ausgelöst", + "schedule_hour_tips": "Die Zyklusberechnung beginnt jeden Tag um Mitternacht (0:00). Unter der Annahme, dass alle drei Stunden 0 Minuten wiederholt werden, geschieht dies täglich um Mitternacht (0:00), 3 Uhr, 6 Uhr, 9 Uhr, 12 Uhr (12 Uhr), 15 Uhr, 18 Uhr und schließlich bei Einbruch der Dunkelheit (21 Uhr).", + "schedule_start_day": "Ab dem 1. Tag des Monats jeden", + "schedule_start_month": "Ab Januar jedes Jahres, jeden", + "schedule_type": "Zeitplantyp", + "schedule_year_tips": "Die Zyklusberechnung beginnt mit dem Zählen ab dem ersten Monat eines jeden Jahres. Unter der Annahme eines Intervalls von drei Monaten am ersten Tag werden Auslöser jedes Jahr am ersten Tag im Januar, April, Juli und Oktober um Mitternacht aktiviert.", "science_and_technology": "Wissenschaft und Technologie", "scroll_screen_down": "Einen Bildschirm nach unten scrollen", "scroll_screen_left": "Einen Bildschirm nach links scrollen", @@ -4492,6 +4656,7 @@ "search_folder_or_sheet": "Dateien suchen", "search_new_admin": "Suche", "search_node_pleaseholder": "Nach Dateien suchen (${shortcutKey})", + "search_node_tip": "Schnellsuche (${shortcutKey})", "search_or_add": "Eine Option suchen oder hinzufügen", "search_role_placeholder": "Rollen suchen", "seats": "Sitze", @@ -4895,6 +5060,7 @@ "space_info": "Übersicht", "space_info_del_confirm1": "1. Wenn Sie diesen Bereich löschen, werden die folgenden Daten bereinigt:", "space_info_del_confirm2": "2. Der Space wird nach sieben Tagen vollständig gelöscht. Sie können den Space vorher wiederherstellen.", + "space_info_del_confirm3": "3. For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "space_info_feishu_desc": "Sie verwenden eine Drittanbieterintegration. Um den Space zu löschen, deaktivieren Sie bitte zuerst die Integration von Drittanbietern.", "space_info_feishu_label": "Integrationen", "space_join_apply": " wurde angefordert, dem \"\" Raum beizutreten.", @@ -4981,6 +5147,7 @@ "start_onfiguration": "Konfiguration starten", "start_time": "Startzeit", "start_use": "Verwendung starten", + "starting_from_midnight": "Ab Mitternacht (00:00 Uhr) jeden Tag, jeden Tag", "startup": "Inbetriebnahme", "startup_company_support_program": "Starthilfeprogramm", "stat_average": "Durchschnittlich", @@ -5014,6 +5181,8 @@ "stay_tuned_for_more_features": "Bleiben Sie dran für weitere Funktionen", "steps_choose_reset_mode": "Wählen Sie eine Reset-Methode", "steps_validate_identities": "Identität überprüfen", + "stop_chunk_content": "Are you sure you want to stop the operation?", + "stop_chunk_title": "Stop", "stop_dingtalk_h5_modal_content": "Die selbst erstellte Anwendung wird von diesem Raum entbunden. Bitte bestätigen Sie .", "storage_per_seats": "", "storage_per_space": "Speichernutzung", @@ -5044,9 +5213,11 @@ "subscribe_credit_usage_over_limit": "Die Anzahl der Guthaben, die in diesem Bereich sind, die das Limit überschreiten, werden verwendet.\n", "subscribe_demonstrate": "Demos anfordern", "subscribe_disabled_seat": "Die Anzahl der Personen darf nicht niedriger sein als das ursprüngliche Programm", + "subscribe_grade_business": "Geschäft", "subscribe_grade_free": "Frei", "subscribe_grade_plus": "Plus", "subscribe_grade_pro": "Profi", + "subscribe_grade_starter": "Anlasser", "subscribe_label_tooltip": "Erweiterte Raumfunktionen", "subscribe_new_choose_member": "Unterstützt bis zu ${member_num} Members", "subscribe_new_choose_member_tips": "Dieser Plan unterstützt 1~${member_num} Mitglieder, um den Raum zu betreten", @@ -5183,7 +5354,7 @@ "template_name_repetition_title": "\"${templateName}\" existiert bereits. Wollen Sie es ersetzen?", "template_no_template": "Keine Vorlagen", "template_not_found": "Sie können die gewünschten Vorlagen nicht finden? Sagen Sie uns", - "template_recommend_title": "Heiß", + "template_recommend_title": "🌟 Hot", "template_type": "Vorlage", "terms_of_service": "", "terms_of_service_pure_string": "Nutzungsbedingungen", @@ -5227,6 +5398,7 @@ "text_editor_tip_end": "\"Enter\" zum Beenden der Bearbeitung", "text_functions": "Zeichenfolgenfunktion", "thailand": "Thailand", + "the_button_field_is_misconfigured": "Das Schaltflächenfeld ist falsch konfiguriert. Bitte überprüfen Sie es und versuchen Sie es erneut", "the_current_automation_workflow_has_no_related_files_you_can_establish_a_link_by_adding_trigger_conditions_and_actions_on_the_left_side": "Der aktuelle Automatisierungsprozess hat keine verwandten Dokumente. Sie können eine Verbindung herstellen, indem Sie Triggerbedingungen und -Aktionen auf der linken Seite hinzufügen", "the_current_button_column_has_expired_please_reselect": "Die aktuelle Schaltflächenspalte ist abgelaufen. Bitte wählen Sie sie erneut aus", "the_last_7_days": "die letzten sieben Tage", @@ -5329,6 +5501,7 @@ "timemachine_update_comment": "aktualisierte(r) Kommentar(e)", "times_per_month_unit": "Aufruf/Monat", "times_unit": "Aufruf(e)", + "timing_rules": "Zeitliche Koordinierung", "timor_leste": "Timor-Leste", "tip_del_success": "Sie können Ihren Space innerhalb von 7 Tagen wiederherstellen", "tip_do_you_want_to_know_about_field_permission": "Möchten Sie Felddaten verschlüsseln? Erfahren Sie mehr über Feldberechtigungen", @@ -5516,6 +5689,7 @@ "verify_account_title": "Konto verifizieren", "verify_via_email": "Identitätsprüfung per E-Mail", "verify_via_phone": "Identitätsprüfung per SMS", + "video": "Video", "video_not_support_play": "Das aktuelle Videoformat unterstützt keine Online-Wiedergabe", "vietnam": "Vietnam", "view": "Ansicht", @@ -5864,7 +6038,8 @@ "workdoc_color_title": "Schriftfarbe", "workdoc_create": "Arbeitsdokument erstellen", "workdoc_expanded": "Erweitern Sie das Inhaltsverzeichnis", - "workdoc_image_max_10mb": "Die Bildgröße darf 10 MB nicht überschreiten", + "workdoc_image_max_10mb": "Null", + "workdoc_image_max_size": "Die Bildgröße darf ${size} nicht überschreiten", "workdoc_info": "WorkDoc Info", "workdoc_info_create_time": "Hergestellt in", "workdoc_info_creator": "Erstellt von", @@ -5872,6 +6047,7 @@ "workdoc_info_last_modify_time": "Zuletzt geändert um", "workdoc_link_placeholder": "Bitte geben Sie den Link ein", "workdoc_only_image": "Es ist nur ein Bild erlaubt", + "workdoc_only_video": "Es sind nur Videos erlaubt", "workdoc_text_placeholder": "Geben Sie „/“ Schnellstart ein", "workdoc_title_placeholder": "Bitte Titel eingeben", "workdoc_unnamed": "Unbenanntes Arbeitsdokument", @@ -5880,9 +6056,11 @@ "workdoc_unsave_ok": "Änderungen verwerfen", "workdoc_unsave_title": "Das WorkDoc wurde nicht gespeichert", "workdoc_upload_failed": "Upload fehlgeschlagen", + "workdoc_video_max_size": "Die Videogröße darf ${size} nicht überschreiten", "workdoc_ws_connected": "In Verbindung gebracht", "workdoc_ws_connecting": "Verbinden...", "workdoc_ws_disconnected": "Getrennt", + "workdoc_ws_reconnecting": "Verbindung wird wieder hergestellt...", "workflow_execute_failed_notify": " konnte bei nicht ausgeführt werden. Bitte überprüfen Sie den Ausführungsverlauf, um das Problem zu beheben. Wenn Sie Hilfe benötigen, wenden Sie sich bitte an unser Kundendienstteam.", "workspace_data": "Weltraumdaten", "workspace_files": "Workbench-Daten", @@ -5973,7 +6151,7 @@ "add_cover": "Add cover", "add_dashboard": "New dashboard", "add_datasheet_editor": "In addition to \"Update-only\", can also add or delete views and delete records", - "add_datasheet_manager": "Can perform all actions on the file", + "add_datasheet_manager": "Can perform all actions on the file node", "add_datasheet_reader": "Can read data or comment on the datasheet", "add_datasheet_updater": "Can read, add and edit records except deleting records", "add_editor": "Editor", @@ -5981,9 +6159,9 @@ "add_filter": "Add filter", "add_filter_condition_tips": "Pick a field to Filter", "add_filter_empty": "Pick another field to Filter", - "add_folder_editor": "In addition to \"Update-only\", can also edit and share files", - "add_folder_manager": "Can perform all actions to the file", - "add_folder_reader": "Can read files in the folder", + "add_folder_editor": "In addition to \"Update-only\", can also edit and share file nodes", + "add_folder_manager": "Can perform all actions to the file node", + "add_folder_reader": "Can read file nodes in the folder", "add_folder_updater": "Can read, add and edit records except deleting records", "add_form": "New form", "add_form_logo": "Add logo", @@ -6032,7 +6210,7 @@ "add_sub_admin_template_configuration": "The sub-admin can delete the Space templates", "add_sub_admin_title_member_team": "Members and teams ", "add_sub_admin_title_workbench": "Workbench", - "add_sub_admin_workbench_configuration": "The sub-admins have the highest authority of all files in \"Workbench\", and can add, delete, modify and set permissions on files", + "add_sub_admin_workbench_configuration": "The sub-admins have the highest authority of all file nodes in \"Workbench\", and can add, delete, modify and set permissions on file nodes", "add_summry_describle": "Add summary describe", "add_target_values": "Add target value", "add_team": "Add team", @@ -6061,6 +6239,15 @@ "agreed": "Approved", "ai_advanced_mode_desc": "Advanced mode allows users to customize prompts, providing greater control over the behavior and responses of the AI agent.", "ai_advanced_mode_title": "Advanced mode", + "ai_agent_anonymous": "Anonymous${ID}", + "ai_agent_conversation_continue_not_supported": "Continuing a previous conversation is not currently supported", + "ai_agent_conversation_list": "Conversation list", + "ai_agent_conversation_log": "Conversation Log", + "ai_agent_conversation_title": "Conversation title", + "ai_agent_feedback": "Feedback", + "ai_agent_historical_message": "The above is historical message", + "ai_agent_history": "History", + "ai_agent_message_consumed": "Message consumed", "ai_api_curl_template": "## Create chat completions\n\n```bash\n\ncurl -X POST \"{{apiBase}}/fusion/v1/ai/{{aiId}}/chat/completions\" \\\n -H \"Content-Type: application/json\" \\\n -H \"Authorization: Bearer {{token}}\" \\\n -d '{\n \"model\": \"gpt-3.5-turbo\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"You are a helpful assistant.\"\n },\n {\n \"role\": \"user\",\n \"content\": \"Hello!\"\n }\n ]\n }'\n\n```\n\n## Returned data example\n\n```json\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", "ai_api_footer_desc": "Embed the AI agent into your website? Learn more", "ai_api_javascript_template": "## Initialize SDK [![github]({{ githubIcon }})](https://github.com/openai/openai-node)\nAITable's chat completion API is compatible with OpenAI's Node.js SDK. You can use our service with the same SDK by simply changing the configuration as follows:\n\n\n```javascript\nconst { Configuration, OpenAIApi } = require(\"openai\");\nconst configuration = new Configuration({\n apiKey: \"{{token}}\",\n basePath: \"{{apiBase}}/fusion/v1/ai/{{aiId}}\"\n});\n```\n\n## Create chat completions\n\n```javascript\nconst openai = new OpenAIApi(configuration);\nconst chatCompletion = await openai.createChatCompletion({\n model: \"gpt-3.5-turbo\",\n messages: [{role: \"user\", content: \"Hello world\"}],\n});\n```\n\n## Returned data example\n\n```javascript\n\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", @@ -6076,6 +6263,9 @@ "ai_chat_unit": "aibot(s)", "ai_close_setting_tip_content": "You have made changes. Do you want to discard them?", "ai_close_setting_tip_title": "Unsaved changes", + "ai_copilot_generate_response": "Generating answer for you...", + "ai_copilot_processs": "Processing, please wait...", + "ai_copilot_start_process_request": "Starting to process your request...", "ai_create_guide_btn_text": "Select datasheet", "ai_create_guide_content": "As an AI agent, I can answer your questions based on the knowledge I have learned. Before starting the conversation, please select a datasheet as a knowledge base, and I will read all the data in it for learning.", "ai_credit_cost_chart_title": "Message credit", @@ -6339,7 +6529,7 @@ "api_param_api_btn_type_error": "the parameter apiBtn must be a boolean type", "api_param_attachment_array_type_error": "Attachment type must be array", "api_param_attachment_name_type_error": "Attachment name must be string", - "api_param_attachment_not_exists": "The file specified by the token does not exist", + "api_param_attachment_not_exists": "The attachment specified by the token does not exist", "api_param_attachment_token_type_error": "Attachment token must be string", "api_param_basic_tools_type_error": "the parameter bannerLogo must be a boolean type", "api_param_checkbox_field_type_error": "field:{field} Checkbox field value must be boolean", @@ -6537,11 +6727,11 @@ "apply_space_beta_feature_success_notify_all": "'s application for enabling the beta feature \"\" has been approved. For details, go to \"Account\" -> \"Experimental features\".", "apply_space_beta_feature_success_notify_me": "Your application for enabling the beta feature \"\" has been approved. For details, go to \"Account\" -> \"Beta Feature\".", "apply_template": "Use template", - "appoint_permission_tip": "Only members below have access to this file", + "appoint_permission_tip": "Only members below have access to this file node", "apps_support": "All-platform client support", "archive_delete_record": "Delete archived records", "archive_delete_record_title": "Delete record", - "archive_notice": "

You are trying to archive specific records. Archiving the records will result in the following changes:

1. All two-way link for this record will be canceled

2. Editing is not supported

3. Functions such as date reminders and subscribe records are not supported

4. No longer participate in the calculation of lookup, formula and other fields

Are you sure you want to continue? (You can unarchive in Archive Box in Advanced)

", + "archive_notice": "

You are trying to archive specific records. Archiving the records will result in the following changes:

1. Editing is not supported

2. Functions such as date reminders and subscribe records are not supported

3. No longer participate in the calculation of lookup, formula and other fields

Are you sure you want to continue? (You can unarchive in Archive Box in Advanced)

", "archive_record_in_activity": " archived this record", "archive_record_in_menu": "Archive record", "archive_record_success": "Successfully archived records", @@ -6599,30 +6789,36 @@ "attachment_upload_fail": "Failed to upload ${count} attachment(s)", "audit_add_field_role": "Add field permissions", "audit_add_field_role_detail": "In the \"\" datasheet , add [] role as [] for the field [] ", - "audit_add_node_role": "Add file permissions", - "audit_add_node_role_detail": "Add file permission,set「${unitNames}」to「${role}」of 「${currentNodeName}」", + "audit_add_node_role": "Add file node permissions", + "audit_add_node_role_detail_end": "to「${role}", + "audit_add_node_role_detail_start": "Add file node permission,set「${unitNames}」", "audit_admin_permission_change_event": "Change admin permissions", "audit_create_template": "Create template", "audit_create_template_detail": "Create template", "audit_datasheet_field_permission_change_event": "Field permissions changed", "audit_delete_field_role": "Delete field permissions", "audit_delete_field_role_detail": "Audit", - "audit_delete_node_role": "Delete file permission", - "audit_delete_node_role_detail": "Delete file permission,delete「${unitNames}」`s 「${role}」role of 「${currentNodeName}」", + "audit_delete_node_role": "Delete file node permission", + "audit_delete_node_role_detail_end": "at 「${role}」role", + "audit_delete_node_role_detail_start": "Delete file node permission,delete「${unitNames}」from", "audit_delete_template": "Delete template", "audit_delete_template_detail": "Delete template", "audit_disable_field_role": "Disable field permissions", "audit_disable_field_role_detail": "Audit", - "audit_disable_node_role": "Disable file permissions", - "audit_disable_node_role_detail": "Disable ${nodeType} 「${currentNodeName}」 `s permission", - "audit_disable_node_share": "Close file public link", - "audit_disable_node_share_detail": "Close ${nodeType} 「${currentNodeName}」 public link", + "audit_disable_node_role": "Disable file node permissions", + "audit_disable_node_role_detail_end": "`s permission", + "audit_disable_node_role_detail_start": "Disable ${nodeType}", + "audit_disable_node_share": "Close file node public link", + "audit_disable_node_share_detail_end": "public link", + "audit_disable_node_share_detail_start": "Close ${nodeType}", "audit_enable_field_role": "Enable field permissions", "audit_enable_field_role_detail": "Audit", - "audit_enable_node_role": "Enable file permissions", - "audit_enable_node_role_detail": "Enable ${nodeType} 「${currentNodeName}」 `s permission", - "audit_enable_node_share": "Open file public link", - "audit_enable_node_share_detail": "Open ${nodeType} 「${currentNodeName}」 public link", + "audit_enable_node_role": "Enable file node permissions", + "audit_enable_node_role_detail_end": "`s permission", + "audit_enable_node_role_detail_start": "Enable ${nodeType}", + "audit_enable_node_share": "Open file node public link", + "audit_enable_node_share_detail_end": "public link", + "audit_enable_node_share_detail_start": "Open ${nodeType}", "audit_login_event": "Login event", "audit_logout_event": "english", "audit_organization_change_event": "The organizational structure of the contacts has changed", @@ -6641,20 +6837,21 @@ "audit_space_entry_workbench_detail": "Member ${member_name} joined the space \n${space_name}", "audit_space_invite_user": "Audit", "audit_space_invite_user_detail": "Audit", - "audit_space_node_copy": "Duplicate file", - "audit_space_node_copy_detail": "Duplicate ${nodeType} 「${sourceNodeName}」, the new file's name is 「${currentNodeName}」", - "audit_space_node_create": "Create file", - "audit_space_node_create_detail": "Create a ${nodeType} named 「${currentNodeName}」", - "audit_space_node_delete": "Delete file", - "audit_space_node_delete_detail": "Delete ${nodeType} named 「${currentNodeName}」", + "audit_space_node_copy": "Duplicate file node", + "audit_space_node_copy_detail_start": "Duplicate ${nodeType} 「${sourceNodeName}」, the new file node's name is", + "audit_space_node_create": "Create file node", + "audit_space_node_create_detail_start": "Create a ${nodeType} named", + "audit_space_node_delete": "Delete file node", + "audit_space_node_delete_detail_start": "Delete ${nodeType} named", "audit_space_node_export": "Export datasheet", "audit_space_node_export_detail": "Member ${member_name} exported datsheet ${node_name}", - "audit_space_node_import": "Import file", - "audit_space_node_import_detail": "Import a file named 「${nodeName}」", - "audit_space_node_move": "Move file", - "audit_space_node_move_detail": "Move ${nodeType} 「${currentNodeName}」to the folder「${parentName}」", - "audit_space_node_rename": "Rename file", - "audit_space_node_rename_detail": "Rename ${nodeType} 「${oldNodeName}」to 「${nodeName}」", + "audit_space_node_import": "Import file node", + "audit_space_node_import_detail_start": "Import a file node named", + "audit_space_node_move": "Move file node", + "audit_space_node_move_detail_end": "to the folder「${parentName}」", + "audit_space_node_move_detail_start": "Move ${nodeType}", + "audit_space_node_rename": "Rename file node", + "audit_space_node_rename_detail_start": "Rename ${nodeType} 「${oldNodeName}」to", "audit_space_node_sort": "Audit", "audit_space_node_sort_detail": "Audit", "audit_space_node_update_cover": "Audit", @@ -6667,19 +6864,22 @@ "audit_space_rename_detail": "Audit", "audit_space_rubbish_node_delete": "Audit", "audit_space_rubbish_node_delete_detail": "Audit", - "audit_space_rubbish_node_recover": "Restore files", - "audit_space_rubbish_node_recover_detail": "Restore ${nodeType} 「${currentNodeName}」 form the trash", + "audit_space_rubbish_node_recover": "Restore file nodes", + "audit_space_rubbish_node_recover_detail_end": "from the trash", + "audit_space_rubbish_node_recover_detail_start": "Restore ${nodeType}", "audit_space_template_event": "Template change", "audit_space_update_logo": "Audit", "audit_space_update_logo_detail": "Audit", - "audit_store_share_node": "Save shared file", - "audit_store_share_node_detail": "Restore ${nodeType} to the space, name is 「${nodeName}」", + "audit_store_share_node": "Save shared file node", + "audit_store_share_node_detail_start": "Restore ${nodeType} to the space, name is", "audit_update_field_role": "Audit", "audit_update_field_role_detail": "Audit", - "audit_update_node_role": "Modify file permission", - "audit_update_node_role_detail": "Modify file permission,modify「${unitNames}」`s role to「${role}」of 「${currentNodeName}」", - "audit_update_node_share_setting": "Modify file public link settings", - "audit_update_node_share_setting_detail": "Modify ${nodeType} 「${currentNodeName}」 public link", + "audit_update_node_role": "Modify file node permission", + "audit_update_node_role_detail_end": "to「${role}」role", + "audit_update_node_role_detail_start": "Modify file node permission,modify「${unitNames}」from", + "audit_update_node_share_setting": "Modify file node public link settings", + "audit_update_node_share_setting_detail_end": "public link settings", + "audit_update_node_share_setting_detail_start": "Modify ${nodeType}", "audit_user_login": "User login", "audit_user_login_detail": "Audit", "audit_user_logout": "User logout", @@ -6689,7 +6889,7 @@ "audit_user_quit_space_detail": "Audit", "audit_work_catalog_change_event": "english", "audit_work_catalog_permission_change_event": "Explorer permissions changed", - "audit_work_catalog_share_event": "Sharing events of files in Explorer", + "audit_work_catalog_share_event": "Sharing events of file nodes in Explorer", "augmented_views": "Augmented Views", "australia": "Australia", "austria": "Austria", @@ -6718,9 +6918,10 @@ "automation_editor_label": "Can edit steps in automation and viewing the run history of the automation", "automation_empty_warning": "Automation cannot be empty", "automation_enabled": "Automation is enabled", - "automation_enabled_return_via_related_files": "Automation is enabled. Please re-enter the original table via \"Related Files\" to use the new button.", + "automation_enabled_return_via_related_files": "Automation is enabled. Please re-enter the original table via \"Related File nodes\" to use the new button.", "automation_field": "Field", "automation_import_variables_from_pre_tep": "Get data from the pre-step", + "automation_is_not_yet_enabled": "Automation is not yet enabled, please enable it and try again", "automation_last_edited_by": "Last edited by", "automation_last_edited_time": "Last edited time", "automation_manager_label": "Can perform all actions on the automation", @@ -6842,10 +7043,19 @@ "button_text": "Button text", "button_text_click_start": "Click to Start", "button_type": "Button Type", + "by_at": "at", + "by_days": "Days", + "by_every": "every", "by_field_id": "Use field ID", + "by_hours": "Hours", + "by_in": " at", + "by_min": "minute(s)", + "by_months": "Months", + "by_on": " on the", "by_the_day": "By day", "by_the_month": "Monthly", "by_the_year": "Yearly", + "by_weeks": "Weeks", "calendar_add_date_time_field": "Create Date field", "calendar_color_more": "More colors", "calendar_const_detail_weeks": "[\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\",\"Sunday\"]", @@ -6908,7 +7118,15 @@ "cannot_access": "Can Access", "cannot_activate_space_by_space_limit": "cannot_activate_space_by_space_limit", "cannot_join_space": "You can't join a new space station because you've exceeded the maximum quota of 10 space stations.", - "cannot_switch_field_permission": "Set field permissions not higher than the file permissions. ", + "cannot_switch_field_permission": "Set field permissions not higher than the file node permissions. ", + "capacity_file_detail_desc": "The total number of file nodes within the Space is calculated by adding the file nodes from the Team to the file nodes created by each member in their Private. Not enough capacity?", + "capacity_file_detail_title": "File Capacity", + "capacity_file_member": "Member", + "capacity_file_member_private_node_count": "Private", + "capacity_file_member_private_percent": "Percent", + "capacity_file_member_team": "Team", + "capacity_file_member_team_node_count": "Team", + "capacity_file_upgrade": "Click to upgrade your Space", "capacity_from_official_gift": "From the official gift", "capacity_from_participation": "By invited ${user} join the space", "capacity_from_purchase": "By purchasing capacity", @@ -6944,7 +7162,9 @@ "cascader_undefined_field_error": "There exists unselected field. Please select the field and try again", "catalog": "Explorer", "catalog_add_from_template_btn_title": "Add from templates", - "catalog_empty_tips": "This workspace is empty now. Get started by using templates to create files.", + "catalog_empty_tips": "This workspace is empty now. Get started by using templates to create file nodes.", + "catalog_private": "Private", + "catalog_team": "Team", "category_blank": "[Blank]", "catering": "Catering", "cayman_islands": "Cayman Islands", @@ -7013,6 +7233,7 @@ "choose_type_of_vika_field": "Select field type", "choose_your_own_space": "(Only supports saving to your own space as creator)", "chose_new_primary_admin_button": "Assign", + "chunk_stopping_title": "Stopping", "claim_special_offer": "Claim This Special Offer!", "clear": "Clear", "clear_all_fields": "Clear all", @@ -7032,9 +7253,9 @@ "click_top_right_to_share": "Click on the top right to share", "click_upload_tip": "Click here to paste an attachment", "client_meta_label_desc": "APITable - a data productivity platform that helps you manage your work data more efficiently", - "client_meta_label_file_deleted_desc": "The shared file is deleted, so the public share link is invalid", - "client_meta_label_file_deleted_title": "Invalid shared file", - "client_meta_label_share_disable_desc": "The shared public link is disabled so you can't access the file", + "client_meta_label_file_deleted_desc": "The shared file node is deleted, so the public share link is invalid", + "client_meta_label_file_deleted_title": "Invalid shared file node", + "client_meta_label_share_disable_desc": "The shared public link is disabled so you can't access the file node", "client_meta_label_share_disable_title": "Can't access", "client_meta_label_template_deleted_desc": "The template does not exist or is deleted, so the share link is invalid", "client_meta_label_template_deleted_title": "Invalid shared template", @@ -7050,7 +7271,7 @@ "close_node_share_modal_content": "After disabling the sharing, the generated share link will become invalid", "close_node_share_modal_title": "Close the sharing of this node", "close_permission": "Restore default", - "close_permission_warning_content": "all members and teams will see the file, and the set permissions will be closed at the same time", + "close_permission_warning_content": "all members and teams will see the file node, and the set permissions will be closed at the same time", "close_public_link_success": "Disable public link successfully", "close_share_link": "Disable public link", "close_share_tip": "Disable sharing ${status}", @@ -7143,6 +7364,7 @@ "confirm_del_current_team": "Are you sure you want to delete the team?", "confirm_delete": "Confirm and delete", "confirm_delete_node_name_as": "Are you sure you want to delete \"${nodeNameDiv}\"?", + "confirm_delete_private_node_name_as": "Are you sure you want to delete \"${nodeNameDiv}\"? The file will be deleted from the Space and the trash.", "confirm_delete_space_btn": "Confirm and delete Space", "confirm_exit": "Confirm to exit", "confirm_exit_space_with_name": "Confirm whether to exit the \"${spaceNameDiv}\" Space", @@ -7180,6 +7402,14 @@ "convert": "Convert", "convert_tip": "This action may clear up data in some cells. You can undo the action if anything unexpected happens.", "cook_islands": "Cook Islands", + "copilot_auto_agent_desc": "Not sure which one to choose Agent? Try AutoAgent.", + "copilot_auto_agent_name": "Auto Agent", + "copilot_data_agent_desc": "generate visualizations/data analysis based on your views.", + "copilot_data_agent_name": "Data Agent", + "copilot_data_agent_policy": "When chatting with Copilot, you agree to the user terms policy", + "copilot_data_agent_policy_button": "Policy", + "copilot_help_agent_desc": "Ask anything about AITable's help center documents .", + "copilot_help_agent_name": "Retrieve Help Center", "copy": " Copy", "copy_automation_url": "Copy URL", "copy_card_link": "Copy record URL", @@ -7214,7 +7444,7 @@ "create": "Create", "create_and_save": "Create and save", "create_date": "Creation date", - "create_file_and_folder": "Create a new file or folder", + "create_file_and_folder": "Create a new file node or folder", "create_form": "Create form", "create_form_panel_title": "Select a datasheet to store form data", "create_invitation_link": "Create Invitation Link", @@ -7224,6 +7454,7 @@ "create_mirror_guide_content": "The mirror function has the ability to hide certain data. You can set \"filter conditions\" and \"hidden fields\" in the original datasheet view to control which records and fields are displayed in the mirror.\n
\n
\nIf used in conjunction with the \"view lock\" function, it can prevent others from making modifications.\n
\n
\nIn addition, you can go to \"Original Table>Hidden Fields\" to modify the configuration for \"Show all fields in Mirrors\".", "create_mirror_guide_title": "Mirror hides some records and fields", "create_new_button_field": "Create a new button column field", + "create_private_node_tip": "Personal or temporary draft documents can be created here ${link}", "create_public_invitation_link": "Create public invitation link(s)", "create_space_sub_title": "Hi, please give a name to your Space~", "create_team_fail": "Create team failed", @@ -7274,7 +7505,7 @@ "current_count_of_person": "Total Seats", "current_datasheet": "Current datasheet", "current_field_fail": "The data went wrong in this field", - "current_file_may_be_changed": "Status of current file has changed", + "current_file_may_be_changed": "Status of current file node has changed", "current_form_is_invalid": "The form is invalid because the original view has been deleted", "current_grade": "Current", "current_main_admin": "Current admin", @@ -7287,10 +7518,12 @@ "custom_enterprise": "Customize enterprise space for you", "custom_function_development": "Custom feature development", "custom_grade_desc": "Provides agent deployment, private installation, assistance support and customized professional services", + "custom_page_setting_title": "Add a custom page", "custom_picture": "Customized picture", "custom_style": "Style", "custom_upload": "Customized upload", "custom_upload_tip": "A 1:1 square size image is recommended for the better visual experience", + "custome_page_title": "Custom Web", "cut_cell_data": "Cut cell(s)", "cyprus": "Cyprus", "czech": "Czech", @@ -7307,7 +7540,7 @@ "datasheet": "Datasheet", "datasheet_1000_rows_limited_tips": "Your datasheet has the maximum number of records", "datasheet_choose_field_type": "Select field type", - "datasheet_count": "Total Files", + "datasheet_count": "Total File nodes", "datasheet_editor_label": "In addition to \"Update-only\", can also add or delete views and delete records", "datasheet_exist_widget": "The datasheet has installed these widgets:", "datasheet_experience_label": "Use the template first, then you can modify or write data", @@ -7342,9 +7575,10 @@ "default": "Default", "default_create_ai_chat_bot": "New AI agent", "default_create_automation": "New automation", + "default_create_custom_page": "New Custom Page", "default_create_dashboard": "New dashboard", "default_create_datasheet": "New datasheet", - "default_create_file": "New file", + "default_create_file": "New file node", "default_create_folder": "New folder", "default_create_form": "New form", "default_create_mirror": "New mirror", @@ -7363,7 +7597,8 @@ "del_invitation_link": "Delete invitation link", "del_invitation_link_desc": "The link will be invalid after deletion", "del_space_now": "Delete Space forever", - "del_space_now_tip": "The Space can't be restored after deletion. All files and attachments will be deleted.", + "del_space_now_confirm_tip": "For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", + "del_space_now_tip": "The Space can't be restored after deletion. All file nodes and attachments will be deleted.", "del_space_res_tip": "The Space deleted", "del_team_success": "Delete Team Success", "del_view_content": "Are you sure you want to delete the ${view_name} view?", @@ -7373,12 +7608,12 @@ "delete_comment_tip_content": "The comment can't be restored after deletion. Continue?", "delete_comment_tip_title": "Delete comment", "delete_completey": "Delete forever", - "delete_completey_fail": "Failed to delete file (folder) forever", + "delete_completey_fail": "Failed to delete file node (folder) forever", "delete_field": "Delete field", "delete_field_success": "Field deleted", "delete_field_tips_content": "Are you sure you want to delete the \"${field_title}\" field?", "delete_field_tips_title": "Delete field", - "delete_file_message_content": "The file has been deleted and you can no longer access it.", + "delete_file_message_content": "The file node has been deleted and you can no longer access it.", "delete_kanban_group": "Delete group", "delete_kanban_tip_content": "All records in this group will be moved to the uncategorized group", "delete_kanban_tip_title": "Delete group", @@ -7477,7 +7712,7 @@ "dingtalk_social_deactivate_tip": "If you need to disable the application, please go to DingTalk Admin Panel -> Applications -> 维格表.", "dingtalk_space_list_item_tag_info": "DingTalk binding", "dingtalk_standard": "Standard Plan with DingTalk", - "dingtalk_sync_address_modal_content": "After manually synchronizing the address book, you need to reassign administrators, file permissions and column permissions for members and departments. Please know", + "dingtalk_sync_address_modal_content": "After manually synchronizing the address book, you need to reassign administrators, file node permissions and column permissions for members and departments. Please know", "dingtalk_tenant_not_exist_tips": "The enterprise didn't authorized, please contact the administrator", "direction_above": "above", "direction_below": "below", @@ -7558,6 +7793,61 @@ "embed_error_page_help": "Learn more", "embed_fail_og_description_content": "The public link for this embed has been disabled and is temporarily unavailable", "embed_failed": "Embed link is unavailable, ", + "embed_link_bilibili": "bilibili", + "embed_link_bilibili_desc": "By embedding the bilibili videos, you can watch tutorials, and guides, or view the channel homepage in Vika.", + "embed_link_bilibili_link_text": "How to embed the bilibili video", + "embed_link_bilibili_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-bilibili-video", + "embed_link_default": "Anything", + "embed_link_default_desc": "Paste a link to view any website. ", + "embed_link_default_link_text": "Learn more", + "embed_link_default_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_link_figma": "Figma", + "embed_link_figma_desc": "By embedding Figma files, members can view and edit design drafts more conveniently, improving collaboration efficiency. ", + "embed_link_figma_link_text": "How to embed Figma files", + "embed_link_figma_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-figma-file", + "embed_link_google_docs": "Docs", + "embed_link_google_docs_desc": "By embedding Google Docs, you can edit and view documents in AITable to facilitate team collaboration.", + "embed_link_google_docs_link_text": "How to embed Google Docs", + "embed_link_google_docs_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-docs-file", + "embed_link_google_sheets": "Sheets", + "embed_link_google_sheets_desc": "By embedding Google Sheets, you can edit and view tables in AITable to facilitate team collaboration. ", + "embed_link_google_sheets_link_text": "How to embed Google Sheets", + "embed_link_google_sheets_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-sheets-file", + "embed_link_jishi_design": "JSdesign", + "embed_link_jishi_design_desc": "By embedding JSdesign files, members can view and edit design drafts more conveniently, improving collaboration efficiency. ", + "embed_link_jishi_design_link_text": "How to embed JSdesign files", + "embed_link_jishi_design_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-js-design-file", + "embed_link_tencent_docs": "Tencent Docs", + "embed_link_tencent_docs_desc": "By embedding Tencent Docs, you can edit and view Tencent docs in Vika to improve collaboration efficiency. ", + "embed_link_tencent_docs_link_text": "How to embed Tencent Docs", + "embed_link_tencent_docs_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-tencent-docs", + "embed_link_wps": "WPS", + "embed_link_wps_desc": "By embedding WPS files, you can edit and view WPS documents, tables, and forms in Vika to improve collaboration efficiency.", + "embed_link_wps_link_text": "How to embed WPS files", + "embed_link_wps_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-wps-file", + "embed_link_youtube": "YouTube", + "embed_link_youtube_desc": "By embedding YouTube videos, you can watch tutorials, and guides, or view the channel homepage in AITable. ", + "embed_link_youtube_link_text": "How to Embed YouTube Videos", + "embed_link_youtube_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-youtube-video", + "embed_page": "Custom Page", + "embed_page_add_url": "Add Url", + "embed_page_doc_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_page_function_desc": "Add web pages into ${edition} for easy access to third-party website documents, videos, and more. You can add recommended website links or any custom links.", + "embed_page_node_permission_editor": "On the basis of \"update only\", can also open the public sharing of the file node", + "embed_page_node_permission_manager": "Can perform all actions on the file node", + "embed_page_node_permission_reader": "Can view the content of the custom page and basic file node information", + "embed_page_node_permission_updater": "On the basis of \"read-only\", can also modify the link of the custom page", + "embed_page_url_invalid": "Please enter the correct URL", + "embed_paste_link_bilibili_placeholder": "Paste the bilibili video link", + "embed_paste_link_default_placeholder": "Paste the URL", + "embed_paste_link_figma_placeholder": "Paste the Figma file’s share link", + "embed_paste_link_google_docs_placeholder": "Paste the Google Docs share link", + "embed_paste_link_google_sheets_placeholder": "Paste the Google Sheets share link", + "embed_paste_link_jsdesign_placeholder": "Paste the JSdesign file’s share link", + "embed_paste_link_tencent_docs_placeholder": "Paste the Tencent Docs share link", + "embed_paste_link_wps_placeholder": "Paste the WPS file’s share link", + "embed_paste_link_youtube_placeholder": "Paste the YouTube video link", + "embed_success": "Add Successfully", "emoji_activity": "Activities", "emoji_custom": "Custom", "emoji_flags": "Flags", @@ -7578,7 +7868,7 @@ "empty_email_tip": "No results, invite a new member via email", "empty_nodes": "Empty", "empty_record": "No records", - "empty_trash": "No files were deleted in the past ${day} days", + "empty_trash": "No file nodes were deleted in the past ${day} days", "enable": "Enable", "enabled_view_lock_success": "View Locked", "enabled_view_lock_tip": "Once the view is locked, it can't be edited until a member who can manage the datasheet unlocks it", @@ -7664,6 +7954,11 @@ "estonia": "Estonia", "ethiopia": "Ethiopia", "event_planning": "Event Planning", + "every": "Every", + "every_day_at": "day(s)", + "every_hour_at": "hour(s)", + "every_month_at": "month(s)", + "every_week_at": "Every Week on", "everyday_life": "Everyday Life", "everyone_visible": "Visible for Everyone", "exact_date": "exact date", @@ -7674,6 +7969,7 @@ "exchange": "Redeem", "exchange_code_times_tip": "Note: The redeem code can be used once only", "exclusive_consultant": "Exclusive V+ consultant", + "exclusive_limit_plan_desc": "Exclusive Limited Tier", "exist_experience": "Exit experience", "exits_space": "Exit space", "expand": "Expand", @@ -7715,8 +8011,8 @@ "faroe_islands": "Faroe Islands", "fashion_and_style": "Fashion and style", "favorite": "Pin", - "favorite_empty_tip1": "Pin files here for quick access.", - "favorite_empty_tip2": "Pinned files are only visible to you", + "favorite_empty_tip1": "Pin file nodes here for quick access.", + "favorite_empty_tip2": "Pinned file nodes are only visible to you", "fee_unit": "yuan", "feedback": "Feedback", "feishu_activity_upgrade_guidance": "", @@ -7765,7 +8061,7 @@ "field_created_by_property_subscription_close_tip": "After closing, the members under the creator column will automatically cancel the records they have followed", "field_created_by_property_subscription_open_tip": "This option only applies to newly created records", "field_desc": "Field description", - "field_desc_attachment": "Add files such as documents, images, and videos, and preview or download them", + "field_desc_attachment": "Add attachments such as documents, images, and videos, and preview or download them", "field_desc_autonumber": "Add a unique and self-increasing number for each record", "field_desc_button": "You can trigger automation or jump to a specified web by clicking a button", "field_desc_cascader": "Using a cascading approach, select pre-options.", @@ -7897,14 +8193,14 @@ "field_title_url": "URL", "field_title_workdoc": "WorkDoc", "field_type": "Field type", - "field_type_attachment_select_cell": "Drop files here", + "field_type_attachment_select_cell": "Drop attachments here", "fiji": "Fiji", - "file": "file", - "file_limits": "${limit} file limits in one space", + "file": "file node", + "file_limits": "${limit} file node limits in one space", "file_name_with_bulk_download": "${fileName}, etc. ${count} files.zip", "file_notification": "Tips", "file_of_rest": "Remaining: ${nodeRest}", - "file_sharing": "File sharing processing...", + "file_sharing": "File node sharing processing...", "file_summary": "Description", "file_upper_bound": "Maximum: ${nodeMax}", "fill_in_completed": "Completed", @@ -7931,14 +8227,14 @@ "fission_reward": "\"Sharing Blessings\" reward from \"${name}\"", "folder": "Folder", "folder_banner_desc": "It is recommended to use pictures with a width larger than 800 px to achieve a better visual experience.", - "folder_contains": "${folders} folders and ${files} files", + "folder_contains": "${folders} folders and ${files} file nodes", "folder_content_empty": "Empty folder", "folder_desc_title_placeholder": "Enter a title", - "folder_editor_label": "In addition to \"Update-only\", can also edit and share files", + "folder_editor_label": "In addition to \"Update-only\", can also edit and share file nodes", "folder_level_2_limit_tips": "Hey, the level of your folder has reached the limit of level-2.", - "folder_manager_label": "In addition to \"Editor\", can also add or delete files", - "folder_permission": "File permissions", - "folder_reader_label": " You can only view the files under this folder and can't edit them.", + "folder_manager_label": "In addition to \"Editor\", can also add or delete file nodes", + "folder_permission": "File node permissions", + "folder_reader_label": " You can only view the file nodes under this folder and can't edit them.", "folder_with_link_share_reminder": "The current folder is associated with external datasheet. Do you want to continue sharing", "folder_with_link_share_view_reminder": "Note: The shared folder has datasheets that link to other datasheets in another folder", "folds_hidden_fields_by_count": "Collapse ${count} hidden field(s)", @@ -8272,26 +8568,26 @@ "gantt_config_color_help": "How to set up", "gantt_config_friday": "Friday", "gantt_config_friday_in_bar": "Fri", - "gantt_config_friday_in_select": "Fri", + "gantt_config_friday_in_select": "Friday", "gantt_config_monday": "Monday", "gantt_config_monday_in_bar": "Mon", - "gantt_config_monday_in_select": "Mon", + "gantt_config_monday_in_select": "Monday", "gantt_config_only_count_workdays": "Duration only counts workdays.", "gantt_config_saturday": "Saturday", "gantt_config_saturday_in_bar": "Sat", - "gantt_config_saturday_in_select": "Sat", + "gantt_config_saturday_in_select": "Saturday", "gantt_config_sunday": "Sunday", "gantt_config_sunday_in_bar": "Sun", - "gantt_config_sunday_in_select": "Sun", + "gantt_config_sunday_in_select": "Sunday", "gantt_config_thursday": "Thursday", "gantt_config_thursday_in_bar": "Thu", - "gantt_config_thursday_in_select": "Thu", + "gantt_config_thursday_in_select": "Thursday", "gantt_config_tuesday": "Tuesday", "gantt_config_tuesday_in_bar": "Tue", - "gantt_config_tuesday_in_select": "Tue", + "gantt_config_tuesday_in_select": "Tuesday", "gantt_config_wednesday": "Wednesday", "gantt_config_wednesday_in_bar": "Wed", - "gantt_config_wednesday_in_select": "Wed", + "gantt_config_wednesday_in_select": "Wednesday", "gantt_config_weekdays_range": "${weekday} to ${weekday}", "gantt_config_workdays_a_week": "Custom standard workdays", "gantt_cycle_connection_warning": "Invalid task dependency, there is a cycle connection\n", @@ -8372,6 +8668,7 @@ "gold_grade": "Gold", "gold_grade_desc": "For teams with complex business process", "gold_seat_200_desc": "200", + "gold_seat_300_desc": "300", "golden_grade": "Gold", "got_it": "Got it", "got_v_coins": "V coins rewarded", @@ -8405,7 +8702,9 @@ "guests_per_space": "Guests per Space", "guide_1": "啊这", "guide_2": "It takes only a few minutes to learn the basic functions. Work more productively from this moment on!", - "guide_flow_of_catalog_step1": "Here is working catalog where all the folders and files of the Space are stored.", + "guide_flow_modal_contact_sales": "Contact Sales", + "guide_flow_modal_get_started": "Get Started", + "guide_flow_of_catalog_step1": "Here is working catalog where all the folders and file nodes of the Space are stored.", "guide_flow_of_catalog_step2": "In the working catalog, you can create a datasheet or a folder as needed.", "guide_flow_of_click_add_view_step1": "In addition to some basic view, you are highly recommended to create an album view if you have attachments in picture format.", "guide_flow_of_datasheet_step1": "This is a list of views that are created for this datasheet. You can create new views here.", @@ -8453,12 +8752,12 @@ "hide_fields_not_go": "Can't go to the hidden field", "hide_graphic_field_tips_in_gantt": "Click to adjust the display fields in the task item", "hide_kanban_grouping": "Hide group", - "hide_node_permission_resource": "Hide no permission file", + "hide_node_permission_resource": "Hide no permission file node", "hide_one_field": "Hide field", "hide_one_graphic_field": "Hide graphic field", "hide_pane": "Hide panel", "hide_uneditable_automation_node": "Hide uneditable automation nodes", - "hide_unmanageable_files": "Hide unmanageable files", + "hide_unmanageable_files": "Hide unmanageable file nodes", "hide_unmanaged_sheet": "Hide unmanageable resource", "hide_unusable_sheet": "Hide uneditable resource", "highlight": "Highlight", @@ -8512,7 +8811,7 @@ "inform": "Report abuse", "inherit_field_permission_tip": "This field is accessible to all members or teams below", "inherit_permission_tip": "Permissons are inherited from the parent folder", - "inherit_permission_tip_root": "All members or teams below can access this file", + "inherit_permission_tip_root": "All members or teams below can access this file node", "inhert_permission_desc": "Members and teams inherit permissions from superior folder \"${nodeName}\" ", "init_roles": "Finance,Marketing,IT,HR,Legal", "initial_size": "Original size", @@ -8583,6 +8882,7 @@ "intro_widget_tips": "What is widget?", "introduction": "Introduction", "invalid_action_sort_tip": "As a grouping field, the sorting of it has been set. The setting of the current order will not take effect.", + "invalid_automation_configuration": "Invalid automation configuration, please check and try again", "invalid_field_type": "Invalid field type", "invalid_option_sort_tip": "As a grouping field, the sorting of it has been set. ", "invalid_redemption_code_entered": "Invalid redeem code", @@ -8713,6 +9013,9 @@ "label_format_day_month_and_year_split_by_slash": "Day/Month/Year", "label_format_month": "Month", "label_format_month_and_day_split_by_dash": "Month-Day", + "label_format_month_day_year_split_by_dash": "Month-Day-Year", + "label_format_month_day_year_split_by_slash": "Month/Day/Year", + "label_format_month_day_year_two_digit_year_split_by_slash": "Month/Day/Year (Two-digit year)", "label_format_year": "Year", "label_format_year_and_month_split_by_dash": "Year-Month", "label_format_year_month_and_day_split_by_dash": "Year-Month-Day", @@ -8742,7 +9045,7 @@ "lark_integration_step1_instructions": "vikadata x Lark Self-Built Application Integration Instructions", "lark_integration_step1_tips": "Tips", "lark_integration_step1_tips_content": "
    \n
  • \n In addition to the build-your-own app approach, we also offer a version of the Lark Store app that is ready to use right out of the box without configuration and binding to the space What's different?\n
  • \n
", - "lark_integration_step1_warning": "
    \n
  • \n

    \n Operators must have administrative access to both vikadata space and Lark\n

    \n

    The operator needs to be the main administrator of the space and also have the permission to create self-built applications in the Lark administration backend

    \n
  • \n
  • \n

    \n The original members of the space will be removed from the space station, and then the member information and department information will be synchronized from the Lark side in one direction\n

    \n

    After Lark integration is enabled, member and department information will be based on the Lark side, so the original member/group information cannot be retained, and related permission information (sub-administrator permission, file permission, column permission, etc.) will be lost, so please let administrators know and make preparations

    \n
  • \n
", + "lark_integration_step1_warning": "
    \n
  • \n

    \n Operators must have administrative access to both vikadata space and Lark\n

    \n

    The operator needs to be the main administrator of the space and also have the permission to create self-built applications in the Lark administration backend

    \n
  • \n
  • \n

    \n The original members of the space will be removed from the space station, and then the member information and department information will be synchronized from the Lark side in one direction\n

    \n

    After Lark integration is enabled, member and department information will be based on the Lark side, so the original member/group information cannot be retained, and related permission information (sub-administrator permission, file node permission, column permission, etc.) will be lost, so please let administrators know and make preparations

    \n
  • \n
", "lark_integration_step2": "Application Credentials", "lark_integration_step2_appid": "App ID", "lark_integration_step2_appsecret": "App Secret", @@ -8791,6 +9094,7 @@ "lark_version_enterprise": "Enterprise Plan with Lark", "lark_version_standard": "Standard Plan with Lark", "lark_versions_free": "Basic Plan with Lark", + "last_day": "Last day", "last_modified_by_select_modal_desc": "If any of the fields you select below are edited, the member who edited most recently will show in the last edited by field", "last_modified_time_select_modal_desc": "If any of the fields you select below are edited, the most recently edited time will show in the last edited time field", "last_step": "Back", @@ -8826,12 +9130,12 @@ "link_to_specific_view": "Link to records from a view", "linked_datasheet": "Linked datasheet", "list": "List", - "list_how_many_folders_and_files": "${folderNumber} Folder, ${fileNumber} files", + "list_how_many_folders_and_files": "${folderNumber} Folder, ${fileNumber} file nodes", "list_of_attachments": "Attachments", "lithuania": "Lithuania", "load_tree_failed": "Failed to load tree resources", "loading": "Loading...", - "loading_file": "Loading files, please wait...", + "loading_file": "Loading file nodes, please wait...", "local_business": "Local Business", "local_data_conflict": "Resources in the process of initialization of data errors, please refresh and retry", "local_drag_upload": "Upload local files", @@ -8935,7 +9239,7 @@ "mail_invite_fail": "Mail invite success.", "mail_invite_success": "Mail invite success.", "main_admin_name": "Admin name", - "main_admin_page_desc": "Admin have full access to the Space, such as assigning sub-admins and transferring ownership of the Space", + "main_admin_page_desc": "Admin have full access to the Space, such as managing members, managing Space settings.", "main_contain": "Main contents", "malawi": "Malawi", "malaysia": "Malaysia", @@ -9016,7 +9320,7 @@ "max_records": "Maximum: ${count}", "max_remain_record_activity_days": "This space supports viewing record activity within ${specification} days, upgrade to view more ", "max_remain_timemachine_days": "The space only shows the record activity within ${specification} days, upgrade to view more record activity.", - "max_remain_trash_days": "This space supports viewing historical files within ${specification} days, upgrade to view more historical files ", + "max_remain_trash_days": "This space supports viewing historical file nodes within ${specification} days, upgrade to view more historical file nodes ", "max_rows_in_space": "The maximum number of records in space is ${specification}. So far, ${usage} records have been created, and you can upgrade to get higher usage.", "max_rows_per_sheet": "The maximum number of records in one datasheet is ${specification}. So far, ${usage} records have been created, and you can upgrade to get higher usage.", "max_seats": "The maximum number of seats in the space is ${specification}, and ${usage} are currently invited, and you can upgrade to get higher usage.", @@ -9029,9 +9333,9 @@ "media_element": "Media Element", "member": "Member", "member_applied_to_close_account": " has requested to delete his accoun", - "member_data_desc_of_appendix": "All attachments uploaded to the Space are counted in. You can't upload any files once the storage reaches its limit.", + "member_data_desc_of_appendix": "All attachments uploaded to the Space are counted in. You can't upload any attachments once the storage reaches its limit.", "member_data_desc_of_dept_number": "Quantity statistics of all teams in the organizational structure (including sub-teams)", - "member_data_desc_of_field_number": "Numbers of all files in the catalog", + "member_data_desc_of_field_number": "Numbers of all files in the catalog & custom templates.", "member_data_desc_of_member_number": "'seats' refers to the number of members joined in the space and AI agents added in workbench.Which means:seats = members+ AI agents", "member_data_desc_of_record_number": "Quantity statistic in all datasheets of working catalog, including the blank record(s)", "member_err": "Nickname cannot exceed 32 characters", @@ -9077,8 +9381,8 @@ "message_exit_space_failed": "Failed to exit the space", "message_exit_space_successfully": "You've exited the space", "message_fields_count_up_to_bound": "The datasheet has reached the upper limit of the field. Unable to create related relations.", - "message_file_size_out_of_upperbound": "The size of a single file cannot exceed 1G", - "message_get_node_share_setting_failed": "Failed to get the sharing settings of the file", + "message_file_size_out_of_upperbound": "The size of a single attachment cannot exceed 1G", + "message_get_node_share_setting_failed": "Failed to get the sharing settings of the file node", "message_hidden_field_desc": "Field descriptions have been hidden", "message_img_size_limit": "The size of the picture should not exceed ${size}", "message_invalid_url": "Invalid address", @@ -9155,10 +9459,14 @@ "more_widget": "More widgets", "morocco": "Morocco", "move": "Move", + "move_datasheet_link_warn": "Cannot be moved to Team Area alone, because there is a two-way link from the current datasheet to another datasheet, it is recommended to put them in a folder and then move them", "move_favorite_node_fail": "Node moving failed. The system will update the list automatically. ", - "move_node_modal_content": "After moving, the visibility of the file may be affected by the parent folder.", + "move_folder_link_warn": "Cannot be moved to Team Area because the files in the current folder are linked to files outside the folder (may be two-way links or linked by forms, etc.) We recommend that they be placed in a folder before moving", + "move_node_modal_content": "After moving, the visibility of the file node may be affected by the parent folder.", + "move_other_link_no_permission": "Unable to move to the corresponding folder because you do not have administrative rights to the folder", + "move_other_link_warn": "It is not allowed to move ${node type} to Team Area alone, because it connects to the datasheet of Private Area, it is recommended to put them in a folder before moving them", "move_to": "Move to", - "move_to_error_equal_parent": "The file is under the current folder. Please select another folder", + "move_to_error_equal_parent": "The file node is under the current folder. Please select another folder", "move_to_modal_title": "Move [${name}] to", "move_to_success": "Move succeeded", "mozambique": "Mozambique", @@ -9187,6 +9495,7 @@ "new_a_line": "Shift+Enter: break line", "new_automation": "New automation", "new_caledonia": "New Caledonia", + "new_custom_page": "New custom page", "new_datasheet": "New datasheet", "new_folder": "New folder", "new_folder_btn_title": "Folder", @@ -9220,7 +9529,7 @@ "nickname_modified_successfully": "Name edited", "niger": "Niger", "nigeria": "Nigeria", - "no_access_node": "The file is hidden", + "no_access_node": "The file node is hidden", "no_access_record": "No access", "no_access_space_descirption": "Unable to access the Space. You might not have the permission or the Space does not exist.", "no_access_space_title": "Note", @@ -9233,9 +9542,9 @@ "no_datasheet_editing_right": "You do not have manageable access to the original datasheet to which the current form is linked and cannot insert fields", "no_editing_rights": "No editing permission", "no_field_role": "You have no access to the field", - "no_file_permission": "The file cannot be accessed", - "no_file_permission_content": "You do not have access to the file or the file has been deleted", - "no_file_permission_message": "The file's permissions have been changed and you cannot access it.", + "no_file_permission": "The file node cannot be accessed", + "no_file_permission_content": "You do not have access to the file node or the file node has been deleted", + "no_file_permission_message": "The file node's permissions have been changed and you cannot access it.", "no_foreignDstId": "Please link to a datasheet", "no_foreign_dst_readable": "No permission to view the related datasheet", "no_link_ds_permission": "No edit permissions for related datasheets", @@ -9274,27 +9583,27 @@ "no_support_pc_sub_desc": "These 4 browsers are recommended: Chrome, Firefox, Safari, and Microsoft Edge", "no_view_create_form": "Can't create a form without a Grid view", "no_view_find": "No results", - "node_info": "File information", + "node_info": "File node information", "node_info_created_time": "Created time:", "node_info_createdby": "Created by:", "node_info_last_modified_by": "Last modified by:", "node_info_last_modified_time": "Last modified time:", "node_name": "Node name", - "node_not_exist_content": "The file you are accessing has no permissions or has been deleted", + "node_not_exist_content": "The file node you are accessing has no permissions or has been deleted", "node_not_exist_title": "Note", - "node_number_err_content": "Your action failed because the Space has reached the maximum number of files", - "node_permission": "File permissions", + "node_number_err_content": "Your action failed because the Space has reached the maximum number of file nodes", + "node_permission": "File node permissions", "node_permission_desc": "The sub-admin will have the access to manage workbench, and to set \"manageable\", \"editable\", and \"read-only\" permissions for other members.", "node_permission_extend_desc": "Permissions inherit from the parent folder", "node_permission_has_been_changed": "Your permission has been changed to \"${nodeRoleName}\"", - "node_permission_item_tips_admin_he": "The administrator of the space who can manage this file", - "node_permission_item_tips_admin_you": "You are the administrator of the space and can manage this file", - "node_permission_item_tips_file_he": "The file manager who can manage this file", - "node_permission_item_tips_file_you": "You are the file manager and can manage this file", - "node_permission_item_tips_other_he": "The ${role} of this file", + "node_permission_item_tips_admin_he": "The administrator of the space who can manage this file node", + "node_permission_item_tips_admin_you": "You are the administrator of the space and can manage this file node", + "node_permission_item_tips_file_he": "The file node manager who can manage this file node", + "node_permission_item_tips_file_you": "You are the file node manager and can manage this file node", + "node_permission_item_tips_other_he": "The ${role} of this file node", "node_permission_item_tips_other_he_edit": ", you can click the menu on the right to modify or remove permission", - "node_permission_item_tips_other_you": "You are the ${role} of this file", - "node_permission_label_space_and_file": "Space & File Manager", + "node_permission_item_tips_other_you": "You are the ${role} of this file node", + "node_permission_label_space_and_file": "Space & File Node Manager", "node_permission_nums": "The maximum number of node permissions to be used in space is ${specification}. So far, ${usage} has been used, and you can upgrade to get higher usage.", "node_with_link_share_reminder": "The current datasheet is associated with the contents of other datasheet. Do you want to continue sharing?", "node_with_link_share_view_reminder": "Note: The shared datasheet has data linked from another datasheet", @@ -9307,7 +9616,7 @@ "not_equal": "is not...", "not_found_field_the_name_as": "Field named \"${value}\" unfound.", "not_found_record_contains_value": "No matches that contain \"${searchValueSpan}\" ", - "not_found_this_file": "The file you are searching for is unfound", + "not_found_this_file": "The file node you are searching for is unfound", "not_found_vika_field_the_name_as": "Column named \"${value}\" unfound", "not_joined_members": "Unactive members", "not_mail_invitee_page_tip": "The current login user is not invitee (${text}).
Please select the corresponding account to enter the space station.", @@ -9353,7 +9662,7 @@ "nvc_start_text": "Drag the bar to the right end", "nvc_yes_text": "Verified", "obtain_verification_code": "Verification code not obtained or expired", - "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrzw0miJVmSkJ7eBBa9k/fomx5qPX0JGPFvfEEP\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", + "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrCvbFC53xc3kl00B4Pg\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", "offical_website_nav_data": "[{\n \"name\": \"产品\",\n \"href\": \"/login\",\n \"children\": [\n {\n \"name\": \"vika维格表 Overview\",\n \"href\": \"/login/\"\n },\n {\n \"name\": \"应用连接 Integration\",\n \"href\": \"/connections/\"\n },\n {\n \"name\": \"客户端(Beta) Download\",\n \"href\": \"/download/\"\n }\n ]\n}, {\n \"name\": \"解决方案\",\n \"href\": \"/\",\n \"children\": [{\n \"name\": \"PMO项目群管理\",\n \"href\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"href\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"href\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"href\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"href\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"href\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"href\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"href\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"href\": \"/shop/\"\n }, {\n \"name\": \"更多解决方案 >\",\n \"href\": \"/solutions/\"\n }]\n}, {\n \"name\": \"模板/案例\",\n \"href\": \"/template\",\n \"children\": [\n {\n \"name\": \"模板中心 Tempaltes\",\n \"href\": \"/template\"\n },\n {\n \"name\": \"客户案例 Customers\",\n \"href\": \"/cases/\"\n }\n ]\n},\n {\n \"name\": \"首页\",\n \"href\": \"/?home=1\"\n },\n {\n \"name\": \"学习资源\",\n \"href\": \"https://edu.vika.cn/index\",\n \"children\": [\n {\n \"name\": \"快速入门 Tutorials\",\n \"href\": \"https://help.vika.cn/docs/guide/tutorial\"\n },\n {\n \"name\": \"产品手册 Manual\",\n \"href\": \"https://help.vika.cn/docs/guide/manual\"\n },\n {\n \"name\": \"维格课堂 Vika Education\",\n \"href\": \"https://edu.vika.cn/\"\n },\n {\n \"name\": \"维格社区 Vika BBS\",\n \"href\": \"https://bbs.vika.cn/\"\n },\n {\n \"name\": \"第三方连接 Integration\",\n \"href\": \"https://help.vika.cn/docs/guide/connection\"\n },\n {\n \"name\": \"开发者中心 Developer Center\",\n \"href\": \"/developers/\"\n },\n {\n \"name\": \"常见问题 FAQ\",\n \"href\": \"https://help.vika.cn/docs/guide/questions\"\n }\n ]\n }]", "office_preview": "Preview Office Files", "office_preview_app_desc": "

Smooth online preview of office files on datasheet, allowing you to view common office files such as Excel, Word, PPT, etc. on your desktop or mobile anywhere, anytime

\n\n
    \n
  • Online preview of .doc, .docx, .xls, .xlsx, .ppt, .pptx, and .pdf formatted office files
  • \n
  • Desktop and mobile both support file previews of the above formats
  • \n
\n\n

Additional notes:

\n
    \n
  • This feature is powered by \"Yoncentric Cloud Conversion\" and officially integrated
  • \n
  • Click the \"Enable\" button below to enable this integration and agree that \"Yoncentric Cloud Conversion\" reads the office files you want to preview
  • \n
  • If you no longer need the office files preview feature, the space admin can disable it on this page
  • \n
", @@ -9393,6 +9702,7 @@ "open_auto_save_success": "Autosave view is turned on successfully", "open_auto_save_warn_content": "All changes under this view are automatically saved and synchronized with other members.", "open_auto_save_warn_title": "Turn on autosave view", + "open_automation_time_arrival": "https://aitable.ai/contact-sales-open-source", "open_failed": "Open failed", "open_in_new_tab": "open in a new tab", "open_invite_after_operate": "Once switched on, all members can invite new members from the contacts panel", @@ -9422,9 +9732,9 @@ "operate_warning": "Action warning", "operated": "Operated", "operation": "Operations", - "operation_log_allow_other_save": "Others can save the file to their own Space", + "operation_log_allow_other_save": "Others can save the file node to their own Space", "operation_log_closed_share": "Sharing disabled", - "operation_log_not_allow_other_save": "Others can't save the file to their own Space", + "operation_log_not_allow_other_save": "Others can't save the file node to their own Space", "operation_log_open_share": "Sharing enabled", "operation_log_update_share": "Share link updated", "operations": "Operations", @@ -9523,8 +9833,8 @@ "password_reset_succeed": "Password reset successfully, and you will log in automatically", "password_rules": "8-24 digits with letters and numbers", "paste": "Paste", - "paste_attachment": "${keyboardShortcut} Paste files here", - "paste_attachment_error": "Please paste the file into an attachment field", + "paste_attachment": "${keyboardShortcut} Paste attachments here", + "paste_attachment_error": "Please paste the attachment into an attachment field", "paste_cell_data": "Paste cell(s)", "paste_tip_add_field": "One or more new fields will be added to this datasheet", "paste_tip_for_add_record": "One or more records will be added to this datasheet", @@ -9539,6 +9849,8 @@ "payment_record": "Payment record", "payment_reminder": "Payment Reminder", "payment_reminder_content": "The new plan you have selected is more deductible than the amount to be paid. It is recommended that you choose the new plan with a longer duration. If you confirm to do so, the excess amount will not be refundable. ${action} if in doubt", + "payment_reminder_modal_content": "You can try the advanced version to enjoy more file nodes, enterprise permissions, attachment capacity, data volume, AI and other advanced features and privileges.", + "payment_reminder_modal_title": "You are currently using the free version", "pending_invite": "Pending invite", "people": " member(s)", "per_person_per_year": "Per person per year", @@ -9559,7 +9871,7 @@ "permission_and_security_content": "Adjust the security level to prevent data leaks", "permission_bound": "Access level", "permission_change_success": "Permission changed", - "permission_config_in_workbench_page": "[{\"key\":0,\"title\":\"About Datasheets\",\"detail\":[{\"title\":\"Edit view settings\",\"permissions\":[0,1,2]},{\"title\":\"Edit view list\",\"permissions\":[0,1,2]},{\"title\":\"Export view data\",\"permissions\":[0,1]},{\"title\":\"Add/Delete/Configure fields\",\"permissions\":[0,1]},{\"title\":\"Edit field layout (width/statistics/order)\",\"permissions\":[0,1,2]},{\"title\":\"Edit records (add/edit records)\",\"permissions\":[0,1,2,3]},{\"title\":\"Delete records\",\"permissions\":[0,1,2]},{\"title\":\"Undo/Redo actions\",\"permissions\":[0,1,2,3]},{\"title\":\"Post a comment\",\"permissions\":[0,1,2,3,4]}]},{\"key\":1,\"title\":\"About Files\",\"detail\":[{\"title\":\"Edit file permissions\",\"permissions\":[0,1]},{\"title\":\"Create files\",\"permissions\":[0,1]},{\"title\":\"Import files\",\"permissions\":[0,1]},{\"title\":\"Export files\",\"permissions\":[0,1]},{\"title\":\"Duplicate files (Need full access to the file and its folder)\",\"permissions\":[0,1]},{\"title\":\"Move files (Need full access to the file and its folder)\",\"permissions\":[0,1]},{\"title\":\"Rename files\",\"permissions\":[0,1]},{\"title\":\"Delete files\",\"permissions\":[0,1]},{\"title\":\"Share files\",\"permissions\":[0,1,2]},{\"title\":\"Add files description\",\"permissions\":[0,1]},{\"title\":\"Save as template\",\"permissions\":[0,1]}]}]", + "permission_config_in_workbench_page": "[{\"key\":0,\"title\":\"About Datasheets\",\"detail\":[{\"title\":\"Edit view settings\",\"permissions\":[0,1,2]},{\"title\":\"Edit view list\",\"permissions\":[0,1,2]},{\"title\":\"Export view data\",\"permissions\":[0,1]},{\"title\":\"Add/Delete/Configure fields\",\"permissions\":[0,1]},{\"title\":\"Edit field layout (width/statistics/order)\",\"permissions\":[0,1,2]},{\"title\":\"Edit records (add/edit records)\",\"permissions\":[0,1,2,3]},{\"title\":\"Delete records\",\"permissions\":[0,1,2]},{\"title\":\"Undo/Redo actions\",\"permissions\":[0,1,2,3]},{\"title\":\"Post a comment\",\"permissions\":[0,1,2,3,4]}]},{\"key\":1,\"title\":\"About File nodes\",\"detail\":[{\"title\":\"Edit file node permissions\",\"permissions\":[0,1]},{\"title\":\"Create file nodes\",\"permissions\":[0,1]},{\"title\":\"Import files\",\"permissions\":[0,1]},{\"title\":\"Export files\",\"permissions\":[0,1]},{\"title\":\"Duplicate file nodes (Need full access to the file node and its folder)\",\"permissions\":[0,1]},{\"title\":\"Move file nodes (Need full access to the file node and its folder)\",\"permissions\":[0,1]},{\"title\":\"Rename file nodes\",\"permissions\":[0,1]},{\"title\":\"Delete file nodes\",\"permissions\":[0,1]},{\"title\":\"Share file nodes\",\"permissions\":[0,1,2]},{\"title\":\"Add file nodes description\",\"permissions\":[0,1]},{\"title\":\"Save as template\",\"permissions\":[0,1]}]}]", "permission_delete_failed": "Failed to delete member(s)/team permission", "permission_delete_success": "Member/team permissions deleted", "permission_edit_failed": "Edit failed", @@ -9571,14 +9883,14 @@ "permission_no_permission_access": "Uneditable", "permission_removed_in_curspace_tip": "Your permission on this Space changed to a member", "permission_setting": "Edit permissions", - "permission_setting_tip": "You can give permissions on this file for members or teams in the Space", + "permission_setting_tip": "You can give permissions on this file node for members or teams in the Space", "permission_settings": "Permission settings", "permission_specific_show": "Specify visibility", "permission_switch_failed": "Failed to switch permission setting mode", "permission_switch_specified": "Enable manual setting", "permission_switch_succeed": "Permission setting mode switched", "permission_switch_to_superior": "Disable manual setting", - "permission_switched_inherit_superior": "After disabled, members and teams will automatically have permission to this file as they have to the superior folder. The already specified permissions will be cleared and cancelled.", + "permission_switched_inherit_superior": "After disabled, members and teams will automatically have permission to this file node as they have to the superior folder. The already specified permissions will be cleared and cancelled.", "permission_switched_reallocate": "After enabled, you can set permissions for specific members or teams", "permission_template_visitor": "Experiencing", "permisson_model_field_owner": "Field owner", @@ -9637,8 +9949,8 @@ "placeholder_select_report_reason": "Please select the reason for the report", "placeholder_set_password": "8-24 digits with letters and numbers", "plan_model_benefits_button": "Viewing Privilege Comparison", - "plan_model_benefits_gold": "1,000 node files per space;\n20,000 records per datasheet;\n500 thousand api call per month;\n200 node files permission per space;\n6 months history to go back;\nattachment capacity increased;\nadvanced views and magic forms increased;", - "plan_model_benefits_sliver": "300 node files per space;\n10,000 records per datasheet;\n100 thousand api call per month;\n6 months history to go back;\nattachment capacity increased;\nadvanced views and magic forms increased;", + "plan_model_benefits_gold": "1,000 file nodes per space;\n20,000 records per datasheet;\n500 thousand api call per month;\n200 file nodes permission per space;\n6 months history to go back;\nattachment capacity increased;\nadvanced views and magic forms increased;", + "plan_model_benefits_sliver": "300 file nodes per space;\n10,000 records per datasheet;\n100 thousand api call per month;\n6 months history to go back;\nattachment capacity increased;\nadvanced views and magic forms increased;", "plan_model_benefits_title": "${space_level} privilege", "plan_model_button": "Pay", "plan_model_choose_members": "Choose seats", @@ -9694,7 +10006,7 @@ "player_step_ui_config_155": "", "player_step_ui_config_156": "{\n \"element\": \".permission_setting_class\",\n \"placement\": \"leftCenter\",\n \"title\": \"Default permissions\",\n \"description\": \"The default permission role is displayed when no permission is specified, and you can assign permissions to members or groups directly here.\",\n \"children\":\"\" \n }", "player_step_ui_config_157": "{\n \"element\": \"#resetPermissionButton\",\n \"placement\": \"topCenter\",\n \"title\": \"Restricted permissions\",\n \"offsetY\": -15,\n \"description\": \"Permissions have been set here, so only the members of the list below are visible. You can click here to restore the default permissions.\",\n \"children\":\"\" \n}", - "player_step_ui_config_158": "{\n \"element\": \"#resetPermissionButton\",\n \"placement\": \"topCenter\",\n \"title\": \"Specify permission role\",\n \"offsetY\": -15,\n \"description\": \"You have modified the permission role of this file again, which means that this file is only visible to the members you specified. You can click \"restore default\" to undo the previous settings.\",\n \"children\":\"\" \n}", + "player_step_ui_config_158": "{\n \"element\": \"#resetPermissionButton\",\n \"placement\": \"topCenter\",\n \"title\": \"Specify permission role\",\n \"offsetY\": -15,\n \"description\": \"You have modified the permission role of this file node again, which means that this file node is only visible to the members you specified. You can click \"restore default\" to undo the previous settings.\",\n \"children\":\"\" \n}", "player_step_ui_config_159": "", "player_step_ui_config_16": "{\n \"element\": \".style_templateItem__1UDe0\"\n}\n", "player_step_ui_config_160": "{\n \"element\": \".permission_setting_class\"\n }", @@ -9708,7 +10020,7 @@ "player_step_ui_config_168": "{\n\"templateKey\":\"createMirrorTip\"\n}", "player_step_ui_config_169": "{\n \"headerImg\": \"https://s4.vika.cn/space/2023/04/04/bcf0695cf35840e6b85e032a8e5ea0a1\",\n \"readMoreUrl\": \"https://help.vika.cn/changelog/23-04-10-updates\",\n \"children\": \"

🚀 Introduction of new functions

\\n
  • New field type \"Cascader\" is launched, making selection from a hierarchy of options on forms easier
  • \"Script\" widget is released, less code for more customization
  • Trigger Automation to send Emails, and get fast notifications
  • Trigger Automation to send a message to Slack, and inform your team in time
  • Exploring AI: \"GPT Content Generator\" Widget Released
\"\n}", "player_step_ui_config_17": "{\n \"element\": \"#TEMPLATE_CENTER_USE_TEMPLATE_BTN>button\", \n\"placement\": \"rightBottom\",\n\"offsetY\": 20,\n \"title\": \"How to use a template\", \n\"description\": \"Click the button on the left to use the template\", \"children\":\"\" \n}", - "player_step_ui_config_176": "{\"title\":\"AI Agent Introduction\",\"video\":\"https://www.youtube.com/embed/cjds1r_roG8?si=irKUpMhwDlOEb8Hc\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", + "player_step_ui_config_176": "{\"title\":\"AITable.ai DEMO\",\"video\":\"https://www.youtube.com/embed/nbqwE21X1hc?si=HYTHEboJtarOL1w8\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", "player_step_ui_config_18": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select>.ant-select-selector\", \n\"placement\": \"bottomLeft\",\n \"title\": \"How to use a template\", \n\"description\": \"Select where to put the template\", \"children\":\"\" \n}", "player_step_ui_config_19": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select .ant-select-selector\"\n}", "player_step_ui_config_2": "{\n \"config\": [\n {\n \"key\": 1,\n \"name\": \"answer1\",\n \"title\": \"What kind of issues are you looking forward to solved by vikadata?\",\n \"type\": \"checkbox\",\n \"answers\": [\n \"Work Planning\",\n \"Customer Service\",\n \"Project Management\",\n \"Sourcing Supply\",\n \"Content Production\",\n \"E-commerce operation\",\n \"Event Planning\",\n \"Human Resources\",\n \"Administration\",\n \"Financial Management\",\n \"Webcast\",\n \"Educational institutes Management\",\n \"Other\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 2,\n \"name\": \"answer2\",\n \"title\": \"Your job title is______\",\n \"type\": \"radio\",\n \"answers\": [\n \"General manager \",\n \"Project manager\",\n \"Product manager\",\n \"Designer\",\n \"R&D engineer\",\n \"Operator, editor\",\n \"Sales, customer service\",\n \"Human resource, administration \",\n \"Finance, accountant\",\n \"Lawyer, legal affairs\",\n \"Marketing\",\n \"Teacher\",\n \"Student\",\n \"Other\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 3,\n \"name\": \"answer3\",\n \"title\": \"What is the name of your company?\",\n \"type\": \"input\",\n \"submit\": false\n },\n {\n \"key\": 4,\n \"name\": \"answer4\",\n \"title\": \"Please leave your email address/ phone number/ Wechat account below so we can reach you in time when you need help.\",\n \"type\": \"input\",\n \"submit\": true\n },\n {\n \"key\": 5,\n \"title\": \"Thank you for filling out the form, you can add our customer service in case of need\",\n \"platform\": {\n \"website\": \"https://s4.vika.cn/space/2023/03/02/b34e3205a9154463be16f497524f1327\",\n \"dingtalk\": \"https://s4.vika.cn/space/2023/03/02/4b16cef6602a4586a21d6346bf25d300\",\n \"wecom\": \"https://s4.vika.cn/space/2023/03/02/60119b1b69b64aa887bd1be6a2928bec\",\n \"feishu\": \"https://u.vika.cn/z9ygm\"\n },\n \"type\": \"contactUs\",\n \"next\": true\n }\n ]\n}\n", @@ -9738,13 +10050,13 @@ "player_step_ui_config_41": "", "player_step_ui_config_42": "{\n \"element\": \"#DATASHEET_FORM_LIST_PANEL\", \n\"placement\": \"leftTop\",\n \"title\": \"Form\", \n\"description\": \"You can quickly create a form from the current view. The number and order of the fields in the form is consistent with the view.\", \"children\":\"\" \n}", "player_step_ui_config_43": "{\n \"element\": \".style_navigation__1U5cR .style_help__1sXEA\", \n\"placement\": \"rightBottom\",\n \"title\": \"Tip\", \n\"offsetY\":5,\n\"description\": \"You can find your Vikaby assistant from the \"Help\" icon on the left\", \"children\":\"\" \n}", - "player_step_ui_config_44": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", + "player_step_ui_config_44": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2023/12/29/212a38dda62f4e52a58a92bf86657705\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", "player_step_ui_config_45": "", "player_step_ui_config_46": "", "player_step_ui_config_47": "{\n \"element\": \"#DATASHEET_WIDGET_BTN\",\n\"placement\": \"bottomRight\",\n \"title\": \"Widget\", \n\"description\": \"Want to use and view your data in a richer way? Try the widget!\", \"children\":\"\" \n}", "player_step_ui_config_48": "", "player_step_ui_config_49": "{\n \"element\": \".style_widgetPanelContainer__1l2ZV\",\n\"placement\": \"leftCenter\",\n \"title\": \"What is a widget\", \n\"description\": \"Vika widgets are an extended application of vikadata that features in richer data visualization, data transfer, data cleansing, and more. By installing widgets in the widget board, you can make work a lot easier.\", \"children\":\"\" \n}", - "player_step_ui_config_5": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", + "player_step_ui_config_5": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", "player_step_ui_config_50": "{\n \"element\": \".style_widgetModal__eXmdB\",\n\"placement\": \"leftTop\",\n \"title\": \"Widget Center\", \n\"description\": \"Officially recommended and custom widgets are published here. You can install any widget you want onto a dashboard or into a widget board of any datasheet.\", \"children\":\"\" \n}", "player_step_ui_config_51": "{\n \"element\": \".style_widgetModal__eXmdB .style_widgetItem__3Pl-1 button\",\n\"placement\": \"rightBottom\",\n \"title\": \"Install widget\", \n\"description\": \"Let's install this \"Chart\" widget\", \"children\":\"\" \n}", "player_step_ui_config_52": "", @@ -9793,7 +10105,7 @@ "player_step_ui_config_91": "{\n \"element\": \"#DATASHEET_TOOL_BAR_VIEW_SETTING\",\n\"placement\": \"bottom\",\n \"title\": \"Watch videos again\", \n\"description\": \"Click \"Settings\" and you can find the tutorial video\" \n}", "player_step_ui_config_92": "", "player_step_ui_config_93": "", - "player_step_ui_config_94": "{\n \"title\": \"Let's go start your project!\",\n \"description\": \"Welcome to Vika Planet! Let's take up a task and our journey will start from here.\",\n \"data\": [\n {\n \"text\": \"Rename a file to make the index clearer\",\n \"stopEvents\": [\n \"onMouseDown\"\n ],\n \"actions\": [\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \"#FOLDER_SHOWCASE_TITLE\",\n \"emitEvent\": \"click\",\n \"nextActions\": [\n {\n \"uiType\": \"popover\",\n \"uiConfig\": \"{\\\"element\\\":\\\"#FOLDER_SHOWCASE_TITLE_INPUT\\\",\\\"placement\\\":\\\"bottom\\\",\\\"title\\\":\\\"How to use a datasheet\\\",\\\"description\\\":\\\"Click here to rename the file 👆\\\"}\",\n \"backdrop\": \"around_mask\"\n },\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \"#FOLDER_SHOWCASE_TITLE_INPUT\",\n \"emitEvent\": \"focus\",\n \"finishTodoWhen\": [\n \"blur\"\n ]\n }\n }\n ]\n }\n }\n ]\n },\n {\n \"text\": \"Modify a file's description to help others understand it better\",\n \"actions\": [\n {\n \"uiType\": \"breath\",\n \"uiConfig\": \"{\\\"element\\\":\\\"#FOLDER_SHOWCASE_DESCRIPTION\\\"}\",\n \"backdrop\": \"around_mask\"\n },\n {\n \"uiType\": \"popover\",\n \"uiConfig\": \"{\\\"element\\\":\\\"#FOLDER_SHOWCASE_DESCRIPTION\\\",\\\"placement\\\":\\\"left\\\",\\\"title\\\":\\\"How to use a datasheet\\\",\\\"description\\\":\\\"Click here to view or modify description\\\"}\"\n },\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \"#FOLDER_SHOWCASE_DESCRIPTION\",\n \"finishTodoWhen\": [\n \"click\"\n ]\n }\n }\n ]\n },\n {\n \"text\": \"Set access permission on a file to prevent data leakage or misoperation\",\n \"actions\": [\n {\n \"uiType\": \"breath\",\n \"uiConfig\": \"{\\\"element\\\":\\\"#FOLDER_SHOWCASE_BTN_MORE\\\"}\"\n },\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \"#FOLDER_SHOWCASE_BTN_MORE\",\n \"nextActions\": [\n {\n \"uiType\": \"breath\",\n \"uiConfig\": \"{\\\"element\\\":\\\".sc-eFehXo div:nth-of-type(1)\\\",\\\"shadowDirection\\\":\\\"inset\\\"}\"\n },\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \".sc-eFehXo div:nth-of-type(1)\",\n \"finishTodoWhen\": [\n \"click\"\n ]\n }\n }\n ]\n }\n }\n ]\n },\n {\n \"text\": \"Pick and enter a node to start collaborating with others\",\n \"actions\": [\n {\n \"uiType\": \"breath\",\n \"uiConfig\": \"{\\\"element\\\":\\\"#FOLDER_SHOWCASE_FIRST_NODE\\\"}\"\n },\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \"#FOLDER_SHOWCASE_NODES_CONTAINER > div\",\n \"finishTodoWhen\": [\n \"click\"\n ]\n }\n }\n ]\n }\n ]\n}", + "player_step_ui_config_94": "{\n \"title\": \"Let's go start your project!\",\n \"description\": \"Welcome to Vika Planet! Let's take up a task and our journey will start from here.\",\n \"data\": [\n {\n \"text\": \"Rename a file node to make the index clearer\",\n \"stopEvents\": [\n \"onMouseDown\"\n ],\n \"actions\": [\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \"#FOLDER_SHOWCASE_TITLE\",\n \"emitEvent\": \"click\",\n \"nextActions\": [\n {\n \"uiType\": \"popover\",\n \"uiConfig\": \"{\\\"element\\\":\\\"#FOLDER_SHOWCASE_TITLE_INPUT\\\",\\\"placement\\\":\\\"bottom\\\",\\\"title\\\":\\\"How to use a datasheet\\\",\\\"description\\\":\\\"Click here to rename the file node 👆\\\"}\",\n \"backdrop\": \"around_mask\"\n },\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \"#FOLDER_SHOWCASE_TITLE_INPUT\",\n \"emitEvent\": \"focus\",\n \"finishTodoWhen\": [\n \"blur\"\n ]\n }\n }\n ]\n }\n }\n ]\n },\n {\n \"text\": \"Modify a file node's description to help others understand it better\",\n \"actions\": [\n {\n \"uiType\": \"breath\",\n \"uiConfig\": \"{\\\"element\\\":\\\"#FOLDER_SHOWCASE_DESCRIPTION\\\"}\",\n \"backdrop\": \"around_mask\"\n },\n {\n \"uiType\": \"popover\",\n \"uiConfig\": \"{\\\"element\\\":\\\"#FOLDER_SHOWCASE_DESCRIPTION\\\",\\\"placement\\\":\\\"left\\\",\\\"title\\\":\\\"How to use a datasheet\\\",\\\"description\\\":\\\"Click here to view or modify description\\\"}\"\n },\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \"#FOLDER_SHOWCASE_DESCRIPTION\",\n \"finishTodoWhen\": [\n \"click\"\n ]\n }\n }\n ]\n },\n {\n \"text\": \"Set access permission on a file node to prevent data leakage or misoperation\",\n \"actions\": [\n {\n \"uiType\": \"breath\",\n \"uiConfig\": \"{\\\"element\\\":\\\"#FOLDER_SHOWCASE_BTN_MORE\\\"}\"\n },\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \"#FOLDER_SHOWCASE_BTN_MORE\",\n \"nextActions\": [\n {\n \"uiType\": \"breath\",\n \"uiConfig\": \"{\\\"element\\\":\\\".sc-eFehXo div:nth-of-type(1)\\\",\\\"shadowDirection\\\":\\\"inset\\\"}\"\n },\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \".sc-eFehXo div:nth-of-type(1)\",\n \"finishTodoWhen\": [\n \"click\"\n ]\n }\n }\n ]\n }\n }\n ]\n },\n {\n \"text\": \"Pick and enter a node to start collaborating with others\",\n \"actions\": [\n {\n \"uiType\": \"breath\",\n \"uiConfig\": \"{\\\"element\\\":\\\"#FOLDER_SHOWCASE_FIRST_NODE\\\"}\"\n },\n {\n \"uiType\": \"element\",\n \"uiConfig\": {\n \"element\": \"#FOLDER_SHOWCASE_NODES_CONTAINER > div\",\n \"finishTodoWhen\": [\n \"click\"\n ]\n }\n }\n ]\n }\n ]\n}", "player_step_ui_config_95": "", "player_step_ui_config_97": "{\n\t\"vikaby\": {\n\t\t\"title\": \"Hello~\",\n\t\t\"description\": \"If you have a problem, you can contact me to help you\",\n\t\t\"list\": \"
  • Not sure how to use vikadata
  • What vikadata can do for me
  • Problems during use
  • What's new in the future
  • Get official invitation code
\",\n\t\t\"tip\": \"Scan the QR code to contact us\"\n\t},\n\t\"questionnaire\": {\n\t\t\"title\": \"Hello, I'm Vika's Digitalization Consultant\",\n\t\t\"list\": \"[{\\\"title\\\": \\\"Report bug\\\", \\\"icon\\\": \\\"BugOutlined\\\"}, {\\\"title\\\": \\\"Give feedback\\\", \\\"icon\\\": \\\"AdviseSmallOutlined\\\"}, {\\\"title\\\": \\\"Customer support\\\", \\\"icon\\\": \\\"ServeOutlined\\\"}, {\\\"title\\\": \\\"Case recommendation\\\", \\\"icon\\\": \\\"ZanOutlined\\\"}, {\\\"title\\\": \\\"Solutions\\\", \\\"icon\\\": \\\"SolutionSmallOutlined\\\"}, {\\\"title\\\": \\\"FAQs\\\", \\\"icon\\\": \\\"InformationLargeOutlined\\\"}]\",\n\t\t\"tip\": \"Please use WeChat to scan the code to add customer service to get more exclusive services\"\n\t},\n\t\"website\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/03/02/59f4cc8e0b2b4395bf0fcd133d208e63\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/03/02/defbf55d1e9646eb929f9f5d11d5c119\"\n\t},\n\t\"dingtalk\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/03/02/964be5e3217b4fa8bfa74ef47a980093?attname=dingtalk-questionnaire.png\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/03/02/964be5e3217b4fa8bfa74ef47a980093?attname=dingtalk-vikaby.png\",\n\"tip\": \"Please use DingTalk to scan the code to join our group\"\n\t},\n\t\"wecom\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/03/02/1346d5efbd5043efb2bfcba0075c0ee9\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/03/02/09401a8f2d8e491a9097b9bac8b5a4e4\"\n\t},\n\t\"feishu\": {\n\t\t\"title\": \"Scan the QR code to contact us\",\n\t\t\"tip\": \"Please use Lark to scan the code and add customer service for more help\",\n\t\t\"description\": \"So that you can get service at any time when you encounter problems during use\",\n\t\t\"originUrl\": \"https://u.vika.cn/z9ygm\"\n\t}\n}", "player_step_ui_config_99": "", @@ -9824,7 +10136,7 @@ "pre_fill_share_copy_title": "The public link with pre-filled data", "pre_fill_title": "Form Pre-fill", "pre_fill_title_btn": "Pre-fill", - "pre_set_node_permission": "Field permissions can only be set after the file permissions of the current datasheet are enabled in the explorer", + "pre_set_node_permission": "Field permissions can only be set after the file node permissions of the current datasheet are enabled in the explorer", "precision": "Precision", "press_again_to_exit": "Press again to exit!", "preview": "Preview", @@ -9841,6 +10153,7 @@ "preview_guide_click_to_restart": "Press the button below to preview again", "preview_guide_enable_it": "Press the button below to turn on this function", "preview_guide_open_office_preview": "To preview this file, please turn on the \"office preview\" function", + "preview_next_automation_execution_time": "Preview next 10 execution times", "preview_not_support_video_codecs": "Only MP4 videos with H.264 video codecs can be preview", "preview_revision": "Preview", "preview_see_more": "Want to learn more about the \"office file preview\" feature? Please click here", @@ -9876,6 +10189,7 @@ "privacy_protection": "\"Privacy Protection\"", "private_cloud": "Private Cloud", "private_external_person_only": " External person only", + "private_help_link": "https://help.aitable.ai/docs/guide/team-and-private-area#private-area", "private_internal_person_only": " Internal person only", "private_product_point": "Own your APITable platform with one click", "privatized_deployment": "Self-Hosted", @@ -9914,10 +10228,10 @@ "quick_import_widget": "Import installed widgets", "quick_login": "Quick login options", "quick_login_bind": "<%= type %>", - "quick_search_intro": "Quickly obtain relevant search results by entering a keyword. Filter by file type (e.g. datasheet, folder, form, mirror, dashboard) using category items", + "quick_search_intro": "Quickly obtain relevant search results by entering a keyword. Filter by file node type (e.g. datasheet, folder, form, mirror, dashboard) using category items", "quick_search_loading": "Searching...", "quick_search_not_found": "We couldn't find what you were searching for", - "quick_search_placeholder": "Search for files", + "quick_search_placeholder": "Search for file nodes", "quick_search_shortcut_esc": "Close", "quick_search_shortcut_open": "Open", "quick_search_shortcut_select": "Select", @@ -9946,13 +10260,15 @@ "reconciled_data": "Data is being reconciled", "record": "Record", "record_activity_experience_tips": "You can view record activity of ${day} days", + "record_archived_data": "archived record", + "record_chunk_text": "${text} rows, please wait", "record_comment": "Comments only", "record_comments": "comments", "record_fail_data": "data error", "record_filter_tips": "This record has been filtered", "record_functions": "Record Function", "record_history": "Revision history only", - "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-history", + "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-activity", "record_history_title": "Record history", "record_pre_filtered": "This record has been filtered and will be hidden once you click outside the record", "record_pre_move": "This record will be moved elsewhere once you click outside the record", @@ -9963,9 +10279,9 @@ "records_of_count": "${count} records", "records_per_datasheet": "The number of records per datasheet", "records_per_space": "Total records of the Space", - "recover_node": "Restore file", - "recover_node_fail": "Failed to restore file", - "recover_node_success": "File restored ", + "recover_node": "Restore file node", + "recover_node_fail": "Failed to restore file node", + "recover_node_success": "File node restored ", "redemption_code": "Used redeem code", "redemption_code_button": "Redeem code", "redo": "Redo", @@ -9984,7 +10300,7 @@ "reject": "Reject", "rejected": "Rejected", "related_automations_disconnect_title": "Are you sure to disconnect this automation?", - "related_files": "Related files", + "related_files": "Related file nodes", "reload_page_later_msg": "Synchronization is done. The page will refresh in 5 seconds.", "remain": "remain:", "remain_capacity": "Remaining capacity", @@ -9998,7 +10314,7 @@ "remove_from_group": "You were removed from the \"\" team of the \"\" Space by .", "remove_from_role": "You were removed from the \"\" role of the \"\" Space by .", "remove_from_space": "Remove from Space", - "remove_from_space_confirm_tip": "Confirm to move the member out of this Space completely", + "remove_from_space_confirm_tip": "Confirm to completely remove the member from this workspace. After removal, the member's private workspace files will no longer occupy the capacity of the workspace station.", "remove_from_team": "Remove from team", "remove_from_team_confirm_tip": "Confirm to remove the member from this team", "remove_from_the_team": "Remove", @@ -10010,9 +10326,9 @@ "remove_members_button": "Remove forever", "remove_members_content": "Remove selected members from the organization?", "remove_members_title": "Remove members", - "remove_own_permissions_desc": "You are removing your own permission, which may prevent you from viewing this file after operation", + "remove_own_permissions_desc": "You are removing your own permission, which may prevent you from viewing this file node after operation", "remove_permissions": "Remove permission", - "remove_permissions_desc": "After removing permissions, the member/team may not be able to view the file", + "remove_permissions_desc": "After removing permissions, the member/team may not be able to view the file node", "remove_role": "Remove permission", "removed_member_tomyself": "You removed from the \"\" Space.", "rename": "Rename", @@ -10045,7 +10361,7 @@ "request_in_api_panel_curl": "Make a request", "request_in_api_panel_curl_warning": "Turn the jump to Apifox (including the API token), do you continue? After clicking confirm, the next time will not be reminded.", "request_tree_node_error_tips": "Request failed, please click retry", - "require_login_tip": "Editing a shared file requires login ", + "require_login_tip": "Editing a shared file node requires login ", "reselect": "Reselect", "reset": "Reset", "reset_password": "Reset password", @@ -10326,7 +10642,7 @@ "role_permission_manage_team": "Manage teams", "role_permission_manage_template": "Manage templates", "role_permission_manage_widget": "Manage Widget Center", - "role_permission_manage_workbench": "Manage file permissions", + "role_permission_manage_workbench": "Manage file node permissions", "rollback": "Rollback", "rollback_fail_content": "The current version has data conflicts and does not support rollback, Learn more", "rollback_fail_tip": "${type} Failed, please try again!", @@ -10381,7 +10697,7 @@ "sao_tome_and_principe": "Sao Tome and Principe", "saudi_arabia": "Saudi Arabia", "save": "Save", - "save_action_desc": "You can save this file as a copy", + "save_action_desc": "You can save this file node as a copy", "save_as_template": "Save as template", "save_document": "Save as copy", "save_template_disabled": "Cannot save as template", @@ -10392,6 +10708,12 @@ "scan_to_login": "Scan to login", "scan_to_login_by_method": "Please scan ${method} to follow official account to login", "scatter_chart": "Scatter Chart", + "schedule_day_tips": "The cycle calculation begins counting from the first day of each month. If we assume that it repeats every 10 days, then it will be triggered on the 1st, 11th, 21st and 31st day of each month", + "schedule_hour_tips": "The cycle calculation begins at midnight (0:00) each day. Assuming it repeats 0 minutes every three hours, it will occur at midnight (0:00), 3 AM, 6 AM, 9 AM, noon (12 PM), \n\n3 PM,6 PM, and finally at nightfall (9 PM) daily", + "schedule_start_day": "Starting from the 1st day of the month, ", + "schedule_start_month": "Starting from January each year, every", + "schedule_type": "Schedule Type", + "schedule_year_tips": "The cycle calculation begins counting from the first month of each year. Assuming an interval of first day 3 months, triggers will be activated at midnight on the first day of January, April, July, and October every year.", "science_and_technology": "Science and technology", "scroll_screen_down": "Scroll one screen down", "scroll_screen_left": "Scroll one screen left", @@ -10404,7 +10726,8 @@ "search_folder_or_form": "Find a folder or form ", "search_folder_or_sheet": "Find a folder or datasheet ", "search_new_admin": "Search", - "search_node_pleaseholder": "Search for files (${shortcutKey})", + "search_node_pleaseholder": "Search for file nodes (${shortcutKey})", + "search_node_tip": "Quick search (${shortcutKey})", "search_or_add": "Find or add an option", "search_role_placeholder": "Search roles", "seats": "Seats", @@ -10451,22 +10774,22 @@ "security_disabled_download_file": "Prevent read-only users from downloading attachments", "security_disabled_download_file_describle": "Users with \"read-Only\" permission cannot download attachments in cells, both on and off the Space", "security_disabled_download_file_modal_describle": "Users with \"read-Only\" permission can download attachments in cells, both on and off the Space", - "security_disabled_download_file_modal_title": "Allow read-only users to export files", + "security_disabled_download_file_modal_title": "Allow read-only users to export file nodes", "security_disabled_download_file_tip": "Users with \"read-Only\" permission cannot download attachments in cells", - "security_disabled_export": "Prohibition of file sharing", + "security_disabled_export": "Prohibition of file node sharing", "security_disabled_export_data": "Prevent members from exporting datasheet or view", "security_disabled_export_data_describle": "All members cannot export datasheet or view data locally", "security_disabled_export_data_modal_describle": "If members have the \"manageable\" permission to a datasheet, they can export it to a local file.", - "security_disabled_export_data_modal_title": "Allow to export files", - "security_disabled_export_tip": "Prohibit all members from sharing files outside the space", + "security_disabled_export_data_modal_title": "Allow to export file nodes", + "security_disabled_export_tip": "Prohibit all members from sharing file nodes outside the space", "security_disabled_invite_member": "Prevent members from inviting user", "security_disabled_invite_member_describle": "No one can invite users to join the Space except Space admin,and the generated invitation link will be invalid", "security_disabled_invite_member_modal_describle": "Once switched on, all members can invite new members from the contacts panel", "security_disabled_invite_member_modal_title": "Allow to invite members", - "security_disabled_share": " Disable sharing files", - "security_disabled_share_describle": "All members cannot creat the public link of the file, and the generated public link becomes invalid", - "security_disabled_share_modal_describle": "members can open the public link of the file", - "security_disabled_share_modal_title": "Allow to share files", + "security_disabled_share": " Disable sharing file nodes", + "security_disabled_share_describle": "All members cannot creat the public link of the file node, and the generated public link becomes invalid", + "security_disabled_share_modal_describle": "members can open the public link of the file node", + "security_disabled_share_modal_title": "Allow to share file nodes", "security_features": "Security", "security_setting_address_list_isolation": "You are experiencing the ${grade} space exclusive feature, which will be unlocked when you upgrade", "security_setting_apply_join_space": "You are experiencing the ${grade} space exclusive feature, which will be unlocked when you upgrade", @@ -10475,8 +10798,8 @@ "security_setting_apply_join_space_title": "Prevent users from applying to join the Space in the sharing page ", "security_setting_catalog_management": "You are experiencing the ${grade} space exclusive feature, which will be unlocked when you upgrade", "security_setting_catalog_management_describle": "Members can create new nodes to the root of the Working catalog. After the function is disabled, only Space admin can create.", - "security_setting_catalog_management_description": "Members can't create new files at the root of the catalog. After toggling this on, only space admins can create new files at the root of the catalog.", - "security_setting_catalog_management_title": "Prevent members from creating new files at the root of the catalog", + "security_setting_catalog_management_description": "Members can't create new file nodes at the root of the catalog. After toggling this on, only space admins can create new file nodes at the root of the catalog.", + "security_setting_catalog_management_title": "Prevent members from creating new file nodes at the root of the catalog", "security_setting_copy_cell_data": "You are experiencing the ${grade} space exclusive feature, which will be unlocked when you upgrade", "security_setting_copy_cell_data_describle": "After the function is disabled,users with \"read-Only\" permission cannot copy cell data, both on and off the Space", "security_setting_copy_cell_data_description": "Users with \"Read-only\" permission cannot copy data in cells", @@ -10500,8 +10823,8 @@ "security_setting_invite_member_title": "Prevent members from inviting user", "security_setting_mobile": "You are experiencing the ${grade} space exclusive feature, which will be unlocked when you upgrade", "security_setting_share": "You are experiencing the ${grade} space exclusive feature, which will be unlocked when you upgrade", - "security_setting_share_describle": "All members cannot creat the public link of the file, and the generated public link becomes invalid", - "security_setting_share_description": "All members cannot creat the public link of the file, and the generated public link becomes invalid", + "security_setting_share_describle": "All members cannot creat the public link of the file node, and the generated public link becomes invalid", + "security_setting_share_description": "All members cannot creat the public link of the file node, and the generated public link becomes invalid", "security_setting_share_title": "Prevent members from creating public links", "security_show_mobile": "Show phone numbers", "security_show_mobile_describle": "Show all members' phone numbers in contacts", @@ -10533,7 +10856,7 @@ "select_link_data_number": "Select the number of linked records", "select_link_data_number_all": "Link all records", "select_link_data_number_first": "Link the first record", - "select_local_file": "Drag and drop files or click here to upload", + "select_local_file": "Drag and drop attachments or click here to upload", "select_one_field": "Select field type", "select_phone_code": "Select country and region", "select_sort_rule": "Select sort rule", @@ -10599,7 +10922,7 @@ "set_permission_modal_help": "https://help.aitable.ai/docs/guide/faq-permission-settings", "set_permission_modal_radio_1": "Inherit superior permission", "set_permission_modal_radio_1_description": "Member and team inherit the permissions of the superior folder\"${parent_node_name}\"", - "set_permission_modal_radio_2": "File permissions", + "set_permission_modal_radio_2": "File node permissions", "set_permission_modal_radio_2_description": "Separately specify permission of member and team for the current ${node_type}", "set_permission_modal_title": "Assign permissions to members in ${name}", "set_permission_success_tips": "Permission set successfully", @@ -10626,7 +10949,7 @@ "share_configuration": "Sharing setting", "share_copy_url_link": "Copy link", "share_edit_exist_member_tip": "The current datasheet has ${content}. Confirm only if you allow others to view the organizational chart of the Space.", - "share_edit_tip": "The file is read-only before you log in. Please log in and try again.", + "share_edit_tip": "The file node is read-only before you log in. Please log in and try again.", "share_editor": "Log in to edit", "share_editor_label": "Log in to edit", "share_email_invite": "Invite collaborators into your Space", @@ -10642,17 +10965,17 @@ "share_form_title": "Fill in the form via the public link", "share_invite_no_permission": "You do not have permission to invite members", "share_link_text": "", - "share_login_tip": "Log in to edit file", + "share_login_tip": "Log in to edit file node", "share_mobile_friendly_tip": "88% of people get a better experience by editing on the computer", "share_modal_desc": "Copy the exclusive link below~
Invite friends to use APITable
Share with friends", "share_modal_title": "Share", "share_node_number_err_content": "share_node_number_err_content", - "share_only_desc": "External users outside the space can only view the file", + "share_only_desc": "External users outside the space can only view the file node", "share_only_title": "Share with others for reading-only", - "share_permisson_model_link_datasheet_label": "Related external files", - "share_permisson_model_link_datasheet_label_desc": "The current file (folder) is related with an external Datasheet", - "share_permisson_model_node_owner": "File owner", - "share_permisson_model_node_owner_desc": "The member has enabled manual permission setting for this file", + "share_permisson_model_link_datasheet_label": "Related external file nodes", + "share_permisson_model_link_datasheet_label_desc": "The current file node (folder) is related with an external Datasheet", + "share_permisson_model_node_owner": "File node owner", + "share_permisson_model_node_owner_desc": "The member has enabled manual permission setting for this file node", "share_permisson_model_open_share_false_1": "Failed to share. Someone else has enabled the sharing.", "share_permisson_model_open_share_label": "Sharing enabled", "share_permisson_model_open_share_label_desc": "${member_name} enables sharing, and external users can access the content via the public link", @@ -10668,8 +10991,8 @@ "share_save_label": "This shared content can be saved as a copy", "share_setting": "Share outside the Space", "share_settings_tip": "Sharing settings updated ${status}", - "share_succeed": "File shared", - "share_tips": "Publish a share link for this file. Users who obtain the link on the Internet can view, edit, or copy the file based on their permissions.", + "share_succeed": "File node shared", + "share_tips": "Publish a share link for this file node. Users who obtain the link on the Internet can view, edit, or copy the file node based on their permissions.", "share_tips_title": "Publish share link", "share_title": "Share \"${node}\"", "share_with_offsite_users": "Share with users outside the Space", @@ -10792,8 +11115,8 @@ "space_exist_dashboard": "Send widget to dashboard", "space_field_permission_limit": "The maximum number of field permissions to be used in the \"\" Space is . So far, has been used, and you can upgrade to get higher usage.", "space_field_permission_limit_email_title": "Usage reminders for the number of field permissions in the \"${SPACE_NAME}\" space", - "space_file_permission_limit": "The maximum number of file permissions to be used in the \"\" Space is . So far, has been used, and you can upgrade to get higher usage.", - "space_file_permission_limit_email_title": "Usage reminders for the number of file permissions in the \"${SPACE_NAME}\" space", + "space_file_permission_limit": "The maximum number of file node permissions to be used in the \"\" Space is . So far, has been used, and you can upgrade to get higher usage.", + "space_file_permission_limit_email_title": "Usage reminders for the number of file node permissions in the \"${SPACE_NAME}\" space", "space_form_limit": "The maximum number of forms to be used in the \"\" Space is . So far, has been used, and you can upgrade to get higher usage.", "space_form_limit_email_title": "Usage reminders for the number of forms in the \"${SPACE_NAME}\" space", "space_free_capacity_expansion": "Free expansion", @@ -10808,6 +11131,7 @@ "space_info": "Overview", "space_info_del_confirm1": "1. Deleting this Space will clean up the following data:", "space_info_del_confirm2": "2. The Space will be deleted completely after 7 days. You can restore the Space before then.", + "space_info_del_confirm3": "3. For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "space_info_feishu_desc": "You are using a third-party integration. To delete the Space, please disable the third-party integration first. ", "space_info_feishu_label": "Integrations", "space_join_apply": " requested to join the \"\" Space.", @@ -10821,7 +11145,7 @@ "space_log_actions": "Actions", "space_log_date_range": "Date range", "space_log_download_button": "Download logs", - "space_log_file_name": "File name", + "space_log_file_name": "File node name", "space_log_operator": "Operator", "space_log_title": "Space logs", "space_log_trial_button": "Try now", @@ -10863,7 +11187,7 @@ "space_template": "Custom", "space_time_machine_limit": "Your Space supports days of record history. You can upgrade the plan to see longer history.", "space_time_machine_limit_email_title": "", - "space_trash_limit": "Your Space supports keeping deleted files in trash within days. You can upgrade the plan to see more.", + "space_trash_limit": "Your Space supports keeping deleted file nodes in trash within days. You can upgrade the plan to see more.", "space_trash_limit_email_title": "", "space_trial": "Congrats! Your \"\" Space has upgraded to the (on trial). The plan will expire at .", "space_watermark_notify": "The Space is using the enterprise-level feature \"Global Watermarks\". Please upgrade to continue using it.", @@ -10894,6 +11218,7 @@ "start_onfiguration": "Start configuration", "start_time": "Start time", "start_use": "Start using", + "starting_from_midnight": "Starting from midnight (12:00 AM) every day, ", "startup": "Startup", "startup_company_support_program": "Startup support Program", "stat_average": "Average", @@ -10927,6 +11252,8 @@ "stay_tuned_for_more_features": "Stay tuned for more features", "steps_choose_reset_mode": "Select a reset method", "steps_validate_identities": "Verify identity", + "stop_chunk_content": "Are you sure you want to stop the operation?", + "stop_chunk_title": "Stop", "stop_dingtalk_h5_modal_content": "The self-built application will be unbound from this space. Please confirm .", "storage_per_seats": "", "storage_per_space": "Storage usage", @@ -10957,9 +11284,11 @@ "subscribe_credit_usage_over_limit": "The number of credits in the current space exceeds the limit, please upgrade your subscription.\n", "subscribe_demonstrate": "Request demos", "subscribe_disabled_seat": "The number of people cannot be lower than the original program", + "subscribe_grade_business": "Business", "subscribe_grade_free": "Free", "subscribe_grade_plus": "Plus", "subscribe_grade_pro": "Pro", + "subscribe_grade_starter": "Starter", "subscribe_label_tooltip": "Advanced space features", "subscribe_new_choose_member": "Supports up to ${member_num} members", "subscribe_new_choose_member_tips": "This plan supports 1~${member_num} members to enter the space", @@ -10975,9 +11304,9 @@ "subscribed_record_unarchived": " unarchived in ", "subscription_expire_error": "Your subscription status has expired", "subscription_fee": "Subscription fee: ${fee}", - "subscription_grades_checklist": "{\n \"Usages\": [\n {\n \"group\": \"Usages\",\n \"id\": \"member_num\",\n \"title\": \"Seats\",\n \"bronze\": \"Incl. 5 seats\",\n \"silver\": \"Incl. 5 seats\",\n \"gold\": \"Incl. 5 seats\",\n \"enterprise\": \"Incl. 5 seats\",\n \"community\":\"Unlimited\",\n \"custom\":\"Custom\"\n },\n {\n \"group\": \"Usages\",\n \"id\": \"datasheet_number\",\n \"title\": \"File nodes \",\n \"bronze\": \"30\",\n \"silver\": \"300\",\n \"gold\": \"1,000\",\n \"enterprise\": \"10,000\",\n \"community\":\"Unlimited\",\n \"custom\":\"Unlimited\"\n },\n {\n \"group\": \"Usages\",\n \"id\": \"datasheet_rows\",\n \"title\": \"Records per datasheet\",\n \"bronze\": \"5,000 \",\n \"silver\": \"10,000\",\n \"gold\": \"20,000\",\n \"enterprise\": \"50,000\",\n \"community\":\"50,000\",\n \"custom\":\"50,000\"\n },\n {\n \"group\": \"Usages\",\n \"id\": \"space_rows\",\n \"title\": \"Records per space\",\n \"bronze\": \"20,000\",\n \"silver\": \"3,000,000\",\n \"gold\": \"20,000,000\",\n \"enterprise\": \"500,000,000\",\n \"community\":\"Unlimited\",\n \"custom\":\"Unlimited\"\n },\n {\n \"group\": \"Usages\",\n \"id\": \"space_capacity\",\n \"title\": \"Attachments storage per space\",\n \"bronze\": \"1GB \",\n \"silver\": \"Seats * 5GB\",\n \"gold\": \"Seats * 7GB\",\n \"enterprise\": \"Seats * 10GB\",\n \"community\":\"Unlimited\",\n \"custom\":\"Unlimited\"\n }\n ],\n \"Features\": [\n {\n \"group\": \"Features\",\n \"id\": \"star_marker\",\n \"title\": \"Pin\",\n \"bronze\": true,\n \"silver\": true,\n \"gold\": true,\n \"enterprise\": true,\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"album_view\",\n \"title\": \"Gallery view\",\n \"bronze\": true,\n \"silver\": true,\n \"gold\": true,\n \"enterprise\": true,\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"kanban_view\",\n \"title\": \"Kanban view\",\n \"bronze\": true,\n \"silver\": true,\n \"gold\": true,\n \"enterprise\": true,\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"org_chart_view\",\n \"title\": \"Architecture view\",\n \"bronze\": true,\n \"silver\": true,\n \"gold\": true,\n \"enterprise\": true,\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"gantt_view\",\n \"title\": \"Gantt view\",\n \"bronze\": \"10 per space\",\n \"silver\": \"50 per space\",\n \"gold\": \"200 per space\",\n \"enterprise\": \"Unlimited\",\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"calendar_view\",\n \"title\": \"Calendar view\",\n \"bronze\": \"5 per space\",\n \"silver\": \"50 per space\",\n \"gold\": \"200 per space\",\n \"enterprise\": \"Unlimited\",\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"collection_table\",\n \"title\": \"Form\",\n \"bronze\": \"20 per space\",\n \"silver\": \"100 per space\",\n \"gold\": \"300 per space\",\n \"enterprise\": \"Unlimited\",\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"mirror\",\n \"title\": \"Mirror(records permission)\",\n \"bronze\": \"5 per space\",\n \"silver\": \"50 per space\",\n \"gold\": \"100 per space\",\n \"enterprise\": \"Unlimited\",\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"widget\",\n \"title\": \"Widget\",\n \"bronze\": \"Free for a limited time\",\n \"silver\": \"Free for a limited time\",\n \"gold\": \"Free for a limited time\",\n \"enterprise\": \"Free for a limited time\",\n \"community\":\"Free for a limited time\",\n \"custom\":\"Free for a limited time\"\n },\n {\n \"group\": \"Features\",\n \"id\": \"dashboard\",\n \"title\": \"Dashboard\",\n \"bronze\": \"5 per space\",\n \"silver\": \"50 per space\",\n \"gold\": \"100 per space\",\n \"enterprise\": \"Unlimited\",\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"custom_embedding\",\n \"title\": \"Custom embedding\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": true,\n \"enterprise\": true,\n \"community\":false,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"rainbow_tags\",\n \"title\": \"Rainbow tags\",\n \"bronze\": \"Basic color\",\n \"silver\": \"Advanced color\",\n \"gold\": \"Advanced color\",\n \"enterprise\": \"Advanced color\",\n \"community\":\"Basic color\",\n \"custom\":\"Advanced color\"\n },\n {\n \"group\": \"Features\",\n \"id\": \"space_capacity\",\n \"title\": \"Record activity\",\n \"bronze\": \"14 days\",\n \"silver\": \"3 months\",\n \"gold\": \"6 months\",\n \"enterprise\": \"24 months\",\n \"community\": true,\n \"custom\": true\n },\n {\n \"group\": \"Features\",\n \"id\": \"recycle_bin\",\n \"title\": \"Trash\",\n \"bronze\": \"14 days\",\n \"silver\": \"3 months\",\n \"gold\": \"6 months\",\n \"enterprise\": \"24 months\",\n \"community\": true,\n \"custom\": true\n },\n {\n \"group\": \"Features\",\n \"id\": \"api_limits\",\n \"title\": \"API\",\n \"bronze\": \"Free for a limited time\",\n \"silver\": \"Free for a limited time\",\n \"gold\": \"Free for a limited time\",\n \"enterprise\": \"Free for a limited time\",\n \"community\": true,\n \"custom\": true\n },\n {\n \"group\": \"Features\",\n \"id\": \"robot\",\n \"title\": \"Automation\",\n \"bronze\": \"Free for a limited time\",\n \"silver\": \"Free for a limited time\",\n \"gold\": \"Free for a limited time\",\n \"enterprise\": \"Free for a limited time\",\n \"community\": true,\n \"custom\": true\n }\n ],\n \"Management and security\": [\n {\n \"group\": \"Management and security\",\n \"id\": \"column_permission\",\n \"title\": \"Field permissions\",\n \"bronze\": \"10 per space\",\n \"silver\": \"50 per space\",\n \"gold\": \"200 per space\",\n \"enterprise\": \"Unlimited\",\n \"community\":false,\n \"custom\":true\n },\n {\n \"group\": \"Management and security\",\n \"id\": \"folder_permission\",\n \"title\": \"File permissions\",\n \"bronze\": \"10 per space\",\n \"silver\": \"50 per space\",\n \"gold\": \"200 per space\",\n \"enterprise\": \"Unlimited\",\n \"community\":false,\n \"custom\":true\n },\n {\n \"group\": \"Management and security\",\n \"id\": \"admin_counts\",\n \"title\": \"Space admin\",\n \"bronze\": \"3\",\n \"silver\": \"5\",\n \"gold\": \"10\",\n \"enterprise\": \"Unlimited\",\n \"community\": false,\n \"custom\": true\n },\n {\n \"group\": \"Management and security\",\n \"id\": \"watermark\",\n \"title\": \"Watermark\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": false,\n \"enterprise\": true,\n \"community\": false,\n \"custom\": true\n },\n {\n \"group\": \"Management and security\",\n \"id\": \"security_disabled_export_data\",\n \"title\": \"Disable data export\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": true,\n \"enterprise\": true,\n \"community\": false,\n \"custom\": true\n },\n {\n \"group\": \"Management and security\",\n \"id\": \"security_disabled_share\",\n \"title\": \"Disable opening public links\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": false,\n \"enterprise\": true,\n \"community\": false,\n \"custom\": true\n },\n {\n \"group\": \"Management and security\",\n \"id\": \"security_disabled_copy\",\n \"title\": \"Disable copying datas\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": false,\n \"enterprise\": true,\n \"community\": false,\n \"custom\": true\n },\n {\n \"group\": \"Management and security\",\n \"id\": \"security_disabled_download_file\",\n \"title\": \"Disable downloadimg files\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": false,\n \"enterprise\": true,\n \"community\": false,\n \"custom\": true\n },\n {\n \"group\": \"Management and security\",\n \"id\": \"security_disabled_invite_members\",\n \"title\": \"Disable inviting off-space user\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": false,\n \"enterprise\": true,\n \"community\": false,\n \"custom\": true\n }\n ,\n {\n \"group\": \"Management and security\",\n \"id\": \"space_log\",\n \"title\": \"Space log\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": false,\n \"enterprise\": true,\n \"community\": false,\n \"custom\": true\n }\n ],\n \"Professional Services\": [\n {\n \"group\": \"Professional Services\",\n \"id\": \"professional_services\",\n \"title\": \"Consultant Services\",\n \"bronze\": \"Community\",\n \"silver\": \"Community\",\n \"gold\": \"Community\",\n \"enterprise\": \"Customer Success Manager\",\n \"community\": \"Community\",\n \"custom\": \"Customer Success Manager\"\n },\n {\n \"group\": \"Professional Services\",\n \"id\": \"enterprise_consulting_training\",\n \"title\": \"Enterprise-level consulting training\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": false,\n \"enterprise\": true,\n \"community\": false,\n \"custom\": true\n }\n ]\n}", - "subscription_grades_checklist_mobile_saas": "[\n {\n \"grade\": \"free\",\n \"btnText\": \"Start Now\",\n \"btnHref\": \"/login\",\n \"primaryContent\": [\n \"30 file nodes\",\n \"5,000 records per datasheet\",\n \"1G attachments storage per sapce\"\n ],\n \"details\": [\n {\n \"name\": \"Usage\",\n \"rules\": [\n \"30 file nodes\",\n \"5,000 records per datasheet\",\n \"20,000 records per sapce\",\n \"1G attachments storage per sapce\"\n ]\n },\n {\n \"name\": \"Features\",\n \"rules\": [\n \"Pin file nodes\",\n \"Gallery view,Kanban view and Architecture view are unlimited\",\n \"10 gantt views per sapce\",\n \"5 calendar views per sapce\",\n \"20 forms per sapce\",\n \"5 mirrors per sapce\",\n \"5 dashbords per sapce\",\n \"Widget is free for a limited time\",\n \"Basic colors for rainbow tags\",\n \"Record activity goes back 14 days\",\n \"Trash goes back 14 days\",\n \"API is free for a limited time\",\n \"Automation is free for a limited time\"\n ]\n },\n {\n \"name\": \"Management and security\",\n \"rules\": [\n \"10 field permissions per sapce\",\n \"10 file permissions per sapce\",\n \"3 admins per sapce\"\n ]\n },\n {\n \"name\": \"Professional Services\",\n \"rules\": [\n \"Community\"\n ]\n }\n ]\n },\n {\n \"grade\": \"plus\",\n \"btnText\": \"Choose Plus\",\n \"btnHref\": \"/login\",\n \"primaryContent\": [\n \"300 file nodes\",\n \"10,000 records per datasheet\",\n \"5G/seats attachments storage per sapce\"\n ],\n \"details\": [\n {\n \"name\": \"Usage\",\n \"rules\": [\n \"300 file nodes\",\n \"10,000 records per datasheet\",\n \"3,0000,000 records per sapce\",\n \"5G/seats attachments storage per sapce\"\n ]\n },\n {\n \"name\": \"Features\",\n \"rules\": [\n \"Pin file nodes\",\n \"Gallery view,Kanban view and Architecture view are unlimited\",\n \"50 gantt views per sapce\",\n \"50 calendar views per sapce\",\n \"100 forms per sapce\",\n \"50 mirrors per sapce\",\n \"50 dashbords per sapce\",\n \"Widget is free for a limited time\",\n \"Advanced colors for rainbow tags\",\n \"Record activity goes back 3 months\",\n \"Trash goes back 3 months\",\n \"API is free for a limited time\",\n \"Automation is free for a limited time\"\n ]\n },\n {\n \"name\": \"Management and security\",\n \"rules\": [\n \"50 field permissions per sapce\",\n \"50 file permissions per sapce\",\n \"5 admins per sapce\"\n ]\n },\n {\n \"name\": \"Professional Services\",\n \"rules\": [\n \"Community\"\n ]\n }\n ]\n },\n {\n \"grade\": \"pro\",\n \"btnText\": \"Choose Pro\",\n \"btnHref\": \"/login\",\n \"primaryContent\": [\n \"1,000 file nodes\",\n \"20,000 records per datasheet\",\n \"7G/seats attachments storage per sapce\",\n \"Custom embedding\"\n ],\n \"details\": [\n {\n \"name\": \"Usage\",\n \"rules\": [\n \"1,000 file nodes\",\n \"20,000 records per datasheet\",\n \"20,000,000 records per sapce\",\n \"7G/seats attachments storage per sapce\"\n ]\n },\n {\n \"name\": \"Features\",\n \"rules\": [\n \"Pin file nodes\",\n \"Gallery view,Kanban view and Architecture view are unlimited\",\n \"200 gantt views per sapce\",\n \"300 calendar views per sapce\",\n \"300 forms per sapce\",\n \"100 mirrors per sapce\",\n \"100 dashbords per sapce\",\n \"Widget is free for a limited time\",\n \"Advanced colors for rainbow tags\",\n \"Custom embedding\",\n \"Record activity goes back 6 months\",\n \"Trash goes back 6 months\",\n \"API is free for a limited time\",\n \"Automation is free for a limited time\"\n ]\n },\n {\n \"name\": \"Management and security\",\n \"rules\": [\n \"200 field permissions per sapce\",\n \"200 file permissions per sapce\",\n \"10 admins per sapce\",\n \"Disable data export\"\n ]\n },\n {\n \"name\": \"Professional Services\",\n \"rules\": [\n \"Community\"\n ]\n }\n ]\n },\n {\n \"grade\": \"enterprise\",\n \"btnText\": \"Contacts us\",\n \"btnHref\": \"\",\n \"primaryContent\": [\n \"10,000 file nodes\",\n \"50,000 records per datasheet\",\n \"10G/seats attachments storage per sapce\",\n \"Unlimited permission and security settings\",\n \"Customer Success Manager\"\n ],\n \"details\": [\n {\n \"name\": \"Usage\",\n \"rules\": [\n \"10,000 file nodes\",\n \"50,000 records per datasheet\",\n \"50,0000,000 records per sapce\",\n \"10G/seats attachments storage per sapce\"\n ]\n },\n {\n \"name\": \"Features\",\n \"rules\": [\n \"Pin file nodes\",\n \"Gallery view,Kanban view and Architecture view are unlimited\",\n \"Gantt views are unlimited\",\n \"Calendar views are unlimited\",\n \"Forms are unlimited\",\n \"Mirrors are unlimited\",\n \"Dashbords are unlimited\",\n \"Widget is free for a limited time\",\n \"Advanced colors for rainbow tags\",\n \"Custom embedding\",\n \"Record activity goes back 24 months\",\n \"Trash goes back 24 months\",\n \"API is free for a limited time\",\n \"Automation is free for a limited time\"\n ]\n },\n {\n \"name\": \"Management and security\",\n \"rules\": [\n \"Field permissions are unlimited\",\n \"File permissions are unlimited\",\n \"Admins are unlimited\",\n \"Watermark\",\n \"Disable data export\",\n \"Disable opening public links\",\n \"Disable copying datas\",\n \"Disable downloadimg files\",\n \"Disable inviting off-space user\",\n \"Space log\"\n ]\n },\n {\n \"name\": \"Professional Services\",\n \"rules\": [\n \"Customer Success Manager\",\n \"Custom function development (additional cost)\",\n \"Enterprise-level consulting training\"\n ]\n }\n ]\n }\n ]", - "subscription_grades_checklist_mobile_selfhost": "[\n {\n \"grade\": \"community\",\n \"btnText\": \"Dowload\",\n \"primaryContent\": [\n \"10,000 file nodes\",\n \"50,000 records per datasheet\",\n \"Unlimitied attachments storage per sapce\"\n ],\n \"details\": [\n {\n \"name\": \"Usage\",\n \"rules\": [\n \"10,000 file nodes\",\n \"50,000 records per datasheet\",\n \"50,0000,000 records per sapce\",\n \"Unlimitied attachments storage per sapce\"\n ]\n },\n {\n \"name\": \"Features\",\n \"rules\": [\n \"Pin file nodes\",\n \"Gallery view,Kanban view and Architecture view are unlimited\",\n \"Gantt views are unlimited\",\n \"Calendar views are unlimited\",\n \"Forms are unlimited\",\n \"Mirrors are unlimited\",\n \"Dashbords are unlimited\",\n \"Widget is free for a limited time\",\n \"Basic colors for rainbow tags\",\n \"Record activity goes back 24 months\",\n \"Trash goes back 24 months\",\n \"API is free for a limited time\",\n \"Automation is free for a limited time\"\n ]\n },\n {\n \"name\": \"Management and security\",\n \"rules\": [\n \"Not supported\"\n ]\n },\n {\n \"name\": \"Professional Services\",\n \"rules\": [\n \"Community\"\n ]\n }\n ]\n },\n {\n \"grade\": \"custom\",\n \"btnText\": \"Contacts us\",\n \"primaryContent\": [\n \"10,000 file nodes\",\n \"50,000 records per datasheet\",\n \"10G/seats attachments storage per sapce\",\n \"Unlimited permission and security settings\",\n \"Customer Success Manager\"\n ],\n \"details\": [\n {\n \"name\": \"Usage\",\n \"rules\": [\n \"10,000 file nodes\",\n \"50,000 records per datasheet\",\n \"50,0000,000 records per sapce\",\n \"Unlimited attachments storage per sapce\"\n ]\n },\n {\n \"name\": \"Features\",\n \"rules\": [\n \"Pin file nodes\",\n \"Gallery view,Kanban view and Architecture view are unlimited\",\n \"Gantt views are unlimited\",\n \"Calendar views are unlimited\",\n \"Forms are unlimited\",\n \"Mirrors are unlimited\",\n \"Dashbords are unlimited\",\n \"Widget is free for a limited time\",\n \"Advanced colors for rainbow tags\",\n \"Custom embedding\",\n \"Record activity goes back 24 months\",\n \"Trash goes back 24 months\",\n \"API is free for a limited time\",\n \"Automation is free for a limited time\"\n ]\n },\n {\n \"name\": \"Management and security\",\n \"rules\": [\n \"Field permissions are unlimited\",\n \"File permissions are unlimited\",\n \"Admins are unlimited\",\n \"Watermark\",\n \"Disable data export\",\n \"Disable opening public links\",\n \"Disable copying datas\",\n \"Disable downloadimg files\",\n \"Disable inviting off-space user\",\n \"Space log\"\n ]\n },\n {\n \"name\": \"Professional Services\",\n \"rules\": [\n \"Customer Success Manager\",\n \"Custom function development (additional cost)\",\n \"Enterprise-level consulting training\"\n ]\n }\n ]\n }\n]", + "subscription_grades_checklist": "{\n \"Usages\": [\n {\n \"group\": \"Usages\",\n \"id\": \"member_num\",\n \"title\": \"Seats\",\n \"bronze\": \"Incl. 5 seats\",\n \"silver\": \"Incl. 5 seats\",\n \"gold\": \"Incl. 5 seats\",\n \"enterprise\": \"Incl. 5 seats\",\n \"community\":\"Unlimited\",\n \"custom\":\"Custom\"\n },\n {\n \"group\": \"Usages\",\n \"id\": \"datasheet_number\",\n \"title\": \"File nodes \",\n \"bronze\": \"30\",\n \"silver\": \"300\",\n \"gold\": \"1,000\",\n \"enterprise\": \"10,000\",\n \"community\":\"Unlimited\",\n \"custom\":\"Unlimited\"\n },\n {\n \"group\": \"Usages\",\n \"id\": \"datasheet_rows\",\n \"title\": \"Records per datasheet\",\n \"bronze\": \"5,000 \",\n \"silver\": \"10,000\",\n \"gold\": \"20,000\",\n \"enterprise\": \"50,000\",\n \"community\":\"50,000\",\n \"custom\":\"50,000\"\n },\n {\n \"group\": \"Usages\",\n \"id\": \"space_rows\",\n \"title\": \"Records per space\",\n \"bronze\": \"20,000\",\n \"silver\": \"3,000,000\",\n \"gold\": \"20,000,000\",\n \"enterprise\": \"500,000,000\",\n \"community\":\"Unlimited\",\n \"custom\":\"Unlimited\"\n },\n {\n \"group\": \"Usages\",\n \"id\": \"space_capacity\",\n \"title\": \"Attachments storage per space\",\n \"bronze\": \"1GB \",\n \"silver\": \"Seats * 5GB\",\n \"gold\": \"Seats * 7GB\",\n \"enterprise\": \"Seats * 10GB\",\n \"community\":\"Unlimited\",\n \"custom\":\"Unlimited\"\n }\n ],\n \"Features\": [\n {\n \"group\": \"Features\",\n \"id\": \"star_marker\",\n \"title\": \"Pin\",\n \"bronze\": true,\n \"silver\": true,\n \"gold\": true,\n \"enterprise\": true,\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"album_view\",\n \"title\": \"Gallery view\",\n \"bronze\": true,\n \"silver\": true,\n \"gold\": true,\n \"enterprise\": true,\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"kanban_view\",\n \"title\": \"Kanban view\",\n \"bronze\": true,\n \"silver\": true,\n \"gold\": true,\n \"enterprise\": true,\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"org_chart_view\",\n \"title\": \"Architecture view\",\n \"bronze\": true,\n \"silver\": true,\n \"gold\": true,\n \"enterprise\": true,\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"gantt_view\",\n \"title\": \"Gantt view\",\n \"bronze\": \"10 per space\",\n \"silver\": \"50 per space\",\n \"gold\": \"200 per space\",\n \"enterprise\": \"Unlimited\",\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"calendar_view\",\n \"title\": \"Calendar view\",\n \"bronze\": \"5 per space\",\n \"silver\": \"50 per space\",\n \"gold\": \"200 per space\",\n \"enterprise\": \"Unlimited\",\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"collection_table\",\n \"title\": \"Form\",\n \"bronze\": \"20 per space\",\n \"silver\": \"100 per space\",\n \"gold\": \"300 per space\",\n \"enterprise\": \"Unlimited\",\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"mirror\",\n \"title\": \"Mirror(records permission)\",\n \"bronze\": \"5 per space\",\n \"silver\": \"50 per space\",\n \"gold\": \"100 per space\",\n \"enterprise\": \"Unlimited\",\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"widget\",\n \"title\": \"Widget\",\n \"bronze\": \"Free for a limited time\",\n \"silver\": \"Free for a limited time\",\n \"gold\": \"Free for a limited time\",\n \"enterprise\": \"Free for a limited time\",\n \"community\":\"Free for a limited time\",\n \"custom\":\"Free for a limited time\"\n },\n {\n \"group\": \"Features\",\n \"id\": \"dashboard\",\n \"title\": \"Dashboard\",\n \"bronze\": \"5 per space\",\n \"silver\": \"50 per space\",\n \"gold\": \"100 per space\",\n \"enterprise\": \"Unlimited\",\n \"community\":true,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"custom_embedding\",\n \"title\": \"Custom embedding\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": true,\n \"enterprise\": true,\n \"community\":false,\n \"custom\":true\n },\n {\n \"group\": \"Features\",\n \"id\": \"rainbow_tags\",\n \"title\": \"Rainbow tags\",\n \"bronze\": \"Basic color\",\n \"silver\": \"Advanced color\",\n \"gold\": \"Advanced color\",\n \"enterprise\": \"Advanced color\",\n \"community\":\"Basic color\",\n \"custom\":\"Advanced color\"\n },\n {\n \"group\": \"Features\",\n \"id\": \"space_capacity\",\n \"title\": \"Record activity\",\n \"bronze\": \"14 days\",\n \"silver\": \"3 months\",\n \"gold\": \"6 months\",\n \"enterprise\": \"24 months\",\n \"community\": true,\n \"custom\": true\n },\n {\n \"group\": \"Features\",\n \"id\": \"recycle_bin\",\n \"title\": \"Trash\",\n \"bronze\": \"14 days\",\n \"silver\": \"3 months\",\n \"gold\": \"6 months\",\n \"enterprise\": \"24 months\",\n \"community\": true,\n \"custom\": true\n },\n {\n \"group\": \"Features\",\n \"id\": \"api_limits\",\n \"title\": \"API\",\n \"bronze\": \"Free for a limited time\",\n \"silver\": \"Free for a limited time\",\n \"gold\": \"Free for a limited time\",\n \"enterprise\": \"Free for a limited time\",\n \"community\": true,\n \"custom\": true\n },\n {\n \"group\": \"Features\",\n \"id\": \"robot\",\n \"title\": \"Automation\",\n \"bronze\": \"Free for a limited time\",\n \"silver\": \"Free for a limited time\",\n \"gold\": \"Free for a limited time\",\n \"enterprise\": \"Free for a limited time\",\n \"community\": true,\n \"custom\": true\n }\n ],\n \"Management and security\": [\n {\n \"group\": \"Management and security\",\n \"id\": \"column_permission\",\n \"title\": \"Field permissions\",\n \"bronze\": \"10 per space\",\n \"silver\": \"50 per space\",\n \"gold\": \"200 per space\",\n \"enterprise\": \"Unlimited\",\n \"community\":false,\n \"custom\":true\n },\n {\n \"group\": \"Management and security\",\n \"id\": \"folder_permission\",\n \"title\": \"File node permissions\",\n \"bronze\": \"10 per space\",\n \"silver\": \"50 per space\",\n \"gold\": \"200 per space\",\n \"enterprise\": \"Unlimited\",\n \"community\":false,\n \"custom\":true\n },\n {\n \"group\": \"Management and security\",\n \"id\": \"admin_counts\",\n \"title\": \"Space admin\",\n \"bronze\": \"3\",\n \"silver\": \"5\",\n \"gold\": \"10\",\n \"enterprise\": \"Unlimited\",\n \"community\": false,\n \"custom\": true\n },\n {\n \"group\": \"Management and security\",\n \"id\": \"watermark\",\n \"title\": \"Watermark\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": false,\n \"enterprise\": true,\n \"community\": false,\n \"custom\": true\n },\n {\n \"group\": \"Management and security\",\n \"id\": \"security_disabled_export_data\",\n \"title\": \"Disable data export\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": true,\n \"enterprise\": true,\n \"community\": false,\n \"custom\": true\n },\n {\n \"group\": \"Management and security\",\n \"id\": \"security_disabled_share\",\n \"title\": \"Disable opening public links\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": false,\n \"enterprise\": true,\n \"community\": false,\n \"custom\": true\n },\n {\n \"group\": \"Management and security\",\n \"id\": \"security_disabled_copy\",\n \"title\": \"Disable copying datas\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": false,\n \"enterprise\": true,\n \"community\": false,\n \"custom\": true\n },\n {\n \"group\": \"Management and security\",\n \"id\": \"security_disabled_download_file\",\n \"title\": \"Disable downloadimg files\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": false,\n \"enterprise\": true,\n \"community\": false,\n \"custom\": true\n },\n {\n \"group\": \"Management and security\",\n \"id\": \"security_disabled_invite_members\",\n \"title\": \"Disable inviting off-space user\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": false,\n \"enterprise\": true,\n \"community\": false,\n \"custom\": true\n }\n ,\n {\n \"group\": \"Management and security\",\n \"id\": \"space_log\",\n \"title\": \"Space log\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": false,\n \"enterprise\": true,\n \"community\": false,\n \"custom\": true\n }\n ],\n \"Professional Services\": [\n {\n \"group\": \"Professional Services\",\n \"id\": \"professional_services\",\n \"title\": \"Consultant Services\",\n \"bronze\": \"Community\",\n \"silver\": \"Community\",\n \"gold\": \"Community\",\n \"enterprise\": \"Customer Success Manager\",\n \"community\": \"Community\",\n \"custom\": \"Customer Success Manager\"\n },\n {\n \"group\": \"Professional Services\",\n \"id\": \"enterprise_consulting_training\",\n \"title\": \"Enterprise-level consulting training\",\n \"bronze\": false,\n \"silver\": false,\n \"gold\": false,\n \"enterprise\": true,\n \"community\": false,\n \"custom\": true\n }\n ]\n}", + "subscription_grades_checklist_mobile_saas": "[\n {\n \"grade\": \"free\",\n \"btnText\": \"Start Now\",\n \"btnHref\": \"/login\",\n \"primaryContent\": [\n \"30 file nodes\",\n \"5,000 records per datasheet\",\n \"1G attachments storage per sapce\"\n ],\n \"details\": [\n {\n \"name\": \"Usage\",\n \"rules\": [\n \"30 file nodes\",\n \"5,000 records per datasheet\",\n \"20,000 records per sapce\",\n \"1G attachments storage per sapce\"\n ]\n },\n {\n \"name\": \"Features\",\n \"rules\": [\n \"Pin file nodes\",\n \"Gallery view,Kanban view and Architecture view are unlimited\",\n \"10 gantt views per sapce\",\n \"5 calendar views per sapce\",\n \"20 forms per sapce\",\n \"5 mirrors per sapce\",\n \"5 dashbords per sapce\",\n \"Widget is free for a limited time\",\n \"Basic colors for rainbow tags\",\n \"Record activity goes back 14 days\",\n \"Trash goes back 14 days\",\n \"API is free for a limited time\",\n \"Automation is free for a limited time\"\n ]\n },\n {\n \"name\": \"Management and security\",\n \"rules\": [\n \"10 field permissions per sapce\",\n \"10 file node permissions per sapce\",\n \"3 admins per sapce\"\n ]\n },\n {\n \"name\": \"Professional Services\",\n \"rules\": [\n \"Community\"\n ]\n }\n ]\n },\n {\n \"grade\": \"plus\",\n \"btnText\": \"Choose Plus\",\n \"btnHref\": \"/login\",\n \"primaryContent\": [\n \"300 file nodes\",\n \"10,000 records per datasheet\",\n \"5G/seats attachments storage per sapce\"\n ],\n \"details\": [\n {\n \"name\": \"Usage\",\n \"rules\": [\n \"300 file nodes\",\n \"10,000 records per datasheet\",\n \"3,0000,000 records per sapce\",\n \"5G/seats attachments storage per sapce\"\n ]\n },\n {\n \"name\": \"Features\",\n \"rules\": [\n \"Pin file nodes\",\n \"Gallery view,Kanban view and Architecture view are unlimited\",\n \"50 gantt views per sapce\",\n \"50 calendar views per sapce\",\n \"100 forms per sapce\",\n \"50 mirrors per sapce\",\n \"50 dashbords per sapce\",\n \"Widget is free for a limited time\",\n \"Advanced colors for rainbow tags\",\n \"Record activity goes back 3 months\",\n \"Trash goes back 3 months\",\n \"API is free for a limited time\",\n \"Automation is free for a limited time\"\n ]\n },\n {\n \"name\": \"Management and security\",\n \"rules\": [\n \"50 field permissions per sapce\",\n \"50 file node permissions per sapce\",\n \"5 admins per sapce\"\n ]\n },\n {\n \"name\": \"Professional Services\",\n \"rules\": [\n \"Community\"\n ]\n }\n ]\n },\n {\n \"grade\": \"pro\",\n \"btnText\": \"Choose Pro\",\n \"btnHref\": \"/login\",\n \"primaryContent\": [\n \"1,000 file nodes\",\n \"20,000 records per datasheet\",\n \"7G/seats attachments storage per sapce\",\n \"Custom embedding\"\n ],\n \"details\": [\n {\n \"name\": \"Usage\",\n \"rules\": [\n \"1,000 file nodes\",\n \"20,000 records per datasheet\",\n \"20,000,000 records per sapce\",\n \"7G/seats attachments storage per sapce\"\n ]\n },\n {\n \"name\": \"Features\",\n \"rules\": [\n \"Pin file nodes\",\n \"Gallery view,Kanban view and Architecture view are unlimited\",\n \"200 gantt views per sapce\",\n \"300 calendar views per sapce\",\n \"300 forms per sapce\",\n \"100 mirrors per sapce\",\n \"100 dashbords per sapce\",\n \"Widget is free for a limited time\",\n \"Advanced colors for rainbow tags\",\n \"Custom embedding\",\n \"Record activity goes back 6 months\",\n \"Trash goes back 6 months\",\n \"API is free for a limited time\",\n \"Automation is free for a limited time\"\n ]\n },\n {\n \"name\": \"Management and security\",\n \"rules\": [\n \"200 field permissions per sapce\",\n \"200 file node permissions per sapce\",\n \"10 admins per sapce\",\n \"Disable data export\"\n ]\n },\n {\n \"name\": \"Professional Services\",\n \"rules\": [\n \"Community\"\n ]\n }\n ]\n },\n {\n \"grade\": \"enterprise\",\n \"btnText\": \"Contacts us\",\n \"btnHref\": \"\",\n \"primaryContent\": [\n \"10,000 file nodes\",\n \"50,000 records per datasheet\",\n \"10G/seats attachments storage per sapce\",\n \"Unlimited permission and security settings\",\n \"Customer Success Manager\"\n ],\n \"details\": [\n {\n \"name\": \"Usage\",\n \"rules\": [\n \"10,000 file nodes\",\n \"50,000 records per datasheet\",\n \"50,0000,000 records per sapce\",\n \"10G/seats attachments storage per sapce\"\n ]\n },\n {\n \"name\": \"Features\",\n \"rules\": [\n \"Pin file nodes\",\n \"Gallery view,Kanban view and Architecture view are unlimited\",\n \"Gantt views are unlimited\",\n \"Calendar views are unlimited\",\n \"Forms are unlimited\",\n \"Mirrors are unlimited\",\n \"Dashbords are unlimited\",\n \"Widget is free for a limited time\",\n \"Advanced colors for rainbow tags\",\n \"Custom embedding\",\n \"Record activity goes back 24 months\",\n \"Trash goes back 24 months\",\n \"API is free for a limited time\",\n \"Automation is free for a limited time\"\n ]\n },\n {\n \"name\": \"Management and security\",\n \"rules\": [\n \"Field permissions are unlimited\",\n \"File node permissions are unlimited\",\n \"Admins are unlimited\",\n \"Watermark\",\n \"Disable data export\",\n \"Disable opening public links\",\n \"Disable copying datas\",\n \"Disable downloadimg files\",\n \"Disable inviting off-space user\",\n \"Space log\"\n ]\n },\n {\n \"name\": \"Professional Services\",\n \"rules\": [\n \"Customer Success Manager\",\n \"Custom function development (additional cost)\",\n \"Enterprise-level consulting training\"\n ]\n }\n ]\n }\n ]", + "subscription_grades_checklist_mobile_selfhost": "[\n {\n \"grade\": \"community\",\n \"btnText\": \"Dowload\",\n \"primaryContent\": [\n \"10,000 file nodes\",\n \"50,000 records per datasheet\",\n \"Unlimitied attachments storage per sapce\"\n ],\n \"details\": [\n {\n \"name\": \"Usage\",\n \"rules\": [\n \"10,000 file nodes\",\n \"50,000 records per datasheet\",\n \"50,0000,000 records per sapce\",\n \"Unlimitied attachments storage per sapce\"\n ]\n },\n {\n \"name\": \"Features\",\n \"rules\": [\n \"Pin file nodes\",\n \"Gallery view,Kanban view and Architecture view are unlimited\",\n \"Gantt views are unlimited\",\n \"Calendar views are unlimited\",\n \"Forms are unlimited\",\n \"Mirrors are unlimited\",\n \"Dashbords are unlimited\",\n \"Widget is free for a limited time\",\n \"Basic colors for rainbow tags\",\n \"Record activity goes back 24 months\",\n \"Trash goes back 24 months\",\n \"API is free for a limited time\",\n \"Automation is free for a limited time\"\n ]\n },\n {\n \"name\": \"Management and security\",\n \"rules\": [\n \"Not supported\"\n ]\n },\n {\n \"name\": \"Professional Services\",\n \"rules\": [\n \"Community\"\n ]\n }\n ]\n },\n {\n \"grade\": \"custom\",\n \"btnText\": \"Contacts us\",\n \"primaryContent\": [\n \"10,000 file nodes\",\n \"50,000 records per datasheet\",\n \"10G/seats attachments storage per sapce\",\n \"Unlimited permission and security settings\",\n \"Customer Success Manager\"\n ],\n \"details\": [\n {\n \"name\": \"Usage\",\n \"rules\": [\n \"10,000 file nodes\",\n \"50,000 records per datasheet\",\n \"50,0000,000 records per sapce\",\n \"Unlimited attachments storage per sapce\"\n ]\n },\n {\n \"name\": \"Features\",\n \"rules\": [\n \"Pin file nodes\",\n \"Gallery view,Kanban view and Architecture view are unlimited\",\n \"Gantt views are unlimited\",\n \"Calendar views are unlimited\",\n \"Forms are unlimited\",\n \"Mirrors are unlimited\",\n \"Dashbords are unlimited\",\n \"Widget is free for a limited time\",\n \"Advanced colors for rainbow tags\",\n \"Custom embedding\",\n \"Record activity goes back 24 months\",\n \"Trash goes back 24 months\",\n \"API is free for a limited time\",\n \"Automation is free for a limited time\"\n ]\n },\n {\n \"name\": \"Management and security\",\n \"rules\": [\n \"Field permissions are unlimited\",\n \"File node permissions are unlimited\",\n \"Admins are unlimited\",\n \"Watermark\",\n \"Disable data export\",\n \"Disable opening public links\",\n \"Disable copying datas\",\n \"Disable downloadimg files\",\n \"Disable inviting off-space user\",\n \"Space log\"\n ]\n },\n {\n \"name\": \"Professional Services\",\n \"rules\": [\n \"Customer Success Manager\",\n \"Custom function development (additional cost)\",\n \"Enterprise-level consulting training\"\n ]\n }\n ]\n }\n]", "subscription_information": "Subscription plan", "subscription_level": "Plan: ${level}", "subscription_product_seats": "Seat", @@ -11096,7 +11425,7 @@ "template_name_repetition_title": "\"${templateName}\" already exists. Do you want to replace it?", "template_no_template": "No templates", "template_not_found": "Can't find templates you want? Tell us", - "template_recommend_title": "Hot", + "template_recommend_title": "🌟 Hot", "template_type": "Template", "terms_of_service": "", "terms_of_service_pure_string": "Terms of service", @@ -11140,7 +11469,8 @@ "text_editor_tip_end": "\"Enter\" to end editing", "text_functions": "String Function", "thailand": "Thailand", - "the_current_automation_workflow_has_no_related_files_you_can_establish_a_link_by_adding_trigger_conditions_and_actions_on_the_left_side": "The current automation workflow has no related files. You can establish a link by adding trigger conditions and actions on the left side", + "the_button_field_is_misconfigured": "The button field is misconfigured, please check and try again", + "the_current_automation_workflow_has_no_related_files_you_can_establish_a_link_by_adding_trigger_conditions_and_actions_on_the_left_side": "The current automation workflow has no related file nodes. You can establish a link by adding trigger conditions and actions on the left side", "the_current_button_column_has_expired_please_reselect": "The current button column has expired, please reselect", "the_last_7_days": "the past 7 days", "the_last_month": "last 30 days", @@ -11242,6 +11572,7 @@ "timemachine_update_comment": "updated comment(s)", "times_per_month_unit": "call(s)/month", "times_unit": " call(s)", + "timing_rules": "Timing", "timor_leste": "Timor-Leste", "tip_del_success": "You can restore your Space within 7 days", "tip_do_you_want_to_know_about_field_permission": "Want to encrypt field data? Learn about field permissions", @@ -11300,8 +11631,8 @@ "training_data_source_title": "通过 \"dataDource\",您可以上传、导入和添加数据到数据集中。您可以将各种类型的数据文件包括图像、文本、等添加到数据集中,以满足您的训练需求。", "transfer_to_public": "Transfer ", "trash": "Trash", - "trash_over_limit_tip": "\"Silver\" space can view ${day} days of historical files, limited-time open experience", - "trash_tip": "You can restore files deleted in the past ${day} days from the Trash. You can only view files with \"manager\" permissions", + "trash_over_limit_tip": "\"Silver\" space can view ${day} days of historical file nodes, limited-time open experience", + "trash_tip": "You can restore file nodes deleted in the past ${day} days from the Trash. You can only view file nodes with \"manager\" permissions", "travel_and_outdoors": "Travel and outdoors", "tree_level": "Lv ${level}", "trial_expires": "Your free trial has expired", @@ -11429,6 +11760,7 @@ "verify_account_title": "Verify account", "verify_via_email": "Identity verification by email", "verify_via_phone": "Identity verification by SMS", + "video": "Video", "video_not_support_play": "The current video format does not support playing online", "vietnam": "Vietnam", "view": "View", @@ -11492,7 +11824,7 @@ "vika_invite_link_template": "From vikadata: You were invited to join the \"${spaceName}\" Space by ${nickName}.", "vika_official_accounts": "Official account", "vika_privacy_policy": "", - "vika_share_link_template": "From vikadata: ${nickName} has shared the \"${nodeName}\" file with you.", + "vika_share_link_template": "From vikadata: ${nickName} has shared the \"${nodeName}\" file node with you.", "vika_small_classroom": "Video tutorials", "vika_star": "Vika Planet", "vikaby_activity_train_camp": "Time-limited welfare", @@ -11659,7 +11991,7 @@ "widget_import_from_airtable_step_2_fields": "Fields", "widget_import_from_airtable_step_2_fields_type": "Field types", "widget_import_from_airtable_step_2_title": "2. Configure field type", - "widget_import_from_airtable_step_2_waring_file_upload": "The attachment column is detected. The widget currently only supports the import of files that do not exceed 10MB. Do you continue?", + "widget_import_from_airtable_step_2_waring_file_upload": "The attachment column is detected. The widget currently only supports the import of attachments that do not exceed 10MB. Do you continue?", "widget_import_from_airtable_step_3_button": "Stop", "widget_import_from_airtable_step_3_description": "Importing data ……", "widget_import_from_airtable_step_3_import_num": "Imported ${ROW_NUM} records", @@ -11760,12 +12092,12 @@ "workbench_instruction_of_all_member_setting_and_node_permission": "Controls what can do and what can't do from the workbench", "workbench_setting": "Workbench Permission", "workbench_setting_all": "Global settings", - "workbench_setting_cannot_export_datasheet_describle": "If turn on, datasheets of the workbench can be imported to local computer when member has the permission of the files.", + "workbench_setting_cannot_export_datasheet_describle": "If turn on, datasheets of the workbench can be imported to local computer when member has the permission of the file nodes.", "workbench_setting_cannot_export_datasheet_tips": "If members have the \"manageable\" permission to a datasheet, they can export it to a local file.", "workbench_setting_cannot_export_datasheet_title": "Allow exporting datasheets", "workbench_setting_show_watermark_tips": "The workbench and the contacts support watermarks to prevent members from leaking enterprise information. A watermark includes the name and phone number suffix/email prefix.", "workbench_setting_show_watermark_title": "Show watermarks", - "workbench_share_link_template": "From APITable: ${nickName} has shared the \"${nodeName}\" file with you.", + "workbench_share_link_template": "From APITable: ${nickName} has shared the \"${nodeName}\" file node with you.", "workbench_side_space_template": "Custom templates", "workbenck_shortcuts": "Workbench", "workdoc_attach_uploading": "Uploading...", @@ -11777,7 +12109,7 @@ "workdoc_color_title": "Text color", "workdoc_create": "Create WorkDoc", "workdoc_expanded": "Expand the table of contents", - "workdoc_image_max_10mb": "The image size cannot exceed 10MB", + "workdoc_image_max_size": "The image size cannot exceed ${size}", "workdoc_info": "WorkDoc Info", "workdoc_info_create_time": "Created at", "workdoc_info_creator": "Created by", @@ -11785,6 +12117,7 @@ "workdoc_info_last_modify_time": "Last modified at", "workdoc_link_placeholder": "Please enter link", "workdoc_only_image": "Only image is allowed", + "workdoc_only_video": "Only video is allowed", "workdoc_text_placeholder": "Enter \"/\" to start", "workdoc_title_placeholder": "Please enter title", "workdoc_unnamed": "Unnamed WorkDoc", @@ -11793,9 +12126,11 @@ "workdoc_unsave_ok": "Discard changes", "workdoc_unsave_title": "The WorkDoc has not been saved", "workdoc_upload_failed": "Upload failed", + "workdoc_video_max_size": "The video size cannot exceed ${size}", "workdoc_ws_connected": "Connected", "workdoc_ws_connecting": "Connecting...", "workdoc_ws_disconnected": "Disconnected", + "workdoc_ws_reconnecting": "Reconnecting...", "workflow_execute_failed_notify": " failed to execute at . Please review the execution history to troubleshoot the issue. If you need any assistance, please contact our customer service team.", "workspace_data": "Space data", "workspace_files": "Workbench data", @@ -11974,6 +12309,15 @@ "agreed": "Aprobado", "ai_advanced_mode_desc": "El modo avanzado permite a los usuarios personalizar las indicaciones, proporcionando un mayor control sobre el comportamiento y las respuestas del AI agent.", "ai_advanced_mode_title": "Modelo avanzado", + "ai_agent_anonymous": "Anónimo${ID}", + "ai_agent_conversation_continue_not_supported": "Actualmente no se admite continuar una conversación anterior", + "ai_agent_conversation_list": "Lista de conversación", + "ai_agent_conversation_log": "Registro de conversación", + "ai_agent_conversation_title": "Título de la conversación", + "ai_agent_feedback": "Comentario", + "ai_agent_historical_message": "Lo anterior es un mensaje histórico.", + "ai_agent_history": "Historia", + "ai_agent_message_consumed": "Mensaje consumido", "ai_api_curl_template": "## Create chat completions\n\n```bash\n\ncurl -X POST \"{{apiBase}}/fusion/v1/ai/{{aiId}}/chat/completions\" \\n -H \"Content-Type: application/json\" \\n -H \"Authorization: Bearer {{token}}\" \\n -d '{\n \"model\": \"gpt-3.5-turbo\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"You are a helpful assistant.\"\n },\n {\n \"role\": \"user\",\n \"content\": \"Hello!\"\n }\n ]\n }'\n\n```\n\n## Returned data example\n\n```json\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", "ai_api_footer_desc": "¿Incorporar al AI agent en tu sitio web? Más información", "ai_api_javascript_template": "## Initialize SDK [![github]({{ githubIcon }})](https://github.com/openai/openai-node)\nAITable's chat completion API is compatible with OpenAI's Node.js SDK. You can use our service with the same SDK by simply changing the configuration as follows:\n\n\n```javascript\nconst { Configuration, OpenAIApi } = require(\"openai\");\nconst configuration = new Configuration({\n apiKey: \"{{token}}\",\n basePath: \"{{apiBase}}/fusion/v1/ai/{{aiId}}\"\n});\n```\n\n## Create chat completions\n\n```javascript\nconst openai = new OpenAIApi(configuration);\nconst chatCompletion = await openai.createChatCompletion({\n model: \"gpt-3.5-turbo\",\n messages: [{role: \"user\", content: \"Hello world\"}],\n});\n```\n\n## Returned data example\n\n```javascript\n\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", @@ -11989,6 +12333,9 @@ "ai_chat_unit": "Aibot(s)", "ai_close_setting_tip_content": "Usted ha hecho cambios. ¿ quieres descartarlos?", "ai_close_setting_tip_title": "Consejos", + "ai_copilot_generate_response": "Generando respuesta para usted...", + "ai_copilot_processs": "Procesando, por favor espere...", + "ai_copilot_start_process_request": "Iniciando el procesamiento de su solicitud...", "ai_create_guide_btn_text": "Seleccionar tabla de datos", "ai_create_guide_content": "Como AI agent, puedo responder a sus preguntas basándose en el conocimiento que he aprendido. Antes de iniciar la conversación, por favor seleccione una hoja de datos como base de conocimiento, y leeré todos los datos en ella para su aprendizaje.", "ai_credit_cost_chart_title": "Costo de crédito", @@ -12049,7 +12396,7 @@ "ai_prompt_title": "Promover", "ai_prompt_wrong_content": "Por favor, incluya el {context} y las {question} en el texto.", "ai_query_of_number": "Uso", - "ai_remain_credit_label": "Mensaje restante: ${crédito}", + "ai_remain_credit_label": "Mensaje restante: ${credit}", "ai_retrain": "Reciclaje", "ai_robot_data_source_title": "Colección de conjuntos de datos", "ai_robot_type_QA_desc": "Un agente de preguntas y respuestas basado en PNL y aprendizaje automático responde de forma rápida y precisa varias preguntas y proporciona información en tiempo real y consejos útiles a los usuarios.", @@ -12457,7 +12804,7 @@ "apps_support": "Soporte cliente de plataforma completa", "archive_delete_record": "Eliminar registros archivados", "archive_delete_record_title": "Eliminar el registro", - "archive_notice": "

Está intentando archivar registros específicos. Archivar los registros resultará en los siguientes cambios:

1. Se cancelará todo enlace bidireccional para este registro.

2. No se admite la edición

3. No se admiten funciones como recordatorios de fechas y registros de suscripción

4. Ya no participa en el cálculo de búsquedas, fórmulas y otros campos.

Estás seguro de que quieres continuar? (Puedes desarchivar en Archive Box en Avanzado)

", + "archive_notice": "

Está intentando archivar registros específicos. Archivar los registros resultará en los siguientes cambios:

1. No se admite la edición

2. No se admiten funciones como recordatorios de fechas y registros de suscripción

3. Ya no participar en el cálculo de búsquedas, fórmulas y otros campos.

Estás seguro de que quieres continuar? (Puedes desarchivar en Archive Box en Avanzado)

", "archive_record_in_activity": "Archivó este registro", "archive_record_in_menu": "Registro de archivo", "archive_record_success": "Se han archivado con éxito los registros", @@ -12517,6 +12864,8 @@ "audit_add_field_role_detail": "[a class = \"membername\" > en la tabla de datos \"[a class =\" nodename \"> < a > en la tabla de datos\" [a class = \"times\" > en la tabla de datos, para el campo [a class = \"field name\" > en la tabla de datos, añadir [a class = \"unitname\" > en la tabla de datos] [/ a > para el personaje ", "audit_add_node_role": "Añadir permisos de archivo", "audit_add_node_role_detail": "Agregar permiso de archivo, establecer 「${unitNames}」a「${role}」de 「${currentNodeName }」", + "audit_add_node_role_detail_end": "to「${role}", + "audit_add_node_role_detail_start": "Add file node permission,set「${unitNames}」", "audit_admin_permission_change_event": "Cambiar los permisos del Administrador", "audit_create_template": "Crear una plantilla", "audit_create_template_detail": "Crear una plantilla", @@ -12525,20 +12874,30 @@ "audit_delete_field_role_detail": "Auditoría", "audit_delete_node_role": "Eliminar permisos de archivo", "audit_delete_node_role_detail": "Eliminar permiso de archivo,eliminar「${unitNames}」`s 「${role}」rol de 「${currentNodeName}」", + "audit_delete_node_role_detail_end": "at 「${role}」role", + "audit_delete_node_role_detail_start": "Delete file node permission,delete「${unitNames}」from", "audit_delete_template": "Eliminar plantilla", "audit_delete_template_detail": "Eliminar plantilla", "audit_disable_field_role": "Desactivar permisos de campo", "audit_disable_field_role_detail": "Auditoría", "audit_disable_node_role": "Desactivar permisos de archivo", "audit_disable_node_role_detail": "Deshabilitar el permiso de ${nodeType} 「${currentNodeName}」", + "audit_disable_node_role_detail_end": "`s permission", + "audit_disable_node_role_detail_start": "Disable ${nodeType}", "audit_disable_node_share": "Cierre el enlace público del archivo", "audit_disable_node_share_detail": "Cierre el enlace público de ${nodeType} 「${currentNodeName}」", + "audit_disable_node_share_detail_end": "public link", + "audit_disable_node_share_detail_start": "Close ${nodeType}", "audit_enable_field_role": "Activar permisos de campo", "audit_enable_field_role_detail": "Auditoría", "audit_enable_node_role": "Activar permisos de archivo", "audit_enable_node_role_detail": "Habilitar el permiso de ${nodeType} 「${currentNodeName}」", + "audit_enable_node_role_detail_end": "`s permission", + "audit_enable_node_role_detail_start": "Enable ${nodeType}", "audit_enable_node_share": "Abrir el enlace público del archivo", "audit_enable_node_share_detail": "Abra el enlace público de ${nodeType} 「${currentNodeName}」", + "audit_enable_node_share_detail_end": "public link", + "audit_enable_node_share_detail_start": "Open ${nodeType}", "audit_login_event": "Evento de inicio de sesión", "audit_logout_event": "Inglés", "audit_organization_change_event": "La estructura organizativa de los contactos ha cambiado", @@ -12559,18 +12918,25 @@ "audit_space_invite_user_detail": "Auditoría", "audit_space_node_copy": "Archivos duplicados", "audit_space_node_copy_detail": "Duplique ${nodeType} 「${sourceNodeName}」, el nombre del nuevo archivo es 「${currentNodeName}」", + "audit_space_node_copy_detail_start": "Duplicate ${nodeType} 「${sourceNodeName}」, the new file node's name is", "audit_space_node_create": "Crear archivo", "audit_space_node_create_detail": "Crear ${nodeType} llamado 「${currentNodeName}」", + "audit_space_node_create_detail_start": "Create a ${nodeType} named", "audit_space_node_delete": "Eliminar archivo", "audit_space_node_delete_detail": "Eliminar ${nodeType}, el nombre es 「${currentNodeName}」", + "audit_space_node_delete_detail_start": "Delete ${nodeType} named", "audit_space_node_export": "Exportar tablas de datos", "audit_space_node_export_detail": "El miembro ${member_name} exportó la hoja de datos ${node_name}", "audit_space_node_import": "Importar archivos", "audit_space_node_import_detail": "Importe un archivo llamado 「${nodeName}」", + "audit_space_node_import_detail_start": "Import a file node named", "audit_space_node_move": "Mover Archivos", "audit_space_node_move_detail": "Mueva ${nodeType} 「${currentNodeName}」 a la carpeta 「${parentName}」", + "audit_space_node_move_detail_end": "to the folder「${parentName}」", + "audit_space_node_move_detail_start": "Move ${nodeType}", "audit_space_node_rename": "Cambiar el nombre del archivo", "audit_space_node_rename_detail": "Cambiar el nombre de ${nodeType} 「${oldNodeName}」a 「${nodeName}」", + "audit_space_node_rename_detail_start": "Rename ${nodeType} 「${oldNodeName}」to", "audit_space_node_sort": "Auditoría", "audit_space_node_sort_detail": "Auditoría", "audit_space_node_update_cover": "Auditoría", @@ -12585,17 +12951,24 @@ "audit_space_rubbish_node_delete_detail": "Auditoría", "audit_space_rubbish_node_recover": "Restaurar archivo", "audit_space_rubbish_node_recover_detail": "Restaure ${nodeType} del contenedor de recuperación con el nombre 「${currentNodeName}」", + "audit_space_rubbish_node_recover_detail_end": "from the trash", + "audit_space_rubbish_node_recover_detail_start": "Restore ${nodeType}", "audit_space_template_event": "Cambio de plantilla", "audit_space_update_logo": "Auditoría", "audit_space_update_logo_detail": "Auditoría", "audit_store_share_node": "Guardar archivos compartidos", "audit_store_share_node_detail": "Restaure ${nodeType} al espacio, el nombre es 「${nodeName}」", + "audit_store_share_node_detail_start": "Restore ${nodeType} to the space, name is", "audit_update_field_role": "Auditoría", "audit_update_field_role_detail": "Auditoría", "audit_update_node_role": "Modificar permisos de archivo", "audit_update_node_role_detail": "Modificar permiso de archivo, modificar el rol de ${unitNames}」 a 「${role}」de 「${currentNodeName}」", + "audit_update_node_role_detail_end": "to「${role}」role", + "audit_update_node_role_detail_start": "Modify file node permission,modify「${unitNames}」from", "audit_update_node_share_setting": "Modificar la configuración del enlace público del archivo", "audit_update_node_share_setting_detail": "Modificar ${nodeType} 「${currentNodeName}」 enlace público", + "audit_update_node_share_setting_detail_end": "public link settings", + "audit_update_node_share_setting_detail_start": "Modify ${nodeType}", "audit_user_login": "Inicio de sesión del usuario", "audit_user_login_detail": "Auditoría", "audit_user_logout": "Cancelación del usuario", @@ -12637,6 +13010,7 @@ "automation_enabled_return_via_related_files": "La automatización está habilitada. Vuelva a ingresar la tabla original a través de \"Archivos relacionados\" para usar el botón nuevo.", "automation_field": "Campo", "automation_import_variables_from_pre_tep": "Obtener datos del paso previo", + "automation_is_not_yet_enabled": "La automatización aún no está habilitada, habilítela e inténtelo nuevamente.", "automation_last_edited_by": "Última edición por", "automation_last_edited_time": "Hora de la última edición", "automation_manager_label": "Puede realizar todas las acciones en la automatización.", @@ -12662,6 +13036,7 @@ "automation_runs_this_month": "Funciona este mes", "automation_stay_tuned": "Manténganse al tanto", "automation_success": "Éxito", + "automation_tips": "El campo del botón está mal configurado, verifíquelo e inténtelo nuevamente.", "automation_updater_label": "Puede ver el historial de ejecución de la automatización.", "automation_variabel_empty": "No hay datos que puedan usarse en el paso previo, ajústelos e inténtelo nuevamente.", "automation_variable_datasheet": "Obtener datos de ${NODE_NAME}", @@ -12697,6 +13072,7 @@ "bermuda": "Bermudas", "bhutan": "Bhután", "billing_over_limit_tip_common": "El uso del espacio ha superado el límite y podrá disfrutar de una cantidad mayor después de la actualización.", + "billing_over_limit_tip_forbidden": "Su duración de prueba o período de suscripción ha expirado. Comuníquese con el asesor de ventas para renovar.", "billing_over_limit_tip_widget": "La cantidad de instalaciones de widgets ha excedido el límite y puede actualizar para obtener un mayor uso.", "billing_period": "Período de facturación: ${period}", "billing_subscription_warning": "Experiencia funcional", @@ -12756,10 +13132,19 @@ "button_text": "Botón de texto", "button_text_click_start": "Haga clic para comenzar", "button_type": "Tipo de botón", + "by_at": "en", + "by_days": "Días", + "by_every": "cada", "by_field_id": "Usar el ID de campo", + "by_hours": "Horas", + "by_in": "en", + "by_min": "minutos)", + "by_months": "Meses", + "by_on": "sobre el", "by_the_day": "Por día", "by_the_month": "Revista mensual", "by_the_year": "Anual", + "by_weeks": "Semanas", "calendar_add_date_time_field": "Crear campo de fecha", "calendar_color_more": "Más colores", "calendar_const_detail_weeks": "[\"lunes\",\"martes\",\"miércoles\",\"jueves\",\"viernes\",\"sábado\",\"domingo\"]", @@ -12823,6 +13208,14 @@ "cannot_activate_space_by_space_limit": "No se puede activar el límite espacial", "cannot_join_space": "No puedes unirte a la nueva estación espacial porque ya has superado la cuota máxima de 10 estaciones espaciales.", "cannot_switch_field_permission": "Establezca los permisos de campo a no más de los permisos de archivo.", + "capacity_file_detail_desc": "The total number of file nodes within the Space is calculated by adding the file nodes from the Team to the file nodes created by each member in their Private. Not enough capacity?", + "capacity_file_detail_title": "File Capacity", + "capacity_file_member": "Member", + "capacity_file_member_private_node_count": "Private", + "capacity_file_member_private_percent": "Percent", + "capacity_file_member_team": "Team", + "capacity_file_member_team_node_count": "Team", + "capacity_file_upgrade": "Click to upgrade your Space", "capacity_from_official_gift": "De regalos oficiales", "capacity_from_participation": "Por invitación ${user} unirse al espacio", "capacity_from_purchase": "Por capacidad de compra", @@ -12859,6 +13252,8 @@ "catalog": "Explorador", "catalog_add_from_template_btn_title": "Añadir desde la plantilla", "catalog_empty_tips": "Este área de Trabajo está ahora vacía. Comienza a crear archivos con plantillas.", + "catalog_private": "Private", + "catalog_team": "Team", "category_blank": "[en blanco]", "catering": "Restauración", "cayman_islands": "Islas Caimán", @@ -12927,6 +13322,7 @@ "choose_type_of_vika_field": "Seleccionar tipo de campo", "choose_your_own_space": "(solo se admite guardar en su propio espacio como creador)", "chose_new_primary_admin_button": "Distribución", + "chunk_stopping_title": "Stopping", "claim_special_offer": "¡¡ solicite este descuento especial!", "clear": "Claro", "clear_all_fields": "Eliminar todo", @@ -13057,6 +13453,7 @@ "confirm_del_current_team": "¿Está seguro de que quiere eliminar al equipo?", "confirm_delete": "Confirmar y eliminar", "confirm_delete_node_name_as": "¿Está seguro de que desea eliminar \"${nodeNameDiv}\"?", + "confirm_delete_private_node_name_as": "Are you sure you want to delete \"${nodeNameDiv}\"? The file will be deleted from the Space and the trash.", "confirm_delete_space_btn": "Confirmar y eliminar espacios", "confirm_exit": "Confirmar salida", "confirm_exit_space_with_name": "Confirme si desea salir del espacio \"${spaceNameDiv}\"", @@ -13094,6 +13491,14 @@ "convert": "Conversión", "convert_tip": "Esta operación puede eliminar los datos en algunas células. Si se produce algún accidente, puede retirar la operación.", "cook_islands": "Islas Cook", + "copilot_auto_agent_desc": "¿No estás seguro de cuál elegir Agente? Pruebe AutoAgent.", + "copilot_auto_agent_name": "Agente automático", + "copilot_data_agent_desc": "Generar análisis de datos/visualizaciones basadas en sus vistas.", + "copilot_data_agent_name": "Agente de datos", + "copilot_data_agent_policy": "Al chatear con Copilot, aceptas la política de términos de usuario", + "copilot_data_agent_policy_button": "Política", + "copilot_help_agent_desc": "Pregunte cualquier cosa sobre los documentos del centro de ayuda de AITable.", + "copilot_help_agent_name": "Recuperar centro de ayuda", "copy": "Copiar", "copy_automation_url": "Copiar URL", "copy_card_link": "Copiar la dirección de registro", @@ -13138,6 +13543,7 @@ "create_mirror_guide_content": "La función de espejo tiene la capacidad de ocultar ciertos datos. Puede establecer \"condiciones de filtro\" y \"campos ocultos\" en la vista de hoja de datos original para controlar qué registros y campos se muestran en el espejo.\n
\n
\nSi se usa junto con la función de \"bloqueo de vista\", puede evitar que otros realicen modificaciones.\n
\n
\nAdemás, puede ir a \"Tabla original>Campos ocultos\" para modificar la configuración de \"Mostrar todos los campos en espejos\".", "create_mirror_guide_title": "El espejo esconde algunos registros y campos", "create_new_button_field": "Crear un nuevo campo de columna de botón", + "create_private_node_tip": "Personal or temporary draft documents can be created here ${link}", "create_public_invitation_link": "Crear enlaces de invitación pública", "create_space_sub_title": "Hola, por favor, nombra tu espacio compartido.", "create_team_fail": "Falló la creación del equipo", @@ -13201,10 +13607,12 @@ "custom_enterprise": "Personalizar el espacio empresarial para usted", "custom_function_development": "Desarrollo de funciones personalizadas", "custom_grade_desc": "Prestación de servicios profesionales para el despliegue de agentes, instalación privada, soporte de asistencia y personalización", + "custom_page_setting_title": "Add a custom page", "custom_picture": "Imagen personalizada", "custom_style": "Estilo", "custom_upload": "Carga personalizada", "custom_upload_tip": "Se recomienda usar imágenes de tamaño cuadrado 1: 1 para una mejor experiencia visual", + "custome_page_title": "Custom Web", "cut_cell_data": "Cortar celdas", "cyprus": "Chipre", "czech": "Checo", @@ -13256,6 +13664,7 @@ "default": "Incumplimiento de contrato", "default_create_ai_chat_bot": "Nuevo AI agent", "default_create_automation": "Nueva automatización", + "default_create_custom_page": "Nueva página personalizada", "default_create_dashboard": "Nuevo salpicadero", "default_create_datasheet": "Nouvelle fiche technique", "default_create_file": "Nuevos archivos", @@ -13277,6 +13686,7 @@ "del_invitation_link": "Eliminar el enlace de invitación", "del_invitation_link_desc": "El enlace no será válido después de la eliminación", "del_space_now": "Eliminar espacio para siempre", + "del_space_now_confirm_tip": "For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "del_space_now_tip": "No se puede restaurar el espacio después de la eliminación. Todos los archivos y archivos adjuntos serán eliminados.", "del_space_res_tip": "Espacios eliminados", "del_team_success": "El equipo de eliminación fue exitoso", @@ -13472,6 +13882,62 @@ "embed_error_page_help": "Aprende más", "embed_fail_og_description_content": "Este enlace público incrustado ha sido desactivado y no está disponible por el momento", "embed_failed": "Los enlaces incrustados no están disponibles,", + "embed_link_bilibili": "bilibili", + "embed_link_bilibili_desc": "Al insertar los videos de bilibili, puede ver tutoriales y guías, o ver la página de inicio del canal en Vika.", + "embed_link_bilibili_link_text": "Cómo insertar el vídeo de bilibili", + "embed_link_bilibili_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-bilibili-video", + "embed_link_default": "Cualquier cosa", + "embed_link_default_desc": "Pegue un enlace para ver cualquier sitio web.", + "embed_link_default_link_text": "Aprende más", + "embed_link_default_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_link_figma": "Figma", + "embed_link_figma_desc": "Al incorporar archivos Figma, los miembros pueden ver y editar borradores de diseño de manera más conveniente, mejorando la eficiencia de la colaboración.", + "embed_link_figma_link_text": "Cómo incrustar archivos Figma", + "embed_link_figma_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-figma-file", + "embed_link_google_docs": "Docs", + "embed_link_google_docs_desc": "Al incorporar Google Docs, puede editar y ver documentos en AITable para facilitar la colaboración en equipo.", + "embed_link_google_docs_link_text": "Cómo incrustar Google Docs", + "embed_link_google_docs_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-docs-file", + "embed_link_google_sheets": "Sheets", + "embed_link_google_sheets_desc": "Al incorporar Google Sheets, puede editar y ver tablas en AITable para facilitar la colaboración en equipo.", + "embed_link_google_sheets_link_text": "Cómo incrustar Hojas de cálculo de Google", + "embed_link_google_sheets_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-sheets-file", + "embed_link_jishi_design": "Diseño JS", + "embed_link_jishi_design_desc": "Al incorporar archivos JSdesign, los miembros pueden ver y editar borradores de diseño de manera más conveniente, mejorando la eficiencia de la colaboración.", + "embed_link_jishi_design_link_text": "Cómo incrustar archivos JSdesign", + "embed_link_jishi_design_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-js-design-file", + "embed_link_tencent_docs": "Documentos Tencent", + "embed_link_tencent_docs_desc": "Al incorporar Tencent Docs, puede editar y ver documentos de Tencent en Vika para mejorar la eficiencia de la colaboración.", + "embed_link_tencent_docs_link_text": "Cómo incrustar documentos Tencent", + "embed_link_tencent_docs_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-tencent-docs", + "embed_link_wps": "WPS", + "embed_link_wps_desc": "Al incorporar archivos WPS, puede editar y ver documentos, tablas y formularios WPS en Vika para mejorar la eficiencia de la colaboración.", + "embed_link_wps_link_text": "Cómo incrustar archivos WPS", + "embed_link_wps_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-wps-file", + "embed_link_youtube": "YouTube", + "embed_link_youtube_desc": "Al insertar videos de YouTube, puede ver tutoriales y guías, o ver la página de inicio del canal en AITable.", + "embed_link_youtube_link_text": "Cómo insertar vídeos de YouTube", + "embed_link_youtube_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-youtube-video", + "embed_page": "Pagina personalizada", + "embed_page_add_url": "Agregar URL", + "embed_page_doc_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_page_function_desc": "Agregue páginas web a ${edition} para acceder fácilmente a documentos, videos y más de sitios web de terceros. Puede agregar enlaces a sitios web recomendados o cualquier enlace personalizado.", + "embed_page_node_permission_editor": "Sobre la base de \"solo actualización\", también se puede abrir el intercambio público del archivo.", + "embed_page_node_permission_manager": "Puede realizar todas las acciones en el archivo.", + "embed_page_node_permission_reader": "Puede ver el contenido de la página personalizada y la información básica del archivo.", + "embed_page_node_permission_updater": "Sobre la base de \"solo lectura\", también puede modificar el enlace de la página personalizada.", + "embed_page_setting_title": "Agregar una página personalizada", + "embed_page_url_invalid": "Por favor ingresa la URL correcta", + "embed_paste_link_bilibili_placeholder": "Pegue el enlace del video bilibili", + "embed_paste_link_default_placeholder": "Pega la URL", + "embed_paste_link_figma_placeholder": "Pegue el enlace para compartir del archivo Figma", + "embed_paste_link_google_docs_placeholder": "Pegue el enlace para compartir de Google Docs", + "embed_paste_link_google_sheets_placeholder": "Pegue el enlace para compartir de Google Sheets", + "embed_paste_link_jsdesign_placeholder": "Pegue el enlace para compartir del archivo JSdesign", + "embed_paste_link_tencent_docs_placeholder": "Pegue el enlace para compartir de Tencent Docs", + "embed_paste_link_wps_placeholder": "Pegue el enlace para compartir del archivo WPS", + "embed_paste_link_youtube_placeholder": "Pega el enlace del vídeo de YouTube.", + "embed_success": "Agregar con éxito", "emoji_activity": "Actividades", "emoji_custom": "Costumbres", "emoji_flags": "Bandera", @@ -13578,6 +14044,11 @@ "estonia": "Estonia", "ethiopia": "Etiopía", "event_planning": "Planificación del evento", + "every": "Cada", + "every_day_at": "día(s) en", + "every_hour_at": "hora(s) a las", + "every_month_at": "mes(es) en el", + "every_week_at": "Cada semana en", "everyday_life": "Vida diaria", "everyone_visible": "Visible para todos", "exact_date": "Fecha exacta", @@ -13588,6 +14059,7 @@ "exchange": "Rescate", "exchange_code_times_tip": "Nota: el Código de cambio solo se puede usar una vez", "exclusive_consultant": "Consultor exclusivo V +.", + "exclusive_limit_plan_desc": "Nivel limitado exclusivo", "exist_experience": "Experiencia de salida", "exits_space": "Espacio de salida", "expand": "Ampliación", @@ -13614,7 +14086,7 @@ "expired": "Expiración", "export": "Se está exportando...", "export_brand_desc": "Soporte técnico", - "export_current_preview_view_data": "", + "export_current_preview_view_data": "Export current preview view data", "export_gantt_button_tips": "Exportar al archivo. PNG", "export_gantt_chart": "Exportar mapa de Gantt", "export_to_excel": "Exportar datos", @@ -14185,26 +14657,26 @@ "gantt_config_color_by_single_select_pleaseholder": "Seleccionar campo de selección", "gantt_config_color_help": "Cómo configurar", "gantt_config_friday": "Viernes", - "gantt_config_friday_in_bar": "Viernes", + "gantt_config_friday_in_bar": "Vie", "gantt_config_friday_in_select": "Viernes", "gantt_config_monday": "Lunes", - "gantt_config_monday_in_bar": "Lunes", + "gantt_config_monday_in_bar": "Lun", "gantt_config_monday_in_select": "Lunes", "gantt_config_only_count_workdays": "La duración solo se calcula en días hábiles.", - "gantt_config_saturday": "Hoy es sábado.", - "gantt_config_saturday_in_bar": "Hoy es sábado.", - "gantt_config_saturday_in_select": "Hoy es sábado.", + "gantt_config_saturday": "Sábado", + "gantt_config_saturday_in_bar": "Sáb", + "gantt_config_saturday_in_select": "Sábado", "gantt_config_sunday": "Domingo", - "gantt_config_sunday_in_bar": "Domingo", + "gantt_config_sunday_in_bar": "Dom", "gantt_config_sunday_in_select": "Domingo", - "gantt_config_thursday": "Hoy es jueves.", - "gantt_config_thursday_in_bar": "Universidad de Tsinghua", - "gantt_config_thursday_in_select": "Universidad de Tsinghua", + "gantt_config_thursday": "Jueves", + "gantt_config_thursday_in_bar": "Jue", + "gantt_config_thursday_in_select": "Jueves", "gantt_config_tuesday": "Martes", - "gantt_config_tuesday_in_bar": "Martes", + "gantt_config_tuesday_in_bar": "Mar", "gantt_config_tuesday_in_select": "Martes", "gantt_config_wednesday": "Miércoles", - "gantt_config_wednesday_in_bar": "Miércoles", + "gantt_config_wednesday_in_bar": "Mié", "gantt_config_wednesday_in_select": "Miércoles", "gantt_config_weekdays_range": "${weekday} a ${weekday}", "gantt_config_workdays_a_week": "Días hábiles estándar personalizados", @@ -14286,6 +14758,7 @@ "gold_grade": "Oro", "gold_grade_desc": "Adecuado para equipos con procesos de negocio complejos", "gold_seat_200_desc": "200", + "gold_seat_300_desc": "300", "golden_grade": "Oro", "got_it": "Lo Tengo.", "got_v_coins": "Recompensa V monedas", @@ -14319,6 +14792,8 @@ "guests_per_space": "Huéspedes en cada espacio", "guide_1": "啊这", "guide_2": "Solo se tarda unos minutos en aprender las funciones básicas. ¡¡ a partir de este momento, el trabajo es más eficiente!", + "guide_flow_modal_contact_sales": "Contacto Ventas", + "guide_flow_modal_get_started": "Empezar", "guide_flow_of_catalog_step1": "Este es el catálogo de trabajo en el que se almacenan todas las carpetas y archivos de space.", "guide_flow_of_catalog_step2": "En el catálogo de trabajo, puede crear una tabla de datos o una carpeta según sea necesario.", "guide_flow_of_click_add_view_step1": "Además de algunas vistas básicas, si tiene un adjunto en formato de imagen, se recomienda encarecidamente crear una vista de álbum.", @@ -14497,6 +14972,7 @@ "intro_widget_tips": "¿Qué es widget?", "introduction": "Introducción", "invalid_action_sort_tip": "Como campo de agrupación, se ha establecido su clasificación. La configuración del pedido actual no entrará en vigor.", + "invalid_automation_configuration": "Configuración de automatización no válida, verifíquela e inténtelo nuevamente.", "invalid_field_type": "Tipo de campo no válido", "invalid_option_sort_tip": "Como campo de agrupación, se ha establecido su clasificación.", "invalid_redemption_code_entered": "El Código de cambio no es válido", @@ -14627,6 +15103,9 @@ "label_format_day_month_and_year_split_by_slash": "Día / mes / año", "label_format_month": "Mes", "label_format_month_and_day_split_by_dash": "Año, mes, día", + "label_format_month_day_year_split_by_dash": "Month-Day-Year", + "label_format_month_day_year_split_by_slash": "Month/Day/Year", + "label_format_month_day_year_two_digit_year_split_by_slash": "Month/Day/Year (Two-digit year)", "label_format_year": "Año", "label_format_year_and_month_split_by_dash": "Año y mes", "label_format_year_month_and_day_split_by_dash": "Año, mes, día", @@ -14705,6 +15184,7 @@ "lark_version_enterprise": "El plan empresarial de Lark", "lark_version_standard": "Plano estándar de Lark", "lark_versions_free": "Plano básico de Lark", + "last_day": "Último día", "last_modified_by_select_modal_desc": "Si se edita alguno de los campos seleccionados a continuación, el miembro recién editado se mostrará en el campo editado por última vez.", "last_modified_time_select_modal_desc": "Si se edita alguno de los campos seleccionados a continuación, el tiempo de edición más reciente se mostrará en el campo de tiempo de la última edición.", "last_step": "Volver", @@ -14849,7 +15329,7 @@ "mail_invite_fail": "La invitación por correo fue exitosa.", "mail_invite_success": "La invitación por correo fue exitosa.", "main_admin_name": "Nombre del Administrador", - "main_admin_page_desc": "Los administradores pueden acceder completamente a los espacios, como los administradores de gametos y la propiedad de los espacios de transferencia.", + "main_admin_page_desc": "El administrador tiene acceso completo al Espacio, como administrar miembros y administrar la configuración del Espacio.", "main_contain": "Contenido principal", "malawi": "Malaui", "malaysia": "Malasia", @@ -15069,8 +15549,12 @@ "more_widget": "Más gadgets", "morocco": "Marruecos", "move": "Mover", + "move_datasheet_link_warn": "Cannot be moved to Team Area alone, because there is a two-way link from the current datasheet to another datasheet, it is recommended to put them in a folder and then move them", "move_favorite_node_fail": "El movimiento del nodo falló. El sistema actualizará automáticamente la lista.", + "move_folder_link_warn": "Cannot be moved to Team Area because the files in the current folder are linked to files outside the folder (may be two-way links or linked by forms, etc.) We recommend that they be placed in a folder before moving", "move_node_modal_content": "Después de moverse, la visibilidad del archivo puede verse afectada por la carpeta padre.", + "move_other_link_no_permission": "Unable to move to the corresponding folder because you do not have administrative rights to the folder", + "move_other_link_warn": "It is not allowed to move ${node type} to Team Area alone, because it connects to the datasheet of Private Area, it is recommended to put them in a folder before moving them", "move_to": "Mover a", "move_to_error_equal_parent": "El archivo se encuentra bajo la carpeta actual. Por favor, elija otra carpeta", "move_to_modal_title": "Mover [${name}] a", @@ -15101,7 +15585,9 @@ "new_a_line": "Tecla shift + enter: cambiar de línea", "new_automation": "Nueva automatización", "new_caledonia": "Nueva Caledonia", + "new_custom_page": "New custom page", "new_datasheet": "Nueva tabla de datos", + "new_ebmed_page": "Nueva página personalizada", "new_folder": "Nueva carpeta", "new_folder_btn_title": "Carpetas", "new_folder_tooltip": "Crear una carpeta", @@ -15267,7 +15753,7 @@ "nvc_start_text": "Arrastre la barra al extremo derecho", "nvc_yes_text": "Confirmado", "obtain_verification_code": "El Código de verificación no se ha obtenido o ha expirado", - "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrzw0miJVmSkJ7eBBa9k/fomx5qPX0JGPFvfEEP\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", + "offical_website_footer_nav_data": "[{ \"title\": \"产品\", \"lists\": [{ \"name\": \"快速入门\", \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick- inicio\" }, { \"nombre\": \"产品指南\", \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\" }, { \"nombre\": \"产品价格\", \"url\": \"/precios/\" }, { \"name\": \"产品路线图\", \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\" }] }, { \"title\": \"关于我们\", \"lists\": [{ \"name\": \"公司介绍\", \"url\": \"/company/\" }, { \"name\": \"加入我们\", \"url \": \"/únete a nosotros/\" }, { \"name\": \"媒体报道\", \"url\": \"/press/\" }, { \"name\": \"vika维格课堂\", \"url\": \"https ://edu.vika.cn/\" }, { \"name\": \"维格合伙人\", \"url\": \"/partners/\" }] }, { \"title\": \"解决方案\", \"listas\" : [{ \"name\": \"PMO项目群管理\", \"url\": \"/business-pmo/\" }, { \"name\": \"智慧电商运营\", \"url\": \"/ecommerce/\" }, { \"nombre\": \"CRM客户管理\", \"url\": \"/crm/\" }, { \"nombre\": \"HR人力资源管理\", \"url\": \"/hr/\" }, { \"nombre\": \"Scrum敏捷开发管理\", \"url\": \"/scrum/\" }, { \"name\": \"营销策划与市场运营\", \"url\": \"/marketing/\" }, { \"name\": \"OKR目标管理\", \"url\": \"/okr/\" }, { \"name\": \"教育培训管理\", \"url\": \"/education/\" }, { \"name\": \"智慧门管理\", \"url\" : \"/tienda/\" }] }, { \"title\": \"支持\", \"lists\": [{ \"name\": \"意见反馈\", \"url\": \"https://vika.cn/share/shrCvbFC53xc3kl00B4Pg \" }, { \"nombre\": \"帮助中心\", \"url\": \"https://help.vika.cn/\" }, { \"nombre\": \"开发者中心\", \"url\": \"/developers/ \" }, { \"nombre\": \"服务条款\", \"url\": \"/acuerdo-de-servicio/\" }, { \"nombre\": \"隐私协议\", \"url\": \"/acuerdo-de-servicio/\" }, { \"name\": \"安全与合规\", \"url\": \"/security/\" }] }, { \"title\": \"服务\", \"lists\": [{ \"name\": \"加入社群\", \" url\": \"/chatgroup/\" }, { \"name\": \"Github开源\", \"url\": \"https://github.com/vikadata\" }, { \"name\": \"预约演示\", \"url\" : \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\" }, { \"name\": \"专有云部署\", \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\" } , { \"name\": \"应用连接\", \"url\": \"/connections/\" }] }, { \"title\": \"联系我们\", \"lists\": [{ \"name\": \"地址:深圳市南山区国信投资大厦1710\", \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\" }, { \"name\": \"售前咨询:点击联系商务\", \"url\": \"https: //vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\" }, { \"name\": \"合作:bd@vikadata.com\", \"url\": \"mailto:bd@vikadata.com\" }, { \"name\": \"媒体:pr@vikadata.com\", \"url\": \"mailto:pr@vikadata.com\" }, { \"name\": \"招聘:hr@vikadata.com\", \"url\": \"mailto:hr@vikadata. es\" }] }]", "offical_website_nav_data": "[{\n \"name\": \"产品\",\n \"href\": \"/login\",\n \"children\": [\n {\n \"name\": \"vika维格表 Overview\",\n \"href\": \"/login/\"\n },\n {\n \"name\": \"应用连接 Integration\",\n \"href\": \"/connections/\"\n },\n {\n \"name\": \"客户端(Beta) Download\",\n \"href\": \"/download/\"\n }\n ]\n}, {\n \"name\": \"解决方案\",\n \"href\": \"/\",\n \"children\": [{\n \"name\": \"PMO项目群管理\",\n \"href\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"href\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"href\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"href\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"href\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"href\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"href\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"href\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"href\": \"/shop/\"\n }, {\n \"name\": \"更多解决方案 >\",\n \"href\": \"/solutions/\"\n }]\n}, {\n \"name\": \"模板/案例\",\n \"href\": \"/template\",\n \"children\": [\n {\n \"name\": \"模板中心 Tempaltes\",\n \"href\": \"/template\"\n },\n {\n \"name\": \"客户案例 Customers\",\n \"href\": \"/cases/\"\n }\n ]\n},\n {\n \"name\": \"首页\",\n \"href\": \"/?home=1\"\n },\n {\n \"name\": \"学习资源\",\n \"href\": \"https://edu.vika.cn/index\",\n \"children\": [\n {\n \"name\": \"快速入门 Tutorials\",\n \"href\": \"https://help.vika.cn/docs/guide/tutorial\"\n },\n {\n \"name\": \"产品手册 Manual\",\n \"href\": \"https://help.vika.cn/docs/guide/manual\"\n },\n {\n \"name\": \"维格课堂 Vika Education\",\n \"href\": \"https://edu.vika.cn/\"\n },\n {\n \"name\": \"维格社区 Vika BBS\",\n \"href\": \"https://bbs.vika.cn/\"\n },\n {\n \"name\": \"第三方连接 Integration\",\n \"href\": \"https://help.vika.cn/docs/guide/connection\"\n },\n {\n \"name\": \"开发者中心 Developer Center\",\n \"href\": \"/developers/\"\n },\n {\n \"name\": \"常见问题 FAQ\",\n \"href\": \"https://help.vika.cn/docs/guide/questions\"\n }\n ]\n }]", "office_preview": "Previsualizar archivos de Office", "office_preview_app_desc": "

Smooth online preview of office files on datasheet, allowing you to view common office files such as Excel, Word, PPT, etc. on your desktop or mobile anywhere, anytime

\n\n
    \n
  • Online preview of .doc, .docx, .xls, .xlsx, .ppt, .pptx, and .pdf formatted office files
  • \n
  • Desktop and mobile both support file previews of the above formats
  • \n
\n\n

Additional notes:

\n
    \n
  • This feature is powered by \"Yoncentric Cloud Conversion\" and officially integrated
  • \n
  • Click the \"Enable\" button below to enable this integration and agree that \"Yoncentric Cloud Conversion\" reads the office files you want to preview
  • \n
  • If you no longer need the office files preview feature, the space admin can disable it on this page
  • \n
", @@ -15307,6 +15793,7 @@ "open_auto_save_success": "La vista de guardar automáticamente se ha abierto con éxito", "open_auto_save_warn_content": "Todos los cambios bajo esta vista se guardan automáticamente y se sincronizan con otros miembros.", "open_auto_save_warn_title": "Activar guardar vista automáticamente", + "open_automation_time_arrival": "https://aitable.ai/contact-sales-open-source", "open_failed": "Abrir falló", "open_in_new_tab": "Abrir en una nueva ficha", "open_invite_after_operate": "Una vez abierto, todos los miembros pueden invitar a nuevos miembros desde el panel de contactos", @@ -15453,6 +15940,8 @@ "payment_record": "Registro de pagos", "payment_reminder": "Consejos de pago", "payment_reminder_content": "El nuevo plan que ha seleccionado es más deducible que el monto a pagar. Se recomienda elegir el nuevo plan de mayor duración. Si confirma hacerlo, el importe de la franquicia no será reembolsable. ${action} en caso de duda", + "payment_reminder_modal_content": "Puede probar la versión avanzada para disfrutar de más nodos de archivos, permisos empresariales, capacidad de archivos adjuntos, volumen de datos, IA y otras funciones y privilegios avanzados.", + "payment_reminder_modal_title": "Actualmente estás usando la versión gratuita.", "pending_invite": "Invitación pendiente", "people": "Miembros", "per_person_per_year": "Por persona y año", @@ -15622,7 +16111,7 @@ "player_step_ui_config_168": "{\n\"templateKey\":\"createMirrorTip\"\n}", "player_step_ui_config_169": "{ \"headerImg\": \"https://s4.vika.cn/space/2023/04/04/bcf0695cf35840e6b85e032a8e5ea0a1\", \"readMoreUrl\": \"https://help.vika.cn/changelog/23-04-10- actualizaciones\", \"niños\": \"

🚀 Introducción de nuevas funciones.

\\norte
  • Se lanza el nuevo tipo de campo \"Cascader\", lo que facilita la selección entre una jerarquía de opciones en los formularios.
  • Se lanza el widget \"Script\", menos código para una mayor personalización
  • Active la automatización para enviar correos electrónicos y recibir notificaciones rápidas
  • Activa la automatización para enviar un mensaje a Slack e informar a tu equipo a tiempo
  • Explorando la IA: Lanzamiento del widget \"Generador de contenido GPT\"
\" }", "player_step_ui_config_17": "{\n \"element\": \"#TEMPLATE_CENTER_USE_TEMPLATE_BTN>button\", \n\"placement\": \"rightBottom\",\n\"offsetY\": 20,\n \"title\": \"How to use a template\", \n\"description\": \"Click the button on the left to use the template\", \"children\":\"\" \n}", - "player_step_ui_config_176": "{\"title\":\"Introducción AI agent\",\"video\":\"https://www.youtube.com/embed/cjds1r_roG8?si=irKUpMhwDlOEb8Hc\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", + "player_step_ui_config_176": "{\"title\":\"AITable.ai DEMO\",\"video\":\"https://www.youtube.com/embed/kGxMyEEo3OU\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", "player_step_ui_config_18": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select>.ant-select-selector\", \n\"placement\": \"bottomLeft\",\n \"title\": \"How to use a template\", \n\"description\": \"Select where to put the template\", \"children\":\"\" \n}", "player_step_ui_config_19": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select .ant-select-selector\"\n}", "player_step_ui_config_2": "{\n \"config\": [\n {\n \"key\": 1,\n \"name\": \"answer1\",\n \"title\": \"What kind of issues are you looking forward to solved by vikadata?\",\n \"type\": \"checkbox\",\n \"answers\": [\n \"Work Planning\",\n \"Customer Service\",\n \"Project Management\",\n \"Sourcing Supply\",\n \"Content Production\",\n \"E-commerce operation\",\n \"Event Planning\",\n \"Human Resources\",\n \"Administration\",\n \"Financial Management\",\n \"Webcast\",\n \"Educational institutes Management\",\n \"Other\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 2,\n \"name\": \"answer2\",\n \"title\": \"Your job title is______\",\n \"type\": \"radio\",\n \"answers\": [\n \"General manager \",\n \"Project manager\",\n \"Product manager\",\n \"Designer\",\n \"R&D engineer\",\n \"Operator, editor\",\n \"Sales, customer service\",\n \"Human resource, administration \",\n \"Finance, accountant\",\n \"Lawyer, legal affairs\",\n \"Marketing\",\n \"Teacher\",\n \"Student\",\n \"Other\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 3,\n \"name\": \"answer3\",\n \"title\": \"What is the name of your company?\",\n \"type\": \"input\",\n \"submit\": false\n },\n {\n \"key\": 4,\n \"name\": \"answer4\",\n \"title\": \"Please leave your email address/ phone number/ Wechat account below so we can reach you in time when you need help.\",\n \"type\": \"input\",\n \"submit\": true\n },\n {\n \"key\": 5,\n \"title\": \"Thank you for filling out the form, you can add our customer service in case of need\",\n \"platform\": {\n \"website\": \"https://s4.vika.cn/space/2023/03/02/b34e3205a9154463be16f497524f1327\",\n \"dingtalk\": \"https://s4.vika.cn/space/2023/03/02/4b16cef6602a4586a21d6346bf25d300\",\n \"wecom\": \"https://s4.vika.cn/space/2023/03/02/60119b1b69b64aa887bd1be6a2928bec\",\n \"feishu\": \"https://u.vika.cn/z9ygm\"\n },\n \"type\": \"contactUs\",\n \"next\": true\n }\n ]\n}\n", @@ -15652,13 +16141,13 @@ "player_step_ui_config_41": "", "player_step_ui_config_42": "{\n \"element\": \"#DATASHEET_FORM_LIST_PANEL\", \n\"placement\": \"leftTop\",\n \"title\": \"Form\", \n\"description\": \"You can quickly create a form from the current view. The number and order of the fields in the form is consistent with the view.\", \"children\":\"\" \n}", "player_step_ui_config_43": "{\n \"element\": \".style_navigation__1U5cR .style_help__1sXEA\", \n\"placement\": \"rightBottom\",\n \"title\": \"Tip\", \n\"offsetY\":5,\n\"description\": \"You can find your Vikaby assistant from the \"Help\" icon on the left\", \"children\":\"\" \n}", - "player_step_ui_config_44": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", + "player_step_ui_config_44": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", "player_step_ui_config_45": "", "player_step_ui_config_46": "", "player_step_ui_config_47": "{\n \"element\": \"#DATASHEET_WIDGET_BTN\",\n\"placement\": \"bottomRight\",\n \"title\": \"Widget\", \n\"description\": \"Want to use and view your data in a richer way? Try the widget!\", \"children\":\"\" \n}", "player_step_ui_config_48": "", "player_step_ui_config_49": "{\n \"element\": \".style_widgetPanelContainer__1l2ZV\",\n\"placement\": \"leftCenter\",\n \"title\": \"What is a widget\", \n\"description\": \"Vika widgets are an extended application of vikadata that features in richer data visualization, data transfer, data cleansing, and more. By installing widgets in the widget board, you can make work a lot easier.\", \"children\":\"\" \n}", - "player_step_ui_config_5": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", + "player_step_ui_config_5": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", "player_step_ui_config_50": "{\n \"element\": \".style_widgetModal__eXmdB\",\n\"placement\": \"leftTop\",\n \"title\": \"Widget Center\", \n\"description\": \"Officially recommended and custom widgets are published here. You can install any widget you want onto a dashboard or into a widget board of any datasheet.\", \"children\":\"\" \n}", "player_step_ui_config_51": "{\n \"element\": \".style_widgetModal__eXmdB .style_widgetItem__3Pl-1 button\",\n\"placement\": \"rightBottom\",\n \"title\": \"Install widget\", \n\"description\": \"Let's install this \"Chart\" widget\", \"children\":\"\" \n}", "player_step_ui_config_52": "", @@ -15755,6 +16244,7 @@ "preview_guide_click_to_restart": "Presione el botón de abajo para Previsualizar de nuevo", "preview_guide_enable_it": "Presione el botón de abajo para abrir esta función", "preview_guide_open_office_preview": "Para Previsualizar este archivo, abra la función \"previsualización de la oficina\"", + "preview_next_automation_execution_time": "Vista previa de los próximos 10 tiempos de ejecución", "preview_not_support_video_codecs": "Solo se pueden Previsualizar vídeos mp4 con Códec de vídeo h.264", "preview_revision": "Vista previa", "preview_see_more": "¿Desea obtener más información sobre la función \"vista previa de archivos de Office\"? Por favor haga clic aquí", @@ -15790,6 +16280,7 @@ "privacy_protection": "\"Protección de la privacidad\"", "private_cloud": "Nube privada", "private_external_person_only": "Solo personal externo", + "private_help_link": "https://help.aitable.ai/docs/guide/team-and-private-area#private-area", "private_internal_person_only": "Solo personal interno", "private_product_point": "Sea dueño de su plataforma APITable con un solo clic", "privatized_deployment": "Autogestión", @@ -15860,13 +16351,15 @@ "reconciled_data": "Se están verificando los datos", "record": "Registro", "record_activity_experience_tips": "Puede ver la actividad de registro de ${day} días", + "record_archived_data": "registro archivado", + "record_chunk_text": "${text} rows, please wait", "record_comment": "Solo anotaciones", "record_comments": "Comentarios", "record_fail_data": "Error de datos", "record_filter_tips": "Este registro ha sido filtrado", "record_functions": "Función de registro", "record_history": "Solo se revisan los registros históricos", - "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-history", + "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-activity", "record_history_title": "Registrar registros históricos", "record_pre_filtered": "Este registro ha sido filtrado y se ocultará al hacer clic en el exterior del registro", "record_pre_move": "Después de hacer clic en el exterior del registro, este registro se moverá a otra posición", @@ -16306,6 +16799,12 @@ "scan_to_login": "Escanear inicio de sesión", "scan_to_login_by_method": "Escanea ${method} para seguir la cuenta oficial e iniciar sesión", "scatter_chart": "Mapa de dispersión", + "schedule_day_tips": "El cómputo del ciclo comienza a contar desde el primer día de cada mes. Si asumimos que se repite cada 10 días, entonces se activará los días 1, 11, 21 y 31 de cada mes.", + "schedule_hour_tips": "El cálculo del ciclo comienza a medianoche (0:00) cada día. Suponiendo que se repite 0 minutos cada tres horas, ocurrirá a medianoche (0:00), 3 a. m., 6 a. m., 9 a. m., mediodía (12 p. m.), 3 p. m., 6 p. m. y finalmente al anochecer (9 p. m.) todos los días.", + "schedule_start_day": "A partir del día 1 del mes, cada", + "schedule_start_month": "A partir de enero de cada año, cada", + "schedule_type": "Tipo de horario", + "schedule_year_tips": "El cómputo del ciclo comienza a contar desde el primer mes de cada año. Suponiendo un intervalo de tres meses durante el primer día, los activadores se activarán a la medianoche del primer día de enero, abril, julio y octubre de cada año.", "science_and_technology": "Ciencia y tecnología", "scroll_screen_down": "Desplácese hacia abajo por una pantalla", "scroll_screen_left": "Desplaza una pantalla a la izquierda", @@ -16319,6 +16818,7 @@ "search_folder_or_sheet": "Buscar archivos", "search_new_admin": "Buscar", "search_node_pleaseholder": "Buscar archivos (${shortcutKey})", + "search_node_tip": "Búsqueda rápida (${shortcutKey})", "search_or_add": "Encontrar o agregar opciones", "search_role_placeholder": "Buscar personajes", "seats": "Asientos", @@ -16722,6 +17222,7 @@ "space_info": "Resumen", "space_info_del_confirm1": "1. eliminar este espacio compartido eliminará los siguientes datos:", "space_info_del_confirm2": "2. los espacios compartidos serán eliminados por completo después de 7 días. Antes de eso, puede restaurar el espacio.", + "space_info_del_confirm3": "3. For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "space_info_feishu_desc": "Está utilizando integración de terceros. Para eliminar el espacio compartido, primero Deshabilite la integración de terceros.", "space_info_feishu_label": "Integración", "space_join_apply": "Se solicita la inclusión en el espacio \" < a class =\" spacename \"> < a > espacio.", @@ -16808,6 +17309,7 @@ "start_onfiguration": "Iniciar configuración", "start_time": "Hora de inicio", "start_use": "Empezar a usar", + "starting_from_midnight": "A partir de medianoche (12:00 a.m.) todos los días, todos", "startup": "Inicio", "startup_company_support_program": "Iniciar el plan de apoyo", "stat_average": "Promedio", @@ -16841,6 +17343,8 @@ "stay_tuned_for_more_features": "Por favor, preste atención a más funciones.", "steps_choose_reset_mode": "Seleccionar el método de reinicio", "steps_validate_identities": "Autenticación", + "stop_chunk_content": "Are you sure you want to stop the operation?", + "stop_chunk_title": "Stop", "stop_dingtalk_h5_modal_content": "La aplicación autoconstruida se desbloqueará desde este espacio. Por favor, confirme.", "storage_per_seats": "", "storage_per_space": "Uso del almacenamiento", @@ -16871,9 +17375,11 @@ "subscribe_credit_usage_over_limit": "El número de créditos en el espacio actual supera el límite, por favor actualice su suscripción.\n", "subscribe_demonstrate": "Solicitud de presentación", "subscribe_disabled_seat": "El número de personas no puede ser inferior al plan original", + "subscribe_grade_business": "Negocio", "subscribe_grade_free": "Libre", "subscribe_grade_plus": "Más", "subscribe_grade_pro": "A favor", + "subscribe_grade_starter": "Inicio", "subscribe_label_tooltip": "Función espacial avanzada", "subscribe_new_choose_member": "Admite hasta ${member_num} miembros", "subscribe_new_choose_member_tips": "Este plan admite 1~${member_num} miembros para ingresar al espacio", @@ -17010,7 +17516,7 @@ "template_name_repetition_title": "\"${templateName}\" ya existe. ¿Quieres cambiarlo?", "template_no_template": "No hay plantilla", "template_not_found": "¿No puede encontrar las plantillas que desea? Dinos", - "template_recommend_title": "Caliente", + "template_recommend_title": "🌟 Hot", "template_type": "Modelo", "terms_of_service": "[términos de servicio]", "terms_of_service_pure_string": "Cláusulas de servicio", @@ -17054,6 +17560,7 @@ "text_editor_tip_end": "\"Entrada\" para terminar la edición", "text_functions": "Función de cadena", "thailand": "Tailandia", + "the_button_field_is_misconfigured": "El campo del botón está mal configurado, verifíquelo e inténtelo nuevamente.", "the_current_automation_workflow_has_no_related_files_you_can_establish_a_link_by_adding_trigger_conditions_and_actions_on_the_left_side": "El flujo de trabajo de automatización actual no tiene archivos relacionados. Usted puede establecer un enlace añadiendo condiciones de activación y acciones en el lado izquierdo", "the_current_button_column_has_expired_please_reselect": "La columna de botones actual ha caducado, vuelva a seleccionarla", "the_last_7_days": "Los últimos 7 días", @@ -17106,8 +17613,8 @@ "time_machine_action_title": "Historial de operaciones", "time_machine_unlimited": "Historia de la máquina del tiempo infinito", "time_zone_inconsistent_tips": "Cuando la zona es inconsistente en ese momento, por defecto se utilizará la zona horaria de la hora de inicio.", - "timemachine_add": "Añadido ${nombre}", - "timemachine_add_field": "se agregaron ${nombre} columna(s)", + "timemachine_add": "Añadido ${name}", + "timemachine_add_field": "se agregaron ${name} columna(s)", "timemachine_add_record": "se agregaron ${count} filas de registros", "timemachine_add_widget": "añadido un nuevo widget", "timemachine_delete_comment": "comentarios eliminados", @@ -17156,6 +17663,7 @@ "timemachine_update_comment": "comentarios actualizados", "times_per_month_unit": "Teléfono / mes", "times_unit": "Teléfono", + "timing_rules": "Momento", "timor_leste": "Timor Oriental", "tip_del_success": "Puede recuperar su espacio compartido en 7 días", "tip_do_you_want_to_know_about_field_permission": "¿Quiere cifrar datos de campo? Más información sobre los permisos de campo", @@ -17343,6 +17851,7 @@ "verify_account_title": "Cuenta de verificación", "verify_via_email": "Autenticación por correo electrónico", "verify_via_phone": "Autenticación SMS", + "video": "Video", "video_not_support_play": "El formato de vídeo actual no admite reproducción en línea", "vietnam": "Vietnam", "view": "Puntos de vista", @@ -17691,7 +18200,8 @@ "workdoc_color_title": "Color de fuente", "workdoc_create": "Crear documento de trabajo", "workdoc_expanded": "Ampliar la tabla de contenidos", - "workdoc_image_max_10mb": "El tamaño de la imagen no puede exceder los 10 MB.", + "workdoc_image_max_10mb": "nulo", + "workdoc_image_max_size": "El tamaño de la imagen no puede exceder ${size}", "workdoc_info": "Información", "workdoc_info_create_time": "Creado en", "workdoc_info_creator": "Creado por", @@ -17699,6 +18209,7 @@ "workdoc_info_last_modify_time": "Última modificación en", "workdoc_link_placeholder": "Por favor ingrese el enlace", "workdoc_only_image": "Solo se permite imagen", + "workdoc_only_video": "Sólo se permite vídeo", "workdoc_text_placeholder": "Ingrese \"/\" inicio rápido", "workdoc_title_placeholder": "Por favor ingresa el título", "workdoc_unnamed": "Documento de trabajo sin nombre", @@ -17707,9 +18218,11 @@ "workdoc_unsave_ok": "Descartar los cambios", "workdoc_unsave_title": "El WorkDoc no ha sido guardado", "workdoc_upload_failed": "Subida fallida", + "workdoc_video_max_size": "El tamaño del video no puede exceder ${size}", "workdoc_ws_connected": "Conectado", "workdoc_ws_connecting": "Conectando...", "workdoc_ws_disconnected": "Desconectado", + "workdoc_ws_reconnecting": "Reconectando...", "workflow_execute_failed_notify": " no pudo ejecutarse en . Revise el historial de ejecución para solucionar el problema. Si necesita ayuda, comuníquese con nuestro equipo de atención al cliente.", "workspace_data": "Datos espaciales", "workspace_files": "Datos de la Mesa de trabajo", @@ -17888,6 +18401,15 @@ "agreed": "Approuvé", "ai_advanced_mode_desc": "El modo avanzado permite a los usuarios personalizar las indicaciones, proporcionando un mayor control sobre el comportamiento y las respuestas del AI agent.", "ai_advanced_mode_title": "Mode avancé", + "ai_agent_anonymous": "Anonyme${ID}", + "ai_agent_conversation_continue_not_supported": "La poursuite d'une conversation précédente n'est actuellement pas prise en charge", + "ai_agent_conversation_list": "Liste de conversations", + "ai_agent_conversation_log": "Journal des conversations", + "ai_agent_conversation_title": "Titre de la conversation", + "ai_agent_feedback": "Retour", + "ai_agent_historical_message": "Ce qui précède est un message historique", + "ai_agent_history": "Histoire", + "ai_agent_message_consumed": "Message consommé", "ai_api_curl_template": "## Create chat completions\n\n```bash\n\ncurl -X POST \"{{apiBase}}/fusion/v1/ai/{{aiId}}/chat/completions\" \\n -H \"Content-Type: application/json\" \\n -H \"Authorization: Bearer {{token}}\" \\n -d '{\n \"model\": \"gpt-3.5-turbo\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"You are a helpful assistant.\"\n },\n {\n \"role\": \"user\",\n \"content\": \"Hello!\"\n }\n ]\n }'\n\n```\n\n## Returned data example\n\n```json\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", "ai_api_footer_desc": "¿Integrar AI agent en su sitio web? Aprende más", "ai_api_javascript_template": "## Initialize SDK [![github]({{ githubIcon }})](https://github.com/openai/openai-node)\nAITable's chat completion API is compatible with OpenAI's Node.js SDK. You can use our service with the same SDK by simply changing the configuration as follows:\n\n\n```javascript\nconst { Configuration, OpenAIApi } = require(\"openai\");\nconst configuration = new Configuration({\n apiKey: \"{{token}}\",\n basePath: \"{{apiBase}}/fusion/v1/ai/{{aiId}}\"\n});\n```\n\n## Create chat completions\n\n```javascript\nconst openai = new OpenAIApi(configuration);\nconst chatCompletion = await openai.createChatCompletion({\n model: \"gpt-3.5-turbo\",\n messages: [{role: \"user\", content: \"Hello world\"}],\n});\n```\n\n## Returned data example\n\n```javascript\n\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", @@ -17903,6 +18425,9 @@ "ai_chat_unit": "aibot(s)", "ai_close_setting_tip_content": "Vous avez apporté des modifications. Tu veux les jeter?", "ai_close_setting_tip_title": "tip", + "ai_copilot_generate_response": "Génération de la réponse pour vous...", + "ai_copilot_processs": "Traitement en cours, veuillez patienter...", + "ai_copilot_start_process_request": "Début du traitement de votre demande...", "ai_create_guide_btn_text": "Sélectionner une fiche de données", "ai_create_guide_content": "En tant qu'AI agent, je peux répondre à vos questions en fonction des connaissances que j'ai apprises. Avant de commencer la conversation, veuillez sélectionner une feuille de données comme base de connaissances, et je lirai toutes les données qu'elle contient pour l'apprentissage.", "ai_credit_cost_chart_title": "Coût du crédit", @@ -17963,7 +18488,7 @@ "ai_prompt_title": "Prompt", "ai_prompt_wrong_content": "Veuillez inclure {context} et {question} dans votre texte.", "ai_query_of_number": "Utilisation", - "ai_remain_credit_label": "Message laissé : ${crédit}", + "ai_remain_credit_label": "Message laissé : ${credit}", "ai_retrain": "Retrain", "ai_robot_data_source_title": "Collection d'ensembles de données", "ai_robot_type_QA_desc": "Un agent de questions-réponses basé sur le PNL et l'apprentissage automatique répond rapidement et précisément à diverses questions et fournit des informations en temps réel et des conseils utiles aux utilisateurs.", @@ -18371,7 +18896,7 @@ "apps_support": "Support client de toutes les plates-formes", "archive_delete_record": "Supprimer les enregistrements archivés", "archive_delete_record_title": "Supprimer l'enregistrement", - "archive_notice": "

Vous essayez d'archiver des enregistrements spécifiques. L'archivage des enregistrements entraînera les modifications suivantes :

1. Tous les liens bidirectionnels pour cet enregistrement seront annulés

2. L'édition n'est pas prise en charge

3. Les fonctions telles que les rappels de date et les enregistrements d'abonnement ne sont pas prises en charge

4. Ne participez plus au calcul des champs de recherche, de formule et autres

Es-tu sur de vouloir continuer? (Vous pouvez désarchiver dans Archive Box dans Advanced)

", + "archive_notice": "

Vous essayez d'archiver des enregistrements spécifiques. L'archivage des enregistrements entraînera les modifications suivantes :

1. L'édition n'est pas prise en charge

2. Les fonctions telles que les rappels de date et les enregistrements d'abonnement ne sont pas prises en charge

3. Ne participez plus au calcul des champs de recherche, de formule et autres

Es-tu sur de vouloir continuer? (Vous pouvez désarchiver dans Archive Box dans Advanced)

", "archive_record_in_activity": "Archivé cet enregistrement", "archive_record_in_menu": "Dossier d'archive", "archive_record_success": "Enregistrements archivés avec succès", @@ -18431,6 +18956,8 @@ "audit_add_field_role_detail": "Dans la \"\"feuille de données , ajouter [] le rôle comme [] pour le champ [] ", "audit_add_node_role": "Ajouter des permissions de fichier", "audit_add_node_role_detail": "Ajouter une autorisation de fichier , définir 「 ${unitNames} 」 à 「 ${role} 」 de 「 ${currentNodeName} 」", + "audit_add_node_role_detail_end": "to「${role}", + "audit_add_node_role_detail_start": "Add file node permission,set「${unitNames}」", "audit_admin_permission_change_event": "Modifier les permissions de l'administrateur", "audit_create_template": "Créer un modèle", "audit_create_template_detail": "Nommer le modèle", @@ -18439,20 +18966,30 @@ "audit_delete_field_role_detail": "Audit", "audit_delete_node_role": "Permission de supprimer le fichier", "audit_delete_node_role_detail": "Supprimer l'autorisation de fichier,delete「${unitNames}」`s 「${role}」rôle de 「${currentNodeName}」", + "audit_delete_node_role_detail_end": "at 「${role}」role", + "audit_delete_node_role_detail_start": "Delete file node permission,delete「${unitNames}」from", "audit_delete_template": "Supprimer ce modèle", "audit_delete_template_detail": "Supprimer ce modèle", "audit_disable_field_role": "Désactiver les autorisations de champ", "audit_disable_field_role_detail": "Audit", "audit_disable_node_role": "Désactiver les permissions de fichier", "audit_disable_node_role_detail": "Désactiver l'autorisation de ${nodeType} 「${currentNodeName}」", + "audit_disable_node_role_detail_end": "`s permission", + "audit_disable_node_role_detail_start": "Disable ${nodeType}", "audit_disable_node_share": "Fermer le lien public du fichier", "audit_disable_node_share_detail": "Fermer le lien public ${nodeType} 「${currentNodeName}」", + "audit_disable_node_share_detail_end": "public link", + "audit_disable_node_share_detail_start": "Close ${nodeType}", "audit_enable_field_role": "Activer les autorisations de champ", "audit_enable_field_role_detail": "Audit", "audit_enable_node_role": "Activer les permissions de fichier", "audit_enable_node_role_detail": "Activer l'autorisation de ${nodeType} 「${currentNodeName}」", + "audit_enable_node_role_detail_end": "`s permission", + "audit_enable_node_role_detail_start": "Enable ${nodeType}", "audit_enable_node_share": "Ouvrir le lien public du fichier", "audit_enable_node_share_detail": "Ouvrez le lien public ${nodeType} 「${currentNodeName}」", + "audit_enable_node_share_detail_end": "public link", + "audit_enable_node_share_detail_start": "Open ${nodeType}", "audit_login_event": "Événement de connexion", "audit_logout_event": "anglais", "audit_organization_change_event": "La structure organisationnelle des contacts a changé", @@ -18473,18 +19010,25 @@ "audit_space_invite_user_detail": "Audit", "audit_space_node_copy": "Dupliquer le fichier", "audit_space_node_copy_detail": "Dupliquer ${nodeType} 「${sourceNodeName}」, le nouveau nom de fichier est 「${currentNodeName}」", + "audit_space_node_copy_detail_start": "Duplicate ${nodeType} 「${sourceNodeName}」, the new file node's name is", "audit_space_node_create": "Créer un fichier", "audit_space_node_create_detail": "Créez un ${nodeType} nommé 「${currentNodeName}」", + "audit_space_node_create_detail_start": "Create a ${nodeType} named", "audit_space_node_delete": "Supprimer le champ", "audit_space_node_delete_detail": "Supprimer ${nodeType} nommé 「${currentNodeName}」", + "audit_space_node_delete_detail_start": "Delete ${nodeType} named", "audit_space_node_export": "Exporter la fiche technique", "audit_space_node_export_detail": "Le membre ${member_name} a exporté la feuille de données ${node_name}", "audit_space_node_import": "Importer fichier", "audit_space_node_import_detail": "Importez un fichier nommé 「${nodeName}」", + "audit_space_node_import_detail_start": "Import a file node named", "audit_space_node_move": "Déplacer le fichier", "audit_space_node_move_detail": "Déplacez ${nodeType} 「${currentNodeName}」 vers le dossier「${parentName}」", + "audit_space_node_move_detail_end": "to the folder「${parentName}」", + "audit_space_node_move_detail_start": "Move ${nodeType}", "audit_space_node_rename": "Renommer le fichier", "audit_space_node_rename_detail": "Renommez ${nodeType} 「${oldNodeName}」 en 「${nodeName}」", + "audit_space_node_rename_detail_start": "Rename ${nodeType} 「${oldNodeName}」to", "audit_space_node_sort": "Audit", "audit_space_node_sort_detail": "Audit", "audit_space_node_update_cover": "Audit", @@ -18499,17 +19043,24 @@ "audit_space_rubbish_node_delete_detail": "Audit", "audit_space_rubbish_node_recover": "Restaurer les fichiers", "audit_space_rubbish_node_recover_detail": "Restaurer ${nodeType} 「${currentNodeName}」 depuis la corbeille", + "audit_space_rubbish_node_recover_detail_end": "from the trash", + "audit_space_rubbish_node_recover_detail_start": "Restore ${nodeType}", "audit_space_template_event": "Changement de modèle", "audit_space_update_logo": "Audit", "audit_space_update_logo_detail": "Audit", "audit_store_share_node": "Enregistrer le fichier partagé", "audit_store_share_node_detail": "Restaurez ${nodeType} dans l'espace, le nom est 「${nodeName}」", + "audit_store_share_node_detail_start": "Restore ${nodeType} to the space, name is", "audit_update_field_role": "Audit", "audit_update_field_role_detail": "Audit", "audit_update_node_role": "Modifier l'autorisation de fichier", "audit_update_node_role_detail": "Modifier l'autorisation de fichier , modifier le rôle de 「 ${unitNames} 」 à 「 ${role} 」 de 「 ${currentNodeName} 」", + "audit_update_node_role_detail_end": "to「${role}」role", + "audit_update_node_role_detail_start": "Modify file node permission,modify「${unitNames}」from", "audit_update_node_share_setting": "Modifier les paramètres des liens publics du fichier", "audit_update_node_share_setting_detail": "Modifier le lien public ${nodeType} 「${currentNodeName}」", + "audit_update_node_share_setting_detail_end": "public link settings", + "audit_update_node_share_setting_detail_start": "Modify ${nodeType}", "audit_user_login": "Connexion de l'utilisateur", "audit_user_login_detail": "Audit", "audit_user_logout": "Déconnexion de l'utilisateur", @@ -18551,6 +19102,7 @@ "automation_enabled_return_via_related_files": "L'automatisation est activée. Veuillez saisir à nouveau le tableau d'origine via \"Fichiers associés\" pour utiliser le nouveau bouton.", "automation_field": "Champ d'application", "automation_import_variables_from_pre_tep": "Obtenez les données de la pré-étape", + "automation_is_not_yet_enabled": "L'automatisation n'est pas encore activée, veuillez l'activer et réessayer", "automation_last_edited_by": "Dernière édition par", "automation_last_edited_time": "Heure de la dernière modification", "automation_manager_label": "Peut effectuer toutes les actions sur l'automatisme", @@ -18576,6 +19128,7 @@ "automation_runs_this_month": "Fonctionne ce mois-ci", "automation_stay_tuned": "Restez à l'écoute", "automation_success": "Succès", + "automation_tips": "Le champ du bouton est mal configuré, veuillez vérifier et réessayer", "automation_updater_label": "Peut afficher l'historique d'exécution de l'automatisation", "automation_variabel_empty": "Aucune donnée ne peut être utilisée lors de l'étape préalable, veuillez ajuster et réessayer.", "automation_variable_datasheet": "Obtenir des données de ${NODE_NAME}", @@ -18611,6 +19164,7 @@ "bermuda": "Les îles Bermudes", "bhutan": "Bhoutan", "billing_over_limit_tip_common": "L'utilisation de l'espace a dépassé la limite et vous pouvez profiter d'un montant plus élevé après la mise à niveau.", + "billing_over_limit_tip_forbidden": "Votre durée d’essai ou votre période d’abonnement a expiré. Veuillez contacter le conseiller commercial pour renouveler.", "billing_over_limit_tip_widget": "Le nombre d'installations de widgets a dépassé la limite et vous pouvez effectuer une mise à niveau pour obtenir une utilisation plus élevée.", "billing_period": "Période de facturation : ${period}", "billing_subscription_warning": "Expérience des fonctionnalités", @@ -18670,10 +19224,19 @@ "button_text": "Texte du bouton", "button_text_click_start": "Cliquez pour démarrer", "button_type": "Type de bouton", + "by_at": "à", + "by_days": "Jours", + "by_every": "chaque", "by_field_id": "Utiliser l'ID du champ", + "by_hours": "Heures", + "by_in": "à", + "by_min": "minutes)", + "by_months": "Mois", + "by_on": "sur le", "by_the_day": "Par jour", "by_the_month": "Mensuel", "by_the_year": "Annuel", + "by_weeks": "Semaines", "calendar_add_date_time_field": "Créer le champ Date", "calendar_color_more": "Plus de couleurs", "calendar_const_detail_weeks": "[\"lundi\",\"mardi\",\"mercredi\",\"jeudi\",\"vendredi\",\"samedi\",\"dimanche\"]", @@ -18737,6 +19300,14 @@ "cannot_activate_space_by_space_limit": "impossible d'activer l'espace de stockage par limite d'espace", "cannot_join_space": "Vous ne pouvez pas rejoindre une nouvelle station spatiale car vous avez dépassé le quota maximum de 10 stations spatiales.", "cannot_switch_field_permission": "Définir les permissions de champ ne sont pas supérieures aux permissions du fichier. ", + "capacity_file_detail_desc": "The total number of file nodes within the Space is calculated by adding the file nodes from the Team to the file nodes created by each member in their Private. Not enough capacity?", + "capacity_file_detail_title": "File Capacity", + "capacity_file_member": "Member", + "capacity_file_member_private_node_count": "Private", + "capacity_file_member_private_percent": "Percent", + "capacity_file_member_team": "Team", + "capacity_file_member_team_node_count": "Team", + "capacity_file_upgrade": "Click to upgrade your Space", "capacity_from_official_gift": "Du cadeau officiel", "capacity_from_participation": "Par invité ${user} rejoindre l'espace", "capacity_from_purchase": "Par capacité d'achat", @@ -18773,6 +19344,8 @@ "catalog": "Explorateur", "catalog_add_from_template_btn_title": "Ajouter à partir des modèles", "catalog_empty_tips": "Cet espace de travail est vide maintenant. Commencez par utiliser des modèles pour créer des fichiers.", + "catalog_private": "Private", + "catalog_team": "Team", "category_blank": "[espace vide]", "catering": "Restauration", "cayman_islands": "Iles Caïmans", @@ -18841,6 +19414,7 @@ "choose_type_of_vika_field": "Sélectionnez le type de champ", "choose_your_own_space": "(Supporte uniquement les sauvegardes dans votre propre espace en tant que créateur)", "chose_new_primary_admin_button": "Attribuer", + "chunk_stopping_title": "Stopping", "claim_special_offer": "Réclamez cette offre spéciale !", "clear": "Nettoyer", "clear_all_fields": "Effacer tout", @@ -18971,6 +19545,7 @@ "confirm_del_current_team": "Êtes-vous sûr de vouloir supprimer cette équipe?", "confirm_delete": "Confirmer et supprimer l'espace", "confirm_delete_node_name_as": "Voulez-vous vraiment supprimer \"${nodeNameDiv}\" ?", + "confirm_delete_private_node_name_as": "Are you sure you want to delete \"${nodeNameDiv}\"? The file will be deleted from the Space and the trash.", "confirm_delete_space_btn": "Confirmer et supprimer l'espace", "confirm_exit": "Confirmez pour quitter", "confirm_exit_space_with_name": "Confirmez si vous souhaitez quitter l'espace \"${spaceNameDiv}\"", @@ -19008,6 +19583,14 @@ "convert": "Convertir", "convert_tip": "Cette action peut effacer des données dans certaines cellules. Vous pouvez annuler l'action si quelque chose d'inattendu se produit.", "cook_islands": "Iles Cook", + "copilot_auto_agent_desc": "Vous ne savez pas lequel choisir Agent ? Essayez AutoAgent.", + "copilot_auto_agent_name": "Agent automobile", + "copilot_data_agent_desc": "Générer des analyses de données/visualisations basées sur vos vues.", + "copilot_data_agent_name": "Agent de données", + "copilot_data_agent_policy": "Lorsque vous discutez avec Copilot, vous acceptez la politique des conditions d'utilisation", + "copilot_data_agent_policy_button": "Politique", + "copilot_help_agent_desc": "Posez des questions sur les documents du centre d'aide d'AITable.", + "copilot_help_agent_name": "Récupérer le centre d'aide", "copy": " Copie", "copy_automation_url": "Copier l'URL", "copy_card_link": "Copier l'URL de l'enregistrement", @@ -19052,6 +19635,7 @@ "create_mirror_guide_content": "La fonction miroir a la capacité de masquer certaines données. Vous pouvez définir des \"conditions de filtre\" et des \"champs masqués\" dans la vue de feuille de données d'origine pour contrôler les enregistrements et les champs affichés dans le miroir.\n
\n
\nS'il est utilisé en conjonction avec la fonction \"verrouiller la vue\", il peut empêcher les autres d'apporter des modifications.\n
\n
\nDe plus, vous pouvez aller dans \"Table d'origine>Champs cachés\" pour modifier la configuration pour \"Afficher tous les champs dans les miroirs\".", "create_mirror_guide_title": "Le miroir masque certains enregistrements et champs", "create_new_button_field": "Créer un nouveau champ de colonne de bouton", + "create_private_node_tip": "Personal or temporary draft documents can be created here ${link}", "create_public_invitation_link": "Créer le(s) lien(s) d'invitation publique", "create_space_sub_title": "Bonjour, veuillez donner un nom à votre espace~", "create_team_fail": "La création de l'équipe a échoué", @@ -19115,10 +19699,12 @@ "custom_enterprise": "Personnaliser l'espace d'entreprise pour vous", "custom_function_development": "Développement de fonctionnalités personnalisées", "custom_grade_desc": "Fournit le déploiement d'agents, l'installation privée, l'assistance technique et des services professionnels personnalisés", + "custom_page_setting_title": "Add a custom page", "custom_picture": "Image personnalisée", "custom_style": "Style", "custom_upload": "Envoi personnalisé", "custom_upload_tip": "Une image de taille 1:1 est recommandée pour une meilleure expérience visuelle", + "custome_page_title": "Custom Web", "cut_cell_data": "Couper la (les) cellule", "cyprus": "Chypre", "czech": "Tchèque", @@ -19170,6 +19756,7 @@ "default": "Par défaut", "default_create_ai_chat_bot": "Nouvel AI agent", "default_create_automation": "Nouvelle automatisation", + "default_create_custom_page": "Nouvelle page personnalisée", "default_create_dashboard": "Nouveau tableau de bord", "default_create_datasheet": "Nouvelle fiche technique", "default_create_file": "Nouveau fichier", @@ -19191,6 +19778,7 @@ "del_invitation_link": "Supprimer le lien d'invitation", "del_invitation_link_desc": "Le lien sera invalide après suppression", "del_space_now": "Supprimer l'espace pour toujours", + "del_space_now_confirm_tip": "For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "del_space_now_tip": "L'espace ne peut pas être restauré après la suppression. Tous les fichiers et pièces jointes seront supprimés.", "del_space_res_tip": "L'espace a été supprimé", "del_team_success": "Suppression de l'équipe réussie", @@ -19386,6 +19974,62 @@ "embed_error_page_help": "En savoir plus", "embed_fail_og_description_content": "Le lien public pour cette intégration a été désactivé et est temporairement indisponible", "embed_failed": "Le lien d'intégration est indisponible ", + "embed_link_bilibili": "bilibili", + "embed_link_bilibili_desc": "En intégrant les vidéos bilibili, vous pouvez regarder des tutoriels et des guides, ou consulter la page d'accueil de la chaîne dans Vika.", + "embed_link_bilibili_link_text": "Comment intégrer la vidéo bilibili", + "embed_link_bilibili_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-bilibili-video", + "embed_link_default": "Rien", + "embed_link_default_desc": "Collez un lien pour afficher n’importe quel site Web.", + "embed_link_default_link_text": "Apprendre encore plus", + "embed_link_default_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_link_figma": "Figma", + "embed_link_figma_desc": "En intégrant des fichiers Figma, les membres peuvent visualiser et modifier les brouillons de conception plus facilement, améliorant ainsi l'efficacité de la collaboration.", + "embed_link_figma_link_text": "Comment intégrer des fichiers Figma", + "embed_link_figma_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-figma-file", + "embed_link_google_docs": "Docs", + "embed_link_google_docs_desc": "En intégrant Google Docs, vous pouvez modifier et afficher des documents dans AITable pour faciliter la collaboration en équipe.", + "embed_link_google_docs_link_text": "Comment intégrer Google Docs", + "embed_link_google_docs_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-docs-file", + "embed_link_google_sheets": "Sheets", + "embed_link_google_sheets_desc": "En intégrant Google Sheets, vous pouvez modifier et afficher des tableaux dans AITable pour faciliter la collaboration en équipe.", + "embed_link_google_sheets_link_text": "Comment intégrer Google Sheets", + "embed_link_google_sheets_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-sheets-file", + "embed_link_jishi_design": "JSconception", + "embed_link_jishi_design_desc": "En intégrant des fichiers JSdesign, les membres peuvent visualiser et modifier les brouillons de conception plus facilement, améliorant ainsi l'efficacité de la collaboration.", + "embed_link_jishi_design_link_text": "Comment intégrer des fichiers JSdesign", + "embed_link_jishi_design_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-js-design-file", + "embed_link_tencent_docs": "Documents Tencent", + "embed_link_tencent_docs_desc": "En intégrant Tencent Docs, vous pouvez modifier et afficher des documents Tencent dans Vika pour améliorer l'efficacité de la collaboration.", + "embed_link_tencent_docs_link_text": "Comment intégrer Tencent Docs", + "embed_link_tencent_docs_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-tencent-docs", + "embed_link_wps": "WPS", + "embed_link_wps_desc": "En intégrant des fichiers WPS, vous pouvez modifier et afficher des documents, des tableaux et des formulaires WPS dans Vika pour améliorer l'efficacité de la collaboration.", + "embed_link_wps_link_text": "Comment intégrer des fichiers WPS", + "embed_link_wps_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-wps-file", + "embed_link_youtube": "Youtube", + "embed_link_youtube_desc": "En intégrant des vidéos YouTube, vous pouvez regarder des didacticiels et des guides, ou afficher la page d'accueil de la chaîne dans AITable.", + "embed_link_youtube_link_text": "Comment intégrer des vidéos YouTube", + "embed_link_youtube_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-youtube-video", + "embed_page": "Page personnalisée", + "embed_page_add_url": "Ajouter l'URL", + "embed_page_doc_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_page_function_desc": "Ajoutez des pages Web dans ${edition} pour accéder facilement aux documents, vidéos et bien plus encore de sites Web tiers. Vous pouvez ajouter des liens de sites Web recommandés ou des liens personnalisés.", + "embed_page_node_permission_editor": "Sur la base de \"mise à jour uniquement\", peut également ouvrir le partage public du fichier", + "embed_page_node_permission_manager": "Peut effectuer toutes les actions sur le fichier", + "embed_page_node_permission_reader": "Peut afficher le contenu de la page personnalisée et les informations de base sur le fichier", + "embed_page_node_permission_updater": "Sur la base du \"lecture seule\", on peut également modifier le lien de la page personnalisée", + "embed_page_setting_title": "Ajouter une page personnalisée", + "embed_page_url_invalid": "Veuillez entrer l'URL correcte", + "embed_paste_link_bilibili_placeholder": "Collez le lien vidéo bilibili", + "embed_paste_link_default_placeholder": "Collez l'URL", + "embed_paste_link_figma_placeholder": "Collez le lien de partage du fichier Figma", + "embed_paste_link_google_docs_placeholder": "Collez le lien de partage Google Docs", + "embed_paste_link_google_sheets_placeholder": "Collez le lien de partage Google Sheets", + "embed_paste_link_jsdesign_placeholder": "Collez le lien de partage du fichier JSdesign", + "embed_paste_link_tencent_docs_placeholder": "Collez le lien de partage Tencent Docs", + "embed_paste_link_wps_placeholder": "Collez le lien de partage du fichier WPS", + "embed_paste_link_youtube_placeholder": "Collez le lien de la vidéo YouTube", + "embed_success": "Ajouter avec succès", "emoji_activity": "Activité", "emoji_custom": "Personnalisée", "emoji_flags": "Drapeaux", @@ -19492,6 +20136,11 @@ "estonia": "Estonie", "ethiopia": "Éthiopie", "event_planning": "Planification d'événements", + "every": "Chaque", + "every_day_at": "jour(s) à", + "every_hour_at": "heure(s) à", + "every_month_at": "mois(s) sur le", + "every_week_at": "Chaque semaine sur", "everyday_life": "Vie du quotidien", "everyone_visible": "Visible pour tous", "exact_date": "date exacte", @@ -19502,6 +20151,7 @@ "exchange": "Rédemption", "exchange_code_times_tip": "Note: Le code de rachat ne peut être utilisé qu'une seule fois", "exclusive_consultant": "Consultant exclusif V+", + "exclusive_limit_plan_desc": "Niveau limité exclusif", "exist_experience": "Quitter l'expérience", "exits_space": "Sortir de l’espace", "expand": "Agrandir", @@ -19528,7 +20178,7 @@ "expired": "Expiré", "export": "Exportation en cours...", "export_brand_desc": "Propulsé par", - "export_current_preview_view_data": "", + "export_current_preview_view_data": "Export current preview view data", "export_gantt_button_tips": "Exporter vers un fichier .png", "export_gantt_chart": "Exporter le diagramme gantt", "export_to_excel": "Exporter les données", @@ -20100,26 +20750,26 @@ "gantt_config_color_help": "Comment configurer", "gantt_config_friday": "Vendredi", "gantt_config_friday_in_bar": "Ven", - "gantt_config_friday_in_select": "Ven", + "gantt_config_friday_in_select": "Vendredi", "gantt_config_monday": "Lundi", - "gantt_config_monday_in_bar": "Lundi", + "gantt_config_monday_in_bar": "Lun", "gantt_config_monday_in_select": "Lundi", "gantt_config_only_count_workdays": "La durée ne compte que les jours ouvrables.", "gantt_config_saturday": "Samedi", "gantt_config_saturday_in_bar": "Sam", - "gantt_config_saturday_in_select": "Sam", + "gantt_config_saturday_in_select": "Samedi", "gantt_config_sunday": "Dimanche", "gantt_config_sunday_in_bar": "Dim", - "gantt_config_sunday_in_select": "Dim", + "gantt_config_sunday_in_select": "Dimanche", "gantt_config_thursday": "Jeudi", - "gantt_config_thursday_in_bar": "Université Tsinghua", - "gantt_config_thursday_in_select": "Université Tsinghua", + "gantt_config_thursday_in_bar": "Jeu", + "gantt_config_thursday_in_select": "Jeudi", "gantt_config_tuesday": "Mardi", - "gantt_config_tuesday_in_bar": "Mai", - "gantt_config_tuesday_in_select": "Mai", + "gantt_config_tuesday_in_bar": "Mar", + "gantt_config_tuesday_in_select": "Mardi", "gantt_config_wednesday": "Mercredi", "gantt_config_wednesday_in_bar": "Mer", - "gantt_config_wednesday_in_select": "Mer", + "gantt_config_wednesday_in_select": "Mercredi", "gantt_config_weekdays_range": "${weekday} à ${weekday}", "gantt_config_workdays_a_week": "Jours de travail standard personnalisés", "gantt_cycle_connection_warning": "Dépendance de tâche non valide, il y a une connexion de cycle\n", @@ -20200,6 +20850,7 @@ "gold_grade": "Or", "gold_grade_desc": "Pour les équipes avec un processus métier complexe", "gold_seat_200_desc": "200", + "gold_seat_300_desc": "300", "golden_grade": "Or", "got_it": "Compris", "got_v_coins": "V pièces récompensées", @@ -20233,6 +20884,8 @@ "guests_per_space": "Invités par Espace", "guide_1": "啊这", "guide_2": "Il ne faut que quelques minutes pour apprendre les fonctions de base. Travaillez de manière plus productive dès maintenant !", + "guide_flow_modal_contact_sales": "Contacter le service commercial", + "guide_flow_modal_get_started": "Commencer", "guide_flow_of_catalog_step1": "Voici un catalogue fonctionnel où sont stockés tous les dossiers et fichiers de l'espace.", "guide_flow_of_catalog_step2": "Dans le catalogue fonctionnel, vous pouvez créer une feuille de données ou un dossier si nécessaire.", "guide_flow_of_click_add_view_step1": "En plus d'une vue de base, il est fortement recommandé de créer une vue d'album si vous avez des pièces jointes au format image.", @@ -20411,6 +21064,7 @@ "intro_widget_tips": "Qu'est-ce que le widget ?", "introduction": "Présentation", "invalid_action_sort_tip": "En tant que champ de regroupement, le tri a été défini. Le paramétrage de l'ordre actuel ne prendra pas effet.", + "invalid_automation_configuration": "Configuration d'automatisation invalide, veuillez vérifier et réessayer", "invalid_field_type": "Type de champ invalide", "invalid_option_sort_tip": "En tant que champ de regroupement, le tri a été défini. ", "invalid_redemption_code_entered": "Code de rachat invalide", @@ -20541,6 +21195,9 @@ "label_format_day_month_and_year_split_by_slash": "Jour/mois/Année", "label_format_month": "Mois", "label_format_month_and_day_split_by_dash": "Mois du jour", + "label_format_month_day_year_split_by_dash": "Month-Day-Year", + "label_format_month_day_year_split_by_slash": "Month/Day/Year", + "label_format_month_day_year_two_digit_year_split_by_slash": "Month/Day/Year (Two-digit year)", "label_format_year": "Année", "label_format_year_and_month_split_by_dash": "Année-Mois", "label_format_year_month_and_day_split_by_dash": "Année-Moise-Jour", @@ -20619,6 +21276,7 @@ "lark_version_enterprise": "Plan d'entreprise avec Lark", "lark_version_standard": "Plan standard avec Lark", "lark_versions_free": "Plan de base avec Lark", + "last_day": "Dernier jour", "last_modified_by_select_modal_desc": "Si l'un des champs que vous sélectionnez ci-dessous est modifié, le membre qui a modifié le plus récemment sera affiché dans la dernière édition par champ", "last_modified_time_select_modal_desc": "Si l'un des champs que vous sélectionnez ci-dessous est modifié, la date de modification la plus récente s'affichera dans le dernier champ de temps modifié", "last_step": "Précédent", @@ -20763,7 +21421,7 @@ "mail_invite_fail": "Invitation par e-mail réussie.", "mail_invite_success": "Invitation par e-mail réussie.", "main_admin_name": "Nom de l'administrateur", - "main_admin_page_desc": "Les administrateurs ont un accès complet à l'espace, comme l'assignation de sous-administrateurs et le transfert de la propriété de l'espace", + "main_admin_page_desc": "L'administrateur a un accès complet à l'espace, comme la gestion des membres et la gestion des paramètres de l'espace.", "main_contain": "Contenu principal", "malawi": "Malawi", "malaysia": "Malaisie", @@ -20983,8 +21641,12 @@ "more_widget": "Plus de widgets", "morocco": "Le Maroc", "move": "Déplacer", + "move_datasheet_link_warn": "Cannot be moved to Team Area alone, because there is a two-way link from the current datasheet to another datasheet, it is recommended to put them in a folder and then move them", "move_favorite_node_fail": "Le déplacement du nœud a échoué. Le système mettra à jour la liste automatiquement. ", + "move_folder_link_warn": "Cannot be moved to Team Area because the files in the current folder are linked to files outside the folder (may be two-way links or linked by forms, etc.) We recommend that they be placed in a folder before moving", "move_node_modal_content": "Après le déplacement, la visibilité du fichier peut être affectée par le dossier parent.", + "move_other_link_no_permission": "Unable to move to the corresponding folder because you do not have administrative rights to the folder", + "move_other_link_warn": "It is not allowed to move ${node type} to Team Area alone, because it connects to the datasheet of Private Area, it is recommended to put them in a folder before moving them", "move_to": "Déplacer vers", "move_to_error_equal_parent": "Le fichier est sous le dossier actuel. Veuillez sélectionner un autre dossier", "move_to_modal_title": "Déplacez [${name}] vers", @@ -21015,7 +21677,9 @@ "new_a_line": "Maj+Entrée : ligne de rupture", "new_automation": "Nouvelle automatisation", "new_caledonia": "Nouvelle-Calédonie", + "new_custom_page": "New custom page", "new_datasheet": "Nouvelle fiche technique", + "new_ebmed_page": "Nouvelle page personnalisée", "new_folder": "Nouveau dossier", "new_folder_btn_title": "Répertoire", "new_folder_tooltip": "Créer un dossier", @@ -21181,7 +21845,7 @@ "nvc_start_text": "Faites glisser la barre vers la droite", "nvc_yes_text": "Vérifié", "obtain_verification_code": "Code de vérification non obtenu ou expiré", - "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrzw0miJVmSkJ7eBBa9k/fomx5qPX0JGPFvfEEP\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", + "offical_website_footer_nav_data": "[{ \"title\": \"产品\", \"lists\": [{ \"name\": \"快速入门\", \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick- start\" }, { \"name\": \"产品指南\", \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\" }, { \"name\": \"产品价格\", \"url\": \"/pricing/\" }, { \"name\": \"产品路线图\", \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\" }] }, { \"title\": \"关于我们\", \"lists\": [{ \"name\": \"公司介绍\", \"url\": \"/company/\" }, { \"name\": \"加入我们\", \"url \": \"/rejoignez-nous/\" }, { \"name\": \"媒体报道\", \"url\": \"/press/\" }, { \"name\": \"vika维格课堂\", \"url\": \"https ://edu.vika.cn/\" }, { \"name\": \"维格合伙人\", \"url\": \"/partners/\" }] }, { \"title\": \"解决方案\", \"lists\" : [{ \"name\": \"PMO项目群管理\", \"url\": \"/business-pmo/\" }, { \"name\": \"智慧电商运营\", \"url\": \"/ecommerce/\" }, { \"name\": \"CRM客户管理\", \"url\": \"/crm/\" }, { \"name\": \"HR人力资源管理\", \"url\": \"/hr/\" }, { \"name\": \"Scrum\"管理\", \"url\": \"/okr/\" }, { \"name\": \"教育培训管理\", \"url\": \"/education/\" }, { \"name\": \"智慧门店管理\", \"url\" : \"/shop/\" }] }, { \"title\": \"支持\", \"lists\": [{ \"name\": \"意见反馈\", \"url\": \"https://vika.cn/share/shrCvbFC53xc3kl00B4Pg \" }, { \"name\": \"帮助中心\", \"url\": \"https://help.vika.cn/\" }, { \"name\": \"开发者中心\", \"url\": \"/developers/ \" }, { \"name\": \"服务条款\", \"url\": \"/service-agreement/\" }, { \"name\": \"隐私协议\", \"url\": \"/service-agreement/\" }, { \"name\": \"安全与合规\", \"url\": \"/security/\" }] }, { \"title\": \"服务\", \"lists\": [{ \"name\": \"加入社群\", \" url\": \"/chatgroup/\" }, { \"name\": \"Github开源\", \"url\": \"https://github.com/vikadata\" }, { \"name\": \"预约演示\", \"url\" : \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\" }, { \"name\": \"专有云部署\", \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\" } , { \"name\": \"应用连接\", \"url\": \"/connections/\" }] }, { \"title\": \"联系我们\", \"lists\": [{ \"name\": \"地址:深圳市南山区国信投资大厦1710\", \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\" }, { \"name\": \"售前咨询:点击联系商务\", \"url\": \"https: //vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\" }, { \"name\": \"合作:bd@vikadata.com\", \"url\": \"mailto:bd@vikadata.com\" }, { \"name\": \"媒体:pr@vikadata.com\", \"url\": \"mailto:pr@vikadata.com\" }, { \"name\": \"招聘:hr@vikadata.com\", \"url\": \"mailto:hr@vikadata. com\" }] }]", "offical_website_nav_data": "[{\n \"name\": \"产品\",\n \"href\": \"/login\",\n \"children\": [\n {\n \"name\": \"vika维格表 Overview\",\n \"href\": \"/login/\"\n },\n {\n \"name\": \"应用连接 Integration\",\n \"href\": \"/connections/\"\n },\n {\n \"name\": \"客户端(Beta) Download\",\n \"href\": \"/download/\"\n }\n ]\n}, {\n \"name\": \"解决方案\",\n \"href\": \"/\",\n \"children\": [{\n \"name\": \"PMO项目群管理\",\n \"href\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"href\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"href\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"href\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"href\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"href\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"href\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"href\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"href\": \"/shop/\"\n }, {\n \"name\": \"更多解决方案 >\",\n \"href\": \"/solutions/\"\n }]\n}, {\n \"name\": \"模板/案例\",\n \"href\": \"/template\",\n \"children\": [\n {\n \"name\": \"模板中心 Tempaltes\",\n \"href\": \"/template\"\n },\n {\n \"name\": \"客户案例 Customers\",\n \"href\": \"/cases/\"\n }\n ]\n},\n {\n \"name\": \"首页\",\n \"href\": \"/?home=1\"\n },\n {\n \"name\": \"学习资源\",\n \"href\": \"https://edu.vika.cn/index\",\n \"children\": [\n {\n \"name\": \"快速入门 Tutorials\",\n \"href\": \"https://help.vika.cn/docs/guide/tutorial\"\n },\n {\n \"name\": \"产品手册 Manual\",\n \"href\": \"https://help.vika.cn/docs/guide/manual\"\n },\n {\n \"name\": \"维格课堂 Vika Education\",\n \"href\": \"https://edu.vika.cn/\"\n },\n {\n \"name\": \"维格社区 Vika BBS\",\n \"href\": \"https://bbs.vika.cn/\"[{\n \"name\": \"产品\",\n \"href\": \"/login\",\n \"children\": [\n {\n \"name\": \"vika维格表 Overview\",\n \"href\": \"/login/\"\n },\n {\n \"name\": \"应用连接 Integration\",\n \"href\": \"/connections/\"\n },\n {\n \"name\": \"客户端(Beta) Download\",\n \"href\": \"/download/\"\n }\n ]\n}, {\n \"name\": \"解决方案\",\n \"href\": \"/\",\n \"children\": [{\n \"name\": \"PMO项目群管理\",\n \"href\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"href\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"href\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"href\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"href\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"href\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"href\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"href\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"href\": \"/shop/\"\n }, {\n \"name\": \"更多解决方案 >\",\n \"href\": \"/solutions/\"\n }]\n}, {\n \"name\": \"模板/案例\",\n \"href\": \"/template\",\n \"children\": [\n {\n \"name\": \"模板中心 Tempaltes\",\n \"href\": \"/template\"\n },\n {\n \"name\": \"客户案例 Customers\",\n \"href\": \"/cases/\"\n }\n ]\n},\n {\n \"name\": \"首页\",\n \"href\": \"/?home=1\"\n },\n {\n \"name\": \"学习资源\",\n \"href\": \"https://edu.vika.cn/index\",\n \"children\": [\n {\n \"name\": \"快速入门 Tutorials\",\n \"href\": \"https://help.vika.cn/docs/guide/tutorial\"\n },\n {\n \"name\": \"产品手册 Manual\",\n \"href\": \"https://help.vika.cn/docs/guide/manual\"\n },\n {\n \"name\": \"维格课堂 Vika Education\",\n \"href\": \"https://edu.vika.cn/\"\n },\n {\n \"name\": \"维格社区 Vika BBS\",\n \"href\": \"https://bbs.vika.cn/\"\n },\n {\n \"name\": \"第三方连接 Integration\",\n \"href\": \"https://help.vika.cn/docs/guide/connection\"\n },\n {\n \"name\": \"开发者中心 Developer Center\",\n \"href\": \"/developers/\"\n },\n {\n \"name\": \"常见问题 FAQ\",\n \"href\": \"https://help.vika.cn/docs/guide/questions\"\n }\n ]\n }]\n },\n {\n \"name\": \"第三方连接 Integration\",\n \"href\": \"https://help.vika.cn/docs/guide/connection\"\n },\n {\n \"name\": \"开发者中心 Developer Center\",\n \"href\": \"/developers/\"\n },\n {\n \"name\": \"常见问题 FAQ\",\n \"href\": \"https://help.vika.cn/docs/guide/questions\"\n }\n ]\n }]", "office_preview": "Aperçu des fichiers Office", "office_preview_app_desc": "

Aperçu en ligne lisse des fichiers bureautiques sur la feuille de données, vous permettant de visualiser les fichiers bureautiques courants tels que Excel, Word, PPT, etc. sur votre ordinateur de bureau ou mobile n'importe où, à tout moment

\n\n
    \n
  • Aperçu en ligne de . oc, .docx, .xls, .xlsx, .ppt, .pptx, et . df fichiers bureautiques formatés
  • \n
  • Bureau et mobile supportent les aperçus de fichiers des formats ci-dessus
  • \n
\n\n

Notes supplémentaires :

\n
    \n
  • Cette fonctionnalité est alimentée par \"Conversion Cloud Yoncentrique\" et officiellement intégrée
  • \n
  • Cliquez sur le bouton \"Activer\" ci-dessous pour activer cette intégration et accepter que \"Conversion Cloud Yoncentrique\" lit les fichiers bureautiques que vous souhaitez prévisualiser
  • \n
  • Si vous n'avez plus besoin de la fonction de prévisualisation des fichiers bureautiques, l'administrateur de l'espace peut le désactiver sur cette page
  • \n
", @@ -21221,6 +21885,7 @@ "open_auto_save_success": "La vue d'enregistrement automatique est activée avec succès", "open_auto_save_warn_content": "Toutes les modifications sous cette vue sont automatiquement enregistrées et synchronisées avec d'autres membres.", "open_auto_save_warn_title": "Activer la vue de sauvegarde automatique", + "open_automation_time_arrival": "https://aitable.ai/contact-sales-open-source", "open_failed": "Échec de l'ouverture", "open_in_new_tab": "ouvrir dans un nouvel onglet", "open_invite_after_operate": "Une fois activé, tous les membres peuvent inviter de nouveaux membres depuis le panneau des contacts", @@ -21367,6 +22032,8 @@ "payment_record": "Dossier de paiement", "payment_reminder": "Rappel de paiement", "payment_reminder_content": "Le nouveau plan que vous avez sélectionné est plus déductible que le montant à payer. Il est recommandé de choisir le nouveau plan avec une durée plus longue. Si vous le confirmez, le montant excédentaire ne sera pas remboursable. ${action} en cas de doute", + "payment_reminder_modal_content": "Vous pouvez essayer la version avancée pour profiter de plus de nœuds de fichiers, d'autorisations d'entreprise, de capacité de pièces jointes, de volume de données, d'IA et d'autres fonctionnalités et privilèges avancés.", + "payment_reminder_modal_title": "Vous utilisez actuellement la version gratuite", "pending_invite": "Invitation en attente", "people": " membre(s)", "per_person_per_year": "Par personne et par an", @@ -21536,7 +22203,7 @@ "player_step_ui_config_168": "{\n\"templateKey\":\"createMirrorTip\"\n}", "player_step_ui_config_169": "{ \"headerImg\": \"https://s4.vika.cn/space/2023/04/04/bcf0695cf35840e6b85e032a8e5ea0a1\", \"readMoreUrl\": \"https://help.vika.cn/changelog/23-04-10- mises à jour\", \"enfants\": \"

🚀 Introduction de nouvelles fonctions

\\n
  • Un nouveau type de champ \"Cascader\" est lancé, facilitant la sélection parmi une hiérarchie d'options sur les formulaires.
  • Le widget \"Script\" est sorti, moins de code pour plus de personnalisation
  • Déclenchez l'automatisation pour envoyer des e-mails et recevoir des notifications rapides
  • Déclenchez l'automatisation pour envoyer un message à Slack et informer votre équipe à temps
  • Explorer l'IA : lancement du widget \"Générateur de contenu GPT\"
\" }", "player_step_ui_config_17": "{\n \"element\": \"#TEMPLATE_CENTER_USE_TEMPLATE_BTN>button\", \n\"placement\": \"rightBottom\",\n\"offsetY\": 20,\n \"title\": \"Comment utiliser un modèle\", \n\"description\": \"Cliquez sur le bouton à gauche pour utiliser le modèle\", \"children\":\"\" \n}", - "player_step_ui_config_176": "{\"title\":\"Introduction au AI agent\",\"video\":\"https://www.youtube.com/embed/cjds1r_roG8?si=irKUpMhwDlOEb8Hc\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", + "player_step_ui_config_176": "{\"title\": DEMO AITable.ai, \"video\": https://www.youtube.com/embed/kGxMyEEo3OU, \"videoId\": \"VIKA_GUIDE_VIDEO_FOR_AI\", \"autoPlay\": true}", "player_step_ui_config_18": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select>. nt-select-selector\", \n\"placement\": \"bottomLeft\",\n \"title\": \"Comment utiliser un modèle\", \n\"description\": \"Sélectionnez où mettre le modèle\", \"children\":\"\" \n}", "player_step_ui_config_19": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select .ant-select-selector\"\n}", "player_step_ui_config_2": "{\n \"config\": [\n {\n \"key\": 1,\n \"nom\": \"réponse1\",\n \"titre\": \"Quel genre de questions êtes-vous impatient de résoudre par vikadata? ,\n \"type\": \"checkbox\",\n \"réponses\": [\n \"Planification de travail\",\n \"Service client\",\n \"Gestion de projet\",\n \"Sourcing Supply\",\n \"Content Production\",\n \"Opération e-commerce\",\n \"Planification d'événement\",\n \"Ressources humaines\",\n \"Administration\",\n \"Gestion financière\",\n \"Webcast\",\n \"Gestion des instituts éducatifs\",\n \"Autre\"\n ],\n \"lastAllowInput\": vrai\n },\n {\n \"key\": 2,\n \"name\": \"answer2\",\n \"title\": \"Votre titre d'emploi est______\",\n \"type\": \"radio\",\n \"réponses\": [\n \"Directeur Général\",\n \"Chef de projet\",\n \"Gestionnaire de produits\",\n \"Designer\",\n \"Ingénieur R&D \",\n \"Opérateur, éditeur\",\n ventes, service à la clientèle\",\n \"Ressources humaines, administration \",\n \"Finance\", comptable\",\n \"Avocat, affaires juridiques\",\n \"Marketing\",\n \"Professeur\",\n \"Étudiant\",\n \"Autre\"\n ],\n \"lastAllowInput\": vrai\n },\n {\n \"key\": 3,\n \"name\": \"answer3\",\n \"title\": \"Quel est le nom de votre entreprise? ,\n \"type\": \"input\",\n \"submit\": false\n },\n {\n \"key\": 4,\n \"name\": \"answer4\",\n \"titre\": \"Veuillez laisser votre adresse e-mail/ numéro de téléphone/ compte Wechat ci-dessous afin que nous puissions vous joindre à temps lorsque vous avez besoin d'aide. ,\n \"type\": \"input\",\n \"submit\": true\n },\n {\n \"key\": 5,\n \"titre\": \"Merci d'avoir rempli le formulaire, vous pouvez ajouter notre service à la clientèle en cas de besoin\",\n \"platform\": {\n \"website\": \"https://s4.vika.cn/space/2023/03/02/b34e3205a9154463be16f497524f1327\",\n \"dingtalk\": \"https://s4.vika.cn/space/2023/03/02/4b16cef6602a4586a21d6346bf25d300\",\n \"wecom\": \"https://s4.vika.cn/space/2023/03/02/60119b1b69b64aa887bd1be6a2928bec\",\n \"feishu\": \"https://u. ika.cn/z9ygm\"\n },\n \"type\": \"contactUs\",\n \"next\": true\n }\n ]\n}\n", @@ -21566,13 +22233,13 @@ "player_step_ui_config_41": "", "player_step_ui_config_42": "{\n \"element\": \"#DATASHEET_FORM_LIST_PANEL\", \n\"placement\": \"leftTop\",\n \"title\": \"Form\", \n\"description\": \"Vous pouvez rapidement créer un formulaire à partir de la vue actuelle. Le nombre et l'ordre des champs dans le formulaire sont compatibles avec la vue.\", \"children\":\"\" \n}", "player_step_ui_config_43": "{\n \"element\": \".style_navigation__1U5cR . tyle_help__1sXEA\", \n\"placement\": \"rightBais\",\n \"title\": \"Conseil\", \n\"offsetY\":5,\n\"description\": \"Vous pouvez trouver votre assistant Vikaby à partir de l'icône \"Aide\" à gauche\", \"enfants\":\"\" \n}", - "player_step_ui_config_44": "{\n\"title\":\"hiérarchie de Vikadata\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", + "player_step_ui_config_44": "{\n\"title\":\"hiérarchie de Vikadata\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", "player_step_ui_config_45": "", "player_step_ui_config_46": "", "player_step_ui_config_47": "{\n \"element\": \"#DATASHEET_WIDGET_BTN\",\n\"placement\": \"bottomRight\",\n \"title\": \"Widget\", \n\"description\": \"Vous voulez utiliser et visualiser vos données de manière plus riche? Essayez le widget ! , \"children\":\"\" \n}", "player_step_ui_config_48": "", "player_step_ui_config_49": "{\n \"élément\": \". tyle_widgetPanelContainer__1l2ZV\",\n\"placement\": \"centre gauche\",\n \"titre\": \"Qu'est-ce qu'un widget\", \n\"description\": \"Les widgets Vika sont une application étendue de vikadonnées qui se caractérise par une visualisation de données plus riche, le transfert de données, le nettoyage de données, et plus encore. En installant des widgets dans le tableau des widgets, vous pouvez faciliter le travail.\", \"enfants\":\"\" \n}", - "player_step_ui_config_5": "{\n\"title\":\"hiérarchie de Vikadata\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", + "player_step_ui_config_5": "{\n\"title\":\"hiérarchie de Vikadata\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", "player_step_ui_config_50": "{\n \"element\": \".style_widgetModal__eXmdB\",\n\"placement\": \"leftTop\",\n \"title\": \"Widget Center\", \n\"description\": \"Officiellement recommandé et personnalisés widgets sont publiés ici. Vous pouvez installer n'importe quel widget que vous voulez sur un tableau de bord ou dans un widget de n'importe quelle feuille de données.\", \"children\":\"\" \n}", "player_step_ui_config_51": "{\n \"element\": \".style_widgetModal__eXmdB .style_widgetItem__3Pl-1 bouton\",\n\"placement\": \"rightBottom\",\n \"title\": \"Installer le widget\", \n\"description\": \"Installons ce widget \"Graphique\" widget\", \"children\":\"\" \n}", "player_step_ui_config_52": "", @@ -21669,6 +22336,7 @@ "preview_guide_click_to_restart": "Appuyez sur le bouton ci-dessous pour prévisualiser à nouveau", "preview_guide_enable_it": "Appuyez sur le bouton ci-dessous pour activer cette fonction", "preview_guide_open_office_preview": "Pour visualiser ce fichier, veuillez activer la fonction \"Prévisualisation bureautique\"", + "preview_next_automation_execution_time": "Aperçu des 10 prochaines heures d'exécution", "preview_not_support_video_codecs": "Seules les vidéos MP4 avec des codecs H.264 peuvent être prévisualisées", "preview_revision": "Aperçu", "preview_see_more": "Vous voulez en savoir plus sur la fonction \"aperçu des dossiers de bureau\" ? Veuillez cliquer ici", @@ -21704,6 +22372,7 @@ "privacy_protection": "\"Protection de la vie privée\"", "private_cloud": "Nuage privé", "private_external_person_only": " Personne externe uniquement", + "private_help_link": "https://help.aitable.ai/docs/guide/team-and-private-area#private-area", "private_internal_person_only": " Personne interne uniquement", "private_product_point": "Possédez votre plateforme APITable en un seul clic", "privatized_deployment": "Auto-hébergé", @@ -21774,13 +22443,15 @@ "reconciled_data": "Les données sont en cours de rapprochement", "record": "Enregistrements", "record_activity_experience_tips": "Vous pouvez afficher l'activité d'enregistrement de ${day} jours", + "record_archived_data": "enregistrement archivé", + "record_chunk_text": "${text} rows, please wait", "record_comment": "Commentaires uniquement", "record_comments": "commenté", "record_fail_data": "erreur de données", "record_filter_tips": "Cet enregistrement a été filtré", "record_functions": "Fonction d'enregistrement", "record_history": "Historique des révisions uniquement", - "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-history", + "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-activity", "record_history_title": "Historique des enregistrements", "record_pre_filtered": "Cet enregistrement a été filtré et sera masqué une fois que vous aurez cliqué en dehors de l'enregistrement", "record_pre_move": "Cet enregistrement sera déplacé ailleurs une fois que vous cliquerez en dehors de l'enregistrement", @@ -22220,6 +22891,12 @@ "scan_to_login": "Scanner pour se connecter", "scan_to_login_by_method": "Veuillez scanner ${method} pour suivre le compte officiel pour vous connecter", "scatter_chart": "Graphique de dispersion", + "schedule_day_tips": "Le calcul du cycle commence à compter à partir du premier jour de chaque mois. Si on suppose qu'il se répète tous les 10 jours, alors il se déclenchera les 1er, 11, 21 et 31 de chaque mois.", + "schedule_hour_tips": "Le calcul du cycle commence à minuit (0h00) chaque jour. En supposant qu'il se répète 0 minute toutes les trois heures, cela se produira quotidiennement à minuit (0h00), 3h00, 6h00, 9h00, midi (12h00), 15h00, 18h00 et enfin à la tombée de la nuit (21h00).", + "schedule_start_day": "A partir du 1er jour du mois, tous les", + "schedule_start_month": "À partir de janvier de chaque année, chaque", + "schedule_type": "Type d'horaire", + "schedule_year_tips": "Le calcul du cycle commence à compter du premier mois de chaque année. En supposant un intervalle de 3 mois le premier jour, les déclencheurs seront activés à minuit le premier jour de janvier, avril, juillet et octobre de chaque année.", "science_and_technology": "Science et technologie", "scroll_screen_down": "Faire défiler un écran vers le bas", "scroll_screen_left": "Faire défiler un écran vers la gauche", @@ -22233,6 +22910,7 @@ "search_folder_or_sheet": "Rechercher des fichiers", "search_new_admin": "Chercher", "search_node_pleaseholder": "Rechercher des fichiers (${shortcutKey})", + "search_node_tip": "Recherche rapide (${shortcutKey})", "search_or_add": "Trouver ou ajouter une option", "search_role_placeholder": "Rechercher des rôles", "seats": "Sièges", @@ -22636,6 +23314,7 @@ "space_info": "Aperçu", "space_info_del_confirm1": "1. La suppression de cet espace va nettoyer les données suivantes :", "space_info_del_confirm2": "2. L'espace sera supprimé complètement après 7 jours. Vous pouvez restaurer l'espace avant cette date.", + "space_info_del_confirm3": "3. For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "space_info_feishu_desc": "Vous utilisez une intégration de tiers. Pour supprimer l'espace, veuillez d'abord désactiver l'intégration de tiers. ", "space_info_feishu_label": "Intégrations", "space_join_apply": " a demandé à rejoindre l'espace \".", @@ -22722,6 +23401,7 @@ "start_onfiguration": "Lancer la configuration", "start_time": "Heure de début", "start_use": "Commencez à utiliser", + "starting_from_midnight": "À partir de minuit (00h00) tous les jours, tous les", "startup": "Démarrage", "startup_company_support_program": "Programme de support de démarrage", "stat_average": "Moyenne", @@ -22755,6 +23435,8 @@ "stay_tuned_for_more_features": "Restez à l'écoute pour plus de fonctions", "steps_choose_reset_mode": "Sélectionnez une méthode de réinitialisation", "steps_validate_identities": "Vérifier l'identité", + "stop_chunk_content": "Are you sure you want to stop the operation?", + "stop_chunk_title": "Stop", "stop_dingtalk_h5_modal_content": "L'application auto-construite sera dissociée de cet espace. Veuillez confirmer .", "storage_per_seats": "", "storage_per_space": "Utilisation du stockage", @@ -22785,9 +23467,11 @@ "subscribe_credit_usage_over_limit": "Le nombre de crédits dans l'espace actuel dépasse la limite, veuillez mettre à jour votre abonnement.\n", "subscribe_demonstrate": "Demander des démos", "subscribe_disabled_seat": "Le nombre de personnes ne peut pas être inférieur au programme original", + "subscribe_grade_business": "Entreprise", "subscribe_grade_free": "Gratuit", "subscribe_grade_plus": "Plus", "subscribe_grade_pro": "Approuvé", + "subscribe_grade_starter": "Entrée", "subscribe_label_tooltip": "Fonctionnalités de l'espace avancé", "subscribe_new_choose_member": "Prend en charge jusqu'à ${member_num} membres", "subscribe_new_choose_member_tips": "Ce forfait permet à 1 ~ ${member_num} membres d'accéder à l'espace", @@ -22924,7 +23608,7 @@ "template_name_repetition_title": "\"${templateName}\" existe déjà. Voulez-vous le remplacer?", "template_no_template": "Aucun modèle", "template_not_found": "Vous ne trouvez pas de modèles que vous voulez ? Dites-nous", - "template_recommend_title": "Chaud", + "template_recommend_title": "🌟 Hot", "template_type": "Gabarit", "terms_of_service": "< conditions d'utilisation >", "terms_of_service_pure_string": "Conditions d'utilisation", @@ -22968,6 +23652,7 @@ "text_editor_tip_end": "\"Entrée\" jusqu'à la fin de l'édition", "text_functions": "Fonction de chaîne de caractères", "thailand": "Thaïlande", + "the_button_field_is_misconfigured": "Le champ du bouton est mal configuré, veuillez vérifier et réessayer", "the_current_automation_workflow_has_no_related_files_you_can_establish_a_link_by_adding_trigger_conditions_and_actions_on_the_left_side": "Le flux de travail d'automatisation actuel n'a pas de fichiers connexes. Vous pouvez établir un lien en ajoutant des conditions de déclenchement et des actions sur le côté gauche", "the_current_button_column_has_expired_please_reselect": "La colonne de boutons actuelle a expiré, veuillez resélectionner", "the_last_7_days": "les 7 derniers jours", @@ -23070,6 +23755,7 @@ "timemachine_update_comment": "commentaire(s) mis à jour", "times_per_month_unit": "appel(s)/mois", "times_unit": " appel(s)", + "timing_rules": "Horaire", "timor_leste": "Timor oriental", "tip_del_success": "Vous pouvez restaurer votre Espace dans les 7 jours", "tip_do_you_want_to_know_about_field_permission": "Vous voulez chiffrer les données des champs ? En savoir plus sur les autorisations des champs", @@ -23257,6 +23943,7 @@ "verify_account_title": "Vérifier le compte", "verify_via_email": "Vérification d'identité par e-mail", "verify_via_phone": "Vérification d'identité par SMS", + "video": "Vidéo", "video_not_support_play": "Le format vidéo actuel ne prend pas en charge la lecture en ligne", "vietnam": "Viêt Nam", "view": "Voir", @@ -23605,7 +24292,8 @@ "workdoc_color_title": "Couleur de la police", "workdoc_create": "Créer un document de travail", "workdoc_expanded": "Développer la table des matières", - "workdoc_image_max_10mb": "La taille de l'image ne peut pas dépasser 10 Mo", + "workdoc_image_max_10mb": "nul", + "workdoc_image_max_size": "La taille de l'image ne peut pas dépasser ${size}", "workdoc_info": "Informations", "workdoc_info_create_time": "Créé à", "workdoc_info_creator": "Créé par", @@ -23613,6 +24301,7 @@ "workdoc_info_last_modify_time": "Dernière modification à", "workdoc_link_placeholder": "Veuillez entrer le lien", "workdoc_only_image": "Seule l'image est autorisée", + "workdoc_only_video": "Seule la vidéo est autorisée", "workdoc_text_placeholder": "Entrez \"/\" démarrage rapide", "workdoc_title_placeholder": "Veuillez entrer le titre", "workdoc_unnamed": "Document de travail sans nom", @@ -23621,9 +24310,11 @@ "workdoc_unsave_ok": "Annuler les modifications", "workdoc_unsave_title": "Le WorkDoc n'a pas été enregistré", "workdoc_upload_failed": "Échec du téléchargement", + "workdoc_video_max_size": "La taille de la vidéo ne peut pas dépasser ${size}", "workdoc_ws_connected": "Connecté", "workdoc_ws_connecting": "De liaison...", "workdoc_ws_disconnected": "Débranché", + "workdoc_ws_reconnecting": "Reconnexion...", "workflow_execute_failed_notify": " n'a pas pu s'exécuter à . Veuillez consulter l'historique d'exécution pour résoudre le problème. Si vous avez besoin d'aide, veuillez contacter notre équipe de service client.", "workspace_data": "Données de l'espace", "workspace_files": "Données de l'établi", @@ -23802,6 +24493,15 @@ "agreed": "Approvato", "ai_advanced_mode_desc": "La modalità avanzata consente agli utenti di personalizzare i messaggi di richiesta, fornendo un maggiore controllo sul comportamento e le risposte dell'agente AI.", "ai_advanced_mode_title": "Modalità avanzata", + "ai_agent_anonymous": "Anonimo${ID}", + "ai_agent_conversation_continue_not_supported": "La continuazione di una conversazione precedente non è attualmente supportata", + "ai_agent_conversation_list": "Elenco conversazioni", + "ai_agent_conversation_log": "Registro delle conversazioni", + "ai_agent_conversation_title": "Titolo della conversazione", + "ai_agent_feedback": "Feedback", + "ai_agent_historical_message": "Quanto sopra è un messaggio storico", + "ai_agent_history": "Storia", + "ai_agent_message_consumed": "Messaggio consumato", "ai_api_curl_template": "## Create chat completions\n\n```bash\n\ncurl -X POST \"{{apiBase}}/fusion/v1/ai/{{aiId}}/chat/completions\" \\n -H \"Content-Type: application/json\" \\n -H \"Authorization: Bearer {{token}}\" \\n -d '{\n \"model\": \"gpt-3.5-turbo\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"You are a helpful assistant.\"\n },\n {\n \"role\": \"user\",\n \"content\": \"Hello!\"\n }\n ]\n }'\n\n```\n\n## Returned data example\n\n```json\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", "ai_api_footer_desc": "Incorpora l'agente AI nel tuo sito web? Per saperne di più", "ai_api_javascript_template": "## Initialize SDK [![github]({{ githubIcon }})](https://github.com/openai/openai-node)\nAITable's chat completion API is compatible with OpenAI's Node.js SDK. You can use our service with the same SDK by simply changing the configuration as follows:\n\n\n```javascript\nconst { Configuration, OpenAIApi } = require(\"openai\");\nconst configuration = new Configuration({\n apiKey: \"{{token}}\",\n basePath: \"{{apiBase}}/fusion/v1/ai/{{aiId}}\"\n});\n```\n\n## Create chat completions\n\n```javascript\nconst openai = new OpenAIApi(configuration);\nconst chatCompletion = await openai.createChatCompletion({\n model: \"gpt-3.5-turbo\",\n messages: [{role: \"user\", content: \"Hello world\"}],\n});\n```\n\n## Returned data example\n\n```javascript\n\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", @@ -23817,6 +24517,9 @@ "ai_chat_unit": "Aibot (i)", "ai_close_setting_tip_content": "Avete fatto dei cambiamenti. Vuoi buttarli via?", "ai_close_setting_tip_title": "Suggerimenti", + "ai_copilot_generate_response": "Generazione della risposta per te...", + "ai_copilot_processs": "Elaborazione in corso, attendi...", + "ai_copilot_start_process_request": "Inizio elaborazione della tua richiesta...", "ai_create_guide_btn_text": "Seleziona foglio dati", "ai_create_guide_content": "Come agente dell'AI, posso rispondere alle vostre domande in base alle conoscenze che ho imparato. Prima di iniziare la conversazione, si prega di selezionare una scheda tecnica come base di conoscenza, e leggerò tutti i dati in esso per l'apprendimento.", "ai_credit_cost_chart_title": "Costo del credito", @@ -23829,7 +24532,7 @@ "ai_credit_time_dimension_year": "Quest'anno", "ai_credit_usage_tooltip": "I crediti di messaggio possono essere utilizzati per le domande di agente AI. I crediti del messaggio sono proporzionali al numero di posti sul vostro spazio.", "ai_data_source_required": "nullo", - "ai_data_source_rows": "${righe} righe di dati", + "ai_data_source_rows": "${rows} righe di dati", "ai_data_source_update": "Aggiornamento disponibile", "ai_datasheet_panel_create_btn_text": "Crea AI Agent", "ai_default_idk": "Non so", @@ -24285,7 +24988,7 @@ "apps_support": "Supporto clienti su tutte le piattaforme", "archive_delete_record": "Elimina i record archiviati", "archive_delete_record_title": "Elimina registrazione", - "archive_notice": "

Stai tentando di archiviare record specifici. L'archiviazione dei record comporterà le seguenti modifiche:

1. Tutti i collegamenti bidirezionali per questo record verranno annullati

2. La modifica non è supportata

3. Funzioni come promemoria della data e record di abbonamento non sono supportate

4. Non partecipare più al calcolo di ricerca, formula e altri campi

Sei sicuro di voler continuare? (Puoi annullare l'archiviazione nella casella Archivio in Avanzato)

", + "archive_notice": "

Stai tentando di archiviare record specifici. L'archiviazione dei record comporterà le seguenti modifiche:

1. La modifica non è supportata

2. Funzioni come promemoria della data e record di abbonamento non sono supportate

3. Non partecipare più al calcolo di ricerca, formula e altri campi

Sei sicuro di voler continuare? (Puoi annullare l'archiviazione nella casella Archivio in Avanzato)

", "archive_record_in_activity": "Archiviato questo disco", "archive_record_in_menu": "Archivio record", "archive_record_success": "Archiviati con successo", @@ -24345,6 +25048,8 @@ "audit_add_field_role_detail": "Nel \" \" scheda dati , aggiungere [ ] ruolo di [ ] per il campo [ ]", "audit_add_node_role": "Aggiungi autorizzazioni file", "audit_add_node_role_detail": "Aggiungi permesso file,imposta「${unitNames}」a「${role}」di 「${currentNodeName}」", + "audit_add_node_role_detail_end": "to「${role}", + "audit_add_node_role_detail_start": "Add file node permission,set「${unitNames}」", "audit_admin_permission_change_event": "Cambia autorizzazioni di amministratore", "audit_create_template": "Crea modello", "audit_create_template_detail": "Crea modello", @@ -24353,20 +25058,30 @@ "audit_delete_field_role_detail": "Verifica", "audit_delete_node_role": "Elimina autorizzazione file", "audit_delete_node_role_detail": "Elimina permesso file,cancella「${unitNames}」`s 「${role}」ruolo di 「${currentNodeName}」", + "audit_delete_node_role_detail_end": "at 「${role}」role", + "audit_delete_node_role_detail_start": "Delete file node permission,delete「${unitNames}」from", "audit_delete_template": "Elimina modello", "audit_delete_template_detail": "Elimina modello", "audit_disable_field_role": "Disabilita le autorizzazioni dei campi", "audit_disable_field_role_detail": "Verifica", "audit_disable_node_role": "Disabilita le autorizzazioni dei file", "audit_disable_node_role_detail": "Disabilita l'autorizzazione `${nodeType} 「${currentNodeName}」", + "audit_disable_node_role_detail_end": "`s permission", + "audit_disable_node_role_detail_start": "Disable ${nodeType}", "audit_disable_node_share": "Chiudi il collegamento pubblico del file", "audit_disable_node_share_detail": "Chiudi il collegamento pubblico ${nodeType} 「${currentNodeName}」", + "audit_disable_node_share_detail_end": "public link", + "audit_disable_node_share_detail_start": "Close ${nodeType}", "audit_enable_field_role": "Abilita le autorizzazioni dei campi", "audit_enable_field_role_detail": "Verifica", "audit_enable_node_role": "Abilita le autorizzazioni dei file", "audit_enable_node_role_detail": "Abilita l'autorizzazione `${nodeType} 「${currentNodeName}」", + "audit_enable_node_role_detail_end": "`s permission", + "audit_enable_node_role_detail_start": "Enable ${nodeType}", "audit_enable_node_share": "Apri il collegamento pubblico del file", "audit_enable_node_share_detail": "Apri il collegamento pubblico ${nodeType} 「${currentNodeName}」", + "audit_enable_node_share_detail_end": "public link", + "audit_enable_node_share_detail_start": "Open ${nodeType}", "audit_login_event": "Evento di accesso", "audit_logout_event": "inglese", "audit_organization_change_event": "La struttura organizzativa dei contatti è cambiata", @@ -24387,18 +25102,25 @@ "audit_space_invite_user_detail": "Verifica", "audit_space_node_copy": "Duplica file", "audit_space_node_copy_detail": "Duplica ${nodeType} 「${sourceNodeName}」, il nuovo nome del file è 「${currentNodeName}」", + "audit_space_node_copy_detail_start": "Duplicate ${nodeType} 「${sourceNodeName}」, the new file node's name is", "audit_space_node_create": "Crea file", "audit_space_node_create_detail": "Crea un ${nodeType} chiamato 「${currentNodeName}」", + "audit_space_node_create_detail_start": "Create a ${nodeType} named", "audit_space_node_delete": "Elimina file", "audit_space_node_delete_detail": "Elimina ${nodeType} chiamato 「${currentNodeName}」", + "audit_space_node_delete_detail_start": "Delete ${nodeType} named", "audit_space_node_export": "Esporta foglio dati", "audit_space_node_export_detail": "Membro ${member_name} foglio dati esportato ${node_name}", "audit_space_node_import": "Importa file", "audit_space_node_import_detail": "Importa un file chiamato 「${nodeName}」", + "audit_space_node_import_detail_start": "Import a file node named", "audit_space_node_move": "Sposta file", "audit_space_node_move_detail": "Sposta ${nodeType} 「${currentNodeName}」 nella cartella「${parentName}」", + "audit_space_node_move_detail_end": "to the folder「${parentName}」", + "audit_space_node_move_detail_start": "Move ${nodeType}", "audit_space_node_rename": "Rinomina file", "audit_space_node_rename_detail": "Rinomina ${nodeType} 「${oldNodeName}」in 「${nodeName}」", + "audit_space_node_rename_detail_start": "Rename ${nodeType} 「${oldNodeName}」to", "audit_space_node_sort": "Verifica", "audit_space_node_sort_detail": "Verifica", "audit_space_node_update_cover": "Verifica", @@ -24413,17 +25135,24 @@ "audit_space_rubbish_node_delete_detail": "Verifica", "audit_space_rubbish_node_recover": "Ripristina file", "audit_space_rubbish_node_recover_detail": "Ripristina ${nodeType} 「${currentNodeName}」 dal cestino", + "audit_space_rubbish_node_recover_detail_end": "from the trash", + "audit_space_rubbish_node_recover_detail_start": "Restore ${nodeType}", "audit_space_template_event": "Modifica modello", "audit_space_update_logo": "Verifica", "audit_space_update_logo_detail": "Verifica", "audit_store_share_node": "Salva file condiviso", "audit_store_share_node_detail": "Ripristina ${nodeType} nello spazio, il nome è 「${nodeName}」", + "audit_store_share_node_detail_start": "Restore ${nodeType} to the space, name is", "audit_update_field_role": "Verifica", "audit_update_field_role_detail": "Verifica", "audit_update_node_role": "Modifica autorizzazione file", "audit_update_node_role_detail": "Modifica l'autorizzazione file , modifica il ruolo di「${unitNames}」 in「${role}」di 「${currentNodeName}」", + "audit_update_node_role_detail_end": "to「${role}」role", + "audit_update_node_role_detail_start": "Modify file node permission,modify「${unitNames}」from", "audit_update_node_share_setting": "Modifica le impostazioni del collegamento pubblico del file", "audit_update_node_share_setting_detail": "Modifica il collegamento pubblico ${nodeType} 「${currentNodeName}」", + "audit_update_node_share_setting_detail_end": "public link settings", + "audit_update_node_share_setting_detail_start": "Modify ${nodeType}", "audit_user_login": "Accesso utente", "audit_user_login_detail": "Verifica", "audit_user_logout": "Accesso utente", @@ -24465,6 +25194,7 @@ "automation_enabled_return_via_related_files": "L'automazione è abilitata. Inserisci nuovamente la tabella originale tramite \"File correlati\" per utilizzare il nuovo pulsante.", "automation_field": "Campo", "automation_import_variables_from_pre_tep": "Ottieni i dati dal passaggio preliminare", + "automation_is_not_yet_enabled": "L'automazione non è ancora abilitata, abilitala e riprova", "automation_last_edited_by": "Ultima modifica di", "automation_last_edited_time": "Ora dell'ultima modifica", "automation_manager_label": "Può eseguire tutte le azioni sull'automazione", @@ -24490,6 +25220,7 @@ "automation_runs_this_month": "Esce questo mese", "automation_stay_tuned": "Rimani sintonizzato", "automation_success": "Successo", + "automation_tips": "Il campo del pulsante non è configurato correttamente, controlla e riprova", "automation_updater_label": "Può visualizzare la cronologia di esecuzione dell'automazione", "automation_variabel_empty": "Non ci sono dati che possano essere utilizzati nel passaggio preliminare, modificali e riprova.", "automation_variable_datasheet": "Ottieni dati da ${NODE_NAME}", @@ -24525,6 +25256,7 @@ "bermuda": "Bermude", "bhutan": "Bhutan", "billing_over_limit_tip_common": "L'utilizzo dello spazio ha superato il limite e potrai usufruire di un importo maggiore dopo l'aggiornamento.", + "billing_over_limit_tip_forbidden": "La durata della prova o il periodo di abbonamento sono scaduti. Si prega di contattare il consulente di vendita per rinnovare.", "billing_over_limit_tip_widget": "Il numero di installazioni di widget ha superato il limite ed è possibile eseguire l'aggiornamento per ottenere un utilizzo maggiore.", "billing_period": "Periodo di fatturazione: ${period}", "billing_subscription_warning": "Esperienza caratteristica", @@ -24584,10 +25316,19 @@ "button_text": "Testo del pulsante", "button_text_click_start": "Fare clic per iniziare", "button_type": "Tipo di pulsante", + "by_at": "A", + "by_days": "Giorni", + "by_every": "ogni", "by_field_id": "Usa ID campo", + "by_hours": "Ore", + "by_in": "A", + "by_min": "minuti)", + "by_months": "Mesi", + "by_on": "sul", "by_the_day": "Di giorno", "by_the_month": "Mensile", "by_the_year": "Annuale", + "by_weeks": "Settimane", "calendar_add_date_time_field": "Crea campo data", "calendar_color_more": "Altri colori", "calendar_const_detail_weeks": "[\"lunedì\",\"martedì\",\"mercoledì\",\"giovedì\",\"venerdì\",\"sabato\",\"domenica\"]", @@ -24651,6 +25392,14 @@ "cannot_activate_space_by_space_limit": "cannot_active_space_by_space_limit", "cannot_join_space": "Non puoi unirti a una nuova stazione spaziale perché hai superato la quota massima di 10 stazioni spaziali.", "cannot_switch_field_permission": "Impostare le autorizzazioni dei campi non superiori alle autorizzazioni dei file.", + "capacity_file_detail_desc": "The total number of file nodes within the Space is calculated by adding the file nodes from the Team to the file nodes created by each member in their Private. Not enough capacity?", + "capacity_file_detail_title": "File Capacity", + "capacity_file_member": "Member", + "capacity_file_member_private_node_count": "Private", + "capacity_file_member_private_percent": "Percent", + "capacity_file_member_team": "Team", + "capacity_file_member_team_node_count": "Team", + "capacity_file_upgrade": "Click to upgrade your Space", "capacity_from_official_gift": "Dal regalo ufficiale", "capacity_from_participation": "Su invito ${user} unisciti allo spazio", "capacity_from_purchase": "Per capacità d'acquisto", @@ -24687,6 +25436,8 @@ "catalog": "Esploratore", "catalog_add_from_template_btn_title": "Aggiungi dai modelli", "catalog_empty_tips": "Questo spazio di lavoro è vuoto ora. Inizia utilizzando modelli per creare file.", + "catalog_private": "Private", + "catalog_team": "Team", "category_blank": "[Vuoto]", "catering": "Ristorazione", "cayman_islands": "Isole Cayman", @@ -24755,6 +25506,7 @@ "choose_type_of_vika_field": "Seleziona tipo di campo", "choose_your_own_space": "(Supporta solo il salvataggio al proprio spazio come creatore)", "chose_new_primary_admin_button": "Assegna", + "chunk_stopping_title": "Stopping", "claim_special_offer": "Richiedi questa offerta speciale!", "clear": "Cancella", "clear_all_fields": "Cancella tutto", @@ -24885,6 +25637,7 @@ "confirm_del_current_team": "Sei sicuro di voler eliminare il team?", "confirm_delete": "Conferma ed elimina", "confirm_delete_node_name_as": "Sei sicuro di voler eliminare \"${nodeNameDiv}\"?", + "confirm_delete_private_node_name_as": "Are you sure you want to delete \"${nodeNameDiv}\"? The file will be deleted from the Space and the trash.", "confirm_delete_space_btn": "Conferma ed elimina spazio", "confirm_exit": "Conferma di uscire", "confirm_exit_space_with_name": "Conferma se uscire dallo spazio \"${spaceNameDiv}\".", @@ -24922,6 +25675,14 @@ "convert": "Converti", "convert_tip": "Questa azione può cancellare i dati in alcune celle. È possibile annullare l'azione se accade qualcosa di inaspettato.", "cook_islands": "Isole Cook", + "copilot_auto_agent_desc": "Non sai quale scegliere Agente? Prova l'agente automatico.", + "copilot_auto_agent_name": "Agente automatico", + "copilot_data_agent_desc": "Genera analisi dati/visualizzazioni basate sulle tue visualizzazioni.", + "copilot_data_agent_name": "Agente dati", + "copilot_data_agent_policy": "Quando chatti con Copilot, accetti la politica sui termini dell'utente", + "copilot_data_agent_policy_button": "Politica", + "copilot_help_agent_desc": "Chiedi qualsiasi cosa riguardo ai documenti del centro assistenza di AITable.", + "copilot_help_agent_name": "Recupera Centro assistenza", "copy": "Copia", "copy_automation_url": "Copia URL", "copy_card_link": "Copia URL del record", @@ -24966,6 +25727,7 @@ "create_mirror_guide_content": "La funzione mirror ha la capacità di nascondere determinati dati. È possibile impostare \"condizioni di filtro\" e \"campi nascosti\" nella visualizzazione del foglio dati originale per controllare quali record e campi vengono visualizzati nel mirror.\n
\n
\nSe utilizzato insieme alla funzione \"Visualizza blocco\", può impedire ad altri di apportare modifiche.\n
\n
\nInoltre, puoi andare su \"Tabella originale>Campi nascosti\" per modificare la configurazione per \"Mostra tutti i campi nei mirror\".", "create_mirror_guide_title": "Specchio nasconde alcuni record e campi", "create_new_button_field": "Crea un nuovo campo colonna pulsante", + "create_private_node_tip": "Personal or temporary draft documents can be created here ${link}", "create_public_invitation_link": "Crea link di invito pubblico", "create_space_sub_title": "Ciao, si prega di dare un nome al vostro spazio~", "create_team_fail": "Crea team fallito", @@ -25029,10 +25791,12 @@ "custom_enterprise": "Personalizza lo spazio aziendale per te", "custom_function_development": "Sviluppo di funzionalità personalizzate", "custom_grade_desc": "Fornisce distribuzione di agenti, installazione privata, supporto di assistenza e servizi professionali personalizzati", + "custom_page_setting_title": "Add a custom page", "custom_picture": "Immagine personalizzata", "custom_style": "Stile", "custom_upload": "Caricamento personalizzato", "custom_upload_tip": "Un'immagine di dimensione quadrata 1:1 è consigliata per una migliore esperienza visiva", + "custome_page_title": "Custom Web", "cut_cell_data": "Celle tagliate", "cyprus": "Cipro", "czech": "Ceco", @@ -25084,6 +25848,7 @@ "default": "Predefinito", "default_create_ai_chat_bot": "Nuovo agente AI", "default_create_automation": "Nuova automazione", + "default_create_custom_page": "Nuova pagina personalizzata", "default_create_dashboard": "Nuovo cruscotto", "default_create_datasheet": "Nuovo foglio dati", "default_create_file": "Nuovo file", @@ -25105,6 +25870,7 @@ "del_invitation_link": "Elimina link di invito", "del_invitation_link_desc": "Il link non sarà valido dopo la cancellazione", "del_space_now": "Elimina spazio per sempre", + "del_space_now_confirm_tip": "For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "del_space_now_tip": "Lo spazio non può essere ripristinato dopo la cancellazione. Tutti i file e gli allegati verranno eliminati.", "del_space_res_tip": "Lo spazio eliminato", "del_team_success": "Elimina team di successo", @@ -25300,6 +26066,62 @@ "embed_error_page_help": "Per saperne di più", "embed_fail_og_description_content": "Il link pubblico per questa incorporazione è stato disabilitato ed è temporaneamente non disponibile", "embed_failed": "Il collegamento incorporato non è disponibile,", + "embed_link_bilibili": "bilibili", + "embed_link_bilibili_desc": "Incorporando i video bilibili, puoi guardare tutorial e guide o visualizzare la home page del canale in Vika.", + "embed_link_bilibili_link_text": "Come incorporare il video bilibili", + "embed_link_bilibili_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-bilibili-video", + "embed_link_default": "Nulla", + "embed_link_default_desc": "Incolla un collegamento per visualizzare qualsiasi sito web.", + "embed_link_default_link_text": "Saperne di più", + "embed_link_default_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_link_figma": "Figma", + "embed_link_figma_desc": "Incorporando i file Figma, i membri possono visualizzare e modificare le bozze di progettazione in modo più conveniente, migliorando l'efficienza della collaborazione.", + "embed_link_figma_link_text": "Come incorporare file Figma", + "embed_link_figma_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-figma-file", + "embed_link_google_docs": "Docs", + "embed_link_google_docs_desc": "Incorporando Google Docs, puoi modificare e visualizzare i documenti in AITable per facilitare la collaborazione del team.", + "embed_link_google_docs_link_text": "Come incorporare Google Documenti", + "embed_link_google_docs_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-docs-file", + "embed_link_google_sheets": "Sheets", + "embed_link_google_sheets_desc": "Incorporando Fogli Google, puoi modificare e visualizzare le tabelle in AITable per facilitare la collaborazione del team.", + "embed_link_google_sheets_link_text": "Come incorporare Fogli Google", + "embed_link_google_sheets_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-sheets-file", + "embed_link_jishi_design": "JSdesign", + "embed_link_jishi_design_desc": "Incorporando file JSdesign, i membri possono visualizzare e modificare le bozze di progettazione in modo più pratico, migliorando l'efficienza della collaborazione.", + "embed_link_jishi_design_link_text": "Come incorporare file JSdesign", + "embed_link_jishi_design_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-js-design-file", + "embed_link_tencent_docs": "Documenti Tencent", + "embed_link_tencent_docs_desc": "Incorporando Tencent Docs, puoi modificare e visualizzare i documenti Tencent in Vika per migliorare l'efficienza della collaborazione.", + "embed_link_tencent_docs_link_text": "Come incorporare Tencent Docs", + "embed_link_tencent_docs_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-tencent-docs", + "embed_link_wps": "WPS", + "embed_link_wps_desc": "Incorporando file WPS, puoi modificare e visualizzare documenti, tabelle e moduli WPS in Vika per migliorare l'efficienza della collaborazione.", + "embed_link_wps_link_text": "Come incorporare file WPS", + "embed_link_wps_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-wps-file", + "embed_link_youtube": "Youtube", + "embed_link_youtube_desc": "Incorporando video di YouTube, puoi guardare tutorial e guide o visualizzare la home page del canale in AITable.", + "embed_link_youtube_link_text": "Come incorporare video di YouTube", + "embed_link_youtube_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-youtube-video", + "embed_page": "Pagina personalizzata", + "embed_page_add_url": "Aggiungi URL", + "embed_page_doc_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_page_function_desc": "Aggiungi pagine web in ${edition} per accedere facilmente a documenti, video e altro ancora di siti web di terze parti. È possibile aggiungere collegamenti a siti Web consigliati o collegamenti personalizzati.", + "embed_page_node_permission_editor": "Sulla base del \"solo aggiornamento\", è possibile anche aprire la condivisione pubblica del file", + "embed_page_node_permission_manager": "Può eseguire tutte le azioni sul file", + "embed_page_node_permission_reader": "Può visualizzare il contenuto della pagina personalizzata e le informazioni di base sul file", + "embed_page_node_permission_updater": "Sulla base della \"sola lettura\", è possibile anche modificare il collegamento della pagina personalizzata", + "embed_page_setting_title": "Aggiungi una pagina personalizzata", + "embed_page_url_invalid": "Inserisci l'URL corretto", + "embed_paste_link_bilibili_placeholder": "Incolla il collegamento del video bilibili", + "embed_paste_link_default_placeholder": "Incolla l'URL", + "embed_paste_link_figma_placeholder": "Incolla il collegamento di condivisione del file Figma", + "embed_paste_link_google_docs_placeholder": "Incolla il link di condivisione di Google Documenti", + "embed_paste_link_google_sheets_placeholder": "Incolla il link di condivisione di Fogli Google", + "embed_paste_link_jsdesign_placeholder": "Incolla il collegamento di condivisione del file JSdesign", + "embed_paste_link_tencent_docs_placeholder": "Incolla il collegamento di condivisione di Tencent Docs", + "embed_paste_link_wps_placeholder": "Incolla il collegamento di condivisione del file WPS", + "embed_paste_link_youtube_placeholder": "Incolla il collegamento del video di YouTube", + "embed_success": "Aggiungi con successo", "emoji_activity": "Attività", "emoji_custom": "Personalizzato", "emoji_flags": "Bandiere", @@ -25406,6 +26228,11 @@ "estonia": "Estonia", "ethiopia": "Etiopia", "event_planning": "Pianificazione eventi", + "every": "Ogni", + "every_day_at": "giorno(i) a", + "every_hour_at": "ora/e alle", + "every_month_at": "mese(i) del", + "every_week_at": "Ogni settimana in poi", "everyday_life": "Vita quotidiana", "everyone_visible": "Visibile per tutti", "exact_date": "data esatta", @@ -25416,6 +26243,7 @@ "exchange": "Riscatta", "exchange_code_times_tip": "Nota: Il codice di riscatto può essere utilizzato una sola volta", "exclusive_consultant": "Consulente V+ esclusivo", + "exclusive_limit_plan_desc": "Livello limitato esclusivo", "exist_experience": "Esperienza di uscita", "exits_space": "Esci dallo spazio", "expand": "Espandi", @@ -25442,7 +26270,7 @@ "expired": "Scaduto", "export": "Esportazione...", "export_brand_desc": "Offerto da", - "export_current_preview_view_data": "", + "export_current_preview_view_data": "Export current preview view data", "export_gantt_button_tips": "Esporta in un file .png", "export_gantt_chart": "Esporta il grafico gantt", "export_to_excel": "Esporta dati", @@ -26014,26 +26842,26 @@ "gantt_config_color_help": "Come impostare", "gantt_config_friday": "Venerdì", "gantt_config_friday_in_bar": "Ven", - "gantt_config_friday_in_select": "Ven", + "gantt_config_friday_in_select": "Venerdì", "gantt_config_monday": "Lunedì", "gantt_config_monday_in_bar": "Lun", - "gantt_config_monday_in_select": "Lun", + "gantt_config_monday_in_select": "Lunedi", "gantt_config_only_count_workdays": "La durata conta solo i giorni lavorativi.", "gantt_config_saturday": "Sabato", "gantt_config_saturday_in_bar": "Sab", - "gantt_config_saturday_in_select": "Sab", + "gantt_config_saturday_in_select": "Sabato", "gantt_config_sunday": "Domenica", - "gantt_config_sunday_in_bar": "Sole", - "gantt_config_sunday_in_select": "Sole", + "gantt_config_sunday_in_bar": "Dom", + "gantt_config_sunday_in_select": "Domenica", "gantt_config_thursday": "Giovedì", "gantt_config_thursday_in_bar": "Gio", - "gantt_config_thursday_in_select": "Gio", + "gantt_config_thursday_in_select": "Giovedì", "gantt_config_tuesday": "Martedì", "gantt_config_tuesday_in_bar": "Mar", - "gantt_config_tuesday_in_select": "Mar", + "gantt_config_tuesday_in_select": "Martedì", "gantt_config_wednesday": "Mercoledì", "gantt_config_wednesday_in_bar": "Mer", - "gantt_config_wednesday_in_select": "Mer", + "gantt_config_wednesday_in_select": "Mercoledì", "gantt_config_weekdays_range": "${weekday} a ${weekday}", "gantt_config_workdays_a_week": "Giorni lavorativi standard personalizzati", "gantt_cycle_connection_warning": "Invalid task dependency, there is a cycle connection\n", @@ -26114,6 +26942,7 @@ "gold_grade": "Oro", "gold_grade_desc": "Per team con processi aziendali complessi", "gold_seat_200_desc": "200", + "gold_seat_300_desc": "300", "golden_grade": "Oro", "got_it": "Ho capito", "got_v_coins": "V monete premiate", @@ -26147,6 +26976,8 @@ "guests_per_space": "Ospiti per spazio", "guide_1": "啊这", "guide_2": "Ci vogliono solo pochi minuti per imparare le funzioni di base. Lavora in modo più produttivo da questo momento in poi!", + "guide_flow_modal_contact_sales": "Contatta l'ufficio vendite", + "guide_flow_modal_get_started": "Iniziare", "guide_flow_of_catalog_step1": "Qui è il catalogo di lavoro in cui tutte le cartelle e i file dello spazio sono memorizzati.", "guide_flow_of_catalog_step2": "Nel catalogo di lavoro è possibile creare un foglio dati o una cartella a seconda delle necessità.", "guide_flow_of_click_add_view_step1": "Oltre ad alcune viste di base, si consiglia vivamente di creare una vista album se si dispone di allegati in formato immagine.", @@ -26325,6 +27156,7 @@ "intro_widget_tips": "Cos'è widget?", "introduction": "Introduzione", "invalid_action_sort_tip": "Come campo di raggruppamento, l'ordinamento di esso è stato impostato. L'impostazione dell'ordine corrente non avrà effetto.", + "invalid_automation_configuration": "Configurazione dell'automazione non valida, controlla e riprova", "invalid_field_type": "Tipo di campo non valido", "invalid_option_sort_tip": "Come campo di raggruppamento, l'ordinamento di esso è stato impostato.", "invalid_redemption_code_entered": "Codice di riscatto non valido", @@ -26455,6 +27287,9 @@ "label_format_day_month_and_year_split_by_slash": "Giorno/Mese/Anno", "label_format_month": "Mese", "label_format_month_and_day_split_by_dash": "Mese-Giorno", + "label_format_month_day_year_split_by_dash": "Month-Day-Year", + "label_format_month_day_year_split_by_slash": "Month/Day/Year", + "label_format_month_day_year_two_digit_year_split_by_slash": "Month/Day/Year (Two-digit year)", "label_format_year": "Anno", "label_format_year_and_month_split_by_dash": "Anno-Mese", "label_format_year_month_and_day_split_by_dash": "Anno-Mese-Giorno", @@ -26533,6 +27368,7 @@ "lark_version_enterprise": "Piano d'impresa con Lark", "lark_version_standard": "Piano standard con Lark", "lark_versions_free": "Piano di base con Lark", + "last_day": "Ultimo giorno", "last_modified_by_select_modal_desc": "Se uno dei campi selezionati di seguito viene modificato, il membro che ha modificato di recente verrà visualizzato nell'ultimo campo modificato", "last_modified_time_select_modal_desc": "Se uno dei campi selezionati di seguito viene modificato, l'ora modificata più recente verrà visualizzata nel campo dell'ultima modifica", "last_step": "Indietro", @@ -26677,7 +27513,7 @@ "mail_invite_fail": "La posta invita il successo.", "mail_invite_success": "La posta invita il successo.", "main_admin_name": "Nome amministratore", - "main_admin_page_desc": "L'amministratore ha pieno accesso allo Spazio, ad esempio assegnando sotto-amministratori e trasferendo la proprietà dello Spazio", + "main_admin_page_desc": "L'amministratore ha accesso completo allo spazio, ad esempio alla gestione dei membri e alle impostazioni dello spazio.", "main_contain": "Contenuti principali", "malawi": "Malawi", "malaysia": "Malaysia", @@ -26897,8 +27733,12 @@ "more_widget": "Altri widget", "morocco": "Marocco", "move": "Sposta", + "move_datasheet_link_warn": "Cannot be moved to Team Area alone, because there is a two-way link from the current datasheet to another datasheet, it is recommended to put them in a folder and then move them", "move_favorite_node_fail": "Spostamento nodo fallito. Il sistema aggiornerà automaticamente l'elenco.", + "move_folder_link_warn": "Cannot be moved to Team Area because the files in the current folder are linked to files outside the folder (may be two-way links or linked by forms, etc.) We recommend that they be placed in a folder before moving", "move_node_modal_content": "Dopo lo spostamento, la visibilità del file potrebbe essere influenzata dalla cartella principale.", + "move_other_link_no_permission": "Unable to move to the corresponding folder because you do not have administrative rights to the folder", + "move_other_link_warn": "It is not allowed to move ${node type} to Team Area alone, because it connects to the datasheet of Private Area, it is recommended to put them in a folder before moving them", "move_to": "Sposta a", "move_to_error_equal_parent": "Il file si trova sotto la cartella corrente. Seleziona un'altra cartella", "move_to_modal_title": "Sposta [${name}] in", @@ -26929,7 +27769,9 @@ "new_a_line": "Shift+Invio: linea di interruzione", "new_automation": "Nuova automazione", "new_caledonia": "Nuova Caledonia", + "new_custom_page": "New custom page", "new_datasheet": "Nuovo foglio dati", + "new_ebmed_page": "Nuova pagina personalizzata", "new_folder": "Nuova cartella", "new_folder_btn_title": "Cartella", "new_folder_tooltip": "Crea cartella", @@ -27095,7 +27937,7 @@ "nvc_start_text": "Trascina la barra verso l'estremità destra", "nvc_yes_text": "Verificato", "obtain_verification_code": "Codice di verifica non ottenuto o scaduto", - "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrzw0miJVmSkJ7eBBa9k/fomx5qPX0JGPFvfEEP\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", + "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrCvbFC53xc3kl00B4Pg\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", "offical_website_nav_data": "[{\n \"name\": \"产品\",\n \"href\": \"/login\",\n \"children\": [\n {\n \"name\": \"vika维格表 Overview\",\n \"href\": \"/login/\"\n },\n {\n \"name\": \"应用连接 Integration\",\n \"href\": \"/connections/\"\n },\n {\n \"name\": \"客户端(Beta) Download\",\n \"href\": \"/download/\"\n }\n ]\n}, {\n \"name\": \"解决方案\",\n \"href\": \"/\",\n \"children\": [{\n \"name\": \"PMO项目群管理\",\n \"href\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"href\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"href\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"href\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"href\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"href\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"href\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"href\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"href\": \"/shop/\"\n }, {\n \"name\": \"更多解决方案 >\",\n \"href\": \"/solutions/\"\n }]\n}, {\n \"name\": \"模板/案例\",\n \"href\": \"/template\",\n \"children\": [\n {\n \"name\": \"模板中心 Tempaltes\",\n \"href\": \"/template\"\n },\n {\n \"name\": \"客户案例 Customers\",\n \"href\": \"/cases/\"\n }\n ]\n},\n {\n \"name\": \"首页\",\n \"href\": \"/?home=1\"\n },\n {\n \"name\": \"学习资源\",\n \"href\": \"https://edu.vika.cn/index\",\n \"children\": [\n {\n \"name\": \"快速入门 Tutorials\",\n \"href\": \"https://help.vika.cn/docs/guide/tutorial\"\n },\n {\n \"name\": \"产品手册 Manual\",\n \"href\": \"https://help.vika.cn/docs/guide/manual\"\n },\n {\n \"name\": \"维格课堂 Vika Education\",\n \"href\": \"https://edu.vika.cn/\"\n },\n {\n \"name\": \"维格社区 Vika BBS\",\n \"href\": \"https://bbs.vika.cn/\"\n },\n {\n \"name\": \"第三方连接 Integration\",\n \"href\": \"https://help.vika.cn/docs/guide/connection\"\n },\n {\n \"name\": \"开发者中心 Developer Center\",\n \"href\": \"/developers/\"\n },\n {\n \"name\": \"常见问题 FAQ\",\n \"href\": \"https://help.vika.cn/docs/guide/questions\"\n }\n ]\n }]", "office_preview": "Anteprima file di Office", "office_preview_app_desc": "

Smooth online preview of office files on datasheet, allowing you to view common office files such as Excel, Word, PPT, etc. on your desktop or mobile anywhere, anytime

\n\n
    \n
  • Online preview of .doc, .docx, .xls, .xlsx, .ppt, .pptx, and .pdf formatted office files
  • \n
  • Desktop and mobile both support file previews of the above formats
  • \n
\n\n

Additional notes:

\n
    \n
  • This feature is powered by \"Yoncentric Cloud Conversion\" and officially integrated
  • \n
  • Click the \"Enable\" button below to enable this integration and agree that \"Yoncentric Cloud Conversion\" reads the office files you want to preview
  • \n
  • If you no longer need the office files preview feature, the space admin can disable it on this page
  • \n
", @@ -27135,6 +27977,7 @@ "open_auto_save_success": "La vista Salvataggio automatico è attivata correttamente", "open_auto_save_warn_content": "Tutte le modifiche in questa visualizzazione vengono salvate e sincronizzate automaticamente con gli altri membri.", "open_auto_save_warn_title": "Attiva la vista salvataggio automatico", + "open_automation_time_arrival": "https://aitable.ai/contact-sales-open-source", "open_failed": "Apertura non riuscita", "open_in_new_tab": "aprire in una nuova scheda", "open_invite_after_operate": "Una volta attivato, tutti i membri possono invitare nuovi membri dal pannello contatti", @@ -27281,6 +28124,8 @@ "payment_record": "Registrazione dei pagamenti", "payment_reminder": "Promemoria di pagamento", "payment_reminder_content": "Il nuovo piano che hai selezionato è più deducibile dell'importo da pagare. Si consiglia di scegliere il nuovo piano con una durata maggiore. Se confermi di farlo, l'importo in eccesso non sarà rimborsabile. ${action} in caso di dubbio", + "payment_reminder_modal_content": "Puoi provare la versione avanzata per usufruire di più nodi di file, autorizzazioni aziendali, capacità di allegati, volume di dati, intelligenza artificiale e altre funzionalità e privilegi avanzati.", + "payment_reminder_modal_title": "Attualmente stai utilizzando la versione gratuita", "pending_invite": "Invito in attesa", "people": "membro(i)", "per_person_per_year": "Per persona all'anno", @@ -27450,7 +28295,7 @@ "player_step_ui_config_168": "{\n\"templateKey\":\"createMirrorTip\"\n}", "player_step_ui_config_169": "{ \"headerImg\": \"https://s4.vika.cn/space/2023/04/04/bcf0695cf35840e6b85e032a8e5ea0a1\", \"readMoreUrl\": \"https://help.vika.cn/changelog/23-04-10- aggiornamenti\", \"bambini\": \"

🚀 Introduzione di nuove funzionalità

\\N
  • Viene lanciato il nuovo tipo di campo \"Cascader\", rendendo più semplice la selezione da una gerarchia di opzioni sui moduli
  • Viene rilasciato il widget \"Script\", meno codice per una maggiore personalizzazione
  • Attiva l'automazione per inviare e-mail e ricevere notifiche rapide
  • Attiva l'automazione per inviare un messaggio a Slack e informare il tuo team in tempo
  • Esplorando l'intelligenza artificiale: rilasciato il widget \"Generatore di contenuti GPT\".
\" }", "player_step_ui_config_17": "{\n \"element\": \"#TEMPLATE_CENTER_USE_TEMPLATE_BTN>button\", \n\"placement\": \"rightBottom\",\n\"offsetY\": 20,\n \"title\": \"How to use a template\", \n\"description\": \"Click the button on the left to use the template\", \"children\":\"\" \n}", - "player_step_ui_config_176": "{\"title\":\"Introduzione agente AI\",\"video\":\"https://www.youtube.com/embed/cjds1r_roG8?si=irKUpMhwDlOEb8Hc\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", + "player_step_ui_config_176": "{\"title\":\"AITable.ai DEMO\",\"video\":\"https://www.youtube.com/embed/kGxMyEEo3OU\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", "player_step_ui_config_18": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select>.ant-select-selector\", \n\"placement\": \"bottomLeft\",\n \"title\": \"How to use a template\", \n\"description\": \"Select where to put the template\", \"children\":\"\" \n}", "player_step_ui_config_19": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select .ant-select-selector\"\n}", "player_step_ui_config_2": "{\n \"config\": [\n {\n \"key\": 1,\n \"name\": \"answer1\",\n \"title\": \"What kind of issues are you looking forward to solved by vikadata?\",\n \"type\": \"checkbox\",\n \"answers\": [\n \"Work Planning\",\n \"Customer Service\",\n \"Project Management\",\n \"Sourcing Supply\",\n \"Content Production\",\n \"E-commerce operation\",\n \"Event Planning\",\n \"Human Resources\",\n \"Administration\",\n \"Financial Management\",\n \"Webcast\",\n \"Educational institutes Management\",\n \"Other\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 2,\n \"name\": \"answer2\",\n \"title\": \"Your job title is______\",\n \"type\": \"radio\",\n \"answers\": [\n \"General manager \",\n \"Project manager\",\n \"Product manager\",\n \"Designer\",\n \"R&D engineer\",\n \"Operator, editor\",\n \"Sales, customer service\",\n \"Human resource, administration \",\n \"Finance, accountant\",\n \"Lawyer, legal affairs\",\n \"Marketing\",\n \"Teacher\",\n \"Student\",\n \"Other\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 3,\n \"name\": \"answer3\",\n \"title\": \"What is the name of your company?\",\n \"type\": \"input\",\n \"submit\": false\n },\n {\n \"key\": 4,\n \"name\": \"answer4\",\n \"title\": \"Please leave your email address/ phone number/ Wechat account below so we can reach you in time when you need help.\",\n \"type\": \"input\",\n \"submit\": true\n },\n {\n \"key\": 5,\n \"title\": \"Thank you for filling out the form, you can add our customer service in case of need\",\n \"platform\": {\n \"website\": \"https://s4.vika.cn/space/2023/03/02/b34e3205a9154463be16f497524f1327\",\n \"dingtalk\": \"https://s4.vika.cn/space/2023/03/02/4b16cef6602a4586a21d6346bf25d300\",\n \"wecom\": \"https://s4.vika.cn/space/2023/03/02/60119b1b69b64aa887bd1be6a2928bec\",\n \"feishu\": \"https://u.vika.cn/z9ygm\"\n },\n \"type\": \"contactUs\",\n \"next\": true\n }\n ]\n}\n", @@ -27480,13 +28325,13 @@ "player_step_ui_config_41": "", "player_step_ui_config_42": "{\n \"element\": \"#DATASHEET_FORM_LIST_PANEL\", \n\"placement\": \"leftTop\",\n \"title\": \"Form\", \n\"description\": \"You can quickly create a form from the current view. The number and order of the fields in the form is consistent with the view.\", \"children\":\"\" \n}", "player_step_ui_config_43": "{\n \"element\": \".style_navigation__1U5cR .style_help__1sXEA\", \n\"placement\": \"rightBottom\",\n \"title\": \"Tip\", \n\"offsetY\":5,\n\"description\": \"You can find your Vikaby assistant from the \"Help\" icon on the left\", \"children\":\"\" \n}", - "player_step_ui_config_44": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", + "player_step_ui_config_44": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", "player_step_ui_config_45": "", "player_step_ui_config_46": "", "player_step_ui_config_47": "{\n \"element\": \"#DATASHEET_WIDGET_BTN\",\n\"placement\": \"bottomRight\",\n \"title\": \"Widget\", \n\"description\": \"Want to use and view your data in a richer way? Try the widget!\", \"children\":\"\" \n}", "player_step_ui_config_48": "", "player_step_ui_config_49": "{\n \"element\": \".style_widgetPanelContainer__1l2ZV\",\n\"placement\": \"leftCenter\",\n \"title\": \"What is a widget\", \n\"description\": \"Vika widgets are an extended application of vikadata that features in richer data visualization, data transfer, data cleansing, and more. By installing widgets in the widget board, you can make work a lot easier.\", \"children\":\"\" \n}", - "player_step_ui_config_5": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", + "player_step_ui_config_5": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", "player_step_ui_config_50": "{\n \"element\": \".style_widgetModal__eXmdB\",\n\"placement\": \"leftTop\",\n \"title\": \"Widget Center\", \n\"description\": \"Officially recommended and custom widgets are published here. You can install any widget you want onto a dashboard or into a widget board of any datasheet.\", \"children\":\"\" \n}", "player_step_ui_config_51": "{\n \"element\": \".style_widgetModal__eXmdB .style_widgetItem__3Pl-1 button\",\n\"placement\": \"rightBottom\",\n \"title\": \"Install widget\", \n\"description\": \"Let's install this \"Chart\" widget\", \"children\":\"\" \n}", "player_step_ui_config_52": "", @@ -27583,6 +28428,7 @@ "preview_guide_click_to_restart": "Premere il pulsante qui sotto per visualizzare nuovamente l'anteprima", "preview_guide_enable_it": "Premere il pulsante qui sotto per attivare questa funzione", "preview_guide_open_office_preview": "Per visualizzare l'anteprima di questo file, attivare la funzione \"anteprima ufficio\"", + "preview_next_automation_execution_time": "Anteprima dei prossimi 10 tempi di esecuzione", "preview_not_support_video_codecs": "Solo i video MP4 con codec video H.264 possono essere visualizzati in anteprima", "preview_revision": "Anteprima", "preview_see_more": "Vuoi saperne di più sulla funzione \"anteprima file di ufficio\"? Clicca qui", @@ -27618,6 +28464,7 @@ "privacy_protection": "\"Tutela della privacy\"", "private_cloud": "Cloud privato", "private_external_person_only": "Solo persona esterna", + "private_help_link": "https://help.aitable.ai/docs/guide/team-and-private-area#private-area", "private_internal_person_only": "Solo persona interna", "private_product_point": "Gestisci la tua piattaforma APITable con un clic", "privatized_deployment": "Self-ospitato", @@ -27688,13 +28535,15 @@ "reconciled_data": "I dati vengono riconciliati", "record": "Registra", "record_activity_experience_tips": "Puoi visualizzare l'attività registrata di ${day} giorni", + "record_archived_data": "registrazione archiviata", + "record_chunk_text": "${text} rows, please wait", "record_comment": "Solo osservazioni", "record_comments": "commenti", "record_fail_data": "errore dei dati", "record_filter_tips": "Questo record è stato filtrato", "record_functions": "Funzione di registrazione", "record_history": "Solo cronologia delle revisioni", - "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-history", + "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-activity", "record_history_title": "Cronologia record", "record_pre_filtered": "Questo record è stato filtrato e verrà nascosto una volta cliccato fuori dal record", "record_pre_move": "Questo record verrà spostato altrove una volta cliccato fuori dal record", @@ -28134,6 +28983,12 @@ "scan_to_login": "Scansiona per accedere", "scan_to_login_by_method": "Scansiona ${method} per seguire l'account ufficiale per accedere", "scatter_chart": "Grafico a dispersione", + "schedule_day_tips": "Il calcolo del ciclo inizia a contare dal primo giorno di ogni mese. Se assumiamo che si ripeta ogni 10 giorni, verrà attivato il 1, 11, 21 e 31 di ogni mese", + "schedule_hour_tips": "Il calcolo del ciclo inizia ogni giorno a mezzanotte (0:00). Supponendo che si ripeta 0 minuti ogni tre ore, avverrà a mezzanotte (0:00), 3:00, 6:00, 9:00, mezzogiorno (12:00), 15:00, 18:00 e infine al calare della notte (21:00) tutti i giorni", + "schedule_start_day": "A partire dal 1° giorno del mese, ogni", + "schedule_start_month": "A partire da gennaio di ogni anno, ogni", + "schedule_type": "Tipo di pianificazione", + "schedule_year_tips": "Il calcolo del ciclo inizia a contare dal primo mese di ogni anno. Supponendo un intervallo di primo giorno e 3 mesi, i trigger verranno attivati alla mezzanotte del primo giorno di gennaio, aprile, luglio e ottobre di ogni anno.", "science_and_technology": "Scienza e tecnologia", "scroll_screen_down": "Scorri uno schermo verso il basso", "scroll_screen_left": "Scorri uno schermo a sinistra", @@ -28147,6 +29002,7 @@ "search_folder_or_sheet": "Cerca file", "search_new_admin": "Cerca", "search_node_pleaseholder": "Cerca file (${shortcutKey})", + "search_node_tip": "Ricerca rapida (${shortcutKey})", "search_or_add": "Trova o aggiungi un'opzione", "search_role_placeholder": "Ricerca ruoli", "seats": "Sedili", @@ -28550,6 +29406,7 @@ "space_info": "Panoramica", "space_info_del_confirm1": "1. Eliminando questo spazio verranno eliminati i seguenti dati:", "space_info_del_confirm2": "2. Lo spazio verrà cancellato completamente dopo 7 giorni. Puoi ripristinare lo Spazio prima di allora.", + "space_info_del_confirm3": "3. For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "space_info_feishu_desc": "Stai utilizzando un'integrazione di terze parti. Per eliminare lo spazio, disattivare prima l'integrazione di terze parti.", "space_info_feishu_label": "Integrazioni", "space_join_apply": " ha richiesto di unirsi allo spazio \"\".", @@ -28636,6 +29493,7 @@ "start_onfiguration": "Avvia configurazione", "start_time": "Ora di inizio", "start_use": "Inizia a usare", + "starting_from_midnight": "A partire da mezzanotte (00:00) tutti i giorni, ogni", "startup": "Avvio", "startup_company_support_program": "Programma di supporto all'avvio", "stat_average": "Media", @@ -28669,6 +29527,8 @@ "stay_tuned_for_more_features": "Rimani sintonizzato per ulteriori funzionalità", "steps_choose_reset_mode": "Seleziona un metodo di ripristino", "steps_validate_identities": "Verifica identità", + "stop_chunk_content": "Are you sure you want to stop the operation?", + "stop_chunk_title": "Stop", "stop_dingtalk_h5_modal_content": "L'applicazione autocostruita sarà svincolata da questo spazio. Si prega di confermare .", "storage_per_seats": "", "storage_per_space": "Uso dello storage", @@ -28699,9 +29559,11 @@ "subscribe_credit_usage_over_limit": "Il numero di crediti nello spazio corrente supera il limite, si prega di aggiornare il vostro abbonamento.\n", "subscribe_demonstrate": "Richiedi demo", "subscribe_disabled_seat": "Il numero di persone non può essere inferiore al programma originale", + "subscribe_grade_business": "Attività commerciale", "subscribe_grade_free": "Gratis", "subscribe_grade_plus": "Più", "subscribe_grade_pro": "Pro", + "subscribe_grade_starter": "Antipasto", "subscribe_label_tooltip": "Caratteristiche avanzate dello spazio", "subscribe_new_choose_member": "Supporta fino a ${member_num} membri", "subscribe_new_choose_member_tips": "Questo piano supporta 1~${member_num} membri per entrare nello spazio", @@ -28838,7 +29700,7 @@ "template_name_repetition_title": "\"${templateName}\" esiste già. Vuoi sostituirlo?", "template_no_template": "Nessun modello", "template_not_found": "Non riesci a trovare i modelli che desideri? Dicci", - "template_recommend_title": "Caldo", + "template_recommend_title": "🌟 Hot", "template_type": "Modello", "terms_of_service": "", "terms_of_service_pure_string": "Condizioni di servizio", @@ -28882,6 +29744,7 @@ "text_editor_tip_end": "\"Invio\" per terminare la modifica", "text_functions": "Funzione stringa", "thailand": "Thailandia", + "the_button_field_is_misconfigured": "Il campo del pulsante non è configurato correttamente, controlla e riprova", "the_current_automation_workflow_has_no_related_files_you_can_establish_a_link_by_adding_trigger_conditions_and_actions_on_the_left_side": "Il flusso di lavoro di automazione corrente non ha file correlati. È possibile stabilire un collegamento aggiungendo le condizioni di innesco e le azioni sul lato sinistro", "the_current_button_column_has_expired_please_reselect": "La colonna del pulsante corrente è scaduta, seleziona nuovamente", "the_last_7_days": "negli ultimi 7 giorni", @@ -28934,7 +29797,7 @@ "time_machine_action_title": "Storia delle operazioni", "time_machine_unlimited": "Storia illimitata delle macchine del tempo", "time_zone_inconsistent_tips": "Quando i fusi orari sono incoerenti, il fuso orario dell'ora di inizio verrà utilizzato per impostazione predefinita", - "timemachine_add": "Aggiunto ${nome}", + "timemachine_add": "Aggiunto ${name}", "timemachine_add_field": "aggiunte colonne ${name}", "timemachine_add_record": "aggiunte ${count} righe di record", "timemachine_add_widget": "aggiunto un nuovo widget", @@ -28984,6 +29847,7 @@ "timemachine_update_comment": "commenti aggiornati", "times_per_month_unit": "invito/mese", "times_unit": "call(s)", + "timing_rules": "Tempistica", "timor_leste": "Timor-Est", "tip_del_success": "Puoi ripristinare il tuo spazio entro 7 giorni", "tip_do_you_want_to_know_about_field_permission": "Vuoi crittografare i dati del campo? Informazioni sulle autorizzazioni dei campi", @@ -29171,6 +30035,7 @@ "verify_account_title": "Verifica account", "verify_via_email": "Verifica dell'identità via e-mail", "verify_via_phone": "Verifica dell'identità tramite SMS", + "video": "video", "video_not_support_play": "Il formato video corrente non supporta la riproduzione online", "vietnam": "Vietnam", "view": "Visualizza", @@ -29519,7 +30384,8 @@ "workdoc_color_title": "Colore del carattere", "workdoc_create": "Crea documento di lavoro", "workdoc_expanded": "Espandi il sommario", - "workdoc_image_max_10mb": "La dimensione dell'immagine non può superare i 10 MB", + "workdoc_image_max_10mb": "nullo", + "workdoc_image_max_size": "La dimensione dell'immagine non può superare ${size}", "workdoc_info": "Informazioni", "workdoc_info_create_time": "Creato a", "workdoc_info_creator": "Creato da", @@ -29527,6 +30393,7 @@ "workdoc_info_last_modify_time": "Ultima modifica a", "workdoc_link_placeholder": "Inserisci il collegamento", "workdoc_only_image": "È consentita solo l'immagine", + "workdoc_only_video": "È consentito solo il video", "workdoc_text_placeholder": "Immettere \"/\" avvio rapido", "workdoc_title_placeholder": "Inserisci il titolo", "workdoc_unnamed": "Documento di lavoro senza nome", @@ -29535,9 +30402,11 @@ "workdoc_unsave_ok": "Non salvare le modifiche", "workdoc_unsave_title": "Il WorkDoc non è stato salvato", "workdoc_upload_failed": "Caricamento fallito", + "workdoc_video_max_size": "La dimensione del video non può superare ${size}", "workdoc_ws_connected": "Collegato", "workdoc_ws_connecting": "Collegamento...", "workdoc_ws_disconnected": "Disconnesso", + "workdoc_ws_reconnecting": "Riconnessione...", "workflow_execute_failed_notify": " impossibile eseguire a . Consulta la cronologia delle esecuzioni per risolvere il problema. Se hai bisogno di assistenza, contatta il nostro team di assistenza clienti.", "workspace_data": "Dati spaziali", "workspace_files": "Dati sul banco di lavoro", @@ -29716,6 +30585,15 @@ "agreed": "承認済み", "ai_advanced_mode_desc": "高度なモデルは,ユーザが提示をカスタマイズすることを可能にし,AIエージェントの行動や応答をより良く制御する.", "ai_advanced_mode_title": "拡張モード", + "ai_agent_anonymous": "匿名${ID}", + "ai_agent_conversation_continue_not_supported": "以前の会話の継続は現在サポートされていません", + "ai_agent_conversation_list": "会話リスト", + "ai_agent_conversation_log": "会話ログ", + "ai_agent_conversation_title": "会話のタイトル", + "ai_agent_feedback": "フィードバック", + "ai_agent_historical_message": "上記は歴史的なメッセージです", + "ai_agent_history": "歴史", + "ai_agent_message_consumed": "消費されたメッセージ", "ai_api_curl_template": "## Create chat completions\n\n```bash\n\ncurl -X POST \"{{apiBase}}/fusion/v1/ai/{{aiId}}/chat/completions\" \\n -H \"Content-Type: application/json\" \\n -H \"Authorization: Bearer {{token}}\" \\n -d '{\n \"model\": \"gpt-3.5-turbo\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"You are a helpful assistant.\"\n },\n {\n \"role\": \"user\",\n \"content\": \"Hello!\"\n }\n ]\n }'\n\n```\n\n## Returned data example\n\n```json\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", "ai_api_footer_desc": "AIエージェントをあなたのサイトに埋め込みますか?もっと知っている", "ai_api_javascript_template": "## Initialize SDK [![github]({{ githubIcon }})](https://github.com/openai/openai-node)\nAITable's chat completion API is compatible with OpenAI's Node.js SDK. You can use our service with the same SDK by simply changing the configuration as follows:\n\n\n```javascript\nconst { Configuration, OpenAIApi } = require(\"openai\");\nconst configuration = new Configuration({\n apiKey: \"{{token}}\",\n basePath: \"{{apiBase}}/fusion/v1/ai/{{aiId}}\"\n});\n```\n\n## Create chat completions\n\n```javascript\nconst openai = new OpenAIApi(configuration);\nconst chatCompletion = await openai.createChatCompletion({\n model: \"gpt-3.5-turbo\",\n messages: [{role: \"user\", content: \"Hello world\"}],\n});\n```\n\n## Returned data example\n\n```javascript\n\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", @@ -29731,6 +30609,9 @@ "ai_chat_unit": "アルバート(S)", "ai_close_setting_tip_content": "変更されました。それらを捨てたいですか。", "ai_close_setting_tip_title": "葉の先", + "ai_copilot_generate_response": "あなたのために回答を生成しています...", + "ai_copilot_processs": "処理中、お待ちください...", + "ai_copilot_start_process_request": "リクエストの処理を開始しています...", "ai_create_guide_btn_text": "データテーブルの選択", "ai_create_guide_content": "AIエージェントとして、私は私が学んだ知識に基づいてあなたの質問に答えることができます。対話を始める前に、知識ベースとしてデータテーブルを選択してください。その中のすべてのデータを読んで学習のために読みます。", "ai_credit_cost_chart_title": "信用コスト", @@ -29743,7 +30624,7 @@ "ai_credit_time_dimension_year": "今年.", "ai_credit_usage_tooltip": "メッセージクレジットは、AIエージェントクエリのために使用することができます。メッセージクレジットは、あなたの空間上の座席数に比例します。", "ai_data_source_required": "ヌル", - "ai_data_source_rows": "${row}行データ", + "ai_data_source_rows": "${rows}行データ", "ai_data_source_update": "使用可能性を更新する", "ai_datasheet_panel_create_btn_text": "AIエージェントの作成", "ai_default_idk": "私は知らない", @@ -30199,7 +31080,7 @@ "apps_support": "フルプラットフォームクライアントサポート", "archive_delete_record": "アーカイブされたレコードを削除する", "archive_delete_record_title": "レコードの削除", - "archive_notice": "

特定のレコードをアーカイブしようとしています。レコードをアーカイブすると、次のような変更が生じます。

1. このレコードの双方向リンクはすべてキャンセルされます

2. 編集はサポートされていません

3. 日付リマインダーや購読記録などの機能はサポートされていません

4. ルックアップ、式、その他のフィールドの計算に参加しなくなりました

続行してもよろしいですか? (詳細設定のアーカイブボックスで解凍できます)

", + "archive_notice": "

特定のレコードをアーカイブしようとしています。レコードをアーカイブすると、次のような変更が生じます。

1. 編集はサポートされていません

2. 日付リマインダーや購読記録などの機能はサポートされていません

3. ルックアップ、式、その他のフィールドの計算に参加しなくなりました

続行してもよろしいですか? (詳細設定のアーカイブボックスで解凍できます)

", "archive_record_in_activity": "この記録をアーカイブしました", "archive_record_in_menu": "アーカイブレコード", "archive_record_success": "レコードは正常にアーカイブされました", @@ -30259,6 +31140,8 @@ "audit_add_field_role_detail": "」データシートに、[] フィールド [] の [] としての役割 ", "audit_add_node_role": "ファイル権限の追加", "audit_add_node_role_detail": "ファイル権限を追加し、「${currentNodeName}」の「${role}」に「${unitNames}」を設定します", + "audit_add_node_role_detail_end": "to「${role}", + "audit_add_node_role_detail_start": "Add file node permission,set「${unitNames}」", "audit_admin_permission_change_event": "管理者権限の変更", "audit_create_template": "テンプレートの作成", "audit_create_template_detail": "テンプレートの作成", @@ -30267,20 +31150,30 @@ "audit_delete_field_role_detail": "監査", "audit_delete_node_role": "ファイル権限の削除", "audit_delete_node_role_detail": "ファイル権限の削除,「$」の「${unitNames}」の「${role}」ロールを削除します 「{currentNodeName}」", + "audit_delete_node_role_detail_end": "at 「${role}」role", + "audit_delete_node_role_detail_start": "Delete file node permission,delete「${unitNames}」from", "audit_delete_template": "テンプレートの削除", "audit_delete_template_detail": "テンプレートの削除", "audit_disable_field_role": "フィールド権限の無効化", "audit_disable_field_role_detail": "監査", "audit_disable_node_role": "ファイル権限の無効化", "audit_disable_node_role_detail": "${nodeType} 「${currentNodeName}」の権限を無効にします", + "audit_disable_node_role_detail_end": "`s permission", + "audit_disable_node_role_detail_start": "Disable ${nodeType}", "audit_disable_node_share": "ファイルパブリックリンクを閉じる", "audit_disable_node_share_detail": "${nodeType} 「${currentNodeName}」パブリック リンクを閉じる", + "audit_disable_node_share_detail_end": "public link", + "audit_disable_node_share_detail_start": "Close ${nodeType}", "audit_enable_field_role": "フィールド権限の有効化", "audit_enable_field_role_detail": "監査", "audit_enable_node_role": "ファイル権限の有効化", "audit_enable_node_role_detail": "${nodeType} 「${currentNodeName}」の権限を有効にする", + "audit_enable_node_role_detail_end": "`s permission", + "audit_enable_node_role_detail_start": "Enable ${nodeType}", "audit_enable_node_share": "ファイルパブリックリンクを開く", "audit_enable_node_share_detail": "${nodeType} 「${currentNodeName}」パブリック リンクを開きます", + "audit_enable_node_share_detail_end": "public link", + "audit_enable_node_share_detail_start": "Open ${nodeType}", "audit_login_event": "ログインイベント", "audit_logout_event": "英語", "audit_organization_change_event": "連絡先の組織構造が変更されました", @@ -30301,18 +31194,25 @@ "audit_space_invite_user_detail": "監査", "audit_space_node_copy": "重複するファイル", "audit_space_node_copy_detail": "${nodeType} 「${sourceNodeName}」が重複しています。新しいファイルの名前は「${currentNodeName}」です。", + "audit_space_node_copy_detail_start": "Duplicate ${nodeType} 「${sourceNodeName}」, the new file node's name is", "audit_space_node_create": "ファイルの作成", "audit_space_node_create_detail": "「${currentNodeName}」という名前の ${nodeType} を作成します", + "audit_space_node_create_detail_start": "Create a ${nodeType} named", "audit_space_node_delete": "ファイルを削除", "audit_space_node_delete_detail": "「${currentNodeName}」という名前の ${nodeType} を削除します", + "audit_space_node_delete_detail_start": "Delete ${nodeType} named", "audit_space_node_export": "データテーブルのエクスポート", "audit_space_node_export_detail": "メンバー ${member_name} がデータシート ${node_name} をエクスポートしました", "audit_space_node_import": "ファイルのインポート", "audit_space_node_import_detail": "「${nodeName}」という名前のファイルをインポートします", + "audit_space_node_import_detail_start": "Import a file node named", "audit_space_node_move": "ファイルの移動", "audit_space_node_move_detail": "${nodeType} 「${currentNodeName}」をフォルダー「${parentName}」に移動します", + "audit_space_node_move_detail_end": "to the folder「${parentName}」", + "audit_space_node_move_detail_start": "Move ${nodeType}", "audit_space_node_rename": "ファイル名の変更", "audit_space_node_rename_detail": "${nodeType} の名前を「${oldNodeName}」から「${nodeName}」に変更します", + "audit_space_node_rename_detail_start": "Rename ${nodeType} 「${oldNodeName}」to", "audit_space_node_sort": "監査", "audit_space_node_sort_detail": "監査", "audit_space_node_update_cover": "監査", @@ -30327,17 +31227,24 @@ "audit_space_rubbish_node_delete_detail": "監査", "audit_space_rubbish_node_recover": "ファイルを復元", "audit_space_rubbish_node_recover_detail": "${nodeType} 「${currentNodeName}」をゴミ箱から復元します", + "audit_space_rubbish_node_recover_detail_end": "from the trash", + "audit_space_rubbish_node_recover_detail_start": "Restore ${nodeType}", "audit_space_template_event": "テンプレートの変更", "audit_space_update_logo": "監査", "audit_space_update_logo_detail": "監査", "audit_store_share_node": "共有ファイルの保存", "audit_store_share_node_detail": "${nodeType} をスペースに復元します。名前は「${nodeName}」です", + "audit_store_share_node_detail_start": "Restore ${nodeType} to the space, name is", "audit_update_field_role": "監査", "audit_update_field_role_detail": "監査", "audit_update_node_role": "ファイル権限の変更", "audit_update_node_role_detail": "ファイル権限を変更し、「${unitNames}」のロールを「 ${currentNodeName}」の「${role}」に変更します", + "audit_update_node_role_detail_end": "to「${role}」role", + "audit_update_node_role_detail_start": "Modify file node permission,modify「${unitNames}」from", "audit_update_node_share_setting": "ファイルパブリックリンク設定の変更", "audit_update_node_share_setting_detail": "${nodeType} 「${currentNodeName}」パブリック リンクを変更します", + "audit_update_node_share_setting_detail_end": "public link settings", + "audit_update_node_share_setting_detail_start": "Modify ${nodeType}", "audit_user_login": "ユーザーログイン", "audit_user_login_detail": "監査", "audit_user_logout": "ユーザーのログアウト", @@ -30379,6 +31286,7 @@ "automation_enabled_return_via_related_files": "自動化が有効になっています。新しいボタンを使用するには、「関連ファイル」から元のテーブルを再入力してください。", "automation_field": "フィールド.フィールド", "automation_import_variables_from_pre_tep": "前ステップからデータを取得する", + "automation_is_not_yet_enabled": "自動化がまだ有効になっていません。有効にしてもう一度お試しください。", "automation_last_edited_by": "最終編集者", "automation_last_edited_time": "最終編集時刻", "automation_manager_label": "オートメーションですべてのアクションを実行できます", @@ -30404,6 +31312,7 @@ "automation_runs_this_month": "今月の運行", "automation_stay_tuned": "乞うご期待", "automation_success": "成功", + "automation_tips": "ボタンフィールドの設定が間違っています。確認してもう一度お試しください。", "automation_updater_label": "オートメーションの実行履歴を表示できます", "automation_variabel_empty": "前段階で使用できるデータがありません。調整して再試行してください。", "automation_variable_datasheet": "${NODE_NAME} からデータを取得する", @@ -30439,6 +31348,7 @@ "bermuda": "バミューダ諸島", "bhutan": "ブータン", "billing_over_limit_tip_common": "容量の使用量が制限を超えているため、アップグレード後はより多くの量をお楽しみいただけます。", + "billing_over_limit_tip_forbidden": "試用期間またはサブスクリプション期間が終了しました。更新するには販売コンサルタントにご連絡ください。", "billing_over_limit_tip_widget": "ウィジェットのインストール数が制限を超えているため、アップグレードして使用量を増やすことができます。", "billing_period": "請求期間: ${period}", "billing_subscription_warning": "機能性", @@ -30498,10 +31408,19 @@ "button_text": "ボタンのテキスト", "button_text_click_start": "クリックして開始", "button_type": "ボタンの種類", + "by_at": "で", + "by_days": "日々", + "by_every": "毎", "by_field_id": "フィールドIDの使用", + "by_hours": "時間", + "by_in": "で", + "by_min": "分)", + "by_months": "月", + "by_on": "で", "by_the_day": "日単位", "by_the_month": "月刊誌", "by_the_year": "毎年", + "by_weeks": "週間", "calendar_add_date_time_field": "作成日フィールド", "calendar_color_more": "その他の色", "calendar_const_detail_weeks": "[\"月曜日\",\"火曜日\",\"水曜日\",\"木曜日\",\"金曜日\",\"土曜日\",\"日曜日\"]", @@ -30565,6 +31484,14 @@ "cannot_activate_space_by_space_limit": "スペース境界をアクティブ化できません", "cannot_join_space": "新しいスペースに参加することはできません。10のスペースの最大クォータを超えているからです。", "cannot_switch_field_permission": "フィールド権限をファイル権限以上に設定します。", + "capacity_file_detail_desc": "The total number of file nodes within the Space is calculated by adding the file nodes from the Team to the file nodes created by each member in their Private. Not enough capacity?", + "capacity_file_detail_title": "File Capacity", + "capacity_file_member": "Member", + "capacity_file_member_private_node_count": "Private", + "capacity_file_member_private_percent": "Percent", + "capacity_file_member_team": "Team", + "capacity_file_member_team_node_count": "Team", + "capacity_file_upgrade": "Click to upgrade your Space", "capacity_from_official_gift": "公式プレゼントより", "capacity_from_participation": "招待された ${user} がスペースに参加します", "capacity_from_purchase": "購買能力別", @@ -30601,6 +31528,8 @@ "catalog": "探索者", "catalog_add_from_template_btn_title": "テンプレートから追加", "catalog_empty_tips": "このワークスペースは空になりました。テンプレートを使用したファイルの作成を開始します。", + "catalog_private": "Private", + "catalog_team": "Team", "category_blank": "[空白]", "catering": "飲食", "cayman_islands": "ケイマン諸島", @@ -30669,6 +31598,7 @@ "choose_type_of_vika_field": "フィールドタイプの選択", "choose_your_own_space": "(作成者として自分のスペースに保存することのみがサポートされています)", "chose_new_primary_admin_button": "割当て", + "chunk_stopping_title": "Stopping", "claim_special_offer": "このスペシャル特典をお申し込みください!", "clear": "はっきりした", "clear_all_fields": "すべて消去", @@ -30799,6 +31729,7 @@ "confirm_del_current_team": "本当にチームを削除しますか?", "confirm_delete": "確認して削除", "confirm_delete_node_name_as": "「${nodeNameDiv}」を削除してもよろしいですか?", + "confirm_delete_private_node_name_as": "Are you sure you want to delete \"${nodeNameDiv}\"? The file will be deleted from the Space and the trash.", "confirm_delete_space_btn": "スペースの確認と削除", "confirm_exit": "終了の確認", "confirm_exit_space_with_name": "「${spaceNameDiv}」スペースを終了するかどうかの確認", @@ -30836,6 +31767,14 @@ "convert": "へんかん", "convert_tip": "これにより、特定のセルのデータが消去される可能性があります。予期しないことが発生した場合は、操作を元に戻すことができます。", "cook_islands": "クック諸島", + "copilot_auto_agent_desc": "どのエージェントを選択すればよいかわかりませんか?オートエージェントを試してください。", + "copilot_auto_agent_name": "自動エージェント", + "copilot_data_agent_desc": "ビューに基づいてデータ分析/可視化を生成します。", + "copilot_data_agent_name": "データエージェント", + "copilot_data_agent_policy": "Copilot とチャットするときは、ユーザー規約ポリシーに同意したことになります。", + "copilot_data_agent_policy_button": "ポリシー", + "copilot_help_agent_desc": "AITableのヘルプセンタードキュメントに関する質問は何でもどうぞ。", + "copilot_help_agent_name": "ヘルプセンターを検索", "copy": "レプリケーション", "copy_automation_url": "URLをコピーする", "copy_card_link": "レコードURLのコピー", @@ -30880,6 +31819,7 @@ "create_mirror_guide_content": "ミラー機能には、特定のデータを非表示にする機能があります。 元のデータシート ビューで「フィルター条件」と「非表示フィールド」を設定して、ミラーに表示するレコードとフィールドを制御できます。\n
\n
\n「閲覧ロック」機能と併用すると、他人による改変を防ぐことができます。\n
\n
\nさらに、「元のテーブル > 非表示フィールド」に移動して、「ミラー内のすべてのフィールドを表示」の設定を変更できます。", "create_mirror_guide_title": "ミラーはいくつかのレコードとフィールドを非表示にします", "create_new_button_field": "新しいボタン列フィールドを作成する", + "create_private_node_tip": "Personal or temporary draft documents can be created here ${link}", "create_public_invitation_link": "パブリック招待リンクの作成", "create_space_sub_title": "ハイ、あなたの共有スペースに名前を付けてください~", "create_team_fail": "チームの作成に失敗しました", @@ -30943,10 +31883,12 @@ "custom_enterprise": "エンタープライズスペースをカスタマイズ", "custom_function_development": "カスタム機能の開発", "custom_grade_desc": "エージェントの導入、プライベート・インストール、サポート、カスタマイズに関するプロフェッショナル・サービスの提供", + "custom_page_setting_title": "Add a custom page", "custom_picture": "カスタム画像", "custom_style": "スタイル", "custom_upload": "アップロードのカスタマイズ", "custom_upload_tip": "1:1正方形サイズの画像を使用して、より良い視覚体験を得ることをお勧めします", + "custome_page_title": "Custom Web", "cut_cell_data": "セルの切り取り", "cyprus": "キプロス.", "czech": "チェコ人人", @@ -30998,6 +31940,7 @@ "default": "約束を破る", "default_create_ai_chat_bot": "新しいAIエージェント", "default_create_automation": "新しい自動化", + "default_create_custom_page": "新しいカスタムページ", "default_create_dashboard": "新規ダッシュボード", "default_create_datasheet": "新規データテーブル", "default_create_file": "新規ファイル", @@ -31019,6 +31962,7 @@ "del_invitation_link": "招待リンクの削除", "del_invitation_link_desc": "削除するとリンクが無効になります", "del_space_now": "スペースを永遠に削除", + "del_space_now_confirm_tip": "For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "del_space_now_tip": "削除後にスペースを復元できませんでした。すべてのファイルと添付ファイルが削除されます。", "del_space_res_tip": "削除されたスペース", "del_team_success": "チームの削除に成功しました", @@ -31214,6 +32158,62 @@ "embed_error_page_help": "詳細はこちら", "embed_fail_og_description_content": "この埋め込まれたパブリックリンクは無効になっており、一時的には使用できません", "embed_failed": "埋め込みリンクは使用できません。", + "embed_link_bilibili": "bilibili", + "embed_link_bilibili_desc": "bilibili ビデオを埋め込むことで、チュートリアルやガイドを視聴したり、Vika でチャンネルのホームページを表示したりできます。", + "embed_link_bilibili_link_text": "bilibili動画を埋め込む方法", + "embed_link_bilibili_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-bilibili-video", + "embed_link_default": "何でも", + "embed_link_default_desc": "リンクを貼り付けて Web サイトを表示します。", + "embed_link_default_link_text": "もっと詳しく知る", + "embed_link_default_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_link_figma": "Figma", + "embed_link_figma_desc": "Figma ファイルを埋め込むことで、メンバーはデザイン ドラフトをより簡単に表示および編集できるようになり、コラボレーションの効率が向上します。", + "embed_link_figma_link_text": "Figma ファイルを埋め込む方法", + "embed_link_figma_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-figma-file", + "embed_link_google_docs": "Docs", + "embed_link_google_docs_desc": "Google ドキュメントを埋め込むことで、AITable でドキュメントを編集および表示して、チームのコラボレーションを促進できます。", + "embed_link_google_docs_link_text": "Googleドキュメントを埋め込む方法", + "embed_link_google_docs_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-docs-file", + "embed_link_google_sheets": "Sheets", + "embed_link_google_sheets_desc": "Google スプレッドシートを埋め込むと、AITable でテーブルを編集および表示して、チームのコラボレーションを促進できます。", + "embed_link_google_sheets_link_text": "Googleスプレッドシートを埋め込む方法", + "embed_link_google_sheets_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-sheets-file", + "embed_link_jishi_design": "JSデザイン", + "embed_link_jishi_design_desc": "JSdesign ファイルを埋め込むことで、メンバーはデザイン ドラフトをより簡単に表示および編集できるようになり、コラボレーションの効率が向上します。", + "embed_link_jishi_design_link_text": "JSdesignファイルを埋め込む方法", + "embed_link_jishi_design_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-js-design-file", + "embed_link_tencent_docs": "テンセントのドキュメント", + "embed_link_tencent_docs_desc": "Tencent ドキュメントを埋め込むことで、Vika で Tencent ドキュメントを編集および表示できるようになり、コラボレーションの効率が向上します。", + "embed_link_tencent_docs_link_text": "Tencent ドキュメントを埋め込む方法", + "embed_link_tencent_docs_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-tencent-docs", + "embed_link_wps": "WPS", + "embed_link_wps_desc": "WPS ファイルを埋め込むことで、Vika で WPS ドキュメント、テーブル、フォームを編集および表示して、コラボレーションの効率を向上させることができます。", + "embed_link_wps_link_text": "WPSファイルを埋め込む方法", + "embed_link_wps_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-wps-file", + "embed_link_youtube": "YouTube", + "embed_link_youtube_desc": "YouTube ビデオを埋め込むことで、チュートリアルやガイドを視聴したり、AITable でチャンネルのホームページを表示したりできます。", + "embed_link_youtube_link_text": "YouTubeビデオを埋め込む方法", + "embed_link_youtube_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-youtube-video", + "embed_page": "カスタムページ", + "embed_page_add_url": "URLを追加", + "embed_page_doc_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_page_function_desc": "Web ページを ${edition} に追加すると、サードパーティの Web サイトのドキュメントやビデオなどに簡単にアクセスできます。推奨される Web サイトのリンクやカスタム リンクを追加できます。", + "embed_page_node_permission_editor": "「更新のみ」に基づいて、ファイルの公開共有を開くこともできます", + "embed_page_node_permission_manager": "ファイルに対するすべてのアクションを実行できます", + "embed_page_node_permission_reader": "カスタムページのコンテンツと基本的なファイル情報を表示できます", + "embed_page_node_permission_updater": "「読み取り専用」に基づいて、カスタムページのリンクを変更することもできます", + "embed_page_setting_title": "カスタムページを追加する", + "embed_page_url_invalid": "正しいURLを入力してください", + "embed_paste_link_bilibili_placeholder": "bilibili動画のリンクを貼り付けます", + "embed_paste_link_default_placeholder": "URLを貼り付けてください", + "embed_paste_link_figma_placeholder": "Figma ファイルの共有リンクを貼り付けます", + "embed_paste_link_google_docs_placeholder": "Google ドキュメントの共有リンクを貼り付けます", + "embed_paste_link_google_sheets_placeholder": "Google スプレッドシートの共有リンクを貼り付けます", + "embed_paste_link_jsdesign_placeholder": "JSdesign ファイルの共有リンクを貼り付けます。", + "embed_paste_link_tencent_docs_placeholder": "Tencent ドキュメントの共有リンクを貼り付けます", + "embed_paste_link_wps_placeholder": "WPS ファイルの共有リンクを貼り付けます", + "embed_paste_link_youtube_placeholder": "YouTube ビデオのリンクを貼り付けます", + "embed_success": "正常に追加されました", "emoji_activity": "アクティビティ", "emoji_custom": "風俗", "emoji_flags": "に旗を立てる", @@ -31320,6 +32320,11 @@ "estonia": "エストニア.", "ethiopia": "エチオピア.", "event_planning": "イベント企画", + "every": "毎", + "every_day_at": "日:", + "every_hour_at": "時", + "every_month_at": "の月", + "every_week_at": "毎週", "everyday_life": "日常生活", "everyone_visible": "すべての人に表示", "exact_date": "正確な日付", @@ -31330,6 +32335,7 @@ "exchange": "請け出す", "exchange_code_times_tip": "注意:為替コードは1回だけ使用できます", "exclusive_consultant": "独占V+コンサルタント", + "exclusive_limit_plan_desc": "限定限定ティア", "exist_experience": "エクスペリエンスの終了", "exits_space": "スペースを終了", "expand": "拡大", @@ -31356,7 +32362,7 @@ "expired": "期限が切れる", "export": "エクスポート中。。。", "export_brand_desc": "テクニカルサポート", - "export_current_preview_view_data": "", + "export_current_preview_view_data": "Export current preview view data", "export_gantt_button_tips": ".pngファイルにエクスポート", "export_gantt_chart": "ガントチャートのエクスポート", "export_to_excel": "データのエクスポート", @@ -32028,6 +33034,7 @@ "gold_grade": "金", "gold_grade_desc": "複雑なビジネスプロセスに対応するチーム", "gold_seat_200_desc": "200", + "gold_seat_300_desc": "300", "golden_grade": "金", "got_it": "わかりました", "got_v_coins": "ご褒美Vコイン", @@ -32061,6 +33068,8 @@ "guests_per_space": "各スペースのお客様", "guide_1": "啊这", "guide_2": "基本機能を学ぶのに数分しかかかりません。この瞬間から、仕事の効率がさらにアップ!", + "guide_flow_modal_contact_sales": "営業担当者へのお問い合わせ", + "guide_flow_modal_get_started": "始めましょう", "guide_flow_of_catalog_step1": "これは作業ディレクトリで、スペースのすべてのフォルダとファイルが格納されています。", "guide_flow_of_catalog_step2": "作業ディレクトリでは、必要に応じてデータテーブルまたはフォルダを作成できます。", "guide_flow_of_click_add_view_step1": "基本ビューのほかに、画像形式の添付ファイルがある場合は、アルバムビューを作成することを強くお勧めします。", @@ -32239,6 +33248,7 @@ "intro_widget_tips": "ウィジェットとは", "introduction": "紹介", "invalid_action_sort_tip": "グループ化フィールドとして、ソートが設定されています。現在の注文の設定は有効になりません。", + "invalid_automation_configuration": "自動化構成が無効です。確認して再試行してください。", "invalid_field_type": "無効なフィールドタイプ", "invalid_option_sort_tip": "グループ化フィールドとして、ソートが設定されています。", "invalid_redemption_code_entered": "無効な換算コード", @@ -32369,6 +33379,9 @@ "label_format_day_month_and_year_split_by_slash": "日/月/年", "label_format_month": "月", "label_format_month_and_day_split_by_dash": "年月日", + "label_format_month_day_year_split_by_dash": "Month-Day-Year", + "label_format_month_day_year_split_by_slash": "Month/Day/Year", + "label_format_month_day_year_two_digit_year_split_by_slash": "Month/Day/Year (Two-digit year)", "label_format_year": "年", "label_format_year_and_month_split_by_dash": "年月", "label_format_year_month_and_day_split_by_dash": "年月日", @@ -32447,6 +33460,7 @@ "lark_version_enterprise": "Larkのエンタープライズ計画", "lark_version_standard": "Lark標準平面図", "lark_versions_free": "Larkの基本平面図", + "last_day": "最終日", "last_modified_by_select_modal_desc": "下で選択したフィールドを編集すると、最後に編集したメンバーが最後に編集したフィールドに表示されます", "last_modified_time_select_modal_desc": "下で選択したフィールドを編集すると、最後に編集した時刻が最後に編集した時刻フィールドに表示されます", "last_step": "リターンマッチ", @@ -32591,7 +33605,7 @@ "mail_invite_fail": "メール招待に成功しました。", "mail_invite_success": "メール招待に成功しました。", "main_admin_name": "管理者名", - "main_admin_page_desc": "管理者は、サブ管理者の割り当てやスペースの所有権の移転など、スペースに完全にアクセスできます。", + "main_admin_page_desc": "管理者は、メンバーの管理、スペース設定の管理など、スペースへの完全なアクセス権を持ちます。", "main_contain": "主な内容", "malawi": "マラウイ.", "malaysia": "マレーシア.", @@ -32811,8 +33825,12 @@ "more_widget": "その他のガジェット", "morocco": "モロッコ.", "move": "移動", + "move_datasheet_link_warn": "Cannot be moved to Team Area alone, because there is a two-way link from the current datasheet to another datasheet, it is recommended to put them in a folder and then move them", "move_favorite_node_fail": "ノードの移動に失敗しました。リストが自動的に更新されます。", + "move_folder_link_warn": "Cannot be moved to Team Area because the files in the current folder are linked to files outside the folder (may be two-way links or linked by forms, etc.) We recommend that they be placed in a folder before moving", "move_node_modal_content": "移動後、ファイルの可視性は親フォルダーの影響を受ける可能性があります。", + "move_other_link_no_permission": "Unable to move to the corresponding folder because you do not have administrative rights to the folder", + "move_other_link_warn": "It is not allowed to move ${node type} to Team Area alone, because it connects to the datasheet of Private Area, it is recommended to put them in a folder before moving them", "move_to": "移動先", "move_to_error_equal_parent": "ファイルは現在のフォルダの下にあります。他のフォルダを選択してください", "move_to_modal_title": "[${name}] を次の場所に移動します", @@ -32843,7 +33861,9 @@ "new_a_line": "Shift+Enterキー:改行", "new_automation": "新しい自動化", "new_caledonia": "ニューカレドニア", + "new_custom_page": "New custom page", "new_datasheet": "新規データテーブル", + "new_ebmed_page": "新しいカスタムページ", "new_folder": "新規フォルダ", "new_folder_btn_title": "フォルダー", "new_folder_tooltip": "フォルダの作成", @@ -33009,7 +34029,7 @@ "nvc_start_text": "棒グラフを右端にドラッグ", "nvc_yes_text": "実証済み", "obtain_verification_code": "認証コードが取得されていないか期限切れです", - "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrzw0miJVmSkJ7eBBa9k/fomx5qPX0JGPFvfEEP\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", + "offical_website_footer_nav_data": "[{ \"title\": \"产品\", \"lists\": [{ \"name\": \"快速入门\", \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick- start\" }, { \"name\": \"产品指南\", \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\" }, { \"name\": \"产品价格\", \"url\": \"/pricing/\" }, { \"name\": \"产品回線图\", \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\" }] }, { \"title\": \"关に関する我们\", \"lists\": [{ \"name\": \"公司介绍\", \"url\": \"/company/\" }, { \"name\": \"添加我们\", \"url \": \"/join-us/\" }, { \"name\": \"メディア报道\", \"url\": \"/press/\" }, { \"name\": \"vika维格课堂\", \"url\": \"https ://edu.vika.cn/\" }, { \"name\": \"维格合伙人\", \"url\": \"/partners/\" }] }, { \"title\": \"解决方案\", \"lists\" : [{ \"name\": \"PMO项目群管理\", \"url\": \"/business-pmo/\" }, { \"name\": \"智慧电商运营\", \"url\": \"/ecommerce/\" }, { \"name\": \"CRM客户管理\", \"url\": \"/crm/\" }, { \"name\": \"HR人力资源管理\", \"url\": \"/hr/\" }, { \"name\": \"Scrum敏捷开発行管理\", \"url\": \"/scrum/\" }, { \"name\": \"营销策划与市场运营\", \"url\": \"/marketing/\" }, { \"name\": \"OKR目标管理\", \"url\": \"/okr/\" }, { \"name\": \"教育培训管理\", \"url\": \"/education/\" }, { \"name\": \"智慧门店管理\", \"url\" : \"/shop/\" }] }, { \"title\": \" サポート\", \"lists\": [{ \"name\": \"意见反馈\", \"url\": \"https://vika.cn/share/shrCvbFC53xc3kl00B4Pg \" }, { \"name\": \"帮助中心\", \"url\": \"https://help.vika.cn/\" }, { \"name\": \"开発行者中心\", \"url\": \"/developers/ \" }, { \"name\": \"服务条款\", \"url\": \"/service-agreement/\" }, { \"name\": \"隐私协议\", \"url\": \"/service-agreement/\" }, { \"name\": \"安全与合规\", \"url\": \"/security/\" }] }, { \"title\": \"服务\", \"lists\": [{ \"name\": \"追加社群\", \" url\": \"/chatgroup/\" }, { \"name\": \"Github开源\", \"url\": \"https://github.com/vikadata\" }, { \"name\": \"预约演示\", \"url\" : \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\" }, { \"name\": \"专有云配置\", \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\" } , { \"name\": \"应用连接\", \"url\": \"/connections/\" }] }, { \"title\": \"联系我们\", \"lists\": [{ \"name\": \"地址:深圳市南山区国信投资大厦1710\", \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\" }, { \"name\": \"售前咨询:点击联系商务\", \"url\": \"https: //vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\" }, { \"name\": \"合作:bd@vikadata.com\", \"url\": \"mailto:bd@vikadata.com\" }, { \"name\": \"メディア:pr@vikadata.com\", \"url\": \"mailto:pr@vikadata.com\" }, { \"name\": \"招聘:hr@vikadata.com\", \"url\": \"mailto:hr@vikadata. com\" }] }]", "offical_website_nav_data": "[{\n \"name\": \"产品\",\n \"href\": \"/login\",\n \"children\": [\n {\n \"name\": \"vika维格表 Overview\",\n \"href\": \"/login/\"\n },\n {\n \"name\": \"应用连接 Integration\",\n \"href\": \"/connections/\"\n },\n {\n \"name\": \"客户端(Beta) Download\",\n \"href\": \"/download/\"\n }\n ]\n}, {\n \"name\": \"解决方案\",\n \"href\": \"/\",\n \"children\": [{\n \"name\": \"PMO项目群管理\",\n \"href\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"href\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"href\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"href\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"href\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"href\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"href\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"href\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"href\": \"/shop/\"\n }, {\n \"name\": \"更多解决方案 >\",\n \"href\": \"/solutions/\"\n }]\n}, {\n \"name\": \"模板/案例\",\n \"href\": \"/template\",\n \"children\": [\n {\n \"name\": \"模板中心 Tempaltes\",\n \"href\": \"/template\"\n },\n {\n \"name\": \"客户案例 Customers\",\n \"href\": \"/cases/\"\n }\n ]\n},\n {\n \"name\": \"首页\",\n \"href\": \"/?home=1\"\n },\n {\n \"name\": \"学习资源\",\n \"href\": \"https://edu.vika.cn/index\",\n \"children\": [\n {\n \"name\": \"快速入门 Tutorials\",\n \"href\": \"https://help.vika.cn/docs/guide/tutorial\"\n },\n {\n \"name\": \"产品手册 Manual\",\n \"href\": \"https://help.vika.cn/docs/guide/manual\"\n },\n {\n \"name\": \"维格课堂 Vika Education\",\n \"href\": \"https://edu.vika.cn/\"\n },\n {\n \"name\": \"维格社区 Vika BBS\",\n \"href\": \"https://bbs.vika.cn/\"\n },\n {\n \"name\": \"第三方连接 Integration\",\n \"href\": \"https://help.vika.cn/docs/guide/connection\"\n },\n {\n \"name\": \"开发者中心 Developer Center\",\n \"href\": \"/developers/\"\n },\n {\n \"name\": \"常见问题 FAQ\",\n \"href\": \"https://help.vika.cn/docs/guide/questions\"\n }\n ]\n }]", "office_preview": "Officeファイルのプレビュー", "office_preview_app_desc": "

Smooth online preview of office files on datasheet, allowing you to view common office files such as Excel, Word, PPT, etc. on your desktop or mobile anywhere, anytime

\n\n
    \n
  • Online preview of .doc, .docx, .xls, .xlsx, .ppt, .pptx, and .pdf formatted office files
  • \n
  • Desktop and mobile both support file previews of the above formats
  • \n
\n\n

Additional notes:

\n
    \n
  • This feature is powered by \"Yoncentric Cloud Conversion\" and officially integrated
  • \n
  • Click the \"Enable\" button below to enable this integration and agree that \"Yoncentric Cloud Conversion\" reads the office files you want to preview
  • \n
  • If you no longer need the office files preview feature, the space admin can disable it on this page
  • \n
", @@ -33049,6 +34069,7 @@ "open_auto_save_success": "自動保存ビューが正常に開きました", "open_auto_save_warn_content": "このビューでの変更はすべて自動的に保存され、他のメンバーと同期されます。", "open_auto_save_warn_title": "自動保存ビューを有効にする", + "open_automation_time_arrival": "https://aitable.ai/contact-sales-open-source", "open_failed": "開けませんでした", "open_in_new_tab": "新しいタブで開く", "open_invite_after_operate": "開くと、すべてのメンバーが連絡先パネルから新しいメンバーを招待できます", @@ -33195,6 +34216,8 @@ "payment_record": "支払記録", "payment_reminder": "支払プロンプト", "payment_reminder_content": "選択した新しいプランは、支払われる金額よりも多くの控除対象となります。期間が長い新しいプランを選択することをお勧めします。確認した場合、超過金額は返金されません。疑わしい場合は ${action}", + "payment_reminder_modal_content": "上級バージョンを試して、より多くのファイル ノード、エンタープライズ権限、添付ファイル容量、データ量、AI、その他の高度な機能と権限を楽しむことができます。", + "payment_reminder_modal_title": "現在無料版を使用しています", "pending_invite": "保留中の招待", "people": "メンバー", "per_person_per_year": "一人当たり毎年", @@ -33364,7 +34387,7 @@ "player_step_ui_config_168": "{\n\"templateKey\":\"createMirrorTip\"\n}", "player_step_ui_config_169": "{ \"headerImg\": \"https://s4.vika.cn/space/2023/04/04/bcf0695cf35840e6b85e032a8e5ea0a1\", \"readMoreUrl\": \"https://help.vika.cn/changelog/23-04-10-更新\"、\"子\": \"

🚀 新機能のご紹介

\\n
  • 新しいフィールド タイプ「Cascader」がリリースされ、フォーム上のオプションの階層からの選択が容易になります。
  • 「スクリプト」ウィジェットがリリースされ、より少ないコードでよりカスタマイズ可能に
  • 自動化をトリガーして電子メールを送信し、迅速な通知を受け取ります
  • 自動化をトリガーして Slack にメッセージを送信し、時間内にチームに通知します
  • AIの探求:「GPT Content Generator」ウィジェットをリリース
\" }", "player_step_ui_config_17": "{\n \"element\": \"#TEMPLATE_CENTER_USE_TEMPLATE_BTN>button\", \n\"placement\": \"rightBottom\",\n\"offsetY\": 20,\n \"title\": \"How to use a template\", \n\"description\": \"Click the button on the left to use the template\", \"children\":\"\" \n}", - "player_step_ui_config_176": "{\"title\":\"AIエージェント入門\",\"video\":\"https://www.youtube.com/embed/cjds1r_roG8?si=irKUpMhwDlOEb8Hc\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", + "player_step_ui_config_176": "{\"title\":\"AITable.ai DEMO\",\"video\":\"https://www.youtube.com/embed/kGxMyEEo3OU\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", "player_step_ui_config_18": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select>.ant-select-selector\", \n\"placement\": \"bottomLeft\",\n \"title\": \"How to use a template\", \n\"description\": \"Select where to put the template\", \"children\":\"\" \n}", "player_step_ui_config_19": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select .ant-select-selector\"\n}", "player_step_ui_config_2": "{\n \"config\": [\n {\n \"key\": 1,\n \"name\": \"answer1\",\n \"title\": \"What kind of issues are you looking forward to solved by vikadata?\",\n \"type\": \"checkbox\",\n \"answers\": [\n \"Work Planning\",\n \"Customer Service\",\n \"Project Management\",\n \"Sourcing Supply\",\n \"Content Production\",\n \"E-commerce operation\",\n \"Event Planning\",\n \"Human Resources\",\n \"Administration\",\n \"Financial Management\",\n \"Webcast\",\n \"Educational institutes Management\",\n \"Other\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 2,\n \"name\": \"answer2\",\n \"title\": \"Your job title is______\",\n \"type\": \"radio\",\n \"answers\": [\n \"General manager \",\n \"Project manager\",\n \"Product manager\",\n \"Designer\",\n \"R&D engineer\",\n \"Operator, editor\",\n \"Sales, customer service\",\n \"Human resource, administration \",\n \"Finance, accountant\",\n \"Lawyer, legal affairs\",\n \"Marketing\",\n \"Teacher\",\n \"Student\",\n \"Other\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 3,\n \"name\": \"answer3\",\n \"title\": \"What is the name of your company?\",\n \"type\": \"input\",\n \"submit\": false\n },\n {\n \"key\": 4,\n \"name\": \"answer4\",\n \"title\": \"Please leave your email address/ phone number/ Wechat account below so we can reach you in time when you need help.\",\n \"type\": \"input\",\n \"submit\": true\n },\n {\n \"key\": 5,\n \"title\": \"Thank you for filling out the form, you can add our customer service in case of need\",\n \"platform\": {\n \"website\": \"https://s4.vika.cn/space/2023/03/02/b34e3205a9154463be16f497524f1327\",\n \"dingtalk\": \"https://s4.vika.cn/space/2023/03/02/4b16cef6602a4586a21d6346bf25d300\",\n \"wecom\": \"https://s4.vika.cn/space/2023/03/02/60119b1b69b64aa887bd1be6a2928bec\",\n \"feishu\": \"https://u.vika.cn/z9ygm\"\n },\n \"type\": \"contactUs\",\n \"next\": true\n }\n ]\n}\n", @@ -33394,13 +34417,13 @@ "player_step_ui_config_41": "", "player_step_ui_config_42": "{\n \"element\": \"#DATASHEET_FORM_LIST_PANEL\", \n\"placement\": \"leftTop\",\n \"title\": \"Form\", \n\"description\": \"You can quickly create a form from the current view. The number and order of the fields in the form is consistent with the view.\", \"children\":\"\" \n}", "player_step_ui_config_43": "{\n \"element\": \".style_navigation__1U5cR .style_help__1sXEA\", \n\"placement\": \"rightBottom\",\n \"title\": \"Tip\", \n\"offsetY\":5,\n\"description\": \"You can find your Vikaby assistant from the \"Help\" icon on the left\", \"children\":\"\" \n}", - "player_step_ui_config_44": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", + "player_step_ui_config_44": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", "player_step_ui_config_45": "", "player_step_ui_config_46": "", "player_step_ui_config_47": "{\n \"element\": \"#DATASHEET_WIDGET_BTN\",\n\"placement\": \"bottomRight\",\n \"title\": \"Widget\", \n\"description\": \"Want to use and view your data in a richer way? Try the widget!\", \"children\":\"\" \n}", "player_step_ui_config_48": "", "player_step_ui_config_49": "{\n \"element\": \".style_widgetPanelContainer__1l2ZV\",\n\"placement\": \"leftCenter\",\n \"title\": \"What is a widget\", \n\"description\": \"Vika widgets are an extended application of vikadata that features in richer data visualization, data transfer, data cleansing, and more. By installing widgets in the widget board, you can make work a lot easier.\", \"children\":\"\" \n}", - "player_step_ui_config_5": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", + "player_step_ui_config_5": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", "player_step_ui_config_50": "{\n \"element\": \".style_widgetModal__eXmdB\",\n\"placement\": \"leftTop\",\n \"title\": \"Widget Center\", \n\"description\": \"Officially recommended and custom widgets are published here. You can install any widget you want onto a dashboard or into a widget board of any datasheet.\", \"children\":\"\" \n}", "player_step_ui_config_51": "{\n \"element\": \".style_widgetModal__eXmdB .style_widgetItem__3Pl-1 button\",\n\"placement\": \"rightBottom\",\n \"title\": \"Install widget\", \n\"description\": \"Let's install this \"Chart\" widget\", \"children\":\"\" \n}", "player_step_ui_config_52": "", @@ -33497,6 +34520,7 @@ "preview_guide_click_to_restart": "下のボタンを押して再度プレビュー", "preview_guide_enable_it": "次のボタンを押してこの機能を開きます", "preview_guide_open_office_preview": "このファイルをプレビューするには、「オフィスプレビュー」機能を開きます", + "preview_next_automation_execution_time": "次の 10 回の実行時間をプレビューする", "preview_not_support_video_codecs": "H.264ビデオコーデック付きMP 4ビデオのみプレビュー可能", "preview_revision": "プレビュー", "preview_see_more": "オフィスファイルプレビュー機能の詳細について知りたいですか?ここをクリックしてください", @@ -33532,6 +34556,7 @@ "privacy_protection": "プライバシー保護", "private_cloud": "プライベートクラウド", "private_external_person_only": "社外ユーザのみ", + "private_help_link": "https://help.aitable.ai/docs/guide/team-and-private-area#private-area", "private_internal_person_only": "社内ユーザのみ", "private_product_point": "ワンクリックで APITable プラットフォームを所有", "privatized_deployment": "自己管理", @@ -33602,13 +34627,15 @@ "reconciled_data": "データの照合", "record": "レコード破り", "record_activity_experience_tips": "${day} 日間のアクティビティの記録を表示できます", + "record_archived_data": "アーカイブされた記録", + "record_chunk_text": "${text} rows, please wait", "record_comment": "コメントのみ", "record_comments": "コメント", "record_fail_data": "データエラー", "record_filter_tips": "このレコードはフィルタされました", "record_functions": "ロギング機能", "record_history": "改訂履歴のみ", - "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-history", + "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-activity", "record_history_title": "レコード履歴", "record_pre_filtered": "このレコードはフィルタされており、レコードの外部をクリックすると非表示になります", "record_pre_move": "レコードの外部をクリックすると、このレコードは別の場所に移動されます", @@ -34048,6 +35075,12 @@ "scan_to_login": "スキャンログイン", "scan_to_login_by_method": "${method} をスキャンして公式アカウントをフォローしてログインしてください", "scatter_chart": "さんぷず", + "schedule_day_tips": "周期の計算は各月の 1 日からカウントされます。 10 日ごとに繰り返すと仮定すると、毎月 1 日、11 日、21 日、31 日にトリガーされます。", + "schedule_hour_tips": "サイクルの計算は毎日午前 0 時 (0:00) に開始されます。 3 時間ごとに 0 分が繰り返されると仮定すると、毎日深夜 (0:00)、午前 3 時、午前 6 時、午前 9 時、正午 (午後 12 時)、午後 3 時、午後 6 時、そして最後に日没 (午後 9 時) に発生します。", + "schedule_start_day": "毎月1日から始まり、", + "schedule_start_month": "毎年1月から毎年、", + "schedule_type": "スケジュールの種類", + "schedule_year_tips": "周期の計算は、各年の最初の月からカウントされます。初日を 3 か月間隔として、毎年 1 月、4 月、7 月、10 月の初日の午前 0 時にトリガーがアクティブになります。", "science_and_technology": "科学と技術", "scroll_screen_down": "画面を下にスクロール", "scroll_screen_left": "画面を左にスクロール", @@ -34061,6 +35094,7 @@ "search_folder_or_sheet": "ファイルを検索する", "search_new_admin": "検索けんさく", "search_node_pleaseholder": "ファイルの検索 (${shortcutKey})", + "search_node_tip": "クイック検索 (${shortcutKey})", "search_or_add": "オプションの検索または追加", "search_role_placeholder": "ロールの検索", "seats": "座席", @@ -34464,6 +35498,7 @@ "space_info": "概要", "space_info_del_confirm1": "1.この共有スペースを削除すると、次のデータが消去されます。", "space_info_del_confirm2": "2.共有スペースは7日後に完全に削除されます。その前に、スペースを復元できます。", + "space_info_del_confirm3": "3. For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "space_info_feishu_desc": "サードパーティ統合を使用しています。共有スペースを削除するには、まずサードパーティ統合を無効にします。", "space_info_feishu_label": "統合", "space_join_apply": "「」スペースへの参加を要求します。", @@ -34550,6 +35585,7 @@ "start_onfiguration": "構成の開始", "start_time": "開始時間", "start_use": "使用開始", + "starting_from_midnight": "毎日午前 0 時 (午前 12 時) から始まり、", "startup": "スタートアップ", "startup_company_support_program": "サポート計画の開始", "stat_average": "へいきん", @@ -34583,6 +35619,8 @@ "stay_tuned_for_more_features": "詳細な機能に注目してください", "steps_choose_reset_mode": "リセット方法の選択", "steps_validate_identities": "認証", + "stop_chunk_content": "Are you sure you want to stop the operation?", + "stop_chunk_title": "Stop", "stop_dingtalk_h5_modal_content": "カスタムアプリケーションは、このスペースからバインドを解除します。確認してください。", "storage_per_seats": "", "storage_per_space": "ストレージの使用状況", @@ -34613,9 +35651,11 @@ "subscribe_credit_usage_over_limit": "現在の空間のポイント数が制限を超えていますので、購読をアップグレードしてください。\n", "subscribe_demonstrate": "デモンストレーションのリクエスト", "subscribe_disabled_seat": "人数は当初の計画を下回ってはならない", + "subscribe_grade_business": "仕事", "subscribe_grade_free": "フリー", "subscribe_grade_plus": "プラス", "subscribe_grade_pro": "プロ", + "subscribe_grade_starter": "スターター", "subscribe_label_tooltip": "高度なスペース機能", "subscribe_new_choose_member": "最大 ${member_num} 人のメンバーをサポート", "subscribe_new_choose_member_tips": "このプランでは 1~${member_num} 名のメンバーがスペースに入場できます", @@ -34752,7 +35792,7 @@ "template_name_repetition_title": "「${templateName}」はすでに存在します。取り替えたいですか?", "template_no_template": "テンプレートなし", "template_not_found": "希望するテンプレートが見つかりませんでしたか?教えて", - "template_recommend_title": "あつい", + "template_recommend_title": "🌟 Hot", "template_type": "テンプレート", "terms_of_service": "<サービス約款>", "terms_of_service_pure_string": "サービス条件", @@ -34796,6 +35836,7 @@ "text_editor_tip_end": "入力(Input)編集の終了", "text_functions": "文字列関数", "thailand": "タイ", + "the_button_field_is_misconfigured": "ボタンフィールドの設定が間違っています。確認してもう一度お試しください。", "the_current_automation_workflow_has_no_related_files_you_can_establish_a_link_by_adding_trigger_conditions_and_actions_on_the_left_side": "現在の自動ワークフローには関連ファイルはありません。左側にトリガ条件と操作を追加することでリンクを確立することができます", "the_current_button_column_has_expired_please_reselect": "現在のボタン列の有効期限が切れています。再選択してください", "the_last_7_days": "過去7日間", @@ -34898,6 +35939,7 @@ "timemachine_update_comment": "コメントを更新しました", "times_per_month_unit": "コール/月", "times_unit": "コール数", + "timing_rules": "タイミング", "timor_leste": "東ティモール", "tip_del_success": "7日以内に共有スペースをリカバリできます", "tip_do_you_want_to_know_about_field_permission": "フィールドデータを暗号化しますか?フィールド権限の理解", @@ -35085,6 +36127,7 @@ "verify_account_title": "アカウントの検証", "verify_via_email": "電子メールによる認証", "verify_via_phone": "SMS認証", + "video": "ビデオ", "video_not_support_play": "現在のビデオフォーマットはオンライン再生をサポートしていません", "vietnam": "ベトナム.", "view": "見方", @@ -35433,7 +36476,8 @@ "workdoc_color_title": "文字の色", "workdoc_create": "ワークドキュメントの作成", "workdoc_expanded": "目次を展開する", - "workdoc_image_max_10mb": "画像サイズは10MBを超えることはできません", + "workdoc_image_max_10mb": "ヌル", + "workdoc_image_max_size": "画像サイズは ${size} を超えることはできません", "workdoc_info": "ワークドキュメント情報", "workdoc_info_create_time": "で作成されました", "workdoc_info_creator": "によって作成された", @@ -35441,6 +36485,7 @@ "workdoc_info_last_modify_time": "最終更新日時", "workdoc_link_placeholder": "リンクを入力してください", "workdoc_only_image": "画像のみ許可されています", + "workdoc_only_video": "動画のみ許可されています", "workdoc_text_placeholder": "「/」を入力してクイックスタート", "workdoc_title_placeholder": "タイトルを入力してください", "workdoc_unnamed": "名前のないワークドキュメント", @@ -35449,9 +36494,11 @@ "workdoc_unsave_ok": "変更を破棄", "workdoc_unsave_title": "WorkDoc は保存されていません", "workdoc_upload_failed": "アップロードに失敗しました", + "workdoc_video_max_size": "動画のサイズは ${size} を超えることはできません", "workdoc_ws_connected": "接続済み", "workdoc_ws_connecting": "接続中...", "workdoc_ws_disconnected": "切断されました", + "workdoc_ws_reconnecting": "再接続中...", "workflow_execute_failed_notify": " で実行できませんでした . 問題のトラブルシューティングを行うには、実行履歴を確認してください。 サポートが必要な場合は、カスタマーサービスチームまでご連絡ください。", "workspace_data": "くうかんデータ", "workspace_files": "ワークベンチデータ", @@ -35630,6 +36677,15 @@ "agreed": "심사비준을 거쳤어", "ai_advanced_mode_desc": "고급 모드를 사용하면 사용자가 프롬프트를 사용자 정의하여 AI 에이전트의 동작과 응답을 더 잘 제어할 수 있습니다.", "ai_advanced_mode_title": "고급 모드", + "ai_agent_anonymous": "익명${ID}", + "ai_agent_conversation_continue_not_supported": "이전 대화를 계속하는 것은 현재 지원되지 않습니다.", + "ai_agent_conversation_list": "대화 목록", + "ai_agent_conversation_log": "대화 기록", + "ai_agent_conversation_title": "대화 제목", + "ai_agent_feedback": "피드백", + "ai_agent_historical_message": "위의 내용은 역사적 메시지입니다.", + "ai_agent_history": "역사", + "ai_agent_message_consumed": "소비된 메시지", "ai_api_curl_template": "## Create chat completions\n\n```bash\n\ncurl -X POST \"{{apiBase}}/fusion/v1/ai/{{aiId}}/chat/completions\" \\n -H \"Content-Type: application/json\" \\n -H \"Authorization: Bearer {{token}}\" \\n -d '{\n \"model\": \"gpt-3.5-turbo\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"You are a helpful assistant.\"\n },\n {\n \"role\": \"user\",\n \"content\": \"Hello!\"\n }\n ]\n }'\n\n```\n\n## Returned data example\n\n```json\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", "ai_api_footer_desc": "웹 사이트에 인공지능 에이전트를 내장하시겠습니까?자세히 알아보기", "ai_api_javascript_template": "## Initialize SDK [![github]({{ githubIcon }})](https://github.com/openai/openai-node)\nAITable's chat completion API is compatible with OpenAI's Node.js SDK. You can use our service with the same SDK by simply changing the configuration as follows:\n\n\n```javascript\nconst { Configuration, OpenAIApi } = require(\"openai\");\nconst configuration = new Configuration({\n apiKey: \"{{token}}\",\n basePath: \"{{apiBase}}/fusion/v1/ai/{{aiId}}\"\n});\n```\n\n## Create chat completions\n\n```javascript\nconst openai = new OpenAIApi(configuration);\nconst chatCompletion = await openai.createChatCompletion({\n model: \"gpt-3.5-turbo\",\n messages: [{role: \"user\", content: \"Hello world\"}],\n});\n```\n\n## Returned data example\n\n```javascript\n\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", @@ -35645,6 +36701,9 @@ "ai_chat_unit": "aibot(s)", "ai_close_setting_tip_content": "변경했습니다.그걸 버리고 싶어?", "ai_close_setting_tip_title": "잎끝", + "ai_copilot_generate_response": "귀하를 위한 답변 생성 중...", + "ai_copilot_processs": "처리 중, 기다려주세요...", + "ai_copilot_start_process_request": "요청 처리 시작 중...", "ai_create_guide_btn_text": "데이터 테이블 선택", "ai_create_guide_content": "AI 에이전트로서 제가 배운 지식에 따라 여러분의 질문에 답할 수 있습니다.대화를 시작하기 전에 기술 자료로 데이터 테이블을 선택하고 학습을 위해 데이터 테이블의 모든 데이터를 읽습니다.", "ai_credit_cost_chart_title": "신용 비용", @@ -35657,7 +36716,7 @@ "ai_credit_time_dimension_year": "올해", "ai_credit_usage_tooltip": "메시지 크레딧은 AI 에이전트 조회에 사용할 수 있습니다. 메시지 크레딧은 스페이스의 좌석 수에 비례합니다.", "ai_data_source_required": "없는", - "ai_data_source_rows": "${row}행 데이터", + "ai_data_source_rows": "${rows}행 데이터", "ai_data_source_update": "사용 가능한 업데이트", "ai_datasheet_panel_create_btn_text": "AI 에이전트 만들기", "ai_default_idk": "잘 모르겠어요", @@ -36113,7 +37172,7 @@ "apps_support": "전체 플랫폼 클라이언트 지원", "archive_delete_record": "보관된 기록 삭제", "archive_delete_record_title": "기록 삭제", - "archive_notice": "

특정 기록을 보관하려고 합니다. 기록을 보관하면 다음과 같은 변경 사항이 발생합니다.

1. 이 기록에 대한 모든 양방향 링크가 취소됩니다.

2. 편집은 지원되지 않습니다.

3. 날짜 알림, 구독 기록 등의 기능은 지원되지 않습니다.

4. 더 이상 조회, 수식 및 기타 필드 계산에 참여하지 않습니다.

너 정말 계속하고 싶니? (고급의 보관함에서 보관을 취소할 수 있습니다)

", + "archive_notice": "

특정 기록을 보관하려고 합니다. 기록을 보관하면 다음과 같은 변경 사항이 발생합니다.

1. 편집은 지원되지 않습니다.

2. 날짜 알림, 구독 기록 등의 기능은 지원되지 않습니다.

3. 더 이상 조회, 수식 및 기타 필드 계산에 참여하지 않습니다.

너 정말 계속하고 싶니? (고급의 보관함에서 보관을 취소할 수 있습니다)

", "archive_record_in_activity": "이 레코드를 보관했습니다.", "archive_record_in_menu": "아카이브 레코드", "archive_record_success": "레코드가 성공적으로 아카이브되었습니다.", @@ -36173,6 +37232,8 @@ "audit_add_field_role_detail": "\"\" 데이터시트 에서 [] 필드 [] 에 대한 [] 역할 ", "audit_add_node_role": "파일 권한 추가", "audit_add_node_role_detail": "파일 권한 추가, 「${unitNames}」를 「 ${currentNodeName}」의 「${role}」 로 설정", + "audit_add_node_role_detail_end": "to「${role}", + "audit_add_node_role_detail_start": "Add file node permission,set「${unitNames}」", "audit_admin_permission_change_event": "관리자 권한 변경", "audit_create_template": "템플릿 만들기", "audit_create_template_detail": "템플릿 만들기", @@ -36181,20 +37242,30 @@ "audit_delete_field_role_detail": "감사", "audit_delete_node_role": "파일 삭제 권한", "audit_delete_node_role_detail": "파일 권한 삭제,「${unitNames}」의 「${role}」 역할 「${currentNodeName}」 삭제", + "audit_delete_node_role_detail_end": "at 「${role}」role", + "audit_delete_node_role_detail_start": "Delete file node permission,delete「${unitNames}」from", "audit_delete_template": "템플릿 삭제", "audit_delete_template_detail": "템플릿 삭제", "audit_disable_field_role": "필드 사용 권한 사용 안 함", "audit_disable_field_role_detail": "감사", "audit_disable_node_role": "파일 사용 권한 사용 안 함", "audit_disable_node_role_detail": "${nodeType} 「${currentNodeName}」 ` 권한 비활성화", + "audit_disable_node_role_detail_end": "`s permission", + "audit_disable_node_role_detail_start": "Disable ${nodeType}", "audit_disable_node_share": "파일 공통 링크 닫기", "audit_disable_node_share_detail": "${nodeType} 「${currentNodeName}」 공개 링크 닫기", + "audit_disable_node_share_detail_end": "public link", + "audit_disable_node_share_detail_start": "Close ${nodeType}", "audit_enable_field_role": "필드 사용 권한 사용", "audit_enable_field_role_detail": "감사", "audit_enable_node_role": "파일 사용 권한 사용", "audit_enable_node_role_detail": "${nodeType} 「${currentNodeName}」 ` 권한 활성화", + "audit_enable_node_role_detail_end": "`s permission", + "audit_enable_node_role_detail_start": "Enable ${nodeType}", "audit_enable_node_share": "파일 공통 링크 열기", "audit_enable_node_share_detail": "${nodeType} 「${currentNodeName}」 공개 링크 열기", + "audit_enable_node_share_detail_end": "public link", + "audit_enable_node_share_detail_start": "Open ${nodeType}", "audit_login_event": "로그인 이벤트", "audit_logout_event": "영어", "audit_organization_change_event": "담당자의 조직 구조 변경", @@ -36215,18 +37286,25 @@ "audit_space_invite_user_detail": "감사", "audit_space_node_copy": "중복된 파일", "audit_space_node_copy_detail": "${nodeType} 「${sourceNodeName}」 복제, 새 파일 이름은 「${currentNodeName}」", + "audit_space_node_copy_detail_start": "Duplicate ${nodeType} 「${sourceNodeName}」, the new file node's name is", "audit_space_node_create": "파일 만들기", "audit_space_node_create_detail": "「${currentNodeName}」 이라는 이름의 ${nodeType} 생성", + "audit_space_node_create_detail_start": "Create a ${nodeType} named", "audit_space_node_delete": "파일 삭제", "audit_space_node_delete_detail": "「${currentNodeName}」 이름의 ${nodeType} 삭제", + "audit_space_node_delete_detail_start": "Delete ${nodeType} named", "audit_space_node_export": "데이터 테이블 내보내기", "audit_space_node_export_detail": "${member_name} 구성원이 ${node_name} 데이터시트를 내보냈습니다.", "audit_space_node_import": "파일 가져오기", "audit_space_node_import_detail": "「${nodeName}」 파일 가져오기", + "audit_space_node_import_detail_start": "Import a file node named", "audit_space_node_move": "파일 이동", "audit_space_node_move_detail": "${nodeType} 「${currentNodeName}」을 「${parentName}」 폴더로 이동", + "audit_space_node_move_detail_end": "to the folder「${parentName}」", + "audit_space_node_move_detail_start": "Move ${nodeType}", "audit_space_node_rename": "파일 이름 바꾸기", "audit_space_node_rename_detail": "${nodeType} 「${oldNodeName}」의 이름을 「${nodeName}」 으로 변경", + "audit_space_node_rename_detail_start": "Rename ${nodeType} 「${oldNodeName}」to", "audit_space_node_sort": "감사", "audit_space_node_sort_detail": "감사", "audit_space_node_update_cover": "감사", @@ -36241,17 +37319,24 @@ "audit_space_rubbish_node_delete_detail": "감사", "audit_space_rubbish_node_recover": "파일 복원", "audit_space_rubbish_node_recover_detail": "${nodeType} 「${currentNodeName}」을 (를) 휴지통에서 복원", + "audit_space_rubbish_node_recover_detail_end": "from the trash", + "audit_space_rubbish_node_recover_detail_start": "Restore ${nodeType}", "audit_space_template_event": "템플릿 변경 내용", "audit_space_update_logo": "감사", "audit_space_update_logo_detail": "감사", "audit_store_share_node": "공유 파일 저장", "audit_store_share_node_detail": "${nodeType}을 공간으로 복원, 이름은 「${nodeName}」", + "audit_store_share_node_detail_start": "Restore ${nodeType} to the space, name is", "audit_update_field_role": "감사", "audit_update_field_role_detail": "감사", "audit_update_node_role": "파일 권한 수정", "audit_update_node_role_detail": "파일 권한 수정, 「${unitNames}」의 역할을 「 ${currentNodeName}」의 「${role}」 로 수정", + "audit_update_node_role_detail_end": "to「${role}」role", + "audit_update_node_role_detail_start": "Modify file node permission,modify「${unitNames}」from", "audit_update_node_share_setting": "파일 공통 링크 설정 수정", "audit_update_node_share_setting_detail": "${nodeType} 「${currentNodeName}」 공개 링크 수정", + "audit_update_node_share_setting_detail_end": "public link settings", + "audit_update_node_share_setting_detail_start": "Modify ${nodeType}", "audit_user_login": "사용자 로그인", "audit_user_login_detail": "감사", "audit_user_logout": "사용자 로그아웃", @@ -36293,6 +37378,7 @@ "automation_enabled_return_via_related_files": "자동화가 활성화되었습니다. 새 버튼을 사용하려면 \"관련 파일\"을 통해 원본 테이블을 다시 입력하세요.", "automation_field": "필드", "automation_import_variables_from_pre_tep": "사전 단계에서 데이터 가져오기", + "automation_is_not_yet_enabled": "자동화가 아직 활성화되지 않았습니다. 활성화하고 다시 시도하십시오.", "automation_last_edited_by": "최종 편집자:", "automation_last_edited_time": "마지막으로 편집한 시간", "automation_manager_label": "자동화에 대한 모든 작업을 수행할 수 있습니다.", @@ -36318,6 +37404,7 @@ "automation_runs_this_month": "이번 달에 실행", "automation_stay_tuned": "계속 지켜봐 주시기 바랍니다", "automation_success": "성공", + "automation_tips": "버튼 필드가 잘못 구성되었습니다. 확인하고 다시 시도해 주세요.", "automation_updater_label": "자동화의 실행 기록을 볼 수 있습니다.", "automation_variabel_empty": "사전 단계에서 사용할 수 있는 데이터가 없습니다. 조정 후 다시 시도해 주세요.", "automation_variable_datasheet": "${NODE_NAME}에서 데이터 가져오기", @@ -36353,6 +37440,7 @@ "bermuda": "버뮤다 제도", "bhutan": "부탄", "billing_over_limit_tip_common": "공간 사용량이 한도를 초과했으며, 업그레이드 후 더 많은 양을 즐기실 수 있습니다.", + "billing_over_limit_tip_forbidden": "평가판 기간 또는 구독 기간이 만료되었습니다. 갱신하려면 영업 컨설턴트에게 문의하세요.", "billing_over_limit_tip_widget": "위젯 설치 수가 한도를 초과했습니다. 업그레이드하여 사용량을 늘릴 수 있습니다.", "billing_period": "청구 기간: ${period}", "billing_subscription_warning": "기능 경험", @@ -36412,10 +37500,19 @@ "button_text": "버튼 텍스트", "button_text_click_start": "시작하려면 클릭하세요", "button_type": "버튼 유형", + "by_at": "~에", + "by_days": "날", + "by_every": "모든", "by_field_id": "필드 ID 사용", + "by_hours": "시간", + "by_in": "~에", + "by_min": "분)", + "by_months": "개월", + "by_on": "에", "by_the_day": "일별", "by_the_month": "월간", "by_the_year": "매년의", + "by_weeks": "주", "calendar_add_date_time_field": "만든 날짜 필드", "calendar_color_more": "추가 색상", "calendar_const_detail_weeks": "[\"월요일\",\"화요일\",\"수요일\",\"목요일\",\"금요일\",\"토요일\",\"일요일\"]", @@ -36479,6 +37576,14 @@ "cannot_activate_space_by_space_limit": "공간 경계를 활성화할 수 없음", "cannot_join_space": "당신은 이미 10개의 우주 정거장의 최대 할당량을 초과했기 때문에 새로운 우주 정거장에 가입할 수 없습니다.", "cannot_switch_field_permission": "필드 사용 권한을 파일 사용 권한 이상으로 설정합니다.", + "capacity_file_detail_desc": "The total number of file nodes within the Space is calculated by adding the file nodes from the Team to the file nodes created by each member in their Private. Not enough capacity?", + "capacity_file_detail_title": "File Capacity", + "capacity_file_member": "Member", + "capacity_file_member_private_node_count": "Private", + "capacity_file_member_private_percent": "Percent", + "capacity_file_member_team": "Team", + "capacity_file_member_team_node_count": "Team", + "capacity_file_upgrade": "Click to upgrade your Space", "capacity_from_official_gift": "공식 선물", "capacity_from_participation": "${user}님을 초대하여 공간에 참여", "capacity_from_purchase": "구매 능력별", @@ -36515,6 +37620,8 @@ "catalog": "탐색자", "catalog_add_from_template_btn_title": "템플릿에서 추가", "catalog_empty_tips": "이 작업공간이 비어 있습니다.템플릿을 사용하여 파일 작성을 시작합니다.", + "catalog_private": "Private", + "catalog_team": "Team", "category_blank": "[공백]", "catering": "음식", "cayman_islands": "케이맨 제도", @@ -36583,6 +37690,7 @@ "choose_type_of_vika_field": "필드 유형 선택", "choose_your_own_space": "(작성자로 사용자 공간에 저장만 지원)", "chose_new_primary_admin_button": "할당", + "chunk_stopping_title": "Stopping", "claim_special_offer": "이 특별 할인 신청!", "clear": "명확했어", "clear_all_fields": "모두 지우기", @@ -36713,6 +37821,7 @@ "confirm_del_current_team": "팀을 삭제하시겠습니까?", "confirm_delete": "확인 및 삭제", "confirm_delete_node_name_as": "\"${nodeNameDiv}\"을(를) 삭제하시겠습니까?", + "confirm_delete_private_node_name_as": "Are you sure you want to delete \"${nodeNameDiv}\"? The file will be deleted from the Space and the trash.", "confirm_delete_space_btn": "스페이스 확인 및 삭제", "confirm_exit": "종료 확인", "confirm_exit_space_with_name": "\"${spaceNameDiv}\" 공간 종료 여부 확인", @@ -36750,6 +37859,14 @@ "convert": "변환", "convert_tip": "이 작업은 일부 셀의 데이터를 지울 수 있습니다.예기치 않은 상황이 발생하면 작업을 취소할 수 있습니다.", "cook_islands": "쿡 제도", + "copilot_auto_agent_desc": "어떤 에이전트를 선택해야 할지 모르시나요? AutoAgent를 사용해 보세요.", + "copilot_auto_agent_name": "자동 에이전트", + "copilot_data_agent_desc": "귀하의 의견을 기반으로 데이터 분석/시각화를 생성합니다.", + "copilot_data_agent_name": "데이터 에이전트", + "copilot_data_agent_policy": "Copilot과 채팅할 때 사용자 약관 정책에 동의하는 것으로 간주됩니다.", + "copilot_data_agent_policy_button": "정책", + "copilot_help_agent_desc": "AITable의 도움말 센터 문서에 관한 모든 것을 물어보세요.", + "copilot_help_agent_name": "도움말 센터 검색", "copy": "복제", "copy_automation_url": "URL 복사", "copy_card_link": "레코드 URL 복사", @@ -36794,6 +37911,7 @@ "create_mirror_guide_content": "미러 기능에는 특정 데이터를 숨길 수 있는 기능이 있습니다. 원본 데이터시트 보기에서 \"필터 조건\" 및 \"숨겨진 필드\"를 설정하여 미러에 표시되는 레코드와 필드를 제어할 수 있습니다.\n
\n
\n\"보기 잠금\" 기능과 함께 사용하면 다른 사람이 수정하는 것을 방지할 수 있습니다.\n
\n
\n또한 \"원래 테이블>숨겨진 필드\"로 이동하여 \"미러에 모든 필드 표시\" 구성을 수정할 수 있습니다.", "create_mirror_guide_title": "미러링은 일부 레코드 및 필드를 숨깁니다.", "create_new_button_field": "새 버튼 열 필드 만들기", + "create_private_node_tip": "Personal or temporary draft documents can be created here ${link}", "create_public_invitation_link": "공개 초대 링크 만들기", "create_space_sub_title": "안녕하세요, 공유 공간의 이름을 지어주세요 ~", "create_team_fail": "팀 생성 실패", @@ -36857,10 +37975,12 @@ "custom_enterprise": "사용자 정의 엔터프라이즈 공간", "custom_function_development": "맞춤형 기능 개발", "custom_grade_desc": "에이전트 배포, 개인 설치, 지원 및 맞춤형 전문 서비스 제공", + "custom_page_setting_title": "Add a custom page", "custom_picture": "사용자 정의 그림", "custom_style": "스타일", "custom_upload": "사용자 지정 업로드", "custom_upload_tip": "1: 1 정사각형 크기의 이미지를 사용하여 보다 나은 시청 환경을 제공하는 것이 좋습니다.", + "custome_page_title": "Custom Web", "cut_cell_data": "셀 잘라내기", "cyprus": "키프로스", "czech": "체코의", @@ -36912,6 +38032,7 @@ "default": "위약", "default_create_ai_chat_bot": "새로운 AI 에이전트", "default_create_automation": "새로운 자동화", + "default_create_custom_page": "새로운 사용자 정의 페이지", "default_create_dashboard": "새 대시보드", "default_create_datasheet": "새 데이터 테이블", "default_create_file": "새 파일", @@ -36933,6 +38054,7 @@ "del_invitation_link": "초대 링크 삭제", "del_invitation_link_desc": "삭제 후 링크가 유효하지 않습니다.", "del_space_now": "스페이스 영원히 삭제", + "del_space_now_confirm_tip": "For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "del_space_now_tip": "삭제 후 공간을 복원할 수 없습니다.모든 파일과 첨부 파일이 삭제됩니다.", "del_space_res_tip": "삭제된 공간", "del_team_success": "팀 삭제 성공", @@ -37128,6 +38250,62 @@ "embed_error_page_help": "자세한 내용", "embed_fail_og_description_content": "이 포함된 공용 링크는 비활성화되어 당분간 사용할 수 없습니다.", "embed_failed": "포함된 링크를 사용할 수 없습니다.", + "embed_link_bilibili": "빌리빌리", + "embed_link_bilibili_desc": "bilibili 동영상을 삽입하면 튜토리얼, 가이드를 시청하거나 Vika에서 채널 홈페이지를 볼 수 있습니다.", + "embed_link_bilibili_link_text": "bilibili 비디오를 삽입하는 방법", + "embed_link_bilibili_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-bilibili-video", + "embed_link_default": "아무것", + "embed_link_default_desc": "웹사이트를 보려면 링크를 붙여넣으세요.", + "embed_link_default_link_text": "더 알아보기", + "embed_link_default_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_link_figma": "Figma", + "embed_link_figma_desc": "Figma 파일을 내장함으로써 회원들은 디자인 초안을 보다 편리하게 보고 편집할 수 있어 협업 효율성이 향상됩니다.", + "embed_link_figma_link_text": "Figma 파일을 삽입하는 방법", + "embed_link_figma_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-figma-file", + "embed_link_google_docs": "Docs", + "embed_link_google_docs_desc": "Google Docs를 삽입하면 AITable에서 문서를 편집하고 볼 수 있어 팀 협업이 용이해집니다.", + "embed_link_google_docs_link_text": "Google 문서를 삽입하는 방법", + "embed_link_google_docs_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-docs-file", + "embed_link_google_sheets": "Sheets", + "embed_link_google_sheets_desc": "Google 스프레드시트를 삽입하면 AITable에서 테이블을 편집하고 볼 수 있어 팀 공동작업이 용이해집니다.", + "embed_link_google_sheets_link_text": "Google 스프레드시트를 삽입하는 방법", + "embed_link_google_sheets_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-sheets-file", + "embed_link_jishi_design": "JS디자인", + "embed_link_jishi_design_desc": "JSdesign 파일을 내장함으로써 구성원은 디자인 초안을 보다 편리하게 보고 편집할 수 있어 협업 효율성이 향상됩니다.", + "embed_link_jishi_design_link_text": "JSdesign 파일을 삽입하는 방법", + "embed_link_jishi_design_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-js-design-file", + "embed_link_tencent_docs": "텐센트 문서", + "embed_link_tencent_docs_desc": "Tencent Docs를 내장하면 Vika에서 Tencent 문서를 편집하고 볼 수 있어 협업 효율성이 향상됩니다.", + "embed_link_tencent_docs_link_text": "Tencent Docs를 삽입하는 방법", + "embed_link_tencent_docs_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-tencent-docs", + "embed_link_wps": "WPS", + "embed_link_wps_desc": "WPS 파일을 삽입하면 Vika에서 WPS 문서, 표, 양식을 편집하고 볼 수 있어 협업 효율성이 향상됩니다.", + "embed_link_wps_link_text": "WPS 파일을 삽입하는 방법", + "embed_link_wps_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-wps-file", + "embed_link_youtube": "유튜브", + "embed_link_youtube_desc": "YouTube 동영상을 삽입하면 튜토리얼, 가이드를 시청하거나 AITable에서 채널 홈페이지를 볼 수 있습니다.", + "embed_link_youtube_link_text": "YouTube 동영상을 삽입하는 방법", + "embed_link_youtube_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-youtube-video", + "embed_page": "사용자 정의 페이지", + "embed_page_add_url": "URL 추가", + "embed_page_doc_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_page_function_desc": "제3자 웹사이트 문서, 비디오 등에 쉽게 액세스하려면 ${edition}에 웹페이지를 추가하세요. 추천 웹사이트 링크나 사용자 정의 링크를 추가할 수 있습니다.", + "embed_page_node_permission_editor": "\"업데이트 전용\"을 기준으로 파일의 공개 공유도 열 수 있습니다.", + "embed_page_node_permission_manager": "파일에 대한 모든 작업을 수행할 수 있습니다.", + "embed_page_node_permission_reader": "사용자 정의 페이지의 내용과 기본 파일 정보를 볼 수 있습니다.", + "embed_page_node_permission_updater": "\"읽기 전용\"을 기반으로 사용자 정의 페이지의 링크를 수정할 수도 있습니다.", + "embed_page_setting_title": "사용자 정의 페이지 추가", + "embed_page_url_invalid": "올바른 URL을 입력하세요.", + "embed_paste_link_bilibili_placeholder": "bilibili 비디오 링크 붙여넣기", + "embed_paste_link_default_placeholder": "URL을 붙여넣으세요", + "embed_paste_link_figma_placeholder": "Figma 파일의 공유 링크를 붙여넣으세요.", + "embed_paste_link_google_docs_placeholder": "Google Docs 공유 링크를 붙여넣으세요.", + "embed_paste_link_google_sheets_placeholder": "Google Sheets 공유 링크를 붙여넣으세요.", + "embed_paste_link_jsdesign_placeholder": "JSdesign 파일의 공유 링크를 붙여넣으세요.", + "embed_paste_link_tencent_docs_placeholder": "Tencent Docs 공유 링크를 붙여넣으세요.", + "embed_paste_link_wps_placeholder": "WPS 파일의 공유 링크를 붙여넣으세요.", + "embed_paste_link_youtube_placeholder": "YouTube 동영상 링크 붙여넣기", + "embed_success": "추가가 성공했습니다.", "emoji_activity": "활동", "emoji_custom": "풍속", "emoji_flags": "깃발", @@ -37234,6 +38412,11 @@ "estonia": "에스토니아", "ethiopia": "에티오피아", "event_planning": "행사 기획", + "every": "모든", + "every_day_at": "일(들)", + "every_hour_at": "시간", + "every_month_at": "월", + "every_week_at": "매주", "everyday_life": "일상 생활", "everyone_visible": "모두에게 보여요", "exact_date": "정확한 날짜", @@ -37244,6 +38427,7 @@ "exchange": "되찾다", "exchange_code_times_tip": "참고: 교환코드는 한 번만 사용할 수 있습니다.", "exclusive_consultant": "독점 V+ 컨설턴트", + "exclusive_limit_plan_desc": "독점적인 한정 등급", "exist_experience": "종료 경험", "exits_space": "스페이스 종료", "expand": "확대", @@ -37270,7 +38454,7 @@ "expired": "만기", "export": "내보내는 중...", "export_brand_desc": "기술 지원", - "export_current_preview_view_data": "", + "export_current_preview_view_data": "Export current preview view data", "export_gantt_button_tips": ".png 파일로 내보내기", "export_gantt_chart": "Gantt 차트 내보내기", "export_to_excel": "데이터 내보내기", @@ -37841,26 +39025,26 @@ "gantt_config_color_by_single_select_pleaseholder": "선택 필드 선택", "gantt_config_color_help": "설정 방법", "gantt_config_friday": "금요일", - "gantt_config_friday_in_bar": "금요일", + "gantt_config_friday_in_bar": "금", "gantt_config_friday_in_select": "금요일", "gantt_config_monday": "월요일", - "gantt_config_monday_in_bar": "월요일", + "gantt_config_monday_in_bar": "월", "gantt_config_monday_in_select": "월요일", "gantt_config_only_count_workdays": "기간은 근무일만 계산됩니다.", "gantt_config_saturday": "토요일", - "gantt_config_saturday_in_bar": "토요일", + "gantt_config_saturday_in_bar": "토", "gantt_config_saturday_in_select": "토요일", "gantt_config_sunday": "일요일", - "gantt_config_sunday_in_bar": "일요일", + "gantt_config_sunday_in_bar": "일", "gantt_config_sunday_in_select": "일요일", "gantt_config_thursday": "목요일", - "gantt_config_thursday_in_bar": "청화대학", - "gantt_config_thursday_in_select": "청화대학", + "gantt_config_thursday_in_bar": "목", + "gantt_config_thursday_in_select": "목요일", "gantt_config_tuesday": "화요일", - "gantt_config_tuesday_in_bar": "화요일", + "gantt_config_tuesday_in_bar": "화", "gantt_config_tuesday_in_select": "화요일", "gantt_config_wednesday": "수요일", - "gantt_config_wednesday_in_bar": "수요일", + "gantt_config_wednesday_in_bar": "수", "gantt_config_wednesday_in_select": "수요일", "gantt_config_weekdays_range": "${weekday} ~ ${weekday}", "gantt_config_workdays_a_week": "표준 근무일 사용자 지정", @@ -37942,6 +39126,7 @@ "gold_grade": "킴", "gold_grade_desc": "비즈니스 프로세스가 복잡한 팀을 위한 설계", "gold_seat_200_desc": "200", + "gold_seat_300_desc": "300", "golden_grade": "킴", "got_it": "알았어", "got_v_coins": "보상 V코인", @@ -37975,6 +39160,8 @@ "guests_per_space": "각 공간의 손님", "guide_1": "啊这", "guide_2": "기본 기능을 학습하는 데 몇 분밖에 걸리지 않습니다.이 순간부터 생산성 향상!", + "guide_flow_modal_contact_sales": "영업팀에 문의", + "guide_flow_modal_get_started": "시작하다", "guide_flow_of_catalog_step1": "Space의 모든 폴더와 파일이 저장된 작업 디렉토리입니다.", "guide_flow_of_catalog_step2": "작업 디렉토리에서 필요에 따라 데이터 테이블이나 폴더를 만들 수 있습니다.", "guide_flow_of_click_add_view_step1": "일부 기본 보기 외에 그림 형식의 첨부 파일이 있으면 앨범 보기를 만드는 것이 좋습니다.", @@ -38153,6 +39340,7 @@ "intro_widget_tips": "위젯이란 무엇입니까?", "introduction": "소개", "invalid_action_sort_tip": "그룹 필드로서 정렬이 설정되어 있습니다.현재 주문에 대한 설정은 적용되지 않습니다.", + "invalid_automation_configuration": "자동화 구성이 잘못되었습니다. 확인하고 다시 시도해 주세요.", "invalid_field_type": "잘못된 필드 유형", "invalid_option_sort_tip": "그룹 필드로서 정렬이 설정되어 있습니다.", "invalid_redemption_code_entered": "잘못된 교환 코드", @@ -38283,6 +39471,9 @@ "label_format_day_month_and_year_split_by_slash": "일 / 월 / 년", "label_format_month": "월", "label_format_month_and_day_split_by_dash": "년 월 일", + "label_format_month_day_year_split_by_dash": "Month-Day-Year", + "label_format_month_day_year_split_by_slash": "Month/Day/Year", + "label_format_month_day_year_two_digit_year_split_by_slash": "Month/Day/Year (Two-digit year)", "label_format_year": "년", "label_format_year_and_month_split_by_dash": "년 월", "label_format_year_month_and_day_split_by_dash": "년 월 일", @@ -38361,6 +39552,7 @@ "lark_version_enterprise": "Lark의 엔터프라이즈 프로그램", "lark_version_standard": "Lark 표준 평면도", "lark_versions_free": "Lark의 기본 평면도", + "last_day": "마지막 날", "last_modified_by_select_modal_desc": "아래에서 선택한 필드를 편집하면 최근에 편집한 구성원이 마지막으로 편집한 필드에 표시됩니다.", "last_modified_time_select_modal_desc": "아래에서 선택한 필드를 편집하면 가장 최근에 편집한 시간이 마지막으로 편집한 시간 필드에 표시됩니다.", "last_step": "반환", @@ -38505,7 +39697,7 @@ "mail_invite_fail": "메일 초대가 성공했습니다.", "mail_invite_success": "메일 초대가 성공했습니다.", "main_admin_name": "관리자 이름", - "main_admin_page_desc": "관리자는 하위 관리자 및 이전 공간의 소유권과 같은 공간에 완전히 액세스할 수 있습니다.", + "main_admin_page_desc": "관리자는 구성원 관리, 공간 설정 관리 등 공간에 대한 모든 액세스 권한을 갖습니다.", "main_contain": "주요 내용", "malawi": "말라위", "malaysia": "말레이시아", @@ -38725,8 +39917,12 @@ "more_widget": "추가 가젯", "morocco": "모로코", "move": "이동", + "move_datasheet_link_warn": "Cannot be moved to Team Area alone, because there is a two-way link from the current datasheet to another datasheet, it is recommended to put them in a folder and then move them", "move_favorite_node_fail": "노드 이동에 실패했습니다.목록이 자동으로 업데이트됩니다.", + "move_folder_link_warn": "Cannot be moved to Team Area because the files in the current folder are linked to files outside the folder (may be two-way links or linked by forms, etc.) We recommend that they be placed in a folder before moving", "move_node_modal_content": "이동하면 상위 폴더의 파일 가시성에 영향을 받을 수 있습니다.", + "move_other_link_no_permission": "Unable to move to the corresponding folder because you do not have administrative rights to the folder", + "move_other_link_warn": "It is not allowed to move ${node type} to Team Area alone, because it connects to the datasheet of Private Area, it is recommended to put them in a folder before moving them", "move_to": "다음으로 이동", "move_to_error_equal_parent": "파일은 현재 폴더 아래에 있습니다.다른 폴더를 선택하십시오.", "move_to_modal_title": "[${name}]을(를) 다음으로 이동", @@ -38757,7 +39953,9 @@ "new_a_line": "Shift+Enter 키: 줄 바꿈", "new_automation": "새로운 자동화", "new_caledonia": "뉴칼레도니아", + "new_custom_page": "New custom page", "new_datasheet": "새 데이터 테이블", + "new_ebmed_page": "새로운 사용자 정의 페이지", "new_folder": "새 폴더", "new_folder_btn_title": "폴더", "new_folder_tooltip": "폴더 만들기", @@ -38923,7 +40121,7 @@ "nvc_start_text": "막대를 오른쪽 끝으로 드래그", "nvc_yes_text": "입증된", "obtain_verification_code": "인증 코드가 검색되지 않았거나 만료되었습니다.", - "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrzw0miJVmSkJ7eBBa9k/fomx5qPX0JGPFvfEEP\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", + "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrCvbFC53xc3kl00B4Pg\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", "offical_website_nav_data": "[{\n \"name\": \"产品\",\n \"href\": \"/login\",\n \"children\": [\n {\n \"name\": \"vika维格表 Overview\",\n \"href\": \"/login/\"\n },\n {\n \"name\": \"应用连接 Integration\",\n \"href\": \"/connections/\"\n },\n {\n \"name\": \"客户端(Beta) Download\",\n \"href\": \"/download/\"\n }\n ]\n}, {\n \"name\": \"解决方案\",\n \"href\": \"/\",\n \"children\": [{\n \"name\": \"PMO项目群管理\",\n \"href\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"href\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"href\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"href\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"href\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"href\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"href\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"href\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"href\": \"/shop/\"\n }, {\n \"name\": \"更多解决方案 >\",\n \"href\": \"/solutions/\"\n }]\n}, {\n \"name\": \"模板/案例\",\n \"href\": \"/template\",\n \"children\": [\n {\n \"name\": \"模板中心 Tempaltes\",\n \"href\": \"/template\"\n },\n {\n \"name\": \"客户案例 Customers\",\n \"href\": \"/cases/\"\n }\n ]\n},\n {\n \"name\": \"首页\",\n \"href\": \"/?home=1\"\n },\n {\n \"name\": \"学习资源\",\n \"href\": \"https://edu.vika.cn/index\",\n \"children\": [\n {\n \"name\": \"快速入门 Tutorials\",\n \"href\": \"https://help.vika.cn/docs/guide/tutorial\"\n },\n {\n \"name\": \"产品手册 Manual\",\n \"href\": \"https://help.vika.cn/docs/guide/manual\"\n },\n {\n \"name\": \"维格课堂 Vika Education\",\n \"href\": \"https://edu.vika.cn/\"\n },\n {\n \"name\": \"维格社区 Vika BBS\",\n \"href\": \"https://bbs.vika.cn/\"\n },\n {\n \"name\": \"第三方连接 Integration\",\n \"href\": \"https://help.vika.cn/docs/guide/connection\"\n },\n {\n \"name\": \"开发者中心 Developer Center\",\n \"href\": \"/developers/\"\n },\n {\n \"name\": \"常见问题 FAQ\",\n \"href\": \"https://help.vika.cn/docs/guide/questions\"\n }\n ]\n }]", "office_preview": "Office 파일 미리 보기", "office_preview_app_desc": "

Smooth online preview of office files on datasheet, allowing you to view common office files such as Excel, Word, PPT, etc. on your desktop or mobile anywhere, anytime

\n\n
    \n
  • Online preview of .doc, .docx, .xls, .xlsx, .ppt, .pptx, and .pdf formatted office files
  • \n
  • Desktop and mobile both support file previews of the above formats
  • \n
\n\n

Additional notes:

\n
    \n
  • This feature is powered by \"Yoncentric Cloud Conversion\" and officially integrated
  • \n
  • Click the \"Enable\" button below to enable this integration and agree that \"Yoncentric Cloud Conversion\" reads the office files you want to preview
  • \n
  • If you no longer need the office files preview feature, the space admin can disable it on this page
  • \n
", @@ -38963,6 +40161,7 @@ "open_auto_save_success": "자동 저장 뷰가 성공적으로 열렸습니다.", "open_auto_save_warn_content": "이 뷰의 모든 변경 사항은 자동으로 저장되고 다른 구성원과 동기화됩니다.", "open_auto_save_warn_title": "뷰 자동 저장 사용", + "open_automation_time_arrival": "https://aitable.ai/contact-sales-open-source", "open_failed": "열기 실패", "open_in_new_tab": "새 탭에서 열기", "open_invite_after_operate": "열면 모든 구성원이 연락처 패널에서 새 구성원을 초대할 수 있습니다.", @@ -39109,6 +40308,8 @@ "payment_record": "결제 기록", "payment_reminder": "결제 팁", "payment_reminder_content": "선택한 새 플랜은 지불해야 하는 금액보다 더 많은 공제액이 있습니다. 기간이 더 긴 새 요금제를 선택하는 것이 좋습니다. 이를 확인하면 초과 금액은 환불되지 않습니다. ${action} 의심스러운 경우", + "payment_reminder_modal_content": "고급 버전을 사용하면 더 많은 파일 노드, 기업 권한, 첨부 용량, 데이터 볼륨, AI 및 기타 고급 기능과 권한을 누릴 수 있습니다.", + "payment_reminder_modal_title": "현재 무료 버전을 사용하고 계십니다", "pending_invite": "보류된 초대", "people": "구성원", "per_person_per_year": "매인당 매년", @@ -39278,7 +40479,7 @@ "player_step_ui_config_168": "{\n\"templateKey\":\"createMirrorTip\"\n}", "player_step_ui_config_169": "{ \"headerImg\": \"https://s4.vika.cn/space/2023/04/04/bcf0695cf35840e6b85e032a8e5ea0a1\", \"readMoreUrl\": \"https://help.vika.cn/changelog/23-04-10- 업데이트\", \"어린이\": \"

🚀 새로운 기능 소개

\\N
  • 새로운 필드 유형 \"캐스케이더\"가 출시되어 양식의 옵션 계층 구조에서 더 쉽게 선택할 수 있습니다.
  • \"스크립트\" 위젯이 출시되었습니다. 더 적은 코드로 더 많은 사용자 정의 가능
  • 자동화를 실행하여 이메일을 보내고 빠른 알림 받기
  • 자동화를 실행하여 Slack에 메시지를 보내고 적시에 팀에 알립니다.
  • AI 탐색: \"GPT 콘텐츠 생성기\" 위젯 출시
\" }", "player_step_ui_config_17": "{\n \"element\": \"#TEMPLATE_CENTER_USE_TEMPLATE_BTN>button\", \n\"placement\": \"rightBottom\",\n\"offsetY\": 20,\n \"title\": \"How to use a template\", \n\"description\": \"Click the button on the left to use the template\", \"children\":\"\" \n}", - "player_step_ui_config_176": "{\"title\":\"AI 프록시 프로필\",\"video\":\"https://www.youtube.com/embed/cjds1r_roG8?si=irKUpMhwDlOEb8Hc\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", + "player_step_ui_config_176": "{\"title\":\"AITable.ai DEMO\",\"video\":\"https://www.youtube.com/embed/kGxMyEEo3OU\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", "player_step_ui_config_18": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select>.ant-select-selector\", \n\"placement\": \"bottomLeft\",\n \"title\": \"How to use a template\", \n\"description\": \"Select where to put the template\", \"children\":\"\" \n}", "player_step_ui_config_19": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select .ant-select-selector\"\n}", "player_step_ui_config_2": "{\n \"config\": [\n {\n \"key\": 1,\n \"name\": \"answer1\",\n \"title\": \"What kind of issues are you looking forward to solved by vikadata?\",\n \"type\": \"checkbox\",\n \"answers\": [\n \"Work Planning\",\n \"Customer Service\",\n \"Project Management\",\n \"Sourcing Supply\",\n \"Content Production\",\n \"E-commerce operation\",\n \"Event Planning\",\n \"Human Resources\",\n \"Administration\",\n \"Financial Management\",\n \"Webcast\",\n \"Educational institutes Management\",\n \"Other\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 2,\n \"name\": \"answer2\",\n \"title\": \"Your job title is______\",\n \"type\": \"radio\",\n \"answers\": [\n \"General manager \",\n \"Project manager\",\n \"Product manager\",\n \"Designer\",\n \"R&D engineer\",\n \"Operator, editor\",\n \"Sales, customer service\",\n \"Human resource, administration \",\n \"Finance, accountant\",\n \"Lawyer, legal affairs\",\n \"Marketing\",\n \"Teacher\",\n \"Student\",\n \"Other\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 3,\n \"name\": \"answer3\",\n \"title\": \"What is the name of your company?\",\n \"type\": \"input\",\n \"submit\": false\n },\n {\n \"key\": 4,\n \"name\": \"answer4\",\n \"title\": \"Please leave your email address/ phone number/ Wechat account below so we can reach you in time when you need help.\",\n \"type\": \"input\",\n \"submit\": true\n },\n {\n \"key\": 5,\n \"title\": \"Thank you for filling out the form, you can add our customer service in case of need\",\n \"platform\": {\n \"website\": \"https://s4.vika.cn/space/2023/03/02/b34e3205a9154463be16f497524f1327\",\n \"dingtalk\": \"https://s4.vika.cn/space/2023/03/02/4b16cef6602a4586a21d6346bf25d300\",\n \"wecom\": \"https://s4.vika.cn/space/2023/03/02/60119b1b69b64aa887bd1be6a2928bec\",\n \"feishu\": \"https://u.vika.cn/z9ygm\"\n },\n \"type\": \"contactUs\",\n \"next\": true\n }\n ]\n}\n", @@ -39308,13 +40509,13 @@ "player_step_ui_config_41": "", "player_step_ui_config_42": "{\n \"element\": \"#DATASHEET_FORM_LIST_PANEL\", \n\"placement\": \"leftTop\",\n \"title\": \"Form\", \n\"description\": \"You can quickly create a form from the current view. The number and order of the fields in the form is consistent with the view.\", \"children\":\"\" \n}", "player_step_ui_config_43": "{\n \"element\": \".style_navigation__1U5cR .style_help__1sXEA\", \n\"placement\": \"rightBottom\",\n \"title\": \"Tip\", \n\"offsetY\":5,\n\"description\": \"You can find your Vikaby assistant from the \"Help\" icon on the left\", \"children\":\"\" \n}", - "player_step_ui_config_44": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", + "player_step_ui_config_44": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", "player_step_ui_config_45": "", "player_step_ui_config_46": "", "player_step_ui_config_47": "{\n \"element\": \"#DATASHEET_WIDGET_BTN\",\n\"placement\": \"bottomRight\",\n \"title\": \"Widget\", \n\"description\": \"Want to use and view your data in a richer way? Try the widget!\", \"children\":\"\" \n}", "player_step_ui_config_48": "", "player_step_ui_config_49": "{\n \"element\": \".style_widgetPanelContainer__1l2ZV\",\n\"placement\": \"leftCenter\",\n \"title\": \"What is a widget\", \n\"description\": \"Vika widgets are an extended application of vikadata that features in richer data visualization, data transfer, data cleansing, and more. By installing widgets in the widget board, you can make work a lot easier.\", \"children\":\"\" \n}", - "player_step_ui_config_5": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", + "player_step_ui_config_5": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", "player_step_ui_config_50": "{\n \"element\": \".style_widgetModal__eXmdB\",\n\"placement\": \"leftTop\",\n \"title\": \"Widget Center\", \n\"description\": \"Officially recommended and custom widgets are published here. You can install any widget you want onto a dashboard or into a widget board of any datasheet.\", \"children\":\"\" \n}", "player_step_ui_config_51": "{\n \"element\": \".style_widgetModal__eXmdB .style_widgetItem__3Pl-1 button\",\n\"placement\": \"rightBottom\",\n \"title\": \"Install widget\", \n\"description\": \"Let's install this \"Chart\" widget\", \"children\":\"\" \n}", "player_step_ui_config_52": "", @@ -39411,6 +40612,7 @@ "preview_guide_click_to_restart": "아래 버튼을 눌러 다시 미리보기", "preview_guide_enable_it": "아래 버튼을 눌러 이 기능을 엽니다.", "preview_guide_open_office_preview": "이 파일을 미리 보려면 사무실 미리 보기 기능을 엽니다.", + "preview_next_automation_execution_time": "다음 10개의 실행 시간 미리보기", "preview_not_support_video_codecs": "H.264 비디오 코덱이 있는 MP4 비디오만 미리 볼 수 있습니다.", "preview_revision": "미리 보기", "preview_see_more": "오피스 파일 미리보기 기능에 대해 더 알고 싶으십니까?여기를 클릭하십시오.", @@ -39446,6 +40648,7 @@ "privacy_protection": "\"개인 정보 보호\"", "private_cloud": "프라이빗 클라우드", "private_external_person_only": "외부인 전용", + "private_help_link": "https://help.aitable.ai/docs/guide/team-and-private-area#private-area", "private_internal_person_only": "내부 인력만", "private_product_point": "클릭 한 번으로 APITable 플랫폼 소유", "privatized_deployment": "자체 관리", @@ -39516,13 +40719,15 @@ "reconciled_data": "데이터 확인 중", "record": "기록", "record_activity_experience_tips": "${day}일의 기록 활동을 볼 수 있습니다.", + "record_archived_data": "보관된 기록", + "record_chunk_text": "${text} rows, please wait", "record_comment": "주석만 해당", "record_comments": "코멘트", "record_fail_data": "데이터 오류", "record_filter_tips": "이 레코드는 필터링됨", "record_functions": "레코드 기능", "record_history": "개정 히스토리만", - "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-history", + "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-activity", "record_history_title": "기록 기록", "record_pre_filtered": "이 레코드는 필터링되었으며 레코드 외부를 클릭하면 숨겨집니다.", "record_pre_move": "레코드 외부를 클릭하면 레코드가 다른 위치로 이동됩니다.", @@ -39962,6 +41167,12 @@ "scan_to_login": "로그인 검색", "scan_to_login_by_method": "로그인하려면 ${method}를 스캔하여 공식 계정을 팔로우하세요.", "scatter_chart": "산포도", + "schedule_day_tips": "주기 계산은 매월 1일부터 시작됩니다. 10일마다 반복한다고 가정하면 매월 1일, 11일, 21일, 31일에 실행됩니다.", + "schedule_hour_tips": "주기 계산은 매일 자정(0:00)에 시작됩니다. 3시간마다 0분씩 반복한다고 가정하면 매일 자정(0:00), 오전 3시, 오전 6시, 오전 9시, 정오(12시), 오후 3시, 오후 6시, 마지막으로 해질녘(오후 9시)에 발생하게 됩니다.", + "schedule_start_day": "매월 1일부터", + "schedule_start_month": "매년 1월부터 매년", + "schedule_type": "일정 유형", + "schedule_year_tips": "주기 계산은 매년 첫 번째 달부터 시작됩니다. 첫 번째 날을 3개월 간격으로 가정하면 매년 1월, 4월, 7월, 10월 첫 번째 날 자정에 트리거가 활성화됩니다.", "science_and_technology": "과학과 기술", "scroll_screen_down": "화면 아래로 스크롤", "scroll_screen_left": "왼쪽으로 화면 스크롤", @@ -39975,6 +41186,7 @@ "search_folder_or_sheet": "파일 검색", "search_new_admin": "검색", "search_node_pleaseholder": "파일 검색(${shortcutKey})", + "search_node_tip": "빠른 검색(${shortcutKey})", "search_or_add": "옵션 찾기 또는 추가", "search_role_placeholder": "역할 검색", "seats": "좌석", @@ -40378,6 +41590,7 @@ "space_info": "개요", "space_info_del_confirm1": "1. 이 공유 공간을 삭제하면 다음 데이터가 지워집니다.", "space_info_del_confirm2": "2. 공유 공간은 7일 후에 완전히 삭제됩니다.그 전에 공간을 복원할 수 있습니다.", + "space_info_del_confirm3": "3. For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "space_info_feishu_desc": "타사 통합을 사용하고 있습니다.공유 공간을 삭제하려면 먼저 타사 통합을 비활성화합니다.", "space_info_feishu_label": "통합", "space_join_apply": "\"\" 공간을 요청합니다.", @@ -40464,6 +41677,7 @@ "start_onfiguration": "시작 구성", "start_time": "시작 시간", "start_use": "사용 시작", + "starting_from_midnight": "매일 자정(오전 12시)부터 매주", "startup": "시작", "startup_company_support_program": "지원 계획 시작", "stat_average": "평균적", @@ -40497,6 +41711,8 @@ "stay_tuned_for_more_features": "더 많은 기능에 관심을 가져주시기 바랍니다.", "steps_choose_reset_mode": "재설정 방법 선택", "steps_validate_identities": "인증 인증", + "stop_chunk_content": "Are you sure you want to stop the operation?", + "stop_chunk_title": "Stop", "stop_dingtalk_h5_modal_content": "자체 제작 응용 프로그램은 이 공간의 바인딩을 해제합니다.확인하세요.", "storage_per_seats": "", "storage_per_space": "스토리지 사용", @@ -40527,9 +41743,11 @@ "subscribe_credit_usage_over_limit": "현재 스페이스의 포인트 수가 제한을 초과합니다. 서브스크립션을 업그레이드하십시오.\n", "subscribe_demonstrate": "요청 프레젠테이션", "subscribe_disabled_seat": "인원수는 원래 계획보다 낮아서는 안 된다.", + "subscribe_grade_business": "사업", "subscribe_grade_free": "자유의", "subscribe_grade_plus": "더하기", "subscribe_grade_pro": "찬성", + "subscribe_grade_starter": "기동기", "subscribe_label_tooltip": "고급 공간 기능", "subscribe_new_choose_member": "최대 ${member_num}명의 회원 지원", "subscribe_new_choose_member_tips": "이 플랜은 1~${member_num}명의 멤버가 공간에 입장할 수 있도록 지원합니다.", @@ -40666,7 +41884,7 @@ "template_name_repetition_title": "\"${templateName}\"이(가) 이미 존재합니다. 교체하시겠습니까?", "template_no_template": "템플릿 없음", "template_not_found": "원하는 템플릿을 찾을 수 없습니까?알려주세요", - "template_recommend_title": "더웠어", + "template_recommend_title": "🌟 Hot", "template_type": "템플릿", "terms_of_service": "<서비스 약관>", "terms_of_service_pure_string": "서비스 약관", @@ -40710,6 +41928,7 @@ "text_editor_tip_end": "가져오기 편집 종료", "text_functions": "문자열 함수", "thailand": "태국", + "the_button_field_is_misconfigured": "버튼 필드가 잘못 구성되었습니다. 확인하고 다시 시도해 주세요.", "the_current_automation_workflow_has_no_related_files_you_can_establish_a_link_by_adding_trigger_conditions_and_actions_on_the_left_side": "현재 자동화된 워크플로우에는 관련 파일이 없습니다.왼쪽에 트리거 조건 및 작업을 추가하여 링크를 설정할 수 있습니다.", "the_current_button_column_has_expired_please_reselect": "현재 버튼 열이 만료되었습니다. 다시 선택하세요.", "the_last_7_days": "지난 7일", @@ -40812,6 +42031,7 @@ "timemachine_update_comment": "업데이트된 댓글", "times_per_month_unit": "전화 / 월", "times_unit": "전화기", + "timing_rules": "타이밍", "timor_leste": "동티모르", "tip_del_success": "7일 이내에 공유 공간을 복구할 수 있습니다.", "tip_do_you_want_to_know_about_field_permission": "필드 데이터를 암호화하시겠습니까?필드 권한 이해", @@ -40999,6 +42219,7 @@ "verify_account_title": "계정 확인", "verify_via_email": "이메일을 통한 인증", "verify_via_phone": "문자 인증", + "video": "동영상", "video_not_support_play": "현재 비디오 형식은 온라인 재생을 지원하지 않습니다.", "vietnam": "베트남", "view": "견해", @@ -41347,7 +42568,8 @@ "workdoc_color_title": "글꼴 색상", "workdoc_create": "Workdoc 만들기", "workdoc_expanded": "목차 펼치기", - "workdoc_image_max_10mb": "이미지 크기는 10MB를 초과할 수 없습니다.", + "workdoc_image_max_10mb": "없는", + "workdoc_image_max_size": "이미지 크기는 ${size}을(를) 초과할 수 없습니다.", "workdoc_info": "WorkDoc 정보", "workdoc_info_create_time": "생성 날짜", "workdoc_info_creator": "작성자:", @@ -41355,6 +42577,7 @@ "workdoc_info_last_modify_time": "마지막 수정 시간:", "workdoc_link_placeholder": "링크를 입력해주세요", "workdoc_only_image": "이미지만 허용됩니다.", + "workdoc_only_video": "영상만 허용됩니다", "workdoc_text_placeholder": "\"/\" 빠른 시작 입력", "workdoc_title_placeholder": "제목을 입력해주세요", "workdoc_unnamed": "이름이 없는 워크문서", @@ -41363,9 +42586,11 @@ "workdoc_unsave_ok": "변경 사항을 취소", "workdoc_unsave_title": "WorkDoc이 저장되지 않았습니다.", "workdoc_upload_failed": "업로드 실패", + "workdoc_video_max_size": "동영상 크기는 ${size}을(를) 초과할 수 없습니다.", "workdoc_ws_connected": "연결됨", "workdoc_ws_connecting": "연결 중...", "workdoc_ws_disconnected": "연결이 끊김", + "workdoc_ws_reconnecting": "다시 연결하는 중...", "workflow_execute_failed_notify": " 에서 실행하지 못했습니다. . 문제를 해결하려면 실행 기록을 검토하세요. 도움이 필요하시면 고객 서비스 팀에 문의해 주세요.", "workspace_data": "공간 데이터", "workspace_files": "워크벤치 데이터", @@ -41544,6 +42769,15 @@ "agreed": "Утвержденные", "ai_advanced_mode_desc": "расширенный режим позволяет пользователям настраивать подсказки, обеспечивая больший контроль за поведением и ответами агента ИИ.", "ai_advanced_mode_title": "Расширенный режим", + "ai_agent_anonymous": "Анонимный${ID}", + "ai_agent_conversation_continue_not_supported": "Продолжение предыдущего разговора в настоящее время не поддерживается.", + "ai_agent_conversation_list": "Список разговоров", + "ai_agent_conversation_log": "Журнал разговоров", + "ai_agent_conversation_title": "Название беседы", + "ai_agent_feedback": "Обратная связь", + "ai_agent_historical_message": "Вышеупомянутое историческое сообщение", + "ai_agent_history": "История", + "ai_agent_message_consumed": "Сообщение использовано", "ai_api_curl_template": "## Create chat completions\n\n```bash\n\ncurl -X POST \"{{apiBase}}/fusion/v1/ai/{{aiId}}/chat/completions\" \\n -H \"Content-Type: application/json\" \\n -H \"Authorization: Bearer {{token}}\" \\n -d '{\n \"model\": \"gpt-3.5-turbo\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"You are a helpful assistant.\"\n },\n {\n \"role\": \"user\",\n \"content\": \"Hello!\"\n }\n ]\n }'\n\n```\n\n## Returned data example\n\n```json\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", "ai_api_footer_desc": "встраивайте агент ИИ на свой сайт? узнать больше", "ai_api_javascript_template": "## Initialize SDK [![github]({{ githubIcon }})](https://github.com/openai/openai-node)\nAITable's chat completion API is compatible with OpenAI's Node.js SDK. You can use our service with the same SDK by simply changing the configuration as follows:\n\n\n```javascript\nconst { Configuration, OpenAIApi } = require(\"openai\");\nconst configuration = new Configuration({\n apiKey: \"{{token}}\",\n basePath: \"{{apiBase}}/fusion/v1/ai/{{aiId}}\"\n});\n```\n\n## Create chat completions\n\n```javascript\nconst openai = new OpenAIApi(configuration);\nconst chatCompletion = await openai.createChatCompletion({\n model: \"gpt-3.5-turbo\",\n messages: [{role: \"user\", content: \"Hello world\"}],\n});\n```\n\n## Returned data example\n\n```javascript\n\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", @@ -41559,6 +42793,9 @@ "ai_chat_unit": "игумен (ы)", "ai_close_setting_tip_content": "Вы внесли изменения. Ты хочешь их выбросить?", "ai_close_setting_tip_title": "tip", + "ai_copilot_generate_response": "Генерация ответа для вас...", + "ai_copilot_processs": "Обработка, подождите...", + "ai_copilot_start_process_request": "Начало обработки вашего запроса...", "ai_create_guide_btn_text": "Выберите таблицу данных", "ai_create_guide_content": "как агент ИИ, я могу ответить на ваши вопросы, основываясь на знаниях, которые я узнал. прежде чем начать разговор, пожалуйста, выберите набор данных в качестве базы знаний, и я прочитаю все данные в нем для обучения.", "ai_credit_cost_chart_title": "стоимость кредита", @@ -42027,7 +43264,7 @@ "apps_support": "Поддержка всех клиентов платформы", "archive_delete_record": "Удалить архивированные записи", "archive_delete_record_title": "Удалить запись", - "archive_notice": "

Вы пытаетесь заархивировать определенные записи. Архивирование записей приведет к следующим изменениям:

1. Все двусторонние ссылки для этой записи будут отменены.

2. Редактирование не поддерживается.

3. Такие функции, как напоминание о дате и запись подписки, не поддерживаются.

4. Больше не участвуйте в вычислении справочных, формул и других полей.

Вы уверены что хотите продолжить? (Вы можете разархивировать в «Архивном ящике» в расширенном режиме)

", + "archive_notice": "

Вы пытаетесь заархивировать определенные записи. Архивирование записей приведет к следующим изменениям:

1. Редактирование не поддерживается.

2. Такие функции, как напоминание о дате и запись подписки, не поддерживаются.

3. Больше не участвуйте в вычислении справочных, формул и других полей.

Вы уверены что хотите продолжить? (Вы можете разархивировать в «Архивном ящике» в расширенном режиме)

", "archive_record_in_activity": "архивная копия", "archive_record_in_menu": "Архив", "archive_record_success": "Успешное архивирование", @@ -42087,6 +43324,8 @@ "audit_add_field_role_detail": "В таблице \"\" добавьте [] роль как [] для поля [] ", "audit_add_node_role": "Добавить права доступа к файлу", "audit_add_node_role_detail": "Добавить права доступа к файлу,установить「${unitNames}」на「${role}」of 「${currentNodeName}」", + "audit_add_node_role_detail_end": "to「${role}", + "audit_add_node_role_detail_start": "Add file node permission,set「${unitNames}」", "audit_admin_permission_change_event": "Изменение прав администратора", "audit_create_template": "Создать шаблон", "audit_create_template_detail": "Создать шаблон", @@ -42095,20 +43334,30 @@ "audit_delete_field_role_detail": "Ревизия", "audit_delete_node_role": "Удалить права файла", "audit_delete_node_role_detail": "Удалить права доступа к файлу,удалить「${unitNames}」`s 「${role}」роль 「${currentNodeName}」", + "audit_delete_node_role_detail_end": "at 「${role}」role", + "audit_delete_node_role_detail_start": "Delete file node permission,delete「${unitNames}」from", "audit_delete_template": "Удалить шаблон", "audit_delete_template_detail": "Удалить шаблон", "audit_disable_field_role": "Отключить права поля", "audit_disable_field_role_detail": "Ревизия", "audit_disable_node_role": "Отключить права доступа к файлу", "audit_disable_node_role_detail": "Отключить разрешение ${nodeType} 「${currentNodeName}」 `", + "audit_disable_node_role_detail_end": "`s permission", + "audit_disable_node_role_detail_start": "Disable ${nodeType}", "audit_disable_node_share": "Закрыть общедоступную ссылку на файл", "audit_disable_node_share_detail": "Закройте общедоступную ссылку ${nodeType} 「${currentNodeName}」", + "audit_disable_node_share_detail_end": "public link", + "audit_disable_node_share_detail_start": "Close ${nodeType}", "audit_enable_field_role": "Права доступа к полям", "audit_enable_field_role_detail": "Ревизия", "audit_enable_node_role": "Включить права доступа к файлу", "audit_enable_node_role_detail": "Включить разрешение ${nodeType} 「${currentNodeName}」 `", + "audit_enable_node_role_detail_end": "`s permission", + "audit_enable_node_role_detail_start": "Enable ${nodeType}", "audit_enable_node_share": "Открыть общедоступную ссылку на файл", "audit_enable_node_share_detail": "Открыть общедоступную ссылку ${nodeType} 「${currentNodeName}」", + "audit_enable_node_share_detail_end": "public link", + "audit_enable_node_share_detail_start": "Open ${nodeType}", "audit_login_event": "Событие регистрации", "audit_logout_event": "Английский язык", "audit_organization_change_event": "Изменилась организационная структура контактных лиц", @@ -42129,18 +43378,25 @@ "audit_space_invite_user_detail": "Ревизия", "audit_space_node_copy": "Повторить файл", "audit_space_node_copy_detail": "Дублируйте ${nodeType} 「${sourceNodeName}」, имя нового файла 「${currentNodeName}」", + "audit_space_node_copy_detail_start": "Duplicate ${nodeType} 「${sourceNodeName}」, the new file node's name is", "audit_space_node_create": "Создать файл", "audit_space_node_create_detail": "Создайте ${nodeType} с именем 「${currentNodeName}」", + "audit_space_node_create_detail_start": "Create a ${nodeType} named", "audit_space_node_delete": "Удалить файл", "audit_space_node_delete_detail": "Удалить ${nodeType} с именем 「${currentNodeName}」", + "audit_space_node_delete_detail_start": "Delete ${nodeType} named", "audit_space_node_export": "Экспорт таблиц данных", "audit_space_node_export_detail": "Участник ${member_name} экспортировал таблицу ${node_name}", "audit_space_node_import": "Импорт файлов", "audit_space_node_import_detail": "Импортируйте файл с именем 「${nodeName}」", + "audit_space_node_import_detail_start": "Import a file node named", "audit_space_node_move": "Переместить файл", "audit_space_node_move_detail": "Переместите ${nodeType} 「${currentNodeName}」 в папку 「${parentName}」", + "audit_space_node_move_detail_end": "to the folder「${parentName}」", + "audit_space_node_move_detail_start": "Move ${nodeType}", "audit_space_node_rename": "Переименовать файл", "audit_space_node_rename_detail": "Переименуйте ${nodeType} 「${oldNodeName}」в 「${nodeName}」", + "audit_space_node_rename_detail_start": "Rename ${nodeType} 「${oldNodeName}」to", "audit_space_node_sort": "Ревизия", "audit_space_node_sort_detail": "Ревизия", "audit_space_node_update_cover": "Ревизия", @@ -42155,17 +43411,24 @@ "audit_space_rubbish_node_delete_detail": "Ревизия", "audit_space_rubbish_node_recover": "Восстановление файла", "audit_space_rubbish_node_recover_detail": "Восстановить ${nodeType} 「${currentNodeName}」 из корзины", + "audit_space_rubbish_node_recover_detail_end": "from the trash", + "audit_space_rubbish_node_recover_detail_start": "Restore ${nodeType}", "audit_space_template_event": "Изменение шаблона", "audit_space_update_logo": "Ревизия", "audit_space_update_logo_detail": "Ревизия", "audit_store_share_node": "Сохранить общий файл", "audit_store_share_node_detail": "Восстановите ${nodeType} в пространстве, имя 「${nodeName}」", + "audit_store_share_node_detail_start": "Restore ${nodeType} to the space, name is", "audit_update_field_role": "Ревизия", "audit_update_field_role_detail": "Ревизия", "audit_update_node_role": "Изменить права доступа к файлу", "audit_update_node_role_detail": "Изменить права доступа к файлу,изменить роль「${unitNames}」 на「${role}」of 「${currentNodeName}」", + "audit_update_node_role_detail_end": "to「${role}」role", + "audit_update_node_role_detail_start": "Modify file node permission,modify「${unitNames}」from", "audit_update_node_share_setting": "Изменить параметры публичных ссылок на файлы", "audit_update_node_share_setting_detail": "Изменить общедоступную ссылку ${nodeType} 「${currentNodeName}」", + "audit_update_node_share_setting_detail_end": "public link settings", + "audit_update_node_share_setting_detail_start": "Modify ${nodeType}", "audit_user_login": "Регистрация пользователей", "audit_user_login_detail": "Ревизия", "audit_user_logout": "Списание пользователей", @@ -42207,6 +43470,7 @@ "automation_enabled_return_via_related_files": "Автоматизация включена. Пожалуйста, повторно введите исходную таблицу через «Связанные файлы», чтобы использовать новую кнопку.", "automation_field": "положение в области прав человека", "automation_import_variables_from_pre_tep": "Получить данные с предварительного шага", + "automation_is_not_yet_enabled": "Автоматизация еще не включена, включите ее и повторите попытку.", "automation_last_edited_by": "Последний раз редактировалось", "automation_last_edited_time": "Время последнего редактирования", "automation_manager_label": "Может выполнять все действия по автоматике", @@ -42232,6 +43496,7 @@ "automation_runs_this_month": "Работает в этом месяце", "automation_stay_tuned": "Следите за обновлениями", "automation_success": "Успех", + "automation_tips": "Поле кнопки настроено неправильно. Проверьте и повторите попытку.", "automation_updater_label": "Можно просмотреть историю запуска автоматизации.", "automation_variabel_empty": "Нет данных, которые можно было бы использовать на предварительном этапе. Измените настройки и повторите попытку.", "automation_variable_datasheet": "Получить данные из ${NODE_NAME}", @@ -42267,6 +43532,7 @@ "bermuda": "Бермудскиеострова", "bhutan": "Бутан", "billing_over_limit_tip_common": "Использование пространства превысило лимит, и после обновления вы сможете получить больший объем.", + "billing_over_limit_tip_forbidden": "Срок действия пробной версии или подписки истек. Пожалуйста, свяжитесь с продавцом-консультантом для продления.", "billing_over_limit_tip_widget": "Количество установок виджетов превысило лимит, и вы можете обновить их, чтобы увеличить использование.", "billing_period": "Расчетный период: ${period}", "billing_subscription_warning": "Функциональный опыт", @@ -42326,10 +43592,19 @@ "button_text": "Текст кнопки", "button_text_click_start": "Нажмите, чтобы начать", "button_type": "Тип кнопки", + "by_at": "в", + "by_days": "Дни", + "by_every": "каждый", "by_field_id": "Использовать идентификатор поля", + "by_hours": "Часы", + "by_in": "в", + "by_min": "минута(ы)", + "by_months": "Месяцы", + "by_on": "на", "by_the_day": "По дням", "by_the_month": "Ежемесячный журнал", "by_the_year": "Ежегодно", + "by_weeks": "Недели", "calendar_add_date_time_field": "Создать поле даты", "calendar_color_more": "Больше цветов", "calendar_const_detail_weeks": "[\"понедельник\",\"вторник\",\"среда\",\"четверг\",\"пятница\",\"суббота\",\"воскресенье\"]", @@ -42393,6 +43668,14 @@ "cannot_activate_space_by_space_limit": "Невозможно активировать границы пространства", "cannot_join_space": "Вы не можете присоединиться к новой космической станции, потому что вы превысили максимальную квоту на 10 космических станций.", "cannot_switch_field_permission": "Установите права поля не выше прав файла.", + "capacity_file_detail_desc": "The total number of file nodes within the Space is calculated by adding the file nodes from the Team to the file nodes created by each member in their Private. Not enough capacity?", + "capacity_file_detail_title": "File Capacity", + "capacity_file_member": "Member", + "capacity_file_member_private_node_count": "Private", + "capacity_file_member_private_percent": "Percent", + "capacity_file_member_team": "Team", + "capacity_file_member_team_node_count": "Team", + "capacity_file_upgrade": "Click to upgrade your Space", "capacity_from_official_gift": "Официальный подарок.", "capacity_from_participation": "По приглашению ${user} присоединиться к пространству", "capacity_from_purchase": "По покупательной способности", @@ -42429,6 +43712,8 @@ "catalog": "Искатель", "catalog_add_from_template_btn_title": "Добавить из шаблона", "catalog_empty_tips": "Сейчас рабочая зона пуста. Начать создавать файлы с помощью шаблонов.", + "catalog_private": "Private", + "catalog_team": "Team", "category_blank": "[Пробел]", "catering": "Питание", "cayman_islands": "Каймановы острова", @@ -42497,6 +43782,7 @@ "choose_type_of_vika_field": "Выберите тип поля", "choose_your_own_space": "(Поддерживается только сохранение в вашем собственном пространстве в качестве создателя)", "chose_new_primary_admin_button": "Распределение", + "chunk_stopping_title": "Stopping", "claim_special_offer": "Подайте заявку на это специальное предложение!", "clear": "Очистить", "clear_all_fields": "Очистить все", @@ -42627,6 +43913,7 @@ "confirm_del_current_team": "Вы уверены, что хотите удалить команду?", "confirm_delete": "Подтвердить и удалить", "confirm_delete_node_name_as": "Вы уверены, что хотите удалить \"${nodeNameDiv}\"?", + "confirm_delete_private_node_name_as": "Are you sure you want to delete \"${nodeNameDiv}\"? The file will be deleted from the Space and the trash.", "confirm_delete_space_btn": "Подтвердить и удалить пространство", "confirm_exit": "Подтверждение выхода", "confirm_exit_space_with_name": "Подтвердите выход из пространства \"${spaceNameDiv}\"", @@ -42664,6 +43951,14 @@ "convert": "Преобразование", "convert_tip": "Эта операция может удалить данные из некоторых ячеек. В случае возникновения каких - либо непредвиденных обстоятельств вы можете отменить операцию.", "cook_islands": "Острова Кука", + "copilot_auto_agent_desc": "Не знаете, какой агент выбрать? Попробуйте Автоагент.", + "copilot_auto_agent_name": "Авто Агент", + "copilot_data_agent_desc": "Генерация анализа данных/визуализаций на основе ваших взглядов.", + "copilot_data_agent_name": "Агент данных", + "copilot_data_agent_policy": "Общаясь с Copilot, вы соглашаетесь с политикой пользовательского соглашения.", + "copilot_data_agent_policy_button": "Политика", + "copilot_help_agent_desc": "Спросите что угодно о документах центра помощи AITable.", + "copilot_help_agent_name": "Получить центр помощи", "copy": "Копирование", "copy_automation_url": "Копировать URL", "copy_card_link": "Копировать URL записи", @@ -42708,6 +44003,7 @@ "create_mirror_guide_content": "Функция зеркала имеет возможность скрывать определенные данные. Вы можете установить «условия фильтрации» и «скрытые поля» в исходном представлении таблицы данных, чтобы контролировать, какие записи и поля отображаются в зеркале.\n
\n
\nПри использовании в сочетании с функцией «блокировки просмотра» она может помешать другим пользователям вносить изменения.\n
\n
\nКроме того, вы можете перейти в «Исходная таблица> Скрытые поля», чтобы изменить конфигурацию «Показать все поля в зеркалах».", "create_mirror_guide_title": "Зеркало скрывает некоторые записи и поля", "create_new_button_field": "Создайте новое поле столбца кнопки", + "create_private_node_tip": "Personal or temporary draft documents can be created here ${link}", "create_public_invitation_link": "Создать ссылку на открытое приглашение", "create_space_sub_title": "Эй, пожалуйста, назовите свое общее пространство.", "create_team_fail": "Ошибка создания команды", @@ -42771,10 +44067,12 @@ "custom_enterprise": "Настройка корпоративного пространства для вас", "custom_function_development": "Разработка пользовательских функций", "custom_grade_desc": "Профессиональные услуги по развертыванию агентов, частной установке, поддержке и настройке", + "custom_page_setting_title": "Add a custom page", "custom_picture": "Пользовательские изображения", "custom_style": "Стиль", "custom_upload": "Настройка загрузки", "custom_upload_tip": "Рекомендуется использовать изображения размером с квадрат 1: 1 для лучшего визуального опыта", + "custome_page_title": "Custom Web", "cut_cell_data": "Вырезать ячейки", "cyprus": "Кипр", "czech": "Чешский", @@ -42826,6 +44124,7 @@ "default": "Нарушение обязательств", "default_create_ai_chat_bot": "новый агент ИИ", "default_create_automation": "Новая автоматизация", + "default_create_custom_page": "Новая пользовательская страница", "default_create_dashboard": "Новые приборные панели", "default_create_datasheet": "Новая таблица данных", "default_create_file": "Новый файл", @@ -42847,6 +44146,7 @@ "del_invitation_link": "Удалить ссылку приглашения", "del_invitation_link_desc": "После удаления ссылка будет недействительной", "del_space_now": "Удалить пространство навсегда", + "del_space_now_confirm_tip": "For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "del_space_now_tip": "Невозможно восстановить пространство после удаления. Все документы и приложения будут удалены.", "del_space_res_tip": "Удалить пространство", "del_team_success": "Удалить команду успешно", @@ -43042,6 +44342,62 @@ "embed_error_page_help": "Узнать больше", "embed_fail_og_description_content": "Эта встроенная общедоступная ссылка отключена и временно недоступна", "embed_failed": "Встроенные ссылки недоступны,", + "embed_link_bilibili": "билибили", + "embed_link_bilibili_desc": "Вставив видеоролики bilibili, вы сможете просматривать обучающие материалы и руководства или просматривать домашнюю страницу канала в Vika.", + "embed_link_bilibili_link_text": "Как вставить видео билибили", + "embed_link_bilibili_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-bilibili-video", + "embed_link_default": "Что-либо", + "embed_link_default_desc": "Вставьте ссылку для просмотра любого веб-сайта.", + "embed_link_default_link_text": "Узнать больше", + "embed_link_default_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_link_figma": "Figma", + "embed_link_figma_desc": "Встраивая файлы Figma, участники могут более удобно просматривать и редактировать черновики проектов, повышая эффективность совместной работы.", + "embed_link_figma_link_text": "Как встроить файлы Figma", + "embed_link_figma_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-figma-file", + "embed_link_google_docs": "Docs", + "embed_link_google_docs_desc": "Встраивая Google Docs, вы можете редактировать и просматривать документы в AITable, что облегчает совместную работу команды.", + "embed_link_google_docs_link_text": "Как встроить Google Документы", + "embed_link_google_docs_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-docs-file", + "embed_link_google_sheets": "Sheets", + "embed_link_google_sheets_desc": "Встраивая Google Таблицы, вы можете редактировать и просматривать таблицы в AITable, чтобы облегчить совместную работу команды.", + "embed_link_google_sheets_link_text": "Как встроить Google Таблицы", + "embed_link_google_sheets_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-sheets-file", + "embed_link_jishi_design": "JSдизайн", + "embed_link_jishi_design_desc": "Встраивая файлы JSdesign, участники могут более удобно просматривать и редактировать черновики проектов, повышая эффективность совместной работы.", + "embed_link_jishi_design_link_text": "Как встроить файлы JSdesign", + "embed_link_jishi_design_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-js-design-file", + "embed_link_tencent_docs": "Документы Tencent", + "embed_link_tencent_docs_desc": "Встраивая документы Tencent, вы можете редактировать и просматривать документы Tencent в Vika, чтобы повысить эффективность совместной работы.", + "embed_link_tencent_docs_link_text": "Как встроить документы Tencent", + "embed_link_tencent_docs_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-tencent-docs", + "embed_link_wps": "WPS", + "embed_link_wps_desc": "Встраивая файлы WPS, вы можете редактировать и просматривать документы, таблицы и формы WPS в Vika, чтобы повысить эффективность совместной работы.", + "embed_link_wps_link_text": "Как встроить файлы WPS", + "embed_link_wps_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-wps-file", + "embed_link_youtube": "YouTube", + "embed_link_youtube_desc": "Встраивая видео YouTube, вы можете просматривать учебные пособия и руководства или просматривать домашнюю страницу канала в AITable.", + "embed_link_youtube_link_text": "Как встроить видео с YouTube", + "embed_link_youtube_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-youtube-video", + "embed_page": "Пользовательская страница", + "embed_page_add_url": "Добавить URL", + "embed_page_doc_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_page_function_desc": "Добавляйте веб-страницы в ${edition} для быстрого доступа к документам, видео и т. д. сторонних веб-сайтов. Вы можете добавить рекомендуемые ссылки на веб-сайты или любые пользовательские ссылки.", + "embed_page_node_permission_editor": "На основе «только обновление» также можно открыть общий доступ к файлу.", + "embed_page_node_permission_manager": "Может выполнять все действия с файлом", + "embed_page_node_permission_reader": "Можно просматривать содержимое пользовательской страницы и основную информацию о файле.", + "embed_page_node_permission_updater": "На основе «только для чтения» также можно изменить ссылку на пользовательскую страницу.", + "embed_page_setting_title": "Добавить пользовательскую страницу", + "embed_page_url_invalid": "Пожалуйста, введите правильный URL", + "embed_paste_link_bilibili_placeholder": "Вставьте ссылку на видео билибили", + "embed_paste_link_default_placeholder": "Вставьте URL-адрес", + "embed_paste_link_figma_placeholder": "Вставьте ссылку общего доступа к файлу Figma.", + "embed_paste_link_google_docs_placeholder": "Вставьте ссылку общего доступа к Документам Google.", + "embed_paste_link_google_sheets_placeholder": "Вставьте ссылку общего доступа к Google Таблицам.", + "embed_paste_link_jsdesign_placeholder": "Вставьте ссылку общего доступа к файлу JSdesign.", + "embed_paste_link_tencent_docs_placeholder": "Вставьте ссылку на общий доступ к документам Tencent.", + "embed_paste_link_wps_placeholder": "Вставьте ссылку общего доступа к файлу WPS.", + "embed_paste_link_youtube_placeholder": "Вставьте ссылку на видео YouTube", + "embed_success": "Добавить успешно", "emoji_activity": "Деятельность", "emoji_custom": "Обычаи", "emoji_flags": "Флаг", @@ -43148,6 +44504,11 @@ "estonia": "Эстония", "ethiopia": "Эфиопияworld. kgm", "event_planning": "Планирование мероприятий", + "every": "Каждый", + "every_day_at": "день (дни) в", + "every_hour_at": "час(а) в", + "every_month_at": "месяц(ы) на", + "every_week_at": "Каждую неделю по", "everyday_life": "Повседневная жизнь", "everyone_visible": "Для всех.", "exact_date": "Точная дата", @@ -43158,6 +44519,7 @@ "exchange": "Выкуп.", "exchange_code_times_tip": "Примечание: Код обмена можно использовать только один раз", "exclusive_consultant": "Эксклюзивный консультант V +", + "exclusive_limit_plan_desc": "Эксклюзивный ограниченный уровень", "exist_experience": "Выход из опыта", "exits_space": "Выход из пространства", "expand": "Расширение", @@ -43184,7 +44546,7 @@ "expired": "Срок действия", "export": "Проводится экспорт.", "export_brand_desc": "Техническая поддержка", - "export_current_preview_view_data": "", + "export_current_preview_view_data": "Export current preview view data", "export_gantt_button_tips": "Экспорт в файл.png", "export_gantt_chart": "Экспорт диаграммы Ганта", "export_to_excel": "Экспорт данных", @@ -43755,26 +45117,26 @@ "gantt_config_color_by_single_select_pleaseholder": "Выберите поле выбора", "gantt_config_color_help": "Как установить", "gantt_config_friday": "Пятница", - "gantt_config_friday_in_bar": "Пятница", + "gantt_config_friday_in_bar": "Пт", "gantt_config_friday_in_select": "Пятница", "gantt_config_monday": "Понедельник", - "gantt_config_monday_in_bar": "Понедельник", + "gantt_config_monday_in_bar": "Пн", "gantt_config_monday_in_select": "Понедельник", "gantt_config_only_count_workdays": "Продолжительность вычисляется только в рабочие дни.", "gantt_config_saturday": "Суббота", - "gantt_config_saturday_in_bar": "Суббота", + "gantt_config_saturday_in_bar": "Сб", "gantt_config_saturday_in_select": "Суббота", "gantt_config_sunday": "Воскресенье", - "gantt_config_sunday_in_bar": "Воскресенье", + "gantt_config_sunday_in_bar": "Вс", "gantt_config_sunday_in_select": "Воскресенье", "gantt_config_thursday": "Четверг", - "gantt_config_thursday_in_bar": "Университет Цинхуа", - "gantt_config_thursday_in_select": "Университет Цинхуа", + "gantt_config_thursday_in_bar": "Чт", + "gantt_config_thursday_in_select": "Четверг", "gantt_config_tuesday": "Вторник", - "gantt_config_tuesday_in_bar": "Вторник", + "gantt_config_tuesday_in_bar": "Вт", "gantt_config_tuesday_in_select": "Вторник", "gantt_config_wednesday": "Среда", - "gantt_config_wednesday_in_bar": "Среда", + "gantt_config_wednesday_in_bar": "Ср", "gantt_config_wednesday_in_select": "Среда", "gantt_config_weekdays_range": "с ${weekday} до ${weekday}", "gantt_config_workdays_a_week": "Пользовательский стандартный рабочий день", @@ -43856,6 +45218,7 @@ "gold_grade": "Цзинь", "gold_grade_desc": "Для групп со сложными бизнес - процессами", "gold_seat_200_desc": "Двести.", + "gold_seat_300_desc": "300", "golden_grade": "Цзинь", "got_it": "Понял.", "got_v_coins": "Награды 5 монет", @@ -43889,6 +45252,8 @@ "guests_per_space": "Гости в каждом пространстве", "guide_1": "啊这", "guide_2": "Изучение основных функций занимает всего несколько минут. С этого момента работа становится эффективнее!", + "guide_flow_modal_contact_sales": "Свяжитесь с отделом продаж", + "guide_flow_modal_get_started": "Начать", "guide_flow_of_catalog_step1": "Это рабочий каталог, в котором хранятся все папки и файлы Space.", "guide_flow_of_catalog_step2": "В рабочем каталоге вы можете создавать таблицы данных или папки по мере необходимости.", "guide_flow_of_click_add_view_step1": "В дополнение к некоторым основным видам, если у вас есть вложения в формате изображения, настоятельно рекомендуется создать вид альбома.", @@ -44067,6 +45432,7 @@ "intro_widget_tips": "Что такое виджеты?", "introduction": "Презентация", "invalid_action_sort_tip": "Как поле группирования, его сортировка уже установлена. Настройки текущего заказа не вступят в силу.", + "invalid_automation_configuration": "Неверная конфигурация автоматизации. Проверьте и повторите попытку.", "invalid_field_type": "Неверный тип поля", "invalid_option_sort_tip": "Как поле группирования, его сортировка уже установлена.", "invalid_redemption_code_entered": "Код обмена не действителен", @@ -44197,6 +45563,9 @@ "label_format_day_month_and_year_split_by_slash": "День / месяц / год", "label_format_month": "Месяц", "label_format_month_and_day_split_by_dash": "Год", + "label_format_month_day_year_split_by_dash": "Month-Day-Year", + "label_format_month_day_year_split_by_slash": "Month/Day/Year", + "label_format_month_day_year_two_digit_year_split_by_slash": "Month/Day/Year (Two-digit year)", "label_format_year": "Год", "label_format_year_and_month_split_by_dash": "Год", "label_format_year_month_and_day_split_by_dash": "Год", @@ -44275,6 +45644,7 @@ "lark_version_enterprise": "Бизнес - план Ларка", "lark_version_standard": "Стандартный план Ларка", "lark_versions_free": "Основные планы Ларка", + "last_day": "Последний день", "last_modified_by_select_modal_desc": "Если какое - либо поле, выбранное ниже, будет отредактировано, последний член редактора будет показан в поле последнего редактирования", "last_modified_time_select_modal_desc": "Если вы отредактировали любое поле, выбранное ниже, время последнего редактирования будет показано в поле времени последнего редактирования", "last_step": "Возвращение", @@ -44419,7 +45789,7 @@ "mail_invite_fail": "Почтовое приглашение успешно.", "mail_invite_success": "Почтовое приглашение успешно.", "main_admin_name": "Имя администратора", - "main_admin_page_desc": "Администраторы имеют полный доступ к пространствам, таким как диспетчеры гамет и передача права собственности на пространство", + "main_admin_page_desc": "Администратор имеет полный доступ к пространству, например, к управлению участниками и настройками пространства.", "main_contain": "Основные элементы", "malawi": "Малави", "malaysia": "Малайзия", @@ -44639,8 +46009,12 @@ "more_widget": "Больше гаджетов", "morocco": "Марокко", "move": "Переместить", + "move_datasheet_link_warn": "Cannot be moved to Team Area alone, because there is a two-way link from the current datasheet to another datasheet, it is recommended to put them in a folder and then move them", "move_favorite_node_fail": "Ошибка перемещения узла. Система автоматически обновляет список.", + "move_folder_link_warn": "Cannot be moved to Team Area because the files in the current folder are linked to files outside the folder (may be two-way links or linked by forms, etc.) We recommend that they be placed in a folder before moving", "move_node_modal_content": "После перемещения на видимость файла может повлиять родительская папка.", + "move_other_link_no_permission": "Unable to move to the corresponding folder because you do not have administrative rights to the folder", + "move_other_link_warn": "It is not allowed to move ${node type} to Team Area alone, because it connects to the datasheet of Private Area, it is recommended to put them in a folder before moving them", "move_to": "Перейти на", "move_to_error_equal_parent": "Файл находится в текущей папке. Выберите другую папку", "move_to_modal_title": "Переместите [${name}] в", @@ -44671,7 +46045,9 @@ "new_a_line": "Клавиша Shift + Enter: Переключение строк", "new_automation": "Новая автоматизация", "new_caledonia": "Новая Каледония", + "new_custom_page": "New custom page", "new_datasheet": "Новая таблица данных", + "new_ebmed_page": "Новая пользовательская страница", "new_folder": "Создать папку", "new_folder_btn_title": "Папка", "new_folder_tooltip": "Создать папку", @@ -44837,7 +46213,7 @@ "nvc_start_text": "Перетащите диаграмму вправо", "nvc_yes_text": "Подтвержденные", "obtain_verification_code": "Код проверки не получен или истек", - "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrzw0miJVmSkJ7eBBa9k/fomx5qPX0JGPFvfEEP\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", + "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrCvbFC53xc3kl00B4Pg\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", "offical_website_nav_data": "[{\n \"name\": \"产品\",\n \"href\": \"/login\",\n \"children\": [\n {\n \"name\": \"vika维格表 Overview\",\n \"href\": \"/login/\"\n },\n {\n \"name\": \"应用连接 Integration\",\n \"href\": \"/connections/\"\n },\n {\n \"name\": \"客户端(Beta) Download\",\n \"href\": \"/download/\"\n }\n ]\n}, {\n \"name\": \"解决方案\",\n \"href\": \"/\",\n \"children\": [{\n \"name\": \"PMO项目群管理\",\n \"href\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"href\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"href\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"href\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"href\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"href\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"href\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"href\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"href\": \"/shop/\"\n }, {\n \"name\": \"更多解决方案 >\",\n \"href\": \"/solutions/\"\n }]\n}, {\n \"name\": \"模板/案例\",\n \"href\": \"/template\",\n \"children\": [\n {\n \"name\": \"模板中心 Tempaltes\",\n \"href\": \"/template\"\n },\n {\n \"name\": \"客户案例 Customers\",\n \"href\": \"/cases/\"\n }\n ]\n},\n {\n \"name\": \"首页\",\n \"href\": \"/?home=1\"\n },\n {\n \"name\": \"学习资源\",\n \"href\": \"https://edu.vika.cn/index\",\n \"children\": [\n {\n \"name\": \"快速入门 Tutorials\",\n \"href\": \"https://help.vika.cn/docs/guide/tutorial\"\n },\n {\n \"name\": \"产品手册 Manual\",\n \"href\": \"https://help.vika.cn/docs/guide/manual\"\n },\n {\n \"name\": \"维格课堂 Vika Education\",\n \"href\": \"https://edu.vika.cn/\"\n },\n {\n \"name\": \"维格社区 Vika BBS\",\n \"href\": \"https://bbs.vika.cn/\"\n },\n {\n \"name\": \"第三方连接 Integration\",\n \"href\": \"https://help.vika.cn/docs/guide/connection\"\n },\n {\n \"name\": \"开发者中心 Developer Center\",\n \"href\": \"/developers/\"\n },\n {\n \"name\": \"常见问题 FAQ\",\n \"href\": \"https://help.vika.cn/docs/guide/questions\"\n }\n ]\n }]", "office_preview": "Предварительный просмотр файлов Office", "office_preview_app_desc": "

Smooth online preview of office files on datasheet, allowing you to view common office files such as Excel, Word, PPT, etc. on your desktop or mobile anywhere, anytime

\n\n
    \n
  • Online preview of .doc, .docx, .xls, .xlsx, .ppt, .pptx, and .pdf formatted office files
  • \n
  • Desktop and mobile both support file previews of the above formats
  • \n
\n\n

Additional notes:

\n
    \n
  • This feature is powered by \"Yoncentric Cloud Conversion\" and officially integrated
  • \n
  • Click the \"Enable\" button below to enable this integration and agree that \"Yoncentric Cloud Conversion\" reads the office files you want to preview
  • \n
  • If you no longer need the office files preview feature, the space admin can disable it on this page
  • \n
", @@ -44877,6 +46253,7 @@ "open_auto_save_success": "Автосохранение просмотра успешно открыто", "open_auto_save_warn_content": "Все изменения в этом представлении будут сохранены автоматически и синхронизированы с другими членами.", "open_auto_save_warn_title": "Включить автоматическое сохранение", + "open_automation_time_arrival": "https://aitable.ai/contact-sales-open-source", "open_failed": "Ошибка открытия", "open_in_new_tab": "Открыть в новой вкладке", "open_invite_after_operate": "После открытия все участники могут пригласить новых членов из панели контактов", @@ -45023,6 +46400,8 @@ "payment_record": "Учет платежей", "payment_reminder": "Подсказка к оплате", "payment_reminder_content": "Новый план, который вы выбрали, является более франшизой, чем сумма, подлежащая оплате. Рекомендуется выбрать новый план с большей продолжительностью. Если вы подтвердите это, избыточная сумма не будет возвращена. ${action}, если сомневаетесь", + "payment_reminder_modal_content": "Вы можете попробовать расширенную версию, чтобы получить больше файловых узлов, корпоративных разрешений, емкости вложений, объема данных, искусственного интеллекта и других расширенных функций и привилегий.", + "payment_reminder_modal_title": "Вы сейчас используете бесплатную версию", "pending_invite": "Повесить приглашение", "people": "Членский состав", "per_person_per_year": "Каждый год", @@ -45192,7 +46571,7 @@ "player_step_ui_config_168": "{\n\"templateKey\":\"createMirrorTip\"\n}", "player_step_ui_config_169": "{ \"headerImg\": \"https://s4.vika.cn/space/2023/04/04/bcf0695cf35840e6b85e032a8e5ea0a1\", \"readMoreUrl\": \"https://help.vika.cn/changelog/23-04-10- обновления\", \"дети\": \"

🚀 Введение новых функций

\\п
  • Запущен новый тип поля «Каскад», упрощающий выбор из иерархии параметров в формах.
  • Выпущен виджет «Скрипт», меньше кода для большей настройки
  • Запустите автоматизацию для отправки электронных писем и быстрого получения уведомлений.
  • Запустите автоматизацию, чтобы отправить сообщение в Slack и вовремя проинформировать свою команду.
  • Исследование искусственного интеллекта: выпущен виджет «GPT Content Generator»
\" }", "player_step_ui_config_17": "{\n \"element\": \"#TEMPLATE_CENTER_USE_TEMPLATE_BTN>button\", \n\"placement\": \"rightBottom\",\n\"offsetY\": 20,\n \"title\": \"How to use a template\", \n\"description\": \"Click the button on the left to use the template\", \"children\":\"\" \n}", - "player_step_ui_config_176": "{\"title\":\"Введение AI-агент\",\"video\":\"https://www.youtube.com/embed/cjds1r_roG8?si=irKUpMhwDlOEb8Hc\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", + "player_step_ui_config_176": "{\"title\":\"AITable.ai DEMO\",\"video\":\"https://www.youtube.com/embed/kGxMyEEo3OU\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", "player_step_ui_config_18": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select>.ant-select-selector\", \n\"placement\": \"bottomLeft\",\n \"title\": \"How to use a template\", \n\"description\": \"Select where to put the template\", \"children\":\"\" \n}", "player_step_ui_config_19": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select .ant-select-selector\"\n}", "player_step_ui_config_2": "{\n \"config\": [\n {\n \"key\": 1,\n \"name\": \"answer1\",\n \"title\": \"What kind of issues are you looking forward to solved by vikadata?\",\n \"type\": \"checkbox\",\n \"answers\": [\n \"Work Planning\",\n \"Customer Service\",\n \"Project Management\",\n \"Sourcing Supply\",\n \"Content Production\",\n \"E-commerce operation\",\n \"Event Planning\",\n \"Human Resources\",\n \"Administration\",\n \"Financial Management\",\n \"Webcast\",\n \"Educational institutes Management\",\n \"Other\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 2,\n \"name\": \"answer2\",\n \"title\": \"Your job title is______\",\n \"type\": \"radio\",\n \"answers\": [\n \"General manager \",\n \"Project manager\",\n \"Product manager\",\n \"Designer\",\n \"R&D engineer\",\n \"Operator, editor\",\n \"Sales, customer service\",\n \"Human resource, administration \",\n \"Finance, accountant\",\n \"Lawyer, legal affairs\",\n \"Marketing\",\n \"Teacher\",\n \"Student\",\n \"Other\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 3,\n \"name\": \"answer3\",\n \"title\": \"What is the name of your company?\",\n \"type\": \"input\",\n \"submit\": false\n },\n {\n \"key\": 4,\n \"name\": \"answer4\",\n \"title\": \"Please leave your email address/ phone number/ Wechat account below so we can reach you in time when you need help.\",\n \"type\": \"input\",\n \"submit\": true\n },\n {\n \"key\": 5,\n \"title\": \"Thank you for filling out the form, you can add our customer service in case of need\",\n \"platform\": {\n \"website\": \"https://s4.vika.cn/space/2023/03/02/b34e3205a9154463be16f497524f1327\",\n \"dingtalk\": \"https://s4.vika.cn/space/2023/03/02/4b16cef6602a4586a21d6346bf25d300\",\n \"wecom\": \"https://s4.vika.cn/space/2023/03/02/60119b1b69b64aa887bd1be6a2928bec\",\n \"feishu\": \"https://u.vika.cn/z9ygm\"\n },\n \"type\": \"contactUs\",\n \"next\": true\n }\n ]\n}\n", @@ -45222,13 +46601,13 @@ "player_step_ui_config_41": "", "player_step_ui_config_42": "{\n \"element\": \"#DATASHEET_FORM_LIST_PANEL\", \n\"placement\": \"leftTop\",\n \"title\": \"Form\", \n\"description\": \"You can quickly create a form from the current view. The number and order of the fields in the form is consistent with the view.\", \"children\":\"\" \n}", "player_step_ui_config_43": "{\n \"element\": \".style_navigation__1U5cR .style_help__1sXEA\", \n\"placement\": \"rightBottom\",\n \"title\": \"Tip\", \n\"offsetY\":5,\n\"description\": \"You can find your Vikaby assistant from the \"Help\" icon on the left\", \"children\":\"\" \n}", - "player_step_ui_config_44": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", + "player_step_ui_config_44": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", "player_step_ui_config_45": "", "player_step_ui_config_46": "", "player_step_ui_config_47": "{\n \"element\": \"#DATASHEET_WIDGET_BTN\",\n\"placement\": \"bottomRight\",\n \"title\": \"Widget\", \n\"description\": \"Want to use and view your data in a richer way? Try the widget!\", \"children\":\"\" \n}", "player_step_ui_config_48": "", "player_step_ui_config_49": "{\n \"element\": \".style_widgetPanelContainer__1l2ZV\",\n\"placement\": \"leftCenter\",\n \"title\": \"What is a widget\", \n\"description\": \"Vika widgets are an extended application of vikadata that features in richer data visualization, data transfer, data cleansing, and more. By installing widgets in the widget board, you can make work a lot easier.\", \"children\":\"\" \n}", - "player_step_ui_config_5": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", + "player_step_ui_config_5": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", "player_step_ui_config_50": "{\n \"element\": \".style_widgetModal__eXmdB\",\n\"placement\": \"leftTop\",\n \"title\": \"Widget Center\", \n\"description\": \"Officially recommended and custom widgets are published here. You can install any widget you want onto a dashboard or into a widget board of any datasheet.\", \"children\":\"\" \n}", "player_step_ui_config_51": "{\n \"element\": \".style_widgetModal__eXmdB .style_widgetItem__3Pl-1 button\",\n\"placement\": \"rightBottom\",\n \"title\": \"Install widget\", \n\"description\": \"Let's install this \"Chart\" widget\", \"children\":\"\" \n}", "player_step_ui_config_52": "", @@ -45325,6 +46704,7 @@ "preview_guide_click_to_restart": "Нажмите кнопку ниже для просмотра", "preview_guide_enable_it": "Нажмите кнопку ниже, чтобы открыть эту функцию", "preview_guide_open_office_preview": "Для предварительного просмотра этого файла откройте функцию \"Office Preview\"", + "preview_next_automation_execution_time": "Предварительный просмотр следующих 10 раз выполнения", "preview_not_support_video_codecs": "Просмотр только видео MP4 с видеокодеком H.264", "preview_revision": "Предварительный просмотр", "preview_see_more": "Хотите узнать больше о функции « Предварительный просмотр офисных документов»? Пожалуйста, нажмите здесь.", @@ -45360,6 +46740,7 @@ "privacy_protection": "\"Защита конфиденциальности\"", "private_cloud": "Частное облако", "private_external_person_only": "Только внешний персонал", + "private_help_link": "https://help.aitable.ai/docs/guide/team-and-private-area#private-area", "private_internal_person_only": "Только внутренний персонал", "private_product_point": "Приобретите свою платформу APITable одним щелчком мыши", "privatized_deployment": "Автохостинг", @@ -45430,13 +46811,15 @@ "reconciled_data": "Данные проверяются.", "record": "Запись", "record_activity_experience_tips": "Вы можете просматривать записи об активности за ${day} дней.", + "record_archived_data": "архивная запись", + "record_chunk_text": "${text} rows, please wait", "record_comment": "Только примечания", "record_comments": "Замечания", "record_fail_data": "Ошибка данных", "record_filter_tips": "Эта запись была просмотрена.", "record_functions": "Функция записи", "record_history": "Пересмотр только исторических записей", - "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-history", + "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-activity", "record_history_title": "История записей", "record_pre_filtered": "Эта запись была отфильтрована и будет скрыта при щелчке на внешней стороне записи", "record_pre_move": "После щелчка на внешней стороне записи запись будет перемещена в другое место", @@ -45876,6 +47259,12 @@ "scan_to_login": "Сканирование записей", "scan_to_login_by_method": "Отсканируйте ${method}, чтобы войти в официальный аккаунт", "scatter_chart": "Диаграмма распространения", + "schedule_day_tips": "Расчет цикла начинается отсчет с первого числа каждого месяца. Если предположить, что он повторяется каждые 10 дней, то он будет срабатывать 1, 11, 21 и 31 числа каждого месяца.", + "schedule_hour_tips": "Расчет цикла начинается в полночь (0:00) каждого дня. Если предположить, что оно повторяется каждые три часа, оно будет происходить в полночь (0:00), 3:00, 6:00, 9:00, полдень (12:00), 15:00, 18:00 и, наконец, с наступлением темноты (21:00) ежедневно.", + "schedule_start_day": "Начиная с 1-го числа месяца, каждый", + "schedule_start_month": "Начиная с января каждого года, каждый", + "schedule_type": "Тип расписания", + "schedule_year_tips": "Расчет цикла начинается отсчет с первого месяца каждого года. Если предположить, что интервал в первый день составляет 3 месяца, триггеры будут активироваться в полночь первого дня января, апреля, июля и октября каждого года.", "science_and_technology": "Наука и техника", "scroll_screen_down": "Прокрутить экран вниз", "scroll_screen_left": "Прокрутить экран влево", @@ -45889,6 +47278,7 @@ "search_folder_or_sheet": "Поиск файлов", "search_new_admin": "Поиск", "search_node_pleaseholder": "Поиск файлов (${shortcutKey})", + "search_node_tip": "Быстрый поиск (${shortcutKey})", "search_or_add": "Поиск или добавление опций", "search_role_placeholder": "Поиск ролей", "seats": "Места", @@ -46292,6 +47682,7 @@ "space_info": "Общий обзор", "space_info_del_confirm1": "Удаление этого общего пространства очистит следующие данные:", "space_info_del_confirm2": "Общее пространство будет полностью удалено через семь дней. До этого времени вы можете восстановить пространство.", + "space_info_del_confirm3": "3. For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "space_info_feishu_desc": "Вы используете стороннюю интеграцию. Чтобы удалить общее пространство, сначала отключите стороннюю интеграцию.", "space_info_feishu_label": "Интеграция", "space_join_apply": "Запрос на включение пространства \"a class =\" spaceName \"< / a >.", @@ -46378,6 +47769,7 @@ "start_onfiguration": "Настройка запуска", "start_time": "Время начала", "start_use": "Начало использования", + "starting_from_midnight": "Начиная с полуночи (12:00) каждый день, каждый", "startup": "Запуск", "startup_company_support_program": "Запуск программы поддержки", "stat_average": "Средний", @@ -46411,6 +47803,8 @@ "stay_tuned_for_more_features": "Пожалуйста, обратите внимание на дополнительные функции.", "steps_choose_reset_mode": "Выберите метод сброса", "steps_validate_identities": "Идентификация", + "stop_chunk_content": "Are you sure you want to stop the operation?", + "stop_chunk_title": "Stop", "stop_dingtalk_h5_modal_content": "Самостоятельное приложение снимет привязку из этого пространства. Пожалуйста, подтвердите.", "storage_per_seats": "", "storage_per_space": "Использование хранилища", @@ -46441,9 +47835,11 @@ "subscribe_credit_usage_over_limit": "количество кредитов в текущем пространстве превышает лимит, пожалуйста, обновите подписку.\n", "subscribe_demonstrate": "Запросить демонстрацию", "subscribe_disabled_seat": "Численность не должна быть ниже запланированной.", + "subscribe_grade_business": "Бизнес", "subscribe_grade_free": "Свободный", "subscribe_grade_plus": "А", "subscribe_grade_pro": "Согласен.", + "subscribe_grade_starter": "Стартер", "subscribe_label_tooltip": "Расширенные пространственные функции", "subscribe_new_choose_member": "Поддерживает до ${member_num} участников", "subscribe_new_choose_member_tips": "Этот план поддерживает 1~${member_num} участников для входа в пространство", @@ -46580,7 +47976,7 @@ "template_name_repetition_title": "\"${templateName}\" уже существует. Вы хотите заменить это?", "template_no_template": "Нет шаблонов", "template_not_found": "Не нашли нужный шаблон? Скажи нам.", - "template_recommend_title": "Горячий", + "template_recommend_title": "🌟 Hot", "template_type": "Образец", "terms_of_service": "< Условия обслуживания >", "terms_of_service_pure_string": "Условия предоставления услуг", @@ -46624,6 +48020,7 @@ "text_editor_tip_end": "\"Введите\" Конец редактирования", "text_functions": "Строчная функция", "thailand": "Таиланд", + "the_button_field_is_misconfigured": "Поле кнопки настроено неправильно. Проверьте и повторите попытку.", "the_current_automation_workflow_has_no_related_files_you_can_establish_a_link_by_adding_trigger_conditions_and_actions_on_the_left_side": "текущий рабочий процесс автоматизации не имеет соответствующих файлов. вы можете установить ссылку, добавив условия триггера и действия с левой стороны", "the_current_button_column_has_expired_please_reselect": "Срок действия текущего столбца кнопок истек, выберите еще раз.", "the_last_7_days": "Последние 7 дней", @@ -46726,6 +48123,7 @@ "timemachine_update_comment": "Обновлены комментарии", "times_per_month_unit": "Телефон / месяц", "times_unit": "Телефон", + "timing_rules": "Тайминг", "timor_leste": "Тимор - Лешти", "tip_del_success": "Вы можете восстановить свое общее пространство за 7 дней.", "tip_do_you_want_to_know_about_field_permission": "Хотите зашифровать данные поля? Права доступа к полю", @@ -46913,6 +48311,7 @@ "verify_account_title": "Проверка учетной записи", "verify_via_email": "Идентификация по электронной почте", "verify_via_phone": "Авторизация SMS", + "video": "видео", "video_not_support_play": "Текущий формат видео не поддерживает онлайн", "vietnam": "Вьетнам", "view": "Замечания", @@ -47261,7 +48660,8 @@ "workdoc_color_title": "Цвет шрифта", "workdoc_create": "Создать рабочий документ", "workdoc_expanded": "Развернуть оглавление", - "workdoc_image_max_10mb": "Размер изображения не может превышать 10 МБ.", + "workdoc_image_max_10mb": "нулевой", + "workdoc_image_max_size": "Размер изображения не может превышать ${size}", "workdoc_info": "Информация о документе", "workdoc_info_create_time": "Создан в", "workdoc_info_creator": "Сделано", @@ -47269,6 +48669,7 @@ "workdoc_info_last_modify_time": "Изменить время", "workdoc_link_placeholder": "Пожалуйста, введите ссылку", "workdoc_only_image": "Разрешено только изображение", + "workdoc_only_video": "Разрешено только видео", "workdoc_text_placeholder": "Введите \"/\" быстрый старт", "workdoc_title_placeholder": "Пожалуйста, введите название", "workdoc_unnamed": "Безымянный рабочий документ", @@ -47277,9 +48678,11 @@ "workdoc_unsave_ok": "Отменить изменения", "workdoc_unsave_title": "Рабочий документ не сохранен.", "workdoc_upload_failed": "Загрузка не удалась", + "workdoc_video_max_size": "Размер видео не может превышать ${size}", "workdoc_ws_connected": "Связанный", "workdoc_ws_connecting": "Подключение...", "workdoc_ws_disconnected": "Отключено", + "workdoc_ws_reconnecting": "Повторное подключение...", "workflow_execute_failed_notify": " не удалось выполнить в . Просмотрите историю выполнения, чтобы устранить проблему. Если вам нужна помощь, пожалуйста, свяжитесь с нашей службой поддержки клиентов.", "workspace_data": "Пространственные данные", "workspace_files": "Данные рабочего стола", @@ -47458,6 +48861,15 @@ "agreed": "已同意", "ai_advanced_mode_desc": "高级模式允许用户自定义提示,从而更好地控制 AI 助手的行为和响应。", "ai_advanced_mode_title": "高级模式", + "ai_agent_anonymous": "匿名用户${ID}", + "ai_agent_conversation_continue_not_supported": "当前暂不支持继续之前的聊天记录会话", + "ai_agent_conversation_list": "会话列表", + "ai_agent_conversation_log": "会话日志", + "ai_agent_conversation_title": "会话标题", + "ai_agent_feedback": "反馈", + "ai_agent_historical_message": "以上是历史消息", + "ai_agent_history": "历史", + "ai_agent_message_consumed": "消耗的算力点", "ai_api_curl_template": "## Create chat completions\n\n```bash\n\ncurl -X POST \"{{apiBase}}/fusion/v1/ai/{{aiId}}/chat/completions\" \\\n -H \"Content-Type: application/json\" \\\n -H \"Authorization: Bearer {{token}}\" \\\n -d '{\n \"model\": \"gpt-3.5-turbo\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"You are a helpful assistant.\"\n },\n {\n \"role\": \"user\",\n \"content\": \"Hello!\"\n }\n ]\n }'\n\n```\n\n## Returned data example\n\n```json\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", "ai_api_footer_desc": "将 chatBot 嵌入您的网站?了解更多", "ai_api_javascript_template": "## Initialize SDK [![github]({{ githubIcon }})](https://github.com/openai/openai-node)\nAITable's chat completion API is compatible with OpenAI's Node.js SDK. You can use our service with the same SDK by simply changing the configuration as follows:\n\n\n```javascript\nconst { Configuration, OpenAIApi } = require(\"openai\");\nconst configuration = new Configuration({\n apiKey: \"{{token}}\",\n basePath: \"{{apiBase}}/fusion/v1/ai/{{aiId}}\"\n});\n```\n\n## Create chat completions\n\n```javascript\nconst openai = new OpenAIApi(configuration);\nconst chatCompletion = await openai.createChatCompletion({\n model: \"gpt-3.5-turbo\",\n messages: [{role: \"user\", content: \"Hello world\"}],\n});\n```\n\n## Returned data example\n\n```javascript\n\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", @@ -47474,6 +48886,9 @@ "ai_chat_unit": "AI 助手", "ai_close_setting_tip_content": "您所做的更改尚未保存,是否要放弃?", "ai_close_setting_tip_title": "未保存的更改", + "ai_copilot_generate_response": "为您生成答案...", + "ai_copilot_processs": "处理中,请稍候...", + "ai_copilot_start_process_request": "开始处理您的请求...", "ai_create_guide_btn_text": "选择表格", "ai_create_guide_content": "作为一个 AI 助手,我可以根据我学到的知识回答你的问题。在开始对话之前,请选择一个表格作为数据集,我会读取其中的所有数据进行学习。", "ai_credit_cost_chart_title": "算力点", @@ -47641,7 +49056,7 @@ "api_delete_error": "删除数据失败", "api_delete_error_foreign_datasheet_deleted": "删除记录失败,因为关联表已被删除", "api_embed_link_id_not_exist": "指定的嵌入链接不存在,请调整 linkId 后再试", - "api_embed_link_instance_limit": "抱歉, 暂时仅支持表格、仪表盘、表单类的节点创建嵌入链接", + "api_embed_link_instance_limit": "抱歉, 暂时仅支持表格、仪表盘、表单、镜像类的节点创建嵌入链接", "api_embed_link_limit": "创建的嵌入链接数量已达上限,单个维格表的嵌入链接数量不能超过{value}个", "api_enterprise_limit": "抱歉,此接口仅可在黄金级以上的空间站中调用", "api_example_request": "示例请求", @@ -47857,6 +49272,7 @@ "api_params_updatedby_can_not_operate": "修改人列的值由系统自动生成,不允许编辑", "api_params_views_max_count_error": "", "api_params_widget_package_id_error": "widgetPackageId 不能为空", + "api_params_workdoc_can_not_operate": "WorkDoc field can't be edited", "api_query_params_invalid_fields": "传入的 fields 不存在:{fields}", "api_query_params_view_id_not_exists": "查询的视图({viewId}) 不存在 ", "api_request_success": "成功", @@ -47939,7 +49355,7 @@ "apps_support": "全平台客户端支持", "archive_delete_record": "删除归档记录", "archive_delete_record_title": "删除记录", - "archive_notice": "

正在尝试对选定的记录进行归档,一旦记录被归档,将会发生以下变化:

1. 该记录的所有双向关联关系将被取消

2. 不支持通过任何方式进行编辑

3. 不支持日期提醒、关注记录等功能

4. 不再参与神奇引用、公式等字段的计算

确定要继续吗?(在高级能力里的归档箱中可以取消归档)

", + "archive_notice": "

正在尝试对选定的记录进行归档,一旦记录被归档,将会发生以下变化:

1. 不支持通过任何方式进行编辑

2. 不支持日期提醒、关注记录等功能

3. 不再参与神奇引用、公式等字段的计算

确定要继续吗?(在高级功能中的归档箱可以取消归档)

", "archive_record_in_activity": " 归档了这条记录", "archive_record_in_menu": "归档记录", "archive_record_success": "已归档记录", @@ -47964,7 +49380,7 @@ "assistant_activity_train_camp": "限时福利", "assistant_beginner_task": "新手任务", "assistant_beginner_task_1_what_is_datasheet": "什么是 APITable", - "assistant_beginner_task_2_quick_start": "一分钟快速入门", + "assistant_beginner_task_2_quick_start": "VIKA产品演示", "assistant_beginner_task_3_how_to_use_datasheet": "玩转一张维格表", "assistant_beginner_task_4_share_and_invite": "分享和邀请成员", "assistant_beginner_task_5_onboarding": "智能引导", @@ -47998,7 +49414,8 @@ "audit_add_field_role": "添加列权限", "audit_add_field_role_detail": "在\"\" 数据表 , 添加 [] 角色作为 [] 字段 [] ", "audit_add_node_role": "添加文件节点权限", - "audit_add_node_role_detail": "添加文件节点权限,将「${unitNames}」设置为「${currentNodeName}」的「${role}」角色", + "audit_add_node_role_detail_end": "的「${role}」角色", + "audit_add_node_role_detail_start": "添加文件节点权限,将「${unitNames}」设置为", "audit_admin_permission_change_event": "管理员权限变更", "audit_create_template": "创建模板", "audit_create_template_detail": "创建模板内容", @@ -48006,21 +49423,26 @@ "audit_delete_field_role": "删除列权限", "audit_delete_field_role_detail": "审计内容", "audit_delete_node_role": "删除文件节点权限", - "audit_delete_node_role_detail": "删除文件节点权限,将「${unitNames}」在「${currentNodeName}」的「${role}」角色删除", + "audit_delete_node_role_detail_end": "的「${role}」角色删除", + "audit_delete_node_role_detail_start": "删除文件节点权限,将「${unitNames}」在", "audit_delete_template": "删除模板", "audit_delete_template_detail": "删除模板内容", "audit_disable_field_role": "关闭列权限", "audit_disable_field_role_detail": "审计内容", "audit_disable_node_role": "关闭文件权限", - "audit_disable_node_role_detail": "关闭${nodeType}权限,名称为「${currentNodeName}」", + "audit_disable_node_role_detail_end": "`s permission", + "audit_disable_node_role_detail_start": "关闭${nodeType}权限,名称为", "audit_disable_node_share": "关闭文件节点公开链接", - "audit_disable_node_share_detail": "关闭${nodeType} 「${currentNodeName}」 的公开链接", + "audit_disable_node_share_detail_end": "的公开链接", + "audit_disable_node_share_detail_start": "关闭${nodeType}", "audit_enable_field_role": "开启列权限", "audit_enable_field_role_detail": "审计内容", "audit_enable_node_role": "开启文件权限", - "audit_enable_node_role_detail": "开启${nodeType}权限,名称为 「${currentNodeName}」", + "audit_enable_node_role_detail_end": "`s permission", + "audit_enable_node_role_detail_start": "开启${nodeType}权限,名称为", "audit_enable_node_share": "开启文件节点公开链接", - "audit_enable_node_share_detail": "开启${nodeType} 「${currentNodeName}」 的公开链接", + "audit_enable_node_share_detail_end": "的公开链接", + "audit_enable_node_share_detail_start": "开启${nodeType}", "audit_login_event": "登录事件", "audit_logout_event": "注销事件", "audit_organization_change_event": "通讯录组织架构变更", @@ -48040,19 +49462,20 @@ "audit_space_invite_user": "审计内容", "audit_space_invite_user_detail": "审计内容", "audit_space_node_copy": "复制文件节点", - "audit_space_node_copy_detail": "复制${nodeType}「${sourceNodeName}」,新文件节点名称为「${currentNodeName}」", + "audit_space_node_copy_detail_start": "复制${nodeType}「${sourceNodeName}」,新文件节点名称为", "audit_space_node_create": "创建文件节点", - "audit_space_node_create_detail": "创建${nodeType},名称为「${currentNodeName}」", + "audit_space_node_create_detail_start": "创建${nodeType},名称为", "audit_space_node_delete": "删除文件节点", - "audit_space_node_delete_detail": "删除${nodeType},名称为「${currentNodeName}」", + "audit_space_node_delete_detail_start": "删除${nodeType},名称为", "audit_space_node_export": "导出数表", "audit_space_node_export_detail": "成员 ${member_name} 导出表 ${node_name}", "audit_space_node_import": "导入文件节点", - "audit_space_node_import_detail": "导入文件节点,名称为 「${nodeName}」", + "audit_space_node_import_detail_start": "导入文件节点,名称为", "audit_space_node_move": "移动文件节点", - "audit_space_node_move_detail": "移动${nodeType}「${currentNodeName}」到文件夹「${parentName}」下方", + "audit_space_node_move_detail_end": "到文件夹「${parentName}」下方", + "audit_space_node_move_detail_start": "移动${nodeType}", "audit_space_node_rename": "重命名文件节点", - "audit_space_node_rename_detail": "重命名${nodeType},将「${oldNodeName}」名称修改为「${nodeName}」", + "audit_space_node_rename_detail_start": "重命名${nodeType},将「${oldNodeName}」名称修改为", "audit_space_node_sort": "审计内容", "audit_space_node_sort_detail": "审计内容", "audit_space_node_update_cover": "审计内容", @@ -48066,18 +49489,21 @@ "audit_space_rubbish_node_delete": "审计内容", "audit_space_rubbish_node_delete_detail": "审计内容", "audit_space_rubbish_node_recover": "恢复回收舱节点", - "audit_space_rubbish_node_recover_detail": "从回收舱恢复${nodeType},名称为「${currentNodeName}」", + "audit_space_rubbish_node_recover_detail_end": "from the trash", + "audit_space_rubbish_node_recover_detail_start": "从回收舱恢复${nodeType},名称为", "audit_space_template_event": "空间站模板事件", "audit_space_update_logo": "审计内容", "audit_space_update_logo_detail": "审计内容", "audit_store_share_node": "转存文件节点", - "audit_store_share_node_detail": "将${nodeType}转存到本空间站,名称为 「${nodeName}」", + "audit_store_share_node_detail_start": "将${nodeType}转存到本空间站,名称为", "audit_update_field_role": "审计内容", "audit_update_field_role_detail": "审计内容", "audit_update_node_role": "修改文件节点权限", - "audit_update_node_role_detail": "修改文件节点权限,将「${unitNames}」修改为「${currentNodeName}」的「${role}」角色", + "audit_update_node_role_detail_end": "的「${role}」角色", + "audit_update_node_role_detail_start": "修改文件节点权限,将「${unitNames}」修改为", "audit_update_node_share_setting": "修改文件节点公开链接", - "audit_update_node_share_setting_detail": "修改${nodeType} 「${currentNodeName}」 的公开链接的设置", + "audit_update_node_share_setting_detail_end": "的公开链接的设置", + "audit_update_node_share_setting_detail_start": "修改${nodeType}", "audit_user_login": "用户登录", "audit_user_login_detail": "审计内容", "audit_user_logout": "用户登出", @@ -48120,6 +49546,7 @@ "automation_enabled_return_via_related_files": "自动化已启用。请通过“相关文件”重新进入原表以使用新的按钮列。", "automation_field": "字段", "automation_import_variables_from_pre_tep": "从前置步骤获取数据", + "automation_is_not_yet_enabled": "自动化尚未启用,请启用后再试", "automation_last_edited_by": "修改者", "automation_last_edited_time": "修改时间", "automation_manager_label": "拥有该自动化的所有操作权限", @@ -48225,7 +49652,7 @@ "button_bind_now": "立即绑定", "button_change_phone": "修改手机", "button_check_history": "查看运行历史", - "button_check_history_end": "", + "button_check_history_end": ".", "button_click_trigger_explanation": "\"按钮被点击时\" 是一个触发条件,当用户点击你新建的按钮列时,它会被触发", "button_color": "按钮颜色", "button_combine": "按钮组合", @@ -48241,10 +49668,19 @@ "button_text": "按钮文案", "button_text_click_start": "点击开始", "button_type": "按钮类型", + "by_at": "的", + "by_days": "按天", + "by_every": "每隔", "by_field_id": "使用 Field ID", + "by_hours": "按小时", + "by_in": "的", + "by_min": "分", + "by_months": "按月", + "by_on": "的", "by_the_day": "按天", "by_the_month": "按月", "by_the_year": "按年", + "by_weeks": "按周", "calendar_add_date_time_field": "创建日期", "calendar_color_more": "更多颜色", "calendar_const_detail_weeks": "[\"星期一\",\"星期二\",\"星期三\",\"星期四\",\"星期五\",\"星期六\",\"星期天\"]", @@ -48308,6 +49744,14 @@ "cannot_activate_space_by_space_limit": "已激活空间站数量达到上限,删除或退出已激活的空间站后,可手动激活", "cannot_join_space": "你的空间站数量已达10个上限,暂时无法加入新的空间站。", "cannot_switch_field_permission": "设置的列权限不能高于 TA 的文件权限,请先提高 TA 的文件权限", + "capacity_file_detail_desc": "空间站内的文件节点总量是由团队工作区的文件节点数与每位成员在个人工作区内创建的文件节点数相加而成。数量不够?", + "capacity_file_detail_title": "文件节点数量详情", + "capacity_file_member": "成员", + "capacity_file_member_private_node_count": "个人文件数", + "capacity_file_member_private_percent": "占比", + "capacity_file_member_team": "小组", + "capacity_file_member_team_node_count": "团队文件数", + "capacity_file_upgrade": "点击升级空间站", "capacity_from_official_gift": "官方赠送", "capacity_from_participation": "邀请新用户 ${user} 加入空间站", "capacity_from_purchase": "购买容量", @@ -48344,6 +49788,8 @@ "catalog": "工作目录", "catalog_add_from_template_btn_title": "从模板创建", "catalog_empty_tips": "当前空间站没有文件,从模板创建文件、仪表盘,快速开始吧", + "catalog_private": "个人", + "catalog_team": "团队", "category_blank": "[空值]", "catering": "餐饮业", "cayman_islands": "开曼群岛", @@ -48412,6 +49858,7 @@ "choose_type_of_vika_field": "选择维格列类型", "choose_your_own_space": "(仅支持另存到自己是主管理员的空间站)", "chose_new_primary_admin_button": "确认移交", + "chunk_stopping_title": "正在终止", "claim_special_offer": "获取特殊优惠", "clear": "清除", "clear_all_fields": "重置", @@ -48542,6 +49989,7 @@ "confirm_del_current_team": "确认是否删除当前小组", "confirm_delete": "确认删除", "confirm_delete_node_name_as": "确认要删除「${nodeNameDiv}」吗?", + "confirm_delete_private_node_name_as": "个人文件删除后无法进行恢复, 确认要删除「${nodeNameDiv}」吗?", "confirm_delete_space_btn": "了解并继续删除", "confirm_exit": "确认退出", "confirm_exit_space_with_name": "确认是否退出「${spaceNameDiv}」空间站\n", @@ -48579,6 +50027,14 @@ "convert": "转换", "convert_tip": "此操作可能会清除某些单元格内已有的数据,如果转换有问题,则可以撤销该操作", "cook_islands": "库克群岛", + "copilot_auto_agent_desc": "不知道选哪个?试试看全能助手", + "copilot_auto_agent_name": "全能助手", + "copilot_data_agent_desc": "基于您的视图生成数据分析/可视化", + "copilot_data_agent_name": "数据分析助手", + "copilot_data_agent_policy": "当与Copliot 开始对话时默认你已同意用户协议", + "copilot_data_agent_policy_button": "用户协议", + "copilot_help_agent_desc": "询问有关AITable帮助中心文档的任何问题", + "copilot_help_agent_name": "检索帮助中心", "copy": "的副本", "copy_automation_url": "复制自动化的 URL", "copy_card_link": "复制该记录的 URL", @@ -48623,6 +50079,7 @@ "create_mirror_guide_content": "镜像具有隐藏部分数据的功能,你可以在原表的视图中设置“筛选条件”和“隐藏字段”来控制镜像中需要展示的记录和字段。\n
\n
\n如果配合「视图锁」功能一起使用,可以防止其他人修改。\n
\n
\n另外,前往「原表>隐藏字段」可以修改“镜像中允许查看隐藏字段”的配置", "create_mirror_guide_title": "镜像将隐藏部分记录和字段", "create_new_button_field": "新建一个按钮列字段", + "create_private_node_tip": "个人或者临时类的草稿文件可以在这里创建 ${link}", "create_public_invitation_link": "创建公开的邀请链接", "create_space_sub_title": "Hi,给你的空间站起个名字吧", "create_team_fail": "添加小组失败", @@ -48686,10 +50143,13 @@ "custom_enterprise": "企业级空间站支持自定义人数、时长,灵活又强大", "custom_function_development": "定制功能开发", "custom_grade_desc": "提供原厂私有化安装部署,您可以获得企业级咨询服务、专家技术支持和定制化专业服务", + "custom_page_setting_title": "新建自定义页面", "custom_picture": "自定义图片", "custom_style": "样式", "custom_upload": "自定义上传", "custom_upload_tip": "推荐使用 1:1 的方形图片以达到更好的视觉体验", + "custome_page_setting_title": "添加自定义页面", + "custome_page_title": "自定义网页", "cut_cell_data": "剪切", "cyprus": "塞浦路斯", "czech": "捷克", @@ -48742,6 +50202,7 @@ "default_create_ai_chat_bot": "新建 AI 助手", "default_create_airagent": "新建Agent", "default_create_automation": "新建自动化", + "default_create_custom_page": "新建自定义页面", "default_create_dashboard": "新建仪表盘", "default_create_datasheet": "新建表格", "default_create_file": "新建节点", @@ -48763,7 +50224,8 @@ "del_invitation_link": "确定删除邀请链接", "del_invitation_link_desc": "删除后已生成的分享链接将会失效", "del_space_now": "彻底删除空间站", - "del_space_now_tip": "请注意:空间站删除后将不可恢复,包含所有表格、附件都会被彻底删除", + "del_space_now_confirm_tip": "再次提醒:如果空间站已订阅付费,删除空间站将会一并移除付费权益,该权益无法转移,请慎重操作!", + "del_space_now_tip": "请注意:空间站删除后将不可恢复,包含所有表格、附件都会被彻底删除。", "del_space_res_tip": "删除空间站成功", "del_team_success": "删除小组成功", "del_view_content": "确认要删除视图「${view_name}」吗?", @@ -48958,6 +50420,61 @@ "embed_error_page_help": "点击了解失效原因", "embed_fail_og_description_content": "该嵌入的公开链接已被关闭,暂时无法访问", "embed_failed": "嵌入链接已失效, ", + "embed_link_bilibili": "哔哩哔哩", + "embed_link_bilibili_desc": "通过嵌入哔哩哔哩视频,你可以在维格云观看教程、指南或其他视频资源,放置个人主页等,", + "embed_link_bilibili_link_text": "如何嵌入哔哩哔哩视频", + "embed_link_bilibili_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-bilibili-video", + "embed_link_default": "任何链接", + "embed_link_default_desc": "任何链接都行,", + "embed_link_default_link_text": "了解更多", + "embed_link_default_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_link_figma": "Figma", + "embed_link_figma_desc": "通过嵌入 Figma 文件,团队成员可以更方便地查看和编辑设计稿,提高协作效率,", + "embed_link_figma_link_text": "如何嵌入 Figma 文件", + "embed_link_figma_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-figma-file", + "embed_link_google_docs": "谷歌文档", + "embed_link_google_docs_desc": "通过嵌入谷歌文档,你可以在 AITable 中编辑和查看文档,方便团队协作,", + "embed_link_google_docs_link_text": "如何嵌入谷歌文档", + "embed_link_google_docs_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-docs-file", + "embed_link_google_sheets": "谷歌表格", + "embed_link_google_sheets_desc": "通过嵌入谷歌表格,你可以在 AITable 中编辑和查看表格,方便团队协作,", + "embed_link_google_sheets_link_text": "如何嵌入谷歌表格", + "embed_link_google_sheets_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-sheets-file", + "embed_link_jishi_design": "即时设计", + "embed_link_jishi_design_desc": "通过嵌入即时设计的文件,团队成员可以更方便地查看和编辑设计稿,提高协作效率,", + "embed_link_jishi_design_link_text": "如何嵌入即时设计文件", + "embed_link_jishi_design_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-js-design-file", + "embed_link_tencent_docs": "腾讯文档", + "embed_link_tencent_docs_desc": "通过嵌入腾讯文档,你可以在维格云中和团队成员协作,实时编辑和查看腾讯文档,提高协作效率,", + "embed_link_tencent_docs_link_text": "如何嵌入腾讯文档", + "embed_link_tencent_docs_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-tencent-docs", + "embed_link_wps": "WPS", + "embed_link_wps_desc": "通过嵌入 WPS 文件,你可以在维格云中编辑和查看 WPS 的文档、表格、表单等,提高协作效率,", + "embed_link_wps_link_text": "如何嵌入 WPS 文件", + "embed_link_wps_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-wps-file", + "embed_link_youtube": "YouTube", + "embed_link_youtube_desc": "通过嵌入 YouTube 视频,你可以在 AITable 中观看教程、指南,或查看频道主页等,", + "embed_link_youtube_link_text": "如何嵌入 Youtube 视频", + "embed_link_youtube_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-youtube-video", + "embed_page": "自定义页面", + "embed_page_add_url": "添加网址", + "embed_page_doc_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_page_function_desc": "将网页添加到${edition},以便轻松访问第三方网站的文档、视频等内容。您可以添加推荐的网站链接或任何自定义链接。", + "embed_page_node_permission_editor": "在「只可更新」基础上,还可以打开文件的公开分享", + "embed_page_node_permission_manager": "拥有该文件的所有操作权限", + "embed_page_node_permission_reader": "可查看自定义页面的内容和文件基本信息", + "embed_page_node_permission_updater": "在「只可阅读」基础上,还可以修改自定义页面的链接", + "embed_page_url_invalid": "请输入正确的网址", + "embed_paste_link_bilibili_placeholder": "粘贴哔哩哔哩视频链接", + "embed_paste_link_default_placeholder": "粘贴链接", + "embed_paste_link_figma_placeholder": "粘贴 Figma 文件的分享链接", + "embed_paste_link_google_docs_placeholder": "粘贴谷歌文档分享链接", + "embed_paste_link_google_sheets_placeholder": "粘贴谷歌表格分享链接", + "embed_paste_link_jsdesign_placeholder": "粘贴即时设计文件的分享链接", + "embed_paste_link_tencent_docs_placeholder": "粘贴腾讯文档的分享链接", + "embed_paste_link_wps_placeholder": "粘贴 WPS 文件的分享链接", + "embed_paste_link_youtube_placeholder": "粘贴 YouTube 视频链接", + "embed_success": "添加成功", "emoji_activity": "活动和事件", "emoji_custom": "自定义", "emoji_flags": "旗帜", @@ -49064,6 +50581,11 @@ "estonia": "爱沙尼亚", "ethiopia": "埃塞俄比亚", "event_planning": "活动策划", + "every": "每", + "every_day_at": "天", + "every_hour_at": "个小时", + "every_month_at": "个月", + "every_week_at": "每周的", "everyday_life": "日常生活", "everyone_visible": "全员可见", "exact_date": "指定日期", @@ -49074,6 +50596,7 @@ "exchange": "兑换", "exchange_code_times_tip": "请注意,兑换码只能兑换一次", "exclusive_consultant": "专属 V+ 顾问", + "exclusive_limit_plan_desc": "Exclusive Limited Tier", "exist_experience": "退出体验", "exits_space": "退出空间", "expand": "展开", @@ -49603,7 +51126,7 @@ "function_set_timezone_summary": "为指定日期设置特定的时区。\n\n【date】是指定日期。\n【tz_identifier】是时区说明符。比如\"8\"代表东8区,\"-2\"代表西2区。\n\n本函数必须与DATETIME_FORMAT结合使用。", "function_sqrt_example": "SQRT(10000)\n=> 100", "function_sqrt_summary": "返回数值的平方根。\n\n【value】是要对其求平方根的数值。\n\n如果数值为负数,则 SQRT 返回 Nan", - "function_substitute_example": "SUBSTITUTE(\"小胡,小张,小王\", \"小\", \"老\")\n=> 老胡,老张,老王\n\nSUBSTITUTE(\"小胡,小张,小王\", \"小\", \"老\", 3)\n=> 小胡,老张,小王", + "function_substitute_example": "SUBSTITUTE(\"小胡,小张,小王\", \"小\", \"老\")\n=> 老胡,老张,老王\n\nSUBSTITUTE(\"小胡,小张,小王\", \"小\", \"老\", 3)\n=> 小胡,小张,老王", "function_substitute_summary": "将内容中特定的文本全部替换为新文本。\n\n【string】是你输入的一段内容,其中包含了被替换的文本。该内容可以是输入的文本或者引用的维格列数据。\n【old_text】要被替换的原文本。\n【new_text】替换原文本的新文本。\n【index】非必填,是索引号,指定索引号后系统仅会替换特定位置的原文本。\n\n本函数将文本中的原字符替换为新字符,在没有特别声明的情况下,新字符将替换所有出现的原字符。\n\n(如果你想替换指定起点位置和终点位置之间的字符,请参见REPLACE。)", "function_sum_example": "SUM(1, 2, \"3\", \"四\")\n=> 1 + 2 + 3 =6\n\nSUM({数学成绩}, {英语成绩}, {语文成绩})", "function_sum_summary": "将所有数值相加。\n\n【number...】是进行运算的数值参数,可以输入数字或引用数值类型的列。数值类型的列包括数字、货币、百分比、评分等。", @@ -49773,6 +51296,7 @@ "gold_grade": "黄金级", "gold_grade_desc": "适用于有复杂业务流程的团队或组织", "gold_seat_200_desc": "200人", + "gold_seat_300_desc": "300人", "golden_grade": "黄金级", "got_it": "知道了", "got_v_coins": "已获得 V 币奖励", @@ -49806,6 +51330,8 @@ "guests_per_space": "外部访客", "guide_1": "来呀互相伤害呀", "guide_2": "花费几分钟跟随我们的指引,学习一下维格表的常规功能,可以让您事半功倍哦!", + "guide_flow_modal_contact_sales": "预约销售", + "guide_flow_modal_get_started": "立刻使用", "guide_flow_of_catalog_step1": "这是工作目录,里边存放的是空间站的所有文件夹和文件", "guide_flow_of_catalog_step2": "工作目录里面,除了可以单独创建维格表,也可以单独创建文件夹", "guide_flow_of_click_add_view_step1": "除了基本的表格视图之外,我们支持创建相册视图,如果你有图片附件的话,我建议你创建个相册视图试试", @@ -49861,6 +51387,7 @@ "hide_uneditable_automation_node": "隐藏无编辑权限的自动化节点", "hide_unmanage_sheet": "隐藏无管理权限的文件", "hide_unmanageable_files": "隐藏无管理权限的文件", + "hide_unmanaged_sheet": "Hide unmanageable resource", "hide_unusable_sheet": "隐藏无编辑权限的文件", "highlight": "高亮", "hint": "提示", @@ -49984,6 +51511,7 @@ "intro_widget_tips": "什么是小程序?", "introduction": "简介", "invalid_action_sort_tip": "该字段作为分组项已被设置排序,当前设置的排序不会生效", + "invalid_automation_configuration": "自动化配置无效,请检查后再试", "invalid_field_type": "非法的字段类型", "invalid_option_sort_tip": "该字段作为分组项已被设置排序", "invalid_redemption_code_entered": "请输入有效的兑换码", @@ -50114,6 +51642,9 @@ "label_format_day_month_and_year_split_by_slash": "日/月/年", "label_format_month": " 月", "label_format_month_and_day_split_by_dash": "月-日", + "label_format_month_day_year_split_by_dash": "月-日-年", + "label_format_month_day_year_split_by_slash": "月/日/年", + "label_format_month_day_year_two_digit_year_split_by_slash": "月/日/年(两位数年份)", "label_format_year": "年", "label_format_year_and_month_split_by_dash": "年-月", "label_format_year_month_and_day_split_by_dash": "年-月-日", @@ -50181,8 +51712,8 @@ "lark_integration_sync_tip": "通讯录同步中", "lark_login": "飞书登录", "lark_org_manage_reject_msg": "成员列表会实时跟飞书通讯录的组织架构保持同步,请在飞书侧进行此操作(企业管理 > 添加团队成员)", - "lark_single_record_comment_mentioned": "", - "lark_single_record_comment_mentioned_title": "", + "lark_single_record_comment_mentioned": "**维格表: **{nodeName}\n**记录: **{recordTitle}\n\n\"{commentContent}\"", + "lark_single_record_comment_mentioned_title": "**有人在评论中提及你**", "lark_single_record_member_mention": "**记录: **{recordTitle}\n**提及人: **{memberName}\n**维格表: **{nodeName}", "lark_single_record_member_mention_title": "**有人在记录中提及你**", "lark_subscribed_record_cell_updated": "**记录:** {recordTitle}\n**原内容:** {oldDisplayValue}\n**修改后的内容:** {newDisplayValue}\n**修改人:** {memberName}\n**维格表:** {nodeName}", @@ -50192,6 +51723,7 @@ "lark_version_enterprise": "飞书企业版", "lark_version_standard": "飞书标准版", "lark_versions_free": "飞书基础版", + "last_day": "最后一天", "last_modified_by_select_modal_desc": "由于该维格列类型的特殊性,下方只展示可编辑的列,每当有人在指定的列进行过修改,则会更新当前的修改人", "last_modified_time_select_modal_desc": "由于该维格列类型的特殊性,下方只展示可编辑的列,每当有人在指定的列进行过修改,则会更新当前的修改时间", "last_step": "上一步", @@ -50336,7 +51868,7 @@ "mail_invite_fail": "邀请成员失败", "mail_invite_success": "邀请成员成功", "main_admin_name": "主管理员名称", - "main_admin_page_desc": "拥有空间站的最高管理权限,可以分配子管理员或转让空间站", + "main_admin_page_desc": "主管理员具有完整的访问权限,可以分配子管理员,或调整空间站设置", "main_contain": "主要包含内容", "malawi": "马拉维", "malaysia": "马来西亚", @@ -50432,7 +51964,7 @@ "member_applied_to_close_account": "已申请账号注销", "member_data_desc_of_appendix": "工作目录中所有表格内上传附件的大小统计,如果上传附件达到容量上限将无法上传新的附件。", "member_data_desc_of_dept_number": "组织架构中所有小组的数量统计,包括子小组。", - "member_data_desc_of_field_number": "工作目录中所有文件(表格、仪表盘、神奇表单、镜像)的数量统计", + "member_data_desc_of_field_number": "工作目录&空间站模板中所有文件(表格、仪表盘、神奇表单、镜像)的数量统计。", "member_data_desc_of_member_number": "席位数包含已加入的成员数和工作台创建的 AI 助手数的总和。席位数超限后将无法添加成员或者创建 AI 助手", "member_data_desc_of_record_number": "工作目录中所有表格中记录的数量统计,包括空白记录", "member_err": "昵称不能超过32个字", @@ -50556,8 +52088,12 @@ "more_widget": "更多小程序", "morocco": "摩洛哥", "move": "移动", + "move_datasheet_link_warn": "无法单独移到团队工作区,因为当前表存在关联关系,建议将关联的所有表放在一个文件夹里进行移动", "move_favorite_node_fail": "移动节点失败,系统将会自动更新列表", + "move_folder_link_warn": "无法移到团队工作区,因为当前文件夹内的文件与文件夹外的文件有连接关系(可能是关联关系或者被表单等所连接)建议将它们放在一个文件夹里再进行移动", "move_node_modal_content": "移动后,文件的可见性可能会受到上级文件夹的影响", + "move_other_link_no_permission": "你无法移动文件至目标文件夹,因为你缺少该文件夹的管理权限", + "move_other_link_warn": "无法单独将${nodeType}移动至团队工作区,因为它连接了个人工作区的表,建议将它们放在一个文件夹里进行移动", "move_to": "移动至", "move_to_error_equal_parent": "文件已在当前文件夹下方,请选择其他文件夹", "move_to_modal_title": "将「${name}」移动至当前文件夹下", @@ -50588,6 +52124,7 @@ "new_a_line": "Shift+Enter 换行", "new_automation": "新建自动化", "new_caledonia": "新喀里多尼亚", + "new_custom_page": "新建自定义页面", "new_datasheet": "新建表格", "new_folder": "新建文件夹", "new_folder_btn_title": "新建文件夹", @@ -50754,7 +52291,7 @@ "nvc_start_text": "请按住滑块,拖动到最右边", "nvc_yes_text": "验证通过", "obtain_verification_code": "未获取验证码或已过期,请重新获取", - "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrzw0miJVmSkJ7eBBa9k/fomx5qPX0JGPFvfEEP\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", + "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrCvbFC53xc3kl00B4Pg\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", "offical_website_nav_data": "[{\n \"name\": \"产品\",\n \"href\": \"/login\",\n \"children\": [\n {\n \"name\": \"vika维格表 Overview\",\n \"href\": \"/login/\"\n },\n {\n \"name\": \"应用连接 Integration\",\n \"href\": \"/connections/\"\n },\n {\n \"name\": \"客户端(Beta) Download\",\n \"href\": \"/download/\"\n }\n ]\n}, {\n \"name\": \"解决方案\",\n \"href\": \"/\",\n \"children\": [{\n \"name\": \"PMO项目群管理\",\n \"href\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"href\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"href\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"href\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"href\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"href\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"href\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"href\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"href\": \"/shop/\"\n }, {\n \"name\": \"更多解决方案 >\",\n \"href\": \"/solutions/\"\n }]\n}, {\n \"name\": \"模板/案例\",\n \"href\": \"/template\",\n \"children\": [\n {\n \"name\": \"模板中心 Tempaltes\",\n \"href\": \"/template\"\n },\n {\n \"name\": \"客户案例 Customers\",\n \"href\": \"/cases/\"\n }\n ]\n},\n {\n \"name\": \"首页\",\n \"href\": \"/?home=1\"\n },\n {\n \"name\": \"学习资源\",\n \"href\": \"https://edu.vika.cn/index\",\n \"children\": [\n {\n \"name\": \"快速入门 Tutorials\",\n \"href\": \"https://help.vika.cn/docs/guide/tutorial\"\n },\n {\n \"name\": \"产品手册 Manual\",\n \"href\": \"https://help.vika.cn/docs/guide/manual\"\n },\n {\n \"name\": \"维格课堂 Vika Education\",\n \"href\": \"https://edu.vika.cn/\"\n },\n {\n \"name\": \"维格社区 Vika BBS\",\n \"href\": \"https://bbs.vika.cn/\"\n },\n {\n \"name\": \"第三方连接 Integration\",\n \"href\": \"https://help.vika.cn/docs/guide/connection\"\n },\n {\n \"name\": \"开发者中心 Developer Center\",\n \"href\": \"/developers/\"\n },\n {\n \"name\": \"常见问题 FAQ\",\n \"href\": \"https://help.vika.cn/docs/guide/questions\"\n }\n ]\n }]", "office_preview": "Office 文件预览", "office_preview_app_desc": "

在维格表里提供无缝的 office 文件在线预览能力, 让你可以随时随地使用 PC 或手机查看 Excel、Word、PPT 等常见的 office 文件

\n\n
  • 支持在线预览 .doc、.docx、.xls、.xlsx、.ppt、.pptx 和 .pdf 格式的 office 文件
  • 桌面端和移动端同步支持对上述格式的文件预览\n
\n\n

补充说明:

\n
  • 该功能由「永中云转换」提供技术支持,维格表官方进行集成
  • 点击下方 “授权” 按钮,表示启用本应用,并同意「永中云转换」读取你将要预览的 office 文件
  • 如不再需要 office 预览功能,管理员可再次访问此页面进行停用操作
", @@ -50794,6 +52331,7 @@ "open_auto_save_success": "开启自动保存视图配置成功", "open_auto_save_warn_content": "所有成员修改当前视图配置会自动保存并同步给其他成员。(视图配置包括:筛选、分组、排序、隐藏列、布局、样式等)", "open_auto_save_warn_title": "开启自动保存视图配置", + "open_automation_time_arrival": "https://aitable.ai/contact-sales-open-source", "open_failed": "查看失败", "open_in_new_tab": "新标签页打开", "open_invite_after_operate": "打开邀请成员后,全体成员可以在“通讯录面板”进行邀请成员操作", @@ -50940,6 +52478,8 @@ "payment_record": "支付记录", "payment_reminder": "支付提醒", "payment_reminder_content": "你所选择的新方案抵扣金额大于待支付金额,建议你选择更长时长的新方案。如果你确认这样做,超出的金额将不能退还。如有疑问请 ${action}", + "payment_reminder_modal_content": "可以试试看高级版本,享受更多文件节点、企业权限、附件容量、数据量、AI等高级功能和特权。", + "payment_reminder_modal_title": "你目前正在使用免费版", "pending_invite": "待邀请", "people": "人", "per_person_per_year": "每人每年", @@ -51104,12 +52644,12 @@ "player_step_ui_config_163": "", "player_step_ui_config_164": "", "player_step_ui_config_165": "{\n \"headerImg\": \"https://s4.vika.cn/space/2023/03/16/8374ca1295664675bd1155b077555113\",\n \"readMoreUrl\": \"https://help.vika.cn/changelog/23-03-16-updates\",\n \"children\": \"

🚀 新功能介绍

\\n
  • 镜像功能再次升级,可禁止查看已隐藏的字段
  • 个人设置追加时区信息,日期字段可指定时区
  • 「全局搜索」优化,新增搜索结果分类
  • 神奇表单支持隐藏官方标识
  • API 性能优化,大幅提高请求速度
\"\n}", - "player_step_ui_config_166": "{\n \"title\": \"恭喜你!获得试用权益\",\n \"description\": \"你获得了14天Enterprise版本的试用权益,你可以点击按钮查看详情\",\n \"listHeader\": \"试用权益:\",\n \"listContent\": [\n \"空间站记录总数上限提高至 500,000,000 行\",\n \"空间站附件容量数提高至 50 GB\",\n \"支持调用所有高级 API\"\n ],\n \"listFooter\": \"更多权益\",\n \"url\": \"https://aitable.ai/management/upgrade\n}", + "player_step_ui_config_166": "{\n \"title\": \"恭喜你!获得试用权益\",\n \"description\": \"你获得了14天Enterprise版本的试用权益,你可以点击按钮查看详情\",\n \"listHeader\": \"试用权益:\",\n \"listContent\": [\n \"空间站记录总数上限提高至 500,000,000 行\",\n \"空间站附件容量数提高至 50 GB\",\n \"支持调用所有高级 API\"\n ],\n \"listFooter\": \"更多权益\",\n \"url\": \"https://aitable.ai/management/upgrade\"\n}", "player_step_ui_config_167": "{\n \"config\": [\n {\n \"key\": 1,\n \"name\": \"answer1\",\n \"title\": \"您希望通过 APITable 解决哪些问题?\",\n \"type\": \"multiButton\",\n \"answers\": [\n \"IT 运维支持\",\n \"教育\",\n \"项目管理\",\n \"市场营销\",\n \"产品管理\",\n \"招聘管理\",\n \"运营\",\n \"金融财务\",\n \"销售 & 客户管理\",\n \"软件开发\",\n \"人力资源 & 合规\",\n \"设计 & 创意\",\n \"非盈利组织\",\n \"制造业\",\n \"其他\"\n ],\n \"lastAllowInput\": false\n },\n {\n \"key\": 2,\n \"name\": \"answer2\",\n \"title\": \"您的工作岗位是?\",\n \"type\": \"radio\",\n \"answers\": [\n \"企业主\",\n \"团队负责人\",\n \"团队成员\",\n \"自由职业者\",\n \"主管\",\n \"高管层\",\n \"副总裁\"\n ],\n \"lastAllowInput\": false\n },\n {\n \"key\": 3,\n \"name\": \"answer3\",\n \"title\": \"您的团队规模是?\",\n \"type\": \"radio\",\n \"answers\": [\n \"只有我\",\n \"2-5\",\n \"6-10\",\n \"11-15\",\n \"16-25\",\n \"25-50\",\n \"51-100\",\n \"101-500\"\n ],\n \"lastAllowInput\": false\n },\n {\n \"key\": 4,\n \"name\": \"answer4\",\n \"title\": \"您的公司规模是?\",\n \"type\": \"radio\",\n \"answers\": [\n \"1-19\",\n \"20-49\",\n \"50-99\",\n \"100-250\",\n \"251-500\",\n \"501-1500\",\n \"1500+\"\n ],\n \"lastAllowInput\": false\n },\n {\n \"key\": 5,\n \"name\": \"answer5\",\n \"title\": \"您从哪种途径了解到我们?\",\n \"type\": \"checkbox\",\n \"answers\": [\n \"搜索引擎\",\n \"YouTube\",\n \"Product Hunt\",\n \"Github\",\n \"推特\",\n \"领英\",\n \"朋友推荐\"\n ],\n \"lastAllowInput\": false\n },\n {\n \"key\": 6,\n \"name\": \"answer6\",\n \"title\": \"加入我们的Discord社区,和全世界 APITable 的使用者一起讨论使用心得吧!在使用过程中如果遇到任何问题,可以随时在社区获得解答和帮助。\",\n \"type\": \"joinUs\",\n \"url\": \"https://discord.gg/2UXAbDTJTX\",\n \"confirmText\": \"加入社区\",\n \"skipText\": \"跳过\",\n \"submit\": true\n }\n ]\n}", "player_step_ui_config_168": "{\n\"templateKey\":\"createMirrorTip\"\n}", "player_step_ui_config_169": "{\n \"headerImg\": \"https://s4.vika.cn/space/2023/04/04/bcf0695cf35840e6b85e032a8e5ea0a1\",\n \"readMoreUrl\": \"https://help.vika.cn/changelog/23-04-10-updates\",\n \"children\": \"

🚀 新功能介绍

\\n
  • 推出新字段类型「多级联动」,神奇表单支持多级选项
  • 脚本小程序上架,少少代码满足多多定制化
  • 维格表自动化支持「发送邮件」
  • 维格表自动化支持「发送到Slack」
  • 维格表的AI探索,「GPT 内容生成」小程序发布
\"\n}", "player_step_ui_config_17": "{\n \"element\": \"#TEMPLATE_CENTER_USE_TEMPLATE_BTN>button\", \n\"placement\": \"rightBottom\",\n\"offsetY\": 20,\n \"title\": \"使用模板教程\", \n\"description\": \"点击左侧按钮使用模板\", \"children\":\"\" \n}", - "player_step_ui_config_176": "{\"title\":\"AI 助手介绍\",\"video\":\"https://www.youtube.com/embed/cjds1r_roG8?si=irKUpMhwDlOEb8Hc\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", + "player_step_ui_config_176": "{\"title\":\"AI 助手介绍\",\"video\":\"https://www.youtube.com/embed/nbqwE21X1hc?si=HYTHEboJtarOL1w8\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", "player_step_ui_config_18": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select>.ant-select-selector\", \n\"placement\": \"bottomLeft\",\n \"title\": \"使用模板教程\", \n\"description\": \"选择模板要存放的位置\", \"children\":\"\" \n}", "player_step_ui_config_19": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select .ant-select-selector\"\n}", "player_step_ui_config_2": "{\n \"config\": [\n {\n \"key\": 1,\n \"name\": \"answer1\",\n \"title\": \"您希望通过维格表解决哪些问题?\",\n \"type\": \"checkbox\",\n \"answers\": [\n \"工作规划\",\n \"客户服务\",\n \"项目管理\",\n \"采购供应\",\n \"内容生产\",\n \"电商运营\",\n \"活动策划\",\n \"人力资源\",\n \"行政管理\",\n \"财务管理\",\n \"网络直播\",\n \"高校管理\",\n \"其它\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 2,\n \"name\": \"answer2\",\n \"title\": \"您的工作岗位是?\",\n \"type\": \"radio\",\n \"answers\": [\n \"管理者\",\n \"项目经理\",\n \"产品经理\",\n \"设计师\",\n \"研发、工程师\",\n \"运营、编辑\",\n \"销售、客服\",\n \"人事、行政\",\n \"财务、会计\",\n \"律师、法务\",\n \"市场\",\n \"教师\",\n \"学生\",\n \"其它\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 3,\n \"name\": \"answer3\",\n \"title\": \"您的公司名称是?\",\n \"type\": \"input\",\n \"submit\": false\n },\n {\n \"key\": 4,\n \"name\": \"answer4\",\n \"title\": \"请留下你的邮箱/手机/微信号,以便我们及时提供帮助。\",\n \"type\": \"input\",\n \"submit\": true\n },\n {\n \"key\": 5,\n \"title\": \"感谢你的填写,请加一下客服号以备不时之需\",\n \"platform\": {\n \"website\": \"https://s4.vika.cn/space/2023/03/02/b34e3205a9154463be16f497524f1327\",\n \"dingtalk\": \"https://s4.vika.cn/space/2023/03/02/4b16cef6602a4586a21d6346bf25d300\",\n \"wecom\": \"https://s4.vika.cn/space/2023/03/02/60119b1b69b64aa887bd1be6a2928bec\",\n \"feishu\": \"https://u.vika.cn/z9ygm\"\n },\n \"type\": \"contactUs\",\n \"next\": true\n }\n ]\n}\n", @@ -51139,13 +52679,13 @@ "player_step_ui_config_41": "", "player_step_ui_config_42": "{\n \"element\": \"#DATASHEET_FORM_LIST_PANEL\", \n\"placement\": \"leftTop\",\n \"title\": \"神奇表单\", \n\"description\": \"在这里可以快速生成当前视图的神奇表单,神奇表单的字段是依照视图的维格列数量以及顺序来生成的哦\", \"children\":\"\" \n}", "player_step_ui_config_43": "{\n \"element\": \".style_navigation__1U5cR .style_help__1sXEA\", \n\"placement\": \"rightBottom\",\n \"title\": \"小提示\", \n\"offsetY\":5,\n\"description\": \"你可以在左侧的「帮助中心」找回你的维格小助手\", \"children\":\"\" \n}", - "player_step_ui_config_44": "{\n\"title\":\"一分钟快速入门\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", + "player_step_ui_config_44": "{\n\"title\":\"VIKA产品演示\",\n\"video\":\"space/2023/12/29/212a38dda62f4e52a58a92bf86657705\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", "player_step_ui_config_45": "", "player_step_ui_config_46": "", "player_step_ui_config_47": "{\n \"element\": \"#DATASHEET_WIDGET_BTN\",\n\"placement\": \"bottomRight\",\n \"title\": \"新功能\", \n\"description\": \"小程序上线!想要让沉淀下来的数据得到更好的运用吗?那就赶紧来体验一下吧\", \"children\":\"\" \n}", "player_step_ui_config_48": "", "player_step_ui_config_49": "{\n \"element\": \".style_widgetPanelContainer__1l2ZV\",\n\"placement\": \"leftCenter\",\n \"title\": \"什么是小程序\", \n\"description\": \"维格小程序是维格表的一种扩展应用,可实现数据可视化、数据传输、数据清洗等等额外功能。通过在小程序面板安装适合团队的小程序,可以让工作事半功倍\", \"children\":\"\" \n}", - "player_step_ui_config_5": "{\n\"title\":\"一分钟快速入门\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}\n", + "player_step_ui_config_5": "{\n\"title\":\"VIKA产品演示\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}\n", "player_step_ui_config_50": "{\n \"element\": \".style_widgetModal__eXmdB\",\n\"placement\": \"leftTop\",\n \"title\": \"小程序中心\", \n\"description\": \"官方推荐和空间站自建的小程序会发布到这里。你可以根据场景,在这里挑选合适的小程序放置到仪表盘或小程序面板里\", \"children\":\"\" \n}", "player_step_ui_config_51": "{\n \"element\": \".style_widgetModal__eXmdB .style_widgetItem__3Pl-1 button\",\n\"placement\": \"rightBottom\",\n \"title\": \"安装小程序\", \n\"description\": \"我们安装这个「图表」小程序看看吧\", \"children\":\"\" \n}", "player_step_ui_config_52": "", @@ -51198,6 +52738,7 @@ "player_step_ui_config_95": "", "player_step_ui_config_97": "{\n\t\"vikaby\": {\n\t\t\"title\": \"你好\",\n\t\t\"description\": \"如果在使用过程中遇到问题,请扫描右侧二维码联系我解决\",\n\t\t\"list\": \"
  • 刚注册维格表,不知道怎么用
  • 维格表可以实现我想要的效果吗
  • 使用过程出现异常问题
  • 后续支持的功能有哪些
  • 获取官方邀请码
\",\n\t\t\"tip\": \"扫码添加客服\"\n\t},\n\t\"questionnaire\": {\n\t\t\"title\": \"您好,我是维格表数字化顾问\",\n\t\t\"list\": \"[{\\\"title\\\": \\\"Bug 吐槽\\\", \\\"icon\\\": \\\"BugOutlined\\\"}, {\\\"title\\\": \\\"需求反馈\\\", \\\"icon\\\": \\\"AdviseSmallOutlined\\\"}, {\\\"title\\\": \\\"服务支持\\\", \\\"icon\\\": \\\"ServeOutlined\\\"}, {\\\"title\\\": \\\"案例推荐\\\", \\\"icon\\\": \\\"ZanOutlined\\\"}, {\\\"title\\\": \\\"解决方案\\\", \\\"icon\\\": \\\"SolutionSmallOutlined\\\"}, {\\\"title\\\": \\\"产品答疑\\\", \\\"icon\\\": \\\"InformationLargeOutlined\\\"}]\",\n\t\t\"tip\": \"扫码添加微信,获得更多专属服务\"\n\t},\n\t\"website\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/03/02/59f4cc8e0b2b4395bf0fcd133d208e63\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/03/02/defbf55d1e9646eb929f9f5d11d5c119\"\n\t},\n\t\"dingtalk\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/03/02/964be5e3217b4fa8bfa74ef47a980093?attname=dingtalk-questionnaire.png\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/03/02/964be5e3217b4fa8bfa74ef47a980093?attname=dingtalk-vikaby.png\",\n\"tip\": \"请使用钉钉扫码,加入交流群\"\n\t},\n\t\"wecom\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/03/02/1346d5efbd5043efb2bfcba0075c0ee9\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/03/02/09401a8f2d8e491a9097b9bac8b5a4e4\"\n\t},\n\t\"feishu\": {\n\t\t\"title\": \"扫码添加客服\",\n\t\t\"tip\": \"请使用飞书扫码,添加客服号备用\",\n\t\t\"description\": \"以便使用过程中遇到问题,可以随时获得服务和解答\",\n\t\t\"originUrl\": \"https://u.vika.cn/z9ygm\"\n\t}\n}", "player_step_ui_config_99": "", + "player_step_ui_config_automation_1": "{\n \"element\": \"#AUTOMATION_ADD_TRIGGER_BTN\", \"title\":\"title\", \"description\": \"description\" \n} ", "player_step_ui_config_button_field_action_create": "{\n \"element\": \"#CONST_ROBOT_ACTION_CREATE\", \"placement\": \"topCenter\", \"title\": \"\", \"description\": \"现在你应该添加一个或多个 Action,以定义按钮点击后应执行的具体动作\" \n} ", "player_step_ui_config_button_field_bound_datasheet": "{\n \"element\": \"#AUTOMATION_BOUND_DATASHEET\", \"title\": \"\", \"description\": \"“按钮被点击时” 需要绑定表格和字段,以便知道哪里发生的点击行为,这里已经为你设置好\" \n} ", "player_step_ui_config_button_field_node": "{\n \"element\": \".TREE_NODE_ACTIVE_ONE\", \"title\": \"\", \"description\": \"自动化节点是自动化流程的起点,你可以在这里设置触发条件和相关动作\" \n} ", @@ -51242,6 +52783,7 @@ "preview_guide_click_to_restart": "点击下方按钮重新预览", "preview_guide_enable_it": "你可以点击下方按钮去启用此功能", "preview_guide_open_office_preview": "开启「office预览」功能后即可预览该文件", + "preview_next_automation_execution_time": "预览最近10次执行时间", "preview_not_support_video_codecs": "当前仅支持预览编码为H.264的MP4视频", "preview_revision": "预览此版本", "preview_see_more": "想要了解更多「office 文件预览」功能?请点击这里", @@ -51277,6 +52819,7 @@ "privacy_protection": "《隐私保护》", "private_cloud": "专有云旗舰版", "private_external_person_only": "外部人员专用", + "private_help_link": "https://help.aitable.ai/docs/guide/team-and-private-area#private-area", "private_internal_person_only": "内部人员专用", "private_product_point": "一键拥有自己的 APITable 平台", "privatized_deployment": "私有化部署", @@ -51347,13 +52890,15 @@ "reconciled_data": "正在核对数据……", "record": "记录", "record_activity_experience_tips": "可查看 ${day} 天的修改历史", + "record_archived_data": "已归档数据", + "record_chunk_text": "正在${text}条行记录,请稍后", "record_comment": "仅评论", "record_comments": "评论", "record_fail_data": "数据已失效", "record_filter_tips": "此记录已被筛选条件过滤", "record_functions": "记录(行)函数", "record_history": "仅修改历史", - "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-history", + "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-activity", "record_history_title": "修改历史", "record_pre_filtered": "此记录已被筛选过滤,点击本记录以外区域它将被隐藏", "record_pre_move": "此记录不属于当前位置,点击本记录以外区域它将被移动", @@ -51399,7 +52944,7 @@ "remove_from_group": "将你移出空间站「」的「」小组", "remove_from_role": "将你移出空间站「」的「」小组", "remove_from_space": "移出空间", - "remove_from_space_confirm_tip": "确认是否将该成员彻底移出此空间", + "remove_from_space_confirm_tip": "确认是否将该成员彻底移出此工作区,移除后该成员存在个人工作区区的文件不会再占用工作区站的容量。", "remove_from_team": "移出小组", "remove_from_team_confirm_tip": "确认是否将该成员移出此小组", "remove_from_the_team": "移出小组", @@ -51793,6 +53338,12 @@ "scan_to_login": "扫码登录", "scan_to_login_by_method": "请使用${method}关注公众号即可安全登录", "scatter_chart": "散点图", + "schedule_day_tips": "周期计算从每个月的 1 日开始算,假设设置为每隔 10 天,则每月的 1 日,11 日,21 日,31 日会触发", + "schedule_hour_tips": "周期计算从每天的 0 点开始算,假设设置为每隔 3 个小时的 0 分,则每天的 0 点,3 点,6 点,9 点,12 点,15 点,18 点,21 点会触发", + "schedule_start_day": "从每月 1 日起,每隔", + "schedule_start_month": "从每年 1 月份起,每隔", + "schedule_type": "定时类型", + "schedule_year_tips": "周期计算从每年的 1 月份开始算,假设设置为每隔 3 个月的 1 日,则每年的 1 月,4 月,7 月,10 月的第一天会触发", "science_and_technology": "科学技术", "scroll_screen_down": "向下滚动一屏", "scroll_screen_left": "向左滚动一屏", @@ -51806,6 +53357,7 @@ "search_folder_or_sheet": "搜索文件夹或维格表", "search_new_admin": "搜索成员昵称,选择移交的主管理员", "search_node_pleaseholder": "搜索文件 (${shortcutKey})", + "search_node_tip": "搜索 (${shortcutKey})", "search_or_add": "查找或添加", "search_role_placeholder": "搜索角色", "seats": "席位数量", @@ -52209,6 +53761,7 @@ "space_info": "空间站驾驶舱", "space_info_del_confirm1": "1. 删除空间站后,以下数据将被全部清除:", "space_info_del_confirm2": "2. 空间站将会在七天后自动彻底删除。在此之前,你可以随时撤销删除操作", + "space_info_del_confirm3": "3. 再次提醒:如果空间站已订阅付费,删除空间站将会一并移除付费权益,该权益无法转移,请慎重操作!", "space_info_feishu_desc": "使用了第三方集成,如需删除空间站请先关闭第三方集成。", "space_info_feishu_label": "第三方应用集成", "space_join_apply": "申请加入空间站「」", @@ -52295,6 +53848,7 @@ "start_onfiguration": "开始配置", "start_time": "起始时间", "start_use": "开始使用", + "starting_from_midnight": "从每天 0 点起,", "startup": "创业", "startup_company_support_program": "创业公司扶持计划", "stat_average": "平均值", @@ -52328,6 +53882,8 @@ "stay_tuned_for_more_features": "更多功能敬请期待…", "steps_choose_reset_mode": "选择重置方式", "steps_validate_identities": "验证身份", + "stop_chunk_content": "终止后将不会继续执行操作,确定终止?", + "stop_chunk_title": "终止", "stop_dingtalk_h5_modal_content": "自建应用将与本空间站解除绑定,请确认停用。", "storage_per_seats": "", "storage_per_space": "附件容量", @@ -52358,9 +53914,11 @@ "subscribe_credit_usage_over_limit": "空间站的算力点数量已耗尽,请升级你的空间站。", "subscribe_demonstrate": "预约演示", "subscribe_disabled_seat": "人数不可低于原方案", + "subscribe_grade_business": "Business", "subscribe_grade_free": "免费版", "subscribe_grade_plus": "Plus", "subscribe_grade_pro": "Pro", + "subscribe_grade_starter": "Starter", "subscribe_label_tooltip": "${grade}以上空间站专享功能", "subscribe_new_choose_member": "最高支持 ${member_num} 人", "subscribe_new_choose_member_tips": "本方案支持 1~${member_num} 名成员进入空间站使用", @@ -52497,7 +54055,7 @@ "template_name_repetition_title": "“${templateName}”已存在,确定要替换它吗?", "template_no_template": "暂无模板", "template_not_found": "找不到想要的模板? 请告诉我们~", - "template_recommend_title": "热门推荐", + "template_recommend_title": "🌟 热门推荐", "template_type": "模板", "terms_of_service": "《服务条款》", "terms_of_service_pure_string": " 服务条款", @@ -52541,6 +54099,7 @@ "text_editor_tip_end": "Enter 结束编辑", "text_functions": "文本函数", "thailand": "泰国", + "the_button_field_is_misconfigured": "按钮列配置错误,请检查后再试", "the_current_automation_workflow_has_no_related_files_you_can_establish_a_link_by_adding_trigger_conditions_and_actions_on_the_left_side": "当前自动化流程没有与之关联的文件,可以通过在左侧添加触发条件和动作来进行关联", "the_current_button_column_has_expired_please_reselect": "当前按钮列已经失效,请重新选择", "the_last_7_days": "过去 7 天", @@ -52643,6 +54202,7 @@ "timemachine_update_comment": "更新了评论", "times_per_month_unit": "次/月", "times_unit": "次", + "timing_rules": "定时规则", "timor_leste": "东帝汶", "tip_del_success": "我们将对您的空间站数据保留七天,七天内可随时撤销删除操作。", "tip_do_you_want_to_know_about_field_permission": "想对列数据加密吗?了解列权限", @@ -52830,6 +54390,7 @@ "verify_account_title": "验证账号", "verify_via_email": "通过邮箱验证码验证身份", "verify_via_phone": "通过短信验证码验证身份", + "video": "视频", "video_not_support_play": "当前视频格式不支持在线播放", "vietnam": "越南", "view": "视图", @@ -52902,7 +54463,7 @@ "vikaby_menu_hidden_vikaby": "取消悬浮", "vikaby_menu_releases_history": "历史更新", "vikaby_todo_menu1": "什么是维格表", - "vikaby_todo_menu2": "一分钟快速入门", + "vikaby_todo_menu2": "VIKA产品演示", "vikaby_todo_menu3": "玩转一张维格表", "vikaby_todo_menu4": "分享和邀请成员", "vikaby_todo_menu5": "智能引导", @@ -52987,7 +54548,7 @@ "weixin_share_card_title": "", "welcome_interface": "欢迎界面", "welcome_module1": "什么是 APITable", - "welcome_module2": "一分钟快速入门", + "welcome_module2": "VIKA产品演示", "welcome_module3": "玩转一张维格表", "welcome_module4": "内容日历", "welcome_module5": "项目管理", @@ -53178,7 +54739,7 @@ "workdoc_color_title": "字体颜色", "workdoc_create": "创建文档", "workdoc_expanded": "展开目录", - "workdoc_image_max_10mb": "图片大小不能超过10MB", + "workdoc_image_max_size": "图片大小不能超过${size}", "workdoc_info": "文档信息", "workdoc_info_create_time": "创建时间", "workdoc_info_creator": "创建人", @@ -53186,6 +54747,7 @@ "workdoc_info_last_modify_time": "修改时间", "workdoc_link_placeholder": "请输入链接", "workdoc_only_image": "只能上传图片", + "workdoc_only_video": "只能上传视频", "workdoc_text_placeholder": "输入 \"/\" 快速插入", "workdoc_title_placeholder": "请输入标题", "workdoc_unnamed": "未命名文档", @@ -53194,9 +54756,11 @@ "workdoc_unsave_ok": "确定退出", "workdoc_unsave_title": "文档未保存", "workdoc_upload_failed": "上传失败", + "workdoc_video_max_size": "视频大小不能超过${size}", "workdoc_ws_connected": "已连接", "workdoc_ws_connecting": "正在连接...", "workdoc_ws_disconnected": "连接已断开", + "workdoc_ws_reconnecting": "正在重连...", "workflow_execute_failed_notify": "执行失败,请根据运行历史排查问题,需要任何帮助或有任何疑问,请随时与客服团队联系", "workspace_data": "空间站数据", "workspace_files": "工作台数据", @@ -53375,6 +54939,15 @@ "agreed": "已同意", "ai_advanced_mode_desc": "高級模式允許用戶定製提示,從而更好地控制 AI 助手的行為和回應。", "ai_advanced_mode_title": "高級模式", + "ai_agent_anonymous": "匿名${ID}", + "ai_agent_conversation_continue_not_supported": "目前不支援繼續之前的對話", + "ai_agent_conversation_list": "對話列表", + "ai_agent_conversation_log": "對話紀錄", + "ai_agent_conversation_title": "對話標題", + "ai_agent_feedback": "回饋", + "ai_agent_historical_message": "以上為歷史消息", + "ai_agent_history": "歷史", + "ai_agent_message_consumed": "消耗的消息", "ai_api_curl_template": "## Create chat completions\n\n```bash\n\ncurl -X POST \"{{apiBase}}/fusion/v1/ai/{{aiId}}/chat/completions\" \\n -H \"Content-Type: application/json\" \\n -H \"Authorization: Bearer {{token}}\" \\n -d '{\n \"model\": \"gpt-3.5-turbo\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"You are a helpful assistant.\"\n },\n {\n \"role\": \"user\",\n \"content\": \"Hello!\"\n }\n ]\n }'\n\n```\n\n## Returned data example\n\n```json\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", "ai_api_footer_desc": "將 AI 助手嵌入您的網站?瞭解更多", "ai_api_javascript_template": "## Initialize SDK [![github]({{ githubIcon }})](https://github.com/openai/openai-node)\nAITable's chat completion API is compatible with OpenAI's Node.js SDK. You can use our service with the same SDK by simply changing the configuration as follows:\n\n\n```javascript\nconst { Configuration, OpenAIApi } = require(\"openai\");\nconst configuration = new Configuration({\n apiKey: \"{{token}}\",\n basePath: \"{{apiBase}}/fusion/v1/ai/{{aiId}}\"\n});\n```\n\n## Create chat completions\n\n```javascript\nconst openai = new OpenAIApi(configuration);\nconst chatCompletion = await openai.createChatCompletion({\n model: \"gpt-3.5-turbo\",\n messages: [{role: \"user\", content: \"Hello world\"}],\n});\n```\n\n## Returned data example\n\n```javascript\n\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", @@ -53390,6 +54963,9 @@ "ai_chat_unit": "ai助理(S)", "ai_close_setting_tip_content": "您所做的更改尚未保存,是否要丟棄?", "ai_close_setting_tip_title": "未保存的更改", + "ai_copilot_generate_response": "為您生成答案...", + "ai_copilot_processs": "處理中,請稍候...", + "ai_copilot_start_process_request": "開始處理您的請求...", "ai_create_guide_btn_text": "選擇表格", "ai_create_guide_content": "作為一名 AI 助手,我可以根據我所學的知識回答您的問題。在開始對話之前,請選擇一份數據表作為知識庫,我將閱讀其中的所有數據以供學習。", "ai_credit_cost_chart_title": "信貸成本", @@ -53858,7 +55434,7 @@ "apps_support": "全平台客戶端支持", "archive_delete_record": "刪除存檔記錄", "archive_delete_record_title": "刪除記錄", - "archive_notice": "

您正在嘗試存檔特定記錄。存檔記錄將導致以下變更:

1. 該記錄的所有雙向關聯將被取消

2. 不支援編輯

3.不支援日期提醒、訂閱記錄等功能

4.不再參與神奇引用、公式等字段的計算

你確定你要繼續嗎?(在高級能力裡的存檔箱中可以取消歸檔)

", + "archive_notice": "

您正在嘗試歸檔特定記錄。歸檔記錄將導致以下變更:

1.不支援編輯

2.不支援日期提醒、訂閱記錄等功能

3.不再參與lookup、formula等字段的計算

你確定你要繼續嗎? (您可以在「進階」的「存檔箱」中取消存檔)

", "archive_record_in_activity": "已將此記錄存檔", "archive_record_in_menu": "存檔記錄", "archive_record_success": "成功存檔記錄", @@ -53918,6 +55494,8 @@ "audit_add_field_role_detail": "在裡面 ” “ 數據表, 添加 [ ] 角色為 [ ] 對於字段 [ ]", "audit_add_node_role": "添加文件節點權限", "audit_add_node_role_detail": "添加文件節點權限,將「${unitNames}」設置為「${currentNodeName}」的「${role}」角色", + "audit_add_node_role_detail_end": "to「${role}", + "audit_add_node_role_detail_start": "Add file node permission,set「${unitNames}」", "audit_admin_permission_change_event": "管理員權限變更", "audit_create_template": "創建模板", "audit_create_template_detail": "創建模板內容", @@ -53926,20 +55504,30 @@ "audit_delete_field_role_detail": "審計內容", "audit_delete_node_role": "刪除文件節點權限", "audit_delete_node_role_detail": "刪除文件節點權限,將「${unitNames}」在「${currentNodeName}」的「${role}」角色刪除", + "audit_delete_node_role_detail_end": "at 「${role}」role", + "audit_delete_node_role_detail_start": "Delete file node permission,delete「${unitNames}」from", "audit_delete_template": "刪除模板", "audit_delete_template_detail": "刪除模板內容", "audit_disable_field_role": "關閉列權限", "audit_disable_field_role_detail": "審計內容", "audit_disable_node_role": "關閉文件權限", "audit_disable_node_role_detail": "關閉${nodeType}權限,名稱為「${currentNodeName}」", + "audit_disable_node_role_detail_end": "`s permission", + "audit_disable_node_role_detail_start": "Disable ${nodeType}", "audit_disable_node_share": "關閉文件節點公開鏈接", "audit_disable_node_share_detail": "關閉${nodeType} 「${currentNodeName}」 的公開鏈接", + "audit_disable_node_share_detail_end": "public link", + "audit_disable_node_share_detail_start": "Close ${nodeType}", "audit_enable_field_role": "開啟列權限", "audit_enable_field_role_detail": "審計內容", "audit_enable_node_role": "開啟文件權限", "audit_enable_node_role_detail": "開啟${nodeType}權限,名稱為 「${currentNodeName}」", + "audit_enable_node_role_detail_end": "`s permission", + "audit_enable_node_role_detail_start": "Enable ${nodeType}", "audit_enable_node_share": "開啟文件節點公開鏈接", "audit_enable_node_share_detail": "開啟${nodeType} 「${currentNodeName}」 的公開鏈接", + "audit_enable_node_share_detail_end": "public link", + "audit_enable_node_share_detail_start": "Open ${nodeType}", "audit_login_event": "登錄事件", "audit_logout_event": "註銷事件", "audit_organization_change_event": "通訊錄組織架構變更", @@ -53960,18 +55548,25 @@ "audit_space_invite_user_detail": "審計內容", "audit_space_node_copy": "複製文件節點", "audit_space_node_copy_detail": "複製${nodeType}「${sourceNodeName}」,新文件節點名稱為「${currentNodeName}」", + "audit_space_node_copy_detail_start": "Duplicate ${nodeType} 「${sourceNodeName}」, the new file node's name is", "audit_space_node_create": "創建文件節點", "audit_space_node_create_detail": "創建${nodeType},名稱為「${currentNodeName}」", + "audit_space_node_create_detail_start": "Create a ${nodeType} named", "audit_space_node_delete": "刪除文件節點", "audit_space_node_delete_detail": "刪除${nodeType},名稱為「${currentNodeName}」", + "audit_space_node_delete_detail_start": "Delete ${nodeType} named", "audit_space_node_export": "導出數表", "audit_space_node_export_detail": "成員 ${member_name} 導出表 ${node_name}", "audit_space_node_import": "導入文件節點", "audit_space_node_import_detail": "導入文件節點,名稱為 「${nodeName}」", + "audit_space_node_import_detail_start": "Import a file node named", "audit_space_node_move": "移動文件節點", "audit_space_node_move_detail": "移動${nodeType}「${currentNodeName}」到文件夾「${parentName}」下方", + "audit_space_node_move_detail_end": "to the folder「${parentName}」", + "audit_space_node_move_detail_start": "Move ${nodeType}", "audit_space_node_rename": "重命名文件節點", "audit_space_node_rename_detail": "重命名${nodeType},將「${oldNodeName}」名稱修改為「${nodeName}」", + "audit_space_node_rename_detail_start": "Rename ${nodeType} 「${oldNodeName}」to", "audit_space_node_sort": "審計內容", "audit_space_node_sort_detail": "審計內容", "audit_space_node_update_cover": "審計內容", @@ -53986,17 +55581,24 @@ "audit_space_rubbish_node_delete_detail": "審計內容", "audit_space_rubbish_node_recover": "恢復回收艙節點", "audit_space_rubbish_node_recover_detail": "從回收艙恢復${nodeType},名稱為「${currentNodeName}」", + "audit_space_rubbish_node_recover_detail_end": "from the trash", + "audit_space_rubbish_node_recover_detail_start": "Restore ${nodeType}", "audit_space_template_event": "空間站模板事件", "audit_space_update_logo": "審計內容", "audit_space_update_logo_detail": "審計內容", "audit_store_share_node": "轉存文件節點", "audit_store_share_node_detail": "將${nodeType}轉存到本空間站,名稱為 「${nodeName}」", + "audit_store_share_node_detail_start": "Restore ${nodeType} to the space, name is", "audit_update_field_role": "審計內容", "audit_update_field_role_detail": "審計內容", "audit_update_node_role": "修改文件節點權限", "audit_update_node_role_detail": "修改文件節點權限,將「${unitNames}」修改為「${currentNodeName}」的「${role}」角色", + "audit_update_node_role_detail_end": "to「${role}」role", + "audit_update_node_role_detail_start": "Modify file node permission,modify「${unitNames}」from", "audit_update_node_share_setting": "修改文件節點公開鏈接", "audit_update_node_share_setting_detail": "修改${nodeType} 「${currentNodeName}」 的公開鏈接的設置", + "audit_update_node_share_setting_detail_end": "public link settings", + "audit_update_node_share_setting_detail_start": "Modify ${nodeType}", "audit_user_login": "用戶登錄", "audit_user_login_detail": "審計內容", "audit_user_logout": "用戶登出", @@ -54038,6 +55640,7 @@ "automation_enabled_return_via_related_files": "自動化已啟用。請透過「相關文件」重新輸入原始表格以使用新按鈕。", "automation_field": "字段", "automation_import_variables_from_pre_tep": "Get data from the pre-step", + "automation_is_not_yet_enabled": "自動化尚未啟用,請啟用它並重試", "automation_last_edited_by": "Last edited by", "automation_last_edited_time": "Last edited time", "automation_manager_label": "可以執行自動化上的所有操作", @@ -54063,6 +55666,7 @@ "automation_runs_this_month": "Runs this month", "automation_stay_tuned": "Stay tuned", "automation_success": "成功", + "automation_tips": "按鈕欄位配置錯誤,請檢查並重試", "automation_updater_label": "可以查看自動化的運行歷史記錄", "automation_variabel_empty": "前一步沒有可以使用的數據,請調整後重試。", "automation_variable_datasheet": "從 ${NODE_NAME} 取得數據", @@ -54098,6 +55702,7 @@ "bermuda": "百慕大群島", "bhutan": "不丹", "billing_over_limit_tip_common": "空間使用量已超過限制,升級後可享有更高的空間使用量。", + "billing_over_limit_tip_forbidden": "您的試用期或訂閱期已過期。請聯絡銷售顧問續訂。", "billing_over_limit_tip_widget": "小組件安裝數量已超出限制,您可以升級以獲得更高的使用量。", "billing_period": "計費周期:${period}", "billing_subscription_warning": "功能體驗", @@ -54157,10 +55762,19 @@ "button_text": "按鈕文字", "button_text_click_start": "點擊開始", "button_type": "按鈕類型", + "by_at": "在", + "by_days": "天", + "by_every": "每一個", "by_field_id": "使用 Field ID", + "by_hours": "小時", + "by_in": "在", + "by_min": "分鐘)", + "by_months": "幾個月", + "by_on": "於", "by_the_day": "按天", "by_the_month": "按月", "by_the_year": "每年", + "by_weeks": "週數", "calendar_add_date_time_field": "創建日期", "calendar_color_more": "更多顏色", "calendar_const_detail_weeks": "[\"星期一\",\"星期二\",\"星期三\",\"星期四\",\"星期五\",\"星期六\",\"星期天\"]", @@ -54224,6 +55838,14 @@ "cannot_activate_space_by_space_limit": "已激活空間站數量達到上限,刪除或退出已激活的空間站後,可手動激活", "cannot_join_space": "你的空間站數量已達10個上限,暫時無法加入新的空間站。", "cannot_switch_field_permission": "設置的列權限不能高於 TA 的文件權限,請先提高 TA 的文件權限", + "capacity_file_detail_desc": "The total number of file nodes within the Space is calculated by adding the file nodes from the Team to the file nodes created by each member in their Private. Not enough capacity?", + "capacity_file_detail_title": "File Capacity", + "capacity_file_member": "Member", + "capacity_file_member_private_node_count": "Private", + "capacity_file_member_private_percent": "Percent", + "capacity_file_member_team": "Team", + "capacity_file_member_team_node_count": "Team", + "capacity_file_upgrade": "Click to upgrade your Space", "capacity_from_official_gift": "來自官方贈送", "capacity_from_participation": "受邀 ${user} 加入空間", "capacity_from_purchase": "按採購能力", @@ -54260,6 +55882,8 @@ "catalog": "工作目錄", "catalog_add_from_template_btn_title": "從模板添加", "catalog_empty_tips": "這個工作區現在是空的。 開始使用模板創建文件。", + "catalog_private": "Private", + "catalog_team": "Team", "category_blank": "[空值]", "catering": "餐飲業", "cayman_islands": "開曼群島", @@ -54328,6 +55952,7 @@ "choose_type_of_vika_field": "選擇維格列類型", "choose_your_own_space": "(僅支持另存到自己是主管理員的空間站)", "chose_new_primary_admin_button": "確認移交", + "chunk_stopping_title": "Stopping", "claim_special_offer": "索取此特別優惠!", "clear": "清除", "clear_all_fields": "重置", @@ -54458,6 +56083,7 @@ "confirm_del_current_team": "確認是否刪除當前小組", "confirm_delete": "確認刪除", "confirm_delete_node_name_as": "確認要刪除「${nodeNameDiv}」嗎?", + "confirm_delete_private_node_name_as": "Are you sure you want to delete \"${nodeNameDiv}\"? The file will be deleted from the Space and the trash.", "confirm_delete_space_btn": "了解並繼續刪除", "confirm_exit": "確認退出", "confirm_exit_space_with_name": "確認是否退出「${spaceNameDiv}」空間站\n", @@ -54495,6 +56121,14 @@ "convert": "轉換", "convert_tip": "此操作可能會清除某些單元格內已有的數據,如果轉換有問題,則可以撤銷該操作", "cook_islands": "庫克群島", + "copilot_auto_agent_desc": "不確定選擇哪一個代理?嘗試自動代理。", + "copilot_auto_agent_name": "自動代理", + "copilot_data_agent_desc": "根據您的觀點生成數據分析/可視化。", + "copilot_data_agent_name": "數據代理", + "copilot_data_agent_policy": "與 Copilot 聊天時,即表示您同意使用者條款政策", + "copilot_data_agent_policy_button": "政策", + "copilot_help_agent_desc": "詢問有關AITable幫助中心文件的任何問題。", + "copilot_help_agent_name": "檢索幫助中心", "copy": "的副本", "copy_automation_url": "複製 URL", "copy_card_link": "複製該記錄的 URL", @@ -54539,6 +56173,7 @@ "create_mirror_guide_content": "鏡像功能具有隱藏某些數據的能力。 您可以在原始數據表視圖中設置“過濾條件”和“隱藏字段”來控制在鏡像中顯示哪些記錄和字段。\n
\n
\n如果與“視圖鎖定”功能配合使用,可以防止他人進行修改。\n
\n
\n另外,您可以在“原始表>隱藏字段”中修改“在鏡像中顯示所有字段”的配置。", "create_mirror_guide_title": "鏡像隱藏了一些記錄和字段", "create_new_button_field": "建立一個新的按鈕列字段", + "create_private_node_tip": "Personal or temporary draft documents can be created here ${link}", "create_public_invitation_link": "創建公開的邀請鏈接", "create_space_sub_title": "Hi,給你的空間站起個名字吧", "create_team_fail": "添加小組失敗", @@ -54602,10 +56237,12 @@ "custom_enterprise": "企業級空間站支持自定義人數、時長,靈活又強大", "custom_function_development": "定制功能開發", "custom_grade_desc": "提供代理部署、私人安裝、協助支持和定制化專業服務", + "custom_page_setting_title": "Add a custom page", "custom_picture": "自定義圖片", "custom_style": "樣式", "custom_upload": "自定義上傳", "custom_upload_tip": "推薦使用 1:1 的方形圖片以達到更好的視覺體驗", + "custome_page_title": "Custom Web", "cut_cell_data": "剪切", "cyprus": "塞浦路斯", "czech": "捷克", @@ -54657,6 +56294,7 @@ "default": "默認", "default_create_ai_chat_bot": "新建 AI 助手", "default_create_automation": "新自動化", + "default_create_custom_page": "新建自定義頁面", "default_create_dashboard": "新建儀錶盤", "default_create_datasheet": "新建維格表", "default_create_file": "新建節點", @@ -54678,6 +56316,7 @@ "del_invitation_link": "確定刪除邀請鏈接", "del_invitation_link_desc": "刪除後已生成的分享鏈接將會失效", "del_space_now": "徹底刪除空間站", + "del_space_now_confirm_tip": "For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "del_space_now_tip": "請注意:空間站刪除後將不可恢復,包含所有表格、附件都會被徹底刪除", "del_space_res_tip": "刪除空間站成功", "del_team_success": "刪除小組成功", @@ -54873,6 +56512,62 @@ "embed_error_page_help": "點擊了解失效原因", "embed_fail_og_description_content": "該嵌入的公開鏈接已被關閉,暫時無法訪問", "embed_failed": "嵌入鏈接已失效,", + "embed_link_bilibili": "嗶哩嗶哩", + "embed_link_bilibili_desc": "透過嵌入bilibili視頻,您可以在Vika中觀看教程和指南,或查看頻道首頁。", + "embed_link_bilibili_link_text": "如何嵌入bilibili視頻", + "embed_link_bilibili_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-bilibili-video", + "embed_link_default": "任何事物", + "embed_link_default_desc": "貼上連結以查看任何網站。", + "embed_link_default_link_text": "了解更多", + "embed_link_default_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_link_figma": "Figma", + "embed_link_figma_desc": "透過嵌入Figma文件,成員可以更方便地查看和編輯設計稿,提高協作效率。", + "embed_link_figma_link_text": "如何嵌入 Figma 文件", + "embed_link_figma_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-figma-file", + "embed_link_google_docs": "Docs", + "embed_link_google_docs_desc": "透過嵌入Google Docs,您可以在AITable中編輯和查看文檔,以方便團隊協作。", + "embed_link_google_docs_link_text": "如何嵌入 Google 文件", + "embed_link_google_docs_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-docs-file", + "embed_link_google_sheets": "Sheets", + "embed_link_google_sheets_desc": "透過嵌入Google Sheets,您可以在AITable中編輯和檢視表格,以促進團隊協作。", + "embed_link_google_sheets_link_text": "如何嵌入 Google Sheets", + "embed_link_google_sheets_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-sheets-file", + "embed_link_jishi_design": "JS設計", + "embed_link_jishi_design_desc": "透過嵌入JSdesign文件,成員可以更方便地查看和編輯設計稿,提高協作效率。", + "embed_link_jishi_design_link_text": "如何嵌入 JSdesign 文件", + "embed_link_jishi_design_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-js-design-file", + "embed_link_tencent_docs": "騰訊文檔", + "embed_link_tencent_docs_desc": "透過嵌入騰訊文檔,您可以在Vika中編輯、查看騰訊文檔,提高協作效率。", + "embed_link_tencent_docs_link_text": "如何嵌入騰訊文檔", + "embed_link_tencent_docs_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-tencent-docs", + "embed_link_wps": "WPS", + "embed_link_wps_desc": "透過嵌入WPS文件,您可以在Vika中編輯並檢視WPS文件、表格和表單,提高協作效率。", + "embed_link_wps_link_text": "如何嵌入WPS文件", + "embed_link_wps_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-wps-file", + "embed_link_youtube": "Youtube", + "embed_link_youtube_desc": "透過嵌入 YouTube 視頻,您可以觀看教程和指南,或查看 AITable 中的頻道主頁。", + "embed_link_youtube_link_text": "如何嵌入 YouTube 影片", + "embed_link_youtube_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-youtube-video", + "embed_page": "自定義頁面", + "embed_page_add_url": "新增網址", + "embed_page_doc_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_page_function_desc": "將網頁加入${edition}中,以便輕鬆存取第三方網站文件、影片等。您可以新增推薦的網站連結或任何自定義連結。", + "embed_page_node_permission_editor": "在「僅更新」的基礎上,還可以開啟檔案的公開共享", + "embed_page_node_permission_manager": "可以對檔案執行所有操作", + "embed_page_node_permission_reader": "可以查看自定義頁面的內容和基本文件訊息", + "embed_page_node_permission_updater": "在「唯讀」的基礎上,也可以修改自定義頁面的連結", + "embed_page_setting_title": "新增自定義頁面", + "embed_page_url_invalid": "請輸入正確的網址", + "embed_paste_link_bilibili_placeholder": "貼上bilibili視頻鏈接", + "embed_paste_link_default_placeholder": "貼上網址", + "embed_paste_link_figma_placeholder": "貼上 Figma 檔案的共享鏈接", + "embed_paste_link_google_docs_placeholder": "貼上 Google 文件共享連結", + "embed_paste_link_google_sheets_placeholder": "貼上 Google 試算表共享鏈接", + "embed_paste_link_jsdesign_placeholder": "貼上 JSdesign 檔案的共享鏈接", + "embed_paste_link_tencent_docs_placeholder": "貼上騰訊文檔分享鏈接", + "embed_paste_link_wps_placeholder": "貼上 WPS 檔案的共享鏈接", + "embed_paste_link_youtube_placeholder": "貼上 YouTube 影片連結", + "embed_success": "添加成功", "emoji_activity": "活動和事件", "emoji_custom": "自定義", "emoji_flags": "旗幟", @@ -54979,6 +56674,11 @@ "estonia": "愛沙尼亞", "ethiopia": "埃塞俄比亞", "event_planning": "活動策劃", + "every": "每一個", + "every_day_at": "天在", + "every_hour_at": "小時於", + "every_month_at": "月", + "every_week_at": "每週於", "everyday_life": "日常生活", "everyone_visible": "全員可見", "exact_date": "指定日期", @@ -54989,6 +56689,7 @@ "exchange": "兌換", "exchange_code_times_tip": "請注意,兌換碼只能兌換一次", "exclusive_consultant": "專屬 V+ 顧問", + "exclusive_limit_plan_desc": "獨家限量等級", "exist_experience": "退出體驗", "exits_space": "退出空間", "expand": "展開", @@ -55015,7 +56716,7 @@ "expired": "已過期", "export": "正在導出…", "export_brand_desc": "提供技術支持", - "export_current_preview_view_data": "", + "export_current_preview_view_data": "Export current preview view data", "export_gantt_button_tips": "導出為圖片", "export_gantt_chart": "導出甘特圖", "export_to_excel": "導出為 Excel 文件", @@ -55687,6 +57388,7 @@ "gold_grade": "黃金級", "gold_grade_desc": "適用於有復雜業務流程的團隊或組織", "gold_seat_200_desc": "200", + "gold_seat_300_desc": "300", "golden_grade": "黃金級", "got_it": "知道了", "got_v_coins": "已獲得 V 幣獎勵", @@ -55720,6 +57422,8 @@ "guests_per_space": "外部訪客", "guide_1": "來呀互相傷害呀", "guide_2": "花費幾分鐘跟隨我們的指引,學習一下維格表的常規功能,可以讓您事半功倍哦!", + "guide_flow_modal_contact_sales": "聯繫銷售人員", + "guide_flow_modal_get_started": "開始使用", "guide_flow_of_catalog_step1": "這是工作目錄,裡邊存放的是空間站的所有文件夾和文件", "guide_flow_of_catalog_step2": "工作目錄裡面,除了可以單獨創建維格表,也可以單獨創建文件夾", "guide_flow_of_click_add_view_step1": "除了基本的維格視圖之外,我們支持創建相冊視圖,如果你有圖片附件的話,我建議你創建個相冊視圖試試", @@ -55898,6 +57602,7 @@ "intro_widget_tips": "什麼是小程序?", "introduction": "簡介", "invalid_action_sort_tip": "該字段作為分組項已被設置排序,當前設置的排序不會生效", + "invalid_automation_configuration": "自動化配置無效,請檢查並重試", "invalid_field_type": "非法的字段類型", "invalid_option_sort_tip": "該字段作為分組項已被設置排序", "invalid_redemption_code_entered": "請輸入有效的兌換碼", @@ -56028,6 +57733,9 @@ "label_format_day_month_and_year_split_by_slash": "日/月/年", "label_format_month": " 月", "label_format_month_and_day_split_by_dash": "月-日", + "label_format_month_day_year_split_by_dash": "Month-Day-Year", + "label_format_month_day_year_split_by_slash": "Month/Day/Year", + "label_format_month_day_year_two_digit_year_split_by_slash": "Month/Day/Year (Two-digit year)", "label_format_year": "年", "label_format_year_and_month_split_by_dash": "年-月", "label_format_year_month_and_day_split_by_dash": "年-月-日", @@ -56106,6 +57814,7 @@ "lark_version_enterprise": "飛書企業版", "lark_version_standard": "飛書標準版", "lark_versions_free": "飛書基礎版", + "last_day": "最後一天", "last_modified_by_select_modal_desc": "由於該維格列類型的特殊性,下方只展示可編輯的列,每當有人在指定的列進行過修改,則會更新當前的修改人", "last_modified_time_select_modal_desc": "由於該維格列類型的特殊性,下方只展示可編輯的列,每當有人在指定的列進行過修改,則會更新當前的修改時間", "last_step": "上一步", @@ -56250,7 +57959,7 @@ "mail_invite_fail": "邀請成員失敗", "mail_invite_success": "邀請成員成功", "main_admin_name": "主管理員名稱", - "main_admin_page_desc": "擁有空間站的最高管理權限,可以分配子管理員或轉讓空間站", + "main_admin_page_desc": "主管理员具有完整的訪問權限,可以分配子管理員,或調整空間站設置。", "main_contain": "主要內容", "malawi": "馬拉維", "malaysia": "馬來西亞", @@ -56470,8 +58179,12 @@ "more_widget": "更多小程序", "morocco": "摩洛哥", "move": "移動", + "move_datasheet_link_warn": "Cannot be moved to Team Area alone, because there is a two-way link from the current datasheet to another datasheet, it is recommended to put them in a folder and then move them", "move_favorite_node_fail": "移動節點失敗,系統將會自動更新列表", + "move_folder_link_warn": "Cannot be moved to Team Area because the files in the current folder are linked to files outside the folder (may be two-way links or linked by forms, etc.) We recommend that they be placed in a folder before moving", "move_node_modal_content": "移動後,文件的可見性可能會受到上級文件夾的影響", + "move_other_link_no_permission": "Unable to move to the corresponding folder because you do not have administrative rights to the folder", + "move_other_link_warn": "It is not allowed to move ${node type} to Team Area alone, because it connects to the datasheet of Private Area, it is recommended to put them in a folder before moving them", "move_to": "搬去", "move_to_error_equal_parent": "該文件位於當前文件夾下。 請選擇另一個文件夾", "move_to_modal_title": "將【${name}】移動至", @@ -56502,7 +58215,9 @@ "new_a_line": "Shift+Enter 換行", "new_automation": "New automation", "new_caledonia": "新喀裡多尼亞", + "new_custom_page": "New custom page", "new_datasheet": "新建維格表", + "new_ebmed_page": "新的自定義頁面", "new_folder": "新建文件夾", "new_folder_btn_title": "文件夾", "new_folder_tooltip": "建立資料夾", @@ -56668,7 +58383,7 @@ "nvc_start_text": "請按住滑塊,拖動到最右邊", "nvc_yes_text": "驗證通過", "obtain_verification_code": "未獲取驗證碼或已過期,請重新獲取", - "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrzw0miJVmSkJ7eBBa9k/fomx5qPX0JGPFvfEEP\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", + "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrCvbFC53xc3kl00B4Pg\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", "offical_website_nav_data": "[{\n \"name\": \"产品\",\n \"href\": \"/login\",\n \"children\": [\n {\n \"name\": \"vika维格表 Overview\",\n \"href\": \"/login/\"\n },\n {\n \"name\": \"应用连接 Integration\",\n \"href\": \"/connections/\"\n },\n {\n \"name\": \"客户端(Beta) Download\",\n \"href\": \"/download/\"\n }\n ]\n}, {\n \"name\": \"解决方案\",\n \"href\": \"/\",\n \"children\": [{\n \"name\": \"PMO项目群管理\",\n \"href\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"href\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"href\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"href\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"href\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"href\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"href\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"href\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"href\": \"/shop/\"\n }, {\n \"name\": \"更多解决方案 >\",\n \"href\": \"/solutions/\"\n }]\n}, {\n \"name\": \"模板/案例\",\n \"href\": \"/template\",\n \"children\": [\n {\n \"name\": \"模板中心 Tempaltes\",\n \"href\": \"/template\"\n },\n {\n \"name\": \"客户案例 Customers\",\n \"href\": \"/cases/\"\n }\n ]\n},\n {\n \"name\": \"首页\",\n \"href\": \"/?home=1\"\n },\n {\n \"name\": \"学习资源\",\n \"href\": \"https://edu.vika.cn/index\",\n \"children\": [\n {\n \"name\": \"快速入门 Tutorials\",\n \"href\": \"https://help.vika.cn/docs/guide/tutorial\"\n },\n {\n \"name\": \"产品手册 Manual\",\n \"href\": \"https://help.vika.cn/docs/guide/manual\"\n },\n {\n \"name\": \"维格课堂 Vika Education\",\n \"href\": \"https://edu.vika.cn/\"\n },\n {\n \"name\": \"维格社区 Vika BBS\",\n \"href\": \"https://bbs.vika.cn/\"\n },\n {\n \"name\": \"第三方连接 Integration\",\n \"href\": \"https://help.vika.cn/docs/guide/connection\"\n },\n {\n \"name\": \"开发者中心 Developer Center\",\n \"href\": \"/developers/\"\n },\n {\n \"name\": \"常见问题 FAQ\",\n \"href\": \"https://help.vika.cn/docs/guide/questions\"\n }\n ]\n }]", "office_preview": "Office 文件預覽", "office_preview_app_desc": "

在維格表裡提供無縫的 office 文件在線預覽能力, 讓你可以隨時隨地使用 PC 或手機查看 Excel、Word、PPT 等常見的 office 文件

\n\n
  • 支持在線預覽 .doc、.docx、.xls、.xlsx、.ppt、.pptx 和 .pdf 格式的 office 文件
  • 桌面端和移動端同步支持對上述格式的文件預覽\n
\n\n

補充說明:

\n
  • 該功能由「永中云轉換」提供技術支持,維格表官方進行集成
  • 點擊下方 “授權” 按鈕,表示啟用本應用,並同意「永中云轉換」讀取你將要預覽的 office 文件
  • 如不再需要 office 預覽功能,管理員可再次訪問此頁面進行停用操作
", @@ -56708,6 +58423,7 @@ "open_auto_save_success": "開啟自動保存視圖配置成功", "open_auto_save_warn_content": "所有成員修改當前視圖配置會自動保存並同步給其他成員。 (視圖配置包括:篩選、分組、排序、隱藏列、佈局、樣式等)", "open_auto_save_warn_title": "開啟自動保存視圖配置", + "open_automation_time_arrival": "https://aitable.ai/contact-sales-open-source", "open_failed": "查看失敗", "open_in_new_tab": "新標籤頁打開", "open_invite_after_operate": "打開邀請成員後,全體成員可以在“通訊錄面板”進行邀請成員操作", @@ -56854,6 +58570,8 @@ "payment_record": "支付記錄", "payment_reminder": "支付提醒", "payment_reminder_content": "你所選擇的新方案抵扣金額大於待支付金額,建議你選擇更長時長的新方案。如果你確認這樣做,超出的金額將不能退還。如有疑問請 ${action}", + "payment_reminder_modal_content": "您可以嘗試進階版本,享受更多檔案節點、企業權限、附件容量、資料量、AI等進階功能和特權。", + "payment_reminder_modal_title": "您目前使用的是免費版本", "pending_invite": "待邀請", "people": "人", "per_person_per_year": "每人每年", @@ -57018,12 +58736,12 @@ "player_step_ui_config_163": "", "player_step_ui_config_164": "", "player_step_ui_config_165": "{\n \"headerImg\": \"https://s4.vika.cn/space/2023/03/16/8374ca1295664675bd1155b077555113\",\n \"readMoreUrl\": \"https://help.vika.cn/changelog/23-03-16-updates\",\n \"children\": \"

🚀 Introduction of new functions

\\n
  • The mirror is upgraded again, hiding sensitive fields and collaborating with peace of mind
  • The time zone of the user account is online, and the time zone of the date list can be set independently, making cross-time zone cooperation smoother.
  • \"Global Search\" experience optimization, new search result categories
  • Gold-level space station benefits are increased, and the sharing form supports hiding official logos
  • API interface performance optimization, greatly improving call efficiency
\"\n}", - "player_step_ui_config_166": "{\n \"title\": \"恭喜你!獲得試用權益\",\n \"description\": \"你獲得了14天Enterprise版本的試用權益,你可以點擊按鈕查看詳情\", \n \"listHeader\": \"試用權益:\",\n \"listContent\": [\n \"空間站記錄總數上限提高至500,000,000 行\",\n \"空間站附件容量數提高至50 GB\",\n \"支持調用所有高級API\"\n ],\n \"listFooter\": \"更多權益\",\n \"url\": \"https://aitable.ai/management/upgrade\n}", + "player_step_ui_config_166": "{\n \"title\": \"恭喜你!獲得試用權益\",\n \"description\": \"你獲得了14天Enterprise版本的試用權益,你可以點擊按鈕查看詳情\", \n \"listHeader\": \"試用權益:\",\n \"listContent\": [\n \"空間站記錄總數上限提高至500,000,000 行\",\n \"空間站附件容量數提高至50 GB\",\n \"支持調用所有高級API\"\n ],\n \"listFooter\": \"更多權益\",\n \"url\": \"https://aitable.ai/management/upgrade\"\n}", "player_step_ui_config_167": "{\n \"config\": [\n {\n \"key\": 1,\n \"name\": \"answer1\",\n \"title\": \"How do you want to use APITable?\",\n \"type\": \"multiButton\",\n \"answers\": [\n \"IT & Support\",\n \"Education\",\n \"Project Management\",\n \"Marketing\",\n \"Product Management\",\n \"HR & Recruiting\",\n \"Operations\",\n \"Finance\",\n \"Sales & CRM\",\n \"Software Development\",\n \"HR & Legal\",\n \"Design & Creative\",\n \"Nonprofit\",\n \"Manufacture\",\n \"Other Things\"\n ],\n \"lastAllowInput\": false\n },\n {\n \"key\": 2,\n \"name\": \"answer2\",\n \"title\": \"What best describes your current role?\",\n \"type\": \"radio\",\n \"answers\": [\n \"Business Owner\",\n \"Team Leader\",\n \"Team Member\",\n \"Freelancer\",\n \"Director\",\n \"C-level\",\n \"VP\"\n ],\n \"lastAllowInput\": false\n },\n {\n \"key\": 3,\n \"name\": \"answer3\",\n \"title\": \"How many people are on your team? \",\n \"type\": \"radio\",\n \"answers\": [\n \"Just me\",\n \"2-5\",\n \"6-10\",\n \"11-15\",\n \"16-25\",\n \"25-50\",\n \"51-100\",\n \"101-500\"\n ],\n \"lastAllowInput\": false\n },\n {\n \"key\": 4,\n \"name\": \"answer4\",\n \"title\": \"How many people work at your company? \",\n \"type\": \"radio\",\n \"answers\": [\n \"1-19\",\n \"20-49\",\n \"50-99\",\n \"100-250\",\n \"251-500\",\n \"501-1500\",\n \"1500+\"\n ],\n \"lastAllowInput\": false\n },\n {\n \"key\": 5,\n \"name\": \"answer5\",\n \"title\": \"How did you hear about us? \",\n \"type\": \"checkbox\",\n \"answers\": [\n \"Search Engine\",\n \"YouTube\",\n \"Product Hunt\",\n \"Github\",\n \"Twitter\",\n \"LinkedIn\",\n \"Through a friend\"\n ],\n \"lastAllowInput\": false\n },\n {\n \"key\": 6,\n \"name\": \"answer6\",\n \"title\": \"We host a Discord channel as a place for discussion with APITable fans, come and join us!\",\n \"type\": \"joinUs\",\n \"url\": \"https://discord.gg/2UXAbDTJTX\",\n \"confirmText\": \"Join Our Community\",\n \"skipText\": \"skip\",\n \"submit\": true\n }\n ]\n}", "player_step_ui_config_168": "{\n\"templateKey\":\"createMirrorTip\"\n}", "player_step_ui_config_169": "{\n \"headerImg\": \"https://s4.vika.cn/space/2023/04/04/bcf0695cf35840e6b85e032a8e5ea0a1\",\n \"readMoreUrl\": \"https://help.vika.cn/changelog/23-04-10-updates\",\n \"children\": \"

🚀 Introduction of new functions

\\n
  • New field type \"Cascader\" is launched, making selection from a hierarchy of options on forms easier
  • \"Script\" widget is released, less code for more customization
  • Trigger Robot to send Emails, and get fast notifications
  • Trigger Robot to send a message to Slack, and inform your team in time
  • Exploring AI: \"GPT Content Generator\" Widget Released
\"\n}", "player_step_ui_config_17": "{\n \"element\": \"#TEMPLATE_CENTER_USE_TEMPLATE_BTN>button\", \n\"placement\": \"rightBottom\",\n\"offsetY\": 20,\n \"title\": \"使用模板教程\", \n\"description\": \"點擊左側按鈕使用模板\", \"children\":\"\" \n}", - "player_step_ui_config_176": "{\"title\":\"AI 助手介紹\",\"video\":\"https://www.youtube.com/embed/cjds1r_roG8?si=irKUpMhwDlOEb8Hc\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", + "player_step_ui_config_176": "{\"title\":\"AITable.ai 示範\",\"video\":\"https://www.youtube.com/embed/kGxMyEEo3OU\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", "player_step_ui_config_18": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select>.ant-select-selector\", \n\"placement\": \"bottomLeft\",\n \"title\": \"使用模板教程\", \n\"description\": \"選擇模板要存放的位置\", \"children\":\"\" \n}", "player_step_ui_config_19": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select .ant-select-selector\"\n}", "player_step_ui_config_2": "{\n \"config\": [\n {\n \"key\": 1,\n \"name\": \"answer1\",\n \"title\": \"您希望通過維格表解決哪些問題?\",\n \"type\": \"checkbox\",\n \"answers\": [\n \"工作規劃\",\n \"客戶服務\",\n \"項目管理\",\n \"採購供應\",\n \"內容生產\",\n \"電商運營\",\n \"活動策劃\",\n \"人力資源\",\n \"行政管理\",\n \"財務管理\",\n \"網絡直播\",\n \"高校管理\",\n \"其它\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 2,\n \"name\": \"answer2\",\n \"title\": \"您的工作崗位是?\",\n \"type\": \"radio\",\n \"answers\": [\n \"管理者\",\n \"項目經理\",\n \"產品經理\",\n \"設計師\",\n \"研發、工程師\",\n \"運營、編輯\",\n \"銷售、客服\",\n \"人事、行政\",\n \"財務、會計\",\n \"律師、法務\",\n \"市場\",\n \"教師\",\n \"學生\",\n \"其它\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 3,\n \"name\": \"answer3\",\n \"title\": \"您的公司名稱是?\",\n \"type\": \"input\",\n \"submit\": false\n },\n {\n \"key\": 4,\n \"name\": \"answer4\",\n \"title\": \"請留下你的郵箱/手機/微信號,以便我們及時提供幫助。\",\n \"type\": \"input\",\n \"submit\": true\n },\n {\n \"key\": 5,\n \"title\": \"感謝你的填寫,請加一下客服號以備不時之需\",\n \"platform\": {\n \"website\": \"https://s4.vika.cn/space/2023/03/02/b34e3205a9154463be16f497524f1327\",\n \"dingtalk\": \"https://s4.vika.cn/space/2023/03/02/4b16cef6602a4586a21d6346bf25d300\",\n \"wecom\": \"https://s4.vika.cn/space/2023/03/02/60119b1b69b64aa887bd1be6a2928bec\",\n \"feishu\": \"https://u.vika.cn/z9ygm\"\n },\n \"type\": \"contactUs\",\n \"next\": true\n }\n ]\n}\n", @@ -57053,13 +58771,13 @@ "player_step_ui_config_41": "", "player_step_ui_config_42": "{\n \"element\": \"#DATASHEET_FORM_LIST_PANEL\", \n\"placement\": \"leftTop\",\n \"title\": \"神奇表單\", \n\"description\": \"在這裡可以快速生成當前視圖的神奇表單,神奇表單的字段是依照視圖的維格列數量以及順序來生成的哦\", \"children\":\"\" \n}", "player_step_ui_config_43": "{\n \"element\": \".style_navigation__1U5cR .style_help__1sXEA\", \n\"placement\": \"rightBottom\",\n \"title\": \"小提示\", \n\"offsetY\":5,\n\"description\": \"你可以在左側的「幫助中心」找回你的維格小助手\", \"children\":\"\" \n}", - "player_step_ui_config_44": "{\n\"title\":\"一分鐘快速入門\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", + "player_step_ui_config_44": "{\n\"title\":\"一分鐘快速入門\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", "player_step_ui_config_45": "", "player_step_ui_config_46": "", "player_step_ui_config_47": "{\n \"element\": \"#DATASHEET_WIDGET_BTN\",\n\"placement\": \"bottomRight\",\n \"title\": \"新功能\", \n\"description\": \"小程序上線!想要讓沉澱下來的數據得到更好的運用嗎?那就趕緊來體驗一下吧\", \"children\":\"\" \n}", "player_step_ui_config_48": "", "player_step_ui_config_49": "{\n \"element\": \".style_widgetPanelContainer__1l2ZV\",\n\"placement\": \"leftCenter\",\n \"title\": \"什麼是小程序\", \n\"description\": \"維格小程序是維格表的一種擴展應用,可實現數據可視化、數據傳輸、數據清洗等等額外功能。通過在小程序面板安裝適合團隊的小程序,可以讓工作事半功倍\", \"children\":\"\" \n}", - "player_step_ui_config_5": "{\n\"title\":\"一分鐘快速入門\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}\n", + "player_step_ui_config_5": "{\n\"title\":\"一分鐘快速入門\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}\n", "player_step_ui_config_50": "{\n \"element\": \".style_widgetModal__eXmdB\",\n\"placement\": \"leftTop\",\n \"title\": \"小程序中心\", \n\"description\": \"官方推薦和空間站自建的小程序會發佈到這裡。你可以根據場景,在這裡挑選合適的小程序放置到儀錶盤或小程序面板裡\", \"children\":\"\" \n}", "player_step_ui_config_51": "{\n \"element\": \".style_widgetModal__eXmdB .style_widgetItem__3Pl-1 button\",\n\"placement\": \"rightBottom\",\n \"title\": \"安裝小程序\", \n\"description\": \"我們安裝這個「圖表」小程序看看吧\", \"children\":\"\" \n}", "player_step_ui_config_52": "", @@ -57156,6 +58874,7 @@ "preview_guide_click_to_restart": "點擊下方按鈕重新預覽", "preview_guide_enable_it": "你可以點擊下方按鈕去啟用此功能", "preview_guide_open_office_preview": "開啟「office預覽」功能後即可預覽該文件", + "preview_next_automation_execution_time": "預覽接下來 10 次執行時間", "preview_not_support_video_codecs": "當前僅支持預覽編碼為H.264的MP4視頻", "preview_revision": "預覽此版本", "preview_see_more": "想要了解更多「office 文件預覽」功能?請點擊這裡", @@ -57191,6 +58910,7 @@ "privacy_protection": "《隱私保護》", "private_cloud": "專有云旗艦版", "private_external_person_only": "外部人員專用", + "private_help_link": "https://help.aitable.ai/docs/guide/team-and-private-area#private-area", "private_internal_person_only": "內部人員專用", "private_product_point": "一鍵擁有自己的 APITable 平台", "privatized_deployment": "自託管", @@ -57261,13 +58981,15 @@ "reconciled_data": "正在核對數據……", "record": "記錄", "record_activity_experience_tips": "可查看 ${day} 天的修改歷史", + "record_archived_data": "存檔記錄", + "record_chunk_text": "${text} rows, please wait", "record_comment": "僅評論", "record_comments": "評論", "record_fail_data": "數據已失效", "record_filter_tips": "記錄已被篩選條件過濾", "record_functions": "記錄(行)函數", "record_history": "僅修改歷史", - "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-history", + "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-activity", "record_history_title": "修改歷史", "record_pre_filtered": "此記錄已被篩選過濾,點擊本記錄以外區域它將被隱藏", "record_pre_move": "此記錄不屬於當前位置,點擊本記錄以外區域它將被移動", @@ -57707,6 +59429,12 @@ "scan_to_login": "掃碼登錄", "scan_to_login_by_method": "請使用${method}關注公眾號即可安全登錄", "scatter_chart": "散點圖", + "schedule_day_tips": "週期計算從每個月的第一天開始計算。如果我們假設它每 10 天重複一次,那麼它將在每月的 1、11、21 和 31 天觸發", + "schedule_hour_tips": "週期計算從每天的午夜 (0:00) 開始。假設每三小時重複0 分鐘,則每天會在午夜(0:00)、凌晨3 點、上午6 點、上午9 點、中午(12 PM)、下午3 點、下午6 點、最後是黃昏時分(9 PM) 發生", + "schedule_start_day": "從每個月的第一天開始,", + "schedule_start_month": "從每年一月開始,每年", + "schedule_type": "時間表類型", + "schedule_year_tips": "週期計算從每年的第一個月開始計算。假設間隔3個月的第一天,觸發器將在每年一月、四月、七月和十月的第一天午夜啟動。", "science_and_technology": "科學技術", "scroll_screen_down": "向下滾動一屏", "scroll_screen_left": "向左滾動一屏", @@ -57720,6 +59448,7 @@ "search_folder_or_sheet": "搜索文件夾或維格表", "search_new_admin": "搜索成員暱稱,選擇移交的主管理員", "search_node_pleaseholder": "搜索文件 (${shortcutKey})", + "search_node_tip": "快速搜尋(${shortcutKey})", "search_or_add": "查找或添加", "search_role_placeholder": "搜索角色", "seats": "席位數量", @@ -58123,6 +59852,7 @@ "space_info": "空間站駕駛艙", "space_info_del_confirm1": "1. 刪除空間站後,以下數據將被全部清除:", "space_info_del_confirm2": "2. 空間站將會在七天后自動徹底刪除。在此之前,你可以隨時撤銷刪除操作", + "space_info_del_confirm3": "3. For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "space_info_feishu_desc": "使用了第三方集成,如需刪除空間站請先關閉第三方集成。", "space_info_feishu_label": "第三方應用集成", "space_join_apply": "申請加入空間站「」", @@ -58209,6 +59939,7 @@ "start_onfiguration": "開始配置", "start_time": "起始時間", "start_use": "開始使用", + "starting_from_midnight": "從每天午夜(12:00 AM)開始,每天", "startup": "創業", "startup_company_support_program": "創業公司扶持計劃", "stat_average": "平均值", @@ -58242,6 +59973,8 @@ "stay_tuned_for_more_features": "更多功能敬請期待…", "steps_choose_reset_mode": "選擇重置方式", "steps_validate_identities": "驗證身份", + "stop_chunk_content": "Are you sure you want to stop the operation?", + "stop_chunk_title": "Stop", "stop_dingtalk_h5_modal_content": "自建應用將與本空間站解除綁定,請確認停用。", "storage_per_seats": "", "storage_per_space": "附件容量", @@ -58272,9 +60005,11 @@ "subscribe_credit_usage_over_limit": "當前空間中的積分數量超過限制,請升級您的訂閱。\n", "subscribe_demonstrate": "預約演示", "subscribe_disabled_seat": "人數不可低於原方案", + "subscribe_grade_business": "商業", "subscribe_grade_free": "免費版", "subscribe_grade_plus": "Plus", "subscribe_grade_pro": "Pro", + "subscribe_grade_starter": "起動機", "subscribe_label_tooltip": "${grade}以上空間站專享功能", "subscribe_new_choose_member": "最高支持 ${member_num} 人", "subscribe_new_choose_member_tips": "本方案支持 1~${member_num} 名成員進入空間站使用", @@ -58411,7 +60146,7 @@ "template_name_repetition_title": "“${templateName}”已存在,確定要替換它嗎?", "template_no_template": "暫無模板", "template_not_found": "找不到想要的模板? 請告訴我們~", - "template_recommend_title": "熱門推薦", + "template_recommend_title": "🌟 熱門推薦", "template_type": "模板", "terms_of_service": "《服務條款》", "terms_of_service_pure_string": " 服務條款", @@ -58455,6 +60190,7 @@ "text_editor_tip_end": "Enter 結束編輯", "text_functions": "文本函數", "thailand": "泰國", + "the_button_field_is_misconfigured": "按鈕欄位配置錯誤,請檢查並重試", "the_current_automation_workflow_has_no_related_files_you_can_establish_a_link_by_adding_trigger_conditions_and_actions_on_the_left_side": "當前自動化工作流沒有相關檔案。您可以通過在左側添加觸發條件和操作來建立鏈接", "the_current_button_column_has_expired_please_reselect": "目前按鈕列已過期,請重新選擇", "the_last_7_days": "過去 7 天", @@ -58557,6 +60293,7 @@ "timemachine_update_comment": "Updated comments", "times_per_month_unit": "次/月", "times_unit": "次", + "timing_rules": "定時", "timor_leste": "東帝汶", "tip_del_success": "我們將對您的空間站數據保留七天,七天內可隨時撤銷刪除操作。", "tip_do_you_want_to_know_about_field_permission": "想對列數據加密嗎?了解列權限", @@ -58744,6 +60481,7 @@ "verify_account_title": "驗證賬號", "verify_via_email": "通過郵箱驗證碼驗證身份", "verify_via_phone": "通過短信驗證碼驗證身份", + "video": "影片", "video_not_support_play": "當前視頻格式不支持在線播放", "vietnam": "越南", "view": "視圖", @@ -59092,7 +60830,8 @@ "workdoc_color_title": "字體顏色", "workdoc_create": "創建輕文檔", "workdoc_expanded": "展開目錄", - "workdoc_image_max_10mb": "圖片大小不能超過10MB", + "workdoc_image_max_10mb": "無效的", + "workdoc_image_max_size": "圖片大小不能超過${size}", "workdoc_info": "文件訊息", "workdoc_info_create_time": "創建時間", "workdoc_info_creator": "創建人", @@ -59100,6 +60839,7 @@ "workdoc_info_last_modify_time": "修改時間", "workdoc_link_placeholder": "請輸入連結", "workdoc_only_image": "僅允許使用影像", + "workdoc_only_video": "僅允許視頻", "workdoc_text_placeholder": "輸入“/”開始", "workdoc_title_placeholder": "請輸入標題", "workdoc_unnamed": "未命名文檔", @@ -59108,9 +60848,11 @@ "workdoc_unsave_ok": "放棄更改", "workdoc_unsave_title": "輕文檔尚未保存", "workdoc_upload_failed": "上傳失敗", + "workdoc_video_max_size": "影片大小不能超過${size}", "workdoc_ws_connected": "已連接", "workdoc_ws_connecting": "正在連接...", "workdoc_ws_disconnected": "已斷開連接", + "workdoc_ws_reconnecting": "正在重新連接...", "workflow_execute_failed_notify": "執行失敗,請根據運行歷史排查問題,需要任何幫助或有任何疑問,請隨時與客服團隊聯繫", "workspace_data": "空間站數據", "workspace_files": "工作台數據", diff --git a/packages/datasheet/public/file/langs/strings.ko-KR.json b/packages/datasheet/public/file/langs/strings.ko-KR.json index 46d46f9f79..2d4d4dd105 100644 --- a/packages/datasheet/public/file/langs/strings.ko-KR.json +++ b/packages/datasheet/public/file/langs/strings.ko-KR.json @@ -146,6 +146,15 @@ "agreed": "심사비준을 거쳤어", "ai_advanced_mode_desc": "고급 모드를 사용하면 사용자가 프롬프트를 사용자 정의하여 AI 에이전트의 동작과 응답을 더 잘 제어할 수 있습니다.", "ai_advanced_mode_title": "고급 모드", + "ai_agent_anonymous": "익명${ID}", + "ai_agent_conversation_continue_not_supported": "이전 대화를 계속하는 것은 현재 지원되지 않습니다.", + "ai_agent_conversation_list": "대화 목록", + "ai_agent_conversation_log": "대화 기록", + "ai_agent_conversation_title": "대화 제목", + "ai_agent_feedback": "피드백", + "ai_agent_historical_message": "위의 내용은 역사적 메시지입니다.", + "ai_agent_history": "역사", + "ai_agent_message_consumed": "소비된 메시지", "ai_api_curl_template": "## Create chat completions\n\n```bash\n\ncurl -X POST \"{{apiBase}}/fusion/v1/ai/{{aiId}}/chat/completions\" \\n -H \"Content-Type: application/json\" \\n -H \"Authorization: Bearer {{token}}\" \\n -d '{\n \"model\": \"gpt-3.5-turbo\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"You are a helpful assistant.\"\n },\n {\n \"role\": \"user\",\n \"content\": \"Hello!\"\n }\n ]\n }'\n\n```\n\n## Returned data example\n\n```json\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", "ai_api_footer_desc": "웹 사이트에 인공지능 에이전트를 내장하시겠습니까?자세히 알아보기", "ai_api_javascript_template": "## Initialize SDK [![github]({{ githubIcon }})](https://github.com/openai/openai-node)\nAITable's chat completion API is compatible with OpenAI's Node.js SDK. You can use our service with the same SDK by simply changing the configuration as follows:\n\n\n```javascript\nconst { Configuration, OpenAIApi } = require(\"openai\");\nconst configuration = new Configuration({\n apiKey: \"{{token}}\",\n basePath: \"{{apiBase}}/fusion/v1/ai/{{aiId}}\"\n});\n```\n\n## Create chat completions\n\n```javascript\nconst openai = new OpenAIApi(configuration);\nconst chatCompletion = await openai.createChatCompletion({\n model: \"gpt-3.5-turbo\",\n messages: [{role: \"user\", content: \"Hello world\"}],\n});\n```\n\n## Returned data example\n\n```javascript\n\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", @@ -161,6 +170,9 @@ "ai_chat_unit": "aibot(s)", "ai_close_setting_tip_content": "변경했습니다.그걸 버리고 싶어?", "ai_close_setting_tip_title": "잎끝", + "ai_copilot_generate_response": "귀하를 위한 답변 생성 중...", + "ai_copilot_processs": "처리 중, 기다려주세요...", + "ai_copilot_start_process_request": "요청 처리 시작 중...", "ai_create_guide_btn_text": "데이터 테이블 선택", "ai_create_guide_content": "AI 에이전트로서 제가 배운 지식에 따라 여러분의 질문에 답할 수 있습니다.대화를 시작하기 전에 기술 자료로 데이터 테이블을 선택하고 학습을 위해 데이터 테이블의 모든 데이터를 읽습니다.", "ai_credit_cost_chart_title": "신용 비용", @@ -173,7 +185,7 @@ "ai_credit_time_dimension_year": "올해", "ai_credit_usage_tooltip": "메시지 크레딧은 AI 에이전트 조회에 사용할 수 있습니다. 메시지 크레딧은 스페이스의 좌석 수에 비례합니다.", "ai_data_source_required": "없는", - "ai_data_source_rows": "${row}행 데이터", + "ai_data_source_rows": "${rows}행 데이터", "ai_data_source_update": "사용 가능한 업데이트", "ai_datasheet_panel_create_btn_text": "AI 에이전트 만들기", "ai_default_idk": "잘 모르겠어요", @@ -629,7 +641,7 @@ "apps_support": "전체 플랫폼 클라이언트 지원", "archive_delete_record": "보관된 기록 삭제", "archive_delete_record_title": "기록 삭제", - "archive_notice": "

특정 기록을 보관하려고 합니다. 기록을 보관하면 다음과 같은 변경 사항이 발생합니다.

1. 이 기록에 대한 모든 양방향 링크가 취소됩니다.

2. 편집은 지원되지 않습니다.

3. 날짜 알림, 구독 기록 등의 기능은 지원되지 않습니다.

4. 더 이상 조회, 수식 및 기타 필드 계산에 참여하지 않습니다.

너 정말 계속하고 싶니? (고급의 보관함에서 보관을 취소할 수 있습니다)

", + "archive_notice": "

특정 기록을 보관하려고 합니다. 기록을 보관하면 다음과 같은 변경 사항이 발생합니다.

1. 편집은 지원되지 않습니다.

2. 날짜 알림, 구독 기록 등의 기능은 지원되지 않습니다.

3. 더 이상 조회, 수식 및 기타 필드 계산에 참여하지 않습니다.

너 정말 계속하고 싶니? (고급의 보관함에서 보관을 취소할 수 있습니다)

", "archive_record_in_activity": "이 레코드를 보관했습니다.", "archive_record_in_menu": "아카이브 레코드", "archive_record_success": "레코드가 성공적으로 아카이브되었습니다.", @@ -689,6 +701,8 @@ "audit_add_field_role_detail": "\"\" 데이터시트 에서 [] 필드 [] 에 대한 [] 역할 ", "audit_add_node_role": "파일 권한 추가", "audit_add_node_role_detail": "파일 권한 추가, 「${unitNames}」를 「 ${currentNodeName}」의 「${role}」 로 설정", + "audit_add_node_role_detail_end": "to「${role}", + "audit_add_node_role_detail_start": "Add file node permission,set「${unitNames}」", "audit_admin_permission_change_event": "관리자 권한 변경", "audit_create_template": "템플릿 만들기", "audit_create_template_detail": "템플릿 만들기", @@ -697,20 +711,30 @@ "audit_delete_field_role_detail": "감사", "audit_delete_node_role": "파일 삭제 권한", "audit_delete_node_role_detail": "파일 권한 삭제,「${unitNames}」의 「${role}」 역할 「${currentNodeName}」 삭제", + "audit_delete_node_role_detail_end": "at 「${role}」role", + "audit_delete_node_role_detail_start": "Delete file node permission,delete「${unitNames}」from", "audit_delete_template": "템플릿 삭제", "audit_delete_template_detail": "템플릿 삭제", "audit_disable_field_role": "필드 사용 권한 사용 안 함", "audit_disable_field_role_detail": "감사", "audit_disable_node_role": "파일 사용 권한 사용 안 함", "audit_disable_node_role_detail": "${nodeType} 「${currentNodeName}」 ` 권한 비활성화", + "audit_disable_node_role_detail_end": "`s permission", + "audit_disable_node_role_detail_start": "Disable ${nodeType}", "audit_disable_node_share": "파일 공통 링크 닫기", "audit_disable_node_share_detail": "${nodeType} 「${currentNodeName}」 공개 링크 닫기", + "audit_disable_node_share_detail_end": "public link", + "audit_disable_node_share_detail_start": "Close ${nodeType}", "audit_enable_field_role": "필드 사용 권한 사용", "audit_enable_field_role_detail": "감사", "audit_enable_node_role": "파일 사용 권한 사용", "audit_enable_node_role_detail": "${nodeType} 「${currentNodeName}」 ` 권한 활성화", + "audit_enable_node_role_detail_end": "`s permission", + "audit_enable_node_role_detail_start": "Enable ${nodeType}", "audit_enable_node_share": "파일 공통 링크 열기", "audit_enable_node_share_detail": "${nodeType} 「${currentNodeName}」 공개 링크 열기", + "audit_enable_node_share_detail_end": "public link", + "audit_enable_node_share_detail_start": "Open ${nodeType}", "audit_login_event": "로그인 이벤트", "audit_logout_event": "영어", "audit_organization_change_event": "담당자의 조직 구조 변경", @@ -731,18 +755,25 @@ "audit_space_invite_user_detail": "감사", "audit_space_node_copy": "중복된 파일", "audit_space_node_copy_detail": "${nodeType} 「${sourceNodeName}」 복제, 새 파일 이름은 「${currentNodeName}」", + "audit_space_node_copy_detail_start": "Duplicate ${nodeType} 「${sourceNodeName}」, the new file node's name is", "audit_space_node_create": "파일 만들기", "audit_space_node_create_detail": "「${currentNodeName}」 이라는 이름의 ${nodeType} 생성", + "audit_space_node_create_detail_start": "Create a ${nodeType} named", "audit_space_node_delete": "파일 삭제", "audit_space_node_delete_detail": "「${currentNodeName}」 이름의 ${nodeType} 삭제", + "audit_space_node_delete_detail_start": "Delete ${nodeType} named", "audit_space_node_export": "데이터 테이블 내보내기", "audit_space_node_export_detail": "${member_name} 구성원이 ${node_name} 데이터시트를 내보냈습니다.", "audit_space_node_import": "파일 가져오기", "audit_space_node_import_detail": "「${nodeName}」 파일 가져오기", + "audit_space_node_import_detail_start": "Import a file node named", "audit_space_node_move": "파일 이동", "audit_space_node_move_detail": "${nodeType} 「${currentNodeName}」을 「${parentName}」 폴더로 이동", + "audit_space_node_move_detail_end": "to the folder「${parentName}」", + "audit_space_node_move_detail_start": "Move ${nodeType}", "audit_space_node_rename": "파일 이름 바꾸기", "audit_space_node_rename_detail": "${nodeType} 「${oldNodeName}」의 이름을 「${nodeName}」 으로 변경", + "audit_space_node_rename_detail_start": "Rename ${nodeType} 「${oldNodeName}」to", "audit_space_node_sort": "감사", "audit_space_node_sort_detail": "감사", "audit_space_node_update_cover": "감사", @@ -757,17 +788,24 @@ "audit_space_rubbish_node_delete_detail": "감사", "audit_space_rubbish_node_recover": "파일 복원", "audit_space_rubbish_node_recover_detail": "${nodeType} 「${currentNodeName}」을 (를) 휴지통에서 복원", + "audit_space_rubbish_node_recover_detail_end": "from the trash", + "audit_space_rubbish_node_recover_detail_start": "Restore ${nodeType}", "audit_space_template_event": "템플릿 변경 내용", "audit_space_update_logo": "감사", "audit_space_update_logo_detail": "감사", "audit_store_share_node": "공유 파일 저장", "audit_store_share_node_detail": "${nodeType}을 공간으로 복원, 이름은 「${nodeName}」", + "audit_store_share_node_detail_start": "Restore ${nodeType} to the space, name is", "audit_update_field_role": "감사", "audit_update_field_role_detail": "감사", "audit_update_node_role": "파일 권한 수정", "audit_update_node_role_detail": "파일 권한 수정, 「${unitNames}」의 역할을 「 ${currentNodeName}」의 「${role}」 로 수정", + "audit_update_node_role_detail_end": "to「${role}」role", + "audit_update_node_role_detail_start": "Modify file node permission,modify「${unitNames}」from", "audit_update_node_share_setting": "파일 공통 링크 설정 수정", "audit_update_node_share_setting_detail": "${nodeType} 「${currentNodeName}」 공개 링크 수정", + "audit_update_node_share_setting_detail_end": "public link settings", + "audit_update_node_share_setting_detail_start": "Modify ${nodeType}", "audit_user_login": "사용자 로그인", "audit_user_login_detail": "감사", "audit_user_logout": "사용자 로그아웃", @@ -809,6 +847,7 @@ "automation_enabled_return_via_related_files": "자동화가 활성화되었습니다. 새 버튼을 사용하려면 \"관련 파일\"을 통해 원본 테이블을 다시 입력하세요.", "automation_field": "필드", "automation_import_variables_from_pre_tep": "사전 단계에서 데이터 가져오기", + "automation_is_not_yet_enabled": "자동화가 아직 활성화되지 않았습니다. 활성화하고 다시 시도하십시오.", "automation_last_edited_by": "최종 편집자:", "automation_last_edited_time": "마지막으로 편집한 시간", "automation_manager_label": "자동화에 대한 모든 작업을 수행할 수 있습니다.", @@ -834,6 +873,7 @@ "automation_runs_this_month": "이번 달에 실행", "automation_stay_tuned": "계속 지켜봐 주시기 바랍니다", "automation_success": "성공", + "automation_tips": "버튼 필드가 잘못 구성되었습니다. 확인하고 다시 시도해 주세요.", "automation_updater_label": "자동화의 실행 기록을 볼 수 있습니다.", "automation_variabel_empty": "사전 단계에서 사용할 수 있는 데이터가 없습니다. 조정 후 다시 시도해 주세요.", "automation_variable_datasheet": "${NODE_NAME}에서 데이터 가져오기", @@ -869,6 +909,7 @@ "bermuda": "버뮤다 제도", "bhutan": "부탄", "billing_over_limit_tip_common": "공간 사용량이 한도를 초과했으며, 업그레이드 후 더 많은 양을 즐기실 수 있습니다.", + "billing_over_limit_tip_forbidden": "평가판 기간 또는 구독 기간이 만료되었습니다. 갱신하려면 영업 컨설턴트에게 문의하세요.", "billing_over_limit_tip_widget": "위젯 설치 수가 한도를 초과했습니다. 업그레이드하여 사용량을 늘릴 수 있습니다.", "billing_period": "청구 기간: ${period}", "billing_subscription_warning": "기능 경험", @@ -928,10 +969,19 @@ "button_text": "버튼 텍스트", "button_text_click_start": "시작하려면 클릭하세요", "button_type": "버튼 유형", + "by_at": "~에", + "by_days": "날", + "by_every": "모든", "by_field_id": "필드 ID 사용", + "by_hours": "시간", + "by_in": "~에", + "by_min": "분)", + "by_months": "개월", + "by_on": "에", "by_the_day": "일별", "by_the_month": "월간", "by_the_year": "매년의", + "by_weeks": "주", "calendar_add_date_time_field": "만든 날짜 필드", "calendar_color_more": "추가 색상", "calendar_const_detail_weeks": "[\"월요일\",\"화요일\",\"수요일\",\"목요일\",\"금요일\",\"토요일\",\"일요일\"]", @@ -995,6 +1045,14 @@ "cannot_activate_space_by_space_limit": "공간 경계를 활성화할 수 없음", "cannot_join_space": "당신은 이미 10개의 우주 정거장의 최대 할당량을 초과했기 때문에 새로운 우주 정거장에 가입할 수 없습니다.", "cannot_switch_field_permission": "필드 사용 권한을 파일 사용 권한 이상으로 설정합니다.", + "capacity_file_detail_desc": "The total number of file nodes within the Space is calculated by adding the file nodes from the Team to the file nodes created by each member in their Private. Not enough capacity?", + "capacity_file_detail_title": "File Capacity", + "capacity_file_member": "Member", + "capacity_file_member_private_node_count": "Private", + "capacity_file_member_private_percent": "Percent", + "capacity_file_member_team": "Team", + "capacity_file_member_team_node_count": "Team", + "capacity_file_upgrade": "Click to upgrade your Space", "capacity_from_official_gift": "공식 선물", "capacity_from_participation": "${user}님을 초대하여 공간에 참여", "capacity_from_purchase": "구매 능력별", @@ -1031,6 +1089,8 @@ "catalog": "탐색자", "catalog_add_from_template_btn_title": "템플릿에서 추가", "catalog_empty_tips": "이 작업공간이 비어 있습니다.템플릿을 사용하여 파일 작성을 시작합니다.", + "catalog_private": "Private", + "catalog_team": "Team", "category_blank": "[공백]", "catering": "음식", "cayman_islands": "케이맨 제도", @@ -1099,6 +1159,7 @@ "choose_type_of_vika_field": "필드 유형 선택", "choose_your_own_space": "(작성자로 사용자 공간에 저장만 지원)", "chose_new_primary_admin_button": "할당", + "chunk_stopping_title": "Stopping", "claim_special_offer": "이 특별 할인 신청!", "clear": "명확했어", "clear_all_fields": "모두 지우기", @@ -1229,6 +1290,7 @@ "confirm_del_current_team": "팀을 삭제하시겠습니까?", "confirm_delete": "확인 및 삭제", "confirm_delete_node_name_as": "\"${nodeNameDiv}\"을(를) 삭제하시겠습니까?", + "confirm_delete_private_node_name_as": "Are you sure you want to delete \"${nodeNameDiv}\"? The file will be deleted from the Space and the trash.", "confirm_delete_space_btn": "스페이스 확인 및 삭제", "confirm_exit": "종료 확인", "confirm_exit_space_with_name": "\"${spaceNameDiv}\" 공간 종료 여부 확인", @@ -1266,6 +1328,14 @@ "convert": "변환", "convert_tip": "이 작업은 일부 셀의 데이터를 지울 수 있습니다.예기치 않은 상황이 발생하면 작업을 취소할 수 있습니다.", "cook_islands": "쿡 제도", + "copilot_auto_agent_desc": "어떤 에이전트를 선택해야 할지 모르시나요? AutoAgent를 사용해 보세요.", + "copilot_auto_agent_name": "자동 에이전트", + "copilot_data_agent_desc": "귀하의 의견을 기반으로 데이터 분석/시각화를 생성합니다.", + "copilot_data_agent_name": "데이터 에이전트", + "copilot_data_agent_policy": "Copilot과 채팅할 때 사용자 약관 정책에 동의하는 것으로 간주됩니다.", + "copilot_data_agent_policy_button": "정책", + "copilot_help_agent_desc": "AITable의 도움말 센터 문서에 관한 모든 것을 물어보세요.", + "copilot_help_agent_name": "도움말 센터 검색", "copy": "복제", "copy_automation_url": "URL 복사", "copy_card_link": "레코드 URL 복사", @@ -1310,6 +1380,7 @@ "create_mirror_guide_content": "미러 기능에는 특정 데이터를 숨길 수 있는 기능이 있습니다. 원본 데이터시트 보기에서 \"필터 조건\" 및 \"숨겨진 필드\"를 설정하여 미러에 표시되는 레코드와 필드를 제어할 수 있습니다.\n
\n
\n\"보기 잠금\" 기능과 함께 사용하면 다른 사람이 수정하는 것을 방지할 수 있습니다.\n
\n
\n또한 \"원래 테이블>숨겨진 필드\"로 이동하여 \"미러에 모든 필드 표시\" 구성을 수정할 수 있습니다.", "create_mirror_guide_title": "미러링은 일부 레코드 및 필드를 숨깁니다.", "create_new_button_field": "새 버튼 열 필드 만들기", + "create_private_node_tip": "Personal or temporary draft documents can be created here ${link}", "create_public_invitation_link": "공개 초대 링크 만들기", "create_space_sub_title": "안녕하세요, 공유 공간의 이름을 지어주세요 ~", "create_team_fail": "팀 생성 실패", @@ -1373,10 +1444,12 @@ "custom_enterprise": "사용자 정의 엔터프라이즈 공간", "custom_function_development": "맞춤형 기능 개발", "custom_grade_desc": "에이전트 배포, 개인 설치, 지원 및 맞춤형 전문 서비스 제공", + "custom_page_setting_title": "Add a custom page", "custom_picture": "사용자 정의 그림", "custom_style": "스타일", "custom_upload": "사용자 지정 업로드", "custom_upload_tip": "1: 1 정사각형 크기의 이미지를 사용하여 보다 나은 시청 환경을 제공하는 것이 좋습니다.", + "custome_page_title": "Custom Web", "cut_cell_data": "셀 잘라내기", "cyprus": "키프로스", "czech": "체코의", @@ -1428,6 +1501,7 @@ "default": "위약", "default_create_ai_chat_bot": "새로운 AI 에이전트", "default_create_automation": "새로운 자동화", + "default_create_custom_page": "새로운 사용자 정의 페이지", "default_create_dashboard": "새 대시보드", "default_create_datasheet": "새 데이터 테이블", "default_create_file": "새 파일", @@ -1449,6 +1523,7 @@ "del_invitation_link": "초대 링크 삭제", "del_invitation_link_desc": "삭제 후 링크가 유효하지 않습니다.", "del_space_now": "스페이스 영원히 삭제", + "del_space_now_confirm_tip": "For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "del_space_now_tip": "삭제 후 공간을 복원할 수 없습니다.모든 파일과 첨부 파일이 삭제됩니다.", "del_space_res_tip": "삭제된 공간", "del_team_success": "팀 삭제 성공", @@ -1644,6 +1719,62 @@ "embed_error_page_help": "자세한 내용", "embed_fail_og_description_content": "이 포함된 공용 링크는 비활성화되어 당분간 사용할 수 없습니다.", "embed_failed": "포함된 링크를 사용할 수 없습니다.", + "embed_link_bilibili": "빌리빌리", + "embed_link_bilibili_desc": "bilibili 동영상을 삽입하면 튜토리얼, 가이드를 시청하거나 Vika에서 채널 홈페이지를 볼 수 있습니다.", + "embed_link_bilibili_link_text": "bilibili 비디오를 삽입하는 방법", + "embed_link_bilibili_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-bilibili-video", + "embed_link_default": "아무것", + "embed_link_default_desc": "웹사이트를 보려면 링크를 붙여넣으세요.", + "embed_link_default_link_text": "더 알아보기", + "embed_link_default_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_link_figma": "Figma", + "embed_link_figma_desc": "Figma 파일을 내장함으로써 회원들은 디자인 초안을 보다 편리하게 보고 편집할 수 있어 협업 효율성이 향상됩니다.", + "embed_link_figma_link_text": "Figma 파일을 삽입하는 방법", + "embed_link_figma_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-figma-file", + "embed_link_google_docs": "Docs", + "embed_link_google_docs_desc": "Google Docs를 삽입하면 AITable에서 문서를 편집하고 볼 수 있어 팀 협업이 용이해집니다.", + "embed_link_google_docs_link_text": "Google 문서를 삽입하는 방법", + "embed_link_google_docs_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-docs-file", + "embed_link_google_sheets": "Sheets", + "embed_link_google_sheets_desc": "Google 스프레드시트를 삽입하면 AITable에서 테이블을 편집하고 볼 수 있어 팀 공동작업이 용이해집니다.", + "embed_link_google_sheets_link_text": "Google 스프레드시트를 삽입하는 방법", + "embed_link_google_sheets_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-sheets-file", + "embed_link_jishi_design": "JS디자인", + "embed_link_jishi_design_desc": "JSdesign 파일을 내장함으로써 구성원은 디자인 초안을 보다 편리하게 보고 편집할 수 있어 협업 효율성이 향상됩니다.", + "embed_link_jishi_design_link_text": "JSdesign 파일을 삽입하는 방법", + "embed_link_jishi_design_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-js-design-file", + "embed_link_tencent_docs": "텐센트 문서", + "embed_link_tencent_docs_desc": "Tencent Docs를 내장하면 Vika에서 Tencent 문서를 편집하고 볼 수 있어 협업 효율성이 향상됩니다.", + "embed_link_tencent_docs_link_text": "Tencent Docs를 삽입하는 방법", + "embed_link_tencent_docs_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-tencent-docs", + "embed_link_wps": "WPS", + "embed_link_wps_desc": "WPS 파일을 삽입하면 Vika에서 WPS 문서, 표, 양식을 편집하고 볼 수 있어 협업 효율성이 향상됩니다.", + "embed_link_wps_link_text": "WPS 파일을 삽입하는 방법", + "embed_link_wps_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-wps-file", + "embed_link_youtube": "유튜브", + "embed_link_youtube_desc": "YouTube 동영상을 삽입하면 튜토리얼, 가이드를 시청하거나 AITable에서 채널 홈페이지를 볼 수 있습니다.", + "embed_link_youtube_link_text": "YouTube 동영상을 삽입하는 방법", + "embed_link_youtube_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-youtube-video", + "embed_page": "사용자 정의 페이지", + "embed_page_add_url": "URL 추가", + "embed_page_doc_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_page_function_desc": "제3자 웹사이트 문서, 비디오 등에 쉽게 액세스하려면 ${edition}에 웹페이지를 추가하세요. 추천 웹사이트 링크나 사용자 정의 링크를 추가할 수 있습니다.", + "embed_page_node_permission_editor": "\"업데이트 전용\"을 기준으로 파일의 공개 공유도 열 수 있습니다.", + "embed_page_node_permission_manager": "파일에 대한 모든 작업을 수행할 수 있습니다.", + "embed_page_node_permission_reader": "사용자 정의 페이지의 내용과 기본 파일 정보를 볼 수 있습니다.", + "embed_page_node_permission_updater": "\"읽기 전용\"을 기반으로 사용자 정의 페이지의 링크를 수정할 수도 있습니다.", + "embed_page_setting_title": "사용자 정의 페이지 추가", + "embed_page_url_invalid": "올바른 URL을 입력하세요.", + "embed_paste_link_bilibili_placeholder": "bilibili 비디오 링크 붙여넣기", + "embed_paste_link_default_placeholder": "URL을 붙여넣으세요", + "embed_paste_link_figma_placeholder": "Figma 파일의 공유 링크를 붙여넣으세요.", + "embed_paste_link_google_docs_placeholder": "Google Docs 공유 링크를 붙여넣으세요.", + "embed_paste_link_google_sheets_placeholder": "Google Sheets 공유 링크를 붙여넣으세요.", + "embed_paste_link_jsdesign_placeholder": "JSdesign 파일의 공유 링크를 붙여넣으세요.", + "embed_paste_link_tencent_docs_placeholder": "Tencent Docs 공유 링크를 붙여넣으세요.", + "embed_paste_link_wps_placeholder": "WPS 파일의 공유 링크를 붙여넣으세요.", + "embed_paste_link_youtube_placeholder": "YouTube 동영상 링크 붙여넣기", + "embed_success": "추가가 성공했습니다.", "emoji_activity": "활동", "emoji_custom": "풍속", "emoji_flags": "깃발", @@ -1750,6 +1881,11 @@ "estonia": "에스토니아", "ethiopia": "에티오피아", "event_planning": "행사 기획", + "every": "모든", + "every_day_at": "일(들)", + "every_hour_at": "시간", + "every_month_at": "월", + "every_week_at": "매주", "everyday_life": "일상 생활", "everyone_visible": "모두에게 보여요", "exact_date": "정확한 날짜", @@ -1760,6 +1896,7 @@ "exchange": "되찾다", "exchange_code_times_tip": "참고: 교환코드는 한 번만 사용할 수 있습니다.", "exclusive_consultant": "독점 V+ 컨설턴트", + "exclusive_limit_plan_desc": "독점적인 한정 등급", "exist_experience": "종료 경험", "exits_space": "스페이스 종료", "expand": "확대", @@ -1786,7 +1923,7 @@ "expired": "만기", "export": "내보내는 중...", "export_brand_desc": "기술 지원", - "export_current_preview_view_data": "", + "export_current_preview_view_data": "Export current preview view data", "export_gantt_button_tips": ".png 파일로 내보내기", "export_gantt_chart": "Gantt 차트 내보내기", "export_to_excel": "데이터 내보내기", @@ -2357,26 +2494,26 @@ "gantt_config_color_by_single_select_pleaseholder": "선택 필드 선택", "gantt_config_color_help": "설정 방법", "gantt_config_friday": "금요일", - "gantt_config_friday_in_bar": "금요일", + "gantt_config_friday_in_bar": "금", "gantt_config_friday_in_select": "금요일", "gantt_config_monday": "월요일", - "gantt_config_monday_in_bar": "월요일", + "gantt_config_monday_in_bar": "월", "gantt_config_monday_in_select": "월요일", "gantt_config_only_count_workdays": "기간은 근무일만 계산됩니다.", "gantt_config_saturday": "토요일", - "gantt_config_saturday_in_bar": "토요일", + "gantt_config_saturday_in_bar": "토", "gantt_config_saturday_in_select": "토요일", "gantt_config_sunday": "일요일", - "gantt_config_sunday_in_bar": "일요일", + "gantt_config_sunday_in_bar": "일", "gantt_config_sunday_in_select": "일요일", "gantt_config_thursday": "목요일", - "gantt_config_thursday_in_bar": "청화대학", - "gantt_config_thursday_in_select": "청화대학", + "gantt_config_thursday_in_bar": "목", + "gantt_config_thursday_in_select": "목요일", "gantt_config_tuesday": "화요일", - "gantt_config_tuesday_in_bar": "화요일", + "gantt_config_tuesday_in_bar": "화", "gantt_config_tuesday_in_select": "화요일", "gantt_config_wednesday": "수요일", - "gantt_config_wednesday_in_bar": "수요일", + "gantt_config_wednesday_in_bar": "수", "gantt_config_wednesday_in_select": "수요일", "gantt_config_weekdays_range": "${weekday} ~ ${weekday}", "gantt_config_workdays_a_week": "표준 근무일 사용자 지정", @@ -2458,6 +2595,7 @@ "gold_grade": "킴", "gold_grade_desc": "비즈니스 프로세스가 복잡한 팀을 위한 설계", "gold_seat_200_desc": "200", + "gold_seat_300_desc": "300", "golden_grade": "킴", "got_it": "알았어", "got_v_coins": "보상 V코인", @@ -2491,6 +2629,8 @@ "guests_per_space": "각 공간의 손님", "guide_1": "啊这", "guide_2": "기본 기능을 학습하는 데 몇 분밖에 걸리지 않습니다.이 순간부터 생산성 향상!", + "guide_flow_modal_contact_sales": "영업팀에 문의", + "guide_flow_modal_get_started": "시작하다", "guide_flow_of_catalog_step1": "Space의 모든 폴더와 파일이 저장된 작업 디렉토리입니다.", "guide_flow_of_catalog_step2": "작업 디렉토리에서 필요에 따라 데이터 테이블이나 폴더를 만들 수 있습니다.", "guide_flow_of_click_add_view_step1": "일부 기본 보기 외에 그림 형식의 첨부 파일이 있으면 앨범 보기를 만드는 것이 좋습니다.", @@ -2669,6 +2809,7 @@ "intro_widget_tips": "위젯이란 무엇입니까?", "introduction": "소개", "invalid_action_sort_tip": "그룹 필드로서 정렬이 설정되어 있습니다.현재 주문에 대한 설정은 적용되지 않습니다.", + "invalid_automation_configuration": "자동화 구성이 잘못되었습니다. 확인하고 다시 시도해 주세요.", "invalid_field_type": "잘못된 필드 유형", "invalid_option_sort_tip": "그룹 필드로서 정렬이 설정되어 있습니다.", "invalid_redemption_code_entered": "잘못된 교환 코드", @@ -2799,6 +2940,9 @@ "label_format_day_month_and_year_split_by_slash": "일 / 월 / 년", "label_format_month": "월", "label_format_month_and_day_split_by_dash": "년 월 일", + "label_format_month_day_year_split_by_dash": "Month-Day-Year", + "label_format_month_day_year_split_by_slash": "Month/Day/Year", + "label_format_month_day_year_two_digit_year_split_by_slash": "Month/Day/Year (Two-digit year)", "label_format_year": "년", "label_format_year_and_month_split_by_dash": "년 월", "label_format_year_month_and_day_split_by_dash": "년 월 일", @@ -2877,6 +3021,7 @@ "lark_version_enterprise": "Lark의 엔터프라이즈 프로그램", "lark_version_standard": "Lark 표준 평면도", "lark_versions_free": "Lark의 기본 평면도", + "last_day": "마지막 날", "last_modified_by_select_modal_desc": "아래에서 선택한 필드를 편집하면 최근에 편집한 구성원이 마지막으로 편집한 필드에 표시됩니다.", "last_modified_time_select_modal_desc": "아래에서 선택한 필드를 편집하면 가장 최근에 편집한 시간이 마지막으로 편집한 시간 필드에 표시됩니다.", "last_step": "반환", @@ -3021,7 +3166,7 @@ "mail_invite_fail": "메일 초대가 성공했습니다.", "mail_invite_success": "메일 초대가 성공했습니다.", "main_admin_name": "관리자 이름", - "main_admin_page_desc": "관리자는 하위 관리자 및 이전 공간의 소유권과 같은 공간에 완전히 액세스할 수 있습니다.", + "main_admin_page_desc": "관리자는 구성원 관리, 공간 설정 관리 등 공간에 대한 모든 액세스 권한을 갖습니다.", "main_contain": "주요 내용", "malawi": "말라위", "malaysia": "말레이시아", @@ -3241,8 +3386,12 @@ "more_widget": "추가 가젯", "morocco": "모로코", "move": "이동", + "move_datasheet_link_warn": "Cannot be moved to Team Area alone, because there is a two-way link from the current datasheet to another datasheet, it is recommended to put them in a folder and then move them", "move_favorite_node_fail": "노드 이동에 실패했습니다.목록이 자동으로 업데이트됩니다.", + "move_folder_link_warn": "Cannot be moved to Team Area because the files in the current folder are linked to files outside the folder (may be two-way links or linked by forms, etc.) We recommend that they be placed in a folder before moving", "move_node_modal_content": "이동하면 상위 폴더의 파일 가시성에 영향을 받을 수 있습니다.", + "move_other_link_no_permission": "Unable to move to the corresponding folder because you do not have administrative rights to the folder", + "move_other_link_warn": "It is not allowed to move ${node type} to Team Area alone, because it connects to the datasheet of Private Area, it is recommended to put them in a folder before moving them", "move_to": "다음으로 이동", "move_to_error_equal_parent": "파일은 현재 폴더 아래에 있습니다.다른 폴더를 선택하십시오.", "move_to_modal_title": "[${name}]을(를) 다음으로 이동", @@ -3273,7 +3422,9 @@ "new_a_line": "Shift+Enter 키: 줄 바꿈", "new_automation": "새로운 자동화", "new_caledonia": "뉴칼레도니아", + "new_custom_page": "New custom page", "new_datasheet": "새 데이터 테이블", + "new_ebmed_page": "새로운 사용자 정의 페이지", "new_folder": "새 폴더", "new_folder_btn_title": "폴더", "new_folder_tooltip": "폴더 만들기", @@ -3439,7 +3590,7 @@ "nvc_start_text": "막대를 오른쪽 끝으로 드래그", "nvc_yes_text": "입증된", "obtain_verification_code": "인증 코드가 검색되지 않았거나 만료되었습니다.", - "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrzw0miJVmSkJ7eBBa9k/fomx5qPX0JGPFvfEEP\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", + "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrCvbFC53xc3kl00B4Pg\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", "offical_website_nav_data": "[{\n \"name\": \"产品\",\n \"href\": \"/login\",\n \"children\": [\n {\n \"name\": \"vika维格表 Overview\",\n \"href\": \"/login/\"\n },\n {\n \"name\": \"应用连接 Integration\",\n \"href\": \"/connections/\"\n },\n {\n \"name\": \"客户端(Beta) Download\",\n \"href\": \"/download/\"\n }\n ]\n}, {\n \"name\": \"解决方案\",\n \"href\": \"/\",\n \"children\": [{\n \"name\": \"PMO项目群管理\",\n \"href\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"href\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"href\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"href\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"href\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"href\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"href\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"href\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"href\": \"/shop/\"\n }, {\n \"name\": \"更多解决方案 >\",\n \"href\": \"/solutions/\"\n }]\n}, {\n \"name\": \"模板/案例\",\n \"href\": \"/template\",\n \"children\": [\n {\n \"name\": \"模板中心 Tempaltes\",\n \"href\": \"/template\"\n },\n {\n \"name\": \"客户案例 Customers\",\n \"href\": \"/cases/\"\n }\n ]\n},\n {\n \"name\": \"首页\",\n \"href\": \"/?home=1\"\n },\n {\n \"name\": \"学习资源\",\n \"href\": \"https://edu.vika.cn/index\",\n \"children\": [\n {\n \"name\": \"快速入门 Tutorials\",\n \"href\": \"https://help.vika.cn/docs/guide/tutorial\"\n },\n {\n \"name\": \"产品手册 Manual\",\n \"href\": \"https://help.vika.cn/docs/guide/manual\"\n },\n {\n \"name\": \"维格课堂 Vika Education\",\n \"href\": \"https://edu.vika.cn/\"\n },\n {\n \"name\": \"维格社区 Vika BBS\",\n \"href\": \"https://bbs.vika.cn/\"\n },\n {\n \"name\": \"第三方连接 Integration\",\n \"href\": \"https://help.vika.cn/docs/guide/connection\"\n },\n {\n \"name\": \"开发者中心 Developer Center\",\n \"href\": \"/developers/\"\n },\n {\n \"name\": \"常见问题 FAQ\",\n \"href\": \"https://help.vika.cn/docs/guide/questions\"\n }\n ]\n }]", "office_preview": "Office 파일 미리 보기", "office_preview_app_desc": "

Smooth online preview of office files on datasheet, allowing you to view common office files such as Excel, Word, PPT, etc. on your desktop or mobile anywhere, anytime

\n\n
    \n
  • Online preview of .doc, .docx, .xls, .xlsx, .ppt, .pptx, and .pdf formatted office files
  • \n
  • Desktop and mobile both support file previews of the above formats
  • \n
\n\n

Additional notes:

\n
    \n
  • This feature is powered by \"Yoncentric Cloud Conversion\" and officially integrated
  • \n
  • Click the \"Enable\" button below to enable this integration and agree that \"Yoncentric Cloud Conversion\" reads the office files you want to preview
  • \n
  • If you no longer need the office files preview feature, the space admin can disable it on this page
  • \n
", @@ -3479,6 +3630,7 @@ "open_auto_save_success": "자동 저장 뷰가 성공적으로 열렸습니다.", "open_auto_save_warn_content": "이 뷰의 모든 변경 사항은 자동으로 저장되고 다른 구성원과 동기화됩니다.", "open_auto_save_warn_title": "뷰 자동 저장 사용", + "open_automation_time_arrival": "https://aitable.ai/contact-sales-open-source", "open_failed": "열기 실패", "open_in_new_tab": "새 탭에서 열기", "open_invite_after_operate": "열면 모든 구성원이 연락처 패널에서 새 구성원을 초대할 수 있습니다.", @@ -3625,6 +3777,8 @@ "payment_record": "결제 기록", "payment_reminder": "결제 팁", "payment_reminder_content": "선택한 새 플랜은 지불해야 하는 금액보다 더 많은 공제액이 있습니다. 기간이 더 긴 새 요금제를 선택하는 것이 좋습니다. 이를 확인하면 초과 금액은 환불되지 않습니다. ${action} 의심스러운 경우", + "payment_reminder_modal_content": "고급 버전을 사용하면 더 많은 파일 노드, 기업 권한, 첨부 용량, 데이터 볼륨, AI 및 기타 고급 기능과 권한을 누릴 수 있습니다.", + "payment_reminder_modal_title": "현재 무료 버전을 사용하고 계십니다", "pending_invite": "보류된 초대", "people": "구성원", "per_person_per_year": "매인당 매년", @@ -3794,7 +3948,7 @@ "player_step_ui_config_168": "{\n\"templateKey\":\"createMirrorTip\"\n}", "player_step_ui_config_169": "{ \"headerImg\": \"https://s4.vika.cn/space/2023/04/04/bcf0695cf35840e6b85e032a8e5ea0a1\", \"readMoreUrl\": \"https://help.vika.cn/changelog/23-04-10- 업데이트\", \"어린이\": \"

🚀 새로운 기능 소개

\\N
  • 새로운 필드 유형 \"캐스케이더\"가 출시되어 양식의 옵션 계층 구조에서 더 쉽게 선택할 수 있습니다.
  • \"스크립트\" 위젯이 출시되었습니다. 더 적은 코드로 더 많은 사용자 정의 가능
  • 자동화를 실행하여 이메일을 보내고 빠른 알림 받기
  • 자동화를 실행하여 Slack에 메시지를 보내고 적시에 팀에 알립니다.
  • AI 탐색: \"GPT 콘텐츠 생성기\" 위젯 출시
\" }", "player_step_ui_config_17": "{\n \"element\": \"#TEMPLATE_CENTER_USE_TEMPLATE_BTN>button\", \n\"placement\": \"rightBottom\",\n\"offsetY\": 20,\n \"title\": \"How to use a template\", \n\"description\": \"Click the button on the left to use the template\", \"children\":\"\" \n}", - "player_step_ui_config_176": "{\"title\":\"AI 프록시 프로필\",\"video\":\"https://www.youtube.com/embed/cjds1r_roG8?si=irKUpMhwDlOEb8Hc\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", + "player_step_ui_config_176": "{\"title\":\"AITable.ai DEMO\",\"video\":\"https://www.youtube.com/embed/kGxMyEEo3OU\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", "player_step_ui_config_18": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select>.ant-select-selector\", \n\"placement\": \"bottomLeft\",\n \"title\": \"How to use a template\", \n\"description\": \"Select where to put the template\", \"children\":\"\" \n}", "player_step_ui_config_19": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select .ant-select-selector\"\n}", "player_step_ui_config_2": "{\n \"config\": [\n {\n \"key\": 1,\n \"name\": \"answer1\",\n \"title\": \"What kind of issues are you looking forward to solved by vikadata?\",\n \"type\": \"checkbox\",\n \"answers\": [\n \"Work Planning\",\n \"Customer Service\",\n \"Project Management\",\n \"Sourcing Supply\",\n \"Content Production\",\n \"E-commerce operation\",\n \"Event Planning\",\n \"Human Resources\",\n \"Administration\",\n \"Financial Management\",\n \"Webcast\",\n \"Educational institutes Management\",\n \"Other\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 2,\n \"name\": \"answer2\",\n \"title\": \"Your job title is______\",\n \"type\": \"radio\",\n \"answers\": [\n \"General manager \",\n \"Project manager\",\n \"Product manager\",\n \"Designer\",\n \"R&D engineer\",\n \"Operator, editor\",\n \"Sales, customer service\",\n \"Human resource, administration \",\n \"Finance, accountant\",\n \"Lawyer, legal affairs\",\n \"Marketing\",\n \"Teacher\",\n \"Student\",\n \"Other\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 3,\n \"name\": \"answer3\",\n \"title\": \"What is the name of your company?\",\n \"type\": \"input\",\n \"submit\": false\n },\n {\n \"key\": 4,\n \"name\": \"answer4\",\n \"title\": \"Please leave your email address/ phone number/ Wechat account below so we can reach you in time when you need help.\",\n \"type\": \"input\",\n \"submit\": true\n },\n {\n \"key\": 5,\n \"title\": \"Thank you for filling out the form, you can add our customer service in case of need\",\n \"platform\": {\n \"website\": \"https://s4.vika.cn/space/2023/03/02/b34e3205a9154463be16f497524f1327\",\n \"dingtalk\": \"https://s4.vika.cn/space/2023/03/02/4b16cef6602a4586a21d6346bf25d300\",\n \"wecom\": \"https://s4.vika.cn/space/2023/03/02/60119b1b69b64aa887bd1be6a2928bec\",\n \"feishu\": \"https://u.vika.cn/z9ygm\"\n },\n \"type\": \"contactUs\",\n \"next\": true\n }\n ]\n}\n", @@ -3824,13 +3978,13 @@ "player_step_ui_config_41": "", "player_step_ui_config_42": "{\n \"element\": \"#DATASHEET_FORM_LIST_PANEL\", \n\"placement\": \"leftTop\",\n \"title\": \"Form\", \n\"description\": \"You can quickly create a form from the current view. The number and order of the fields in the form is consistent with the view.\", \"children\":\"\" \n}", "player_step_ui_config_43": "{\n \"element\": \".style_navigation__1U5cR .style_help__1sXEA\", \n\"placement\": \"rightBottom\",\n \"title\": \"Tip\", \n\"offsetY\":5,\n\"description\": \"You can find your Vikaby assistant from the \"Help\" icon on the left\", \"children\":\"\" \n}", - "player_step_ui_config_44": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", + "player_step_ui_config_44": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", "player_step_ui_config_45": "", "player_step_ui_config_46": "", "player_step_ui_config_47": "{\n \"element\": \"#DATASHEET_WIDGET_BTN\",\n\"placement\": \"bottomRight\",\n \"title\": \"Widget\", \n\"description\": \"Want to use and view your data in a richer way? Try the widget!\", \"children\":\"\" \n}", "player_step_ui_config_48": "", "player_step_ui_config_49": "{\n \"element\": \".style_widgetPanelContainer__1l2ZV\",\n\"placement\": \"leftCenter\",\n \"title\": \"What is a widget\", \n\"description\": \"Vika widgets are an extended application of vikadata that features in richer data visualization, data transfer, data cleansing, and more. By installing widgets in the widget board, you can make work a lot easier.\", \"children\":\"\" \n}", - "player_step_ui_config_5": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", + "player_step_ui_config_5": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", "player_step_ui_config_50": "{\n \"element\": \".style_widgetModal__eXmdB\",\n\"placement\": \"leftTop\",\n \"title\": \"Widget Center\", \n\"description\": \"Officially recommended and custom widgets are published here. You can install any widget you want onto a dashboard or into a widget board of any datasheet.\", \"children\":\"\" \n}", "player_step_ui_config_51": "{\n \"element\": \".style_widgetModal__eXmdB .style_widgetItem__3Pl-1 button\",\n\"placement\": \"rightBottom\",\n \"title\": \"Install widget\", \n\"description\": \"Let's install this \"Chart\" widget\", \"children\":\"\" \n}", "player_step_ui_config_52": "", @@ -3927,6 +4081,7 @@ "preview_guide_click_to_restart": "아래 버튼을 눌러 다시 미리보기", "preview_guide_enable_it": "아래 버튼을 눌러 이 기능을 엽니다.", "preview_guide_open_office_preview": "이 파일을 미리 보려면 사무실 미리 보기 기능을 엽니다.", + "preview_next_automation_execution_time": "다음 10개의 실행 시간 미리보기", "preview_not_support_video_codecs": "H.264 비디오 코덱이 있는 MP4 비디오만 미리 볼 수 있습니다.", "preview_revision": "미리 보기", "preview_see_more": "오피스 파일 미리보기 기능에 대해 더 알고 싶으십니까?여기를 클릭하십시오.", @@ -3962,6 +4117,7 @@ "privacy_protection": "\"개인 정보 보호\"", "private_cloud": "프라이빗 클라우드", "private_external_person_only": "외부인 전용", + "private_help_link": "https://help.aitable.ai/docs/guide/team-and-private-area#private-area", "private_internal_person_only": "내부 인력만", "private_product_point": "클릭 한 번으로 APITable 플랫폼 소유", "privatized_deployment": "자체 관리", @@ -4032,13 +4188,15 @@ "reconciled_data": "데이터 확인 중", "record": "기록", "record_activity_experience_tips": "${day}일의 기록 활동을 볼 수 있습니다.", + "record_archived_data": "보관된 기록", + "record_chunk_text": "${text} rows, please wait", "record_comment": "주석만 해당", "record_comments": "코멘트", "record_fail_data": "데이터 오류", "record_filter_tips": "이 레코드는 필터링됨", "record_functions": "레코드 기능", "record_history": "개정 히스토리만", - "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-history", + "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-activity", "record_history_title": "기록 기록", "record_pre_filtered": "이 레코드는 필터링되었으며 레코드 외부를 클릭하면 숨겨집니다.", "record_pre_move": "레코드 외부를 클릭하면 레코드가 다른 위치로 이동됩니다.", @@ -4478,6 +4636,12 @@ "scan_to_login": "로그인 검색", "scan_to_login_by_method": "로그인하려면 ${method}를 스캔하여 공식 계정을 팔로우하세요.", "scatter_chart": "산포도", + "schedule_day_tips": "주기 계산은 매월 1일부터 시작됩니다. 10일마다 반복한다고 가정하면 매월 1일, 11일, 21일, 31일에 실행됩니다.", + "schedule_hour_tips": "주기 계산은 매일 자정(0:00)에 시작됩니다. 3시간마다 0분씩 반복한다고 가정하면 매일 자정(0:00), 오전 3시, 오전 6시, 오전 9시, 정오(12시), 오후 3시, 오후 6시, 마지막으로 해질녘(오후 9시)에 발생하게 됩니다.", + "schedule_start_day": "매월 1일부터", + "schedule_start_month": "매년 1월부터 매년", + "schedule_type": "일정 유형", + "schedule_year_tips": "주기 계산은 매년 첫 번째 달부터 시작됩니다. 첫 번째 날을 3개월 간격으로 가정하면 매년 1월, 4월, 7월, 10월 첫 번째 날 자정에 트리거가 활성화됩니다.", "science_and_technology": "과학과 기술", "scroll_screen_down": "화면 아래로 스크롤", "scroll_screen_left": "왼쪽으로 화면 스크롤", @@ -4491,6 +4655,7 @@ "search_folder_or_sheet": "파일 검색", "search_new_admin": "검색", "search_node_pleaseholder": "파일 검색(${shortcutKey})", + "search_node_tip": "빠른 검색(${shortcutKey})", "search_or_add": "옵션 찾기 또는 추가", "search_role_placeholder": "역할 검색", "seats": "좌석", @@ -4894,6 +5059,7 @@ "space_info": "개요", "space_info_del_confirm1": "1. 이 공유 공간을 삭제하면 다음 데이터가 지워집니다.", "space_info_del_confirm2": "2. 공유 공간은 7일 후에 완전히 삭제됩니다.그 전에 공간을 복원할 수 있습니다.", + "space_info_del_confirm3": "3. For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "space_info_feishu_desc": "타사 통합을 사용하고 있습니다.공유 공간을 삭제하려면 먼저 타사 통합을 비활성화합니다.", "space_info_feishu_label": "통합", "space_join_apply": "\"\" 공간을 요청합니다.", @@ -4980,6 +5146,7 @@ "start_onfiguration": "시작 구성", "start_time": "시작 시간", "start_use": "사용 시작", + "starting_from_midnight": "매일 자정(오전 12시)부터 매주", "startup": "시작", "startup_company_support_program": "지원 계획 시작", "stat_average": "평균적", @@ -5013,6 +5180,8 @@ "stay_tuned_for_more_features": "더 많은 기능에 관심을 가져주시기 바랍니다.", "steps_choose_reset_mode": "재설정 방법 선택", "steps_validate_identities": "인증 인증", + "stop_chunk_content": "Are you sure you want to stop the operation?", + "stop_chunk_title": "Stop", "stop_dingtalk_h5_modal_content": "자체 제작 응용 프로그램은 이 공간의 바인딩을 해제합니다.확인하세요.", "storage_per_seats": "", "storage_per_space": "스토리지 사용", @@ -5043,9 +5212,11 @@ "subscribe_credit_usage_over_limit": "현재 스페이스의 포인트 수가 제한을 초과합니다. 서브스크립션을 업그레이드하십시오.\n", "subscribe_demonstrate": "요청 프레젠테이션", "subscribe_disabled_seat": "인원수는 원래 계획보다 낮아서는 안 된다.", + "subscribe_grade_business": "사업", "subscribe_grade_free": "자유의", "subscribe_grade_plus": "더하기", "subscribe_grade_pro": "찬성", + "subscribe_grade_starter": "기동기", "subscribe_label_tooltip": "고급 공간 기능", "subscribe_new_choose_member": "최대 ${member_num}명의 회원 지원", "subscribe_new_choose_member_tips": "이 플랜은 1~${member_num}명의 멤버가 공간에 입장할 수 있도록 지원합니다.", @@ -5182,7 +5353,7 @@ "template_name_repetition_title": "\"${templateName}\"이(가) 이미 존재합니다. 교체하시겠습니까?", "template_no_template": "템플릿 없음", "template_not_found": "원하는 템플릿을 찾을 수 없습니까?알려주세요", - "template_recommend_title": "더웠어", + "template_recommend_title": "🌟 Hot", "template_type": "템플릿", "terms_of_service": "<서비스 약관>", "terms_of_service_pure_string": "서비스 약관", @@ -5226,6 +5397,7 @@ "text_editor_tip_end": "가져오기 편집 종료", "text_functions": "문자열 함수", "thailand": "태국", + "the_button_field_is_misconfigured": "버튼 필드가 잘못 구성되었습니다. 확인하고 다시 시도해 주세요.", "the_current_automation_workflow_has_no_related_files_you_can_establish_a_link_by_adding_trigger_conditions_and_actions_on_the_left_side": "현재 자동화된 워크플로우에는 관련 파일이 없습니다.왼쪽에 트리거 조건 및 작업을 추가하여 링크를 설정할 수 있습니다.", "the_current_button_column_has_expired_please_reselect": "현재 버튼 열이 만료되었습니다. 다시 선택하세요.", "the_last_7_days": "지난 7일", @@ -5328,6 +5500,7 @@ "timemachine_update_comment": "업데이트된 댓글", "times_per_month_unit": "전화 / 월", "times_unit": "전화기", + "timing_rules": "타이밍", "timor_leste": "동티모르", "tip_del_success": "7일 이내에 공유 공간을 복구할 수 있습니다.", "tip_do_you_want_to_know_about_field_permission": "필드 데이터를 암호화하시겠습니까?필드 권한 이해", @@ -5515,6 +5688,7 @@ "verify_account_title": "계정 확인", "verify_via_email": "이메일을 통한 인증", "verify_via_phone": "문자 인증", + "video": "동영상", "video_not_support_play": "현재 비디오 형식은 온라인 재생을 지원하지 않습니다.", "vietnam": "베트남", "view": "견해", @@ -5863,7 +6037,8 @@ "workdoc_color_title": "글꼴 색상", "workdoc_create": "Workdoc 만들기", "workdoc_expanded": "목차 펼치기", - "workdoc_image_max_10mb": "이미지 크기는 10MB를 초과할 수 없습니다.", + "workdoc_image_max_10mb": "없는", + "workdoc_image_max_size": "이미지 크기는 ${size}을(를) 초과할 수 없습니다.", "workdoc_info": "WorkDoc 정보", "workdoc_info_create_time": "생성 날짜", "workdoc_info_creator": "작성자:", @@ -5871,6 +6046,7 @@ "workdoc_info_last_modify_time": "마지막 수정 시간:", "workdoc_link_placeholder": "링크를 입력해주세요", "workdoc_only_image": "이미지만 허용됩니다.", + "workdoc_only_video": "영상만 허용됩니다", "workdoc_text_placeholder": "\"/\" 빠른 시작 입력", "workdoc_title_placeholder": "제목을 입력해주세요", "workdoc_unnamed": "이름이 없는 워크문서", @@ -5879,9 +6055,11 @@ "workdoc_unsave_ok": "변경 사항을 취소", "workdoc_unsave_title": "WorkDoc이 저장되지 않았습니다.", "workdoc_upload_failed": "업로드 실패", + "workdoc_video_max_size": "동영상 크기는 ${size}을(를) 초과할 수 없습니다.", "workdoc_ws_connected": "연결됨", "workdoc_ws_connecting": "연결 중...", "workdoc_ws_disconnected": "연결이 끊김", + "workdoc_ws_reconnecting": "다시 연결하는 중...", "workflow_execute_failed_notify": " 에서 실행하지 못했습니다. . 문제를 해결하려면 실행 기록을 검토하세요. 도움이 필요하시면 고객 서비스 팀에 문의해 주세요.", "workspace_data": "공간 데이터", "workspace_files": "워크벤치 데이터", diff --git a/packages/datasheet/public/file/langs/strings.ru-RU.json b/packages/datasheet/public/file/langs/strings.ru-RU.json index 7582546f60..69f476c5fd 100644 --- a/packages/datasheet/public/file/langs/strings.ru-RU.json +++ b/packages/datasheet/public/file/langs/strings.ru-RU.json @@ -146,6 +146,15 @@ "agreed": "Утвержденные", "ai_advanced_mode_desc": "расширенный режим позволяет пользователям настраивать подсказки, обеспечивая больший контроль за поведением и ответами агента ИИ.", "ai_advanced_mode_title": "Расширенный режим", + "ai_agent_anonymous": "Анонимный${ID}", + "ai_agent_conversation_continue_not_supported": "Продолжение предыдущего разговора в настоящее время не поддерживается.", + "ai_agent_conversation_list": "Список разговоров", + "ai_agent_conversation_log": "Журнал разговоров", + "ai_agent_conversation_title": "Название беседы", + "ai_agent_feedback": "Обратная связь", + "ai_agent_historical_message": "Вышеупомянутое историческое сообщение", + "ai_agent_history": "История", + "ai_agent_message_consumed": "Сообщение использовано", "ai_api_curl_template": "## Create chat completions\n\n```bash\n\ncurl -X POST \"{{apiBase}}/fusion/v1/ai/{{aiId}}/chat/completions\" \\n -H \"Content-Type: application/json\" \\n -H \"Authorization: Bearer {{token}}\" \\n -d '{\n \"model\": \"gpt-3.5-turbo\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"You are a helpful assistant.\"\n },\n {\n \"role\": \"user\",\n \"content\": \"Hello!\"\n }\n ]\n }'\n\n```\n\n## Returned data example\n\n```json\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", "ai_api_footer_desc": "встраивайте агент ИИ на свой сайт? узнать больше", "ai_api_javascript_template": "## Initialize SDK [![github]({{ githubIcon }})](https://github.com/openai/openai-node)\nAITable's chat completion API is compatible with OpenAI's Node.js SDK. You can use our service with the same SDK by simply changing the configuration as follows:\n\n\n```javascript\nconst { Configuration, OpenAIApi } = require(\"openai\");\nconst configuration = new Configuration({\n apiKey: \"{{token}}\",\n basePath: \"{{apiBase}}/fusion/v1/ai/{{aiId}}\"\n});\n```\n\n## Create chat completions\n\n```javascript\nconst openai = new OpenAIApi(configuration);\nconst chatCompletion = await openai.createChatCompletion({\n model: \"gpt-3.5-turbo\",\n messages: [{role: \"user\", content: \"Hello world\"}],\n});\n```\n\n## Returned data example\n\n```javascript\n\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", @@ -161,6 +170,9 @@ "ai_chat_unit": "игумен (ы)", "ai_close_setting_tip_content": "Вы внесли изменения. Ты хочешь их выбросить?", "ai_close_setting_tip_title": "tip", + "ai_copilot_generate_response": "Генерация ответа для вас...", + "ai_copilot_processs": "Обработка, подождите...", + "ai_copilot_start_process_request": "Начало обработки вашего запроса...", "ai_create_guide_btn_text": "Выберите таблицу данных", "ai_create_guide_content": "как агент ИИ, я могу ответить на ваши вопросы, основываясь на знаниях, которые я узнал. прежде чем начать разговор, пожалуйста, выберите набор данных в качестве базы знаний, и я прочитаю все данные в нем для обучения.", "ai_credit_cost_chart_title": "стоимость кредита", @@ -629,7 +641,7 @@ "apps_support": "Поддержка всех клиентов платформы", "archive_delete_record": "Удалить архивированные записи", "archive_delete_record_title": "Удалить запись", - "archive_notice": "

Вы пытаетесь заархивировать определенные записи. Архивирование записей приведет к следующим изменениям:

1. Все двусторонние ссылки для этой записи будут отменены.

2. Редактирование не поддерживается.

3. Такие функции, как напоминание о дате и запись подписки, не поддерживаются.

4. Больше не участвуйте в вычислении справочных, формул и других полей.

Вы уверены что хотите продолжить? (Вы можете разархивировать в «Архивном ящике» в расширенном режиме)

", + "archive_notice": "

Вы пытаетесь заархивировать определенные записи. Архивирование записей приведет к следующим изменениям:

1. Редактирование не поддерживается.

2. Такие функции, как напоминание о дате и запись подписки, не поддерживаются.

3. Больше не участвуйте в вычислении справочных, формул и других полей.

Вы уверены что хотите продолжить? (Вы можете разархивировать в «Архивном ящике» в расширенном режиме)

", "archive_record_in_activity": "архивная копия", "archive_record_in_menu": "Архив", "archive_record_success": "Успешное архивирование", @@ -689,6 +701,8 @@ "audit_add_field_role_detail": "В таблице \"\" добавьте [] роль как [] для поля [] ", "audit_add_node_role": "Добавить права доступа к файлу", "audit_add_node_role_detail": "Добавить права доступа к файлу,установить「${unitNames}」на「${role}」of 「${currentNodeName}」", + "audit_add_node_role_detail_end": "to「${role}", + "audit_add_node_role_detail_start": "Add file node permission,set「${unitNames}」", "audit_admin_permission_change_event": "Изменение прав администратора", "audit_create_template": "Создать шаблон", "audit_create_template_detail": "Создать шаблон", @@ -697,20 +711,30 @@ "audit_delete_field_role_detail": "Ревизия", "audit_delete_node_role": "Удалить права файла", "audit_delete_node_role_detail": "Удалить права доступа к файлу,удалить「${unitNames}」`s 「${role}」роль 「${currentNodeName}」", + "audit_delete_node_role_detail_end": "at 「${role}」role", + "audit_delete_node_role_detail_start": "Delete file node permission,delete「${unitNames}」from", "audit_delete_template": "Удалить шаблон", "audit_delete_template_detail": "Удалить шаблон", "audit_disable_field_role": "Отключить права поля", "audit_disable_field_role_detail": "Ревизия", "audit_disable_node_role": "Отключить права доступа к файлу", "audit_disable_node_role_detail": "Отключить разрешение ${nodeType} 「${currentNodeName}」 `", + "audit_disable_node_role_detail_end": "`s permission", + "audit_disable_node_role_detail_start": "Disable ${nodeType}", "audit_disable_node_share": "Закрыть общедоступную ссылку на файл", "audit_disable_node_share_detail": "Закройте общедоступную ссылку ${nodeType} 「${currentNodeName}」", + "audit_disable_node_share_detail_end": "public link", + "audit_disable_node_share_detail_start": "Close ${nodeType}", "audit_enable_field_role": "Права доступа к полям", "audit_enable_field_role_detail": "Ревизия", "audit_enable_node_role": "Включить права доступа к файлу", "audit_enable_node_role_detail": "Включить разрешение ${nodeType} 「${currentNodeName}」 `", + "audit_enable_node_role_detail_end": "`s permission", + "audit_enable_node_role_detail_start": "Enable ${nodeType}", "audit_enable_node_share": "Открыть общедоступную ссылку на файл", "audit_enable_node_share_detail": "Открыть общедоступную ссылку ${nodeType} 「${currentNodeName}」", + "audit_enable_node_share_detail_end": "public link", + "audit_enable_node_share_detail_start": "Open ${nodeType}", "audit_login_event": "Событие регистрации", "audit_logout_event": "Английский язык", "audit_organization_change_event": "Изменилась организационная структура контактных лиц", @@ -731,18 +755,25 @@ "audit_space_invite_user_detail": "Ревизия", "audit_space_node_copy": "Повторить файл", "audit_space_node_copy_detail": "Дублируйте ${nodeType} 「${sourceNodeName}」, имя нового файла 「${currentNodeName}」", + "audit_space_node_copy_detail_start": "Duplicate ${nodeType} 「${sourceNodeName}」, the new file node's name is", "audit_space_node_create": "Создать файл", "audit_space_node_create_detail": "Создайте ${nodeType} с именем 「${currentNodeName}」", + "audit_space_node_create_detail_start": "Create a ${nodeType} named", "audit_space_node_delete": "Удалить файл", "audit_space_node_delete_detail": "Удалить ${nodeType} с именем 「${currentNodeName}」", + "audit_space_node_delete_detail_start": "Delete ${nodeType} named", "audit_space_node_export": "Экспорт таблиц данных", "audit_space_node_export_detail": "Участник ${member_name} экспортировал таблицу ${node_name}", "audit_space_node_import": "Импорт файлов", "audit_space_node_import_detail": "Импортируйте файл с именем 「${nodeName}」", + "audit_space_node_import_detail_start": "Import a file node named", "audit_space_node_move": "Переместить файл", "audit_space_node_move_detail": "Переместите ${nodeType} 「${currentNodeName}」 в папку 「${parentName}」", + "audit_space_node_move_detail_end": "to the folder「${parentName}」", + "audit_space_node_move_detail_start": "Move ${nodeType}", "audit_space_node_rename": "Переименовать файл", "audit_space_node_rename_detail": "Переименуйте ${nodeType} 「${oldNodeName}」в 「${nodeName}」", + "audit_space_node_rename_detail_start": "Rename ${nodeType} 「${oldNodeName}」to", "audit_space_node_sort": "Ревизия", "audit_space_node_sort_detail": "Ревизия", "audit_space_node_update_cover": "Ревизия", @@ -757,17 +788,24 @@ "audit_space_rubbish_node_delete_detail": "Ревизия", "audit_space_rubbish_node_recover": "Восстановление файла", "audit_space_rubbish_node_recover_detail": "Восстановить ${nodeType} 「${currentNodeName}」 из корзины", + "audit_space_rubbish_node_recover_detail_end": "from the trash", + "audit_space_rubbish_node_recover_detail_start": "Restore ${nodeType}", "audit_space_template_event": "Изменение шаблона", "audit_space_update_logo": "Ревизия", "audit_space_update_logo_detail": "Ревизия", "audit_store_share_node": "Сохранить общий файл", "audit_store_share_node_detail": "Восстановите ${nodeType} в пространстве, имя 「${nodeName}」", + "audit_store_share_node_detail_start": "Restore ${nodeType} to the space, name is", "audit_update_field_role": "Ревизия", "audit_update_field_role_detail": "Ревизия", "audit_update_node_role": "Изменить права доступа к файлу", "audit_update_node_role_detail": "Изменить права доступа к файлу,изменить роль「${unitNames}」 на「${role}」of 「${currentNodeName}」", + "audit_update_node_role_detail_end": "to「${role}」role", + "audit_update_node_role_detail_start": "Modify file node permission,modify「${unitNames}」from", "audit_update_node_share_setting": "Изменить параметры публичных ссылок на файлы", "audit_update_node_share_setting_detail": "Изменить общедоступную ссылку ${nodeType} 「${currentNodeName}」", + "audit_update_node_share_setting_detail_end": "public link settings", + "audit_update_node_share_setting_detail_start": "Modify ${nodeType}", "audit_user_login": "Регистрация пользователей", "audit_user_login_detail": "Ревизия", "audit_user_logout": "Списание пользователей", @@ -809,6 +847,7 @@ "automation_enabled_return_via_related_files": "Автоматизация включена. Пожалуйста, повторно введите исходную таблицу через «Связанные файлы», чтобы использовать новую кнопку.", "automation_field": "положение в области прав человека", "automation_import_variables_from_pre_tep": "Получить данные с предварительного шага", + "automation_is_not_yet_enabled": "Автоматизация еще не включена, включите ее и повторите попытку.", "automation_last_edited_by": "Последний раз редактировалось", "automation_last_edited_time": "Время последнего редактирования", "automation_manager_label": "Может выполнять все действия по автоматике", @@ -834,6 +873,7 @@ "automation_runs_this_month": "Работает в этом месяце", "automation_stay_tuned": "Следите за обновлениями", "automation_success": "Успех", + "automation_tips": "Поле кнопки настроено неправильно. Проверьте и повторите попытку.", "automation_updater_label": "Можно просмотреть историю запуска автоматизации.", "automation_variabel_empty": "Нет данных, которые можно было бы использовать на предварительном этапе. Измените настройки и повторите попытку.", "automation_variable_datasheet": "Получить данные из ${NODE_NAME}", @@ -869,6 +909,7 @@ "bermuda": "Бермудскиеострова", "bhutan": "Бутан", "billing_over_limit_tip_common": "Использование пространства превысило лимит, и после обновления вы сможете получить больший объем.", + "billing_over_limit_tip_forbidden": "Срок действия пробной версии или подписки истек. Пожалуйста, свяжитесь с продавцом-консультантом для продления.", "billing_over_limit_tip_widget": "Количество установок виджетов превысило лимит, и вы можете обновить их, чтобы увеличить использование.", "billing_period": "Расчетный период: ${period}", "billing_subscription_warning": "Функциональный опыт", @@ -928,10 +969,19 @@ "button_text": "Текст кнопки", "button_text_click_start": "Нажмите, чтобы начать", "button_type": "Тип кнопки", + "by_at": "в", + "by_days": "Дни", + "by_every": "каждый", "by_field_id": "Использовать идентификатор поля", + "by_hours": "Часы", + "by_in": "в", + "by_min": "минута(ы)", + "by_months": "Месяцы", + "by_on": "на", "by_the_day": "По дням", "by_the_month": "Ежемесячный журнал", "by_the_year": "Ежегодно", + "by_weeks": "Недели", "calendar_add_date_time_field": "Создать поле даты", "calendar_color_more": "Больше цветов", "calendar_const_detail_weeks": "[\"понедельник\",\"вторник\",\"среда\",\"четверг\",\"пятница\",\"суббота\",\"воскресенье\"]", @@ -995,6 +1045,14 @@ "cannot_activate_space_by_space_limit": "Невозможно активировать границы пространства", "cannot_join_space": "Вы не можете присоединиться к новой космической станции, потому что вы превысили максимальную квоту на 10 космических станций.", "cannot_switch_field_permission": "Установите права поля не выше прав файла.", + "capacity_file_detail_desc": "The total number of file nodes within the Space is calculated by adding the file nodes from the Team to the file nodes created by each member in their Private. Not enough capacity?", + "capacity_file_detail_title": "File Capacity", + "capacity_file_member": "Member", + "capacity_file_member_private_node_count": "Private", + "capacity_file_member_private_percent": "Percent", + "capacity_file_member_team": "Team", + "capacity_file_member_team_node_count": "Team", + "capacity_file_upgrade": "Click to upgrade your Space", "capacity_from_official_gift": "Официальный подарок.", "capacity_from_participation": "По приглашению ${user} присоединиться к пространству", "capacity_from_purchase": "По покупательной способности", @@ -1031,6 +1089,8 @@ "catalog": "Искатель", "catalog_add_from_template_btn_title": "Добавить из шаблона", "catalog_empty_tips": "Сейчас рабочая зона пуста. Начать создавать файлы с помощью шаблонов.", + "catalog_private": "Private", + "catalog_team": "Team", "category_blank": "[Пробел]", "catering": "Питание", "cayman_islands": "Каймановы острова", @@ -1099,6 +1159,7 @@ "choose_type_of_vika_field": "Выберите тип поля", "choose_your_own_space": "(Поддерживается только сохранение в вашем собственном пространстве в качестве создателя)", "chose_new_primary_admin_button": "Распределение", + "chunk_stopping_title": "Stopping", "claim_special_offer": "Подайте заявку на это специальное предложение!", "clear": "Очистить", "clear_all_fields": "Очистить все", @@ -1229,6 +1290,7 @@ "confirm_del_current_team": "Вы уверены, что хотите удалить команду?", "confirm_delete": "Подтвердить и удалить", "confirm_delete_node_name_as": "Вы уверены, что хотите удалить \"${nodeNameDiv}\"?", + "confirm_delete_private_node_name_as": "Are you sure you want to delete \"${nodeNameDiv}\"? The file will be deleted from the Space and the trash.", "confirm_delete_space_btn": "Подтвердить и удалить пространство", "confirm_exit": "Подтверждение выхода", "confirm_exit_space_with_name": "Подтвердите выход из пространства \"${spaceNameDiv}\"", @@ -1266,6 +1328,14 @@ "convert": "Преобразование", "convert_tip": "Эта операция может удалить данные из некоторых ячеек. В случае возникновения каких - либо непредвиденных обстоятельств вы можете отменить операцию.", "cook_islands": "Острова Кука", + "copilot_auto_agent_desc": "Не знаете, какой агент выбрать? Попробуйте Автоагент.", + "copilot_auto_agent_name": "Авто Агент", + "copilot_data_agent_desc": "Генерация анализа данных/визуализаций на основе ваших взглядов.", + "copilot_data_agent_name": "Агент данных", + "copilot_data_agent_policy": "Общаясь с Copilot, вы соглашаетесь с политикой пользовательского соглашения.", + "copilot_data_agent_policy_button": "Политика", + "copilot_help_agent_desc": "Спросите что угодно о документах центра помощи AITable.", + "copilot_help_agent_name": "Получить центр помощи", "copy": "Копирование", "copy_automation_url": "Копировать URL", "copy_card_link": "Копировать URL записи", @@ -1310,6 +1380,7 @@ "create_mirror_guide_content": "Функция зеркала имеет возможность скрывать определенные данные. Вы можете установить «условия фильтрации» и «скрытые поля» в исходном представлении таблицы данных, чтобы контролировать, какие записи и поля отображаются в зеркале.\n
\n
\nПри использовании в сочетании с функцией «блокировки просмотра» она может помешать другим пользователям вносить изменения.\n
\n
\nКроме того, вы можете перейти в «Исходная таблица> Скрытые поля», чтобы изменить конфигурацию «Показать все поля в зеркалах».", "create_mirror_guide_title": "Зеркало скрывает некоторые записи и поля", "create_new_button_field": "Создайте новое поле столбца кнопки", + "create_private_node_tip": "Personal or temporary draft documents can be created here ${link}", "create_public_invitation_link": "Создать ссылку на открытое приглашение", "create_space_sub_title": "Эй, пожалуйста, назовите свое общее пространство.", "create_team_fail": "Ошибка создания команды", @@ -1373,10 +1444,12 @@ "custom_enterprise": "Настройка корпоративного пространства для вас", "custom_function_development": "Разработка пользовательских функций", "custom_grade_desc": "Профессиональные услуги по развертыванию агентов, частной установке, поддержке и настройке", + "custom_page_setting_title": "Add a custom page", "custom_picture": "Пользовательские изображения", "custom_style": "Стиль", "custom_upload": "Настройка загрузки", "custom_upload_tip": "Рекомендуется использовать изображения размером с квадрат 1: 1 для лучшего визуального опыта", + "custome_page_title": "Custom Web", "cut_cell_data": "Вырезать ячейки", "cyprus": "Кипр", "czech": "Чешский", @@ -1428,6 +1501,7 @@ "default": "Нарушение обязательств", "default_create_ai_chat_bot": "новый агент ИИ", "default_create_automation": "Новая автоматизация", + "default_create_custom_page": "Новая пользовательская страница", "default_create_dashboard": "Новые приборные панели", "default_create_datasheet": "Новая таблица данных", "default_create_file": "Новый файл", @@ -1449,6 +1523,7 @@ "del_invitation_link": "Удалить ссылку приглашения", "del_invitation_link_desc": "После удаления ссылка будет недействительной", "del_space_now": "Удалить пространство навсегда", + "del_space_now_confirm_tip": "For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "del_space_now_tip": "Невозможно восстановить пространство после удаления. Все документы и приложения будут удалены.", "del_space_res_tip": "Удалить пространство", "del_team_success": "Удалить команду успешно", @@ -1644,6 +1719,62 @@ "embed_error_page_help": "Узнать больше", "embed_fail_og_description_content": "Эта встроенная общедоступная ссылка отключена и временно недоступна", "embed_failed": "Встроенные ссылки недоступны,", + "embed_link_bilibili": "билибили", + "embed_link_bilibili_desc": "Вставив видеоролики bilibili, вы сможете просматривать обучающие материалы и руководства или просматривать домашнюю страницу канала в Vika.", + "embed_link_bilibili_link_text": "Как вставить видео билибили", + "embed_link_bilibili_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-bilibili-video", + "embed_link_default": "Что-либо", + "embed_link_default_desc": "Вставьте ссылку для просмотра любого веб-сайта.", + "embed_link_default_link_text": "Узнать больше", + "embed_link_default_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_link_figma": "Figma", + "embed_link_figma_desc": "Встраивая файлы Figma, участники могут более удобно просматривать и редактировать черновики проектов, повышая эффективность совместной работы.", + "embed_link_figma_link_text": "Как встроить файлы Figma", + "embed_link_figma_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-figma-file", + "embed_link_google_docs": "Docs", + "embed_link_google_docs_desc": "Встраивая Google Docs, вы можете редактировать и просматривать документы в AITable, что облегчает совместную работу команды.", + "embed_link_google_docs_link_text": "Как встроить Google Документы", + "embed_link_google_docs_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-docs-file", + "embed_link_google_sheets": "Sheets", + "embed_link_google_sheets_desc": "Встраивая Google Таблицы, вы можете редактировать и просматривать таблицы в AITable, чтобы облегчить совместную работу команды.", + "embed_link_google_sheets_link_text": "Как встроить Google Таблицы", + "embed_link_google_sheets_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-sheets-file", + "embed_link_jishi_design": "JSдизайн", + "embed_link_jishi_design_desc": "Встраивая файлы JSdesign, участники могут более удобно просматривать и редактировать черновики проектов, повышая эффективность совместной работы.", + "embed_link_jishi_design_link_text": "Как встроить файлы JSdesign", + "embed_link_jishi_design_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-js-design-file", + "embed_link_tencent_docs": "Документы Tencent", + "embed_link_tencent_docs_desc": "Встраивая документы Tencent, вы можете редактировать и просматривать документы Tencent в Vika, чтобы повысить эффективность совместной работы.", + "embed_link_tencent_docs_link_text": "Как встроить документы Tencent", + "embed_link_tencent_docs_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-tencent-docs", + "embed_link_wps": "WPS", + "embed_link_wps_desc": "Встраивая файлы WPS, вы можете редактировать и просматривать документы, таблицы и формы WPS в Vika, чтобы повысить эффективность совместной работы.", + "embed_link_wps_link_text": "Как встроить файлы WPS", + "embed_link_wps_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-wps-file", + "embed_link_youtube": "YouTube", + "embed_link_youtube_desc": "Встраивая видео YouTube, вы можете просматривать учебные пособия и руководства или просматривать домашнюю страницу канала в AITable.", + "embed_link_youtube_link_text": "Как встроить видео с YouTube", + "embed_link_youtube_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-youtube-video", + "embed_page": "Пользовательская страница", + "embed_page_add_url": "Добавить URL", + "embed_page_doc_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_page_function_desc": "Добавляйте веб-страницы в ${edition} для быстрого доступа к документам, видео и т. д. сторонних веб-сайтов. Вы можете добавить рекомендуемые ссылки на веб-сайты или любые пользовательские ссылки.", + "embed_page_node_permission_editor": "На основе «только обновление» также можно открыть общий доступ к файлу.", + "embed_page_node_permission_manager": "Может выполнять все действия с файлом", + "embed_page_node_permission_reader": "Можно просматривать содержимое пользовательской страницы и основную информацию о файле.", + "embed_page_node_permission_updater": "На основе «только для чтения» также можно изменить ссылку на пользовательскую страницу.", + "embed_page_setting_title": "Добавить пользовательскую страницу", + "embed_page_url_invalid": "Пожалуйста, введите правильный URL", + "embed_paste_link_bilibili_placeholder": "Вставьте ссылку на видео билибили", + "embed_paste_link_default_placeholder": "Вставьте URL-адрес", + "embed_paste_link_figma_placeholder": "Вставьте ссылку общего доступа к файлу Figma.", + "embed_paste_link_google_docs_placeholder": "Вставьте ссылку общего доступа к Документам Google.", + "embed_paste_link_google_sheets_placeholder": "Вставьте ссылку общего доступа к Google Таблицам.", + "embed_paste_link_jsdesign_placeholder": "Вставьте ссылку общего доступа к файлу JSdesign.", + "embed_paste_link_tencent_docs_placeholder": "Вставьте ссылку на общий доступ к документам Tencent.", + "embed_paste_link_wps_placeholder": "Вставьте ссылку общего доступа к файлу WPS.", + "embed_paste_link_youtube_placeholder": "Вставьте ссылку на видео YouTube", + "embed_success": "Добавить успешно", "emoji_activity": "Деятельность", "emoji_custom": "Обычаи", "emoji_flags": "Флаг", @@ -1750,6 +1881,11 @@ "estonia": "Эстония", "ethiopia": "Эфиопияworld. kgm", "event_planning": "Планирование мероприятий", + "every": "Каждый", + "every_day_at": "день (дни) в", + "every_hour_at": "час(а) в", + "every_month_at": "месяц(ы) на", + "every_week_at": "Каждую неделю по", "everyday_life": "Повседневная жизнь", "everyone_visible": "Для всех.", "exact_date": "Точная дата", @@ -1760,6 +1896,7 @@ "exchange": "Выкуп.", "exchange_code_times_tip": "Примечание: Код обмена можно использовать только один раз", "exclusive_consultant": "Эксклюзивный консультант V +", + "exclusive_limit_plan_desc": "Эксклюзивный ограниченный уровень", "exist_experience": "Выход из опыта", "exits_space": "Выход из пространства", "expand": "Расширение", @@ -1786,7 +1923,7 @@ "expired": "Срок действия", "export": "Проводится экспорт.", "export_brand_desc": "Техническая поддержка", - "export_current_preview_view_data": "", + "export_current_preview_view_data": "Export current preview view data", "export_gantt_button_tips": "Экспорт в файл.png", "export_gantt_chart": "Экспорт диаграммы Ганта", "export_to_excel": "Экспорт данных", @@ -2357,26 +2494,26 @@ "gantt_config_color_by_single_select_pleaseholder": "Выберите поле выбора", "gantt_config_color_help": "Как установить", "gantt_config_friday": "Пятница", - "gantt_config_friday_in_bar": "Пятница", + "gantt_config_friday_in_bar": "Пт", "gantt_config_friday_in_select": "Пятница", "gantt_config_monday": "Понедельник", - "gantt_config_monday_in_bar": "Понедельник", + "gantt_config_monday_in_bar": "Пн", "gantt_config_monday_in_select": "Понедельник", "gantt_config_only_count_workdays": "Продолжительность вычисляется только в рабочие дни.", "gantt_config_saturday": "Суббота", - "gantt_config_saturday_in_bar": "Суббота", + "gantt_config_saturday_in_bar": "Сб", "gantt_config_saturday_in_select": "Суббота", "gantt_config_sunday": "Воскресенье", - "gantt_config_sunday_in_bar": "Воскресенье", + "gantt_config_sunday_in_bar": "Вс", "gantt_config_sunday_in_select": "Воскресенье", "gantt_config_thursday": "Четверг", - "gantt_config_thursday_in_bar": "Университет Цинхуа", - "gantt_config_thursday_in_select": "Университет Цинхуа", + "gantt_config_thursday_in_bar": "Чт", + "gantt_config_thursday_in_select": "Четверг", "gantt_config_tuesday": "Вторник", - "gantt_config_tuesday_in_bar": "Вторник", + "gantt_config_tuesday_in_bar": "Вт", "gantt_config_tuesday_in_select": "Вторник", "gantt_config_wednesday": "Среда", - "gantt_config_wednesday_in_bar": "Среда", + "gantt_config_wednesday_in_bar": "Ср", "gantt_config_wednesday_in_select": "Среда", "gantt_config_weekdays_range": "с ${weekday} до ${weekday}", "gantt_config_workdays_a_week": "Пользовательский стандартный рабочий день", @@ -2458,6 +2595,7 @@ "gold_grade": "Цзинь", "gold_grade_desc": "Для групп со сложными бизнес - процессами", "gold_seat_200_desc": "Двести.", + "gold_seat_300_desc": "300", "golden_grade": "Цзинь", "got_it": "Понял.", "got_v_coins": "Награды 5 монет", @@ -2491,6 +2629,8 @@ "guests_per_space": "Гости в каждом пространстве", "guide_1": "啊这", "guide_2": "Изучение основных функций занимает всего несколько минут. С этого момента работа становится эффективнее!", + "guide_flow_modal_contact_sales": "Свяжитесь с отделом продаж", + "guide_flow_modal_get_started": "Начать", "guide_flow_of_catalog_step1": "Это рабочий каталог, в котором хранятся все папки и файлы Space.", "guide_flow_of_catalog_step2": "В рабочем каталоге вы можете создавать таблицы данных или папки по мере необходимости.", "guide_flow_of_click_add_view_step1": "В дополнение к некоторым основным видам, если у вас есть вложения в формате изображения, настоятельно рекомендуется создать вид альбома.", @@ -2669,6 +2809,7 @@ "intro_widget_tips": "Что такое виджеты?", "introduction": "Презентация", "invalid_action_sort_tip": "Как поле группирования, его сортировка уже установлена. Настройки текущего заказа не вступят в силу.", + "invalid_automation_configuration": "Неверная конфигурация автоматизации. Проверьте и повторите попытку.", "invalid_field_type": "Неверный тип поля", "invalid_option_sort_tip": "Как поле группирования, его сортировка уже установлена.", "invalid_redemption_code_entered": "Код обмена не действителен", @@ -2799,6 +2940,9 @@ "label_format_day_month_and_year_split_by_slash": "День / месяц / год", "label_format_month": "Месяц", "label_format_month_and_day_split_by_dash": "Год", + "label_format_month_day_year_split_by_dash": "Month-Day-Year", + "label_format_month_day_year_split_by_slash": "Month/Day/Year", + "label_format_month_day_year_two_digit_year_split_by_slash": "Month/Day/Year (Two-digit year)", "label_format_year": "Год", "label_format_year_and_month_split_by_dash": "Год", "label_format_year_month_and_day_split_by_dash": "Год", @@ -2877,6 +3021,7 @@ "lark_version_enterprise": "Бизнес - план Ларка", "lark_version_standard": "Стандартный план Ларка", "lark_versions_free": "Основные планы Ларка", + "last_day": "Последний день", "last_modified_by_select_modal_desc": "Если какое - либо поле, выбранное ниже, будет отредактировано, последний член редактора будет показан в поле последнего редактирования", "last_modified_time_select_modal_desc": "Если вы отредактировали любое поле, выбранное ниже, время последнего редактирования будет показано в поле времени последнего редактирования", "last_step": "Возвращение", @@ -3021,7 +3166,7 @@ "mail_invite_fail": "Почтовое приглашение успешно.", "mail_invite_success": "Почтовое приглашение успешно.", "main_admin_name": "Имя администратора", - "main_admin_page_desc": "Администраторы имеют полный доступ к пространствам, таким как диспетчеры гамет и передача права собственности на пространство", + "main_admin_page_desc": "Администратор имеет полный доступ к пространству, например, к управлению участниками и настройками пространства.", "main_contain": "Основные элементы", "malawi": "Малави", "malaysia": "Малайзия", @@ -3241,8 +3386,12 @@ "more_widget": "Больше гаджетов", "morocco": "Марокко", "move": "Переместить", + "move_datasheet_link_warn": "Cannot be moved to Team Area alone, because there is a two-way link from the current datasheet to another datasheet, it is recommended to put them in a folder and then move them", "move_favorite_node_fail": "Ошибка перемещения узла. Система автоматически обновляет список.", + "move_folder_link_warn": "Cannot be moved to Team Area because the files in the current folder are linked to files outside the folder (may be two-way links or linked by forms, etc.) We recommend that they be placed in a folder before moving", "move_node_modal_content": "После перемещения на видимость файла может повлиять родительская папка.", + "move_other_link_no_permission": "Unable to move to the corresponding folder because you do not have administrative rights to the folder", + "move_other_link_warn": "It is not allowed to move ${node type} to Team Area alone, because it connects to the datasheet of Private Area, it is recommended to put them in a folder before moving them", "move_to": "Перейти на", "move_to_error_equal_parent": "Файл находится в текущей папке. Выберите другую папку", "move_to_modal_title": "Переместите [${name}] в", @@ -3273,7 +3422,9 @@ "new_a_line": "Клавиша Shift + Enter: Переключение строк", "new_automation": "Новая автоматизация", "new_caledonia": "Новая Каледония", + "new_custom_page": "New custom page", "new_datasheet": "Новая таблица данных", + "new_ebmed_page": "Новая пользовательская страница", "new_folder": "Создать папку", "new_folder_btn_title": "Папка", "new_folder_tooltip": "Создать папку", @@ -3439,7 +3590,7 @@ "nvc_start_text": "Перетащите диаграмму вправо", "nvc_yes_text": "Подтвержденные", "obtain_verification_code": "Код проверки не получен или истек", - "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrzw0miJVmSkJ7eBBa9k/fomx5qPX0JGPFvfEEP\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", + "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrCvbFC53xc3kl00B4Pg\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", "offical_website_nav_data": "[{\n \"name\": \"产品\",\n \"href\": \"/login\",\n \"children\": [\n {\n \"name\": \"vika维格表 Overview\",\n \"href\": \"/login/\"\n },\n {\n \"name\": \"应用连接 Integration\",\n \"href\": \"/connections/\"\n },\n {\n \"name\": \"客户端(Beta) Download\",\n \"href\": \"/download/\"\n }\n ]\n}, {\n \"name\": \"解决方案\",\n \"href\": \"/\",\n \"children\": [{\n \"name\": \"PMO项目群管理\",\n \"href\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"href\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"href\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"href\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"href\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"href\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"href\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"href\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"href\": \"/shop/\"\n }, {\n \"name\": \"更多解决方案 >\",\n \"href\": \"/solutions/\"\n }]\n}, {\n \"name\": \"模板/案例\",\n \"href\": \"/template\",\n \"children\": [\n {\n \"name\": \"模板中心 Tempaltes\",\n \"href\": \"/template\"\n },\n {\n \"name\": \"客户案例 Customers\",\n \"href\": \"/cases/\"\n }\n ]\n},\n {\n \"name\": \"首页\",\n \"href\": \"/?home=1\"\n },\n {\n \"name\": \"学习资源\",\n \"href\": \"https://edu.vika.cn/index\",\n \"children\": [\n {\n \"name\": \"快速入门 Tutorials\",\n \"href\": \"https://help.vika.cn/docs/guide/tutorial\"\n },\n {\n \"name\": \"产品手册 Manual\",\n \"href\": \"https://help.vika.cn/docs/guide/manual\"\n },\n {\n \"name\": \"维格课堂 Vika Education\",\n \"href\": \"https://edu.vika.cn/\"\n },\n {\n \"name\": \"维格社区 Vika BBS\",\n \"href\": \"https://bbs.vika.cn/\"\n },\n {\n \"name\": \"第三方连接 Integration\",\n \"href\": \"https://help.vika.cn/docs/guide/connection\"\n },\n {\n \"name\": \"开发者中心 Developer Center\",\n \"href\": \"/developers/\"\n },\n {\n \"name\": \"常见问题 FAQ\",\n \"href\": \"https://help.vika.cn/docs/guide/questions\"\n }\n ]\n }]", "office_preview": "Предварительный просмотр файлов Office", "office_preview_app_desc": "

Smooth online preview of office files on datasheet, allowing you to view common office files such as Excel, Word, PPT, etc. on your desktop or mobile anywhere, anytime

\n\n
    \n
  • Online preview of .doc, .docx, .xls, .xlsx, .ppt, .pptx, and .pdf formatted office files
  • \n
  • Desktop and mobile both support file previews of the above formats
  • \n
\n\n

Additional notes:

\n
    \n
  • This feature is powered by \"Yoncentric Cloud Conversion\" and officially integrated
  • \n
  • Click the \"Enable\" button below to enable this integration and agree that \"Yoncentric Cloud Conversion\" reads the office files you want to preview
  • \n
  • If you no longer need the office files preview feature, the space admin can disable it on this page
  • \n
", @@ -3479,6 +3630,7 @@ "open_auto_save_success": "Автосохранение просмотра успешно открыто", "open_auto_save_warn_content": "Все изменения в этом представлении будут сохранены автоматически и синхронизированы с другими членами.", "open_auto_save_warn_title": "Включить автоматическое сохранение", + "open_automation_time_arrival": "https://aitable.ai/contact-sales-open-source", "open_failed": "Ошибка открытия", "open_in_new_tab": "Открыть в новой вкладке", "open_invite_after_operate": "После открытия все участники могут пригласить новых членов из панели контактов", @@ -3625,6 +3777,8 @@ "payment_record": "Учет платежей", "payment_reminder": "Подсказка к оплате", "payment_reminder_content": "Новый план, который вы выбрали, является более франшизой, чем сумма, подлежащая оплате. Рекомендуется выбрать новый план с большей продолжительностью. Если вы подтвердите это, избыточная сумма не будет возвращена. ${action}, если сомневаетесь", + "payment_reminder_modal_content": "Вы можете попробовать расширенную версию, чтобы получить больше файловых узлов, корпоративных разрешений, емкости вложений, объема данных, искусственного интеллекта и других расширенных функций и привилегий.", + "payment_reminder_modal_title": "Вы сейчас используете бесплатную версию", "pending_invite": "Повесить приглашение", "people": "Членский состав", "per_person_per_year": "Каждый год", @@ -3794,7 +3948,7 @@ "player_step_ui_config_168": "{\n\"templateKey\":\"createMirrorTip\"\n}", "player_step_ui_config_169": "{ \"headerImg\": \"https://s4.vika.cn/space/2023/04/04/bcf0695cf35840e6b85e032a8e5ea0a1\", \"readMoreUrl\": \"https://help.vika.cn/changelog/23-04-10- обновления\", \"дети\": \"

🚀 Введение новых функций

\\п
  • Запущен новый тип поля «Каскад», упрощающий выбор из иерархии параметров в формах.
  • Выпущен виджет «Скрипт», меньше кода для большей настройки
  • Запустите автоматизацию для отправки электронных писем и быстрого получения уведомлений.
  • Запустите автоматизацию, чтобы отправить сообщение в Slack и вовремя проинформировать свою команду.
  • Исследование искусственного интеллекта: выпущен виджет «GPT Content Generator»
\" }", "player_step_ui_config_17": "{\n \"element\": \"#TEMPLATE_CENTER_USE_TEMPLATE_BTN>button\", \n\"placement\": \"rightBottom\",\n\"offsetY\": 20,\n \"title\": \"How to use a template\", \n\"description\": \"Click the button on the left to use the template\", \"children\":\"\" \n}", - "player_step_ui_config_176": "{\"title\":\"Введение AI-агент\",\"video\":\"https://www.youtube.com/embed/cjds1r_roG8?si=irKUpMhwDlOEb8Hc\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", + "player_step_ui_config_176": "{\"title\":\"AITable.ai DEMO\",\"video\":\"https://www.youtube.com/embed/kGxMyEEo3OU\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", "player_step_ui_config_18": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select>.ant-select-selector\", \n\"placement\": \"bottomLeft\",\n \"title\": \"How to use a template\", \n\"description\": \"Select where to put the template\", \"children\":\"\" \n}", "player_step_ui_config_19": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select .ant-select-selector\"\n}", "player_step_ui_config_2": "{\n \"config\": [\n {\n \"key\": 1,\n \"name\": \"answer1\",\n \"title\": \"What kind of issues are you looking forward to solved by vikadata?\",\n \"type\": \"checkbox\",\n \"answers\": [\n \"Work Planning\",\n \"Customer Service\",\n \"Project Management\",\n \"Sourcing Supply\",\n \"Content Production\",\n \"E-commerce operation\",\n \"Event Planning\",\n \"Human Resources\",\n \"Administration\",\n \"Financial Management\",\n \"Webcast\",\n \"Educational institutes Management\",\n \"Other\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 2,\n \"name\": \"answer2\",\n \"title\": \"Your job title is______\",\n \"type\": \"radio\",\n \"answers\": [\n \"General manager \",\n \"Project manager\",\n \"Product manager\",\n \"Designer\",\n \"R&D engineer\",\n \"Operator, editor\",\n \"Sales, customer service\",\n \"Human resource, administration \",\n \"Finance, accountant\",\n \"Lawyer, legal affairs\",\n \"Marketing\",\n \"Teacher\",\n \"Student\",\n \"Other\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 3,\n \"name\": \"answer3\",\n \"title\": \"What is the name of your company?\",\n \"type\": \"input\",\n \"submit\": false\n },\n {\n \"key\": 4,\n \"name\": \"answer4\",\n \"title\": \"Please leave your email address/ phone number/ Wechat account below so we can reach you in time when you need help.\",\n \"type\": \"input\",\n \"submit\": true\n },\n {\n \"key\": 5,\n \"title\": \"Thank you for filling out the form, you can add our customer service in case of need\",\n \"platform\": {\n \"website\": \"https://s4.vika.cn/space/2023/03/02/b34e3205a9154463be16f497524f1327\",\n \"dingtalk\": \"https://s4.vika.cn/space/2023/03/02/4b16cef6602a4586a21d6346bf25d300\",\n \"wecom\": \"https://s4.vika.cn/space/2023/03/02/60119b1b69b64aa887bd1be6a2928bec\",\n \"feishu\": \"https://u.vika.cn/z9ygm\"\n },\n \"type\": \"contactUs\",\n \"next\": true\n }\n ]\n}\n", @@ -3824,13 +3978,13 @@ "player_step_ui_config_41": "", "player_step_ui_config_42": "{\n \"element\": \"#DATASHEET_FORM_LIST_PANEL\", \n\"placement\": \"leftTop\",\n \"title\": \"Form\", \n\"description\": \"You can quickly create a form from the current view. The number and order of the fields in the form is consistent with the view.\", \"children\":\"\" \n}", "player_step_ui_config_43": "{\n \"element\": \".style_navigation__1U5cR .style_help__1sXEA\", \n\"placement\": \"rightBottom\",\n \"title\": \"Tip\", \n\"offsetY\":5,\n\"description\": \"You can find your Vikaby assistant from the \"Help\" icon on the left\", \"children\":\"\" \n}", - "player_step_ui_config_44": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", + "player_step_ui_config_44": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", "player_step_ui_config_45": "", "player_step_ui_config_46": "", "player_step_ui_config_47": "{\n \"element\": \"#DATASHEET_WIDGET_BTN\",\n\"placement\": \"bottomRight\",\n \"title\": \"Widget\", \n\"description\": \"Want to use and view your data in a richer way? Try the widget!\", \"children\":\"\" \n}", "player_step_ui_config_48": "", "player_step_ui_config_49": "{\n \"element\": \".style_widgetPanelContainer__1l2ZV\",\n\"placement\": \"leftCenter\",\n \"title\": \"What is a widget\", \n\"description\": \"Vika widgets are an extended application of vikadata that features in richer data visualization, data transfer, data cleansing, and more. By installing widgets in the widget board, you can make work a lot easier.\", \"children\":\"\" \n}", - "player_step_ui_config_5": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", + "player_step_ui_config_5": "{\n\"title\":\"Vikadata's hierarchy\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}", "player_step_ui_config_50": "{\n \"element\": \".style_widgetModal__eXmdB\",\n\"placement\": \"leftTop\",\n \"title\": \"Widget Center\", \n\"description\": \"Officially recommended and custom widgets are published here. You can install any widget you want onto a dashboard or into a widget board of any datasheet.\", \"children\":\"\" \n}", "player_step_ui_config_51": "{\n \"element\": \".style_widgetModal__eXmdB .style_widgetItem__3Pl-1 button\",\n\"placement\": \"rightBottom\",\n \"title\": \"Install widget\", \n\"description\": \"Let's install this \"Chart\" widget\", \"children\":\"\" \n}", "player_step_ui_config_52": "", @@ -3927,6 +4081,7 @@ "preview_guide_click_to_restart": "Нажмите кнопку ниже для просмотра", "preview_guide_enable_it": "Нажмите кнопку ниже, чтобы открыть эту функцию", "preview_guide_open_office_preview": "Для предварительного просмотра этого файла откройте функцию \"Office Preview\"", + "preview_next_automation_execution_time": "Предварительный просмотр следующих 10 раз выполнения", "preview_not_support_video_codecs": "Просмотр только видео MP4 с видеокодеком H.264", "preview_revision": "Предварительный просмотр", "preview_see_more": "Хотите узнать больше о функции « Предварительный просмотр офисных документов»? Пожалуйста, нажмите здесь.", @@ -3962,6 +4117,7 @@ "privacy_protection": "\"Защита конфиденциальности\"", "private_cloud": "Частное облако", "private_external_person_only": "Только внешний персонал", + "private_help_link": "https://help.aitable.ai/docs/guide/team-and-private-area#private-area", "private_internal_person_only": "Только внутренний персонал", "private_product_point": "Приобретите свою платформу APITable одним щелчком мыши", "privatized_deployment": "Автохостинг", @@ -4032,13 +4188,15 @@ "reconciled_data": "Данные проверяются.", "record": "Запись", "record_activity_experience_tips": "Вы можете просматривать записи об активности за ${day} дней.", + "record_archived_data": "архивная запись", + "record_chunk_text": "${text} rows, please wait", "record_comment": "Только примечания", "record_comments": "Замечания", "record_fail_data": "Ошибка данных", "record_filter_tips": "Эта запись была просмотрена.", "record_functions": "Функция записи", "record_history": "Пересмотр только исторических записей", - "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-history", + "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-activity", "record_history_title": "История записей", "record_pre_filtered": "Эта запись была отфильтрована и будет скрыта при щелчке на внешней стороне записи", "record_pre_move": "После щелчка на внешней стороне записи запись будет перемещена в другое место", @@ -4478,6 +4636,12 @@ "scan_to_login": "Сканирование записей", "scan_to_login_by_method": "Отсканируйте ${method}, чтобы войти в официальный аккаунт", "scatter_chart": "Диаграмма распространения", + "schedule_day_tips": "Расчет цикла начинается отсчет с первого числа каждого месяца. Если предположить, что он повторяется каждые 10 дней, то он будет срабатывать 1, 11, 21 и 31 числа каждого месяца.", + "schedule_hour_tips": "Расчет цикла начинается в полночь (0:00) каждого дня. Если предположить, что оно повторяется каждые три часа, оно будет происходить в полночь (0:00), 3:00, 6:00, 9:00, полдень (12:00), 15:00, 18:00 и, наконец, с наступлением темноты (21:00) ежедневно.", + "schedule_start_day": "Начиная с 1-го числа месяца, каждый", + "schedule_start_month": "Начиная с января каждого года, каждый", + "schedule_type": "Тип расписания", + "schedule_year_tips": "Расчет цикла начинается отсчет с первого месяца каждого года. Если предположить, что интервал в первый день составляет 3 месяца, триггеры будут активироваться в полночь первого дня января, апреля, июля и октября каждого года.", "science_and_technology": "Наука и техника", "scroll_screen_down": "Прокрутить экран вниз", "scroll_screen_left": "Прокрутить экран влево", @@ -4491,6 +4655,7 @@ "search_folder_or_sheet": "Поиск файлов", "search_new_admin": "Поиск", "search_node_pleaseholder": "Поиск файлов (${shortcutKey})", + "search_node_tip": "Быстрый поиск (${shortcutKey})", "search_or_add": "Поиск или добавление опций", "search_role_placeholder": "Поиск ролей", "seats": "Места", @@ -4894,6 +5059,7 @@ "space_info": "Общий обзор", "space_info_del_confirm1": "Удаление этого общего пространства очистит следующие данные:", "space_info_del_confirm2": "Общее пространство будет полностью удалено через семь дней. До этого времени вы можете восстановить пространство.", + "space_info_del_confirm3": "3. For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "space_info_feishu_desc": "Вы используете стороннюю интеграцию. Чтобы удалить общее пространство, сначала отключите стороннюю интеграцию.", "space_info_feishu_label": "Интеграция", "space_join_apply": "Запрос на включение пространства \"a class =\" spaceName \"< / a >.", @@ -4980,6 +5146,7 @@ "start_onfiguration": "Настройка запуска", "start_time": "Время начала", "start_use": "Начало использования", + "starting_from_midnight": "Начиная с полуночи (12:00) каждый день, каждый", "startup": "Запуск", "startup_company_support_program": "Запуск программы поддержки", "stat_average": "Средний", @@ -5013,6 +5180,8 @@ "stay_tuned_for_more_features": "Пожалуйста, обратите внимание на дополнительные функции.", "steps_choose_reset_mode": "Выберите метод сброса", "steps_validate_identities": "Идентификация", + "stop_chunk_content": "Are you sure you want to stop the operation?", + "stop_chunk_title": "Stop", "stop_dingtalk_h5_modal_content": "Самостоятельное приложение снимет привязку из этого пространства. Пожалуйста, подтвердите.", "storage_per_seats": "", "storage_per_space": "Использование хранилища", @@ -5043,9 +5212,11 @@ "subscribe_credit_usage_over_limit": "количество кредитов в текущем пространстве превышает лимит, пожалуйста, обновите подписку.\n", "subscribe_demonstrate": "Запросить демонстрацию", "subscribe_disabled_seat": "Численность не должна быть ниже запланированной.", + "subscribe_grade_business": "Бизнес", "subscribe_grade_free": "Свободный", "subscribe_grade_plus": "А", "subscribe_grade_pro": "Согласен.", + "subscribe_grade_starter": "Стартер", "subscribe_label_tooltip": "Расширенные пространственные функции", "subscribe_new_choose_member": "Поддерживает до ${member_num} участников", "subscribe_new_choose_member_tips": "Этот план поддерживает 1~${member_num} участников для входа в пространство", @@ -5182,7 +5353,7 @@ "template_name_repetition_title": "\"${templateName}\" уже существует. Вы хотите заменить это?", "template_no_template": "Нет шаблонов", "template_not_found": "Не нашли нужный шаблон? Скажи нам.", - "template_recommend_title": "Горячий", + "template_recommend_title": "🌟 Hot", "template_type": "Образец", "terms_of_service": "< Условия обслуживания >", "terms_of_service_pure_string": "Условия предоставления услуг", @@ -5226,6 +5397,7 @@ "text_editor_tip_end": "\"Введите\" Конец редактирования", "text_functions": "Строчная функция", "thailand": "Таиланд", + "the_button_field_is_misconfigured": "Поле кнопки настроено неправильно. Проверьте и повторите попытку.", "the_current_automation_workflow_has_no_related_files_you_can_establish_a_link_by_adding_trigger_conditions_and_actions_on_the_left_side": "текущий рабочий процесс автоматизации не имеет соответствующих файлов. вы можете установить ссылку, добавив условия триггера и действия с левой стороны", "the_current_button_column_has_expired_please_reselect": "Срок действия текущего столбца кнопок истек, выберите еще раз.", "the_last_7_days": "Последние 7 дней", @@ -5328,6 +5500,7 @@ "timemachine_update_comment": "Обновлены комментарии", "times_per_month_unit": "Телефон / месяц", "times_unit": "Телефон", + "timing_rules": "Тайминг", "timor_leste": "Тимор - Лешти", "tip_del_success": "Вы можете восстановить свое общее пространство за 7 дней.", "tip_do_you_want_to_know_about_field_permission": "Хотите зашифровать данные поля? Права доступа к полю", @@ -5515,6 +5688,7 @@ "verify_account_title": "Проверка учетной записи", "verify_via_email": "Идентификация по электронной почте", "verify_via_phone": "Авторизация SMS", + "video": "видео", "video_not_support_play": "Текущий формат видео не поддерживает онлайн", "vietnam": "Вьетнам", "view": "Замечания", @@ -5863,7 +6037,8 @@ "workdoc_color_title": "Цвет шрифта", "workdoc_create": "Создать рабочий документ", "workdoc_expanded": "Развернуть оглавление", - "workdoc_image_max_10mb": "Размер изображения не может превышать 10 МБ.", + "workdoc_image_max_10mb": "нулевой", + "workdoc_image_max_size": "Размер изображения не может превышать ${size}", "workdoc_info": "Информация о документе", "workdoc_info_create_time": "Создан в", "workdoc_info_creator": "Сделано", @@ -5871,6 +6046,7 @@ "workdoc_info_last_modify_time": "Изменить время", "workdoc_link_placeholder": "Пожалуйста, введите ссылку", "workdoc_only_image": "Разрешено только изображение", + "workdoc_only_video": "Разрешено только видео", "workdoc_text_placeholder": "Введите \"/\" быстрый старт", "workdoc_title_placeholder": "Пожалуйста, введите название", "workdoc_unnamed": "Безымянный рабочий документ", @@ -5879,9 +6055,11 @@ "workdoc_unsave_ok": "Отменить изменения", "workdoc_unsave_title": "Рабочий документ не сохранен.", "workdoc_upload_failed": "Загрузка не удалась", + "workdoc_video_max_size": "Размер видео не может превышать ${size}", "workdoc_ws_connected": "Связанный", "workdoc_ws_connecting": "Подключение...", "workdoc_ws_disconnected": "Отключено", + "workdoc_ws_reconnecting": "Повторное подключение...", "workflow_execute_failed_notify": " не удалось выполнить в . Просмотрите историю выполнения, чтобы устранить проблему. Если вам нужна помощь, пожалуйста, свяжитесь с нашей службой поддержки клиентов.", "workspace_data": "Пространственные данные", "workspace_files": "Данные рабочего стола", diff --git a/packages/datasheet/public/file/langs/strings.zh-CN.json b/packages/datasheet/public/file/langs/strings.zh-CN.json index f8eb01d849..9694047b37 100644 --- a/packages/datasheet/public/file/langs/strings.zh-CN.json +++ b/packages/datasheet/public/file/langs/strings.zh-CN.json @@ -146,6 +146,15 @@ "agreed": "已同意", "ai_advanced_mode_desc": "高级模式允许用户自定义提示,从而更好地控制 AI 助手的行为和响应。", "ai_advanced_mode_title": "高级模式", + "ai_agent_anonymous": "匿名用户${ID}", + "ai_agent_conversation_continue_not_supported": "当前暂不支持继续之前的聊天记录会话", + "ai_agent_conversation_list": "会话列表", + "ai_agent_conversation_log": "会话日志", + "ai_agent_conversation_title": "会话标题", + "ai_agent_feedback": "反馈", + "ai_agent_historical_message": "以上是历史消息", + "ai_agent_history": "历史", + "ai_agent_message_consumed": "消耗的算力点", "ai_api_curl_template": "## Create chat completions\n\n```bash\n\ncurl -X POST \"{{apiBase}}/fusion/v1/ai/{{aiId}}/chat/completions\" \\\n -H \"Content-Type: application/json\" \\\n -H \"Authorization: Bearer {{token}}\" \\\n -d '{\n \"model\": \"gpt-3.5-turbo\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"You are a helpful assistant.\"\n },\n {\n \"role\": \"user\",\n \"content\": \"Hello!\"\n }\n ]\n }'\n\n```\n\n## Returned data example\n\n```json\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", "ai_api_footer_desc": "将 chatBot 嵌入您的网站?了解更多", "ai_api_javascript_template": "## Initialize SDK [![github]({{ githubIcon }})](https://github.com/openai/openai-node)\nAITable's chat completion API is compatible with OpenAI's Node.js SDK. You can use our service with the same SDK by simply changing the configuration as follows:\n\n\n```javascript\nconst { Configuration, OpenAIApi } = require(\"openai\");\nconst configuration = new Configuration({\n apiKey: \"{{token}}\",\n basePath: \"{{apiBase}}/fusion/v1/ai/{{aiId}}\"\n});\n```\n\n## Create chat completions\n\n```javascript\nconst openai = new OpenAIApi(configuration);\nconst chatCompletion = await openai.createChatCompletion({\n model: \"gpt-3.5-turbo\",\n messages: [{role: \"user\", content: \"Hello world\"}],\n});\n```\n\n## Returned data example\n\n```javascript\n\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", @@ -162,6 +171,9 @@ "ai_chat_unit": "AI 助手", "ai_close_setting_tip_content": "您所做的更改尚未保存,是否要放弃?", "ai_close_setting_tip_title": "未保存的更改", + "ai_copilot_generate_response": "为您生成答案...", + "ai_copilot_processs": "处理中,请稍候...", + "ai_copilot_start_process_request": "开始处理您的请求...", "ai_create_guide_btn_text": "选择表格", "ai_create_guide_content": "作为一个 AI 助手,我可以根据我学到的知识回答你的问题。在开始对话之前,请选择一个表格作为数据集,我会读取其中的所有数据进行学习。", "ai_credit_cost_chart_title": "算力点", @@ -329,7 +341,7 @@ "api_delete_error": "删除数据失败", "api_delete_error_foreign_datasheet_deleted": "删除记录失败,因为关联表已被删除", "api_embed_link_id_not_exist": "指定的嵌入链接不存在,请调整 linkId 后再试", - "api_embed_link_instance_limit": "抱歉, 暂时仅支持表格、仪表盘、表单类的节点创建嵌入链接", + "api_embed_link_instance_limit": "抱歉, 暂时仅支持表格、仪表盘、表单、镜像类的节点创建嵌入链接", "api_embed_link_limit": "创建的嵌入链接数量已达上限,单个维格表的嵌入链接数量不能超过{value}个", "api_enterprise_limit": "抱歉,此接口仅可在黄金级以上的空间站中调用", "api_example_request": "示例请求", @@ -545,6 +557,7 @@ "api_params_updatedby_can_not_operate": "修改人列的值由系统自动生成,不允许编辑", "api_params_views_max_count_error": "", "api_params_widget_package_id_error": "widgetPackageId 不能为空", + "api_params_workdoc_can_not_operate": "WorkDoc field can't be edited", "api_query_params_invalid_fields": "传入的 fields 不存在:{fields}", "api_query_params_view_id_not_exists": "查询的视图({viewId}) 不存在 ", "api_request_success": "成功", @@ -627,7 +640,7 @@ "apps_support": "全平台客户端支持", "archive_delete_record": "删除归档记录", "archive_delete_record_title": "删除记录", - "archive_notice": "

正在尝试对选定的记录进行归档,一旦记录被归档,将会发生以下变化:

1. 该记录的所有双向关联关系将被取消

2. 不支持通过任何方式进行编辑

3. 不支持日期提醒、关注记录等功能

4. 不再参与神奇引用、公式等字段的计算

确定要继续吗?(在高级能力里的归档箱中可以取消归档)

", + "archive_notice": "

正在尝试对选定的记录进行归档,一旦记录被归档,将会发生以下变化:

1. 不支持通过任何方式进行编辑

2. 不支持日期提醒、关注记录等功能

3. 不再参与神奇引用、公式等字段的计算

确定要继续吗?(在高级功能中的归档箱可以取消归档)

", "archive_record_in_activity": " 归档了这条记录", "archive_record_in_menu": "归档记录", "archive_record_success": "已归档记录", @@ -652,7 +665,7 @@ "assistant_activity_train_camp": "限时福利", "assistant_beginner_task": "新手任务", "assistant_beginner_task_1_what_is_datasheet": "什么是 APITable", - "assistant_beginner_task_2_quick_start": "一分钟快速入门", + "assistant_beginner_task_2_quick_start": "VIKA产品演示", "assistant_beginner_task_3_how_to_use_datasheet": "玩转一张维格表", "assistant_beginner_task_4_share_and_invite": "分享和邀请成员", "assistant_beginner_task_5_onboarding": "智能引导", @@ -686,7 +699,8 @@ "audit_add_field_role": "添加列权限", "audit_add_field_role_detail": "在\"\" 数据表 , 添加 [] 角色作为 [] 字段 [] ", "audit_add_node_role": "添加文件节点权限", - "audit_add_node_role_detail": "添加文件节点权限,将「${unitNames}」设置为「${currentNodeName}」的「${role}」角色", + "audit_add_node_role_detail_end": "的「${role}」角色", + "audit_add_node_role_detail_start": "添加文件节点权限,将「${unitNames}」设置为", "audit_admin_permission_change_event": "管理员权限变更", "audit_create_template": "创建模板", "audit_create_template_detail": "创建模板内容", @@ -694,21 +708,26 @@ "audit_delete_field_role": "删除列权限", "audit_delete_field_role_detail": "审计内容", "audit_delete_node_role": "删除文件节点权限", - "audit_delete_node_role_detail": "删除文件节点权限,将「${unitNames}」在「${currentNodeName}」的「${role}」角色删除", + "audit_delete_node_role_detail_end": "的「${role}」角色删除", + "audit_delete_node_role_detail_start": "删除文件节点权限,将「${unitNames}」在", "audit_delete_template": "删除模板", "audit_delete_template_detail": "删除模板内容", "audit_disable_field_role": "关闭列权限", "audit_disable_field_role_detail": "审计内容", "audit_disable_node_role": "关闭文件权限", - "audit_disable_node_role_detail": "关闭${nodeType}权限,名称为「${currentNodeName}」", + "audit_disable_node_role_detail_end": "`s permission", + "audit_disable_node_role_detail_start": "关闭${nodeType}权限,名称为", "audit_disable_node_share": "关闭文件节点公开链接", - "audit_disable_node_share_detail": "关闭${nodeType} 「${currentNodeName}」 的公开链接", + "audit_disable_node_share_detail_end": "的公开链接", + "audit_disable_node_share_detail_start": "关闭${nodeType}", "audit_enable_field_role": "开启列权限", "audit_enable_field_role_detail": "审计内容", "audit_enable_node_role": "开启文件权限", - "audit_enable_node_role_detail": "开启${nodeType}权限,名称为 「${currentNodeName}」", + "audit_enable_node_role_detail_end": "`s permission", + "audit_enable_node_role_detail_start": "开启${nodeType}权限,名称为", "audit_enable_node_share": "开启文件节点公开链接", - "audit_enable_node_share_detail": "开启${nodeType} 「${currentNodeName}」 的公开链接", + "audit_enable_node_share_detail_end": "的公开链接", + "audit_enable_node_share_detail_start": "开启${nodeType}", "audit_login_event": "登录事件", "audit_logout_event": "注销事件", "audit_organization_change_event": "通讯录组织架构变更", @@ -728,19 +747,20 @@ "audit_space_invite_user": "审计内容", "audit_space_invite_user_detail": "审计内容", "audit_space_node_copy": "复制文件节点", - "audit_space_node_copy_detail": "复制${nodeType}「${sourceNodeName}」,新文件节点名称为「${currentNodeName}」", + "audit_space_node_copy_detail_start": "复制${nodeType}「${sourceNodeName}」,新文件节点名称为", "audit_space_node_create": "创建文件节点", - "audit_space_node_create_detail": "创建${nodeType},名称为「${currentNodeName}」", + "audit_space_node_create_detail_start": "创建${nodeType},名称为", "audit_space_node_delete": "删除文件节点", - "audit_space_node_delete_detail": "删除${nodeType},名称为「${currentNodeName}」", + "audit_space_node_delete_detail_start": "删除${nodeType},名称为", "audit_space_node_export": "导出数表", "audit_space_node_export_detail": "成员 ${member_name} 导出表 ${node_name}", "audit_space_node_import": "导入文件节点", - "audit_space_node_import_detail": "导入文件节点,名称为 「${nodeName}」", + "audit_space_node_import_detail_start": "导入文件节点,名称为", "audit_space_node_move": "移动文件节点", - "audit_space_node_move_detail": "移动${nodeType}「${currentNodeName}」到文件夹「${parentName}」下方", + "audit_space_node_move_detail_end": "到文件夹「${parentName}」下方", + "audit_space_node_move_detail_start": "移动${nodeType}", "audit_space_node_rename": "重命名文件节点", - "audit_space_node_rename_detail": "重命名${nodeType},将「${oldNodeName}」名称修改为「${nodeName}」", + "audit_space_node_rename_detail_start": "重命名${nodeType},将「${oldNodeName}」名称修改为", "audit_space_node_sort": "审计内容", "audit_space_node_sort_detail": "审计内容", "audit_space_node_update_cover": "审计内容", @@ -754,18 +774,21 @@ "audit_space_rubbish_node_delete": "审计内容", "audit_space_rubbish_node_delete_detail": "审计内容", "audit_space_rubbish_node_recover": "恢复回收舱节点", - "audit_space_rubbish_node_recover_detail": "从回收舱恢复${nodeType},名称为「${currentNodeName}」", + "audit_space_rubbish_node_recover_detail_end": "from the trash", + "audit_space_rubbish_node_recover_detail_start": "从回收舱恢复${nodeType},名称为", "audit_space_template_event": "空间站模板事件", "audit_space_update_logo": "审计内容", "audit_space_update_logo_detail": "审计内容", "audit_store_share_node": "转存文件节点", - "audit_store_share_node_detail": "将${nodeType}转存到本空间站,名称为 「${nodeName}」", + "audit_store_share_node_detail_start": "将${nodeType}转存到本空间站,名称为", "audit_update_field_role": "审计内容", "audit_update_field_role_detail": "审计内容", "audit_update_node_role": "修改文件节点权限", - "audit_update_node_role_detail": "修改文件节点权限,将「${unitNames}」修改为「${currentNodeName}」的「${role}」角色", + "audit_update_node_role_detail_end": "的「${role}」角色", + "audit_update_node_role_detail_start": "修改文件节点权限,将「${unitNames}」修改为", "audit_update_node_share_setting": "修改文件节点公开链接", - "audit_update_node_share_setting_detail": "修改${nodeType} 「${currentNodeName}」 的公开链接的设置", + "audit_update_node_share_setting_detail_end": "的公开链接的设置", + "audit_update_node_share_setting_detail_start": "修改${nodeType}", "audit_user_login": "用户登录", "audit_user_login_detail": "审计内容", "audit_user_logout": "用户登出", @@ -808,6 +831,7 @@ "automation_enabled_return_via_related_files": "自动化已启用。请通过“相关文件”重新进入原表以使用新的按钮列。", "automation_field": "字段", "automation_import_variables_from_pre_tep": "从前置步骤获取数据", + "automation_is_not_yet_enabled": "自动化尚未启用,请启用后再试", "automation_last_edited_by": "修改者", "automation_last_edited_time": "修改时间", "automation_manager_label": "拥有该自动化的所有操作权限", @@ -913,7 +937,7 @@ "button_bind_now": "立即绑定", "button_change_phone": "修改手机", "button_check_history": "查看运行历史", - "button_check_history_end": "", + "button_check_history_end": ".", "button_click_trigger_explanation": "\"按钮被点击时\" 是一个触发条件,当用户点击你新建的按钮列时,它会被触发", "button_color": "按钮颜色", "button_combine": "按钮组合", @@ -929,10 +953,19 @@ "button_text": "按钮文案", "button_text_click_start": "点击开始", "button_type": "按钮类型", + "by_at": "的", + "by_days": "按天", + "by_every": "每隔", "by_field_id": "使用 Field ID", + "by_hours": "按小时", + "by_in": "的", + "by_min": "分", + "by_months": "按月", + "by_on": "的", "by_the_day": "按天", "by_the_month": "按月", "by_the_year": "按年", + "by_weeks": "按周", "calendar_add_date_time_field": "创建日期", "calendar_color_more": "更多颜色", "calendar_const_detail_weeks": "[\"星期一\",\"星期二\",\"星期三\",\"星期四\",\"星期五\",\"星期六\",\"星期天\"]", @@ -996,6 +1029,14 @@ "cannot_activate_space_by_space_limit": "已激活空间站数量达到上限,删除或退出已激活的空间站后,可手动激活", "cannot_join_space": "你的空间站数量已达10个上限,暂时无法加入新的空间站。", "cannot_switch_field_permission": "设置的列权限不能高于 TA 的文件权限,请先提高 TA 的文件权限", + "capacity_file_detail_desc": "空间站内的文件节点总量是由团队工作区的文件节点数与每位成员在个人工作区内创建的文件节点数相加而成。数量不够?", + "capacity_file_detail_title": "文件节点数量详情", + "capacity_file_member": "成员", + "capacity_file_member_private_node_count": "个人文件数", + "capacity_file_member_private_percent": "占比", + "capacity_file_member_team": "小组", + "capacity_file_member_team_node_count": "团队文件数", + "capacity_file_upgrade": "点击升级空间站", "capacity_from_official_gift": "官方赠送", "capacity_from_participation": "邀请新用户 ${user} 加入空间站", "capacity_from_purchase": "购买容量", @@ -1032,6 +1073,8 @@ "catalog": "工作目录", "catalog_add_from_template_btn_title": "从模板创建", "catalog_empty_tips": "当前空间站没有文件,从模板创建文件、仪表盘,快速开始吧", + "catalog_private": "个人", + "catalog_team": "团队", "category_blank": "[空值]", "catering": "餐饮业", "cayman_islands": "开曼群岛", @@ -1100,6 +1143,7 @@ "choose_type_of_vika_field": "选择维格列类型", "choose_your_own_space": "(仅支持另存到自己是主管理员的空间站)", "chose_new_primary_admin_button": "确认移交", + "chunk_stopping_title": "正在终止", "claim_special_offer": "获取特殊优惠", "clear": "清除", "clear_all_fields": "重置", @@ -1230,6 +1274,7 @@ "confirm_del_current_team": "确认是否删除当前小组", "confirm_delete": "确认删除", "confirm_delete_node_name_as": "确认要删除「${nodeNameDiv}」吗?", + "confirm_delete_private_node_name_as": "个人文件删除后无法进行恢复, 确认要删除「${nodeNameDiv}」吗?", "confirm_delete_space_btn": "了解并继续删除", "confirm_exit": "确认退出", "confirm_exit_space_with_name": "确认是否退出「${spaceNameDiv}」空间站\n", @@ -1267,6 +1312,14 @@ "convert": "转换", "convert_tip": "此操作可能会清除某些单元格内已有的数据,如果转换有问题,则可以撤销该操作", "cook_islands": "库克群岛", + "copilot_auto_agent_desc": "不知道选哪个?试试看全能助手", + "copilot_auto_agent_name": "全能助手", + "copilot_data_agent_desc": "基于您的视图生成数据分析/可视化", + "copilot_data_agent_name": "数据分析助手", + "copilot_data_agent_policy": "当与Copliot 开始对话时默认你已同意用户协议", + "copilot_data_agent_policy_button": "用户协议", + "copilot_help_agent_desc": "询问有关AITable帮助中心文档的任何问题", + "copilot_help_agent_name": "检索帮助中心", "copy": "的副本", "copy_automation_url": "复制自动化的 URL", "copy_card_link": "复制该记录的 URL", @@ -1311,6 +1364,7 @@ "create_mirror_guide_content": "镜像具有隐藏部分数据的功能,你可以在原表的视图中设置“筛选条件”和“隐藏字段”来控制镜像中需要展示的记录和字段。\n
\n
\n如果配合「视图锁」功能一起使用,可以防止其他人修改。\n
\n
\n另外,前往「原表>隐藏字段」可以修改“镜像中允许查看隐藏字段”的配置", "create_mirror_guide_title": "镜像将隐藏部分记录和字段", "create_new_button_field": "新建一个按钮列字段", + "create_private_node_tip": "个人或者临时类的草稿文件可以在这里创建 ${link}", "create_public_invitation_link": "创建公开的邀请链接", "create_space_sub_title": "Hi,给你的空间站起个名字吧", "create_team_fail": "添加小组失败", @@ -1374,10 +1428,13 @@ "custom_enterprise": "企业级空间站支持自定义人数、时长,灵活又强大", "custom_function_development": "定制功能开发", "custom_grade_desc": "提供原厂私有化安装部署,您可以获得企业级咨询服务、专家技术支持和定制化专业服务", + "custom_page_setting_title": "新建自定义页面", "custom_picture": "自定义图片", "custom_style": "样式", "custom_upload": "自定义上传", "custom_upload_tip": "推荐使用 1:1 的方形图片以达到更好的视觉体验", + "custome_page_setting_title": "添加自定义页面", + "custome_page_title": "自定义网页", "cut_cell_data": "剪切", "cyprus": "塞浦路斯", "czech": "捷克", @@ -1430,6 +1487,7 @@ "default_create_ai_chat_bot": "新建 AI 助手", "default_create_airagent": "新建Agent", "default_create_automation": "新建自动化", + "default_create_custom_page": "新建自定义页面", "default_create_dashboard": "新建仪表盘", "default_create_datasheet": "新建表格", "default_create_file": "新建节点", @@ -1451,7 +1509,8 @@ "del_invitation_link": "确定删除邀请链接", "del_invitation_link_desc": "删除后已生成的分享链接将会失效", "del_space_now": "彻底删除空间站", - "del_space_now_tip": "请注意:空间站删除后将不可恢复,包含所有表格、附件都会被彻底删除", + "del_space_now_confirm_tip": "再次提醒:如果空间站已订阅付费,删除空间站将会一并移除付费权益,该权益无法转移,请慎重操作!", + "del_space_now_tip": "请注意:空间站删除后将不可恢复,包含所有表格、附件都会被彻底删除。", "del_space_res_tip": "删除空间站成功", "del_team_success": "删除小组成功", "del_view_content": "确认要删除视图「${view_name}」吗?", @@ -1646,6 +1705,61 @@ "embed_error_page_help": "点击了解失效原因", "embed_fail_og_description_content": "该嵌入的公开链接已被关闭,暂时无法访问", "embed_failed": "嵌入链接已失效, ", + "embed_link_bilibili": "哔哩哔哩", + "embed_link_bilibili_desc": "通过嵌入哔哩哔哩视频,你可以在维格云观看教程、指南或其他视频资源,放置个人主页等,", + "embed_link_bilibili_link_text": "如何嵌入哔哩哔哩视频", + "embed_link_bilibili_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-bilibili-video", + "embed_link_default": "任何链接", + "embed_link_default_desc": "任何链接都行,", + "embed_link_default_link_text": "了解更多", + "embed_link_default_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_link_figma": "Figma", + "embed_link_figma_desc": "通过嵌入 Figma 文件,团队成员可以更方便地查看和编辑设计稿,提高协作效率,", + "embed_link_figma_link_text": "如何嵌入 Figma 文件", + "embed_link_figma_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-figma-file", + "embed_link_google_docs": "谷歌文档", + "embed_link_google_docs_desc": "通过嵌入谷歌文档,你可以在 AITable 中编辑和查看文档,方便团队协作,", + "embed_link_google_docs_link_text": "如何嵌入谷歌文档", + "embed_link_google_docs_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-docs-file", + "embed_link_google_sheets": "谷歌表格", + "embed_link_google_sheets_desc": "通过嵌入谷歌表格,你可以在 AITable 中编辑和查看表格,方便团队协作,", + "embed_link_google_sheets_link_text": "如何嵌入谷歌表格", + "embed_link_google_sheets_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-sheets-file", + "embed_link_jishi_design": "即时设计", + "embed_link_jishi_design_desc": "通过嵌入即时设计的文件,团队成员可以更方便地查看和编辑设计稿,提高协作效率,", + "embed_link_jishi_design_link_text": "如何嵌入即时设计文件", + "embed_link_jishi_design_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-js-design-file", + "embed_link_tencent_docs": "腾讯文档", + "embed_link_tencent_docs_desc": "通过嵌入腾讯文档,你可以在维格云中和团队成员协作,实时编辑和查看腾讯文档,提高协作效率,", + "embed_link_tencent_docs_link_text": "如何嵌入腾讯文档", + "embed_link_tencent_docs_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-tencent-docs", + "embed_link_wps": "WPS", + "embed_link_wps_desc": "通过嵌入 WPS 文件,你可以在维格云中编辑和查看 WPS 的文档、表格、表单等,提高协作效率,", + "embed_link_wps_link_text": "如何嵌入 WPS 文件", + "embed_link_wps_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-wps-file", + "embed_link_youtube": "YouTube", + "embed_link_youtube_desc": "通过嵌入 YouTube 视频,你可以在 AITable 中观看教程、指南,或查看频道主页等,", + "embed_link_youtube_link_text": "如何嵌入 Youtube 视频", + "embed_link_youtube_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-youtube-video", + "embed_page": "自定义页面", + "embed_page_add_url": "添加网址", + "embed_page_doc_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_page_function_desc": "将网页添加到${edition},以便轻松访问第三方网站的文档、视频等内容。您可以添加推荐的网站链接或任何自定义链接。", + "embed_page_node_permission_editor": "在「只可更新」基础上,还可以打开文件的公开分享", + "embed_page_node_permission_manager": "拥有该文件的所有操作权限", + "embed_page_node_permission_reader": "可查看自定义页面的内容和文件基本信息", + "embed_page_node_permission_updater": "在「只可阅读」基础上,还可以修改自定义页面的链接", + "embed_page_url_invalid": "请输入正确的网址", + "embed_paste_link_bilibili_placeholder": "粘贴哔哩哔哩视频链接", + "embed_paste_link_default_placeholder": "粘贴链接", + "embed_paste_link_figma_placeholder": "粘贴 Figma 文件的分享链接", + "embed_paste_link_google_docs_placeholder": "粘贴谷歌文档分享链接", + "embed_paste_link_google_sheets_placeholder": "粘贴谷歌表格分享链接", + "embed_paste_link_jsdesign_placeholder": "粘贴即时设计文件的分享链接", + "embed_paste_link_tencent_docs_placeholder": "粘贴腾讯文档的分享链接", + "embed_paste_link_wps_placeholder": "粘贴 WPS 文件的分享链接", + "embed_paste_link_youtube_placeholder": "粘贴 YouTube 视频链接", + "embed_success": "添加成功", "emoji_activity": "活动和事件", "emoji_custom": "自定义", "emoji_flags": "旗帜", @@ -1752,6 +1866,11 @@ "estonia": "爱沙尼亚", "ethiopia": "埃塞俄比亚", "event_planning": "活动策划", + "every": "每", + "every_day_at": "天", + "every_hour_at": "个小时", + "every_month_at": "个月", + "every_week_at": "每周的", "everyday_life": "日常生活", "everyone_visible": "全员可见", "exact_date": "指定日期", @@ -1762,6 +1881,7 @@ "exchange": "兑换", "exchange_code_times_tip": "请注意,兑换码只能兑换一次", "exclusive_consultant": "专属 V+ 顾问", + "exclusive_limit_plan_desc": "Exclusive Limited Tier", "exist_experience": "退出体验", "exits_space": "退出空间", "expand": "展开", @@ -2291,7 +2411,7 @@ "function_set_timezone_summary": "为指定日期设置特定的时区。\n\n【date】是指定日期。\n【tz_identifier】是时区说明符。比如\"8\"代表东8区,\"-2\"代表西2区。\n\n本函数必须与DATETIME_FORMAT结合使用。", "function_sqrt_example": "SQRT(10000)\n=> 100", "function_sqrt_summary": "返回数值的平方根。\n\n【value】是要对其求平方根的数值。\n\n如果数值为负数,则 SQRT 返回 Nan", - "function_substitute_example": "SUBSTITUTE(\"小胡,小张,小王\", \"小\", \"老\")\n=> 老胡,老张,老王\n\nSUBSTITUTE(\"小胡,小张,小王\", \"小\", \"老\", 3)\n=> 小胡,老张,小王", + "function_substitute_example": "SUBSTITUTE(\"小胡,小张,小王\", \"小\", \"老\")\n=> 老胡,老张,老王\n\nSUBSTITUTE(\"小胡,小张,小王\", \"小\", \"老\", 3)\n=> 小胡,小张,老王", "function_substitute_summary": "将内容中特定的文本全部替换为新文本。\n\n【string】是你输入的一段内容,其中包含了被替换的文本。该内容可以是输入的文本或者引用的维格列数据。\n【old_text】要被替换的原文本。\n【new_text】替换原文本的新文本。\n【index】非必填,是索引号,指定索引号后系统仅会替换特定位置的原文本。\n\n本函数将文本中的原字符替换为新字符,在没有特别声明的情况下,新字符将替换所有出现的原字符。\n\n(如果你想替换指定起点位置和终点位置之间的字符,请参见REPLACE。)", "function_sum_example": "SUM(1, 2, \"3\", \"四\")\n=> 1 + 2 + 3 =6\n\nSUM({数学成绩}, {英语成绩}, {语文成绩})", "function_sum_summary": "将所有数值相加。\n\n【number...】是进行运算的数值参数,可以输入数字或引用数值类型的列。数值类型的列包括数字、货币、百分比、评分等。", @@ -2461,6 +2581,7 @@ "gold_grade": "黄金级", "gold_grade_desc": "适用于有复杂业务流程的团队或组织", "gold_seat_200_desc": "200人", + "gold_seat_300_desc": "300人", "golden_grade": "黄金级", "got_it": "知道了", "got_v_coins": "已获得 V 币奖励", @@ -2494,6 +2615,8 @@ "guests_per_space": "外部访客", "guide_1": "来呀互相伤害呀", "guide_2": "花费几分钟跟随我们的指引,学习一下维格表的常规功能,可以让您事半功倍哦!", + "guide_flow_modal_contact_sales": "预约销售", + "guide_flow_modal_get_started": "立刻使用", "guide_flow_of_catalog_step1": "这是工作目录,里边存放的是空间站的所有文件夹和文件", "guide_flow_of_catalog_step2": "工作目录里面,除了可以单独创建维格表,也可以单独创建文件夹", "guide_flow_of_click_add_view_step1": "除了基本的表格视图之外,我们支持创建相册视图,如果你有图片附件的话,我建议你创建个相册视图试试", @@ -2549,6 +2672,7 @@ "hide_uneditable_automation_node": "隐藏无编辑权限的自动化节点", "hide_unmanage_sheet": "隐藏无管理权限的文件", "hide_unmanageable_files": "隐藏无管理权限的文件", + "hide_unmanaged_sheet": "Hide unmanageable resource", "hide_unusable_sheet": "隐藏无编辑权限的文件", "highlight": "高亮", "hint": "提示", @@ -2672,6 +2796,7 @@ "intro_widget_tips": "什么是小程序?", "introduction": "简介", "invalid_action_sort_tip": "该字段作为分组项已被设置排序,当前设置的排序不会生效", + "invalid_automation_configuration": "自动化配置无效,请检查后再试", "invalid_field_type": "非法的字段类型", "invalid_option_sort_tip": "该字段作为分组项已被设置排序", "invalid_redemption_code_entered": "请输入有效的兑换码", @@ -2802,6 +2927,9 @@ "label_format_day_month_and_year_split_by_slash": "日/月/年", "label_format_month": " 月", "label_format_month_and_day_split_by_dash": "月-日", + "label_format_month_day_year_split_by_dash": "月-日-年", + "label_format_month_day_year_split_by_slash": "月/日/年", + "label_format_month_day_year_two_digit_year_split_by_slash": "月/日/年(两位数年份)", "label_format_year": "年", "label_format_year_and_month_split_by_dash": "年-月", "label_format_year_month_and_day_split_by_dash": "年-月-日", @@ -2869,8 +2997,8 @@ "lark_integration_sync_tip": "通讯录同步中", "lark_login": "飞书登录", "lark_org_manage_reject_msg": "成员列表会实时跟飞书通讯录的组织架构保持同步,请在飞书侧进行此操作(企业管理 > 添加团队成员)", - "lark_single_record_comment_mentioned": "", - "lark_single_record_comment_mentioned_title": "", + "lark_single_record_comment_mentioned": "**维格表: **{nodeName}\n**记录: **{recordTitle}\n\n\"{commentContent}\"", + "lark_single_record_comment_mentioned_title": "**有人在评论中提及你**", "lark_single_record_member_mention": "**记录: **{recordTitle}\n**提及人: **{memberName}\n**维格表: **{nodeName}", "lark_single_record_member_mention_title": "**有人在记录中提及你**", "lark_subscribed_record_cell_updated": "**记录:** {recordTitle}\n**原内容:** {oldDisplayValue}\n**修改后的内容:** {newDisplayValue}\n**修改人:** {memberName}\n**维格表:** {nodeName}", @@ -2880,6 +3008,7 @@ "lark_version_enterprise": "飞书企业版", "lark_version_standard": "飞书标准版", "lark_versions_free": "飞书基础版", + "last_day": "最后一天", "last_modified_by_select_modal_desc": "由于该维格列类型的特殊性,下方只展示可编辑的列,每当有人在指定的列进行过修改,则会更新当前的修改人", "last_modified_time_select_modal_desc": "由于该维格列类型的特殊性,下方只展示可编辑的列,每当有人在指定的列进行过修改,则会更新当前的修改时间", "last_step": "上一步", @@ -3024,7 +3153,7 @@ "mail_invite_fail": "邀请成员失败", "mail_invite_success": "邀请成员成功", "main_admin_name": "主管理员名称", - "main_admin_page_desc": "拥有空间站的最高管理权限,可以分配子管理员或转让空间站", + "main_admin_page_desc": "主管理员具有完整的访问权限,可以分配子管理员,或调整空间站设置", "main_contain": "主要包含内容", "malawi": "马拉维", "malaysia": "马来西亚", @@ -3120,7 +3249,7 @@ "member_applied_to_close_account": "已申请账号注销", "member_data_desc_of_appendix": "工作目录中所有表格内上传附件的大小统计,如果上传附件达到容量上限将无法上传新的附件。", "member_data_desc_of_dept_number": "组织架构中所有小组的数量统计,包括子小组。", - "member_data_desc_of_field_number": "工作目录中所有文件(表格、仪表盘、神奇表单、镜像)的数量统计", + "member_data_desc_of_field_number": "工作目录&空间站模板中所有文件(表格、仪表盘、神奇表单、镜像)的数量统计。", "member_data_desc_of_member_number": "席位数包含已加入的成员数和工作台创建的 AI 助手数的总和。席位数超限后将无法添加成员或者创建 AI 助手", "member_data_desc_of_record_number": "工作目录中所有表格中记录的数量统计,包括空白记录", "member_err": "昵称不能超过32个字", @@ -3244,8 +3373,12 @@ "more_widget": "更多小程序", "morocco": "摩洛哥", "move": "移动", + "move_datasheet_link_warn": "无法单独移到团队工作区,因为当前表存在关联关系,建议将关联的所有表放在一个文件夹里进行移动", "move_favorite_node_fail": "移动节点失败,系统将会自动更新列表", + "move_folder_link_warn": "无法移到团队工作区,因为当前文件夹内的文件与文件夹外的文件有连接关系(可能是关联关系或者被表单等所连接)建议将它们放在一个文件夹里再进行移动", "move_node_modal_content": "移动后,文件的可见性可能会受到上级文件夹的影响", + "move_other_link_no_permission": "你无法移动文件至目标文件夹,因为你缺少该文件夹的管理权限", + "move_other_link_warn": "无法单独将${nodeType}移动至团队工作区,因为它连接了个人工作区的表,建议将它们放在一个文件夹里进行移动", "move_to": "移动至", "move_to_error_equal_parent": "文件已在当前文件夹下方,请选择其他文件夹", "move_to_modal_title": "将「${name}」移动至当前文件夹下", @@ -3276,6 +3409,7 @@ "new_a_line": "Shift+Enter 换行", "new_automation": "新建自动化", "new_caledonia": "新喀里多尼亚", + "new_custom_page": "新建自定义页面", "new_datasheet": "新建表格", "new_folder": "新建文件夹", "new_folder_btn_title": "新建文件夹", @@ -3442,7 +3576,7 @@ "nvc_start_text": "请按住滑块,拖动到最右边", "nvc_yes_text": "验证通过", "obtain_verification_code": "未获取验证码或已过期,请重新获取", - "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrzw0miJVmSkJ7eBBa9k/fomx5qPX0JGPFvfEEP\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", + "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrCvbFC53xc3kl00B4Pg\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", "offical_website_nav_data": "[{\n \"name\": \"产品\",\n \"href\": \"/login\",\n \"children\": [\n {\n \"name\": \"vika维格表 Overview\",\n \"href\": \"/login/\"\n },\n {\n \"name\": \"应用连接 Integration\",\n \"href\": \"/connections/\"\n },\n {\n \"name\": \"客户端(Beta) Download\",\n \"href\": \"/download/\"\n }\n ]\n}, {\n \"name\": \"解决方案\",\n \"href\": \"/\",\n \"children\": [{\n \"name\": \"PMO项目群管理\",\n \"href\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"href\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"href\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"href\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"href\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"href\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"href\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"href\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"href\": \"/shop/\"\n }, {\n \"name\": \"更多解决方案 >\",\n \"href\": \"/solutions/\"\n }]\n}, {\n \"name\": \"模板/案例\",\n \"href\": \"/template\",\n \"children\": [\n {\n \"name\": \"模板中心 Tempaltes\",\n \"href\": \"/template\"\n },\n {\n \"name\": \"客户案例 Customers\",\n \"href\": \"/cases/\"\n }\n ]\n},\n {\n \"name\": \"首页\",\n \"href\": \"/?home=1\"\n },\n {\n \"name\": \"学习资源\",\n \"href\": \"https://edu.vika.cn/index\",\n \"children\": [\n {\n \"name\": \"快速入门 Tutorials\",\n \"href\": \"https://help.vika.cn/docs/guide/tutorial\"\n },\n {\n \"name\": \"产品手册 Manual\",\n \"href\": \"https://help.vika.cn/docs/guide/manual\"\n },\n {\n \"name\": \"维格课堂 Vika Education\",\n \"href\": \"https://edu.vika.cn/\"\n },\n {\n \"name\": \"维格社区 Vika BBS\",\n \"href\": \"https://bbs.vika.cn/\"\n },\n {\n \"name\": \"第三方连接 Integration\",\n \"href\": \"https://help.vika.cn/docs/guide/connection\"\n },\n {\n \"name\": \"开发者中心 Developer Center\",\n \"href\": \"/developers/\"\n },\n {\n \"name\": \"常见问题 FAQ\",\n \"href\": \"https://help.vika.cn/docs/guide/questions\"\n }\n ]\n }]", "office_preview": "Office 文件预览", "office_preview_app_desc": "

在维格表里提供无缝的 office 文件在线预览能力, 让你可以随时随地使用 PC 或手机查看 Excel、Word、PPT 等常见的 office 文件

\n\n
  • 支持在线预览 .doc、.docx、.xls、.xlsx、.ppt、.pptx 和 .pdf 格式的 office 文件
  • 桌面端和移动端同步支持对上述格式的文件预览\n
\n\n

补充说明:

\n
  • 该功能由「永中云转换」提供技术支持,维格表官方进行集成
  • 点击下方 “授权” 按钮,表示启用本应用,并同意「永中云转换」读取你将要预览的 office 文件
  • 如不再需要 office 预览功能,管理员可再次访问此页面进行停用操作
", @@ -3482,6 +3616,7 @@ "open_auto_save_success": "开启自动保存视图配置成功", "open_auto_save_warn_content": "所有成员修改当前视图配置会自动保存并同步给其他成员。(视图配置包括:筛选、分组、排序、隐藏列、布局、样式等)", "open_auto_save_warn_title": "开启自动保存视图配置", + "open_automation_time_arrival": "https://aitable.ai/contact-sales-open-source", "open_failed": "查看失败", "open_in_new_tab": "新标签页打开", "open_invite_after_operate": "打开邀请成员后,全体成员可以在“通讯录面板”进行邀请成员操作", @@ -3628,6 +3763,8 @@ "payment_record": "支付记录", "payment_reminder": "支付提醒", "payment_reminder_content": "你所选择的新方案抵扣金额大于待支付金额,建议你选择更长时长的新方案。如果你确认这样做,超出的金额将不能退还。如有疑问请 ${action}", + "payment_reminder_modal_content": "可以试试看高级版本,享受更多文件节点、企业权限、附件容量、数据量、AI等高级功能和特权。", + "payment_reminder_modal_title": "你目前正在使用免费版", "pending_invite": "待邀请", "people": "人", "per_person_per_year": "每人每年", @@ -3792,12 +3929,12 @@ "player_step_ui_config_163": "", "player_step_ui_config_164": "", "player_step_ui_config_165": "{\n \"headerImg\": \"https://s4.vika.cn/space/2023/03/16/8374ca1295664675bd1155b077555113\",\n \"readMoreUrl\": \"https://help.vika.cn/changelog/23-03-16-updates\",\n \"children\": \"

🚀 新功能介绍

\\n
  • 镜像功能再次升级,可禁止查看已隐藏的字段
  • 个人设置追加时区信息,日期字段可指定时区
  • 「全局搜索」优化,新增搜索结果分类
  • 神奇表单支持隐藏官方标识
  • API 性能优化,大幅提高请求速度
\"\n}", - "player_step_ui_config_166": "{\n \"title\": \"恭喜你!获得试用权益\",\n \"description\": \"你获得了14天Enterprise版本的试用权益,你可以点击按钮查看详情\",\n \"listHeader\": \"试用权益:\",\n \"listContent\": [\n \"空间站记录总数上限提高至 500,000,000 行\",\n \"空间站附件容量数提高至 50 GB\",\n \"支持调用所有高级 API\"\n ],\n \"listFooter\": \"更多权益\",\n \"url\": \"https://aitable.ai/management/upgrade\n}", + "player_step_ui_config_166": "{\n \"title\": \"恭喜你!获得试用权益\",\n \"description\": \"你获得了14天Enterprise版本的试用权益,你可以点击按钮查看详情\",\n \"listHeader\": \"试用权益:\",\n \"listContent\": [\n \"空间站记录总数上限提高至 500,000,000 行\",\n \"空间站附件容量数提高至 50 GB\",\n \"支持调用所有高级 API\"\n ],\n \"listFooter\": \"更多权益\",\n \"url\": \"https://aitable.ai/management/upgrade\"\n}", "player_step_ui_config_167": "{\n \"config\": [\n {\n \"key\": 1,\n \"name\": \"answer1\",\n \"title\": \"您希望通过 APITable 解决哪些问题?\",\n \"type\": \"multiButton\",\n \"answers\": [\n \"IT 运维支持\",\n \"教育\",\n \"项目管理\",\n \"市场营销\",\n \"产品管理\",\n \"招聘管理\",\n \"运营\",\n \"金融财务\",\n \"销售 & 客户管理\",\n \"软件开发\",\n \"人力资源 & 合规\",\n \"设计 & 创意\",\n \"非盈利组织\",\n \"制造业\",\n \"其他\"\n ],\n \"lastAllowInput\": false\n },\n {\n \"key\": 2,\n \"name\": \"answer2\",\n \"title\": \"您的工作岗位是?\",\n \"type\": \"radio\",\n \"answers\": [\n \"企业主\",\n \"团队负责人\",\n \"团队成员\",\n \"自由职业者\",\n \"主管\",\n \"高管层\",\n \"副总裁\"\n ],\n \"lastAllowInput\": false\n },\n {\n \"key\": 3,\n \"name\": \"answer3\",\n \"title\": \"您的团队规模是?\",\n \"type\": \"radio\",\n \"answers\": [\n \"只有我\",\n \"2-5\",\n \"6-10\",\n \"11-15\",\n \"16-25\",\n \"25-50\",\n \"51-100\",\n \"101-500\"\n ],\n \"lastAllowInput\": false\n },\n {\n \"key\": 4,\n \"name\": \"answer4\",\n \"title\": \"您的公司规模是?\",\n \"type\": \"radio\",\n \"answers\": [\n \"1-19\",\n \"20-49\",\n \"50-99\",\n \"100-250\",\n \"251-500\",\n \"501-1500\",\n \"1500+\"\n ],\n \"lastAllowInput\": false\n },\n {\n \"key\": 5,\n \"name\": \"answer5\",\n \"title\": \"您从哪种途径了解到我们?\",\n \"type\": \"checkbox\",\n \"answers\": [\n \"搜索引擎\",\n \"YouTube\",\n \"Product Hunt\",\n \"Github\",\n \"推特\",\n \"领英\",\n \"朋友推荐\"\n ],\n \"lastAllowInput\": false\n },\n {\n \"key\": 6,\n \"name\": \"answer6\",\n \"title\": \"加入我们的Discord社区,和全世界 APITable 的使用者一起讨论使用心得吧!在使用过程中如果遇到任何问题,可以随时在社区获得解答和帮助。\",\n \"type\": \"joinUs\",\n \"url\": \"https://discord.gg/2UXAbDTJTX\",\n \"confirmText\": \"加入社区\",\n \"skipText\": \"跳过\",\n \"submit\": true\n }\n ]\n}", "player_step_ui_config_168": "{\n\"templateKey\":\"createMirrorTip\"\n}", "player_step_ui_config_169": "{\n \"headerImg\": \"https://s4.vika.cn/space/2023/04/04/bcf0695cf35840e6b85e032a8e5ea0a1\",\n \"readMoreUrl\": \"https://help.vika.cn/changelog/23-04-10-updates\",\n \"children\": \"

🚀 新功能介绍

\\n
  • 推出新字段类型「多级联动」,神奇表单支持多级选项
  • 脚本小程序上架,少少代码满足多多定制化
  • 维格表自动化支持「发送邮件」
  • 维格表自动化支持「发送到Slack」
  • 维格表的AI探索,「GPT 内容生成」小程序发布
\"\n}", "player_step_ui_config_17": "{\n \"element\": \"#TEMPLATE_CENTER_USE_TEMPLATE_BTN>button\", \n\"placement\": \"rightBottom\",\n\"offsetY\": 20,\n \"title\": \"使用模板教程\", \n\"description\": \"点击左侧按钮使用模板\", \"children\":\"\" \n}", - "player_step_ui_config_176": "{\"title\":\"AI 助手介绍\",\"video\":\"https://www.youtube.com/embed/cjds1r_roG8?si=irKUpMhwDlOEb8Hc\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", + "player_step_ui_config_176": "{\"title\":\"AI 助手介绍\",\"video\":\"https://www.youtube.com/embed/nbqwE21X1hc?si=HYTHEboJtarOL1w8\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", "player_step_ui_config_18": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select>.ant-select-selector\", \n\"placement\": \"bottomLeft\",\n \"title\": \"使用模板教程\", \n\"description\": \"选择模板要存放的位置\", \"children\":\"\" \n}", "player_step_ui_config_19": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select .ant-select-selector\"\n}", "player_step_ui_config_2": "{\n \"config\": [\n {\n \"key\": 1,\n \"name\": \"answer1\",\n \"title\": \"您希望通过维格表解决哪些问题?\",\n \"type\": \"checkbox\",\n \"answers\": [\n \"工作规划\",\n \"客户服务\",\n \"项目管理\",\n \"采购供应\",\n \"内容生产\",\n \"电商运营\",\n \"活动策划\",\n \"人力资源\",\n \"行政管理\",\n \"财务管理\",\n \"网络直播\",\n \"高校管理\",\n \"其它\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 2,\n \"name\": \"answer2\",\n \"title\": \"您的工作岗位是?\",\n \"type\": \"radio\",\n \"answers\": [\n \"管理者\",\n \"项目经理\",\n \"产品经理\",\n \"设计师\",\n \"研发、工程师\",\n \"运营、编辑\",\n \"销售、客服\",\n \"人事、行政\",\n \"财务、会计\",\n \"律师、法务\",\n \"市场\",\n \"教师\",\n \"学生\",\n \"其它\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 3,\n \"name\": \"answer3\",\n \"title\": \"您的公司名称是?\",\n \"type\": \"input\",\n \"submit\": false\n },\n {\n \"key\": 4,\n \"name\": \"answer4\",\n \"title\": \"请留下你的邮箱/手机/微信号,以便我们及时提供帮助。\",\n \"type\": \"input\",\n \"submit\": true\n },\n {\n \"key\": 5,\n \"title\": \"感谢你的填写,请加一下客服号以备不时之需\",\n \"platform\": {\n \"website\": \"https://s4.vika.cn/space/2023/03/02/b34e3205a9154463be16f497524f1327\",\n \"dingtalk\": \"https://s4.vika.cn/space/2023/03/02/4b16cef6602a4586a21d6346bf25d300\",\n \"wecom\": \"https://s4.vika.cn/space/2023/03/02/60119b1b69b64aa887bd1be6a2928bec\",\n \"feishu\": \"https://u.vika.cn/z9ygm\"\n },\n \"type\": \"contactUs\",\n \"next\": true\n }\n ]\n}\n", @@ -3827,13 +3964,13 @@ "player_step_ui_config_41": "", "player_step_ui_config_42": "{\n \"element\": \"#DATASHEET_FORM_LIST_PANEL\", \n\"placement\": \"leftTop\",\n \"title\": \"神奇表单\", \n\"description\": \"在这里可以快速生成当前视图的神奇表单,神奇表单的字段是依照视图的维格列数量以及顺序来生成的哦\", \"children\":\"\" \n}", "player_step_ui_config_43": "{\n \"element\": \".style_navigation__1U5cR .style_help__1sXEA\", \n\"placement\": \"rightBottom\",\n \"title\": \"小提示\", \n\"offsetY\":5,\n\"description\": \"你可以在左侧的「帮助中心」找回你的维格小助手\", \"children\":\"\" \n}", - "player_step_ui_config_44": "{\n\"title\":\"一分钟快速入门\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", + "player_step_ui_config_44": "{\n\"title\":\"VIKA产品演示\",\n\"video\":\"space/2023/12/29/212a38dda62f4e52a58a92bf86657705\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", "player_step_ui_config_45": "", "player_step_ui_config_46": "", "player_step_ui_config_47": "{\n \"element\": \"#DATASHEET_WIDGET_BTN\",\n\"placement\": \"bottomRight\",\n \"title\": \"新功能\", \n\"description\": \"小程序上线!想要让沉淀下来的数据得到更好的运用吗?那就赶紧来体验一下吧\", \"children\":\"\" \n}", "player_step_ui_config_48": "", "player_step_ui_config_49": "{\n \"element\": \".style_widgetPanelContainer__1l2ZV\",\n\"placement\": \"leftCenter\",\n \"title\": \"什么是小程序\", \n\"description\": \"维格小程序是维格表的一种扩展应用,可实现数据可视化、数据传输、数据清洗等等额外功能。通过在小程序面板安装适合团队的小程序,可以让工作事半功倍\", \"children\":\"\" \n}", - "player_step_ui_config_5": "{\n\"title\":\"一分钟快速入门\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}\n", + "player_step_ui_config_5": "{\n\"title\":\"VIKA产品演示\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}\n", "player_step_ui_config_50": "{\n \"element\": \".style_widgetModal__eXmdB\",\n\"placement\": \"leftTop\",\n \"title\": \"小程序中心\", \n\"description\": \"官方推荐和空间站自建的小程序会发布到这里。你可以根据场景,在这里挑选合适的小程序放置到仪表盘或小程序面板里\", \"children\":\"\" \n}", "player_step_ui_config_51": "{\n \"element\": \".style_widgetModal__eXmdB .style_widgetItem__3Pl-1 button\",\n\"placement\": \"rightBottom\",\n \"title\": \"安装小程序\", \n\"description\": \"我们安装这个「图表」小程序看看吧\", \"children\":\"\" \n}", "player_step_ui_config_52": "", @@ -3886,6 +4023,7 @@ "player_step_ui_config_95": "", "player_step_ui_config_97": "{\n\t\"vikaby\": {\n\t\t\"title\": \"你好\",\n\t\t\"description\": \"如果在使用过程中遇到问题,请扫描右侧二维码联系我解决\",\n\t\t\"list\": \"
  • 刚注册维格表,不知道怎么用
  • 维格表可以实现我想要的效果吗
  • 使用过程出现异常问题
  • 后续支持的功能有哪些
  • 获取官方邀请码
\",\n\t\t\"tip\": \"扫码添加客服\"\n\t},\n\t\"questionnaire\": {\n\t\t\"title\": \"您好,我是维格表数字化顾问\",\n\t\t\"list\": \"[{\\\"title\\\": \\\"Bug 吐槽\\\", \\\"icon\\\": \\\"BugOutlined\\\"}, {\\\"title\\\": \\\"需求反馈\\\", \\\"icon\\\": \\\"AdviseSmallOutlined\\\"}, {\\\"title\\\": \\\"服务支持\\\", \\\"icon\\\": \\\"ServeOutlined\\\"}, {\\\"title\\\": \\\"案例推荐\\\", \\\"icon\\\": \\\"ZanOutlined\\\"}, {\\\"title\\\": \\\"解决方案\\\", \\\"icon\\\": \\\"SolutionSmallOutlined\\\"}, {\\\"title\\\": \\\"产品答疑\\\", \\\"icon\\\": \\\"InformationLargeOutlined\\\"}]\",\n\t\t\"tip\": \"扫码添加微信,获得更多专属服务\"\n\t},\n\t\"website\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/03/02/59f4cc8e0b2b4395bf0fcd133d208e63\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/03/02/defbf55d1e9646eb929f9f5d11d5c119\"\n\t},\n\t\"dingtalk\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/03/02/964be5e3217b4fa8bfa74ef47a980093?attname=dingtalk-questionnaire.png\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/03/02/964be5e3217b4fa8bfa74ef47a980093?attname=dingtalk-vikaby.png\",\n\"tip\": \"请使用钉钉扫码,加入交流群\"\n\t},\n\t\"wecom\": {\n\t\t\"questionnaire\": \"https://s4.vika.cn/space/2023/03/02/1346d5efbd5043efb2bfcba0075c0ee9\",\n\t\t\"vikaby\": \"https://s4.vika.cn/space/2023/03/02/09401a8f2d8e491a9097b9bac8b5a4e4\"\n\t},\n\t\"feishu\": {\n\t\t\"title\": \"扫码添加客服\",\n\t\t\"tip\": \"请使用飞书扫码,添加客服号备用\",\n\t\t\"description\": \"以便使用过程中遇到问题,可以随时获得服务和解答\",\n\t\t\"originUrl\": \"https://u.vika.cn/z9ygm\"\n\t}\n}", "player_step_ui_config_99": "", + "player_step_ui_config_automation_1": "{\n \"element\": \"#AUTOMATION_ADD_TRIGGER_BTN\", \"title\":\"title\", \"description\": \"description\" \n} ", "player_step_ui_config_button_field_action_create": "{\n \"element\": \"#CONST_ROBOT_ACTION_CREATE\", \"placement\": \"topCenter\", \"title\": \"\", \"description\": \"现在你应该添加一个或多个 Action,以定义按钮点击后应执行的具体动作\" \n} ", "player_step_ui_config_button_field_bound_datasheet": "{\n \"element\": \"#AUTOMATION_BOUND_DATASHEET\", \"title\": \"\", \"description\": \"“按钮被点击时” 需要绑定表格和字段,以便知道哪里发生的点击行为,这里已经为你设置好\" \n} ", "player_step_ui_config_button_field_node": "{\n \"element\": \".TREE_NODE_ACTIVE_ONE\", \"title\": \"\", \"description\": \"自动化节点是自动化流程的起点,你可以在这里设置触发条件和相关动作\" \n} ", @@ -3930,6 +4068,7 @@ "preview_guide_click_to_restart": "点击下方按钮重新预览", "preview_guide_enable_it": "你可以点击下方按钮去启用此功能", "preview_guide_open_office_preview": "开启「office预览」功能后即可预览该文件", + "preview_next_automation_execution_time": "预览最近10次执行时间", "preview_not_support_video_codecs": "当前仅支持预览编码为H.264的MP4视频", "preview_revision": "预览此版本", "preview_see_more": "想要了解更多「office 文件预览」功能?请点击这里", @@ -3965,6 +4104,7 @@ "privacy_protection": "《隐私保护》", "private_cloud": "专有云旗舰版", "private_external_person_only": "外部人员专用", + "private_help_link": "https://help.aitable.ai/docs/guide/team-and-private-area#private-area", "private_internal_person_only": "内部人员专用", "private_product_point": "一键拥有自己的 APITable 平台", "privatized_deployment": "私有化部署", @@ -4035,13 +4175,15 @@ "reconciled_data": "正在核对数据……", "record": "记录", "record_activity_experience_tips": "可查看 ${day} 天的修改历史", + "record_archived_data": "已归档数据", + "record_chunk_text": "正在${text}条行记录,请稍后", "record_comment": "仅评论", "record_comments": "评论", "record_fail_data": "数据已失效", "record_filter_tips": "此记录已被筛选条件过滤", "record_functions": "记录(行)函数", "record_history": "仅修改历史", - "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-history", + "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-activity", "record_history_title": "修改历史", "record_pre_filtered": "此记录已被筛选过滤,点击本记录以外区域它将被隐藏", "record_pre_move": "此记录不属于当前位置,点击本记录以外区域它将被移动", @@ -4087,7 +4229,7 @@ "remove_from_group": "将你移出空间站「」的「」小组", "remove_from_role": "将你移出空间站「」的「」小组", "remove_from_space": "移出空间", - "remove_from_space_confirm_tip": "确认是否将该成员彻底移出此空间", + "remove_from_space_confirm_tip": "确认是否将该成员彻底移出此工作区,移除后该成员存在个人工作区区的文件不会再占用工作区站的容量。", "remove_from_team": "移出小组", "remove_from_team_confirm_tip": "确认是否将该成员移出此小组", "remove_from_the_team": "移出小组", @@ -4481,6 +4623,12 @@ "scan_to_login": "扫码登录", "scan_to_login_by_method": "请使用${method}关注公众号即可安全登录", "scatter_chart": "散点图", + "schedule_day_tips": "周期计算从每个月的 1 日开始算,假设设置为每隔 10 天,则每月的 1 日,11 日,21 日,31 日会触发", + "schedule_hour_tips": "周期计算从每天的 0 点开始算,假设设置为每隔 3 个小时的 0 分,则每天的 0 点,3 点,6 点,9 点,12 点,15 点,18 点,21 点会触发", + "schedule_start_day": "从每月 1 日起,每隔", + "schedule_start_month": "从每年 1 月份起,每隔", + "schedule_type": "定时类型", + "schedule_year_tips": "周期计算从每年的 1 月份开始算,假设设置为每隔 3 个月的 1 日,则每年的 1 月,4 月,7 月,10 月的第一天会触发", "science_and_technology": "科学技术", "scroll_screen_down": "向下滚动一屏", "scroll_screen_left": "向左滚动一屏", @@ -4494,6 +4642,7 @@ "search_folder_or_sheet": "搜索文件夹或维格表", "search_new_admin": "搜索成员昵称,选择移交的主管理员", "search_node_pleaseholder": "搜索文件 (${shortcutKey})", + "search_node_tip": "搜索 (${shortcutKey})", "search_or_add": "查找或添加", "search_role_placeholder": "搜索角色", "seats": "席位数量", @@ -4897,6 +5046,7 @@ "space_info": "空间站驾驶舱", "space_info_del_confirm1": "1. 删除空间站后,以下数据将被全部清除:", "space_info_del_confirm2": "2. 空间站将会在七天后自动彻底删除。在此之前,你可以随时撤销删除操作", + "space_info_del_confirm3": "3. 再次提醒:如果空间站已订阅付费,删除空间站将会一并移除付费权益,该权益无法转移,请慎重操作!", "space_info_feishu_desc": "使用了第三方集成,如需删除空间站请先关闭第三方集成。", "space_info_feishu_label": "第三方应用集成", "space_join_apply": "申请加入空间站「」", @@ -4983,6 +5133,7 @@ "start_onfiguration": "开始配置", "start_time": "起始时间", "start_use": "开始使用", + "starting_from_midnight": "从每天 0 点起,", "startup": "创业", "startup_company_support_program": "创业公司扶持计划", "stat_average": "平均值", @@ -5016,6 +5167,8 @@ "stay_tuned_for_more_features": "更多功能敬请期待…", "steps_choose_reset_mode": "选择重置方式", "steps_validate_identities": "验证身份", + "stop_chunk_content": "终止后将不会继续执行操作,确定终止?", + "stop_chunk_title": "终止", "stop_dingtalk_h5_modal_content": "自建应用将与本空间站解除绑定,请确认停用。", "storage_per_seats": "", "storage_per_space": "附件容量", @@ -5046,9 +5199,11 @@ "subscribe_credit_usage_over_limit": "空间站的算力点数量已耗尽,请升级你的空间站。", "subscribe_demonstrate": "预约演示", "subscribe_disabled_seat": "人数不可低于原方案", + "subscribe_grade_business": "Business", "subscribe_grade_free": "免费版", "subscribe_grade_plus": "Plus", "subscribe_grade_pro": "Pro", + "subscribe_grade_starter": "Starter", "subscribe_label_tooltip": "${grade}以上空间站专享功能", "subscribe_new_choose_member": "最高支持 ${member_num} 人", "subscribe_new_choose_member_tips": "本方案支持 1~${member_num} 名成员进入空间站使用", @@ -5185,7 +5340,7 @@ "template_name_repetition_title": "“${templateName}”已存在,确定要替换它吗?", "template_no_template": "暂无模板", "template_not_found": "找不到想要的模板? 请告诉我们~", - "template_recommend_title": "热门推荐", + "template_recommend_title": "🌟 热门推荐", "template_type": "模板", "terms_of_service": "《服务条款》", "terms_of_service_pure_string": " 服务条款", @@ -5229,6 +5384,7 @@ "text_editor_tip_end": "Enter 结束编辑", "text_functions": "文本函数", "thailand": "泰国", + "the_button_field_is_misconfigured": "按钮列配置错误,请检查后再试", "the_current_automation_workflow_has_no_related_files_you_can_establish_a_link_by_adding_trigger_conditions_and_actions_on_the_left_side": "当前自动化流程没有与之关联的文件,可以通过在左侧添加触发条件和动作来进行关联", "the_current_button_column_has_expired_please_reselect": "当前按钮列已经失效,请重新选择", "the_last_7_days": "过去 7 天", @@ -5331,6 +5487,7 @@ "timemachine_update_comment": "更新了评论", "times_per_month_unit": "次/月", "times_unit": "次", + "timing_rules": "定时规则", "timor_leste": "东帝汶", "tip_del_success": "我们将对您的空间站数据保留七天,七天内可随时撤销删除操作。", "tip_do_you_want_to_know_about_field_permission": "想对列数据加密吗?了解列权限", @@ -5518,6 +5675,7 @@ "verify_account_title": "验证账号", "verify_via_email": "通过邮箱验证码验证身份", "verify_via_phone": "通过短信验证码验证身份", + "video": "视频", "video_not_support_play": "当前视频格式不支持在线播放", "vietnam": "越南", "view": "视图", @@ -5590,7 +5748,7 @@ "vikaby_menu_hidden_vikaby": "取消悬浮", "vikaby_menu_releases_history": "历史更新", "vikaby_todo_menu1": "什么是维格表", - "vikaby_todo_menu2": "一分钟快速入门", + "vikaby_todo_menu2": "VIKA产品演示", "vikaby_todo_menu3": "玩转一张维格表", "vikaby_todo_menu4": "分享和邀请成员", "vikaby_todo_menu5": "智能引导", @@ -5675,7 +5833,7 @@ "weixin_share_card_title": "", "welcome_interface": "欢迎界面", "welcome_module1": "什么是 APITable", - "welcome_module2": "一分钟快速入门", + "welcome_module2": "VIKA产品演示", "welcome_module3": "玩转一张维格表", "welcome_module4": "内容日历", "welcome_module5": "项目管理", @@ -5866,7 +6024,7 @@ "workdoc_color_title": "字体颜色", "workdoc_create": "创建文档", "workdoc_expanded": "展开目录", - "workdoc_image_max_10mb": "图片大小不能超过10MB", + "workdoc_image_max_size": "图片大小不能超过${size}", "workdoc_info": "文档信息", "workdoc_info_create_time": "创建时间", "workdoc_info_creator": "创建人", @@ -5874,6 +6032,7 @@ "workdoc_info_last_modify_time": "修改时间", "workdoc_link_placeholder": "请输入链接", "workdoc_only_image": "只能上传图片", + "workdoc_only_video": "只能上传视频", "workdoc_text_placeholder": "输入 \"/\" 快速插入", "workdoc_title_placeholder": "请输入标题", "workdoc_unnamed": "未命名文档", @@ -5882,9 +6041,11 @@ "workdoc_unsave_ok": "确定退出", "workdoc_unsave_title": "文档未保存", "workdoc_upload_failed": "上传失败", + "workdoc_video_max_size": "视频大小不能超过${size}", "workdoc_ws_connected": "已连接", "workdoc_ws_connecting": "正在连接...", "workdoc_ws_disconnected": "连接已断开", + "workdoc_ws_reconnecting": "正在重连...", "workflow_execute_failed_notify": "执行失败,请根据运行历史排查问题,需要任何帮助或有任何疑问,请随时与客服团队联系", "workspace_data": "空间站数据", "workspace_files": "工作台数据", diff --git a/packages/datasheet/public/file/langs/strings.zh-HK.json b/packages/datasheet/public/file/langs/strings.zh-HK.json index 688d3034e8..281d798025 100644 --- a/packages/datasheet/public/file/langs/strings.zh-HK.json +++ b/packages/datasheet/public/file/langs/strings.zh-HK.json @@ -146,6 +146,15 @@ "agreed": "已同意", "ai_advanced_mode_desc": "高級模式允許用戶定製提示,從而更好地控制 AI 助手的行為和回應。", "ai_advanced_mode_title": "高級模式", + "ai_agent_anonymous": "匿名${ID}", + "ai_agent_conversation_continue_not_supported": "目前不支援繼續之前的對話", + "ai_agent_conversation_list": "對話列表", + "ai_agent_conversation_log": "對話紀錄", + "ai_agent_conversation_title": "對話標題", + "ai_agent_feedback": "回饋", + "ai_agent_historical_message": "以上為歷史消息", + "ai_agent_history": "歷史", + "ai_agent_message_consumed": "消耗的消息", "ai_api_curl_template": "## Create chat completions\n\n```bash\n\ncurl -X POST \"{{apiBase}}/fusion/v1/ai/{{aiId}}/chat/completions\" \\n -H \"Content-Type: application/json\" \\n -H \"Authorization: Bearer {{token}}\" \\n -d '{\n \"model\": \"gpt-3.5-turbo\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"You are a helpful assistant.\"\n },\n {\n \"role\": \"user\",\n \"content\": \"Hello!\"\n }\n ]\n }'\n\n```\n\n## Returned data example\n\n```json\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", "ai_api_footer_desc": "將 AI 助手嵌入您的網站?瞭解更多", "ai_api_javascript_template": "## Initialize SDK [![github]({{ githubIcon }})](https://github.com/openai/openai-node)\nAITable's chat completion API is compatible with OpenAI's Node.js SDK. You can use our service with the same SDK by simply changing the configuration as follows:\n\n\n```javascript\nconst { Configuration, OpenAIApi } = require(\"openai\");\nconst configuration = new Configuration({\n apiKey: \"{{token}}\",\n basePath: \"{{apiBase}}/fusion/v1/ai/{{aiId}}\"\n});\n```\n\n## Create chat completions\n\n```javascript\nconst openai = new OpenAIApi(configuration);\nconst chatCompletion = await openai.createChatCompletion({\n model: \"gpt-3.5-turbo\",\n messages: [{role: \"user\", content: \"Hello world\"}],\n});\n```\n\n## Returned data example\n\n```javascript\n\n{\n \"id\": \"aitable_ai_CkZH2zQokhry31j_1693452659\",\n \"conversation_id\": \"CS-0253eb8d-d6c6-4543-88d4-fcb555f52982\",\n \"actions\": null,\n \"object\": \"chat.completion\",\n \"created\": 1693452659,\n \"model\":\"gpt-3.5-turbo\",\n \"choices\": [{\n \"index\": 0,\n \"message\": {\n \"role\": \"assistant\",\n \"content\": \"\\n\\nHello there, how may I assist you today\",\n },\n \"finish_reason\": \"stop\"\n }],\n \"usage\": {\n \"prompt_tokens\": 9,\n \"completion_tokens\": 12,\n \"total_tokens\": 21,\n \"total_cost\": 7.900000000000001e-05,\n \"result\": \"I am an AI, specifically a language model developed by OpenAI.\"\n }\n}\n```\n", @@ -161,6 +170,9 @@ "ai_chat_unit": "ai助理(S)", "ai_close_setting_tip_content": "您所做的更改尚未保存,是否要丟棄?", "ai_close_setting_tip_title": "未保存的更改", + "ai_copilot_generate_response": "為您生成答案...", + "ai_copilot_processs": "處理中,請稍候...", + "ai_copilot_start_process_request": "開始處理您的請求...", "ai_create_guide_btn_text": "選擇表格", "ai_create_guide_content": "作為一名 AI 助手,我可以根據我所學的知識回答您的問題。在開始對話之前,請選擇一份數據表作為知識庫,我將閱讀其中的所有數據以供學習。", "ai_credit_cost_chart_title": "信貸成本", @@ -629,7 +641,7 @@ "apps_support": "全平台客戶端支持", "archive_delete_record": "刪除存檔記錄", "archive_delete_record_title": "刪除記錄", - "archive_notice": "

您正在嘗試存檔特定記錄。存檔記錄將導致以下變更:

1. 該記錄的所有雙向關聯將被取消

2. 不支援編輯

3.不支援日期提醒、訂閱記錄等功能

4.不再參與神奇引用、公式等字段的計算

你確定你要繼續嗎?(在高級能力裡的存檔箱中可以取消歸檔)

", + "archive_notice": "

您正在嘗試歸檔特定記錄。歸檔記錄將導致以下變更:

1.不支援編輯

2.不支援日期提醒、訂閱記錄等功能

3.不再參與lookup、formula等字段的計算

你確定你要繼續嗎? (您可以在「進階」的「存檔箱」中取消存檔)

", "archive_record_in_activity": "已將此記錄存檔", "archive_record_in_menu": "存檔記錄", "archive_record_success": "成功存檔記錄", @@ -689,6 +701,8 @@ "audit_add_field_role_detail": "在裡面 ” “ 數據表, 添加 [ ] 角色為 [ ] 對於字段 [ ]", "audit_add_node_role": "添加文件節點權限", "audit_add_node_role_detail": "添加文件節點權限,將「${unitNames}」設置為「${currentNodeName}」的「${role}」角色", + "audit_add_node_role_detail_end": "to「${role}", + "audit_add_node_role_detail_start": "Add file node permission,set「${unitNames}」", "audit_admin_permission_change_event": "管理員權限變更", "audit_create_template": "創建模板", "audit_create_template_detail": "創建模板內容", @@ -697,20 +711,30 @@ "audit_delete_field_role_detail": "審計內容", "audit_delete_node_role": "刪除文件節點權限", "audit_delete_node_role_detail": "刪除文件節點權限,將「${unitNames}」在「${currentNodeName}」的「${role}」角色刪除", + "audit_delete_node_role_detail_end": "at 「${role}」role", + "audit_delete_node_role_detail_start": "Delete file node permission,delete「${unitNames}」from", "audit_delete_template": "刪除模板", "audit_delete_template_detail": "刪除模板內容", "audit_disable_field_role": "關閉列權限", "audit_disable_field_role_detail": "審計內容", "audit_disable_node_role": "關閉文件權限", "audit_disable_node_role_detail": "關閉${nodeType}權限,名稱為「${currentNodeName}」", + "audit_disable_node_role_detail_end": "`s permission", + "audit_disable_node_role_detail_start": "Disable ${nodeType}", "audit_disable_node_share": "關閉文件節點公開鏈接", "audit_disable_node_share_detail": "關閉${nodeType} 「${currentNodeName}」 的公開鏈接", + "audit_disable_node_share_detail_end": "public link", + "audit_disable_node_share_detail_start": "Close ${nodeType}", "audit_enable_field_role": "開啟列權限", "audit_enable_field_role_detail": "審計內容", "audit_enable_node_role": "開啟文件權限", "audit_enable_node_role_detail": "開啟${nodeType}權限,名稱為 「${currentNodeName}」", + "audit_enable_node_role_detail_end": "`s permission", + "audit_enable_node_role_detail_start": "Enable ${nodeType}", "audit_enable_node_share": "開啟文件節點公開鏈接", "audit_enable_node_share_detail": "開啟${nodeType} 「${currentNodeName}」 的公開鏈接", + "audit_enable_node_share_detail_end": "public link", + "audit_enable_node_share_detail_start": "Open ${nodeType}", "audit_login_event": "登錄事件", "audit_logout_event": "註銷事件", "audit_organization_change_event": "通訊錄組織架構變更", @@ -731,18 +755,25 @@ "audit_space_invite_user_detail": "審計內容", "audit_space_node_copy": "複製文件節點", "audit_space_node_copy_detail": "複製${nodeType}「${sourceNodeName}」,新文件節點名稱為「${currentNodeName}」", + "audit_space_node_copy_detail_start": "Duplicate ${nodeType} 「${sourceNodeName}」, the new file node's name is", "audit_space_node_create": "創建文件節點", "audit_space_node_create_detail": "創建${nodeType},名稱為「${currentNodeName}」", + "audit_space_node_create_detail_start": "Create a ${nodeType} named", "audit_space_node_delete": "刪除文件節點", "audit_space_node_delete_detail": "刪除${nodeType},名稱為「${currentNodeName}」", + "audit_space_node_delete_detail_start": "Delete ${nodeType} named", "audit_space_node_export": "導出數表", "audit_space_node_export_detail": "成員 ${member_name} 導出表 ${node_name}", "audit_space_node_import": "導入文件節點", "audit_space_node_import_detail": "導入文件節點,名稱為 「${nodeName}」", + "audit_space_node_import_detail_start": "Import a file node named", "audit_space_node_move": "移動文件節點", "audit_space_node_move_detail": "移動${nodeType}「${currentNodeName}」到文件夾「${parentName}」下方", + "audit_space_node_move_detail_end": "to the folder「${parentName}」", + "audit_space_node_move_detail_start": "Move ${nodeType}", "audit_space_node_rename": "重命名文件節點", "audit_space_node_rename_detail": "重命名${nodeType},將「${oldNodeName}」名稱修改為「${nodeName}」", + "audit_space_node_rename_detail_start": "Rename ${nodeType} 「${oldNodeName}」to", "audit_space_node_sort": "審計內容", "audit_space_node_sort_detail": "審計內容", "audit_space_node_update_cover": "審計內容", @@ -757,17 +788,24 @@ "audit_space_rubbish_node_delete_detail": "審計內容", "audit_space_rubbish_node_recover": "恢復回收艙節點", "audit_space_rubbish_node_recover_detail": "從回收艙恢復${nodeType},名稱為「${currentNodeName}」", + "audit_space_rubbish_node_recover_detail_end": "from the trash", + "audit_space_rubbish_node_recover_detail_start": "Restore ${nodeType}", "audit_space_template_event": "空間站模板事件", "audit_space_update_logo": "審計內容", "audit_space_update_logo_detail": "審計內容", "audit_store_share_node": "轉存文件節點", "audit_store_share_node_detail": "將${nodeType}轉存到本空間站,名稱為 「${nodeName}」", + "audit_store_share_node_detail_start": "Restore ${nodeType} to the space, name is", "audit_update_field_role": "審計內容", "audit_update_field_role_detail": "審計內容", "audit_update_node_role": "修改文件節點權限", "audit_update_node_role_detail": "修改文件節點權限,將「${unitNames}」修改為「${currentNodeName}」的「${role}」角色", + "audit_update_node_role_detail_end": "to「${role}」role", + "audit_update_node_role_detail_start": "Modify file node permission,modify「${unitNames}」from", "audit_update_node_share_setting": "修改文件節點公開鏈接", "audit_update_node_share_setting_detail": "修改${nodeType} 「${currentNodeName}」 的公開鏈接的設置", + "audit_update_node_share_setting_detail_end": "public link settings", + "audit_update_node_share_setting_detail_start": "Modify ${nodeType}", "audit_user_login": "用戶登錄", "audit_user_login_detail": "審計內容", "audit_user_logout": "用戶登出", @@ -809,6 +847,7 @@ "automation_enabled_return_via_related_files": "自動化已啟用。請透過「相關文件」重新輸入原始表格以使用新按鈕。", "automation_field": "字段", "automation_import_variables_from_pre_tep": "Get data from the pre-step", + "automation_is_not_yet_enabled": "自動化尚未啟用,請啟用它並重試", "automation_last_edited_by": "Last edited by", "automation_last_edited_time": "Last edited time", "automation_manager_label": "可以執行自動化上的所有操作", @@ -834,6 +873,7 @@ "automation_runs_this_month": "Runs this month", "automation_stay_tuned": "Stay tuned", "automation_success": "成功", + "automation_tips": "按鈕欄位配置錯誤,請檢查並重試", "automation_updater_label": "可以查看自動化的運行歷史記錄", "automation_variabel_empty": "前一步沒有可以使用的數據,請調整後重試。", "automation_variable_datasheet": "從 ${NODE_NAME} 取得數據", @@ -869,6 +909,7 @@ "bermuda": "百慕大群島", "bhutan": "不丹", "billing_over_limit_tip_common": "空間使用量已超過限制,升級後可享有更高的空間使用量。", + "billing_over_limit_tip_forbidden": "您的試用期或訂閱期已過期。請聯絡銷售顧問續訂。", "billing_over_limit_tip_widget": "小組件安裝數量已超出限制,您可以升級以獲得更高的使用量。", "billing_period": "計費周期:${period}", "billing_subscription_warning": "功能體驗", @@ -928,10 +969,19 @@ "button_text": "按鈕文字", "button_text_click_start": "點擊開始", "button_type": "按鈕類型", + "by_at": "在", + "by_days": "天", + "by_every": "每一個", "by_field_id": "使用 Field ID", + "by_hours": "小時", + "by_in": "在", + "by_min": "分鐘)", + "by_months": "幾個月", + "by_on": "於", "by_the_day": "按天", "by_the_month": "按月", "by_the_year": "每年", + "by_weeks": "週數", "calendar_add_date_time_field": "創建日期", "calendar_color_more": "更多顏色", "calendar_const_detail_weeks": "[\"星期一\",\"星期二\",\"星期三\",\"星期四\",\"星期五\",\"星期六\",\"星期天\"]", @@ -995,6 +1045,14 @@ "cannot_activate_space_by_space_limit": "已激活空間站數量達到上限,刪除或退出已激活的空間站後,可手動激活", "cannot_join_space": "你的空間站數量已達10個上限,暫時無法加入新的空間站。", "cannot_switch_field_permission": "設置的列權限不能高於 TA 的文件權限,請先提高 TA 的文件權限", + "capacity_file_detail_desc": "The total number of file nodes within the Space is calculated by adding the file nodes from the Team to the file nodes created by each member in their Private. Not enough capacity?", + "capacity_file_detail_title": "File Capacity", + "capacity_file_member": "Member", + "capacity_file_member_private_node_count": "Private", + "capacity_file_member_private_percent": "Percent", + "capacity_file_member_team": "Team", + "capacity_file_member_team_node_count": "Team", + "capacity_file_upgrade": "Click to upgrade your Space", "capacity_from_official_gift": "來自官方贈送", "capacity_from_participation": "受邀 ${user} 加入空間", "capacity_from_purchase": "按採購能力", @@ -1031,6 +1089,8 @@ "catalog": "工作目錄", "catalog_add_from_template_btn_title": "從模板添加", "catalog_empty_tips": "這個工作區現在是空的。 開始使用模板創建文件。", + "catalog_private": "Private", + "catalog_team": "Team", "category_blank": "[空值]", "catering": "餐飲業", "cayman_islands": "開曼群島", @@ -1099,6 +1159,7 @@ "choose_type_of_vika_field": "選擇維格列類型", "choose_your_own_space": "(僅支持另存到自己是主管理員的空間站)", "chose_new_primary_admin_button": "確認移交", + "chunk_stopping_title": "Stopping", "claim_special_offer": "索取此特別優惠!", "clear": "清除", "clear_all_fields": "重置", @@ -1229,6 +1290,7 @@ "confirm_del_current_team": "確認是否刪除當前小組", "confirm_delete": "確認刪除", "confirm_delete_node_name_as": "確認要刪除「${nodeNameDiv}」嗎?", + "confirm_delete_private_node_name_as": "Are you sure you want to delete \"${nodeNameDiv}\"? The file will be deleted from the Space and the trash.", "confirm_delete_space_btn": "了解並繼續刪除", "confirm_exit": "確認退出", "confirm_exit_space_with_name": "確認是否退出「${spaceNameDiv}」空間站\n", @@ -1266,6 +1328,14 @@ "convert": "轉換", "convert_tip": "此操作可能會清除某些單元格內已有的數據,如果轉換有問題,則可以撤銷該操作", "cook_islands": "庫克群島", + "copilot_auto_agent_desc": "不確定選擇哪一個代理?嘗試自動代理。", + "copilot_auto_agent_name": "自動代理", + "copilot_data_agent_desc": "根據您的觀點生成數據分析/可視化。", + "copilot_data_agent_name": "數據代理", + "copilot_data_agent_policy": "與 Copilot 聊天時,即表示您同意使用者條款政策", + "copilot_data_agent_policy_button": "政策", + "copilot_help_agent_desc": "詢問有關AITable幫助中心文件的任何問題。", + "copilot_help_agent_name": "檢索幫助中心", "copy": "的副本", "copy_automation_url": "複製 URL", "copy_card_link": "複製該記錄的 URL", @@ -1310,6 +1380,7 @@ "create_mirror_guide_content": "鏡像功能具有隱藏某些數據的能力。 您可以在原始數據表視圖中設置“過濾條件”和“隱藏字段”來控制在鏡像中顯示哪些記錄和字段。\n
\n
\n如果與“視圖鎖定”功能配合使用,可以防止他人進行修改。\n
\n
\n另外,您可以在“原始表>隱藏字段”中修改“在鏡像中顯示所有字段”的配置。", "create_mirror_guide_title": "鏡像隱藏了一些記錄和字段", "create_new_button_field": "建立一個新的按鈕列字段", + "create_private_node_tip": "Personal or temporary draft documents can be created here ${link}", "create_public_invitation_link": "創建公開的邀請鏈接", "create_space_sub_title": "Hi,給你的空間站起個名字吧", "create_team_fail": "添加小組失敗", @@ -1373,10 +1444,12 @@ "custom_enterprise": "企業級空間站支持自定義人數、時長,靈活又強大", "custom_function_development": "定制功能開發", "custom_grade_desc": "提供代理部署、私人安裝、協助支持和定制化專業服務", + "custom_page_setting_title": "Add a custom page", "custom_picture": "自定義圖片", "custom_style": "樣式", "custom_upload": "自定義上傳", "custom_upload_tip": "推薦使用 1:1 的方形圖片以達到更好的視覺體驗", + "custome_page_title": "Custom Web", "cut_cell_data": "剪切", "cyprus": "塞浦路斯", "czech": "捷克", @@ -1428,6 +1501,7 @@ "default": "默認", "default_create_ai_chat_bot": "新建 AI 助手", "default_create_automation": "新自動化", + "default_create_custom_page": "新建自定義頁面", "default_create_dashboard": "新建儀錶盤", "default_create_datasheet": "新建維格表", "default_create_file": "新建節點", @@ -1449,6 +1523,7 @@ "del_invitation_link": "確定刪除邀請鏈接", "del_invitation_link_desc": "刪除後已生成的分享鏈接將會失效", "del_space_now": "徹底刪除空間站", + "del_space_now_confirm_tip": "For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "del_space_now_tip": "請注意:空間站刪除後將不可恢復,包含所有表格、附件都會被徹底刪除", "del_space_res_tip": "刪除空間站成功", "del_team_success": "刪除小組成功", @@ -1644,6 +1719,62 @@ "embed_error_page_help": "點擊了解失效原因", "embed_fail_og_description_content": "該嵌入的公開鏈接已被關閉,暫時無法訪問", "embed_failed": "嵌入鏈接已失效,", + "embed_link_bilibili": "嗶哩嗶哩", + "embed_link_bilibili_desc": "透過嵌入bilibili視頻,您可以在Vika中觀看教程和指南,或查看頻道首頁。", + "embed_link_bilibili_link_text": "如何嵌入bilibili視頻", + "embed_link_bilibili_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-bilibili-video", + "embed_link_default": "任何事物", + "embed_link_default_desc": "貼上連結以查看任何網站。", + "embed_link_default_link_text": "了解更多", + "embed_link_default_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_link_figma": "Figma", + "embed_link_figma_desc": "透過嵌入Figma文件,成員可以更方便地查看和編輯設計稿,提高協作效率。", + "embed_link_figma_link_text": "如何嵌入 Figma 文件", + "embed_link_figma_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-figma-file", + "embed_link_google_docs": "Docs", + "embed_link_google_docs_desc": "透過嵌入Google Docs,您可以在AITable中編輯和查看文檔,以方便團隊協作。", + "embed_link_google_docs_link_text": "如何嵌入 Google 文件", + "embed_link_google_docs_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-docs-file", + "embed_link_google_sheets": "Sheets", + "embed_link_google_sheets_desc": "透過嵌入Google Sheets,您可以在AITable中編輯和檢視表格,以促進團隊協作。", + "embed_link_google_sheets_link_text": "如何嵌入 Google Sheets", + "embed_link_google_sheets_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-google-sheets-file", + "embed_link_jishi_design": "JS設計", + "embed_link_jishi_design_desc": "透過嵌入JSdesign文件,成員可以更方便地查看和編輯設計稿,提高協作效率。", + "embed_link_jishi_design_link_text": "如何嵌入 JSdesign 文件", + "embed_link_jishi_design_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-js-design-file", + "embed_link_tencent_docs": "騰訊文檔", + "embed_link_tencent_docs_desc": "透過嵌入騰訊文檔,您可以在Vika中編輯、查看騰訊文檔,提高協作效率。", + "embed_link_tencent_docs_link_text": "如何嵌入騰訊文檔", + "embed_link_tencent_docs_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-tencent-docs", + "embed_link_wps": "WPS", + "embed_link_wps_desc": "透過嵌入WPS文件,您可以在Vika中編輯並檢視WPS文件、表格和表單,提高協作效率。", + "embed_link_wps_link_text": "如何嵌入WPS文件", + "embed_link_wps_link_url": "https://help.vika.cn/docs/guide/manual-custom-page#how-to-add-wps-file", + "embed_link_youtube": "Youtube", + "embed_link_youtube_desc": "透過嵌入 YouTube 視頻,您可以觀看教程和指南,或查看 AITable 中的頻道主頁。", + "embed_link_youtube_link_text": "如何嵌入 YouTube 影片", + "embed_link_youtube_link_url": "https://help.aitable.ai/docs/guide/manual-custom-page#how-to-add-a-youtube-video", + "embed_page": "自定義頁面", + "embed_page_add_url": "新增網址", + "embed_page_doc_url": "https://help.aitable.ai/docs/guide/manual-custom-page", + "embed_page_function_desc": "將網頁加入${edition}中,以便輕鬆存取第三方網站文件、影片等。您可以新增推薦的網站連結或任何自定義連結。", + "embed_page_node_permission_editor": "在「僅更新」的基礎上,還可以開啟檔案的公開共享", + "embed_page_node_permission_manager": "可以對檔案執行所有操作", + "embed_page_node_permission_reader": "可以查看自定義頁面的內容和基本文件訊息", + "embed_page_node_permission_updater": "在「唯讀」的基礎上,也可以修改自定義頁面的連結", + "embed_page_setting_title": "新增自定義頁面", + "embed_page_url_invalid": "請輸入正確的網址", + "embed_paste_link_bilibili_placeholder": "貼上bilibili視頻鏈接", + "embed_paste_link_default_placeholder": "貼上網址", + "embed_paste_link_figma_placeholder": "貼上 Figma 檔案的共享鏈接", + "embed_paste_link_google_docs_placeholder": "貼上 Google 文件共享連結", + "embed_paste_link_google_sheets_placeholder": "貼上 Google 試算表共享鏈接", + "embed_paste_link_jsdesign_placeholder": "貼上 JSdesign 檔案的共享鏈接", + "embed_paste_link_tencent_docs_placeholder": "貼上騰訊文檔分享鏈接", + "embed_paste_link_wps_placeholder": "貼上 WPS 檔案的共享鏈接", + "embed_paste_link_youtube_placeholder": "貼上 YouTube 影片連結", + "embed_success": "添加成功", "emoji_activity": "活動和事件", "emoji_custom": "自定義", "emoji_flags": "旗幟", @@ -1750,6 +1881,11 @@ "estonia": "愛沙尼亞", "ethiopia": "埃塞俄比亞", "event_planning": "活動策劃", + "every": "每一個", + "every_day_at": "天在", + "every_hour_at": "小時於", + "every_month_at": "月", + "every_week_at": "每週於", "everyday_life": "日常生活", "everyone_visible": "全員可見", "exact_date": "指定日期", @@ -1760,6 +1896,7 @@ "exchange": "兌換", "exchange_code_times_tip": "請注意,兌換碼只能兌換一次", "exclusive_consultant": "專屬 V+ 顧問", + "exclusive_limit_plan_desc": "獨家限量等級", "exist_experience": "退出體驗", "exits_space": "退出空間", "expand": "展開", @@ -1786,7 +1923,7 @@ "expired": "已過期", "export": "正在導出…", "export_brand_desc": "提供技術支持", - "export_current_preview_view_data": "", + "export_current_preview_view_data": "Export current preview view data", "export_gantt_button_tips": "導出為圖片", "export_gantt_chart": "導出甘特圖", "export_to_excel": "導出為 Excel 文件", @@ -2458,6 +2595,7 @@ "gold_grade": "黃金級", "gold_grade_desc": "適用於有復雜業務流程的團隊或組織", "gold_seat_200_desc": "200", + "gold_seat_300_desc": "300", "golden_grade": "黃金級", "got_it": "知道了", "got_v_coins": "已獲得 V 幣獎勵", @@ -2491,6 +2629,8 @@ "guests_per_space": "外部訪客", "guide_1": "來呀互相傷害呀", "guide_2": "花費幾分鐘跟隨我們的指引,學習一下維格表的常規功能,可以讓您事半功倍哦!", + "guide_flow_modal_contact_sales": "聯繫銷售人員", + "guide_flow_modal_get_started": "開始使用", "guide_flow_of_catalog_step1": "這是工作目錄,裡邊存放的是空間站的所有文件夾和文件", "guide_flow_of_catalog_step2": "工作目錄裡面,除了可以單獨創建維格表,也可以單獨創建文件夾", "guide_flow_of_click_add_view_step1": "除了基本的維格視圖之外,我們支持創建相冊視圖,如果你有圖片附件的話,我建議你創建個相冊視圖試試", @@ -2669,6 +2809,7 @@ "intro_widget_tips": "什麼是小程序?", "introduction": "簡介", "invalid_action_sort_tip": "該字段作為分組項已被設置排序,當前設置的排序不會生效", + "invalid_automation_configuration": "自動化配置無效,請檢查並重試", "invalid_field_type": "非法的字段類型", "invalid_option_sort_tip": "該字段作為分組項已被設置排序", "invalid_redemption_code_entered": "請輸入有效的兌換碼", @@ -2799,6 +2940,9 @@ "label_format_day_month_and_year_split_by_slash": "日/月/年", "label_format_month": " 月", "label_format_month_and_day_split_by_dash": "月-日", + "label_format_month_day_year_split_by_dash": "Month-Day-Year", + "label_format_month_day_year_split_by_slash": "Month/Day/Year", + "label_format_month_day_year_two_digit_year_split_by_slash": "Month/Day/Year (Two-digit year)", "label_format_year": "年", "label_format_year_and_month_split_by_dash": "年-月", "label_format_year_month_and_day_split_by_dash": "年-月-日", @@ -2877,6 +3021,7 @@ "lark_version_enterprise": "飛書企業版", "lark_version_standard": "飛書標準版", "lark_versions_free": "飛書基礎版", + "last_day": "最後一天", "last_modified_by_select_modal_desc": "由於該維格列類型的特殊性,下方只展示可編輯的列,每當有人在指定的列進行過修改,則會更新當前的修改人", "last_modified_time_select_modal_desc": "由於該維格列類型的特殊性,下方只展示可編輯的列,每當有人在指定的列進行過修改,則會更新當前的修改時間", "last_step": "上一步", @@ -3021,7 +3166,7 @@ "mail_invite_fail": "邀請成員失敗", "mail_invite_success": "邀請成員成功", "main_admin_name": "主管理員名稱", - "main_admin_page_desc": "擁有空間站的最高管理權限,可以分配子管理員或轉讓空間站", + "main_admin_page_desc": "主管理员具有完整的訪問權限,可以分配子管理員,或調整空間站設置。", "main_contain": "主要內容", "malawi": "馬拉維", "malaysia": "馬來西亞", @@ -3241,8 +3386,12 @@ "more_widget": "更多小程序", "morocco": "摩洛哥", "move": "移動", + "move_datasheet_link_warn": "Cannot be moved to Team Area alone, because there is a two-way link from the current datasheet to another datasheet, it is recommended to put them in a folder and then move them", "move_favorite_node_fail": "移動節點失敗,系統將會自動更新列表", + "move_folder_link_warn": "Cannot be moved to Team Area because the files in the current folder are linked to files outside the folder (may be two-way links or linked by forms, etc.) We recommend that they be placed in a folder before moving", "move_node_modal_content": "移動後,文件的可見性可能會受到上級文件夾的影響", + "move_other_link_no_permission": "Unable to move to the corresponding folder because you do not have administrative rights to the folder", + "move_other_link_warn": "It is not allowed to move ${node type} to Team Area alone, because it connects to the datasheet of Private Area, it is recommended to put them in a folder before moving them", "move_to": "搬去", "move_to_error_equal_parent": "該文件位於當前文件夾下。 請選擇另一個文件夾", "move_to_modal_title": "將【${name}】移動至", @@ -3273,7 +3422,9 @@ "new_a_line": "Shift+Enter 換行", "new_automation": "New automation", "new_caledonia": "新喀裡多尼亞", + "new_custom_page": "New custom page", "new_datasheet": "新建維格表", + "new_ebmed_page": "新的自定義頁面", "new_folder": "新建文件夾", "new_folder_btn_title": "文件夾", "new_folder_tooltip": "建立資料夾", @@ -3439,7 +3590,7 @@ "nvc_start_text": "請按住滑塊,拖動到最右邊", "nvc_yes_text": "驗證通過", "obtain_verification_code": "未獲取驗證碼或已過期,請重新獲取", - "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrzw0miJVmSkJ7eBBa9k/fomx5qPX0JGPFvfEEP\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", + "offical_website_footer_nav_data": "[{\n \"title\": \"产品\",\n \"lists\": [{\n \"name\": \"快速入门\",\n \"url\": \"https://help.vika.cn/docs/guide/tutorial-1-quick-start\"\n }, {\n \"name\": \"产品指南\",\n \"url\": \"https://help.vika.cn/docs/guide/manual-1-what-is-vikadata\"\n }, {\n \"name\": \"产品价格\",\n \"url\": \"/pricing/\"\n }, {\n \"name\": \"产品路线图\",\n \"url\": \"https://vika.cn/share/shrvp76H9lQBFLaRG1wSY/dstB1RtGAw5qMoqnnY/viw9giKo0IcT5\"\n }]\n}, {\n \"title\": \"关于我们\",\n \"lists\": [{\n \"name\": \"公司介绍\",\n \"url\": \"/company/\"\n }, {\n \"name\": \"加入我们\",\n \"url\": \"/join-us/\"\n }, {\n \"name\": \"媒体报道\",\n \"url\": \"/press/\"\n }, {\n \"name\": \"vika维格课堂\",\n \"url\": \"https://edu.vika.cn/\"\n }, {\n \"name\": \"维格合伙人\",\n \"url\": \"/partners/\"\n }]\n}, {\n \"title\": \"解决方案\",\n \"lists\": [{\n \"name\": \"PMO项目群管理\",\n \"url\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"url\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"url\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"url\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"url\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"url\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"url\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"url\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"url\": \"/shop/\"\n }]\n}, {\n \"title\": \"支持\",\n \"lists\": [{\n \"name\": \"意见反馈\",\n \"url\": \"https://vika.cn/share/shrCvbFC53xc3kl00B4Pg\"\n }, {\n \"name\": \"帮助中心\",\n \"url\": \"https://help.vika.cn/\"\n }, {\n \"name\": \"开发者中心\",\n \"url\": \"/developers/\"\n }, {\n \"name\": \"服务条款\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"隐私协议\",\n \"url\": \"/service-agreement/\"\n }, {\n \"name\": \"安全与合规\",\n \"url\": \"/security/\"\n }]\n}, {\n \"title\": \"服务\",\n \"lists\": [{\n \"name\": \"加入社群\",\n \"url\": \"/chatgroup/\"\n }, {\n \"name\": \"Github开源\",\n \"url\": \"https://github.com/vikadata\"\n }, {\n \"name\": \"预约演示\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"专有云部署\",\n \"url\": \"https://vika.cn/share/shrVrGPclBql6w9ysUHzR/fomed5397fFJfdcRvL\"\n }, {\n \"name\": \"应用连接\",\n \"url\": \"/connections/\"\n }]\n}, {\n \"title\": \"联系我们\",\n \"lists\": [{\n \"name\": \"地址:深圳市南山区国信投资大厦1710\",\n \"url\": \"https://ditu.amap.com/place/B0FFJ14BJ7\"\n }, {\n \"name\": \"售前咨询:点击联系商务\",\n \"url\": \"https://vika.cn/share/shrlRw3YWmqZ4BMl0B7qZ/fomUMtKMblNchCG7Ef\"\n }, {\n \"name\": \"合作:bd@vikadata.com\",\n \"url\": \"mailto:bd@vikadata.com\"\n }, {\n \"name\": \"媒体:pr@vikadata.com\",\n \"url\": \"mailto:pr@vikadata.com\"\n }, {\n \"name\": \"招聘:hr@vikadata.com\",\n \"url\": \"mailto:hr@vikadata.com\"\n }]\n}]", "offical_website_nav_data": "[{\n \"name\": \"产品\",\n \"href\": \"/login\",\n \"children\": [\n {\n \"name\": \"vika维格表 Overview\",\n \"href\": \"/login/\"\n },\n {\n \"name\": \"应用连接 Integration\",\n \"href\": \"/connections/\"\n },\n {\n \"name\": \"客户端(Beta) Download\",\n \"href\": \"/download/\"\n }\n ]\n}, {\n \"name\": \"解决方案\",\n \"href\": \"/\",\n \"children\": [{\n \"name\": \"PMO项目群管理\",\n \"href\": \"/business-pmo/\"\n }, {\n \"name\": \"智慧电商运营\",\n \"href\": \"/ecommerce/\"\n }, {\n \"name\": \"CRM客户管理\",\n \"href\": \"/crm/\"\n }, {\n \"name\": \"HR人力资源管理\",\n \"href\": \"/hr/\"\n }, {\n \"name\": \"Scrum敏捷开发管理\",\n \"href\": \"/scrum/\"\n }, {\n \"name\": \"营销策划与市场运营\",\n \"href\": \"/marketing/\"\n }, {\n \"name\": \"OKR目标管理\",\n \"href\": \"/okr/\"\n }, {\n \"name\": \"教育培训管理\",\n \"href\": \"/education/\"\n }, {\n \"name\": \"智慧门店管理\",\n \"href\": \"/shop/\"\n }, {\n \"name\": \"更多解决方案 >\",\n \"href\": \"/solutions/\"\n }]\n}, {\n \"name\": \"模板/案例\",\n \"href\": \"/template\",\n \"children\": [\n {\n \"name\": \"模板中心 Tempaltes\",\n \"href\": \"/template\"\n },\n {\n \"name\": \"客户案例 Customers\",\n \"href\": \"/cases/\"\n }\n ]\n},\n {\n \"name\": \"首页\",\n \"href\": \"/?home=1\"\n },\n {\n \"name\": \"学习资源\",\n \"href\": \"https://edu.vika.cn/index\",\n \"children\": [\n {\n \"name\": \"快速入门 Tutorials\",\n \"href\": \"https://help.vika.cn/docs/guide/tutorial\"\n },\n {\n \"name\": \"产品手册 Manual\",\n \"href\": \"https://help.vika.cn/docs/guide/manual\"\n },\n {\n \"name\": \"维格课堂 Vika Education\",\n \"href\": \"https://edu.vika.cn/\"\n },\n {\n \"name\": \"维格社区 Vika BBS\",\n \"href\": \"https://bbs.vika.cn/\"\n },\n {\n \"name\": \"第三方连接 Integration\",\n \"href\": \"https://help.vika.cn/docs/guide/connection\"\n },\n {\n \"name\": \"开发者中心 Developer Center\",\n \"href\": \"/developers/\"\n },\n {\n \"name\": \"常见问题 FAQ\",\n \"href\": \"https://help.vika.cn/docs/guide/questions\"\n }\n ]\n }]", "office_preview": "Office 文件預覽", "office_preview_app_desc": "

在維格表裡提供無縫的 office 文件在線預覽能力, 讓你可以隨時隨地使用 PC 或手機查看 Excel、Word、PPT 等常見的 office 文件

\n\n
  • 支持在線預覽 .doc、.docx、.xls、.xlsx、.ppt、.pptx 和 .pdf 格式的 office 文件
  • 桌面端和移動端同步支持對上述格式的文件預覽\n
\n\n

補充說明:

\n
  • 該功能由「永中云轉換」提供技術支持,維格表官方進行集成
  • 點擊下方 “授權” 按鈕,表示啟用本應用,並同意「永中云轉換」讀取你將要預覽的 office 文件
  • 如不再需要 office 預覽功能,管理員可再次訪問此頁面進行停用操作
", @@ -3479,6 +3630,7 @@ "open_auto_save_success": "開啟自動保存視圖配置成功", "open_auto_save_warn_content": "所有成員修改當前視圖配置會自動保存並同步給其他成員。 (視圖配置包括:篩選、分組、排序、隱藏列、佈局、樣式等)", "open_auto_save_warn_title": "開啟自動保存視圖配置", + "open_automation_time_arrival": "https://aitable.ai/contact-sales-open-source", "open_failed": "查看失敗", "open_in_new_tab": "新標籤頁打開", "open_invite_after_operate": "打開邀請成員後,全體成員可以在“通訊錄面板”進行邀請成員操作", @@ -3625,6 +3777,8 @@ "payment_record": "支付記錄", "payment_reminder": "支付提醒", "payment_reminder_content": "你所選擇的新方案抵扣金額大於待支付金額,建議你選擇更長時長的新方案。如果你確認這樣做,超出的金額將不能退還。如有疑問請 ${action}", + "payment_reminder_modal_content": "您可以嘗試進階版本,享受更多檔案節點、企業權限、附件容量、資料量、AI等進階功能和特權。", + "payment_reminder_modal_title": "您目前使用的是免費版本", "pending_invite": "待邀請", "people": "人", "per_person_per_year": "每人每年", @@ -3789,12 +3943,12 @@ "player_step_ui_config_163": "", "player_step_ui_config_164": "", "player_step_ui_config_165": "{\n \"headerImg\": \"https://s4.vika.cn/space/2023/03/16/8374ca1295664675bd1155b077555113\",\n \"readMoreUrl\": \"https://help.vika.cn/changelog/23-03-16-updates\",\n \"children\": \"

🚀 Introduction of new functions

\\n
  • The mirror is upgraded again, hiding sensitive fields and collaborating with peace of mind
  • The time zone of the user account is online, and the time zone of the date list can be set independently, making cross-time zone cooperation smoother.
  • \"Global Search\" experience optimization, new search result categories
  • Gold-level space station benefits are increased, and the sharing form supports hiding official logos
  • API interface performance optimization, greatly improving call efficiency
\"\n}", - "player_step_ui_config_166": "{\n \"title\": \"恭喜你!獲得試用權益\",\n \"description\": \"你獲得了14天Enterprise版本的試用權益,你可以點擊按鈕查看詳情\", \n \"listHeader\": \"試用權益:\",\n \"listContent\": [\n \"空間站記錄總數上限提高至500,000,000 行\",\n \"空間站附件容量數提高至50 GB\",\n \"支持調用所有高級API\"\n ],\n \"listFooter\": \"更多權益\",\n \"url\": \"https://aitable.ai/management/upgrade\n}", + "player_step_ui_config_166": "{\n \"title\": \"恭喜你!獲得試用權益\",\n \"description\": \"你獲得了14天Enterprise版本的試用權益,你可以點擊按鈕查看詳情\", \n \"listHeader\": \"試用權益:\",\n \"listContent\": [\n \"空間站記錄總數上限提高至500,000,000 行\",\n \"空間站附件容量數提高至50 GB\",\n \"支持調用所有高級API\"\n ],\n \"listFooter\": \"更多權益\",\n \"url\": \"https://aitable.ai/management/upgrade\"\n}", "player_step_ui_config_167": "{\n \"config\": [\n {\n \"key\": 1,\n \"name\": \"answer1\",\n \"title\": \"How do you want to use APITable?\",\n \"type\": \"multiButton\",\n \"answers\": [\n \"IT & Support\",\n \"Education\",\n \"Project Management\",\n \"Marketing\",\n \"Product Management\",\n \"HR & Recruiting\",\n \"Operations\",\n \"Finance\",\n \"Sales & CRM\",\n \"Software Development\",\n \"HR & Legal\",\n \"Design & Creative\",\n \"Nonprofit\",\n \"Manufacture\",\n \"Other Things\"\n ],\n \"lastAllowInput\": false\n },\n {\n \"key\": 2,\n \"name\": \"answer2\",\n \"title\": \"What best describes your current role?\",\n \"type\": \"radio\",\n \"answers\": [\n \"Business Owner\",\n \"Team Leader\",\n \"Team Member\",\n \"Freelancer\",\n \"Director\",\n \"C-level\",\n \"VP\"\n ],\n \"lastAllowInput\": false\n },\n {\n \"key\": 3,\n \"name\": \"answer3\",\n \"title\": \"How many people are on your team? \",\n \"type\": \"radio\",\n \"answers\": [\n \"Just me\",\n \"2-5\",\n \"6-10\",\n \"11-15\",\n \"16-25\",\n \"25-50\",\n \"51-100\",\n \"101-500\"\n ],\n \"lastAllowInput\": false\n },\n {\n \"key\": 4,\n \"name\": \"answer4\",\n \"title\": \"How many people work at your company? \",\n \"type\": \"radio\",\n \"answers\": [\n \"1-19\",\n \"20-49\",\n \"50-99\",\n \"100-250\",\n \"251-500\",\n \"501-1500\",\n \"1500+\"\n ],\n \"lastAllowInput\": false\n },\n {\n \"key\": 5,\n \"name\": \"answer5\",\n \"title\": \"How did you hear about us? \",\n \"type\": \"checkbox\",\n \"answers\": [\n \"Search Engine\",\n \"YouTube\",\n \"Product Hunt\",\n \"Github\",\n \"Twitter\",\n \"LinkedIn\",\n \"Through a friend\"\n ],\n \"lastAllowInput\": false\n },\n {\n \"key\": 6,\n \"name\": \"answer6\",\n \"title\": \"We host a Discord channel as a place for discussion with APITable fans, come and join us!\",\n \"type\": \"joinUs\",\n \"url\": \"https://discord.gg/2UXAbDTJTX\",\n \"confirmText\": \"Join Our Community\",\n \"skipText\": \"skip\",\n \"submit\": true\n }\n ]\n}", "player_step_ui_config_168": "{\n\"templateKey\":\"createMirrorTip\"\n}", "player_step_ui_config_169": "{\n \"headerImg\": \"https://s4.vika.cn/space/2023/04/04/bcf0695cf35840e6b85e032a8e5ea0a1\",\n \"readMoreUrl\": \"https://help.vika.cn/changelog/23-04-10-updates\",\n \"children\": \"

🚀 Introduction of new functions

\\n
  • New field type \"Cascader\" is launched, making selection from a hierarchy of options on forms easier
  • \"Script\" widget is released, less code for more customization
  • Trigger Robot to send Emails, and get fast notifications
  • Trigger Robot to send a message to Slack, and inform your team in time
  • Exploring AI: \"GPT Content Generator\" Widget Released
\"\n}", "player_step_ui_config_17": "{\n \"element\": \"#TEMPLATE_CENTER_USE_TEMPLATE_BTN>button\", \n\"placement\": \"rightBottom\",\n\"offsetY\": 20,\n \"title\": \"使用模板教程\", \n\"description\": \"點擊左側按鈕使用模板\", \"children\":\"\" \n}", - "player_step_ui_config_176": "{\"title\":\"AI 助手介紹\",\"video\":\"https://www.youtube.com/embed/cjds1r_roG8?si=irKUpMhwDlOEb8Hc\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", + "player_step_ui_config_176": "{\"title\":\"AITable.ai 示範\",\"video\":\"https://www.youtube.com/embed/kGxMyEEo3OU\",\"videoId\":\"VIKA_GUIDE_VIDEO_FOR_AI\",\"autoPlay\":true}", "player_step_ui_config_18": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select>.ant-select-selector\", \n\"placement\": \"bottomLeft\",\n \"title\": \"使用模板教程\", \n\"description\": \"選擇模板要存放的位置\", \"children\":\"\" \n}", "player_step_ui_config_19": "{\n \"element\": \".style_usingTemplateWrapper__2vLm0 .ant-select .ant-select-selector\"\n}", "player_step_ui_config_2": "{\n \"config\": [\n {\n \"key\": 1,\n \"name\": \"answer1\",\n \"title\": \"您希望通過維格表解決哪些問題?\",\n \"type\": \"checkbox\",\n \"answers\": [\n \"工作規劃\",\n \"客戶服務\",\n \"項目管理\",\n \"採購供應\",\n \"內容生產\",\n \"電商運營\",\n \"活動策劃\",\n \"人力資源\",\n \"行政管理\",\n \"財務管理\",\n \"網絡直播\",\n \"高校管理\",\n \"其它\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 2,\n \"name\": \"answer2\",\n \"title\": \"您的工作崗位是?\",\n \"type\": \"radio\",\n \"answers\": [\n \"管理者\",\n \"項目經理\",\n \"產品經理\",\n \"設計師\",\n \"研發、工程師\",\n \"運營、編輯\",\n \"銷售、客服\",\n \"人事、行政\",\n \"財務、會計\",\n \"律師、法務\",\n \"市場\",\n \"教師\",\n \"學生\",\n \"其它\"\n ],\n \"lastAllowInput\": true\n },\n {\n \"key\": 3,\n \"name\": \"answer3\",\n \"title\": \"您的公司名稱是?\",\n \"type\": \"input\",\n \"submit\": false\n },\n {\n \"key\": 4,\n \"name\": \"answer4\",\n \"title\": \"請留下你的郵箱/手機/微信號,以便我們及時提供幫助。\",\n \"type\": \"input\",\n \"submit\": true\n },\n {\n \"key\": 5,\n \"title\": \"感謝你的填寫,請加一下客服號以備不時之需\",\n \"platform\": {\n \"website\": \"https://s4.vika.cn/space/2023/03/02/b34e3205a9154463be16f497524f1327\",\n \"dingtalk\": \"https://s4.vika.cn/space/2023/03/02/4b16cef6602a4586a21d6346bf25d300\",\n \"wecom\": \"https://s4.vika.cn/space/2023/03/02/60119b1b69b64aa887bd1be6a2928bec\",\n \"feishu\": \"https://u.vika.cn/z9ygm\"\n },\n \"type\": \"contactUs\",\n \"next\": true\n }\n ]\n}\n", @@ -3824,13 +3978,13 @@ "player_step_ui_config_41": "", "player_step_ui_config_42": "{\n \"element\": \"#DATASHEET_FORM_LIST_PANEL\", \n\"placement\": \"leftTop\",\n \"title\": \"神奇表單\", \n\"description\": \"在這裡可以快速生成當前視圖的神奇表單,神奇表單的字段是依照視圖的維格列數量以及順序來生成的哦\", \"children\":\"\" \n}", "player_step_ui_config_43": "{\n \"element\": \".style_navigation__1U5cR .style_help__1sXEA\", \n\"placement\": \"rightBottom\",\n \"title\": \"小提示\", \n\"offsetY\":5,\n\"description\": \"你可以在左側的「幫助中心」找回你的維格小助手\", \"children\":\"\" \n}", - "player_step_ui_config_44": "{\n\"title\":\"一分鐘快速入門\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", + "player_step_ui_config_44": "{\n\"title\":\"一分鐘快速入門\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_NEW_USER\",\n\"autoPlay\":true\n}\n", "player_step_ui_config_45": "", "player_step_ui_config_46": "", "player_step_ui_config_47": "{\n \"element\": \"#DATASHEET_WIDGET_BTN\",\n\"placement\": \"bottomRight\",\n \"title\": \"新功能\", \n\"description\": \"小程序上線!想要讓沉澱下來的數據得到更好的運用嗎?那就趕緊來體驗一下吧\", \"children\":\"\" \n}", "player_step_ui_config_48": "", "player_step_ui_config_49": "{\n \"element\": \".style_widgetPanelContainer__1l2ZV\",\n\"placement\": \"leftCenter\",\n \"title\": \"什麼是小程序\", \n\"description\": \"維格小程序是維格表的一種擴展應用,可實現數據可視化、數據傳輸、數據清洗等等額外功能。通過在小程序面板安裝適合團隊的小程序,可以讓工作事半功倍\", \"children\":\"\" \n}", - "player_step_ui_config_5": "{\n\"title\":\"一分鐘快速入門\",\n\"video\":\"space/2021/03/10/a68dbf1e2e7943b09b1550175253fdab\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}\n", + "player_step_ui_config_5": "{\n\"title\":\"一分鐘快速入門\",\n\"video\":\"space/2023/12/12/8e870a50d98646f0a4cc2f76e3cd6d46\",\n\"videoId\":\"VIKA_GUIDE_VIDEO_2\",\n\"autoPlay\":true\n}\n", "player_step_ui_config_50": "{\n \"element\": \".style_widgetModal__eXmdB\",\n\"placement\": \"leftTop\",\n \"title\": \"小程序中心\", \n\"description\": \"官方推薦和空間站自建的小程序會發佈到這裡。你可以根據場景,在這裡挑選合適的小程序放置到儀錶盤或小程序面板裡\", \"children\":\"\" \n}", "player_step_ui_config_51": "{\n \"element\": \".style_widgetModal__eXmdB .style_widgetItem__3Pl-1 button\",\n\"placement\": \"rightBottom\",\n \"title\": \"安裝小程序\", \n\"description\": \"我們安裝這個「圖表」小程序看看吧\", \"children\":\"\" \n}", "player_step_ui_config_52": "", @@ -3927,6 +4081,7 @@ "preview_guide_click_to_restart": "點擊下方按鈕重新預覽", "preview_guide_enable_it": "你可以點擊下方按鈕去啟用此功能", "preview_guide_open_office_preview": "開啟「office預覽」功能後即可預覽該文件", + "preview_next_automation_execution_time": "預覽接下來 10 次執行時間", "preview_not_support_video_codecs": "當前僅支持預覽編碼為H.264的MP4視頻", "preview_revision": "預覽此版本", "preview_see_more": "想要了解更多「office 文件預覽」功能?請點擊這裡", @@ -3962,6 +4117,7 @@ "privacy_protection": "《隱私保護》", "private_cloud": "專有云旗艦版", "private_external_person_only": "外部人員專用", + "private_help_link": "https://help.aitable.ai/docs/guide/team-and-private-area#private-area", "private_internal_person_only": "內部人員專用", "private_product_point": "一鍵擁有自己的 APITable 平台", "privatized_deployment": "自託管", @@ -4032,13 +4188,15 @@ "reconciled_data": "正在核對數據……", "record": "記錄", "record_activity_experience_tips": "可查看 ${day} 天的修改歷史", + "record_archived_data": "存檔記錄", + "record_chunk_text": "${text} rows, please wait", "record_comment": "僅評論", "record_comments": "評論", "record_fail_data": "數據已失效", "record_filter_tips": "記錄已被篩選條件過濾", "record_functions": "記錄(行)函數", "record_history": "僅修改歷史", - "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-history", + "record_history_help_url": "https://help.aitable.ai/docs/guide/manual-record-activity", "record_history_title": "修改歷史", "record_pre_filtered": "此記錄已被篩選過濾,點擊本記錄以外區域它將被隱藏", "record_pre_move": "此記錄不屬於當前位置,點擊本記錄以外區域它將被移動", @@ -4478,6 +4636,12 @@ "scan_to_login": "掃碼登錄", "scan_to_login_by_method": "請使用${method}關注公眾號即可安全登錄", "scatter_chart": "散點圖", + "schedule_day_tips": "週期計算從每個月的第一天開始計算。如果我們假設它每 10 天重複一次,那麼它將在每月的 1、11、21 和 31 天觸發", + "schedule_hour_tips": "週期計算從每天的午夜 (0:00) 開始。假設每三小時重複0 分鐘,則每天會在午夜(0:00)、凌晨3 點、上午6 點、上午9 點、中午(12 PM)、下午3 點、下午6 點、最後是黃昏時分(9 PM) 發生", + "schedule_start_day": "從每個月的第一天開始,", + "schedule_start_month": "從每年一月開始,每年", + "schedule_type": "時間表類型", + "schedule_year_tips": "週期計算從每年的第一個月開始計算。假設間隔3個月的第一天,觸發器將在每年一月、四月、七月和十月的第一天午夜啟動。", "science_and_technology": "科學技術", "scroll_screen_down": "向下滾動一屏", "scroll_screen_left": "向左滾動一屏", @@ -4491,6 +4655,7 @@ "search_folder_or_sheet": "搜索文件夾或維格表", "search_new_admin": "搜索成員暱稱,選擇移交的主管理員", "search_node_pleaseholder": "搜索文件 (${shortcutKey})", + "search_node_tip": "快速搜尋(${shortcutKey})", "search_or_add": "查找或添加", "search_role_placeholder": "搜索角色", "seats": "席位數量", @@ -4894,6 +5059,7 @@ "space_info": "空間站駕駛艙", "space_info_del_confirm1": "1. 刪除空間站後,以下數據將被全部清除:", "space_info_del_confirm2": "2. 空間站將會在七天后自動徹底刪除。在此之前,你可以隨時撤銷刪除操作", + "space_info_del_confirm3": "3. For subscribers: Benefits attach to your Space. Removing it cancels those benefits. Be wary!", "space_info_feishu_desc": "使用了第三方集成,如需刪除空間站請先關閉第三方集成。", "space_info_feishu_label": "第三方應用集成", "space_join_apply": "申請加入空間站「」", @@ -4980,6 +5146,7 @@ "start_onfiguration": "開始配置", "start_time": "起始時間", "start_use": "開始使用", + "starting_from_midnight": "從每天午夜(12:00 AM)開始,每天", "startup": "創業", "startup_company_support_program": "創業公司扶持計劃", "stat_average": "平均值", @@ -5013,6 +5180,8 @@ "stay_tuned_for_more_features": "更多功能敬請期待…", "steps_choose_reset_mode": "選擇重置方式", "steps_validate_identities": "驗證身份", + "stop_chunk_content": "Are you sure you want to stop the operation?", + "stop_chunk_title": "Stop", "stop_dingtalk_h5_modal_content": "自建應用將與本空間站解除綁定,請確認停用。", "storage_per_seats": "", "storage_per_space": "附件容量", @@ -5043,9 +5212,11 @@ "subscribe_credit_usage_over_limit": "當前空間中的積分數量超過限制,請升級您的訂閱。\n", "subscribe_demonstrate": "預約演示", "subscribe_disabled_seat": "人數不可低於原方案", + "subscribe_grade_business": "商業", "subscribe_grade_free": "免費版", "subscribe_grade_plus": "Plus", "subscribe_grade_pro": "Pro", + "subscribe_grade_starter": "起動機", "subscribe_label_tooltip": "${grade}以上空間站專享功能", "subscribe_new_choose_member": "最高支持 ${member_num} 人", "subscribe_new_choose_member_tips": "本方案支持 1~${member_num} 名成員進入空間站使用", @@ -5182,7 +5353,7 @@ "template_name_repetition_title": "“${templateName}”已存在,確定要替換它嗎?", "template_no_template": "暫無模板", "template_not_found": "找不到想要的模板? 請告訴我們~", - "template_recommend_title": "熱門推薦", + "template_recommend_title": "🌟 熱門推薦", "template_type": "模板", "terms_of_service": "《服務條款》", "terms_of_service_pure_string": " 服務條款", @@ -5226,6 +5397,7 @@ "text_editor_tip_end": "Enter 結束編輯", "text_functions": "文本函數", "thailand": "泰國", + "the_button_field_is_misconfigured": "按鈕欄位配置錯誤,請檢查並重試", "the_current_automation_workflow_has_no_related_files_you_can_establish_a_link_by_adding_trigger_conditions_and_actions_on_the_left_side": "當前自動化工作流沒有相關檔案。您可以通過在左側添加觸發條件和操作來建立鏈接", "the_current_button_column_has_expired_please_reselect": "目前按鈕列已過期,請重新選擇", "the_last_7_days": "過去 7 天", @@ -5328,6 +5500,7 @@ "timemachine_update_comment": "Updated comments", "times_per_month_unit": "次/月", "times_unit": "次", + "timing_rules": "定時", "timor_leste": "東帝汶", "tip_del_success": "我們將對您的空間站數據保留七天,七天內可隨時撤銷刪除操作。", "tip_do_you_want_to_know_about_field_permission": "想對列數據加密嗎?了解列權限", @@ -5515,6 +5688,7 @@ "verify_account_title": "驗證賬號", "verify_via_email": "通過郵箱驗證碼驗證身份", "verify_via_phone": "通過短信驗證碼驗證身份", + "video": "影片", "video_not_support_play": "當前視頻格式不支持在線播放", "vietnam": "越南", "view": "視圖", @@ -5863,7 +6037,8 @@ "workdoc_color_title": "字體顏色", "workdoc_create": "創建輕文檔", "workdoc_expanded": "展開目錄", - "workdoc_image_max_10mb": "圖片大小不能超過10MB", + "workdoc_image_max_10mb": "無效的", + "workdoc_image_max_size": "圖片大小不能超過${size}", "workdoc_info": "文件訊息", "workdoc_info_create_time": "創建時間", "workdoc_info_creator": "創建人", @@ -5871,6 +6046,7 @@ "workdoc_info_last_modify_time": "修改時間", "workdoc_link_placeholder": "請輸入連結", "workdoc_only_image": "僅允許使用影像", + "workdoc_only_video": "僅允許視頻", "workdoc_text_placeholder": "輸入“/”開始", "workdoc_title_placeholder": "請輸入標題", "workdoc_unnamed": "未命名文檔", @@ -5879,9 +6055,11 @@ "workdoc_unsave_ok": "放棄更改", "workdoc_unsave_title": "輕文檔尚未保存", "workdoc_upload_failed": "上傳失敗", + "workdoc_video_max_size": "影片大小不能超過${size}", "workdoc_ws_connected": "已連接", "workdoc_ws_connecting": "正在連接...", "workdoc_ws_disconnected": "已斷開連接", + "workdoc_ws_reconnecting": "正在重新連接...", "workflow_execute_failed_notify": "執行失敗,請根據運行歷史排查問題,需要任何幫助或有任何疑問,請隨時與客服團隊聯繫", "workspace_data": "空間站數據", "workspace_files": "工作台數據", diff --git a/packages/datasheet/public/static/icon/embed/Anything_dark.png b/packages/datasheet/public/static/icon/embed/Anything_dark.png new file mode 100644 index 0000000000..a8a6f6056e Binary files /dev/null and b/packages/datasheet/public/static/icon/embed/Anything_dark.png differ diff --git a/packages/datasheet/public/static/icon/embed/Anything_light.png b/packages/datasheet/public/static/icon/embed/Anything_light.png new file mode 100644 index 0000000000..05736e8635 Binary files /dev/null and b/packages/datasheet/public/static/icon/embed/Anything_light.png differ diff --git a/packages/datasheet/public/static/icon/embed/Bilbili.png b/packages/datasheet/public/static/icon/embed/Bilbili.png new file mode 100644 index 0000000000..20fc9fd117 Binary files /dev/null and b/packages/datasheet/public/static/icon/embed/Bilbili.png differ diff --git a/packages/datasheet/public/static/icon/embed/Docs.png b/packages/datasheet/public/static/icon/embed/Docs.png new file mode 100644 index 0000000000..6dbe23bd8b Binary files /dev/null and b/packages/datasheet/public/static/icon/embed/Docs.png differ diff --git a/packages/datasheet/public/static/icon/embed/Figma.png b/packages/datasheet/public/static/icon/embed/Figma.png new file mode 100644 index 0000000000..2cbfdd7c2a Binary files /dev/null and b/packages/datasheet/public/static/icon/embed/Figma.png differ diff --git a/packages/datasheet/public/static/icon/embed/Jishi.png b/packages/datasheet/public/static/icon/embed/Jishi.png new file mode 100644 index 0000000000..a9eeaff814 Binary files /dev/null and b/packages/datasheet/public/static/icon/embed/Jishi.png differ diff --git a/packages/datasheet/public/static/icon/embed/Notion.png b/packages/datasheet/public/static/icon/embed/Notion.png new file mode 100644 index 0000000000..70eb913ac7 Binary files /dev/null and b/packages/datasheet/public/static/icon/embed/Notion.png differ diff --git a/packages/datasheet/public/static/icon/embed/Sheet.png b/packages/datasheet/public/static/icon/embed/Sheet.png new file mode 100644 index 0000000000..9d7065408b Binary files /dev/null and b/packages/datasheet/public/static/icon/embed/Sheet.png differ diff --git a/packages/datasheet/public/static/icon/embed/TencentDoc.png b/packages/datasheet/public/static/icon/embed/TencentDoc.png new file mode 100644 index 0000000000..577cdf654a Binary files /dev/null and b/packages/datasheet/public/static/icon/embed/TencentDoc.png differ diff --git a/packages/datasheet/public/static/icon/embed/WPS.png b/packages/datasheet/public/static/icon/embed/WPS.png new file mode 100644 index 0000000000..4639a1db0f Binary files /dev/null and b/packages/datasheet/public/static/icon/embed/WPS.png differ diff --git a/packages/datasheet/public/static/icon/embed/YouTube.png b/packages/datasheet/public/static/icon/embed/YouTube.png new file mode 100644 index 0000000000..b29e6cd88c Binary files /dev/null and b/packages/datasheet/public/static/icon/embed/YouTube.png differ diff --git a/packages/datasheet/public/static/icon/embed/embed.svg b/packages/datasheet/public/static/icon/embed/embed.svg new file mode 100644 index 0000000000..b0436fe79a --- /dev/null +++ b/packages/datasheet/public/static/icon/embed/embed.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/packages/datasheet/scripts/generate-tailwindcss-config.ts b/packages/datasheet/scripts/generate-tailwindcss-config.ts new file mode 100644 index 0000000000..545a474a71 --- /dev/null +++ b/packages/datasheet/scripts/generate-tailwindcss-config.ts @@ -0,0 +1,59 @@ +import fs from 'fs'; +import path from 'path'; + +const CSS_FILE_PATH = path.resolve(__dirname, '../src/pc/styles/lib_colors.css'); + +function generateThemeObjectFromCSSFile() { + const cssContent = fs.readFileSync(CSS_FILE_PATH, 'utf-8'); + const themeStartIndex = cssContent.indexOf(':root[data-theme="light"]'); + const themeEndIndex = cssContent.indexOf('}', themeStartIndex); + const themeContent = cssContent.slice(themeStartIndex, themeEndIndex); + + const themeObject: { [key: string]: string } = {}; + const themeItems = themeContent.match(/--\w+:\s[^;]+;/g); + + if (themeItems) { + themeItems.forEach((item) => { + const [key, value] = item.split(':'); + const formattedKey = key.replace('--', '').trim(); + themeObject[formattedKey] = `var(${key.trim()})`; + }); + } + + return themeObject; +} + +const themeObject = generateThemeObjectFromCSSFile(); +const CONFIG_PATH = path.resolve(__dirname, '..', 'tailwind.config.js'); + +function addColorsToTailwindConfig(newColors) { + const config = require(CONFIG_PATH); + + console.log('config', config); + + const colors = { + ...config.theme.extend.colors, + ...newColors, + }; + + const newConfigContent = `/** @type {import('tailwindcss').Config} */ +module.exports = { + prefix: 'vk-', + darkMode: ['data-theme'], + content: ['./pages/**/*.{js,ts,jsx,tsx,mdx}', './src/**/*.{js,ts,jsx,tsx,mdx}'], + theme: { + extend: { + colors: ${JSON.stringify(colors, null, 2)} + }, + }, + corePlugins: { + preflight: false, + }, + plugins: [require('@tailwindcss/typography')], +}; + `; + + fs.writeFileSync(CONFIG_PATH, newConfigContent, 'utf8'); +} + +addColorsToTailwindConfig(themeObject); diff --git a/packages/datasheet/sentry.client.config.ts b/packages/datasheet/sentry.client.config.ts index 2959b1bae8..fe0c6c64bf 100644 --- a/packages/datasheet/sentry.client.config.ts +++ b/packages/datasheet/sentry.client.config.ts @@ -51,5 +51,6 @@ Sentry.init({ ignoreErrors: [ // It was found that all hovers where tooltip appears send a request to sentry and the exception status is this 'ResizeObserver loop limit exceeded', + 'JSON Parse error: Unexpected EOF', ], }); \ No newline at end of file diff --git a/packages/datasheet/sentry.edge.config.ts b/packages/datasheet/sentry.edge.config.ts new file mode 100644 index 0000000000..0af3f6a66f --- /dev/null +++ b/packages/datasheet/sentry.edge.config.ts @@ -0,0 +1,56 @@ +/** + * APITable + * Copyright (C) 2022 APITable Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import { RewriteFrames } from '@sentry/integrations'; +import * as Sentry from '@sentry/nextjs'; +import { Integrations } from '@sentry/tracing'; +import { getEnvVariables, getInitializationData, getReleaseVersion } from 'pc/utils/env'; + +Sentry.init({ + enabled: true, + dsn: getEnvVariables().SENTRY_DSN, + integrations: [ + new Integrations.BrowserTracing()!, + new RewriteFrames()!, + /** + * @description Sentry's handling of requestAnimationFrame in Chrome 74 can be problematic and lead to unexpected errors + * Currently rewriting the check for requestAnimationFrame based on the method provided in Sentry's issue + * @issue https://github.com/getsentry/sentry-javascript/issues/3388 + * @type {boolean} + */ + // new Sentry.Integrations.TryCatch({ + // requestAnimationFrame: false, + // }) + ], + environment: getInitializationData().env, + release: getReleaseVersion(), + normalizeDepth: 5, + // We recommend adjusting this value in production, or using tracesSampler + // for finer control + tracesSampleRate: 0.1, + maxBreadcrumbs: 10, + /** Every time a page is entered, a pageload or a route change is made, a record is automatically sent to the sentry, + * which doesn't make much sense at the moment, so turn it off and watch it later. + */ + autoSessionTracking: false, + ignoreErrors: [ + // It was found that all hovers where tooltip appears send a request to sentry and the exception status is this + 'ResizeObserver loop limit exceeded', + 'JSON Parse error: Unexpected EOF', + ], +}); diff --git a/packages/datasheet/sentry.server.config.ts b/packages/datasheet/sentry.server.config.ts index 2959b1bae8..fe0c6c64bf 100644 --- a/packages/datasheet/sentry.server.config.ts +++ b/packages/datasheet/sentry.server.config.ts @@ -51,5 +51,6 @@ Sentry.init({ ignoreErrors: [ // It was found that all hovers where tooltip appears send a request to sentry and the exception status is this 'ResizeObserver loop limit exceeded', + 'JSON Parse error: Unexpected EOF', ], }); \ No newline at end of file diff --git a/packages/datasheet/src/error_page.tsx b/packages/datasheet/src/error_page.tsx index 2e537fe9cd..372c274ff0 100644 --- a/packages/datasheet/src/error_page.tsx +++ b/packages/datasheet/src/error_page.tsx @@ -23,9 +23,7 @@ import * as React from 'react'; import { useEffect } from 'react'; import { Button, colorVars, LinkButton, Typography } from '@apitable/components'; import { Strings, t } from '@apitable/core'; -// import { navigationToUrl } from 'pc/components/route_manager/navigation_to_url'; import { useAppSelector } from 'pc/store/react-redux'; -import { getEnvVariables } from 'pc/utils/env'; const ErrorPage = () => { useEffect(() => { diff --git a/packages/datasheet/src/get_env.ts b/packages/datasheet/src/get_env.ts index cf9f9dc0b1..1615b4761f 100644 --- a/packages/datasheet/src/get_env.ts +++ b/packages/datasheet/src/get_env.ts @@ -148,7 +148,7 @@ export const getEnvVars = () => { HELP_CONFIG: process.env.HELP_CONFIG, CUSTOM_WIDGET_VISIBLE: process.env.CUSTOM_WIDGET_VISIBLE === 'true', HELP_MENU_CONTACT_US_URL: process.env.HELP_MENU_CONTACT_US_URL, - SHARE_LOGO:process.env.SHARE_LOGO, + SHARE_LOGO: process.env.SHARE_LOGO, LOGO: process.env.LOGO, COMMON_IMG_LOGO: process.env.COMMON_IMG_LOGO, LONG_DARK_LOGO: process.env.LONG_DARK_LOGO, @@ -215,6 +215,7 @@ export const getEnvVars = () => { VIEW_MANUAL_SAVE_INFO_IMAGE: process.env.VIEW_MANUAL_SAVE_INFO_IMAGE, IS_CANVAS_IMAGE_CROSS_ORIGIN: process.env.IS_CANVAS_IMAGE_CROSS_ORIGIN === 'true', GOOGLE_TAG_MANAGER_ID: process.env.GOOGLE_TAG_MANAGER_ID, + SIDEBAR_CUSTOM_BUTTON_LIST: process.env.SIDEBAR_CUSTOM_BUTTON_LIST, ENABLED_REWARDFUL: process.env.ENABLED_REWARDFUL === 'true', FORM_LOGIN_URL: process.env.FORM_LOGIN_URL, TRANSLATION_FEEDBACK_HELP_URL: process.env.TRANSLATION_FEEDBACK_HELP_URL, @@ -230,5 +231,12 @@ export const getEnvVars = () => { ENABLE_WORKDOC_FIELD: process.env.ENABLE_WORKDOC_FIELD === 'true', AI_TRAINING_HELP_DOC_LINK: process.env.AI_TRAINING_HELP_DOC_LINK, AI_SETTING_HELP_DOC_LINK: process.env.AI_SETTING_HELP_DOC_LINK, + EDITION: process.env.EDITION, + ENABLE_TIME_MACHINE_ROOLBACK: process.env.ENABLE_TIME_MACHINE_ROOLBACK === 'true', + YACH_ENABLED: process.env.YACH_ENABLED === 'true', + + HIDDEN_SEE_MORE_MEMBER_LIST: process.env.HIDDEN_SEE_MORE_MEMBER_LIST === 'true', + ALLOW_EMBED_SEND_REMIND: process.env.ALLOW_EMBED_SEND_REMIND === 'true', + NEXT_PUBLIC_UNIT_SEARCH_TYPE: process.env.NEXT_PUBLIC_UNIT_SEARCH_TYPE, }; }; diff --git a/packages/datasheet/src/global.less b/packages/datasheet/src/global.less index a612f63cbd..57e3c9c98c 100644 --- a/packages/datasheet/src/global.less +++ b/packages/datasheet/src/global.less @@ -1,8 +1,7 @@ // @import "~antd/dist/antd.less"; // @import "custom_antd_style.less"; -@import "~pc/styles/lib_screen.less"; -@import "~pc/styles/lib_mixins.less"; - +@import '~pc/styles/lib_screen.less'; +@import '~pc/styles/lib_mixins.less'; .treeViewRoot { /* Clean up default styles */ @@ -21,7 +20,6 @@ @node-drag-line-size: 2px; @node-drag-dot-size: 6px; - .treeItemRoot { &, .group { @@ -84,7 +82,7 @@ // Line when dragging and dropping .label::before { display: none; - content: "\0020"; + content: '\0020'; position: absolute; left: @node-drag-dot-size - 1; right: 0; @@ -96,7 +94,7 @@ // Point when dragging and dropping .label::after { display: none; - content: "\0020"; + content: '\0020'; position: absolute; width: @node-drag-dot-size; height: @node-drag-dot-size; @@ -210,10 +208,9 @@ a { background-color: transparent; outline: none; cursor: pointer; - transition: color .3s; + transition: color 0.3s; } - .ant-tabs-tab-btn:focus, .ant-tabs-tab-remove:focus, .ant-tabs-tab-btn:active, @@ -221,7 +218,6 @@ a { color: var(--black_900); } - #dingtalk_qrcode { width: 100%; height: 100%; @@ -252,4 +248,23 @@ a { #chat-widget-container { z-index: 1003 !important; -} \ No newline at end of file +} + +.rc-virtual-list-holder { + overflow-y: auto !important; + .default-scroll-bar(true); +} + +.rc-virtual-list-scrollbar { + background: transparent; + width: 14px !important; + display: flex; + justify-content: center; + border-left: 4px solid transparent; + border-right: 4px solid transparent; + background-clip: padding-box; + + .rc-virtual-list-scrollbar-thumb { + background-color: transparent !important; + } +} diff --git a/packages/datasheet/src/main.less b/packages/datasheet/src/main.less index 414f76d872..66edf4a606 100644 --- a/packages/datasheet/src/main.less +++ b/packages/datasheet/src/main.less @@ -37,7 +37,7 @@ } } -.custom-scroll-bar(12px, 12px); +.default-scroll-bar(); // https://www.zhangxinxu.com/wordpress/2020/01/css-any-hover-media/ @media (any-hover: none) { diff --git a/packages/datasheet/src/modules/api/node/api.ts b/packages/datasheet/src/modules/api/node/api.ts new file mode 100644 index 0000000000..a01a055485 --- /dev/null +++ b/packages/datasheet/src/modules/api/node/api.ts @@ -0,0 +1,11 @@ +import urlcat from 'urlcat'; +import { javaApi } from 'api/java_api'; +import { GET_NODE_DESCRIPTION } from './const'; + +export const getNodeDescription = (nodeId) => { + return javaApi.get( + urlcat(GET_NODE_DESCRIPTION, { + nodeId, + }), + ); +}; diff --git a/packages/datasheet/src/modules/api/node/const.ts b/packages/datasheet/src/modules/api/node/const.ts new file mode 100644 index 0000000000..8e3a0e96c3 --- /dev/null +++ b/packages/datasheet/src/modules/api/node/const.ts @@ -0,0 +1 @@ +export const GET_NODE_DESCRIPTION = '/node/:nodeId/description'; diff --git a/packages/datasheet/src/modules/api/utils/init_axios.tsx b/packages/datasheet/src/modules/api/utils/init_axios.tsx index 18bf919312..27e6fc983c 100644 --- a/packages/datasheet/src/modules/api/utils/init_axios.tsx +++ b/packages/datasheet/src/modules/api/utils/init_axios.tsx @@ -1,11 +1,11 @@ -import { IReduxState, Navigation, StatusCode, StoreActions, Strings, t } from '@apitable/core'; import { Modal } from 'antd'; import { apiErrorManager } from 'api/utils/error_manager'; import axios from 'axios'; +import { Store } from 'redux'; +import { IReduxState, Navigation, StatusCode, StoreActions, Strings, t } from '@apitable/core'; import { Router } from 'pc/components/route_manager/router'; import { store } from 'pc/store'; import { getInitializationData, getReleaseVersion, getSpaceIdFormTemplate } from 'pc/utils/env'; -import { Store } from 'redux'; declare let window: any; @@ -29,6 +29,8 @@ declare let window: any; // return false; // } +const isDingtalkFunc = () => !process.env.SSR && navigator.userAgent.toLowerCase().indexOf('dingtalk') > -1; + export function redirectIfUserApplyLogout() { const state = store.getState(); const initData = getInitializationData(); @@ -39,7 +41,7 @@ export function redirectIfUserApplyLogout() { } export function handleResponse(response, headers: any | undefined, url: string | undefined) { - const { success, code, data, message = 'Error' } = response; + const { success, code, message = 'Error' } = response; // const IGNORE_PATH_REG = /^\/(share|template|notify|embed)/; // if (success && data && url?.startsWith('/nest/v1/') && !IGNORE_PATH_REG.test(location.pathname)) { @@ -84,6 +86,11 @@ export function handleResponse(response, headers: any | undefined, url: strin content: t(Strings.login_status_expired_content), okText: t(Strings.login_status_expired_button), onOk: () => { + const isDingding = isDingtalkFunc(); + if (isDingding) { + window.location.href = `/user/dingtalk/social_login${window.location.search}`; + return; + } const IS_EMBED_LINK_REG = /^\/embed/; const reference = !IS_EMBED_LINK_REG.test(location.pathname) ? new URLSearchParams(window.location.search).get('reference')?.toString() @@ -192,9 +199,10 @@ export function initAxios(store: Store) { return config; }); + const IGNORE_PATHS = ['/client/info', '/user/me', '/space/link/join', '/org/loadOrSearch', '/field/permission', '/space/features', '/space/info']; axios.interceptors.response.use((response) => { if (!response) return response; - if (response.config && response.config.url && response.config.url?.includes('/client/info')) { + if (response.config && response.config.url && IGNORE_PATHS.some((path) => response.config.url?.includes(path))) { return response; } return handleResponse(response.data, response, response?.config?.url); diff --git a/packages/datasheet/src/modules/api/widget/api.ts b/packages/datasheet/src/modules/api/widget/api.ts index 800221d871..9fac9c5719 100644 --- a/packages/datasheet/src/modules/api/widget/api.ts +++ b/packages/datasheet/src/modules/api/widget/api.ts @@ -17,8 +17,8 @@ */ import axios from 'axios'; +import { IApiWrapper, IWidget, WidgetPackageType, WidgetReleaseType } from '@apitable/core'; import * as Url from './const'; -import {IApiWrapper, IWidget, WidgetPackageType, WidgetReleaseType} from '@apitable/core'; // const baseURL = '/nest/v1'; /** @@ -54,4 +54,3 @@ export const installWidget = (nodeId: string, packageId: string, name?: string) }); }; - diff --git a/packages/datasheet/src/modules/billing/index.ts b/packages/datasheet/src/modules/billing/index.ts index d563aafbd6..5a407bd746 100644 --- a/packages/datasheet/src/modules/billing/index.ts +++ b/packages/datasheet/src/modules/billing/index.ts @@ -1 +1 @@ -export * from './get_billing_info' +export * from './get_billing_info'; diff --git a/packages/datasheet/src/modules/shared/apphook/hook_bindings.ts b/packages/datasheet/src/modules/shared/apphook/hook_bindings.ts index aa28897e72..2e47b4a7f8 100644 --- a/packages/datasheet/src/modules/shared/apphook/hook_bindings.ts +++ b/packages/datasheet/src/modules/shared/apphook/hook_bindings.ts @@ -48,6 +48,7 @@ const fixInnerConsistency = (datasheetId: string, errors: IInnerConsistencyError fixConsistencyMetadata = null; console.log('Fix inner consistency changesets', ops); + resourceService.instance!.operationExecuted(ops); Sentry.captureMessage('fixInnerConsistency: Inner data inconsistency of datasheet found and attempts made to fix', { diff --git a/packages/datasheet/src/modules/shared/apphook/trigger_commands.ts b/packages/datasheet/src/modules/shared/apphook/trigger_commands.ts index 81818ec383..b90cc3b8c5 100644 --- a/packages/datasheet/src/modules/shared/apphook/trigger_commands.ts +++ b/packages/datasheet/src/modules/shared/apphook/trigger_commands.ts @@ -26,8 +26,17 @@ */ import { SystemConfigInterfacePlayer, SystemConfigInterfaceGuide, Api } from '@apitable/core'; -// @ts-ignore -import { openGuideWizard, openGuideWizards, openGuideNextStep, skipCurrentWizard, skipAllWizards, clearGuideUis, clearGuideAllUi, setWizardCompleted } from 'enterprise/guide/trigger_guide_commands'; +import { + openGuideWizard, + openGuideWizards, + openGuideNextStep, + skipCurrentWizard, + skipAllWizards, + clearGuideUis, + clearGuideAllUi, + setWizardCompleted, + // @ts-ignore +} from 'enterprise/guide/trigger_guide_commands'; // @ts-ignore import { openVikaby } from 'enterprise/vikaby/vikaby'; @@ -53,8 +62,8 @@ export const TriggerCommands: any = { open_vikaby: (props: { defaultExpandMenu: true; visible: true }) => { openVikaby?.({ ...props }); }, - open_guide_wizard: (wizardId: number) => { - openGuideWizard?.(wizardId); + open_guide_wizard: (wizardId: number, ignoreRepeat?: boolean) => { + openGuideWizard?.(wizardId, ignoreRepeat); }, open_guide_wizards: (wizards: number[]) => { openGuideWizards?.(wizards); diff --git a/packages/datasheet/src/modules/shared/player/init.ts b/packages/datasheet/src/modules/shared/player/init.ts index 408f3a18d0..d49abf4a70 100644 --- a/packages/datasheet/src/modules/shared/player/init.ts +++ b/packages/datasheet/src/modules/shared/player/init.ts @@ -17,6 +17,7 @@ */ // @ts-ignore import { IWizardsConfig, Player, SystemConfig } from '@apitable/core'; +import { modifyWizardConfig } from 'pc/common/wizard'; import { startActions, TriggerCommands } from '../apphook/trigger_commands'; import { isEventStateMatch, isRulesPassed, isTimeRulePassed } from './rules'; // @ts-ignore @@ -40,9 +41,9 @@ export function init() { * if not distinguish the environment, the impact on debugging will be greater */ if (process.env.NODE_ENV === 'development') { - config = { player: SystemConfig.player, guide: SystemConfig.guide }; + config = modifyWizardConfig({ player: SystemConfig.player, guide: SystemConfig.guide }); } else if (HooksConfig) { - config = HooksConfig; + config = modifyWizardConfig(HooksConfig); } if (!config) return; @@ -72,11 +73,21 @@ export function init() { const validTriggers = allTriggerIds.filter((triggerId) => { const curTrigger = triggers.find((item: any) => item.id === triggerId); if (!curTrigger) return; - const eventMatch = isEventStateMatch(args, curTrigger.eventState); const timeRulePassed = isTimeRulePassed((curTrigger as any).startTime, (curTrigger as any).endTime); const rulesPassed = isRulesPassed(config?.player.rule, curTrigger.rules); + if ( + triggerId === + 'workbench_shown,[device_IS_pc, url_EXCLUDES_templateId, url_EXCLUDES_shareId, edition_IS_aitable],[open_guide_wizards([105, 115, 104])]' + ) { + console.log({ + eventMatch, + timeRulePassed, + rulesPassed, + }); + } + return eventMatch && timeRulePassed && rulesPassed; }); // Iterate through multiple triggers and execute the corresponding actions diff --git a/packages/datasheet/src/modules/shared/player/rules.ts b/packages/datasheet/src/modules/shared/player/rules.ts index 2b450d5b9f..c01aace567 100644 --- a/packages/datasheet/src/modules/shared/player/rules.ts +++ b/packages/datasheet/src/modules/shared/player/rules.ts @@ -107,7 +107,7 @@ export const getConditionValue = (str: string) => { return state.labs; } case PlayerRulesConditionType.EDITION: { - return getInitializationData().env?.split('-')[0]; + return getInitializationData().envVars.EDITION?.split('-')[0]; } default: return str; @@ -140,10 +140,10 @@ export const isRulePassed = (conditionValue: any, operator: IPlayerRulesOperator return Boolean(conditionValue === conditionArgs); } case 'IS_BEFORE': { - return dayjs.tz(conditionValue).isBefore(conditionArgs); + return dayjs(conditionValue).isBefore(conditionArgs); } case 'IS_AFTER': { - return dayjs.tz(conditionValue).isAfter(conditionArgs); + return dayjs(conditionValue).isAfter(conditionArgs); } case 'GREATER_THAN': { return Number(conditionValue) > Number(conditionArgs); @@ -205,9 +205,9 @@ export const isTimeRulePassed = (startTime?: string | number, endTime?: string | if (!startTime && !endTime) { return true; } - const cur = dayjs.tz().valueOf(); - const start = startTime ? dayjs.tz(startTime).valueOf() : Number.NEGATIVE_INFINITY; - const end = endTime ? dayjs.tz(endTime).valueOf() : Number.POSITIVE_INFINITY; + const cur = dayjs().valueOf(); + const start = startTime ? dayjs(startTime).valueOf() : Number.NEGATIVE_INFINITY; + const end = endTime ? dayjs(endTime).valueOf() : Number.POSITIVE_INFINITY; return cur > start && cur < end; }; diff --git a/packages/datasheet/src/modules/shared/shortcut_key/enum.ts b/packages/datasheet/src/modules/shared/shortcut_key/enum.ts index d69e94cd00..5bcff6a949 100644 --- a/packages/datasheet/src/modules/shared/shortcut_key/enum.ts +++ b/packages/datasheet/src/modules/shared/shortcut_key/enum.ts @@ -29,6 +29,7 @@ export enum ContextName { recordEditable = 'recordEditable', // Record Record Editing modalVisible = 'modalVisible', // Is the modal window currently open isQuickSearchExpanding = 'isQuickSearchExpanding', // quick search is expanding + isWorkdocOpen = 'isWorkdocOpen', // Workdoc is open } export enum ShortcutActionName { @@ -103,6 +104,7 @@ export enum ShortcutActionName { ToggleApiPanel = 'ToggleApiPanel', ToggleRobotPanel = 'ToggleRobotPanel', ToggleTimeMachinePanel = 'ToggleTimeMachinePanel', + ToggleCopilotPanel = 'ToggleCopilotPanel', ToggleArchivedRecordsPanel = 'ToggleArchivedRecordsPanel', // Expand the card PreviousRecord = 'PreviousRecord', diff --git a/packages/datasheet/src/modules/shared/shortcut_key/shortcut_actions/append_row.ts b/packages/datasheet/src/modules/shared/shortcut_key/shortcut_actions/append_row.ts index 2dfa5ca199..08c319d999 100644 --- a/packages/datasheet/src/modules/shared/shortcut_key/shortcut_actions/append_row.ts +++ b/packages/datasheet/src/modules/shared/shortcut_key/shortcut_actions/append_row.ts @@ -17,7 +17,7 @@ */ /** - * https://www.notion.so/vikadata/9ac1f271807f4d99a30c1b5cae32437a + * https://www.notion.so/9ac1f271807f4d99a30c1b5cae32437a */ import { CollaCommandName, diff --git a/packages/datasheet/src/modules/shared/shortcut_key/shortcut_key.ts b/packages/datasheet/src/modules/shared/shortcut_key/shortcut_key.ts index d370dcd0a7..6cfbe58328 100644 --- a/packages/datasheet/src/modules/shared/shortcut_key/shortcut_key.ts +++ b/packages/datasheet/src/modules/shared/shortcut_key/shortcut_key.ts @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +import { isEmpty } from 'lodash'; import { ContextName, ShortcutActionName } from 'modules/shared/shortcut_key/enum'; import { CollaCommandName, @@ -34,6 +35,7 @@ import { notify } from 'pc/components/common/notify/notify'; import { NotifyKey } from 'pc/components/common/notify/notify.interface'; import { EXPAND_RECORD } from 'pc/components/expand_record/expand_record.enum'; import { expandRecordIdNavigate } from 'pc/components/expand_record/utils'; +import { string2Query } from 'pc/components/form_container/util'; import { EXPAND_SEARCH } from 'pc/components/quick_search/const'; import { resourceService } from 'pc/resource_service'; import { store } from 'pc/store'; @@ -80,6 +82,12 @@ export class ShortcutContext { if (state.space.isSideRecordOpen) return false; return Boolean(document.querySelectorAll(`.${EXPAND_RECORD}`).length); }, + [ContextName.isWorkdocOpen]: () => { + const query = string2Query(); + const recordId = query.recordId as string | undefined; + const fieldId = query.fieldId as string | undefined; + return Boolean(recordId && fieldId); + }, [ContextName['true']]: () => true, [ContextName.isFocusing]: () => { const ele = document.getElementById(DATASHEET_ID.DOM_CONTAINER); @@ -158,12 +166,13 @@ export class ShortcutActionManager { private constructor() {} static actionMap = new Map boolean | void | Promise>([ - [ - ShortcutActionName.None, - () => { - console.warn('! ' + 'A shortcut action of None'); - }, - ], + // Compatible with German Vietnamese special characters + // [ + // ShortcutActionName.None, + // () => { + // console.warn('! ' + 'A shortcut action of None'); + // }, + // ], [ ShortcutActionName.ToastForSave, () => { @@ -263,7 +272,19 @@ const getUndoManager = () => { }; export function clear() { + const query = string2Query(); const state = store.getState(); + const recordId = query.recordId as string | undefined; + const fieldId = query.fieldId as string | undefined; + if (recordId && fieldId) { + const snapshot = Selectors.getSnapshot(state)!; + const fieldMap = snapshot.meta?.fieldMap; + const fieldType = fieldMap[fieldId]?.type; + const cv = Selectors.getCellValue(state, snapshot, recordId, fieldId); + if (fieldType === FieldType.WorkDoc && !isEmpty(cv)) { + return; + } + } const fieldMap = Selectors.getFieldMap(state, state.pageParams.datasheetId!); const uploadManager = resourceService.instance!.uploadManager; const data: ISetRecordOptions[] = []; diff --git a/packages/datasheet/src/modules/space/member_stash/hooks/use_get_member_stash.ts b/packages/datasheet/src/modules/space/member_stash/hooks/use_get_member_stash.ts index 9466709889..c971e1fa8e 100644 --- a/packages/datasheet/src/modules/space/member_stash/hooks/use_get_member_stash.ts +++ b/packages/datasheet/src/modules/space/member_stash/hooks/use_get_member_stash.ts @@ -1,7 +1,6 @@ -import { useEffect, useState } from 'react'; import { memberStash } from 'modules/space/member_stash/member_stash'; - -import {useAppSelector} from "pc/store/react-redux"; +import { useEffect, useState } from 'react'; +import { useAppSelector } from 'pc/store/react-redux'; export const useGetMemberStash = () => { const [loading, setLoading] = useState(false); diff --git a/packages/datasheet/src/pc/common/api-client.ts b/packages/datasheet/src/pc/common/api-client.ts index 800a08a7f3..5647b8e022 100644 --- a/packages/datasheet/src/pc/common/api-client.ts +++ b/packages/datasheet/src/pc/common/api-client.ts @@ -1,4 +1,3 @@ -import { apiErrorManager, redirectIfUserApplyLogout } from 'api/utils'; import axios from 'axios'; import { createConfiguration, @@ -7,6 +6,7 @@ import { ServerConfiguration, WorkbenchNodeApiApi } from '@apitable/api-client'; import { isServer } from '@apitable/core/dist/utils/env'; +import { apiErrorManager, redirectIfUserApplyLogout } from 'api/utils'; import { getCookie } from 'pc/utils'; import { getReleaseVersion, getSpaceIdFormTemplate } from 'pc/utils/env'; diff --git a/packages/datasheet/src/pc/common/clipboard/clipboard.ts b/packages/datasheet/src/pc/common/clipboard/clipboard.ts index 34f35a4e34..de16bf88d4 100644 --- a/packages/datasheet/src/pc/common/clipboard/clipboard.ts +++ b/packages/datasheet/src/pc/common/clipboard/clipboard.ts @@ -23,7 +23,8 @@ import { ExecuteResult, FieldType, IAttachmentValue, - ICollaCommandExecuteResult, IField, + ICollaCommandExecuteResult, + IField, IGridViewColumn, IGridViewProperty, IRange, @@ -38,6 +39,7 @@ import { Strings, t, ViewType, + getRecordChunkSize, } from '@apitable/core'; import { Message } from 'pc/components/common/message/message'; import { Modal } from 'pc/components/common/modal/modal/modal'; @@ -220,6 +222,7 @@ export class Clipboard { rows: IViewRow[]; }; isCutting = false; + chunkSize = getRecordChunkSize(); selectWithWorkdocField(tableHeader?: IField[]) { const state = store.getState() as IReduxState; @@ -235,11 +238,13 @@ export class Clipboard { // select section with workdoc field cannot be const visibleColumns = Selectors.getVisibleColumns(state); const fieldMap = Selectors.getFieldMap(state)!; - if (tableHeader) { // paste + if (tableHeader) { + // paste // loop tableHeader to check if there is workdoc field _selectWithWorkdocField = tableHeader.some((field) => field.type === FieldType.WorkDoc); - } else { // copy - for(let idx = fieldMinIndex; idx <= fieldMaxIndex; idx++) { + } else { + // copy + for (let idx = fieldMinIndex; idx <= fieldMaxIndex; idx++) { const { fieldId } = visibleColumns[idx]; const field = fieldMap[fieldId]; if (field.type === FieldType.WorkDoc) { @@ -252,7 +257,7 @@ export class Clipboard { return _selectWithWorkdocField; } - paste(e: ClipboardEvent, ignoreEdit?: boolean) { + paste(e: ClipboardEvent, ignoreEdit?: boolean, cb?: (_total: number, _completed: number) => void) { const state = store.getState() as IReduxState; if (ShortcutContext.context.isEditing() && !ignoreEdit) { return; @@ -266,8 +271,9 @@ export class Clipboard { } const selection = selections[0]; - const clipboardData = e.clipboardData; + const clipboardData = e.clipboardData || (window as any).clipboardData; if (!clipboardData) { + console.warn('! ' + 'Clipboard data is not supported'); return; } @@ -316,6 +322,7 @@ export class Clipboard { selection, stdValueTable!, clipboardText, + cb, )) as any as ICollaCommandExecuteResult<{}> & { isPasteIncompatibleField: boolean }; this.clearCuttingStatus(); if (commandResult.result === ExecuteResult.Fail) { @@ -351,11 +358,18 @@ export class Clipboard { pasteRange: IRange, stdValueTable: IStandardValueTable, clipboardText: string, + cb?: (_total: number, _completed: number) => void, ) { const viewId = pasteView.id; const { row, column } = Range.bindModel(pasteRange).toNumberBaseRange(state)!; const { id: datasheetId, snapshot } = Selectors.getDatasheet(state)!; const rows = Selectors.getVisibleRows(state); + const viewLength = snapshot.meta.views.length; + const fieldLength = Object.keys(snapshot.meta.fieldMap).length; + // view length over 10 or field length over 50, set chunkSize to 100 + if (viewLength > 10 || fieldLength > 50) { + this.chunkSize = 100; + } const groupFields = Selectors.getGroupFields(pasteView, Selectors.getFieldMap(state, state.pageParams.datasheetId!)!).map((f) => f.id); const recordValue = snapshot.recordMap[rows[row].recordId].data; const cellValues = groupFields.map((f) => (recordValue ? recordValue[f] : null)); @@ -379,20 +393,55 @@ export class Clipboard { } } - commandResult = this.commandManager.execute({ - cmd: CollaCommandName.PasteSetRecords, - row, - column, - viewId, - fields: stdValueTable.header, - stdValues: stdValueTable.body, - recordIds: stdValueTable.recordIds, - cut: isRealCutting ? this.cuttingRangeData : undefined, - groupCellValues: cellValues, - notifyExistIncompatibleField: () => { - isPasteIncompatibleField = true; - }, + const length = stdValueTable.recordIds?.length ?? stdValueTable.body.length ?? 0; + const times = Math.ceil(length / this.chunkSize); + console.log('paste data', { + stdValueTable, times }); + for (let i = 0; i < times; i++) { + if (i === 0) { + cb?.(length, 0); + } + const recordIds = stdValueTable.recordIds?.slice(i * this.chunkSize, (i + 1) * this.chunkSize); + const stdValues = stdValueTable.body.slice(i * this.chunkSize, (i + 1) * this.chunkSize); + const _row = row + i * this.chunkSize; + commandResult = this.commandManager.execute({ + cmd: CollaCommandName.PasteSetRecords, + row: _row, + column, + viewId, + fields: stdValueTable.header, + stdValues, + recordIds, + cut: isRealCutting ? this.cuttingRangeData : undefined, + groupCellValues: cellValues, + notifyExistIncompatibleField: () => { + isPasteIncompatibleField = true; + }, + }); + // cover paste no actions and result is None + if (commandResult.result !== ExecuteResult.None) { + // await until the operation is completed + await new Promise((resolve) => { + const doingOpMessageId = localStorage.getItem('doing_op_messageId'); + if (doingOpMessageId) { + window.addEventListener(doingOpMessageId, () => { + resolve(); + // remove event listener + window.removeEventListener(doingOpMessageId, () => {}); + }); + } + }); + } + await new Promise((resolve) => setTimeout(resolve, 1000)); + cb?.(length, this.chunkSize * i + (recordIds?.length ?? stdValues?.length ?? 0)); + const isChunkStop = localStorage.getItem('stop_chunk') === 'stop'; + if (isChunkStop) { + localStorage.removeItem('stop_chunk'); + window.location.reload(); + break; + } + } recogClipboardURLData({ state, row, @@ -427,11 +476,50 @@ export class Clipboard { if (!stdValueTable) { return pre; } + + const allowCopyDataToExternal = state.space.spaceFeatures?.allowCopyDataToExternal || state.share.allowCopyDataToExternal; + const fieldPermissionMap = Selectors.getFieldPermissionMap(state); + const noPermissionCopyFieldIndex: number[] = []; + + stdValueTable.header = stdValueTable.header.filter((field, index) => { + const fieldRole = Selectors.getFieldRoleByFieldId(fieldPermissionMap, field.id); + + if (!allowCopyDataToExternal && fieldRole && fieldRole !== ConfigConstant.Role.Editor) { + noPermissionCopyFieldIndex.push(index); + return false; + } + + return true; + }); + + if (!stdValueTable.header.length) { + // 如果经过权限筛选后,选区内的所有列都没有权限 copy 数据,这里直接返回 + return pre; + } + + let _body = stdValueTable.body; + + if (noPermissionCopyFieldIndex.length) { + /** + * 这里 stdValueTable.body 的数据格式为一个二维数组, + * 第一个纬度是选区的每一行, + * 第二个纬度是每一行中,选区从左往右对应每一列的单元格数据 + * + * 因此这里的逻辑就是删除第二层数组中,对应位置的数据 + */ + _body = _body.map((row) => { + return row.filter((_, index) => !noPermissionCopyFieldIndex.includes(index)); + }); + } + return { ...stdValueTable, - body: pre.body ? [...pre.body, ...stdValueTable.body] : stdValueTable.body, + body: pre.body ? [...pre.body, ..._body] : _body, }; }, {} as IStandardValueTable); + + if (!Object.keys(stdValueTable).length) return; + const text = Serializer.csv.serialize(stdValueTable); const ie = browser?.satisfies({ ie: '*' }); let html = ''; @@ -515,6 +603,7 @@ export class Clipboard { } const activeCell = Selectors.getActiveCell(store.getState()); if (!activeCell) { + console.warn('! ' + 'No active cell'); return; } const snapshot = Selectors.getSnapshot(store.getState()); diff --git a/packages/datasheet/src/pc/common/initializer.ts b/packages/datasheet/src/pc/common/initializer.ts index ee69a97f75..086cca0da8 100644 --- a/packages/datasheet/src/pc/common/initializer.ts +++ b/packages/datasheet/src/pc/common/initializer.ts @@ -74,6 +74,7 @@ function initBugTracker() { ignoreErrors: [ // It was found that all hovers where tooltip appears send a request to sentry and the exception status is this 'ResizeObserver loop limit exceeded', + 'JSON Parse error: Unexpected EOF', ], }); } diff --git a/packages/datasheet/src/pc/common/store_subscribe/keep_id.ts b/packages/datasheet/src/pc/common/store_subscribe/keep_id.ts index 87b2cbf5b5..b01dec11e8 100644 --- a/packages/datasheet/src/pc/common/store_subscribe/keep_id.ts +++ b/packages/datasheet/src/pc/common/store_subscribe/keep_id.ts @@ -24,6 +24,7 @@ let viewId: string | undefined; let dashboardId: string | undefined; let mirrorId: string | undefined; let aiId: string | undefined; +let automationId: string | undefined; store.subscribe(function folderIdChange() { const previousFolderId = folderId; @@ -31,6 +32,7 @@ store.subscribe(function folderIdChange() { const previousDashboard = dashboardId; const previousMirrorId = mirrorId; const previousAIId = aiId; + const previousAutomationId = automationId; const state = store.getState(); // The userInfo is not updated until it is loaded. @@ -47,6 +49,7 @@ store.subscribe(function folderIdChange() { mirrorId = state.pageParams.mirrorId; dashboardId = state.pageParams.dashboardId; aiId = state.pageParams.aiId; + automationId = state.pageParams.automationId; if (folderId && previousFolderId !== folderId && !templateId && !shareId) { Api.keepTabbar({ @@ -56,6 +59,14 @@ store.subscribe(function folderIdChange() { return; } + if (automationId && previousAutomationId !== automationId && !templateId && !shareId) { + Api.keepTabbar({ + nodeId: automationId, + }); + store.dispatch(StoreActions.updateUserInfo({ activeNodeId: automationId })); + return; + } + if (aiId && previousAIId !== aiId && !templateId && !shareId) { Api.keepTabbar({ nodeId: aiId, diff --git a/packages/datasheet/src/pc/common/store_subscribe/mirror_id.ts b/packages/datasheet/src/pc/common/store_subscribe/mirror_id.ts index 7d1b8a7c95..e3a929cdb5 100644 --- a/packages/datasheet/src/pc/common/store_subscribe/mirror_id.ts +++ b/packages/datasheet/src/pc/common/store_subscribe/mirror_id.ts @@ -28,14 +28,22 @@ let mirrorId: string | undefined; store.subscribe(function datasheetIdChange() { const state = store.getState(); const spaceId = state.space.activeId || state.share.spaceId; - const { shareId, templateId } = state.pageParams; - if (!spaceId && !shareId && !templateId) { + const { shareId, templateId, embedId } = state.pageParams; + + if (!spaceId && !shareId && !templateId && !embedId) { return; } + if (shareId && (!spaceId || !resourceService.instance?.initialized)) { return; } + + if (embedId && (!resourceService.instance?.initialized || !state.embedInfo?.spaceId)) { + return; + } + const previousMirrorId = mirrorId; + mirrorId = state.pageParams.mirrorId; if (!mirrorId || previousMirrorId === mirrorId) { diff --git a/packages/datasheet/src/pc/common/store_subscribe/share_id.ts b/packages/datasheet/src/pc/common/store_subscribe/share_id.ts index f2b0ee8a69..4c9df783ca 100644 --- a/packages/datasheet/src/pc/common/store_subscribe/share_id.ts +++ b/packages/datasheet/src/pc/common/store_subscribe/share_id.ts @@ -38,6 +38,7 @@ store.subscribe(function shareIdChange() { store.dispatch( StoreActions.setShareInfo({ spaceId: data.spaceId, + shareNodeTree: data.shareNodeTree, }), ); } diff --git a/packages/datasheet/src/pc/common/wizard.ts b/packages/datasheet/src/pc/common/wizard.ts new file mode 100644 index 0000000000..08a2fd80de --- /dev/null +++ b/packages/datasheet/src/pc/common/wizard.ts @@ -0,0 +1,256 @@ +import produce from 'immer'; +import { SystemConfigInterfaceGuide, SystemConfigInterfacePlayer, t, Strings } from '@apitable/core'; + +interface IWizardsConfig { + player: SystemConfigInterfacePlayer; + guide: SystemConfigInterfaceGuide; +} + +class WizardBuilder { + private event: WizardEvent | null = null; + action: IAction | null = null; + + trigger: IWizardTrigger | null = null; + + private steps: { id: number; item: any }[] = []; + + wizardId: number | null = null; + wizard: IWizardItem | null = null; + + get getSteps() { + return this.steps.reduce((acc, cur) => { + acc[cur.id] = cur.item; + return acc; + }, {}); + } + + constructor() {} + + public addEvent(_event: WizardEvent) { + this.event = _event; + return this; + } + + public addAction(action: IAction) { + this.action = action; + return this; + } + + public addWizard(id: number, item: IWizardItem) { + this.wizardId = id; + this.wizard = item; + return this; + } + + public addTrigger(trigger: IWizardTrigger) { + this.trigger = trigger; + return this; + } + + public addStep(id: number, guide: any) { + this.steps = [ + ...this.steps, + { + id, + item: guide, + }, + ]; + return this; + } +} + +const CONST_MODIFYED_WIZARDS = [ + new WizardBuilder() + .addEvent({ + module: 'guide', + name: 'use_automation_first_time', + }) + .addAction({ + id: 'open_guide_wizard(118)', + description: '打开引导向导 首次Button列', + command: 'open_guide_wizard', + commandArgs: '118', + }) + .addTrigger({ + actions: ['open_guide_wizard(118)'], + rules: ['device_IS_pc', 'url_EXCLUDES_templateId', 'url_EXCLUDES_shareId'], + id: 'guide_use_button_column_first_time,[device_IS_pc, url_EXCLUDES_templateId, url_EXCLUDES_shareId],[open_guide_wizard(118)]', + event: ['guide_use_button_column_first_time'], + }) + .addStep(181, { + description: 'ui dialog for use button field first time active create action ', + next: '好的', + nextId: 'okay', + onClose: ['set_wizard_completed({"curWizard": true})', 'open_guide_next_step({"clearAllPrevUi":true})'], + onSkip: ['clear_guide_all_ui()'], + onTarget: ['set_wizard_completed({"curWizard": true})', 'open_guide_next_step({"clearAllPrevUi":true})'], + onNext: ['set_wizard_completed({"curWizard": true})', 'open_guide_next_step({"clearAllPrevUi":true})'], + uiConfig: '{\n "element": "#CONST_ROBOT_ACTION_CREATE"\n} ', + uiConfigId: 'player_step_ui_config_button_field_action_create', + skipId: 'skip', + uiType: 'popover', + }) + .addStep(180, { + description: 'ui dialog for use button field first time active bind datasheeet ', + nextId: 'next_step', + next: '下一步', + onSkip: ['clear_guide_all_ui()'], + onClose: ['set_wizard_completed({"curWizard": true})', 'open_guide_next_step({"clearAllPrevUi":true})'], + skip: '跳过', + skipId: 'skip', + onTarget: ['set_wizard_completed({"curWizard": true})', 'open_guide_next_step({"clearAllPrevUi":true})'], + onNext: ['open_guide_next_step({"clearAllPrevUi":true})'], + uiConfig: '{\n "element": "#AUTOMATION_BOUND_DATASHEET"\n} ', + uiConfigId: 'player_step_ui_config_button_field_bound_datasheet', + uiType: 'popover', + }) + .addStep(178, { + description: 'ui dialog for use button field first time and active node ', + next: '下一步', + nextId: 'next_step', + onClose: ['open_guide_next_step({"clearAllPrevUi":true})'], + onSkip: ['clear_guide_all_ui()'], + onTarget: ['open_guide_next_step({"clearAllPrevUi":true})'], + onNext: ['open_guide_next_step({"clearAllPrevUi":true})'], + skip: '跳过', + skipId: 'skip', + uiConfig: '{\n "element": ".TREE_NODE_ACTIVE_ONE", "description": "description", "title": "title"\n} ', + uiConfigId: 'player_step_ui_config_button_field_node', + uiType: 'popover', + }) + .addStep(179, { + description: 'ui dialog for use button field first time for node actived status ', + next: '下一步', + nextId: 'next_step', + onClose: ['set_wizard_completed({"curWizard": true})', 'open_guide_next_step({"clearAllPrevUi":true})'], + onSkip: ['clear_guide_all_ui()'], + onTarget: ['set_wizard_completed({"curWizard": true})', 'open_guide_next_step({"clearAllPrevUi":true})'], + onNext: ['open_guide_next_step({"clearAllPrevUi":true})'], + skip: '跳过', + skipId: 'skip', + uiConfig: '{\n "element": "#NODE_FORM_ACTIVE"\n} ', + uiConfigId: 'player_step_ui_config_button_field_node_form_active', + uiType: 'popover', + }) + .addWizard(118, { + description: 'steps for automation button', + completeIndex: 0, + player: { + action: ['rec4kT7UZkdww'], + }, + repeat: true, + steps: '[[178], [179], [180], [181]]', + }), +]; + +interface IUIConfig { + element?: string; + description?: string; + title?: string; + placement: 'bottomLeft' | string; +} + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +const uiConfig: IUIConfig = { + element: '#NODE_FORM_ACTIVE', + title: t(Strings.export), + placement: 'bottomLeft', + description: t(Strings.export), +}; + +interface IGuideItem { + description?: string; + next?: string; + nextId?: string; + skip?: string; + skipId: string; + onClose?: string[]; + onNext?: string[]; + onSkip?: string[]; + uiConfig?: string; + uiConfigId?: string; + onTarget: string[]; + uiType: 'popover' | string; +} + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +const stepId = 179; +// eslint-disable-next-line @typescript-eslint/no-unused-vars +const stepItem: IGuideItem = { + description: 'ui dialog for use button field first time for node actived status ', + next: '下一步', + nextId: 'next_step', + onClose: ['set_wizard_completed({"curWizard": true})', 'open_guide_next_step({"clearAllPrevUi":true})'], + onSkip: ['clear_guide_all_ui()'], + onTarget: ['set_wizard_completed({"curWizard": true})', 'open_guide_next_step({"clearAllPrevUi":true})'], + onNext: ['open_guide_next_step({"clearAllPrevUi":true})'], + skip: '跳过', + skipId: 'skip', + uiConfig: '{\n "element": "#NODE_FORM_ACTIVE"\n} ', + uiConfigId: 'player_step_ui_config_button_field_node_form_active', + uiType: 'popover', +}; + +// const 118 = +interface IWizardItem { + description?: string; + completeIndex?: number; + steps: string; + repeat: boolean; + player: { + action: string[]; + }; +} + +export interface IAction { + id: string; + description: string; + command: string; + commandArgs: string; +} + +export interface IWizardTrigger { + actions: string[]; + rules: string[]; + id: string; + event: string[]; +} + +// eslint-disable-next-line @typescript-eslint/no-unused-vars +const action: IWizardTrigger = { + actions: ['open_guide_wizard(118)'], + rules: ['device_IS_pc', 'url_EXCLUDES_templateId', 'url_EXCLUDES_shareId'], + id: 'guide_use_button_column_first_time,[device_IS_pc, url_EXCLUDES_templateId, url_EXCLUDES_shareId],[open_guide_wizard(118)]', + event: ['guide_use_button_column_first_time'], +}; + +// eslint-disable-next-line @typescript-eslint/naming-convention +export interface WizardEvent { + module: string; + name: string; +} + +export interface IRobotItem { + actions: string[]; + rules: string[]; + id: string; + event: string[]; +} + +export const transpile = (item: IWizardsConfig, wizardBuilder: WizardBuilder) => { + return produce(item, (draft) => { + draft.guide.step = { ...draft.guide.step, ...wizardBuilder.getSteps }; + if (wizardBuilder.wizard) { + draft.guide.wizard = { ...draft.guide.wizard, [String(wizardBuilder.wizardId)]: wizardBuilder.wizard }; + } + if (wizardBuilder.action) { + draft.player.action = [...draft.player.action, wizardBuilder.action]; + } + if (wizardBuilder.trigger) { + draft.player.trigger = draft.player.trigger.concat(wizardBuilder.trigger); + } + }); +}; +export function modifyWizardConfig(item: IWizardsConfig): IWizardsConfig { + return CONST_MODIFYED_WIZARDS.reduce((acc, cur) => transpile(acc, cur), item); +} diff --git a/packages/datasheet/src/pc/components/address_list/address_list.tsx b/packages/datasheet/src/pc/components/address_list/address_list.tsx index 985dcfcdf3..41308a76f0 100644 --- a/packages/datasheet/src/pc/components/address_list/address_list.tsx +++ b/packages/datasheet/src/pc/components/address_list/address_list.tsx @@ -26,6 +26,7 @@ import { IReduxState, StoreActions, Strings, t } from '@apitable/core'; // eslint-disable-next-line no-restricted-imports import { Tooltip } from 'pc/components/common'; import { useAppDispatch } from 'pc/hooks/use_app_dispatch'; +import { useAppSelector } from 'pc/store/react-redux'; import OrgImageDark from 'static/icon/organization/contacts_empty_dark.png'; import OrgImageLight from 'static/icon/organization/contacts_empty_light.png'; import { ComponentDisplay } from '../common/component_display'; @@ -34,11 +35,9 @@ import { CommonSide } from '../common_side'; import { MobileBar } from '../mobile_bar'; import { MemberInfo } from './member_info'; import { MemberList } from './member_list'; -import styles from './style.module.less'; // @ts-ignore import { isContactSyncing, isSocialDingTalk } from 'enterprise/home/social_platform/utils'; - -import {useAppSelector} from "pc/store/react-redux"; +import styles from './style.module.less'; const _SplitPane: any = SplitPane; @@ -87,7 +86,7 @@ export const AddressList: React.FC> = () => {
{selectedTeamInfo.teamTitle}
- ({memberListTotal} + ({memberList.length}/{memberListTotal} {t(Strings.person)}) diff --git a/packages/datasheet/src/pc/components/address_list/address_tree_menu/address_tree_menu.tsx b/packages/datasheet/src/pc/components/address_list/address_tree_menu/address_tree_menu.tsx index 043fce581d..f42059c949 100644 --- a/packages/datasheet/src/pc/components/address_list/address_tree_menu/address_tree_menu.tsx +++ b/packages/datasheet/src/pc/components/address_list/address_tree_menu/address_tree_menu.tsx @@ -25,8 +25,8 @@ import { TriangleRightFilled } from '@apitable/icons'; // eslint-disable-next-line no-restricted-imports import { Tooltip } from 'pc/components/common'; import { useAppDispatch } from 'pc/hooks/use_app_dispatch'; +import { useAppSelector } from 'pc/store/react-redux'; import styles from './style.module.less'; -import {useAppSelector} from "pc/store/react-redux"; const { TreeNode, DirectoryTree } = Tree; diff --git a/packages/datasheet/src/pc/components/address_list/address_tree_menu/style.module.less b/packages/datasheet/src/pc/components/address_list/address_tree_menu/style.module.less index d308050896..1f2eaed76f 100644 --- a/packages/datasheet/src/pc/components/address_list/address_tree_menu/style.module.less +++ b/packages/datasheet/src/pc/components/address_list/address_tree_menu/style.module.less @@ -5,7 +5,7 @@ flex-direction: column; height: 100%; overflow: hidden; - .light-scroll-bar(); + .default-scroll-bar(); &:hover { overflow-y: auto; } diff --git a/packages/datasheet/src/pc/components/address_list/member_info/member_info.tsx b/packages/datasheet/src/pc/components/address_list/member_info/member_info.tsx index 4e062b02e6..edf60620d5 100644 --- a/packages/datasheet/src/pc/components/address_list/member_info/member_info.tsx +++ b/packages/datasheet/src/pc/components/address_list/member_info/member_info.tsx @@ -27,12 +27,11 @@ import { EditOutlined } from '@apitable/icons'; import { Avatar, Tooltip, AvatarSize, ButtonPlus } from 'pc/components/common'; import { Identity } from 'pc/components/space_manage/identity'; import { useAddressRequest } from 'pc/hooks'; +import { useAppSelector } from 'pc/store/react-redux'; import { getEnvVariables } from 'pc/utils/env'; -import styles from './style.module.less'; // @ts-ignore import { getSocialWecomUnitName, isSocialFeiShu, isSocialPlatformEnabled } from 'enterprise/home/social_platform/utils'; - -import {useAppSelector} from "pc/store/react-redux"; +import styles from './style.module.less'; export const getIdentity = (memberInfo: IMemberInfoInAddressList) => { if (!memberInfo.isActive) return 'inactive'; @@ -100,8 +99,8 @@ export const MemberInfo: FC> = () => { const identity = getIdentity({ ...memberInfo, - isMainAdmin: memberInfo.isSubAdmin, - isAdmin: memberInfo.isPrimary, + isMainAdmin: memberInfo.isPrimary, + isAdmin: memberInfo.isSubAdmin, }); const { avatar, avatarColor, nickName, memberId, memberName, mobile, email, isMemberNameModified, teamData } = memberInfo; diff --git a/packages/datasheet/src/pc/components/address_list/member_list/member_list.tsx b/packages/datasheet/src/pc/components/address_list/member_list/member_list.tsx index b0862f76fa..82e1759be4 100644 --- a/packages/datasheet/src/pc/components/address_list/member_list/member_list.tsx +++ b/packages/datasheet/src/pc/components/address_list/member_list/member_list.tsx @@ -20,7 +20,7 @@ import { useThrottleFn } from 'ahooks'; import { List } from 'antd'; import VirtualList from 'rc-virtual-list'; import { FC, useState, useEffect } from 'react'; -import { Loading } from '@apitable/components'; +import { Loading, TextButton } from '@apitable/components'; import { IMemberInfoInAddressList, Navigation, StoreActions, Strings, t, ConfigConstant } from '@apitable/core'; import { InfoCard } from 'pc/components/common'; import { ScreenSize } from 'pc/components/common/component_display/enum'; @@ -28,13 +28,12 @@ import { Router } from 'pc/components/route_manager/router'; import { Identity } from 'pc/components/space_manage/identity'; import { useResponsive } from 'pc/hooks'; import { useAppDispatch } from 'pc/hooks/use_app_dispatch'; +import { useAppSelector } from 'pc/store/react-redux'; import { expandMemberInfo } from '../expand_member_info'; import { getIdentity } from '../member_info'; -import styles from './style.module.less'; // @ts-ignore import { getSocialWecomUnitName } from 'enterprise/home/social_platform/utils'; - -import {useAppSelector} from "pc/store/react-redux"; +import styles from './style.module.less'; export interface IMemberList { memberList: IMemberInfoInAddressList[]; @@ -83,25 +82,27 @@ export const MemberList: FC> = (props) => { const { run: loadData } = useThrottleFn(() => handleScroll(), { wait: 500 }); - const onScroll = (e: React.UIEvent) => { - const pages = Math.ceil(memberListTotal / ConfigConstant.MEMBER_LIST_PAGE_SIZE); - if (e.currentTarget.scrollHeight - e.currentTarget.scrollTop === listHeight && memberListPageNo < pages) { - loadData(); - } - }; + const hasMore = memberListPageNo < Math.ceil(memberListTotal / ConfigConstant.MEMBER_LIST_PAGE_SIZE); return (
- {(item) => { + {(_item) => { + if (_item === 'end') { + return ( + loadData()} color="primary"> + {t(Strings.click_load_more)} + + ); + } + const item = _item as IMemberInfoInAddressList; const { memberId, memberName, email, avatar, isActive, isMemberNameModified, avatarColor, nickName } = item; const title = getSocialWecomUnitName?.({ @@ -149,7 +150,6 @@ export const MemberList: FC> = (props) => { ); }} - {/*
*/}
{memberListLoading && (
diff --git a/packages/datasheet/src/pc/components/address_list/member_list/style.module.less b/packages/datasheet/src/pc/components/address_list/member_list/style.module.less index 69ed5df2bb..bb993a9f74 100644 --- a/packages/datasheet/src/pc/components/address_list/member_list/style.module.less +++ b/packages/datasheet/src/pc/components/address_list/member_list/style.module.less @@ -14,7 +14,7 @@ .memberListWrapper { .rc-virtual-list-holder-inner { - .light-scroll-bar(); + .default-scroll-bar(); } } diff --git a/packages/datasheet/src/pc/components/api_panel/api_panel.tsx b/packages/datasheet/src/pc/components/api_panel/api_panel.tsx index e1582ac063..1f04741209 100644 --- a/packages/datasheet/src/pc/components/api_panel/api_panel.tsx +++ b/packages/datasheet/src/pc/components/api_panel/api_panel.tsx @@ -23,6 +23,7 @@ import { useDispatch } from 'react-redux'; import { Button, Checkbox, Divider, useThemeColors } from '@apitable/components'; import { ResourceType, Selectors, StoreActions, Strings, t } from '@apitable/core'; import { ApiOutlined, BookOutlined, AdjustmentOutlined, CloseOutlined } from '@apitable/icons'; +import { useAppSelector } from 'pc/store/react-redux'; import { getEnvVariables } from 'pc/utils/env'; import { Message } from '../common'; import { InlineNodeName } from '../common/inline_node_name'; @@ -32,8 +33,6 @@ import { FieldCode } from './field_codes/field_codes'; import { FieldDocs } from './field_docs'; import styles from './styles.module.less'; -import {useAppSelector} from "pc/store/react-redux"; - export const ApiPanel: React.FC> = () => { const colors = useThemeColors(); const isApiPanelOpen = useAppSelector((state) => state.space.isApiPanelOpen); diff --git a/packages/datasheet/src/pc/components/api_panel/field_codes/doc_inner_html.tsx b/packages/datasheet/src/pc/components/api_panel/field_codes/doc_inner_html.tsx index a3c1d5e4c1..7c9a884e5b 100644 --- a/packages/datasheet/src/pc/components/api_panel/field_codes/doc_inner_html.tsx +++ b/packages/datasheet/src/pc/components/api_panel/field_codes/doc_inner_html.tsx @@ -20,14 +20,13 @@ import template from 'lodash/template'; import * as React from 'react'; import { ModalType, Strings, t } from '@apitable/core'; import { Modal } from 'pc/components/common'; +import { useAppSelector } from 'pc/store/react-redux'; import { getEnvVariables } from 'pc/utils/env'; import { getStorage, setStorage, StorageName } from 'pc/utils/storage'; import { CodeLanguage } from './enum'; import { getDoc } from './examples'; import mdStyles from './markdown.module.less'; -import {useAppSelector} from "pc/store/react-redux"; - export interface IDocInnerHtmlProps { language: CodeLanguage; exampleConfig: any; diff --git a/packages/datasheet/src/pc/components/api_panel/field_codes/field_codes.tsx b/packages/datasheet/src/pc/components/api_panel/field_codes/field_codes.tsx index 4c9aaac655..c5a4948eea 100644 --- a/packages/datasheet/src/pc/components/api_panel/field_codes/field_codes.tsx +++ b/packages/datasheet/src/pc/components/api_panel/field_codes/field_codes.tsx @@ -23,14 +23,13 @@ import { LinkButton } from '@apitable/components'; import { Field, FieldType, Selectors, Strings, t } from '@apitable/core'; import { Loading } from 'pc/components/common'; import { store } from 'pc/store'; +import { useAppSelector } from 'pc/store/react-redux'; import { getEnvVariables } from 'pc/utils/env'; import githubIcon from 'static/icon/common/github_octopus.png'; import { getFieldDocs } from '../field_docs/api_panel_config'; import { CodeLanguage, CodeType } from './enum'; import styles from './styles.module.less'; -import {useAppSelector} from "pc/store/react-redux"; - const DocInnerHtml = dynamic(() => import('./doc_inner_html'), { ssr: false, loading: () => , diff --git a/packages/datasheet/src/pc/components/api_panel/field_docs/field_docs.tsx b/packages/datasheet/src/pc/components/api_panel/field_docs/field_docs.tsx index 4ea0465655..82ce1a08cf 100644 --- a/packages/datasheet/src/pc/components/api_panel/field_docs/field_docs.tsx +++ b/packages/datasheet/src/pc/components/api_panel/field_docs/field_docs.tsx @@ -21,11 +21,10 @@ import { useThemeColors } from '@apitable/components'; import { Field, FieldType, FieldTypeDescriptionMap, Selectors, Strings, t } from '@apitable/core'; import { useGetSignatureAssertByToken } from '@apitable/widget-sdk'; import { getFieldTypeIcon } from 'pc/components/multi_grid/field_setting'; +import { useAppSelector } from 'pc/store/react-redux'; import { getFieldDocs } from './api_panel_config'; import styles from './styles.module.less'; -import {useAppSelector} from "pc/store/react-redux"; - interface IFieldDocs { recordId?: string; fieldId: string; diff --git a/packages/datasheet/src/pc/components/archive_record/index.tsx b/packages/datasheet/src/pc/components/archive_record/index.tsx index d0c784344b..f06fc65ed0 100644 --- a/packages/datasheet/src/pc/components/archive_record/index.tsx +++ b/packages/datasheet/src/pc/components/archive_record/index.tsx @@ -200,9 +200,8 @@ export const ArchivedRecords: React.FC `${item.name} (${getEnvVariables()[item.bucket] + item.token})`).join(', '); case FieldType.Link: - return null; case FieldType.OneWayLink: - return cellValue?.map((item) => item).join(', '); + return Array.isArray(cellValue) ? cellValue.map((item) => item).join(', ') : cellValue; case FieldType.Currency: case FieldType.Percent: case FieldType.AutoNumber: diff --git a/packages/datasheet/src/pc/components/archive_record/style.module.less b/packages/datasheet/src/pc/components/archive_record/style.module.less index 77488e0443..a38a8ebbd1 100644 --- a/packages/datasheet/src/pc/components/archive_record/style.module.less +++ b/packages/datasheet/src/pc/components/archive_record/style.module.less @@ -99,7 +99,7 @@ .ant-table-row { &:hover { td { - background-color: var(--bgBglessSolidHover) !important; + background-color: var(--bgBglessHoverSolid) !important; } } } diff --git a/packages/datasheet/src/pc/components/automation/components/list_with_footer/index.tsx b/packages/datasheet/src/pc/components/automation/components/list_with_footer/index.tsx index 967637f032..90424fe363 100644 --- a/packages/datasheet/src/pc/components/automation/components/list_with_footer/index.tsx +++ b/packages/datasheet/src/pc/components/automation/components/list_with_footer/index.tsx @@ -6,7 +6,7 @@ export const ListWithFooter: FC<{ padding?: string; footer: ReactElement; children: ReactElement; -}> = ({ footer, children, className ,padding}) => { +}> = ({ footer, children, className, padding }) => { return ( <> diff --git a/packages/datasheet/src/pc/components/automation/config.ts b/packages/datasheet/src/pc/components/automation/config.ts index 38a0955dbd..cd9330bf8b 100644 --- a/packages/datasheet/src/pc/components/automation/config.ts +++ b/packages/datasheet/src/pc/components/automation/config.ts @@ -8,7 +8,8 @@ export function orDisabled(arr: T[], enabled: boolean) { } export const AutomationConstant = { - DEFAULT_TEXT : t(Strings.click_start), - defaultColor : 40, - whiteColor : 50, + DEFAULT_TEXT: t(Strings.click_start), + defaultColor: 40, + whiteColor: 50, + buttonHeight: 24, }; diff --git a/packages/datasheet/src/pc/components/automation/content/basic_info/index.tsx b/packages/datasheet/src/pc/components/automation/content/basic_info/index.tsx index 2e2895dae4..91f1eb1d6b 100644 --- a/packages/datasheet/src/pc/components/automation/content/basic_info/index.tsx +++ b/packages/datasheet/src/pc/components/automation/content/basic_info/index.tsx @@ -12,6 +12,7 @@ import { TimeOutlined, UserEditOutlined } from '@apitable/icons'; +import EllipsisText from 'pc/components/ellipsis_text'; import { getNodeTypeByNodeId } from '../../../../utils'; import { NodeIcon } from '../../../catalog/tree/node_icon'; import { Avatar, AvatarType } from '../../../common'; @@ -24,7 +25,6 @@ import { automationHistoryAtom, automationStateAtom } from '../../controller/ato import { useAutomationResourcePermission } from '../../controller/use_automation_permission'; import { TaskList } from '../../run_history/list/task'; import style from './styles.module.less'; -import EllipsisText from "pc/components/ellipsis_text"; const StyledGrip = styled(Box)` gap: 16px; diff --git a/packages/datasheet/src/pc/components/automation/content/index.tsx b/packages/datasheet/src/pc/components/automation/content/index.tsx index 47c1b7c89c..5c88d51909 100644 --- a/packages/datasheet/src/pc/components/automation/content/index.tsx +++ b/packages/datasheet/src/pc/components/automation/content/index.tsx @@ -2,14 +2,12 @@ import { Tabs } from 'antd'; import TabPane from 'antd/es/tabs/TabPane'; import { useAtom } from 'jotai'; import * as React from 'react'; -import { FunctionComponent, memo, useEffect } from 'react'; +import { FunctionComponent, memo } from 'react'; import AutoSizer from 'react-virtualized-auto-sizer'; import styled, { css } from 'styled-components'; import { Box, Switch, Typography, useThemeColors, useThemeMode } from '@apitable/components'; import { IReduxState, Strings, t } from '@apitable/core'; import { InfoCircleOutlined } from '@apitable/icons'; -// @ts-ignore -import { goToUpgrade } from 'enterprise/subscribe_system/upgrade_method'; import { VikaSplitPanel } from 'pc/components/common'; import { useAppSelector } from 'pc/store/react-redux'; import { useResponsive, useSideBarVisible } from '../../../hooks'; @@ -20,6 +18,8 @@ import { ListWithFooter } from '../components/list_with_footer'; import { automationPanelAtom, PanelName } from '../controller/atoms'; import { useAutomationResourcePermission } from '../controller/use_automation_permission'; import { Side } from './side'; +// @ts-ignore +import { goToUpgrade } from 'enterprise/subscribe_system/upgrade_method'; import styles from './styles.module.less'; export const ConstAutomationContentLeft = 'automation-content-left'; diff --git a/packages/datasheet/src/pc/components/automation/controller/atoms/index.tsx b/packages/datasheet/src/pc/components/automation/controller/atoms/index.tsx index 7cb4634a26..04209f2dc4 100644 --- a/packages/datasheet/src/pc/components/automation/controller/atoms/index.tsx +++ b/packages/datasheet/src/pc/components/automation/controller/atoms/index.tsx @@ -3,7 +3,6 @@ import { selectAtom } from 'jotai/utils'; import { atomWithImmer } from 'jotai-immer'; import { atomsWithQuery } from 'jotai-tanstack-query'; import { Api, ConfigConstant, FormApi, IServerFormPack } from '@apitable/core'; -// import { fetchFormPack } from '@apitable/core/dist/modules/database/api/form_api'; import { getFormId } from 'pc/components/automation/controller/hooks/get_form_id'; import { INodeSchema, IRobotAction, IRobotContext, IRobotTrigger } from '../../../robot/interface'; import { loadableWithDefault } from '../../../robot/robot_detail/api'; @@ -17,40 +16,39 @@ const automationDrawerVisibleAtom = atomWithImmer(false); export const formListDstIdAtom = atomWithImmer(''); const automationTriggerDatasheetAtom = atomWithImmer<{ - formId: string|undefined, - id: string|undefined, + formId: string | undefined; + id: string | undefined; }>({ formId: undefined, - id: undefined + id: undefined, }); const automationStateAtom = atomWithImmer(undefined); export const automationNameAtom = selectAtom(automationStateAtom, (automation) => automation?.robot?.name); -export const automationCacheAtom = atomWithImmer< { - map?: Map, - id?:string, - panel?: IAutomationPanel -}>({ - -}); +export const automationCacheAtom = atomWithImmer<{ + map?: Map; + id?: string; + panel?: IAutomationPanel; +}>({}); export const automationCurrentTriggerId = atomWithImmer(undefined); export const automationSourceAtom = atomWithImmer<'datasheet' | undefined>(undefined); export interface ILocalAutomation { - trigger: Map, - action: Map, + trigger: Map; + action: Map; } -const automationLocalMap = atomWithImmer>( - new Map() -); +const automationLocalMap = atomWithImmer>(new Map()); -const automationTriggerAtom: Atom = atom((get) => get(automationStateAtom)?.robot?.triggers?.find(item=> item.triggerId ===get(automationCurrentTriggerId))); +const automationTriggerAtom: Atom = atom( + (get) => get(automationStateAtom)?.robot?.triggers?.find((item) => item.triggerId === get(automationCurrentTriggerId)), +); export const automationTriggersAtom = atom((get) => - (get(automationStateAtom)?.robot?.triggers ?? []).map(item => ({ ...item, id: item.triggerId }))); + (get(automationStateAtom)?.robot?.triggers ?? []).map((item) => ({ ...item, id: item.triggerId })), +); export const formIdAtom = atom((get) => getFormId(get(automationTriggerAtom))); export const automationActionsAtom = atomWithImmer([]); @@ -63,7 +61,6 @@ const automationHistoryAtom = atomWithImmer<{ }); export interface IAutomationPanel { - panelName?: PanelName; dataId?: string; data?: { @@ -83,32 +80,30 @@ const automationPanelAtom = atomWithImmer({ const [selectFormMeta] = atomsWithQuery((get) => ({ queryKey: ['automation_fetchFormPack_formIdMeta', get(automationTriggerDatasheetAtom).formId], queryFn: async ({ queryKey: [, id] }) => { - if(!id) { + if (!id) { return {}; } - return await FormApi.fetchFormPack(String(id!)).then(res => res?.data?.data ?? { - }); + return await FormApi.fetchFormPack(String(id!)).then((res) => res?.data?.data ?? {}); }, })); const [formListAtom] = atomsWithQuery((get) => ({ queryKey: ['automation_ConfigConstant.NodeType.FORM', get(formListDstIdAtom)], queryFn: async ({ queryKey: [, id] }) => { - if(!id) { + if (!id) { return []; } - return await Api.getRelateNodeByDstId(String(id!), undefined, ConfigConstant.NodeType.FORM).then(res => res?.data?.data ?? []); + return await Api.getRelateNodeByDstId(String(id!), undefined, ConfigConstant.NodeType.FORM).then((res) => res?.data?.data ?? []); }, })); const [fetchFormMeta] = atomsWithQuery((get) => ({ queryKey: ['automation_fetchFormPack_formId', get(formIdAtom)], queryFn: async ({ queryKey: [, id] }) => { - if(!id) { + if (!id) { return {}; } - return await FormApi.fetchFormPack(String(id!)).then(res => res?.data?.data ?? { - } as IServerFormPack); + return await FormApi.fetchFormPack(String(id!)).then((res) => res?.data?.data ?? ({} as IServerFormPack)); }, })); @@ -116,4 +111,12 @@ export const loadableFormMeta = loadableWithDefault(fetchFormMeta, undefined); export const loadableFormList = loadableWithDefault(formListAtom, []); export const loadableFormItemAtom = loadableWithDefault(selectFormMeta, []); -export { automationLocalMap, automationStateAtom, automationDrawerVisibleAtom, automationHistoryAtom, automationPanelAtom, automationTriggerAtom, automationTriggerDatasheetAtom }; +export { + automationLocalMap, + automationStateAtom, + automationDrawerVisibleAtom, + automationHistoryAtom, + automationPanelAtom, + automationTriggerAtom, + automationTriggerDatasheetAtom, +}; diff --git a/packages/datasheet/src/pc/components/automation/controller/hooks/get_data_parameter.ts b/packages/datasheet/src/pc/components/automation/controller/hooks/get_data_parameter.ts new file mode 100644 index 0000000000..373508b083 --- /dev/null +++ b/packages/datasheet/src/pc/components/automation/controller/hooks/get_data_parameter.ts @@ -0,0 +1,55 @@ +/** + * APITable + * Copyright (C) 2022 APITable Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +import { IRobotTrigger } from 'pc/components/robot/interface'; + +export const getDataParameter = (trigger: IRobotTrigger['input'] | undefined, fieldName: string) => { + if (!trigger) { + return undefined; + } + + const operands = trigger?.value?.operands ?? []; + + if (operands.length === 0) { + return undefined; + } + // @ts-ignore + const f = operands.findIndex((item) => item === fieldName); + if (f > -1) { + return operands[f + 1].value as T; + } + return undefined; +}; + +export const getDataSlot = (trigger: IRobotTrigger['input'] | undefined, fieldName: string) => { + if (!trigger) { + return undefined; + } + + const operands = trigger?.value?.operands ?? []; + + if (operands.length === 0) { + return undefined; + } + // @ts-ignore + const f = operands.findIndex((item) => item === fieldName); + if (f > -1) { + return operands[f + 1] as T; + } + return undefined; +}; diff --git a/packages/datasheet/src/pc/components/automation/controller/hooks/get_datasheet_id.ts b/packages/datasheet/src/pc/components/automation/controller/hooks/get_datasheet_id.ts index 6f8aaf724c..4c8cdcdb9b 100644 --- a/packages/datasheet/src/pc/components/automation/controller/hooks/get_datasheet_id.ts +++ b/packages/datasheet/src/pc/components/automation/controller/hooks/get_datasheet_id.ts @@ -1,3 +1,21 @@ +/** + * APITable + * Copyright (C) 2022 APITable Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + import { IRobotTrigger } from 'pc/components/robot/interface'; export const getDatasheetId = (trigger?: Pick) => { @@ -11,7 +29,7 @@ export const getDatasheetId = (trigger?: Pick) => { return undefined; } // @ts-ignore - const f = operands.findIndex(item => item === 'datasheetId'); + const f = operands.findIndex((item) => item === 'datasheetId'); if (f > -1) { return operands[f + 1].value; } diff --git a/packages/datasheet/src/pc/components/automation/controller/hooks/get_field_id.ts b/packages/datasheet/src/pc/components/automation/controller/hooks/get_field_id.ts index 101412f272..0d56118251 100644 --- a/packages/datasheet/src/pc/components/automation/controller/hooks/get_field_id.ts +++ b/packages/datasheet/src/pc/components/automation/controller/hooks/get_field_id.ts @@ -1,3 +1,21 @@ +/** + * APITable + * Copyright (C) 2022 APITable Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + import { IRobotTrigger } from 'pc/components/robot/interface'; // TODO refactor rename extract as a parameter @@ -12,7 +30,7 @@ export const getFieldId = (trigger?: Pick) => { return undefined; } // @ts-ignore - const f = operands.findIndex(item => item === 'fieldId'); + const f = operands.findIndex((item) => item === 'fieldId'); if (f > -1) { return operands[f + 1].value; } diff --git a/packages/datasheet/src/pc/components/automation/controller/hooks/get_form_id.ts b/packages/datasheet/src/pc/components/automation/controller/hooks/get_form_id.ts index de68c002b7..d8ade8148a 100644 --- a/packages/datasheet/src/pc/components/automation/controller/hooks/get_form_id.ts +++ b/packages/datasheet/src/pc/components/automation/controller/hooks/get_form_id.ts @@ -1,19 +1,36 @@ -import {IRobotTrigger} from "pc/components/robot/interface"; +/** + * APITable + * Copyright (C) 2022 APITable Ltd. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ -export const getFormId = (trigger?: Pick) => { +import { IRobotTrigger } from 'pc/components/robot/interface'; - if (!trigger) { - return undefined; - } - const operands = trigger?.input?.value?.operands ?? []; +export const getFormId = (trigger?: Pick) => { + if (!trigger) { + return undefined; + } + const operands = trigger?.input?.value?.operands ?? []; - if (operands.length === 0) { - return undefined; - } - // @ts-ignore - const f = operands.findIndex(item => item === 'formId'); - if (f > -1) { - return operands[f + 1].value; - } + if (operands.length === 0) { return undefined; + } + // @ts-ignore + const f = operands.findIndex((item) => item === 'formId'); + if (f > -1) { + return operands[f + 1].value; + } + return undefined; }; diff --git a/packages/datasheet/src/pc/components/automation/controller/hooks/use_robot_fields.ts b/packages/datasheet/src/pc/components/automation/controller/hooks/use_robot_fields.ts index 27775e5214..c9d7d53f02 100644 --- a/packages/datasheet/src/pc/components/automation/controller/hooks/use_robot_fields.ts +++ b/packages/datasheet/src/pc/components/automation/controller/hooks/use_robot_fields.ts @@ -40,51 +40,17 @@ export const getTriggerDatasheetId: (triggers: IRobotTrigger[]) => Promise { - - const automationTrigger = useAtomValue(automationTriggerAtom); - const automationState = useAtomValue(automationStateAtom); - const data = useMemo(() => ({ - formId: getFormId(automationTrigger), - datasheetId: getDatasheetId(automationTrigger) - }), [automationTrigger]); - - const formMeta = useAtomValue(loadableFormMeta); - - const dispatch = useAppDispatch(); - useEffect(() => { - // @ts-ignore - const dId = formMeta?.data?.sourceInfo?.datasheetId; - if (dId) { - dispatch(StoreActions.fetchDatasheet(dId)); - } - - }, [dispatch, formMeta]); - - if (data.datasheetId) { - return data.datasheetId; - } - - if (automationState?.scenario === AutomationScenario.datasheet) { - return activeDatasheetId; - } - // @ts-ignore - return formMeta?.data?.sourceInfo?.datasheetId; -}; - -export const useAutomationRobotFields = (dstId: string) => { - const fieldPermissionMap = useSelector((state: IReduxState) => { - return Selectors.getFieldPermissionMap(state, dstId); - }); - const fields = useAllFieldsByDstId(dstId); - return { fields, fieldPermissionMap }; +export const getTriggerDatasheetId2: (triggers: string[]) => Promise = async (triggers: string[]) => { + const arr = triggers.map(item=> getTriggerDstId(item ?? '')); + const list = await Promise.all(arr); + return list; }; -export const useAutomationFieldInfo = (triggers: IRobotTrigger[], dstIds: IFetchedDatasheet[]) => { +export const useAutomationFieldInfo = (triggers: string[]) => { const fieldPermissionMap = useSelector((state: IReduxState) => { - return triggers.map((trigger, index) => ({ - fields: getAllFieldsByDstIdFp(state, dstIds[index]), - fieldPermissionMap: Selectors.getFieldPermissionMap(state, dstIds[index]) + return triggers.map((trigger) => ({ + fields: getAllFieldsByDstIdFp(state, trigger), + fieldPermissionMap: Selectors.getFieldPermissionMap(state, trigger) })); }); diff --git a/packages/datasheet/src/pc/components/automation/controller/use_automation_permission.ts b/packages/datasheet/src/pc/components/automation/controller/use_automation_permission.ts index 45d40a1afc..31283fd974 100644 --- a/packages/datasheet/src/pc/components/automation/controller/use_automation_permission.ts +++ b/packages/datasheet/src/pc/components/automation/controller/use_automation_permission.ts @@ -10,7 +10,7 @@ export const useAutomationResourceNode = (): INodesMapItem=> { const stateValue = useAtomValue(automationStateAtom); return useAppSelector((state: IReduxState) => { - return state.catalogTree.treeNodesMap[stateValue?.resourceId!]; + return state.catalogTree.treeNodesMap[stateValue?.resourceId!] || state.catalogTree.privateTreeNodesMap[stateValue?.resourceId!]; }); }; @@ -20,7 +20,10 @@ export const useAutomationResourcePermission = (): INodePermissions => { const { screenIsAtMost } = useResponsive(); const isMobile = screenIsAtMost(ScreenSize.lg); const mirrorCreatable = useAppSelector((state: IReduxState) => { - const defaultValue= state.catalogTree.treeNodesMap[stateValue?.resourceId!]?.permissions || { + const resourceId = stateValue?.resourceId!; + const defaultValue= state.catalogTree.treeNodesMap[resourceId]?.permissions || + state.catalogTree.privateTreeNodesMap[resourceId]?.permissions || + state.datasheetMap[resourceId]?.datasheet?.permissions || { manageable: false, editable: false, readable: true, diff --git a/packages/datasheet/src/pc/components/automation/controller/use_robot_list.tsx b/packages/datasheet/src/pc/components/automation/controller/use_robot_list.tsx index 39fee4ff1a..6571a9527b 100644 --- a/packages/datasheet/src/pc/components/automation/controller/use_robot_list.tsx +++ b/packages/datasheet/src/pc/components/automation/controller/use_robot_list.tsx @@ -1,10 +1,9 @@ import { useMemo } from 'react'; import useSWR from 'swr'; import { Selectors } from '@apitable/core'; +import { useAppSelector } from 'pc/store/react-redux'; import { getResourceAutomations } from '../../robot/api'; -import {useAppSelector} from "pc/store/react-redux"; - export const useAutomationList = () => { const datasheetId = useAppSelector(Selectors.getActiveDatasheetId); const { data: automationList, error, mutate: mutateRefresh } diff --git a/packages/datasheet/src/pc/components/automation/panel/index.tsx b/packages/datasheet/src/pc/components/automation/panel/index.tsx index 2106898f01..d371328926 100644 --- a/packages/datasheet/src/pc/components/automation/panel/index.tsx +++ b/packages/datasheet/src/pc/components/automation/panel/index.tsx @@ -74,6 +74,7 @@ export const AutomationPanel: FC<{ onClose?: () => void; resourceId?: string, pa const { initialize } = useAutomationNavigateController(); const dispatch = useAppDispatch(); const { templateId } = useAppSelector((state: IReduxState) => state.pageParams); + const favoriteTreeNodeIds = useAppSelector((state: IReduxState) => state.catalogTree.favoriteTreeNodeIds); const { screenIsAtMost } = useResponsive(); const isLg = screenIsAtMost(ScreenSize.lg); @@ -282,7 +283,10 @@ export const AutomationPanel: FC<{ onClose?: () => void; resourceId?: string, pa { nodeItem && ( - + ) } diff --git a/packages/datasheet/src/pc/components/automation/run_history/modal/index.tsx b/packages/datasheet/src/pc/components/automation/run_history/modal/index.tsx index 761f18487f..0faa5d70e4 100644 --- a/packages/datasheet/src/pc/components/automation/run_history/modal/index.tsx +++ b/packages/datasheet/src/pc/components/automation/run_history/modal/index.tsx @@ -17,6 +17,7 @@ import { import { Strings, t, ThemeName } from '@apitable/core'; import { DownloadOutlined, LoadingOutlined, RefreshOutlined } from '@apitable/icons'; import { RobotRunHistoryItemDetail, useRunTaskDetail } from 'pc/components/robot/robot_detail/robot_run_history/robot_run_history_item_detail'; +import { useAppSelector } from 'pc/store/react-redux'; import EmptyStateDarkImg from 'static/icon/datasheet/empty_state_dark.png'; import EmptyStateLightImg from 'static/icon/datasheet/empty_state_light.png'; import { getAutomationRunHistoryDetail } from '../../../robot/api'; @@ -27,7 +28,6 @@ import { CONST_DATETIME_FORMAT } from '../list'; import { TaskList } from '../list/task'; import { handleDownload } from '../list/util'; -import {useAppSelector} from "pc/store/react-redux"; dayjs.extend(duration); const CONST_STATUS_SUCCESS = 1; @@ -50,6 +50,12 @@ export const RunHistoryDetail = () => { end: undefined, }; } + if (!nodes) { + return { + start: undefined, + end: undefined, + }; + } if (dataItem?.executedNodeIds?.length === 0) { return { start: undefined, diff --git a/packages/datasheet/src/pc/components/automation/select_dst/index.tsx b/packages/datasheet/src/pc/components/automation/select_dst/index.tsx index a9d0d68015..065036a8b0 100644 --- a/packages/datasheet/src/pc/components/automation/select_dst/index.tsx +++ b/packages/datasheet/src/pc/components/automation/select_dst/index.tsx @@ -8,12 +8,11 @@ import { DataSourceSelectorForNode } from 'pc/components/data_source_selector_enhanced/data_source_selector_for_node/data_source_selector_for_node'; import { SearchPanel } from 'pc/components/datasheet_search_panel'; +import { useAppSelector } from 'pc/store/react-redux'; import { RelatedResource } from '../../robot/robot_context'; import { automationStateAtom, loadableFormItemAtom } from '../controller'; import { SelectTrigger } from './select_trigger'; -import {useAppSelector} from "pc/store/react-redux"; - export const SelectDst: FC<{ value: string; onChange: (dstId: string | undefined) => void }> = memo(({ value, onChange diff --git a/packages/datasheet/src/pc/components/calendar_view/calendar_month_picker.tsx b/packages/datasheet/src/pc/components/calendar_view/calendar_month_picker.tsx index 40d7f377dc..c6262bd8fa 100644 --- a/packages/datasheet/src/pc/components/calendar_view/calendar_month_picker.tsx +++ b/packages/datasheet/src/pc/components/calendar_view/calendar_month_picker.tsx @@ -20,12 +20,12 @@ import { useClickAway } from 'ahooks'; import dayjs from 'dayjs'; import { get } from 'lodash'; import { useState } from 'react'; +import { formatDate } from '@apitable/components'; import { getLanguage } from '@apitable/core'; import { ComponentDisplay, ScreenSize } from '../common/component_display'; import MonthPicker from '../editors/date_time_editor/date_picker/month_picker'; import { PickerContent } from '../editors/date_time_editor/mobile/picker_content'; import { FORMAT_DATE } from './constants'; -import { formatString2Date } from './utils'; interface ICalendarMonthPicker { showValue: string; setDate: (date: dayjs.Dayjs | null) => void; @@ -50,6 +50,9 @@ export const CalendarMonthPicker = (props: ICalendarMonthPicker) => { () => document.querySelector('.cp-calendar'), ); + const showValueArray = showValue.split('-'); + const formatValue = formatDate(Number(showValueArray[0]), Number(showValueArray[1]), lang); + return ( <> @@ -60,14 +63,14 @@ export const CalendarMonthPicker = (props: ICalendarMonthPicker) => { align={{ offset: [-8, 31], }} - value={dayjs.tz(formatString2Date(showValue))} + value={dayjs.tz(showValue)} onChange={(val) => { setDate(val); setOpen(!open); }} open={open} readOnly - inputDateValue={showValue} + inputDateValue={formatValue} onOpenChange={() => { setOpen(!open); }} @@ -75,7 +78,7 @@ export const CalendarMonthPicker = (props: ICalendarMonthPicker) => { . */ +import { TriggerCommands } from 'modules/shared/apphook/trigger_commands'; import { FC, useContext, useMemo } from 'react'; import { shallowEqual, useDispatch } from 'react-redux'; import { batchActions } from 'redux-batched-actions'; @@ -43,7 +44,6 @@ import { t, } from '@apitable/core'; import { AddOutlined, ChevronRightOutlined, ClassOutlined, CloseOutlined, QuestionCircleOutlined, WarnCircleOutlined } from '@apitable/icons'; -import { TriggerCommands } from 'modules/shared/apphook/trigger_commands'; import { ColorPicker, OptionSetting } from 'pc/components/common/color_picker'; import { notify } from 'pc/components/common/notify'; import { NotifyKey } from 'pc/components/common/notify/notify.interface'; @@ -52,14 +52,13 @@ import { getFieldTypeIcon } from 'pc/components/multi_grid/field_setting'; import { setColor } from 'pc/components/multi_grid/format'; import { useShowViewLockModal } from 'pc/components/view_lock/use_show_view_lock_modal'; import { resourceService } from 'pc/resource_service'; +import { useAppSelector } from 'pc/store/react-redux'; import { getEnvVariables } from 'pc/utils/env'; import { executeCommandWithMirror } from 'pc/utils/execute_command_with_mirror'; import { setStorage, StorageName } from 'pc/utils/storage'; import { CalendarContext } from '../calendar_context'; import styles from './styles.module.less'; -import {useAppSelector} from "pc/store/react-redux"; - const UNUSED_END_DATE = 'unusedEndDate'; interface ICalendarSettingPanel { @@ -77,13 +76,14 @@ export const CalendarSettingPanel: FC { - const { datasheetId: dstId, viewId: vId } = state.pageParams; + const { spaceId, viewId, datasheetId, cacheTheme, embedId } = useAppSelector((state) => { + const { datasheetId: dstId, viewId: vId, embedId } = state.pageParams; return { datasheetId: dstId, viewId: vId, spaceId: state.space.activeId!, cacheTheme: state.theme, + embedId }; }, shallowEqual); const { CALENDAR_SETTING_HELP_URL } = getEnvVariables(); @@ -231,7 +231,7 @@ export const CalendarSettingPanel: FC - {getEnvVariables().CALENDAR_SETTING_GUIDE_VIDEO_VISIBLE && ( + {getEnvVariables().CALENDAR_SETTING_GUIDE_VIDEO_VISIBLE && !Boolean(embedId) && (
diff --git a/packages/datasheet/src/pc/components/calendar_view/calendar_view.tsx b/packages/datasheet/src/pc/components/calendar_view/calendar_view.tsx index 12f8ca0500..909d13a46f 100644 --- a/packages/datasheet/src/pc/components/calendar_view/calendar_view.tsx +++ b/packages/datasheet/src/pc/components/calendar_view/calendar_view.tsx @@ -46,6 +46,7 @@ import { RecordMenu } from 'pc/components/multi_grid/context_menu/record_menu'; import { setColor } from 'pc/components/multi_grid/format'; import { useResponsive } from 'pc/hooks'; import { resourceService } from 'pc/resource_service'; +import { useAppSelector } from 'pc/store/react-redux'; import { getStorage, setStorage, StorageName } from 'pc/utils/storage'; import { VikaSplitPanel } from '../common'; import { ScreenSize } from '../common/component_display/enum'; @@ -60,8 +61,6 @@ import { Drop } from './drop'; import { RecordList } from './record_list'; import styles from './styles.module.less'; -import {useAppSelector} from "pc/store/react-redux"; - interface ICalendarViewProps { height: number; width: number; diff --git a/packages/datasheet/src/pc/components/catalog/catalog.tsx b/packages/datasheet/src/pc/components/catalog/catalog.tsx index 9e3de345fd..d58ea6b2cc 100644 --- a/packages/datasheet/src/pc/components/catalog/catalog.tsx +++ b/packages/datasheet/src/pc/components/catalog/catalog.tsx @@ -26,13 +26,12 @@ import { ShortcutActionManager, ShortcutActionName } from 'modules/shared/shortc import { useRootManageable } from 'pc/hooks'; import { useCatalog } from 'pc/hooks/use_catalog'; import { store } from 'pc/store'; +import { useAppSelector } from 'pc/store/react-redux'; import { getContextTypeByNodeType } from 'pc/utils'; import { dndH5Manager } from 'pc/utils/dnd_manager'; import { WorkbenchSideContext } from '../common_side/workbench_side/workbench_side_context'; -import styles from './style.module.less'; import { Tree } from './tree'; - -import {useAppSelector} from "pc/store/react-redux"; +import styles from './style.module.less'; export const CatalogBase: React.FC> = () => { // Whether the node is loaded or not (expand the node) diff --git a/packages/datasheet/src/pc/components/catalog/generate_template/generate_template.tsx b/packages/datasheet/src/pc/components/catalog/generate_template/generate_template.tsx index 4042ca25bd..812e7b3581 100644 --- a/packages/datasheet/src/pc/components/catalog/generate_template/generate_template.tsx +++ b/packages/datasheet/src/pc/components/catalog/generate_template/generate_template.tsx @@ -24,20 +24,21 @@ import { ConfigConstant, IReduxState, Navigation, Selectors, Strings, t } from ' import { BaseModal, Message, Modal } from 'pc/components/common'; import { Router } from 'pc/components/route_manager/router'; import { useRequest, useTemplateRequest } from 'pc/hooks'; +import { useAppSelector } from 'pc/store/react-redux'; import styles from './style.module.less'; -import {useAppSelector} from "pc/store/react-redux"; - export interface IGenerateTemplateProps { nodeId?: string; onCancel: () => void; } export const GenerateTemplate: FC> = ({ nodeId, onCancel }) => { - const treeNodesMap = useAppSelector((state: IReduxState) => state.catalogTree.treeNodesMap); + const catalogTreeActiveType = useAppSelector((state) => state.catalogTree.activeType); + const nodeKey = catalogTreeActiveType === ConfigConstant.Modules.PRIVATE ? 'privateTreeNodesMap' : 'treeNodesMap'; + const nodesMap = useAppSelector((state: IReduxState) => state.catalogTree[nodeKey]); const activeNodeId = useAppSelector((state: IReduxState) => Selectors.getNodeId(state)); nodeId = nodeId || activeNodeId; - const [name, setName] = useState(treeNodesMap[nodeId!].nodeName); + const [name, setName] = useState(nodesMap[nodeId!].nodeName); const [errorMsg, setErrorMsg] = useState(''); const spaceId = useAppSelector((state) => state.space.activeId); const { createTemplateReq, templateNameValidateReq } = useTemplateRequest(); diff --git a/packages/datasheet/src/pc/components/catalog/import_file/import_file.tsx b/packages/datasheet/src/pc/components/catalog/import_file/import_file.tsx index aca811d1ed..ae8908a4d7 100644 --- a/packages/datasheet/src/pc/components/catalog/import_file/import_file.tsx +++ b/packages/datasheet/src/pc/components/catalog/import_file/import_file.tsx @@ -25,25 +25,26 @@ import { Message, Modal } from 'pc/components/common'; import { Router } from 'pc/components/route_manager/router'; import { useAppDispatch } from 'pc/hooks/use_app_dispatch'; import { usePercent } from 'pc/hooks/use_percent'; +import { useAppSelector } from 'pc/store/react-redux'; import { byte2Mb } from 'pc/utils'; import styles from './style.module.less'; -import {useAppSelector} from "pc/store/react-redux"; - const { Dragger } = Upload; export interface IImportFileProps { parentId: string; onCancel: () => void; + isPrivate?: boolean; } let reqToken: () => void; type ProgressType = 'normal' | 'active' | 'success' | 'exception' | undefined; -export const ImportFile: FC> = ({ parentId, onCancel }) => { +export const ImportFile: FC> = ({ parentId, onCancel, isPrivate }) => { const colors = useThemeColors(); const spaceId = useAppSelector((state) => state.space.activeId); + const userUnitId = useAppSelector((state) => state.user.info?.unitId); const expandedKeys = useAppSelector((state: IReduxState) => state.catalogTree.expandedKeys); const [uploadPercent, setUploadPercent] = useState(0); const [file, setFile] = useState(); @@ -86,6 +87,9 @@ export const ImportFile: FC> = ({ pare formData.append('file', curFile); formData.append('parentId', parentId); formData.append('spaceId', spaceId); + if (isPrivate && userUnitId) { + formData.append('unitId', userUnitId); + } setProcessing(true); Api.importFile(formData, onUploadProgress, (c: () => void) => { reqToken = c; @@ -95,8 +99,8 @@ export const ImportFile: FC> = ({ pare setProcessing(false); const { success, data, message } = res.data; if (success) { - dispatch(StoreActions.setExpandedKeys([...expandedKeys, parentId])); - dispatch(StoreActions.addNode(data)); + dispatch(StoreActions.setExpandedKeys([...expandedKeys, parentId], isPrivate ? ConfigConstant.Modules.PRIVATE : undefined)); + dispatch(StoreActions.addNode(data, isPrivate ? ConfigConstant.Modules.PRIVATE : undefined)); dispatch(StoreActions.getSpaceInfo(spaceId)); Router.push(Navigation.WORKBENCH, { params: { @@ -192,7 +196,7 @@ export const ImportFile: FC> = ({ pare void; + onClick: (_folderId: string, _nodePrivate?: boolean) => void; level?: string; + nodePrivate?: boolean; }> > = (props) => { - const { folderId, folderName, icon, onClick, level } = props; + const { folderId, folderName, icon, onClick, level, nodePrivate } = props; const colors = useThemeColors(); const { screenIsAtMost } = useResponsive(); const isMobile = screenIsAtMost(ScreenSize.md); @@ -40,12 +42,14 @@ export const FolderItem: React.FC< const fontVariant = isMobile ? 'body1' : 'body3'; const levelVariant = isMobile ? 'body3' : 'body4'; const Icon = icon ? ( - + + {getNodeIcon(icon, ConfigConstant.NodeType.DATASHEET, { size: iconSize })} + ) : ( ); return ( -
onClick(folderId)}> +
onClick(folderId, nodePrivate)}>
{Icon} diff --git a/packages/datasheet/src/pc/components/catalog/move_to/move_to.tsx b/packages/datasheet/src/pc/components/catalog/move_to/move_to.tsx index 182eaa1a80..eb6233851f 100644 --- a/packages/datasheet/src/pc/components/catalog/move_to/move_to.tsx +++ b/packages/datasheet/src/pc/components/catalog/move_to/move_to.tsx @@ -19,33 +19,38 @@ import classNames from 'classnames'; import { useEffect, useState } from 'react'; import { useDispatch } from 'react-redux'; -import { Api, IParent, Navigation, StoreActions, Strings, t } from '@apitable/core'; +import { Api, ConfigConstant, IParent, Navigation, StoreActions, Strings, t, StatusCode } from '@apitable/core'; import { ComponentDisplay, ScreenSize } from 'pc/components/common/component_display'; import { Message } from 'pc/components/common/message/message'; import { Popup } from 'pc/components/common/mobile/popup'; import { Modal } from 'pc/components/common/modal/modal/modal'; import { TComponent } from 'pc/components/common/t_component'; import { Router } from 'pc/components/route_manager/router'; +import { useAppSelector } from 'pc/store/react-redux'; import { SelectFolder } from './select_folder'; -import styles from './style.module.less'; import { MobileFooter, MobileTitle, Title } from './title'; - -import {useAppSelector} from "pc/store/react-redux"; +import styles from './style.module.less'; export const MoveTo: React.FC< React.PropsWithChildren<{ nodeIds: string[]; onClose?: () => void; + isPrivate?: boolean; }> > = (props) => { - const { nodeIds, onClose } = props; + const { nodeIds, onClose, isPrivate } = props; const [selectedNodeId, setSelectedNodeId] = useState(); + const [catalog, setCatalog] = useState(); const [parentList, setParentList] = useState([]); const [confirmLoading, setConfirmLoading] = useState(false); - const { nodeName, parentId, nodePermitSet } = useAppSelector((state) => { - const { nodeName, parentId, nodePermitSet } = state.catalogTree.treeNodesMap[nodeIds[0]]; - return { nodeName, parentId, nodePermitSet }; + const { nodeName, nodePermitSet } = useAppSelector((state) => { + const nodeMapKey = isPrivate ? 'privateTreeNodesMap' : 'treeNodesMap'; + const { nodeName, nodePermitSet } = state.catalogTree[nodeMapKey][nodeIds[0]]; + return { nodeName, nodePermitSet }; }); + const userUnitId = useAppSelector((state) => state.user.info?.unitId); + const rootId = useAppSelector((state) => state.catalogTree.rootId); + const rootName = useAppSelector((state) => state.catalogTree.treeNodesMap[rootId]?.nodeName); const currentNodeId = useAppSelector((state) => state.pageParams.nodeId); const dispatch = useDispatch(); @@ -61,7 +66,8 @@ export const MoveTo: React.FC< Message.error({ content: message }); return; } - setParentList(data); + const _data = data.some((v) => v.nodeId === rootId) ? data : [{ nodeId: rootId, nodeName: rootName }, ...data]; + setParentList(_data); }); }; @@ -70,9 +76,19 @@ export const MoveTo: React.FC< return; } getParentList(selectedNodeId); + // eslint-disable-next-line react-hooks/exhaustive-deps }, [selectedNodeId]); - const main = ; + const main = ( + + ); const selectedNodeName = parentList.find((v) => v.nodeId === selectedNodeId)?.nodeName; @@ -82,25 +98,51 @@ export const MoveTo: React.FC< return; } // selected nodeId is equal nodeId current parentId - if (selectedNodeId === parentId) { - Message.error({ content: t(Strings.move_to_error_equal_parent) }); - return; - } + // if (selectedNodeId === parentId) { + // Message.error({ content: t(Strings.move_to_error_equal_parent) }); + // return; + // } const move = () => { setConfirmLoading(true); - Api.nodeMove(nodeId, selectedNodeId).then((res) => { + const unitId = catalog === ConfigConstant.Modules.PRIVATE ? userUnitId : undefined; + Api.nodeMove(nodeId, selectedNodeId, undefined, unitId).then((res) => { setConfirmLoading(false); - const { data, success, message } = res.data; + const { data, success, code } = res.data; if (!success) { - Message.error({ content: message }); - dispatch(StoreActions.setErr(message)); + console.log('code', code, typeof code); + let content: string | React.ReactNode = ''; + if (code === StatusCode.NOT_PERMISSION) { + content = t(Strings.move_other_link_no_permission); + } else if (nodeId.startsWith(ConfigConstant.NodeTypeReg.DATASHEET)) { + content = t(Strings.move_datasheet_link_warn); + } else if (nodeId.startsWith(ConfigConstant.NodeTypeReg.FOLDER)) { + content = t(Strings.move_folder_link_warn); + } else { + const nodeType = ConfigConstant.nodePrefixNameMap.get(nodeId.slice(0, 3) as ConfigConstant.NodeTypeReg); + content = ; + } + Modal.warning({ + title: t(Strings.please_note), + content, + }); return; } - dispatch(StoreActions.moveTo(nodeId, selectedNodeId, 0)); - dispatch(StoreActions.addNodeToMap(data)); - onClose && onClose(); - moveSuccess(nodeId); + // private => team should reload + if (isPrivate && catalog === ConfigConstant.Modules.CATALOG) { + moveSuccess(nodeId); + setTimeout(() => { + window.location.reload(); + }, 2000); + } else { + dispatch(StoreActions.moveTo(nodeId, selectedNodeId, 0, catalog)); + dispatch(StoreActions.addNodeToMap(data, true, catalog)); + onClose && onClose(); + moveSuccess(nodeId); + } }); }; if (!nodePermitSet) { @@ -164,7 +206,7 @@ export const MoveTo: React.FC< } - visible + open centered onCancel={onClose} okText={t(Strings.move)} diff --git a/packages/datasheet/src/pc/components/catalog/move_to/select_folder.tsx b/packages/datasheet/src/pc/components/catalog/move_to/select_folder.tsx index b76ac2c79f..0a224e6424 100644 --- a/packages/datasheet/src/pc/components/catalog/move_to/select_folder.tsx +++ b/packages/datasheet/src/pc/components/catalog/move_to/select_folder.tsx @@ -18,31 +18,36 @@ import { useMount } from 'ahooks'; import classNames from 'classnames'; +import { compact } from 'lodash'; import throttle from 'lodash/throttle'; -import { useEffect, useState, useMemo, useRef } from 'react'; +import React, { useEffect, useState, useMemo, useRef, useCallback } from 'react'; import { Box, LinkButton, Loading, Message, TextInput, useThemeColors } from '@apitable/components'; import { Api, ApiInterface, ConfigConstant, INode, INodesMapItem, IParent, Strings, t } from '@apitable/core'; import { ChevronRightOutlined, SearchOutlined } from '@apitable/icons'; import { ScreenSize } from 'pc/components/common/component_display'; import { useResponsive } from 'pc/hooks'; +import { useAppSelector } from 'pc/store/react-redux'; import { FolderItem } from './folder_item'; import { SelectFolderTips } from './select_folder_tips'; - import styles from './style.module.less'; -import {useAppSelector} from "pc/store/react-redux"; - export const SelectFolder: React.FC< React.PropsWithChildren<{ selectedFolderId?: string; selectedFolderParentList: IParent[]; - onChange: (folderId: string) => void; + onChange: (_folderId: string) => void; + catalog?: ConfigConstant.Modules; + setCatalog: (_catalog?: ConfigConstant.Modules) => void; + isPrivate?: boolean; }> > = (props) => { - const { selectedFolderId, selectedFolderParentList, onChange } = props; + const { selectedFolderId, selectedFolderParentList, onChange, catalog, setCatalog } = props; + const [firstParentList, ...restParentList] = selectedFolderParentList; const rootId = useAppSelector((state) => state.catalogTree.rootId); const spaceName = useAppSelector((state) => state.user.info?.spaceName); const spaceId = useAppSelector((state) => state.space.activeId); + const catalogTreeActiveType = useAppSelector((state) => state.catalogTree.activeType); + const isPrivate = catalogTreeActiveType === ConfigConstant.Modules.PRIVATE; const currentFolderId = selectedFolderId || rootId; const isWhole = Boolean(selectedFolderId); @@ -75,15 +80,9 @@ export const SelectFolder: React.FC< } }); - useEffect(() => { - if (!isWhole || !currentFolderId) { - return; - } - getWholeList(currentFolderId); - }, [currentFolderId, isWhole]); - - const getWholeList = (folderId: string) => { - Api.getChildNodeList(folderId, ConfigConstant.NodeType.FOLDER).then((res) => { + const getWholeList = useCallback((folderId: string) => { + const unitType = catalog === ConfigConstant.Modules.PRIVATE ? 3 : undefined; + Api.getChildNodeList(folderId, ConfigConstant.NodeType.FOLDER, unitType).then((res) => { const { data, success, message } = res.data; if (!success) { Message.error({ content: message }); @@ -91,11 +90,18 @@ export const SelectFolder: React.FC< } setWholeList(data); }); - }; + }, [catalog]); + + useEffect(() => { + if (!isWhole || !currentFolderId || (isPrivate && !catalog)) { + return; + } + getWholeList(currentFolderId); + }, [currentFolderId, isWhole, catalog, getWholeList, isPrivate]); const getSearchList = useMemo(() => { return throttle((spaceId: string, keyword: string) => { - Api.searchNode(spaceId, keyword).then((res) => { + Api.searchNode(spaceId, keyword, isPrivate ? undefined : 1).then((res) => { const { data, success, message } = res.data; if (!success) { Message.error({ content: message }); @@ -105,7 +111,7 @@ export const SelectFolder: React.FC< setSearchList(folders); }); }, 500); - }, []); + }, [isPrivate]); useEffect(() => { if (!keyword || !spaceId) { @@ -114,9 +120,19 @@ export const SelectFolder: React.FC< getSearchList(spaceId, keyword); }, [spaceId, keyword, getSearchList]); - const onClickItem = (folderId: string) => { + const onClickItem = (folderIdOrCatalogType: string, nodePrivate?: boolean) => { setKeyword(''); - onChange(folderId); + if (folderIdOrCatalogType === ConfigConstant.Modules.CATALOG || folderIdOrCatalogType === ConfigConstant.Modules.PRIVATE) { + setCatalog(folderIdOrCatalogType); + firstParentList?.nodeId && onChange(firstParentList?.nodeId); + return; + } + if (firstParentList?.nodeId === folderIdOrCatalogType) { + setCatalog(undefined); + setWholeList([]); + } + nodePrivate !== undefined && setCatalog(nodePrivate ? ConfigConstant.Modules.PRIVATE : ConfigConstant.Modules.CATALOG); + onChange(folderIdOrCatalogType); }; const enterWhole = () => { @@ -148,6 +164,23 @@ export const SelectFolder: React.FC< const showLevel = !isWhole || keyword; const isShowWholeButton = isMobile && !isWhole; const list = keyword ? searchList : isWhole ? wholeList : recentlyBrowsedList; + const catalogList = isPrivate ? [ + { + nodeId: ConfigConstant.Modules.CATALOG, + nodeName: t(Strings.catalog_team), + }, + { + nodeId: ConfigConstant.Modules.PRIVATE, + nodeName: t(Strings.catalog_private), + }, + ] : []; + + const folderCatalogTips = catalogList.length > 0 ? catalogList.filter(l => l.nodeId === catalog) : [ + { + nodeId: ConfigConstant.Modules.CATALOG, + nodeName: t(Strings.catalog_team), + } + ]; return (
@@ -164,26 +197,58 @@ export const SelectFolder: React.FC< onChange={(e) => setKeyword(e.target.value)} /> )} - {isShowTips && } + {isShowTips && ( + + )}
{firstLoading ? ( ) : ( - list.map((item) => { - const { nodeId, nodeName, icon } = item; - return ( - - ); - }) + <> + {list.map((item) => { + const { nodeId, nodeName, icon, nodePrivate } = item; + return ( + + ); + })} + {!catalog && selectedFolderId === rootId && catalogList.map((item) => { + const { nodeId, nodeName } = item; + return ( +
{ + setCatalog(nodeId); + }} + > + {nodeName} +
+ ); + })} + )}
diff --git a/packages/datasheet/src/pc/components/catalog/move_to/select_folder_tips.tsx b/packages/datasheet/src/pc/components/catalog/move_to/select_folder_tips.tsx index 29b36a0e26..8f2cb4652d 100644 --- a/packages/datasheet/src/pc/components/catalog/move_to/select_folder_tips.tsx +++ b/packages/datasheet/src/pc/components/catalog/move_to/select_folder_tips.tsx @@ -21,7 +21,6 @@ import { LinkButton, Typography, useThemeColors } from '@apitable/components'; import { IParent, Strings, t } from '@apitable/core'; import { ChevronRightOutlined } from '@apitable/icons'; import { HorizontalScroll } from 'pc/components/common/horizontal_scroll'; - import styles from './style.module.less'; export const SelectFolderTips: React.FC< diff --git a/packages/datasheet/src/pc/components/catalog/move_to/style.module.less b/packages/datasheet/src/pc/components/catalog/move_to/style.module.less index 6f90b9315b..0015e9cd34 100644 --- a/packages/datasheet/src/pc/components/catalog/move_to/style.module.less +++ b/packages/datasheet/src/pc/components/catalog/move_to/style.module.less @@ -75,6 +75,19 @@ } } } + .catalogItem { + padding: 8px 16px; + display: flex; + align-items: center; + cursor: pointer; + &:hover { + background: var(--bgBglessHover); + } + &:active { + background: var(--bgBglessActive); + } + + } .folderList { flex: 1; overflow-y: auto; diff --git a/packages/datasheet/src/pc/components/catalog/node_context_menu/context_menu_data.tsx b/packages/datasheet/src/pc/components/catalog/node_context_menu/context_menu_data.tsx index e4be315a0f..195dd91c85 100644 --- a/packages/datasheet/src/pc/components/catalog/node_context_menu/context_menu_data.tsx +++ b/packages/datasheet/src/pc/components/catalog/node_context_menu/context_menu_data.tsx @@ -16,11 +16,11 @@ * along with this program. If not, see . */ +import { ShortcutActionName } from 'modules/shared/shortcut_key'; +import { getShortcutKeyString } from 'modules/shared/shortcut_key/keybinding_config'; import { isMobile } from 'react-device-detect'; import { black, colorVars } from '@apitable/components'; import { ConfigConstant, Strings, t, WORKBENCH_SIDE_ID } from '@apitable/core'; -import { ShortcutActionName } from 'modules/shared/shortcut_key'; -import { getShortcutKeyString } from 'modules/shared/shortcut_key/keybinding_config'; import { getEnvVariables } from 'pc/utils/env'; import { makeNodeIconComponent, NodeIcon } from './node_icons'; import styles from './style.module.less'; @@ -45,6 +45,7 @@ export enum ContextItemKey { addAi, CreateBackup, AddAutomation, + AddEmbed, } const getCopyUrlText = (nodeType: ConfigConstant.NodeType) => { @@ -229,6 +230,16 @@ export const contextItemMap = new Map([ id: WORKBENCH_SIDE_ID.NEW_DATASHEET, }), ], + [ + ContextItemKey.AddEmbed, + (onClick: () => void, hidden: boolean) => ({ + icon: makeNodeIconComponent(NodeIcon.AddEmbed), + text: t(Strings.new_custom_page), + onClick, + hidden, + id: WORKBENCH_SIDE_ID.NEW_EMBED, + }), + ], [ ContextItemKey.AddForm, (onClick: () => void, hidden: boolean) => ({ diff --git a/packages/datasheet/src/pc/components/catalog/node_context_menu/node_context_menu.tsx b/packages/datasheet/src/pc/components/catalog/node_context_menu/node_context_menu.tsx index 66d1216cc9..cf852b28bf 100644 --- a/packages/datasheet/src/pc/components/catalog/node_context_menu/node_context_menu.tsx +++ b/packages/datasheet/src/pc/components/catalog/node_context_menu/node_context_menu.tsx @@ -15,6 +15,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ +import { compact } from 'lodash'; import { FC, memo, useContext, useMemo } from 'react'; import { useDispatch } from 'react-redux'; import { ContextMenu, IContextMenuClickState } from '@apitable/components'; @@ -52,24 +53,35 @@ export const NodeContextMenu: FC> const dispatch = useDispatch(); const { rightClickInfo } = useContext(WorkbenchSideContext); const { setNewTdbId } = useContext(SideBarContext); - const treeNodesMap = useAppSelector((state: IReduxState) => state.catalogTree.treeNodesMap); - const rootId = useAppSelector((state: IReduxState) => state.catalogTree.rootId); const spaceId = useAppSelector((state) => state.space.activeId); + const favoriteTreeNodeIds = useAppSelector((state: IReduxState) => state.catalogTree.favoriteTreeNodeIds); + const catalogTreeActiveType = useAppSelector((state) => state.catalogTree.activeType); + const clickNodeId = rightClickInfo?.id; + const activeNodePrivate = useAppSelector((state) => { + if (!clickNodeId) { + return false; + } + return state.catalogTree.treeNodesMap[clickNodeId]?.nodePrivate || state.catalogTree.privateTreeNodesMap[clickNodeId]?.nodePrivate; + }); + const nodesMap = useAppSelector((state: IReduxState) => + activeNodePrivate ? state.catalogTree.privateTreeNodesMap : state.catalogTree.treeNodesMap + ); + const rootId = useAppSelector((state: IReduxState) => activeNodePrivate ? state.catalogTree.privateRootId : state.catalogTree.rootId); const spaceInfo = useAppSelector((state) => state.space.curSpaceInfo); const { updateNodeFavoriteStatusReq, copyNodeReq } = useCatalogTreeRequest(); const { run: updateNodeFavoriteStatus } = useRequest(updateNodeFavoriteStatusReq, { manual: true }); - const { run: copyNode } = useRequest(copyNodeReq, { manual: true }); + const { run: copyNode } = useRequest((nodeId: string) => copyNodeReq(nodeId, true, catalogTreeActiveType), { manual: true }); const { setSideBarVisible } = useSideBarVisible(); const { screenIsAtMost } = useResponsive(); const isMobile = screenIsAtMost(ScreenSize.md); const rename = (nodeId: string, level: string, module: ConfigConstant.Modules) => { - const editNodeId = module === ConfigConstant.Modules.CATALOG ? nodeId : `${level},${nodeId}`; + const editNodeId = module !== ConfigConstant.Modules.FAVORITE ? nodeId : `${level},${nodeId}`; dispatch(StoreActions.setEditNodeId(editNodeId, module)); }; const deleteNode = (nodeId: string, level: string, module: ConfigConstant.Modules) => { - const delNodeId = module === ConfigConstant.Modules.CATALOG ? nodeId : `${level},${nodeId}`; + const delNodeId = module !== ConfigConstant.Modules.FAVORITE ? nodeId : `${level},${nodeId}`; dispatch(StoreActions.setDelNodeId(delNodeId, module)); }; @@ -146,17 +158,18 @@ export const NodeContextMenu: FC> return []; } const { contextMenuType, module, id, level } = rightClickInfo; - const { nodeId, permissions, nodeFavorite, parentId, type } = treeNodesMap[id]; + const { nodeId, permissions, parentId, type, nodePrivate } = nodesMap[id]; + const nodeFavorite = nodesMap[id].nodeFavorite || favoriteTreeNodeIds.includes(id); const targetId = nodeId || rootId; const targetManageable = rootManageable || !isRootNodeId(targetId); const { exportable, nodeAssignable, templateCreatable, sharable, editable } = permissions; const renamable = permissions.renamable && targetManageable; const removable = permissions.removable && targetManageable; const movable = permissions.movable && targetManageable; - const parentPermissions = treeNodesMap[parentId]?.permissions; + const parentPermissions = nodesMap[parentId]?.permissions; const backupcreatAble = permissions.manageable && Boolean(createBackupSnapshot); const copyable = - parentPermissions && parentPermissions.manageable && permissions.manageable && module === ConfigConstant.Modules.CATALOG && targetManageable; + parentPermissions && parentPermissions.manageable && permissions.manageable && module !== ConfigConstant.Modules.FAVORITE && targetManageable; const nodeUrl = `${window.location.protocol}//${window.location.host}/workbench/${nodeId}`; let data: any = []; switch (contextMenuType) { @@ -165,18 +178,18 @@ export const NodeContextMenu: FC> [ contextItemMap.get(ContextItemKey.Rename)(() => rename(nodeId, level, module), !renamable), contextItemMap.get(ContextItemKey.Favorite)(() => { - updateNodeFavoriteStatus(nodeId); + updateNodeFavoriteStatus(nodeId, nodePrivate); }, nodeFavorite), - contextItemMap.get(ContextItemKey.Copy)(() => copyNode(nodeId), !copyable), + contextItemMap.get(ContextItemKey.Copy)(() => copyNode(nodeId), !copyable, module), contextItemMap.get(ContextItemKey.CopyUrl)(() => copyUrl(nodeUrl), type), ], - [ - contextItemMap.get(ContextItemKey.Permission)(() => openPermissionSetting(nodeId), nodeAssignable), + compact([ + !activeNodePrivate && contextItemMap.get(ContextItemKey.Permission)(() => openPermissionSetting(nodeId), nodeAssignable), contextItemMap.get(ContextItemKey.Share)(() => openShareModal(nodeId), !sharable), contextItemMap.get(ContextItemKey.NodeInfo)(() => openNodeInfo(nodeId)), contextItemMap.get(ContextItemKey.MoveTo)(() => openMoveTo(nodeId), !movable), contextItemMap.get(ContextItemKey.SaveAsTemplate)(() => openSaveAsTemplateModal(nodeId), !templateCreatable), - ], + ]), [contextItemMap.get(ContextItemKey.Delete)(() => deleteNode(nodeId, level, module), !removable)], ]; Player.applyFilters(Events.get_context_menu_file_more, data); @@ -187,7 +200,7 @@ export const NodeContextMenu: FC> [ contextItemMap.get(ContextItemKey.Rename)(() => rename(nodeId, level, module), !renamable), contextItemMap.get(ContextItemKey.Favorite)(() => { - updateNodeFavoriteStatus(nodeId); + updateNodeFavoriteStatus(nodeId, nodePrivate); }, nodeFavorite), contextItemMap.get(ContextItemKey.Copy)(() => copyNode(nodeId), !copyable), contextItemMap.get(ContextItemKey.CopyUrl)(() => copyUrl(nodeUrl), type), @@ -199,14 +212,14 @@ export const NodeContextMenu: FC> !exportable || isMobileApp(), ), ], - [ - contextItemMap.get(ContextItemKey.Permission)(() => openPermissionSetting(nodeId), nodeAssignable), - contextItemMap.get(ContextItemKey.CreateBackup)(() => _createBackupSnapshot(nodeId), !backupcreatAble), + compact([ + !activeNodePrivate && contextItemMap.get(ContextItemKey.Permission)(() => openPermissionSetting(nodeId), nodeAssignable), + !activeNodePrivate && contextItemMap.get(ContextItemKey.CreateBackup)(() => _createBackupSnapshot(nodeId), !backupcreatAble), contextItemMap.get(ContextItemKey.Share)(() => openShareModal(nodeId), !sharable), contextItemMap.get(ContextItemKey.NodeInfo)(() => openNodeInfo(nodeId)), contextItemMap.get(ContextItemKey.MoveTo)(() => openMoveTo(nodeId), !movable), contextItemMap.get(ContextItemKey.SaveAsTemplate)(() => openSaveAsTemplateModal(nodeId), !templateCreatable), - ], + ]), [contextItemMap.get(ContextItemKey.Delete)(() => deleteNode(nodeId, level, module), !removable)], ]; Player.applyFilters(Events.get_context_menu_file_more, data); @@ -215,15 +228,15 @@ export const NodeContextMenu: FC> case ConfigConstant.ContextMenuType.FOLDER: { data = [ [contextItemMap.get(ContextItemKey.Rename)(() => rename(nodeId, level, module), !renamable)], - [ - contextItemMap.get(ContextItemKey.Favorite)(() => updateNodeFavoriteStatus(nodeId), nodeFavorite), + compact([ + contextItemMap.get(ContextItemKey.Favorite)(() => updateNodeFavoriteStatus(nodeId, nodePrivate), nodeFavorite), contextItemMap.get(ContextItemKey.CopyUrl)(() => copyUrl(nodeUrl), type), - contextItemMap.get(ContextItemKey.Permission)(() => openPermissionSetting(nodeId), nodeAssignable), + !activeNodePrivate && contextItemMap.get(ContextItemKey.Permission)(() => openPermissionSetting(nodeId), nodeAssignable), contextItemMap.get(ContextItemKey.Share)(() => openShareModal(nodeId), !sharable), contextItemMap.get(ContextItemKey.NodeInfo)(() => openNodeInfo(nodeId)), contextItemMap.get(ContextItemKey.MoveTo)(() => openMoveTo(nodeId), !movable), contextItemMap.get(ContextItemKey.SaveAsTemplate)(() => openSaveAsTemplateModal(nodeId), !templateCreatable), - ], + ]), [contextItemMap.get(ContextItemKey.Delete)(() => deleteNode(nodeId, level, module), !removable)], ]; Player.applyFilters(Events.get_context_menu_folder_more, data); @@ -233,16 +246,16 @@ export const NodeContextMenu: FC> data = [ [ contextItemMap.get(ContextItemKey.Rename)(() => rename(nodeId, level, module), !renamable), - contextItemMap.get(ContextItemKey.Favorite)(() => updateNodeFavoriteStatus(nodeId), nodeFavorite), + contextItemMap.get(ContextItemKey.Favorite)(() => updateNodeFavoriteStatus(nodeId, nodePrivate), nodeFavorite), contextItemMap.get(ContextItemKey.Copy)(() => copyNode(nodeId), !copyable), contextItemMap.get(ContextItemKey.CopyUrl)(() => copyUrl(nodeUrl), type), ], - [ - contextItemMap.get(ContextItemKey.Permission)(() => openPermissionSetting(nodeId), nodeAssignable), + compact([ + !activeNodePrivate && contextItemMap.get(ContextItemKey.Permission)(() => openPermissionSetting(nodeId), nodeAssignable), contextItemMap.get(ContextItemKey.Share)(() => openShareModal(nodeId), !sharable), contextItemMap.get(ContextItemKey.NodeInfo)(() => openNodeInfo(nodeId)), contextItemMap.get(ContextItemKey.MoveTo)(() => openMoveTo(nodeId), !movable), - ], + ]), [contextItemMap.get(ContextItemKey.Delete)(() => deleteNode(nodeId, level, module), !removable)], ]; Player.applyFilters(Events.get_context_menu_file_more, data); @@ -252,15 +265,34 @@ export const NodeContextMenu: FC> data = [ [ contextItemMap.get(ContextItemKey.Rename)(() => rename(nodeId, level, module), !renamable), - contextItemMap.get(ContextItemKey.Favorite)(() => updateNodeFavoriteStatus(nodeId), nodeFavorite), + contextItemMap.get(ContextItemKey.Favorite)(() => updateNodeFavoriteStatus(nodeId, nodePrivate), nodePrivate), contextItemMap.get(ContextItemKey.Copy)(() => copyNode(nodeId), !copyable), contextItemMap.get(ContextItemKey.CopyUrl)(() => copyUrl(nodeUrl), type), ], - [ - contextItemMap.get(ContextItemKey.Permission)(() => openPermissionSetting(nodeId), nodeAssignable), + compact([ + !activeNodePrivate && contextItemMap.get(ContextItemKey.Permission)(() => openPermissionSetting(nodeId), nodeAssignable), contextItemMap.get(ContextItemKey.NodeInfo)(() => openNodeInfo(nodeId)), contextItemMap.get(ContextItemKey.MoveTo)(() => openMoveTo(nodeId), !movable), + ]), + [contextItemMap.get(ContextItemKey.Delete)(() => deleteNode(nodeId, level, module), !removable)], + ]; + Player.applyFilters(Events.get_context_menu_file_more, data); + break; + } + case ConfigConstant.ContextMenuType.CUSTOM_PAGE: { + data = [ + [ + contextItemMap.get(ContextItemKey.Rename)(() => rename(nodeId, level, module), !renamable), + contextItemMap.get(ContextItemKey.Favorite)(() => updateNodeFavoriteStatus(nodeId, nodePrivate), nodeFavorite), + contextItemMap.get(ContextItemKey.Copy)(() => copyNode(nodeId), !copyable), + contextItemMap.get(ContextItemKey.CopyUrl)(() => copyUrl(nodeUrl), type), ], + compact([ + !activeNodePrivate && contextItemMap.get(ContextItemKey.Permission)(() => openPermissionSetting(nodeId), nodeAssignable), + contextItemMap.get(ContextItemKey.Share)(() => openShareModal(nodeId), !sharable), + contextItemMap.get(ContextItemKey.NodeInfo)(() => openNodeInfo(nodeId)), + contextItemMap.get(ContextItemKey.MoveTo)(() => openMoveTo(nodeId), !movable), + ]), [contextItemMap.get(ContextItemKey.Delete)(() => deleteNode(nodeId, level, module), !removable)], ]; Player.applyFilters(Events.get_context_menu_file_more, data); @@ -270,7 +302,7 @@ export const NodeContextMenu: FC> data = [ [ contextItemMap.get(ContextItemKey.Rename)(() => rename(nodeId, level, module), !renamable), - contextItemMap.get(ContextItemKey.Favorite)(() => updateNodeFavoriteStatus(nodeId), nodeFavorite), + contextItemMap.get(ContextItemKey.Favorite)(() => updateNodeFavoriteStatus(nodeId, nodePrivate), nodeFavorite), contextItemMap.get(ContextItemKey.Copy)(() => copyNode(nodeId), !copyable), contextItemMap.get(ContextItemKey.CopyUrl)(() => copyUrl(nodeUrl), type), ], @@ -281,12 +313,12 @@ export const NodeContextMenu: FC> !exportable || isMobileApp(), ), ], - [ - contextItemMap.get(ContextItemKey.Permission)(() => openPermissionSetting(nodeId), nodeAssignable), + compact([ + !activeNodePrivate && contextItemMap.get(ContextItemKey.Permission)(() => openPermissionSetting(nodeId), nodeAssignable), contextItemMap.get(ContextItemKey.NodeInfo)(() => openNodeInfo(nodeId)), contextItemMap.get(ContextItemKey.Share)(() => openShareModal(nodeId), !sharable), contextItemMap.get(ContextItemKey.MoveTo)(() => openMoveTo(nodeId), !movable), - ], + ]), [contextItemMap.get(ContextItemKey.Delete)(() => deleteNode(nodeId, level, module), !removable)], ]; Player.applyFilters(Events.get_context_menu_file_more, data); @@ -296,15 +328,15 @@ export const NodeContextMenu: FC> data = [ [ contextItemMap.get(ContextItemKey.Rename)(() => rename(nodeId, level, module), !renamable), - contextItemMap.get(ContextItemKey.Favorite)(() => updateNodeFavoriteStatus(nodeId), nodeFavorite), + contextItemMap.get(ContextItemKey.Favorite)(() => updateNodeFavoriteStatus(nodeId, nodePrivate), nodeFavorite), contextItemMap.get(ContextItemKey.CopyUrl)(() => copyUrl(nodeUrl), type), ], - [ - contextItemMap.get(ContextItemKey.Permission)(() => openPermissionSetting(nodeId), nodeAssignable), + compact([ + !activeNodePrivate && contextItemMap.get(ContextItemKey.Permission)(() => openPermissionSetting(nodeId), nodeAssignable), contextItemMap.get(ContextItemKey.NodeInfo)(() => openNodeInfo(nodeId)), contextItemMap.get(ContextItemKey.Share)(() => openShareModal(nodeId), !sharable), contextItemMap.get(ContextItemKey.MoveTo)(() => openMoveTo(nodeId), !movable), - ], + ]), [contextItemMap.get(ContextItemKey.Delete)(() => deleteNode(nodeId, level, module), !removable)], ]; Player.applyFilters(Events.get_context_menu_file_more, data); @@ -336,10 +368,8 @@ export const NodeContextMenu: FC> judgeShowAIEntrance() ? contextItemMap.get(ContextItemKey.addAi)(() => { if (!spaceInfo?.isEnableChatbot) { - const version = getReleaseVersion(); - const env = getEnvVariables(); - if (!env.ENV.includes('apitable')) { - if (version !== 'development') { + if (!getEnvVariables().IS_APITABLE) { + if (getReleaseVersion() !== 'development') { window.open(getAIOpenFormUrl()); return; } @@ -361,11 +391,17 @@ export const NodeContextMenu: FC> contextItemMap.get(ContextItemKey.AddAutomation)(() => { addTreeNode(targetId, ConfigConstant.NodeType.AUTOMATION); }), + contextItemMap.get(ContextItemKey.AddEmbed)(() => { + addTreeNode(targetId, ConfigConstant.NodeType.CUSTOM_PAGE); + }), ], [ contextItemMap.get(ContextItemKey.AddFolder)(() => { openCatalog(); - addTreeNode(targetId, ConfigConstant.NodeType.FOLDER); + addTreeNode( + targetId, + ConfigConstant.NodeType.FOLDER, + ) ; }), ], [ @@ -402,7 +438,7 @@ export const NodeContextMenu: FC> case ConfigConstant.ContextMenuType.DEFAULT: return t(Strings.new_something); default: - return ; + return ; } }; diff --git a/packages/datasheet/src/pc/components/catalog/node_context_menu/node_icons.tsx b/packages/datasheet/src/pc/components/catalog/node_context_menu/node_icons.tsx index 72158c5fc3..bf89f6f90b 100644 --- a/packages/datasheet/src/pc/components/catalog/node_context_menu/node_icons.tsx +++ b/packages/datasheet/src/pc/components/catalog/node_context_menu/node_icons.tsx @@ -54,8 +54,8 @@ import { FolderRightOutlined, RobotOutlined, RefreshOutlined, + EmbedOutlined, } from '@apitable/icons'; - /** * Node icon type, external use of this enumeration as configuration * @@ -101,6 +101,7 @@ export enum NodeIcon { Ai = 'Ai', AddAutomation = 'add_automation', CreateBackup = 'CreateBackup', + AddEmbed = 'add_embed', } // Enumeration and Resource Location Matching Table @@ -146,6 +147,7 @@ export const nodeIconImportMap: { [NodeIcon.MoveTo]: FolderRightOutlined, [NodeIcon.Ai]: RobotOutlined, [NodeIcon.CreateBackup]: RefreshOutlined, + [NodeIcon.AddEmbed]: EmbedOutlined, }; /** diff --git a/packages/datasheet/src/pc/components/catalog/node_context_menu/utils.ts b/packages/datasheet/src/pc/components/catalog/node_context_menu/utils.ts index 594fbf3881..2780108876 100644 --- a/packages/datasheet/src/pc/components/catalog/node_context_menu/utils.ts +++ b/packages/datasheet/src/pc/components/catalog/node_context_menu/utils.ts @@ -5,12 +5,5 @@ export const judgeShowAIEntrance = () => { }; export const getAIOpenFormUrl = () => { - const env = getEnvVariables(); - // if (env.ENV === 'apitable-integration') { - // return 'https://integration.aitable.ai/share/shrs5C6Gw4shPl826fjeD/fomAEFm52XjVGctUx4'; - // } - if (env.ENV === 'vika-integration') { - return 'https://integration.vika.ltd/share/shrBUWrYskgQKxzGT4rtz/fom0zfvUnZkPwp9nrC'; - } - return env.AI_OPEN_FORM; + return getEnvVariables().AI_OPEN_FORM; }; diff --git a/packages/datasheet/src/pc/components/catalog/node_info/node_info.tsx b/packages/datasheet/src/pc/components/catalog/node_info/node_info.tsx index 53f56481e3..886ea129d0 100644 --- a/packages/datasheet/src/pc/components/catalog/node_info/node_info.tsx +++ b/packages/datasheet/src/pc/components/catalog/node_info/node_info.tsx @@ -28,12 +28,11 @@ import { ScreenSize } from 'pc/components/common/component_display/enum'; import { Modal } from 'pc/components/common/modal/modal/modal'; import { useRequest, useResponsive } from 'pc/hooks'; import { store } from 'pc/store'; +import { useAppSelector } from 'pc/store/react-redux'; import { getNodeIcon } from '../tree/node_icon'; -import styles from './styles.module.less'; // @ts-ignore import { getSocialWecomUnitName } from 'enterprise/home/social_platform/utils'; - -import {useAppSelector} from "pc/store/react-redux"; +import styles from './styles.module.less'; interface INodeInfoProps { nodeId: string; diff --git a/packages/datasheet/src/pc/components/catalog/permission_settings/permission/search_result/search_result.tsx b/packages/datasheet/src/pc/components/catalog/permission_settings/permission/search_result/search_result.tsx index 03a42f9c35..9424c97f84 100644 --- a/packages/datasheet/src/pc/components/catalog/permission_settings/permission/search_result/search_result.tsx +++ b/packages/datasheet/src/pc/components/catalog/permission_settings/permission/search_result/search_result.tsx @@ -20,11 +20,11 @@ import Image from 'next/image'; import { FC } from 'react'; import { ThemeName } from '@apitable/components'; import { Strings, t } from '@apitable/core'; +import { useAppSelector } from 'pc/store/react-redux'; import NotDataImgDark from 'static/icon/datasheet/empty_state_dark.png'; import NotDataImgLight from 'static/icon/datasheet/empty_state_light.png'; import styles from './style.module.less'; -import {useAppSelector} from "pc/store/react-redux"; export interface ISearchResultProps { isEmpty?: boolean; } diff --git a/packages/datasheet/src/pc/components/catalog/permission_settings/permission/search_result/style.module.less b/packages/datasheet/src/pc/components/catalog/permission_settings/permission/search_result/style.module.less index 14f3c6ffca..529d724b70 100644 --- a/packages/datasheet/src/pc/components/catalog/permission_settings/permission/search_result/style.module.less +++ b/packages/datasheet/src/pc/components/catalog/permission_settings/permission/search_result/style.module.less @@ -7,7 +7,7 @@ overflow: hidden; height: 100%; - .light-scroll-bar(); + .default-scroll-bar(); } .notData { diff --git a/packages/datasheet/src/pc/components/catalog/permission_settings/permission/select_unit_modal/select_unit_left.tsx b/packages/datasheet/src/pc/components/catalog/permission_settings/permission/select_unit_modal/select_unit_left.tsx index 2ae6997835..582ed7249c 100644 --- a/packages/datasheet/src/pc/components/catalog/permission_settings/permission/select_unit_modal/select_unit_left.tsx +++ b/packages/datasheet/src/pc/components/catalog/permission_settings/permission/select_unit_modal/select_unit_left.tsx @@ -23,21 +23,26 @@ import { RadioChangeEvent } from 'antd/lib/radio'; import classnames from 'classnames'; import * as React from 'react'; import { ReactChild, useCallback, useEffect, useState } from 'react'; -import { Loading, stopPropagation, useThemeColors } from '@apitable/components'; -import { IBreadCrumbData, IMember, ISpaceBasicInfo, ISpaceInfo, ITeam, IUnit, Selectors, Strings, t, UnitItem } from '@apitable/core'; +import { Loading, stopPropagation, useThemeColors, TextButton, Button } from '@apitable/components'; +import { IBreadCrumbData, IMember, ISpaceBasicInfo, ISpaceInfo, ITeam, IUnit, Selectors, Strings, t, UnitItem, StoreActions } from '@apitable/core'; import { ChevronRightOutlined } from '@apitable/icons'; import { AvatarType, ButtonPlus, HorizontalScroll, InfoCard, SearchInput } from 'pc/components/common'; import { ScreenSize } from 'pc/components/common/component_display'; import { useCatalogTreeRequest, useRequest, useResponsive } from 'pc/hooks'; +import { useAppDispatch } from 'pc/hooks/use_app_dispatch'; import { IRoleItem, useRoleRequest } from 'pc/hooks/use_role'; +import { useAppSelector } from 'pc/store/react-redux'; import { getEnvVariables } from 'pc/utils/env'; import { SearchResult } from '../search_result'; -import styles from './style.module.less'; // @ts-ignore import { getSocialWecomUnitName } from 'enterprise/home/social_platform/utils'; import { SelectUnitSource } from '.'; +import styles from './style.module.less'; -import {useAppSelector} from "pc/store/react-redux"; +interface IGroupItem { + groupName: string; + groupId: string; +} export interface ISelectUnitLeftProps { isSingleSelect?: boolean; @@ -50,11 +55,13 @@ export interface ISelectUnitLeftProps { setUnits: React.Dispatch>; spaceInfo?: ISpaceInfo | ISpaceBasicInfo | null; showTab?: boolean; + showGroup?: boolean; } enum TabKey { Org = 'org', Role = 'role', + Group = 'group', } const BreadcrumbItem = Breadcrumb.Item; @@ -82,11 +89,13 @@ export const SelectUnitLeft: React.FC([{ name: t(Strings.contacts), teamId: '' }]); // Search by keyword @@ -96,22 +105,42 @@ export const SelectUnitLeft: React.FC(); - const [tabActiveKey, setTabActiveKey] = useState(TabKey.Org); + const [groupList, setGroupList] = useState([]); + const [groupMore, setGroupMore] = useState(false); + const [pageNo, setPageNo] = useState(1); + const [groupListLoading, setGroupListLoading] = useState(false); + const [moreLoading, setMoreLoading] = useState(false); + + const { run: getOrgYachGroupListReqDebounce } = useDebounceFn((keyword) => { + getOrgYachGroupListReq(1, keyword).then((res) => { + setGroupList(res.records); + setGroupMore(res.hasNextPage); + setPageNo(2); + dispatch(StoreActions.updateGroupList(res.records)); + setGroupListLoading(false); + }); + }, { wait: 300 }); - // role - const isRole = tabActiveKey === TabKey.Role; const { run: getRoleList, data } = useRoleRequest(); const { isOpen: roleIsOpen, roles: roleList } = data; let linkId = useAppSelector(Selectors.getLinkId); const spaceInfo = useAppSelector((state) => state.space.curSpaceInfo) || defaultSpaceInfo; const embedId = useAppSelector((state) => state.pageParams.embedId); - const { CUSTOM_SYNC_CONTACTS_LINKID } = getEnvVariables(); + const { CUSTOM_SYNC_CONTACTS_LINKID, YACH_ENABLED } = getEnvVariables(); if (CUSTOM_SYNC_CONTACTS_LINKID && source === SelectUnitSource.SyncMember) { linkId = CUSTOM_SYNC_CONTACTS_LINKID; } + const [tabActiveKey, setTabActiveKey] = useState(TabKey.Org); + + // group + const isGroup = tabActiveKey === TabKey.Group; + + // role + const isRole = tabActiveKey === TabKey.Role; + const { screenIsAtMost } = useResponsive(); const isMobile = screenIsAtMost(ScreenSize.md); @@ -127,12 +156,22 @@ export const SelectUnitLeft: React.FC { + if (isGroup) { + return; + } if (isRole || !keyword) { return; } search(keyword, linkId); // eslint-disable-next-line - }, [keyword, linkId, isRole]); + }, [keyword, linkId, isRole, isGroup]); + + useEffect(() => { + if (isGroup) { + !keyword && setGroupListLoading(true); + getOrgYachGroupListReqDebounce(keyword); + } + }, [isGroup, keyword]); useEffect(() => { if (source === SelectUnitSource.ChangeMemberTeam && unitsData && 'members' in unitsData) { @@ -149,7 +188,7 @@ export const SelectUnitLeft: React.FC @@ -375,7 +414,33 @@ export const SelectUnitLeft: React.FC ); - function RadioList(data: IUnit | IRoleItem[], inSearch = false) { + const GroupItem = (item: { + groupName: string; + unitId: string; + }) => ( +
+
+ onChangeChecked(e, item as any)}> +
+ +
+
+
+
+ ); + + function RadioList(data: IUnit | IRoleItem[] | IGroupItem[], inSearch = false) { if (!data) return; const units = isRole ? null : (data as IUnit); @@ -408,6 +473,8 @@ export const SelectUnitLeft: React.FC {isRole ? ( <>{roleList.map(RoleItem)} + ) : isGroup ? ( + <>{groupList.map(item => ({ ...item, unitId: item.groupId })).map(GroupItem)} ) : ( <> {inSearch && teams.length !== 0 &&
{t(Strings.team)}
} @@ -421,7 +488,7 @@ export const SelectUnitLeft: React.FC )}
- item.unitId)}> + item.unitId!)}> {isRole ? ( <>{roleList.map(RoleItem)} + ) : isGroup ? ( + <> + {groupList.map(item => ({ ...item, unitId: item.groupId })).map(GroupItem)} + {groupMore && ( +
+ {moreLoading ? ( + + ) : ( + { + setMoreLoading(true); + getOrgYachGroupListReq(pageNo, keyword)?.then((res) => { + setGroupList([...groupList, ...res.records]); + setGroupMore(res.hasNextPage); + setPageNo(pageNo + 1); + setMoreLoading(false); + }); + + }}> + {t(Strings.click_load_more)} + + + )} +
+ )} + ) : ( <> {inSearch && teams.length !== 0 &&
{t(Strings.team)}
} @@ -499,13 +593,13 @@ export const SelectUnitLeft: React.FC !keyword || v.roleName.includes(keyword)) : orgSearchData; + const listData = isRole ? roleList : isGroup ? groupList : units; + const searchData = isRole ? roleList.filter((v) => !keyword || v.roleName.includes(keyword)) : isGroup ? groupList : orgSearchData; // search result is empty const isEmptySearch = isRole - ? !roleList.length - : !orgSearchData || (!orgSearchData.teams?.length && !orgSearchData.members?.length && !orgSearchData.tags?.length); + ? !roleList.length : isGroup ? !groupList.length + : !orgSearchData || (!orgSearchData.teams?.length && !orgSearchData.members?.length && !orgSearchData.tags?.length); return (
@@ -525,6 +619,17 @@ export const SelectUnitLeft: React.FC + {showGroup && YACH_ENABLED && } + + )} + {!roleIsOpen && showGroup && YACH_ENABLED && ( + setTabActiveKey(value as TabKey)} + > + + )} {!isRole && ( diff --git a/packages/datasheet/src/pc/components/catalog/permission_settings/permission/select_unit_modal/select_unit_modal.tsx b/packages/datasheet/src/pc/components/catalog/permission_settings/permission/select_unit_modal/select_unit_modal.tsx index 769a729319..dc2b944518 100644 --- a/packages/datasheet/src/pc/components/catalog/permission_settings/permission/select_unit_modal/select_unit_modal.tsx +++ b/packages/datasheet/src/pc/components/catalog/permission_settings/permission/select_unit_modal/select_unit_modal.tsx @@ -30,14 +30,13 @@ import { IModalProps } from 'pc/components/common/modal/modal/modal.interface'; import { expandInviteModal } from 'pc/components/invite'; import { useSpaceInfo } from 'pc/hooks'; import { store } from 'pc/store'; +import { useAppSelector } from 'pc/store/react-redux'; import { stopPropagation } from 'pc/utils'; import { SelectUnitLeft } from './select_unit_left'; import { SelectUnitPopup } from './select_unit_popup'; import { SelectUnitRight } from './select_unit_right'; import styles from './style.module.less'; -import {useAppSelector} from "pc/store/react-redux"; - export enum SelectUnitSource { Perm = 'perm', Member = 'member', @@ -60,6 +59,7 @@ export interface ISelectUnitModalProps extends Omit { spaceId?: string; allowEmtpyCheckedList?: boolean; showTab?: boolean; // show role and org tab + showGroup?: boolean; // show group tab } export const SelectUnitModal: FC> = (props) => { @@ -75,6 +75,7 @@ export const SelectUnitModal: FC> spaceId, allowEmtpyCheckedList, showTab, + showGroup, ...rest } = props; @@ -159,6 +160,7 @@ export const SelectUnitModal: FC> setUnits={setUnits} spaceInfo={spaceInfo} showTab={showTab} + showGroup={showGroup} />
diff --git a/packages/datasheet/src/pc/components/catalog/permission_settings/permission/select_unit_modal/select_unit_popup.tsx b/packages/datasheet/src/pc/components/catalog/permission_settings/permission/select_unit_modal/select_unit_popup.tsx index 1aef5ad206..2c8f21349f 100644 --- a/packages/datasheet/src/pc/components/catalog/permission_settings/permission/select_unit_modal/select_unit_popup.tsx +++ b/packages/datasheet/src/pc/components/catalog/permission_settings/permission/select_unit_modal/select_unit_popup.tsx @@ -22,11 +22,10 @@ import { Strings, t } from '@apitable/core'; import { UserAddOutlined } from '@apitable/icons'; import { Popup } from 'pc/components/common/mobile/popup'; import { expandInviteModal } from 'pc/components/invite'; +import { useAppSelector } from 'pc/store/react-redux'; import { ISelectUnitLeftProps, SelectUnitLeft } from './select_unit_left'; import styles from './style.module.less'; -import {useAppSelector} from "pc/store/react-redux"; - interface ISelectPopupProps extends ISelectUnitLeftProps { onCancel(): void; onOk(): void; diff --git a/packages/datasheet/src/pc/components/catalog/permission_settings/permission/select_unit_modal/select_unit_right.tsx b/packages/datasheet/src/pc/components/catalog/permission_settings/permission/select_unit_modal/select_unit_right.tsx index 14fa24dd6d..d5f29da7c6 100644 --- a/packages/datasheet/src/pc/components/catalog/permission_settings/permission/select_unit_modal/select_unit_right.tsx +++ b/packages/datasheet/src/pc/components/catalog/permission_settings/permission/select_unit_modal/select_unit_right.tsx @@ -18,14 +18,13 @@ import * as React from 'react'; import { MemberType, Strings, t, IMember, ISpaceInfo, ISpaceBasicInfo, UnitItem } from '@apitable/core'; +import { useAppSelector } from 'pc/store/react-redux'; import { generateUserInfo } from 'pc/utils'; -import styles from './style.module.less'; import { UnitTag } from './unit_tag'; // @ts-ignore import { getSocialWecomUnitName } from 'enterprise/home/social_platform/utils'; import { SelectUnitSource } from '.'; - -import {useAppSelector} from "pc/store/react-redux"; +import styles from './style.module.less'; interface ISelectUnitRightProps { source?: SelectUnitSource; @@ -67,7 +66,7 @@ export const SelectUnitRight: React.FC> = return; } - const unitIds = unitInfos.map((item) => item.unitId); + const unitInfosNoGroup = unitInfos.filter((item) => item.type !== MemberType.Group); + const unitIdsNoGroup = unitInfosNoGroup.map((item) => item.unitId); + + const unitInfosGroup = unitInfos.filter((item) => item.type === MemberType.Group); + const groupIds = unitInfosGroup.map((item) => item.unitId); const res = await disableRoleExtend(); if (!res) { return; } - Api.addRole(data.nodeId, unitIds, permission.value + '').then(async (res) => { + groupIds.length > 0 && Api.yachAddRole({ nodeId: data.nodeId, unitIds: groupIds, role: permission.value + '' }).then(async (res) => { + const { success, message } = res.data; + if (success) { + Message.success({ content: t(Strings.permission_add_success) }); + await getNodeRoleMap(); + scrollBottom(); + } else { + Message.error({ content: message }); + } + }); + + unitIdsNoGroup.length > 0 && Api.addRole(data.nodeId, unitIdsNoGroup, permission.value + '').then(async (res) => { const { success, message } = res.data; if (success) { Message.success({ content: t(Strings.permission_add_success) }); @@ -287,6 +302,7 @@ export const Permission: FC> = permissionList={optionData} onSubmit={onSubmit} adminAndOwnerUnitIds={adminAndOwnerUnitIds} + showGroup />
)} diff --git a/packages/datasheet/src/pc/components/catalog/permission_settings_plus/permission/permission_info_setting.tsx b/packages/datasheet/src/pc/components/catalog/permission_settings_plus/permission/permission_info_setting.tsx index e5349c7944..7784430c2f 100644 --- a/packages/datasheet/src/pc/components/catalog/permission_settings_plus/permission/permission_info_setting.tsx +++ b/packages/datasheet/src/pc/components/catalog/permission_settings_plus/permission/permission_info_setting.tsx @@ -26,9 +26,9 @@ import { ScreenSize } from 'pc/components/common/component_display'; import { Popconfirm } from 'pc/components/common/popconfirm'; import { useResponsive } from 'pc/hooks'; import { Menu, MenuItem } from './menu'; -import styles from './style.module.less'; import { IRoleOption } from './unit_item/interface'; import { PermissionSelectMobile } from './unit_item/permission_select_mobile'; +import styles from './style.module.less'; export const PermissionInfoSetting: React.FC< React.PropsWithChildren<{ diff --git a/packages/datasheet/src/pc/components/catalog/permission_settings_plus/permission/unit_item/unit_item.tsx b/packages/datasheet/src/pc/components/catalog/permission_settings_plus/permission/unit_item/unit_item.tsx index 9455759c1f..87db38fa45 100644 --- a/packages/datasheet/src/pc/components/catalog/permission_settings_plus/permission/unit_item/unit_item.tsx +++ b/packages/datasheet/src/pc/components/catalog/permission_settings_plus/permission/unit_item/unit_item.tsx @@ -26,14 +26,13 @@ import { ChevronDownOutlined, ChevronUpOutlined } from '@apitable/icons'; import { AvatarType, InfoCard } from 'pc/components/common'; import { ComponentDisplay, ScreenSize } from 'pc/components/common/component_display'; import { useResponsive } from 'pc/hooks'; +import { useAppSelector } from 'pc/store/react-redux'; import { Menu, MenuItem } from '../menu'; import { IRoleOption, IUnitItemProps } from './interface'; import { PermissionSelectMobile } from './permission_select_mobile'; -import styles from './style.module.less'; // @ts-ignore import { getSocialWecomUnitName } from 'enterprise/home/social_platform/utils'; - -import {useAppSelector} from "pc/store/react-redux"; +import styles from './style.module.less'; export const DEFAULT_ROLE: IRoleOption[] = [ { diff --git a/packages/datasheet/src/pc/components/catalog/share/share.tsx b/packages/datasheet/src/pc/components/catalog/share/share.tsx index 8c3b7e0d19..a5805eae96 100644 --- a/packages/datasheet/src/pc/components/catalog/share/share.tsx +++ b/packages/datasheet/src/pc/components/catalog/share/share.tsx @@ -18,10 +18,9 @@ import { FC } from 'react'; import { IReduxState } from '@apitable/core'; +import { useAppSelector } from 'pc/store/react-redux'; import { ShareNode } from '../share_node'; -import {useAppSelector} from "pc/store/react-redux"; - export interface IShareProps { nodeId: string; onClose?: () => void; @@ -29,7 +28,14 @@ export interface IShareProps { } export const Share: FC> = ({ nodeId, onClose, isTriggerRender }) => { - const treeNodesMap = useAppSelector((state: IReduxState) => state.catalogTree.treeNodesMap); + const activeNodePrivate = useAppSelector((state) => { + if (!nodeId) { + return false; + } + return state.catalogTree.treeNodesMap[nodeId]?.nodePrivate || state.catalogTree.privateTreeNodesMap[nodeId]?.nodePrivate; + }); + const nodeKey = activeNodePrivate ? 'privateTreeNodesMap' : 'treeNodesMap'; + const nodesMap = useAppSelector((state: IReduxState) => state.catalogTree[nodeKey]); if (!nodeId) { return null; } @@ -37,9 +43,9 @@ export const Share: FC> = ({ nodeId, onClos { const spaceResource = useAppSelector((state: IReduxState) => state.spacePermissionManage.spaceResource); @@ -32,7 +31,7 @@ export const DisabledShareFile = ({ style }: { style?: React.CSSProperties }) => return (
- +
{t(Strings.disabled_file_shared)} diff --git a/packages/datasheet/src/pc/components/catalog/share_node/permission_and_collaborator.tsx b/packages/datasheet/src/pc/components/catalog/share_node/permission_and_collaborator.tsx index 3e520e279c..6ae97eeb2a 100644 --- a/packages/datasheet/src/pc/components/catalog/share_node/permission_and_collaborator.tsx +++ b/packages/datasheet/src/pc/components/catalog/share_node/permission_and_collaborator.tsx @@ -23,6 +23,7 @@ import { Skeleton, IOption, Typography, LinkButton } from '@apitable/components' import { Api, INodeRoleMap, IReduxState, IUnitValue, StoreActions, Strings, t } from '@apitable/core'; import { ChevronRightOutlined, QuestionCircleOutlined, UserAddOutlined, LinkOutlined } from '@apitable/icons'; import { useCatalogTreeRequest, useRequest, NodeChangeInfoType } from 'pc/hooks'; +import { useAppSelector } from 'pc/store/react-redux'; import { copy2clipBoard, permissionMenuData } from 'pc/utils'; import { getEnvVariables } from 'pc/utils/env'; import { Avatar, AvatarSize, Message, Tooltip } from '../../common'; @@ -31,13 +32,11 @@ import { expandInviteModal } from '../../invite'; import { IMemberList } from '../permission_settings_plus/permission'; import { MembersDetail } from '../permission_settings_plus/permission/members_detail'; import { IShareContentProps } from './interface'; -import styles from './style.module.less'; // @ts-ignore import { SubscribeUsageTipType, triggerUsageAlert } from 'enterprise/billing/trigger_usage_alert'; // @ts-ignore import { isSocialPlatformEnabled } from 'enterprise/home/social_platform/utils'; - -import {useAppSelector} from "pc/store/react-redux"; +import styles from './style.module.less'; export const PermissionAndCollaborator: React.FC = ({ data }) => { const [detailModalVisible, setDetailModalVisible] = useState(false); diff --git a/packages/datasheet/src/pc/components/catalog/share_node/public_link/public_share_invite_link.tsx b/packages/datasheet/src/pc/components/catalog/share_node/public_link/public_share_invite_link.tsx index 3326775e22..627947f656 100644 --- a/packages/datasheet/src/pc/components/catalog/share_node/public_link/public_share_invite_link.tsx +++ b/packages/datasheet/src/pc/components/catalog/share_node/public_link/public_share_invite_link.tsx @@ -21,7 +21,7 @@ import { Tooltip } from 'antd'; import { FC, useState, useCallback } from 'react'; import { shallowEqual, useDispatch } from 'react-redux'; import { Skeleton, IconButton, Button, LinkButton, DoubleSelect, IDoubleOptions, Switch, Typography, useThemeColors } from '@apitable/components'; -import { Api, Navigation, IReduxState, IShareSettings, StoreActions, Strings, t } from '@apitable/core'; +import { Api, Navigation, IReduxState, IShareSettings, StoreActions, Strings, t, ConfigConstant } from '@apitable/core'; import { CodeOutlined, LinkOutlined, @@ -46,7 +46,6 @@ import { ShareQrCode } from '../share_qr_code'; import { WidgetEmbed } from 'enterprise/chat/widget_embed'; import styles from './style.module.less'; - export interface IPublicShareLinkProps { nodeId: string; } @@ -65,7 +64,7 @@ export const PublicShareInviteLink: FC { @@ -232,8 +231,6 @@ export const PublicShareInviteLink: FC - {renderShareSwitchButton()} - - + ); } @@ -321,7 +315,7 @@ export const PublicShareInviteLink: FC ); } - + return (
{renderShareSwitchButton()} diff --git a/packages/datasheet/src/pc/components/catalog/share_node/public_link/style.module.less b/packages/datasheet/src/pc/components/catalog/share_node/public_link/style.module.less index c1340dbb68..7e20a023d7 100644 --- a/packages/datasheet/src/pc/components/catalog/share_node/public_link/style.module.less +++ b/packages/datasheet/src/pc/components/catalog/share_node/public_link/style.module.less @@ -170,7 +170,7 @@ padding-left: 7px; max-height: 72px; overflow: auto; - .light-scroll-bar(); + .default-scroll-bar(); .linkNode { padding-bottom: 8px; diff --git a/packages/datasheet/src/pc/components/catalog/share_node/share/share.tsx b/packages/datasheet/src/pc/components/catalog/share_node/share/share.tsx index dfabb7c7d1..442f998fc7 100644 --- a/packages/datasheet/src/pc/components/catalog/share_node/share/share.tsx +++ b/packages/datasheet/src/pc/components/catalog/share_node/share/share.tsx @@ -29,11 +29,10 @@ import { Popup } from 'pc/components/common/mobile/popup'; import { Modal } from 'pc/components/common/modal/modal/modal'; import { TComponent } from 'pc/components/common/t_component'; import { useRequest, useCatalogTreeRequest, useResponsive } from 'pc/hooks'; +import { useAppSelector } from 'pc/store/react-redux'; import { ShareLink } from './share_link'; import styles from './style.module.less'; -import {useAppSelector} from "pc/store/react-redux"; - export interface IShareProps { shareSettings: IShareSettings; nodeId: string; diff --git a/packages/datasheet/src/pc/components/catalog/share_node/share/style.module.less b/packages/datasheet/src/pc/components/catalog/share_node/share/style.module.less index b00427eedd..adc21dc20e 100644 --- a/packages/datasheet/src/pc/components/catalog/share_node/share/style.module.less +++ b/packages/datasheet/src/pc/components/catalog/share_node/share/style.module.less @@ -230,7 +230,7 @@ padding-left: 7px; max-height: 72px; overflow: auto; - .light-scroll-bar(); + .default-scroll-bar(); .linkNode { padding-bottom: 8px; diff --git a/packages/datasheet/src/pc/components/catalog/share_node/share_content.tsx b/packages/datasheet/src/pc/components/catalog/share_node/share_content.tsx index 4a3ca98bd0..8e4f8ce296 100644 --- a/packages/datasheet/src/pc/components/catalog/share_node/share_content.tsx +++ b/packages/datasheet/src/pc/components/catalog/share_node/share_content.tsx @@ -17,10 +17,12 @@ */ import { Tabs, TabsProps } from 'antd'; import cls from 'classnames'; +import { compact } from 'lodash'; import { FC } from 'react'; import { Strings, t } from '@apitable/core'; import { ScreenSize } from 'pc/components/common/component_display'; import { useResponsive } from 'pc/hooks'; +import { useAppSelector } from 'pc/store/react-redux'; import { IShareContentProps } from './interface'; import { PermissionAndCollaborator } from './permission_and_collaborator'; import { PublicShareInviteLink } from './public_link'; @@ -28,10 +30,14 @@ import styles from './style.module.less'; export const ShareContent: FC> = ({ data, defaultActiveKey = 'Invite' }) => { const { screenIsAtMost } = useResponsive(); + const nodeId = data.nodeId; + const activeNodePrivate = useAppSelector((state) => + state.catalogTree.treeNodesMap[nodeId]?.nodePrivate || state.catalogTree.privateTreeNodesMap[nodeId]?.nodePrivate + ); const isMobile = screenIsAtMost(ScreenSize.md); const renderTabs = () => { - const items: TabsProps['items'] = [ - { + const items: TabsProps['items'] = compact([ + !activeNodePrivate && { key: 'Invite', label: t(Strings.invite), children: , @@ -41,8 +47,8 @@ export const ShareContent: FC> = ({ label: t(Strings.publish), children: , }, - ]; - return ; + ]); + return ; }; return
{renderTabs()}
; diff --git a/packages/datasheet/src/pc/components/catalog/share_node/share_node.tsx b/packages/datasheet/src/pc/components/catalog/share_node/share_node.tsx index 80a40a8244..d334213e1c 100644 --- a/packages/datasheet/src/pc/components/catalog/share_node/share_node.tsx +++ b/packages/datasheet/src/pc/components/catalog/share_node/share_node.tsx @@ -17,17 +17,15 @@ */ import { FC } from 'react'; -import { ConfigConstant, IReduxState, Strings, t } from '@apitable/core'; +import { ConfigConstant, Strings, t } from '@apitable/core'; import { ComponentDisplay, ScreenSize } from 'pc/components/common/component_display'; import { Popup } from 'pc/components/common/mobile/popup'; import { Modal } from 'pc/components/common/modal/modal/modal'; import { TComponent } from 'pc/components/common/t_component'; -// import HeaderPng from 'static/icon/datasheet/share/datasheet_img_share.png'; +import { useAppSelector } from 'pc/store/react-redux'; import { ShareContent } from './share_content'; import styles from './style.module.less'; -import {useAppSelector} from "pc/store/react-redux"; - export interface IShareNodeProps { /** Information about the node being operated on */ data: { @@ -49,8 +47,10 @@ export enum ShareTab { } export const ShareNode: FC> = ({ data, visible, onClose, isTriggerRender }) => { - const treeNodesMap = useAppSelector((state: IReduxState) => state.catalogTree.treeNodesMap); - const { nodeName } = treeNodesMap[data.nodeId]; + const nodeId = data.nodeId; + const nodeName = useAppSelector((state) => + state.catalogTree.treeNodesMap[nodeId]?.nodeName || state.catalogTree.privateTreeNodesMap[nodeId]?.nodeName + ); if (isTriggerRender) { return ; @@ -62,7 +62,7 @@ export const ShareNode: FC> = ({ data, > = ({ nodeId, const dispatch = useDispatch(); const [secondVerify, setSecondVerify] = useState(null); const spaceInfo = useAppSelector((state: IReduxState) => state.space.curSpaceInfo)!; + const spaceId = useAppSelector((state) => state.space.activeId)!; useMount(() => { initNoTraceVerification(setSecondVerify, ConfigConstant.CaptchaIds.LOGIN); @@ -94,7 +94,7 @@ export const Teamwork: FC> = ({ nodeId, if (secondVerify) { setSecondVerify(null); } - const success = await sendInvite([{ email: inviteEmail, teamId: joinTeamId }], nodeId, nvcVal); + const success = await sendInvite(spaceId, [{ email: inviteEmail, teamId: joinTeamId }], nvcVal); if (success) { Message.success({ content: t(Strings.invite_success) }); } diff --git a/packages/datasheet/src/pc/components/catalog/tree/constants.ts b/packages/datasheet/src/pc/components/catalog/tree/constants.ts new file mode 100644 index 0000000000..ce0f0edaed --- /dev/null +++ b/packages/datasheet/src/pc/components/catalog/tree/constants.ts @@ -0,0 +1,11 @@ +import { ConfigConstant } from '@apitable/core'; + +export const LEAF_NODES = new Set([ + ConfigConstant.NodeType.DATASHEET, + ConfigConstant.NodeType.FORM, + ConfigConstant.NodeType.AUTOMATION, + ConfigConstant.NodeType.DASHBOARD, + ConfigConstant.NodeType.MIRROR, + ConfigConstant.NodeType.AI, + ConfigConstant.NodeType.CUSTOM_PAGE, +]); \ No newline at end of file diff --git a/packages/datasheet/src/pc/components/catalog/tree/node_icon/node_icon.tsx b/packages/datasheet/src/pc/components/catalog/tree/node_icon/node_icon.tsx index 84cce61d1b..69c5d7703d 100644 --- a/packages/datasheet/src/pc/components/catalog/tree/node_icon/node_icon.tsx +++ b/packages/datasheet/src/pc/components/catalog/tree/node_icon/node_icon.tsx @@ -99,9 +99,7 @@ export const getNodeIcon = ( }} alt="" /> - ) : ( - - ); + ) :; } const nodeConfig = nodeConfigData.find((item) => item.type === type); if (!nodeConfig) return; diff --git a/packages/datasheet/src/pc/components/catalog/tree/node_item/editing_node/editing_node.tsx b/packages/datasheet/src/pc/components/catalog/tree/node_item/editing_node/editing_node.tsx index 0ff2cf3eff..bb47dab7f9 100644 --- a/packages/datasheet/src/pc/components/catalog/tree/node_item/editing_node/editing_node.tsx +++ b/packages/datasheet/src/pc/components/catalog/tree/node_item/editing_node/editing_node.tsx @@ -16,10 +16,10 @@ * along with this program. If not, see . */ -import { FC, useState } from 'react'; import * as React from 'react'; +import { FC, useState } from 'react'; import { useDispatch } from 'react-redux'; -import { t, Strings, StoreActions, INodesMapItem, ConfigConstant } from '@apitable/core'; +import { ConfigConstant, INodesMapItem, StoreActions, Strings, t } from '@apitable/core'; import { RenameInput } from 'pc/components/common'; import { useCatalogTreeRequest, useRequest } from 'pc/hooks'; import { useCatalog } from 'pc/hooks/use_catalog'; @@ -31,15 +31,18 @@ export const NODE_NAME_MAX_LEN = 100; export interface IEditingNodeProps { node: INodesMapItem; + isPrivate?: boolean; } -export const EditingNode: FC> = ({ node }) => { +export const EditingNode: FC> = ({ node, isPrivate }) => { const [errMsg, setErrMsg] = useState(''); const { checkRepeat } = useCatalog(); const dispatch = useDispatch(); const { renameNodeReq } = useCatalogTreeRequest(); const [value, setValue] = useState(node.nodeName); - const { run: renameNode } = useRequest(renameNodeReq, { manual: true }); + const { run: renameNode } = useRequest((nodeId: string, nodeName: string) => + renameNodeReq(nodeId, nodeName, isPrivate ? ConfigConstant.Modules.PRIVATE : undefined), { manual: true } + ); const blurHandler = (e: React.FocusEvent) => { const inputValue = e.target.value.trim(); @@ -51,7 +54,7 @@ export const EditingNode: FC> = ({ no }; const cancelEdit = () => { - dispatch(StoreActions.setEditNodeId('')); + dispatch(StoreActions.setEditNodeId('', isPrivate ? ConfigConstant.Modules.PRIVATE : undefined)); dispatch(StoreActions.setEditNodeId('', ConfigConstant.Modules.FAVORITE)); }; diff --git a/packages/datasheet/src/pc/components/catalog/tree/node_item/node_item.tsx b/packages/datasheet/src/pc/components/catalog/tree/node_item/node_item.tsx index f3389f5df1..1957028dcd 100644 --- a/packages/datasheet/src/pc/components/catalog/tree/node_item/node_item.tsx +++ b/packages/datasheet/src/pc/components/catalog/tree/node_item/node_item.tsx @@ -40,6 +40,7 @@ export interface INodeItemProps { deleting: boolean; from: ConfigConstant.Modules; level: string; + isPrivate?: boolean; } let mobileModalClose: () => void; @@ -53,6 +54,7 @@ const NodeItemBase: FC> = ({ deleting, from, level, + isPrivate, }) => { const { deleteNodeReq } = useCatalogTreeRequest(); const { run: deleteNode } = useRequest(deleteNodeReq, { manual: true }); @@ -62,6 +64,7 @@ const NodeItemBase: FC> = ({ const isMobile = screenIsAtMost(ScreenSize.md); const currentLevel = level.split('-').length - 1; const childCreatable = node.type === ConfigConstant.NodeType.FOLDER && node.permissions.childCreatable && currentLevel < 5; + const moduleType = isPrivate ? ConfigConstant.Modules.PRIVATE : undefined; useEffect(() => { if (actived) { const activeElem = document.getElementById(`${ConfigConstant.Modules.CATALOG}${node.nodeId}`); @@ -91,13 +94,13 @@ const NodeItemBase: FC> = ({ const cancelDeleteModalHandler = () => { mobileModalClose?.(); - dispatch(StoreActions.setDelNodeId('')); + dispatch(StoreActions.setDelNodeId('', moduleType)); dispatch(StoreActions.setDelNodeId('', ConfigConstant.Modules.FAVORITE)); }; const deleteNodeHandler = () => { const { nodeId, parentId } = node; - deleteNode({ nodeId, parentId }); + deleteNode({ nodeId, parentId, module: moduleType }); cancelDeleteModalHandler(); }; @@ -105,7 +108,7 @@ const NodeItemBase: FC> = ({
{ {node.nodeName}
, }} @@ -148,6 +151,7 @@ const NodeItemBase: FC> = ({ expanded={expanded} hasChildren={hasChildren} node={node} + isPrivate={isPrivate} /> ) : ( @@ -163,6 +167,7 @@ const NodeItemBase: FC> = ({ expanded={expanded} hasChildren={hasChildren} node={node} + isPrivate={isPrivate} /> ); }; diff --git a/packages/datasheet/src/pc/components/catalog/tree/node_item/node_item_render.tsx b/packages/datasheet/src/pc/components/catalog/tree/node_item/node_item_render.tsx index 6ecd0c0f72..12ac5ba5b9 100644 --- a/packages/datasheet/src/pc/components/catalog/tree/node_item/node_item_render.tsx +++ b/packages/datasheet/src/pc/components/catalog/tree/node_item/node_item_render.tsx @@ -40,10 +40,11 @@ export interface IItemRender { expanded: boolean; hasChildren: boolean; node: INodesMapItem; + isPrivate?: boolean; } export const ItemRender: React.FC> = (props) => { - const { id, actived, isMobile, iconClassNames, editing, childCreatable, onClickMore, onNodeAdd, expanded, hasChildren, node } = props; + const { id, actived, isMobile, iconClassNames, editing, childCreatable, onClickMore, onNodeAdd, expanded, hasChildren, node, isPrivate } = props; const iconProps = { expanded, @@ -79,7 +80,7 @@ export const ItemRender: React.FC> = (props
{editing ? ( - + ) : ( diff --git a/packages/datasheet/src/pc/components/catalog/tree/tree.tsx b/packages/datasheet/src/pc/components/catalog/tree/tree.tsx index 9074e068e3..ab50361233 100644 --- a/packages/datasheet/src/pc/components/catalog/tree/tree.tsx +++ b/packages/datasheet/src/pc/components/catalog/tree/tree.tsx @@ -27,12 +27,12 @@ import { TComponent } from 'pc/components/common/t_component'; import { ITreeViewRef, TreeItem, TreeView } from 'pc/components/common/tree_view'; import { Router } from 'pc/components/route_manager/router'; import { useCatalogTreeRequest, useRequest, useResponsive } from 'pc/hooks'; +import { useAppSelector } from 'pc/store/react-redux'; import { isTouchDevice, shouldOpenInNewTab } from 'pc/utils'; +import { LEAF_NODES } from './constants'; import { NodeItem } from './node_item'; import styles from './style.module.less'; -import {useAppSelector} from "pc/store/react-redux"; - export const EMOJI_SIZE = 20; export interface ITreeProps { @@ -62,15 +62,7 @@ const TreeBase: FC> = ({ rightClick }) => { } rightClick(e, data); }; - const leafNodes = new Set([ - ConfigConstant.NodeType.DATASHEET, - ConfigConstant.NodeType.FORM, - ConfigConstant.NodeType.AUTOMATION, - ConfigConstant.NodeType.DASHBOARD, - ConfigConstant.NodeType.MIRROR, - ConfigConstant.NodeType.AI, - ]); - + const onContextMenu = (e: React.MouseEvent) => { e.stopPropagation(); e.preventDefault(); @@ -142,7 +134,7 @@ const TreeBase: FC> = ({ rightClick }) => { className={classNames} data={nodeInfo} draggable={!operating} - isLeaf={leafNodes.has(type)} + isLeaf={LEAF_NODES.has(type)} /> ); }); diff --git a/packages/datasheet/src/pc/components/common/color_picker/color_group.tsx b/packages/datasheet/src/pc/components/common/color_picker/color_group.tsx index 5955f0684f..6a39699a3b 100644 --- a/packages/datasheet/src/pc/components/common/color_picker/color_group.tsx +++ b/packages/datasheet/src/pc/components/common/color_picker/color_group.tsx @@ -21,7 +21,7 @@ import classNames from 'classnames'; import * as React from 'react'; import { FC, useState } from 'react'; import styled from 'styled-components'; -import { Box, FloatUiTooltip, Typography } from '@apitable/components'; +import { Box, FloatUiTooltip, Typography, TooltipBase } from '@apitable/components'; import { ButtonStyleType, ISelectFieldOption, Selectors, Strings, t } from '@apitable/core'; import { AutomationConstant } from 'pc/components/automation/config'; import { setColor, useColorColorWheel } from 'pc/components/multi_grid/format'; @@ -39,7 +39,7 @@ export interface IColorGroupProps { disabled?: boolean; itemStyle?: React.CSSProperties; options?: { - style?: ButtonStyleType, + style?: ButtonStyleType; content?: string; }; } @@ -48,6 +48,9 @@ const StyledFloatUiTooltip = styled(FloatUiTooltip)` padding: 0 !important; `; +const StyledTooltipBase = styled(TooltipBase)` +`; + export const ColorGroup: FC> = (props) => { const { colorGroup, options, option, onChange, style, disabled, itemStyle } = props; const [colorIdx, setColorIdx] = useState(); @@ -55,10 +58,10 @@ export const ColorGroup: FC> = (props) const cacheTheme = useAppSelector(Selectors.getTheme); const colorList = useColorColorWheel(cacheTheme); - const getTextColor=(color: number) => { - let textColor : string= colors.textStaticPrimary; - if(cacheTheme === 'dark') { - if(color === AutomationConstant.whiteColor) { + const getTextColor = (color: number) => { + let textColor: string = colors.textStaticPrimary; + if (cacheTheme === 'dark') { + if (color === AutomationConstant.whiteColor) { textColor = colors.textReverseDefault; } } @@ -101,25 +104,25 @@ export const ColorGroup: FC> = (props) - { - options?.style === ButtonStyleType.Background ? ( - - - {props?.options?.content} - - - ): ( - - - {props?.options?.content} - - - ) - } - + + {options?.style === ButtonStyleType.Background ? ( + + + {props?.options?.content} + + + ) : ( + + + {props?.options?.content} + + + )} + } >
. */ -import { ShortcutActionManager, ShortcutActionName } from 'modules/shared/shortcut_key'; import { Selectors, FieldType, CollaCommandName, t, Strings, ExecuteResult } from '@apitable/core'; +import { ShortcutActionManager, ShortcutActionName } from 'modules/shared/shortcut_key'; import { Modal } from 'pc/components/common/modal/modal/modal'; import { notify } from 'pc/components/common/notify'; import { resourceService } from 'pc/resource_service'; diff --git a/packages/datasheet/src/pc/components/common/horizontal_scroll/style.module.less b/packages/datasheet/src/pc/components/common/horizontal_scroll/style.module.less index b603d99387..3509a8bf0b 100644 --- a/packages/datasheet/src/pc/components/common/horizontal_scroll/style.module.less +++ b/packages/datasheet/src/pc/components/common/horizontal_scroll/style.module.less @@ -9,12 +9,7 @@ .scrollWrapper { position: relative; height: 28px; - overflow: auto; - - &::-webkit-scrollbar { - width: 0; - height: 0; - } + overflow: hidden; } .beadCrumb { diff --git a/packages/datasheet/src/pc/components/common/modal/modal/modal.tsx b/packages/datasheet/src/pc/components/common/modal/modal/modal.tsx index a9eaa0e2f3..ffdb65b860 100644 --- a/packages/datasheet/src/pc/components/common/modal/modal/modal.tsx +++ b/packages/datasheet/src/pc/components/common/modal/modal/modal.tsx @@ -18,11 +18,11 @@ import classNames from 'classnames'; import parser from 'html-react-parser'; -import { getBillingInfo } from 'modules/billing'; import React, { FC } from 'react'; import { Provider } from 'react-redux'; import { Strings, t } from '@apitable/core'; import { CloseOutlined } from '@apitable/icons'; +import { getBillingInfo } from 'modules/billing'; import { FooterBtnInModal } from 'pc/components/common/modal/components/footer_btn'; import { IDingTalkModalType, showModalInDingTalk } from 'pc/components/economy/upgrade_modal'; import { store } from 'pc/store'; diff --git a/packages/datasheet/src/pc/components/common/modal/modal/modal_with_theme.tsx b/packages/datasheet/src/pc/components/common/modal/modal/modal_with_theme.tsx index 5e56b1ef10..68dd282214 100644 --- a/packages/datasheet/src/pc/components/common/modal/modal/modal_with_theme.tsx +++ b/packages/datasheet/src/pc/components/common/modal/modal/modal_with_theme.tsx @@ -21,7 +21,7 @@ import React from 'react'; import { ThemeProvider } from '@apitable/components'; import { Selectors } from '@apitable/core'; -import {useAppSelector} from "pc/store/react-redux"; +import { useAppSelector } from 'pc/store/react-redux'; export const ModalWithTheme = (props: any) => { const cacheTheme = useAppSelector(Selectors.getTheme); diff --git a/packages/datasheet/src/pc/components/common/node_favorite_status/node_favorite_status.tsx b/packages/datasheet/src/pc/components/common/node_favorite_status/node_favorite_status.tsx index d3f707adfe..11abf672bd 100644 --- a/packages/datasheet/src/pc/components/common/node_favorite_status/node_favorite_status.tsx +++ b/packages/datasheet/src/pc/components/common/node_favorite_status/node_favorite_status.tsx @@ -20,6 +20,7 @@ import { FC } from 'react'; import { t, Strings } from '@apitable/core'; import { StarOutlined, StarFilled } from '@apitable/icons'; import { useCatalogTreeRequest, useRequest } from 'pc/hooks'; +import { useAppSelector } from 'pc/store/react-redux'; import { Tooltip } from '../tooltip'; import styles from './style.module.less'; @@ -29,6 +30,9 @@ export interface INodeFavoriteStatusProps { } export const NodeFavoriteStatus: FC> = ({ nodeId, enabled }) => { + const activeNodePrivate = useAppSelector((state) => { + return state.catalogTree.treeNodesMap[nodeId]?.nodePrivate || state.catalogTree.privateTreeNodesMap[nodeId]?.nodePrivate; + }); const { updateNodeFavoriteStatusReq } = useCatalogTreeRequest(); const { run: updateNodeFavoriteStatus, loading } = useRequest(updateNodeFavoriteStatusReq, { manual: true }); @@ -36,7 +40,7 @@ export const NodeFavoriteStatus: FC> = ({ da type, name, role = ConfigConstant.Role.Administrator, - favoriteEnabled = false, nameEditable = false, iconEditable = false, + subscribeEnabled = false, iconSize, } = data; const [newName, setNewName] = useState(name); @@ -75,7 +76,9 @@ export const NodeInfoBar: FC> = ({ da const { run: renameNode } = useRequest(renameNodeReq, { manual: true }); const isDatasheet = type === ConfigConstant.NodeType.DATASHEET; const embedId = useAppSelector((state) => state.pageParams.embedId); - const _showDescription = isDatasheet; + const _showDescription = isDatasheet || subscribeEnabled; + const favoriteTreeNodeIds = useAppSelector((state: IReduxState) => state.catalogTree.favoriteTreeNodeIds); + const favoriteEnabled = data.favoriteEnabled || favoriteTreeNodeIds.includes(nodeId); useEffect(() => { setNewName(name); diff --git a/packages/datasheet/src/pc/components/common/record_card/record_card.tsx b/packages/datasheet/src/pc/components/common/record_card/record_card.tsx index fe5d06df29..076785431c 100644 --- a/packages/datasheet/src/pc/components/common/record_card/record_card.tsx +++ b/packages/datasheet/src/pc/components/common/record_card/record_card.tsx @@ -22,6 +22,8 @@ import * as React from 'react'; import { useMemo } from 'react'; import { Field, FieldType, IField, IRecord, IReduxState, IViewColumn, Selectors, Strings, t } from '@apitable/core'; import { SubtractCircleFilled } from '@apitable/icons'; +// eslint-disable-next-line no-restricted-imports +import { Tooltip } from 'pc/components/common'; import { DisplayFile } from 'pc/components/display_file'; import { CellValue } from 'pc/components/multi_grid/cell/cell_value'; import { useResponsive } from 'pc/hooks'; @@ -92,7 +94,9 @@ export const RecordCard: React.FC> = ( [styles.noReadablePermission]: !foreignDstReadable, })} > -

{title || t(Strings.record_unnamed)}

+

+ {title || t(Strings.record_unnamed)} +

{foreignDstReadable && (
{normalColumns.map((column) => { @@ -113,7 +117,13 @@ export const RecordCard: React.FC> = (
{cellValue == null ? ( + ) : field.type === FieldType.SingleText || field.type === FieldType.Text ? ( + // + + + ) : ( + // )}
diff --git a/packages/datasheet/src/pc/components/common/record_card/style.module.less b/packages/datasheet/src/pc/components/common/record_card/style.module.less index c55eeb96f7..e9232770ce 100644 --- a/packages/datasheet/src/pc/components/common/record_card/style.module.less +++ b/packages/datasheet/src/pc/components/common/record_card/style.module.less @@ -67,6 +67,19 @@ height: 31px; display: flex; align-items: center; + :global { + .expandWorkdoc { + padding: 0; + } + .workdocBtn { + max-width: 94px; + padding: 0 2px; + cursor: default; + &:hover{ + background-color: var(--bgBrandLightDefault); + } + } + } .cellHolder { border: solid 1px var(--fourthLevelText); diff --git a/packages/datasheet/src/pc/components/common/search_control/search_control.tsx b/packages/datasheet/src/pc/components/common/search_control/search_control.tsx index 21faa2d313..8837646454 100644 --- a/packages/datasheet/src/pc/components/common/search_control/search_control.tsx +++ b/packages/datasheet/src/pc/components/common/search_control/search_control.tsx @@ -22,12 +22,11 @@ import { forwardRef, memo, useImperativeHandle, useRef } from 'react'; import { Switch } from '@apitable/components'; import { LineSearchInput } from 'pc/components/list/common_list/line_search_input'; import { useResponsive } from 'pc/hooks'; +import { useAppSelector } from 'pc/store/react-redux'; import { stopPropagation } from '../../../utils/dom'; import { ScreenSize } from '../component_display'; import style from './style.module.less'; -import {useAppSelector} from "pc/store/react-redux"; - interface ISearchControlProps { onValueChange?: (searchValue: string) => void; onSwitcherChange?: (checked: boolean) => void; diff --git a/packages/datasheet/src/pc/components/common/search_empty/search_empty.tsx b/packages/datasheet/src/pc/components/common/search_empty/search_empty.tsx index 9e0f1cad5c..da3242a8be 100644 --- a/packages/datasheet/src/pc/components/common/search_empty/search_empty.tsx +++ b/packages/datasheet/src/pc/components/common/search_empty/search_empty.tsx @@ -20,12 +20,11 @@ import Image from 'next/image'; import { FC } from 'react'; import { ThemeName } from '@apitable/components'; import { Strings, t } from '@apitable/core'; +import { useAppSelector } from 'pc/store/react-redux'; import NotDataImgDark from 'static/icon/datasheet/empty_state_dark.png'; import NotDataImgLight from 'static/icon/datasheet/empty_state_light.png'; import styles from './style.module.less'; -import {useAppSelector} from "pc/store/react-redux"; - export const SearchEmpty: FC> = () => { const themeName = useAppSelector((state) => state.theme); const SearchImage = themeName === ThemeName.Light ? NotDataImgLight : NotDataImgDark; diff --git a/packages/datasheet/src/pc/components/common/search_member_list/search_member_list.tsx b/packages/datasheet/src/pc/components/common/search_member_list/search_member_list.tsx index f92d15b072..6863a499f9 100644 --- a/packages/datasheet/src/pc/components/common/search_member_list/search_member_list.tsx +++ b/packages/datasheet/src/pc/components/common/search_member_list/search_member_list.tsx @@ -23,16 +23,15 @@ import { FC, useEffect, useState } from 'react'; import { TextInput, ThemeName } from '@apitable/components'; import { ISearchMemberData, Strings, t } from '@apitable/core'; import { SearchOutlined } from '@apitable/icons'; +import { useAppSelector } from 'pc/store/react-redux'; import NotDataImgDark from 'static/icon/datasheet/empty_state_dark.png'; import NotDataImgLight from 'static/icon/datasheet/empty_state_light.png'; import { InfoCard } from '../index'; -import styles from './style.module.less'; -// @ts-ignore -import { WecomOpenData } from 'enterprise/wecom/wecom_open_data/wecom_open_data'; // @ts-ignore import { getSocialWecomUnitName, isSocialWecom } from 'enterprise/home/social_platform/utils'; - -import {useAppSelector} from "pc/store/react-redux"; +// @ts-ignore +import { WecomOpenData } from 'enterprise/wecom/wecom_open_data/wecom_open_data'; +import styles from './style.module.less'; interface ISearchMemberListProps { onChange: (value: string) => void; diff --git a/packages/datasheet/src/pc/components/common/search_member_list/style.module.less b/packages/datasheet/src/pc/components/common/search_member_list/style.module.less index ec201414ee..bc2cd08977 100644 --- a/packages/datasheet/src/pc/components/common/search_member_list/style.module.less +++ b/packages/datasheet/src/pc/components/common/search_member_list/style.module.less @@ -22,7 +22,7 @@ &:hover { overflow: auto; } - .light-scroll-bar(); + .default-scroll-bar(); } .infoCardWrap { diff --git a/packages/datasheet/src/pc/components/common/search_team_and_member/search_list/search_list.tsx b/packages/datasheet/src/pc/components/common/search_team_and_member/search_list/search_list.tsx index 61ed8165ea..1f8341eb91 100644 --- a/packages/datasheet/src/pc/components/common/search_team_and_member/search_list/search_list.tsx +++ b/packages/datasheet/src/pc/components/common/search_team_and_member/search_list/search_list.tsx @@ -20,12 +20,11 @@ import { List } from 'antd'; import { FC } from 'react'; import { ITeamsInSearch, IMembersInSearch, t, Strings } from '@apitable/core'; import { InfoCard } from 'pc/components/common'; +import { useAppSelector } from 'pc/store/react-redux'; import { AvatarType } from '../../avatar'; -import styles from './style.module.less'; // @ts-ignore import { getSocialWecomUnitName } from 'enterprise/home/social_platform/utils'; - -import {useAppSelector} from "pc/store/react-redux"; +import styles from './style.module.less'; export enum ListType { MemberList = 'MEMBER_LIST', diff --git a/packages/datasheet/src/pc/components/common/search_team_and_member/search_team_and_member.tsx b/packages/datasheet/src/pc/components/common/search_team_and_member/search_team_and_member.tsx index 47704a9978..02ac9c190d 100644 --- a/packages/datasheet/src/pc/components/common/search_team_and_member/search_team_and_member.tsx +++ b/packages/datasheet/src/pc/components/common/search_team_and_member/search_team_and_member.tsx @@ -21,13 +21,12 @@ import classNames from 'classnames'; import { FC, useState, useRef, useEffect } from 'react'; import { IReduxState, Api, ITeamsInSearch, IMembersInSearch } from '@apitable/core'; import { useRequest, useResponsive } from 'pc/hooks'; +import { useAppSelector } from 'pc/store/react-redux'; import { ScreenSize } from '../component_display'; import { SearchInput, SearchEmpty } from '../index'; import { SearchList, ListType } from './search_list'; import styles from './style.module.less'; -import {useAppSelector} from "pc/store/react-redux"; - interface ISearchTeamAndMemberProps { setInSearch: (inSearch: boolean) => void; teamClick: (id: string) => void; diff --git a/packages/datasheet/src/pc/components/common/slider_verification/slider_verification.tsx b/packages/datasheet/src/pc/components/common/slider_verification/slider_verification.tsx index 5845f26021..d34d7bfe94 100644 --- a/packages/datasheet/src/pc/components/common/slider_verification/slider_verification.tsx +++ b/packages/datasheet/src/pc/components/common/slider_verification/slider_verification.tsx @@ -24,7 +24,6 @@ import { getEnvVariables } from 'pc/utils/env'; import styles from './style.module.less'; export const SliderVerification: FC> = () => { - useMount(() => { const env = getEnvVariables(); if (!env.IS_SELFHOST) { @@ -48,7 +47,7 @@ export const openSliderVerificationModal = () => { icon: '', title: t(Strings.safety_verification), content: ( -
+
{t(Strings.safety_verification_tip)} diff --git a/packages/datasheet/src/pc/components/common/slider_verification/style.module.less b/packages/datasheet/src/pc/components/common/slider_verification/style.module.less index 04926f971d..dadb578c0a 100644 --- a/packages/datasheet/src/pc/components/common/slider_verification/style.module.less +++ b/packages/datasheet/src/pc/components/common/slider_verification/style.module.less @@ -1,4 +1,3 @@ - .sliderVerificationModal { .tip { padding-bottom: 16px !important; @@ -13,7 +12,7 @@ div.nc_scale { height: 48px; line-height: 48px; - background-color: #E9E9F5 !important; + background-color: #e9e9f5 !important; } .nc_wrapper { diff --git a/packages/datasheet/src/pc/components/common/tree_view/tree_view/style.module.less b/packages/datasheet/src/pc/components/common/tree_view/tree_view/style.module.less index be0ec0467e..4a2fcc39fc 100644 --- a/packages/datasheet/src/pc/components/common/tree_view/tree_view/style.module.less +++ b/packages/datasheet/src/pc/components/common/tree_view/tree_view/style.module.less @@ -3,6 +3,9 @@ padding: 0 8px; text-align: center; max-width:234px; + a { + display: inline; + } :global { .typography { margin-bottom: 16px; diff --git a/packages/datasheet/src/pc/components/common/tree_view/tree_view/tree_view.tsx b/packages/datasheet/src/pc/components/common/tree_view/tree_view/tree_view.tsx index f98715d7fb..7d254d94ce 100644 --- a/packages/datasheet/src/pc/components/common/tree_view/tree_view/tree_view.tsx +++ b/packages/datasheet/src/pc/components/common/tree_view/tree_view/tree_view.tsx @@ -19,10 +19,10 @@ import { isEmpty, isEqual, xor } from 'lodash'; import * as React from 'react'; import { forwardRef, memo, ReactNode, useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react'; -import { Button, Typography } from '@apitable/components'; +import { Button, LinkButton, Typography } from '@apitable/components'; import { ConfigConstant, Navigation, t, Strings } from '@apitable/core'; import { AddOutlined, TriangleRightFilled } from '@apitable/icons'; - +import { TComponent } from 'pc/components/common/t_component'; import { Router } from '../../../route_manager/router'; import { TreeItem } from '../tree_item'; import TreeViewContext from '../tree_view_context'; @@ -157,6 +157,10 @@ export const TreeViewBase: React.ForwardRefRenderFunction - {t(Strings.catalog_empty_tips)} + + {module === ConfigConstant.Modules.PRIVATE ? ( + + {t(Strings.know_more)} + + ), + }} + /> + ) : t(Strings.catalog_empty_tips)} + +
+ ) : ( +
+ + +
+ )} + +
+ ); +}; diff --git a/packages/datasheet/src/pc/components/custom_page/components/setting/style.module.less b/packages/datasheet/src/pc/components/custom_page/components/setting/style.module.less new file mode 100644 index 0000000000..e03e241695 --- /dev/null +++ b/packages/datasheet/src/pc/components/custom_page/components/setting/style.module.less @@ -0,0 +1,21 @@ +.drawerWrapper { + :global { + .ant-drawer-header { + border-bottom: 0; + } + .ant-drawer-body { + padding-top: 0; + } + } +} + +.popupWrapper { + :global { + .ant-drawer-header { + padding: 16px; + } + .ant-drawer-body { + padding: 0 16px 32px; + } + } +} diff --git a/packages/datasheet/src/pc/components/custom_page/components/tab/tab.tsx b/packages/datasheet/src/pc/components/custom_page/components/tab/tab.tsx new file mode 100644 index 0000000000..38b5b2ec26 --- /dev/null +++ b/packages/datasheet/src/pc/components/custom_page/components/tab/tab.tsx @@ -0,0 +1,97 @@ +import { Dispatch, SetStateAction } from 'react'; +import { TextButton, useThemeColors } from '@apitable/components'; +import { ConfigConstant, Strings, t } from '@apitable/core'; +import { ListOutlined, SettingOutlined, ShareOutlined } from '@apitable/icons'; +import { NodeInfoBar } from 'pc/components/common/node_info_bar'; +import { useSideBarVisible } from 'pc/hooks'; +import { useAppSelector } from 'pc/store/react-redux'; +import { getPermission } from 'pc/utils'; +import { useGetInfo } from '../../hooks/use_get_info'; + +interface ITabProps { + setNodeId: Dispatch>; + setOpenSetting: any; + isMobile: boolean; +} + +export const Tab: React.FC = ({ setOpenSetting, isMobile, setNodeId }) => { + const colors = useThemeColors(); + const { setSideBarVisible } = useSideBarVisible(); + const { customPageId, shareId, templateId } = useAppSelector((state) => state.pageParams); + const { nodeFavorite, permissions: nodePermissions, icon, nodeName, role } = useGetInfo(); + + const canShare = getPermission(role) === 'editor' || getPermission(role) === 'manager'; + const canSetting = canShare || getPermission(role) === 'updater'; + + if (isMobile) { + return ( +
+
setSideBarVisible(true)}> + +
+ {!shareId && ( +
+ {canSetting && ( + } size="x-small" onClick={() => setOpenSetting(true)} className={'!vk-collapsevk-px-1'}> + {t(Strings.form_tab_setting)} + + )} + {canShare && ( + } size="x-small" className={'!vk-px-1'} onClick={() => setNodeId(customPageId!)}> + {t(Strings.form_tab_share)} + + )} +
+ )} +
+ ); + } + + return ( +
+
+ +
+ {!shareId && ( +
+ {/*
*/} + {canSetting && ( + } size="small" onClick={() => setOpenSetting(true)}> + {t(Strings.form_tab_setting)} + + )} + {canShare && ( + } size="small" onClick={() => setNodeId(customPageId!)}> + {t(Strings.form_tab_share)} + + )} +
+ )} +
+ ); +}; diff --git a/packages/datasheet/src/pc/components/custom_page/config/config.ts b/packages/datasheet/src/pc/components/custom_page/config/config.ts new file mode 100644 index 0000000000..5e7695a498 --- /dev/null +++ b/packages/datasheet/src/pc/components/custom_page/config/config.ts @@ -0,0 +1,110 @@ +import { Strings, t } from '@apitable/core'; +import { CodeOutlined } from '@apitable/icons'; +import { getEnvVariables } from 'pc/utils/env'; + +import AnythingDarkPng from 'static/icon/embed/Anything_dark.png'; +import AnythingLightPng from 'static/icon/embed/Anything_light.png'; +import BilibiliPng from 'static/icon/embed/Bilbili.png'; +import DocsPng from 'static/icon/embed/Docs.png'; +import FigmaPng from 'static/icon/embed/Figma.png'; +import JishiPng from 'static/icon/embed/Jishi.png'; +import SheetPng from 'static/icon/embed/Sheet.png'; +import TencentDocPng from 'static/icon/embed/TencentDoc.png'; +import WpsPng from 'static/icon/embed/WPS.png'; +import YouTubePng from 'static/icon/embed/YouTube.png'; + +const AI_TABLE_CONFIG = [ + { + name: t(Strings.embed_link_default), + desc: t(Strings.embed_link_default_desc), + linkText: t(Strings.embed_link_default_link_text), + linkUrl: t(Strings.embed_link_default_link_url), + tip: t(Strings.embed_paste_link_default_placeholder), + icon: { + dark: AnythingDarkPng.src, + light: AnythingLightPng.src, + }, + }, + { + name: t(Strings.embed_link_google_docs), + desc: t(Strings.embed_link_google_docs_desc), + linkText: t(Strings.embed_link_google_docs_link_text), + linkUrl: t(Strings.embed_link_google_docs_link_url), + tip: t(Strings.embed_paste_link_google_docs_placeholder), + icon: DocsPng.src, + }, + { + name: t(Strings.embed_link_google_sheets), + desc: t(Strings.embed_link_google_sheets_desc), + linkText: t(Strings.embed_link_google_sheets_link_text), + linkUrl: t(Strings.embed_link_google_sheets_link_url), + tip: t(Strings.embed_paste_link_google_sheets_placeholder), + icon: SheetPng.src, + }, + { + name: t(Strings.embed_link_figma), + desc: t(Strings.embed_link_figma_desc), + linkText: t(Strings.embed_link_figma_link_text), + linkUrl: t(Strings.embed_link_figma_link_url), + tip: t(Strings.embed_paste_link_figma_placeholder), + icon: FigmaPng.src, + }, + { + name: t(Strings.embed_link_youtube), + desc: t(Strings.embed_link_youtube_desc), + linkText: t(Strings.embed_link_youtube_link_text), + linkUrl: t(Strings.embed_link_youtube_link_url), + tip: t(Strings.embed_paste_link_youtube_placeholder), + icon: YouTubePng.src, + }, +]; + +const VIKA_CONFIG = [ + { + name: t(Strings.embed_link_default), + desc: t(Strings.embed_link_default_desc), + linkText: t(Strings.embed_link_default_link_text), + linkUrl: t(Strings.embed_link_default_link_url), + tip: t(Strings.embed_paste_link_default_placeholder), + icon: { + dark: AnythingDarkPng.src, + light: AnythingLightPng.src, + }, + }, + { + name: t(Strings.embed_link_wps), + desc: t(Strings.embed_link_wps_desc), + linkText: t(Strings.embed_link_wps_link_text), + linkUrl: t(Strings.embed_link_wps_link_url), + tip: t(Strings.embed_paste_link_wps_placeholder), + icon: WpsPng.src, + }, + { + name: t(Strings.embed_link_tencent_docs), + desc: t(Strings.embed_link_tencent_docs_desc), + linkText: t(Strings.embed_link_tencent_docs_link_text), + linkUrl: t(Strings.embed_link_tencent_docs_link_url), + tip: t(Strings.embed_paste_link_tencent_docs_placeholder), + icon: TencentDocPng.src, + }, + { + name: t(Strings.embed_link_jishi_design), + desc: t(Strings.embed_link_jishi_design_desc), + linkText: t(Strings.embed_link_jishi_design_link_text), + linkUrl: t(Strings.embed_link_jishi_design_link_url), + tip: t(Strings.embed_paste_link_jsdesign_placeholder), + icon: JishiPng.src, + }, + { + name: t(Strings.embed_link_bilibili), + desc: t(Strings.embed_link_bilibili_desc), + linkText: t(Strings.embed_link_bilibili_link_text), + linkUrl: t(Strings.embed_link_bilibili_link_url), + tip: t(Strings.embed_paste_link_bilibili_placeholder), + icon: BilibiliPng.src, + }, +]; + +export const getConfig = () => { + return getEnvVariables().IS_AITABLE ? AI_TABLE_CONFIG : VIKA_CONFIG; +}; diff --git a/packages/datasheet/src/pc/components/custom_page/custom_page.tsx b/packages/datasheet/src/pc/components/custom_page/custom_page.tsx new file mode 100644 index 0000000000..a8c870819c --- /dev/null +++ b/packages/datasheet/src/pc/components/custom_page/custom_page.tsx @@ -0,0 +1,62 @@ +import { useEffect, useState } from 'react'; +import { Button, ScreenSize, useResponsive } from '@apitable/components'; +import { ConfigConstant, Strings, t } from '@apitable/core'; +import { SettingOutlined } from '@apitable/icons'; +import { useAppSelector } from 'pc/store/react-redux'; +import AutomationEmptyDark from 'static/icon/datasheet/automation_empty_dark.png'; +import { Share } from '../catalog/share'; +import { NoPermission } from '../no_permission'; +import { Setting } from './components/setting/setting'; +import { Tab } from './components/tab/tab'; +import { useGetDesc } from './hooks/use_get_desc'; +import { useGetInfo } from './hooks/use_get_info'; +import { useGetNodesMap } from './hooks/use_get_tree_node_map'; + +export const CustomPage = () => { + const { url, role } = useGetInfo(); + const [openSetting, setOpenSetting] = useState(false); + const [nodeId, setNodeId] = useState(''); + const { screenIsAtMost } = useResponsive(); + const isMobile = screenIsAtMost(ScreenSize.md); + const { shareId, customPageId, templateId } = useAppSelector((state) => state.pageParams); + const nodesMap = useGetNodesMap(customPageId!); + + const node = nodesMap[customPageId!]; + + useEffect(() => { + if (!node) return; + const _url = node?.extra ? JSON.parse(node?.extra).embedPage.url : ''; + + setOpenSetting(!Boolean(_url)); + }, [node]); + + const canAddUrl = role !== ConfigConstant.Role.Reader; + + useGetDesc(); + + if (!role && !shareId && !templateId) { + return ; + } + + return ( +
+ +
+ {url ? ( +