mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
Merge remote-tracking branch 'origin/main' into develop
# Conflicts: # frontend/appflowy_flutter/lib/plugins/database_view/application/database_view_service.dart # frontend/appflowy_flutter/lib/plugins/document/presentation/plugins/base/link_to_page_widget.dart # frontend/appflowy_flutter/lib/plugins/trash/application/trash_bloc.dart # frontend/appflowy_flutter/lib/plugins/trash/application/trash_service.dart # frontend/appflowy_flutter/lib/workspace/application/app/app_bloc.dart # frontend/appflowy_flutter/lib/workspace/application/app/app_service.dart # frontend/appflowy_flutter/lib/workspace/application/menu/menu_bloc.dart # frontend/appflowy_flutter/lib/workspace/application/workspace/workspace_service.dart # frontend/appflowy_flutter/lib/workspace/presentation/home/menu/app/header/header.dart # frontend/appflowy_flutter/test/bloc_test/grid_test/filter/filter_util.dart # frontend/appflowy_flutter/test/bloc_test/grid_test/grid_bloc_test.dart # frontend/appflowy_flutter/test/bloc_test/grid_test/util.dart # frontend/appflowy_flutter/test/bloc_test/home_test/view_bloc_test.dart # frontend/rust-lib/flowy-database/src/services/database/database_editor.rs # frontend/rust-lib/flowy-database/src/services/persistence/migration/database_view_migration.rs
This commit is contained in:
@ -1,4 +1 @@
|
|||||||
frontend/appflowy_flutter/
|
.git
|
||||||
frontend/scripts/
|
|
||||||
frontend/rust-lib/target
|
|
||||||
shared-lib/target/
|
|
||||||
|
47
.github/workflows/docker_ci.yml
vendored
Normal file
47
.github/workflows/docker_ci.yml
vendored
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
name: Docker-CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- release/*
|
||||||
|
paths:
|
||||||
|
- frontend/**
|
||||||
|
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
- release/*
|
||||||
|
paths:
|
||||||
|
- frontend/**
|
||||||
|
types:
|
||||||
|
- opened
|
||||||
|
- synchronize
|
||||||
|
- reopened
|
||||||
|
- unlocked
|
||||||
|
- ready_for_review
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-app:
|
||||||
|
if: github.event.pull_request.draft != true
|
||||||
|
concurrency:
|
||||||
|
group: docker_ci-${{ github.event.pull_request.number || github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout source code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Build the app
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -eu -o pipefail
|
||||||
|
cd frontend/scripts/docker-buildfiles
|
||||||
|
docker-compose build --no-cache --progress=plain \
|
||||||
|
| while read line; do \
|
||||||
|
if [[ "$line" =~ ^Step[[:space:]] ]]; then \
|
||||||
|
echo "$(date -u '+%H:%M:%S') | $line"; \
|
||||||
|
else \
|
||||||
|
echo "$line"; \
|
||||||
|
fi; \
|
||||||
|
done \
|
3
.github/workflows/flutter_ci.yaml
vendored
3
.github/workflows/flutter_ci.yaml
vendored
@ -99,7 +99,8 @@ jobs:
|
|||||||
|
|
||||||
- name: Flutter Analyzer
|
- name: Flutter Analyzer
|
||||||
working-directory: frontend/appflowy_flutter
|
working-directory: frontend/appflowy_flutter
|
||||||
run: flutter analyze
|
run: |
|
||||||
|
flutter analyze .
|
||||||
|
|
||||||
- name: Run Flutter unit tests
|
- name: Run Flutter unit tests
|
||||||
working-directory: frontend
|
working-directory: frontend
|
||||||
|
11
.github/workflows/integration_test.yml
vendored
11
.github/workflows/integration_test.yml
vendored
@ -22,7 +22,7 @@ jobs:
|
|||||||
tests:
|
tests:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [macos-latest]
|
os: [ubuntu-latest]
|
||||||
|
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
@ -105,11 +105,14 @@ jobs:
|
|||||||
working-directory: frontend/appflowy_flutter
|
working-directory: frontend/appflowy_flutter
|
||||||
run: |
|
run: |
|
||||||
if [ "$RUNNER_OS" == "Linux" ]; then
|
if [ "$RUNNER_OS" == "Linux" ]; then
|
||||||
flutter test integration_test/runner.dart -d Linux --coverage
|
export DISPLAY=:99
|
||||||
|
sudo Xvfb -ac :99 -screen 0 1280x1024x24 > /dev/null 2>&1 &
|
||||||
|
sudo apt-get install network-manager
|
||||||
|
flutter test integration_test/runner.dart -d Linux --coverage --verbose
|
||||||
elif [ "$RUNNER_OS" == "macOS" ]; then
|
elif [ "$RUNNER_OS" == "macOS" ]; then
|
||||||
flutter test integration_test/runner.dart -d macOS --coverage
|
flutter test integration_test/runner.dart -d macOS --coverage --verbose
|
||||||
elif [ "$RUNNER_OS" == "Windows" ]; then
|
elif [ "$RUNNER_OS" == "Windows" ]; then
|
||||||
flutter test integration_test/runner.dart -d Windows --coverage
|
flutter test integration_test/runner.dart -d Windows --coverage --verbose
|
||||||
fi
|
fi
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
|
@ -205,12 +205,17 @@ script = [
|
|||||||
]
|
]
|
||||||
script_runner = "@duckscript"
|
script_runner = "@duckscript"
|
||||||
|
|
||||||
[env.test-macos]
|
[env.test-macos-x86_64]
|
||||||
TEST_CRATE_TYPE = "cdylib"
|
TEST_CRATE_TYPE = "cdylib"
|
||||||
TEST_LIB_EXT = "dylib"
|
TEST_LIB_EXT = "dylib"
|
||||||
# For the moment, the DynamicLibrary only supports open x86_64 architectures binary.
|
# For the moment, the DynamicLibrary only supports open x86_64 architectures binary.
|
||||||
TEST_COMPILE_TARGET = "x86_64-apple-darwin"
|
TEST_COMPILE_TARGET = "x86_64-apple-darwin"
|
||||||
|
|
||||||
|
[env.test-macos-arm64]
|
||||||
|
TEST_CRATE_TYPE = "cdylib"
|
||||||
|
TEST_LIB_EXT = "dylib"
|
||||||
|
TEST_COMPILE_TARGET = "aarch64-apple-darwin"
|
||||||
|
|
||||||
[env.test-linux]
|
[env.test-linux]
|
||||||
TEST_CRATE_TYPE = "cdylib"
|
TEST_CRATE_TYPE = "cdylib"
|
||||||
TEST_LIB_EXT = "so"
|
TEST_LIB_EXT = "so"
|
||||||
|
@ -14,9 +14,7 @@ analyzer:
|
|||||||
exclude:
|
exclude:
|
||||||
- "**/*.g.dart"
|
- "**/*.g.dart"
|
||||||
- "**/*.freezed.dart"
|
- "**/*.freezed.dart"
|
||||||
- "packages/appflowy_editor/**"
|
|
||||||
- "packages/editor/**"
|
|
||||||
# - "packages/flowy_infra_ui/**"
|
|
||||||
linter:
|
linter:
|
||||||
# The lint rules applied to this project can be customized in the
|
# The lint rules applied to this project can be customized in the
|
||||||
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
|
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
|
||||||
@ -30,8 +28,7 @@ linter:
|
|||||||
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
|
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
|
||||||
# producing the lint.
|
# producing the lint.
|
||||||
rules:
|
rules:
|
||||||
# avoid_print: false # Uncomment to disable the `avoid_print` rule
|
- require_trailing_commas
|
||||||
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
|
|
||||||
|
|
||||||
# Additional information about this file can be found at
|
# Additional information about this file can be found at
|
||||||
# https://dart.dev/guides/language/analysis-options
|
# https://dart.dev/guides/language/analysis-options
|
||||||
|
@ -1,112 +1 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 761.68 143.1"><title>Asset 16</title><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path d="M271,40.73h18v6.7c4.37-4.68,12.64-8.42,21.69-8.42C330,39,342.5,54,342.5,74.74c0,21.38-14.67,37.92-37.14,37.92-6.24,0-12.32-1.09-16.38-3.44v32.93H271Zm18,22.78v28.4c4.84,3.12,8.89,4,14.82,4,12.48,0,19.66-9,19.66-20.75,0-11.24-6.55-19.35-18.41-19.35C299,55.86,293.35,58.67,289,63.51Z" style="fill:#fff"/><path d="M226.66,39.4c-22.48,0-37.14,16.54-37.14,37.91,0,20.76,12.47,35.74,31.83,35.74,9,0,17.31-3.75,21.68-8.43v6.72h18V52.42C247.68,42.36,232.89,39.4,226.66,39.4ZM243,88.55c-4.37,4.83-10,7.64-16.07,7.64-11.85,0-18.41-8.11-18.41-19.34,0-11.7,7.18-20.76,19.66-20.76,5.93,0,10,.94,14.82,4.07Z" style="fill:#fff"/><path d="M350.16,40.73h17.95v6.7c4.36-4.68,12.63-8.42,21.68-8.42,19.35,0,31.84,15,31.84,35.73,0,21.38-14.67,37.92-37.14,37.92-6.24,0-12.33-1.09-16.38-3.44v32.93H350.16Zm17.95,22.78v28.4c4.83,3.12,8.89,4,14.82,4,12.48,0,19.66-9,19.66-20.75,0-11.24-6.55-19.35-18.41-19.35C378.09,55.86,372.47,58.67,368.11,63.51Z" style="fill:#fff"/><path d="M473.63,20.6a20.34,20.34,0,0,0-11.08-3.75c-8.11,0-12.32,4.22-12.32,13.89v10h12.64V57.58H450.23v53.36h-18V29.34c0-19.51,9.36-29.34,25-29.34,7.18,0,13.73,1.72,18.41,4.68h15.92V84.26c0,8,2,11.39,6.08,11.39a12.6,12.6,0,0,0,7.49-2.81l3.75,13.73c-4.06,3.28-10.15,5.93-18.57,5.93-10.77,0-16.7-6.55-16.7-20.91Z" style="fill:#fff"/><path d="M547.12,39c23.25,0,38.23,15.76,38.23,36.82s-15,36.83-38.23,36.83S508.9,96.9,508.9,75.83,523.87,39,547.12,39Zm0,57c11.08,0,19.2-8,19.2-20.13,0-11.86-8.27-20-19.2-20-10.61,0-19,7.8-19,20C528.09,87.54,536.2,96,547.12,96Z" style="fill:#fff"/><path d="M674.14,111.25H658.07l-15-39c-1.1-2.65-1.56-5.61-2.34-8.27a50.32,50.32,0,0,1-2.5,8.59l-14.82,38.69h-15.3L585.35,40.73h19.2L615.78,79a73.76,73.76,0,0,1,2,9.37A91.46,91.46,0,0,1,620.46,79l13.11-38.22h15.91L663.06,78.8a98.26,98.26,0,0,1,2.65,9.67c.63-3.28,1.41-6.71,2.18-10.14l10.3-37.6h18.1Z" style="fill:#fff"/><path d="M734.06,110.94c-10.3,25.12-16.85,31.21-27.15,31.21-6.4,0-11.08-2.5-15.14-5.46l5.78-13.58c1.87,1.09,4.52,2.5,7.33,2.5,4.53,0,7.8-3.59,10.77-10.92l1.56-3.75L684.75,40.73h21.54l16.38,38.38c1.4,3.43,2.34,6.71,3.43,10.14A71.08,71.08,0,0,1,728.6,79l12.64-38.22h20.44Z" style="fill:#fff"/><path d="M140.91,87.45c-4,21.87-21.71,41-42.18,51.75-2.57,1.35-3.58,2.12-6.47,2.3h41.49a7,7,0,0,0,7.2-7V87.45Z" style="fill:#f7931e"/><path d="M95.68,140.24a15.15,15.15,0,0,1-2.52,0Z" style="fill:#ffce00"/><path d="M54.36,45.23c-.63.51-1.25,1-1.89,1.44C42,54.06,9.9,78,2.65,67.71-4.46,57.58,3,28.86,21.49,15c.35-.28.71-.53,1.06-.78,20-14.09,35-12.13,42.28-1.81C71.63,22.13,64,37.31,54.36,45.23Z" style="fill:#8427e0"/><path d="M132.72,67.41c-9.91,7-25.55-1.17-33.32-11.14-.31-.4-.61-.81-.91-1.22-7.38-10.51-31.34-42.57-21-49.82s39.94.67,53.45,19.9c.3.43.59.85.87,1.27C144.91,45.8,142.81,60.31,132.72,67.41Z" style="fill:#00b5ff"/><path d="M119.45,130.66c-.34.26-.69.52-1,.76-20,14.09-35,12.12-42.28,1.82-6.79-9.68.8-24.85,10.46-32.78.62-.52,1.26-1,1.9-1.45C99,91.62,131.06,67.67,138.31,78,145.42,88.1,137.93,116.83,119.45,130.66Z" style="fill:#ffbd00"/><path d="M63.51,140.45c-10.32,7.24-39.94-.67-53.45-19.91-.28-.38-.54-.77-.8-1.16a0,0,0,0,0,0,0c-13.19-19.44-11.1-34-1-41.08,9.9-7,25.55,1.15,33.31,11.12.31.4.62.82.91,1.23C49.86,101.14,73.82,133.2,63.51,140.45Z" style="fill:#e3006d"/><path d="M54.36,45.23C40,51.53,9.65,64.64,5.08,54.12,1.25,45.3,8.34,27.25,21.49,15c.35-.28.71-.53,1.06-.78,20-14.09,35-12.13,42.28-1.81C71.63,22.13,64,37.31,54.36,45.23Z" style="fill:#9327ff"/><path d="M132.72,67.41c-9.91,7-25.55-1.17-33.32-11.14C93,41.57,80.68,12.49,91,8c9.26-4,28.65,4,40.83,18.37C144.91,45.8,142.81,60.31,132.72,67.41Z" style="fill:#00c8ff"/><path d="M119.45,130.66c-.34.26-.69.52-1,.76-20,14.09-35,12.12-42.28,1.82-6.79-9.68.8-24.85,10.46-32.78,14.32-6.3,44.72-19.42,49.29-8.91C139.71,100.38,132.62,118.44,119.45,130.66Z" style="fill:#ffce00"/><path d="M50,137.65c-9.23,4-28.57-3.94-40.75-18.27a0,0,0,0,0,0,0c-13.19-19.44-11.1-34-1-41.08,9.9-7,25.55,1.15,33.31,11.12C48,104.11,60.28,133.2,50,137.65Z" style="fill:#fb006d"/></g></g></svg>
|
||||||
<svg
|
|
||||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
|
||||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
|
||||||
xmlns:svg="http://www.w3.org/2000/svg"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
id="svg873"
|
|
||||||
version="1.1"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 92 17"
|
|
||||||
height="17"
|
|
||||||
width="92">
|
|
||||||
<metadata
|
|
||||||
id="metadata877">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
<dc:title></dc:title>
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<g
|
|
||||||
id="g866"
|
|
||||||
clip-path="url(#clip0)">
|
|
||||||
<path
|
|
||||||
style="fill:#ffffff"
|
|
||||||
id="path834"
|
|
||||||
fill="black"
|
|
||||||
d="M32.7324 4.84144H34.892V5.63601C35.4179 5.08166 36.4132 4.63818 37.5212 4.63818C39.8498 4.63818 41.3709 6.4121 41.3709 8.88818C41.3709 11.4197 39.6057 13.3969 36.8827 13.3969C36.1315 13.3969 35.3991 13.2675 34.9108 12.9904V16.9078H32.7512V4.84144H32.7324ZM34.9108 7.53927V10.9208C35.493 11.2904 35.9812 11.4012 36.6949 11.4012C38.1972 11.4012 39.0611 10.3295 39.0611 8.94362C39.0611 7.61318 38.2723 6.65231 36.8451 6.65231C36.1127 6.63384 35.4366 6.96644 34.9108 7.53927Z" />
|
|
||||||
<path
|
|
||||||
style="fill:#ffffff"
|
|
||||||
id="path836"
|
|
||||||
fill="black"
|
|
||||||
d="M27.3804 4.6748C24.6573 4.6748 22.8921 6.6335 22.8921 9.1835C22.8921 11.6596 24.3944 13.4335 26.7419 13.4335C27.8311 13.4335 28.8264 12.99 29.371 12.4357V13.2302H31.5306V6.22698C29.9156 5.02589 28.1315 4.6748 27.3804 4.6748ZM29.3522 10.5324C28.8264 11.1052 28.1503 11.4378 27.4179 11.4378C25.9907 11.4378 25.2019 10.477 25.2019 9.14654C25.2019 7.76067 26.0658 6.67046 27.5681 6.67046C28.2818 6.67046 28.77 6.78133 29.3522 7.15089V10.5324Z" />
|
|
||||||
<path
|
|
||||||
style="fill:#ffffff"
|
|
||||||
id="path838"
|
|
||||||
fill="black"
|
|
||||||
d="M42.291 4.84144H44.4506V5.63601C44.9765 5.08166 45.9718 4.63818 47.0797 4.63818C49.4084 4.63818 50.9295 6.4121 50.9295 8.88818C50.9295 11.4197 49.1642 13.3969 46.4412 13.3969C45.6901 13.3969 44.9577 13.2675 44.4694 12.9904V16.9078H42.3098V4.84144H42.291ZM44.4694 7.53927V10.9208C45.0516 11.2904 45.5398 11.4012 46.2535 11.4012C47.7558 11.4012 48.6196 10.3295 48.6196 8.94362C48.6196 7.61318 47.8309 6.65231 46.4037 6.65231C45.6713 6.63384 44.9952 6.96644 44.4694 7.53927Z" />
|
|
||||||
<path
|
|
||||||
style="fill:#ffffff"
|
|
||||||
id="path840"
|
|
||||||
fill="black"
|
|
||||||
d="M57.2019 2.43913C56.8826 2.21739 56.3756 1.99565 55.8685 1.99565C54.892 1.99565 54.3849 2.49457 54.3849 3.64022V4.82283H55.9061V6.83696H54.3849V13.175H52.2065V3.49239C52.2065 1.18261 53.3333 0 55.23 0C56.0939 0 56.8826 0.203261 57.446 0.554348H59.3615V10.0152C59.3615 10.9576 59.6056 11.3641 60.0939 11.3641C60.4507 11.3641 60.7324 11.2163 60.9953 11.0315L61.446 12.6576C60.9577 13.0457 60.2253 13.3598 59.2112 13.3598C57.9155 13.3598 57.2019 12.5837 57.2019 10.8837V2.43913Z" />
|
|
||||||
<path
|
|
||||||
style="fill:#ffffff"
|
|
||||||
id="path842"
|
|
||||||
fill="black"
|
|
||||||
d="M66.0846 4.63818C68.9015 4.63818 70.7043 6.50449 70.7043 9.01753C70.7043 11.5121 68.9015 13.3969 66.0846 13.3969C63.2677 13.3969 61.4648 11.5306 61.4648 9.01753C61.4648 6.50449 63.2864 4.63818 66.0846 4.63818ZM66.0846 11.4012C67.4179 11.4012 68.3944 10.4588 68.3944 9.01753C68.3944 7.61318 67.3991 6.65231 66.0846 6.65231C64.8076 6.65231 63.7935 7.57623 63.7935 9.01753C63.7935 10.4034 64.77 11.4012 66.0846 11.4012Z" />
|
|
||||||
<path
|
|
||||||
style="fill:#ffffff"
|
|
||||||
id="path844"
|
|
||||||
fill="black"
|
|
||||||
d="M81.4271 13.2307H79.4928L77.69 8.59264C77.5586 8.27851 77.5022 7.92742 77.4083 7.61329C77.3332 7.98286 77.2393 8.29699 77.1079 8.6296L75.305 13.2307H73.4647L70.7041 4.84155H73.014L74.3661 9.38721C74.4975 9.79373 74.5351 10.1079 74.6102 10.4959C74.7041 10.1448 74.7604 9.84916 74.9295 9.38721L76.5069 4.84155H78.4224L80.0562 9.36873C80.1877 9.73829 80.2816 10.1263 80.3755 10.5144C80.4506 10.1263 80.5445 9.71981 80.6384 9.31329L81.8778 4.84155H84.0562L81.4271 13.2307Z" />
|
|
||||||
<path
|
|
||||||
style="fill:#ffffff"
|
|
||||||
id="path846"
|
|
||||||
fill="black"
|
|
||||||
d="M88.6574 13.1936C87.4179 16.187 86.6292 16.9077 85.371 16.9077C84.601 16.9077 84.0377 16.612 83.5494 16.2609L84.2442 14.6533C84.4696 14.7827 84.7888 14.949 85.1269 14.949C85.6715 14.949 86.0658 14.524 86.4226 13.6555L86.6104 13.212L82.6855 4.85986H85.2959L87.2677 9.42399C87.4367 9.83052 87.5494 10.2186 87.6808 10.6251C87.756 10.237 87.8311 9.83052 87.9813 9.40552L89.5024 4.85986H91.9625L88.6574 13.1936Z" />
|
|
||||||
<path
|
|
||||||
id="path848"
|
|
||||||
fill="#F7931E"
|
|
||||||
d="M17.0142 10.4033C16.5259 13.0088 14.3851 15.2816 11.925 16.5566C11.6245 16.7229 11.2677 16.8153 10.9297 16.8338H16.1503C16.6574 16.8338 17.0142 16.4642 17.0142 16.0022V10.4033Z" />
|
|
||||||
<path
|
|
||||||
id="path850"
|
|
||||||
fill="#8427E0"
|
|
||||||
d="M6.57258 5.37743C6.49746 5.43286 6.42235 5.4883 6.34723 5.54373C5.07023 6.43069 1.20169 9.27634 0.319059 8.0383C-0.544791 6.83721 0.375397 3.43721 2.59136 1.79264C2.62892 1.75569 2.68526 1.73721 2.72281 1.70025C5.14535 0.0187313 6.94817 0.258949 7.8308 1.47851C8.65709 2.62417 7.7369 4.43504 6.57258 5.37743Z" />
|
|
||||||
<path
|
|
||||||
id="path852"
|
|
||||||
fill="#00B5FF"
|
|
||||||
d="M16.0373 8.02043C14.8354 8.85195 12.9575 7.89108 12.0185 6.69C11.981 6.63456 11.9434 6.59761 11.9059 6.54217C11.0045 5.28565 8.11244 1.47913 9.35188 0.629126C10.5913 -0.239352 14.1782 0.703039 15.812 2.99434C15.8495 3.04978 15.8871 3.08674 15.9246 3.14217C17.5021 5.45195 17.258 7.17043 16.0373 8.02043Z" />
|
|
||||||
<path
|
|
||||||
id="path854"
|
|
||||||
fill="#FFBD00"
|
|
||||||
d="M14.4226 15.5219C14.385 15.5589 14.3475 15.5773 14.2911 15.6143C11.8686 17.2958 10.0658 17.0556 9.18315 15.836C8.35686 14.6904 9.27705 12.8795 10.4414 11.9371C10.5165 11.8817 10.5916 11.8263 10.6667 11.7708C11.9437 10.9023 15.8123 8.03821 16.6761 9.27625C17.5587 10.4773 16.6573 13.8773 14.4226 15.5219Z" />
|
|
||||||
<path
|
|
||||||
id="path856"
|
|
||||||
fill="#E3006D"
|
|
||||||
d="M7.66182 16.6859C6.42238 17.5544 2.85431 16.612 1.22051 14.3207C1.18295 14.2838 1.14539 14.2283 1.12661 14.1914C-0.469635 11.8816 -0.206725 10.1446 1.01393 9.31311C2.21581 8.48159 4.09374 9.44246 5.03271 10.6435C5.07027 10.699 5.10783 10.7359 5.14539 10.7914C6.02802 12.0294 8.92004 15.8359 7.66182 16.6859Z" />
|
|
||||||
<path
|
|
||||||
id="path858"
|
|
||||||
fill="#9327FF"
|
|
||||||
d="M6.57283 5.37743C4.84513 6.13504 1.16438 7.68721 0.619779 6.43069C0.150295 5.37743 1.01415 3.23395 2.59161 1.79264C2.62917 1.75569 2.68551 1.73721 2.72307 1.70025C5.1456 0.0187312 6.94842 0.258949 7.83105 1.47851C8.65734 2.62417 7.73715 4.43504 6.57283 5.37743Z" />
|
|
||||||
<path
|
|
||||||
id="path860"
|
|
||||||
fill="#00C8FF"
|
|
||||||
d="M16.0374 8.01967C14.8355 8.8512 12.9576 7.89033 12.0186 6.68924C11.2487 4.9338 9.76511 1.47837 11.0045 0.960978C12.1313 0.480543 14.4599 1.44141 15.9435 3.14141C17.5022 5.4512 17.2581 7.16967 16.0374 8.01967Z" />
|
|
||||||
<path
|
|
||||||
id="path862"
|
|
||||||
fill="#FFCE00"
|
|
||||||
d="M14.4226 15.5217C14.385 15.5586 14.3475 15.5771 14.2911 15.6141C11.8686 17.2956 10.0658 17.0554 9.18315 15.8358C8.35686 14.6901 9.27705 12.8793 10.4414 11.9369C12.1691 11.1793 15.8498 9.6271 16.3944 10.8836C16.8827 11.9369 16.0188 14.0804 14.4226 15.5217Z" />
|
|
||||||
<path
|
|
||||||
id="path864"
|
|
||||||
fill="#FB006D"
|
|
||||||
d="M6.0468 16.3533C4.92004 16.8338 2.5914 15.8914 1.12661 14.1914C-0.469635 11.8816 -0.206725 10.1446 1.01393 9.31311C2.21581 8.48159 4.09374 9.44246 5.03271 10.6435C5.80266 12.3805 7.28623 15.8359 6.0468 16.3533Z" />
|
|
||||||
</g>
|
|
||||||
<defs
|
|
||||||
id="defs871">
|
|
||||||
<clipPath
|
|
||||||
id="clip0">
|
|
||||||
<rect
|
|
||||||
id="rect868"
|
|
||||||
fill="white"
|
|
||||||
height="17"
|
|
||||||
width="92" />
|
|
||||||
</clipPath>
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 4.1 KiB |
@ -1,150 +1,159 @@
|
|||||||
{
|
{
|
||||||
"appName": "AppFlowy",
|
"appName": "AppFlowy",
|
||||||
"defaultUsername": "Ich",
|
"defaultUsername": "Ich",
|
||||||
"welcomeText": "Willkommen bei @:appName",
|
"welcomeText": "Willkommen bei @:appName",
|
||||||
"githubStarText": "GitHub Star vergeben",
|
"githubStarText": "GitHub Star vergeben",
|
||||||
"subscribeNewsletterText": "Abonniere den Newsletter",
|
"subscribeNewsletterText": "Abonniere den Newsletter",
|
||||||
"letsGoButtonText": "Los geht's",
|
"letsGoButtonText": "Los geht's",
|
||||||
"title": "Titel",
|
"title": "Titel",
|
||||||
"signUp": {
|
"signUp": {
|
||||||
"buttonText": "Registrieren",
|
"buttonText": "Registrieren",
|
||||||
"title": "Registriere dich bei @:appName",
|
"title": "Registriere dich bei @:appName",
|
||||||
"getStartedText": "Erste Schritte",
|
"getStartedText": "Erste Schritte",
|
||||||
"emptyPasswordError": "Passwort darf nicht leer sein",
|
"emptyPasswordError": "Passwort darf nicht leer sein",
|
||||||
"repeatPasswordEmptyError": "Passwortwiederholung darf nicht leer sein",
|
"repeatPasswordEmptyError": "Passwortwiederholung darf nicht leer sein",
|
||||||
"unmatchedPasswordError": "Passwörter stimmen nicht überein",
|
"unmatchedPasswordError": "Passwörter stimmen nicht überein",
|
||||||
"alreadyHaveAnAccount": "Bereits registriert?",
|
"alreadyHaveAnAccount": "Bereits registriert?",
|
||||||
"emailHint": "E-Mail",
|
"emailHint": "E-Mail",
|
||||||
"passwordHint": "Passwort",
|
"passwordHint": "Passwort",
|
||||||
"repeatPasswordHint": "Wiederhole Passwort"
|
"repeatPasswordHint": "Wiederhole Passwort"
|
||||||
},
|
},
|
||||||
"signIn": {
|
"signIn": {
|
||||||
"loginTitle": "Bei @:appName einloggen",
|
"loginTitle": "Bei @:appName einloggen",
|
||||||
"loginButtonText": "Anmelden",
|
"loginButtonText": "Anmelden",
|
||||||
"buttonText": "Anmelden",
|
"buttonText": "Anmelden",
|
||||||
"forgotPassword": "Passwort vergessen?",
|
"forgotPassword": "Passwort vergessen?",
|
||||||
"emailHint": "E-Mail",
|
"emailHint": "E-Mail",
|
||||||
"passwordHint": "Passwort",
|
"passwordHint": "Passwort",
|
||||||
"dontHaveAnAccount": "Du besitzt noch kein Konto?",
|
"dontHaveAnAccount": "Du besitzt noch kein Konto?",
|
||||||
"repeatPasswordEmptyError": "Passwortwiederholung darf nicht leer sein",
|
"repeatPasswordEmptyError": "Passwortwiederholung darf nicht leer sein",
|
||||||
"unmatchedPasswordError": "Passwörter stimmen nicht überein"
|
"unmatchedPasswordError": "Passwörter stimmen nicht überein"
|
||||||
},
|
},
|
||||||
"workspace": {
|
"workspace": {
|
||||||
"create": "Arbeitsbereich erstellen",
|
"create": "Arbeitsbereich erstellen",
|
||||||
"hint": "Arbeitsbereich",
|
"hint": "Arbeitsbereich",
|
||||||
"notFoundError": "Arbeitsbereich nicht gefunden"
|
"notFoundError": "Arbeitsbereich nicht gefunden"
|
||||||
},
|
},
|
||||||
"shareAction": {
|
"shareAction": {
|
||||||
"buttonText": "Teilen",
|
"buttonText": "Teilen",
|
||||||
"workInProgress": "Demnächst verfügbar",
|
"workInProgress": "Demnächst verfügbar",
|
||||||
"markdown": "Markdown",
|
"markdown": "Markdown",
|
||||||
"copyLink": "Link kopieren"
|
"copyLink": "Link kopieren"
|
||||||
},
|
},
|
||||||
"disclosureAction": {
|
"disclosureAction": {
|
||||||
"rename": "Umbenennen",
|
"rename": "Umbenennen",
|
||||||
"delete": "Löschen",
|
"delete": "Löschen",
|
||||||
"duplicate": "Duplizieren"
|
"duplicate": "Duplizieren"
|
||||||
},
|
},
|
||||||
"blankPageTitle": "Leere Seite",
|
"blankPageTitle": "Leere Seite",
|
||||||
"newPageText": "Neue Seite",
|
"newPageText": "Neue Seite",
|
||||||
"trash": {
|
"trash": {
|
||||||
"text": "Papierkorb",
|
"text": "Papierkorb",
|
||||||
"restoreAll": "Alles wiederherstellen",
|
"restoreAll": "Alles wiederherstellen",
|
||||||
"deleteAll": "Alles löschen",
|
"deleteAll": "Alles löschen",
|
||||||
"pageHeader": {
|
"pageHeader": {
|
||||||
"fileName": "Dateiname",
|
"fileName": "Dateiname",
|
||||||
"lastModified": "Letzte Änderung",
|
"lastModified": "Letzte Änderung",
|
||||||
"created": "Erstellt"
|
"created": "Erstellt"
|
||||||
}
|
|
||||||
},
|
|
||||||
"deletePagePrompt": {
|
|
||||||
"text": "Diese Seite ist im Papierkorb",
|
|
||||||
"restore": "Seite wiederherstellen",
|
|
||||||
"deletePermanent": "Dauerhaft löschen"
|
|
||||||
},
|
|
||||||
"dialogCreatePageNameHint": "Seitenname",
|
|
||||||
"questionBubble": {
|
|
||||||
"whatsNew": "Was gibt es Neues?",
|
|
||||||
"help": "Hilfe & Support",
|
|
||||||
"debug": {
|
|
||||||
"name": "Debug-Informationen",
|
|
||||||
"success": "Debug-Informationen in die Zwischenablage kopiert!",
|
|
||||||
"fail": "Debug-Informationen können nicht in die Zwischenablage kopiert werden"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"menuAppHeader": {
|
|
||||||
"addPageTooltip": "Schnell eine Seite innerhalb hinzufügen",
|
|
||||||
"defaultNewPageName": "Unbenannt",
|
|
||||||
"renameDialog": "Umbenennen"
|
|
||||||
},
|
|
||||||
"toolbar": {
|
|
||||||
"undo": "Rückgängig",
|
|
||||||
"redo": "Wiederherstellen",
|
|
||||||
"bold": "Fett",
|
|
||||||
"italic": "Kursiv",
|
|
||||||
"underline": "Unterstreichen",
|
|
||||||
"strike": "Durchstreichen",
|
|
||||||
"numList": "Nummerierte Liste",
|
|
||||||
"bulletList": "Aufzählung",
|
|
||||||
"checkList": "Checkliste",
|
|
||||||
"inlineCode": "Inline-Code",
|
|
||||||
"quote": "Zitat",
|
|
||||||
"header": "Überschrift",
|
|
||||||
"highlight": "Hervorhebung"
|
|
||||||
},
|
|
||||||
"tooltip": {
|
|
||||||
"lightMode": "In den hellen Modus wechseln",
|
|
||||||
"darkMode": "In den dunklen Modus wechseln"
|
|
||||||
},
|
|
||||||
"contactsPage": {
|
|
||||||
"title": "Kontakte",
|
|
||||||
"whatsHappening": "Was geschieht diese Woche?",
|
|
||||||
"addContact": "Kontakt hinzufügen",
|
|
||||||
"editContact": "Kontakt bearbeiten"
|
|
||||||
},
|
|
||||||
"button": {
|
|
||||||
"OK": "OK",
|
|
||||||
"Cancel": "Abbrechen",
|
|
||||||
"signIn": "Anmelden",
|
|
||||||
"signOut": "Abmelden",
|
|
||||||
"complete": "Fertig",
|
|
||||||
"save": "Speichern"
|
|
||||||
},
|
|
||||||
"label": {
|
|
||||||
"welcome": "Willkommen!",
|
|
||||||
"firstName": "Vorname",
|
|
||||||
"middleName": "Zweiter Vorname",
|
|
||||||
"lastName": "Nachname",
|
|
||||||
"stepX": "Schritt {X}"
|
|
||||||
},
|
|
||||||
"oAuth": {
|
|
||||||
"err": {
|
|
||||||
"failedTitle": "Keine Verbindung zu Ihrem Konto möglich.",
|
|
||||||
"failedMsg": "Bitte vergewissern Sie sich, dass Sie den Anmeldevorgang in Ihrem Browser abgeschlossen haben."
|
|
||||||
},
|
|
||||||
"google": {
|
|
||||||
"title": "GOOGLE ANMELDUNG",
|
|
||||||
"instruction1": "Um Ihre Google-Kontakte zu importieren, müssen Sie diese Anwendung über Ihren Webbrowser autorisieren.",
|
|
||||||
"instruction2": "Kopieren Sie diesen Code in Ihre Zwischenablage, indem Sie auf das Symbol klicken oder den Text auswählen:",
|
|
||||||
"instruction3": "Rufen Sie den folgenden Link in Ihrem Webbrowser auf, und geben Sie den obigen Code ein:",
|
|
||||||
"instruction4": "Klicken Sie unten auf die Schaltfläche, wenn Sie die Anmeldung abgeschlossen haben:"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"settings": {
|
|
||||||
"title": "Einstellungen",
|
|
||||||
"menu": {
|
|
||||||
"appearance": "Aussehen",
|
|
||||||
"language": "Sprache",
|
|
||||||
"open": "Einstellungen öffnen"
|
|
||||||
},
|
|
||||||
"appearance": {
|
|
||||||
"lightLabel": "Heller Modus",
|
|
||||||
"darkLabel": "Dunkler Modus"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"sideBar": {
|
|
||||||
"openSidebar": "Open sidebar",
|
|
||||||
"closeSidebar": "Close sidebar"
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"deletePagePrompt": {
|
||||||
|
"text": "Diese Seite ist im Papierkorb",
|
||||||
|
"restore": "Seite wiederherstellen",
|
||||||
|
"deletePermanent": "Dauerhaft löschen"
|
||||||
|
},
|
||||||
|
"dialogCreatePageNameHint": "Seitenname",
|
||||||
|
"questionBubble": {
|
||||||
|
"whatsNew": "Was gibt es Neues?",
|
||||||
|
"help": "Hilfe & Support",
|
||||||
|
"debug": {
|
||||||
|
"name": "Debug-Informationen",
|
||||||
|
"success": "Debug-Informationen in die Zwischenablage kopiert!",
|
||||||
|
"fail": "Debug-Informationen können nicht in die Zwischenablage kopiert werden"
|
||||||
|
},
|
||||||
|
"shortcuts": "Abkürzungen"
|
||||||
|
},
|
||||||
|
"menuAppHeader": {
|
||||||
|
"addPageTooltip": "Schnell eine Seite innerhalb hinzufügen",
|
||||||
|
"defaultNewPageName": "Unbenannt",
|
||||||
|
"renameDialog": "Umbenennen"
|
||||||
|
},
|
||||||
|
"toolbar": {
|
||||||
|
"undo": "Rückgängig",
|
||||||
|
"redo": "Wiederherstellen",
|
||||||
|
"bold": "Fett",
|
||||||
|
"italic": "Kursiv",
|
||||||
|
"underline": "Unterstreichen",
|
||||||
|
"strike": "Durchstreichen",
|
||||||
|
"numList": "Nummerierte Liste",
|
||||||
|
"bulletList": "Aufzählung",
|
||||||
|
"checkList": "Checkliste",
|
||||||
|
"inlineCode": "Inline-Code",
|
||||||
|
"quote": "Zitat",
|
||||||
|
"header": "Überschrift",
|
||||||
|
"highlight": "Hervorhebung",
|
||||||
|
"color": "Farbe"
|
||||||
|
},
|
||||||
|
"tooltip": {
|
||||||
|
"lightMode": "In den hellen Modus wechseln",
|
||||||
|
"darkMode": "In den dunklen Modus wechseln",
|
||||||
|
"openAsPage": "Als Seite öffnen"
|
||||||
|
},
|
||||||
|
"contactsPage": {
|
||||||
|
"title": "Kontakte",
|
||||||
|
"whatsHappening": "Was geschieht diese Woche?",
|
||||||
|
"addContact": "Kontakt hinzufügen",
|
||||||
|
"editContact": "Kontakt bearbeiten"
|
||||||
|
},
|
||||||
|
"button": {
|
||||||
|
"OK": "OK",
|
||||||
|
"Cancel": "Abbrechen",
|
||||||
|
"signIn": "Anmelden",
|
||||||
|
"signOut": "Abmelden",
|
||||||
|
"complete": "Fertig",
|
||||||
|
"save": "Speichern"
|
||||||
|
},
|
||||||
|
"label": {
|
||||||
|
"welcome": "Willkommen!",
|
||||||
|
"firstName": "Vorname",
|
||||||
|
"middleName": "Zweiter Vorname",
|
||||||
|
"lastName": "Nachname",
|
||||||
|
"stepX": "Schritt {X}"
|
||||||
|
},
|
||||||
|
"oAuth": {
|
||||||
|
"err": {
|
||||||
|
"failedTitle": "Keine Verbindung zu Ihrem Konto möglich.",
|
||||||
|
"failedMsg": "Bitte vergewissern Sie sich, dass Sie den Anmeldevorgang in Ihrem Browser abgeschlossen haben."
|
||||||
|
},
|
||||||
|
"google": {
|
||||||
|
"title": "GOOGLE ANMELDUNG",
|
||||||
|
"instruction1": "Um Ihre Google-Kontakte zu importieren, müssen Sie diese Anwendung über Ihren Webbrowser autorisieren.",
|
||||||
|
"instruction2": "Kopieren Sie diesen Code in Ihre Zwischenablage, indem Sie auf das Symbol klicken oder den Text auswählen:",
|
||||||
|
"instruction3": "Rufen Sie den folgenden Link in Ihrem Webbrowser auf, und geben Sie den obigen Code ein:",
|
||||||
|
"instruction4": "Klicken Sie unten auf die Schaltfläche, wenn Sie die Anmeldung abgeschlossen haben:"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"title": "Einstellungen",
|
||||||
|
"menu": {
|
||||||
|
"appearance": "Aussehen",
|
||||||
|
"language": "Sprache",
|
||||||
|
"open": "Einstellungen öffnen"
|
||||||
|
},
|
||||||
|
"appearance": {
|
||||||
|
"lightLabel": "Heller Modus",
|
||||||
|
"darkLabel": "Dunkler Modus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sideBar": {
|
||||||
|
"openSidebar": "Open sidebar",
|
||||||
|
"closeSidebar": "Close sidebar"
|
||||||
|
},
|
||||||
|
"moreAction": {
|
||||||
|
"small": "klein",
|
||||||
|
"medium": "mittel",
|
||||||
|
"large": "groß",
|
||||||
|
"fontSize": "Schriftgröße",
|
||||||
|
"import": "Importieren"
|
||||||
}
|
}
|
||||||
|
}
|
@ -282,6 +282,7 @@
|
|||||||
"dateFormatISO": "Year-Month-Day",
|
"dateFormatISO": "Year-Month-Day",
|
||||||
"dateFormatLocal": "Month/Day/Year",
|
"dateFormatLocal": "Month/Day/Year",
|
||||||
"dateFormatUS": "Year/Month/Day",
|
"dateFormatUS": "Year/Month/Day",
|
||||||
|
"dateFormatDayMonthYear": "Day/Month/Year",
|
||||||
"timeFormat": "Time format",
|
"timeFormat": "Time format",
|
||||||
"invalidTimeFormat": "Invalid format",
|
"invalidTimeFormat": "Invalid format",
|
||||||
"timeFormatTwelveHour": "12 hour",
|
"timeFormatTwelveHour": "12 hour",
|
||||||
@ -290,7 +291,7 @@
|
|||||||
"optionTitle": "Options",
|
"optionTitle": "Options",
|
||||||
"addOption": "Add option",
|
"addOption": "Add option",
|
||||||
"editProperty": "Edit property",
|
"editProperty": "Edit property",
|
||||||
"newColumn": "New column",
|
"newProperty": "New property",
|
||||||
"deleteFieldPromptMessage": "Are you sure? This property will be deleted"
|
"deleteFieldPromptMessage": "Are you sure? This property will be deleted"
|
||||||
},
|
},
|
||||||
"sort": {
|
"sort": {
|
||||||
@ -383,7 +384,9 @@
|
|||||||
"pickFromFiles": "Pick from files",
|
"pickFromFiles": "Pick from files",
|
||||||
"couldNotFetchImage": "Could not fetch image",
|
"couldNotFetchImage": "Could not fetch image",
|
||||||
"imageSavingFailed": "Image Saving Failed",
|
"imageSavingFailed": "Image Saving Failed",
|
||||||
"addIcon": "Add Icon"
|
"addIcon": "Add Icon",
|
||||||
|
"coverRemoveAlert": "It will be removed from cover after it is deleted.",
|
||||||
|
"alertDialogConfirmation": "Are you sure, you want to continue?"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -271,7 +271,7 @@
|
|||||||
"optionTitle": "Aukerak",
|
"optionTitle": "Aukerak",
|
||||||
"addOption": "Gehitu aukera",
|
"addOption": "Gehitu aukera",
|
||||||
"editProperty": "Editatu propietatea",
|
"editProperty": "Editatu propietatea",
|
||||||
"newColumn": "Zutabe berria",
|
"newProperty": "Zutabe berria",
|
||||||
"deleteFieldPromptMessage": "Ziur al zaude? Propietate hau ezabatu egingo da"
|
"deleteFieldPromptMessage": "Ziur al zaude? Propietate hau ezabatu egingo da"
|
||||||
},
|
},
|
||||||
"sort": {
|
"sort": {
|
||||||
|
@ -195,7 +195,7 @@
|
|||||||
"optionTitle": "Options",
|
"optionTitle": "Options",
|
||||||
"addOption": "Ajouter une option",
|
"addOption": "Ajouter une option",
|
||||||
"editProperty": "Modifier la propriété",
|
"editProperty": "Modifier la propriété",
|
||||||
"newColumn": "Nouvelle colonne",
|
"newProperty": "Nouvelle colonne",
|
||||||
"deleteFieldPromptMessage": "Vous voulez supprimer cette propriété ?"
|
"deleteFieldPromptMessage": "Vous voulez supprimer cette propriété ?"
|
||||||
},
|
},
|
||||||
"row": {
|
"row": {
|
||||||
|
@ -191,7 +191,7 @@
|
|||||||
"optionTitle": "옵션",
|
"optionTitle": "옵션",
|
||||||
"addOption": "옵션 추가",
|
"addOption": "옵션 추가",
|
||||||
"editProperty": "속성 편집",
|
"editProperty": "속성 편집",
|
||||||
"newColumn": "열 추가",
|
"newProperty": "열 추가",
|
||||||
"deleteFieldPromptMessage": "해당 속성을 삭제 하시겠습니까?"
|
"deleteFieldPromptMessage": "해당 속성을 삭제 하시겠습니까?"
|
||||||
},
|
},
|
||||||
"row": {
|
"row": {
|
||||||
|
@ -39,7 +39,7 @@
|
|||||||
"workInProgress": "Em breve",
|
"workInProgress": "Em breve",
|
||||||
"markdown": "Marcador",
|
"markdown": "Marcador",
|
||||||
"copyLink": "Copiar link"
|
"copyLink": "Copiar link"
|
||||||
},
|
},
|
||||||
"moreAction": {
|
"moreAction": {
|
||||||
"small": "pequeno",
|
"small": "pequeno",
|
||||||
"medium": "médio",
|
"medium": "médio",
|
||||||
@ -177,7 +177,7 @@
|
|||||||
"system": "Adaptar-se ao sistema"
|
"system": "Adaptar-se ao sistema"
|
||||||
},
|
},
|
||||||
"theme": "Tema"
|
"theme": "Tema"
|
||||||
},
|
},
|
||||||
"files": {
|
"files": {
|
||||||
"defaultLocation": "Onde os seus dados ficam armazenados",
|
"defaultLocation": "Onde os seus dados ficam armazenados",
|
||||||
"doubleTapToCopy": "Clique duas vezes para copiar o caminho",
|
"doubleTapToCopy": "Clique duas vezes para copiar o caminho",
|
||||||
@ -287,7 +287,7 @@
|
|||||||
"optionTitle": "Opções",
|
"optionTitle": "Opções",
|
||||||
"addOption": "Adicioar opção",
|
"addOption": "Adicioar opção",
|
||||||
"editProperty": "Editar propriedade",
|
"editProperty": "Editar propriedade",
|
||||||
"newColumn": "Nova coluna",
|
"newProperty": "Nova coluna",
|
||||||
"deleteFieldPromptMessage": "Tem certeza? Esta propriedade será excluída"
|
"deleteFieldPromptMessage": "Tem certeza? Esta propriedade será excluída"
|
||||||
},
|
},
|
||||||
"sort": {
|
"sort": {
|
||||||
@ -320,7 +320,7 @@
|
|||||||
"pannelTitle": "Escolha uma opção ou crie uma",
|
"pannelTitle": "Escolha uma opção ou crie uma",
|
||||||
"searchOption": "Procurar uma opção"
|
"searchOption": "Procurar uma opção"
|
||||||
},
|
},
|
||||||
"checklist": {
|
"checklist": {
|
||||||
"panelTitle": "Adicionar um item"
|
"panelTitle": "Adicionar um item"
|
||||||
},
|
},
|
||||||
"menuName": "Grade"
|
"menuName": "Grade"
|
||||||
|
@ -1,150 +1,149 @@
|
|||||||
{
|
{
|
||||||
"appName": "AppFlowy",
|
"appName": "AppFlowy",
|
||||||
"defaultUsername": "Me",
|
"defaultUsername": "Me",
|
||||||
"welcomeText": "Bem vindo ao @:appName",
|
"welcomeText": "Bem vindo ao @:appName",
|
||||||
"githubStarText": "Star on GitHub",
|
"githubStarText": "Star on GitHub",
|
||||||
"subscribeNewsletterText": "Inscreve-te ao Newsletter",
|
"subscribeNewsletterText": "Inscreve-te ao Newsletter",
|
||||||
"letsGoButtonText": "Bora",
|
"letsGoButtonText": "Bora",
|
||||||
"title": "Título",
|
"title": "Título",
|
||||||
"signUp": {
|
"signUp": {
|
||||||
"buttonText": "Inscreve-te",
|
"buttonText": "Inscreve-te",
|
||||||
"title": "Inscreve-te ao @:appName",
|
"title": "Inscreve-te ao @:appName",
|
||||||
"getStartedText": "Começar",
|
"getStartedText": "Começar",
|
||||||
"emptyPasswordError": "A palavra-passe não pode estar em branco.",
|
"emptyPasswordError": "A palavra-passe não pode estar em branco.",
|
||||||
"repeatPasswordEmptyError": "Confirmar a palavra-passe não pode estar em branco.",
|
"repeatPasswordEmptyError": "Confirmar a palavra-passe não pode estar em branco.",
|
||||||
"unmatchedPasswordError": "As palavras-passes não coincidem.",
|
"unmatchedPasswordError": "As palavras-passes não coincidem.",
|
||||||
"alreadyHaveAnAccount": "Já possuis uma conta?",
|
"alreadyHaveAnAccount": "Já possuis uma conta?",
|
||||||
"emailHint": "Email",
|
"emailHint": "Email",
|
||||||
"passwordHint": "Password",
|
"passwordHint": "Password",
|
||||||
"repeatPasswordHint": "Confirma a tua password"
|
"repeatPasswordHint": "Confirma a tua password"
|
||||||
},
|
},
|
||||||
"signIn": {
|
"signIn": {
|
||||||
"loginTitle": "Entre no @:appName",
|
"loginTitle": "Entre no @:appName",
|
||||||
"loginButtonText": "Login",
|
"loginButtonText": "Login",
|
||||||
"buttonText": "Entre",
|
"buttonText": "Entre",
|
||||||
"forgotPassword": "Esqueceste-te da tua palavra-passe?",
|
"forgotPassword": "Esqueceste-te da tua palavra-passe?",
|
||||||
"emailHint": "Email",
|
"emailHint": "Email",
|
||||||
"passwordHint": "Palavra-passe",
|
"passwordHint": "Palavra-passe",
|
||||||
"dontHaveAnAccount": "Não possuis uma conta?",
|
"dontHaveAnAccount": "Não possuis uma conta?",
|
||||||
"repeatPasswordEmptyError": "Confirmar a palavra-passe não pode estar em branco.",
|
"repeatPasswordEmptyError": "Confirmar a palavra-passe não pode estar em branco.",
|
||||||
"unmatchedPasswordError": "As palavras-passes não conferem."
|
"unmatchedPasswordError": "As palavras-passes não conferem."
|
||||||
},
|
},
|
||||||
"workspace": {
|
"workspace": {
|
||||||
"create": "Cria um ambiente de trabalho",
|
"create": "Cria um ambiente de trabalho",
|
||||||
"hint": "ambiente de trabalho",
|
"hint": "ambiente de trabalho",
|
||||||
"notFoundError": "Ambiente de trabalho não encontrada"
|
"notFoundError": "Ambiente de trabalho não encontrada"
|
||||||
},
|
},
|
||||||
"shareAction": {
|
"shareAction": {
|
||||||
"buttonText": "Partilhar",
|
"buttonText": "Partilhar",
|
||||||
"workInProgress": "Em breve",
|
"workInProgress": "Em breve",
|
||||||
"markdown": "Markdown",
|
"markdown": "Markdown",
|
||||||
"copyLink": "Copiar o link"
|
"copyLink": "Copiar o link"
|
||||||
},
|
},
|
||||||
"disclosureAction": {
|
"disclosureAction": {
|
||||||
"rename": "Renomear",
|
"rename": "Renomear",
|
||||||
"delete": "Apagar",
|
"delete": "Apagar",
|
||||||
"duplicate": "Duplicar"
|
"duplicate": "Duplicar"
|
||||||
},
|
},
|
||||||
"blankPageTitle": "Página em branco",
|
"blankPageTitle": "Página em branco",
|
||||||
"newPageText": "Nova página",
|
"newPageText": "Nova página",
|
||||||
"trash": {
|
"trash": {
|
||||||
"text": "Lixo",
|
"text": "Lixo",
|
||||||
"restoreAll": "Restaurar todos",
|
"restoreAll": "Restaurar todos",
|
||||||
"deleteAll": "Apagar todos",
|
"deleteAll": "Apagar todos",
|
||||||
"pageHeader": {
|
"pageHeader": {
|
||||||
"fileName": "Nome do ficheiro",
|
"fileName": "Nome do ficheiro",
|
||||||
"lastModified": "Última modificação",
|
"lastModified": "Última modificação",
|
||||||
"created": "Criado"
|
"created": "Criado"
|
||||||
}
|
|
||||||
},
|
|
||||||
"deletePagePrompt": {
|
|
||||||
"text": "Esta página está no lixo",
|
|
||||||
"restore": "Restaurar a página",
|
|
||||||
"deletePermanent": "Apagar permanentemente"
|
|
||||||
},
|
|
||||||
"dialogCreatePageNameHint": "Nome da página",
|
|
||||||
"questionBubble": {
|
|
||||||
"whatsNew": "O que há de novo?",
|
|
||||||
"help": "Ajuda & Suporte",
|
|
||||||
"debug": {
|
|
||||||
"name": "Informação de depuração",
|
|
||||||
"success": "Copiar informação de depuração para o clipboard!",
|
|
||||||
"fail": "Falha em copiar a informação de depuração para o clipboard"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"menuAppHeader": {
|
|
||||||
"addPageTooltip": "Adiciona uma nova página.",
|
|
||||||
"defaultNewPageName": "Sem título",
|
|
||||||
"renameDialog": "Renomear"
|
|
||||||
},
|
|
||||||
"toolbar": {
|
|
||||||
"undo": "Desfazer",
|
|
||||||
"redo": "Refazer",
|
|
||||||
"bold": "Negrito",
|
|
||||||
"italic": "Itálico",
|
|
||||||
"underline": "Sublinhado",
|
|
||||||
"strike": "Riscado",
|
|
||||||
"numList": "Lista numerada",
|
|
||||||
"bulletList": "Lista com marcadores",
|
|
||||||
"checkList": "Lista de verificação",
|
|
||||||
"inlineCode": "Embutir código",
|
|
||||||
"quote": "Citação em bloco",
|
|
||||||
"header": "Cabeçalho",
|
|
||||||
"highlight": "Realçar"
|
|
||||||
},
|
|
||||||
"tooltip": {
|
|
||||||
"lightMode": "Mudar para o modo Claro.",
|
|
||||||
"darkMode": "Mudar para o modo Escuro."
|
|
||||||
},
|
|
||||||
"contactsPage": {
|
|
||||||
"title": "Conctatos",
|
|
||||||
"whatsHappening": "O que está a acontecer nesta semana?",
|
|
||||||
"addContact": "Adicionar um conctato",
|
|
||||||
"editContact": "Editar um conctato"
|
|
||||||
},
|
|
||||||
"button": {
|
|
||||||
"OK": "OK",
|
|
||||||
"Cancel": "Cancelar",
|
|
||||||
"signIn": "Entrar",
|
|
||||||
"signOut": "Sair",
|
|
||||||
"complete": "Completar",
|
|
||||||
"save": "Guardar"
|
|
||||||
},
|
|
||||||
"label": {
|
|
||||||
"welcome": "Bem vindo!",
|
|
||||||
"firstName": "Nome",
|
|
||||||
"middleName": "Nome do Meio",
|
|
||||||
"lastName": "Apelido",
|
|
||||||
"stepX": "Passo {X}"
|
|
||||||
},
|
|
||||||
"oAuth": {
|
|
||||||
"err": {
|
|
||||||
"failedTitle": "Erro ao conectar à sua conta.",
|
|
||||||
"failedMsg": "Verifica se concluiste o processo de login no teu navegador."
|
|
||||||
},
|
|
||||||
"google": {
|
|
||||||
"title": "GOOGLE SIGN-IN",
|
|
||||||
"instruction1": "Para importar os teus Conctatos do Google, tens de autorizar esta aplicação usando o teu navegador web.",
|
|
||||||
"instruction2": "Copia este código para a tua área de transferências clicando no ícone ou selecionando o texto:",
|
|
||||||
"instruction3": "Navega até o link a seguir no seu navegador e digite o código acima:",
|
|
||||||
"instruction4": "Clica no botão abaixo ao concluir a inscrição:"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"settings": {
|
|
||||||
"title": "Definições",
|
|
||||||
"menu": {
|
|
||||||
"appearance": "Aparência",
|
|
||||||
"language": "Idioma",
|
|
||||||
"open": "Abrir as Definições"
|
|
||||||
},
|
|
||||||
"appearance": {
|
|
||||||
"lightLabel": "Modo Claro",
|
|
||||||
"darkLabel": "Modo Escuro"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"sideBar": {
|
|
||||||
"openSidebar": "Open sidebar",
|
|
||||||
"closeSidebar": "Close sidebar"
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"deletePagePrompt": {
|
||||||
|
"text": "Esta página está no lixo",
|
||||||
|
"restore": "Restaurar a página",
|
||||||
|
"deletePermanent": "Apagar permanentemente"
|
||||||
|
},
|
||||||
|
"dialogCreatePageNameHint": "Nome da página",
|
||||||
|
"questionBubble": {
|
||||||
|
"whatsNew": "O que há de novo?",
|
||||||
|
"help": "Ajuda & Suporte",
|
||||||
|
"debug": {
|
||||||
|
"name": "Informação de depuração",
|
||||||
|
"success": "Copiar informação de depuração para o clipboard!",
|
||||||
|
"fail": "Falha em copiar a informação de depuração para o clipboard"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"menuAppHeader": {
|
||||||
|
"addPageTooltip": "Adiciona uma nova página.",
|
||||||
|
"defaultNewPageName": "Sem título",
|
||||||
|
"renameDialog": "Renomear"
|
||||||
|
},
|
||||||
|
"toolbar": {
|
||||||
|
"undo": "Desfazer",
|
||||||
|
"redo": "Refazer",
|
||||||
|
"bold": "Negrito",
|
||||||
|
"italic": "Itálico",
|
||||||
|
"underline": "Sublinhado",
|
||||||
|
"strike": "Riscado",
|
||||||
|
"numList": "Lista numerada",
|
||||||
|
"bulletList": "Lista com marcadores",
|
||||||
|
"checkList": "Lista de verificação",
|
||||||
|
"inlineCode": "Embutir código",
|
||||||
|
"quote": "Citação em bloco",
|
||||||
|
"header": "Cabeçalho",
|
||||||
|
"highlight": "Realçar"
|
||||||
|
},
|
||||||
|
"tooltip": {
|
||||||
|
"lightMode": "Mudar para o modo Claro.",
|
||||||
|
"darkMode": "Mudar para o modo Escuro."
|
||||||
|
},
|
||||||
|
"contactsPage": {
|
||||||
|
"title": "Conctatos",
|
||||||
|
"whatsHappening": "O que está a acontecer nesta semana?",
|
||||||
|
"addContact": "Adicionar um conctato",
|
||||||
|
"editContact": "Editar um conctato"
|
||||||
|
},
|
||||||
|
"button": {
|
||||||
|
"OK": "OK",
|
||||||
|
"Cancel": "Cancelar",
|
||||||
|
"signIn": "Entrar",
|
||||||
|
"signOut": "Sair",
|
||||||
|
"complete": "Completar",
|
||||||
|
"save": "Guardar"
|
||||||
|
},
|
||||||
|
"label": {
|
||||||
|
"welcome": "Bem vindo!",
|
||||||
|
"firstName": "Nome",
|
||||||
|
"middleName": "Nome do Meio",
|
||||||
|
"lastName": "Apelido",
|
||||||
|
"stepX": "Passo {X}"
|
||||||
|
},
|
||||||
|
"oAuth": {
|
||||||
|
"err": {
|
||||||
|
"failedTitle": "Erro ao conectar à sua conta.",
|
||||||
|
"failedMsg": "Verifica se concluiste o processo de login no teu navegador."
|
||||||
|
},
|
||||||
|
"google": {
|
||||||
|
"title": "GOOGLE SIGN-IN",
|
||||||
|
"instruction1": "Para importar os teus Conctatos do Google, tens de autorizar esta aplicação usando o teu navegador web.",
|
||||||
|
"instruction2": "Copia este código para a tua área de transferências clicando no ícone ou selecionando o texto:",
|
||||||
|
"instruction3": "Navega até o link a seguir no seu navegador e digite o código acima:",
|
||||||
|
"instruction4": "Clica no botão abaixo ao concluir a inscrição:"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"title": "Definições",
|
||||||
|
"menu": {
|
||||||
|
"appearance": "Aparência",
|
||||||
|
"language": "Idioma",
|
||||||
|
"open": "Abrir as Definições"
|
||||||
|
},
|
||||||
|
"appearance": {
|
||||||
|
"lightLabel": "Modo Claro",
|
||||||
|
"darkLabel": "Modo Escuro"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sideBar": {
|
||||||
|
"openSidebar": "Open sidebar",
|
||||||
|
"closeSidebar": "Close sidebar"
|
||||||
}
|
}
|
||||||
|
}
|
@ -1,348 +1,413 @@
|
|||||||
{
|
{
|
||||||
"appName": "AppFlowy",
|
"appName": "AppFlowy",
|
||||||
"defaultUsername": "Я",
|
"defaultUsername": "Я",
|
||||||
"welcomeText": "Добро пожаловать в @:appName",
|
"welcomeText": "Добро пожаловать в @:appName",
|
||||||
"githubStarText": "Поставить звезду на GitHub",
|
"githubStarText": "Поставить звезду на GitHub",
|
||||||
"subscribeNewsletterText": "Подписаться на рассылку",
|
"subscribeNewsletterText": "Подписаться на рассылку",
|
||||||
"letsGoButtonText": "Начнём",
|
"letsGoButtonText": "Начнём",
|
||||||
"title": "Заголовок",
|
"title": "Заголовок",
|
||||||
"signUp": {
|
"signUp": {
|
||||||
"buttonText": "Зарегистрироваться",
|
"buttonText": "Зарегистрироваться",
|
||||||
"title": "Регистрация в @:appName",
|
"title": "Регистрация в @:appName",
|
||||||
"getStartedText": "Начать",
|
"getStartedText": "Начать",
|
||||||
"emptyPasswordError": "Пароль не может быть пустым",
|
"emptyPasswordError": "Пароль не может быть пустым",
|
||||||
"repeatPasswordEmptyError": "Повтор пароля не может быть пустым",
|
"repeatPasswordEmptyError": "Повтор пароля не может быть пустым",
|
||||||
"unmatchedPasswordError": "Пароли не совпадают",
|
"unmatchedPasswordError": "Пароли не совпадают",
|
||||||
"alreadyHaveAnAccount": "Уже есть аккаунт?",
|
"alreadyHaveAnAccount": "Уже есть аккаунт?",
|
||||||
"emailHint": "Электронная почта",
|
"emailHint": "Электронная почта",
|
||||||
"passwordHint": "Пароль",
|
"passwordHint": "Пароль",
|
||||||
"repeatPasswordHint": "Повторите пароль"
|
"repeatPasswordHint": "Повторите пароль"
|
||||||
|
},
|
||||||
|
"signIn": {
|
||||||
|
"loginTitle": "Войти в @:appName",
|
||||||
|
"loginButtonText": "Войти",
|
||||||
|
"buttonText": "Авторизация",
|
||||||
|
"forgotPassword": "Забыли пароль?",
|
||||||
|
"emailHint": "Электронная почта",
|
||||||
|
"passwordHint": "Пароль",
|
||||||
|
"dontHaveAnAccount": "Нет аккаунта?",
|
||||||
|
"repeatPasswordEmptyError": "Повтор пароля не может быть пустым",
|
||||||
|
"unmatchedPasswordError": "Пароли не совпадают"
|
||||||
|
},
|
||||||
|
"workspace": {
|
||||||
|
"create": "Создать рабочее пространство",
|
||||||
|
"hint": "рабочее пространство",
|
||||||
|
"notFoundError": "Нет такого рабочего пространства"
|
||||||
|
},
|
||||||
|
"shareAction": {
|
||||||
|
"buttonText": "Поделиться",
|
||||||
|
"workInProgress": "В разработке",
|
||||||
|
"markdown": "Markdown",
|
||||||
|
"copyLink": "Скопировать ссылку"
|
||||||
|
},
|
||||||
|
"moreAction": {
|
||||||
|
"small": "маленький",
|
||||||
|
"medium": "средний",
|
||||||
|
"large": "большой",
|
||||||
|
"fontSize": "Размер шрифта"
|
||||||
|
},
|
||||||
|
"disclosureAction": {
|
||||||
|
"rename": "Переименовать",
|
||||||
|
"delete": "Удалить",
|
||||||
|
"duplicate": "Дублировать"
|
||||||
|
},
|
||||||
|
"blankPageTitle": "Пустая страница",
|
||||||
|
"newPageText": "Новая страница",
|
||||||
|
"trash": {
|
||||||
|
"text": "Корзина",
|
||||||
|
"restoreAll": "Восстановить всё",
|
||||||
|
"deleteAll": "Очистить",
|
||||||
|
"pageHeader": {
|
||||||
|
"fileName": "Имя",
|
||||||
|
"lastModified": "Последнее изменение",
|
||||||
|
"created": "Создан"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"deletePagePrompt": {
|
||||||
|
"text": "Эта страница в Корзине",
|
||||||
|
"restore": "Восстановить страницу",
|
||||||
|
"deletePermanent": "Удалить навсегда"
|
||||||
|
},
|
||||||
|
"dialogCreatePageNameHint": "Имя страницы",
|
||||||
|
"questionBubble": {
|
||||||
|
"whatsNew": "Что нового?",
|
||||||
|
"help": "Помощь",
|
||||||
|
"debug": {
|
||||||
|
"name": "Отладочная информация",
|
||||||
|
"success": "Скопировано в буфер обмена!",
|
||||||
|
"fail": "Не получилось скопировать"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"menuAppHeader": {
|
||||||
|
"addPageTooltip": "Быстро добавить новую страницу",
|
||||||
|
"defaultNewPageName": "Без заголовка",
|
||||||
|
"renameDialog": "Переименовать"
|
||||||
|
},
|
||||||
|
"toolbar": {
|
||||||
|
"undo": "Отменить",
|
||||||
|
"redo": "Повторить",
|
||||||
|
"bold": "Жирный",
|
||||||
|
"italic": "Курсив",
|
||||||
|
"underline": "Подчёркнутый",
|
||||||
|
"strike": "Зачёркнутый",
|
||||||
|
"numList": "Нумерованный список",
|
||||||
|
"bulletList": "Маркированный список",
|
||||||
|
"checkList": "Список To-Do",
|
||||||
|
"inlineCode": "Код",
|
||||||
|
"quote": "Цитата",
|
||||||
|
"header": "Заголовок",
|
||||||
|
"highlight": "Выделение",
|
||||||
|
"color": "Цвет"
|
||||||
|
},
|
||||||
|
"tooltip": {
|
||||||
|
"lightMode": "Переключить на светлую тему",
|
||||||
|
"darkMode": "Переключить на тёмную тему",
|
||||||
|
"openAsPage": "Открыть как страницу",
|
||||||
|
"addNewRow": "Добавить новую строку",
|
||||||
|
"openMenu": "Открыть меню",
|
||||||
|
"viewDataBase": "Просмотр базы данных",
|
||||||
|
"referencePage": "Ссылаются на {name}"
|
||||||
|
},
|
||||||
|
"sideBar": {
|
||||||
|
"closeSidebar": "Закрыть боковое меню",
|
||||||
|
"openSidebar": "Открыть боковое меню"
|
||||||
|
},
|
||||||
|
"notifications": {
|
||||||
|
"export": {
|
||||||
|
"markdown": "Заметка экспортирована в Markdown",
|
||||||
|
"path": "Документы/flowy"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contactsPage": {
|
||||||
|
"title": "Контакты",
|
||||||
|
"whatsHappening": "Какие события на этой неделе?",
|
||||||
|
"addContact": "Добавить контакт",
|
||||||
|
"editContact": "Редактировать контакт"
|
||||||
|
},
|
||||||
|
"button": {
|
||||||
|
"OK": "OK",
|
||||||
|
"Cancel": "Отмена",
|
||||||
|
"signIn": "Войти",
|
||||||
|
"signOut": "Выйти",
|
||||||
|
"complete": "Завершить",
|
||||||
|
"save": "Сохранить",
|
||||||
|
"generate": "Сгенерировать",
|
||||||
|
"esc": "ESC",
|
||||||
|
"keep": "Оставить",
|
||||||
|
"tryAgain": "Повторить",
|
||||||
|
"discard": "Отменить",
|
||||||
|
"replace": "Заменить",
|
||||||
|
"insertBelow": "Вставить ниже"
|
||||||
|
},
|
||||||
|
"label": {
|
||||||
|
"welcome": "Добро пожаловать!",
|
||||||
|
"firstName": "Имя",
|
||||||
|
"middleName": "Отчество",
|
||||||
|
"lastName": "Фамилия",
|
||||||
|
"stepX": "Этап {X}"
|
||||||
|
},
|
||||||
|
"oAuth": {
|
||||||
|
"err": {
|
||||||
|
"failedTitle": "Не удалось подключиться к вашей учетной записи.",
|
||||||
|
"failedMsg": "Убедитесь, что вы завершили вход в своём браузере."
|
||||||
},
|
},
|
||||||
"signIn": {
|
"google": {
|
||||||
"loginTitle": "Войти в @:appName",
|
"title": "Вход через Google",
|
||||||
"loginButtonText": "Войти",
|
"instruction1": "Чтобы импортировать ваши Google Контакты, вам нужно будет авторизовать приложение через браузер.",
|
||||||
"buttonText": "Авторизация",
|
"instruction2": "Скопируйте этот код в буфер обмена (нажав кнопку или выделив текст):",
|
||||||
"forgotPassword": "Забыли пароль?",
|
"instruction3": "Пройдите по ссылке и введите этот код:",
|
||||||
"emailHint": "Электронная почта",
|
"instruction4": "Нажмите на кнопку ниже, когда завершите вход:"
|
||||||
"passwordHint": "Пароль",
|
}
|
||||||
"dontHaveAnAccount": "Нет аккаунта?",
|
},
|
||||||
"repeatPasswordEmptyError": "Повтор пароля не может быть пустым",
|
"settings": {
|
||||||
"unmatchedPasswordError": "Пароли не совпадают"
|
"title": "Настройки",
|
||||||
|
"menu": {
|
||||||
|
"appearance": "Внешний вид",
|
||||||
|
"language": "Язык",
|
||||||
|
"user": "Пользователь",
|
||||||
|
"files": "Файлы",
|
||||||
|
"open": "Открыть настройки"
|
||||||
},
|
},
|
||||||
"workspace": {
|
"appearance": {
|
||||||
"create": "Создать рабочее пространство",
|
"themeMode": {
|
||||||
"hint": "рабочее пространство",
|
"label": "Режим темы",
|
||||||
"notFoundError": "Нет такого рабочего пространства"
|
"light": "Светлая",
|
||||||
|
"dark": "Тёмная",
|
||||||
|
"system": "Системная"
|
||||||
|
},
|
||||||
|
"theme": "Тема"
|
||||||
},
|
},
|
||||||
"shareAction": {
|
"files": {
|
||||||
"buttonText": "Поделиться",
|
"defaultLocation": "Где сейчас хранятся ваши данные",
|
||||||
"workInProgress": "В разработке",
|
"doubleTapToCopy": "Нажмите дважды, чтобы скопировать путь",
|
||||||
"markdown": "Markdown",
|
"restoreLocation": "Восстановить путь AppFlowy по умолчанию",
|
||||||
"copyLink": "Скопировать ссылку"
|
"customizeLocation": "Открыть другую папку",
|
||||||
|
"restartApp": "Пожалуйста, перезапустите приложение, чтобы изменения вступили в силу.",
|
||||||
|
"exportDatabase": "Экспорт базы данных",
|
||||||
|
"selectFiles": "Выбрать файлы, которые необходимо экспортировать",
|
||||||
|
"createNewFolder": "Создать новую папку",
|
||||||
|
"createNewFolderDesc": "Указать, где хранить свои данные ...",
|
||||||
|
"open": "Открыть",
|
||||||
|
"openFolder": "Открыть существующую папку",
|
||||||
|
"openFolderDesc": "Чтение и запись в существующую папку AppFlowy ...",
|
||||||
|
"folderHintText": "имя папки",
|
||||||
|
"location": "Создание новой папки",
|
||||||
|
"locationDesc": "Выбрать имя папки данных AppFlowy",
|
||||||
|
"browser": "Обзор",
|
||||||
|
"create": "Создать",
|
||||||
|
"folderPath": "Путь к вашей папке",
|
||||||
|
"locationCannotBeEmpty": "Путь не может быть пустым",
|
||||||
|
"pathCopiedSnackbar": "File storage path copied to clipboard!"
|
||||||
},
|
},
|
||||||
"moreAction": {
|
"user": {
|
||||||
"small": "маленький",
|
"name": "Имя",
|
||||||
"medium": "средний",
|
"icon": "Иконка",
|
||||||
"large": "большой",
|
"selectAnIcon": "Выбрать иконку",
|
||||||
"fontSize": "Размер шрифта"
|
"pleaseInputYourOpenAIKey": "Введите токен OpenAI"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"grid": {
|
||||||
|
"settings": {
|
||||||
|
"filter": "Фильтр",
|
||||||
|
"sort": "Сортировать",
|
||||||
|
"sortBy": "Сортировать по",
|
||||||
|
"Properties": "Свойства",
|
||||||
|
"group": "Группировать",
|
||||||
|
"addFilter": "Добавить фильтр",
|
||||||
|
"deleteFilter": "Удалить фильтр",
|
||||||
|
"filterBy": "Фильтровать по...",
|
||||||
|
"typeAValue": "Введите значение..."
|
||||||
},
|
},
|
||||||
"disclosureAction": {
|
"textFilter": {
|
||||||
"rename": "Переименовать",
|
"contains": "Содержит",
|
||||||
"delete": "Удалить",
|
"doesNotContain": "Не содержит",
|
||||||
"duplicate": "Дублировать"
|
"endsWith": "Заканчивается на",
|
||||||
|
"startWith": "Начинается с",
|
||||||
|
"is": "Является",
|
||||||
|
"isNot": "Не является",
|
||||||
|
"isEmpty": "Пусто",
|
||||||
|
"isNotEmpty": "Не пусто",
|
||||||
|
"choicechipPrefix": {
|
||||||
|
"isNot": "Не является",
|
||||||
|
"startWith": "Начинается с",
|
||||||
|
"endWith": "Заканчивается на",
|
||||||
|
"isEmpty": "пусто",
|
||||||
|
"isNotEmpty": "не пусто"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"blankPageTitle": "Пустая страница",
|
"checkboxFilter": {
|
||||||
"newPageText": "Новая страница",
|
"isChecked": "Отмечено",
|
||||||
"trash": {
|
"isUnchecked": "Не отмечено",
|
||||||
"text": "Корзина",
|
"choicechipPrefix": {
|
||||||
"restoreAll": "Восстановить всё",
|
"is": "является"
|
||||||
"deleteAll": "Очистить",
|
}
|
||||||
"pageHeader": {
|
|
||||||
"fileName": "Имя",
|
|
||||||
"lastModified": "Последнее изменение",
|
|
||||||
"created": "Создан"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"deletePagePrompt": {
|
"checklistFilter": {
|
||||||
"text": "Эта страница в Корзине",
|
"isComplete": "завершено",
|
||||||
"restore": "Восстановить страницу",
|
"isIncomplted": "не завершено"
|
||||||
"deletePermanent": "Удалить навсегда"
|
|
||||||
},
|
},
|
||||||
"dialogCreatePageNameHint": "Имя страницы",
|
"singleSelectOptionFilter": {
|
||||||
"questionBubble": {
|
"is": "Является",
|
||||||
"whatsNew": "Что нового?",
|
"isNot": "Не является",
|
||||||
"help": "Помощь",
|
"isEmpty": "Пусто",
|
||||||
"debug": {
|
"isNotEmpty": "Не пусто"
|
||||||
"name": "Отладочная информация",
|
|
||||||
"success": "Скопировано в буфер обмена!",
|
|
||||||
"fail": "Не получилось скопировать"
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"menuAppHeader": {
|
"multiSelectOptionFilter": {
|
||||||
"addPageTooltip": "Быстро добавить новую страницу",
|
"contains": "Содержит",
|
||||||
"defaultNewPageName": "Без заголовка",
|
"doesNotContain": "Не содержит",
|
||||||
"renameDialog": "Переименовать"
|
"isEmpty": "Пусто",
|
||||||
|
"isNotEmpty": "Не пусто"
|
||||||
},
|
},
|
||||||
"toolbar": {
|
"field": {
|
||||||
"undo": "Отменить",
|
"hide": "Скрыть",
|
||||||
"redo": "Повторить",
|
"insertLeft": "Вставить слева",
|
||||||
"bold": "Жирный",
|
"insertRight": "Вставить справа",
|
||||||
"italic": "Курсив",
|
"duplicate": "Дублировать",
|
||||||
"underline": "Подчёркнутый",
|
"delete": "Удалить",
|
||||||
"strike": "Зачёркнутый",
|
"textFieldName": "Текст",
|
||||||
"numList": "Нумерованный список",
|
"checkboxFieldName": "Чекбокс",
|
||||||
"bulletList": "Маркированный список",
|
"dateFieldName": "Дата",
|
||||||
"checkList": "Список To-Do",
|
"numberFieldName": "Число",
|
||||||
"inlineCode": "Код",
|
"singleSelectFieldName": "Выбор",
|
||||||
"quote": "Цитата",
|
"multiSelectFieldName": "Выбор нескольких",
|
||||||
"header": "Заголовок",
|
"urlFieldName": "URL",
|
||||||
"highlight": "Выделение",
|
"checklistFieldName": "Контрольный список",
|
||||||
"color": "Цвет"
|
"numberFormat": "Формат числа",
|
||||||
|
"dateFormat": "Формат даты",
|
||||||
|
"includeTime": "Время",
|
||||||
|
"dateFormatFriendly": "День Месяц, Год",
|
||||||
|
"dateFormatISO": "Год-Месяц-День",
|
||||||
|
"dateFormatLocal": "Месяц/День/Год",
|
||||||
|
"dateFormatUS": "Год/Месяц/День",
|
||||||
|
"dateFormatDayMonthYear": "День/Mесяц/Год",
|
||||||
|
"timeFormat": "Формат времени",
|
||||||
|
"invalidTimeFormat": "Неверный формат",
|
||||||
|
"timeFormatTwelveHour": "12 часов",
|
||||||
|
"timeFormatTwentyFourHour": "24 часа",
|
||||||
|
"addSelectOption": "Добавить вариант",
|
||||||
|
"optionTitle": "Варианты",
|
||||||
|
"addOption": "Добавить",
|
||||||
|
"editProperty": "Редактировать свойство",
|
||||||
|
"newProperty": "Добавить колонку",
|
||||||
|
"deleteFieldPromptMessage": "Вы уверены? Свойство будет удалено"
|
||||||
},
|
},
|
||||||
"tooltip": {
|
"sort": {
|
||||||
"lightMode": "Переключить на светлую тему",
|
"ascending": "По возрастанию",
|
||||||
"darkMode": "Переключить на тёмную тему",
|
"descending": "По убыванию",
|
||||||
"openAsPage": "Открыть как страницу",
|
"deleteSort": "Удалить сортировку",
|
||||||
"addNewRow": "Добавить новую строку",
|
"addSort": "Добавить сортировку"
|
||||||
"openMenu": "Открыть меню",
|
|
||||||
"viewDataBase": "Просмотр базы данных",
|
|
||||||
"referencePage": "Ссылаются на {name}"
|
|
||||||
},
|
},
|
||||||
"sideBar": {
|
"row": {
|
||||||
"closeSidebar": "Закрыть боковое меню",
|
"duplicate": "Дублировать",
|
||||||
"openSidebar": "Открыть боковое меню"
|
"delete": "Удалить",
|
||||||
|
"textPlaceholder": "Пусто",
|
||||||
|
"copyProperty": "Свойство скопировано",
|
||||||
|
"count": "Количество",
|
||||||
|
"newRow": "Новая строка"
|
||||||
},
|
},
|
||||||
"notifications": {
|
"selectOption": {
|
||||||
"export": {
|
"create": "Создать",
|
||||||
"markdown": "Заметка экспортирована в Markdown",
|
"purpleColor": "Фиолетовый",
|
||||||
"path": "Документы/flowy"
|
"pinkColor": "Розовый",
|
||||||
}
|
"lightPinkColor": "Светло-розовый",
|
||||||
|
"orangeColor": "Оранжевый",
|
||||||
|
"yellowColor": "Желтый",
|
||||||
|
"limeColor": "Ярко-зелёный",
|
||||||
|
"greenColor": "Зелёный",
|
||||||
|
"aquaColor": "Бирюзовый",
|
||||||
|
"blueColor": "Синий",
|
||||||
|
"deleteTag": "Удалить вариант",
|
||||||
|
"colorPanelTitle": "Цвета",
|
||||||
|
"panelTitle": "Выберите или создайте вариант",
|
||||||
|
"searchOption": "Поиск"
|
||||||
},
|
},
|
||||||
"contactsPage": {
|
"checklist": {
|
||||||
"title": "Контакты",
|
"panelTitle": "Добавить элемент"
|
||||||
"whatsHappening": "Какие события на этой неделе?",
|
|
||||||
"addContact": "Добавить контакт",
|
|
||||||
"editContact": "Редактировать контакт"
|
|
||||||
},
|
},
|
||||||
"button": {
|
"menuName": "Сетка",
|
||||||
"OK": "OK",
|
"referencedGridPrefix": "Просмотр"
|
||||||
"Cancel": "Отмена",
|
},
|
||||||
"signIn": "Войти",
|
"document": {
|
||||||
"signOut": "Выйти",
|
"menuName": "Документ",
|
||||||
"complete": "Завершить",
|
"date": {
|
||||||
"save": "Сохранить"
|
"timeHintTextInTwelveHour": "01:00 PM",
|
||||||
|
"timeHintTextInTwentyFourHour": "13:00"
|
||||||
},
|
},
|
||||||
"label": {
|
"slashMenu": {
|
||||||
"welcome": "Добро пожаловать!",
|
"board": {
|
||||||
"firstName": "Имя",
|
"selectABoardToLinkTo": "Выбрать доску для связи с",
|
||||||
"middleName": "Отчество",
|
"createANewBoard": "Создать доску"
|
||||||
"lastName": "Фамилия",
|
},
|
||||||
"stepX": "Этап {X}"
|
"grid": {
|
||||||
|
"selectAGridToLinkTo": "Выберите сетку для связи с",
|
||||||
|
"createANewGrid": "Создать сетку"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"oAuth": {
|
"plugins": {
|
||||||
"err": {
|
"referencedBoard": "Связанные доски",
|
||||||
"failedTitle": "Не удалось подключиться к вашей учетной записи.",
|
"referencedGrid": "Связанные сетки",
|
||||||
"failedMsg": "Убедитесь, что вы завершили вход в своём браузере."
|
"autoGeneratorMenuItemName": "Генератор OpenAI",
|
||||||
},
|
"autoGeneratorTitleName": "OpenAI: попросить ИИ написать что угодно...",
|
||||||
"google": {
|
"autoGeneratorLearnMore": "Узнать больше",
|
||||||
"title": "Вход через Google",
|
"autoGeneratorGenerate": "Генерировать",
|
||||||
"instruction1": "Чтобы импортировать ваши Google Контакты, вам нужно будет авторизовать приложение через браузер.",
|
"autoGeneratorHintText": "Спросить OpenAI ...",
|
||||||
"instruction2": "Скопируйте этот код в буфер обмена (нажав кнопку или выделив текст):",
|
"autoGeneratorCantGetOpenAIKey": "Не могу получить токен OpenAI",
|
||||||
"instruction3": "Пройдите по ссылке и введите этот код:",
|
"smartEdit": "ИИ ассистенты",
|
||||||
"instruction4": "Нажмите на кнопку ниже, когда завершите вход:"
|
"openAI": "OpenAI",
|
||||||
}
|
"smartEditFixSpelling": "Исправить правописание",
|
||||||
|
"warning": "⚠️ Ответы ИИ могут быть неправильными или неточными.",
|
||||||
|
"smartEditSummarize": "Выделить суть",
|
||||||
|
"smartEditCouldNotFetchResult": "Не могу получить ответ от OpenAI",
|
||||||
|
"smartEditCouldNotFetchKey": "Не могу получить токен OpenAI",
|
||||||
|
"smartEditDisabled": "Подключить OpenAI",
|
||||||
|
"discardResponse": "Хотите убрать ответы ИИ?",
|
||||||
|
"cover": {
|
||||||
|
"changeCover": "Сменить обложку",
|
||||||
|
"colors": "Цвета",
|
||||||
|
"images": "Изображения",
|
||||||
|
"clearAll": "Очистить",
|
||||||
|
"abstract": "Абстракные",
|
||||||
|
"addCover": "Добавить обложку",
|
||||||
|
"addLocalImage": "Добавить изображение с диска",
|
||||||
|
"invalidImageUrl": "Некорректная ссылка на изображение",
|
||||||
|
"failedToAddImageToGallery": "Ошибка добавления изображения в галерею",
|
||||||
|
"enterImageUrl": "Введите ссылку на изображение",
|
||||||
|
"add": "Добавить",
|
||||||
|
"back": "Назад",
|
||||||
|
"saveToGallery": "Сохранить в галерею",
|
||||||
|
"removeIcon": "Удалить иконку",
|
||||||
|
"pasteImageUrl": "Вставить ссылку на изображение",
|
||||||
|
"or": "ИЛИ",
|
||||||
|
"pickFromFiles": "Выбрать с диска",
|
||||||
|
"couldNotFetchImage": "Не удалось получить изображение",
|
||||||
|
"imageSavingFailed": "Не удалось сохранить изображение",
|
||||||
|
"addIcon": "Добавить иконку",
|
||||||
|
"coverRemoveAlert": "Изображение будет удалено с обложки",
|
||||||
|
"alertDialogConfirmation": "Вы хотите продолжить?"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"board": {
|
||||||
|
"column": {
|
||||||
|
"create_new_card": "Создать"
|
||||||
|
},
|
||||||
|
"menuName": "Доска",
|
||||||
|
"referencedBoardPrefix": "Просмотр"
|
||||||
|
},
|
||||||
|
"calendar": {
|
||||||
|
"menuName": "Календарь",
|
||||||
|
"defaultNewCalendarTitle": "Безымянный",
|
||||||
|
"navigation": {
|
||||||
|
"today": "Сегодня",
|
||||||
|
"jumpToday": "Перейти к сегодняшнему дню",
|
||||||
|
"previousMonth": "Предыдущий месяц",
|
||||||
|
"nextMonth": "Следующий месяц"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"title": "Настройки",
|
"showWeekNumbers": "Показывать номера недель",
|
||||||
"menu": {
|
"showWeekends": "Показывать выходные",
|
||||||
"appearance": "Внешний вид",
|
"firstDayOfWeek": "Первый день недели",
|
||||||
"language": "Язык",
|
"layoutDateField": "Вид календаря"
|
||||||
"user": "Пользователь",
|
|
||||||
"files": "Файлы",
|
|
||||||
"open": "Открыть настройки"
|
|
||||||
},
|
|
||||||
"appearance": {
|
|
||||||
"themeMode": {
|
|
||||||
"label": "Режим темы",
|
|
||||||
"light": "Светлая",
|
|
||||||
"dark": "Тёмная",
|
|
||||||
"system": "Системная"
|
|
||||||
},
|
|
||||||
"theme": "Тема"
|
|
||||||
},
|
|
||||||
"files": {
|
|
||||||
"defaultLocation": "Где сейчас хранятся ваши данные",
|
|
||||||
"doubleTapToCopy": "Нажмите дважды, чтобы скопировать путь",
|
|
||||||
"restoreLocation": "Восстановить путь AppFlowy по умолчанию",
|
|
||||||
"customizeLocation": "Открыть другую папку",
|
|
||||||
"restartApp": "Пожалуйста, перезапустите приложение, чтобы изменения вступили в силу.",
|
|
||||||
"exportDatabase": "Экспорт базы данных",
|
|
||||||
"selectFiles": "Выбрать файлы, которые необходимо экспортировать",
|
|
||||||
"createNewFolder": "Создать новую папку",
|
|
||||||
"createNewFolderDesc": "Указать, где хранить свои данные ...",
|
|
||||||
"open": "Открыть",
|
|
||||||
"openFolder": "Открыть существующую папку",
|
|
||||||
"openFolderDesc": "Чтение и запись в существующую папку AppFlowy ...",
|
|
||||||
"folderHintText": "имя папки",
|
|
||||||
"location": "Создание новой папки",
|
|
||||||
"locationDesc": "Выбрать имя папки данных AppFlowy",
|
|
||||||
"browser": "Обзор",
|
|
||||||
"create": "Создать",
|
|
||||||
"folderPath": "Путь к вашей папке",
|
|
||||||
"locationCannotBeEmpty": "Путь не может быть пустым"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"grid": {
|
|
||||||
"settings": {
|
|
||||||
"filter": "Фильтр",
|
|
||||||
"sort": "Сортировать",
|
|
||||||
"sortBy": "Сортировать по",
|
|
||||||
"Properties": "Свойства",
|
|
||||||
"group": "Группировать",
|
|
||||||
"addFilter": "Добавить фильтр",
|
|
||||||
"deleteFilter": "Удалить фильтр",
|
|
||||||
"filterBy": "Фильтровать по...",
|
|
||||||
"typeAValue": "Введите значение..."
|
|
||||||
},
|
|
||||||
"textFilter": {
|
|
||||||
"contains": "Содержит",
|
|
||||||
"doesNotContain": "Не содержит",
|
|
||||||
"endsWith": "Заканчивается на",
|
|
||||||
"startWith": "Начинается с",
|
|
||||||
"is": "Является",
|
|
||||||
"isNot": "Не является",
|
|
||||||
"isEmpty": "Пусто",
|
|
||||||
"isNotEmpty": "Не пусто",
|
|
||||||
"choicechipPrefix": {
|
|
||||||
"isNot": "Не является",
|
|
||||||
"startWith": "Начинается с",
|
|
||||||
"endWith": "Заканчивается на",
|
|
||||||
"isEmpty": "пусто",
|
|
||||||
"isNotEmpty": "не пусто"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"checkboxFilter": {
|
|
||||||
"isChecked": "Отмечено",
|
|
||||||
"isUnchecked": "Не отмечено",
|
|
||||||
"choicechipPrefix": {
|
|
||||||
"is": "является"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"checklistFilter": {
|
|
||||||
"isComplete": "завершено",
|
|
||||||
"isIncomplted": "не завершено"
|
|
||||||
},
|
|
||||||
"singleSelectOptionFilter": {
|
|
||||||
"is": "Является",
|
|
||||||
"isNot": "Не является",
|
|
||||||
"isEmpty": "Пусто",
|
|
||||||
"isNotEmpty": "Не пусто"
|
|
||||||
},
|
|
||||||
"multiSelectOptionFilter": {
|
|
||||||
"contains": "Содержит",
|
|
||||||
"doesNotContain": "Не содержит",
|
|
||||||
"isEmpty": "Пусто",
|
|
||||||
"isNotEmpty": "Не пусто"
|
|
||||||
},
|
|
||||||
"field": {
|
|
||||||
"hide": "Скрыть",
|
|
||||||
"insertLeft": "Вставить слева",
|
|
||||||
"insertRight": "Вставить справа",
|
|
||||||
"duplicate": "Дублировать",
|
|
||||||
"delete": "Удалить",
|
|
||||||
"textFieldName": "Текст",
|
|
||||||
"checkboxFieldName": "Чекбокс",
|
|
||||||
"dateFieldName": "Дата",
|
|
||||||
"numberFieldName": "Число",
|
|
||||||
"singleSelectFieldName": "Выбор",
|
|
||||||
"multiSelectFieldName": "Выбор нескольких",
|
|
||||||
"urlFieldName": "URL",
|
|
||||||
"checklistFieldName": "Контрольный список",
|
|
||||||
"numberFormat": "Формат числа",
|
|
||||||
"dateFormat": "Формат даты",
|
|
||||||
"includeTime": "Время",
|
|
||||||
"dateFormatFriendly": "День Месяц, Год",
|
|
||||||
"dateFormatISO": "Год-Месяц-День",
|
|
||||||
"dateFormatLocal": "Месяц/День/Год",
|
|
||||||
"dateFormatUS": "Год/Месяц/День",
|
|
||||||
"timeFormat": "Форматировать время",
|
|
||||||
"invalidTimeFormat": "Неверный формат",
|
|
||||||
"timeFormatTwelveHour": "12 часов",
|
|
||||||
"timeFormatTwentyFourHour": "24 часа",
|
|
||||||
"addSelectOption": "Добавить вариант",
|
|
||||||
"optionTitle": "Варианты",
|
|
||||||
"addOption": "Добавить",
|
|
||||||
"editProperty": "Редактировать свойство",
|
|
||||||
"newColumn": "Добавить колонку",
|
|
||||||
"deleteFieldPromptMessage": "Вы уверены? Свойство будет удалено"
|
|
||||||
},
|
|
||||||
"sort": {
|
|
||||||
"ascending": "По возрастанию",
|
|
||||||
"descending": "По убыванию",
|
|
||||||
"deleteSort": "Удалить сортировку",
|
|
||||||
"addSort": "Добавить сортировку"
|
|
||||||
},
|
|
||||||
"row": {
|
|
||||||
"duplicate": "Дублировать",
|
|
||||||
"delete": "Удалить",
|
|
||||||
"textPlaceholder": "Пусто",
|
|
||||||
"copyProperty": "Свойство скопировано",
|
|
||||||
"count": "Количество",
|
|
||||||
"newRow": "Новая строка"
|
|
||||||
},
|
|
||||||
"selectOption": {
|
|
||||||
"create": "Создать",
|
|
||||||
"purpleColor": "Фиолетовый",
|
|
||||||
"pinkColor": "Розовый",
|
|
||||||
"lightPinkColor": "Светло-розовый",
|
|
||||||
"orangeColor": "Оранжевый",
|
|
||||||
"yellowColor": "Желтый",
|
|
||||||
"limeColor": "Ярко-зелёный",
|
|
||||||
"greenColor": "Зелёный",
|
|
||||||
"aquaColor": "Бирюзовый",
|
|
||||||
"blueColor": "Синий",
|
|
||||||
"deleteTag": "Удалить вариант",
|
|
||||||
"colorPanelTitle": "Цвета",
|
|
||||||
"panelTitle": "Выберите или создайте вариант",
|
|
||||||
"searchOption": "Поиск"
|
|
||||||
},
|
|
||||||
"checklist": {
|
|
||||||
"panelTitle": "Добавить элемент"
|
|
||||||
},
|
|
||||||
"menuName": "Сетка"
|
|
||||||
},
|
|
||||||
"document": {
|
|
||||||
"menuName": "Документ",
|
|
||||||
"date": {
|
|
||||||
"timeHintTextInTwelveHour": "01:00 PM",
|
|
||||||
"timeHintTextInTwentyFourHour": "13:00"
|
|
||||||
},
|
|
||||||
"slashMenu": {
|
|
||||||
"board": {
|
|
||||||
"selectABoardToLinkTo": "Выбрать доску для связи с"
|
|
||||||
},
|
|
||||||
"grid": {
|
|
||||||
"selectAGridToLinkTo": "Выберите сетку для связи с"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"plugins": {
|
|
||||||
"referencedBoard": "Связанные доски",
|
|
||||||
"referencedGrid": "Связанные сетки"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"board": {
|
|
||||||
"column": {
|
|
||||||
"create_new_card": "Создать"
|
|
||||||
},
|
|
||||||
"menuName": "Доска"
|
|
||||||
},
|
|
||||||
"calendar": {
|
|
||||||
"menuName": "Календарь",
|
|
||||||
"navigation": {
|
|
||||||
"today": "Сегодня",
|
|
||||||
"jumpToday": "Перейти к сегодняшнему дню",
|
|
||||||
"previousMonth": "Предыдущий месяц",
|
|
||||||
"nextMonth": "Следующий месяц"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -195,7 +195,7 @@
|
|||||||
"optionTitle": "Alternativ",
|
"optionTitle": "Alternativ",
|
||||||
"addOption": "Lägg till alternativ",
|
"addOption": "Lägg till alternativ",
|
||||||
"editProperty": "Redigera egenskap",
|
"editProperty": "Redigera egenskap",
|
||||||
"newColumn": "Ny kolumn",
|
"newProperty": "Ny kolumn",
|
||||||
"deleteFieldPromptMessage": "Är du säker? Denna egenskap kommer att raderas."
|
"deleteFieldPromptMessage": "Är du säker? Denna egenskap kommer att raderas."
|
||||||
},
|
},
|
||||||
"row": {
|
"row": {
|
||||||
|
@ -195,7 +195,7 @@
|
|||||||
"optionTitle": "标签",
|
"optionTitle": "标签",
|
||||||
"addOption": "添加标签",
|
"addOption": "添加标签",
|
||||||
"editProperty": "编辑列属性",
|
"editProperty": "编辑列属性",
|
||||||
"newColumn": "增加一列",
|
"newProperty": "增加一列",
|
||||||
"deleteFieldPromptMessage": "确定要删除这个属性吗? "
|
"deleteFieldPromptMessage": "确定要删除这个属性吗? "
|
||||||
},
|
},
|
||||||
"row": {
|
"row": {
|
||||||
|
@ -290,7 +290,7 @@
|
|||||||
"optionTitle": "選項",
|
"optionTitle": "選項",
|
||||||
"addOption": "新增選項",
|
"addOption": "新增選項",
|
||||||
"editProperty": "編輯內容",
|
"editProperty": "編輯內容",
|
||||||
"newColumn": "新欄位",
|
"newProperty": "新欄位",
|
||||||
"deleteFieldPromptMessage": "你確定嗎?這個內容將被刪除"
|
"deleteFieldPromptMessage": "你確定嗎?這個內容將被刪除"
|
||||||
},
|
},
|
||||||
"sort": {
|
"sort": {
|
||||||
|
@ -35,7 +35,9 @@ void main() {
|
|||||||
setUpAll(() async => await service.setUpAll());
|
setUpAll(() async => await service.setUpAll());
|
||||||
setUp(() async => await service.setUp());
|
setUp(() async => await service.setUp());
|
||||||
|
|
||||||
testWidgets('integration test unzips the proper workspace and loads it correctly.', (tester) async {
|
testWidgets(
|
||||||
|
'integration test unzips the proper workspace and loads it correctly.',
|
||||||
|
(tester) async {
|
||||||
await tester.initializeAppFlowy();
|
await tester.initializeAppFlowy();
|
||||||
expect(find.byType(AppFlowyBoard), findsOneWidget);
|
expect(find.byType(AppFlowyBoard), findsOneWidget);
|
||||||
});
|
});
|
||||||
|
@ -31,7 +31,8 @@ void main() {
|
|||||||
setUpAll(() async => await service.setUpAll());
|
setUpAll(() async => await service.setUpAll());
|
||||||
setUp(() async => await service.setUp());
|
setUp(() async => await service.setUp());
|
||||||
|
|
||||||
testWidgets('/board shortcut creates a new board and view of the board', (tester) async {
|
testWidgets('/board shortcut creates a new board and view of the board',
|
||||||
|
(tester) async {
|
||||||
await tester.initializeAppFlowy();
|
await tester.initializeAppFlowy();
|
||||||
|
|
||||||
// Needs tab to obtain focus for the app flowy editor.
|
// Needs tab to obtain focus for the app flowy editor.
|
||||||
@ -44,24 +45,30 @@ void main() {
|
|||||||
// does not contain any EditableText widgets.
|
// does not contain any EditableText widgets.
|
||||||
// to interact with the app during an integration test,
|
// to interact with the app during an integration test,
|
||||||
// simulate physical keyboard events.
|
// simulate physical keyboard events.
|
||||||
await FlowyTestKeyboard.simulateKeyDownEvent([
|
await FlowyTestKeyboard.simulateKeyDownEvent(
|
||||||
LogicalKeyboardKey.slash,
|
[
|
||||||
LogicalKeyboardKey.keyB,
|
LogicalKeyboardKey.slash,
|
||||||
LogicalKeyboardKey.keyO,
|
LogicalKeyboardKey.keyB,
|
||||||
LogicalKeyboardKey.keyA,
|
LogicalKeyboardKey.keyO,
|
||||||
LogicalKeyboardKey.keyR,
|
LogicalKeyboardKey.keyA,
|
||||||
LogicalKeyboardKey.keyD,
|
LogicalKeyboardKey.keyR,
|
||||||
LogicalKeyboardKey.arrowDown,
|
LogicalKeyboardKey.keyD,
|
||||||
], tester: tester);
|
LogicalKeyboardKey.arrowDown,
|
||||||
|
],
|
||||||
|
tester: tester,
|
||||||
|
);
|
||||||
|
|
||||||
// Checks whether the options in the selection menu
|
// Checks whether the options in the selection menu
|
||||||
// for /board exist.
|
// for /board exist.
|
||||||
expect(find.byType(SelectionMenuItemWidget), findsAtLeastNWidgets(2));
|
expect(find.byType(SelectionMenuItemWidget), findsAtLeastNWidgets(2));
|
||||||
|
|
||||||
// Finalizes the slash command that creates the board.
|
// Finalizes the slash command that creates the board.
|
||||||
await FlowyTestKeyboard.simulateKeyDownEvent([
|
await FlowyTestKeyboard.simulateKeyDownEvent(
|
||||||
LogicalKeyboardKey.enter,
|
[
|
||||||
], tester: tester);
|
LogicalKeyboardKey.enter,
|
||||||
|
],
|
||||||
|
tester: tester,
|
||||||
|
);
|
||||||
|
|
||||||
// Checks whether new board is referenced and properly on the page.
|
// Checks whether new board is referenced and properly on the page.
|
||||||
expect(find.byType(BuiltInPageWidget), findsOneWidget);
|
expect(find.byType(BuiltInPageWidget), findsOneWidget);
|
||||||
@ -75,7 +82,8 @@ void main() {
|
|||||||
expect(find.text(viewOfBoardLabel), findsNWidgets(2));
|
expect(find.text(viewOfBoardLabel), findsNWidgets(2));
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('/grid shortcut creates a new grid and view of the grid', (tester) async {
|
testWidgets('/grid shortcut creates a new grid and view of the grid',
|
||||||
|
(tester) async {
|
||||||
await tester.initializeAppFlowy();
|
await tester.initializeAppFlowy();
|
||||||
|
|
||||||
// Needs tab to obtain focus for the app flowy editor.
|
// Needs tab to obtain focus for the app flowy editor.
|
||||||
@ -88,14 +96,17 @@ void main() {
|
|||||||
// does not contain any EditableText widgets.
|
// does not contain any EditableText widgets.
|
||||||
// to interact with the app during an integration test,
|
// to interact with the app during an integration test,
|
||||||
// simulate physical keyboard events.
|
// simulate physical keyboard events.
|
||||||
await FlowyTestKeyboard.simulateKeyDownEvent([
|
await FlowyTestKeyboard.simulateKeyDownEvent(
|
||||||
LogicalKeyboardKey.slash,
|
[
|
||||||
LogicalKeyboardKey.keyG,
|
LogicalKeyboardKey.slash,
|
||||||
LogicalKeyboardKey.keyR,
|
LogicalKeyboardKey.keyG,
|
||||||
LogicalKeyboardKey.keyI,
|
LogicalKeyboardKey.keyR,
|
||||||
LogicalKeyboardKey.keyD,
|
LogicalKeyboardKey.keyI,
|
||||||
LogicalKeyboardKey.arrowDown,
|
LogicalKeyboardKey.keyD,
|
||||||
], tester: tester);
|
LogicalKeyboardKey.arrowDown,
|
||||||
|
],
|
||||||
|
tester: tester,
|
||||||
|
);
|
||||||
|
|
||||||
// Checks whether the options in the selection menu
|
// Checks whether the options in the selection menu
|
||||||
// for /grid exist.
|
// for /grid exist.
|
||||||
|
@ -61,6 +61,8 @@ class TestWorkspaceService {
|
|||||||
InputFileStream(await workspace.zip.then((value) => value.path));
|
InputFileStream(await workspace.zip.then((value) => value.path));
|
||||||
final archive = ZipDecoder().decodeBuffer(inputStream);
|
final archive = ZipDecoder().decodeBuffer(inputStream);
|
||||||
extractArchiveToDisk(
|
extractArchiveToDisk(
|
||||||
archive, await TestWorkspace._parent.then((value) => value.path));
|
archive,
|
||||||
|
await TestWorkspace._parent.then((value) => value.path),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,10 @@ import 'package:flutter/services.dart';
|
|||||||
import 'package:flutter_test/flutter_test.dart' as flutter_test;
|
import 'package:flutter_test/flutter_test.dart' as flutter_test;
|
||||||
|
|
||||||
class FlowyTestKeyboard {
|
class FlowyTestKeyboard {
|
||||||
static Future<void> simulateKeyDownEvent(List<LogicalKeyboardKey> keys,
|
static Future<void> simulateKeyDownEvent(
|
||||||
{required flutter_test.WidgetTester tester}) async {
|
List<LogicalKeyboardKey> keys, {
|
||||||
|
required flutter_test.WidgetTester tester,
|
||||||
|
}) async {
|
||||||
for (final LogicalKeyboardKey key in keys) {
|
for (final LogicalKeyboardKey key in keys) {
|
||||||
await flutter_test.simulateKeyDownEvent(key);
|
await flutter_test.simulateKeyDownEvent(key);
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
@ -16,9 +16,10 @@ typedef FolderNotificationCallback = void Function(
|
|||||||
|
|
||||||
class FolderNotificationParser
|
class FolderNotificationParser
|
||||||
extends NotificationParser<FolderNotification, FlowyError> {
|
extends NotificationParser<FolderNotification, FlowyError> {
|
||||||
FolderNotificationParser(
|
FolderNotificationParser({
|
||||||
{String? id, required FolderNotificationCallback callback})
|
String? id,
|
||||||
: super(
|
required FolderNotificationCallback callback,
|
||||||
|
}) : super(
|
||||||
id: id,
|
id: id,
|
||||||
callback: callback,
|
callback: callback,
|
||||||
tyParser: (ty) => FolderNotification.valueOf(ty),
|
tyParser: (ty) => FolderNotification.valueOf(ty),
|
||||||
|
@ -16,9 +16,10 @@ typedef DatabaseNotificationCallback = void Function(
|
|||||||
|
|
||||||
class DatabaseNotificationParser
|
class DatabaseNotificationParser
|
||||||
extends NotificationParser<DatabaseNotification, FlowyError> {
|
extends NotificationParser<DatabaseNotification, FlowyError> {
|
||||||
DatabaseNotificationParser(
|
DatabaseNotificationParser({
|
||||||
{String? id, required DatabaseNotificationCallback callback})
|
String? id,
|
||||||
: super(
|
required DatabaseNotificationCallback callback,
|
||||||
|
}) : super(
|
||||||
id: id,
|
id: id,
|
||||||
callback: callback,
|
callback: callback,
|
||||||
tyParser: (ty) => DatabaseNotification.valueOf(ty),
|
tyParser: (ty) => DatabaseNotification.valueOf(ty),
|
||||||
@ -27,7 +28,9 @@ class DatabaseNotificationParser
|
|||||||
}
|
}
|
||||||
|
|
||||||
typedef DatabaseNotificationHandler = Function(
|
typedef DatabaseNotificationHandler = Function(
|
||||||
DatabaseNotification ty, Either<Uint8List, FlowyError> result);
|
DatabaseNotification ty,
|
||||||
|
Either<Uint8List, FlowyError> result,
|
||||||
|
);
|
||||||
|
|
||||||
class DatabaseNotificationListener {
|
class DatabaseNotificationListener {
|
||||||
StreamSubscription<SubscribeObject>? _subscription;
|
StreamSubscription<SubscribeObject>? _subscription;
|
||||||
|
@ -9,11 +9,12 @@ class NotificationParser<T, E> {
|
|||||||
T? Function(int) tyParser;
|
T? Function(int) tyParser;
|
||||||
E Function(Uint8List) errorParser;
|
E Function(Uint8List) errorParser;
|
||||||
|
|
||||||
NotificationParser(
|
NotificationParser({
|
||||||
{this.id,
|
this.id,
|
||||||
required this.callback,
|
required this.callback,
|
||||||
required this.errorParser,
|
required this.errorParser,
|
||||||
required this.tyParser});
|
required this.tyParser,
|
||||||
|
});
|
||||||
void parse(SubscribeObject subject) {
|
void parse(SubscribeObject subject) {
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
if (subject.id != id) {
|
if (subject.id != id) {
|
||||||
|
@ -16,9 +16,10 @@ typedef UserNotificationCallback = void Function(
|
|||||||
|
|
||||||
class UserNotificationParser
|
class UserNotificationParser
|
||||||
extends NotificationParser<UserNotification, FlowyError> {
|
extends NotificationParser<UserNotification, FlowyError> {
|
||||||
UserNotificationParser(
|
UserNotificationParser({
|
||||||
{required String id, required UserNotificationCallback callback})
|
required String id,
|
||||||
: super(
|
required UserNotificationCallback callback,
|
||||||
|
}) : super(
|
||||||
id: id,
|
id: id,
|
||||||
callback: callback,
|
callback: callback,
|
||||||
tyParser: (ty) => UserNotification.valueOf(ty),
|
tyParser: (ty) => UserNotification.valueOf(ty),
|
||||||
@ -27,7 +28,9 @@ class UserNotificationParser
|
|||||||
}
|
}
|
||||||
|
|
||||||
typedef UserNotificationHandler = Function(
|
typedef UserNotificationHandler = Function(
|
||||||
UserNotification ty, Either<Uint8List, FlowyError> result);
|
UserNotification ty,
|
||||||
|
Either<Uint8List, FlowyError> result,
|
||||||
|
);
|
||||||
|
|
||||||
class UserNotificationListener {
|
class UserNotificationListener {
|
||||||
StreamSubscription<SubscribeObject>? _subscription;
|
StreamSubscription<SubscribeObject>? _subscription;
|
||||||
|
@ -73,28 +73,35 @@ class CellController<T, D> extends Equatable {
|
|||||||
/// For example:
|
/// For example:
|
||||||
/// user input: 12
|
/// user input: 12
|
||||||
/// cell display: $12
|
/// cell display: $12
|
||||||
_cellListener?.start(onCellChanged: (result) {
|
_cellListener?.start(
|
||||||
result.fold(
|
onCellChanged: (result) {
|
||||||
(_) {
|
result.fold(
|
||||||
_cellCache.remove(_cacheKey);
|
(_) {
|
||||||
_loadData();
|
_cellCache.remove(_cacheKey);
|
||||||
},
|
_loadData();
|
||||||
(err) => Log.error(err),
|
},
|
||||||
);
|
(err) => Log.error(err),
|
||||||
});
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
/// 2.Listen on the field event and load the cell data if needed.
|
/// 2.Listen on the field event and load the cell data if needed.
|
||||||
_fieldListener.start(onFieldChanged: (result) {
|
_fieldListener.start(
|
||||||
result.fold((fieldPB) {
|
onFieldChanged: (result) {
|
||||||
/// reloadOnFieldChanged should be true if you need to load the data when the corresponding field is changed
|
result.fold(
|
||||||
/// For example:
|
(fieldPB) {
|
||||||
/// ¥12 -> $12
|
/// reloadOnFieldChanged should be true if you need to load the data when the corresponding field is changed
|
||||||
if (_cellDataLoader.reloadOnFieldChanged) {
|
/// For example:
|
||||||
_loadData();
|
/// ¥12 -> $12
|
||||||
}
|
if (_cellDataLoader.reloadOnFieldChanged) {
|
||||||
_onCellFieldChanged?.call();
|
_loadData();
|
||||||
}, (err) => Log.error(err));
|
}
|
||||||
});
|
_onCellFieldChanged?.call();
|
||||||
|
},
|
||||||
|
(err) => Log.error(err),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Listen on the cell content or field changes
|
/// Listen on the cell content or field changes
|
||||||
@ -130,7 +137,8 @@ class CellController<T, D> extends Equatable {
|
|||||||
/// Return the TypeOptionPB that can be parsed into corresponding class using the [parser].
|
/// Return the TypeOptionPB that can be parsed into corresponding class using the [parser].
|
||||||
/// [PD] is the type that the parser return.
|
/// [PD] is the type that the parser return.
|
||||||
Future<Either<PD, FlowyError>> getTypeOption<PD, P extends TypeOptionParser>(
|
Future<Either<PD, FlowyError>> getTypeOption<PD, P extends TypeOptionParser>(
|
||||||
P parser) {
|
P parser,
|
||||||
|
) {
|
||||||
return _fieldBackendSvc
|
return _fieldBackendSvc
|
||||||
.getFieldTypeOptionData(fieldType: fieldType)
|
.getFieldTypeOptionData(fieldType: fieldType)
|
||||||
.then((result) {
|
.then((result) {
|
||||||
|
@ -19,7 +19,9 @@ class CellListener {
|
|||||||
void start({required void Function(UpdateFieldNotifiedValue) onCellChanged}) {
|
void start({required void Function(UpdateFieldNotifiedValue) onCellChanged}) {
|
||||||
_updateCellNotifier?.addPublishListener(onCellChanged);
|
_updateCellNotifier?.addPublishListener(onCellChanged);
|
||||||
_listener = DatabaseNotificationListener(
|
_listener = DatabaseNotificationListener(
|
||||||
objectId: "$rowId:$fieldId", handler: _handler);
|
objectId: "$rowId:$fieldId",
|
||||||
|
handler: _handler,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handler(DatabaseNotification ty, Either<Uint8List, FlowyError> result) {
|
void _handler(DatabaseNotification ty, Either<Uint8List, FlowyError> result) {
|
||||||
|
@ -187,8 +187,10 @@ class DatabaseController {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Either<Unit, FlowyError>> moveGroup(
|
Future<Either<Unit, FlowyError>> moveGroup({
|
||||||
{required String fromGroupId, required String toGroupId}) {
|
required String fromGroupId,
|
||||||
|
required String toGroupId,
|
||||||
|
}) {
|
||||||
return _databaseViewBackendSvc.moveGroup(
|
return _databaseViewBackendSvc.moveGroup(
|
||||||
fromGroupId: fromGroupId,
|
fromGroupId: fromGroupId,
|
||||||
toGroupId: toGroupId,
|
toGroupId: toGroupId,
|
||||||
@ -196,7 +198,8 @@ class DatabaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> updateCalenderLayoutSetting(
|
Future<void> updateCalenderLayoutSetting(
|
||||||
CalendarLayoutSettingsPB layoutSetting) async {
|
CalendarLayoutSettingsPB layoutSetting,
|
||||||
|
) async {
|
||||||
await _databaseViewBackendSvc
|
await _databaseViewBackendSvc
|
||||||
.updateLayoutSetting(calendarLayoutSetting: layoutSetting)
|
.updateLayoutSetting(calendarLayoutSetting: layoutSetting)
|
||||||
.then((result) {
|
.then((result) {
|
||||||
@ -234,16 +237,20 @@ class DatabaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _listenOnRowsChanged() {
|
void _listenOnRowsChanged() {
|
||||||
final callbacks =
|
final callbacks = DatabaseViewCallbacks(
|
||||||
DatabaseViewCallbacks(onRowsChanged: (rows, rowByRowId, reason) {
|
onRowsChanged: (rows, rowByRowId, reason) {
|
||||||
_databaseCallbacks?.onRowsChanged?.call(rows, rowByRowId, reason);
|
_databaseCallbacks?.onRowsChanged?.call(rows, rowByRowId, reason);
|
||||||
}, onRowsDeleted: (ids) {
|
},
|
||||||
_databaseCallbacks?.onRowsDeleted?.call(ids);
|
onRowsDeleted: (ids) {
|
||||||
}, onRowsUpdated: (ids) {
|
_databaseCallbacks?.onRowsDeleted?.call(ids);
|
||||||
_databaseCallbacks?.onRowsUpdated?.call(ids);
|
},
|
||||||
}, onRowsCreated: (ids) {
|
onRowsUpdated: (ids) {
|
||||||
_databaseCallbacks?.onRowsCreated?.call(ids);
|
_databaseCallbacks?.onRowsUpdated?.call(ids);
|
||||||
});
|
},
|
||||||
|
onRowsCreated: (ids) {
|
||||||
|
_databaseCallbacks?.onRowsCreated?.call(ids);
|
||||||
|
},
|
||||||
|
);
|
||||||
_viewCache.addListener(callbacks);
|
_viewCache.addListener(callbacks);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,42 +268,58 @@ class DatabaseController {
|
|||||||
void _listenOnGroupChanged() {
|
void _listenOnGroupChanged() {
|
||||||
groupListener.start(
|
groupListener.start(
|
||||||
onNumOfGroupsChanged: (result) {
|
onNumOfGroupsChanged: (result) {
|
||||||
result.fold((changeset) {
|
result.fold(
|
||||||
if (changeset.updateGroups.isNotEmpty) {
|
(changeset) {
|
||||||
_groupCallbacks?.onUpdateGroup?.call(changeset.updateGroups);
|
if (changeset.updateGroups.isNotEmpty) {
|
||||||
}
|
_groupCallbacks?.onUpdateGroup?.call(changeset.updateGroups);
|
||||||
|
}
|
||||||
|
|
||||||
if (changeset.deletedGroups.isNotEmpty) {
|
if (changeset.deletedGroups.isNotEmpty) {
|
||||||
_groupCallbacks?.onDeleteGroup?.call(changeset.deletedGroups);
|
_groupCallbacks?.onDeleteGroup?.call(changeset.deletedGroups);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (final insertedGroup in changeset.insertedGroups) {
|
for (final insertedGroup in changeset.insertedGroups) {
|
||||||
_groupCallbacks?.onInsertGroup?.call(insertedGroup);
|
_groupCallbacks?.onInsertGroup?.call(insertedGroup);
|
||||||
}
|
}
|
||||||
}, (r) => Log.error(r));
|
},
|
||||||
|
(r) => Log.error(r),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
onGroupByNewField: (result) {
|
onGroupByNewField: (result) {
|
||||||
result.fold((groups) {
|
result.fold(
|
||||||
_groupCallbacks?.onGroupByField?.call(groups);
|
(groups) {
|
||||||
}, (r) => Log.error(r));
|
_groupCallbacks?.onGroupByField?.call(groups);
|
||||||
|
},
|
||||||
|
(r) => Log.error(r),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _listenOnLayoutChanged() {
|
void _listenOnLayoutChanged() {
|
||||||
layoutListener.start(onLayoutChanged: (result) {
|
layoutListener.start(
|
||||||
result.fold((l) {
|
onLayoutChanged: (result) {
|
||||||
_layoutCallbacks?.onLayoutChanged(l);
|
result.fold(
|
||||||
}, (r) => Log.error(r));
|
(l) {
|
||||||
});
|
_layoutCallbacks?.onLayoutChanged(l);
|
||||||
|
},
|
||||||
|
(r) => Log.error(r),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _listenOnCalendarLayoutChanged() {
|
void _listenOnCalendarLayoutChanged() {
|
||||||
calendarLayoutListener.start(onCalendarLayoutChanged: (result) {
|
calendarLayoutListener.start(
|
||||||
result.fold((l) {
|
onCalendarLayoutChanged: (result) {
|
||||||
_calendarLayoutCallbacks?.onCalendarLayoutChanged(l);
|
result.fold(
|
||||||
}, (r) => Log.error(r));
|
(l) {
|
||||||
});
|
_calendarLayoutCallbacks?.onCalendarLayoutChanged(l);
|
||||||
|
},
|
||||||
|
(r) => Log.error(r),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,8 +73,9 @@ class DatabaseViewBackendService {
|
|||||||
return DatabaseEventMoveGroup(payload).send();
|
return DatabaseEventMoveGroup(payload).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Either<List<FieldPB>, FlowyError>> getFields(
|
Future<Either<List<FieldPB>, FlowyError>> getFields({
|
||||||
{List<FieldIdPB>? fieldIds}) {
|
List<FieldIdPB>? fieldIds,
|
||||||
|
}) {
|
||||||
var payload = GetFieldPayloadPB.create()..viewId = viewId;
|
var payload = GetFieldPayloadPB.create()..viewId = viewId;
|
||||||
|
|
||||||
if (fieldIds != null) {
|
if (fieldIds != null) {
|
||||||
@ -86,15 +87,17 @@ class DatabaseViewBackendService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<Either<LayoutSettingPB, FlowyError>> getLayoutSetting(
|
Future<Either<LayoutSettingPB, FlowyError>> getLayoutSetting(
|
||||||
DatabaseLayoutPB layoutType) {
|
DatabaseLayoutPB layoutType,
|
||||||
|
) {
|
||||||
final payload = DatabaseLayoutIdPB.create()
|
final payload = DatabaseLayoutIdPB.create()
|
||||||
..viewId = viewId
|
..viewId = viewId
|
||||||
..layout = layoutType;
|
..layout = layoutType;
|
||||||
return DatabaseEventGetLayoutSetting(payload).send();
|
return DatabaseEventGetLayoutSetting(payload).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Either<Unit, FlowyError>> updateLayoutSetting(
|
Future<Either<Unit, FlowyError>> updateLayoutSetting({
|
||||||
{CalendarLayoutSettingsPB? calendarLayoutSetting}) {
|
CalendarLayoutSettingsPB? calendarLayoutSetting,
|
||||||
|
}) {
|
||||||
final layoutSetting = LayoutSettingPB.create();
|
final layoutSetting = LayoutSettingPB.create();
|
||||||
if (calendarLayoutSetting != null) {
|
if (calendarLayoutSetting != null) {
|
||||||
layoutSetting.calendar = calendarLayoutSetting;
|
layoutSetting.calendar = calendarLayoutSetting;
|
||||||
|
@ -17,7 +17,9 @@ class FieldCellBloc extends Bloc<FieldCellEvent, FieldCellState> {
|
|||||||
required FieldCellContext cellContext,
|
required FieldCellContext cellContext,
|
||||||
}) : _fieldListener = SingleFieldListener(fieldId: cellContext.field.id),
|
}) : _fieldListener = SingleFieldListener(fieldId: cellContext.field.id),
|
||||||
_fieldBackendSvc = FieldBackendService(
|
_fieldBackendSvc = FieldBackendService(
|
||||||
viewId: cellContext.viewId, fieldId: cellContext.field.id),
|
viewId: cellContext.viewId,
|
||||||
|
fieldId: cellContext.field.id,
|
||||||
|
),
|
||||||
super(FieldCellState.initial(cellContext)) {
|
super(FieldCellState.initial(cellContext)) {
|
||||||
on<FieldCellEvent>(
|
on<FieldCellEvent>(
|
||||||
(event, emit) async {
|
(event, emit) async {
|
||||||
@ -49,15 +51,17 @@ class FieldCellBloc extends Bloc<FieldCellEvent, FieldCellState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _startListening() {
|
void _startListening() {
|
||||||
_fieldListener.start(onFieldChanged: (result) {
|
_fieldListener.start(
|
||||||
if (isClosed) {
|
onFieldChanged: (result) {
|
||||||
return;
|
if (isClosed) {
|
||||||
}
|
return;
|
||||||
result.fold(
|
}
|
||||||
(field) => add(FieldCellEvent.didReceiveFieldUpdate(field)),
|
result.fold(
|
||||||
(err) => Log.error(err),
|
(field) => add(FieldCellEvent.didReceiveFieldUpdate(field)),
|
||||||
);
|
(err) => Log.error(err),
|
||||||
});
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,24 +255,26 @@ class FieldController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_filtersListener.start(onFilterChanged: (result) {
|
_filtersListener.start(
|
||||||
result.fold(
|
onFilterChanged: (result) {
|
||||||
(FilterChangesetNotificationPB changeset) {
|
result.fold(
|
||||||
final List<FilterInfo> filters = filterInfos;
|
(FilterChangesetNotificationPB changeset) {
|
||||||
// Deletes the filters
|
final List<FilterInfo> filters = filterInfos;
|
||||||
deleteFilterFromChangeset(filters, changeset);
|
// Deletes the filters
|
||||||
|
deleteFilterFromChangeset(filters, changeset);
|
||||||
|
|
||||||
// Inserts the new filter if it's not exist
|
// Inserts the new filter if it's not exist
|
||||||
insertFilterFromChangeset(filters, changeset);
|
insertFilterFromChangeset(filters, changeset);
|
||||||
|
|
||||||
updateFilterFromChangeset(filters, changeset);
|
updateFilterFromChangeset(filters, changeset);
|
||||||
|
|
||||||
_updateFieldInfos();
|
_updateFieldInfos();
|
||||||
_filterNotifier?.filters = filters;
|
_filterNotifier?.filters = filters;
|
||||||
},
|
},
|
||||||
(err) => Log.error(err),
|
(err) => Log.error(err),
|
||||||
);
|
);
|
||||||
});
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _listenOnSortChanged() {
|
void _listenOnSortChanged() {
|
||||||
@ -347,48 +349,54 @@ class FieldController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_sortsListener.start(onSortChanged: (result) {
|
_sortsListener.start(
|
||||||
result.fold(
|
onSortChanged: (result) {
|
||||||
(SortChangesetNotificationPB changeset) {
|
result.fold(
|
||||||
final List<SortInfo> newSortInfos = sortInfos;
|
(SortChangesetNotificationPB changeset) {
|
||||||
deleteSortFromChangeset(newSortInfos, changeset);
|
final List<SortInfo> newSortInfos = sortInfos;
|
||||||
insertSortFromChangeset(newSortInfos, changeset);
|
deleteSortFromChangeset(newSortInfos, changeset);
|
||||||
updateSortFromChangeset(newSortInfos, changeset);
|
insertSortFromChangeset(newSortInfos, changeset);
|
||||||
|
updateSortFromChangeset(newSortInfos, changeset);
|
||||||
|
|
||||||
_updateFieldInfos();
|
_updateFieldInfos();
|
||||||
_sortNotifier?.sorts = newSortInfos;
|
_sortNotifier?.sorts = newSortInfos;
|
||||||
},
|
},
|
||||||
(err) => Log.error(err),
|
(err) => Log.error(err),
|
||||||
);
|
);
|
||||||
});
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _listenOnSettingChanges() {
|
void _listenOnSettingChanges() {
|
||||||
//Listen on setting changes
|
//Listen on setting changes
|
||||||
_settingListener.start(onSettingUpdated: (result) {
|
_settingListener.start(
|
||||||
result.fold(
|
onSettingUpdated: (result) {
|
||||||
(setting) => _updateSetting(setting),
|
result.fold(
|
||||||
(r) => Log.error(r),
|
(setting) => _updateSetting(setting),
|
||||||
);
|
(r) => Log.error(r),
|
||||||
});
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _listenOnFieldChanges() {
|
void _listenOnFieldChanges() {
|
||||||
//Listen on field's changes
|
//Listen on field's changes
|
||||||
_fieldListener.start(onFieldsChanged: (result) {
|
_fieldListener.start(
|
||||||
result.fold(
|
onFieldsChanged: (result) {
|
||||||
(changeset) {
|
result.fold(
|
||||||
_deleteFields(changeset.deletedFields);
|
(changeset) {
|
||||||
_insertFields(changeset.insertedFields);
|
_deleteFields(changeset.deletedFields);
|
||||||
|
_insertFields(changeset.insertedFields);
|
||||||
|
|
||||||
final updatedFields = _updateFields(changeset.updatedFields);
|
final updatedFields = _updateFields(changeset.updatedFields);
|
||||||
for (final listener in _updatedFieldCallbacks.values) {
|
for (final listener in _updatedFieldCallbacks.values) {
|
||||||
listener(updatedFields);
|
listener(updatedFields);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
(err) => Log.error(err),
|
(err) => Log.error(err),
|
||||||
);
|
);
|
||||||
});
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _updateSetting(DatabaseViewSettingPB setting) {
|
void _updateSetting(DatabaseViewSettingPB setting) {
|
||||||
|
@ -36,11 +36,13 @@ class FieldEditorBloc extends Bloc<FieldEditorEvent, FieldEditorState> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
didReceiveFieldChanged: (FieldPB field) {
|
didReceiveFieldChanged: (FieldPB field) {
|
||||||
emit(state.copyWith(
|
emit(
|
||||||
field: Some(field),
|
state.copyWith(
|
||||||
name: field.name,
|
field: Some(field),
|
||||||
canDelete: field.isPrimary,
|
name: field.name,
|
||||||
));
|
canDelete: field.isPrimary,
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
deleteField: () {
|
deleteField: () {
|
||||||
state.field.fold(
|
state.field.fold(
|
||||||
|
@ -17,8 +17,9 @@ class SingleFieldListener {
|
|||||||
|
|
||||||
SingleFieldListener({required this.fieldId});
|
SingleFieldListener({required this.fieldId});
|
||||||
|
|
||||||
void start(
|
void start({
|
||||||
{required void Function(UpdateFieldNotifiedValue) onFieldChanged}) {
|
required void Function(UpdateFieldNotifiedValue) onFieldChanged,
|
||||||
|
}) {
|
||||||
_updateFieldNotifier?.addPublishListener(onFieldChanged);
|
_updateFieldNotifier?.addPublishListener(onFieldChanged);
|
||||||
_listener = DatabaseNotificationListener(
|
_listener = DatabaseNotificationListener(
|
||||||
objectId: fieldId,
|
objectId: fieldId,
|
||||||
@ -60,8 +61,9 @@ class FieldsListener {
|
|||||||
DatabaseNotificationListener? _listener;
|
DatabaseNotificationListener? _listener;
|
||||||
FieldsListener({required this.viewId});
|
FieldsListener({required this.viewId});
|
||||||
|
|
||||||
void start(
|
void start({
|
||||||
{required void Function(UpdateFieldsNotifiedValue) onFieldsChanged}) {
|
required void Function(UpdateFieldsNotifiedValue) onFieldsChanged,
|
||||||
|
}) {
|
||||||
updateFieldsNotifier?.addPublishListener(onFieldsChanged);
|
updateFieldsNotifier?.addPublishListener(onFieldsChanged);
|
||||||
_listener = DatabaseNotificationListener(
|
_listener = DatabaseNotificationListener(
|
||||||
objectId: viewId,
|
objectId: viewId,
|
||||||
|
@ -15,16 +15,25 @@ class DateTypeOptionBloc
|
|||||||
(event, emit) async {
|
(event, emit) async {
|
||||||
event.map(
|
event.map(
|
||||||
didSelectDateFormat: (_DidSelectDateFormat value) {
|
didSelectDateFormat: (_DidSelectDateFormat value) {
|
||||||
emit(state.copyWith(
|
emit(
|
||||||
typeOption: _updateTypeOption(dateFormat: value.format)));
|
state.copyWith(
|
||||||
|
typeOption: _updateTypeOption(dateFormat: value.format),
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
didSelectTimeFormat: (_DidSelectTimeFormat value) {
|
didSelectTimeFormat: (_DidSelectTimeFormat value) {
|
||||||
emit(state.copyWith(
|
emit(
|
||||||
typeOption: _updateTypeOption(timeFormat: value.format)));
|
state.copyWith(
|
||||||
|
typeOption: _updateTypeOption(timeFormat: value.format),
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
includeTime: (_IncludeTime value) {
|
includeTime: (_IncludeTime value) {
|
||||||
emit(state.copyWith(
|
emit(
|
||||||
typeOption: _updateTypeOption(includeTime: value.includeTime)));
|
state.copyWith(
|
||||||
|
typeOption: _updateTypeOption(includeTime: value.includeTime),
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -7,16 +7,20 @@ class NumberFormatBloc extends Bloc<NumberFormatEvent, NumberFormatState> {
|
|||||||
NumberFormatBloc() : super(NumberFormatState.initial()) {
|
NumberFormatBloc() : super(NumberFormatState.initial()) {
|
||||||
on<NumberFormatEvent>(
|
on<NumberFormatEvent>(
|
||||||
(event, emit) async {
|
(event, emit) async {
|
||||||
event.map(setFilter: (_SetFilter value) {
|
event.map(
|
||||||
final List<NumberFormat> formats = List.from(NumberFormat.values);
|
setFilter: (_SetFilter value) {
|
||||||
if (value.filter.isNotEmpty) {
|
final List<NumberFormat> formats = List.from(NumberFormat.values);
|
||||||
formats.retainWhere((element) => element
|
if (value.filter.isNotEmpty) {
|
||||||
.title()
|
formats.retainWhere(
|
||||||
.toLowerCase()
|
(element) => element
|
||||||
.contains(value.filter.toLowerCase()));
|
.title()
|
||||||
}
|
.toLowerCase()
|
||||||
emit(state.copyWith(formats: formats, filter: value.filter));
|
.contains(value.filter.toLowerCase()),
|
||||||
});
|
);
|
||||||
|
}
|
||||||
|
emit(state.copyWith(formats: formats, filter: value.filter));
|
||||||
|
},
|
||||||
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -59,9 +59,11 @@ class SelectOptionTypeOptionEvent with _$SelectOptionTypeOptionEvent {
|
|||||||
const factory SelectOptionTypeOptionEvent.endAddingOption() =
|
const factory SelectOptionTypeOptionEvent.endAddingOption() =
|
||||||
_EndAddingOption;
|
_EndAddingOption;
|
||||||
const factory SelectOptionTypeOptionEvent.updateOption(
|
const factory SelectOptionTypeOptionEvent.updateOption(
|
||||||
SelectOptionPB option) = _UpdateOption;
|
SelectOptionPB option,
|
||||||
|
) = _UpdateOption;
|
||||||
const factory SelectOptionTypeOptionEvent.deleteOption(
|
const factory SelectOptionTypeOptionEvent.deleteOption(
|
||||||
SelectOptionPB option) = _DeleteOption;
|
SelectOptionPB option,
|
||||||
|
) = _DeleteOption;
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
|
@ -158,7 +158,9 @@ abstract class IFieldTypeOptionLoader {
|
|||||||
Future<Either<TypeOptionPB, FlowyError>> load();
|
Future<Either<TypeOptionPB, FlowyError>> load();
|
||||||
|
|
||||||
Future<Either<Unit, FlowyError>> switchToField(
|
Future<Either<Unit, FlowyError>> switchToField(
|
||||||
String fieldId, FieldType fieldType) {
|
String fieldId,
|
||||||
|
FieldType fieldType,
|
||||||
|
) {
|
||||||
final payload = UpdateFieldTypePayloadPB.create()
|
final payload = UpdateFieldTypePayloadPB.create()
|
||||||
..viewId = viewId
|
..viewId = viewId
|
||||||
..fieldId = fieldId
|
..fieldId = fieldId
|
||||||
|
@ -107,7 +107,8 @@ class FilterListener {
|
|||||||
case DatabaseNotification.DidUpdateFilter:
|
case DatabaseNotification.DidUpdateFilter:
|
||||||
result.fold(
|
result.fold(
|
||||||
(payload) => handleChangeset(
|
(payload) => handleChangeset(
|
||||||
FilterChangesetNotificationPB.fromBuffer(payload)),
|
FilterChangesetNotificationPB.fromBuffer(payload),
|
||||||
|
),
|
||||||
(error) {},
|
(error) {},
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
@ -97,7 +97,8 @@ class FilterBackendService {
|
|||||||
filter.end = $fixnum.Int64(end);
|
filter.end = $fixnum.Int64(end);
|
||||||
} else {
|
} else {
|
||||||
throw Exception(
|
throw Exception(
|
||||||
"Start and end should not be null if the timestamp is null");
|
"Start and end should not be null if the timestamp is null",
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,8 +15,9 @@ class DatabaseCalendarLayoutListener {
|
|||||||
DatabaseNotificationListener? _listener;
|
DatabaseNotificationListener? _listener;
|
||||||
DatabaseCalendarLayoutListener(this.viewId);
|
DatabaseCalendarLayoutListener(this.viewId);
|
||||||
|
|
||||||
void start(
|
void start({
|
||||||
{required void Function(NewLayoutFieldValue) onCalendarLayoutChanged}) {
|
required void Function(NewLayoutFieldValue) onCalendarLayoutChanged,
|
||||||
|
}) {
|
||||||
_newLayoutFieldNotifier?.addPublishListener(onCalendarLayoutChanged);
|
_newLayoutFieldNotifier?.addPublishListener(onCalendarLayoutChanged);
|
||||||
_listener = DatabaseNotificationListener(
|
_listener = DatabaseNotificationListener(
|
||||||
objectId: viewId,
|
objectId: viewId,
|
||||||
|
@ -102,11 +102,16 @@ class RowCache {
|
|||||||
final rowInfo = _rowList.get(reorderRow.rowId);
|
final rowInfo = _rowList.get(reorderRow.rowId);
|
||||||
if (rowInfo != null) {
|
if (rowInfo != null) {
|
||||||
_rowList.moveRow(
|
_rowList.moveRow(
|
||||||
reorderRow.rowId, reorderRow.oldIndex, reorderRow.newIndex);
|
reorderRow.rowId,
|
||||||
_rowChangeReasonNotifier.receive(RowsChangedReason.reorderSingleRow(
|
reorderRow.oldIndex,
|
||||||
reorderRow,
|
reorderRow.newIndex,
|
||||||
rowInfo,
|
);
|
||||||
));
|
_rowChangeReasonNotifier.receive(
|
||||||
|
RowsChangedReason.reorderSingleRow(
|
||||||
|
reorderRow,
|
||||||
|
rowInfo,
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,7 +330,9 @@ class RowsChangedReason with _$RowsChangedReason {
|
|||||||
const factory RowsChangedReason.initial() = InitialListState;
|
const factory RowsChangedReason.initial() = InitialListState;
|
||||||
const factory RowsChangedReason.reorderRows() = _ReorderRows;
|
const factory RowsChangedReason.reorderRows() = _ReorderRows;
|
||||||
const factory RowsChangedReason.reorderSingleRow(
|
const factory RowsChangedReason.reorderSingleRow(
|
||||||
ReorderSingleRowPB reorderRow, RowInfo rowInfo) = _ReorderSingleRow;
|
ReorderSingleRowPB reorderRow,
|
||||||
|
RowInfo rowInfo,
|
||||||
|
) = _ReorderSingleRow;
|
||||||
}
|
}
|
||||||
|
|
||||||
class InsertedIndex {
|
class InsertedIndex {
|
||||||
|
@ -23,10 +23,12 @@ class RowController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void addListener({OnRowChanged? onRowChanged}) {
|
void addListener({OnRowChanged? onRowChanged}) {
|
||||||
_onRowChangedListeners.add(_rowCache.addListener(
|
_onRowChangedListeners.add(
|
||||||
rowId: rowId,
|
_rowCache.addListener(
|
||||||
onCellUpdated: onRowChanged,
|
rowId: rowId,
|
||||||
));
|
onCellUpdated: onRowChanged,
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
@ -85,10 +85,12 @@ class RowList {
|
|||||||
insert(index, builder(insertRow.row));
|
insert(index, builder(insertRow.row));
|
||||||
|
|
||||||
if (!isContains) {
|
if (!isContains) {
|
||||||
insertIndexs.add(InsertedIndex(
|
insertIndexs.add(
|
||||||
index: index,
|
InsertedIndex(
|
||||||
rowId: insertRow.row.id,
|
index: index,
|
||||||
));
|
rowId: insertRow.row.id,
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return insertIndexs;
|
return insertIndexs;
|
||||||
|
@ -67,7 +67,8 @@ class DatabaseGroupEvent with _$DatabaseGroupEvent {
|
|||||||
FieldType fieldType,
|
FieldType fieldType,
|
||||||
) = _DatabaseGroupEvent;
|
) = _DatabaseGroupEvent;
|
||||||
const factory DatabaseGroupEvent.didReceiveFieldUpdate(
|
const factory DatabaseGroupEvent.didReceiveFieldUpdate(
|
||||||
List<FieldInfo> fields) = _DidReceiveFieldUpdate;
|
List<FieldInfo> fields,
|
||||||
|
) = _DidReceiveFieldUpdate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
@ -78,7 +79,9 @@ class DatabaseGroupState with _$DatabaseGroupState {
|
|||||||
}) = _DatabaseGroupState;
|
}) = _DatabaseGroupState;
|
||||||
|
|
||||||
factory DatabaseGroupState.initial(
|
factory DatabaseGroupState.initial(
|
||||||
String viewId, List<FieldInfo> fieldContexts) =>
|
String viewId,
|
||||||
|
List<FieldInfo> fieldContexts,
|
||||||
|
) =>
|
||||||
DatabaseGroupState(
|
DatabaseGroupState(
|
||||||
viewId: viewId,
|
viewId: viewId,
|
||||||
fieldContexts: fieldContexts,
|
fieldContexts: fieldContexts,
|
||||||
|
@ -13,11 +13,13 @@ class DatabasePropertyBloc
|
|||||||
final FieldController _fieldController;
|
final FieldController _fieldController;
|
||||||
Function(List<FieldInfo>)? _onFieldsFn;
|
Function(List<FieldInfo>)? _onFieldsFn;
|
||||||
|
|
||||||
DatabasePropertyBloc(
|
DatabasePropertyBloc({
|
||||||
{required String viewId, required FieldController fieldController})
|
required String viewId,
|
||||||
: _fieldController = fieldController,
|
required FieldController fieldController,
|
||||||
|
}) : _fieldController = fieldController,
|
||||||
super(
|
super(
|
||||||
DatabasePropertyState.initial(viewId, fieldController.fieldInfos)) {
|
DatabasePropertyState.initial(viewId, fieldController.fieldInfos),
|
||||||
|
) {
|
||||||
on<DatabasePropertyEvent>(
|
on<DatabasePropertyEvent>(
|
||||||
(event, emit) async {
|
(event, emit) async {
|
||||||
await event.map(
|
await event.map(
|
||||||
@ -68,9 +70,12 @@ class DatabasePropertyBloc
|
|||||||
class DatabasePropertyEvent with _$DatabasePropertyEvent {
|
class DatabasePropertyEvent with _$DatabasePropertyEvent {
|
||||||
const factory DatabasePropertyEvent.initial() = _Initial;
|
const factory DatabasePropertyEvent.initial() = _Initial;
|
||||||
const factory DatabasePropertyEvent.setFieldVisibility(
|
const factory DatabasePropertyEvent.setFieldVisibility(
|
||||||
String fieldId, bool visibility) = _SetFieldVisibility;
|
String fieldId,
|
||||||
|
bool visibility,
|
||||||
|
) = _SetFieldVisibility;
|
||||||
const factory DatabasePropertyEvent.didReceiveFieldUpdate(
|
const factory DatabasePropertyEvent.didReceiveFieldUpdate(
|
||||||
List<FieldInfo> fields) = _DidReceiveFieldUpdate;
|
List<FieldInfo> fields,
|
||||||
|
) = _DidReceiveFieldUpdate;
|
||||||
const factory DatabasePropertyEvent.moveField(int fromIndex, int toIndex) =
|
const factory DatabasePropertyEvent.moveField(int fromIndex, int toIndex) =
|
||||||
_MoveField;
|
_MoveField;
|
||||||
}
|
}
|
||||||
|
@ -11,9 +11,11 @@ class DatabaseSettingBloc
|
|||||||
: super(DatabaseSettingState.initial()) {
|
: super(DatabaseSettingState.initial()) {
|
||||||
on<DatabaseSettingEvent>(
|
on<DatabaseSettingEvent>(
|
||||||
(event, emit) async {
|
(event, emit) async {
|
||||||
event.map(performAction: (_PerformAction value) {
|
event.map(
|
||||||
emit(state.copyWith(selectedAction: Some(value.action)));
|
performAction: (_PerformAction value) {
|
||||||
});
|
emit(state.copyWith(selectedAction: Some(value.action)));
|
||||||
|
},
|
||||||
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -22,7 +24,8 @@ class DatabaseSettingBloc
|
|||||||
@freezed
|
@freezed
|
||||||
class DatabaseSettingEvent with _$DatabaseSettingEvent {
|
class DatabaseSettingEvent with _$DatabaseSettingEvent {
|
||||||
const factory DatabaseSettingEvent.performAction(
|
const factory DatabaseSettingEvent.performAction(
|
||||||
DatabaseSettingAction action) = _PerformAction;
|
DatabaseSettingAction action,
|
||||||
|
) = _PerformAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
|
@ -28,12 +28,14 @@ class SettingController {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Listen on the setting changes
|
// Listen on the setting changes
|
||||||
_listener.start(onSettingUpdated: (result) {
|
_listener.start(
|
||||||
result.fold(
|
onSettingUpdated: (result) {
|
||||||
(newSetting) => updateSetting(newSetting),
|
result.fold(
|
||||||
(err) => _onError?.call(err),
|
(newSetting) => updateSetting(newSetting),
|
||||||
);
|
(err) => _onError?.call(err),
|
||||||
});
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void startListening({
|
void startListening({
|
||||||
|
@ -69,9 +69,11 @@ class DatabaseViewCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (changeset.insertedRows.isNotEmpty) {
|
if (changeset.insertedRows.isNotEmpty) {
|
||||||
_callbacks?.onRowsCreated?.call(changeset.insertedRows
|
_callbacks?.onRowsCreated?.call(
|
||||||
.map((insertedRow) => insertedRow.row.id)
|
changeset.insertedRows
|
||||||
.toList());
|
.map((insertedRow) => insertedRow.row.id)
|
||||||
|
.toList(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
(err) => Log.error(err),
|
(err) => Log.error(err),
|
||||||
|
@ -105,23 +105,31 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
didCreateRow: (group, row, int? index) {
|
didCreateRow: (group, row, int? index) {
|
||||||
emit(state.copyWith(
|
emit(
|
||||||
editingRow: Some(BoardEditingRow(
|
state.copyWith(
|
||||||
group: group,
|
editingRow: Some(
|
||||||
row: row,
|
BoardEditingRow(
|
||||||
index: index,
|
group: group,
|
||||||
)),
|
row: row,
|
||||||
));
|
index: index,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
_groupItemStartEditing(group, row, true);
|
_groupItemStartEditing(group, row, true);
|
||||||
},
|
},
|
||||||
startEditingRow: (group, row) {
|
startEditingRow: (group, row) {
|
||||||
emit(state.copyWith(
|
emit(
|
||||||
editingRow: Some(BoardEditingRow(
|
state.copyWith(
|
||||||
group: group,
|
editingRow: Some(
|
||||||
row: row,
|
BoardEditingRow(
|
||||||
index: null,
|
group: group,
|
||||||
)),
|
row: row,
|
||||||
));
|
index: null,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
_groupItemStartEditing(group, row, true);
|
_groupItemStartEditing(group, row, true);
|
||||||
},
|
},
|
||||||
endEditingRow: (rowId) {
|
endEditingRow: (rowId) {
|
||||||
@ -175,10 +183,12 @@ class BoardBloc extends Bloc<BoardEvent, BoardState> {
|
|||||||
groupControllers.clear();
|
groupControllers.clear();
|
||||||
boardController.clear();
|
boardController.clear();
|
||||||
|
|
||||||
boardController.addGroups(groups
|
boardController.addGroups(
|
||||||
.where((group) => fieldController.getField(group.fieldId) != null)
|
groups
|
||||||
.map((group) => initializeGroupData(group))
|
.where((group) => fieldController.getField(group.fieldId) != null)
|
||||||
.toList());
|
.map((group) => initializeGroupData(group))
|
||||||
|
.toList(),
|
||||||
|
);
|
||||||
|
|
||||||
for (final group in groups) {
|
for (final group in groups) {
|
||||||
final controller = initializeGroupController(group);
|
final controller = initializeGroupController(group);
|
||||||
@ -334,7 +344,8 @@ class BoardState with _$BoardState {
|
|||||||
class GridLoadingState with _$GridLoadingState {
|
class GridLoadingState with _$GridLoadingState {
|
||||||
const factory GridLoadingState.loading() = _Loading;
|
const factory GridLoadingState.loading() = _Loading;
|
||||||
const factory GridLoadingState.finish(
|
const factory GridLoadingState.finish(
|
||||||
Either<Unit, FlowyError> successOrFail) = _Finish;
|
Either<Unit, FlowyError> successOrFail,
|
||||||
|
) = _Finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
class GridFieldEquatable extends Equatable {
|
class GridFieldEquatable extends Equatable {
|
||||||
|
@ -41,44 +41,46 @@ class GroupController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void startListening() {
|
void startListening() {
|
||||||
_listener.start(onGroupChanged: (result) {
|
_listener.start(
|
||||||
result.fold(
|
onGroupChanged: (result) {
|
||||||
(GroupRowsNotificationPB changeset) {
|
result.fold(
|
||||||
for (final deletedRow in changeset.deletedRows) {
|
(GroupRowsNotificationPB changeset) {
|
||||||
group.rows.removeWhere((rowPB) => rowPB.id == deletedRow);
|
for (final deletedRow in changeset.deletedRows) {
|
||||||
delegate.removeRow(group, deletedRow);
|
group.rows.removeWhere((rowPB) => rowPB.id == deletedRow);
|
||||||
}
|
delegate.removeRow(group, deletedRow);
|
||||||
|
|
||||||
for (final insertedRow in changeset.insertedRows) {
|
|
||||||
final index = insertedRow.hasIndex() ? insertedRow.index : null;
|
|
||||||
if (insertedRow.hasIndex() &&
|
|
||||||
group.rows.length > insertedRow.index) {
|
|
||||||
group.rows.insert(insertedRow.index, insertedRow.row);
|
|
||||||
} else {
|
|
||||||
group.rows.add(insertedRow.row);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (insertedRow.isNew) {
|
for (final insertedRow in changeset.insertedRows) {
|
||||||
delegate.addNewRow(group, insertedRow.row, index);
|
final index = insertedRow.hasIndex() ? insertedRow.index : null;
|
||||||
} else {
|
if (insertedRow.hasIndex() &&
|
||||||
delegate.insertRow(group, insertedRow.row, index);
|
group.rows.length > insertedRow.index) {
|
||||||
}
|
group.rows.insert(insertedRow.index, insertedRow.row);
|
||||||
}
|
} else {
|
||||||
|
group.rows.add(insertedRow.row);
|
||||||
|
}
|
||||||
|
|
||||||
for (final updatedRow in changeset.updatedRows) {
|
if (insertedRow.isNew) {
|
||||||
final index = group.rows.indexWhere(
|
delegate.addNewRow(group, insertedRow.row, index);
|
||||||
(rowPB) => rowPB.id == updatedRow.id,
|
} else {
|
||||||
);
|
delegate.insertRow(group, insertedRow.row, index);
|
||||||
|
}
|
||||||
if (index != -1) {
|
|
||||||
group.rows[index] = updatedRow;
|
|
||||||
delegate.updateRow(group, updatedRow);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
for (final updatedRow in changeset.updatedRows) {
|
||||||
(err) => Log.error(err),
|
final index = group.rows.indexWhere(
|
||||||
);
|
(rowPB) => rowPB.id == updatedRow.id,
|
||||||
});
|
);
|
||||||
|
|
||||||
|
if (index != -1) {
|
||||||
|
group.rows[index] = updatedRow;
|
||||||
|
delegate.updateRow(group, updatedRow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(err) => Log.error(err),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> dispose() async {
|
Future<void> dispose() async {
|
||||||
|
@ -10,9 +10,11 @@ class BoardSettingBloc extends Bloc<BoardSettingEvent, BoardSettingState> {
|
|||||||
: super(BoardSettingState.initial()) {
|
: super(BoardSettingState.initial()) {
|
||||||
on<BoardSettingEvent>(
|
on<BoardSettingEvent>(
|
||||||
(event, emit) async {
|
(event, emit) async {
|
||||||
event.when(performAction: (action) {
|
event.when(
|
||||||
emit(state.copyWith(selectedAction: Some(action)));
|
performAction: (action) {
|
||||||
});
|
emit(state.copyWith(selectedAction: Some(action)));
|
||||||
|
},
|
||||||
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -80,8 +80,8 @@ class _BoardContentState extends State<BoardContent> {
|
|||||||
late AppFlowyBoardScrollController scrollManager;
|
late AppFlowyBoardScrollController scrollManager;
|
||||||
final cardConfiguration = CardConfiguration<String>();
|
final cardConfiguration = CardConfiguration<String>();
|
||||||
|
|
||||||
final config = AppFlowyBoardConfig(
|
final config = const AppFlowyBoardConfig(
|
||||||
groupBackgroundColor: HexColor.fromHex('#F7F8FC'),
|
groupBackgroundColor: Color(0xffF7F8FC),
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -292,9 +292,10 @@ class _BoardContentState extends State<BoardContent> {
|
|||||||
color: Theme.of(context).dividerColor,
|
color: Theme.of(context).dividerColor,
|
||||||
width: 1.0,
|
width: 1.0,
|
||||||
);
|
);
|
||||||
|
final isLightMode = Theme.of(context).brightness == Brightness.light;
|
||||||
return BoxDecoration(
|
return BoxDecoration(
|
||||||
color: Theme.of(context).colorScheme.surface,
|
color: Theme.of(context).colorScheme.surface,
|
||||||
border: Border.fromBorderSide(borderSide),
|
border: isLightMode ? Border.fromBorderSide(borderSide) : null,
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(6)),
|
borderRadius: const BorderRadius.all(Radius.circular(6)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -349,15 +350,6 @@ class _ToolbarBlocAdaptor extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension HexColor on Color {
|
|
||||||
static Color fromHex(String hexString) {
|
|
||||||
final buffer = StringBuffer();
|
|
||||||
if (hexString.length == 6 || hexString.length == 7) buffer.write('ff');
|
|
||||||
buffer.write(hexString.replaceFirst('#', ''));
|
|
||||||
return Color(int.parse(buffer.toString(), radix: 16));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget? _buildHeaderIcon(GroupData customData) {
|
Widget? _buildHeaderIcon(GroupData customData) {
|
||||||
Widget? widget;
|
Widget? widget;
|
||||||
switch (customData.fieldType) {
|
switch (customData.fieldType) {
|
||||||
|
@ -7,6 +7,7 @@ import 'package:appflowy/plugins/database_view/grid/presentation/widgets/toolbar
|
|||||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:easy_localization/easy_localization.dart';
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
|
import 'package:flowy_infra/theme_extension.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/button.dart';
|
import 'package:flowy_infra_ui/style_widget/button.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
|
import 'package:flowy_infra_ui/style_widget/scrolling/styled_list.dart';
|
||||||
import 'package:flowy_infra_ui/style_widget/text.dart';
|
import 'package:flowy_infra_ui/style_widget/text.dart';
|
||||||
@ -104,8 +105,12 @@ class _SettingItem extends StatelessWidget {
|
|||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: 30,
|
height: 30,
|
||||||
child: FlowyButton(
|
child: FlowyButton(
|
||||||
|
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||||
isSelected: isSelected,
|
isSelected: isSelected,
|
||||||
text: FlowyText.medium(action.title()),
|
text: FlowyText.medium(
|
||||||
|
action.title(),
|
||||||
|
color: AFThemeExtension.of(context).textColor,
|
||||||
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
context
|
context
|
||||||
.read<BoardSettingBloc>()
|
.read<BoardSettingBloc>()
|
||||||
|
@ -71,6 +71,7 @@ class _SettingButtonState extends State<_SettingButton> {
|
|||||||
margin: EdgeInsets.zero,
|
margin: EdgeInsets.zero,
|
||||||
child: FlowyTextButton(
|
child: FlowyTextButton(
|
||||||
LocaleKeys.settings_title.tr(),
|
LocaleKeys.settings_title.tr(),
|
||||||
|
fontColor: AFThemeExtension.of(context).textColor,
|
||||||
fillColor: Colors.transparent,
|
fillColor: Colors.transparent,
|
||||||
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||||
padding: GridSize.typeOptionContentInsets,
|
padding: GridSize.typeOptionContentInsets,
|
||||||
|
@ -67,16 +67,20 @@ class CalendarBloc extends Bloc<CalendarEvent, CalendarState> {
|
|||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
allEvents[index] = eventData;
|
allEvents[index] = eventData;
|
||||||
}
|
}
|
||||||
emit(state.copyWith(
|
emit(
|
||||||
allEvents: allEvents,
|
state.copyWith(
|
||||||
updateEvent: eventData,
|
allEvents: allEvents,
|
||||||
));
|
updateEvent: eventData,
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
didReceiveNewEvent: (CalendarEventData<CalendarDayEvent> event) {
|
didReceiveNewEvent: (CalendarEventData<CalendarDayEvent> event) {
|
||||||
emit(state.copyWith(
|
emit(
|
||||||
allEvents: [...state.allEvents, event],
|
state.copyWith(
|
||||||
newEvent: event,
|
allEvents: [...state.allEvents, event],
|
||||||
));
|
newEvent: event,
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
didDeleteEvents: (List<String> deletedRowIds) {
|
didDeleteEvents: (List<String> deletedRowIds) {
|
||||||
var events = [...state.allEvents];
|
var events = [...state.allEvents];
|
||||||
@ -155,7 +159,8 @@ class CalendarBloc extends Bloc<CalendarEvent, CalendarState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _updateCalendarLayoutSetting(
|
Future<void> _updateCalendarLayoutSetting(
|
||||||
CalendarLayoutSettingsPB layoutSetting) async {
|
CalendarLayoutSettingsPB layoutSetting,
|
||||||
|
) async {
|
||||||
return _databaseController.updateCalenderLayoutSetting(layoutSetting);
|
return _databaseController.updateCalenderLayoutSetting(layoutSetting);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,7 +203,8 @@ class CalendarBloc extends Bloc<CalendarEvent, CalendarState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CalendarEventData<CalendarDayEvent>? _calendarEventDataFromEventPB(
|
CalendarEventData<CalendarDayEvent>? _calendarEventDataFromEventPB(
|
||||||
CalendarEventPB eventPB) {
|
CalendarEventPB eventPB,
|
||||||
|
) {
|
||||||
final fieldInfo = fieldInfoByFieldId[eventPB.titleFieldId];
|
final fieldInfo = fieldInfoByFieldId[eventPB.titleFieldId];
|
||||||
if (fieldInfo != null) {
|
if (fieldInfo != null) {
|
||||||
final cellId = CellIdentifier(
|
final cellId = CellIdentifier(
|
||||||
@ -214,7 +220,6 @@ class CalendarBloc extends Bloc<CalendarEvent, CalendarState> {
|
|||||||
|
|
||||||
final date = DateTime.fromMillisecondsSinceEpoch(
|
final date = DateTime.fromMillisecondsSinceEpoch(
|
||||||
eventPB.timestamp.toInt() * 1000,
|
eventPB.timestamp.toInt() * 1000,
|
||||||
isUtc: true,
|
|
||||||
);
|
);
|
||||||
return CalendarEventData(
|
return CalendarEventData(
|
||||||
title: eventPB.title,
|
title: eventPB.title,
|
||||||
@ -267,7 +272,8 @@ class CalendarBloc extends Bloc<CalendarEvent, CalendarState> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
final onCalendarLayoutFieldChanged = CalendarLayoutCallbacks(
|
final onCalendarLayoutFieldChanged = CalendarLayoutCallbacks(
|
||||||
onCalendarLayoutChanged: _didReceiveNewLayoutField);
|
onCalendarLayoutChanged: _didReceiveNewLayoutField,
|
||||||
|
);
|
||||||
|
|
||||||
_databaseController.addListener(
|
_databaseController.addListener(
|
||||||
onDatabaseChanged: onDatabaseChanged,
|
onDatabaseChanged: onDatabaseChanged,
|
||||||
@ -299,7 +305,8 @@ class CalendarEvent with _$CalendarEvent {
|
|||||||
|
|
||||||
// Called after loading the calendar layout setting from the backend
|
// Called after loading the calendar layout setting from the backend
|
||||||
const factory CalendarEvent.didReceiveCalendarSettings(
|
const factory CalendarEvent.didReceiveCalendarSettings(
|
||||||
CalendarLayoutSettingsPB settings) = _ReceiveCalendarSettings;
|
CalendarLayoutSettingsPB settings,
|
||||||
|
) = _ReceiveCalendarSettings;
|
||||||
|
|
||||||
// Called after loading all the current evnets
|
// Called after loading all the current evnets
|
||||||
const factory CalendarEvent.didLoadAllEvents(Events events) =
|
const factory CalendarEvent.didLoadAllEvents(Events events) =
|
||||||
@ -307,11 +314,13 @@ class CalendarEvent with _$CalendarEvent {
|
|||||||
|
|
||||||
// Called when specific event was updated
|
// Called when specific event was updated
|
||||||
const factory CalendarEvent.didUpdateEvent(
|
const factory CalendarEvent.didUpdateEvent(
|
||||||
CalendarEventData<CalendarDayEvent> event) = _DidUpdateEvent;
|
CalendarEventData<CalendarDayEvent> event,
|
||||||
|
) = _DidUpdateEvent;
|
||||||
|
|
||||||
// Called after creating a new event
|
// Called after creating a new event
|
||||||
const factory CalendarEvent.didReceiveNewEvent(
|
const factory CalendarEvent.didReceiveNewEvent(
|
||||||
CalendarEventData<CalendarDayEvent> event) = _DidReceiveNewEvent;
|
CalendarEventData<CalendarDayEvent> event,
|
||||||
|
) = _DidReceiveNewEvent;
|
||||||
|
|
||||||
// Called when deleting events
|
// Called when deleting events
|
||||||
const factory CalendarEvent.didDeleteEvents(List<String> rowIds) =
|
const factory CalendarEvent.didDeleteEvents(List<String> rowIds) =
|
||||||
@ -323,13 +332,15 @@ class CalendarEvent with _$CalendarEvent {
|
|||||||
|
|
||||||
// Called when updating the calendar's layout settings
|
// Called when updating the calendar's layout settings
|
||||||
const factory CalendarEvent.updateCalendarLayoutSetting(
|
const factory CalendarEvent.updateCalendarLayoutSetting(
|
||||||
CalendarLayoutSettingsPB layoutSetting) = _UpdateCalendarLayoutSetting;
|
CalendarLayoutSettingsPB layoutSetting,
|
||||||
|
) = _UpdateCalendarLayoutSetting;
|
||||||
|
|
||||||
const factory CalendarEvent.didReceiveDatabaseUpdate(DatabasePB database) =
|
const factory CalendarEvent.didReceiveDatabaseUpdate(DatabasePB database) =
|
||||||
_ReceiveDatabaseUpdate;
|
_ReceiveDatabaseUpdate;
|
||||||
|
|
||||||
const factory CalendarEvent.didReceiveNewLayoutField(
|
const factory CalendarEvent.didReceiveNewLayoutField(
|
||||||
CalendarLayoutSettingsPB layoutSettings) = _DidReceiveNewLayoutField;
|
CalendarLayoutSettingsPB layoutSettings,
|
||||||
|
) = _DidReceiveNewLayoutField;
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
@ -361,7 +372,8 @@ class CalendarState with _$CalendarState {
|
|||||||
class DatabaseLoadingState with _$DatabaseLoadingState {
|
class DatabaseLoadingState with _$DatabaseLoadingState {
|
||||||
const factory DatabaseLoadingState.loading() = _Loading;
|
const factory DatabaseLoadingState.loading() = _Loading;
|
||||||
const factory DatabaseLoadingState.finish(
|
const factory DatabaseLoadingState.finish(
|
||||||
Either<Unit, FlowyError> successOrFail) = _Finish;
|
Either<Unit, FlowyError> successOrFail,
|
||||||
|
) = _Finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
class CalendarEditingRow {
|
class CalendarEditingRow {
|
||||||
|
@ -22,7 +22,6 @@ class CalendarSettingBloc
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
@ -33,7 +32,8 @@ class CalendarSettingState with _$CalendarSettingState {
|
|||||||
}) = _CalendarSettingState;
|
}) = _CalendarSettingState;
|
||||||
|
|
||||||
factory CalendarSettingState.initial(
|
factory CalendarSettingState.initial(
|
||||||
CalendarLayoutSettingsPB? layoutSettings) =>
|
CalendarLayoutSettingsPB? layoutSettings,
|
||||||
|
) =>
|
||||||
CalendarSettingState(
|
CalendarSettingState(
|
||||||
selectedAction: none(),
|
selectedAction: none(),
|
||||||
layoutSetting: layoutSettings == null ? none() : Some(layoutSettings),
|
layoutSetting: layoutSettings == null ? none() : Some(layoutSettings),
|
||||||
@ -43,9 +43,11 @@ class CalendarSettingState with _$CalendarSettingState {
|
|||||||
@freezed
|
@freezed
|
||||||
class CalendarSettingEvent with _$CalendarSettingEvent {
|
class CalendarSettingEvent with _$CalendarSettingEvent {
|
||||||
const factory CalendarSettingEvent.performAction(
|
const factory CalendarSettingEvent.performAction(
|
||||||
CalendarSettingAction action) = _PerformAction;
|
CalendarSettingAction action,
|
||||||
|
) = _PerformAction;
|
||||||
const factory CalendarSettingEvent.updateLayoutSetting(
|
const factory CalendarSettingEvent.updateLayoutSetting(
|
||||||
CalendarLayoutSettingsPB setting) = _UpdateLayoutSetting;
|
CalendarLayoutSettingsPB setting,
|
||||||
|
) = _UpdateLayoutSetting;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum CalendarSettingAction {
|
enum CalendarSettingAction {
|
||||||
|
@ -62,30 +62,32 @@ class CalendarDayCard extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
final child = Padding(
|
final child = Column(
|
||||||
padding: const EdgeInsets.all(8.0),
|
mainAxisSize: MainAxisSize.min,
|
||||||
child: Column(
|
children: [
|
||||||
mainAxisSize: MainAxisSize.min,
|
Padding(
|
||||||
children: [
|
padding: const EdgeInsets.all(8.0),
|
||||||
_Header(
|
child: _Header(
|
||||||
date: date,
|
date: date,
|
||||||
isInMonth: isInMonth,
|
isInMonth: isInMonth,
|
||||||
isToday: isToday,
|
isToday: isToday,
|
||||||
onCreate: () => onCreateEvent(date),
|
onCreate: () => onCreateEvent(date),
|
||||||
),
|
),
|
||||||
VSpace(GridSize.typeOptionSeparatorHeight),
|
),
|
||||||
Flexible(
|
VSpace(GridSize.typeOptionSeparatorHeight),
|
||||||
child: ListView.separated(
|
Flexible(
|
||||||
itemBuilder: (BuildContext context, int index) {
|
child: ListView.separated(
|
||||||
return children[index];
|
itemBuilder: (BuildContext context, int index) {
|
||||||
},
|
return children[index];
|
||||||
itemCount: children.length,
|
},
|
||||||
separatorBuilder: (BuildContext context, int index) =>
|
itemCount: children.length,
|
||||||
VSpace(GridSize.typeOptionSeparatorHeight),
|
padding: const EdgeInsets.symmetric(horizontal: 8.0),
|
||||||
),
|
separatorBuilder: (BuildContext context, int index) =>
|
||||||
),
|
VSpace(GridSize.typeOptionSeparatorHeight),
|
||||||
],
|
),
|
||||||
));
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
color: backgroundColor,
|
color: backgroundColor,
|
||||||
@ -93,7 +95,10 @@ class CalendarDayCard extends StatelessWidget {
|
|||||||
cursor: SystemMouseCursors.click,
|
cursor: SystemMouseCursors.click,
|
||||||
onEnter: (p) => notifyEnter(context, true),
|
onEnter: (p) => notifyEnter(context, true),
|
||||||
onExit: (p) => notifyEnter(context, false),
|
onExit: (p) => notifyEnter(context, false),
|
||||||
child: child,
|
child: Padding(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}),
|
}),
|
||||||
@ -148,6 +153,15 @@ class _DayEventCell extends StatelessWidget {
|
|||||||
onTap: onClick,
|
onTap: onClick,
|
||||||
child: Container(
|
child: Container(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 8),
|
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
border: Border.fromBorderSide(
|
||||||
|
BorderSide(
|
||||||
|
color: Theme.of(context).dividerColor,
|
||||||
|
width: 1.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
borderRadius: Corners.s6Border,
|
||||||
|
),
|
||||||
child: child,
|
child: child,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -73,9 +73,11 @@ class _CalendarPageState extends State<CalendarPage> {
|
|||||||
listenWhen: (p, c) => p.updateEvent != c.updateEvent,
|
listenWhen: (p, c) => p.updateEvent != c.updateEvent,
|
||||||
listener: (context, state) {
|
listener: (context, state) {
|
||||||
if (state.updateEvent != null) {
|
if (state.updateEvent != null) {
|
||||||
_eventController.removeWhere((element) =>
|
_eventController.removeWhere(
|
||||||
state.updateEvent!.event!.eventId ==
|
(element) =>
|
||||||
element.event!.eventId);
|
state.updateEvent!.event!.eventId ==
|
||||||
|
element.event!.eventId,
|
||||||
|
);
|
||||||
_eventController.add(state.updateEvent!);
|
_eventController.add(state.updateEvent!);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -18,6 +18,8 @@ import 'package:protobuf/protobuf.dart';
|
|||||||
|
|
||||||
import 'calendar_setting.dart';
|
import 'calendar_setting.dart';
|
||||||
|
|
||||||
|
/// Widget that displays a list of settings that alters the appearance of the
|
||||||
|
/// calendar
|
||||||
class CalendarLayoutSetting extends StatefulWidget {
|
class CalendarLayoutSetting extends StatefulWidget {
|
||||||
final CalendarSettingContext settingContext;
|
final CalendarSettingContext settingContext;
|
||||||
final Function(CalendarLayoutSettingsPB? layoutSettings) onUpdated;
|
final Function(CalendarLayoutSettingsPB? layoutSettings) onUpdated;
|
||||||
@ -96,18 +98,15 @@ class _CalendarLayoutSettingState extends State<CalendarLayoutSetting> {
|
|||||||
fieldId: settings.layoutFieldId,
|
fieldId: settings.layoutFieldId,
|
||||||
popoverMutex: popoverMutex,
|
popoverMutex: popoverMutex,
|
||||||
onUpdated: (fieldId) {
|
onUpdated: (fieldId) {
|
||||||
_updateLayoutSettings(context,
|
_updateLayoutSettings(
|
||||||
onUpdated: widget.onUpdated, layoutFieldId: fieldId);
|
context,
|
||||||
|
onUpdated: widget.onUpdated,
|
||||||
|
layoutFieldId: fieldId,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
default:
|
default:
|
||||||
return ShowWeekends(
|
return const SizedBox();
|
||||||
showWeekends: settings.showWeekends,
|
|
||||||
onUpdated: (showWeekends) {
|
|
||||||
_updateLayoutSettings(context,
|
|
||||||
onUpdated: widget.onUpdated, showWeekends: showWeekends);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
@ -129,7 +128,8 @@ class _CalendarLayoutSettingState extends State<CalendarLayoutSetting> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<CalendarLayoutSettingAction> _availableCalendarSettings(
|
List<CalendarLayoutSettingAction> _availableCalendarSettings(
|
||||||
CalendarLayoutSettingsPB layoutSettings) {
|
CalendarLayoutSettingsPB layoutSettings,
|
||||||
|
) {
|
||||||
List<CalendarLayoutSettingAction> settings = [
|
List<CalendarLayoutSettingAction> settings = [
|
||||||
CalendarLayoutSettingAction.layoutField,
|
CalendarLayoutSettingAction.layoutField,
|
||||||
// CalendarLayoutSettingAction.layoutType,
|
// CalendarLayoutSettingAction.layoutType,
|
||||||
@ -220,8 +220,9 @@ class LayoutDateField extends StatelessWidget {
|
|||||||
popupBuilder: (context) {
|
popupBuilder: (context) {
|
||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (context) => getIt<DatabasePropertyBloc>(
|
create: (context) => getIt<DatabasePropertyBloc>(
|
||||||
param1: viewId, param2: fieldController)
|
param1: viewId,
|
||||||
..add(const DatabasePropertyEvent.initial()),
|
param2: fieldController,
|
||||||
|
)..add(const DatabasePropertyEvent.initial()),
|
||||||
child: BlocBuilder<DatabasePropertyBloc, DatabasePropertyState>(
|
child: BlocBuilder<DatabasePropertyBloc, DatabasePropertyState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
final items = state.fieldContexts
|
final items = state.fieldContexts
|
||||||
@ -264,7 +265,8 @@ class LayoutDateField extends StatelessWidget {
|
|||||||
child: FlowyButton(
|
child: FlowyButton(
|
||||||
margin: const EdgeInsets.symmetric(vertical: 2.0, horizontal: 10.0),
|
margin: const EdgeInsets.symmetric(vertical: 2.0, horizontal: 10.0),
|
||||||
text: FlowyText.medium(
|
text: FlowyText.medium(
|
||||||
LocaleKeys.calendar_settings_layoutDateField.tr()),
|
LocaleKeys.calendar_settings_layoutDateField.tr(),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -368,7 +370,8 @@ class FirstDayOfWeek extends StatelessWidget {
|
|||||||
child: FlowyButton(
|
child: FlowyButton(
|
||||||
margin: const EdgeInsets.symmetric(vertical: 2.0, horizontal: 10.0),
|
margin: const EdgeInsets.symmetric(vertical: 2.0, horizontal: 10.0),
|
||||||
text: FlowyText.medium(
|
text: FlowyText.medium(
|
||||||
LocaleKeys.calendar_settings_firstDayOfWeek.tr()),
|
LocaleKeys.calendar_settings_firstDayOfWeek.tr(),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -15,8 +15,8 @@ import 'package:styled_widget/styled_widget.dart';
|
|||||||
import 'calendar_layout_setting.dart';
|
import 'calendar_layout_setting.dart';
|
||||||
|
|
||||||
/// The highest-level widget shown in the popover triggered by clicking the
|
/// The highest-level widget shown in the popover triggered by clicking the
|
||||||
/// "Settings" button. By default, shows [AllCalendarSettings] but upon
|
/// "Settings" button. Shows [AllCalendarSettings] by default, but replaces its
|
||||||
/// selecting a category, replaces contents with contents of the submenu.
|
/// contents with the submenu when a category is selected.
|
||||||
class CalendarSetting extends StatelessWidget {
|
class CalendarSetting extends StatelessWidget {
|
||||||
final CalendarSettingContext settingContext;
|
final CalendarSettingContext settingContext;
|
||||||
final CalendarLayoutSettingsPB? layoutSettings;
|
final CalendarLayoutSettingsPB? layoutSettings;
|
||||||
|
@ -45,10 +45,12 @@ class CheckboxFilterEditorBloc
|
|||||||
didReceiveFilter: (FilterPB filter) {
|
didReceiveFilter: (FilterPB filter) {
|
||||||
final filterInfo = state.filterInfo.copyWith(filter: filter);
|
final filterInfo = state.filterInfo.copyWith(filter: filter);
|
||||||
final checkboxFilter = filterInfo.checkboxFilter()!;
|
final checkboxFilter = filterInfo.checkboxFilter()!;
|
||||||
emit(state.copyWith(
|
emit(
|
||||||
filterInfo: filterInfo,
|
state.copyWith(
|
||||||
filter: checkboxFilter,
|
filterInfo: filterInfo,
|
||||||
));
|
filter: checkboxFilter,
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -79,7 +81,8 @@ class CheckboxFilterEditorEvent with _$CheckboxFilterEditorEvent {
|
|||||||
const factory CheckboxFilterEditorEvent.didReceiveFilter(FilterPB filter) =
|
const factory CheckboxFilterEditorEvent.didReceiveFilter(FilterPB filter) =
|
||||||
_DidReceiveFilter;
|
_DidReceiveFilter;
|
||||||
const factory CheckboxFilterEditorEvent.updateCondition(
|
const factory CheckboxFilterEditorEvent.updateCondition(
|
||||||
CheckboxFilterConditionPB condition) = _UpdateCondition;
|
CheckboxFilterConditionPB condition,
|
||||||
|
) = _UpdateCondition;
|
||||||
const factory CheckboxFilterEditorEvent.delete() = _Delete;
|
const factory CheckboxFilterEditorEvent.delete() = _Delete;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,10 +46,12 @@ class ChecklistFilterEditorBloc
|
|||||||
didReceiveFilter: (FilterPB filter) {
|
didReceiveFilter: (FilterPB filter) {
|
||||||
final filterInfo = state.filterInfo.copyWith(filter: filter);
|
final filterInfo = state.filterInfo.copyWith(filter: filter);
|
||||||
final checklistFilter = filterInfo.checklistFilter()!;
|
final checklistFilter = filterInfo.checklistFilter()!;
|
||||||
emit(state.copyWith(
|
emit(
|
||||||
filterInfo: filterInfo,
|
state.copyWith(
|
||||||
filter: checklistFilter,
|
filterInfo: filterInfo,
|
||||||
));
|
filter: checklistFilter,
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -82,7 +84,8 @@ class ChecklistFilterEditorEvent with _$ChecklistFilterEditorEvent {
|
|||||||
const factory ChecklistFilterEditorEvent.didReceiveFilter(FilterPB filter) =
|
const factory ChecklistFilterEditorEvent.didReceiveFilter(FilterPB filter) =
|
||||||
_DidReceiveFilter;
|
_DidReceiveFilter;
|
||||||
const factory ChecklistFilterEditorEvent.updateCondition(
|
const factory ChecklistFilterEditorEvent.updateCondition(
|
||||||
ChecklistFilterConditionPB condition) = _UpdateCondition;
|
ChecklistFilterConditionPB condition,
|
||||||
|
) = _UpdateCondition;
|
||||||
const factory ChecklistFilterEditorEvent.delete() = _Delete;
|
const factory ChecklistFilterEditorEvent.delete() = _Delete;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,11 +14,13 @@ class GridFilterMenuBloc
|
|||||||
void Function(List<FieldInfo>)? _onFieldFn;
|
void Function(List<FieldInfo>)? _onFieldFn;
|
||||||
|
|
||||||
GridFilterMenuBloc({required this.viewId, required this.fieldController})
|
GridFilterMenuBloc({required this.viewId, required this.fieldController})
|
||||||
: super(GridFilterMenuState.initial(
|
: super(
|
||||||
viewId,
|
GridFilterMenuState.initial(
|
||||||
fieldController.filterInfos,
|
viewId,
|
||||||
fieldController.fieldInfos,
|
fieldController.filterInfos,
|
||||||
)) {
|
fieldController.fieldInfos,
|
||||||
|
),
|
||||||
|
) {
|
||||||
on<GridFilterMenuEvent>(
|
on<GridFilterMenuEvent>(
|
||||||
(event, emit) async {
|
(event, emit) async {
|
||||||
event.when(
|
event.when(
|
||||||
@ -82,7 +84,8 @@ class GridFilterMenuBloc
|
|||||||
class GridFilterMenuEvent with _$GridFilterMenuEvent {
|
class GridFilterMenuEvent with _$GridFilterMenuEvent {
|
||||||
const factory GridFilterMenuEvent.initial() = _Initial;
|
const factory GridFilterMenuEvent.initial() = _Initial;
|
||||||
const factory GridFilterMenuEvent.didReceiveFilters(
|
const factory GridFilterMenuEvent.didReceiveFilters(
|
||||||
List<FilterInfo> filters) = _DidReceiveFilters;
|
List<FilterInfo> filters,
|
||||||
|
) = _DidReceiveFilters;
|
||||||
const factory GridFilterMenuEvent.didReceiveFields(List<FieldInfo> fields) =
|
const factory GridFilterMenuEvent.didReceiveFields(List<FieldInfo> fields) =
|
||||||
_DidReceiveFields;
|
_DidReceiveFields;
|
||||||
const factory GridFilterMenuEvent.toggleMenu() = _SetMenuVisibility;
|
const factory GridFilterMenuEvent.toggleMenu() = _SetMenuVisibility;
|
||||||
|
@ -61,10 +61,12 @@ class SelectOptionFilterEditorBloc
|
|||||||
didReceiveFilter: (FilterPB filter) {
|
didReceiveFilter: (FilterPB filter) {
|
||||||
final filterInfo = state.filterInfo.copyWith(filter: filter);
|
final filterInfo = state.filterInfo.copyWith(filter: filter);
|
||||||
final selectOptionFilter = filterInfo.selectOptionFilter()!;
|
final selectOptionFilter = filterInfo.selectOptionFilter()!;
|
||||||
emit(state.copyWith(
|
emit(
|
||||||
filterInfo: filterInfo,
|
state.copyWith(
|
||||||
filter: selectOptionFilter,
|
filterInfo: filterInfo,
|
||||||
));
|
filter: selectOptionFilter,
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
updateFilterDescription: (String desc) {
|
updateFilterDescription: (String desc) {
|
||||||
emit(state.copyWith(filterDesc: desc));
|
emit(state.copyWith(filterDesc: desc));
|
||||||
@ -112,13 +114,17 @@ class SelectOptionFilterEditorBloc
|
|||||||
class SelectOptionFilterEditorEvent with _$SelectOptionFilterEditorEvent {
|
class SelectOptionFilterEditorEvent with _$SelectOptionFilterEditorEvent {
|
||||||
const factory SelectOptionFilterEditorEvent.initial() = _Initial;
|
const factory SelectOptionFilterEditorEvent.initial() = _Initial;
|
||||||
const factory SelectOptionFilterEditorEvent.didReceiveFilter(
|
const factory SelectOptionFilterEditorEvent.didReceiveFilter(
|
||||||
FilterPB filter) = _DidReceiveFilter;
|
FilterPB filter,
|
||||||
|
) = _DidReceiveFilter;
|
||||||
const factory SelectOptionFilterEditorEvent.updateCondition(
|
const factory SelectOptionFilterEditorEvent.updateCondition(
|
||||||
SelectOptionConditionPB condition) = _UpdateCondition;
|
SelectOptionConditionPB condition,
|
||||||
|
) = _UpdateCondition;
|
||||||
const factory SelectOptionFilterEditorEvent.updateContent(
|
const factory SelectOptionFilterEditorEvent.updateContent(
|
||||||
List<String> optionIds) = _UpdateContent;
|
List<String> optionIds,
|
||||||
|
) = _UpdateContent;
|
||||||
const factory SelectOptionFilterEditorEvent.updateFilterDescription(
|
const factory SelectOptionFilterEditorEvent.updateFilterDescription(
|
||||||
String desc) = _UpdateDesc;
|
String desc,
|
||||||
|
) = _UpdateDesc;
|
||||||
const factory SelectOptionFilterEditorEvent.delete() = _Delete;
|
const factory SelectOptionFilterEditorEvent.delete() = _Delete;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,15 +43,22 @@ class SelectOptionFilterListBloc<T>
|
|||||||
didReceiveOptions: (newOptions) {
|
didReceiveOptions: (newOptions) {
|
||||||
List<SelectOptionPB> options = List.from(newOptions);
|
List<SelectOptionPB> options = List.from(newOptions);
|
||||||
options.retainWhere(
|
options.retainWhere(
|
||||||
(element) => element.name.contains(state.predicate));
|
(element) => element.name.contains(state.predicate),
|
||||||
|
);
|
||||||
|
|
||||||
final visibleOptions = options.map((option) {
|
final visibleOptions = options.map((option) {
|
||||||
return VisibleSelectOption(
|
return VisibleSelectOption(
|
||||||
option, state.selectedOptionIds.contains(option.id));
|
option,
|
||||||
|
state.selectedOptionIds.contains(option.id),
|
||||||
|
);
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
emit(state.copyWith(
|
emit(
|
||||||
options: options, visibleOptions: visibleOptions));
|
state.copyWith(
|
||||||
|
options: options,
|
||||||
|
visibleOptions: visibleOptions,
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
filterOption: (optionName) {
|
filterOption: (optionName) {
|
||||||
_updateSelectOptions(predicate: optionName, emit: emit);
|
_updateSelectOptions(predicate: optionName, emit: emit);
|
||||||
@ -71,11 +78,13 @@ class SelectOptionFilterListBloc<T>
|
|||||||
selectedOptionIds ?? state.selectedOptionIds,
|
selectedOptionIds ?? state.selectedOptionIds,
|
||||||
);
|
);
|
||||||
|
|
||||||
emit(state.copyWith(
|
emit(
|
||||||
predicate: predicate ?? state.predicate,
|
state.copyWith(
|
||||||
visibleOptions: visibleOptions,
|
predicate: predicate ?? state.predicate,
|
||||||
selectedOptionIds: selectedOptionIds ?? state.selectedOptionIds,
|
visibleOptions: visibleOptions,
|
||||||
));
|
selectedOptionIds: selectedOptionIds ?? state.selectedOptionIds,
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<VisibleSelectOption> _makeVisibleOptions(
|
List<VisibleSelectOption> _makeVisibleOptions(
|
||||||
@ -105,11 +114,14 @@ class SelectOptionFilterListBloc<T>
|
|||||||
class SelectOptionFilterListEvent with _$SelectOptionFilterListEvent {
|
class SelectOptionFilterListEvent with _$SelectOptionFilterListEvent {
|
||||||
const factory SelectOptionFilterListEvent.initial() = _Initial;
|
const factory SelectOptionFilterListEvent.initial() = _Initial;
|
||||||
const factory SelectOptionFilterListEvent.selectOption(
|
const factory SelectOptionFilterListEvent.selectOption(
|
||||||
SelectOptionPB option) = _SelectOption;
|
SelectOptionPB option,
|
||||||
|
) = _SelectOption;
|
||||||
const factory SelectOptionFilterListEvent.unselectOption(
|
const factory SelectOptionFilterListEvent.unselectOption(
|
||||||
SelectOptionPB option) = _UnSelectOption;
|
SelectOptionPB option,
|
||||||
|
) = _UnSelectOption;
|
||||||
const factory SelectOptionFilterListEvent.didReceiveOptions(
|
const factory SelectOptionFilterListEvent.didReceiveOptions(
|
||||||
List<SelectOptionPB> options) = _DidReceiveOptions;
|
List<SelectOptionPB> options,
|
||||||
|
) = _DidReceiveOptions;
|
||||||
const factory SelectOptionFilterListEvent.filterOption(String optionName) =
|
const factory SelectOptionFilterListEvent.filterOption(String optionName) =
|
||||||
_SelectOptionFilter;
|
_SelectOptionFilter;
|
||||||
}
|
}
|
||||||
|
@ -54,10 +54,12 @@ class TextFilterEditorBloc
|
|||||||
didReceiveFilter: (FilterPB filter) {
|
didReceiveFilter: (FilterPB filter) {
|
||||||
final filterInfo = state.filterInfo.copyWith(filter: filter);
|
final filterInfo = state.filterInfo.copyWith(filter: filter);
|
||||||
final textFilter = filterInfo.textFilter()!;
|
final textFilter = filterInfo.textFilter()!;
|
||||||
emit(state.copyWith(
|
emit(
|
||||||
filterInfo: filterInfo,
|
state.copyWith(
|
||||||
filter: textFilter,
|
filterInfo: filterInfo,
|
||||||
));
|
filter: textFilter,
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -88,7 +90,8 @@ class TextFilterEditorEvent with _$TextFilterEditorEvent {
|
|||||||
const factory TextFilterEditorEvent.didReceiveFilter(FilterPB filter) =
|
const factory TextFilterEditorEvent.didReceiveFilter(FilterPB filter) =
|
||||||
_DidReceiveFilter;
|
_DidReceiveFilter;
|
||||||
const factory TextFilterEditorEvent.updateCondition(
|
const factory TextFilterEditorEvent.updateCondition(
|
||||||
TextFilterConditionPB condition) = _UpdateCondition;
|
TextFilterConditionPB condition,
|
||||||
|
) = _UpdateCondition;
|
||||||
const factory TextFilterEditorEvent.updateContent(String content) =
|
const factory TextFilterEditorEvent.updateContent(String content) =
|
||||||
_UpdateContent;
|
_UpdateContent;
|
||||||
const factory TextFilterEditorEvent.delete() = _Delete;
|
const factory TextFilterEditorEvent.delete() = _Delete;
|
||||||
|
@ -8,9 +8,11 @@ class GridAccessoryMenuBloc
|
|||||||
final String viewId;
|
final String viewId;
|
||||||
|
|
||||||
GridAccessoryMenuBloc({required this.viewId})
|
GridAccessoryMenuBloc({required this.viewId})
|
||||||
: super(GridAccessoryMenuState.initial(
|
: super(
|
||||||
viewId,
|
GridAccessoryMenuState.initial(
|
||||||
)) {
|
viewId,
|
||||||
|
),
|
||||||
|
) {
|
||||||
on<GridAccessoryMenuEvent>(
|
on<GridAccessoryMenuEvent>(
|
||||||
(event, emit) async {
|
(event, emit) async {
|
||||||
event.when(
|
event.when(
|
||||||
|
@ -39,16 +39,20 @@ class GridBloc extends Bloc<GridEvent, GridState> {
|
|||||||
emit(state.copyWith(grid: Some(grid)));
|
emit(state.copyWith(grid: Some(grid)));
|
||||||
},
|
},
|
||||||
didReceiveFieldUpdate: (fields) {
|
didReceiveFieldUpdate: (fields) {
|
||||||
emit(state.copyWith(
|
emit(
|
||||||
fields: GridFieldEquatable(fields),
|
state.copyWith(
|
||||||
));
|
fields: GridFieldEquatable(fields),
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
didReceiveRowUpdate: (newRowInfos, reason) {
|
didReceiveRowUpdate: (newRowInfos, reason) {
|
||||||
emit(state.copyWith(
|
emit(
|
||||||
rowInfos: newRowInfos,
|
state.copyWith(
|
||||||
rowCount: newRowInfos.length,
|
rowInfos: newRowInfos,
|
||||||
reason: reason,
|
rowCount: newRowInfos.length,
|
||||||
));
|
reason: reason,
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -146,7 +150,8 @@ class GridState with _$GridState {
|
|||||||
class GridLoadingState with _$GridLoadingState {
|
class GridLoadingState with _$GridLoadingState {
|
||||||
const factory GridLoadingState.loading() = _Loading;
|
const factory GridLoadingState.loading() = _Loading;
|
||||||
const factory GridLoadingState.finish(
|
const factory GridLoadingState.finish(
|
||||||
Either<Unit, FlowyError> successOrFail) = _Finish;
|
Either<Unit, FlowyError> successOrFail,
|
||||||
|
) = _Finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
class GridFieldEquatable extends Equatable {
|
class GridFieldEquatable extends Equatable {
|
||||||
|
@ -40,7 +40,9 @@ class GridHeaderBloc extends Bloc<GridHeaderEvent, GridHeaderState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _moveField(
|
Future<void> _moveField(
|
||||||
_MoveField value, Emitter<GridHeaderState> emit) async {
|
_MoveField value,
|
||||||
|
Emitter<GridHeaderState> emit,
|
||||||
|
) async {
|
||||||
final fields = List<FieldInfo>.from(state.fields);
|
final fields = List<FieldInfo>.from(state.fields);
|
||||||
fields.insert(value.toIndex, fields.removeAt(value.fromIndex));
|
fields.insert(value.toIndex, fields.removeAt(value.fromIndex));
|
||||||
emit(state.copyWith(fields: fields));
|
emit(state.copyWith(fields: fields));
|
||||||
@ -69,7 +71,10 @@ class GridHeaderEvent with _$GridHeaderEvent {
|
|||||||
const factory GridHeaderEvent.didReceiveFieldUpdate(List<FieldInfo> fields) =
|
const factory GridHeaderEvent.didReceiveFieldUpdate(List<FieldInfo> fields) =
|
||||||
_DidReceiveFieldUpdate;
|
_DidReceiveFieldUpdate;
|
||||||
const factory GridHeaderEvent.moveField(
|
const factory GridHeaderEvent.moveField(
|
||||||
FieldPB field, int fromIndex, int toIndex) = _MoveField;
|
FieldPB field,
|
||||||
|
int fromIndex,
|
||||||
|
int toIndex,
|
||||||
|
) = _MoveField;
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
|
@ -35,11 +35,13 @@ class RowBloc extends Bloc<RowEvent, RowState> {
|
|||||||
final cells = cellByFieldId.values
|
final cells = cellByFieldId.values
|
||||||
.map((e) => GridCellEquatable(e.fieldInfo))
|
.map((e) => GridCellEquatable(e.fieldInfo))
|
||||||
.toList();
|
.toList();
|
||||||
emit(state.copyWith(
|
emit(
|
||||||
cellByFieldId: cellByFieldId,
|
state.copyWith(
|
||||||
cells: UnmodifiableListView(cells),
|
cellByFieldId: cellByFieldId,
|
||||||
changeReason: reason,
|
cells: UnmodifiableListView(cells),
|
||||||
));
|
changeReason: reason,
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -68,8 +70,9 @@ class RowEvent with _$RowEvent {
|
|||||||
const factory RowEvent.initial() = _InitialRow;
|
const factory RowEvent.initial() = _InitialRow;
|
||||||
const factory RowEvent.createRow() = _CreateRow;
|
const factory RowEvent.createRow() = _CreateRow;
|
||||||
const factory RowEvent.didReceiveCells(
|
const factory RowEvent.didReceiveCells(
|
||||||
CellByFieldId cellsByFieldId, RowsChangedReason reason) =
|
CellByFieldId cellsByFieldId,
|
||||||
_DidReceiveCells;
|
RowsChangedReason reason,
|
||||||
|
) = _DidReceiveCells;
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
|
@ -59,7 +59,8 @@ class RowDetailEvent with _$RowDetailEvent {
|
|||||||
const factory RowDetailEvent.initial() = _Initial;
|
const factory RowDetailEvent.initial() = _Initial;
|
||||||
const factory RowDetailEvent.deleteField(String fieldId) = _DeleteField;
|
const factory RowDetailEvent.deleteField(String fieldId) = _DeleteField;
|
||||||
const factory RowDetailEvent.didReceiveCellDatas(
|
const factory RowDetailEvent.didReceiveCellDatas(
|
||||||
List<CellIdentifier> gridCells) = _DidReceiveCellDatas;
|
List<CellIdentifier> gridCells,
|
||||||
|
) = _DidReceiveCellDatas;
|
||||||
}
|
}
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
|
@ -82,9 +82,10 @@ class CreateSortBloc extends Bloc<CreateSortEvent, CreateSortState> {
|
|||||||
|
|
||||||
Future<Either<Unit, FlowyError>> _createDefaultSort(FieldInfo field) async {
|
Future<Either<Unit, FlowyError>> _createDefaultSort(FieldInfo field) async {
|
||||||
final result = await _sortBackendSvc.insertSort(
|
final result = await _sortBackendSvc.insertSort(
|
||||||
fieldId: field.id,
|
fieldId: field.id,
|
||||||
fieldType: field.fieldType,
|
fieldType: field.fieldType,
|
||||||
condition: SortConditionPB.Ascending);
|
condition: SortConditionPB.Ascending,
|
||||||
|
);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,9 @@ class SortEditorEvent with _$SortEditorEvent {
|
|||||||
const factory SortEditorEvent.didReceiveSorts(List<SortInfo> sortInfos) =
|
const factory SortEditorEvent.didReceiveSorts(List<SortInfo> sortInfos) =
|
||||||
_DidReceiveSorts;
|
_DidReceiveSorts;
|
||||||
const factory SortEditorEvent.setCondition(
|
const factory SortEditorEvent.setCondition(
|
||||||
SortInfo sortInfo, SortConditionPB condition) = _SetCondition;
|
SortInfo sortInfo,
|
||||||
|
SortConditionPB condition,
|
||||||
|
) = _SetCondition;
|
||||||
const factory SortEditorEvent.deleteSort(SortInfo sortInfo) = _DeleteSort;
|
const factory SortEditorEvent.deleteSort(SortInfo sortInfo) = _DeleteSort;
|
||||||
const factory SortEditorEvent.deleteAllSorts() = _DeleteAllSorts;
|
const factory SortEditorEvent.deleteAllSorts() = _DeleteAllSorts;
|
||||||
}
|
}
|
||||||
|
@ -14,11 +14,13 @@ class SortMenuBloc extends Bloc<SortMenuEvent, SortMenuState> {
|
|||||||
void Function(List<FieldInfo>)? _onFieldFn;
|
void Function(List<FieldInfo>)? _onFieldFn;
|
||||||
|
|
||||||
SortMenuBloc({required this.viewId, required this.fieldController})
|
SortMenuBloc({required this.viewId, required this.fieldController})
|
||||||
: super(SortMenuState.initial(
|
: super(
|
||||||
viewId,
|
SortMenuState.initial(
|
||||||
fieldController.sortInfos,
|
viewId,
|
||||||
fieldController.fieldInfos,
|
fieldController.sortInfos,
|
||||||
)) {
|
fieldController.fieldInfos,
|
||||||
|
),
|
||||||
|
) {
|
||||||
on<SortMenuEvent>(
|
on<SortMenuEvent>(
|
||||||
(event, emit) async {
|
(event, emit) async {
|
||||||
event.when(
|
event.when(
|
||||||
|
@ -117,7 +117,8 @@ class FlowyGrid extends StatefulWidget {
|
|||||||
|
|
||||||
class _FlowyGridState extends State<FlowyGrid> {
|
class _FlowyGridState extends State<FlowyGrid> {
|
||||||
final _scrollController = GridScrollController(
|
final _scrollController = GridScrollController(
|
||||||
scrollGroupController: LinkedScrollControllerGroup());
|
scrollGroupController: LinkedScrollControllerGroup(),
|
||||||
|
);
|
||||||
late ScrollController headerScrollController;
|
late ScrollController headerScrollController;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -319,13 +320,14 @@ class _GridRowsState extends State<_GridRows> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
FlowyOverlay.show(
|
FlowyOverlay.show(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (BuildContext context) {
|
builder: (BuildContext context) {
|
||||||
return RowDetailPage(
|
return RowDetailPage(
|
||||||
cellBuilder: cellBuilder,
|
cellBuilder: cellBuilder,
|
||||||
dataController: dataController,
|
dataController: dataController,
|
||||||
);
|
);
|
||||||
});
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,9 +8,9 @@ class GridScrollController {
|
|||||||
|
|
||||||
final List<ScrollController> _linkHorizontalControllers = [];
|
final List<ScrollController> _linkHorizontalControllers = [];
|
||||||
|
|
||||||
GridScrollController(
|
GridScrollController({
|
||||||
{required LinkedScrollControllerGroup scrollGroupController})
|
required LinkedScrollControllerGroup scrollGroupController,
|
||||||
: _scrollGroupController = scrollGroupController,
|
}) : _scrollGroupController = scrollGroupController,
|
||||||
verticalController = ScrollController(),
|
verticalController = ScrollController(),
|
||||||
horizontalController = scrollGroupController.addAndGet();
|
horizontalController = scrollGroupController.addAndGet();
|
||||||
|
|
||||||
|
@ -28,10 +28,7 @@ class GridSize {
|
|||||||
vertical: GridSize.cellVPadding,
|
vertical: GridSize.cellVPadding,
|
||||||
);
|
);
|
||||||
|
|
||||||
static EdgeInsets get typeOptionContentInsets => const EdgeInsets.symmetric(
|
static EdgeInsets get typeOptionContentInsets => const EdgeInsets.all(4);
|
||||||
horizontal: 6,
|
|
||||||
vertical: 2,
|
|
||||||
);
|
|
||||||
|
|
||||||
static EdgeInsets get footerContentInsets => EdgeInsets.fromLTRB(
|
static EdgeInsets get footerContentInsets => EdgeInsets.fromLTRB(
|
||||||
GridSize.leadingHeaderPadding,
|
GridSize.leadingHeaderPadding,
|
||||||
|
@ -21,10 +21,11 @@ class GridAccessoryMenu extends StatelessWidget {
|
|||||||
child: MultiBlocListener(
|
child: MultiBlocListener(
|
||||||
listeners: [
|
listeners: [
|
||||||
BlocListener<GridFilterMenuBloc, GridFilterMenuState>(
|
BlocListener<GridFilterMenuBloc, GridFilterMenuState>(
|
||||||
listenWhen: (p, c) => p.isVisible != c.isVisible,
|
listenWhen: (p, c) => p.isVisible != c.isVisible,
|
||||||
listener: (context, state) => context
|
listener: (context, state) => context
|
||||||
.read<GridAccessoryMenuBloc>()
|
.read<GridAccessoryMenuBloc>()
|
||||||
.add(const GridAccessoryMenuEvent.toggleMenu())),
|
.add(const GridAccessoryMenuEvent.toggleMenu()),
|
||||||
|
),
|
||||||
BlocListener<SortMenuBloc, SortMenuState>(
|
BlocListener<SortMenuBloc, SortMenuState>(
|
||||||
listenWhen: (p, c) => p.isVisible != c.isVisible,
|
listenWhen: (p, c) => p.isVisible != c.isVisible,
|
||||||
listener: (context, state) => context
|
listener: (context, state) => context
|
||||||
|
@ -100,7 +100,9 @@ class _CheckboxFilterEditorState extends State<CheckboxFilterEditor> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildFilterPanel(
|
Widget _buildFilterPanel(
|
||||||
BuildContext context, CheckboxFilterEditorState state) {
|
BuildContext context,
|
||||||
|
CheckboxFilterEditorState state,
|
||||||
|
) {
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: 20,
|
height: 20,
|
||||||
child: Row(
|
child: Row(
|
||||||
|
@ -70,9 +70,11 @@ class _ChecklistFilterChoicechipState extends State<ChecklistFilterChoicechip> {
|
|||||||
class ChecklistFilterEditor extends StatefulWidget {
|
class ChecklistFilterEditor extends StatefulWidget {
|
||||||
final ChecklistFilterEditorBloc bloc;
|
final ChecklistFilterEditorBloc bloc;
|
||||||
final PopoverMutex popoverMutex;
|
final PopoverMutex popoverMutex;
|
||||||
const ChecklistFilterEditor(
|
const ChecklistFilterEditor({
|
||||||
{required this.bloc, required this.popoverMutex, Key? key})
|
required this.bloc,
|
||||||
: super(key: key);
|
required this.popoverMutex,
|
||||||
|
Key? key,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ChecklistState createState() => ChecklistState();
|
ChecklistState createState() => ChecklistState();
|
||||||
|
@ -65,8 +65,10 @@ class _ChoicechipFilterDesc extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final arrow = Transform.rotate(
|
final arrow = Transform.rotate(
|
||||||
angle: -math.pi / 2,
|
angle: -math.pi / 2,
|
||||||
child: svgWidget("home/arrow_left",
|
child: svgWidget(
|
||||||
color: AFThemeExtension.of(context).textColor),
|
"home/arrow_left",
|
||||||
|
color: AFThemeExtension.of(context).textColor,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 2),
|
padding: const EdgeInsets.symmetric(horizontal: 2),
|
||||||
|
@ -110,7 +110,10 @@ class _SelectOptionFilterEditorState extends State<SelectOptionFilterEditor> {
|
|||||||
selectedOptionIds: state.filter.optionIds,
|
selectedOptionIds: state.filter.optionIds,
|
||||||
onSelectedOptions: (optionIds) {
|
onSelectedOptions: (optionIds) {
|
||||||
context.read<SelectOptionFilterEditorBloc>().add(
|
context.read<SelectOptionFilterEditorBloc>().add(
|
||||||
SelectOptionFilterEditorEvent.updateContent(optionIds));
|
SelectOptionFilterEditorEvent.updateContent(
|
||||||
|
optionIds,
|
||||||
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -132,7 +135,9 @@ class _SelectOptionFilterEditorState extends State<SelectOptionFilterEditor> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildFilterPanel(
|
Widget _buildFilterPanel(
|
||||||
BuildContext context, SelectOptionFilterEditorState state) {
|
BuildContext context,
|
||||||
|
SelectOptionFilterEditorState state,
|
||||||
|
) {
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: 20,
|
height: 20,
|
||||||
child: Row(
|
child: Row(
|
||||||
@ -144,7 +149,8 @@ class _SelectOptionFilterEditorState extends State<SelectOptionFilterEditor> {
|
|||||||
popoverMutex: popoverMutex,
|
popoverMutex: popoverMutex,
|
||||||
onCondition: (condition) {
|
onCondition: (condition) {
|
||||||
context.read<SelectOptionFilterEditorBloc>().add(
|
context.read<SelectOptionFilterEditorBloc>().add(
|
||||||
SelectOptionFilterEditorEvent.updateCondition(condition));
|
SelectOptionFilterEditorEvent.updateCondition(condition),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
const Spacer(),
|
const Spacer(),
|
||||||
|
@ -147,7 +147,9 @@ class _TextFilterEditorState extends State<TextFilterEditor> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildFilterTextField(
|
Widget _buildFilterTextField(
|
||||||
BuildContext context, TextFilterEditorState state) {
|
BuildContext context,
|
||||||
|
TextFilterEditorState state,
|
||||||
|
) {
|
||||||
return FlowyTextField(
|
return FlowyTextField(
|
||||||
text: state.filter.content,
|
text: state.filter.content,
|
||||||
hintText: LocaleKeys.grid_settings_typeAValue.tr(),
|
hintText: LocaleKeys.grid_settings_typeAValue.tr(),
|
||||||
|
@ -18,8 +18,10 @@ class ConditionButton extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final arrow = Transform.rotate(
|
final arrow = Transform.rotate(
|
||||||
angle: -math.pi / 2,
|
angle: -math.pi / 2,
|
||||||
child: svgWidget("home/arrow_left",
|
child: svgWidget(
|
||||||
color: AFThemeExtension.of(context).textColor),
|
"home/arrow_left",
|
||||||
|
color: AFThemeExtension.of(context).textColor,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
|
@ -117,7 +117,10 @@ class _FilterTextFieldDelegate extends SliverPersistentHeaderDelegate {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(
|
Widget build(
|
||||||
BuildContext context, double shrinkOffset, bool overlapsContent) {
|
BuildContext context,
|
||||||
|
double shrinkOffset,
|
||||||
|
bool overlapsContent,
|
||||||
|
) {
|
||||||
return Container(
|
return Container(
|
||||||
padding: const EdgeInsets.only(top: 4),
|
padding: const EdgeInsets.only(top: 4),
|
||||||
height: fixHeight,
|
height: fixHeight,
|
||||||
|
@ -95,17 +95,20 @@ class _GridHeaderCellContainer extends StatelessWidget {
|
|||||||
width: 1.0,
|
width: 1.0,
|
||||||
);
|
);
|
||||||
final decoration = BoxDecoration(
|
final decoration = BoxDecoration(
|
||||||
border: Border(
|
border: Border(
|
||||||
top: borderSide,
|
top: borderSide,
|
||||||
right: borderSide,
|
right: borderSide,
|
||||||
bottom: borderSide,
|
bottom: borderSide,
|
||||||
));
|
),
|
||||||
|
);
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
width: width,
|
width: width,
|
||||||
decoration: decoration,
|
decoration: decoration,
|
||||||
child: ConstrainedBox(
|
child: ConstrainedBox(
|
||||||
constraints: const BoxConstraints.expand(), child: child),
|
constraints: const BoxConstraints.expand(),
|
||||||
|
child: child,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -149,10 +152,12 @@ class FieldCellButton extends StatelessWidget {
|
|||||||
final VoidCallback onTap;
|
final VoidCallback onTap;
|
||||||
final FieldPB field;
|
final FieldPB field;
|
||||||
final int? maxLines;
|
final int? maxLines;
|
||||||
|
final BorderRadius? radius;
|
||||||
const FieldCellButton({
|
const FieldCellButton({
|
||||||
required this.field,
|
required this.field,
|
||||||
required this.onTap,
|
required this.onTap,
|
||||||
this.maxLines = 1,
|
this.maxLines = 1,
|
||||||
|
this.radius = BorderRadius.zero,
|
||||||
Key? key,
|
Key? key,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@ -169,7 +174,7 @@ class FieldCellButton extends StatelessWidget {
|
|||||||
leftIcon: FlowySvg(
|
leftIcon: FlowySvg(
|
||||||
name: field.fieldType.iconName(),
|
name: field.fieldType.iconName(),
|
||||||
),
|
),
|
||||||
radius: BorderRadius.zero,
|
radius: radius,
|
||||||
text: FlowyText.medium(
|
text: FlowyText.medium(
|
||||||
text,
|
text,
|
||||||
maxLines: maxLines,
|
maxLines: maxLines,
|
||||||
|
@ -101,25 +101,27 @@ class _FieldOperationList extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Column(children: [
|
return Column(
|
||||||
Flex(
|
children: [
|
||||||
direction: Axis.horizontal,
|
Flex(
|
||||||
children: [
|
direction: Axis.horizontal,
|
||||||
_actionCell(FieldAction.hide),
|
children: [
|
||||||
HSpace(GridSize.typeOptionSeparatorHeight),
|
_actionCell(FieldAction.hide),
|
||||||
_actionCell(FieldAction.duplicate),
|
HSpace(GridSize.typeOptionSeparatorHeight),
|
||||||
],
|
_actionCell(FieldAction.duplicate),
|
||||||
),
|
],
|
||||||
VSpace(GridSize.typeOptionSeparatorHeight),
|
),
|
||||||
Flex(
|
VSpace(GridSize.typeOptionSeparatorHeight),
|
||||||
direction: Axis.horizontal,
|
Flex(
|
||||||
children: [
|
direction: Axis.horizontal,
|
||||||
_actionCell(FieldAction.delete),
|
children: [
|
||||||
HSpace(GridSize.typeOptionSeparatorHeight),
|
_actionCell(FieldAction.delete),
|
||||||
const Spacer(),
|
HSpace(GridSize.typeOptionSeparatorHeight),
|
||||||
],
|
const Spacer(),
|
||||||
),
|
],
|
||||||
]);
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _actionCell(FieldAction action) {
|
Widget _actionCell(FieldAction action) {
|
||||||
|
@ -90,11 +90,13 @@ class _SwitchFieldButton extends StatelessWidget {
|
|||||||
mutex: popoverMutex,
|
mutex: popoverMutex,
|
||||||
offset: const Offset(8, 0),
|
offset: const Offset(8, 0),
|
||||||
popupBuilder: (popOverContext) {
|
popupBuilder: (popOverContext) {
|
||||||
return FieldTypeList(onSelectField: (newFieldType) {
|
return FieldTypeList(
|
||||||
context
|
onSelectField: (newFieldType) {
|
||||||
.read<FieldTypeOptionEditBloc>()
|
context
|
||||||
.add(FieldTypeOptionEditEvent.switchToField(newFieldType));
|
.read<FieldTypeOptionEditBloc>()
|
||||||
});
|
.add(FieldTypeOptionEditEvent.switchToField(newFieldType));
|
||||||
|
},
|
||||||
|
);
|
||||||
},
|
},
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12.0),
|
padding: const EdgeInsets.symmetric(horizontal: 12.0),
|
||||||
|
@ -39,7 +39,9 @@ class _GridHeaderSliverAdaptorState extends State<GridHeaderSliverAdaptor> {
|
|||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (context) {
|
create: (context) {
|
||||||
final bloc = getIt<GridHeaderBloc>(
|
final bloc = getIt<GridHeaderBloc>(
|
||||||
param1: widget.viewId, param2: widget.fieldController);
|
param1: widget.viewId,
|
||||||
|
param2: widget.fieldController,
|
||||||
|
);
|
||||||
bloc.add(const GridHeaderEvent.initial());
|
bloc.add(const GridHeaderEvent.initial());
|
||||||
return bloc;
|
return bloc;
|
||||||
},
|
},
|
||||||
@ -98,10 +100,16 @@ class _GridHeaderState extends State<_GridHeader> {
|
|||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
final cells = state.fields
|
final cells = state.fields
|
||||||
.where((field) => field.visibility)
|
.where((field) => field.visibility)
|
||||||
.map((field) =>
|
.map(
|
||||||
FieldCellContext(viewId: widget.viewId, field: field.field))
|
(field) =>
|
||||||
.map((ctx) =>
|
FieldCellContext(viewId: widget.viewId, field: field.field),
|
||||||
GridFieldCell(key: _getKeyById(ctx.field.id), cellContext: ctx))
|
)
|
||||||
|
.map(
|
||||||
|
(ctx) => GridFieldCell(
|
||||||
|
key: _getKeyById(ctx.field.id),
|
||||||
|
cellContext: ctx,
|
||||||
|
),
|
||||||
|
)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
@ -124,8 +132,12 @@ class _GridHeaderState extends State<_GridHeader> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onReorder(List<GridFieldCell> cells, int oldIndex, BuildContext context,
|
void _onReorder(
|
||||||
int newIndex) {
|
List<GridFieldCell> cells,
|
||||||
|
int oldIndex,
|
||||||
|
BuildContext context,
|
||||||
|
int newIndex,
|
||||||
|
) {
|
||||||
if (cells.length > oldIndex) {
|
if (cells.length > oldIndex) {
|
||||||
final field = cells[oldIndex].cellContext.field;
|
final field = cells[oldIndex].cellContext.field;
|
||||||
context
|
context
|
||||||
@ -177,7 +189,7 @@ class CreateFieldButton extends StatelessWidget {
|
|||||||
constraints: BoxConstraints.loose(const Size(240, 600)),
|
constraints: BoxConstraints.loose(const Size(240, 600)),
|
||||||
child: FlowyButton(
|
child: FlowyButton(
|
||||||
radius: BorderRadius.zero,
|
radius: BorderRadius.zero,
|
||||||
text: FlowyText.medium(LocaleKeys.grid_field_newColumn.tr()),
|
text: FlowyText.medium(LocaleKeys.grid_field_newProperty.tr()),
|
||||||
hoverColor: AFThemeExtension.of(context).greyHover,
|
hoverColor: AFThemeExtension.of(context).greyHover,
|
||||||
onTap: () {},
|
onTap: () {},
|
||||||
leftIcon: const FlowySvg(name: 'home/add'),
|
leftIcon: const FlowySvg(name: 'home/add'),
|
||||||
@ -197,12 +209,17 @@ class SliverHeaderDelegateImplementation
|
|||||||
final String gridId;
|
final String gridId;
|
||||||
final List<FieldPB> fields;
|
final List<FieldPB> fields;
|
||||||
|
|
||||||
SliverHeaderDelegateImplementation(
|
SliverHeaderDelegateImplementation({
|
||||||
{required this.gridId, required this.fields});
|
required this.gridId,
|
||||||
|
required this.fields,
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(
|
Widget build(
|
||||||
BuildContext context, double shrinkOffset, bool overlapsContent) {
|
BuildContext context,
|
||||||
|
double shrinkOffset,
|
||||||
|
bool overlapsContent,
|
||||||
|
) {
|
||||||
return _GridHeader(viewId: gridId);
|
return _GridHeader(viewId: gridId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,12 +76,13 @@ TypeOptionWidgetBuilder makeTypeOptionWidgetBuilder({
|
|||||||
);
|
);
|
||||||
case FieldType.DateTime:
|
case FieldType.DateTime:
|
||||||
return DateTypeOptionWidgetBuilder(
|
return DateTypeOptionWidgetBuilder(
|
||||||
makeTypeOptionContextWithDataController<DateTypeOptionPB>(
|
makeTypeOptionContextWithDataController<DateTypeOptionPB>(
|
||||||
viewId: viewId,
|
viewId: viewId,
|
||||||
fieldType: fieldType,
|
fieldType: fieldType,
|
||||||
dataController: dataController,
|
dataController: dataController,
|
||||||
),
|
),
|
||||||
popoverMutex);
|
popoverMutex,
|
||||||
|
);
|
||||||
case FieldType.SingleSelect:
|
case FieldType.SingleSelect:
|
||||||
return SingleSelectTypeOptionWidgetBuilder(
|
return SingleSelectTypeOptionWidgetBuilder(
|
||||||
makeTypeOptionContextWithDataController<SingleSelectTypeOptionPB>(
|
makeTypeOptionContextWithDataController<SingleSelectTypeOptionPB>(
|
||||||
|
@ -4,7 +4,8 @@ import 'builder.dart';
|
|||||||
|
|
||||||
class ChecklistTypeOptionWidgetBuilder extends TypeOptionWidgetBuilder {
|
class ChecklistTypeOptionWidgetBuilder extends TypeOptionWidgetBuilder {
|
||||||
ChecklistTypeOptionWidgetBuilder(
|
ChecklistTypeOptionWidgetBuilder(
|
||||||
ChecklistTypeOptionContext typeOptionContext);
|
ChecklistTypeOptionContext typeOptionContext,
|
||||||
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget? build(BuildContext context) => null;
|
Widget? build(BuildContext context) => null;
|
||||||
|
@ -299,6 +299,8 @@ extension DateFormatExtension on DateFormat {
|
|||||||
return LocaleKeys.grid_field_dateFormatLocal.tr();
|
return LocaleKeys.grid_field_dateFormatLocal.tr();
|
||||||
case DateFormat.US:
|
case DateFormat.US:
|
||||||
return LocaleKeys.grid_field_dateFormatUS.tr();
|
return LocaleKeys.grid_field_dateFormatUS.tr();
|
||||||
|
case DateFormat.DayMonthYear:
|
||||||
|
return LocaleKeys.grid_field_dateFormatDayMonthYear.tr();
|
||||||
default:
|
default:
|
||||||
throw UnimplementedError;
|
throw UnimplementedError;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ import 'package:appflowy/plugins/database_view/application/field/type_option/num
|
|||||||
import 'package:appflowy/plugins/database_view/application/field/type_option/type_option_context.dart';
|
import 'package:appflowy/plugins/database_view/application/field/type_option/type_option_context.dart';
|
||||||
import 'package:appflowy_popover/appflowy_popover.dart';
|
import 'package:appflowy_popover/appflowy_popover.dart';
|
||||||
import 'package:flowy_infra/image.dart';
|
import 'package:flowy_infra/image.dart';
|
||||||
|
import 'package:flowy_infra/theme_extension.dart';
|
||||||
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
import 'package:flowy_infra_ui/flowy_infra_ui.dart';
|
||||||
import 'package:appflowy_backend/protobuf/flowy-database/format.pbenum.dart';
|
import 'package:appflowy_backend/protobuf/flowy-database/format.pbenum.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@ -28,10 +29,13 @@ class NumberTypeOptionWidgetBuilder extends TypeOptionWidgetBuilder {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget? build(BuildContext context) {
|
Widget? build(BuildContext context) {
|
||||||
return Column(children: [
|
return Column(
|
||||||
VSpace(GridSize.typeOptionSeparatorHeight),
|
children: [
|
||||||
_widget,
|
VSpace(GridSize.typeOptionSeparatorHeight),
|
||||||
]);
|
const TypeOptionSeparator(),
|
||||||
|
_widget,
|
||||||
|
],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,55 +53,65 @@ class NumberTypeOptionWidget extends TypeOptionWidget {
|
|||||||
return BlocProvider(
|
return BlocProvider(
|
||||||
create: (context) =>
|
create: (context) =>
|
||||||
NumberTypeOptionBloc(typeOptionContext: typeOptionContext),
|
NumberTypeOptionBloc(typeOptionContext: typeOptionContext),
|
||||||
child: SizedBox(
|
child: BlocConsumer<NumberTypeOptionBloc, NumberTypeOptionState>(
|
||||||
height: GridSize.popoverItemHeight,
|
listener: (context, state) =>
|
||||||
child: BlocConsumer<NumberTypeOptionBloc, NumberTypeOptionState>(
|
typeOptionContext.typeOption = state.typeOption,
|
||||||
listener: (context, state) =>
|
builder: (context, state) {
|
||||||
typeOptionContext.typeOption = state.typeOption,
|
final selectNumUnitButton = SizedBox(
|
||||||
builder: (context, state) {
|
height: GridSize.popoverItemHeight,
|
||||||
final button = SizedBox(
|
child: FlowyButton(
|
||||||
height: GridSize.popoverItemHeight,
|
hoverColor: AFThemeExtension.of(context).lightGreyHover,
|
||||||
child: FlowyButton(
|
margin: GridSize.typeOptionContentInsets,
|
||||||
margin: GridSize.typeOptionContentInsets,
|
rightIcon: svgWidget(
|
||||||
rightIcon: svgWidget(
|
"grid/more",
|
||||||
"grid/more",
|
color: AFThemeExtension.of(context).textColor,
|
||||||
color: Theme.of(context).iconTheme.color,
|
|
||||||
),
|
|
||||||
text: Row(
|
|
||||||
children: [
|
|
||||||
FlowyText.medium(LocaleKeys.grid_field_numberFormat.tr()),
|
|
||||||
const Spacer(),
|
|
||||||
FlowyText.regular(state.typeOption.format.title()),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
text: FlowyText.regular(
|
||||||
|
state.typeOption.format.title(),
|
||||||
|
color: AFThemeExtension.of(context).textColor,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
return AppFlowyPopover(
|
final numFormatTitle = Container(
|
||||||
mutex: popoverMutex,
|
padding: const EdgeInsets.only(left: 6),
|
||||||
triggerActions:
|
height: GridSize.popoverItemHeight,
|
||||||
PopoverTriggerFlags.hover | PopoverTriggerFlags.click,
|
alignment: Alignment.centerLeft,
|
||||||
offset: const Offset(8, 0),
|
child: FlowyText.medium(
|
||||||
constraints: BoxConstraints.loose(const Size(460, 440)),
|
LocaleKeys.grid_field_numberFormat.tr(),
|
||||||
margin: EdgeInsets.zero,
|
color: AFThemeExtension.of(context).textColor,
|
||||||
child: Padding(
|
),
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12.0),
|
);
|
||||||
child: button,
|
return Padding(
|
||||||
),
|
padding: const EdgeInsets.symmetric(horizontal: 12),
|
||||||
popupBuilder: (BuildContext popoverContext) {
|
child: Column(
|
||||||
return NumberFormatList(
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
onSelected: (format) {
|
children: [
|
||||||
context
|
numFormatTitle,
|
||||||
.read<NumberTypeOptionBloc>()
|
AppFlowyPopover(
|
||||||
.add(NumberTypeOptionEvent.didSelectFormat(format));
|
mutex: popoverMutex,
|
||||||
PopoverContainer.of(popoverContext).close();
|
triggerActions:
|
||||||
|
PopoverTriggerFlags.hover | PopoverTriggerFlags.click,
|
||||||
|
offset: const Offset(8, 0),
|
||||||
|
constraints: BoxConstraints.loose(const Size(460, 440)),
|
||||||
|
margin: EdgeInsets.zero,
|
||||||
|
child: selectNumUnitButton,
|
||||||
|
popupBuilder: (BuildContext popoverContext) {
|
||||||
|
return NumberFormatList(
|
||||||
|
onSelected: (format) {
|
||||||
|
context
|
||||||
|
.read<NumberTypeOptionBloc>()
|
||||||
|
.add(NumberTypeOptionEvent.didSelectFormat(format));
|
||||||
|
PopoverContainer.of(popoverContext).close();
|
||||||
|
},
|
||||||
|
selectedFormat: state.typeOption.format,
|
||||||
|
);
|
||||||
},
|
},
|
||||||
selectedFormat: state.typeOption.format,
|
),
|
||||||
);
|
],
|
||||||
},
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -108,9 +122,11 @@ typedef SelectNumberFormatCallback = Function(NumberFormat format);
|
|||||||
class NumberFormatList extends StatelessWidget {
|
class NumberFormatList extends StatelessWidget {
|
||||||
final SelectNumberFormatCallback onSelected;
|
final SelectNumberFormatCallback onSelected;
|
||||||
final NumberFormat selectedFormat;
|
final NumberFormat selectedFormat;
|
||||||
const NumberFormatList(
|
const NumberFormatList({
|
||||||
{required this.selectedFormat, required this.onSelected, Key? key})
|
required this.selectedFormat,
|
||||||
: super(key: key);
|
required this.onSelected,
|
||||||
|
Key? key,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -127,11 +143,12 @@ class NumberFormatList extends StatelessWidget {
|
|||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
final cells = state.formats.map((format) {
|
final cells = state.formats.map((format) {
|
||||||
return NumberFormatCell(
|
return NumberFormatCell(
|
||||||
isSelected: format == selectedFormat,
|
isSelected: format == selectedFormat,
|
||||||
format: format,
|
format: format,
|
||||||
onSelected: (format) {
|
onSelected: (format) {
|
||||||
onSelected(format);
|
onSelected(format);
|
||||||
});
|
},
|
||||||
|
);
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
final list = ListView.separated(
|
final list = ListView.separated(
|
||||||
|
@ -71,9 +71,11 @@ class OptionTitle extends StatelessWidget {
|
|||||||
return BlocBuilder<SelectOptionTypeOptionBloc, SelectOptionTypeOptionState>(
|
return BlocBuilder<SelectOptionTypeOptionBloc, SelectOptionTypeOptionState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
List<Widget> children = [
|
List<Widget> children = [
|
||||||
FlowyText.medium(
|
Padding(
|
||||||
LocaleKeys.grid_field_optionTitle.tr(),
|
padding: const EdgeInsets.only(left: 9),
|
||||||
color: Theme.of(context).hintColor,
|
child: FlowyText.medium(
|
||||||
|
LocaleKeys.grid_field_optionTitle.tr(),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
];
|
];
|
||||||
if (state.options.isNotEmpty && !state.isEditingOption) {
|
if (state.options.isNotEmpty && !state.isEditingOption) {
|
||||||
|
@ -66,7 +66,8 @@ class SelectOptionTypeOptionEditor extends StatelessWidget {
|
|||||||
if (showOptions) {
|
if (showOptions) {
|
||||||
cells.add(const TypeOptionSeparator());
|
cells.add(const TypeOptionSeparator());
|
||||||
cells.add(
|
cells.add(
|
||||||
SelectOptionColorList(selectedColor: state.option.color));
|
SelectOptionColorList(selectedColor: state.option.color),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
@ -126,9 +127,11 @@ class _DeleteTag extends StatelessWidget {
|
|||||||
class _OptionNameTextField extends StatelessWidget {
|
class _OptionNameTextField extends StatelessWidget {
|
||||||
final String name;
|
final String name;
|
||||||
final bool autoFocus;
|
final bool autoFocus;
|
||||||
const _OptionNameTextField(
|
const _OptionNameTextField({
|
||||||
{required this.name, required this.autoFocus, Key? key})
|
required this.name,
|
||||||
: super(key: key);
|
required this.autoFocus,
|
||||||
|
Key? key,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@ -157,7 +160,9 @@ class SelectOptionColorList extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final cells = SelectOptionColorPB.values.map((color) {
|
final cells = SelectOptionColorPB.values.map((color) {
|
||||||
return _SelectOptionColorCell(
|
return _SelectOptionColorCell(
|
||||||
color: color, isSelected: selectedColor == color);
|
color: color,
|
||||||
|
isSelected: selectedColor == color,
|
||||||
|
);
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
@ -195,9 +200,11 @@ class SelectOptionColorList extends StatelessWidget {
|
|||||||
class _SelectOptionColorCell extends StatelessWidget {
|
class _SelectOptionColorCell extends StatelessWidget {
|
||||||
final SelectOptionColorPB color;
|
final SelectOptionColorPB color;
|
||||||
final bool isSelected;
|
final bool isSelected;
|
||||||
const _SelectOptionColorCell(
|
const _SelectOptionColorCell({
|
||||||
{required this.color, required this.isSelected, Key? key})
|
required this.color,
|
||||||
: super(key: key);
|
required this.isSelected,
|
||||||
|
Key? key,
|
||||||
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -68,11 +68,13 @@ class _GridRowState extends State<GridRow> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
return Row(children: [
|
return Row(
|
||||||
const _RowLeading(),
|
children: [
|
||||||
content,
|
const _RowLeading(),
|
||||||
const _RowTrailing(),
|
content,
|
||||||
]);
|
const _RowTrailing(),
|
||||||
|
],
|
||||||
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -129,9 +131,11 @@ class _RowLeadingState extends State<_RowLeading> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
const _InsertButton(),
|
const _InsertButton(),
|
||||||
_MenuButton(openMenu: () {
|
_MenuButton(
|
||||||
popoverController.show();
|
openMenu: () {
|
||||||
}),
|
popoverController.show();
|
||||||
|
},
|
||||||
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -216,12 +220,13 @@ class RowContent extends StatelessWidget {
|
|||||||
!listEquals(previous.cells, current.cells),
|
!listEquals(previous.cells, current.cells),
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
return IntrinsicHeight(
|
return IntrinsicHeight(
|
||||||
child: Row(
|
child: Row(
|
||||||
mainAxisSize: MainAxisSize.max,
|
mainAxisSize: MainAxisSize.max,
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: _makeCells(context, state.cellByFieldId),
|
children: _makeCells(context, state.cellByFieldId),
|
||||||
));
|
),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,10 @@ class _FilterTextFieldDelegate extends SliverPersistentHeaderDelegate {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(
|
Widget build(
|
||||||
BuildContext context, double shrinkOffset, bool overlapsContent) {
|
BuildContext context,
|
||||||
|
double shrinkOffset,
|
||||||
|
bool overlapsContent,
|
||||||
|
) {
|
||||||
return Container(
|
return Container(
|
||||||
padding: const EdgeInsets.only(top: 4),
|
padding: const EdgeInsets.only(top: 4),
|
||||||
height: fixHeight,
|
height: fixHeight,
|
||||||
|
@ -76,13 +76,15 @@ class _SortList extends StatelessWidget {
|
|||||||
return BlocBuilder<SortEditorBloc, SortEditorState>(
|
return BlocBuilder<SortEditorBloc, SortEditorState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
final List<Widget> children = state.sortInfos
|
final List<Widget> children = state.sortInfos
|
||||||
.map((info) => Padding(
|
.map(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 6),
|
(info) => Padding(
|
||||||
child: _SortItem(
|
padding: const EdgeInsets.symmetric(vertical: 6),
|
||||||
sortInfo: info,
|
child: _SortItem(
|
||||||
popoverMutex: popoverMutex,
|
sortInfo: info,
|
||||||
),
|
popoverMutex: popoverMutex,
|
||||||
))
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user