diff --git a/.decidim-version b/.decidim-version index 166c9e29b70b1..12a91df0e0b30 100644 --- a/.decidim-version +++ b/.decidim-version @@ -1 +1 @@ -0.25.2 +0.26.4 diff --git a/.github/actions/module-rspec/action.yml b/.github/actions/module-rspec/action.yml new file mode 100644 index 0000000000000..2ad1e16db6896 --- /dev/null +++ b/.github/actions/module-rspec/action.yml @@ -0,0 +1,58 @@ +name: '[CI] Module rspec' +description: 'Test module with rspec' +inputs: + name: + description: 'Module Name' + required: true + github_token: + description: 'Github token' + required: true + ruby-version: + description: 'Ruby Version' + default: "2.7.5" + required: false + node-version: + description: 'Node version' + default: '16.9.1' + required: false + +runs: + using: "composite" + steps: + - uses: rokroskar/workflow-run-cleanup-action@v0.3.3 + if: "github.ref != 'refs/heads/develop'" + env: + GITHUB_TOKEN: " ${{ inputs.github_token }}" + - uses: ruby/setup-ruby@v1 + with: + ruby-version: ${{ inputs.ruby-version }} + bundler-cache: true + - uses: actions/setup-node@v1 + with: + node-version: ${{ inputs.node-version }} + - name: Get npm cache directory path + id: npm-cache-dir-path + run: echo "::set-output name=dir::$(npm get cache)-${{ inputs.name }}" + shell: "bash" + - uses: actions/cache@v2 + id: npm-cache + with: + path: ${{ steps.npm-cache-dir-path.outputs.dir }} + key: npm-${{ hashFiles('**/package-lock.json') }} + restore-keys: | + npm- + - run: bundle exec rake test_app + name: Create test app + shell: "bash" + - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots + name: Create the screenshots folder + shell: "bash" + - uses: nanasess/setup-chromedriver@v1.0.1 + - run: RAILS_ENV=test bundle exec rails assets:precompile + name: Precompile assets + working-directory: ./spec/decidim_dummy_app/ + shell: "bash" + - run: bundle exec brakeman --rails6 --force-scan . + name: Scanning Security issues on module + working-directory: ${{ inputs.name }} + shell: "bash" diff --git a/.github/workflows/ci_accountability.yml b/.github/workflows/ci_accountability.yml index 9bfe96e837f49..5b9916af2b891 100644 --- a/.github/workflows/ci_accountability.yml +++ b/.github/workflows/ci_accountability.yml @@ -23,15 +23,14 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-accountability jobs: main: name: Tests - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 if: "!startsWith(github.head_ref, 'chore/l10n')" timeout-minutes: 60 services: @@ -45,47 +44,28 @@ jobs: --health-retries 5 env: POSTGRES_PASSWORD: postgres + validator: + image: ghcr.io/validator/validator:latest + ports: ["8888:8888"] env: DATABASE_USERNAME: postgres DATABASE_PASSWORD: postgres DATABASE_HOST: localhost RUBYOPT: '-W:no-deprecated' + VALIDATOR_HTML_URI: http://localhost:8888/ steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 - if: "github.ref != 'refs/heads/develop'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - uses: actions/checkout@v2.0.0 with: fetch-depth: 1 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ env.RUBY_VERSION }} - bundler-cache: true - - uses: actions/setup-node@v1 + - uses: ./.github/actions/module-rspec with: - node-version: ${{ env.NODE_VERSION }} - - name: Get npm cache directory path - id: npm-cache-dir-path - run: echo "::set-output name=dir::$(npm get cache)-${{ env.DECIDIM_MODULE }}" - - uses: actions/cache@v2 - id: npm-cache - with: - path: ${{ steps.npm-cache-dir-path.outputs.dir }} - key: npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - npm- - - run: bundle exec rake test_app - name: Create test app - - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots - name: Create the screenshots folder - - uses: nanasess/setup-chromedriver@v1.0.1 - - run: RAILS_ENV=test bundle exec rails assets:precompile - name: Precompile assets - working-directory: ./spec/decidim_dummy_app/ + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} - run: bundle exec rspec name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh $DECIDIM_MODULE $GITHUB_EVENT_PATH name: Upload coverage - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/ci_admin.yml b/.github/workflows/ci_admin.yml index ba5c69bfdc65b..2851d6f87c63c 100644 --- a/.github/workflows/ci_admin.yml +++ b/.github/workflows/ci_admin.yml @@ -1,4 +1,4 @@ -name: "[CI] Admin" +name: "[CI] Admin (unit tests)" on: push: branches: @@ -18,15 +18,14 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-admin jobs: main: name: Tests - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 if: "!startsWith(github.head_ref, 'chore/l10n')" timeout-minutes: 60 services: @@ -46,41 +45,18 @@ jobs: DATABASE_HOST: localhost RUBYOPT: '-W:no-deprecated' steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 - if: "github.ref != 'refs/heads/develop'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - uses: actions/checkout@v2.0.0 with: fetch-depth: 1 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ env.RUBY_VERSION }} - bundler-cache: true - - uses: actions/setup-node@v1 + - uses: ./.github/actions/module-rspec with: - node-version: ${{ env.NODE_VERSION }} - - name: Get npm cache directory path - id: npm-cache-dir-path - run: echo "::set-output name=dir::$(npm get cache)-${{ env.DECIDIM_MODULE }}" - - uses: actions/cache@v2 - id: npm-cache - with: - path: ${{ steps.npm-cache-dir-path.outputs.dir }} - key: npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - npm- - - run: bundle exec rake test_app - name: Create test app - - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots - name: Create the screenshots folder - - uses: nanasess/setup-chromedriver@v1.0.1 - - run: RAILS_ENV=test bundle exec rails assets:precompile - name: Precompile assets - working-directory: ./spec/decidim_dummy_app/ - - run: bundle exec rspec + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} + - run: bundle exec rspec --exclude-pattern 'spec/system/**/*_spec.rb' name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh $DECIDIM_MODULE $GITHUB_EVENT_PATH name: Upload coverage - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/ci_admin_system_1.yml b/.github/workflows/ci_admin_system_1.yml new file mode 100644 index 0000000000000..260b6342b38b3 --- /dev/null +++ b/.github/workflows/ci_admin_system_1.yml @@ -0,0 +1,75 @@ +name: "[CI] Admin (system tests 1)" +on: + push: + branches: + - develop + - release/* + - "*-stable" + pull_request: + branches-ignore: + - "chore/l10n*" + paths: + - "*" + - ".github/**" + - "decidim-admin/**" + - "decidim-core/**" + - "decidim-dev/**" + - "decidim-participatory_processes/**" + +env: + CI: "true" + RUBY_VERSION: 2.7.5 + NODE_VERSION: 16.9.1 + DECIDIM_MODULE: decidim-admin + +jobs: + main: + name: Tests + runs-on: ubuntu-20.04 + if: "!startsWith(github.head_ref, 'chore/l10n')" + timeout-minutes: 60 + services: + postgres: + image: postgres:11 + ports: ["5432:5432"] + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + env: + POSTGRES_PASSWORD: postgres + validator: + image: ghcr.io/validator/validator:latest + ports: ["8888:8888"] + env: + DATABASE_USERNAME: postgres + DATABASE_PASSWORD: postgres + DATABASE_HOST: localhost + RUBYOPT: '-W:no-deprecated' + VALIDATOR_HTML_URI: http://localhost:8888/ + steps: + - uses: actions/checkout@v2.0.0 + with: + fetch-depth: 1 + - uses: ./.github/actions/module-rspec + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} + - run: | + count=$(ls spec/system/*_spec.rb | wc -l | tr -d ' ') + half=$(expr $count / 2) + list_of_files=$(ls spec/system/*_spec.rb | sed -n "1,$(echo $half)p" | xargs) + bundle exec rspec $list_of_files + name: RSpec + working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" + - run: ./.github/upload_coverage.sh $DECIDIM_MODULE $GITHUB_EVENT_PATH + name: Upload coverage + - uses: actions/upload-artifact@v2 + if: always() + with: + name: screenshots + path: ./spec/decidim_dummy_app/tmp/screenshots + if-no-files-found: ignore diff --git a/.github/workflows/ci_admin_system_2.yml b/.github/workflows/ci_admin_system_2.yml new file mode 100644 index 0000000000000..4fea30c920bee --- /dev/null +++ b/.github/workflows/ci_admin_system_2.yml @@ -0,0 +1,71 @@ +name: "[CI] Admin (system tests 2)" +on: + push: + branches: + - develop + - release/* + - "*-stable" + pull_request: + branches-ignore: + - "chore/l10n*" + paths: + - "*" + - ".github/**" + - "decidim-admin/**" + - "decidim-core/**" + - "decidim-dev/**" + - "decidim-participatory_processes/**" + +env: + CI: "true" + RUBY_VERSION: 2.7.5 + NODE_VERSION: 16.9.1 + DECIDIM_MODULE: decidim-admin + +jobs: + main: + name: Tests + runs-on: ubuntu-20.04 + if: "!startsWith(github.head_ref, 'chore/l10n')" + timeout-minutes: 60 + services: + postgres: + image: postgres:11 + ports: ["5432:5432"] + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + env: + POSTGRES_PASSWORD: postgres + env: + DATABASE_USERNAME: postgres + DATABASE_PASSWORD: postgres + DATABASE_HOST: localhost + RUBYOPT: '-W:no-deprecated' + steps: + - uses: actions/checkout@v2.0.0 + with: + fetch-depth: 1 + - uses: ./.github/actions/module-rspec + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} + - run: | + count=$(ls spec/system/*_spec.rb | wc -l | tr -d ' ') + half=$(expr $count / 2) + list_of_files=$(ls spec/system/*_spec.rb | sed -n "$(expr $half + 1), $(echo $count)p" | xargs) + bundle exec rspec $list_of_files + name: RSpec + working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" + - run: ./.github/upload_coverage.sh $DECIDIM_MODULE $GITHUB_EVENT_PATH + name: Upload coverage + - uses: actions/upload-artifact@v2 + if: always() + with: + name: screenshots + path: ./spec/decidim_dummy_app/tmp/screenshots + if-no-files-found: ignore diff --git a/.github/workflows/ci_api.yml b/.github/workflows/ci_api.yml index 6585d9da5fd69..b74bc376cba6d 100644 --- a/.github/workflows/ci_api.yml +++ b/.github/workflows/ci_api.yml @@ -19,15 +19,14 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-api jobs: main: name: Tests - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 if: "!startsWith(github.head_ref, 'chore/l10n')" timeout-minutes: 60 services: @@ -47,41 +46,18 @@ jobs: DATABASE_HOST: localhost RUBYOPT: '-W:no-deprecated' steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 - if: "github.ref != 'refs/heads/develop'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - uses: actions/checkout@v2.0.0 with: fetch-depth: 1 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ env.RUBY_VERSION }} - bundler-cache: true - - uses: actions/setup-node@v1 + - uses: ./.github/actions/module-rspec with: - node-version: ${{ env.NODE_VERSION }} - - name: Get npm cache directory path - id: npm-cache-dir-path - run: echo "::set-output name=dir::$(npm get cache)-${{ env.DECIDIM_MODULE }}" - - uses: actions/cache@v2 - id: npm-cache - with: - path: ${{ steps.npm-cache-dir-path.outputs.dir }} - key: npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - npm- - - run: bundle exec rake test_app - name: Create test app - - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots - name: Create the screenshots folder - - uses: nanasess/setup-chromedriver@v1.0.1 - - run: RAILS_ENV=test bundle exec rails assets:precompile - name: Precompile assets - working-directory: ./spec/decidim_dummy_app/ + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} - run: bundle exec rspec name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh $DECIDIM_MODULE $GITHUB_EVENT_PATH name: Upload coverage - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/ci_assemblies.yml b/.github/workflows/ci_assemblies.yml index 1ce6b01521a3c..2b1cfdebcf777 100644 --- a/.github/workflows/ci_assemblies.yml +++ b/.github/workflows/ci_assemblies.yml @@ -18,15 +18,14 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-assemblies jobs: main: name: Tests - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 if: "!startsWith(github.head_ref, 'chore/l10n')" timeout-minutes: 60 services: @@ -40,47 +39,28 @@ jobs: --health-retries 5 env: POSTGRES_PASSWORD: postgres + validator: + image: ghcr.io/validator/validator:latest + ports: ["8888:8888"] env: DATABASE_USERNAME: postgres DATABASE_PASSWORD: postgres DATABASE_HOST: localhost RUBYOPT: '-W:no-deprecated' + VALIDATOR_HTML_URI: http://localhost:8888/ steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 - if: "github.ref != 'refs/heads/develop'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - uses: actions/checkout@v2.0.0 with: fetch-depth: 1 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ env.RUBY_VERSION }} - bundler-cache: true - - uses: actions/setup-node@v1 + - uses: ./.github/actions/module-rspec with: - node-version: ${{ env.NODE_VERSION }} - - name: Get npm cache directory path - id: npm-cache-dir-path - run: echo "::set-output name=dir::$(npm get cache)-${{ env.DECIDIM_MODULE }}" - - uses: actions/cache@v2 - id: npm-cache - with: - path: ${{ steps.npm-cache-dir-path.outputs.dir }} - key: npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - npm- - - run: bundle exec rake test_app - name: Create test app - - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots - name: Create the screenshots folder - - uses: nanasess/setup-chromedriver@v1.0.1 - - run: RAILS_ENV=test bundle exec rails assets:precompile - name: Precompile assets - working-directory: ./spec/decidim_dummy_app/ + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} - run: bundle exec rspec name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh $DECIDIM_MODULE $GITHUB_EVENT_PATH name: Upload coverage - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/ci_blogs.yml b/.github/workflows/ci_blogs.yml index 52f0576cec5a6..325afedc45462 100644 --- a/.github/workflows/ci_blogs.yml +++ b/.github/workflows/ci_blogs.yml @@ -21,15 +21,14 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-blogs jobs: main: name: Tests - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 if: "!startsWith(github.head_ref, 'chore/l10n')" timeout-minutes: 60 services: @@ -43,47 +42,28 @@ jobs: --health-retries 5 env: POSTGRES_PASSWORD: postgres + validator: + image: ghcr.io/validator/validator:latest + ports: ["8888:8888"] env: DATABASE_USERNAME: postgres DATABASE_PASSWORD: postgres DATABASE_HOST: localhost RUBYOPT: '-W:no-deprecated' + VALIDATOR_HTML_URI: http://localhost:8888/ steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 - if: "github.ref != 'refs/heads/develop'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - uses: actions/checkout@v2.0.0 with: fetch-depth: 1 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ env.RUBY_VERSION }} - bundler-cache: true - - uses: actions/setup-node@v1 + - uses: ./.github/actions/module-rspec with: - node-version: ${{ env.NODE_VERSION }} - - name: Get npm cache directory path - id: npm-cache-dir-path - run: echo "::set-output name=dir::$(npm get cache)-${{ env.DECIDIM_MODULE }}" - - uses: actions/cache@v2 - id: npm-cache - with: - path: ${{ steps.npm-cache-dir-path.outputs.dir }} - key: npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - npm- - - run: bundle exec rake test_app - name: Create test app - - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots - name: Create the screenshots folder - - uses: nanasess/setup-chromedriver@v1.0.1 - - run: RAILS_ENV=test bundle exec rails assets:precompile - name: Precompile assets - working-directory: ./spec/decidim_dummy_app/ + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} - run: bundle exec rspec name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh $DECIDIM_MODULE $GITHUB_EVENT_PATH name: Upload coverage - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/ci_budgets.yml b/.github/workflows/ci_budgets.yml index e0c9925c5007d..d42cb042f9bf9 100644 --- a/.github/workflows/ci_budgets.yml +++ b/.github/workflows/ci_budgets.yml @@ -20,15 +20,14 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-budgets jobs: main: name: Tests - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 if: "!startsWith(github.head_ref, 'chore/l10n')" timeout-minutes: 60 services: @@ -42,47 +41,28 @@ jobs: --health-retries 5 env: POSTGRES_PASSWORD: postgres + validator: + image: ghcr.io/validator/validator:latest + ports: ["8888:8888"] env: DATABASE_USERNAME: postgres DATABASE_PASSWORD: postgres DATABASE_HOST: localhost RUBYOPT: '-W:no-deprecated' + VALIDATOR_HTML_URI: http://localhost:8888/ steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 - if: "github.ref != 'refs/heads/develop'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - uses: actions/checkout@v2.0.0 with: fetch-depth: 1 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ env.RUBY_VERSION }} - bundler-cache: true - - uses: actions/setup-node@v1 + - uses: ./.github/actions/module-rspec with: - node-version: ${{ env.NODE_VERSION }} - - name: Get npm cache directory path - id: npm-cache-dir-path - run: echo "::set-output name=dir::$(npm get cache)-${{ env.DECIDIM_MODULE }}" - - uses: actions/cache@v2 - id: npm-cache - with: - path: ${{ steps.npm-cache-dir-path.outputs.dir }} - key: npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - npm- - - run: bundle exec rake test_app - name: Create test app - - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots - name: Create the screenshots folder - - uses: nanasess/setup-chromedriver@v1.0.1 - - run: RAILS_ENV=test bundle exec rails assets:precompile - name: Precompile assets - working-directory: ./spec/decidim_dummy_app/ + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} - run: bundle exec rspec name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh $DECIDIM_MODULE $GITHUB_EVENT_PATH name: Upload coverage - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/ci_comments.yml b/.github/workflows/ci_comments.yml index 685035d40a168..cae48432a1f4c 100644 --- a/.github/workflows/ci_comments.yml +++ b/.github/workflows/ci_comments.yml @@ -18,15 +18,14 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-comments jobs: main: name: Tests - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 if: "!startsWith(github.head_ref, 'chore/l10n')" timeout-minutes: 60 services: @@ -40,51 +39,28 @@ jobs: --health-retries 5 env: POSTGRES_PASSWORD: postgres + validator: + image: ghcr.io/validator/validator:latest + ports: ["8888:8888"] env: DATABASE_USERNAME: postgres DATABASE_PASSWORD: postgres DATABASE_HOST: localhost RUBYOPT: "-W:no-deprecated" + VALIDATOR_HTML_URI: http://localhost:8888/ steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 - if: "github.ref != 'refs/heads/develop'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - uses: actions/checkout@v2.0.0 with: fetch-depth: 1 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ env.RUBY_VERSION }} - bundler-cache: true - - uses: actions/setup-node@v1 + - uses: ./.github/actions/module-rspec with: - node-version: ${{ env.NODE_VERSION }} - - name: Get npm cache directory path - id: npm-cache-dir-path - run: echo "::set-output name=dir::$(npm get cache)-${{ env.DECIDIM_MODULE }}" - - uses: actions/cache@v2 - id: npm-cache - with: - path: ${{ steps.npm-cache-dir-path.outputs.dir }} - key: npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - npm- - - name: Install JS dependencies - run: npm ci - - run: bundle exec rake test_app - name: Create test app - - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots - name: Create the screenshots folder - - uses: nanasess/setup-chromedriver@v1.0.1 - - run: RAILS_ENV=test bundle exec rails assets:precompile - name: Precompile assets - working-directory: ./spec/decidim_dummy_app/ - - run: npm run test - name: Test JS files + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} - run: bundle exec rspec name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh $DECIDIM_MODULE $GITHUB_EVENT_PATH name: Upload coverage - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/ci_conferences.yml b/.github/workflows/ci_conferences.yml index 2ff815ae716e6..d424f7220c616 100644 --- a/.github/workflows/ci_conferences.yml +++ b/.github/workflows/ci_conferences.yml @@ -19,15 +19,14 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-conferences jobs: main: name: Tests - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 if: "!startsWith(github.head_ref, 'chore/l10n')" timeout-minutes: 60 services: @@ -41,47 +40,28 @@ jobs: --health-retries 5 env: POSTGRES_PASSWORD: postgres + validator: + image: ghcr.io/validator/validator:latest + ports: ["8888:8888"] env: DATABASE_USERNAME: postgres DATABASE_PASSWORD: postgres DATABASE_HOST: localhost RUBYOPT: '-W:no-deprecated' + VALIDATOR_HTML_URI: http://localhost:8888/ steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 - if: "github.ref != 'refs/heads/develop'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - uses: actions/checkout@v2.0.0 with: fetch-depth: 1 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ env.RUBY_VERSION }} - bundler-cache: true - - uses: actions/setup-node@v1 + - uses: ./.github/actions/module-rspec with: - node-version: ${{ env.NODE_VERSION }} - - name: Get npm cache directory path - id: npm-cache-dir-path - run: echo "::set-output name=dir::$(npm get cache)-${{ env.DECIDIM_MODULE }}" - - uses: actions/cache@v2 - id: npm-cache - with: - path: ${{ steps.npm-cache-dir-path.outputs.dir }} - key: npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - npm- - - run: bundle exec rake test_app - name: Create test app - - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots - name: Create the screenshots folder - - uses: nanasess/setup-chromedriver@v1.0.1 - - run: RAILS_ENV=test bundle exec rails assets:precompile - name: Precompile assets - working-directory: ./spec/decidim_dummy_app/ + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} - run: bundle exec rspec name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh $DECIDIM_MODULE $GITHUB_EVENT_PATH name: Upload coverage - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/ci_consultations.yml b/.github/workflows/ci_consultations.yml index 665d42cb64892..4824fc15a8f5b 100644 --- a/.github/workflows/ci_consultations.yml +++ b/.github/workflows/ci_consultations.yml @@ -19,15 +19,14 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-consultations jobs: main: name: Tests - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 if: "!startsWith(github.head_ref, 'chore/l10n')" timeout-minutes: 60 services: @@ -41,47 +40,28 @@ jobs: --health-retries 5 env: POSTGRES_PASSWORD: postgres + validator: + image: ghcr.io/validator/validator:latest + ports: ["8888:8888"] env: DATABASE_USERNAME: postgres DATABASE_PASSWORD: postgres DATABASE_HOST: localhost RUBYOPT: '-W:no-deprecated' + VALIDATOR_HTML_URI: http://localhost:8888/ steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 - if: "github.ref != 'refs/heads/develop'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - uses: actions/checkout@v2.0.0 with: fetch-depth: 1 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ env.RUBY_VERSION }} - bundler-cache: true - - uses: actions/setup-node@v1 + - uses: ./.github/actions/module-rspec with: - node-version: ${{ env.NODE_VERSION }} - - name: Get npm cache directory path - id: npm-cache-dir-path - run: echo "::set-output name=dir::$(npm get cache)-${{ env.DECIDIM_MODULE }}" - - uses: actions/cache@v2 - id: npm-cache - with: - path: ${{ steps.npm-cache-dir-path.outputs.dir }} - key: npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - npm- - - run: bundle exec rake test_app - name: Create test app - - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots - name: Create the screenshots folder - - uses: nanasess/setup-chromedriver@v1.0.1 - - run: RAILS_ENV=test bundle exec rails assets:precompile - name: Precompile assets - working-directory: ./spec/decidim_dummy_app/ + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} - run: bundle exec rspec name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh $DECIDIM_MODULE $GITHUB_EVENT_PATH name: Upload coverage - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/ci_core_lib.yml b/.github/workflows/ci_core_lib.yml new file mode 100644 index 0000000000000..f2b5e5766eab0 --- /dev/null +++ b/.github/workflows/ci_core_lib.yml @@ -0,0 +1,66 @@ +name: "[CI] Core (lib specs)" +on: + push: + branches: + - develop + - release/* + - "*-stable" + pull_request: + branches-ignore: + - "chore/l10n*" + paths: + - "*" + - ".github/**" + - "decidim-api/**" + - "decidim-core/**" + - "decidim-dev/**" + +env: + CI: "true" + RUBY_VERSION: 2.7.5 + NODE_VERSION: 16.9.1 + DECIDIM_MODULE: decidim-core + +jobs: + main: + name: Tests + runs-on: ubuntu-20.04 + if: "!startsWith(github.head_ref, 'chore/l10n')" + timeout-minutes: 60 + services: + postgres: + image: postgres:11 + ports: ["5432:5432"] + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + env: + POSTGRES_PASSWORD: postgres + env: + DATABASE_USERNAME: postgres + DATABASE_PASSWORD: postgres + DATABASE_HOST: localhost + RUBYOPT: '-W:no-deprecated' + steps: + - uses: actions/checkout@v2.0.0 + with: + fetch-depth: 1 + - uses: ./.github/actions/module-rspec + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} + - run: bundle exec rspec spec/lib + name: RSpec + working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" + - run: ./.github/upload_coverage.sh $DECIDIM_MODULE $GITHUB_EVENT_PATH + name: Upload coverage + - uses: actions/upload-artifact@v2 + if: always() + with: + name: screenshots + path: ./spec/decidim_dummy_app/tmp/screenshots + if-no-files-found: ignore diff --git a/.github/workflows/ci_core_system.yml b/.github/workflows/ci_core_system.yml index bcf088a2b6654..7f8a56f6bb8d0 100644 --- a/.github/workflows/ci_core_system.yml +++ b/.github/workflows/ci_core_system.yml @@ -17,15 +17,14 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-core jobs: main: name: Tests - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 if: "!startsWith(github.head_ref, 'chore/l10n')" timeout-minutes: 60 services: @@ -39,47 +38,28 @@ jobs: --health-retries 5 env: POSTGRES_PASSWORD: postgres + validator: + image: ghcr.io/validator/validator:latest + ports: ["8888:8888"] env: DATABASE_USERNAME: postgres DATABASE_PASSWORD: postgres DATABASE_HOST: localhost RUBYOPT: '-W:no-deprecated' + VALIDATOR_HTML_URI: http://localhost:8888/ steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 - if: "github.ref != 'refs/heads/develop'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - uses: actions/checkout@v2.0.0 with: fetch-depth: 1 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ env.RUBY_VERSION }} - bundler-cache: true - - uses: actions/setup-node@v1 + - uses: ./.github/actions/module-rspec with: - node-version: ${{ env.NODE_VERSION }} - - name: Get npm cache directory path - id: npm-cache-dir-path - run: echo "::set-output name=dir::$(npm get cache)-${{ env.DECIDIM_MODULE }}" - - uses: actions/cache@v2 - id: npm-cache - with: - path: ${{ steps.npm-cache-dir-path.outputs.dir }} - key: npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - npm- - - run: bundle exec rake test_app - name: Create test app - - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots - name: Create the screenshots folder - - uses: nanasess/setup-chromedriver@v1.0.1 - - run: RAILS_ENV=test bundle exec rails assets:precompile - name: Precompile assets - working-directory: ./spec/decidim_dummy_app/ + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} - run: bundle exec rspec spec/system name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh $DECIDIM_MODULE $GITHUB_EVENT_PATH name: Upload coverage - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/ci_core_unit.yml b/.github/workflows/ci_core_unit.yml index 5063b1bac1346..6364021bb915d 100644 --- a/.github/workflows/ci_core_unit.yml +++ b/.github/workflows/ci_core_unit.yml @@ -17,15 +17,14 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-core jobs: main: name: Tests - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 if: "!startsWith(github.head_ref, 'chore/l10n')" timeout-minutes: 60 services: @@ -45,41 +44,18 @@ jobs: DATABASE_HOST: localhost RUBYOPT: '-W:no-deprecated' steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 - if: "github.ref != 'refs/heads/develop'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - uses: actions/checkout@v2.0.0 with: fetch-depth: 1 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ env.RUBY_VERSION }} - bundler-cache: true - - uses: actions/setup-node@v1 + - uses: ./.github/actions/module-rspec with: - node-version: ${{ env.NODE_VERSION }} - - name: Get npm cache directory path - id: npm-cache-dir-path - run: echo "::set-output name=dir::$(npm get cache)-${{ env.DECIDIM_MODULE }}" - - uses: actions/cache@v2 - id: npm-cache - with: - path: ${{ steps.npm-cache-dir-path.outputs.dir }} - key: npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - npm- - - run: bundle exec rake test_app - name: Create test app - - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots - name: Create the screenshots folder - - uses: nanasess/setup-chromedriver@v1.0.1 - - run: RAILS_ENV=test bundle exec rails assets:precompile - name: Precompile assets - working-directory: ./spec/decidim_dummy_app/ - - run: bundle exec rspec --exclude-pattern 'spec/system/**/*_spec.rb' + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} + - run: bundle exec rspec --exclude-pattern 'spec/{system,lib}/**/*_spec.rb' name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh $DECIDIM_MODULE $GITHUB_EVENT_PATH name: Upload coverage - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/ci_debates.yml b/.github/workflows/ci_debates.yml index 62b4244f6849a..2e68aa6acae7b 100644 --- a/.github/workflows/ci_debates.yml +++ b/.github/workflows/ci_debates.yml @@ -19,15 +19,14 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-debates jobs: main: name: Tests - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 if: "!startsWith(github.head_ref, 'chore/l10n')" timeout-minutes: 60 services: @@ -41,47 +40,28 @@ jobs: --health-retries 5 env: POSTGRES_PASSWORD: postgres + validator: + image: ghcr.io/validator/validator:latest + ports: ["8888:8888"] env: DATABASE_USERNAME: postgres DATABASE_PASSWORD: postgres DATABASE_HOST: localhost RUBYOPT: '-W:no-deprecated' + VALIDATOR_HTML_URI: http://localhost:8888/ steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 - if: "github.ref != 'refs/heads/develop'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - uses: actions/checkout@v2.0.0 with: fetch-depth: 1 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ env.RUBY_VERSION }} - bundler-cache: true - - uses: actions/setup-node@v1 + - uses: ./.github/actions/module-rspec with: - node-version: ${{ env.NODE_VERSION }} - - name: Get npm cache directory path - id: npm-cache-dir-path - run: echo "::set-output name=dir::$(npm get cache)-${{ env.DECIDIM_MODULE }}" - - uses: actions/cache@v2 - id: npm-cache - with: - path: ${{ steps.npm-cache-dir-path.outputs.dir }} - key: npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - npm- - - run: bundle exec rake test_app - name: Create test app - - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots - name: Create the screenshots folder - - uses: nanasess/setup-chromedriver@v1.0.1 - - run: bundle exec rails assets:precompile - name: Precompile assets - working-directory: ./spec/decidim_dummy_app/ + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} - run: bundle exec rspec name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh $DECIDIM_MODULE $GITHUB_EVENT_PATH name: Upload coverage - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/ci_dev_system.yml b/.github/workflows/ci_dev_system.yml index d27509e46fd31..9b63b096d3bc0 100644 --- a/.github/workflows/ci_dev_system.yml +++ b/.github/workflows/ci_dev_system.yml @@ -16,15 +16,14 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-dev jobs: main: name: Tests - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 if: "!startsWith(github.head_ref, 'chore/l10n')" timeout-minutes: 60 services: @@ -44,41 +43,18 @@ jobs: DATABASE_HOST: localhost RUBYOPT: '-W:no-deprecated' steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 - if: "github.ref != 'refs/heads/develop'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - uses: actions/checkout@v2.0.0 with: fetch-depth: 1 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ env.RUBY_VERSION }} - bundler-cache: true - - uses: actions/setup-node@v1 + - uses: ./.github/actions/module-rspec with: - node-version: ${{ env.NODE_VERSION }} - - name: Get npm cache directory path - id: npm-cache-dir-path - run: echo "::set-output name=dir::$(npm get cache)-${{ env.DECIDIM_MODULE }}" - - uses: actions/cache@v2 - id: npm-cache - with: - path: ${{ steps.npm-cache-dir-path.outputs.dir }} - key: npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - npm- - - run: bundle exec rake test_app - name: Create test app - - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots - name: Create the screenshots folder - - uses: nanasess/setup-chromedriver@v1.0.1 - - run: RAILS_ENV=test bundle exec rails assets:precompile - name: Precompile assets - working-directory: ./spec/decidim_dummy_app/ + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} - run: bundle exec rspec spec/system name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh $DECIDIM_MODULE $GITHUB_EVENT_PATH name: Upload coverage - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/ci_elections_system_admin_1.yml b/.github/workflows/ci_elections_system_admin_1.yml new file mode 100644 index 0000000000000..db42892332694 --- /dev/null +++ b/.github/workflows/ci_elections_system_admin_1.yml @@ -0,0 +1,90 @@ +name: "[CI] Elections (system admin 1)" +on: + push: + branches: + - develop + - release/* + - "*-stable" + pull_request: + branches-ignore: + - "chore/l10n*" + paths: + - "*" + - ".github/**" + - "decidim-admin/**" + - "decidim-bulletin_board/**" + - "decidim-core/**" + - "decidim-dev/**" + - "decidim-elections/**" + - "decidim-forms/**" + - "decidim-proposals/**" + +env: + CI: "true" + RUBY_VERSION: 2.7.5 + NODE_VERSION: 16.9.1 + DECIDIM_MODULE: decidim-elections + +jobs: + main: + name: Tests + runs-on: ubuntu-20.04 + if: "!startsWith(github.head_ref, 'chore/l10n')" + timeout-minutes: 60 + services: + postgres: + image: postgres:11 + ports: ["5432:5432"] + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + env: + POSTGRES_PASSWORD: postgres + validator: + image: ghcr.io/validator/validator:latest + ports: ["8888:8888"] + bulletin_board: + image: codegram/decidim-bulletin-board:0.22.3 + ports: ["8000:8000"] + env: + DATABASE_URL: postgresql://postgres:postgres@postgres/bb + RAILS_ENV: test + SEED: 1 + IDENTIFICATION_PRIVATE_KEY: '{"kty":"RSA","n":"zMXsZpYPKkDlSmezX898y7zNOaJ7ENIN4kj4UhQ95Vm4HlgTpIs2VMMsO0eqynMaOR_G1mXdqbpbaJtXijBe4V8323QwGm6WVAa71E7pDXa5g6-uo5f8GePitN0YER9y2yNQN4uTaNzJiWV2uLBUYfMdj3SIif31YwLULHAOj3B_oleFK8coE_Qr3NzATcYBmsqE8AR4NljxTO6KDmP1SLdf5GBOBhOAIFbnL_Kpj2xkm7MS3hjMVKpiRhqA1UgX5oKZ8ixBv46fNJF0pBsHi3fHNjK9oZzgdx_AI-YFpdE_40-8bh_g9sWzxacqOM2-MdQLHbvRPEVltO3E8tr6I5YWrylcP7l9VD8OJeqjq2qFYHnGYdmLoD2XuXmI9EuBvSb9H4-qcartxZSIQCimKib_fxZvgrG1FSRRhK6YpvIdGv4-G2zfCCRsC4XD80TYI2bf-oYCoy7eU3_eVHFMV2yg4p1Wnuw2Vgq0edPL_bKaV9JvGx7F-U5juxNN0WZR9LzbPl4ReejzN95lyHgbj0nTH_u3bSpZmgJrQF-PwdnPcG46deVjJgUeosrlC4lQxVrRz0GL58BuFunnz2uYDBDrcJCiG60EbdkAFHjOcXU4wrUWATin7je_aqdBXhSnkTafcJAMvL7Y2Ld7vDge8nLqjAVlAi5am3rN0kqKT6M","e":"AQAB","kid":"a8e86f02ca27e1861bfc49e2a9a4614ca9068f8efdb6d42d19d3aab0eb2a31be"}' + DISABLE_DATABASE_ENVIRONMENT_CHECK: 1 + RAILS_SERVE_STATIC_FILES: enabled + DATABASE_CLEANER_ALLOW_REMOTE_DATABASE_URL: true + env: + DATABASE_USERNAME: postgres + DATABASE_PASSWORD: postgres + DATABASE_HOST: localhost + RUBYOPT: "-W:no-deprecated" + VALIDATOR_HTML_URI: http://localhost:8888/ + ELECTIONS_BULLETIN_BOARD_SERVER: http://localhost:8000/api + steps: + - uses: actions/checkout@v2.0.0 + with: + fetch-depth: 1 + - uses: ./.github/actions/module-rspec + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} + - run: | + count=$(ls spec/system/admin/*_spec.rb | wc -l | tr -d ' ') + half=$(expr $count / 2) + list_of_files=$(ls spec/system/admin/*_spec.rb | sed -n "1,$(echo $half)p" | xargs) + bundle exec rspec $list_of_files + name: RSpec + working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" + - run: ./.github/upload_coverage.sh decidim-elections-system-admin $GITHUB_EVENT_PATH + name: Upload coverage + - uses: actions/upload-artifact@v2 + if: always() + with: + name: screenshots + path: ./spec/decidim_dummy_app/tmp/screenshots + if-no-files-found: ignore diff --git a/.github/workflows/ci_elections_system_admin.yml b/.github/workflows/ci_elections_system_admin_2.yml similarity index 67% rename from .github/workflows/ci_elections_system_admin.yml rename to .github/workflows/ci_elections_system_admin_2.yml index 29192600dc0fc..9e00e1479709f 100644 --- a/.github/workflows/ci_elections_system_admin.yml +++ b/.github/workflows/ci_elections_system_admin_2.yml @@ -1,4 +1,4 @@ -name: "[CI] Elections (system admin)" +name: "[CI] Elections (system admin 2)" on: push: branches: @@ -21,8 +21,7 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-elections @@ -44,7 +43,7 @@ jobs: env: POSTGRES_PASSWORD: postgres bulletin_board: - image: codegram/decidim-bulletin-board:0.21.1 + image: codegram/decidim-bulletin-board:0.22.3 ports: ["8000:8000"] env: DATABASE_URL: postgresql://postgres:postgres@postgres/bb @@ -61,41 +60,22 @@ jobs: RUBYOPT: "-W:no-deprecated" ELECTIONS_BULLETIN_BOARD_SERVER: http://localhost:8000/api steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 - if: "github.ref != 'refs/heads/develop'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - uses: actions/checkout@v2.0.0 with: fetch-depth: 1 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ env.RUBY_VERSION }} - bundler-cache: true - - uses: actions/setup-node@v1 + - uses: ./.github/actions/module-rspec with: - node-version: ${{ env.NODE_VERSION }} - - name: Get npm cache directory path - id: npm-cache-dir-path - run: echo "::set-output name=dir::$(npm get cache)-${{ env.DECIDIM_MODULE }}" - - uses: actions/cache@v2 - id: npm-cache - with: - path: ${{ steps.npm-cache-dir-path.outputs.dir }} - key: npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - npm- - - run: bundle exec rake test_app - name: Create test app - - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots - name: Create the screenshots folder - - run: RAILS_ENV=test bundle exec rails assets:precompile - name: Precompile assets - working-directory: ./spec/decidim_dummy_app/ - - uses: nanasess/setup-chromedriver@v1.0.1 - - run: bundle exec rspec spec/system/admin + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} + - run: | + count=$(ls spec/system/admin/*_spec.rb | wc -l | tr -d ' ') + half=$(expr $count / 2) + list_of_files=$(ls spec/system/admin/*_spec.rb | sed -n "$(expr $half + 1), $(echo $count)p" | xargs) + bundle exec rspec $list_of_files name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh decidim-elections-system-admin $GITHUB_EVENT_PATH name: Upload coverage - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/ci_elections_system_public.yml b/.github/workflows/ci_elections_system_public.yml index 673b3708f21a5..b3ee2724f3c2f 100644 --- a/.github/workflows/ci_elections_system_public.yml +++ b/.github/workflows/ci_elections_system_public.yml @@ -21,15 +21,14 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-elections jobs: main: name: Tests - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 if: "!startsWith(github.head_ref, 'chore/l10n')" timeout-minutes: 60 services: @@ -43,8 +42,11 @@ jobs: --health-retries 5 env: POSTGRES_PASSWORD: postgres + validator: + image: ghcr.io/validator/validator:latest + ports: ["8888:8888"] bulletin_board: - image: codegram/decidim-bulletin-board:0.21.1 + image: codegram/decidim-bulletin-board:0.22.3 ports: ["8000:8000"] env: DATABASE_URL: postgresql://postgres:postgres@postgres/bb @@ -59,43 +61,21 @@ jobs: DATABASE_PASSWORD: postgres DATABASE_HOST: localhost RUBYOPT: "-W:no-deprecated" + VALIDATOR_HTML_URI: http://localhost:8888/ ELECTIONS_BULLETIN_BOARD_SERVER: http://localhost:8000/api steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 - if: "github.ref != 'refs/heads/develop'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - uses: actions/checkout@v2.0.0 with: fetch-depth: 1 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ env.RUBY_VERSION }} - bundler-cache: true - - uses: actions/setup-node@v1 + - uses: ./.github/actions/module-rspec with: - node-version: ${{ env.NODE_VERSION }} - - name: Get npm cache directory path - id: npm-cache-dir-path - run: echo "::set-output name=dir::$(npm get cache)-${{ env.DECIDIM_MODULE }}" - - uses: actions/cache@v2 - id: npm-cache - with: - path: ${{ steps.npm-cache-dir-path.outputs.dir }} - key: npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - npm- - - run: bundle exec rake test_app - name: Create test app - - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots - name: Create the screenshots folder - - run: RAILS_ENV=test bundle exec rails assets:precompile - name: Precompile assets - working-directory: ./spec/decidim_dummy_app/ - - uses: nanasess/setup-chromedriver@v1.0.1 + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} - run: bundle exec rspec spec/system/ --exclude-pattern 'spec/system/admin/**/*_spec.rb' name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh decidim-elections-system-public $GITHUB_EVENT_PATH name: Upload coverage - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/ci_elections_unit_tests.yml b/.github/workflows/ci_elections_unit_tests.yml index 04b483b26d12a..fc10cc94236d9 100644 --- a/.github/workflows/ci_elections_unit_tests.yml +++ b/.github/workflows/ci_elections_unit_tests.yml @@ -21,15 +21,14 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-elections jobs: main: name: Tests - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 if: "!startsWith(github.head_ref, 'chore/l10n')" timeout-minutes: 60 services: @@ -44,7 +43,7 @@ jobs: env: POSTGRES_PASSWORD: postgres bulletin_board: - image: codegram/decidim-bulletin-board:0.21.1 + image: codegram/decidim-bulletin-board:0.22.3 ports: ["8000:8000"] env: DATABASE_URL: postgresql://postgres:postgres@postgres/bb @@ -61,41 +60,18 @@ jobs: RUBYOPT: "-W:no-deprecated" ELECTIONS_BULLETIN_BOARD_SERVER: http://localhost:8000/api steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 - if: "github.ref != 'refs/heads/develop'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - uses: actions/checkout@v2.0.0 with: fetch-depth: 1 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ env.RUBY_VERSION }} - bundler-cache: true - - uses: actions/setup-node@v1 + - uses: ./.github/actions/module-rspec with: - node-version: ${{ env.NODE_VERSION }} - - name: Get npm cache directory path - id: npm-cache-dir-path - run: echo "::set-output name=dir::$(npm get cache)-${{ env.DECIDIM_MODULE }}" - - uses: actions/cache@v2 - id: npm-cache - with: - path: ${{ steps.npm-cache-dir-path.outputs.dir }} - key: npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - npm- - - run: bundle exec rake test_app - name: Create test app - - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots - name: Create the screenshots folder - - run: RAILS_ENV=test bundle exec rails assets:precompile - name: Precompile assets - working-directory: ./spec/decidim_dummy_app/ - - uses: nanasess/setup-chromedriver@v1.0.1 + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} - run: bundle exec rspec --exclude-pattern 'spec/system/**/*_spec.rb' name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh $DECIDIM_MODULE $GITHUB_EVENT_PATH name: Upload coverage - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/ci_forms.yml b/.github/workflows/ci_forms.yml index 206a324bb2691..607012f7d2e02 100644 --- a/.github/workflows/ci_forms.yml +++ b/.github/workflows/ci_forms.yml @@ -18,15 +18,14 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-forms jobs: main: name: Tests - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 if: "!startsWith(github.head_ref, 'chore/l10n')" timeout-minutes: 60 services: @@ -46,41 +45,18 @@ jobs: DATABASE_HOST: localhost RUBYOPT: '-W:no-deprecated' steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 - if: "github.ref != 'refs/heads/develop'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - uses: actions/checkout@v2.0.0 with: fetch-depth: 1 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ env.RUBY_VERSION }} - bundler-cache: true - - uses: actions/setup-node@v1 + - uses: ./.github/actions/module-rspec with: - node-version: ${{ env.NODE_VERSION }} - - name: Get npm cache directory path - id: npm-cache-dir-path - run: echo "::set-output name=dir::$(npm get cache)-${{ env.DECIDIM_MODULE }}" - - uses: actions/cache@v2 - id: npm-cache - with: - path: ${{ steps.npm-cache-dir-path.outputs.dir }} - key: npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - npm- - - run: bundle exec rake test_app - name: Create test app - - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots - name: Create the screenshots folder - - uses: nanasess/setup-chromedriver@v1.0.1 - - run: RAILS_ENV=test bundle exec rails assets:precompile - name: Precompile assets - working-directory: ./spec/decidim_dummy_app/ + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} - run: bundle exec rspec name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh $DECIDIM_MODULE $GITHUB_EVENT_PATH name: Upload coverage - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/ci_generators.yml b/.github/workflows/ci_generators.yml index 18200ac3872e5..ce4a8c3ba456b 100644 --- a/.github/workflows/ci_generators.yml +++ b/.github/workflows/ci_generators.yml @@ -16,15 +16,14 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-generators jobs: main: name: Tests - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 if: "!startsWith(github.head_ref, 'chore/l10n')" timeout-minutes: 60 services: @@ -44,7 +43,7 @@ jobs: DATABASE_HOST: localhost RUBYOPT: '-W:no-deprecated' steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 + - uses: rokroskar/workflow-run-cleanup-action@v0.3.3 if: "github.ref != 'refs/heads/develop'" env: GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" @@ -71,8 +70,13 @@ jobs: - run: bundle install --jobs 4 --retry 3 name: Install Ruby deps working-directory: ${{ env.DECIDIM_MODULE }} + - run: bundle exec brakeman --rails6 --force-scan . + name: Scanning Security issues on module + working-directory: ${{ env.DECIDIM_MODULE }} - run: bundle exec rspec name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh $DECIDIM_MODULE $GITHUB_EVENT_PATH name: Upload coverage diff --git a/.github/workflows/ci_initiatives.yml b/.github/workflows/ci_initiatives.yml index c6a0d76c35b1a..2280c67b736ab 100644 --- a/.github/workflows/ci_initiatives.yml +++ b/.github/workflows/ci_initiatives.yml @@ -1,4 +1,4 @@ -name: "[CI] Initiatives" +name: "[CI] Initiatives (unit tests)" on: push: branches: @@ -20,15 +20,14 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-initiatives jobs: main: name: Tests - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 if: "!startsWith(github.head_ref, 'chore/l10n')" timeout-minutes: 60 services: @@ -48,41 +47,18 @@ jobs: DATABASE_HOST: localhost RUBYOPT: '-W:no-deprecated' steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 - if: "github.ref != 'refs/heads/develop'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - uses: actions/checkout@v2.0.0 with: fetch-depth: 1 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ env.RUBY_VERSION }} - bundler-cache: true - - uses: actions/setup-node@v1 + - uses: ./.github/actions/module-rspec with: - node-version: ${{ env.NODE_VERSION }} - - name: Get npm cache directory path - id: npm-cache-dir-path - run: echo "::set-output name=dir::$(npm get cache)-${{ env.DECIDIM_MODULE }}" - - uses: actions/cache@v2 - id: npm-cache - with: - path: ${{ steps.npm-cache-dir-path.outputs.dir }} - key: npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - npm- - - run: bundle exec rake test_app - name: Create test app - - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots - name: Create the screenshots folder - - uses: nanasess/setup-chromedriver@v1.0.1 - - run: RAILS_ENV=test bundle exec rails assets:precompile - name: Precompile assets - working-directory: ./spec/decidim_dummy_app/ - - run: bundle exec rspec + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} + - run: bundle exec rspec --exclude-pattern 'spec/system/**/*_spec.rb' name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh $DECIDIM_MODULE $GITHUB_EVENT_PATH name: Upload coverage - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/ci_initiatives_system_admin.yml b/.github/workflows/ci_initiatives_system_admin.yml new file mode 100644 index 0000000000000..53c81faafdbcb --- /dev/null +++ b/.github/workflows/ci_initiatives_system_admin.yml @@ -0,0 +1,73 @@ +name: "[CI] Initiatives (system admin)" +on: + push: + branches: + - develop + - release/* + - "*-stable" + pull_request: + branches-ignore: + - "chore/l10n*" + paths: + - "*" + - ".github/**" + - "decidim-admin/**" + - "decidim-comments/**" + - "decidim-core/**" + - "decidim-dev/**" + - "decidim-initiatives/**" + - "decidim-verifications/**" + +env: + CI: "true" + RUBY_VERSION: 2.7.5 + NODE_VERSION: 16.9.1 + DECIDIM_MODULE: decidim-initiatives + +jobs: + main: + name: Tests + runs-on: ubuntu-20.04 + if: "!startsWith(github.head_ref, 'chore/l10n')" + timeout-minutes: 60 + services: + postgres: + image: postgres:11 + ports: ["5432:5432"] + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + env: + POSTGRES_PASSWORD: postgres + validator: + image: ghcr.io/validator/validator:latest + ports: ["8888:8888"] + env: + DATABASE_USERNAME: postgres + DATABASE_PASSWORD: postgres + DATABASE_HOST: localhost + RUBYOPT: '-W:no-deprecated' + VALIDATOR_HTML_URI: http://localhost:8888/ + steps: + - uses: actions/checkout@v2.0.0 + with: + fetch-depth: 1 + - uses: ./.github/actions/module-rspec + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} + - run: bundle exec rspec spec/system/admin + name: RSpec + working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" + - run: ./.github/upload_coverage.sh $DECIDIM_MODULE $GITHUB_EVENT_PATH + name: Upload coverage + - uses: actions/upload-artifact@v2 + if: always() + with: + name: screenshots + path: ./spec/decidim_dummy_app/tmp/screenshots + if-no-files-found: ignore diff --git a/.github/workflows/ci_initiatives_system_public.yml b/.github/workflows/ci_initiatives_system_public.yml new file mode 100644 index 0000000000000..e0a6648b2259a --- /dev/null +++ b/.github/workflows/ci_initiatives_system_public.yml @@ -0,0 +1,73 @@ +name: "[CI] Initiatives (system public)" +on: + push: + branches: + - develop + - release/* + - "*-stable" + pull_request: + branches-ignore: + - "chore/l10n*" + paths: + - "*" + - ".github/**" + - "decidim-admin/**" + - "decidim-comments/**" + - "decidim-core/**" + - "decidim-dev/**" + - "decidim-initiatives/**" + - "decidim-verifications/**" + +env: + CI: "true" + RUBY_VERSION: 2.7.5 + NODE_VERSION: 16.9.1 + DECIDIM_MODULE: decidim-initiatives + +jobs: + main: + name: Tests + runs-on: ubuntu-20.04 + if: "!startsWith(github.head_ref, 'chore/l10n')" + timeout-minutes: 60 + services: + postgres: + image: postgres:11 + ports: ["5432:5432"] + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + env: + POSTGRES_PASSWORD: postgres + validator: + image: ghcr.io/validator/validator:latest + ports: ["8888:8888"] + env: + DATABASE_USERNAME: postgres + DATABASE_PASSWORD: postgres + DATABASE_HOST: localhost + RUBYOPT: '-W:no-deprecated' + VALIDATOR_HTML_URI: http://localhost:8888/ + steps: + - uses: actions/checkout@v2.0.0 + with: + fetch-depth: 1 + - uses: ./.github/actions/module-rspec + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} + - run: bundle exec rspec spec/system/ --exclude-pattern 'spec/system/admin/**/*_spec.rb' + name: RSpec + working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" + - run: ./.github/upload_coverage.sh $DECIDIM_MODULE $GITHUB_EVENT_PATH + name: Upload coverage + - uses: actions/upload-artifact@v2 + if: always() + with: + name: screenshots + path: ./spec/decidim_dummy_app/tmp/screenshots + if-no-files-found: ignore diff --git a/.github/workflows/ci_main.yml b/.github/workflows/ci_main.yml index b754366dd2df7..36ef1772f1fe8 100644 --- a/.github/workflows/ci_main.yml +++ b/.github/workflows/ci_main.yml @@ -11,17 +11,16 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 jobs: main: name: Tests - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 timeout-minutes: 60 steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 + - uses: rokroskar/workflow-run-cleanup-action@v0.3.3 if: "github.ref != 'refs/heads/develop'" env: GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" @@ -49,3 +48,5 @@ jobs: run: npm ci - run: bundle exec rspec name: RSpec + env: + SIMPLECOV: "true" diff --git a/.github/workflows/ci_meetings_system_admin.yml b/.github/workflows/ci_meetings_system_admin.yml index 0f4addb057bb8..11ba9ff9f01c9 100644 --- a/.github/workflows/ci_meetings_system_admin.yml +++ b/.github/workflows/ci_meetings_system_admin.yml @@ -21,15 +21,14 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-meetings jobs: main: name: Tests - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 if: "!startsWith(github.head_ref, 'chore/l10n')" timeout-minutes: 60 services: @@ -43,47 +42,28 @@ jobs: --health-retries 5 env: POSTGRES_PASSWORD: postgres + validator: + image: ghcr.io/validator/validator:latest + ports: ["8888:8888"] env: DATABASE_USERNAME: postgres DATABASE_PASSWORD: postgres DATABASE_HOST: localhost RUBYOPT: '-W:no-deprecated' + VALIDATOR_HTML_URI: http://localhost:8888/ steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 - if: "github.ref != 'refs/heads/develop'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - uses: actions/checkout@v2.0.0 with: fetch-depth: 1 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ env.RUBY_VERSION }} - bundler-cache: true - - uses: actions/setup-node@v1 + - uses: ./.github/actions/module-rspec with: - node-version: ${{ env.NODE_VERSION }} - - name: Get npm cache directory path - id: npm-cache-dir-path - run: echo "::set-output name=dir::$(npm get cache)-${{ env.DECIDIM_MODULE }}" - - uses: actions/cache@v2 - id: npm-cache - with: - path: ${{ steps.npm-cache-dir-path.outputs.dir }} - key: npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - npm- - - run: bundle exec rake test_app - name: Create test app - - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots - name: Create the screenshots folder - - uses: nanasess/setup-chromedriver@v1.0.1 - - run: RAILS_ENV=test bundle exec rails assets:precompile - name: Precompile assets - working-directory: ./spec/decidim_dummy_app/ + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} - run: bundle exec rspec spec/system/admin name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh decidim-meetings-system-admin $GITHUB_EVENT_PATH name: Upload coverage - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/ci_meetings_system_public_1.yml b/.github/workflows/ci_meetings_system_public_1.yml new file mode 100644 index 0000000000000..ba7aaf643db14 --- /dev/null +++ b/.github/workflows/ci_meetings_system_public_1.yml @@ -0,0 +1,78 @@ +name: "[CI] Meetings (system public 1)" +on: + push: + branches: + - develop + - release/* + - "*-stable" + pull_request: + branches-ignore: + - "chore/l10n*" + paths: + - "*" + - ".github/**" + - "decidim-admin/**" + - "decidim-assemblies/**" + - "decidim-core/**" + - "decidim-dev/**" + - "decidim-forms/**" + - "decidim-meetings/**" + - "decidim-participatory_processes/**" + +env: + CI: "true" + RUBY_VERSION: 2.7.5 + NODE_VERSION: 16.9.1 + DECIDIM_MODULE: decidim-meetings + +jobs: + main: + name: Tests + runs-on: ubuntu-20.04 + if: "!startsWith(github.head_ref, 'chore/l10n')" + timeout-minutes: 60 + services: + postgres: + image: postgres:11 + ports: ["5432:5432"] + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + env: + POSTGRES_PASSWORD: postgres + validator: + image: ghcr.io/validator/validator:latest + ports: ["8888:8888"] + env: + DATABASE_USERNAME: postgres + DATABASE_PASSWORD: postgres + DATABASE_HOST: localhost + RUBYOPT: '-W:no-deprecated' + VALIDATOR_HTML_URI: http://localhost:8888/ + steps: + - uses: actions/checkout@v2.0.0 + with: + fetch-depth: 1 + - uses: ./.github/actions/module-rspec + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} + - run: | + count=$(ls spec/system/*_spec.rb | wc -l | tr -d ' ') + half=$(expr $count / 2) + list_of_files=$(ls spec/system/*_spec.rb | sed -n "1,$(echo $half)p" | xargs) + bundle exec rspec $list_of_files + name: RSpec + working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" + - run: ./.github/upload_coverage.sh decidim-meetings-system-public $GITHUB_EVENT_PATH + name: Upload coverage + - uses: actions/upload-artifact@v2 + if: always() + with: + name: screenshots + path: ./spec/decidim_dummy_app/tmp/screenshots + if-no-files-found: ignore diff --git a/.github/workflows/ci_meetings_system_public.yml b/.github/workflows/ci_meetings_system_public_2.yml similarity index 53% rename from .github/workflows/ci_meetings_system_public.yml rename to .github/workflows/ci_meetings_system_public_2.yml index 0c0b4a60d71fd..3e7e08bfa6007 100644 --- a/.github/workflows/ci_meetings_system_public.yml +++ b/.github/workflows/ci_meetings_system_public_2.yml @@ -1,4 +1,4 @@ -name: "[CI] Meetings (system public)" +name: "[CI] Meetings (system public 2)" on: push: branches: @@ -21,8 +21,7 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-meetings @@ -49,41 +48,22 @@ jobs: DATABASE_HOST: localhost RUBYOPT: '-W:no-deprecated' steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 - if: "github.ref != 'refs/heads/develop'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - uses: actions/checkout@v2.0.0 with: fetch-depth: 1 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ env.RUBY_VERSION }} - bundler-cache: true - - uses: actions/setup-node@v1 + - uses: ./.github/actions/module-rspec with: - node-version: ${{ env.NODE_VERSION }} - - name: Get npm cache directory path - id: npm-cache-dir-path - run: echo "::set-output name=dir::$(npm get cache)-${{ env.DECIDIM_MODULE }}" - - uses: actions/cache@v2 - id: npm-cache - with: - path: ${{ steps.npm-cache-dir-path.outputs.dir }} - key: npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - npm- - - run: bundle exec rake test_app - name: Create test app - - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots - name: Create the screenshots folder - - uses: nanasess/setup-chromedriver@v1.0.1 - - run: RAILS_ENV=test bundle exec rails assets:precompile - name: Precompile assets - working-directory: ./spec/decidim_dummy_app/ - - run: bundle exec rspec spec/system/ --exclude-pattern 'spec/system/admin/**/*_spec.rb' + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} + - run: | + count=$(ls spec/system/*_spec.rb | wc -l | tr -d ' ') + half=$(expr $count / 2) + list_of_files=$(ls spec/system/*_spec.rb | sed -n "$(expr $half + 1), $(echo $count)p" | xargs) + bundle exec rspec $list_of_files name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh decidim-meetings-system-public $GITHUB_EVENT_PATH name: Upload coverage - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/ci_meetings_unit_tests.yml b/.github/workflows/ci_meetings_unit_tests.yml index 0d42cb44026bd..65223a0fb1712 100644 --- a/.github/workflows/ci_meetings_unit_tests.yml +++ b/.github/workflows/ci_meetings_unit_tests.yml @@ -21,15 +21,14 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-meetings jobs: main: name: Tests - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 if: "!startsWith(github.head_ref, 'chore/l10n')" timeout-minutes: 60 services: @@ -49,41 +48,18 @@ jobs: DATABASE_HOST: localhost RUBYOPT: '-W:no-deprecated' steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 - if: "github.ref != 'refs/heads/develop'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - uses: actions/checkout@v2.0.0 with: fetch-depth: 1 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ env.RUBY_VERSION }} - bundler-cache: true - - uses: actions/setup-node@v1 + - uses: ./.github/actions/module-rspec with: - node-version: ${{ env.NODE_VERSION }} - - name: Get npm cache directory path - id: npm-cache-dir-path - run: echo "::set-output name=dir::$(npm get cache)-${{ env.DECIDIM_MODULE }}" - - uses: actions/cache@v2 - id: npm-cache - with: - path: ${{ steps.npm-cache-dir-path.outputs.dir }} - key: npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - npm- - - run: bundle exec rake test_app - name: Create test app - - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots - name: Create the screenshots folder - - uses: nanasess/setup-chromedriver@v1.0.1 - - run: RAILS_ENV=test bundle exec rails assets:precompile - name: Precompile assets - working-directory: ./spec/decidim_dummy_app/ + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} - run: bundle exec rspec --exclude-pattern 'spec/system/**/*_spec.rb' name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh $DECIDIM_MODULE $GITHUB_EVENT_PATH name: Upload coverage - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/ci_pages.yml b/.github/workflows/ci_pages.yml index 3477df644cfa3..dfe045b831392 100644 --- a/.github/workflows/ci_pages.yml +++ b/.github/workflows/ci_pages.yml @@ -18,15 +18,14 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-pages jobs: main: name: Tests - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 if: "!startsWith(github.head_ref, 'chore/l10n')" timeout-minutes: 60 services: @@ -40,47 +39,28 @@ jobs: --health-retries 5 env: POSTGRES_PASSWORD: postgres + validator: + image: ghcr.io/validator/validator:latest + ports: ["8888:8888"] env: DATABASE_USERNAME: postgres DATABASE_PASSWORD: postgres DATABASE_HOST: localhost RUBYOPT: '-W:no-deprecated' + VALIDATOR_HTML_URI: http://localhost:8888/ steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 - if: "github.ref != 'refs/heads/develop'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - uses: actions/checkout@v2.0.0 with: fetch-depth: 1 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ env.RUBY_VERSION }} - bundler-cache: true - - uses: actions/setup-node@v1 + - uses: ./.github/actions/module-rspec with: - node-version: ${{ env.NODE_VERSION }} - - name: Get npm cache directory path - id: npm-cache-dir-path - run: echo "::set-output name=dir::$(npm get cache)-${{ env.DECIDIM_MODULE }}" - - uses: actions/cache@v2 - id: npm-cache - with: - path: ${{ steps.npm-cache-dir-path.outputs.dir }} - key: npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - npm- - - run: bundle exec rake test_app - name: Create test app - - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots - name: Create the screenshots folder - - uses: nanasess/setup-chromedriver@v1.0.1 - - run: RAILS_ENV=test bundle exec rails assets:precompile - name: Precompile assets - working-directory: ./spec/decidim_dummy_app/ + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} - run: bundle exec rspec name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh $DECIDIM_MODULE $GITHUB_EVENT_PATH name: Upload coverage - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/ci_participatory_processes.yml b/.github/workflows/ci_participatory_processes.yml index b6dbc8f2fbe3b..c7fb39309078c 100644 --- a/.github/workflows/ci_participatory_processes.yml +++ b/.github/workflows/ci_participatory_processes.yml @@ -19,15 +19,14 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-participatory_processes jobs: main: name: Tests - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 if: "!startsWith(github.head_ref, 'chore/l10n')" timeout-minutes: 60 services: @@ -41,47 +40,28 @@ jobs: --health-retries 5 env: POSTGRES_PASSWORD: postgres + validator: + image: ghcr.io/validator/validator:latest + ports: ["8888:8888"] env: DATABASE_USERNAME: postgres DATABASE_PASSWORD: postgres DATABASE_HOST: localhost RUBYOPT: '-W:no-deprecated' + VALIDATOR_HTML_URI: http://localhost:8888/ steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 - if: "github.ref != 'refs/heads/develop'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - uses: actions/checkout@v2.0.0 with: fetch-depth: 1 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ env.RUBY_VERSION }} - bundler-cache: true - - uses: actions/setup-node@v1 + - uses: ./.github/actions/module-rspec with: - node-version: ${{ env.NODE_VERSION }} - - name: Get npm cache directory path - id: npm-cache-dir-path - run: echo "::set-output name=dir::$(npm get cache)-${{ env.DECIDIM_MODULE }}" - - uses: actions/cache@v2 - id: npm-cache - with: - path: ${{ steps.npm-cache-dir-path.outputs.dir }} - key: npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - npm- - - run: bundle exec rake test_app - name: Create test app - - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots - name: Create the screenshots folder - - uses: nanasess/setup-chromedriver@v1.0.1 - - run: RAILS_ENV=test bundle exec rails assets:precompile - name: Precompile assets - working-directory: ./spec/decidim_dummy_app/ + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} - run: bundle exec rspec name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh $DECIDIM_MODULE $GITHUB_EVENT_PATH name: Upload coverage - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/ci_proposals_system_admin.yml b/.github/workflows/ci_proposals_system_admin.yml index 16794c6c527c6..50717bb43a7a6 100644 --- a/.github/workflows/ci_proposals_system_admin.yml +++ b/.github/workflows/ci_proposals_system_admin.yml @@ -23,15 +23,14 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-proposals jobs: main: name: Tests - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 if: "!startsWith(github.head_ref, 'chore/l10n')" timeout-minutes: 60 services: @@ -45,47 +44,28 @@ jobs: --health-retries 5 env: POSTGRES_PASSWORD: postgres + validator: + image: ghcr.io/validator/validator:latest + ports: ["8888:8888"] env: DATABASE_USERNAME: postgres DATABASE_PASSWORD: postgres DATABASE_HOST: localhost RUBYOPT: '-W:no-deprecated' + VALIDATOR_HTML_URI: http://localhost:8888/ steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 - if: "github.ref != 'refs/heads/develop'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - uses: actions/checkout@v2.0.0 with: fetch-depth: 1 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ env.RUBY_VERSION }} - bundler-cache: true - - uses: actions/setup-node@v1 + - uses: ./.github/actions/module-rspec with: - node-version: ${{ env.NODE_VERSION }} - - name: Get npm cache directory path - id: npm-cache-dir-path - run: echo "::set-output name=dir::$(npm get cache)-${{ env.DECIDIM_MODULE }}" - - uses: actions/cache@v2 - id: npm-cache - with: - path: ${{ steps.npm-cache-dir-path.outputs.dir }} - key: npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - npm- - - run: bundle exec rake test_app - name: Create test app - - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots - name: Create the screenshots folder - - uses: nanasess/setup-chromedriver@v1.0.1 - - run: RAILS_ENV=test bundle exec rails assets:precompile - name: Precompile assets - working-directory: ./spec/decidim_dummy_app/ + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} - run: bundle exec rspec spec/system/admin name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh decidim-proposals-system-admin $GITHUB_EVENT_PATH name: Upload coverage - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/ci_proposals_system_public_1.yml b/.github/workflows/ci_proposals_system_public_1.yml index e400dd45b74b2..d551f91fe0186 100644 --- a/.github/workflows/ci_proposals_system_public_1.yml +++ b/.github/workflows/ci_proposals_system_public_1.yml @@ -23,15 +23,14 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-proposals jobs: main: name: Tests - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 if: "!startsWith(github.head_ref, 'chore/l10n')" timeout-minutes: 60 services: @@ -45,44 +44,23 @@ jobs: --health-retries 5 env: POSTGRES_PASSWORD: postgres + validator: + image: ghcr.io/validator/validator:latest + ports: ["8888:8888"] env: DATABASE_USERNAME: postgres DATABASE_PASSWORD: postgres DATABASE_HOST: localhost RUBYOPT: '-W:no-deprecated' + VALIDATOR_HTML_URI: http://localhost:8888/ steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 - if: "github.ref != 'refs/heads/develop'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - uses: actions/checkout@v2.0.0 with: fetch-depth: 1 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ env.RUBY_VERSION }} - bundler-cache: true - - uses: actions/setup-node@v1 + - uses: ./.github/actions/module-rspec with: - node-version: ${{ env.NODE_VERSION }} - - name: Get npm cache directory path - id: npm-cache-dir-path - run: echo "::set-output name=dir::$(npm get cache)-${{ env.DECIDIM_MODULE }}" - - uses: actions/cache@v2 - id: npm-cache - with: - path: ${{ steps.npm-cache-dir-path.outputs.dir }} - key: npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - npm- - - run: bundle exec rake test_app - name: Create test app - - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots - name: Create the screenshots folder - - uses: nanasess/setup-chromedriver@v1.0.1 - - run: RAILS_ENV=test bundle exec rails assets:precompile - name: Precompile assets - working-directory: ./spec/decidim_dummy_app/ + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} - run: | count=$(ls spec/system/*_spec.rb | wc -l | tr -d ' ') half=$(expr $count / 2) @@ -90,6 +68,8 @@ jobs: bundle exec rspec $list_of_files name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh decidim-proposals-system-public $GITHUB_EVENT_PATH name: Upload coverage - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/ci_proposals_system_public_2.yml b/.github/workflows/ci_proposals_system_public_2.yml index dfeea2a12419a..616d06902c8b0 100644 --- a/.github/workflows/ci_proposals_system_public_2.yml +++ b/.github/workflows/ci_proposals_system_public_2.yml @@ -23,8 +23,7 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-proposals @@ -51,38 +50,13 @@ jobs: DATABASE_HOST: localhost RUBYOPT: '-W:no-deprecated' steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 - if: "github.ref != 'refs/heads/develop'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - uses: actions/checkout@v2.0.0 with: fetch-depth: 1 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ env.RUBY_VERSION }} - bundler-cache: true - - uses: actions/setup-node@v1 + - uses: ./.github/actions/module-rspec with: - node-version: ${{ env.NODE_VERSION }} - - name: Get npm cache directory path - id: npm-cache-dir-path - run: echo "::set-output name=dir::$(npm get cache)-${{ env.DECIDIM_MODULE }}" - - uses: actions/cache@v2 - id: npm-cache - with: - path: ${{ steps.npm-cache-dir-path.outputs.dir }} - key: npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - npm- - - run: bundle exec rake test_app - name: Create test app - - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots - name: Create the screenshots folder - - uses: nanasess/setup-chromedriver@v1.0.1 - - run: RAILS_ENV=test bundle exec rails assets:precompile - name: Precompile assets - working-directory: ./spec/decidim_dummy_app/ + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} - run: | count=$(ls spec/system/*_spec.rb | wc -l | tr -d ' ') half=$(expr $count / 2) @@ -90,6 +64,8 @@ jobs: bundle exec rspec $list_of_files name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh decidim-proposals-system-public $GITHUB_EVENT_PATH name: Upload coverage - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/ci_proposals_unit_tests.yml b/.github/workflows/ci_proposals_unit_tests.yml index 050168de20749..31cc0d03148cb 100644 --- a/.github/workflows/ci_proposals_unit_tests.yml +++ b/.github/workflows/ci_proposals_unit_tests.yml @@ -23,15 +23,14 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-proposals jobs: main: name: Tests - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 if: "!startsWith(github.head_ref, 'chore/l10n')" timeout-minutes: 60 services: @@ -51,41 +50,18 @@ jobs: DATABASE_HOST: localhost RUBYOPT: '-W:no-deprecated' steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 - if: "github.ref != 'refs/heads/develop'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - uses: actions/checkout@v2.0.0 with: fetch-depth: 1 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ env.RUBY_VERSION }} - bundler-cache: true - - uses: actions/setup-node@v1 + - uses: ./.github/actions/module-rspec with: - node-version: ${{ env.NODE_VERSION }} - - name: Get npm cache directory path - id: npm-cache-dir-path - run: echo "::set-output name=dir::$(npm get cache)-${{ env.DECIDIM_MODULE }}" - - uses: actions/cache@v2 - id: npm-cache - with: - path: ${{ steps.npm-cache-dir-path.outputs.dir }} - key: npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - npm- - - run: bundle exec rake test_app - name: Create test app - - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots - name: Create the screenshots folder - - uses: nanasess/setup-chromedriver@v1.0.1 - - run: RAILS_ENV=test bundle exec rails assets:precompile - name: Precompile assets - working-directory: ./spec/decidim_dummy_app/ + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} - run: bundle exec rspec --exclude-pattern 'spec/system/**/*_spec.rb' name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh $DECIDIM_MODULE $GITHUB_EVENT_PATH name: Upload coverage - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/ci_sortitions.yml b/.github/workflows/ci_sortitions.yml index 009318137e8a9..d3723609188fb 100644 --- a/.github/workflows/ci_sortitions.yml +++ b/.github/workflows/ci_sortitions.yml @@ -20,15 +20,14 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-sortitions jobs: main: name: Tests - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 if: "!startsWith(github.head_ref, 'chore/l10n')" timeout-minutes: 60 services: @@ -42,47 +41,28 @@ jobs: --health-retries 5 env: POSTGRES_PASSWORD: postgres + validator: + image: ghcr.io/validator/validator:latest + ports: ["8888:8888"] env: DATABASE_USERNAME: postgres DATABASE_PASSWORD: postgres DATABASE_HOST: localhost RUBYOPT: '-W:no-deprecated' + VALIDATOR_HTML_URI: http://localhost:8888/ steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 - if: "github.ref != 'refs/heads/develop'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - uses: actions/checkout@v2.0.0 with: fetch-depth: 1 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ env.RUBY_VERSION }} - bundler-cache: true - - uses: actions/setup-node@v1 + - uses: ./.github/actions/module-rspec with: - node-version: ${{ env.NODE_VERSION }} - - name: Get npm cache directory path - id: npm-cache-dir-path - run: echo "::set-output name=dir::$(npm get cache)-${{ env.DECIDIM_MODULE }}" - - uses: actions/cache@v2 - id: npm-cache - with: - path: ${{ steps.npm-cache-dir-path.outputs.dir }} - key: npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - npm- - - run: bundle exec rake test_app - name: Create test app - - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots - name: Create the screenshots folder - - uses: nanasess/setup-chromedriver@v1.0.1 - - run: RAILS_ENV=test bundle exec rails assets:precompile - name: Precompile assets - working-directory: ./spec/decidim_dummy_app/ + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} - run: bundle exec rspec name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh $DECIDIM_MODULE $GITHUB_EVENT_PATH name: Upload coverage - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/ci_surveys.yml b/.github/workflows/ci_surveys.yml index f77d10256bd08..17f34a2303087 100644 --- a/.github/workflows/ci_surveys.yml +++ b/.github/workflows/ci_surveys.yml @@ -21,15 +21,14 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-surveys jobs: main: name: Tests - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 if: "!startsWith(github.head_ref, 'chore/l10n')" timeout-minutes: 60 services: @@ -43,47 +42,28 @@ jobs: --health-retries 5 env: POSTGRES_PASSWORD: postgres + validator: + image: ghcr.io/validator/validator:latest + ports: ["8888:8888"] env: DATABASE_USERNAME: postgres DATABASE_PASSWORD: postgres DATABASE_HOST: localhost RUBYOPT: '-W:no-deprecated' + VALIDATOR_HTML_URI: http://localhost:8888/ steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 - if: "github.ref != 'refs/heads/develop'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - uses: actions/checkout@v2.0.0 with: fetch-depth: 1 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ env.RUBY_VERSION }} - bundler-cache: true - - uses: actions/setup-node@v1 + - uses: ./.github/actions/module-rspec with: - node-version: ${{ env.NODE_VERSION }} - - name: Get npm cache directory path - id: npm-cache-dir-path - run: echo "::set-output name=dir::$(npm get cache)-${{ env.DECIDIM_MODULE }}" - - uses: actions/cache@v2 - id: npm-cache - with: - path: ${{ steps.npm-cache-dir-path.outputs.dir }} - key: npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - npm- - - run: bundle exec rake test_app - name: Create test app - - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots - name: Create the screenshots folder - - uses: nanasess/setup-chromedriver@v1.0.1 - - run: RAILS_ENV=test bundle exec rails assets:precompile - name: Precompile assets - working-directory: ./spec/decidim_dummy_app/ + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} - run: bundle exec rspec name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh $DECIDIM_MODULE $GITHUB_EVENT_PATH name: Upload coverage - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/ci_system.yml b/.github/workflows/ci_system.yml index 3bed5e6bf22ce..e4b464a31a492 100644 --- a/.github/workflows/ci_system.yml +++ b/.github/workflows/ci_system.yml @@ -17,15 +17,14 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-system jobs: main: name: Tests - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 if: "!startsWith(github.head_ref, 'chore/l10n')" timeout-minutes: 60 services: @@ -39,47 +38,28 @@ jobs: --health-retries 5 env: POSTGRES_PASSWORD: postgres + validator: + image: ghcr.io/validator/validator:latest + ports: ["8888:8888"] env: DATABASE_USERNAME: postgres DATABASE_PASSWORD: postgres DATABASE_HOST: localhost RUBYOPT: '-W:no-deprecated' + VALIDATOR_HTML_URI: http://localhost:8888/ steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 - if: "github.ref != 'refs/heads/develop'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - uses: actions/checkout@v2.0.0 with: fetch-depth: 1 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ env.RUBY_VERSION }} - bundler-cache: true - - uses: actions/setup-node@v1 + - uses: ./.github/actions/module-rspec with: - node-version: ${{ env.NODE_VERSION }} - - name: Get npm cache directory path - id: npm-cache-dir-path - run: echo "::set-output name=dir::$(npm get cache)-${{ env.DECIDIM_MODULE }}" - - uses: actions/cache@v2 - id: npm-cache - with: - path: ${{ steps.npm-cache-dir-path.outputs.dir }} - key: npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - npm- - - run: bundle exec rake test_app - name: Create test app - - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots - name: Create the screenshots folder - - uses: nanasess/setup-chromedriver@v1.0.1 - - run: RAILS_ENV=test bundle exec rails assets:precompile - name: Precompile assets - working-directory: ./spec/decidim_dummy_app/ + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} - run: bundle exec rspec name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh $DECIDIM_MODULE $GITHUB_EVENT_PATH name: Upload coverage - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/ci_templates.yml b/.github/workflows/ci_templates.yml index 6fc2340a66653..c8dd390a95df8 100644 --- a/.github/workflows/ci_templates.yml +++ b/.github/workflows/ci_templates.yml @@ -20,15 +20,14 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-templates jobs: main: name: Tests - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 if: "!startsWith(github.head_ref, 'chore/l10n')" timeout-minutes: 60 services: @@ -42,47 +41,28 @@ jobs: --health-retries 5 env: POSTGRES_PASSWORD: postgres + validator: + image: ghcr.io/validator/validator:latest + ports: ["8888:8888"] env: DATABASE_USERNAME: postgres DATABASE_PASSWORD: postgres DATABASE_HOST: localhost RUBYOPT: '-W:no-deprecated' + VALIDATOR_HTML_URI: http://localhost:8888/ steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 - if: "github.ref != 'refs/heads/develop'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - uses: actions/checkout@v2.0.0 with: fetch-depth: 1 - - uses: ruby/setup-ruby@master - with: - ruby-version: ${{ env.RUBY_VERSION }} - bundler-cache: true - - uses: actions/setup-node@v1 + - uses: ./.github/actions/module-rspec with: - node-version: ${{ env.NODE_VERSION }} - - name: Get npm cache directory path - id: npm-cache-dir-path - run: echo "::set-output name=dir::$(npm get cache)-${{ env.DECIDIM_MODULE }}" - - uses: actions/cache@v2 - id: npm-cache - with: - path: ${{ steps.npm-cache-dir-path.outputs.dir }} - key: npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - npm- - - run: bundle exec rake test_app - name: Create test app - - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots - name: Create the screenshots folder - - uses: nanasess/setup-chromedriver@v1.0.1 - - run: RAILS_ENV=test bundle exec rails assets:precompile - name: Precompile assets - working-directory: ./spec/decidim_dummy_app/ + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} - run: bundle exec rspec name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh $DECIDIM_MODULE $GITHUB_EVENT_PATH name: Upload coverage - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/ci_verifications.yml b/.github/workflows/ci_verifications.yml index 9cff15756c746..a62bc1b42b7df 100644 --- a/.github/workflows/ci_verifications.yml +++ b/.github/workflows/ci_verifications.yml @@ -18,15 +18,14 @@ on: env: CI: "true" - SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 DECIDIM_MODULE: decidim-verifications jobs: main: name: Tests - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 if: "!startsWith(github.head_ref, 'chore/l10n')" timeout-minutes: 60 services: @@ -40,47 +39,28 @@ jobs: --health-retries 5 env: POSTGRES_PASSWORD: postgres + validator: + image: ghcr.io/validator/validator:latest + ports: ["8888:8888"] env: DATABASE_USERNAME: postgres DATABASE_PASSWORD: postgres DATABASE_HOST: localhost RUBYOPT: '-W:no-deprecated' + VALIDATOR_HTML_URI: http://localhost:8888/ steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 - if: "github.ref != 'refs/heads/develop'" - env: - GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" - uses: actions/checkout@v2.0.0 with: fetch-depth: 1 - - uses: ruby/setup-ruby@v1 - with: - ruby-version: ${{ env.RUBY_VERSION }} - bundler-cache: true - - uses: actions/setup-node@v1 + - uses: ./.github/actions/module-rspec with: - node-version: ${{ env.NODE_VERSION }} - - name: Get npm cache directory path - id: npm-cache-dir-path - run: echo "::set-output name=dir::$(npm get cache)-${{ env.DECIDIM_MODULE }}" - - uses: actions/cache@v2 - id: npm-cache - with: - path: ${{ steps.npm-cache-dir-path.outputs.dir }} - key: npm-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - npm- - - run: bundle exec rake test_app - name: Create test app - - run: mkdir -p ./spec/decidim_dummy_app/tmp/screenshots - name: Create the screenshots folder - - uses: nanasess/setup-chromedriver@v1.0.1 - - run: RAILS_ENV=test bundle exec rails assets:precompile - name: Precompile assets - working-directory: ./spec/decidim_dummy_app/ + github_token: ${{ secrets.GITHUB_TOKEN }} + name: ${{ env.DECIDIM_MODULE }} - run: bundle exec rspec name: RSpec working-directory: ${{ env.DECIDIM_MODULE }} + env: + SIMPLECOV: "true" - run: ./.github/upload_coverage.sh $DECIDIM_MODULE $GITHUB_EVENT_PATH name: Upload coverage - uses: actions/upload-artifact@v2 diff --git a/.github/workflows/lint_code.yml b/.github/workflows/lint_code.yml index 05c956387f6de..78f4f048bc1b3 100644 --- a/.github/workflows/lint_code.yml +++ b/.github/workflows/lint_code.yml @@ -1,4 +1,4 @@ -name: "[CI] Lint" +name: "[CI] Lint code" on: push: branches: @@ -12,17 +12,17 @@ on: env: CI: "true" SIMPLECOV: "true" - RUBY_VERSION: 2.7.1 + RUBY_VERSION: 2.7.5 NODE_VERSION: 16.9.1 jobs: lint: name: Lint code - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 if: "!startsWith(github.head_ref, 'chore/l10n')" timeout-minutes: 60 steps: - - uses: rokroskar/workflow-run-cleanup-action@v0.3.0 + - uses: rokroskar/workflow-run-cleanup-action@v0.3.3 if: "github.ref != 'refs/heads/develop'" env: GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/lint_pr_format.yml b/.github/workflows/lint_pr_format.yml new file mode 100644 index 0000000000000..bcf58f8b8ad86 --- /dev/null +++ b/.github/workflows/lint_pr_format.yml @@ -0,0 +1,22 @@ +name: "[CI] Lint PR format" +on: + pull_request: + branches-ignore: + - "chore/l10n*" + types: [opened, edited, synchronize, reopened] + +jobs: + check_title: + name: Check PR title + runs-on: ubuntu-20.04 + steps: + - uses: rokroskar/workflow-run-cleanup-action@v0.3.3 + if: "github.ref != 'refs/heads/develop'" + env: + GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + - uses: deepakputhraya/action-pr-title@master + with: + disallowed_prefixes: "feat,chore,build,ci,refactor,docs,wip" + prefix_case_sensitive: false + min_length: 5 + max_length: 100 diff --git a/.github/workflows/on_docs_update.yml b/.github/workflows/on_docs_update.yml index 2a497a96273bd..b1f2d60381f2e 100644 --- a/.github/workflows/on_docs_update.yml +++ b/.github/workflows/on_docs_update.yml @@ -9,7 +9,7 @@ on: jobs: trigger_documentation_build: name: Trigger decidim/documentation build - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 timeout-minutes: 60 steps: - name: Send dispatch for trigger_build workflow diff --git a/.github/workflows/on_release.yml b/.github/workflows/on_release.yml index 303f649cc1bf7..5e0be24ad03f0 100644 --- a/.github/workflows/on_release.yml +++ b/.github/workflows/on_release.yml @@ -6,7 +6,7 @@ on: jobs: trigger_docker_build: name: Trigger decidim/docker build - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 timeout-minutes: 60 steps: - name: Send dispatch for Docker Hub build diff --git a/.ruby-version b/.ruby-version index 860487ca19ced..a603bb50a29e3 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.7.1 +2.7.5 diff --git a/.simplecov b/.simplecov index 18cc4ce39998f..76114887f8c90 100644 --- a/.simplecov +++ b/.simplecov @@ -1,6 +1,9 @@ # frozen_string_literal: true if ENV["SIMPLECOV"] + test_env = ENV.fetch("TEST_ENV_NUMBER", "") + test_env = "1" if test_env.empty? + SimpleCov.start do # `ENGINE_ROOT` holds the name of the engine we're testing. # This brings us to the main Decidim folder. @@ -24,6 +27,7 @@ if ENV["SIMPLECOV"] end SimpleCov.merge_timeout 1800 + SimpleCov.coverage_dir "coverage/#{test_env}/" if ENV["CI"] require "simplecov-cobertura" diff --git a/CHANGELOG.md b/CHANGELOG.md index dc21320c3d06f..c8656efbdc20f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -224,110 +224,429 @@ Nothing. #### Statistics change As per [\#8147](https://github.com/decidim/decidim/pull/8147), the participants stats will not take into account deleted and blocked users. +Nothing. -#### Webpacker migration -As per [#7464](https://github.com/decidim/decidim/pull/7464), [#7733](https://github.com/decidim/decidim/pull/7733) Decidim has been upgraded to use Webpacker to manage its assets. It's a huge change that requires some updates in your applications. Please refer to the guide [Migrate to Webpacker an instance app](https://github.com/decidim/decidim/blob/develop/docs/modules/develop/pages/guide_migrate_webpacker_app.adoc) and follow the steps described. +## [0.26.4](https://github.com/decidim/decidim/tree/v0.26.4) -#### Improved menu api -As per [\#7368](https://github.com/decidim/decidim/pull/7368), [\#7382](https://github.com/decidim/decidim/pull/7382) the entire admin structure has been migrated from menus being rendered in partials, to the existing menu structure. Before, this change adding a new menu item to an admin submenu required partial override. +### Added -As per [\#7545](https://github.com/decidim/decidim/pull/7545) the menu api has been enhanced to support removal of elements and reordering. All the menu items have an identifier that allow any developer to interact without overriding the entire menu structure. As a result of this change, the old ```menu.item``` function has been deprecated in favour of a more verbose version ```menu.add_item ```, of which first argument is the menu identifier. +Nothing. -Example on adding new elements to a menu: -```ruby -Decidim.menu :menu do |menu| - menu.add_item :root, - I18n.t("menu.home", scope: "decidim"), - decidim.root_path, - position: 1, - active: :exclusive - - menu.add_item :pages, - I18n.t("menu.help", scope: "decidim"), - decidim.pages_path, - position: 7, - active: :inclusive -end -``` +### Changed -Example Customizing the elements of a menu: +Nothing. -```ruby -Decidim.menu :menu do |menu| - # Completely remove a menu item - menu.remove_item :my_item - - # Change the items order - menu.move :root, after: :pages - # alternative - menu.move :pages, before: :root -end -``` +### Fixed + +- **decidim-core**: Backport 'Prevent the account edit route through Devise' to v0.26 [\#9932](https://github.com/decidim/decidim/pull/9932) +- **decidim-participatory processes**: Backport 'Fix unpublished processes shown in the group process count' to v0.26 [\#9934](https://github.com/decidim/decidim/pull/9934) +- **decidim-admin**: Backport 'Fix global moderation types not translated' to v0.26 [\#9937](https://github.com/decidim/decidim/pull/9937) +- **decidim-admin**: Backport 'Fix updating organization settings in case there were errors' to v0.26 [\#9938](https://github.com/decidim/decidim/pull/9938) +- **decidim-budgets**, **decidim-core**, **decidim-elections**, **decidim-proposals**: Backport 'Do not import resources multiple times' to v0.26 [\#9942](https://github.com/decidim/decidim/pull/9942) +- **decidim-forms**, **decidim-surveys**: Backport 'Fix form answer attachments breaking the answer view' to v0.26 [\#9945](https://github.com/decidim/decidim/pull/9945) +- **decidim-comments**: Backport 'Fix "disappearing" underscores with comments' to v0.26 [\#9949](https://github.com/decidim/decidim/pull/9949) +- **decidim-admin**, **decidim-core**: Backport 'Fix editor content saving when the content has only one video' to v0.26 [\#9951](https://github.com/decidim/decidim/pull/9951) +- **decidim-proposals**: Backport 'Fix collaborative drafts page when there are errors on the form' to v0.26 [\#9955](https://github.com/decidim/decidim/pull/9955) +- **decidim-debates**: Backport 'Fix the finite value on the debate form when editing an existing debate' to v0.26 [\#9957](https://github.com/decidim/decidim/pull/9957) +- **decidim-pages**: Backport 'Fix exporting and importing a page component' to v0.26 [\#9959](https://github.com/decidim/decidim/pull/9959) +- **decidim-participatory processes**: Backport 'Fix importing participatory process from legacy format' to v0.26 [\#9964](https://github.com/decidim/decidim/pull/9964) +- **decidim-assemblies**, **decidim-core**, **decidim-participatory processes**: Backport 'Fix duplicate stats on home page and participatory space main page' to v0.26 [\#9966](https://github.com/decidim/decidim/pull/9966) +- **decidim-budgets**, **decidim-core**, **decidim-proposals**, **decidim-templates**: Backport 'Address Crowdin feedback' to v0.26 [\#9970](https://github.com/decidim/decidim/pull/9970) +- **decidim-core**: Backport 'Limit invitation redirects only to paths within the application' to v0.26 [\#9973](https://github.com/decidim/decidim/pull/9973) +- **decidim-initiatives**: Backport 'Fix initiative sign if the authorization metadata is set to `nil`' to v0.26 [\#9981](https://github.com/decidim/decidim/pull/9981) +- **decidim-initiatives**: Backport 'Add missing i18n key in Initiatives' to v0.26 [\#9983](https://github.com/decidim/decidim/pull/9983) +- **decidim-core**: Backport 'Fix correct resource linking for amendments' to v0.26 [\#9988](https://github.com/decidim/decidim/pull/9988) +- **decidim-core**: Backport 'Fix user sign up with invalid name' to v0.26 [\#9991](https://github.com/decidim/decidim/pull/9991) +- **decidim-initiatives**: Backport 'Make initiatives order translatable' to v0.26 [\#9995](https://github.com/decidim/decidim/pull/9995) +- **decidim-core**: Backport 'Make ToS agreement translatable' to v0.26 [\#9997](https://github.com/decidim/decidim/pull/9997) +- **decidim-debates**: Backport 'Make Scopes field in debates translatable' to v0.26 [\#9999](https://github.com/decidim/decidim/pull/9999) +- **decidim-core**: Backport 'Remove invitations badge' to v0.26 [\#10001](https://github.com/decidim/decidim/pull/10001) +- **decidim-conferences**: Backport 'Fix conference invitations' to v0.26 [\#10004](https://github.com/decidim/decidim/pull/10004) +- **decidim-admin**, **decidim-core**: Backport 'Fix preserving bold text in the rich text editor when pasting content' to v0.26 [\#9962](https://github.com/decidim/decidim/pull/9962) +- **decidim-admin**, **decidim-assemblies**, **decidim-initiatives**, **decidim-participatory processes**, **decidim-verifications**: Backport 'Add missing active actions on admin navigation menu' to v0.26 [\#9993](https://github.com/decidim/decidim/pull/9993) +- **decidim-core**: Backport 'Fix disappearing sub-lists in rich text editors' to v0.26 [\#9968](https://github.com/decidim/decidim/pull/9968) +- **decidim-elections**: Backport 'Define the component import routes, permissions and controller at votings' to v0.26 [\#9977](https://github.com/decidim/decidim/pull/9977) +- **decidim-core**, **decidim-proposals**: Backport 'Fix proposal etiquette and length validator with base64 images' to v0.26 [\#10010](https://github.com/decidim/decidim/pull/10010) +- **decidim-core**, **decidim-debates**, **decidim-meetings**, **decidim-proposals**: Backport 'Refactor cell titles' to v0.26 [\#10041](https://github.com/decidim/decidim/pull/10041) +- **decidim-admin**, **decidim-comments**: Backport 'Fix moderations for comments that are mapped to deleted resources' to v0.26 [\#9941](https://github.com/decidim/decidim/pull/9941) +- **decidim-comments**, **decidim-core**, **decidim-verifications**: Backport 'Fix user related absolute URLs' to v0.26 [\#9947](https://github.com/decidim/decidim/pull/9947) +- **decidim-core**: Backport 'Fix duplicate user activity records when public spaces have private users' to v0.26 [\#9979](https://github.com/decidim/decidim/pull/9979) +- **decidim-meetings**: Backport 'Refactor the meeting list item title display' to v0.26 [\#10047](https://github.com/decidim/decidim/pull/10047) +- **decidim-accountability**, **decidim-admin**, **decidim-proposals**: Backport 'Reformat CSV help for import files on Accountability and Proposals' to v0.26 [\#10055](https://github.com/decidim/decidim/pull/10055) +- **decidim-system**: Backport 'Fix organization SMTP password not saved (became blank) in system panel' to v0.26 [\#10053](https://github.com/decidim/decidim/pull/10053) +- **decidim-budgets**, **decidim-elections**, **decidim-proposals**, **decidim-sortitions**: Backport 'Fix usages of `reorder` and `paginate`' to v0.26 [\#10051](https://github.com/decidim/decidim/pull/10051) +- **decidim-admin**: Backport 'Show only ToS acceptance when admin hasn't accepted it' to v0.26 [\#10057](https://github.com/decidim/decidim/pull/10057) +- **decidim-debates**, **decidim-meetings**, **decidim-proposals**: Backport 'Refactor admin listing titles' to v0.26 [\#10049](https://github.com/decidim/decidim/pull/10049) +- **decidim-core**: Backport 'Fix date/time formats at component forms' to v0.26 [\#9953](https://github.com/decidim/decidim/pull/9953) + +### Removed + +Nothing. + +### Internal + +- Backport 'Fix importing a page component without a body' to v0.26 [\#10023](https://github.com/decidim/decidim/pull/10023) -#### Meetings merge minutes and close actions +### Developer improvements -With changes introduced in [\#7968](https://github.com/decidim/decidim/pull/7968) the `Decidim::Meetings::Minutes` model and related table are removed and the attributes of the previously existing minutes are migrated to `Decidim::Meetings::Meeting` model in the `closing_report`, `video_url`, `audio_url` and `closing_visible` columns. These are the different results of the merge according to the initial data: +Nothing. -* It there was no minutes data and the meeting was not closed nothing changes -* If there was no minutes data and the meeting was closed, the meeting remains closed with the `closing_visible` attribute to true. In this way the closing data will remain visible. -* If there was minutes data and the meeting was not closed, the meeting is closed and the minutes `description` value is copied to the meeting `closing_report`, the `video_url` and `audio_url` minutes attributes values are copied to the respective meeting attributes and the minutes `visible` attribute value is copied to the meeting `closing_visible` attribute. -* If there was minutes data and the meeting was closed, the meeting remains closed and the meeting `closing_report` value remains if present. Elsewere the minutes `description` value is copied to the meeting `closing_report`. the `video_url` and `audio_url` minutes attributes values are copied to the respective meeting attributes and the minutes `visible` attribute value is copied to the meeting `closing_visible` attribute. In this case the visibility of closing report may change to false if there was a minutes with `visible` set to false. +## [0.26.3](https://github.com/decidim/decidim/tree/v0.26.3) -Please, note that if there was previously `minutes_description` and `closing_report` data for a meeting, after applying the changes of this release, the `minutes_description` data will be lost. +### Added + +Nothing. -If there is previous activity of creation or edition of minutes, `Decidim::ActionLog` instances and an associated `PaperTrail::Version` instance for each one will have been created pointing to these elements in their polymorphic associations. To avoid errors, the migration includes changing those associations to point to the meeting and changing the action to `close` in the action log items. This change is not reversible +### Changed -#### New Job queues +Nothing. -PR [\#7986](https://github.com/decidim/decidim/pull/7986) splits some jobs from the `:default` queue to two new queues: +### Fixed -- `:exports` -- `:translations` +- **decidim-core**: Backport 'Fix / Expose createMapController properly to let overriding' to v0.26 [\#9520](https://github.com/decidim/decidim/pull/9520) +- **decidim-elections**: Backport 'Capture unhandled errors from JS promises and inform the user' to v0.26 [\#9521](https://github.com/decidim/decidim/pull/9521) +- **decidim-elections**: Backport 'Remove description from questions in elections' to v0.26 [\#9522](https://github.com/decidim/decidim/pull/9522) +- **decidim-initiatives**: Backport 'Return 404 when there isn't an initiative' to v0.26 [\#9523](https://github.com/decidim/decidim/pull/9523) +- **decidim-forms**, **decidim-meetings**, **decidim-surveys**: Backport 'Fix rollback questionnaire answer when file is invalid' to v0.26 [\#9524](https://github.com/decidim/decidim/pull/9524) +- **decidim-elections**: Backport 'Make sure component is published when starting an election' to v0.26 [\#9525](https://github.com/decidim/decidim/pull/9525) +- **decidim-core**, **decidim-meetings**, **decidim-proposals**: Backport 'Fix email subject when resource title has special characters' to v0.26 [\#9526](https://github.com/decidim/decidim/pull/9526) +- **decidim-core**: Backport 'Prevent users to validate nicknames/emails taken by user groups' to v0.26 [\#9527](https://github.com/decidim/decidim/pull/9527) +- **decidim-elections**: Backport 'Fix hardcoded hour in election dashboard' to v0.26 [\#9528](https://github.com/decidim/decidim/pull/9528) +- **decidim-comments**, **decidim-core**: Backport 'Fix long word breaking on comments and cards' to v0.26 [\#9529](https://github.com/decidim/decidim/pull/9529) +- **decidim-assemblies**, **decidim-conferences**, **decidim-consultations**, **decidim-core**, **decidim-elections**, **decidim-initiatives**, **decidim-participatory processes**: Backport 'Fix background-image URLs with weird characters' to v0.26 [\#9531](https://github.com/decidim/decidim/pull/9531) +- **decidim-assemblies**, **decidim-conferences**, **decidim-elections**: Backport 'Fix cache hash on Hightlighted spaces' to v0.26 [\#9536](https://github.com/decidim/decidim/pull/9536) +- **decidim-accountability**: Backport 'Add short format to result date' to v0.26 [\#9540](https://github.com/decidim/decidim/pull/9540) +- **decidim-elections**: Backport 'Advertise users if BB connection is lost in trustees/admin zones' to v0.26 [\#9535](https://github.com/decidim/decidim/pull/9535) +- **decidim-core**: Backport 'Fix email subject when participatory space title is present' to v0.26 [\#9573](https://github.com/decidim/decidim/pull/9573) +- **decidim-conferences**: Backport 'Fix published conferences order' to v0.26 [\#9688](https://github.com/decidim/decidim/pull/9688) +- **decidim-comments**: Backport 'Fix creation notification when editing a comment ' to v0.26 [\#9690](https://github.com/decidim/decidim/pull/9690) +- **decidim-elections**: Backport 'Remove margin-bottom on votings navigation' to v0.26 [\#9692](https://github.com/decidim/decidim/pull/9692) +- **decidim-initiatives**: Backport 'Use public link on initiatives mailer' to v0.26 [\#9694](https://github.com/decidim/decidim/pull/9694) +- **decidim-accountability**: Backport 'Disallow creating grandchildren results' to v0.26 [\#9698](https://github.com/decidim/decidim/pull/9698) +- **decidim-forms**, **decidim-meetings**: Backport 'Prevent showing announcement on meetings registrations' to v0.26 [\#9700](https://github.com/decidim/decidim/pull/9700) +- **decidim-initiatives**: Backport 'Fix for initiative mailer when promoting committee is disabled' to v0.26 [\#9696](https://github.com/decidim/decidim/pull/9696) +- **decidim-elections**: Backport 'Improve steps election check page with census' to v0.26 [\#9702](https://github.com/decidim/decidim/pull/9702) +- **decidim-core**: Backport 'Fix translated attributes field type change' to v0.26 [\#9704](https://github.com/decidim/decidim/pull/9704) +- **decidim-core**: Backport 'Prevent missing ActionLog entries to break the application' to v0.26 [\#9706](https://github.com/decidim/decidim/pull/9706) +- **decidim-proposals**: Backport 'Fix publish event on official proposals' to v0.26 [\#9708](https://github.com/decidim/decidim/pull/9708) +- **decidim-admin**, **decidim-proposals**: Backport 'Add help text for proposals' 'publish answers immediately' setting ' to v0.26 [\#9712](https://github.com/decidim/decidim/pull/9712) +- **decidim-conferences**: Backport 'Return 404 when there isn't a valid component in program' to v0.26 [\#9717](https://github.com/decidim/decidim/pull/9717) +- **decidim-budgets**: Backport 'Fix budgets seeds on non development apps' to v0.26 [\#9719](https://github.com/decidim/decidim/pull/9719) +- **decidim-core**: Backport 'Fix creating automatic nicknames when taken by user_groups' to v0.26 [\#9721](https://github.com/decidim/decidim/pull/9721) +- **decidim-debates**: Backport 'Fix resource endorsed notification with Debates' to v0.26 [\#9723](https://github.com/decidim/decidim/pull/9723) +- **decidim-meetings**: Backport 'Fix agenda_item association with agenda' to v0.26 [\#9728](https://github.com/decidim/decidim/pull/9728) +- **decidim-verifications**: Backport 'Fix absolute urls on 'managed user error' event' to v0.26 [\#9730](https://github.com/decidim/decidim/pull/9730) +- **decidim-core**: Backport 'Fix mobile notifications switch component overlaps' to v0.26 [\#9732](https://github.com/decidim/decidim/pull/9732) +- **decidim-core**: Backport 'Fix blocked user nickname and avatar in user presenter' to v0.26 [\#9741](https://github.com/decidim/decidim/pull/9741) +- **decidim-admin**: Backport 'Fix form error overlap with character counter in the admin panel' to v0.26 [\#9749](https://github.com/decidim/decidim/pull/9749) +- **decidim-core**: Backport 'Fix the endorsement permissions' to v0.26 [\#9734](https://github.com/decidim/decidim/pull/9734) +- **decidim-meetings**: Backport 'Fix order when filtering Meetings' to v0.26 [\#9751](https://github.com/decidim/decidim/pull/9751) +- **decidim-proposals**: Backport 'Fix redundant notification on comments with linked proposals' to v0.26 [\#9746](https://github.com/decidim/decidim/pull/9746) +- **decidim-core**: Backport 'Make the HERE Map display in the currently selected language' to v0.26 [\#9714](https://github.com/decidim/decidim/pull/9714) +- **decidim-admin**, **decidim-forms**: Backport 'Fix admin language selector with more than 4 locales' to v0.26 [\#9710](https://github.com/decidim/decidim/pull/9710) +- **decidim-meetings**: Backport 'Ignore participatory spaces without models in meetings visible_for scope' to v0.26 [\#9794](https://github.com/decidim/decidim/pull/9794) +- **decidim-admin**: Backport 'Fix leaking emails on admin user search controller' to 0.26 [\#9797](https://github.com/decidim/decidim/pull/9797) +- **decidim-assemblies**, **decidim-participatory processes**: Backport 'Fix import of images on spaces' to v0.26 [\#9803](https://github.com/decidim/decidim/pull/9803) +- **decidim-core**: Backport 'Fix hashtags not recognized at the beginning of the string' to v0.26 [\#9811](https://github.com/decidim/decidim/pull/9811) +- **decidim-accountability**, **decidim-core**, **decidim-debates**, **decidim-initiatives**, **decidim-meetings**, **decidim-proposals**: Backport 'Fix version pages showing a HTTP 500 error when the version does not exist' to v0.26 [\#9809](https://github.com/decidim/decidim/pull/9809) +- **decidim-core**: Backport 'Fix hidden error messages on the registration form' to v0.26 [\#9813](https://github.com/decidim/decidim/pull/9813) +- **decidim-core**: Backport 'Fix multitenant organizations stats cache' to v0.26 [\#9807](https://github.com/decidim/decidim/pull/9807) +- **decidim-admin**, **decidim-initiatives**: Backport 'Fix initiatives components' to v0.26 [\#9825](https://github.com/decidim/decidim/pull/9825) +- Backport 'Fix doorkeeper initialization after 5.6.0 release' to v0.26 [\#9788](https://github.com/decidim/decidim/pull/9788) -If your application uses Sidekiq and you set a manual configuration file, you'll need to update it to add these two new queues. Otherwise these queues [will never run](https://github.com/mperham/sidekiq/issues/4897). +### Removed -#### User groups in global search +Nothing. -PR [\#8061](https://github.com/decidim/decidim/pull/8061) adds user groups to the global search and previously existing groups need to be indexed, otherwise it won't be available as search results. Run in a rails console or create a migration with: +### Internal + +- Backport 'Fix invalid translation in spec' to v0.26 [\#9435](https://github.com/decidim/decidim/pull/9435) +- Backport 'Remove the description field from the elections component seeds' to v0.26 [\#9553](https://github.com/decidim/decidim/pull/9553) +- Fix API GraphiQL system spec for 0.26 with newer ChromeDriver [\#9556](https://github.com/decidim/decidim/pull/9556) +- Backport 'Update `rokroskar/workflow-run-cleanup-action` GitHub action to v0.3.3' to v0.26 [\#9829](https://github.com/decidim/decidim/pull/9829) +- Backport 'Split parallel test coverage reports into their own folders' to v0.26 [\#9819](https://github.com/decidim/decidim/pull/9819) +- Backport 'Improve release process' to v0.26 [\#9864](https://github.com/decidim/decidim/pull/9864) + +### Developer improvements + +Nothing. + +## [0.26.2](https://github.com/decidim/decidim/tree/v0.26.2) + +### Added + +Nothing. + +### Changed + +Nothing. + +### Fixed + +- **decidim-comments**, **decidim-core**, **decidim-meetings**: Backport "Fix timeout in comment view and during meetings" to v0.26 [\#9091](https://github.com/decidim/decidim/pull/9091) +- **decidim-core**: Backport "Dont add external link container inside editor" to v0.26 [\#9108](https://github.com/decidim/decidim/pull/9108) +- **decidim-core**: Backport "Add base URI to meta image URLs" to v0.26 [\#9153](https://github.com/decidim/decidim/pull/9153) +- **decidim-initiatives**: Backport "Remove 'edit link' in topbar for initiative's authors" to v0.26 [\#9239](https://github.com/decidim/decidim/pull/9239) +- **decidim-elections**: Backport 'Clarify message to user when checking census' to v0.26 [\#9240](https://github.com/decidim/decidim/pull/9240) +- **decidim-participatory processes**: Backport 'Fix processes count in processes group title cell' to v0.26 [\#9242](https://github.com/decidim/decidim/pull/9242) +- **decidim-elections**: Backport 'Improve wording when casting your vote' to v0.26 [\#9243](https://github.com/decidim/decidim/pull/9243) +- **decidim-proposals**: Backport 'Add 'not answered' as a possible answer in proposals' to v0.26 [\#9246](https://github.com/decidim/decidim/pull/9246) +- **decidim-meetings**: Backport 'Fix meetings minutes migration' to v0.26 [\#9247](https://github.com/decidim/decidim/pull/9247) +- **decidim-assemblies**, **decidim-proposals**: Backport "Fix absolute urls on 'assembly member' and 'collaborative drafts' events" to v0.26 [\#9248](https://github.com/decidim/decidim/pull/9248) +- **decidim-accountability**, **decidim-consultations**: Backport 'Fix components navbar in consultations mobile ' to v0.26 [\#9249](https://github.com/decidim/decidim/pull/9249) +- **decidim-meetings**: Backport 'Move modal to body and fix condition' to v0.26 [\#9250](https://github.com/decidim/decidim/pull/9250) +- **decidim-meetings**: Backport 'Do not send upcoming meeting notification for hidden or withdrawn meetings' to v0.26 [\#9251](https://github.com/decidim/decidim/pull/9251) +- **decidim-core**: Backport 'Show only current organization in verification conflicts with multitenants' to v0.26 [\#9252](https://github.com/decidim/decidim/pull/9252) +- **decidim-elections**: Backport 'Send email to newly added trustees' to v0.26 [\#9253](https://github.com/decidim/decidim/pull/9253) +- **decidim-meetings**: Backport 'Fix registration type field highlighted in admin meeting creation form' to v0.26 [\#9254](https://github.com/decidim/decidim/pull/9254) +- **decidim-surveys**: Backport 'Fix contradictory form errors on survey form' to v0.26 [\#9257](https://github.com/decidim/decidim/pull/9257) +- **decidim-initiatives**: Backport 'Add edit and delete actions in InitiativeType admin table' to v0.26 [\#9260](https://github.com/decidim/decidim/pull/9260) +- **decidim-surveys**: Backport 'Clarify unregistered answers on surveys behavior' to v0.26 [\#9261](https://github.com/decidim/decidim/pull/9261) +- **decidim-elections**: Backport 'Fix voting with single election' to v0.26 [\#9262](https://github.com/decidim/decidim/pull/9262) +- **decidim-initiatives**: Backport 'Fix initiative print link, margin, and organization logo' to v0.26 [\#9263](https://github.com/decidim/decidim/pull/9263) +- **decidim-elections**: Backport 'Remove show more button on elections' to v0.26 [\#9264](https://github.com/decidim/decidim/pull/9264) +- **decidim-surveys**: Backport 'Fix survey activity log entries' to v0.26 [\#9265](https://github.com/decidim/decidim/pull/9265) +- **decidim-budgets**: Backport 'Remove beforeunload confirmation panel from the budgets voting' to v0.26 [\#9266](https://github.com/decidim/decidim/pull/9266) +- **decidim-admin**, **decidim-elections**: Backport 'Fix newsletters and Decidim Votings' to v0.26 [\#9258](https://github.com/decidim/decidim/pull/9258) +- **decidim-core**: Backport 'Fix notifications where resources are missing' to v0.26 [\#9256](https://github.com/decidim/decidim/pull/9256) +- **decidim-core**: Backport 'Enforce password validation rules on 'Forgot your password?' form' to v0.26 [\#9245](https://github.com/decidim/decidim/pull/9245) +- **decidim-core**: Backport 'Fix displaying blocked users in account follow pages' to v0.26 [\#9255](https://github.com/decidim/decidim/pull/9255) +- **decidim-core**: Backport 'Fix Leaflet trying to load "infinite amount of tiles"' to v0.26 [\#9269](https://github.com/decidim/decidim/pull/9269) +- **decidim-system**: Backport 'Enforce password validation rules on system admins' to v0.26 [\#9259](https://github.com/decidim/decidim/pull/9259) +- **decidim-meetings**: Backport 'Remove presenters in the meetings admin backoffice' to v0.26 [\#9323](https://github.com/decidim/decidim/pull/9323) +- **decidim-elections**: Backport 'Correctly show trustees and votings menu' to v0.26 [\#9324](https://github.com/decidim/decidim/pull/9324) +- **decidim-core**: Backport 'Fix hashtag parsing on URLs with fragments' to v0.26 [\#9326](https://github.com/decidim/decidim/pull/9326) +- **decidim-comments**, **decidim-core**: Backport 'Add missing events locales' to v0.26 [\#9327](https://github.com/decidim/decidim/pull/9327) +- **decidim-conferences**: Backport 'Make conference's partners logos always mandatory' to v0.26 [\#9328](https://github.com/decidim/decidim/pull/9328) +- **decidim-admin**: Backport 'Fix margin around warning message in colour settings' to v0.26 [\#9329](https://github.com/decidim/decidim/pull/9329) +- **decidim-elections**: Backport 'Hide more information link when there's no description on an election' to v0.26 [\#9331](https://github.com/decidim/decidim/pull/9331) +- **decidim-admin**, **decidim-assemblies**, **decidim-budgets**, **decidim-core**, **decidim-elections**, **decidim-meetings**, **decidim-pages**, **decidim-proposals**: Backport 'Apply crowdin feedback' to v0.26 [\#9333](https://github.com/decidim/decidim/pull/9333) +- **decidim-comments**, **decidim-core**: Backport 'Don't show deleted resources in last activities ' to v0.26 [\#9330](https://github.com/decidim/decidim/pull/9330) +- **decidim-elections**: Backport 'Fix election label translations' to v0.26 [\#9343](https://github.com/decidim/decidim/pull/9343) +- **decidim-verifications**: Backport 'Allow to renew expired verifications (if renewable)' to v0.26 [\#9344](https://github.com/decidim/decidim/pull/9344) +- **decidim-elections**: Backport 'Add error message when adding question and election has started' to v0.26 [\#9404](https://github.com/decidim/decidim/pull/9404) +- **decidim-core**: Backport 'Fix user interests' to v0.26 [\#9406](https://github.com/decidim/decidim/pull/9406) +- **decidim-elections**: Backport 'Fix regular expression on census check' to v0.26 [\#9408](https://github.com/decidim/decidim/pull/9408) +- **decidim-elections**: Backport 'Enforce YYYYmmdd format in birthdate when uploading census' to v0.26 [\#9410](https://github.com/decidim/decidim/pull/9410) +- **decidim-consultations**: Backport 'Return 404 when there isn't a question' to v0.26 [\#9414](https://github.com/decidim/decidim/pull/9414) +- **decidim-consultations**: Backport 'Return 404 when there isn't a consultation' to v0.26 [\#9413](https://github.com/decidim/decidim/pull/9413) +- **decidim-elections**: Backport 'Return 404 when there isn't a voting in elections_log' to v0.26 [\#9415](https://github.com/decidim/decidim/pull/9415) +- **decidim-proposals**: Backport 'Fix proposals creation with Participatory Texts ' to v0.26 [\#9416](https://github.com/decidim/decidim/pull/9416) +- **decidim-elections**: Backport 'Fix ActionLog when a ballot style is deleted' to v0.26 [\#9411](https://github.com/decidim/decidim/pull/9411) +- **decidim-elections**: Backport 'Only show that the code can be requested via SMS if its true' to v0.26 [\#9409](https://github.com/decidim/decidim/pull/9409) +- **decidim-budgets**, **decidim-proposals**: Backport 'Add missing translation keys proposals import and proposals picker' to v0.26 [\#9412](https://github.com/decidim/decidim/pull/9412) +- **decidim-elections**: Backport 'Fix HTML safe content in election voting' to v0.26 [\#9405](https://github.com/decidim/decidim/pull/9405) +- **decidim-core**: Backport 'Fix for internal links not displaying on page title' to v0.26 [\#9407](https://github.com/decidim/decidim/pull/9407) + +### Removed + +Nothing. + +### Internal + +- Backport 'Fix generators specs target branch' to v0.26 [\#9290](https://github.com/decidim/decidim/pull/9290) + +### Developer improvements + +Nothing. + +## [0.26.1](https://github.com/decidim/decidim/tree/v0.26.1) + +### Added + +Nothing. + +### Changed + +Nothing. + +### Fixed + +- **decidim-meetings**: Backport "Fix the meetings export to also include unpublished meetings" to v0.26 [\#8939](https://github.com/decidim/decidim/pull/8939) +- **decidim-system**, **decidim-verifications**: Backport "Fix verification report with multitenants" to v0.26 [\#8940](https://github.com/decidim/decidim/pull/8940) +- **decidim-core**: Backport "Fix officialized user event missing translations" to v0.26 [\#8942](https://github.com/decidim/decidim/pull/8942) +- **decidim-verifications**: Backport "Fix email for verification conflict with managed users" to v0.26 [\#8945](https://github.com/decidim/decidim/pull/8945) +- **decidim-core**: Backport "Fix profile notifications" to v0.26 [\#8949](https://github.com/decidim/decidim/pull/8949) +- **decidim-assemblies**, **decidim-budgets**, **decidim-comments**, **decidim-consultations**, **decidim-core**, **decidim-elections**, **decidim-forms**, **decidim-initiatives**, **decidim-participatory processes**, **decidim-proposals**: Backport several accessibility fixes to v0.26 [\#8950](https://github.com/decidim/decidim/pull/8950) +- **decidim-core**: Backport "Add missing 'Locale' string in i18n in account page" to v0.26 [\#8980](https://github.com/decidim/decidim/pull/8980) +- **decidim-meetings**: Backport "Truncate the meetings card description" to v0.26 [\#8979](https://github.com/decidim/decidim/pull/8979) +- **decidim-proposals**: Backport "Fix proposals' cards with big images" to v0.26 [\#8978](https://github.com/decidim/decidim/pull/8978) +- **decidim-initiatives**: Backport "Fix link to docs in initiatives admin" to v0.26 [\#8975](https://github.com/decidim/decidim/pull/8975) +- **decidim-comments**: Backport "Fix budget hard dependency and caching flag issues in comments" to v0.26 [\#8973](https://github.com/decidim/decidim/pull/8973) +- **decidim-participatory processes**: Backport "Fix processes creation form with stats, metrics and announcements" to v0.26 [\#8977](https://github.com/decidim/decidim/pull/8977) +- **decidim-initiatives**: Backport "Show signatures in answered initiatives" to v0.26 [\#8991](https://github.com/decidim/decidim/pull/8991) +- **decidim-core**: Backport "Add missing reveal__title classes" to v0.26 [\#8999](https://github.com/decidim/decidim/pull/8999) +- **decidim-core**: Backport "Remove the label from the dropdown menu opener" to v0.26 [\#9002](https://github.com/decidim/decidim/pull/9002) +- **decidim-core**: Backport "Fix mobile nav keyboard focus" to v0.26 [\#9001](https://github.com/decidim/decidim/pull/9001) +- **decidim-core**: Backport "Fix main navigation aria-current attribute" to v0.26 [\#9000](https://github.com/decidim/decidim/pull/9000) +- **decidim-core**: Backport "Show character counter when replying to message" to v0.26 [\#9003](https://github.com/decidim/decidim/pull/9003) +- **decidim-core**: Backport "Fix character counter with emoji picker close to maximum characters" to v0.26 [\#9012](https://github.com/decidim/decidim/pull/9012) +- **decidim-api**, **decidim-assemblies**, **decidim-conferences**, **decidim-consultations**, **decidim-initiatives**, **decidim-meetings**, **decidim-participatory processes**, **decidim-proposals**: Backport "Fix API when meetings have proposal linking disabled" to v0.26 [\#8992](https://github.com/decidim/decidim/pull/8992) +- **decidim-core**: Backport "Fix Devise flash messages translation" to v0.26 [\#9043](https://github.com/decidim/decidim/pull/9043) +- **decidim-core**: Backport "Disable new conversation next button when no users selected" to v0.26 [\#9054](https://github.com/decidim/decidim/pull/9054) +- **decidim-initiatives**: Backport "Fix initiatives signatures issues" to v0.26 [\#8974](https://github.com/decidim/decidim/pull/8974) +- **decidim-blogs**, **decidim-core**, **decidim-debates**, **decidim-proposals**: Backport "Fix for endorsed_by with other user group's member" to v0.26 [\#9062](https://github.com/decidim/decidim/pull/9062) +- **decidim-proposals**: Backport "Fix footer actions caching on proposals' card" to v0.26 [\#9063](https://github.com/decidim/decidim/pull/9063) +- **decidim-admin**: Backport "Add missing 'Locale' string in i18n in selective newsletter" to v0.26 [\#9064](https://github.com/decidim/decidim/pull/9064) +- **decidim-core**: Backport "Fix social share button sharing" to v0.26 [\#9065](https://github.com/decidim/decidim/pull/9065) +- **decidim-meetings**: Backport "Use published meetings scope on processes landing and proposal's form" to v0.26 [\#9066](https://github.com/decidim/decidim/pull/9066) +- **decidim-core**: Backport "Require omniauth/rails_csrf_protection explicitly" to v0.26 [\#9067](https://github.com/decidim/decidim/pull/9067) +- **decidim-core**, **decidim-proposals**: Backport "Fix amendable events title" to v0.26 [\#9079](https://github.com/decidim/decidim/pull/9079) +- **decidim-proposals**: Backport "Create admin log records when proposals are imported from a file" to v0.26 [\#9077](https://github.com/decidim/decidim/pull/9077) +- **decidim-comments**, **decidim-core**, **decidim-proposals**: Backport "Add noreferrer and ugc to links" to v0.26 [\#9078](https://github.com/decidim/decidim/pull/9078) +- **decidim-meetings**: Backport "Fix submit in meetings admin form" to v0.26 [\#9076](https://github.com/decidim/decidim/pull/9076) +- **decidim-core**: Backport "Fix session cookie SameSite policy" to v0.26 [\#9059](https://github.com/decidim/decidim/pull/9059) +- **decidim-budgets**, **decidim-core**, **decidim-debates**, **decidim-meetings**, **decidim-proposals**: Backport "Fix cache URLs on cards" to v0.26 [\#9074](https://github.com/decidim/decidim/pull/9074) +- **decidim-assemblies**, **decidim-conferences**, **decidim-consultations**, **decidim-core**, **decidim-initiatives**, **decidim-participatory processes**: Backport "Fix Twitter hashtag search when it starts with a number" to v0.26 [\#9075](https://github.com/decidim/decidim/pull/9075) + +### Removed + +Nothing. + +### Internal + +- Backport "Fix ActionMailer preview loading" to v0.26 [\#8963](https://github.com/decidim/decidim/pull/8963) +- Backport "Fix flaky spec in meetings multi-date selectors" to v0.26 [\#8976](https://github.com/decidim/decidim/pull/8976) +- Backport "Local HTML validator for the CI" to v0.26 [\#9004](https://github.com/decidim/decidim/pull/9004) +- Backport "Fix API when meetings have proposal linking disabled" to v0.26 [\#8992](https://github.com/decidim/decidim/pull/8992) + +### Developer improvements + +- Backport "Fix Devise configs that depend on Decidim configs" to v0.26 [\#9022](https://github.com/decidim/decidim/pull/9022) +- Backport "Fix Faker address country code in seeds" to v0.26 [\#9046](https://github.com/decidim/decidim/pull/9046) + +## [0.26.0](https://github.com/decidim/decidim/tree/v0.26.0) + +### Added + +Nothing. + +### Changed + +- **decidim-comments**: Backport "Show hidden comments replies" to v0.26 [\#8868](https://github.com/decidim/decidim/pull/8868) + +### Fixed + +- **decidim-proposals**: Backport "Fix geocoding NaN values" to v0.26 [\#8778](https://github.com/decidim/decidim/pull/8778) +- **decidim-core**: Backport "Add 'nofollow noopener' rel to the profile personal URL" to v0.26 [\#8780](https://github.com/decidim/decidim/pull/8780) +- **decidim-generators**: Backport "Add .keep file to empty directory to include on git committing" to v0.26 [\#8788](https://github.com/decidim/decidim/pull/8788) +- **decidim-core**: Backport "Fix avatar upload validation errors are displayed twice" to v0.26 [\#8798](https://github.com/decidim/decidim/pull/8798) +- **decidim-meetings**: Backport "Fix displaying hidden meetings in homepage's 'upcoming meetings' content block" to v0.26 [\#8819](https://github.com/decidim/decidim/pull/8819) +- **decidim-participatory processes**: Backport "Fix characters not encoded in highlighted participatory processes groups title" to v0.26 [\#8824](https://github.com/decidim/decidim/pull/8824) +- **decidim-comments**: Backport "Fix displaying hidden related resources" to v0.26 [\#8835](https://github.com/decidim/decidim/pull/8835) +- **decidim-generators**: Backport "Add natively a .keep file to empty directory to include on git committing" to v0.26 [\#8836](https://github.com/decidim/decidim/pull/8836) +- **decidim-consultations**, **decidim-core**, **decidim-elections**: Backport "Fix report moderation for all the spaces" to v0.26 [\#8841](https://github.com/decidim/decidim/pull/8841) +- **decidim-meetings**, **decidim-participatory processes**: Backport "Fix displaying hidden meetings in show process page" to v0.26 [\#8843](https://github.com/decidim/decidim/pull/8843) +- **decidim-meetings**: Backport "Fix displaying hidden resources in global search" to v0.26 [\#8850](https://github.com/decidim/decidim/pull/8850) +- **decidim-core**: Backport "Fix activity cell disappearing author images" to v0.26 [\#8848](https://github.com/decidim/decidim/pull/8848) +- **decidim-initiatives**: Backport "Fix scope validation on initiative's creation" to v0.26 [\#8857](https://github.com/decidim/decidim/pull/8857) +- **decidim-accountability**: Backport "Fix accountability categories' colors" to v0.26 [\#8858](https://github.com/decidim/decidim/pull/8858) +- **decidim-debates**: Backport "Remove actions from debates' cards" to v0.26 [\#8861](https://github.com/decidim/decidim/pull/8861) +- **decidim-assemblies**: Backport "Fix assemblies title when there are unpublished children" to v0.26 [\#8860](https://github.com/decidim/decidim/pull/8860) +- **decidim-core**: Backport "Fix cache_hash generation in AuthorCell" to v0.26 [\#8862](https://github.com/decidim/decidim/pull/8862) +- **decidim-meetings**, **decidim-participatory processes**: Backport "Fix displaying hidden meetings in processes group's 'upcoming meetings' content block" to v0.26 [\#8864](https://github.com/decidim/decidim/pull/8864) +- **decidim-assemblies**, **decidim-conferences**, **decidim-consultations**, **decidim-proposals**: Backport "Fix notifications when there is a note proposal in other spaces than processes" to v0.26 [\#8865](https://github.com/decidim/decidim/pull/8865) +- **decidim-proposals**: Backport "Fix answered proposals display" to v0.26 [\#8863](https://github.com/decidim/decidim/pull/8863) +- **decidim-comments**: Backport "Show hidden comments replies" to v0.26 [\#8868](https://github.com/decidim/decidim/pull/8868) +- **decidim-meetings**: Backport "Fix meetings iframe embed code" to v0.26 [\#8884](https://github.com/decidim/decidim/pull/8884) + +### Removed + +Nothing. + +### Internal + +- Backport "Fix flaky test in UpdateAssemblyMember" to v0.26 [\#8803](https://github.com/decidim/decidim/pull/8803) + +### Developer improvements + +Nothing. + +## [0.26.0.rc2](https://github.com/decidim/decidim/tree/v0.26.0.rc2) + +### Added + +Nothing. +#### Moderated content can now be removed from search index +PR [\#8811](https://github.com/decidim/decidim/pull/8811) is addressing an issue when the moderated resources are not removed from the general search index. + +This will automatically work for new moderated resources. For already existing ones, we have introduced a new task that will remove the moderated content from being displayed in search: ```ruby - Decidim::UserGroup.find_each(&:try_update_index_for_search_resource) +bin/rails decidim:upgrade:moderation:remove_from_search ``` -Please be aware that it could take a while if your database has a lot of groups. +#### Default Decidim app fully configurable via ENV vars + +### Changed + +Nothing. + +### Fixed + +- **decidim-meetings**: Backport "Fix for preview unpublished meetings by admin user" to v0.26 [\#8724](https://github.com/decidim/decidim/pull/8724) +- **decidim-comments**: Backport "Adds emojis when user edits a comment" to v0.26 [\#8743](https://github.com/decidim/decidim/pull/8743) +- **decidim-core**: Backport "Properly mark sender and recipient in Conversation" to v0.26 [\#8746](https://github.com/decidim/decidim/pull/8746) +- **decidim-participatory processes**: Backport "Fix order by weight in processes groups' processes content block" to v0.26 [\#8771](https://github.com/decidim/decidim/pull/8771) +- **decidim-core**: Backport "Don't display blocked users in mentions" to v0.26 [\#8770](https://github.com/decidim/decidim/pull/8770) + +### Removed + +Nothing. + +### Internal + +- Backport "Revert the i18n-tasks initialization syntax" to v0.26 [\#8696](https://github.com/decidim/decidim/pull/8696) +- Backport "Lock graphql version to 1.12 minor" to v0.26 [\#8695](https://github.com/decidim/decidim/pull/8695) +- Disable codeclimate's stylelint [\#8711](https://github.com/decidim/decidim/pull/8711) -#### ActiveStorage migration +### Developer improvements -PR [\#7598](https://github.com/decidim/decidim/pull/7598) migrates attachments from `CarrierWave` to `ActiveStorage`. There was a migration to move some organization fields to a content block (decidim-core/db/migrate/20180810092428_move_organization_fields_to_hero_content_block.rb) including the use of `CarrierWave` to migrate an image. This part has been removed. Please, if your application has the old migration replace its content with the changed file to avoid errors in the future because `CarrierWave` dependency will be eliminated. +- Backport "Fix webpacker generator for modules" to v0.26 [\#8750](https://github.com/decidim/decidim/pull/8750) -PR[\#7902](https://github.com/decidim/decidim/pull/7902) provides a task to migrate existing `CarrierWave` attachment files to `ActiveStorage`. Keep in mind that the `ActiveStorage` migration PRs don't delete `CarrierWave` attachments and preserve the columns used by it. To guarantee the access to `CarrierWave` files the gem must be installed (the current core engine maintains that dependency) and configured as it was before the migration to `ActiveStorage`. The task downloads each file using `CarrierWave` uploaders and uploads it again using `ActiveStorage`. This PR provides 2 tasks: +## [0.26.0.rc1](https://github.com/decidim/decidim/tree/v0.26.0.rc1) -* The task to copy files to `ActiveStorage`. The task generates a log file in `log/` with a line with the result of each migration. The result can be: - * `[OK] Migrated - [OK] Checksum identical` if the file was copied successfully and the checksums of the origin and copied files are identical. This should be the expected result. - * `[KO] Migrated - [KO] Checksum different` if the file was copied successfully but the checksums are different. - * `[SKIP] Migrated` The migration was skipped because the task detected that there was already an existing file attached with `ActiveStorage` (the other task allows us to check if `CarrierWave` and `ActiveStorage` files are identical. - * `[ERROR] Exception` if any error prevents the migration of the file. The error message is included in the result. +### Migration notes +#### Register assets paths +To prevent Zeitwerk from trying to autoload classes from the `app/packs` folder, it's necesary to register these paths for each module and for the application using the method `Decidim.register_assets_path` on initializers. This is explained in the webpacker migration guides for [applications](https://github.com/decidim/decidim/blob/develop/docs/modules/develop/pages/guide_migrate_webpacker_app.adoc#help-decidim-to-know-the-applications-assets-folder) and [modules](https://github.com/decidim/decidim/blob/develop/docs/modules/develop/pages/guide_migrate_webpacker_module.adoc#help-decidim-to-know-the-modules-assets-folder)), and was implemented in [\#8449](https://github.com/decidim/decidim/pull/8449). -The task also creates a mapping of paths in `tmp/attachment_mappings.csv` with the id of the instance, the name of the `CarrierWave` attribute and its origin path and the destination path in `ActiveStorage`. To run this task execute: +#### Unconfirmed access disabled by default +As per [\#8233](https://github.com/decidim/decidim/pull/8233), by default all participants must confirm their email account to sign in. Implementors can change this setting as a [initializer configuration](https://docs.decidim.org/en/configure/initializer/#_unconfirmed_access_for_users): +```ruby +Decidim.configure do |config| + config.unconfirmed_access_for = 2.days +end ``` -rails decidim:active_storage_migrations:migrate_from_carrierwave_to_active_storage + +#### User workflows change to prevent user enumeration attacks + +Until now it was possible to see if an email account was registered in Decidim, by using features like "Forgot your password", as the response changed if the email existed ("`You will receive an email with instructions on how to reset your password in a few minutes`") that's different to a non-existing user account ("`could not be found. Did you sign up previously?`"). This allows User Enumration attacks, where a malicious actor can check if anyone has an acount in the platform. As per [\#8537](https://github.com/decidim/decidim/pull/8537), anyone has the same answer always "`If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes`". + +#### Blocked user in global search + +PR [\#8658](https://github.com/decidim/decidim/pull/8658) Blocked users are present in global search, to update the search and make them disappear, Run in a rails console or create a migration with: + +```ruby + Decidim::User.find_each(&:try_update_index_for_search_resource) ``` -Note that the migration generates instances of `ActiveStorage::Attachment` in case they are not yet created. To repeat the migration from scratch it would be enough to delete all `ActiveStorage::Attachment` items (be careful not to delete attachments that were created earlier with `ActiveStorage`) +Please be aware that it could take a while if your database has a lot of Users. +#### Fix statistics in Comments -* The task to check migration and compare files. This task finds each `CarrierWave` attachment file and looks for corresponding `ActiveStorage` attachment and compares them if possible. The result for each attachment can be: - * `[OK] Checksum identical` if both files exist and checkums are identical. - * `[KO] Checksum different` if both files exist but checkums are different. - * `[SKIP] Pending migration` if the `ActiveStorage` file is not present. - * `[ERROR] Exception` if there is any error in the checking process. The error message is included in the result. +As per [#8012](https://github.com/decidim/decidim/pull/8012), for fixing statistic in comments. There's a rake task that you need to run: +```ruby +rake decidim_comments:update_participatory_process_in_comments +``` -To run this task execute: +#### Base64 images migration + +As per [\#8250](https://github.com/decidim/decidim/pull/8250), we've replaced the default base64 editor images attachment with the use of ActiveStorage attachments. This PR also adds a task to parse all editor contents and replace existing base64 images with attachments. The task parses all the attributes which can be edited from admin using the WYSIWYG editor. The task requires an argument with the email of an admin used to create EditorImage instances. To run this task execute: ``` -rails decidim:active_storage_migrations:check_migration_from_carrierwave_to_active_storage +rails decidim:active_storage_migrations:migrate_inline_images_to_active_storage[admin_email] ``` ### Added @@ -704,7 +1023,199 @@ rails decidim:active_storage_migrations:check_migration_from_carrierwave_to_acti - Bump addressable version because security issues [\#8229](https://github.com/decidim/decidim/pull/8229) - Active storage migrations service [\#7902](https://github.com/decidim/decidim/pull/7902) - Remove obsolete rake webpack task [\#8237](https://github.com/decidim/decidim/pull/8237) +- **decidim-budgets**: Port decidim-budgets improvements from AjuntamentdeBarcelona/decidim [\#8249](https://github.com/decidim/decidim/pull/8249) +- **decidim-elections**: Improve evote admin logs [\#8263](https://github.com/decidim/decidim/pull/8263) +- **decidim-blogs**, **decidim-meetings**: Add card images to meetings and blog posts [\#8276](https://github.com/decidim/decidim/pull/8276) +- **decidim-admin**: Align UI groups filtering with the rest of decidim [\#8105](https://github.com/decidim/decidim/pull/8105) +- **decidim-admin**, **decidim-proposals**: Improve error messages in admin panel [\#8193](https://github.com/decidim/decidim/pull/8193) +- **decidim-elections**: Allow to mark trustees as missing [\#8314](https://github.com/decidim/decidim/pull/8314) +- **decidim-admin**: Add sorting to private participants in a participatory space [\#8242](https://github.com/decidim/decidim/pull/8242) +- **decidim-comments**: Improve control of comments in meetings and debates [\#8027](https://github.com/decidim/decidim/pull/8027) +- **decidim-proposals**: Offer a way to see all proposals in withdrawn proposal list [\#8251](https://github.com/decidim/decidim/pull/8251) +- **decidim-admin**, **decidim-proposals**: Configurable default order for proposals [\#8295](https://github.com/decidim/decidim/pull/8295) +- **decidim-assemblies**: Filter assemblies by assembly type in admin [\#7153](https://github.com/decidim/decidim/pull/7153) +- **decidim-assemblies**: Non participant assembly members avatar [\#8277](https://github.com/decidim/decidim/pull/8277) +- **decidim-core**: Add image file upload in QuillJS editor [\#8250](https://github.com/decidim/decidim/pull/8250) +- **decidim-meetings**: Make meeting report editable by the author in front-end [\#8209](https://github.com/decidim/decidim/pull/8209) +- **decidim-core**: Improve dialog accessibility [\#8294](https://github.com/decidim/decidim/pull/8294) +- **decidim-meetings**: Ability for users to withdraw their meetings [\#8248](https://github.com/decidim/decidim/pull/8248) +- **decidim-admin**: Add colors accessibility warning in admin Appearance [\#8354](https://github.com/decidim/decidim/pull/8354) +- **decidim-proposals**: Import proposal answers [\#8271](https://github.com/decidim/decidim/pull/8271) +- **decidim-core**: Add more actions in QuillJS toolbar [\#8120](https://github.com/decidim/decidim/pull/8120) +- **decidim-meetings**: Add more filter options to directory meetings page [\#8333](https://github.com/decidim/decidim/pull/8333) +- **decidim-assemblies**, **decidim-conferences**, **decidim-participatory processes**: Add filters for Participatory process admins section [\#8106](https://github.com/decidim/decidim/pull/8106) +- **decidim-budgets**: Show modal when user is trying to leave with pending vote [\#8387](https://github.com/decidim/decidim/pull/8387) +- **decidim-meetings**: Meetings iframe visibility [\#8307](https://github.com/decidim/decidim/pull/8307) +- **decidim-budgets**: Add search, filters and sorting to admin panel budget projects [\#8592](https://github.com/decidim/decidim/pull/8592) +- **decidim-core**: Describe the notifications' time with words [\#8564](https://github.com/decidim/decidim/pull/8564) +- **decidim-comments**, **decidim-core**: Add link to comments in Notifications [\#8607](https://github.com/decidim/decidim/pull/8607) +- **decidim-comments**, **decidim-core**: Add full content of comments in notifications [\#8581](https://github.com/decidim/decidim/pull/8581) +- **decidim-core**: Change colors on mobile navigation bar [\#8628](https://github.com/decidim/decidim/pull/8628) +- **decidim-core**, **decidim-proposals**: Add author to proposals in notifications [\#8603](https://github.com/decidim/decidim/pull/8603) +- **decidim-comments**, **decidim-core**, **decidim-meetings**, **decidim-proposals**: Allow participants to receive translated content by email [\#8174](https://github.com/decidim/decidim/pull/8174) +- **decidim-admin**: Add search, filters, pagination and sorting to moderated users [\#8620](https://github.com/decidim/decidim/pull/8620) +- **decidim-surveys**: Add "title and description" in surveys [\#8588](https://github.com/decidim/decidim/pull/8588) + +### Changed + +- **decidim-elections**: Validate census CSV headers [\#8264](https://github.com/decidim/decidim/pull/8264) +- **decidim-meetings**: Improve Attendees count error handling on frontend [\#8238](https://github.com/decidim/decidim/pull/8238) +- **decidim-core**: Disable unconfirmed access by default [\#8233](https://github.com/decidim/decidim/pull/8233) +- **decidim-meetings**: Rename 'upcoming events' content block to 'upcoming meetings' [\#8412](https://github.com/decidim/decidim/pull/8412) +- **decidim-core**: Change user workflows to prevent user enumeration attacks [\#8537](https://github.com/decidim/decidim/pull/8537) + +### Fixed + +- **decidim-accountability**: Fix accountability notifications proposal title [\#8240](https://github.com/decidim/decidim/pull/8240) +- **decidim-elections**: Remove white spaces in Census [\#8262](https://github.com/decidim/decidim/pull/8262) +- **decidim-debates**, **decidim-meetings**, **decidim-proposals**: Fix characters not encoded in title [\#8253](https://github.com/decidim/decidim/pull/8253) +- **decidim-proposals**: Fix flaky test on proposals splitting [\#8302](https://github.com/decidim/decidim/pull/8302) +- **decidim-core**: Fix invalid i18n values for diff changeset [\#8299](https://github.com/decidim/decidim/pull/8299) +- **decidim-meetings**: Fix live? missing method delegation in online_meeting cell [\#8241](https://github.com/decidim/decidim/pull/8241) +- **decidim-comments**: Fix statistics in Comments [\#8012](https://github.com/decidim/decidim/pull/8012) +- **decidim-budgets**: Fix some explore budgets specs [\#8303](https://github.com/decidim/decidim/pull/8303) +- **decidim-core**: Fix missing icons after CORS [\#8290](https://github.com/decidim/decidim/pull/8290) +- **decidim-core**: Remove unnecessary spacer from external link indicator [\#8291](https://github.com/decidim/decidim/pull/8291) +- **decidim-core**: [CVE-2021-22942] Possible Open Redirect in Host Authorization Middleware [\#8265](https://github.com/decidim/decidim/pull/8265) +- **decidim-debates**: Fix "last comment by" when commenter is a user group [\#8279](https://github.com/decidim/decidim/pull/8279) +- **decidim-proposals**: Similar proposal functionality breaks when the machine translation is enabled. [\#8098](https://github.com/decidim/decidim/pull/8098) +- **decidim-core**: Fix regex that parses users and groups references inside content. [\#8297](https://github.com/decidim/decidim/pull/8297) +- **decidim-assemblies**: Fix birthday attribute type in Assembly Members [\#8311](https://github.com/decidim/decidim/pull/8311) +- **decidim-comments**: Fix issues with dynamic comments polling [\#8317](https://github.com/decidim/decidim/pull/8317) +- **decidim-assemblies**: Fix "Edit" and "View public page" in Assembly Members [\#8312](https://github.com/decidim/decidim/pull/8312) +- **decidim-comments**: Fix "View all comments" link in single comment page [\#8308](https://github.com/decidim/decidim/pull/8308) +- **decidim-budgets**: Fix dont allow budget exceeding in project view [\#8261](https://github.com/decidim/decidim/pull/8261) +- **decidim-debates**: Fix title meta tag for debates [\#8323](https://github.com/decidim/decidim/pull/8323) +- **decidim-proposals**: Fix UserAnswersSerializer for CSV exports [\#8329](https://github.com/decidim/decidim/pull/8329) +- **decidim-admin**: Do not block registered users with InviteUserAgain [\#8268](https://github.com/decidim/decidim/pull/8268) +- **decidim-conferences**: Fix error when accessing the meetings of a conference with speakers related [\#8369](https://github.com/decidim/decidim/pull/8369) +- **decidim-conferences**: Fix details on conference speakers: affiliation order, personal URL link, seeds and more info link [\#8378](https://github.com/decidim/decidim/pull/8378) +- **decidim-meetings**: Define localized fields in Decidim::Meetings:DiffRenderer [\#8381](https://github.com/decidim/decidim/pull/8381) +- **decidim-core**: Include only public entities in the following page [\#8361](https://github.com/decidim/decidim/pull/8361) +- **decidim-proposals**: Any user can access proposal's pages representing the "create a proposal" steps [\#8390](https://github.com/decidim/decidim/pull/8390) +- **decidim-core**: Fix localized faker with single locale [\#8394](https://github.com/decidim/decidim/pull/8394) +- **decidim-core**: Fix user activity page error message with missing username [\#8403](https://github.com/decidim/decidim/pull/8403) +- **decidim-core**: Fix conversation with deleted account [\#8409](https://github.com/decidim/decidim/pull/8409) +- **decidim-core**: Fix javascript exception when geocoding proposals is disabled [\#8413](https://github.com/decidim/decidim/pull/8413) +- **decidim-blogs**: Add missing translations [\#8426](https://github.com/decidim/decidim/pull/8426) +- **decidim-comments**: Refresh comments component after updating [\#8362](https://github.com/decidim/decidim/pull/8362) +- **decidim-core**: Fix webpacker issue when using zeitwerk [\#8444](https://github.com/decidim/decidim/pull/8444) +- **decidim-core**: Improve Zeitwerk assets paths to ignore [\#8449](https://github.com/decidim/decidim/pull/8449) +- **decidim-surveys**: Fix notification after creating survey [\#8463](https://github.com/decidim/decidim/pull/8463) +- **decidim-budgets**, **decidim-comments**: Fix comment's get link in project view [\#8450](https://github.com/decidim/decidim/pull/8450) +- **decidim-elections**: Fix report missing trustee admin log entry [\#8468](https://github.com/decidim/decidim/pull/8468) +- **decidim-system**: Add `pptx` in allowed_file_extensions (of admin) [\#8502](https://github.com/decidim/decidim/pull/8502) +- **decidim-core**: Fix 404 link in 'how to participate' home content block [\#8513](https://github.com/decidim/decidim/pull/8513) +- **decidim-meetings**: Fix meetings with multiple dates [\#8497](https://github.com/decidim/decidim/pull/8497) +- **decidim-core**: Fix pt-BR issue [\#8523](https://github.com/decidim/decidim/pull/8523) +- **decidim-generators**: Freezing webpacker to RC.5 until RC.7 is fixed [\#8531](https://github.com/decidim/decidim/pull/8531) +- **decidim-conferences**: Fix conference speakers when there isn't any avatar [\#8520](https://github.com/decidim/decidim/pull/8520) +- **decidim-assemblies**, **decidim-participatory processes**: Fix the copy of components weights in participatory processes and assemblies [\#8498](https://github.com/decidim/decidim/pull/8498) +- **decidim-meetings**: Fix meetings input when rich text editor is disabled [\#8534](https://github.com/decidim/decidim/pull/8534) +- **decidim-meetings**: Fix showing created meetings in 'my public profile' [\#8519](https://github.com/decidim/decidim/pull/8519) +- **decidim-meetings**, **decidim-proposals**: Fix various proposal picker issues when there are thousands of proposals [\#8558](https://github.com/decidim/decidim/pull/8558) +- **decidim-core**: Remove border on all the fieldsets [\#8561](https://github.com/decidim/decidim/pull/8561) +- **decidim-initiatives**: Remove wrong in initiatives header [\#8563](https://github.com/decidim/decidim/pull/8563) +- **decidim-core**: Fix CSS layout wrapper top padding [\#8562](https://github.com/decidim/decidim/pull/8562) +- **decidim-forms**, **decidim-surveys**: Fix duplicated answers in surveys [\#8560](https://github.com/decidim/decidim/pull/8560) +- **decidim-meetings**: Fix the meeting copy functionality [\#8430](https://github.com/decidim/decidim/pull/8430) +- **decidim-core**: Move social login buttons to the top of the login modal [\#8574](https://github.com/decidim/decidim/pull/8574) +- **decidim-comments**, **decidim-meetings**: Fix HTML injection in comments and meeting's description [\#8511](https://github.com/decidim/decidim/pull/8511) +- **decidim-core**: Fix avatar thumbnail in participants' profile [\#8577](https://github.com/decidim/decidim/pull/8577) +- **decidim-core**: Rename index to avoid conflicts with decidim_awesome module migrations [\#8613](https://github.com/decidim/decidim/pull/8613) +- **decidim-core**: Fix group mentions in notifications [\#8598](https://github.com/decidim/decidim/pull/8598) +- **decidim-forms**, **decidim-surveys**: Fix surveys exports with free text in multiple option [\#8582](https://github.com/decidim/decidim/pull/8582) +- **decidim-core**: Fix reply to a conversation with deleted participants [\#8635](https://github.com/decidim/decidim/pull/8635) +- **decidim-admin**, **decidim-debates**, **decidim-proposals**: Fix consistency in creation actions phrasing: "Participants can create XXX" [\#8650](https://github.com/decidim/decidim/pull/8650) +- **decidim-core**: Fix wrong display of deleted accounts in conversations [\#8641](https://github.com/decidim/decidim/pull/8641) +- **decidim-core**: Fix cache key on ActivityCell [\#8654](https://github.com/decidim/decidim/pull/8654) +- **decidim-participatory processes**: Fix participatory groups leaks on other organizations/tenants [\#8651](https://github.com/decidim/decidim/pull/8651) +- **decidim-core**: Fix blocked users appear in search [\#8658](https://github.com/decidim/decidim/pull/8658) +- **decidim-meetings**: Don't start poll meetings component when DOM elements are not present [\#8676](https://github.com/decidim/decidim/pull/8676) +- **decidim-initiatives**, **decidim-proposals**: Fix initiative attachments [\#7452](https://github.com/decidim/decidim/pull/7452) +- **decidim-assemblies**: Fix performance issues on assemblies page when having many private users [\#8509](https://github.com/decidim/decidim/pull/8509) +- **decidim-proposals**: Add location data to proposals export and import [\#8679](https://github.com/decidim/decidim/pull/8679) +- **decidim-meetings**: Fix meetings form embed type visibility [\#8602](https://github.com/decidim/decidim/pull/8602) +- **decidim-meetings**: Do not send upcoming meeting events notification for past events [\#8665](https://github.com/decidim/decidim/pull/8665) + +### Removed + +- **decidim-proposals**: Remove "Allow card image" setting from Proposals [\#8281](https://github.com/decidim/decidim/pull/8281) +- **decidim-assemblies**: Remove designation_mode field from Assembly Members [\#8310](https://github.com/decidim/decidim/pull/8310) +- **decidim-participatory processes**: Remove admin show page in Participatory Process Groups [\#8313](https://github.com/decidim/decidim/pull/8313) + +### Developer improvements + +- Fix Luxembourgish locale [\#8270](https://github.com/decidim/decidim/pull/8270) +- Fix ARIA roles for dialogs and tooltips [\#8293](https://github.com/decidim/decidim/pull/8293) +- Add selectors on edit_form_fields [\#8353](https://github.com/decidim/decidim/pull/8353) +- Fix HTTPOnly and secure flag on the cookie acceptance cookie [\#8358](https://github.com/decidim/decidim/pull/8358) +- Add Brakeman to GitHub Actions for improving security [\#6832](https://github.com/decidim/decidim/pull/6832) +- Disallow redirection to the host when performing redirect_back [\#8296](https://github.com/decidim/decidim/pull/8296) +- Improve performance on the serializers by using includes, query counter [\#8278](https://github.com/decidim/decidim/pull/8278) +- Enforce redirects to include the organization host [\#8385](https://github.com/decidim/decidim/pull/8385) +- Fix issues with the session/environment security configs [\#8360](https://github.com/decidim/decidim/pull/8360) +- Improve extendability on some controllers [\#8398](https://github.com/decidim/decidim/pull/8398) +- Add avatar eager logging to UserEntityFinder #8416 [\#8417](https://github.com/decidim/decidim/pull/8417) +- Increase text contrast in current phase of a participatory process [\#8422](https://github.com/decidim/decidim/pull/8422) +- Fix CVE-2021-41136 (HTTP Request Smuggling in puma) [\#8431](https://github.com/decidim/decidim/pull/8431) +- Remove anchored dependency [\#8453](https://github.com/decidim/decidim/pull/8453) +- Fix pt-BR issue [\#8523](https://github.com/decidim/decidim/pull/8523) +- Add rendered view instrumentation information [\#8530](https://github.com/decidim/decidim/pull/8530) +- Optimize open data exporter for large amount of data [\#8503](https://github.com/decidim/decidim/pull/8503) +- Add cache key separator to cache_hash [\#8559](https://github.com/decidim/decidim/pull/8559) +- Improve generation of the opendata export [\#8593](https://github.com/decidim/decidim/pull/8593) +- Add several cache keys to cells [\#8566](https://github.com/decidim/decidim/pull/8566) +- Update password strength check [\#8455](https://github.com/decidim/decidim/pull/8455) +- Remove etherpad-lite dependency [\#8541](https://github.com/decidim/decidim/pull/8541) +- Fix Rack::Attack initializer custom parameter configuration [\#8643](https://github.com/decidim/decidim/pull/8643) + +### Internal + +- Fix dependencies locks after 0.26.0.dev bump [\#8247](https://github.com/decidim/decidim/pull/8247) +- Add modules recommendations in documentation [\#8218](https://github.com/decidim/decidim/pull/8218) +- Fix webpacker dependency lock [\#8272](https://github.com/decidim/decidim/pull/8272) +- Improve README with examples [\#8244](https://github.com/decidim/decidim/pull/8244) +- Update foundation-sites to 6.7.0 for better Dart Sass compatibility [\#8273](https://github.com/decidim/decidim/pull/8273) +- Fix NPM packages versioning during release process [\#8280](https://github.com/decidim/decidim/pull/8280) +- Add 'Lint PR title' workflow to CI [\#8285](https://github.com/decidim/decidim/pull/8285) +- Don't trigger PR linting on pushes, only on PRs [\#8304](https://github.com/decidim/decidim/pull/8304) +- Prevent root package.json to be treated as a package [\#8315](https://github.com/decidim/decidim/pull/8315) +- Fix CSS validation tests caused by a bug on the validation service [\#8322](https://github.com/decidim/decidim/pull/8322) +- **decidim-core**: Remove npm decidim packages with dependencies from other decidim packages [\#8330](https://github.com/decidim/decidim/pull/8330) +- **decidim-core**: Fix problems introduced by #8330 [\#8341](https://github.com/decidim/decidim/pull/8341) +- Update Node and NPM version [\#8343](https://github.com/decidim/decidim/pull/8343) +- Remove hack for CSS validation [\#8326](https://github.com/decidim/decidim/pull/8326) +- Update docs in migrating to webpacker [\#8349](https://github.com/decidim/decidim/pull/8349) +- **decidim-comments**: Ignore errors during comments migration task [\#8351](https://github.com/decidim/decidim/pull/8351) +- **decidim-meetings**: Fix published and title in seeded meetings [\#8359](https://github.com/decidim/decidim/pull/8359) +- **decidim-core**: Fix SQL to make version display faster [\#8393](https://github.com/decidim/decidim/pull/8393) +- Remove GraphQL deprecated API call [\#8432](https://github.com/decidim/decidim/pull/8432) +- **decidim-generators**: Fixing generator webpacker issues [\#8427](https://github.com/decidim/decidim/pull/8427) +- **decidim-generators**: Fix railties requirements on created applications [\#8415](https://github.com/decidim/decidim/pull/8415) +- **decidim-core**: Update omniauth gem and dependencies [\#8388](https://github.com/decidim/decidim/pull/8388) +- Document how to enable machine translations on organization [\#8458](https://github.com/decidim/decidim/pull/8458) +- **decidim-dev**: Improves manual installation documentation [\#8508](https://github.com/decidim/decidim/pull/8508) +- Update the i18n-tasks initialization syntax [\#8544](https://github.com/decidim/decidim/pull/8544) +- Documentation: improve develop section [\#8553](https://github.com/decidim/decidim/pull/8553) +- Change default window size in Capybara configuration [\#8576](https://github.com/decidim/decidim/pull/8576) +- Fix security instructions [\#8587](https://github.com/decidim/decidim/pull/8587) +- Temporarily ignore CSS validation issue in CI [\#8597](https://github.com/decidim/decidim/pull/8597) +- Update nokogiri to 1.12.5 [\#8609](https://github.com/decidim/decidim/pull/8609) +- Update paper_trail to 12.1 [\#8608](https://github.com/decidim/decidim/pull/8608) +- Update ruby to 2.7.5 [\#8629](https://github.com/decidim/decidim/pull/8629) +- Remove truncato dependency [\#8507](https://github.com/decidim/decidim/pull/8507) +- Change figaro to rbenv-vars in "manual installation" documentation [\#8575](https://github.com/decidim/decidim/pull/8575) +- Add instructions PostgreSQL configuration in development app [\#8618](https://github.com/decidim/decidim/pull/8618) +- Fix etherpad doc reference in initializer [\#8632](https://github.com/decidim/decidim/pull/8632) +- Clarifies git branches conventions in doc [\#8644](https://github.com/decidim/decidim/pull/8644) +- Fix changelog link [\#8671](https://github.com/decidim/decidim/pull/8671) +- Enable simplecov only for rspec step [\#8674](https://github.com/decidim/decidim/pull/8674) +- **decidim-dev**: Improve machine translation documentation and comments [\#8668](https://github.com/decidim/decidim/pull/8668) +- Split the workflows files for CI [\#8675](https://github.com/decidim/decidim/pull/8675) +- DRY GitHub workflows with composite actions [\#8677](https://github.com/decidim/decidim/pull/8677) +- Change Gitter to Matrix.org in documentation [\#8466](https://github.com/decidim/decidim/pull/8466) ## Previous versions -Please check [release/0.24-stable](https://github.com/decidim/decidim/blob/release/0.24-stable/CHANGELOG.md) for previous changes. +Please check [release/0.25-stable](https://github.com/decidim/decidim/blob/release/0.25-stable/CHANGELOG.md) for previous changes. diff --git a/CONTRIBUTING.adoc b/CONTRIBUTING.adoc index 5c91a36f64150..24f607c2298aa 100644 --- a/CONTRIBUTING.adoc +++ b/CONTRIBUTING.adoc @@ -1,11 +1,13 @@ = How to contribute to Decidim -We're really glad you're reading this, because we need volunteer developers to help this project come to fruition. - -If you haven't already, come find us in https://gitter.im/decidim/decidim[Gitter]. We want you working on things you're excited about. +We're really glad you're reading this, because we need volunteer contributors to help this project come to fruition. Please note that by making a Pull Request in this repository you're agreeing with https://decidim.org/contract[Decidim's Social Contract]. +== Do you want to say hello to us? + +Come find us at https://matrix.to/#/#decidim:matrix.org[our Matrix.org space]. We have chat rooms for developers, designers and translators. + == Did you find a bug? * *Do not open up a GitHub issue if the bug is a security vulnerability in Decidim*, and instead send us an email to security [at] decidim.org. @@ -21,7 +23,7 @@ Be sure to include a *title and clear description*, as much relevant information Include the relevant issue number if applicable. * Check our https://docs.decidim.org/en/develop/guide/[development_guide]. * When the PR includes a breaking change or includes something that requires manual intervention when deploying, it's necessary to add it on the changelog upgrade notes. -See https://docs.decidim.org/en/develop/guide_changelog/[rules for the changelog page in docs]. +See https://docs.decidim.org/en/develop/guide_conventions/#_changelog[rules for the changelog page in docs]. == Do you intend to add a new feature or change an existing one? @@ -37,7 +39,7 @@ You can read in detail about this process in https://docs.decidim.org/en/governa == Do you have questions about the source code? -* Ask any question about how to use Decidim in https://gitter.im/decidim/decidim[Gitter]. +* Ask any question about how to use Decidim in https://matrix.to/#/#decidimdevs:matrix.org[our Decidim Devs Matrix chat room]. == Do you want to contribute to Decidim documentation? diff --git a/Dockerfile.design b/Dockerfile.design index be47c1e76932f..732d10c38f015 100644 --- a/Dockerfile.design +++ b/Dockerfile.design @@ -1,4 +1,4 @@ -FROM ruby:2.7.1 +FROM ruby:2.7.5 LABEL maintainer="info@codegram.com" ENV LANG C.UTF-8 diff --git a/Gemfile b/Gemfile index ea9b4db088074..36a8274c232ce 100644 --- a/Gemfile +++ b/Gemfile @@ -27,6 +27,8 @@ group :development, :test do gem "simplecov", "~> 0.19.0" gem "decidim-dev", path: "." + + gem "brakeman", "~> 5.1" end group :development do diff --git a/Gemfile.lock b/Gemfile.lock index 8f684cf1e20fa..3ed050bce7ec3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -11,65 +11,64 @@ GIT PATH remote: . specs: - decidim (0.25.2) - decidim-accountability (= 0.25.2) - decidim-admin (= 0.25.2) - decidim-api (= 0.25.2) - decidim-assemblies (= 0.25.2) - decidim-blogs (= 0.25.2) - decidim-budgets (= 0.25.2) - decidim-comments (= 0.25.2) - decidim-core (= 0.25.2) - decidim-debates (= 0.25.2) - decidim-forms (= 0.25.2) - decidim-generators (= 0.25.2) - decidim-meetings (= 0.25.2) - decidim-pages (= 0.25.2) - decidim-participatory_processes (= 0.25.2) - decidim-proposals (= 0.25.2) - decidim-sortitions (= 0.25.2) - decidim-surveys (= 0.25.2) - decidim-system (= 0.25.2) - decidim-templates (= 0.25.2) - decidim-verifications (= 0.25.2) - decidim-accountability (0.25.2) - decidim-comments (= 0.25.2) - decidim-core (= 0.25.2) - decidim-admin (0.25.2) + decidim (0.26.4) + decidim-accountability (= 0.26.4) + decidim-admin (= 0.26.4) + decidim-api (= 0.26.4) + decidim-assemblies (= 0.26.4) + decidim-blogs (= 0.26.4) + decidim-budgets (= 0.26.4) + decidim-comments (= 0.26.4) + decidim-core (= 0.26.4) + decidim-debates (= 0.26.4) + decidim-forms (= 0.26.4) + decidim-generators (= 0.26.4) + decidim-meetings (= 0.26.4) + decidim-pages (= 0.26.4) + decidim-participatory_processes (= 0.26.4) + decidim-proposals (= 0.26.4) + decidim-sortitions (= 0.26.4) + decidim-surveys (= 0.26.4) + decidim-system (= 0.26.4) + decidim-templates (= 0.26.4) + decidim-verifications (= 0.26.4) + decidim-accountability (0.26.4) + decidim-comments (= 0.26.4) + decidim-core (= 0.26.4) + decidim-admin (0.26.4) active_link_to (~> 1.0) - decidim-core (= 0.25.2) + decidim-core (= 0.26.4) devise (~> 4.7) devise-i18n (~> 1.2) devise_invitable (~> 2.0) - decidim-api (0.25.2) - graphql (~> 1.12, >= 1.12.3) + decidim-api (0.26.4) + graphql (~> 1.12, < 1.13) rack-cors (~> 1.0) redcarpet (~> 3.5, >= 3.5.1) - decidim-assemblies (0.25.2) - decidim-core (= 0.25.2) - decidim-blogs (0.25.2) - decidim-admin (= 0.25.2) - decidim-comments (= 0.25.2) - decidim-core (= 0.25.2) - decidim-budgets (0.25.2) - decidim-comments (= 0.25.2) - decidim-core (= 0.25.2) - decidim-comments (0.25.2) - decidim-core (= 0.25.2) + decidim-assemblies (0.26.4) + decidim-core (= 0.26.4) + decidim-blogs (0.26.4) + decidim-admin (= 0.26.4) + decidim-comments (= 0.26.4) + decidim-core (= 0.26.4) + decidim-budgets (0.26.4) + decidim-comments (= 0.26.4) + decidim-core (= 0.26.4) + decidim-comments (0.26.4) + decidim-core (= 0.26.4) redcarpet (~> 3.5, >= 3.5.1) - decidim-conferences (0.25.2) - decidim-core (= 0.25.2) - decidim-meetings (= 0.25.2) + decidim-conferences (0.26.4) + decidim-core (= 0.26.4) + decidim-meetings (= 0.26.4) wicked_pdf (~> 2.1) wkhtmltopdf-binary (~> 0.12) - decidim-consultations (0.25.2) - decidim-admin (= 0.25.2) - decidim-comments (= 0.25.2) - decidim-core (= 0.25.2) - decidim-core (0.25.2) + decidim-consultations (0.26.4) + decidim-admin (= 0.26.4) + decidim-comments (= 0.26.4) + decidim-core (= 0.26.4) + decidim-core (0.26.4) active_link_to (~> 1.0) acts_as_list (~> 0.9) - anchored (~> 1.1) batch-loader (~> 1.2) browser (~> 2.7) carrierwave (~> 2.2.1) @@ -77,30 +76,29 @@ PATH cells-rails (~> 0.1.3) charlock_holmes (~> 0.7) date_validator (~> 0.9.0) - decidim-api (= 0.25.2) + decidim-api (= 0.26.4) devise (~> 4.7) devise-i18n (~> 1.2) diffy (~> 3.3) doorkeeper (~> 5.1) doorkeeper-i18n (~> 4.0) - etherpad-lite (~> 0.3) file_validators (~> 2.1) fog-local (~> 0.6) foundation_rails_helper - geocoder (~> 1.5) + geocoder (~> 1.7.5) hashdiff (>= 0.4.0, < 2.0.0) invisible_captcha (~> 0.12) kaminari (~> 1.2, >= 1.2.1) loofah (~> 2.3.1) + mime-types (>= 1.16, < 4.0) mini_magick (~> 4.9) mustache (~> 1.1.0) - nobspw (~> 0.6.0) omniauth (~> 2.0) omniauth-facebook (~> 5.0) omniauth-google-oauth2 (~> 1.0) omniauth-rails_csrf_protection (~> 1.0) omniauth-twitter (~> 1.4) - paper_trail (~> 10.3) + paper_trail (~> 12.0) pg (~> 1.1.4, < 2) pg_search (~> 2.2) premailer-rails (~> 1.10) @@ -117,24 +115,23 @@ PATH searchlight (~> 4.1) seven_zip_ruby (~> 1.3) social-share-button (~> 1.2, >= 1.2.1) - truncato (~> 0.7) valid_email2 (~> 2.1) webpacker (= 6.0.0.rc.5) wisper (~> 2.0) - decidim-debates (0.25.2) - decidim-comments (= 0.25.2) - decidim-core (= 0.25.2) - decidim-dev (0.25.2) + decidim-debates (0.26.4) + decidim-comments (= 0.26.4) + decidim-core (= 0.26.4) + decidim-dev (0.26.4) axe-core-rspec (~> 4.1.0) byebug (~> 11.0) capybara (~> 3.24) db-query-matchers (~> 0.10.0) - decidim (= 0.25.2) + decidim (= 0.26.4) erb_lint (~> 0.0.35) factory_bot_rails (~> 4.8) i18n-tasks (~> 0.9.18) mdl (~> 0.5) - nokogiri (~> 1.11, >= 1.11.4) + nokogiri (~> 1.12) puma (~> 5.0) rails-controller-testing (~> 1.0) rspec-cells (~> 0.3.4) @@ -152,63 +149,63 @@ PATH w3c_rspec_validators (~> 0.3.0) webmock (~> 3.6) wisper-rspec (~> 1.0) - decidim-elections (0.25.2) - decidim-bulletin_board (= 0.21.2) - decidim-core (= 0.25.2) - decidim-forms (= 0.25.2) - decidim-proposals (= 0.25.2) + decidim-elections (0.26.4) + decidim-bulletin_board (= 0.22.3) + decidim-core (= 0.26.4) + decidim-forms (= 0.26.4) + decidim-proposals (= 0.26.4) rack-attack (~> 6.0) - voting_schemes-dummy (= 0.21.2) - voting_schemes-electionguard (= 0.21.2) - decidim-forms (0.25.2) - decidim-core (= 0.25.2) + voting_schemes-dummy (= 0.22.3) + voting_schemes-electionguard (= 0.22.3) + decidim-forms (0.26.4) + decidim-core (= 0.26.4) wicked_pdf (~> 2.1) wkhtmltopdf-binary (~> 0.12) - decidim-generators (0.25.2) - decidim-core (= 0.25.2) - decidim-initiatives (0.25.2) - decidim-admin (= 0.25.2) - decidim-comments (= 0.25.2) - decidim-core (= 0.25.2) - decidim-verifications (= 0.25.2) + decidim-generators (0.26.4) + decidim-core (= 0.26.4) + decidim-initiatives (0.26.4) + decidim-admin (= 0.26.4) + decidim-comments (= 0.26.4) + decidim-core (= 0.26.4) + decidim-verifications (= 0.26.4) origami (~> 2.1) virtus-multiparams (~> 0.1) wicked (~> 1.3) wicked_pdf (~> 2.1) wkhtmltopdf-binary (~> 0.12) - decidim-meetings (0.25.2) - decidim-core (= 0.25.2) - decidim-forms (= 0.25.2) + decidim-meetings (0.26.4) + decidim-core (= 0.26.4) + decidim-forms (= 0.26.4) icalendar (~> 2.5) - decidim-pages (0.25.2) - decidim-core (= 0.25.2) - decidim-participatory_processes (0.25.2) - decidim-core (= 0.25.2) - decidim-proposals (0.25.2) - decidim-comments (= 0.25.2) - decidim-core (= 0.25.2) - doc2text (~> 0.4.3) + decidim-pages (0.26.4) + decidim-core (= 0.26.4) + decidim-participatory_processes (0.26.4) + decidim-core (= 0.26.4) + decidim-proposals (0.26.4) + decidim-comments (= 0.26.4) + decidim-core (= 0.26.4) + doc2text (~> 0.4.4) redcarpet (~> 3.5, >= 3.5.1) - decidim-sortitions (0.25.2) - decidim-admin (= 0.25.2) - decidim-comments (= 0.25.2) - decidim-core (= 0.25.2) - decidim-proposals (= 0.25.2) - decidim-surveys (0.25.2) - decidim-core (= 0.25.2) - decidim-forms (= 0.25.2) - decidim-templates (= 0.25.2) - decidim-system (0.25.2) + decidim-sortitions (0.26.4) + decidim-admin (= 0.26.4) + decidim-comments (= 0.26.4) + decidim-core (= 0.26.4) + decidim-proposals (= 0.26.4) + decidim-surveys (0.26.4) + decidim-core (= 0.26.4) + decidim-forms (= 0.26.4) + decidim-templates (= 0.26.4) + decidim-system (0.26.4) active_link_to (~> 1.0) - decidim-core (= 0.25.2) + decidim-core (= 0.26.4) devise (~> 4.7) devise-i18n (~> 1.2) devise_invitable (~> 2.0) - decidim-templates (0.25.2) - decidim-core (= 0.25.2) - decidim-forms (= 0.25.2) - decidim-verifications (0.25.2) - decidim-core (= 0.25.2) + decidim-templates (0.26.4) + decidim-core (= 0.26.4) + decidim-forms (= 0.26.4) + decidim-verifications (0.26.4) + decidim-core (= 0.26.4) GEM remote: https://rubygems.org/ @@ -275,9 +272,8 @@ GEM activerecord (>= 3.0) addressable (2.8.0) public_suffix (>= 2.0.2, < 5.0) - anchored (1.1.0) ast (2.4.2) - axe-core-api (4.3.2) + axe-core-api (4.4.2) dumb_delegator virtus axe-core-rspec (4.1.0) @@ -289,7 +285,7 @@ GEM ice_nine (~> 0.11.0) thread_safe (~> 0.3, >= 0.3.1) batch-loader (1.5.0) - bcrypt (3.1.16) + bcrypt (3.1.18) better_html (1.0.16) actionview (>= 4.0) activesupport (>= 4.0) @@ -301,10 +297,11 @@ GEM bindex (0.8.1) bootsnap (1.7.5) msgpack (~> 1.0) + brakeman (5.1.1) browser (2.7.1) builder (3.2.4) byebug (11.1.3) - capybara (3.36.0) + capybara (3.38.0) addressable matrix mini_mime (>= 0.1.3) @@ -329,11 +326,11 @@ GEM cells-erb (0.1.0) cells (~> 4.0) erbse (>= 0.1.1) - cells-rails (0.1.4) + cells-rails (0.1.5) actionpack (>= 5.0) cells (>= 4.1.6, < 5.0.0) charlock_holmes (0.7.7) - chef-utils (17.7.29) + chef-utils (18.0.172) concurrent-ruby childprocess (3.0.0) coercible (1.0.0) @@ -350,7 +347,7 @@ GEM crack (0.4.5) rexml crass (1.0.6) - css_parser (1.10.0) + css_parser (1.12.0) addressable date_validator (0.9.0) activemodel @@ -358,37 +355,35 @@ GEM db-query-matchers (0.10.0) activesupport (>= 4.0, < 7) rspec (~> 3.0) - decidim-bulletin_board (0.21.2) + decidim-bulletin_board (0.22.3) byebug (~> 11.0) graphlient (~> 0.4.0) jwt (~> 2.2.2) - rails (>= 5.0.0) + rails (~> 6.0, >= 5.0.0) wisper (~> 2.0.0) declarative-builder (0.1.0) declarative-option (< 0.2.0) declarative-option (0.1.0) descendants_tracker (0.0.4) thread_safe (~> 0.3, >= 0.3.1) - devise (4.8.0) + devise (4.8.1) bcrypt (~> 3.0) orm_adapter (~> 0.1) railties (>= 4.1.0) responders warden (~> 1.2.3) - devise-i18n (1.10.1) + devise-i18n (1.10.2) devise (>= 4.8.0) - devise_invitable (2.0.5) + devise_invitable (2.0.6) actionmailer (>= 5.0) devise (>= 4.6) - diff-lcs (1.4.4) - diffy (3.4.0) - doc2text (0.4.3) - nokogiri (~> 1.11.1) + diff-lcs (1.5.0) + diffy (3.4.2) + doc2text (0.4.4) + nokogiri (>= 1.12.5, < 1.13.0) rubyzip (~> 2.3.0) docile (1.4.0) - domain_name (0.5.20190701) - unf (>= 0.0.5, < 1.0.0) - doorkeeper (5.5.4) + doorkeeper (5.6.0) railties (>= 5) doorkeeper-i18n (4.0.1) dumb_delegator (1.0.0) @@ -404,9 +399,7 @@ GEM erbse (0.1.4) temple erubi (1.10.0) - etherpad-lite (0.3.0) - rest-client (>= 1.6) - excon (0.88.0) + excon (0.93.1) execjs (2.8.1) factory_bot (4.11.1) activesupport (>= 3.0.0) @@ -415,61 +408,62 @@ GEM railties (>= 3.0.0) faker (2.18.0) i18n (>= 1.6, < 2) - faraday (1.8.0) + faraday (1.10.2) faraday-em_http (~> 1.0) faraday-em_synchrony (~> 1.0) faraday-excon (~> 1.1) - faraday-httpclient (~> 1.0.1) + faraday-httpclient (~> 1.0) + faraday-multipart (~> 1.0) faraday-net_http (~> 1.0) - faraday-net_http_persistent (~> 1.1) + faraday-net_http_persistent (~> 1.0) faraday-patron (~> 1.0) faraday-rack (~> 1.0) - multipart-post (>= 1.2, < 3) + faraday-retry (~> 1.0) ruby2_keywords (>= 0.0.4) faraday-em_http (1.0.0) faraday-em_synchrony (1.0.0) faraday-excon (1.1.0) faraday-httpclient (1.0.1) + faraday-multipart (1.0.4) + multipart-post (~> 2) faraday-net_http (1.0.1) faraday-net_http_persistent (1.2.0) faraday-patron (1.0.0) faraday-rack (1.0.0) + faraday-retry (1.0.3) faraday_middleware (1.2.0) faraday (~> 1.0) ffi (1.15.1) file_validators (2.3.0) activemodel (>= 3.2) mime-types (>= 1.0) - fog-core (2.2.4) + fog-core (2.3.0) builder excon (~> 0.71) - formatador (~> 0.2) + formatador (>= 0.2, < 2.0) mime-types - fog-local (0.7.0) + fog-local (0.8.0) fog-core (>= 1.27, < 3.0) - formatador (0.3.0) - geocoder (1.7.0) + formatador (1.1.0) + geocoder (1.7.5) globalid (0.5.2) activesupport (>= 5.0) graphlient (0.4.0) faraday (>= 1.0) faraday_middleware graphql-client - graphql (1.12.20) - graphql-client (0.17.0) + graphql (1.12.24) + graphql-client (0.18.0) activesupport (>= 3.0) - graphql (~> 1.10) + graphql hashdiff (1.0.1) hashie (5.0.0) highline (2.0.3) html_tokenizer (0.0.7) htmlentities (4.3.4) - http-accept (1.7.0) - http-cookie (1.0.4) - domain_name (~> 0.5) i18n (1.8.11) concurrent-ruby (~> 1.0) - i18n-tasks (0.9.35) + i18n-tasks (0.9.37) activesupport (>= 4.0.2) ast (>= 2.1.0) erubi @@ -479,30 +473,30 @@ GEM rails-i18n rainbow (>= 2.2.2, < 4.0) terminal-table (>= 1.5.1) - icalendar (2.7.1) + icalendar (2.8.0) ice_cube (~> 0.16) ice_cube (0.16.4) ice_nine (0.11.2) - image_processing (1.12.1) + image_processing (1.12.2) mini_magick (>= 4.9.5, < 5) ruby-vips (>= 2.0.17, < 3) invisible_captcha (0.13.0) rails (>= 3.2.0) - json (2.6.1) + json (2.6.2) jwt (2.2.3) - kaminari (1.2.1) + kaminari (1.2.2) activesupport (>= 4.1.0) - kaminari-actionview (= 1.2.1) - kaminari-activerecord (= 1.2.1) - kaminari-core (= 1.2.1) - kaminari-actionview (1.2.1) + kaminari-actionview (= 1.2.2) + kaminari-activerecord (= 1.2.2) + kaminari-core (= 1.2.2) + kaminari-actionview (1.2.2) actionview - kaminari-core (= 1.2.1) - kaminari-activerecord (1.2.1) + kaminari-core (= 1.2.2) + kaminari-activerecord (1.2.2) activerecord - kaminari-core (= 1.2.1) - kaminari-core (1.2.1) - kramdown (2.3.1) + kaminari-core (= 1.2.2) + kaminari-core (1.2.2) + kramdown (2.4.0) rexml kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) @@ -524,7 +518,7 @@ GEM mini_mime (>= 0.1.1) marcel (1.0.2) matrix (0.4.2) - mdl (0.11.0) + mdl (0.12.0) kramdown (~> 2.3) kramdown-parser-gfm (~> 1.1) mixlib-cli (~> 2.1, >= 2.1.1) @@ -533,52 +527,55 @@ GEM method_source (1.0.0) mime-types (3.4.1) mime-types-data (~> 3.2015) - mime-types-data (3.2021.1115) + mime-types-data (3.2022.0105) mini_magick (4.11.0) mini_mime (1.1.1) - mini_portile2 (2.5.3) + mini_portile2 (2.6.1) minitest (5.14.4) mixlib-cli (2.1.8) - mixlib-config (3.0.9) + mixlib-config (3.0.27) tomlrb - mixlib-shellout (3.2.5) + mixlib-shellout (3.2.7) chef-utils msgpack (1.4.2) - multi_json (1.15.0) multi_xml (0.6.0) - multipart-post (2.1.1) + multipart-post (2.2.3) mustache (1.1.1) - netrc (0.11.0) nio4r (2.5.8) - nobspw (0.6.2) - nokogiri (1.11.7) - mini_portile2 (~> 2.5.0) + nokogiri (1.12.5) + mini_portile2 (~> 2.6.1) racc (~> 1.4) - oauth (0.5.8) - oauth2 (1.4.7) - faraday (>= 0.8, < 2.0) + oauth (1.1.0) + oauth-tty (~> 1.0, >= 1.0.1) + snaky_hash (~> 2.0) + version_gem (~> 1.1) + oauth-tty (1.0.5) + version_gem (~> 1.1, >= 1.1.1) + oauth2 (2.0.9) + faraday (>= 0.17.3, < 3.0) jwt (>= 1.0, < 3.0) - multi_json (~> 1.3) multi_xml (~> 0.5) - rack (>= 1.2, < 3) - omniauth (2.0.4) + rack (>= 1.2, < 4) + snaky_hash (~> 2.0) + version_gem (~> 1.1) + omniauth (2.1.0) hashie (>= 3.4.6) - rack (>= 1.6.2, < 3) + rack (>= 2.2.3) rack-protection omniauth-facebook (5.0.0) omniauth-oauth2 (~> 1.2) - omniauth-google-oauth2 (1.0.0) + omniauth-google-oauth2 (1.1.1) jwt (>= 2.0) - oauth2 (~> 1.1) + oauth2 (~> 2.0.6) omniauth (~> 2.0) - omniauth-oauth2 (~> 1.7.1) + omniauth-oauth2 (~> 1.8.0) omniauth-oauth (1.2.0) oauth omniauth (>= 1.0, < 3) - omniauth-oauth2 (1.7.2) - oauth2 (~> 1.4) - omniauth (>= 1.9, < 3) - omniauth-rails_csrf_protection (1.0.0) + omniauth-oauth2 (1.8.0) + oauth2 (>= 1.4, < 3) + omniauth (~> 2.0) + omniauth-rails_csrf_protection (1.0.1) actionpack (>= 4.2) omniauth (~> 2.0) omniauth-twitter (1.4.0) @@ -587,19 +584,19 @@ GEM origami (2.1.0) colorize (~> 0.7) orm_adapter (0.5.0) - paper_trail (10.3.1) - activerecord (>= 4.2) + paper_trail (12.3.0) + activerecord (>= 5.2) request_store (~> 1.1) parallel (1.20.1) parser (3.0.2.0) ast (~> 2.4.1) pg (1.1.4) - pg_search (2.3.5) + pg_search (2.3.6) activerecord (>= 5.2) activesupport (>= 5.2) - premailer (1.15.0) + premailer (1.18.0) addressable - css_parser (>= 1.6.0) + css_parser (>= 1.12.0) htmlentities (>= 4.0.0) premailer-rails (1.11.1) actionmailer (>= 3) @@ -609,13 +606,13 @@ GEM nio4r (~> 2.0) racc (1.6.0) rack (2.2.3) - rack-attack (6.5.0) + rack-attack (6.6.1) rack (>= 1.0, < 3) rack-cors (1.1.1) rack (>= 2.0.0) - rack-protection (2.1.0) + rack-protection (3.0.2) rack - rack-proxy (0.7.0) + rack-proxy (0.7.4) rack rack-test (1.1.0) rack (>= 1.0, < 3) @@ -668,37 +665,32 @@ GEM virtus (~> 1.0.5) wisper (>= 1.6.1) redcarpet (3.5.1) - redis (4.5.1) + redis (4.8.0) regexp_parser (2.1.1) - request_store (1.5.0) + request_store (1.5.1) rack (>= 1.4) responders (3.0.1) actionpack (>= 5.0) railties (>= 5.0) - rest-client (2.1.0) - http-accept (>= 1.7.0, < 2.0) - http-cookie (>= 1.0.2, < 2.0) - mime-types (>= 1.16, < 4.0) - netrc (~> 0.8) rexml (3.2.5) - rspec (3.10.0) - rspec-core (~> 3.10.0) - rspec-expectations (~> 3.10.0) - rspec-mocks (~> 3.10.0) - rspec-cells (0.3.7) + rspec (3.12.0) + rspec-core (~> 3.12.0) + rspec-expectations (~> 3.12.0) + rspec-mocks (~> 3.12.0) + rspec-cells (0.3.8) cells (>= 4.0.0, < 6.0.0) - rspec-rails (< 6.0) - rspec-core (3.10.1) - rspec-support (~> 3.10.0) - rspec-expectations (3.10.1) + rspec-rails (>= 3.0.0, < 6.1.0) + rspec-core (3.12.0) + rspec-support (~> 3.12.0) + rspec-expectations (3.12.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.10.0) + rspec-support (~> 3.12.0) rspec-html-matchers (0.9.4) nokogiri (~> 1) rspec (>= 3.0.0.a, < 4) - rspec-mocks (3.10.2) + rspec-mocks (3.12.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.10.0) + rspec-support (~> 3.12.0) rspec-rails (4.1.2) actionpack (>= 4.2) activesupport (>= 4.2) @@ -709,7 +701,7 @@ GEM rspec-support (~> 3.10) rspec-retry (0.6.2) rspec-core (> 3.3) - rspec-support (3.10.3) + rspec-support (3.12.0) rspec_junit_formatter (0.3.0) rspec-core (>= 2, < 4, != 2.12.0) rubocop (0.92.0) @@ -736,7 +728,7 @@ GEM ruby-vips (2.1.4) ffi (~> 1.12) ruby2_keywords (0.0.5) - rubyXL (3.4.18) + rubyXL (3.4.25) nokogiri (>= 1.10.8) rubyzip (>= 1.3.0) rubyzip (2.3.2) @@ -752,43 +744,41 @@ GEM simplecov-cobertura (1.3.1) simplecov (~> 0.8) simplecov-html (0.12.3) - smart_properties (1.16.3) + smart_properties (1.17.0) + snaky_hash (2.0.1) + hashie + version_gem (~> 1.1, >= 1.1.1) social-share-button (1.2.4) coffee-rails spring (2.1.1) spring-watcher-listen (2.0.1) listen (>= 2.7, < 4.0) spring (>= 1.2, < 3.0) - sprockets (4.0.2) + sprockets (4.1.1) concurrent-ruby (~> 1.0) rack (> 1, < 3) - sprockets-rails (3.4.1) + sprockets-rails (3.4.2) actionpack (>= 5.2) activesupport (>= 5.2) sprockets (>= 3.0.0) - ssrf_filter (1.0.7) + ssrf_filter (1.1.1) system_test_html_screenshots (0.2.0) actionpack (>= 5.2, < 6.1.a) - temple (0.8.2) + temple (0.9.1) terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) thor (1.1.0) thread_safe (0.3.6) - tilt (2.0.10) - tomlrb (2.0.1) - truncato (0.7.11) - htmlentities (~> 4.3.1) - nokogiri (>= 1.7.0, <= 2.0) + tilt (2.0.11) + tomlrb (2.0.3) tzinfo (1.2.9) thread_safe (~> 0.1) uber (0.1.0) - unf (0.1.4) - unf_ext - unf_ext (0.0.8) unicode-display_width (1.8.0) valid_email2 (2.3.1) activemodel (>= 3.2) mail (~> 2.5) + version_gem (1.1.1) virtus (1.0.5) axiom-types (~> 0.1) coercible (~> 1.0) @@ -796,15 +786,15 @@ GEM equalizer (~> 0.0, >= 0.0.9) virtus-multiparams (0.1.1) virtus (~> 1.0) - voting_schemes-dummy (0.21.2) + voting_schemes-dummy (0.22.3) rails (>= 5.0.0) - voting_schemes-electionguard (0.21.2) + voting_schemes-electionguard (0.22.3) rails (>= 5.0.0) w3c_rspec_validators (0.3.0) rails rspec w3c_validators - w3c_validators (1.3.6) + w3c_validators (1.3.7) json (>= 1.8) nokogiri (~> 1.6) rexml (~> 3.2) @@ -815,7 +805,7 @@ GEM activemodel (>= 6.0.0) bindex (>= 0.4.0) railties (>= 6.0.0) - webmock (3.14.0) + webmock (3.18.1) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) @@ -827,13 +817,13 @@ GEM websocket-driver (0.7.5) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) - wicked (1.3.4) + wicked (1.4.0) railties (>= 3.0.7) - wicked_pdf (2.1.0) + wicked_pdf (2.6.3) activesupport wisper (2.0.1) wisper-rspec (1.1.0) - wkhtmltopdf-binary (0.12.6.6) + wkhtmltopdf-binary (0.12.6.5) xpath (3.2.0) nokogiri (~> 1.8) zeitwerk (2.5.1) @@ -843,6 +833,7 @@ PLATFORMS DEPENDENCIES bootsnap (~> 1.4) + brakeman (~> 5.1) byebug (~> 11.0) decidim! decidim-conferences! @@ -863,7 +854,7 @@ DEPENDENCIES web-console (= 4.0.4) RUBY VERSION - ruby 2.7.1p83 + ruby 2.7.5p203 BUNDLED WITH - 2.2.18 + 2.3.5 diff --git a/README.adoc b/README.adoc index 86636ffadba86..af2273591ef9c 100644 --- a/README.adoc +++ b/README.adoc @@ -1,4 +1,4 @@ -:doctype: book +D:doctype: book image::https://cdn.rawgit.com/decidim/decidim/develop/logo.svg[Decidim Logo,400] @@ -15,7 +15,7 @@ All members of the Decidim community agree with http://www.decidim.org/contract/ ''' -image:https://img.shields.io/gem/v/decidim.svg[Gem,link=https://rubygems.org/gems/decidim] image:https://img.shields.io/gem/dt/decidim.svg[Gem,link=https://rubygems.org/gems/decidim] image:https://img.shields.io/github/contributors/decidim/decidim.svg[GitHub contributors,link=https://github.com/decidim/decidim/graphs/contributors] image:http://img.shields.io/badge/yard-docs-blue.svg[Yard Docs,link=http://rubydoc.info/github/decidim/decidim/master] image:https://img.shields.io/gitter/room/nwjs/nw.js.svg[Gitter,link=https://gitter.im/decidim/decidim] +image:https://img.shields.io/gem/v/decidim.svg[Gem,link=https://rubygems.org/gems/decidim] image:https://img.shields.io/gem/dt/decidim.svg[Gem,link=https://rubygems.org/gems/decidim] image:https://img.shields.io/github/contributors/decidim/decidim.svg[GitHub contributors,link=https://github.com/decidim/decidim/graphs/contributors] image:http://img.shields.io/badge/yard-docs-blue.svg[Yard Docs,link=http://rubydoc.info/github/decidim/decidim/master] image:https://img.shields.io/matrix/decidimdevs:matrix.org[Matrix,link=https://matrix.to/#/#decidimdevs:matrix.org] Code quality @@ -85,60 +85,29 @@ If you need to have some features that we don't have yet, we recommend that you This is a Ruby on Rails engine with some APIs specific to Decidim (for registering with the menus, integration with spaces like Participatory Processes or Assemblies, with /admin or /api, etc). As a base you can use these modules, although check first that the version is compatible with your current Decidim version. -Also you should know that until v1.0.0 We're under development and these internal APIs can change. +Also, you should know that until v1.0.0 We're under development, and these internal APIs can change. + We recommend that you extensively test your module. See https://decidim.org/modules[Modules page on Decidim.org]. === Authorizations Strategies -One specific thing regarding these kind of applications is the xref:decidim-verifications/README.adoc[authorization/verification] logic. -Here are some examples: - -- https://github.com/AjuntamentdeBarcelona/decidim-barcelona/blob/master/app/services/census_authorization_handler.rb[Barcelona (City)] -- https://github.com/AjuntamentdeCalafell/decidim-calafell/blob/master/app/services/census_authorization_handler.rb[Calafell] -- https://github.com/diputacioBCN/decidim-diba/blob/master/decidim-diba_census_api/app/services/diba_census_api_authorization_handler.rb[DIBA (Barcelona Province)] -- https://github.com/AjuntamentDeGava/decidim-gava/blob/master/app/services/census_authorization_handler.rb[Gavà] -- https://github.com/HospitaletDeLlobregat/decidim-hospitalet/blob/master/app/services/census_authorization_handler.rb[Hospitalet de Llobregat] -- https://github.com/AjMalgrat/decidim-malgrat/blob/master/app/services/carpetaciutada_handler.rb[Malgrat de Mar] -- https://github.com/AjuntamentDeMataro/decidimmataro.cat/blob/master/app/services/census_authorization_handler.rb[Mataró] -- https://github.com/ErabakiPamplona/erabaki/blob/master/app/services/census_authorization_handler.rb[Pamplona] -- https://github.com/AjuntamentdeReus/decidim/blob/master/app/services/census_authorization_handler.rb[Reus] -- https://github.com/AjuntamentDeSabadell/decidim-sabadell/blob/master/app/services/census_authorization_handler.rb[Sabadell] -- https://github.com/AjuntamentdeSantCugat/decidim-sant_cugat/blob/master/app/services/census_authorization_handler.rb[Sant Cugat] -- https://github.com/AjuntamentDeTerrassa/decidim-terrassa/blob/master/app/services/census_authorization_handler.rb[Terrassa] -- https://github.com/vilanovailageltru/decidim-vilanova/blob/master/app/services/vilanova_authorization_handler.rb[Vilanova i la Geltrú] - -Other special verifications: - -- https://github.com/podemos-info/participa2/tree/master/decidim-module-census_connector[Podemos] -- https://github.com/ElectricThings/fund_action/blob/master/app/services/anybody_authorization_handler.rb[FundAction] -- https://github.com/CodiTramuntana/decidim-verifications-csv_emails[CSV emails] -- https://github.com/mainio/decidim-module-access_requests[Access Requests] +One specific thing regarding these kind of applications is the authorization or verification logic. This tries to solve the problem of how to verify that the user is who they say they are and that they have the right to participate in this city or organization. Read more about https://docs.decidim.org/en/customize/authorizations/[Authorizations] in our documentation. == Following our license -If you plan to release your application you'll need to publish it using the same license: GPL Affero 3. -We recommend doing that on GitHub before publishing, you can read more on "http://producingoss.com/en/governments-and-open-source.html#starting-open-for-govs[Being Open Source From Day One is Especially Important for Government Projects]". -If you have any trouble you can contact us on https://gitter.im/decidim/decidim[Gitter]. +If you plan to put your application in production, you'll need to publish it using the same license: GPL Affero 3. + +We recommend doing that on GitHub (or any other code hosting platform) before publishing. + +You can read more on "http://producingoss.com/en/governments-and-open-source.html#starting-open-for-govs[Being Open Source From Day One is Especially Important for Government Projects]". + +If you have any trouble you can contact us on https://app.element.io/#/room/#decidimdevs:matrix.org[our Matrix.org chat room for developers]. == Example applications -Since Decidim is a ruby gem, you can check out the https://github.com/decidim/decidim/network/dependents?type=application[dependent repositories] to see how many applications are on the wild or tests that other developers have made. -Here's a partial list with some of the projects that have used Decidim: - -- http://staging.decidim.codegram.com[Demo] -- https://decidim.barcelona[Decidim Barcelona] - https://github.com/AjuntamentdeBarcelona/decidim-barcelona[View code] -- https://www.lhon-participa.cat[L'H ON Participa] - https://github.com/HospitaletDeLlobregat/decidim-hospitalet[View code] -- https://participa.terrassa.cat[Decidim Terrassa] - https://github.com/AjuntamentDeTerrassa/decidim-terrassa[View code] -- https://decidim.sabadell.cat[Decidim Sabadell] - https://github.com/AjuntamentDeSabadell/decidim-sabadell[View code] -- https://participa.gavaciutat.cat[Decidim Gavà] - https://github.com/AjuntamentDeGava/decidim-gava[View code] -- https://dialogluzern.ch[Dialog Luzern] - https://github.com/stadtluzern/decidim-ocl[View code] -- https://decidim.santcugat.cat/[Decidim Sant Cugat] - https://github.com/AjuntamentdeSantCugat/decidim-sant_cugat[View code] -- http://participa.vilanova.cat[Vilanova Participa] - https://github.com/vilanovailageltru/decidim-vilanova[View code] -- https://erabaki.pamplona.es[Erabaki Pamplona] - https://github.com/ErabakiPamplona/erabaki[View code] -- https://www.decidimmataro.cat[Decidim Mataró] - https://github.com/AjuntamentDeMataro/decidim-mataro[View code] -- https://meta.decidim.barcelona/[MetaDecidim] - https://github.com/decidim/metadecidim[View Code] +Since Decidim is a ruby gem, you can check out the https://github.com/decidim/decidim/network/dependents?type=application[dependent repositories] to see how many applications are on the wild or tests that other developers have made. You can see a highlight of https://docs.decidim.org/en/develop/guide_example_apps/[example applications] in our documentation. == Security diff --git a/Rakefile b/Rakefile index 7bb0cf9df3e5c..51ef610b05a3a 100644 --- a/Rakefile +++ b/Rakefile @@ -57,17 +57,36 @@ task :uninstall_all do end desc "Pushes a new build for each gem and package." -task release_all: [:update_versions, :check_locale_completeness] do - Decidim::GemManager.run_all("rake release") - Decidim::GemManager.run_packages("npm publish --access public") +task release_all: [:update_versions, :check_uncommitted_changes, :check_locale_completeness] do + commands = {} + Decidim::GemManager.all_dirs { |dir| commands[dir] = "rake release" } + Decidim::GemManager.package_dirs { |dir| commands[dir] = "npm publish --access public" } + + commands.each do |dir, command| + status = Decidim::GemManager.run_at(dir, command) + + break if !status && Decidim::GemManager.fail_fast? + end +end + +desc "Makes sure there are no uncommitted changes." +task :check_uncommitted_changes do + unless system("git diff --exit-code --quiet") + puts "There are uncommitted changes, run `git diff` to see them." + abort "Please commit your changes before release!" + end end desc "Makes sure all official locales are complete and clean." task :check_locale_completeness do - system({ "ENFORCED_LOCALES" => "en,ca,es", "SKIP_NORMALIZATION" => "true" }, "rspec spec/i18n_spec.rb") + unless system({ "ENFORCED_LOCALES" => "en,ca,es", "SKIP_NORMALIZATION" => "true" }, "rspec spec/i18n_spec.rb") + puts "The officially supported locales have problems in them." + abort "Please correct these problems by following the instructions from the above outputs before release!" + end end load "decidim-dev/lib/tasks/generators.rake" +load "lib/tasks/common_passwords_tasks.rake" desc "Generates a dummy app for testing" task test_app: "decidim:generate_external_test_app" diff --git a/SECURITY.adoc b/SECURITY.adoc index 4b94f3e5313e6..5976fd090631a 100644 --- a/SECURITY.adoc +++ b/SECURITY.adoc @@ -7,10 +7,10 @@ Until we have the version 1.0 we support only the last minor and major version w |=== | Version | Supported -| 0.24.x +| 0.25.x | :white_check_mark: -| \<= 0.23 +| \<= 0.24 | :x: |=== @@ -26,5 +26,5 @@ To download our key: [source,bash] ---- -gpg --keyserver pgp.key-server.io --recv 84B935C4 +gpg --keyserver pgp.mit.edu --recv 84B935C4 ---- diff --git a/bin/changelog_generator b/bin/changelog_generator index 0b3c1e0d389ae..837a82847d55a 100755 --- a/bin/changelog_generator +++ b/bin/changelog_generator @@ -117,6 +117,10 @@ types = { label: "type: removal", skip_modules: false }, + "Internal" => { + label: "type: internal", + skip_modules: true + }, "Developer improvements" => { label: "target: developer-experience", skip_modules: true diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml index de9e13f1a9224..2d6367dcd2106 100644 --- a/config/i18n-tasks.yml +++ b/config/i18n-tasks.yml @@ -121,6 +121,7 @@ ignore_unused: - activerecord.models.* - booleans.* - '{date,time.formats}.*' + - datetime.distance_in_words.* - decidim.admin.participatory_process_steps.default_title - decidim.authorization_handlers.{direct,multistep} - decidim.admin.models.assembly_member.positions.* @@ -164,6 +165,7 @@ ignore_unused: - decidim.accountability.models.project.valid_statuses.* - decidim.accountability.admin_log.* - decidim.elections.admin_log.* + - decidim.elections.connection.failed.* - decidim.elections.orders.* - decidim.elections.election_m.* - decidim.proposals.admin_log.* @@ -304,7 +306,17 @@ ignore_unused: - decidim.admin.menu.questions_submenu.attachments - decidim.admin.menu.questions_submenu.categories - decidim.meetings.public_participants_list.hidden_participants_count.* - + - decidim.budgets.budgets_list.* + - decidim.budgets.projects.project_budget_button.* + - decidim.meetings.meetings.show.withdraw_btn_hint + - decidim.meetings.meetings.show.withdraw_confirmation_html + - decidim.meetings.meetings.show.withdraw_meeting + - decidim.proposals.proposals.show.withdraw_btn_hint + - decidim.proposals.proposals.show.withdraw_confirmation_html + - decidim.proposals.proposals.show.withdraw_proposal + - decidim.assemblies.admin.assembly_members.form.explanation + - decidim.assemblies.admin.assembly_members.form.image_guide + - decidim.assemblies.admin.assembly_members.form.non_user_avatar_help ## Exclude these keys from the `i18n-tasks eq-base' report: # ignore_eq_base: diff --git a/crowdin.yaml b/crowdin.yaml index bf1aab7ee4503..c8ec1bce62c2f 100644 --- a/crowdin.yaml +++ b/crowdin.yaml @@ -36,8 +36,9 @@ files: nl: nl no: no pl: pl - pt-BR: pt-BR + pt: pt pt-PT: pt + pt-BR: pt-BR ro-RO: ro rumany: ru sk: sk diff --git a/decidim-accountability/app/packs/images/decidim/accountability/decidim_accountability_icon.svg b/decidim-accountability/app/packs/images/decidim/accountability/decidim_accountability.svg similarity index 100% rename from decidim-accountability/app/packs/images/decidim/accountability/decidim_accountability_icon.svg rename to decidim-accountability/app/packs/images/decidim/accountability/decidim_accountability.svg diff --git a/decidim-accountability/app/packs/stylesheets/decidim/accountability/accountability/_categories.scss b/decidim-accountability/app/packs/stylesheets/decidim/accountability/accountability/_categories.scss index 29d631348818f..31f8cdf95d036 100644 --- a/decidim-accountability/app/packs/stylesheets/decidim/accountability/accountability/_categories.scss +++ b/decidim-accountability/app/packs/stylesheets/decidim/accountability/accountability/_categories.scss @@ -1,7 +1,6 @@ .accountability{ .categories{ a:hover{ - background-color: var(--secondary); text-decoration: underline; } @@ -69,7 +68,7 @@ .card__link{ .category--line{ - background-color: var(--secondary); + background-color: $light-gray-dark; border-radius: 4px; min-height: 9rem; padding: 1rem; diff --git a/decidim-accountability/app/permissions/decidim/accountability/admin/permissions.rb b/decidim-accountability/app/permissions/decidim/accountability/admin/permissions.rb index f30b8aec5c497..d673e9f7d5f8e 100644 --- a/decidim-accountability/app/permissions/decidim/accountability/admin/permissions.rb +++ b/decidim-accountability/app/permissions/decidim/accountability/admin/permissions.rb @@ -30,9 +30,10 @@ def timeline_entry def can_perform_actions_on?(subject, resource) return unless permission_action.subject == subject + return false if can_create_grandchildren_results? case permission_action.action - when :create + when :create, :create_children true when :update, :destroy resource.present? @@ -40,6 +41,11 @@ def can_perform_actions_on?(subject, resource) false end end + + def can_create_grandchildren_results? + result&.parent&.present? && + permission_action.action == :create_children + end end end end diff --git a/decidim-accountability/app/views/decidim/accountability/admin/import_results/new.html.erb b/decidim-accountability/app/views/decidim/accountability/admin/import_results/new.html.erb index 314b389e4a0ee..236fdb601a440 100644 --- a/decidim-accountability/app/views/decidim/accountability/admin/import_results/new.html.erb +++ b/decidim-accountability/app/views/decidim/accountability/admin/import_results/new.html.erb @@ -7,6 +7,13 @@
+
+

<%= t(".info", + link_new_status: new_status_path, + link_new_result: new_result_path, + link_export_csv: link_to(t(".download_export"),exports_path(current_component, id: "results", format: "CSV"), method: :post) + ).try("html_safe") %>

+
<%= file_field_tag :csv_file %>
@@ -16,7 +23,4 @@
<%= submit_tag t(".import"), class: "button" %>
-
- <%= t(".info", link_new_status: new_status_path, link_new_result: new_result_path, link_export_csv: link_to(t(".link"), exports_path(current_component, id: "results", format: "CSV"), method: :post)).try("html_safe") %> -
<% end %> diff --git a/decidim-accountability/app/views/decidim/accountability/admin/results/index.html.erb b/decidim-accountability/app/views/decidim/accountability/admin/results/index.html.erb index a814b409c4d43..967ed96a23601 100644 --- a/decidim-accountability/app/views/decidim/accountability/admin/results/index.html.erb +++ b/decidim-accountability/app/views/decidim/accountability/admin/results/index.html.erb @@ -74,7 +74,7 @@ <%= icon_link_to "eye", resource_locator(result).path, t("actions.preview", scope: "decidim.accountability"), class: "action-icon--preview", target: :blank %> - <% if allowed_to? :update, :result, result: result %> + <% if allowed_to? :create_children, :result, result: result %> <%= icon_link_to "plus", results_path(parent_id: result.id), t("actions.new", scope: "decidim.accountability", name: t("models.result.name", scope: "decidim.accountability.admin")), class: "action-icon--plus" %> <% end %> diff --git a/decidim-accountability/app/views/decidim/accountability/admin/timeline_entries/index.html.erb b/decidim-accountability/app/views/decidim/accountability/admin/timeline_entries/index.html.erb index ea442c2c133ae..644d544c96c8f 100644 --- a/decidim-accountability/app/views/decidim/accountability/admin/timeline_entries/index.html.erb +++ b/decidim-accountability/app/views/decidim/accountability/admin/timeline_entries/index.html.erb @@ -20,7 +20,7 @@ <% timeline_entries.each do |timeline_entry| %> - <%= timeline_entry.entry_date %>
+ <%= l timeline_entry.entry_date, format: :decidim_short %>
<%= translated_attribute(timeline_entry.description) %> <% if allowed_to? :update, :timeline_entry, timeline_entry: timeline_entry %> diff --git a/decidim-accountability/app/views/decidim/accountability/results/_results_leaf.html.erb b/decidim-accountability/app/views/decidim/accountability/results/_results_leaf.html.erb index 091f418970a93..5a3408b8b47c5 100644 --- a/decidim-accountability/app/views/decidim/accountability/results/_results_leaf.html.erb +++ b/decidim-accountability/app/views/decidim/accountability/results/_results_leaf.html.erb @@ -1,7 +1,7 @@
-

+

<%= heading_leaf_level_results(total_count) %> -

+
@@ -19,12 +19,12 @@
<% if result.start_date %> <%= t("models.result.fields.start_date", scope: "decidim.accountability") %> - <%= result.start_date %> + <%= l result.start_date, format: :decidim_short %> <% end %> <% if result.end_date %> <%= t("models.result.fields.end_date", scope: "decidim.accountability") %> - <%= result.end_date %> + <%= l result.end_date, format: :decidim_short %> <% end %> <% if result.status %> diff --git a/decidim-accountability/app/views/decidim/accountability/results/_show_leaf.html.erb b/decidim-accountability/app/views/decidim/accountability/results/_show_leaf.html.erb index 49299056588af..e66e8f7c03085 100644 --- a/decidim-accountability/app/views/decidim/accountability/results/_show_leaf.html.erb +++ b/decidim-accountability/app/views/decidim/accountability/results/_show_leaf.html.erb @@ -31,14 +31,14 @@
<% if result.start_date %>
<%= t("models.result.fields.start_date", scope: "decidim.accountability") %>
-
<%= result.start_date %>
+
<%= l result.start_date, format: :decidim_short %>
<% end %>
<% if result.end_date %>
<%= t("models.result.fields.end_date", scope: "decidim.accountability") %>
-
<%= result.end_date %>
+
<%= l result.end_date, format: :decidim_short %>
<% end %>
diff --git a/decidim-accountability/app/views/decidim/accountability/results/_timeline.html.erb b/decidim-accountability/app/views/decidim/accountability/results/_timeline.html.erb index 0f975caab877b..b4408a38d0db6 100644 --- a/decidim-accountability/app/views/decidim/accountability/results/_timeline.html.erb +++ b/decidim-accountability/app/views/decidim/accountability/results/_timeline.html.erb @@ -10,7 +10,7 @@
- <%= timeline_entry.entry_date %> + <%= l timeline_entry.entry_date, format: :decidim_short %>

<%= translated_attribute timeline_entry.description %> diff --git a/decidim-accountability/app/views/decidim/participatory_spaces/_result.html.erb b/decidim-accountability/app/views/decidim/participatory_spaces/_result.html.erb index 5c4bb0b36b5bd..3a4aea23b83f2 100644 --- a/decidim-accountability/app/views/decidim/participatory_spaces/_result.html.erb +++ b/decidim-accountability/app/views/decidim/participatory_spaces/_result.html.erb @@ -9,12 +9,12 @@
<% if result.start_date %> <%= t("models.result.fields.start_date", scope: "decidim.accountability") %> - <%= result.start_date %> + <%= l result.start_date, format: :short %> <% end %> <% if result.end_date %> <%= t("models.result.fields.end_date", scope: "decidim.accountability") %> - <%= result.end_date %> + <%= l result.end_date, format: :short %> <% end %> <% if result.status %> diff --git a/decidim-accountability/config/locales/ar.yml b/decidim-accountability/config/locales/ar.yml index f97e909767858..8a12578600339 100644 --- a/decidim-accountability/config/locales/ar.yml +++ b/decidim-accountability/config/locales/ar.yml @@ -53,8 +53,6 @@ ar: import_results: new: import: استيراد - info: "

نحن ننصح باتباع هذه الخطوات:

\n
    \n
  1. قم بإنشاء حالات النتائج التي تريد إضافتها (الرابط)
  2. \n
  3. قم بإنشاء نتيجة واحدة على الأقل يدويًا من خلال لوحة المدير هذه (link) قبل أستخدام الاستيراد, للحصول على فهم أفضل للتنسيق وما ستحتاج لملئه.
  4. \n
  5. قم بتنزيل التصدير بتنسيق CSV(%{link_export_csv})
  6. \n
  7. قم بإجراء التغييرات محليًا على جهازك. يمكنك فقط تغيير الأعمدة التالية من ملف CSV:
  8. \n
\n
    \n
  • category/id:رقم مٌعرف للفئه
  • \n
  • scope/id:رقم مٌعرف للمجال
  • \n
  • parent/id: رقم مٌعرف بالأب (للنتائج ذات الصلة). اختياري
  • \n
  • title/I18N: عنوان اللغه
  • \n
  • description/I18N: وصف اللغه
  • \n
  • start_date:التاريخ الذي يبدأ فيه تنفيذ النتيجة (التنسيق YYYY-MM-DD)
  • \n
  • end_date: التاريخ الذي ينتهى فيه تنفيذ النتيجة (التنسيق YYYY-MM-DD
  • \n
  • status/id: رقم مٌعرف لحالة النتيجة
  • \n
  • progress: النسبة المئوية (من 0 الى 100) للتنفيذ
  • \n
  • proposals_ids: رقم مُعرف داخلى للمقترحات ذات الصلة (مفصولاً بفاصلة). يتم تحويله تلقائيًا إلى رابط للمقترح
  • \n
" - link: الرابط title: استيراد النتائج من ملف CSV imports: create: diff --git a/decidim-accountability/config/locales/bg.yml b/decidim-accountability/config/locales/bg.yml index 4d6262d32dd70..7bbc56a63dc51 100644 --- a/decidim-accountability/config/locales/bg.yml +++ b/decidim-accountability/config/locales/bg.yml @@ -46,8 +46,6 @@ bg: import_results: new: import: Внасяне - info: "

Препоръчваме ви да изпълните следните стъпки:

  1. Създайте статусите на резултатите, които искате да добавите (връзка)
  2. Създайте поне един Резултат ръчно чрез администраторския панел (връзка), преди да използвате Импортиране, за с по-добро разбиране на формата и това, което ще трябва да попълните.
  3. Изтеглете експортиране с CSV формат (%{link_export_csv})
  4. Направете промените локално. Можете да промените само следните колони от CSV:
  • категория/id: ID за категорията
  • обхват/id:ИД за обхвата
  • родител / id: ID на родителя (за свързани резултати). Незадължително
  • заглавие/I18N:Заглавие на езика X
  • описание/I18N Описание на X език
  • < li>начало_дата:дата, когато резултатът стартира изпълнението (формат ГГГГ-ММ-DD)
  • край_ дата:дата, когато резултатът приключи изпълнението (формат ГГГГ-MM-DD)
  • status/id:ID на състоянието за този резултат
  • прогрес:Процент (от 0 до 100) на изпълнението
  • offers_ids:вътрешен ID на свързаните предложения (разделени със запетая). Той автоматично се преобразува в предложение_url
" - link: връзка title: Импортирай резултати от CSV imports: create: diff --git a/decidim-accountability/config/locales/ca.yml b/decidim-accountability/config/locales/ca.yml index 378a47977b396..b38227b35e454 100644 --- a/decidim-accountability/config/locales/ca.yml +++ b/decidim-accountability/config/locales/ca.yml @@ -48,9 +48,29 @@ ca: results: Resultats import_results: new: + download_export: Descarregar l'exportació en format CSV import: Importar - info: "

Et recomanem que segueixis les passes següents:

  1. Crea els estats per als resultats que vulguis afegir (link)
  2. Crea com a mínim un resultat manualment a través del taulell d'administració (link) abans d'importar, per a entendre millor el format i com cal omplir-ho.
  3. Descarrega l'arxiu en format CSV(%{link_export_csv})
  4. Fes els canvis en local. Només pots modificar les següents columnes del CSV:
  • id category/id: ID per la categoria
  • scope/id: ID per a l'àmbit
  • parent/id: ID per al pare (per a resultats relacionats). Opcional
  • title/I18N: Title en la llengua X
  • description/I18N: Descripció en la lleguna X
  • start_date: data en la que s'inicia l'execució del resultat (format YYYY-MM-DD)
  • end_date: data en la que finalitza l'execució del resultat (format YYYY-MM-DD)
  • status/id: ID de l'estat per a aquest resultat
  • progress: Tant per cent (de 0 a 100) d'execució
  • proposals_ids: ID intern de les propostes relacionades (separades per comes). Es convertirà automàticament en proposal_url
" - link: enllaç + info: | +

Et recomanem que segueixis les passes següents:

+
    +
  1. Crea els estats per als resultats que vulguis afegir
  2. +
  3. Crea com a mínim un resultat manualment a través del taulell d'administració abans d'importar, per a entendre millor el format i com cal omplir-ho.
  4. +
  5. %{link_export_csv}
  6. +
  7. Fes els canvis en local. Només pots modificar les següents columnes del CSV: +
      +
    • id category/id: ID per la categoria
    • +
    • scope/id: ID per a l'àmbit
    • +
    • parent/id: ID per al pare (per a resultats relacionats). Opcional
    • +
    • title/I18N: Title en la llengua X
    • +
    • description/I18N: Descripció en la lleguna X
    • +
    • start_date: data en la que s'inicia l'execució del resultat (format YYYY-MM-DD)
    • +
    • end_date: data en la que finalitza l'execució del resultat (format YYYY-MM-DD)
    • +
    • status/id: ID de l'estat per a aquest resultat
    • +
    • progress: Tant per cent (de 0 a 100) d'execució
    • +
    • proposals_ids: ID intern de les propostes relacionades (separades per comes). Es convertirà automàticament en proposal_url
    • +
    +
  8. +
title: Importar resultats via CSV imports: create: diff --git a/decidim-accountability/config/locales/cs.yml b/decidim-accountability/config/locales/cs.yml index 75fcf8a4352ef..07d8f7a8899ff 100644 --- a/decidim-accountability/config/locales/cs.yml +++ b/decidim-accountability/config/locales/cs.yml @@ -50,9 +50,8 @@ cs: results: Výsledky import_results: new: + download_export: Stáhnout export s CSV formátem import: Importovat - info: "

Doporučujeme postupovat podle těchto kroků:

  1. Vytvořte stavy pro výsledky, které chcete přidat (odkaz)
  2. Vytvořte alespoň jeden výsledek ručně přes tento Admin panel (odkaz) před použitím Importu, pro lepší pochopení formátu a toho, co budete muset vyplnit.
  3. Stáhněte si export s CSV formátem (%{link_export_csv})
  4. Proveďte změny lokálně. Následující sloupce CSV:
  • kategorie / id: ID pro kategorii
  • rozsah / id: ID pro rozsah
  • nadřazené / id: ID nadřazených (pro související výsledky). Nepovinný
  • název / I18N: Název jazyka X
  • popis / I18N: Popis jazyka X
  • start_date: datum, kdy výsledek začne provádět (formát YYYY-MM-DD)
  • end_date: den, kdy výsledek končí provedení (formát YYYY-MM-DD)
  • status / id: ID stavu pro tento výsledek
  • pokrok: procenta (od 0 do 100) provedení
  • proposals_ids: interní ID souvisejících návrhů (oddělené čárkou). Automaticky se převede na proposal_url
" - link: odkaz title: Importovat výsledky z CSV imports: create: diff --git a/decidim-accountability/config/locales/da.yml b/decidim-accountability/config/locales/da.yml index 2f80fe6d42c07..245d5875cca62 100644 --- a/decidim-accountability/config/locales/da.yml +++ b/decidim-accountability/config/locales/da.yml @@ -46,8 +46,6 @@ da: import_results: new: import: Import - info: "

Vi anbefaler, at du følger disse trin:

  1. Opret status for de resultater, du ønsker at tilføje (link)
  2. Opret mindst ét resultat manuelt via dette administrationspanel (link) før brug af import for at få en bedre forståelse af formatet, og hvad du har brug for til at udfylde det.
  3. Download eksporten som CSV-format (%{link_export_csv})
  4. Lav ændringerne lokalt. Du kan kun ændre følgende kolonner i CSV’et:
  • category/id: ID for kategorien
  • scope/id: ID for anvendelsesområde
  • parent/id: ID for forælder(tilknyttede resultater). Valgfrit
  • title/I18N: Titel for X-sprog
  • description/I18N: Beskrivelse på X-sprog
  • dato, hvor resultatet begynder med at blive gennemført (format YYYY-MM-DD)
  • slutdato: dato, hvor gennemførelsen af resultatet afsluttes (format YYYY-MM-DD)
  • status/id: ID for status for dette resultat
  • fremskridt: procentandel (fra 0 til 100) for gennemførelsen
  • proposals_ids: internt ID for de tilknyttede forslag (adskilt med et komma). Den konverteres automatisk til proposal_url
" - link: link title: Importresultater fra CSV imports: create: diff --git a/decidim-accountability/config/locales/de.yml b/decidim-accountability/config/locales/de.yml index 0064addbd1133..9e008a3b7f868 100644 --- a/decidim-accountability/config/locales/de.yml +++ b/decidim-accountability/config/locales/de.yml @@ -49,8 +49,6 @@ de: import_results: new: import: Importieren - info: "

Wir empfehlen, dass Sie folgende Schritte befolgen:

  1. Erstellen Sie den Status der Ergebnisse, die Sie hinzufügen möchten (link)
  2. Erstellen Sie mindestens ein Ergebnis über diesen Administrator-Panel (link) bevor Sie Importieren, damit Sie mit dem Format und den benötigten Eingaben vertraut sind.
  3. Laden Sie den Export im CSV-Format herunter (%{link_export_csv})
  4. Nehmen Sie Änderungen lokal vor. Sie können nur die folgenden Spalten der CSV ändern:
  • Kategorie/ID: ID der Kategorie
  • Umfang/ID: ID des Umfangs
  • Übergeordnet/ID: Übergeordnete ID (für verwandte Ergebnisse). Optional
  • Titel/I18N: Titel in Sprache X
  • Beschreibung/I18N: Beschreibung in Sprache X
  • start_datum: Datum, an dem die Ausführung des Ergebnisses beginnt (Format JJJJ-MM-TT)
  • end_datum: Datum, an dem die Ausführung des Ergebnisses endet (Format JJJJ-MM-TT)
  • Status/ID: ID des Status dieses Ergebnisses
  • Fortschritt: Prozentualer (von 0 bis 100) Fortschritt der Durchführung
  • Vorschläge_IDs: Interne ID der verwandten Vorschläge (getrennt durch Komma). Dies wird automatisch umgewandelt in proposal_url
" - link: Verknüpfung title: Ergebnisse von CSV importieren imports: create: diff --git a/decidim-accountability/config/locales/el.yml b/decidim-accountability/config/locales/el.yml index ca5549a49d2f9..c669b1e6f88f3 100644 --- a/decidim-accountability/config/locales/el.yml +++ b/decidim-accountability/config/locales/el.yml @@ -49,8 +49,6 @@ el: import_results: new: import: Εισαγωγή - info: "

Σας συνιστούμε να ακολουθήσετε αυτά τα βήματα:

  1. Δημιουργήστε τις Καταστάσεις για τα Αποτελέσματα που θέλετε να προσθέσετε (link)
  2. Δημιουργήστε τουλάχιστον ένα Αποτέλεσμα χειροκίνητα μέσω αυτού του Πίνακα διαχειριστή (link), προτού χρησιμοποιήσετε την Εισαγωγή, προκειμένου να κατανοήσετε καλύτερα τη μορφή και τα στοιχεία που πρέπει να συμπληρώσετε.
  3. Πραγματοποιήστε λήψη της Εξαγωγής σε μορφή CSV (%{link_export_csv})
  4. Πραγματοποιήστε τις αλλαγές τοπικά. Μπορείτε να αλλάξετε μόνο τις παρακάτω στήλες του CSV:
  • κατηγορία/αναγνωριστικό: Αναγνωριστικό για την Κατηγορία
  • πεδίο εφαρμογής/αναγνωριστικό: Αναγνωριστικό για το Πεδίο εφαρμογής
  • γονικό στοιχείο/αναγνωριστικό: Αναγνωριστικό για το γονικό στοιχείο (για σχετικά Αποτελέσματα). Προαιρετικά
  • τίτλος/I18N: Τίτλος στη γλώσσα X
  • περιγραφή/I18N: Περιγραφή στη γλώσσα X
  • ημερομηνία_έναρξης: ημερομηνία κατά την οποία το αποτέλεσμα ξεκινά την εκτέλεση (μορφή ΕΕΕΕ-ΜΜ-ΗΗ)
  • ημερομηνία_λήξης: ημερομηνία κατά την οποία το αποτέλεσμα ολοκληρώνει την εκτέλεση (μορφή ΕΕΕΕ-ΜΜ-ΗΗ)
  • κατάσταση/αναγνωριστικό: Αναγνωριστικό της Κατάστασης αυτού του αποτελέσματος
  • πρόοδος: Ποσοστό (από 0 έως 100) της εκτέλεσης
  • αναγνωριστικά_προτάσεων: εσωτερικό αναγνωριστικό των σχετικών προτάσεων (διαχωρισμένων με κόμμα). Μετατρέπεται αυτόματα σε url_πρότασης
" - link: σύνδεσμος title: Εισαγωγή αποτελεσμάτων από αρχείο CSV imports: create: diff --git a/decidim-accountability/config/locales/en.yml b/decidim-accountability/config/locales/en.yml index 419226530b006..abd1bf725ca9d 100644 --- a/decidim-accountability/config/locales/en.yml +++ b/decidim-accountability/config/locales/en.yml @@ -49,9 +49,29 @@ en: results: Results import_results: new: + download_export: Download the Export with CSV format import: Import - info: "

We recommend that you follow these steps:

  1. Create the Statuses for the Results that you want to add (link)
  2. Create at least one Result manually through this Admin panel (link) before using Import, for having a better understanding of the format and what you'll need to fill out.
  3. Download the Export with CSV format (%{link_export_csv})
  4. Make the changes locally. You can only change the following columns of the CSV:
  • category/id: ID for the Category
  • scope/id: ID for the Scope
  • parent/id: ID of the parent (for related Results). Optional
  • title/I18N: Title on X language
  • description/I18N: Description on X language
  • start_date: date when the result starts execution (format YYYY-MM-DD)
  • end_date: date when the result ends execution (format YYYY-MM-DD)
  • status/id: ID of the Status for this result
  • progress: Percentage (from 0 to 100) of the execution
  • proposals_ids: internal ID of the related proposals (separated with a comma). It gets automatically converted to proposal_url
" - link: link + info: | +

We recommend that you follow these steps:

+
    +
  1. Create the Statuses for the Results that you want to add
  2. +
  3. Create at least one Result manually through this Admin panel before using Import, for having a better understanding of the format and what you'll need to fill out.
  4. +
  5. %{link_export_csv}
  6. +
  7. Make the changes locally. You can only change the following columns of the CSV: +
      +
    • category/id: ID for the Category
    • +
    • scope/id: ID for the Scope
    • +
    • parent/id: ID of the parent (for related Results). Optional
    • +
    • title/en: Title on English language. This will depend on your platform language configuration.
    • +
    • description/en: Description on English language. This will depend on your platform language configuration.
    • +
    • start_date: date when the result starts execution (format YYYY-MM-DD)
    • +
    • end_date: date when the result ends execution (format YYYY-MM-DD)
    • +
    • status/id: ID of the Status for this result
    • +
    • progress: Percentage (from 0 to 100) of the execution
    • +
    • proposals_ids: internal ID of the related proposals (separated with a comma). It gets automatically converted to proposal_url
    • +
    +
  8. +
title: Import results from CSV imports: create: diff --git a/decidim-accountability/config/locales/es-MX.yml b/decidim-accountability/config/locales/es-MX.yml index 8754980db4e27..452a98514aab6 100644 --- a/decidim-accountability/config/locales/es-MX.yml +++ b/decidim-accountability/config/locales/es-MX.yml @@ -48,9 +48,29 @@ es-MX: results: Resultados import_results: new: + download_export: Descargar la exportación con formato CSV import: Importar - info: "

Te recomendamos que sigas los siguientes pasos:

  1. Crea los estados para los resultados que quieras agregar ( link )
  2. Crea por lo menos un resultado manualmente a través del panel de administración (link) antes de importar, para entender mejor el formato y cómo rellenarlo.
  3. Descarga el archivo en formato CSV (%{link_export_csv})
  4. Haz los cambios en local. Sólo puedes modificar las siguientes columnas del CSV:
  • id category /id: ID para la categoría
  • scope /id: ID para el ámbito
  • parent /id: ID para el padre (para resultados relacionados). Opcional
  • title /I18N: título en la lengua X
  • description /I18N: descripción en la lleguna X
  • start_date: date en la que se inicia la ejecución del resultado (formato AAAA-MM-DD)
  • end_date: fecha en la que finaliza la ejecución del resultado (formato AAAA-MM-DD)
  • status /id: ID del estado para este resultado
  • progress: Tanto por ciento (de 0 a 100) de ejecución
  • proposals_ids: ID interno de las propuestas relacionadas (separadas por comas). Se convertirá automáticamente en proposal_url
" - link: enlace + info: | +

Te recomendamos que sigas los siguientes pasos:

+
    +
  1. Crea los estados para los resultados que quieras agregar
  2. +
  3. Crea por lo menos un resultado manualmente a través del panel de administración antes de importar, para entender mejor el formato y cómo rellenarlo.
  4. +
  5. %{link_export_csv}
  6. +
  7. Haz los cambios en local. Sólo puedes modificar las siguientes columnas del CSV: +
      +
    • id category/id: ID para la categoría
    • +
    • scope/id: ID para el ámbito
    • +
    • parent/id: ID para el padre (para resultados relacionados). Opcional
    • +
    • title/I18N: título en el idioma X
    • +
    • description/I18N: descripción en el idioma X
    • +
    • start_date: fecha en la que se inicia la ejecución del resultado (formato AAAA-MM-DD)
    • +
    • end_date: fecha en la que finaliza la ejecución del resultado (formato AAAA-MM-DD)
    • +
    • status/id: ID del estado para este resultado
    • +
    • progress: Tanto por ciento (de 0 a 100) de ejecución
    • +
    • proposals_ids: ID interno de las propuestas relacionadas (separadas por comas). Se convertirá automáticamente en proposal_url
    • +
    +
  8. +
title: Importa resultados vía CSV imports: create: diff --git a/decidim-accountability/config/locales/es-PY.yml b/decidim-accountability/config/locales/es-PY.yml index 9f97192902857..ac438bcc13dc0 100644 --- a/decidim-accountability/config/locales/es-PY.yml +++ b/decidim-accountability/config/locales/es-PY.yml @@ -48,9 +48,29 @@ es-PY: results: Resultados import_results: new: + download_export: Descargar la exportación con formato CSV import: Importar - info: "

Te recomendamos que sigas los siguientes pasos:

  1. Crea los estados para los resultados que quieras agregar ( link )
  2. Crea por lo menos un resultado manualmente a través del panel de administración (link) antes de importar, para entender mejor el formato y cómo rellenarlo.
  3. Descarga el archivo en formato CSV (%{link_export_csv})
  4. Haz los cambios en local. Sólo puedes modificar las siguientes columnas del CSV:
  • id category /id: ID para la categoría
  • scope /id: ID para el ámbito
  • parent /id: ID para el padre (para resultados relacionados). Opcional
  • title /I18N: título en la lengua X
  • description /I18N: descripción en la lleguna X
  • start_date: date en la que se inicia la ejecución del resultado (formato AAAA-MM-DD)
  • end_date: fecha en la que finaliza la ejecución del resultado (formato AAAA-MM-DD)
  • status /id: ID del estado para este resultado
  • progress: Tanto por ciento (de 0 a 100) de ejecución
  • proposals_ids: ID interno de las propuestas relacionadas (separadas por comas). Se convertirá automáticamente en proposal_url
" - link: enlace + info: | +

Te recomendamos que sigas los siguientes pasos:

+
    +
  1. Crea los estados para los resultados que quieras agregar
  2. +
  3. Crea por lo menos un resultado manualmente a través del panel de administración antes de importar, para entender mejor el formato y cómo rellenarlo.
  4. +
  5. %{link_export_csv}
  6. +
  7. Haz los cambios en local. Sólo puedes modificar las siguientes columnas del CSV: +
      +
    • id category/id: ID para la categoría
    • +
    • scope/id: ID para el ámbito
    • +
    • parent/id: ID para el padre (para resultados relacionados). Opcional
    • +
    • title/I18N: título en el idioma X
    • +
    • description/I18N: descripción en el idioma X
    • +
    • start_date: fecha en la que se inicia la ejecución del resultado (formato AAAA-MM-DD)
    • +
    • end_date: fecha en la que finaliza la ejecución del resultado (formato AAAA-MM-DD)
    • +
    • status/id: ID del estado para este resultado
    • +
    • progress: Tanto por ciento (de 0 a 100) de ejecución
    • +
    • proposals_ids: ID interno de las propuestas relacionadas (separadas por comas). Se convertirá automáticamente en proposal_url
    • +
    +
  8. +
title: Importa resultados vía CSV imports: create: diff --git a/decidim-accountability/config/locales/es.yml b/decidim-accountability/config/locales/es.yml index e93f33ef8a253..5810f782d2f89 100644 --- a/decidim-accountability/config/locales/es.yml +++ b/decidim-accountability/config/locales/es.yml @@ -48,9 +48,29 @@ es: results: Resultados import_results: new: + download_export: Descargar la exportación con formato CSV import: Importar - info: "

Te recomendamos que sigas los siguientes pasos:

  1. Crea los estados para los resultados que quieras agregar ( link )
  2. Crea por lo menos un resultado manualmente a través del panel de administración (link) antes de importar, para entender mejor el formato y cómo rellenarlo.
  3. Descarga el archivo en formato CSV (%{link_export_csv})
  4. Haz los cambios en local. Sólo puedes modificar las siguientes columnas del CSV:
  • id category /id: ID para la categoría
  • scope /id: ID para el ámbito
  • parent /id: ID para el padre (para resultados relacionados). Opcional
  • title /I18N: título en el idioma X
  • description /I18N: descripción en el idioma X
  • start_date: fecha en la que se inicia la ejecución del resultado (formato AAAA-MM-DD)
  • end_date: fecha en la que finaliza la ejecución del resultado (formato AAAA-MM-DD)
  • status /id: ID del estado para este resultado
  • progress: Tanto por ciento (de 0 a 100) de ejecución
  • proposals_ids: ID interno de las propuestas relacionadas (separadas por comas). Se convertirá automáticamente en proposal_url
" - link: enlace + info: | +

Te recomendamos que sigas los siguientes pasos:

+
    +
  1. Crea los estados para los resultados que quieras agregar
  2. +
  3. Crea por lo menos un resultado manualmente a través del panel de administración antes de importar, para entender mejor el formato y cómo rellenarlo.
  4. +
  5. %{link_export_csv}
  6. +
  7. Haz los cambios en local. Sólo puedes modificar las siguientes columnas del CSV: +
      +
    • id category/id: ID para la categoría
    • +
    • scope/id: ID para el ámbito
    • +
    • parent/id: ID para el padre (para resultados relacionados). Opcional
    • +
    • title/I18N: título en el idioma X
    • +
    • description/I18N: descripción en el idioma X
    • +
    • start_date: fecha en la que se inicia la ejecución del resultado (formato AAAA-MM-DD)
    • +
    • end_date: fecha en la que finaliza la ejecución del resultado (formato AAAA-MM-DD)
    • +
    • status/id: ID del estado para este resultado
    • +
    • progress: Tanto por ciento (de 0 a 100) de ejecución
    • +
    • proposals_ids: ID interno de las propuestas relacionadas (separadas por comas). Se convertirá automáticamente en proposal_url
    • +
    +
  8. +
title: Importar resultados vía CSV imports: create: diff --git a/decidim-accountability/config/locales/eu.yml b/decidim-accountability/config/locales/eu.yml index d150f22924d0c..3046863e1050a 100644 --- a/decidim-accountability/config/locales/eu.yml +++ b/decidim-accountability/config/locales/eu.yml @@ -49,8 +49,6 @@ eu: import_results: new: import: Inportatu - info: "Ondoko urrats hauek ematea gomendatzen dizugu:

  1. Sortu egoerak erantsi nahi dituzun emaitzetarako ( link )
  2. ) Sortu emaitza bat gutxienez eskuz administrazioaren panelaren bidez (link) inportatu baino lehen, hobeto ulertzeko formatua eta nola bete.
  3. Deskargatu CSV formatuko artxiboa (%{link_export_csv}
  4. Egin aldaketak lokalean. CSVren ondoko zutabeak baino ezin dituzu aldatu:
  • id category /id: ID kategoriarako
  • scope /id: ID eremurako
  • parent /id: ID aitarentzat (erlazionatutako emaitzetarako). Aukerakoa
  • title /I18N: izenburua hizkuntzan X
  • deskribapena /I18N: deskribapena hizkuntzan X
  • start_date: emaitza gauzatzen den hasiera-data (AAAA-MM-DD formatua)
  • end emaitza gauzatzen den amaiera-data (AAAA-MM-DD formatua)
  • status /id: egoeraren ID emaitza honetarako
  • progress: gauzatzearen ehunekoa (0tik 100era)
  • proposals_ids: erlazionatutako proposamenen barneko ID (komez bidez bereizita). Automatikoki bihurtuko da: proposal_url
" - link: lotura title: Inportatu emaitzak CSVtik imports: create: diff --git a/decidim-accountability/config/locales/fi-plain.yml b/decidim-accountability/config/locales/fi-plain.yml index e36971f6fdafb..318a68b9c5c94 100644 --- a/decidim-accountability/config/locales/fi-plain.yml +++ b/decidim-accountability/config/locales/fi-plain.yml @@ -48,9 +48,29 @@ fi-pl: results: Tulokset import_results: new: + download_export: Lataa vientitiedosto CSV-muodossa import: Tuo - info: "

Suosittelemme, että teet seuraavat toimenpiteet tässä järjestyksessä:

  1. Luo tulosten tilat (linkki)
  2. Luo vähintään yksi tulos manuaalisesti hallintapaneelin kautta (linkki) ennen tuontia, ymmärtääksesi millaisessa muodossa tulosten tiedot tulee määrittää.
  3. Vie tulokset CSV-tiedostoon (%{link_export_csv})
  4. Tee muutokset tietokoneellasi. Voit ainoastaan muuttaa seuraavia asioita CSV-tiedoston kautta:
  • category/id: Aihepiirin ID-numero
  • scope/id: Teeman ID-numero
  • parent/id: Isäntätuloksen ID-numero (toisiinsa liitetyille tuloksille, muille tyhjä). Valinnainen
  • title/I18N Otsikko kielelle X
  • description/I18N: Kuvaus kielelle X
  • start_date: Päivämäärä, jolloin tuloksen toteuttaminen aloitetaan (muodossa YYYY-MM-DD)
  • end_date: Päivämäärä, jolloin tuloksen toteuttaminen lopetetaan (muodossa YYYY-MM-DD)
  • status/id: Tuloksen tilan ID-numero
  • progress: Tuloksen toteutuksen tilan prosentuaalinen kuvaus (0-100)
  • proposal_ids: Tulokseen liitettyjen ehdotusten ID-numerot (eroteltuna pilkulla). Muutetaan automaattisesti proposal_url
" - link: linkki + info: | +

Suorittelemme tekemään seuraavat toimenpiteet suorittaaksesi tuonnin onnistuneesti:

+
    +
  1. Luo tilat tuloksille
  2. +
  3. Luo vähintään yksi tulos käsin hallintapaneelin kautta ennen tuontia, jotta ymmärrät paremmin, miltä tuontitiedoston tulee näyttää.
  4. +
  5. %{link_export_csv}
  6. +
  7. Tee tiedostoon muutoksia tietokoneellasi. Voit muuttaa ainoastaan seuraavia sarakkeita CSV-tiedostossa: +
      +
    • category/id: Aihepiirin ID-tunniste
    • +
    • scope/id: Teeman ID-tunniste
    • +
    • parent/id: Tuloksen isännän ID-tunniste. Vapaaehtoinen
    • +
    • title/fi: Otsikko suomeksi. Tämän sarakkeen nimi riippuu alustalle määritetyistä kielistä.
    • +
    • description/fi: Kuvaus suomeksi. Tämän sarakkeen nimi riippuu alustalle määritetyistä kielistä.
    • +
    • start_date: Tuloksen toteuttamisen aloituspäivämäärä (muodossa YYYY-MM-DD)
    • +
    • end_date: Tuloksen toteuttamisen päättymispäivämäärä (muodossa YYYY-MM-DD)
    • +
    • status/id: Tuloksen tilan ID-tunniste
    • +
    • progress: Tuloksen toteutuksen prosentuaalisen etenemisen tila (välillä 0-100)
    • +
    • proposals_ids: Liittyvien ehdotusten ID-numerot (pilkulla eroteltuna). Nämä muutetaan automaattisesti proposal_url
    • +
    +
  8. +
title: Tuo tulokset CSV-tiedostosta imports: create: diff --git a/decidim-accountability/config/locales/fi.yml b/decidim-accountability/config/locales/fi.yml index dcc765dc09f17..38f41ae6adbdc 100644 --- a/decidim-accountability/config/locales/fi.yml +++ b/decidim-accountability/config/locales/fi.yml @@ -48,9 +48,29 @@ fi: results: Tulokset import_results: new: + download_export: Lataa vientitiedosto CSV-muodossa import: Tuo - info: "

Suosittelemme, että teet seuraavat toimenpiteet tässä järjestyksessä:

  1. Luo tulosten tilat (linkki)
  2. Luo vähintään yksi tulos manuaalisesti hallintapaneelin kautta (linkki) ennen tuontia, ymmärtääksesi millaisessa muodossa tulosten tiedot tulee määrittää.
  3. Vie tulokset CSV-tiedostoon (%{link_export_csv})
  4. Tee muutokset tietokoneellasi. Voit ainoastaan muuttaa seuraavia asioita CSV-tiedoston kautta:
  • category/id: Aihepiirin ID-numero
  • scope/id: Teeman ID-numero
  • parent/id: Isäntätuloksen ID-numero (toisiinsa liitetyille tuloksille, muille tyhjä). Valinnainen
  • title/I18N Otsikko kielelle X
  • description/I18N: Kuvaus kielelle X
  • start_date: Päivämäärä, jolloin tuloksen toteuttaminen aloitetaan (muodossa YYYY-MM-DD)
  • end_date: Päivämäärä, jolloin tuloksen toteuttaminen lopetetaan (muodossa YYYY-MM-DD)
  • status/id: Tuloksen tilan ID-numero
  • progress: Tuloksen toteutuksen tilan prosentuaalinen kuvaus (0-100)
  • proposal_ids: Tulokseen liitettyjen ehdotusten ID-numerot (eroteltuna pilkulla). Muutetaan automaattisesti proposal_url
" - link: linkki + info: | +

Suorittelemme tekemään seuraavat toimenpiteet suorittaaksesi tuonnin onnistuneesti:

+
    +
  1. Luo tilat tuloksille
  2. +
  3. Luo vähintään yksi tulos käsin hallintapaneelin kautta ennen tuontia, jotta ymmärrät paremmin, miltä tuontitiedoston tulee näyttää.
  4. +
  5. %{link_export_csv}
  6. +
  7. Tee tiedostoon muutoksia tietokoneellasi. Voit muuttaa ainoastaan seuraavia sarakkeita CSV-tiedostossa: +
      +
    • category/id: Aihepiirin ID-tunniste
    • +
    • scope/id: Teeman ID-tunniste
    • +
    • parent/id: Tuloksen isännän ID-tunniste. Vapaaehtoinen
    • +
    • title/fi: Otsikko suomeksi. Tämän sarakkeen nimi riippuu alustalle määritetyistä kielistä.
    • +
    • description/fi: Kuvaus suomeksi. Tämän sarakkeen nimi riippuu alustalle määritetyistä kielistä.
    • +
    • start_date: Tuloksen toteuttamisen aloituspäivämäärä (muodossa YYYY-MM-DD)
    • +
    • end_date: Tuloksen toteuttamisen päättymispäivämäärä (muodossa YYYY-MM-DD)
    • +
    • status/id: Tuloksen tilan ID-tunniste
    • +
    • progress: Tuloksen toteutuksen prosentuaalisen etenemisen tila (välillä 0-100)
    • +
    • proposals_ids: Liittyvien ehdotusten ID-numerot (pilkulla eroteltuna). Nämä muutetaan automaattisesti proposal_url
    • +
    +
  8. +
title: Tuo tulokset CSV-tiedostosta imports: create: diff --git a/decidim-accountability/config/locales/fr-CA.yml b/decidim-accountability/config/locales/fr-CA.yml index 370e9e01757cc..2f073a03e55e7 100644 --- a/decidim-accountability/config/locales/fr-CA.yml +++ b/decidim-accountability/config/locales/fr-CA.yml @@ -48,9 +48,29 @@ fr-CA: results: Réalisations import_results: new: + download_export: Télécharger l'export au format CSV import: Importer - info: "

Nous vous recommandons de suivre les étapes suivantes :

  1. Créez les statuts pour les résultats que vous souhaitez ajouter (lien)
  2. Créez au moins un résultat manuellement via ce panneau administrateur (lien) avant d'utiliser l'import, pour comprendre ce que vous aurez besoin de remplir.
  3. Téléchargez l'export en format CSV (%{link_export_csv})
  4. Faites les modifications nécessaires. Vous pouvez uniquement changer les colonnes suivantes du fichier CSV :
  • category/id: Identifiant de la catégorie
  • scope/id : Identifiant du secteur
  • parent/id : Identifiant du parent (pour les résultats liés). Optional
  • title/I18N: Titre en langue X
  • description/I18N: Description en langue X
  • start_date: date à laquelle le résultat commence (format AAAA-MM-JJ)
  • end_date: date à laquelle le résultat finit (format AAAA-MM-JJ)
  • status/id: Identifiant du statut du résultat
  • progress: Pourcentage (de 0 à 100) de l'exécution du résultat
  • proposals_ids: Identifiant interne des propositions liées (séparées avec une virgule). La conversion en URL de la proposition se fait automatiquement.
" - link: lien + info: | +

Nous vous recommandons les étapes suivantes:

+
    +
  1. Créer les Status pour les résultats que vous voulez ajouter
  2. +
  3. Créer au moins un résultat manuellement via ce panneau admin avant d'utiliser l'import, pour mieux comprendre le format et ce que vous devrez compléter.
  4. +
  5. %{link_export_csv}
  6. +
  7. Appliquer les changement localement. Vous ne pouvez changer que les colonnes suivantes du CSV: +
      +
    • category/id: ID de la catégorie
    • +
    • scope/id: ID du périmètre d'application
    • +
    • parent/id: ID du parent (pour résultat liés). Optionel
    • +
    • title/en: Titre en anglais. Cela dépend de la configuration des langues sur votre plateforme.
    • +
    • description/en: Description en anglais. Cela dépend de la configuration des langues sur votre plateforme.
    • +
    • start_date: date à partir de laquelle le résultat est mis en œuvre (format AAAA-MM-JJ)
    • +
    • end_date: date à laquelle se termine la mise en œuvre du résultat (format AAAA-MM-JJ)
    • +
    • status/id: ID du status de ce résultat
    • +
    • progress: Pourcentage (de 0 à 100) de l'exécution
    • +
    • proposals_ids: IDs des propositions liées (séparés par une virgule). C'est automatiquement converti en proposal_url
    • +
    +
  8. +
title: Importer les résultats depuis un fichier CSV imports: create: diff --git a/decidim-accountability/config/locales/fr.yml b/decidim-accountability/config/locales/fr.yml index b448518478a95..338b7546cd957 100644 --- a/decidim-accountability/config/locales/fr.yml +++ b/decidim-accountability/config/locales/fr.yml @@ -48,9 +48,29 @@ fr: results: Réalisations import_results: new: + download_export: Télécharger l'export au format CSV import: Importer - info: "

Nous vous recommandons de suivre les étapes suivantes :

  1. Créez les statuts pour les résultats que vous souhaitez ajouter (lien)
  2. Créez au moins un résultat manuellement via ce panneau administrateur (lien) avant d'utiliser l'import, pour comprendre ce que vous aurez besoin de remplir.
  3. Téléchargez l'export en format CSV (%{link_export_csv})
  4. Faites les modifications nécessaires. Vous pouvez uniquement changer les colonnes suivantes du fichier CSV :
  • category/id: Identifiant de la catégorie
  • scope/id : Identifiant du secteur
  • parent/id : Identifiant du parent (pour les résultats liés). Optional
  • title/I18N: Titre en langue X
  • description/I18N: Description en langue X
  • start_date: date à laquelle le résultat commence (format AAAA-MM-JJ)
  • end_date: date à laquelle le résultat finit (format AAAA-MM-JJ)
  • status/id: Identifiant du statut du résultat
  • progress: Pourcentage (de 0 à 100) de l'exécution du résultat
  • proposals_ids: Identifiant interne des propositions liées (séparées avec une virgule). La conversion en URL de la proposition se fait automatiquement.
" - link: lien + info: | +

Nous vous recommandons les étapes suivantes:

+
    +
  1. Créer les Status pour les résultats que vous voulez ajouter
  2. +
  3. Créer au moins un résultat manuellement via ce panneau admin avant d'utiliser l'import, pour mieux comprendre le format et ce que vous devrez compléter.
  4. +
  5. %{link_export_csv}
  6. +
  7. Appliquer les changement localement. Vous ne pouvez changer que les colonnes suivantes du CSV: +
      +
    • category/id: ID de la catégorie
    • +
    • scope/id: ID du périmètre d'application
    • +
    • parent/id: ID du parent (pour résultat liés). Optionel
    • +
    • title/en: Titre en anglais. Cela dépend de la configuration des langues sur votre plateforme.
    • +
    • description/en: Description en anglais. Cela dépend de la configuration des langues sur votre plateforme.
    • +
    • start_date: date à partir de laquelle le résultat est mis en œuvre (format AAAA-MM-JJ)
    • +
    • end_date: date à laquelle se termine la mise en œuvre du résultat (format AAAA-MM-JJ)
    • +
    • status/id: ID du status de ce résultat
    • +
    • progress: Pourcentage (de 0 à 100) de l'exécution
    • +
    • proposals_ids: IDs des propositions liées (séparés par une virgule). C'est automatiquement converti en proposal_url
    • +
    +
  8. +
title: Importer les résultats depuis un fichier CSV imports: create: diff --git a/decidim-accountability/config/locales/ga-IE.yml b/decidim-accountability/config/locales/ga-IE.yml index 546945258af5d..e8978232894ee 100644 --- a/decidim-accountability/config/locales/ga-IE.yml +++ b/decidim-accountability/config/locales/ga-IE.yml @@ -30,7 +30,6 @@ ga: import_results: new: import: Iompórtáil - link: nasc models: result: name: Toradh diff --git a/decidim-accountability/config/locales/gl.yml b/decidim-accountability/config/locales/gl.yml index 7b16c9aa87b46..bc0bbddaeb0b4 100644 --- a/decidim-accountability/config/locales/gl.yml +++ b/decidim-accountability/config/locales/gl.yml @@ -49,8 +49,6 @@ gl: import_results: new: import: Importar - info: "

Recomendámosche seguir os seguintes pasos:

  1. Crear os estados para os Resultados que desexes engadir (ligazón)
  2. Crear polo menos un Resultado de xeito manual a través deste panel de administrador (ligazón) antes de usar Importar, para entender o formato e que precisas encher.
  3. Descargar o ficheiro en formato CSV (%{link_export_csv})
  4. Fai os trocos localmente. Só podes trocar as seguintes columnas do CSV:
  • category/id: ID da categoría
  • scope/id: ID do ámbito
  • parent/id: ID do pai (para Resultados relacionados). Opcional
  • title/I18N: Título no idioma X
  • description/I18N: Descrición no idioma X
  • start_date: data na que se inicia a execución do resultado (formato YYYY-MM-DD)
  • end_date: data na que remata a execución (formato YYYY-MM-DD)
  • status/id: ID do estado do resultado
  • progress: Porcentaxe (de 0 a 100) da execución
  • proposals_ids: ID interno das propostas relacionadas (separadas por comas). Isto converterase automaticamente en proposal_url
" - link: ligazón title: Importar resultados dun CSV imports: create: diff --git a/decidim-accountability/config/locales/gn-PY.yml b/decidim-accountability/config/locales/gn-PY.yml new file mode 100644 index 0000000000000..bd442b0ad85de --- /dev/null +++ b/decidim-accountability/config/locales/gn-PY.yml @@ -0,0 +1 @@ +gn: diff --git a/decidim-accountability/config/locales/hu.yml b/decidim-accountability/config/locales/hu.yml index 1df574547c6b0..a1519c9223b83 100644 --- a/decidim-accountability/config/locales/hu.yml +++ b/decidim-accountability/config/locales/hu.yml @@ -49,8 +49,6 @@ hu: import_results: new: import: Importál - info: "

Javasoljuk, hogy kövesse az alábbi lépéseket:

  1. Hozza létre a hozzáadni kívánt Eredmények állapotait (link).
  2. Az Importálás lehetőség használata előtt hozzon létre legalább egy eredményt manuálisan ezen az Adminisztrációs panelen keresztül (link), hogy jobban megismerje a használni kívánt formátumot, valamint az adatokat, amelyeket meg kell adnia.
  3. Töltse le az Exportált elemet CSV-formátumban (%{link_export_csv})
  4. A módosításokat helyileg végezze el. A CSV-fájlban kizárólag a következő oszlopokat módosíthatja:
  • category/id: a Kategória azonosítója
  • scope/id: az Alkalmazási kör azonosítója
  • parent/id: a Fölérendelt objektum azonosítója (a kapcsolódó Eredmények esetében). Opcionális
  • title/I18N: Cím X nyelven
  • description/I18N: Leírás X nyelven
  • start_date: az eredmény végrehajtásának kezdő dátuma (formátum: ÉÉÉÉ-HH-NN)
  • end_date: az eredmény végrehajtásának záró dátuma (formátum: ÉÉÉÉ-HH-NN)
  • status/id: az eredmény Állapotának azonosítója
  • progress: a végrehajtás mértéke százalékban kifejezve (0 és 100 közötti érték)
  • proposals_ids: a kapcsolódó javaslatok belső azonosítói (vesszővel elválasztva). Automatikusan a következőre konvertálva: proposal_url
" - link: link title: Eredmények betöltése CSV-ből imports: create: diff --git a/decidim-accountability/config/locales/is-IS.yml b/decidim-accountability/config/locales/is-IS.yml index 1943665a1de39..7d9e5c9c40560 100644 --- a/decidim-accountability/config/locales/is-IS.yml +++ b/decidim-accountability/config/locales/is-IS.yml @@ -48,7 +48,6 @@ is-IS: import_results: new: import: Flytja inn - link: hlekkur title: Flytja inn niðurstöður frá CSV imports: create: diff --git a/decidim-accountability/config/locales/it.yml b/decidim-accountability/config/locales/it.yml index 590df439b4415..ff6a5b520b19d 100644 --- a/decidim-accountability/config/locales/it.yml +++ b/decidim-accountability/config/locales/it.yml @@ -49,8 +49,6 @@ it: import_results: new: import: Importa - info: "

Si consiglia di seguire questi passaggi:

  1. Creare gli Stati per i risultati che si desidera aggiungere (link)
  2. Creare manualmente almeno un risultato attraverso questo pannello di amministrazione (link) prima di utilizzare Import, per avere una migliore comprensione del formato e di ciò che è necessario compilare.
  3. Scarica l'esportazione nel formato CSV (%{link_export_csv})
  4. Effettua le modifiche localmente. È possibile modificare solo le seguenti colonne del CSV:
  • categoria/id: ID per la categoria
  • scope/id: ID per l'ambito
  • parent/id: ID dell'origine (per i risultati correlati). Opzionale
  • titolo/I18N: Titolo sulla lingua X
  • descrizione/I18N: Descrizione sulla lingua X
  • start_date: data in cui il risultato inizia l'esecuzione (formato YYYY-MM-DD)
  • end_date: data in cui il risultato termina l'esecuzione (formato AAAA-MM-DD)
  • status/id: ID dello stato per questo risultato
  • progresso: Percentuale (da 0 a 100) dell'esecuzione
  • proposte_ids: ID interno delle relative proposte (separate da una virgola). Viene convertito automaticamente in proposal_url
" - link: collegamento title: Importa risultati da CSV imports: create: diff --git a/decidim-accountability/config/locales/ja.yml b/decidim-accountability/config/locales/ja.yml index 99f64728f0de9..8de5ddeca41e0 100644 --- a/decidim-accountability/config/locales/ja.yml +++ b/decidim-accountability/config/locales/ja.yml @@ -48,8 +48,6 @@ ja: import_results: new: import: インポート - info: "

以下の手順をお勧めします:

  1. 追加したい結果のステータスを作成する (link)
  2. この管理ページを使用して、少なくとも1つの結果を手動で作成します。 (link) インポートを使用する前に、フォーマットと何を記入する必要があるかをよりよく理解してください。
  3. CSV形式でエクスポートをダウンロードしてください。 (%{link_export_csv})
  4. ローカルで変更を行います。変更できるのは、CSVの次の列のみです:
  • category/id: CategoryのID
  • scope/id: Scope の ID
  • parent/id: 関連する結果の親ID。任意
  • title/I18N: 言語Xのタイトル
  • description/I18N: 言語XのDescription
  • start_date: 結果の効力が開始される日 (format YYYY-MM-DD)
  • end_date: 結果の効力が失われる日 (format YYYY-MM-DD)
  • status/id: 結果のステータスID
  • progress: 進行のパーセンテージ(0 から 100)
  • proposals_ids: 提案に関連する内部ID(カンマ区切り)。 自動的に proposal_url に変換されます。
" - link: リンク title: CSVから結果をインポート imports: create: diff --git a/decidim-accountability/config/locales/lb-LU.yml b/decidim-accountability/config/locales/lb-LU.yml index 823df018114f4..c5ddcbd0b1da2 100644 --- a/decidim-accountability/config/locales/lb-LU.yml +++ b/decidim-accountability/config/locales/lb-LU.yml @@ -1 +1,250 @@ lb: + activemodel: + attributes: + result: + decidim_accountability_status_id: Status + decidim_category_id: Kategorie + decidim_scope_id: Umfang + description: Beschreiwung + end_date: Schlussdatum + progress: Progrès + project_ids: Bedeelegt Projeten + proposals: Bedeelegt Proposen + start_date: Ufanksdatum + title: Titel + updated_at: Aktualiséiert den + status: + description: Beschreiwung + key: Schlëssel + name: Numm + progress: Progrès + timeline_entry: + description: Beschreiwung + entry_date: Datum + models: + decidim/accountability/proposal_linked_event: Propose déi Deel vun engem Resultat ass + decidim/accountability/result_progress_updated_event: Aktualiséiert Entwécklung vun engem Resultat + activerecord: + models: + decidim/accountability/result: + one: Resultat + other: Resultat + decidim: + accountability: + actions: + attachment_collections: Dossier + attachments: Unhäng + confirm_destroy: Sidd Dir sécher datt Dir dësen %{name} läsche wëllt? + destroy: Läschen + edit: Editéieren + import_csv: CSV importéieren + new: Néi %{name} + preview: Preview + timeline_entries: Projektentwécklung + title: Aktiounen + admin: + exports: + result_comments: Kommentarer + results: Resultater + import_results: + new: + import: Import + info: "

Wir empfehlen, dass Sie folgende Schritte befolgen:

  1. Erstellen Sie den Status der Ergebnisse, die Sie hinzufügen möchten (link)
  2. Erstellen Sie mindestens ein Ergebnis über diesen Administrator-Panel (link) bevor Sie Importieren, damit Sie mit dem Format und den benötigten Eingaben vertraut sind.
  3. Laden Sie den Export im CSV-Format herunter (%{link_export_csv})
  4. Nehmen Sie Änderungen lokal vor. Sie können nur die folgenden Spalten der CSV ändern:
  • Kategorie/ID: ID der Kategorie
  • Umfang/ID: ID des Umfangs
  • Übergeordnet/ID: Übergeordnete ID (für verwandte Ergebnisse). Optional
  • Titel/I18N: Titel in Sprache X
  • Beschreibung/I18N: Beschreibung in Sprache X
  • start_datum: Datum, an dem die Ausführung des Ergebnisses beginnt (Format JJJJ-MM-TT)
  • end_datum: Datum, an dem die Ausführung des Ergebnisses endet (Format JJJJ-MM-TT)
  • Status/ID: ID des Status dieses Ergebnisses
  • Fortschritt: Prozentualer (von 0 bis 100) Fortschritt der Durchführung
  • Vorschläge_IDs: Interne ID der verwandten Vorschläge (getrennt durch Komma). Dies wird automatisch umgewandelt in proposal_url
" + link: link + title: Resultater aus engem CSV-Fichier importéieren + imports: + create: + success: Den Import vum Fichier huet ugefaang. Dir kritt eng Email an den nächste puer Minutte mam Resultat vum Import + models: + result: + name: Resultat + status: + name: Status + timeline_entry: + name: Zeitachseneintrag + results: + create: + invalid: Beim Erstellen dieses Ergebnisses ist ein Problem aufgetreten + success: Ergebnis erfolgreich erstellt + destroy: + success: Ergebnis erfolgreich gelöscht + edit: + title: Ergebnis bearbeiten + update: Ergebnis aktualisieren + index: + title: Resultater + new: + create: Ergebnis erstellen + title: Neues Ergebnis + update: + invalid: Beim Aktualisieren dieses Ergebnisses ist ein Problem aufgetreten + success: Ergebnis erfolgreich aktualisiert + shared: + subnav: + statuses: Status + statuses: + create: + invalid: Beim Erstellen dieses Status ist ein Problem aufgetreten + success: Status erfolgreich erstellt + destroy: + success: Status erfolgreich gelöscht + edit: + title: Status bearbeiten + update: Update Status + index: + title: Status + new: + create: Status erstellen + title: Neuer Status + update: + invalid: Beim Aktualisieren dieses Status ist ein Problem aufgetreten + success: Status erfolgreich aktualisiert + timeline_entries: + create: + invalid: Beim Erstellen dieses Eintrags ist ein Problem aufgetreten + success: Der Eintrag wurde erfolgreich erstellt + destroy: + success: Der Eintrag wurde erfolgreich gelöscht + edit: + title: Eintrag bearbeiten + update: Eintrag aktualisieren + index: + title: Projektzeitplaneinträge + new: + create: Eintrag erstellen + title: Neuer Eintrag + update: + invalid: Beim Aktualisieren dieses Eintrags ist ein Problem aufgetreten + success: Eintrag erfolgreich aktualisiert + admin_log: + result: + create: "%{user_name} hat das Ergebnis %{resource_name} in %{space_name} erstellt" + delete: "%{user_name} hat das Ergebnis %{resource_name} in %{space_name} gelöscht" + update: "%{user_name} hat das Ergebnis %{resource_name} in %{space_name} aktualisiert" + value_types: + parent_presenter: + not_found: 'Das übergeordnete Objekt wurde nicht in der Datenbank gefunden (ID: %{id})' + content_blocks: + highlighted_results: + dates: Daten + results: Ergebnisse + unspecified: Keine Angabe + import_mailer: + import: + errors: Fehler + errors_present: Beim Importieren der Ergebnisse ist ein Fehler aufgetreten + row_number: Zeile + subject: Ergebnisse wurden erfolgreich importiert + success: Ergebnisse wurden erfolgreich importiert. Sie können die Ergebnisse über die Administrationsoberfläche aufrufen. + last_activity: + new_result_at_html: "Neues Ergebnis bei %{link}" + models: + result: + fields: + category: Kategorie + created_at: Erstellt am + end_date: Enddatum + id: ID + progress: Fortschritt + scope: Themenbereich + start_date: Startdatum + status: Status + title: Titel + status: + fields: + description: Beschreibung + key: Schlüssel + name: Name + progress: Fortschritt + timeline_entry: + fields: + description: Beschreibung + entry_date: Datum + result_m: + executed: Ausgeführt + view: Ansicht + results: + count: + results_count: + one: 1 Ergebnis + other: "%{count} Ergebnisse" + filters: + all: Alle + scopes: Bereiche + home: + categories_label: Kategorien + subcategories_label: Unterkategorien + home_header: + global_status: Globaler Umsetzungsstatus + nav_breadcrumb: + global: Globale Ausführung + search: + search: Suche nach Aktionen + show: + stats: + attendees: Teilnehmer + back_to_resource: Gehe zurück zum Ergebnis + comments: Bemerkungen + contributions: Beiträge + last_edited_by: Zuletzt bearbeitet von + last_updated_at: Zuletzt aktualisiert am + meetings: Meetings + proposals: Vorschläge + votes: Unterstützt + timeline: + title: Projektentwicklung + admin: + filters: + results: + category_id_eq: + label: Kategorie + scope_id_eq: + label: Themenberäich + status_id_eq: + label: Status + components: + accountability: + actions: + comment: Kommentar + name: Rechenschaftspflicht + settings: + global: + categories_label: Name für "Kategorien" + comments_enabled: Kommentare aktiviert + comments_max_length: Maximale Länge der Kommentare (0 für Standardwert) + display_progress_enabled: Fortschritt anzeigen + heading_leaf_level_results: Name für "Projekte" + heading_parent_level_results: Name für "Resultate" + intro: Einführung + scope_id: Bereich + scopes_enabled: Bereiche aktiviert + subcategories_label: Name für "Unterkategorien" + step: + comments_blocked: Kommentare blockiert + events: + accountability: + proposal_linked: + email_intro: 'Der Vorschlag "%{proposal_title}" wurde in ein Ergebnis aufgenommen. Sie können das auf dieser Seite sehen:' + email_outro: Sie haben diese Benachrichtigung erhalten, weil Sie "%{proposal_title}" folgen. Falls Sie keine solchen Benachrichtigungen mehr erhalten möchten, besuchen Sie den obigen Link. + email_subject: Eine Aktualisierung auf %{proposal_title} + notification_title: Der Vorschlag %{proposal_title} wurde im Ergebnis %{resource_title} aufgenommen. + result_progress_updated: + email_intro: 'Das Ergebnis "%{resource_title}", das den Vorschlag "%{proposal_title}" enthält, ist jetzt zu %{progress}% abgeschlossen. Sie können das auf dieser Seite sehen:' + email_outro: Sie haben diese Benachrichtigung erhalten, weil Sie "%{proposal_title}" folgen und dieser Vorschlag in das Ergebnis "%{resource_title}" aufgenommen wurde. Falls Sie keine solchen Benachrichtigungen mehr erhalten möchten, besuchen Sie den obigen Link. + email_subject: Fortschritt von %{resource_title} aktualisiert + notification_title: Das Ergebnis %{resource_title}, das den Vorschlag %{proposal_title} enthält, ist jetzt zu %{progress}% abgeschlossen. + metrics: + results: + description: Anzahl der generierten Ergebnisse + object: Ergebnisse + title: Ergebnisse + participatory_spaces: + highlighted_results: + see_all: Alle Ergebnisse ansehen (%{count}) + resource_links: + included_projects: + result_project: Projekte in diesem Ergebnis enthalten + included_proposals: + result_proposal: Vorschläge in diesem Ergebnis enthalten + statistics: + results_count: Ergebnisse diff --git a/decidim-accountability/config/locales/lb.yml b/decidim-accountability/config/locales/lb.yml index e1d6b597e2663..37a2d7b06c705 100644 --- a/decidim-accountability/config/locales/lb.yml +++ b/decidim-accountability/config/locales/lb.yml @@ -49,8 +49,6 @@ lb: import_results: new: import: Import - info: "

Wir empfehlen, dass Sie folgende Schritte befolgen:

  1. Erstellen Sie den Status der Ergebnisse, die Sie hinzufügen möchten (link)
  2. Erstellen Sie mindestens ein Ergebnis über diesen Administrator-Panel (link) bevor Sie Importieren, damit Sie mit dem Format und den benötigten Eingaben vertraut sind.
  3. Laden Sie den Export im CSV-Format herunter (%{link_export_csv})
  4. Nehmen Sie Änderungen lokal vor. Sie können nur die folgenden Spalten der CSV ändern:
  • Kategorie/ID: ID der Kategorie
  • Umfang/ID: ID des Umfangs
  • Übergeordnet/ID: Übergeordnete ID (für verwandte Ergebnisse). Optional
  • Titel/I18N: Titel in Sprache X
  • Beschreibung/I18N: Beschreibung in Sprache X
  • start_datum: Datum, an dem die Ausführung des Ergebnisses beginnt (Format JJJJ-MM-TT)
  • end_datum: Datum, an dem die Ausführung des Ergebnisses endet (Format JJJJ-MM-TT)
  • Status/ID: ID des Status dieses Ergebnisses
  • Fortschritt: Prozentualer (von 0 bis 100) Fortschritt der Durchführung
  • Vorschläge_IDs: Interne ID der verwandten Vorschläge (getrennt durch Komma). Dies wird automatisch umgewandelt in proposal_url
" - link: link title: Resultater aus engem CSV-Fichier importéieren imports: create: diff --git a/decidim-accountability/config/locales/lo-LA.yml b/decidim-accountability/config/locales/lo-LA.yml new file mode 100644 index 0000000000000..27a02bfece429 --- /dev/null +++ b/decidim-accountability/config/locales/lo-LA.yml @@ -0,0 +1 @@ +lo: diff --git a/decidim-accountability/config/locales/lt.yml b/decidim-accountability/config/locales/lt.yml index 1a4d6b169fb95..9ef24d7061a69 100644 --- a/decidim-accountability/config/locales/lt.yml +++ b/decidim-accountability/config/locales/lt.yml @@ -51,8 +51,6 @@ lt: import_results: new: import: Importuoti - info: "

Rekomenduojame atlikti šiuos veiksmus:

  1. Sukurti norimų pridėti rezultatų būsenas (link)
  2. Sukurti bent vieną rezultatą rankiniu būdu pasinaudojant šia Administratoriaus panele (link) prieš spustelint „Importuoti“, kad geriau suprastumėte formatą ir tai, ką turite užpildyti.
  3. Parsisiųskite eksporto rinkmeną CSV formatu (%{link_export_csv})
  4. Atlikite pakeitimus lokaliai. Galite pakeisti tik šias CSV skiltis:
  • category/id: ID, skirtą kategorijai
  • scope/id: ID, skirtą sričiai
  • parent/id: pirminio elemento ID (skirtą susijusiems rezultatams). Neprivaloma
  • title/I18N: Pavadinimas X kalba
  • description/I18N: Aprašymas X kalba
  • start_date: data, kada rezultatas pradedamas generuoti (MMMM-MM-DD formatas)
  • end_date: data, kada rezultatas baigiamas generuoti (MMMM-MM-DD formatas)
  • status/id: šio rezultato būsenos ID
  • progress: Įvykdymo procentinė dalis (nuo 0 iki 100)
  • proposals_ids: susijusių pasiūlymų vidaus ID (atskirta kableliu). Tai automatiškai pakeičiama į proposal_url
" - link: nuoroda title: Importuoti rezultatus iš CSV imports: create: diff --git a/decidim-accountability/config/locales/lv.yml b/decidim-accountability/config/locales/lv.yml index ff06cfa9d52de..aac3223a752d1 100644 --- a/decidim-accountability/config/locales/lv.yml +++ b/decidim-accountability/config/locales/lv.yml @@ -45,8 +45,6 @@ lv: import_results: new: import: Importēt - info: "

Mēs iesakām veikt šādas darbības:

  1. izveidojiet statusu rezultātiem, ko vēlaties pievienot (link)
  2. Pirms importēšanas manuāli izveidojiet vismaz vienu rezultātu, izmantojot šo administratora paneli, (link) lai labāk izprastu formātu un to, kas būs jāaizpilda.
  3. Lejupielādējiet formātā Eksportēt ar CSV (%{link_export_csv})
  4. Veiciet lokālas izmaiņas. Jūs varat mainīt tikai šādas CSV kolonnas:
  • category/id: Kategorijas ID
  • scope/id: Tvēruma ID
  • parent/id: Saistītais ID (saistītajiem rezultātiem). Pēc izvēles:
  • title/I18N: Virsraksts X valodā
  • description/I18N: Apraksts X valodā
  • start_date: datums, kurā uzsākta rezultāta izpilde (formāts GGGG-MM-DD)
  • end_date: datums, kurā beidzas rezultāta izpilde (formāts GGGG-MM-DD)
  • status/id: šī rezultāta statusa ID
  • progress: Izpildes līmenis procentos (no 0 līdz 100)
  • proposals_ids: saistīto priekšlikumu iekšējais ID (atdalīts ar komatu). Tas tiek automātiski konvertēts uz proposal_url
" - link: saite title: Importēt rezultātus no CSV imports: create: diff --git a/decidim-accountability/config/locales/nl.yml b/decidim-accountability/config/locales/nl.yml index 3a5a07fcf0ae9..322f457b33179 100644 --- a/decidim-accountability/config/locales/nl.yml +++ b/decidim-accountability/config/locales/nl.yml @@ -49,8 +49,6 @@ nl: import_results: new: import: Importeren - info: "

Wij bevelen aan dat u de volgende stappen volgt:

  1. Maak de Statussen aan voor de Resultaten die u wilt toevoegen (link)
  2. Maak ten minste één Resultaat handmatig aan via dit Beheerderspaneel (link) voordat u Importeren gebruikt, zodat u een beter inzicht hebt in het formaat en wat u moet invullen.
  3. Download de Export in CSV-formaat (%{link_export_csv})
  4. Voer de wijzigingen lokaal door. U kunt alleen de volgende kolommen van de CSV wijzigen:
  • category/id: ID voor de Categorie
  • scope/id: ID voor het Toepassingsgebied
  • parent/id: ID van de hoofdwaarde (voor aanverwante resultaten). Facultatief
  • title/I18N: Titel in X taal
  • description/I18N: Beschrijving in X taal
  • start_date: datum waarop de uitvoering van het resultaat start (formaat JJJJ-MM-DD)
  • end_date: datum waarop de uitvoering van het resultaat eindigt (formaat JJJJ-MM-DD)
  • status/id: ID van de status voor dit resultaat
  • progress: Percentage (van 0 tot 100) van de uitvoering
  • proposals_ids: intern ID van de aanverwante voorstellen (gescheiden door een komma). Het wordt automatisch omgezet in proposal_url
" - link: link title: Importeer resultaten van CSV imports: create: diff --git a/decidim-accountability/config/locales/no.yml b/decidim-accountability/config/locales/no.yml index 23f0623e6c20b..b187deceecde9 100644 --- a/decidim-accountability/config/locales/no.yml +++ b/decidim-accountability/config/locales/no.yml @@ -49,8 +49,6 @@ import_results: new: import: Importer - info: "

Vi anbefaler at du følger disse stegene:

  1. Lag Statuser for de Resultatene du vil legge til (link)
  2. Lag manuelt i hvert fall ett Resultat via dette Admin-panelet (link) før du bruker Importer, for å bedre forstå formatet og det du trenger for å fylle ut.
  3. Last ned Eksporter med CSV-format (%{link_export_csv})
  4. Gjør endringene lokalt. Du kan bare endre følgende kolonner i CSV:
  • kategori/id: ID for Kategorien
  • omfang/id: ID for Omfanget
  • parent/id: ID for parent (for relaterte Resultater). Alternativt
  • tittel/I18N: Tittel på X språk
  • beskrivelse/I18N: Beskrivelse på X språk
  • start_dato: dato for når resultat starter oppgave (format YYYY-MM-DD)
  • slutt_dato: dato for når resultater avslutter oppgave (format YYYY-MM-DD)
  • status/id: ID for Status for dette resultatet
  • fremgang: Prosent (fra 0 to 100) av oppgaven
  • forslag_id: intern ID for relaterte forslag (separert med komma). Det blir automatisk konvertert til forslag_url
" - link: lenke title: Importere resultater fra CSV imports: create: diff --git a/decidim-accountability/config/locales/oc-FR.yml b/decidim-accountability/config/locales/oc-FR.yml new file mode 100644 index 0000000000000..325b348894124 --- /dev/null +++ b/decidim-accountability/config/locales/oc-FR.yml @@ -0,0 +1 @@ +oc: diff --git a/decidim-accountability/config/locales/pl.yml b/decidim-accountability/config/locales/pl.yml index 1fcd7c0c4cb91..4428cafb69fb9 100644 --- a/decidim-accountability/config/locales/pl.yml +++ b/decidim-accountability/config/locales/pl.yml @@ -50,9 +50,8 @@ pl: results: Wyniki import_results: new: + download_export: Pobierz Eksport w formacie CSV import: Importuj - info: "

Zalecamy wykonanie następujących kroków:

  1. Utwórz Statusy dla Wyników, które chcesz dodać (link)
  2. Utwórz co najmniej jeden wynik ręcznie z poziomu tego Panelu administracyjnego (link) przed wybraniem opcji Importuj, aby lepiej zrozumieć format oraz jakie informacje należy załączyć.
  3. Pobierz plik Eksport w formacie CSV (%{link_export_csv})
  4. Wprowadź zmiany lokalnie. Możesz zmienić tylko następujące kolumny pliku CSV:
  • kategoria/id: ID kategorii
  • zakres/id: ID zakresu
  • element nadrzędny/id: ID elementu nadrzędnego (dla powiązanych wyników). Opcjonalnie
  • tytuł/I18N: Tytuł w języku X
  • opis/I18N: Opis w języku X
  • start_date: data rozpoczęcia pracy nad utworzeniem wyniku (format RRRR-MM-DD)
  • end_date: data zakończenia pracy nad utworzeniem wyniku (format RRRR-MM-DD)
  • status/id: ID statusu dla tego wyniku
  • postęp: Postęp prac nad wynikiem wyrażony procentowo (od 0 do 100)
  • proposals_ids: wewnętrzne ID powiązanych propozycji (oddzielone przecinkiem). Jest ono automatycznie konwertowane na proposal_url
" - link: link title: Importuj wyniki z CSV imports: create: diff --git a/decidim-accountability/config/locales/pt-BR.yml b/decidim-accountability/config/locales/pt-BR.yml index eff62079183cd..8dbbad22378ba 100644 --- a/decidim-accountability/config/locales/pt-BR.yml +++ b/decidim-accountability/config/locales/pt-BR.yml @@ -48,9 +48,8 @@ pt-BR: results: Resultados import_results: new: + download_export: Baixe a Exportação com formato CSV import: Importar - info: "

Nós recomendamos que vosê siga os seguintes passos:

  1. Crie os Status para os Resultados que você gostaria de adicionar(link)
  2. Crie o último Resultado manualmente através do Painel de Administração(link) antes de usar Importação, para ter um melhor entendimento do formato e o que você precisa preencher.
  3. Baixe a Exportação em formato CSV (%{link_export_csv})
  4. Faça as mudanças localmente. Você só pode fazer mudanças nas seguintes colunas do CSV:
  • categoria/id: ID da Categoria
  • escopo/id: ID do Escopo
  • pai/id: ID do pai(para resultados Relacionados). Opcional
  • Título/I18N: Título na liinguagem X
  • Descrição/I18N: Descrição na linguagem X
  • data_inicial: data em que os resultados começaram a ser executados (formato YYYY-MM-DD)
  • data_final: em que os resultados pararam de ser executados (formato YYYY-MM-DD)
  • status/id: ID do Status para este resultado
  • progresso: Percentual (De 0 a 100) de execução
  • id_propostas: ID interno relacionado às propostas (separados por vírgula). Ele é convertido automaticamente paraurl_proposta
" - link: link title: Importar resultados de CSV imports: create: @@ -204,6 +203,8 @@ pt-BR: label: Status components: accountability: + actions: + comment: Comentário name: Prestação de contas settings: global: diff --git a/decidim-accountability/config/locales/pt.yml b/decidim-accountability/config/locales/pt.yml index 7a3669a2fb5c7..de881e94778ea 100644 --- a/decidim-accountability/config/locales/pt.yml +++ b/decidim-accountability/config/locales/pt.yml @@ -49,8 +49,6 @@ pt: import_results: new: import: Importar - info: "

Recomendamos que siga os seguintes passos:

  1. Crie os Estados para os Resultados que deseja adicionar (hiperligação)
  2. Crie pelo menos um Resultado de forma manual através deste painel de Administrador (link) antes de usar Importar, para obter uma melhor compreensão do formato e daquilo que terá de preencher.
  3. Transfira a Exportação com o formato CSV (%{link_export_csv})
  4. Faça as alterações localmente. Apenas poderá alterar as seguintes colunas do CSV:
  • categoria/id: ID para a Categoria
  • âmbito/id: ID para o Âmbito
  • principal/id: ID do principal (para os Resultados relacionados). Opcional
  • título/I18N: Título no idioma X
  • descrição/I18N: Descrição no idioma X
  • data_início: data na qual o resultado inicia a execução (formato AAAA-MM-DD)
  • data_fim: data na qual o resultado termina a execução (formato AAAA-MM-DD)
  • estado/id: ID do Estado para este resultado
  • progresso: Percentagem (de 0 a 100) da execução
  • ids_propostas: ID interna das propostas relacionadas (separado por vírgula). Automaticamente convertido para url_proposta
" - link: hiperligação title: Importar resultados do CSV imports: create: diff --git a/decidim-accountability/config/locales/ro-RO.yml b/decidim-accountability/config/locales/ro-RO.yml index 2c7d7f1a2f370..9c354f76552c6 100644 --- a/decidim-accountability/config/locales/ro-RO.yml +++ b/decidim-accountability/config/locales/ro-RO.yml @@ -50,8 +50,6 @@ ro: import_results: new: import: Importă - info: "

Vă recomandăm să urmați aceste etape:

  1. Creați statutele pentru rezultatele pe care doriți să le adăugați (link)
  2. Creați manual cel puțin un rezultat prin acest panou de administrare (link) înainte de a folosi funcția Importare, pentru a înțelege mai bine formatul și ceea ce trebuie completat.
  3. Descărcați exportul cu format CVS (%{link_export_csv})
  4. Efectuați modificările local. Puteți modifica numai următoarele coloane din CSV:
  • category/id: ID-ul categoriei
  • scope/id: ID-ul domeniului
  • parent/id: ID-ul elementului părinte (pentru rezultatele corelate). Opțional
  • title/I18N: Titlu în limba X
  • description/I18N: Descriere în limba X
  • start_date: data la care rezultatul începe executarea (format YYYY-MM-DD)
  • end_date: data la care rezultatul încheie executarea (format YYYY-MM-DD)
  • status/id: ID-ul Statutului pentru acest rezultat
  • progres: Procent (de la 0 la 100) de executare
  • proposals_ids: ID-ul intern al propunerilor înrudite (separate prin virgulă). Este automat convertit în proposal_url
" - link: link title: Importați rezultate de la CSV imports: create: diff --git a/decidim-accountability/config/locales/si-LK.yml b/decidim-accountability/config/locales/si-LK.yml index 17496068e8fcf..1b7b24d2d73c1 100644 --- a/decidim-accountability/config/locales/si-LK.yml +++ b/decidim-accountability/config/locales/si-LK.yml @@ -33,7 +33,6 @@ si: import_results: new: import: ආයාත කරන්න - link: සබැඳිය models: result: name: ප්‍රතිඵලය diff --git a/decidim-accountability/config/locales/sk.yml b/decidim-accountability/config/locales/sk.yml index e98f28afe3bf0..0765bcbe9b15e 100644 --- a/decidim-accountability/config/locales/sk.yml +++ b/decidim-accountability/config/locales/sk.yml @@ -48,7 +48,6 @@ sk: import_results: new: import: Importovať - link: odkaz title: Importovať výsledky zo súboru CSV imports: create: diff --git a/decidim-accountability/config/locales/sl.yml b/decidim-accountability/config/locales/sl.yml index 4f4df057ce321..c6309d71815f1 100644 --- a/decidim-accountability/config/locales/sl.yml +++ b/decidim-accountability/config/locales/sl.yml @@ -41,7 +41,6 @@ sl: import_results: new: import: Uvozi - link: povezava title: Uvozi postavke iz CSV datoteke models: result: diff --git a/decidim-accountability/config/locales/sv.yml b/decidim-accountability/config/locales/sv.yml index f78cf1fd18f97..1dd8592457bab 100644 --- a/decidim-accountability/config/locales/sv.yml +++ b/decidim-accountability/config/locales/sv.yml @@ -49,8 +49,6 @@ sv: import_results: new: import: Importera - info: "

Vi rekommenderar att du följer dessa steg:

  1. Skapa statusar för de resultat som du vill lägga till (länk)
  2. Skapa minst ett resultat manuellt genom denna Admin panel (länk) innan du använder Importera, för att ha en bättre förståelse för formatet och vad du behöver för att fylla i.
  3. Ladda ner exporten med CSV-format (%{link_export_csv})
  4. Gör ändringarna lokalt. Du kan bara ändra följande kolumner i CSV:
  • kategori/id: ID för kategorin
  • omfattning/id: ID för omfattningen
  • förälder/id: ID för föräldern (för relaterade resultat). Valfri
  • title/I18N: Titel på X språk
  • beskrivning/I18N: Beskrivning på X språk
  • start_date: datum när resultatet startar exekvering (format YYYY-MM-DD)
  • end_date: datum när resultatet slutar exekvering (format YYYY-MM-DD)
  • status/id: ID för status för detta resultat
  • fortskrider: Procent (från 0 till 100) av exekveringen
  • förslag_ids: internt ID för de relaterade förslagen (separerade med komma). Det konverteras automatiskt till proposal_url
" - link: länk title: Importera resultat från CSV imports: create: diff --git a/decidim-accountability/config/locales/tr-TR.yml b/decidim-accountability/config/locales/tr-TR.yml index af652136e1d94..98753197f080b 100644 --- a/decidim-accountability/config/locales/tr-TR.yml +++ b/decidim-accountability/config/locales/tr-TR.yml @@ -47,8 +47,6 @@ tr: import_results: new: import: İçe aktar - info: "

Bu adımları izlemenizi tavsiye ederiz:

  1. Eklemek istediğiniz Sonuçlar için Statüleri oluşturun (bağlantı)
  2. Biçimi ve neleri doldurmanız gerektiğini daha iyi anlamak için İçe Aktar'ı kullanmadan önce bu Yönetici paneli (bağlantı) aracılığıyla yeniden en az bir Sonuç oluşturun.
  3. Dışa aktarımı CSV formatında indirin (%{link_export_csv})
  4. Değişiklikleri yerel olarak yapın. CSV'nin yalnızca aşağıdaki sütunlarını değiştirebilirsiniz:
  • category/id: Kategori ID
  • scope/id: Kapsam ID
  • parent/id: Üst ID (ilgili Sonuçlar için). İsteğe bağlı
  • title/I18N: X dilinde başlık
  • description/I18N: X dilinde açıklama
  • start_date: sonucun uygulamaya başladığı tarih (biçim YYYY-AA-GG)
  • end_date: sonucun yürütmeyi bitirdiği tarih (biçim YYYY-AA-GG)
  • status/id: Durum ID
  • progress: Yürütme yüzdesi (0'dan 100'e)
  • proposals_ids: İlgili tekliflerin ID'leri (virgülle ayrılmış). Otomatik olarak proposal_url'e dönüştürülür
" - link: bağlantı title: Sonuçları CSV'den içe aktar imports: create: diff --git a/decidim-accountability/config/locales/zh-CN.yml b/decidim-accountability/config/locales/zh-CN.yml index d0c56b8910d5f..8c7472b1b0196 100644 --- a/decidim-accountability/config/locales/zh-CN.yml +++ b/decidim-accountability/config/locales/zh-CN.yml @@ -45,7 +45,6 @@ zh-CN: import_results: new: import: 导入 - link: 链接 title: 从 CSV 导入结果 imports: create: diff --git a/decidim-accountability/lib/decidim/accountability/component.rb b/decidim-accountability/lib/decidim/accountability/component.rb index bcbbb21331cc2..1c7ad7bc4cdc7 100644 --- a/decidim-accountability/lib/decidim/accountability/component.rb +++ b/decidim-accountability/lib/decidim/accountability/component.rb @@ -50,7 +50,7 @@ exports.collection do |component_instance| Decidim::Accountability::Result .where(component: component_instance) - .includes(:category, component: { participatory_space: :organization }) + .includes(:category, :scope, :status, component: { participatory_space: :organization }) end exports.include_in_open_data = true @@ -62,7 +62,7 @@ exports.collection do |component_instance| Decidim::Comments::Export.comments_for_resource( Decidim::Accountability::Result, component_instance - ) + ).includes(:author, :root_commentable, :commentable) end exports.include_in_open_data = true diff --git a/decidim-accountability/lib/decidim/accountability/version.rb b/decidim-accountability/lib/decidim/accountability/version.rb index e9f744f54508f..d9902d7879b53 100644 --- a/decidim-accountability/lib/decidim/accountability/version.rb +++ b/decidim-accountability/lib/decidim/accountability/version.rb @@ -4,7 +4,7 @@ module Decidim # This holds decidim-accountability version. module Accountability def self.version - "0.25.2" + "0.26.4" end end end diff --git a/decidim-accountability/spec/controllers/decidim/accountability/versions_controller_spec.rb b/decidim-accountability/spec/controllers/decidim/accountability/versions_controller_spec.rb new file mode 100644 index 0000000000000..3740e2b872403 --- /dev/null +++ b/decidim-accountability/spec/controllers/decidim/accountability/versions_controller_spec.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require "spec_helper" + +module Decidim + module Accountability + describe VersionsController, versioning: true, type: :controller do + routes { Decidim::Accountability::Engine.routes } + + let(:resource) { create(:result) } + + it_behaves_like "versions controller" + end + end +end diff --git a/decidim-accountability/spec/permissions/decidim/accountability/admin/permissions_spec.rb b/decidim-accountability/spec/permissions/decidim/accountability/admin/permissions_spec.rb index bb765c315b0f4..0c1ee17c03212 100644 --- a/decidim-accountability/spec/permissions/decidim/accountability/admin/permissions_spec.rb +++ b/decidim-accountability/spec/permissions/decidim/accountability/admin/permissions_spec.rb @@ -71,6 +71,27 @@ let(:extra_context) { { result: resource } } it_behaves_like "crud permissions" + + describe "creating a children" do + let(:resource) { create :result, component: accountability_component } + let(:action_subject) { :result } + let(:extra_context) { { result: resource } } + let(:action) do + { scope: :admin, action: :create_children, subject: action_subject } + end + + it { is_expected.to be true } + end + + describe "creating a grandchildren" do + let(:parent_result) { create :result, component: accountability_component } + let(:resource) { create :result, parent: parent_result } + let(:action) do + { scope: :admin, action: :create_children, subject: action_subject } + end + + it_behaves_like "permission is not set" + end end describe "status" do diff --git a/decidim-accountability/spec/shared/manage_child_results_examples.rb b/decidim-accountability/spec/shared/manage_child_results_examples.rb index d2c2df17d2928..b0099159b901b 100644 --- a/decidim-accountability/spec/shared/manage_child_results_examples.rb +++ b/decidim-accountability/spec/shared/manage_child_results_examples.rb @@ -67,6 +67,7 @@ within "table" do expect(page).to have_content("My result") + expect(page).not_to have_selector(".action-icon--plus"), "results grandchildren creation is disallowed" end end diff --git a/decidim-admin/app/commands/decidim/admin/create_import_example.rb b/decidim-admin/app/commands/decidim/admin/create_import_example.rb new file mode 100644 index 0000000000000..f10dc0e714f85 --- /dev/null +++ b/decidim-admin/app/commands/decidim/admin/create_import_example.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Decidim + module Admin + class CreateImportExample < Rectify::Command + def initialize(form) + @form = form + end + + def call + return broadcast(:invalid) if form.invalid? + + broadcast(:ok, form.example) + end + + private + + attr_reader :form + end + end +end diff --git a/decidim-admin/app/commands/decidim/admin/create_static_page.rb b/decidim-admin/app/commands/decidim/admin/create_static_page.rb index 465e8b328894f..a0970d2ef17a9 100644 --- a/decidim-admin/app/commands/decidim/admin/create_static_page.rb +++ b/decidim-admin/app/commands/decidim/admin/create_static_page.rb @@ -34,15 +34,21 @@ def create_page @page = Decidim.traceability.create!( StaticPage, form.current_user, + attributes + ) + end + + def attributes + { + organization: form.organization, title: form.title, slug: form.slug, - content: form.content, show_in_footer: form.show_in_footer, weight: form.weight, topic: form.topic, - organization: form.organization, + content: form.content, allow_public_access: form.allow_public_access - ) + } end def update_organization_tos_version diff --git a/decidim-admin/app/commands/decidim/admin/unblock_user.rb b/decidim-admin/app/commands/decidim/admin/unblock_user.rb index 021183ddfbece..2bc9017cf353a 100644 --- a/decidim-admin/app/commands/decidim/admin/unblock_user.rb +++ b/decidim-admin/app/commands/decidim/admin/unblock_user.rb @@ -39,7 +39,7 @@ def unblock! @blocked_user.blocked = false @blocked_user.blocked_at = nil @blocked_user.block_id = nil - @blocked_user.name = @blocked_user.user_name + @blocked_user.name = @blocked_user.extended_data["user_name"] @blocked_user.save! end end diff --git a/decidim-admin/app/commands/decidim/admin/update_organization_appearance.rb b/decidim-admin/app/commands/decidim/admin/update_organization_appearance.rb index 92d6fabe10cb3..c0c043bf910ab 100644 --- a/decidim-admin/app/commands/decidim/admin/update_organization_appearance.rb +++ b/decidim-admin/app/commands/decidim/admin/update_organization_appearance.rb @@ -102,7 +102,8 @@ def colors_attributes warning: form.warning_color, alert: form.alert_color, highlight: form.highlight_color, - "highlight-alternative": form.highlight_alternative_color + "highlight-alternative": form.highlight_alternative_color, + theme: form.theme_color } } end diff --git a/decidim-admin/app/controllers/concerns/decidim/admin/user_groups/filterable.rb b/decidim-admin/app/controllers/concerns/decidim/admin/user_groups/filterable.rb new file mode 100644 index 0000000000000..4c8d08448c4e9 --- /dev/null +++ b/decidim-admin/app/controllers/concerns/decidim/admin/user_groups/filterable.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require "active_support/concern" + +module Decidim + module Admin + module UserGroups + module Filterable + extend ActiveSupport::Concern + + included do + include Decidim::Admin::Filterable + + private + + def base_query + collection + end + + def search_field_predicate + :name_or_nickname_or_email_cont + end + + def filters + [ + :state_eq + ] + end + + def filters_with_values + { + state_eq: user_groups_states + } + end + + protected + + def user_groups_states + %w(all pending rejected verified) + end + end + end + end + end +end diff --git a/decidim-admin/app/controllers/concerns/decidim/moderated_users/admin/filterable.rb b/decidim-admin/app/controllers/concerns/decidim/moderated_users/admin/filterable.rb new file mode 100644 index 0000000000000..f28028ed53d08 --- /dev/null +++ b/decidim-admin/app/controllers/concerns/decidim/moderated_users/admin/filterable.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +require "active_support/concern" + +module Decidim + module ModeratedUsers + module Admin + module Filterable + extend ActiveSupport::Concern + + included do + include Decidim::Admin::Filterable + + private + + def base_query + collection + end + + def filters + [ + :reports_reason_eq + ] + end + + def filters_with_values + { + reports_reason_eq: report_reasons + } + end + + def dynamically_translated_filters + [] + end + + def search_field_predicate + :user_name_or_user_nickname_or_user_email_cont + end + + def report_reasons + Decidim::UserReport::REASONS + end + + def extra_allowed_params + [:per_page, :blocked] + end + end + end + end + end +end diff --git a/decidim-admin/app/controllers/decidim/admin/block_user_controller.rb b/decidim-admin/app/controllers/decidim/admin/block_user_controller.rb index e9554bd4e2b1e..3a4619d32ed1a 100644 --- a/decidim-admin/app/controllers/decidim/admin/block_user_controller.rb +++ b/decidim-admin/app/controllers/decidim/admin/block_user_controller.rb @@ -21,7 +21,7 @@ def create BlockUser.call(@form) do on(:ok) do flash[:notice] = I18n.t("officializations.block.success", scope: "decidim.admin") - redirect_to officializations_path(q: { name_or_nickname_or_email_cont: user.name }), notice: notice + redirect_to moderated_users_path(blocked: true), notice: notice end on(:invalid) do @@ -44,13 +44,13 @@ def destroy end end - redirect_to officializations_path(q: { name_or_nickname_or_email_cont: user.name }), notice: notice + redirect_to moderated_users_path(blocked: false), notice: notice end private def user - @user ||= Decidim::User.find_by( + @user ||= Decidim::UserBaseEntity.find_by( id: params[:user_id], organization: current_organization ) diff --git a/decidim-admin/app/controllers/decidim/admin/conflicts_controller.rb b/decidim-admin/app/controllers/decidim/admin/conflicts_controller.rb index 3061adb7e90ee..3d39f57690cb2 100644 --- a/decidim-admin/app/controllers/decidim/admin/conflicts_controller.rb +++ b/decidim-admin/app/controllers/decidim/admin/conflicts_controller.rb @@ -6,7 +6,9 @@ class ConflictsController < Decidim::Admin::ApplicationController layout "decidim/admin/users" def index - @conflicts = Decidim::Verifications::Conflict.all + @conflicts = Decidim::Verifications::Conflict.joins(:current_user).where( + decidim_users: { decidim_organization_id: current_organization.id } + ) end def edit diff --git a/decidim-admin/app/controllers/decidim/admin/global_moderations_controller.rb b/decidim-admin/app/controllers/decidim/admin/global_moderations_controller.rb index 0656e5bad36e7..2bdb8c750a854 100644 --- a/decidim-admin/app/controllers/decidim/admin/global_moderations_controller.rb +++ b/decidim-admin/app/controllers/decidim/admin/global_moderations_controller.rb @@ -14,9 +14,9 @@ class GlobalModerationsController < Decidim::Admin::ModerationsController def collection @collection ||= if params[:hidden] - moderations_for_user.where.not(hidden_at: nil) + moderations_for_user.hidden else - moderations_for_user.where(hidden_at: nil) + moderations_for_user.not_hidden end end diff --git a/decidim-admin/app/controllers/decidim/admin/imports_controller.rb b/decidim-admin/app/controllers/decidim/admin/imports_controller.rb index 07c349addc092..679de55e9d478 100644 --- a/decidim-admin/app/controllers/decidim/admin/imports_controller.rb +++ b/decidim-admin/app/controllers/decidim/admin/imports_controller.rb @@ -5,24 +5,24 @@ module Admin # This controller allows admins to import resources from a file. class ImportsController < Decidim::Admin::ApplicationController include Decidim::ComponentPathHelper - helper UserGroupHelper + + helper_method :import_manifest def new enforce_permission_to :import, :component_data, component: current_component - @form = form(Admin::ImportForm).from_params( - { - # We need to set "default" creator because form-class doesn't have context / current_component - # when it sets it's default values. - creator: current_component.manifest.import_manifests.first.creator - }, + raise ActionController::RoutingError, "Not Found" unless import_manifest + + @form = form(import_manifest.form_class).from_params( + { name: import_manifest.name }, current_component: current_component ) end def create enforce_permission_to :import, :component_data, component: current_component + raise ActionController::RoutingError, "Not Found" unless import_manifest - @form = form(Admin::ImportForm).from_params( + @form = form(import_manifest.form_class).from_params( params, current_component: current_component, current_organization: current_organization @@ -31,8 +31,8 @@ def create CreateImport.call(@form) do on(:ok) do |imported_data| flash[:notice] = t("decidim.admin.imports.notice", - number: imported_data.length, - resource_name: imported_data.first.resource_manifest.name.pluralize) + count: imported_data.length, + resource_name: import_manifest.message(:resource_name, count: imported_data.length)) redirect_to manage_component_path(current_component) end @@ -43,8 +43,46 @@ def create end end + def example + enforce_permission_to :import, :component_data, component: current_component + raise ActionController::RoutingError, "Not Found" unless import_manifest + + @form = form(Decidim::Admin::ImportExampleForm).from_params(params).with_context( + current_component: current_component, + current_organization: current_organization + ) + + respond_to do |format| + @form.available_formats.each do |key, mime| + format.public_send(key) do + CreateImportExample.call(@form) do + on(:ok) do |data| + filename = "#{current_component.manifest_name}-#{import_manifest.name}-example.#{key}" + send_data data.read, disposition: :attachment, filename: filename, type: mime + end + + on(:invalid) do + flash[:alert] = t("decidim.admin.imports.example_error") + redirect_to admin_imports_path(current_component, name: import_name) + end + end + end + end + end + end + private + def import_manifest + @import_manifest ||= current_component.manifest.import_manifests.find do |import_manifest| + import_manifest.name.to_s == import_name + end + end + + def import_name + params[:name] + end + def current_component @current_component ||= current_participatory_space.components.find(params[:component_id]) end diff --git a/decidim-admin/app/controllers/decidim/admin/moderated_users_controller.rb b/decidim-admin/app/controllers/decidim/admin/moderated_users_controller.rb index ddcd458e2ba73..bf0c57b707d83 100644 --- a/decidim-admin/app/controllers/decidim/admin/moderated_users_controller.rb +++ b/decidim-admin/app/controllers/decidim/admin/moderated_users_controller.rb @@ -3,14 +3,14 @@ module Decidim module Admin class ModeratedUsersController < Decidim::Admin::ApplicationController - include Decidim::Moderations::Admin::Filterable + include Decidim::ModeratedUsers::Admin::Filterable layout "decidim/admin/users" def index enforce_permission_to :read, :moderate_users - @moderated_users = filtered_collection.page(params[:page]).per(15) + @moderated_users = filtered_collection end def ignore diff --git a/decidim-admin/app/controllers/decidim/admin/moderations_controller.rb b/decidim-admin/app/controllers/decidim/admin/moderations_controller.rb index d648af2dec2c6..048f46a2307c2 100644 --- a/decidim-admin/app/controllers/decidim/admin/moderations_controller.rb +++ b/decidim-admin/app/controllers/decidim/admin/moderations_controller.rb @@ -72,9 +72,9 @@ def unhide def collection @collection ||= begin if params[:hidden] - participatory_space_moderations.where.not(hidden_at: nil) + participatory_space_moderations.hidden else - participatory_space_moderations.where(hidden_at: nil) + participatory_space_moderations.not_hidden end end end diff --git a/decidim-admin/app/controllers/decidim/admin/organization_controller.rb b/decidim-admin/app/controllers/decidim/admin/organization_controller.rb index 14be01e7c8230..b5d566b68c723 100644 --- a/decidim-admin/app/controllers/decidim/admin/organization_controller.rb +++ b/decidim-admin/app/controllers/decidim/admin/organization_controller.rb @@ -15,6 +15,7 @@ def edit def update enforce_permission_to :update, :organization, organization: current_organization @form = form(OrganizationForm).from_params(params) + @form.id = current_organization.id UpdateOrganization.call(current_organization, @form) do on(:ok) do @@ -30,11 +31,11 @@ def update end def users - search(current_organization.users) + search(current_organization.users.available) end def user_entities - search(current_organization.user_entities) + search(current_organization.user_entities.available) end private @@ -51,7 +52,7 @@ def search(relation) query.where("email ILIKE ?", "%#{term}%") ) end - render json: query.all.collect { |u| { value: u.id, label: "#{u.name} (@#{u.nickname}) #{u.email}" } } + render json: query.all.collect { |u| { value: u.id, label: "#{u.name} (@#{u.nickname})" } } else render json: [] end diff --git a/decidim-admin/app/controllers/decidim/admin/resource_permissions_controller.rb b/decidim-admin/app/controllers/decidim/admin/resource_permissions_controller.rb index 1a0ebabda1e95..28a9cca29803b 100644 --- a/decidim-admin/app/controllers/decidim/admin/resource_permissions_controller.rb +++ b/decidim-admin/app/controllers/decidim/admin/resource_permissions_controller.rb @@ -83,7 +83,7 @@ def resource end def manifest_name - @manifest_name ||= resource.manifest.name + @manifest_name ||= resource.resource_manifest.name end def permissions diff --git a/decidim-admin/app/controllers/decidim/admin/scopes_controller.rb b/decidim-admin/app/controllers/decidim/admin/scopes_controller.rb index c32094a5cb054..490e30172b01b 100644 --- a/decidim-admin/app/controllers/decidim/admin/scopes_controller.rb +++ b/decidim-admin/app/controllers/decidim/admin/scopes_controller.rb @@ -10,7 +10,8 @@ class ScopesController < Decidim::Admin::ApplicationController def index enforce_permission_to :read, :scope - @scopes = children_scopes.order(Arel.sql("name->'#{I18n.locale}' ASC")) + field = Arel::Nodes::InfixOperation.new("->", Decidim::Scope.arel_table[:name], Arel::Nodes.build_quoted(I18n.locale)) + @scopes = children_scopes.order(Arel::Nodes::InfixOperation.new("", field, Arel.sql("ASC"))) end def new diff --git a/decidim-admin/app/controllers/decidim/admin/user_groups_controller.rb b/decidim-admin/app/controllers/decidim/admin/user_groups_controller.rb index c3dc6de1d94bd..6c5b8a707b313 100644 --- a/decidim-admin/app/controllers/decidim/admin/user_groups_controller.rb +++ b/decidim-admin/app/controllers/decidim/admin/user_groups_controller.rb @@ -6,6 +6,7 @@ module Admin # class UserGroupsController < Decidim::Admin::ApplicationController include UserGroups + include Decidim::Admin::UserGroups::Filterable before_action :enforce_user_groups_enabled @@ -13,11 +14,8 @@ class UserGroupsController < Decidim::Admin::ApplicationController def index enforce_permission_to :index, :user_group - @query = params[:q] - @state = params[:state] - @user_groups = Decidim::Admin::UserGroupsEvaluation.for(collection, @query, @state) - .page(params[:page]).per(15) + @user_groups = filtered_collection end def verify @@ -56,10 +54,20 @@ def reject private + def filtered_collection + paginate(query.result) + end + + def base_query + Decidim::Admin::UserGroupsEvaluation.for(collection, @query, @state) + end + def collection UserGroup - .includes(:memberships) + .left_outer_joins(:memberships) + .select("decidim_users.*, COUNT(decidim_user_group_memberships.decidim_user_group_id) as users_count") .where(decidim_user_group_memberships: { decidim_user_id: current_organization.users }) + .group(Arel.sql("decidim_users.id")) end end end diff --git a/decidim-admin/app/forms/decidim/admin/block_user_form.rb b/decidim-admin/app/forms/decidim/admin/block_user_form.rb index 451ffcac30e5a..f43e92fa8b7e2 100644 --- a/decidim-admin/app/forms/decidim/admin/block_user_form.rb +++ b/decidim-admin/app/forms/decidim/admin/block_user_form.rb @@ -2,7 +2,7 @@ module Decidim module Admin - # A form object used to officialize users from the admin dashboard. + # A form object used to block users or user groups on the admin dashboard. class BlockUserForm < Form attribute :user_id, Integer attribute :justification, String @@ -15,7 +15,7 @@ def map_model(user) end def user - @user ||= Decidim::User.find_by( + @user ||= Decidim::UserBaseEntity.find_by( id: user_id, organization: current_organization ) diff --git a/decidim-admin/app/forms/decidim/admin/import_example_form.rb b/decidim-admin/app/forms/decidim/admin/import_example_form.rb new file mode 100644 index 0000000000000..bcece5da6b487 --- /dev/null +++ b/decidim-admin/app/forms/decidim/admin/import_example_form.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +module Decidim + module Admin + class ImportExampleForm < Form + attribute :name, String + attribute :format, String + + validates :name, presence: true + validates :format, presence: true + validates :manifest, presence: true + validates :reader_klass, presence: true + validates :example_data, presence: true + + def example + reader.example_file(example_data) + end + + def available_formats + Decidim::Admin::Import::Readers::ACCEPTED_MIME_TYPES + end + + private + + def manifest + @manifest ||= current_component.manifest.import_manifests.find do |import_manifest| + import_manifest.name.to_s == name + end + end + + def example_data + return unless manifest + + manifest.example(self, current_component) + end + + def reader + @reader ||= begin + return unless reader_klass + + reader_klass.new("/dev/null") + end + end + + def reader_klass + @reader_klass ||= Decidim::Admin::Import::Readers.search_by_file_extension(format) + end + end + end +end diff --git a/decidim-admin/app/forms/decidim/admin/import_form.rb b/decidim-admin/app/forms/decidim/admin/import_form.rb index 894e9f4de82fc..6181657402f85 100644 --- a/decidim-admin/app/forms/decidim/admin/import_form.rb +++ b/decidim-admin/app/forms/decidim/admin/import_form.rb @@ -6,36 +6,23 @@ class ImportForm < Form ACCEPTED_MIME_TYPES = Decidim::Admin::Import::Readers::ACCEPTED_MIME_TYPES include Decidim::HasUploadValidations - attribute :creator, String, default: ->(form, _attribute) { form.creators.first[:creator].to_s } + attribute :name, String attribute :file - attribute :user_group_id, Integer validates :file, presence: true - validates :creator, presence: true - validate :accepted_mime_type - validate :check_invalid_lines + validates :name, presence: true + validate :check_accepted_mime_type + validate :check_invalid_file, if: -> { file.present? && accepted_mime_type? } + validate :verify_import, if: -> { file.present? && accepted_mime_type? && !importer.invalid_file? } - def check_invalid_lines - return if file.blank? || !accepted_mime_type - - importer.prepare - invalid_lines = importer.invalid_lines - errors.add(:file, I18n.t("decidim.admin.imports.invalid_lines", invalid_lines: invalid_lines.join(","))) unless invalid_lines.empty? - end - - def file_path - file&.path + def importer + @importer ||= importer_for(file_path, mime_type) end - def mime_type - file&.content_type - end + private - def accepted_mime_type - accepted_mime_types = ACCEPTED_MIME_TYPES.values - return true if accepted_mime_types.include?(mime_type) - # Avoid duplicating error messages - return false if errors[:file].present? + def check_accepted_mime_type + return if accepted_mime_type? errors.add( :file, @@ -46,41 +33,60 @@ def accepted_mime_type end.join(", ") ) ) - false end - def creators - @creators ||= current_component.manifest.import_manifests.map do |manifest| - { creator: manifest.creator, name: manifest.creator.to_s.split("::").last.downcase } - end + def check_invalid_file + return unless importer.invalid_file? + + errors.add(:file, I18n.t("activemodel.errors.new_import.attributes.file.invalid_file")) end - def creator_class - return creator.constantize if creator.is_a?(String) + def verify_import + return if importer.verify - creator + importer.errors.each do |_col, message| + errors.add(:file, message) + end end - def user_group - @user_group ||= Decidim::UserGroup.find_by( - organization: current_organization, - id: user_group_id.to_i - ) + def file_path + file&.path end - def importer - @importer ||= importer_for(file_path, mime_type) + def mime_type + file&.content_type + end + + def creator_class + manifest.creator end def importer_for(filepath, mime_type) - context[:user_group] = user_group Import::ImporterFactory.build( filepath, mime_type, - context: context, + context: importer_context, creator: creator_class ) end + + protected + + def accepted_mime_type? + return true if ACCEPTED_MIME_TYPES.values.include?(mime_type) + + false + end + + def importer_context + context + end + + def manifest + @manifest ||= current_component.manifest.import_manifests.find do |import_manifest| + import_manifest.name.to_s == name + end + end end end end diff --git a/decidim-admin/app/forms/decidim/admin/organization_appearance_form.rb b/decidim-admin/app/forms/decidim/admin/organization_appearance_form.rb index aed6b2ca996a8..6ad5a5134c21f 100644 --- a/decidim-admin/app/forms/decidim/admin/organization_appearance_form.rb +++ b/decidim-admin/app/forms/decidim/admin/organization_appearance_form.rb @@ -36,6 +36,7 @@ class OrganizationAppearanceForm < Form attribute :alert_color, String, default: "#ec5840" attribute :highlight_color, String, default: "#be6400" attribute :highlight_alternative_color, String, default: "#ff5731" + attribute :theme_color, String, default: "#ef604d" translatable_attribute :cta_button_text, String translatable_attribute :description, String diff --git a/decidim-admin/app/forms/decidim/admin/selective_newsletter_form.rb b/decidim-admin/app/forms/decidim/admin/selective_newsletter_form.rb index 5f438183a9af7..a13a73083d3d1 100644 --- a/decidim-admin/app/forms/decidim/admin/selective_newsletter_form.rb +++ b/decidim-admin/app/forms/decidim/admin/selective_newsletter_form.rb @@ -35,7 +35,7 @@ def scope_ids def at_least_one_participatory_space_selected return if send_to_all_users && current_user.admin? - errors.add(:base, "Select atleast one participatory space") if spaces_selected.blank? + errors.add(:base, :at_least_one_space) if spaces_selected.blank? end def spaces_selected diff --git a/decidim-admin/app/helpers/decidim/admin/bulk_actions_helper.rb b/decidim-admin/app/helpers/decidim/admin/bulk_actions_helper.rb index a71ec2694802c..b4f71f596f5f8 100644 --- a/decidim-admin/app/helpers/decidim/admin/bulk_actions_helper.rb +++ b/decidim-admin/app/helpers/decidim/admin/bulk_actions_helper.rb @@ -14,9 +14,8 @@ def proposal_find(id) # Returns a String. def bulk_categories_select(collection) categories = bulk_categories_for_select collection - disabled = bulk_disabled_categories_for collection prompt = t("decidim.proposals.admin.proposals.index.change_category") - select(:category, :id, options_for_select(categories, selected: [], disabled: disabled), prompt: prompt) + select(:category, :id, options_for_select(categories, selected: []), prompt: prompt) end def bulk_categories_for_select(scope) @@ -39,10 +38,6 @@ def bulk_categories_for_select(scope) end end - def bulk_disabled_categories_for(scope) - scope.first_class.joins(:subcategories).pluck(:id) - end - # Public: Generates a select field with the components. # # siblings - A collection of components. diff --git a/decidim-admin/app/helpers/decidim/admin/imports_helper.rb b/decidim-admin/app/helpers/decidim/admin/imports_helper.rb index 1731b69ebfc47..542d3a2ff9da1 100644 --- a/decidim-admin/app/helpers/decidim/admin/imports_helper.rb +++ b/decidim-admin/app/helpers/decidim/admin/imports_helper.rb @@ -12,13 +12,13 @@ module ImportsHelper # resource_id - The resource id that is passed to route. # # Returns a rendered dropdown. - def import_dropdown(component = current_component, resource_id = nil) - locals = { component: component, resource_id: resource_id } - locals[:block] = yield if block_given? - render partial: "decidim/admin/imports/dropdown", locals: locals + def import_dropdown(component = current_component, resource_id: nil) + render "decidim/admin/imports/dropdown", component: component, resource_id: resource_id, custom: block_given? do + yield if block_given? + end end - # Routes to the correct importer for a component. + # Route to the correct importer for a component. # # component - The component to be routed. # options - Extra options that need to be passed to the route. @@ -28,10 +28,20 @@ def admin_imports_path(component, options) EngineRouter.admin_proxy(component.participatory_space).new_component_import_path(options.merge(component_id: component)) end + # Route to the correct importer example for a component. + # + # component - The component to be routed. + # options - Extra options that need to be passed to the route. + # + # Returns the path to the component importer example. + def admin_imports_example_path(component, options) + EngineRouter.admin_proxy(component.participatory_space).example_component_imports_path(options.merge(component_id: component)) + end + # Public: A formatted collection of mime_type to be used in forms. def mime_types accepted_mime_types = Decidim::Admin::Import::Readers::ACCEPTED_MIME_TYPES.keys - accepted_mime_types.map { |mime_type| t("decidim.admin.imports.new.accepted_mime_types.#{mime_type}") }.join(", ") + accepted_mime_types.index_with { |mime_type| I18n.t("decidim.admin.imports.new.accepted_mime_types.#{mime_type}") } end # Returns verified user groups of current user diff --git a/decidim-admin/app/helpers/decidim/admin/newsletters_helper.rb b/decidim-admin/app/helpers/decidim/admin/newsletters_helper.rb index dd25ceee70ff0..0c78d2150aceb 100644 --- a/decidim-admin/app/helpers/decidim/admin/newsletters_helper.rb +++ b/decidim-admin/app/helpers/decidim/admin/newsletters_helper.rb @@ -102,7 +102,7 @@ def organization_participatory_space(manifest_name) .find_participatory_space_manifest(manifest_name) .participatory_spaces.call(current_organization) .published - .sort_by { |space| [space.closed? ? 1 : 0, space.title[current_locale]] } + .sort_by { |space| [space.try(:closed?) ? 1 : 0, space.title[current_locale]] } end def spaces_user_can_admin diff --git a/decidim-admin/app/helpers/decidim/admin/resource_scope_helper.rb b/decidim-admin/app/helpers/decidim/admin/resource_scope_helper.rb index 0b55ff4f1b8df..c3ffb557b16fd 100644 --- a/decidim-admin/app/helpers/decidim/admin/resource_scope_helper.rb +++ b/decidim-admin/app/helpers/decidim/admin/resource_scope_helper.rb @@ -29,6 +29,15 @@ def td_resource_scope_for(current_scope) content_tag(:td, scope_name) end + # Public: This helper shows th with the sort link element. + def th_scope_sort_link + return unless resource_with_scopes_enabled? + + content_tag(:th) do + sort_link(query, :scope_name, t("decidim.admin.resources.index.headers.scope")) + end + end + private def resource_with_scopes_enabled? diff --git a/decidim-admin/app/helpers/decidim/admin/settings_helper.rb b/decidim-admin/app/helpers/decidim/admin/settings_helper.rb index 858665404daf7..56a6abc95cfda 100644 --- a/decidim-admin/app/helpers/decidim/admin/settings_helper.rb +++ b/decidim-admin/app/helpers/decidim/admin/settings_helper.rb @@ -12,21 +12,25 @@ module SettingsHelper integer: :number_field, string: :text_field, text: :text_area, + select: :select_field, scope: :scope_field, enum: :collection_radio_buttons, time: :datetime_field }.freeze - # Public: Renders a form field that matches a settings attribute's - # type. + # Renders a form field that matches a settings attribute's type. + # Besides the field itself, it also renders all the metadata (like the labels and help texts) # - # form - The form in which to render the field. - # attribute - The Settings::Attribute instance with the - # description of the attribute. - # name - The name of the field. - # options - Extra options to be passed to the field helper. - # - # Returns a rendered form field. + # @param form [Decidim::Admin::FormBuilder] The form in which to render the field + # @param attribute [Decidim::SettingsManifest::Attribute] The Settings::Attribute instance with the + # description of the attribute. + # @param name [Symbol] The name of the field. + # @param i18n_scope [String] The scope where it'll find all the texts for the internationalization (locales) + # @param options [Hash] Extra options to be passed to the field helper. + # @option options [String] :tabs_prefix The type of the setting. + # It can be "global-settings" or "step-N-settings", where N is the number of the step. + # @option options [nil, Boolean] :readonly True if the input is readonly. + # @return [ActiveSupport::SafeBuffer] Rendered form field. def settings_attribute_input(form, attribute, name, i18n_scope, options = {}) form_method = form_method_for_attribute(attribute) @@ -49,6 +53,8 @@ def settings_attribute_input(form, attribute, name, i18n_scope, options = {}) form.send(:translated, form_method, name, options) elsif form_method == :collection_radio_buttons render_enum_form_field(form, attribute, name, i18n_scope, options) + elsif form_method == :select_field + render_select_form_field(form, attribute, name, i18n_scope, options) elsif form_method == :scope_field scopes_picker_field(form, name) else @@ -59,7 +65,40 @@ def settings_attribute_input(form, attribute, name, i18n_scope, options = {}) private + # Renders a select field collection input for the given attribute + # + # @param form (see #settings_attribute_input) + # @param attribute (see #settings_attribute_input) + # @param name (see #settings_attribute_input) + # @param i18n_scope (see #settings_attribute_input) + # @param options (see #settings_attribute_input) + # @option :tabs_prefix (see #settings_attribute_input) + # @option :readonly (see #settings_attribute_input) + # @option options [String] :label The label that this field has + # @option options [String] :help_text The help text shown after the input field + # @return (see #settings_attribute_input) + def render_select_form_field(form, attribute, name, i18n_scope, options) + html = form.select( + name, + attribute.build_choices.map { |o| [t("#{name}_options.#{o}", scope: i18n_scope), o] }, + { include_blank: attribute.include_blank, label: options[:label] } + ) + html << content_tag(:p, options[:help_text], class: "help-text") if options[:help_text] + html + end + # Returns a radio buttons collection input for the given attribute + # + # @param form (see #settings_attribute_input) + # @param attribute (see #settings_attribute_input) + # @param name (see #settings_attribute_input) + # @param i18n_scope (see #settings_attribute_input) + # @param options (see #settings_attribute_input) + # @option :tabs_prefix (see #settings_attribute_input) + # @option :readonly (see #settings_attribute_input) + # @option :label (see #render_select_form_field) + # @option :help_text (see #render_select_form_field) + # @return (see #settings_attribute_input) def render_enum_form_field(form, attribute, name, i18n_scope, options) html = label_tag(name) do concat options[:label] @@ -75,13 +114,25 @@ def render_enum_form_field(form, attribute, name, i18n_scope, options) html end + # Get the translation for a given attribute # Returns a translation or nil. If nil, ZURB Foundation won't add the help_text. + # + # @param name (see #settings_attribute_input) + # @param suffix [String] What suffix the i18n key has + # @param i18n_scope (see #settings_attribute_input) + # @return [String, nil] def text_for_setting(name, suffix, i18n_scope) + html_key = "#{i18n_scope}.#{name}_#{suffix}_html" + return t(html_key) if I18n.exists?(html_key) + key = "#{i18n_scope}.#{name}_#{suffix}" return t(key) if I18n.exists?(key) end - # Returns the FormBuilder's method used to render + # Which form method is being used for this attribute + # + # @param attribute [Decidim::SettingsManifest::Attribute] + # @return [Symbol] The FormBuilder's method used to render def form_method_for_attribute(attribute) return :editor if attribute.type.to_sym == :text && attribute.editor? @@ -89,7 +140,9 @@ def form_method_for_attribute(attribute) end # Handles special cases. - # Returns an empty Hash or a Hash with extra HTML options. + # + # @param input_type [Symbol] + # @return [Hash] Empty Hash or a Hash with extra HTML options. def extra_options_for_type(input_type) case input_type when :text_area @@ -100,6 +153,12 @@ def extra_options_for_type(input_type) end # Build options for enum attributes + # Get the translation for a given attribute of type choice + # + # @param name (see #settings_attribute_input) + # @param i18n_scope (see #settings_attribute_input) + # @param choices [Array] + # @return [Array>] def build_enum_choices(name, i18n_scope, choices) choices.map do |choice| [t("#{name}_choices.#{choice}", scope: i18n_scope), choice] diff --git a/decidim-admin/app/packs/entrypoints/decidim_admin.js b/decidim-admin/app/packs/entrypoints/decidim_admin.js index 996881d5ff9ee..98e1bbc937461 100644 --- a/decidim-admin/app/packs/entrypoints/decidim_admin.js +++ b/decidim-admin/app/packs/entrypoints/decidim_admin.js @@ -14,13 +14,12 @@ import "jquery.autocomplete" import "jquery-serializejson" import "src/decidim/admin/tab_focus" -import "src/decidim/admin/choose_language" +import initLanguageChangeSelect from "src/decidim/admin/choose_language" import "src/decidim/admin/application" import "src/decidim/admin/resources_permissions" import "src/decidim/admin/welcome_notification" import "src/decidim/admin/newsletters" import "src/decidim/admin/form" -import "src/decidim/admin/import_guidance" import "src/decidim/admin/external_domain_whitelist" import "src/decidim/confirm" import "src/decidim/admin/draggable-list" @@ -41,3 +40,7 @@ import "entrypoints/decidim_admin.scss"; // This needs to be loaded after confirm dialog to bind properly Rails.start() + +window.addEventListener("DOMContentLoaded", () => { + initLanguageChangeSelect(document.querySelectorAll("select.language-change")); +}); diff --git a/decidim-admin/app/packs/src/decidim/admin/choose_language.js b/decidim-admin/app/packs/src/decidim/admin/choose_language.js index a378ccf68ad65..631256d4da9f7 100644 --- a/decidim-admin/app/packs/src/decidim/admin/choose_language.js +++ b/decidim-admin/app/packs/src/decidim/admin/choose_language.js @@ -1,12 +1,14 @@ /* eslint-disable no-invalid-this */ +/* eslint-disable require-jsdoc */ -$(() => { - $("select.language-change").change(function () { - let $select = $(this); - let targetTabPaneSelector = $select.val(); - let $tabsContent = $select.parent().parent().siblings(); +export default function initLanguageChangeSelect(elements) { + elements.forEach((select) => { + select.addEventListener("change", () => { + let targetTabPaneSelector = select.value; + let tabsContent = select.parentElement.parentElement.nextElementSibling; - $tabsContent.children(".is-active").removeClass("is-active"); - $tabsContent.children(targetTabPaneSelector).addClass("is-active"); - }) -}); + tabsContent.querySelector(".is-active").classList.remove("is-active"); + tabsContent.querySelector(targetTabPaneSelector).classList.add("is-active"); + }) + }); +} diff --git a/decidim-admin/app/packs/src/decidim/admin/dynamic_fields.component.js b/decidim-admin/app/packs/src/decidim/admin/dynamic_fields.component.js index c13c7dc656f33..85fd6b165de5b 100644 --- a/decidim-admin/app/packs/src/decidim/admin/dynamic_fields.component.js +++ b/decidim-admin/app/packs/src/decidim/admin/dynamic_fields.component.js @@ -6,8 +6,10 @@ class DynamicFieldsComponent { this.fieldSelector = options.fieldSelector; this.addFieldButtonSelector = options.addFieldButtonSelector; this.addSeparatorButtonSelector = options.addSeparatorButtonSelector; + this.addTitleAndDescriptionButtonSelector = options.addTitleAndDescriptionButtonSelector; this.fieldTemplateSelector = options.fieldTemplateSelector; this.separatorTemplateSelector = options.separatorTemplateSelector; + this.TitleAndDescriptionTemplateSelector = options.TitleAndDescriptionTemplateSelector; this.removeFieldButtonSelector = options.removeFieldButtonSelector; this.moveUpFieldButtonSelector = options.moveUpFieldButtonSelector; this.moveDownFieldButtonSelector = options.moveDownFieldButtonSelector; @@ -68,6 +70,7 @@ class DynamicFieldsComponent { $(this).replaceAttribute("for", placeholder, value); $(this).replaceAttribute("tabs_id", placeholder, value); $(this).replaceAttribute("href", placeholder, value); + $(this).replaceAttribute("value", placeholder, value); return this; } @@ -84,6 +87,12 @@ class DynamicFieldsComponent { ); } + if (this.addTitleAndDescriptionButtonSelector) { + $(this.wrapperSelector).on("click", this.addTitleAndDescriptionButtonSelector, (event) => + this._bindSafeEvent(event, () => this._addField(this.TitleAndDescriptionTemplateSelector)) + ); + } + $(this.wrapperSelector).on("click", this.removeFieldButtonSelector, (event) => this._bindSafeEvent(event, (target) => this._removeField(target)) ); diff --git a/decidim-admin/app/packs/src/decidim/admin/import_guidance.js b/decidim-admin/app/packs/src/decidim/admin/import_guidance.js deleted file mode 100644 index 2eea096f1a3c0..0000000000000 --- a/decidim-admin/app/packs/src/decidim/admin/import_guidance.js +++ /dev/null @@ -1,28 +0,0 @@ -$(() => { - const $creatorSelect = $("#import_creator"); - const $creatorGuidances = $(".creator-guidances").find(".guidance"); - - const showGuidance = (text) => { - const formatted = text.replace(/\s/g, "").toLocaleLowerCase(); - $.each($creatorGuidances, (_index, currentValue) => { - if (currentValue.className.includes(formatted)) { - const elem = $(currentValue) - elem.show(); - } - }) - } - - $creatorSelect.on("change", function() { - const text = $("#import_creator option:selected").text() - $creatorGuidances.hide(); - if (text) { - showGuidance(text) - } - }) - - if ($creatorSelect.children("option").length < 2) { - $("label[for='import_creator']").hide(); - } - $creatorGuidances.hide(); - $creatorGuidances.first().show(); -}) diff --git a/decidim-admin/app/packs/stylesheets/decidim/admin/modules/_forms.scss b/decidim-admin/app/packs/stylesheets/decidim/admin/modules/_forms.scss index 519b151442c65..b4e3e52803c30 100644 --- a/decidim-admin/app/packs/stylesheets/decidim/admin/modules/_forms.scss +++ b/decidim-admin/app/packs/stylesheets/decidim/admin/modules/_forms.scss @@ -116,6 +116,12 @@ label, margin-bottom: $input-margin; } +.form-input-extra-before{ + margin-bottom: $form-spacing * 1.5; + display: block; + margin-top: $form-spacing * -1; +} + .custom-error{ @extend .form-error; } diff --git a/decidim-admin/app/packs/stylesheets/decidim/admin/modules/_import_result.scss b/decidim-admin/app/packs/stylesheets/decidim/admin/modules/_import_result.scss deleted file mode 100644 index 8842b24b726fa..0000000000000 --- a/decidim-admin/app/packs/stylesheets/decidim/admin/modules/_import_result.scss +++ /dev/null @@ -1,10 +0,0 @@ -.new_import .import-process-info{ - margin-top: 1em; - font-style: italic; - - span.attribute-name{ - background-color: lightgrey; - font-style: normal; - padding: 1px 4px; - } -} diff --git a/decidim-admin/app/packs/stylesheets/decidim/admin/modules/_modules.scss b/decidim-admin/app/packs/stylesheets/decidim/admin/modules/_modules.scss index 6c209a5f036cf..9d43d857829ce 100644 --- a/decidim-admin/app/packs/stylesheets/decidim/admin/modules/_modules.scss +++ b/decidim-admin/app/packs/stylesheets/decidim/admin/modules/_modules.scss @@ -29,7 +29,6 @@ @import "stylesheets/decidim/admin/modules/agenda"; @import "stylesheets/decidim/admin/modules/draggable-list"; @import "stylesheets/decidim/admin/modules/loading-spinner"; -@import "stylesheets/decidim/admin/modules/import_result"; @import "stylesheets/decidim/admin/modules/reveal"; // mentions__container diff --git a/decidim-admin/app/permissions/decidim/admin/permissions.rb b/decidim-admin/app/permissions/decidim/admin/permissions.rb index cbc837d22b291..a5c4812e68e34 100644 --- a/decidim-admin/app/permissions/decidim/admin/permissions.rb +++ b/decidim-admin/app/permissions/decidim/admin/permissions.rb @@ -29,12 +29,14 @@ def permissions read_admin_dashboard_action? apply_newsletter_permissions_for_admin! - allow! if permission_action.subject == :global_moderation + allow! if permission_action.subject == :global_moderation && admin_terms_accepted? if user.admin? && admin_terms_accepted? allow! if read_admin_log_action? + allow! if read_user_statistics_action? allow! if read_metrics_action? allow! if static_page_action? + allow! if templates_action? allow! if organization_action? allow! if user_action? @@ -42,6 +44,7 @@ def permissions allow! if permission_action.subject == :component allow! if permission_action.subject == :admin_user allow! if permission_action.subject == :attachment + allow! if permission_action.subject == :editor_image allow! if permission_action.subject == :attachment_collection allow! if permission_action.subject == :scope allow! if permission_action.subject == :scope_type @@ -100,6 +103,11 @@ def space_allows_admin_access? end end + def read_user_statistics_action? + permission_action.subject == :users_statistics && + permission_action.action == :read + end + def read_metrics_action? permission_action.subject == :metrics && permission_action.action == :read @@ -127,6 +135,11 @@ def static_page_action? end end + def templates_action? + permission_action.subject == :templates && + permission_action.action == :read + end + def organization_action? return unless permission_action.subject == :organization return unless permission_action.action == :update @@ -138,6 +151,7 @@ def managed_user_action? return unless permission_action.subject == :managed_user return user_manager_permissions if user_manager? return unless user&.admin? + return unless user&.admin_terms_accepted? case permission_action.action when :create @@ -182,7 +196,7 @@ def user_can_enter_space_area?(**args) def space_allows_admin_access_to_current_action?(require_admin_terms_accepted: false) Decidim.participatory_space_manifests.any? do |manifest| - next if manifest.name != :initiatives && require_admin_terms_accepted && !admin_terms_accepted? + next if require_admin_terms_accepted && !admin_terms_accepted? new_permission_action = Decidim::PermissionAction.new( action: permission_action.action, diff --git a/decidim-admin/app/queries/decidim/admin/newsletter_recipients.rb b/decidim-admin/app/queries/decidim/admin/newsletter_recipients.rb index c58e9b59beb34..a2b8e21f78689 100644 --- a/decidim-admin/app/queries/decidim/admin/newsletter_recipients.rb +++ b/decidim-admin/app/queries/decidim/admin/newsletter_recipients.rb @@ -51,11 +51,12 @@ def spaces @spaces ||= @form.participatory_space_types.map do |type| next if type.ids.blank? - object_class = "Decidim::#{type.manifest_name.classify}" + object_class = Decidim.participatory_space_registry.find(type.manifest_name).model_class_name.constantize + if type.ids.include?("all") - object_class.constantize.where(organization: @organization) + object_class.where(organization: @organization) else - object_class.constantize.where(id: type.ids.reject(&:blank?)) + object_class.where(id: type.ids.reject(&:blank?)) end end.flatten.compact end diff --git a/decidim-admin/app/views/decidim/admin/dashboard/show.html.erb b/decidim-admin/app/views/decidim/admin/dashboard/show.html.erb index e5511800ca442..495c7c68482a2 100644 --- a/decidim-admin/app/views/decidim/admin/dashboard/show.html.erb +++ b/decidim-admin/app/views/decidim/admin/dashboard/show.html.erb @@ -12,7 +12,7 @@ <% end %>
- <% if current_user.admin? && current_user.organization&.id == current_organization.id %> + <% if allowed_to? :read, :users_statistics %>
<%= render( partial: "decidim/admin/users_statistics/users_count", diff --git a/decidim-admin/app/views/decidim/admin/imports/_dropdown.html.erb b/decidim-admin/app/views/decidim/admin/imports/_dropdown.html.erb index d911d5c388742..232dd39365e25 100644 --- a/decidim-admin/app/views/decidim/admin/imports/_dropdown.html.erb +++ b/decidim-admin/app/views/decidim/admin/imports/_dropdown.html.erb @@ -1,9 +1,14 @@ <%= t "actions.import", scope: "decidim.admin" %> diff --git a/decidim-admin/app/views/decidim/admin/imports/new.html.erb b/decidim-admin/app/views/decidim/admin/imports/new.html.erb index 9290e99b86b32..653a0162512ed 100644 --- a/decidim-admin/app/views/decidim/admin/imports/new.html.erb +++ b/decidim-admin/app/views/decidim/admin/imports/new.html.erb @@ -1,38 +1,40 @@ -<%= decidim_form_for(@form, url: component_imports_path, class: "form grid-container") do |form| %> +<%= decidim_form_for(@form, url: component_imports_path(name: import_manifest.name), class: "form grid-container") do |form| %>
-

+
+
+ <%= import_manifest.message(:title, self) %> +
+ <% if import_manifest.has_example? %> + <%= t(".download_example") %> + + <% end %> + <%= link_to t(".actions.back"), manage_component_path(@current_component), class: "button hollow tiny button--simple" %>
-

+
-
- <%= - form.select :creator, - @form.creators.map { |m| [t("decidim.admin.imports.creators.#{m[:name]}"), m[:creator]] }, - { prompt: true } - %> -
- <% if current_organization.user_groups_enabled? && Decidim::UserGroups::ManageableUserGroups.for(current_user).verified.any? %> -
- <%= user_group_select_field form, :user_group_id %> -
- <% end %> + <%= render partial: import_manifest.form_view, locals: { form: form } if import_manifest.form_view %>
- <%= t(".file_legend", valid_mime_types: mime_types).html_safe %> -
- <% @form.creators.each do |creator| %> - <%= content_tag :div, class: "guidance creator-#{creator[:name]}" do %> - <% t("decidim.admin.imports.help.#{creator[:name]}") %> - <% end %> - <% end %> + <%= t(".file_legend", valid_mime_types: mime_types.values.join(", ")).html_safe %> +
+ <%= import_manifest.message(:help, self).html_safe %>
diff --git a/decidim-admin/app/views/decidim/admin/moderated_users/_report.html.erb b/decidim-admin/app/views/decidim/admin/moderated_users/_report.html.erb index ff1114403369c..38934979d838d 100644 --- a/decidim-admin/app/views/decidim/admin/moderated_users/_report.html.erb +++ b/decidim-admin/app/views/decidim/admin/moderated_users/_report.html.erb @@ -3,7 +3,6 @@ <% else %> <%= t(".reasons.#{report.reason}") %> diff --git a/decidim-admin/app/views/decidim/admin/moderated_users/index.html.erb b/decidim-admin/app/views/decidim/admin/moderated_users/index.html.erb index f686b77d8668c..d76ff812e4db7 100644 --- a/decidim-admin/app/views/decidim/admin/moderated_users/index.html.erb +++ b/decidim-admin/app/views/decidim/admin/moderated_users/index.html.erb @@ -1,4 +1,4 @@ -
+

<%= t(".title") %> @@ -27,6 +27,8 @@

+ <%= admin_filter_selector(:moderated_users) %> +
@@ -58,8 +60,8 @@
- <% if allowed_to?(:unreport, :moderate_users) %> - <%= icon_link_to "action-undo", ignore_moderated_user_path(id: moderation), t(".actions.unreport"), class: "action-icon--unreport", method: :put %> + <% if !moderation.user.blocked? && allowed_to?(:unreport, :moderate_users) %> + <%= icon_link_to "action-undo", ignore_moderated_user_path(id: moderation), t(".actions.unreport"), class: "action-icon--unreport", method: :put %> <% end %> <% if allowed_to?(:block, :moderate_users) %> <% if moderation.user.blocked? %> @@ -73,6 +75,7 @@ <% end %>
+ <%= paginate @moderated_users, theme: "decidim" %>
diff --git a/decidim-admin/app/views/decidim/admin/moderations/_report.html.erb b/decidim-admin/app/views/decidim/admin/moderations/_report.html.erb index ff1114403369c..38934979d838d 100644 --- a/decidim-admin/app/views/decidim/admin/moderations/_report.html.erb +++ b/decidim-admin/app/views/decidim/admin/moderations/_report.html.erb @@ -3,7 +3,6 @@ <% else %> <%= t(".reasons.#{report.reason}") %> diff --git a/decidim-admin/app/views/decidim/admin/moderations/index.html.erb b/decidim-admin/app/views/decidim/admin/moderations/index.html.erb index 5f86c6775010e..5e4329b9f3323 100644 --- a/decidim-admin/app/views/decidim/admin/moderations/index.html.erb +++ b/decidim-admin/app/views/decidim/admin/moderations/index.html.erb @@ -37,7 +37,7 @@ <%= moderation.reportable.id %> - <%= moderation.reportable.class.name.demodulize %> + <%= moderation.reportable.class.model_name.human %> <% if !respond_to?(:current_participatory_space) %> @@ -48,9 +48,13 @@ <%= moderation.report_count %> - <%= - link_to t("models.moderation.fields.visit_url", scope: "decidim.moderations"), moderation.reportable.reported_content_url, data: { tooltip: true }, aria: { haspopup: true }, title: strip_tags(reported_content_excerpt_for(moderation.reportable, limit: 250)) - %> + <% if (reportable_url = moderation.reportable.reported_content_url) %> + <%= + link_to t("models.moderation.fields.visit_url", scope: "decidim.moderations"), reportable_url, data: { tooltip: true }, title: strip_tags(reported_content_excerpt_for(moderation.reportable, limit: 250)) + %> + <% else %> + <%= t("models.moderation.fields.deleted_resource", scope: "decidim.moderations") %> + <% end %> <% reports = moderation.reports.map { |report| render "report", report: report } %> diff --git a/decidim-admin/app/views/decidim/admin/moderations/reports/index.html.erb b/decidim-admin/app/views/decidim/admin/moderations/reports/index.html.erb index 821c3122266c1..d15de49ca03f2 100644 --- a/decidim-admin/app/views/decidim/admin/moderations/reports/index.html.erb +++ b/decidim-admin/app/views/decidim/admin/moderations/reports/index.html.erb @@ -12,7 +12,11 @@
<%= t("models.moderation.fields.reported_content_url", scope: "decidim.moderations") %>
-
<%= link_to moderation.reportable.reported_content_url, moderation.reportable.reported_content_url, target: "_blank" %>
+ <% if (reportable_url = moderation.reportable.reported_content_url) %> +
<%= link_to moderation.reportable.reported_content_url, reportable_url, target: "_blank" %>
+ <% else %> +
<%= t("models.moderation.fields.deleted_resource", scope: "decidim.moderations") %>
+ <% end %>
<%= t("models.moderation.fields.reportable_id", scope: "decidim.moderations") %>
<%= moderation.reportable.id %>
diff --git a/decidim-admin/app/views/decidim/admin/organization_appearance/form/_colors.html.erb b/decidim-admin/app/views/decidim/admin/organization_appearance/form/_colors.html.erb index 69379bcc9c486..155491d41d7f7 100644 --- a/decidim-admin/app/views/decidim/admin/organization_appearance/form/_colors.html.erb +++ b/decidim-admin/app/views/decidim/admin/organization_appearance/form/_colors.html.erb @@ -3,6 +3,12 @@

<%= t ".colors_title" %>

+
+

+ <%= icon "warning" %> + <%= t ".colors_warning_html", link: "https://webaim.org/resources/contrastchecker" %> +

+
<%= form.color_field :primary_color, value: current_organization.colors["primary"] %> <%= form.color_field :secondary_color, value: current_organization.colors["secondary"] %> @@ -11,6 +17,7 @@ <%= form.color_field :alert_color, value: current_organization.colors["alert"] %> <%= form.color_field :highlight_color, value: current_organization.colors["highlight"] %> <%= form.color_field :highlight_alternative_color, value: current_organization.colors["highlight-alternative"] %> + <%= form.color_field :theme_color, value: current_organization.colors["theme"] %>
<% if Decidim.enable_html_header_snippets %> diff --git a/decidim-admin/app/views/decidim/admin/participatory_space_private_users/index.html.erb b/decidim-admin/app/views/decidim/admin/participatory_space_private_users/index.html.erb index 7e25b2c148efc..78378ca138a13 100644 --- a/decidim-admin/app/views/decidim/admin/participatory_space_private_users/index.html.erb +++ b/decidim-admin/app/views/decidim/admin/participatory_space_private_users/index.html.erb @@ -15,10 +15,18 @@ - - - - + + + + diff --git a/decidim-admin/app/views/decidim/admin/resource_permissions/edit.html.erb b/decidim-admin/app/views/decidim/admin/resource_permissions/edit.html.erb index 4bd55ce04a5b2..e519e86152201 100644 --- a/decidim-admin/app/views/decidim/admin/resource_permissions/edit.html.erb +++ b/decidim-admin/app/views/decidim/admin/resource_permissions/edit.html.erb @@ -21,7 +21,7 @@ <% if @component %>
<%= t("#{@component.manifest.name}.actions.#{action}", scope: "decidim.components") %>
<% else %> -
<%= t("#{resource.manifest.name}.actions.#{action}", scope: "decidim.resources") %>
+
<%= t("#{resource.resource_manifest.name}.actions.#{action}", scope: "decidim.resources") %>
<% end %>
diff --git a/decidim-admin/app/views/decidim/admin/user_groups/index.html.erb b/decidim-admin/app/views/decidim/admin/user_groups/index.html.erb index 6aa15592ce5c8..456a090523023 100644 --- a/decidim-admin/app/views/decidim/admin/user_groups/index.html.erb +++ b/decidim-admin/app/views/decidim/admin/user_groups/index.html.erb @@ -1,41 +1,3 @@ -
-
- <%= t(".filter_by") %> : - -
-
- <%= form_tag "", method: :get do %> - - <% end %> -
-
-

@@ -43,17 +5,19 @@ <%= link_to t(".verify_via_csv"), new_user_groups_csv_verification_path, class: "button tiny button--title" %>

+ <%= admin_filter_selector %> +
<%= t("models.assembly_user_role.fields.name", scope: "decidim.admin") %><%= t("models.assembly_user_role.fields.email", scope: "decidim.admin") %><%= t("models.user.fields.invitation_sent_at", scope: "decidim.admin") %><%= t("models.user.fields.invitation_accepted_at", scope: "decidim.admin") %> + <%= sort_link(query, :name, t("models.user.fields.name", scope: "decidim.admin"), default_order: :desc ) %> + + <%= sort_link(query, :email, t("models.user.fields.email", scope: "decidim.admin"), default_order: :desc ) %> + + <%= sort_link(query, :invitation_sent_at, t("models.user.fields.invitation_sent_at", scope: "decidim.admin"), default_order: :desc ) %> + + <%= sort_link(query, :invitation_accepted_at, t("models.user.fields.invitation_accepted_at", scope: "decidim.admin"), default_order: :desc ) %> +
- - - - - - + + + + + + diff --git a/decidim-admin/app/views/layouts/decidim/admin/_callouts_full.html.erb b/decidim-admin/app/views/layouts/decidim/admin/_callouts_full.html.erb index ca008b74fb4bf..9796a6c3a562c 100644 --- a/decidim-admin/app/views/layouts/decidim/admin/_callouts_full.html.erb +++ b/decidim-admin/app/views/layouts/decidim/admin/_callouts_full.html.erb @@ -1,5 +1,9 @@
<% flash.each do |key, value| %> + <% if /_html\Z/.match?(key) + key = key.gsub(/_html\Z/, "") + value = decidim_sanitize(value) + end %>
<%= value %>
<% else %> -
<%= image_tag asset_pack_path("media/images/default-avatar.svg"), alt: "member-avatar" %>
+
<%= image_tag model.non_user_avatar_path, alt: "member-avatar" %>
diff --git a/decidim-assemblies/app/cells/decidim/assemblies/content_blocks/highlighted_assemblies/show.erb b/decidim-assemblies/app/cells/decidim/assemblies/content_blocks/highlighted_assemblies/show.erb index 25fb35d108b6f..1b3245c1082a0 100644 --- a/decidim-assemblies/app/cells/decidim/assemblies/content_blocks/highlighted_assemblies/show.erb +++ b/decidim-assemblies/app/cells/decidim/assemblies/content_blocks/highlighted_assemblies/show.erb @@ -8,7 +8,7 @@
<%= link_to decidim_assemblies.assembly_path(assembly), class: "card card--assembly card--mini" do %> + style="background-image:url('<%= assembly.attached_uploader(:hero_image).path %>')">
<%= translated_attribute assembly.title %>
diff --git a/decidim-assemblies/app/cells/decidim/assemblies/content_blocks/highlighted_assemblies_cell.rb b/decidim-assemblies/app/cells/decidim/assemblies/content_blocks/highlighted_assemblies_cell.rb index 7b724ba4ff014..b315b4af02dfa 100644 --- a/decidim-assemblies/app/cells/decidim/assemblies/content_blocks/highlighted_assemblies_cell.rb +++ b/decidim-assemblies/app/cells/decidim/assemblies/content_blocks/highlighted_assemblies_cell.rb @@ -6,6 +6,10 @@ module ContentBlocks class HighlightedAssembliesCell < Decidim::ViewModel delegate :current_user, to: :controller + cache :show, expires_in: 10.minutes, if: :perform_caching? do + cache_hash + end + def show render if highlighted_assemblies.any? end @@ -29,6 +33,15 @@ def i18n_scope def decidim_assemblies Decidim::Assemblies::Engine.routes.url_helpers end + + private + + def cache_hash + hash = [] + hash.push(I18n.locale) + hash.push(highlighted_assemblies.map(&:cache_key_with_version)) + hash.join(Decidim.cache_key_separator) + end end end end diff --git a/decidim-assemblies/app/commands/decidim/assemblies/admin/create_assembly_member.rb b/decidim-assemblies/app/commands/decidim/assemblies/admin/create_assembly_member.rb index 653eb1d021733..9f440cfba8e74 100644 --- a/decidim-assemblies/app/commands/decidim/assemblies/admin/create_assembly_member.rb +++ b/decidim-assemblies/app/commands/decidim/assemblies/admin/create_assembly_member.rb @@ -6,6 +6,8 @@ module Admin # A command with all the business logic when creating a new assembly # member in the system. class CreateAssemblyMember < Rectify::Command + include ::Decidim::AttachmentAttributesMethods + # Public: Initializes the command. # # form - A form object with the params. @@ -25,16 +27,49 @@ def initialize(form, current_user, assembly) def call return broadcast(:invalid) if form.invalid? - create_assembly_member! - notify_assembly_member_about_new_membership + if assembly_member_with_attributes.valid? + create_assembly_member! + notify_assembly_member_about_new_membership - broadcast(:ok) + broadcast(:ok) + else + if assembly_member_with_attributes.errors.include? :non_user_avatar + form.errors.add( + :non_user_avatar, + assembly_member_with_attributes.errors[:non_user_avatar] + ) + end + broadcast(:invalid) + end end private attr_reader :form, :assembly, :current_user + def assembly_member_with_attributes + @assembly_member_with_attributes ||= Decidim::AssemblyMember.new(assembly_member_attributes) + end + + def assembly_member_attributes + form.attributes.slice( + :full_name, + :gender, + :birthday, + :birthplace, + :ceased_date, + :designation_date, + :position, + :position_other, + :weight + ).merge( + assembly: assembly, + user: form.user + ).merge( + attachment_attributes(:non_user_avatar) + ) + end + def create_assembly_member! log_info = { resource: { @@ -48,21 +83,7 @@ def create_assembly_member! @assembly_member = Decidim.traceability.create!( Decidim::AssemblyMember, current_user, - form.attributes.slice( - :full_name, - :gender, - :birthday, - :birthplace, - :ceased_date, - :designation_date, - :designation_mode, - :position, - :position_other, - :weight - ).merge( - assembly: assembly, - user: form.user - ), + assembly_member_attributes, log_info ) end diff --git a/decidim-assemblies/app/commands/decidim/assemblies/admin/update_assembly_member.rb b/decidim-assemblies/app/commands/decidim/assemblies/admin/update_assembly_member.rb index b4228bfb7d48b..ee590e0665906 100644 --- a/decidim-assemblies/app/commands/decidim/assemblies/admin/update_assembly_member.rb +++ b/decidim-assemblies/app/commands/decidim/assemblies/admin/update_assembly_member.rb @@ -6,6 +6,8 @@ module Admin # A command with all the business logic when updating an assembly # member in the system. class UpdateAssemblyMember < Rectify::Command + include ::Decidim::AttachmentAttributesMethods + # Public: Initializes the command. # # form - A form object with the params. @@ -25,14 +27,46 @@ def call return broadcast(:invalid) if form.invalid? return broadcast(:invalid) unless assembly_member - update_assembly_member! - broadcast(:ok) + assembly_member.assign_attributes(attributes) + + if assembly_member.valid? + assembly_member.reload + update_assembly_member! + broadcast(:ok) + else + if assembly_member.errors.include? :non_user_avatar + form.errors.add( + :non_user_avatar, + assembly_member.errors[:non_user_avatar] + ) + end + + broadcast(:invalid) + end end private attr_reader :form, :assembly_member + def attributes + form.attributes.slice( + :full_name, + :gender, + :birthday, + :birthplace, + :ceased_date, + :designation_date, + :position, + :position_other, + :weight + ).merge( + user: form.user + ).merge( + attachment_attributes(:non_user_avatar) + ) + end + def update_assembly_member! log_info = { resource: { @@ -46,20 +80,7 @@ def update_assembly_member! Decidim.traceability.update!( assembly_member, form.current_user, - form.attributes.slice( - :full_name, - :gender, - :birthday, - :birthplace, - :ceased_date, - :designation_date, - :designation_mode, - :position, - :position_other, - :weight - ).merge( - user: form.user - ), + attributes, log_info ) end diff --git a/decidim-assemblies/app/controllers/concerns/decidim/assemblies/admin/filterable.rb b/decidim-assemblies/app/controllers/concerns/decidim/assemblies/admin/filterable.rb index 88ab1bfb60388..7cb4ea992cf57 100644 --- a/decidim-assemblies/app/controllers/concerns/decidim/assemblies/admin/filterable.rb +++ b/decidim-assemblies/app/controllers/concerns/decidim/assemblies/admin/filterable.rb @@ -23,6 +23,26 @@ def base_query def extra_filters [:parent_id_eq] end + + def filters + [:private_space_eq, :published_at_null, :decidim_assemblies_type_id_eq] + end + + def filters_with_values + { + private_space_eq: [true, false], + published_at_null: [true, false], + decidim_assemblies_type_id_eq: AssembliesType.where(organization: current_organization).pluck(:id) + } + end + + def dynamically_translated_filters + [:decidim_assemblies_type_id_eq] + end + + def translated_decidim_assemblies_type_id_eq(id) + translated_attribute(Decidim::AssembliesType.find(id).title) + end end end end diff --git a/decidim-assemblies/app/controllers/decidim/assemblies/admin/assembly_members_controller.rb b/decidim-assemblies/app/controllers/decidim/assemblies/admin/assembly_members_controller.rb index 12829611d7d65..eb425117f9f3f 100644 --- a/decidim-assemblies/app/controllers/decidim/assemblies/admin/assembly_members_controller.rb +++ b/decidim-assemblies/app/controllers/decidim/assemblies/admin/assembly_members_controller.rb @@ -7,6 +7,7 @@ module Admin # class AssemblyMembersController < Decidim::Assemblies::Admin::ApplicationController include Concerns::AssemblyAdmin + layout "decidim/admin/assembly_members" def index enforce_permission_to :index, :assembly_member diff --git a/decidim-assemblies/app/controllers/decidim/assemblies/admin/assembly_user_roles_controller.rb b/decidim-assemblies/app/controllers/decidim/assemblies/admin/assembly_user_roles_controller.rb index a66edc3c530d2..2d80f3f02717e 100644 --- a/decidim-assemblies/app/controllers/decidim/assemblies/admin/assembly_user_roles_controller.rb +++ b/decidim-assemblies/app/controllers/decidim/assemblies/admin/assembly_user_roles_controller.rb @@ -7,10 +7,11 @@ module Admin # class AssemblyUserRolesController < Decidim::Assemblies::Admin::ApplicationController include Concerns::AssemblyAdmin + include Decidim::Admin::Officializations::Filterable def index enforce_permission_to :index, :assembly_user_role - @assembly_user_roles = collection + @assembly_user_roles = filtered_collection end def new @@ -90,11 +91,18 @@ def resend_invitation private + def search_field_predicate + :name_or_nickname_or_email_cont + end + + def filters + [:invitation_accepted_at_present, :last_sign_in_at_present] + end + def collection @collection ||= Decidim::AssemblyUserRole - .includes(:user) + .joins(:user) .where(assembly: current_assembly) - .order(:role, "decidim_users.name") end end end diff --git a/decidim-assemblies/app/forms/decidim/assemblies/admin/assembly_member_form.rb b/decidim-assemblies/app/forms/decidim/assemblies/admin/assembly_member_form.rb index 5c549a0817a4f..96ca9f578b460 100644 --- a/decidim-assemblies/app/forms/decidim/assemblies/admin/assembly_member_form.rb +++ b/decidim-assemblies/app/forms/decidim/assemblies/admin/assembly_member_form.rb @@ -10,12 +10,13 @@ class AssemblyMemberForm < Form attribute :weight, Integer, default: 0 attribute :full_name, String + attribute :non_user_avatar + attribute :remove_non_user_avatar, Boolean, default: false attribute :gender, String - attribute :birthday, Decidim::Attributes::TimeWithZone + attribute :birthday, Decidim::Attributes::LocalizedDate attribute :birthplace, String attribute :ceased_date, Decidim::Attributes::LocalizedDate attribute :designation_date, Decidim::Attributes::LocalizedDate - attribute :designation_mode, String attribute :position, String attribute :position_other, String attribute :user_id, Integer @@ -23,6 +24,18 @@ class AssemblyMemberForm < Form validates :designation_date, presence: true validates :full_name, presence: true, unless: proc { |object| object.existing_user } + validates :non_user_avatar, passthru: { + to: Decidim::AssemblyMember, + with: { + # The member gets its organization context through the assembly + # object which is why we need to create a dummy assembly in order + # to pass the correct organization context to the file upload + # validators. + assembly: lambda do |form| + Decidim::Assembly.new(organization: form.current_organization) + end + } + } validates :position, presence: true, inclusion: { in: Decidim::AssemblyMember::POSITIONS } validates :position_other, presence: true, if: ->(form) { form.position == "other" } validates :ceased_date, date: { after: :designation_date, allow_blank: true } diff --git a/decidim-assemblies/app/helpers/decidim/assemblies/assemblies_helper.rb b/decidim-assemblies/app/helpers/decidim/assemblies/assemblies_helper.rb index f04429d6703cd..f6a80ef06a139 100644 --- a/decidim-assemblies/app/helpers/decidim/assemblies/assemblies_helper.rb +++ b/decidim-assemblies/app/helpers/decidim/assemblies/assemblies_helper.rb @@ -34,7 +34,7 @@ def assembly_features(assembly) html += "#{translated_attribute(assembly.title)}: ".html_safe html += t("assemblies.show.private_space", scope: "decidim").to_s.html_safe html += ", #{t("assemblies.show.is_transparent.#{assembly.is_transparent}", scope: "decidim")}".html_safe if assembly.is_transparent? - html += " #{decidim_sanitize translated_attribute(assembly.special_features)}".html_safe + html += " #{decidim_sanitize_editor translated_attribute(assembly.special_features)}".html_safe html.html_safe end diff --git a/decidim-assemblies/app/models/decidim/assembly.rb b/decidim-assemblies/app/models/decidim/assembly.rb index 0407b13607789..abd90d9b8e03c 100644 --- a/decidim-assemblies/app/models/decidim/assembly.rb +++ b/decidim-assemblies/app/models/decidim/assembly.rb @@ -93,21 +93,6 @@ class Assembly < ApplicationRecord index_on_create: ->(_assembly) { false }, index_on_update: ->(assembly) { assembly.visible? }) - # Overwriting existing method Decidim::HasPrivateUsers.visible_for - def self.visible_for(user) - if user - return all if user.admin? - - left_outer_joins(:participatory_space_private_users).where( - %{private_space = false OR - (private_space = true AND is_transparent = true) OR - decidim_participatory_space_private_users.decidim_user_id = ?}, user.id - ).distinct - else - public_spaces - end - end - # Overwriting existing method Decidim::HasPrivateUsers.public_spaces def self.public_spaces where(private_space: false).or(where(private_space: true).where(is_transparent: true)).published diff --git a/decidim-assemblies/app/models/decidim/assembly_member.rb b/decidim-assemblies/app/models/decidim/assembly_member.rb index 7ab2f63036903..d3dbaceca297a 100644 --- a/decidim-assemblies/app/models/decidim/assembly_member.rb +++ b/decidim-assemblies/app/models/decidim/assembly_member.rb @@ -6,6 +6,7 @@ module Decidim class AssemblyMember < ApplicationRecord include Decidim::Traceable include Decidim::Loggable + include Decidim::HasUploadValidations POSITIONS = %w(president vice_president secretary other).freeze @@ -13,6 +14,11 @@ class AssemblyMember < ApplicationRecord belongs_to :assembly, foreign_key: "decidim_assembly_id", class_name: "Decidim::Assembly" alias participatory_space assembly + has_one_attached :non_user_avatar + validates_avatar :non_user_avatar, uploader: Decidim::AvatarUploader + + delegate :organization, to: :assembly + default_scope { order(weight: :asc, created_at: :asc) } scope :not_ceased, -> { where("ceased_date >= ? OR ceased_date IS NULL", Time.zone.today) } @@ -20,5 +26,9 @@ class AssemblyMember < ApplicationRecord def self.log_presenter_class_for(_log) Decidim::Assemblies::AdminLog::AssemblyMemberPresenter end + + def remove_non_user_avatar + false + end end end diff --git a/decidim-assemblies/app/models/decidim/assembly_user_role.rb b/decidim-assemblies/app/models/decidim/assembly_user_role.rb index deb2ad92a28de..9a9e9e4bf6ea2 100644 --- a/decidim-assemblies/app/models/decidim/assembly_user_role.rb +++ b/decidim-assemblies/app/models/decidim/assembly_user_role.rb @@ -19,6 +19,26 @@ def self.log_presenter_class_for(_log) Decidim::Assemblies::AdminLog::AssemblyUserRolePresenter end + ransacker :name do + Arel.sql(%{("decidim_users"."name")::text}) + end + + ransacker :nickname do + Arel.sql(%{("decidim_users"."nickname")::text}) + end + + ransacker :email do + Arel.sql(%{("decidim_users"."email")::text}) + end + + ransacker :invitation_accepted_at do + Arel.sql(%{("decidim_users"."invitation_accepted_at")::text}) + end + + ransacker :last_sign_in_at do + Arel.sql(%{("decidim_users"."last_sign_in_at")::text}) + end + private # Private: check if the process and the user have the same organization diff --git a/decidim-assemblies/app/packs/src/decidim/assemblies/admin/assembly_members.js b/decidim-assemblies/app/packs/src/decidim/assemblies/admin/assembly_members.js index 696cc7eeedb32..a5a638023cde5 100644 --- a/decidim-assemblies/app/packs/src/decidim/assemblies/admin/assembly_members.js +++ b/decidim-assemblies/app/packs/src/decidim/assemblies/admin/assembly_members.js @@ -13,6 +13,16 @@ $(() => { } }); + createFieldDependentInputs({ + controllerField: $assemblyMemberType, + wrapperSelector: ".user-fields", + dependentFieldsSelector: ".user-fields--non-user-avatar", + dependentInputSelector: "input", + enablingCondition: ($field) => { + return $field.val() === "false" + } + }); + createFieldDependentInputs({ controllerField: $assemblyMemberType, wrapperSelector: ".user-fields", diff --git a/decidim-assemblies/app/presenters/decidim/assemblies/admin_log/assembly_member_presenter.rb b/decidim-assemblies/app/presenters/decidim/assemblies/admin_log/assembly_member_presenter.rb index 5db37d3bfb5c8..32719ba083fdc 100644 --- a/decidim-assemblies/app/presenters/decidim/assemblies/admin_log/assembly_member_presenter.rb +++ b/decidim-assemblies/app/presenters/decidim/assemblies/admin_log/assembly_member_presenter.rb @@ -22,7 +22,6 @@ def diff_fields_mapping birthday: :date, birthplace: :string, designation_date: :date, - designation_mode: :string, position: "Decidim::Assemblies::AdminLog::ValueTypes::MemberPositionPresenter", position_other: :string, weight: :integer, diff --git a/decidim-assemblies/app/presenters/decidim/assembly_member_presenter.rb b/decidim-assemblies/app/presenters/decidim/assembly_member_presenter.rb index 57850cc8153a3..5abe7bc32674d 100644 --- a/decidim-assemblies/app/presenters/decidim/assembly_member_presenter.rb +++ b/decidim-assemblies/app/presenters/decidim/assembly_member_presenter.rb @@ -33,6 +33,16 @@ def position I18n.t(__getobj__.position, scope: "decidim.admin.models.assembly_member.positions", default: "") end + def non_user_avatar_path + return non_user_avatar.default_url unless non_user_avatar.attached? + + non_user_avatar.path + end + + def non_user_avatar + attached_uploader(:non_user_avatar) + end + private def user diff --git a/decidim-assemblies/app/serializers/decidim/assemblies/assembly_importer.rb b/decidim-assemblies/app/serializers/decidim/assemblies/assembly_importer.rb index 3da1600c53f80..9888e72a7fe1c 100644 --- a/decidim-assemblies/app/serializers/decidim/assemblies/assembly_importer.rb +++ b/decidim-assemblies/app/serializers/decidim/assemblies/assembly_importer.rb @@ -61,8 +61,9 @@ def import(attributes, _user, opts) meta_scope: attributes["meta_scope"], announcement: attributes["announcement"] ) - @imported_assembly.remote_hero_image_url = attributes["remote_hero_image_url"] if remote_file_exists?(attributes["remote_hero_image_url"]) - @imported_assembly.remote_banner_image_url = attributes["remote_banner_image_url"] if remote_file_exists?(attributes["remote_banner_image_url"]) + @imported_assembly.attached_uploader(:hero_image).remote_url = attributes["remote_hero_image_url"] if attributes["remote_hero_image_url"].present? + @imported_assembly.attached_uploader(:banner_image).remote_url = attributes["remote_banner_image_url"] if attributes["remote_banner_image_url"].present? + @imported_assembly.save! @imported_assembly end diff --git a/decidim-assemblies/app/views/decidim/assemblies/admin/assemblies/index.html.erb b/decidim-assemblies/app/views/decidim/assemblies/admin/assemblies/index.html.erb index 67b44613d6181..6d04262cee75d 100644 --- a/decidim-assemblies/app/views/decidim/assemblies/admin/assemblies/index.html.erb +++ b/decidim-assemblies/app/views/decidim/assemblies/admin/assemblies/index.html.erb @@ -48,7 +48,7 @@
diff --git a/decidim_app-design/app/views/public/partials/_filters_small_view.html.erb b/decidim_app-design/app/views/public/partials/_filters_small_view.html.erb index 7f7064d4f67a8..29457b2dc02b5 100644 --- a/decidim_app-design/app/views/public/partials/_filters_small_view.html.erb +++ b/decidim_app-design/app/views/public/partials/_filters_small_view.html.erb @@ -1,12 +1,12 @@
-
-
+
diff --git a/decidim_app-design/app/views/public/partials/_process_header_OLD.html.erb b/decidim_app-design/app/views/public/partials/_process_header_OLD.html.erb index cb88b9f6eed93..93e3227de822a 100644 --- a/decidim_app-design/app/views/public/partials/_process_header_OLD.html.erb +++ b/decidim_app-design/app/views/public/partials/_process_header_OLD.html.erb @@ -9,10 +9,10 @@
-

+

#urbaGracia Proceso de mejoras del barrio de Gracia -

+

diff --git a/decidim_app-design/app/views/public/partials/_process_header_home.html.erb b/decidim_app-design/app/views/public/partials/_process_header_home.html.erb index e0e788a656e32..6626364eee899 100644 --- a/decidim_app-design/app/views/public/partials/_process_header_home.html.erb +++ b/decidim_app-design/app/views/public/partials/_process_header_home.html.erb @@ -9,10 +9,10 @@
-

+

#urbaGracia Proceso de mejoras del barrio de Gracia -

+

diff --git a/decidim_app-design/app/views/public/partials/_process_header_new_proposal.html.erb b/decidim_app-design/app/views/public/partials/_process_header_new_proposal.html.erb index 66c08097d2b23..7e90b69fb6044 100644 --- a/decidim_app-design/app/views/public/partials/_process_header_new_proposal.html.erb +++ b/decidim_app-design/app/views/public/partials/_process_header_new_proposal.html.erb @@ -9,10 +9,10 @@
-

+

#urbaGracia Proceso de mejoras del barrio de Gracia -

+

diff --git a/decidim_app-design/package-lock.json b/decidim_app-design/package-lock.json index bd87c26d7f77b..9d5beaabb0b6e 100644 --- a/decidim_app-design/package-lock.json +++ b/decidim_app-design/package-lock.json @@ -5,7 +5,6 @@ "packages": { "": { "name": "a-decidim-app", - "license": "AGPL-3.0", "dependencies": { "@decidim/browserslist-config": "file:packages/browserslist-config", "@decidim/core": "file:packages/core", @@ -1710,31 +1709,6 @@ "node": ">=0.1.95" } }, - "node_modules/@codegram/decidim-bulletin_board": { - "version": "0.21.2", - "resolved": "https://registry.npmjs.org/@codegram/decidim-bulletin_board/-/decidim-bulletin_board-0.21.2.tgz", - "integrity": "sha512-o4eqR46lqtF/y+VyaV1elsLXLWnMEjMN1eCw27cDhvZHY4L+5Ec68w1HzC+brzLf5v5847DyS91kpxWIoi9C4A==", - "dependencies": { - "@apollo/client": "^3.2.7", - "core-js": "^3.8.3", - "graphql": "^15.4.0", - "node-jose": "^2.0.0", - "regenerator-runtime": "^0.13.7", - "rxjs": "^6.6.3", - "webpack": "^5.11.0", - "webpack-cli": "^4.2.0" - } - }, - "node_modules/@codegram/voting_schemes-dummy": { - "version": "0.21.2", - "resolved": "https://registry.npmjs.org/@codegram/voting_schemes-dummy/-/voting_schemes-dummy-0.21.2.tgz", - "integrity": "sha512-zwrBPIO8Escg54vxaqYqz4dgTbXq3xacu5h1u52mzABoYgniWLVzmsjTm6fKIzXs/RASgpxVmsIRgqiUDlHgCg==" - }, - "node_modules/@codegram/voting_schemes-electionguard": { - "version": "0.21.2", - "resolved": "https://registry.npmjs.org/@codegram/voting_schemes-electionguard/-/voting_schemes-electionguard-0.21.2.tgz", - "integrity": "sha512-BcAzcPVlC1glH8WRpyjeNZ804KAjbn3khUuzyNiOPnvFqYZoUhjcrKhB13S1YJNIk6v8NsGFDpkZq+s+irJQ/g==" - }, "node_modules/@csstools/convert-colors": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@csstools/convert-colors/-/convert-colors-1.4.0.tgz", @@ -1751,6 +1725,21 @@ "resolved": "packages/core", "link": true }, + "node_modules/@decidim/decidim-bulletin_board": { + "version": "0.22.3", + "resolved": "https://registry.npmjs.org/@decidim/decidim-bulletin_board/-/decidim-bulletin_board-0.22.3.tgz", + "integrity": "sha512-LN7wIK9IB9Zegr++fvEY2vAWdUvReLPCe3sbPMGadX3b2aurrx/SK3B38OfRdN2eqblksMzyNYtXALszA9dU2w==", + "dependencies": { + "@apollo/client": "^3.2.7", + "core-js": "^3.8.3", + "graphql": "^15.4.0", + "node-jose": "^2.0.0", + "regenerator-runtime": "^0.13.7", + "rxjs": "^6.6.3", + "webpack": "^5.11.0", + "webpack-cli": "^4.2.0" + } + }, "node_modules/@decidim/dev": { "resolved": "packages/dev", "link": true @@ -1767,6 +1756,16 @@ "resolved": "packages/stylelint-config", "link": true }, + "node_modules/@decidim/voting_schemes-dummy": { + "version": "0.22.3", + "resolved": "https://registry.npmjs.org/@decidim/voting_schemes-dummy/-/voting_schemes-dummy-0.22.3.tgz", + "integrity": "sha512-Z5CwSUJNYW2KkoE5anAqAIwHnQHqpgGL4Xu2I7YqEn3thThlbWlY9U9Eq0O6fq7/pfBQLiAFFiBBAnCDv0HC2g==" + }, + "node_modules/@decidim/voting_schemes-electionguard": { + "version": "0.22.3", + "resolved": "https://registry.npmjs.org/@decidim/voting_schemes-electionguard/-/voting_schemes-electionguard-0.22.3.tgz", + "integrity": "sha512-RZn/1GO5PM6a2SuN8h/SoS4EeLYnHPWw6/tl2M26ms/Xzf1ewJIgBSiByxk4qHoqvE892rccH4+G56h6iVrIqg==" + }, "node_modules/@decidim/webpacker": { "resolved": "packages/webpacker", "link": true @@ -3129,6 +3128,13 @@ "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", "dev": true }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "optional": true, + "peer": true + }, "node_modules/accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -3274,6 +3280,16 @@ "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=" }, + "node_modules/amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.4.2" + } + }, "node_modules/ansi-colors": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", @@ -3340,6 +3356,50 @@ "node": ">= 8" } }, + "node_modules/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "optional": true, + "peer": true + }, + "node_modules/are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "optional": true, + "peer": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "node_modules/are-we-there-yet/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "optional": true, + "peer": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/are-we-there-yet/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, + "peer": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -3389,6 +3449,16 @@ "node": ">=0.10.0" } }, + "node_modules/array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -3558,6 +3628,16 @@ "lodash": "^4.17.14" } }, + "node_modules/async-foreach": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", + "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=", + "optional": true, + "peer": true, + "engines": { + "node": "*" + } + }, "node_modules/async-limiter": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", @@ -4380,6 +4460,14 @@ "ieee754": "^1.1.13" } }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "engines": { + "node": "*" + } + }, "node_modules/buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", @@ -4499,11 +4587,35 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6" } }, + "node_modules/camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "optional": true, + "peer": true, + "dependencies": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/camelcase-keys/node_modules/camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/caniuse-api": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", @@ -5094,6 +5206,13 @@ "node": ">=0.8" } }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "optional": true, + "peer": true + }, "node_modules/content-disposition": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", @@ -5728,6 +5847,19 @@ "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", "dev": true }, + "node_modules/currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "optional": true, + "peer": true, + "dependencies": { + "array-find-index": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/d3": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/d3/-/d3-5.4.0.tgz", @@ -6230,6 +6362,13 @@ "node": ">=0.4.0" } }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "optional": true, + "peer": true + }, "node_modules/denque": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.0.tgz", @@ -6549,6 +6688,16 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "optional": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, "node_modules/envinfo": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", @@ -6739,6 +6888,14 @@ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" }, + "node_modules/es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "dependencies": { + "es6-promise": "^4.0.3" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -8084,6 +8241,80 @@ "node": ">=0.10.0" } }, + "node_modules/extract-zip": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", + "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==", + "dependencies": { + "concat-stream": "^1.6.2", + "debug": "^2.6.9", + "mkdirp": "^0.5.4", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + } + }, + "node_modules/extract-zip/node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/extract-zip/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/extract-zip/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/extract-zip/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/extract-zip/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/extract-zip/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", @@ -8161,6 +8392,14 @@ "bser": "2.1.1" } }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dependencies": { + "pend": "~1.2.0" + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -8347,9 +8586,12 @@ "integrity": "sha1-bciR8/ZCICghn3QoTRaEVIqMpL8=" }, "node_modules/foundation-sites": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/foundation-sites/-/foundation-sites-6.7.1.tgz", - "integrity": "sha512-Qr+9oQUItVInQG4wK2PKL53RwPe1eyx1irmgTkTGfm1CM0snQuenCRl7OtD8MfMykqw4NOU9JQGDLgV8oz0jxg==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/foundation-sites/-/foundation-sites-6.7.0.tgz", + "integrity": "sha512-dajdL/7i5rn5F70I2FMnfDOlgXD5klCw8OS9a+Y3rM2fyj9f8JZkJ50eYukmeEM4zVnj+Xo6rJfciLxN/QEYWQ==", + "dependencies": { + "puppeteer": "^1.11.0" + }, "engines": { "node": ">=12.0" }, @@ -8484,6 +8726,87 @@ "resolved": "https://registry.npmjs.org/fuzzysort/-/fuzzysort-1.1.4.tgz", "integrity": "sha512-JzK/lHjVZ6joAg3OnCjylwYXYVjRiwTY6Yb25LvfpJHK8bjisfnZJ5bY8aVWwTwCXgxPNgLAtmHL+Hs5q1ddLQ==" }, + "node_modules/gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "optional": true, + "peer": true, + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/gauge/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "optional": true, + "peer": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "optional": true, + "peer": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "optional": true, + "peer": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gaze": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", + "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", + "optional": true, + "peer": true, + "dependencies": { + "globule": "^1.0.0" + }, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -8496,7 +8819,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, + "devOptional": true, "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -8523,6 +8846,16 @@ "node": ">=8.0.0" } }, + "node_modules/get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/get-stream": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", @@ -8673,6 +9006,21 @@ "dev": true, "peer": true }, + "node_modules/globule": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.2.tgz", + "integrity": "sha512-7IDTQTIu2xzXkT+6mlluidnWo+BypnbSoEVVQCGfzqnl5Ik8d3e1d4wycb8Rj9tWW+Z39uPWsdlquqiqPCd/pA==", + "optional": true, + "peer": true, + "dependencies": { + "glob": "~7.1.1", + "lodash": "~4.17.10", + "minimatch": "~3.0.2" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/gonzales-pe": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz", @@ -9168,6 +9516,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "optional": true, + "peer": true + }, "node_modules/has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -9973,6 +10328,19 @@ "node": ">=0.10.0" } }, + "node_modules/is-finite": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", + "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -11928,6 +12296,13 @@ "node": ">=4.2" } }, + "node_modules/js-base64": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", + "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==", + "optional": true, + "peer": true + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -12504,6 +12879,20 @@ "loose-envify": "cli.js" } }, + "node_modules/loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "optional": true, + "peer": true, + "dependencies": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -12562,7 +12951,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true, + "devOptional": true, "peer": true, "engines": { "node": ">=0.10.0" @@ -12722,6 +13111,142 @@ "node": ">= 4.0.0" } }, + "node_modules/meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "optional": true, + "peer": true, + "dependencies": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/meow/node_modules/find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "optional": true, + "peer": true, + "dependencies": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/meow/node_modules/load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "optional": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/meow/node_modules/parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "optional": true, + "peer": true, + "dependencies": { + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/meow/node_modules/path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "optional": true, + "peer": true, + "dependencies": { + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/meow/node_modules/path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "optional": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/meow/node_modules/read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "optional": true, + "peer": true, + "dependencies": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/meow/node_modules/read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "optional": true, + "peer": true, + "dependencies": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/meow/node_modules/strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "optional": true, + "peer": true, + "dependencies": { + "is-utf8": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -13079,6 +13604,13 @@ "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=" }, + "node_modules/nan": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", + "optional": true, + "peer": true + }, "node_modules/nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -13155,6 +13687,47 @@ "node": ">= 6.0.0" } }, + "node_modules/node-gyp": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz", + "integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==", + "optional": true, + "peer": true, + "dependencies": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.3", + "nopt": "^5.0.0", + "npmlog": "^4.1.2", + "request": "^2.88.2", + "rimraf": "^3.0.2", + "semver": "^7.3.2", + "tar": "^6.0.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": ">= 10.12.0" + } + }, + "node_modules/node-gyp/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "optional": true, + "peer": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -13231,6 +13804,127 @@ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.75.tgz", "integrity": "sha512-Qe5OUajvqrqDSy6wrWFmMwfJ0jVgwiw4T3KqmbTcZ62qW0gQkheXYhcFM1+lOVcGUoRxcEcfyvFMAnDgaF1VWw==" }, + "node_modules/node-sass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-5.0.0.tgz", + "integrity": "sha512-opNgmlu83ZCF792U281Ry7tak9IbVC+AKnXGovcQ8LG8wFaJv6cLnRlc6DIHlmNxWEexB5bZxi9SZ9JyUuOYjw==", + "hasInstallScript": true, + "optional": true, + "peer": true, + "dependencies": { + "async-foreach": "^0.1.3", + "chalk": "^1.1.1", + "cross-spawn": "^7.0.3", + "gaze": "^1.0.0", + "get-stdin": "^4.0.1", + "glob": "^7.0.3", + "lodash": "^4.17.15", + "meow": "^3.7.0", + "mkdirp": "^0.5.1", + "nan": "^2.13.2", + "node-gyp": "^7.1.0", + "npmlog": "^4.0.0", + "request": "^2.88.0", + "sass-graph": "2.2.5", + "stdout-stream": "^1.4.0", + "true-case-path": "^1.0.2" + }, + "bin": { + "node-sass": "bin/node-sass" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-sass/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-sass/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-sass/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "optional": true, + "peer": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-sass/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "optional": true, + "peer": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/node-sass/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "optional": true, + "peer": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-sass/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "optional": true, + "peer": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -13292,6 +13986,19 @@ "node": ">=8" } }, + "node_modules/npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "optional": true, + "peer": true, + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, "node_modules/nth-check": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz", @@ -13920,6 +14627,11 @@ "node": ">=8" } }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" + }, "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -15447,7 +16159,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "peer": true, "engines": { "node": ">=0.4.0" } @@ -15503,6 +16214,11 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -15526,6 +16242,86 @@ "node": ">=6" } }, + "node_modules/puppeteer": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.20.0.tgz", + "integrity": "sha512-bt48RDBy2eIwZPrkgbcwHtb51mj2nKvHOPMaSH2IsWiv7lOG9k9zhaRzpDZafrk05ajMc3cu+lSQYYOfH2DkVQ==", + "hasInstallScript": true, + "dependencies": { + "debug": "^4.1.0", + "extract-zip": "^1.6.6", + "https-proxy-agent": "^2.2.1", + "mime": "^2.0.3", + "progress": "^2.0.1", + "proxy-from-env": "^1.0.0", + "rimraf": "^2.6.1", + "ws": "^6.1.0" + }, + "engines": { + "node": ">=6.4.0" + } + }, + "node_modules/puppeteer/node_modules/agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "dependencies": { + "es6-promisify": "^5.0.0" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/puppeteer/node_modules/https-proxy-agent": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", + "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", + "dependencies": { + "agent-base": "^4.3.0", + "debug": "^3.1.0" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/puppeteer/node_modules/https-proxy-agent/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/puppeteer/node_modules/mime": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/puppeteer/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/puppeteer/node_modules/ws": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "dependencies": { + "async-limiter": "~1.0.0" + } + }, "node_modules/q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", @@ -15860,6 +16656,33 @@ "node": ">= 0.10" } }, + "node_modules/redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "optional": true, + "peer": true, + "dependencies": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/redent/node_modules/indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "optional": true, + "peer": true, + "dependencies": { + "repeating": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/redis": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/redis/-/redis-3.1.2.tgz", @@ -16093,6 +16916,19 @@ "node": ">=0.10" } }, + "node_modules/repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "optional": true, + "peer": true, + "dependencies": { + "is-finite": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", @@ -16179,7 +17015,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true + "devOptional": true }, "node_modules/requires-port": { "version": "1.0.0", @@ -16662,6 +17498,181 @@ "node": ">=8.9.0" } }, + "node_modules/sass-graph": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.5.tgz", + "integrity": "sha512-VFWDAHOe6mRuT4mZRd4eKE+d8Uedrk6Xnh7Sh9b4NGufQLQjOrvf/MQoOdx+0s92L89FeyUUNfU597j/3uNpag==", + "optional": true, + "peer": true, + "dependencies": { + "glob": "^7.0.0", + "lodash": "^4.0.0", + "scss-tokenizer": "^0.2.3", + "yargs": "^13.3.2" + } + }, + "node_modules/sass-graph/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "optional": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/sass-graph/node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "optional": true, + "peer": true, + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/sass-graph/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "optional": true, + "peer": true + }, + "node_modules/sass-graph/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "optional": true, + "peer": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sass-graph/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "optional": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/sass-graph/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "optional": true, + "peer": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sass-graph/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "optional": true, + "peer": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sass-graph/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "optional": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/sass-graph/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "optional": true, + "peer": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sass-graph/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "optional": true, + "peer": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sass-graph/node_modules/wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "optional": true, + "peer": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sass-graph/node_modules/yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "optional": true, + "peer": true, + "dependencies": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "node_modules/sass-graph/node_modules/yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "optional": true, + "peer": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, "node_modules/sass-loader": { "version": "11.1.1", "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-11.1.1.tgz", @@ -16738,6 +17749,30 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/scss-tokenizer": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", + "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", + "optional": true, + "peer": true, + "dependencies": { + "js-base64": "^2.1.8", + "source-map": "^0.4.2" + } + }, + "node_modules/scss-tokenizer/node_modules/source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "optional": true, + "peer": true, + "dependencies": { + "amdefine": ">=0.0.4" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/select": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", @@ -17597,6 +18632,42 @@ "node": ">= 0.6" } }, + "node_modules/stdout-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz", + "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==", + "optional": true, + "peer": true, + "dependencies": { + "readable-stream": "^2.0.1" + } + }, + "node_modules/stdout-stream/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "optional": true, + "peer": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/stdout-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, + "peer": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -17748,6 +18819,22 @@ "node": ">=6" } }, + "node_modules/strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "optional": true, + "peer": true, + "dependencies": { + "get-stdin": "^4.0.1" + }, + "bin": { + "strip-indent": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -18738,6 +19825,16 @@ "resolved": "https://registry.npmjs.org/tributejs/-/tributejs-5.1.3.tgz", "integrity": "sha512-B5CXihaVzXw+1UHhNFyAwUTMDk1EfoLP5Tj1VhD9yybZ1I8DZJEv8tZ1l0RJo0t0tk9ZhR8eG5tEsaCvRigmdQ==" }, + "node_modules/trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/trough": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", @@ -18749,6 +19846,16 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/true-case-path": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz", + "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==", + "optional": true, + "peer": true, + "dependencies": { + "glob": "^7.1.2" + } + }, "node_modules/tryer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", @@ -18899,8 +20006,7 @@ "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, "node_modules/typedarray-to-buffer": { "version": "3.1.5", @@ -20044,7 +21150,64 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true + "devOptional": true + }, + "node_modules/wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "optional": true, + "peer": true, + "dependencies": { + "string-width": "^1.0.2 || 2" + } + }, + "node_modules/wide-align/node_modules/ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "optional": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "optional": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "optional": true, + "peer": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "optional": true, + "peer": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } }, "node_modules/wildcard": { "version": "2.0.0", @@ -20179,7 +21342,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true + "devOptional": true }, "node_modules/yallist": { "version": "4.0.0", @@ -20238,6 +21401,15 @@ "node": ">=6" } }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -20267,12 +21439,12 @@ }, "packages/browserslist-config": { "name": "@decidim/browserslist-config", - "version": "0.25.2", + "version": "0.26.4", "license": "AGPL-3.0" }, "packages/core": { "name": "@decidim/core", - "version": "0.25.2", + "version": "0.26.4", "license": "AGPL-3.0", "dependencies": { "@joeattardi/emoji-button": "^4.6.0", @@ -20327,7 +21499,7 @@ }, "packages/dev": { "name": "@decidim/dev", - "version": "0.25.2", + "version": "0.26.4", "dev": true, "license": "AGPL-3.0", "dependencies": { @@ -20336,17 +21508,17 @@ }, "packages/elections": { "name": "@decidim/elections", - "version": "0.25.2", + "version": "0.26.4", "license": "AGPL-3.0", "dependencies": { - "@codegram/decidim-bulletin_board": "0.21.2", - "@codegram/voting_schemes-dummy": "0.21.2", - "@codegram/voting_schemes-electionguard": "0.21.2" + "@decidim/decidim-bulletin_board": "0.22.3", + "@decidim/voting_schemes-dummy": "0.22.3", + "@decidim/voting_schemes-electionguard": "0.22.3" } }, "packages/eslint-config": { "name": "@decidim/eslint-config", - "version": "0.25.2", + "version": "0.26.4", "dev": true, "license": "AGPL-3.0", "peerDependencies": { @@ -20363,7 +21535,7 @@ }, "packages/stylelint-config": { "name": "@decidim/stylelint-config", - "version": "0.25.2", + "version": "0.26.4", "dev": true, "license": "AGPL-3.0", "peerDependencies": { @@ -20372,7 +21544,7 @@ }, "packages/webpacker": { "name": "@decidim/webpacker", - "version": "0.25.2", + "version": "0.26.4", "license": "AGPL-3.0", "dependencies": { "@babel/core": "^7.13.13", @@ -21544,31 +22716,6 @@ "minimist": "^1.2.0" } }, - "@codegram/decidim-bulletin_board": { - "version": "0.21.2", - "resolved": "https://registry.npmjs.org/@codegram/decidim-bulletin_board/-/decidim-bulletin_board-0.21.2.tgz", - "integrity": "sha512-o4eqR46lqtF/y+VyaV1elsLXLWnMEjMN1eCw27cDhvZHY4L+5Ec68w1HzC+brzLf5v5847DyS91kpxWIoi9C4A==", - "requires": { - "@apollo/client": "^3.2.7", - "core-js": "^3.8.3", - "graphql": "^15.4.0", - "node-jose": "^2.0.0", - "regenerator-runtime": "^0.13.7", - "rxjs": "^6.6.3", - "webpack": "^5.11.0", - "webpack-cli": "^4.2.0" - } - }, - "@codegram/voting_schemes-dummy": { - "version": "0.21.2", - "resolved": "https://registry.npmjs.org/@codegram/voting_schemes-dummy/-/voting_schemes-dummy-0.21.2.tgz", - "integrity": "sha512-zwrBPIO8Escg54vxaqYqz4dgTbXq3xacu5h1u52mzABoYgniWLVzmsjTm6fKIzXs/RASgpxVmsIRgqiUDlHgCg==" - }, - "@codegram/voting_schemes-electionguard": { - "version": "0.21.2", - "resolved": "https://registry.npmjs.org/@codegram/voting_schemes-electionguard/-/voting_schemes-electionguard-0.21.2.tgz", - "integrity": "sha512-BcAzcPVlC1glH8WRpyjeNZ804KAjbn3khUuzyNiOPnvFqYZoUhjcrKhB13S1YJNIk6v8NsGFDpkZq+s+irJQ/g==" - }, "@csstools/convert-colors": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@csstools/convert-colors/-/convert-colors-1.4.0.tgz", @@ -21624,6 +22771,21 @@ } } }, + "@decidim/decidim-bulletin_board": { + "version": "0.22.3", + "resolved": "https://registry.npmjs.org/@decidim/decidim-bulletin_board/-/decidim-bulletin_board-0.22.3.tgz", + "integrity": "sha512-LN7wIK9IB9Zegr++fvEY2vAWdUvReLPCe3sbPMGadX3b2aurrx/SK3B38OfRdN2eqblksMzyNYtXALszA9dU2w==", + "requires": { + "@apollo/client": "^3.2.7", + "core-js": "^3.8.3", + "graphql": "^15.4.0", + "node-jose": "^2.0.0", + "regenerator-runtime": "^0.13.7", + "rxjs": "^6.6.3", + "webpack": "^5.11.0", + "webpack-cli": "^4.2.0" + } + }, "@decidim/dev": { "version": "file:packages/dev", "requires": { @@ -21633,9 +22795,9 @@ "@decidim/elections": { "version": "file:packages/elections", "requires": { - "@codegram/decidim-bulletin_board": "0.21.2", - "@codegram/voting_schemes-dummy": "0.21.2", - "@codegram/voting_schemes-electionguard": "0.21.2" + "@decidim/decidim-bulletin_board": "0.22.3", + "@decidim/voting_schemes-dummy": "0.22.3", + "@decidim/voting_schemes-electionguard": "0.22.3" } }, "@decidim/eslint-config": { @@ -21646,6 +22808,16 @@ "version": "file:packages/stylelint-config", "requires": {} }, + "@decidim/voting_schemes-dummy": { + "version": "0.22.3", + "resolved": "https://registry.npmjs.org/@decidim/voting_schemes-dummy/-/voting_schemes-dummy-0.22.3.tgz", + "integrity": "sha512-Z5CwSUJNYW2KkoE5anAqAIwHnQHqpgGL4Xu2I7YqEn3thThlbWlY9U9Eq0O6fq7/pfBQLiAFFiBBAnCDv0HC2g==" + }, + "@decidim/voting_schemes-electionguard": { + "version": "0.22.3", + "resolved": "https://registry.npmjs.org/@decidim/voting_schemes-electionguard/-/voting_schemes-electionguard-0.22.3.tgz", + "integrity": "sha512-RZn/1GO5PM6a2SuN8h/SoS4EeLYnHPWw6/tl2M26ms/Xzf1ewJIgBSiByxk4qHoqvE892rccH4+G56h6iVrIqg==" + }, "@decidim/webpacker": { "version": "file:packages/webpacker", "requires": { @@ -22805,6 +23977,13 @@ "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", "dev": true }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "optional": true, + "peer": true + }, "accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -22912,6 +24091,13 @@ "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=" }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "optional": true, + "peer": true + }, "ansi-colors": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", @@ -22954,6 +24140,52 @@ "picomatch": "^2.0.4" } }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "optional": true, + "peer": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "optional": true, + "peer": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "optional": true, + "peer": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, + "peer": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -22991,6 +24223,13 @@ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", "dev": true }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "optional": true, + "peer": true + }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -23115,6 +24354,13 @@ "lodash": "^4.17.14" } }, + "async-foreach": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", + "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=", + "optional": true, + "peer": true + }, "async-limiter": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", @@ -23777,6 +25023,11 @@ "ieee754": "^1.1.13" } }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" + }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", @@ -23874,7 +25125,27 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true + "devOptional": true + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "optional": true, + "peer": true, + "requires": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "optional": true, + "peer": true + } + } }, "caniuse-api": { "version": "3.0.0", @@ -24343,6 +25614,13 @@ "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==" }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "optional": true, + "peer": true + }, "content-disposition": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", @@ -24811,6 +26089,16 @@ } } }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "optional": true, + "peer": true, + "requires": { + "array-find-index": "^1.0.1" + } + }, "d3": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/d3/-/d3-5.4.0.tgz", @@ -25239,6 +26527,13 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "optional": true, + "peer": true + }, "denque": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.0.tgz", @@ -25484,6 +26779,13 @@ "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" }, + "env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "optional": true, + "peer": true + }, "envinfo": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", @@ -25634,6 +26936,14 @@ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "requires": { + "es6-promise": "^4.0.3" + } + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -26674,6 +27984,73 @@ } } }, + "extract-zip": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", + "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==", + "requires": { + "concat-stream": "^1.6.2", + "debug": "^2.6.9", + "mkdirp": "^0.5.4", + "yauzl": "^2.10.0" + }, + "dependencies": { + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", @@ -26742,6 +28119,14 @@ "bser": "2.1.1" } }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "requires": { + "pend": "~1.2.0" + } + }, "file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -26880,10 +28265,12 @@ "integrity": "sha1-bciR8/ZCICghn3QoTRaEVIqMpL8=" }, "foundation-sites": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/foundation-sites/-/foundation-sites-6.7.1.tgz", - "integrity": "sha512-Qr+9oQUItVInQG4wK2PKL53RwPe1eyx1irmgTkTGfm1CM0snQuenCRl7OtD8MfMykqw4NOU9JQGDLgV8oz0jxg==", - "requires": {} + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/foundation-sites/-/foundation-sites-6.7.0.tgz", + "integrity": "sha512-dajdL/7i5rn5F70I2FMnfDOlgXD5klCw8OS9a+Y3rM2fyj9f8JZkJ50eYukmeEM4zVnj+Xo6rJfciLxN/QEYWQ==", + "requires": { + "puppeteer": "^1.11.0" + } }, "fragment-cache": { "version": "0.2.1", @@ -26982,6 +28369,74 @@ "resolved": "https://registry.npmjs.org/fuzzysort/-/fuzzysort-1.1.4.tgz", "integrity": "sha512-JzK/lHjVZ6joAg3OnCjylwYXYVjRiwTY6Yb25LvfpJHK8bjisfnZJ5bY8aVWwTwCXgxPNgLAtmHL+Hs5q1ddLQ==" }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "optional": true, + "peer": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "optional": true, + "peer": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "optional": true, + "peer": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "optional": true, + "peer": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "optional": true, + "peer": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "gaze": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", + "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", + "optional": true, + "peer": true, + "requires": { + "globule": "^1.0.0" + } + }, "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -26991,7 +28446,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true + "devOptional": true }, "get-intrinsic": { "version": "1.1.1", @@ -27009,6 +28464,13 @@ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "optional": true, + "peer": true + }, "get-stream": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", @@ -27124,6 +28586,18 @@ "dev": true, "peer": true }, + "globule": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.2.tgz", + "integrity": "sha512-7IDTQTIu2xzXkT+6mlluidnWo+BypnbSoEVVQCGfzqnl5Ik8d3e1d4wycb8Rj9tWW+Z39uPWsdlquqiqPCd/pA==", + "optional": true, + "peer": true, + "requires": { + "glob": "~7.1.1", + "lodash": "~4.17.10", + "minimatch": "~3.0.2" + } + }, "gonzales-pe": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz", @@ -27499,6 +28973,13 @@ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "optional": true, + "peer": true + }, "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -28107,6 +29588,13 @@ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" }, + "is-finite": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", + "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", + "optional": true, + "peer": true + }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -29559,6 +31047,13 @@ "resolved": "https://registry.npmjs.org/jquery.autocomplete/-/jquery.autocomplete-1.2.0.tgz", "integrity": "sha512-aoJC3KVrPpRGaZBUo9UxhwznYmQ0UuYd+FfjP9RAKmyB+1T3OLIjuQImT8pKX6eKpBt1z9JmD48GiD2Dx303bA==" }, + "js-base64": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", + "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==", + "optional": true, + "peer": true + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -30029,6 +31524,17 @@ "js-tokens": "^3.0.0 || ^4.0.0" } }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "optional": true, + "peer": true, + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + } + }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -30072,7 +31578,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true, + "devOptional": true, "peer": true }, "map-visit": { @@ -30190,6 +31696,117 @@ "fs-monkey": "1.0.3" } }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "optional": true, + "peer": true, + "requires": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "optional": true, + "peer": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "optional": true, + "peer": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "optional": true, + "peer": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "optional": true, + "peer": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "optional": true, + "peer": true, + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "optional": true, + "peer": true, + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "optional": true, + "peer": true, + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "optional": true, + "peer": true, + "requires": { + "is-utf8": "^0.2.0" + } + } + } + }, "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -30442,6 +32059,13 @@ "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=" }, + "nan": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", + "optional": true, + "peer": true + }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -30499,6 +32123,37 @@ "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==" }, + "node-gyp": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz", + "integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==", + "optional": true, + "peer": true, + "requires": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.3", + "nopt": "^5.0.0", + "npmlog": "^4.1.2", + "request": "^2.88.2", + "rimraf": "^3.0.2", + "semver": "^7.3.2", + "tar": "^6.0.2", + "which": "^2.0.2" + }, + "dependencies": { + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "optional": true, + "peer": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -30566,6 +32221,98 @@ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.75.tgz", "integrity": "sha512-Qe5OUajvqrqDSy6wrWFmMwfJ0jVgwiw4T3KqmbTcZ62qW0gQkheXYhcFM1+lOVcGUoRxcEcfyvFMAnDgaF1VWw==" }, + "node-sass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-5.0.0.tgz", + "integrity": "sha512-opNgmlu83ZCF792U281Ry7tak9IbVC+AKnXGovcQ8LG8wFaJv6cLnRlc6DIHlmNxWEexB5bZxi9SZ9JyUuOYjw==", + "optional": true, + "peer": true, + "requires": { + "async-foreach": "^0.1.3", + "chalk": "^1.1.1", + "cross-spawn": "^7.0.3", + "gaze": "^1.0.0", + "get-stdin": "^4.0.1", + "glob": "^7.0.3", + "lodash": "^4.17.15", + "meow": "^3.7.0", + "mkdirp": "^0.5.1", + "nan": "^2.13.2", + "node-gyp": "^7.1.0", + "npmlog": "^4.0.0", + "request": "^2.88.0", + "sass-graph": "2.2.5", + "stdout-stream": "^1.4.0", + "true-case-path": "^1.0.2" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "optional": true, + "peer": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "optional": true, + "peer": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "optional": true, + "peer": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "optional": true, + "peer": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "optional": true, + "peer": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "optional": true, + "peer": true + } + } + }, + "nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "optional": true, + "peer": true, + "requires": { + "abbrev": "1" + } + }, "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -30614,6 +32361,19 @@ "path-key": "^3.0.0" } }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "optional": true, + "peer": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, "nth-check": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz", @@ -31068,6 +32828,11 @@ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -32330,8 +34095,7 @@ "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "peer": true + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" }, "promise-inflight": { "version": "1.0.1", @@ -32378,6 +34142,11 @@ "ipaddr.js": "1.9.1" } }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -32398,6 +34167,71 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, + "puppeteer": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.20.0.tgz", + "integrity": "sha512-bt48RDBy2eIwZPrkgbcwHtb51mj2nKvHOPMaSH2IsWiv7lOG9k9zhaRzpDZafrk05ajMc3cu+lSQYYOfH2DkVQ==", + "requires": { + "debug": "^4.1.0", + "extract-zip": "^1.6.6", + "https-proxy-agent": "^2.2.1", + "mime": "^2.0.3", + "progress": "^2.0.1", + "proxy-from-env": "^1.0.0", + "rimraf": "^2.6.1", + "ws": "^6.1.0" + }, + "dependencies": { + "agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "requires": { + "es6-promisify": "^5.0.0" + } + }, + "https-proxy-agent": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", + "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", + "requires": { + "agent-base": "^4.3.0", + "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "mime": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==" + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + } + }, + "ws": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, "q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", @@ -32653,6 +34487,29 @@ "resolve": "^1.9.0" } }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "optional": true, + "peer": true, + "requires": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + }, + "dependencies": { + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "optional": true, + "peer": true, + "requires": { + "repeating": "^2.0.0" + } + } + } + }, "redis": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/redis/-/redis-3.1.2.tgz", @@ -32830,6 +34687,16 @@ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "optional": true, + "peer": true, + "requires": { + "is-finite": "^1.0.0" + } + }, "request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", @@ -32898,7 +34765,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true + "devOptional": true }, "requires-port": { "version": "1.0.0", @@ -33273,6 +35140,156 @@ "chokidar": ">=3.0.0 <4.0.0" } }, + "sass-graph": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.5.tgz", + "integrity": "sha512-VFWDAHOe6mRuT4mZRd4eKE+d8Uedrk6Xnh7Sh9b4NGufQLQjOrvf/MQoOdx+0s92L89FeyUUNfU597j/3uNpag==", + "optional": true, + "peer": true, + "requires": { + "glob": "^7.0.0", + "lodash": "^4.0.0", + "scss-tokenizer": "^0.2.3", + "yargs": "^13.3.2" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "optional": true, + "peer": true + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "optional": true, + "peer": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "optional": true, + "peer": true + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "optional": true, + "peer": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "optional": true, + "peer": true + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "optional": true, + "peer": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "optional": true, + "peer": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "optional": true, + "peer": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "optional": true, + "peer": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "optional": true, + "peer": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "optional": true, + "peer": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "optional": true, + "peer": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "optional": true, + "peer": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, "sass-loader": { "version": "11.1.1", "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-11.1.1.tgz", @@ -33315,6 +35332,29 @@ "ajv-keywords": "^3.5.2" } }, + "scss-tokenizer": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", + "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", + "optional": true, + "peer": true, + "requires": { + "js-base64": "^2.1.8", + "source-map": "^0.4.2" + }, + "dependencies": { + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "optional": true, + "peer": true, + "requires": { + "amdefine": ">=0.0.4" + } + } + } + }, "select": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", @@ -34052,6 +36092,44 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" }, + "stdout-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz", + "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==", + "optional": true, + "peer": true, + "requires": { + "readable-stream": "^2.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "optional": true, + "peer": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, + "peer": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -34158,6 +36236,16 @@ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "optional": true, + "peer": true, + "requires": { + "get-stdin": "^4.0.1" + } + }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -34918,6 +37006,13 @@ "resolved": "https://registry.npmjs.org/tributejs/-/tributejs-5.1.3.tgz", "integrity": "sha512-B5CXihaVzXw+1UHhNFyAwUTMDk1EfoLP5Tj1VhD9yybZ1I8DZJEv8tZ1l0RJo0t0tk9ZhR8eG5tEsaCvRigmdQ==" }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "optional": true, + "peer": true + }, "trough": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", @@ -34925,6 +37020,16 @@ "dev": true, "peer": true }, + "true-case-path": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz", + "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==", + "optional": true, + "peer": true, + "requires": { + "glob": "^7.1.2" + } + }, "tryer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", @@ -35042,8 +37147,7 @@ "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, "typedarray-to-buffer": { "version": "3.1.5", @@ -35868,7 +37972,54 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true + "devOptional": true + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "optional": true, + "peer": true, + "requires": { + "string-width": "^1.0.2 || 2" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "optional": true, + "peer": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "optional": true, + "peer": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "optional": true, + "peer": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "optional": true, + "peer": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } }, "wildcard": { "version": "2.0.0", @@ -35967,7 +38118,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true + "devOptional": true }, "yallist": { "version": "4.0.0", @@ -36017,6 +38168,15 @@ "decamelize": "^1.2.0" } }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/decidim_app-design/package.json b/decidim_app-design/package.json index e17f3a666de2a..836b0e80e2773 100644 --- a/decidim_app-design/package.json +++ b/decidim_app-design/package.json @@ -1,12 +1,7 @@ { "name": "a-decidim-app", - "description": "The participatory democracy framework", - "repository": { - "url": "git@github.com:decidim/decidim.git", - "type": "git" - }, - "author": "Marc Riera ", - "license": "AGPL-3.0", + "description": "Note: this is not a package, just the dependencies for the project in the dev environment.", + "private": true, "engines": { "node": "^16.9.1", "npm": "^7.21.1" diff --git a/decidim_app-design/packages/browserslist-config/package.json b/decidim_app-design/packages/browserslist-config/package.json index 3627d00953dbe..036979a3b8d61 100644 --- a/decidim_app-design/packages/browserslist-config/package.json +++ b/decidim_app-design/packages/browserslist-config/package.json @@ -1,7 +1,7 @@ { "name": "@decidim/browserslist-config", "description": "The Browserslist configuration for Decidim", - "version": "0.25.2", + "version": "0.26.4", "repository": { "url": "git@github.com:decidim/decidim.git", "type": "git", diff --git a/decidim_app-design/packages/core/package.json b/decidim_app-design/packages/core/package.json index aa44fc0a4dcbc..028cc4436b852 100644 --- a/decidim_app-design/packages/core/package.json +++ b/decidim_app-design/packages/core/package.json @@ -1,7 +1,7 @@ { "name": "@decidim/core", "description": "The core dependencies for Decidim", - "version": "0.25.2", + "version": "0.26.4", "repository": { "url": "git@github.com:decidim/decidim.git", "type": "git", diff --git a/decidim_app-design/packages/dev/package.json b/decidim_app-design/packages/dev/package.json index 6fc2e61a20fb7..5d7e41d108ba9 100644 --- a/decidim_app-design/packages/dev/package.json +++ b/decidim_app-design/packages/dev/package.json @@ -1,7 +1,7 @@ { "name": "@decidim/dev", "description": "The dev dependencies for Decidim", - "version": "0.25.2", + "version": "0.26.4", "repository": { "url": "git@github.com:decidim/decidim.git", "type": "git", diff --git a/decidim_app-design/packages/elections/package.json b/decidim_app-design/packages/elections/package.json index 9190b6351e7ed..792013cb0df5d 100644 --- a/decidim_app-design/packages/elections/package.json +++ b/decidim_app-design/packages/elections/package.json @@ -1,7 +1,7 @@ { "name": "@decidim/elections", "description": "The elections and votings dependencies for Decidim", - "version": "0.25.2", + "version": "0.26.4", "repository": { "url": "git@github.com:decidim/decidim.git", "type": "git", @@ -10,8 +10,8 @@ "author": "Decidim Contributors", "license": "AGPL-3.0", "dependencies": { - "@codegram/decidim-bulletin_board": "0.21.2", - "@codegram/voting_schemes-dummy": "0.21.2", - "@codegram/voting_schemes-electionguard": "0.21.2" + "@decidim/decidim-bulletin_board": "0.22.3", + "@decidim/voting_schemes-dummy": "0.22.3", + "@decidim/voting_schemes-electionguard": "0.22.3" } -} +} \ No newline at end of file diff --git a/decidim_app-design/packages/eslint-config/package.json b/decidim_app-design/packages/eslint-config/package.json index 722fec48bedf0..df75dded763a3 100644 --- a/decidim_app-design/packages/eslint-config/package.json +++ b/decidim_app-design/packages/eslint-config/package.json @@ -1,7 +1,7 @@ { "name": "@decidim/eslint-config", "description": "The eslint configuration for Decidim", - "version": "0.25.2", + "version": "0.26.4", "repository": { "url": "git@github.com:decidim/decidim.git", "type": "git", diff --git a/decidim_app-design/packages/stylelint-config/package.json b/decidim_app-design/packages/stylelint-config/package.json index 139a19d1559a1..e1fce92515b18 100644 --- a/decidim_app-design/packages/stylelint-config/package.json +++ b/decidim_app-design/packages/stylelint-config/package.json @@ -1,7 +1,7 @@ { "name": "@decidim/stylelint-config", "description": "The stylelint configuration for Decidim", - "version": "0.25.2", + "version": "0.26.4", "repository": { "url": "git@github.com:decidim/decidim.git", "type": "git", diff --git a/decidim_app-design/packages/webpacker/package.json b/decidim_app-design/packages/webpacker/package.json index 7c57597e0f3a0..9f4da510d2b29 100644 --- a/decidim_app-design/packages/webpacker/package.json +++ b/decidim_app-design/packages/webpacker/package.json @@ -1,7 +1,7 @@ { "name": "@decidim/webpacker", "description": "The webpacker dependencies for Decidim", - "version": "0.25.2", + "version": "0.26.4", "repository": { "url": "git@github.com:decidim/decidim.git", "type": "git", diff --git a/docs/antora.yml b/docs/antora.yml index fc603b7b13988..1bb34d5f9d147 100644 --- a/docs/antora.yml +++ b/docs/antora.yml @@ -1,6 +1,6 @@ name: en -title: "Decidim Developers Documentation" -version: master +title: "Decidim Documentation" +version: v0.26 asciidoc: attributes: page-lang: en@ diff --git a/docs/modules/customize/pages/authorizations.adoc b/docs/modules/customize/pages/authorizations.adoc index c70b900cda1d6..79bb7eb87b091 100644 --- a/docs/modules/customize/pages/authorizations.adoc +++ b/docs/modules/customize/pages/authorizations.adoc @@ -20,3 +20,29 @@ Each decidim instance is in full control of its authorizations, and can customiz * The different actions in decidim that require authorization, and which authorization method they require. For example, a decidim instance might choose to require census authorization to create proposals, but a fully verified address via a verification code sent by postal mail for voting on proposals. See https://github.com/decidim/decidim/blob/develop/decidim-verifications/README.md[decidim-verifications's README] and https://decidim.org/modules[Decidim's Modules page]. + +== Examples + +Here are some examples: + +- https://github.com/AjuntamentdeBarcelona/decidim-barcelona/blob/master/app/services/census_authorization_handler.rb[Barcelona (City)] +- https://github.com/AjuntamentdeCalafell/decidim-calafell/blob/master/app/services/census_authorization_handler.rb[Calafell] +- https://github.com/diputacioBCN/decidim-diba/blob/master/decidim-diba_census_api/app/services/diba_census_api_authorization_handler.rb[DIBA (Barcelona Province)] +- https://github.com/AjuntamentDeGava/decidim-gava/blob/master/app/services/census_authorization_handler.rb[Gavà] +- https://github.com/HospitaletDeLlobregat/decidim-hospitalet/blob/master/app/services/census_authorization_handler.rb[Hospitalet de Llobregat] +- https://github.com/AjMalgrat/decidim-malgrat/blob/master/app/services/carpetaciutada_handler.rb[Malgrat de Mar] +- https://github.com/AjuntamentDeMataro/decidimmataro.cat/blob/master/app/services/census_authorization_handler.rb[Mataró] +- https://github.com/ErabakiPamplona/erabaki/blob/master/app/services/census_authorization_handler.rb[Pamplona] +- https://github.com/AjuntamentdeReus/decidim/blob/master/app/services/census_authorization_handler.rb[Reus] +- https://github.com/AjuntamentDeSabadell/decidim-sabadell/blob/master/app/services/census_authorization_handler.rb[Sabadell] +- https://github.com/AjuntamentdeSantCugat/decidim-sant_cugat/blob/master/app/services/census_authorization_handler.rb[Sant Cugat] +- https://github.com/AjuntamentDeTerrassa/decidim-terrassa/blob/master/app/services/census_authorization_handler.rb[Terrassa] +- https://github.com/vilanovailageltru/decidim-vilanova/blob/master/app/services/vilanova_authorization_handler.rb[Vilanova i la Geltrú] + +Other special verifications: + +- https://github.com/podemos-info/participa2/tree/master/decidim-module-census_connector[Podemos] +- https://github.com/ElectricThings/fund_action/blob/master/app/services/anybody_authorization_handler.rb[FundAction] +- https://github.com/CodiTramuntana/decidim-verifications-csv_emails[CSV emails] +- https://github.com/mainio/decidim-module-access_requests[Access Requests] + diff --git a/docs/modules/customize/pages/code.adoc b/docs/modules/customize/pages/code.adoc index d859bc272cd41..7814134f3dd50 100644 --- a/docs/modules/customize/pages/code.adoc +++ b/docs/modules/customize/pages/code.adoc @@ -2,7 +2,7 @@ Decidim is multiple things: -* A command line utility, which can create an application +* A command-line utility, which can create an application * A set of libraries, that the application can use Most of the time, you should work with the generated application. That application (development_app on this docs) should be named as your project, for instance for Barcelona City Council is `DecidimBarcelona`, so for creating it should be: @@ -17,7 +17,7 @@ If you want to override/change anything, you can just do it with the same name o * https://github.com/gencat/participa/blob/master/app/decorators/decidim/admin/selective_newsletter_form_decorator.rb[Decidim::Admin::SelectiveNewsletterForm]. As it's a decorator you also need to make it available in the https://github.com/gencat/participa/blob/3416992ae095f6ab1e826fee961253514c4ff0ef/config/application.rb#L48[application config] * https://github.com/barcelonaregional/decidim-premet25/blob/master/config/initializers/etiquette_validator.rb[EtiquetteValidator.class_eval] -If you want to extend Decidim, the prefered way should be by having a Module. This is a Ruby on Rails Engine which provides ruby code (models, views, controllers, assets, etc). You can use it through multiple ways: +If you want to extend Decidim, the preferred way should be by having a Module. This is a Ruby on Rails Engine which provides ruby code (models, views, controllers, assets, etc). You can use it in multiple ways: * Putting it on the same directory as your app and pointing on the Gemfile. https://github.com/AjuntamentdeBarcelona/decidim-barcelona/tree/c210b5338d7ba1338c9879627e081da1441f1946[See example on GitHub]. For instance: @@ -34,3 +34,5 @@ gem "decidim-consultations", git: "https://github.com/decidim/decidim-module-con ---- * Publishing it on rubygems.org + +You can learn more about xref:develop:modules.adoc[Modules] in the development guide. \ No newline at end of file diff --git a/docs/modules/develop/pages/components.adoc b/docs/modules/develop/pages/components.adoc index 54367f0747770..eec0ab900059e 100644 --- a/docs/modules/develop/pages/components.adoc +++ b/docs/modules/develop/pages/components.adoc @@ -69,11 +69,44 @@ Decidim.register_component(:my_component) do |component| # Import definitions allow data to be imported into a component. # - # For now supported formats for imports are CSV, JSON and Excel (.xls). - # Every resource type needs it's own creator, which creates resource - # from parsed data. + # For now supported formats for imports are CSV, JSON and Excel (.xlsx). + # Every resource type needs it's own creator, which creates resource from + # parsed data. You also need to define specific messages for the importer and + # can provide some extra options, too. component.imports :component_resources do |imports| + # Define a form partial if you want to add custom fields to the form + # imports.form_view = "decidim/my_component/admin/imports/component_resources_fields" + # Define a custom form class name if you want to customize the form object + # imports.form_class_name = "MyComponent::Admin::CustomImportForm" + + # Define UI messages for the import functionality + imports.messages do |msg| + # The resource name is used in the success message: + # "X your resources successfully imported" (the "your resources" part) + msg.set(:resource_name) { |count: 1| I18n.t("decidim.my_component.admin.imports.resources.component_resources", count: count) } + # The title is the message shown at the top of the import page + msg.set(:title) { I18n.t("decidim.my_component.admin.imports.title.component_resources") } + # The label is what is shown in the import dropdown menu + msg.set(:label) { I18n.t("decidim.my_component.admin.imports.label.component_resources") } + # The optional help message can be used to provide additional contextual + # help for the import file, e.g. how it should be formatted + # msg.set(:help) { I18n.t("decidim.my_component.admin.imports.help.component_resources") } + end + + # Define the creator that is used to create resources from the import data imports.creator MyComponent::ResourceCreator + + # Define an example data set to guide the user how to format the import + # file. This will be available for download in the import view for each + # supported import format. + imports.example do |import_component| + organization = import_component.organization + [ + organization.available_locales.map { |l| "title/#{l}" } + organization.available_locales.map { |l| "body/#{l}" }, + organization.available_locales.map { "Example title" } + organization.available_locales.map { "Example body" }, + organization.available_locales.map { "Example title 2" } + organization.available_locales.map { "Example body 2" }, + ] + end end end ---- diff --git a/docs/modules/develop/pages/guide_development_with_custom_seed_data.adoc b/docs/modules/develop/pages/custom_seed_data.adoc similarity index 98% rename from docs/modules/develop/pages/guide_development_with_custom_seed_data.adoc rename to docs/modules/develop/pages/custom_seed_data.adoc index 7330b0d8753c5..b8421fe5a305d 100644 --- a/docs/modules/develop/pages/guide_development_with_custom_seed_data.adoc +++ b/docs/modules/develop/pages/custom_seed_data.adoc @@ -1,4 +1,4 @@ -= Development with custom seed data += Custom seed data The seed data is not only useful for local development, but also for staging environments to showcase your work to your clients. In this case, you might need to customize some of that seed data to make sure it fits your needs. diff --git a/docs/modules/develop/pages/guide.adoc b/docs/modules/develop/pages/guide.adoc index 7e432d6b896f4..58c1c8267a929 100644 --- a/docs/modules/develop/pages/guide.adoc +++ b/docs/modules/develop/pages/guide.adoc @@ -1,13 +1,10 @@ = Developing Decidim -* xref:develop:guide_architecture.adoc[Architecture] -* xref:develop:guide_changelog.adoc[Changelog] -* xref:develop:guide_commands.adoc[Commands] -* xref:develop:guide_development_app.adoc[Development App] -* xref:develop:guide_example_apps.adoc[Example Applications] -* xref:develop:guide_git_conventions.adoc[Git conventions] -* xref:develop:guide_github_projects.adoc[GitHub Projects Workflow] -* xref:develop:guide_semver.adoc[Semantic Versioning] +* xref:develop:guide_example_apps.adoc[1. Example Applications] +* xref:develop:guide_development_app.adoc[2. Development App] +* xref:develop:guide_commands.adoc[3. Commands] +* xref:develop:guide_conventions.adoc[4. Conventions] +* xref:develop:guide_architecture.adoc[5. Architecture] == Good to know diff --git a/docs/modules/develop/pages/guide_changelog.adoc b/docs/modules/develop/pages/guide_changelog.adoc deleted file mode 100644 index f1ef3bb989e70..0000000000000 --- a/docs/modules/develop/pages/guide_changelog.adoc +++ /dev/null @@ -1,8 +0,0 @@ -= Changelog - -For keeping track of changes we like the rules of https://keepachangelog.com/en/1.0.0/[Keep A Changelog]. - -In the past we kept a file for all the development of a given version but that was difficult to maintain, as we had conflicts all the time. See the full discussion in https://github.com/decidim/decidim/issues/5908[#5908]. We decided that: - -* We will not ask CHANGELOG for all the changes make on this repository. We will ask for CHANGELOG instructions only for special changes that really need some actions on part of developers/implementers or something to comunicate on the releases notes -* The CHANGELOG will be manually made as part of the release process with the tooling from git (`git log v0.20.0..v0.20.1 --grep " (#[0-9]\+)" --oneline`) or https://github.com/decidim/decidim/compare/v0.20.0...v0.20.1[github] diff --git a/docs/modules/develop/pages/guide_git_conventions.adoc b/docs/modules/develop/pages/guide_conventions.adoc similarity index 57% rename from docs/modules/develop/pages/guide_git_conventions.adoc rename to docs/modules/develop/pages/guide_conventions.adoc index 9414e76fe4db1..3c5edc0608dd0 100644 --- a/docs/modules/develop/pages/guide_git_conventions.adoc +++ b/docs/modules/develop/pages/guide_conventions.adoc @@ -1,4 +1,4 @@ -= Git Conventions += Conventions == GitFlow Branching model @@ -61,6 +61,14 @@ We would like to have all branches following this namings: | We only offer support for the last mayor version. |=== +After the prefix we recommend to add some words that describe what the change is doing, like a summary of the Pull Request title. For instance, some good branch names are: + +. refactor/autocomplete +. feature/add-pagination-to-moderated-users +. fix/free-text-choice-answer + +The rationale behind this is that we don't like to have the issue number (`fix/9123` or just `9123`) as that difficults working with `git`. + == Git commit messages and Pull Request titles We recommend following https://chris.beams.io/posts/git-commit/[this guide] for making good git commit messages. It also applies to Pull Request titles. The summary is: @@ -73,3 +81,19 @@ We recommend following https://chris.beams.io/posts/git-commit/[this guide] for . Wrap the body at 72 characters . Use the body to explain what and why vs. how +== Changelog + +For keeping track of changes we like the rules of https://keepachangelog.com/en/1.0.0/[Keep A Changelog]. + +In the past we kept a file for all the development of a given version but that was difficult to maintain, as we had conflicts all the time. See the full discussion in https://github.com/decidim/decidim/issues/5908[#5908]. We decided that: + +* We will not ask CHANGELOG for all the changes make on this repository. We will ask for CHANGELOG instructions only for special changes that really need some actions on part of developers/implementers or something to comunicate on the releases notes +* The CHANGELOG will be manually made as part of the release process with the tooling from git (`git log v0.20.0..v0.20.1 --grep " (#[0-9]\+)" --oneline`) or https://github.com/decidim/decidim/compare/v0.20.0...v0.20.1[github] + +== Semantic Versioning + +For releases we follow https://semver.org/[Semantic Versioning recommendations]. Some details in our case: + +* Until v1 there could be changes in the API. We'll let you know on the Release Notes for a given version +* Upgrading on patch versions should be safe (for instance from 0.20.0 to 0.20.1). The only things that we add are bug fixes and new languages. + diff --git a/docs/modules/develop/pages/guide_development_app.adoc b/docs/modules/develop/pages/guide_development_app.adoc index 108c59f565415..6edf7f25af92a 100644 --- a/docs/modules/develop/pages/guide_development_app.adoc +++ b/docs/modules/develop/pages/guide_development_app.adoc @@ -1,39 +1,72 @@ = Development App -In order to start developing you will need what is called a `development_app`. This is nearly the same as a new Decidim app (that you can create with `decidim app_name`) but with a Gemfile pre-configured for local development and some other small config modifications. -You need it in order to have a Rails application configured to lookup Decidim modules from your filesystem. This way changes in your modules will be directly observed by this `development_app`. +In order to start developing you will need what is called a `development_app`. This is nearly the same as a new Decidim +app (that you can create with `decidim app_name`) but with a Gemfile pre-configured for local development and some other small config modifications. -You can create a `development_app` from inside the project's root folder with the command: +We recommend that you first have a xref:install:manual.adoc[working Decidim app] so that you have fullfilled all the necessary +system and services requirements, like having a working Ruby installation, PostgreSQL, Node.JS, etc. + +You'll need to configure the PostgreSQL database before anything. For this, + +1. Configure postgresql with a super-user. For instance, for a user called `decidim_development_app_user` with password `changeme`, it'd be: + +[source,console] +---- +sudo -u postgres psql -c "CREATE USER decidim_development_app_user WITH SUPERUSER CREATEDB NOCREATEROLE PASSWORD 'changeme'" +---- + +2. Save the database configuration in your environment variables configuration. If you've followed the xref:install:manual.adoc[Decidim installation manual], +then you should have a working https://github.com/rbenv/rbenv-vars[rbenv-vars] in your environment: + +[source,console] +---- +echo "DATABASE_USERNAME=decidim_development_app_user" >> ~/.rbenv-vars +echo "DATABASE_PASSWORD=changeme" >> ~/.rbenv-vars +---- + +Of course you should change the password before anything. + +2. Then you can create a `development_app` from inside the project's root folder with the command: [source,console] ---- git clone https://github.com/decidim/decidim.git cd decidim bundle install -bundle exec rake development_app -cd development_app +bin/rake development_app ---- A development_app/ entry appears in the .gitignore file, so you don't have to worry about committing the development app by mistake. -On creation, this steps are automatically invoked by the generator: +[NOTE] +==== +On creation, these steps are automatically invoked by the generator: * create a `config/database.yml` * `bundle install` * `bin/rails decidim:upgrade` -* `bin/rails db:migrate db:seed` +* `bin/rails db:create` +* `bin/rails db:migrate` +* `bin/rails db:seed` + +Mind that if everything went well you shouldn't need to run these commands manually. +==== -If the default database.yml does not suit your needs you can always configure it at your will and run this steps manually. +If the default database.yml does not suit your needs you can always configure it at your will and run these steps manually, although +we recommend that you make the database configurations with environment variables (ENV VARs) so it's easy for you to regenerate the database. -The last command will set your database and add some example data (called "seed data") so that you can start trying Decidim. We don't recommend using seed data for production environments, but it's useful for local development and staging environments. +The last command will set your database and add some example data (called "seed data") so that you can start trying Decidim. +We don't recommend using seed data for production environments, but it's useful for local development and staging environments. Once the app is created you are ready to start the server: -* `bin/rails s` +* `bin/rails server` == Migrations -When creating new migrations in Decidim's modules, you will need to "apply" this migrations to your development_app. The way to do this is by copying the migration from your module into the db/migrate dir of your development_app. Luckily we already have a script that automates this: it copies all missing migrations in development_app/db/migrate. The command is: +When creating new migrations in Decidim's modules, you will need to "apply" this migrations to your development_app. The way +to do this is by copying the migration from your module into the db/migrate dir of your development_app. Luckily we already +have a script that automates this: it copies all missing migrations in development_app/db/migrate. The command is: [source,console] ---- @@ -42,3 +75,25 @@ bin/rails decidim:upgrade Anyway we recommend re-creating your development_app every once in a while. +== Updating from develop + +We recommend that you periodically update your codebase with the last changes from the main repository. For this, you'll need +to follow these instructions: + +[source,console] +---- +git pull origin develop +bin/rails decidim:upgrade +bin/rails db:migrate +---- + +And restart your rails server (with Ctrl+C to stop it). + +== Re-creating the development_app + +If you're working with old branches or there were multiple changes in develop, you'll need to re-create your development_app. + +[source,console] +---- +bin/rake development_app +---- diff --git a/docs/modules/develop/pages/guide_migrate_webpacker_app.adoc b/docs/modules/develop/pages/guide_migrate_webpacker_app.adoc index be496956d01d6..fa50b36d2564a 100644 --- a/docs/modules/develop/pages/guide_migrate_webpacker_app.adoc +++ b/docs/modules/develop/pages/guide_migrate_webpacker_app.adoc @@ -2,14 +2,14 @@ In order to migrate an existing Decidim app to Webpacker, there are a few changes your need to run in your code. -Disclaimer: this recipe might not work for all the cases, it tries to cover the generic scenarios. If you find yourself with a complex scenario and want to improve this guide feel free to open a PR to complete the guide. +NOTE: this recipe might not work for all the cases, it tries to cover the generic scenarios. If you find yourself with a complex scenario and want to improve this guide feel free to open a PR to complete the guide. == About Webpacker It's recommended to understand how Webpacker works. More information: -* https://github.com/rails/webpacker#usage -* https://edgeguides.rubyonrails.org/webpacker.html +* https://github.com/rails/webpacker#usage[Webpacker README] +* https://edgeguides.rubyonrails.org/webpacker.html[Rails Webpacker guide] == Requirements @@ -17,12 +17,15 @@ Before starting the migration, please check you have the following dependencies - Node.js version 16.9.x (this version is mandatory) - Npm version 7.21.x (it works with other versions, but this is the recommended) +- Decidim updated to at least v0.25.0.rc4 -== Add Webpacker to the application +== Guide -Follow the steps described https://github.com/rails/webpacker#installation[here] +=== Add Webpacker to the application -- Install it +Follow these steps. If you want more information you can find it at the https://github.com/rails/webpacker#installation[Webpacker installation guide]. + +* Install it [source,console] ---- @@ -40,7 +43,7 @@ This task do a few steps to allow the Rails instance to have a webpacker instanc This task is automatically performed every time decidim is updated, to get the latest Webpack configuration. This happens when you run the `decidim:upgrade` task. -== Copy Decidim custom CSS and Javascript +=== Copy Decidim custom CSS and Javascript `webpacker:install` task should have created to you the following dirs structure: @@ -61,11 +64,27 @@ If it's not the case you must create it. Then, copy Decidim customizable assets These files are hooked into Decidim packs (specifically into decidim-core pack) and will be automatically included inside that pack when compiled. -== Migrate images +You can download these files directly with these commands: + +[source,console] +---- +mkdir -p app/packs/src/decidim app/packs/stylesheets/decidim app/packs/stylesheets/images +touch app/packs/src/decidim/.keep app/packs/stylesheets/decidim/.keep app/packs/stylesheets/images/.keep +wget https://raw.githubusercontent.com/decidim/decidim/develop/decidim-generators/lib/decidim/generators/app_templates/decidim_application.js -O app/packs/src/decidim/decidim_application.js +wget https://raw.githubusercontent.com/decidim/decidim/develop/decidim-generators/lib/decidim/generators/app_templates/decidim_application.scss -O app/packs/stylesheets/decidim/decidim_application.scss +wget https://raw.githubusercontent.com/decidim/decidim/develop/decidim-generators/lib/decidim/generators/app_templates/_decidim-settings.scss -O app/packs/stylesheets/decidim/_decidim-settings.scss +---- + +=== Migrate images Copy the existing images from `app/assets/images` to `app/packs/images`. Images will be available at `/media/images/image.png` -== Migrate stylesheets +[source,console] +---- +cp -rp app/assets/images/* app/packs/images/ +---- + +=== Migrate stylesheets Existing stylesheets should be moved from `app/assets/stylesheets` to `app/packs/stylesheets` and imported with `@import` into `decidim_application.scss`. Take into account that you might need to adjust a bit the paths of the `@import` to adjust them to the new locations. @@ -73,26 +92,26 @@ If that CSS file is replacing a Decidim file, there's no need to add it to `deci If any of the CSS is re-defining CSS vars add them to `_decidim-settings.scss`. -== Migrate javascripts +=== Migrate javascripts Existing javascripts should be moved from `app/assets/javascsripts` to `app/packs/src` and imported with `import` into `decidim_application.js`. Take into account that you might need to adjust a bit the paths of the `import` to adjust them to the new locations. If that JS file is replacing a Decidim file, there's no need to add it to `decidim_application.js` -== Update Rails helpers +=== Update Rails helpers -`javascript_include_tag` and `stylesheet_link_tag` have been replaced by `javascript_pack_tag` and `stylesheet_pack_tag`. +`javascript_include_tag` and `stylesheet_link_tag` have been replaced by `javascript_pack_tag` and `stylesheet_pack_tag`. This only needs to be done if you're modifying the `application.html` file or partial in your layout. -For images, if they are in `app/packs/images` you could use `image_pack_tag`. +For images, if they are in `app/packs/images` you need to replace `ìmage_tag` with `image_pack_tag`. -== Migrate vendorized files and gems +=== Migrate vendorized files and gems Sometimes assets are included in `vendor/assets/` folder or imported from gems. For each specific one you should check: 1. if the asset is a javascript that is available as npm package the recommendation is to add it to package.json with `npm install`. If it's not available you might want to copy it to `app/packs/src` and import it. 2. if the asset is a stylesheet it should be copied to `app/packs/stylesheets` and imported with `@import...` from `_decidim-settings.scss`. Alternatively you can use the optional asset includes as described below to include these in the Decidim main SCSS files. -== Optional asset includes +=== Optional asset includes Decidim Webpacker provides a new configuration convention that allows you to add extra configurations for webpacker using a configuration file named `config/assets.rb`. Within this file, you have the following API methods available: @@ -117,7 +136,7 @@ Decidim::Webpacker.register_stylesheet_import("stylesheets/your_app_extensions") Decidim::Webpacker.register_stylesheet_import("stylesheets/your_app_admin_extensions", group: :admin) ---- -== Remove Sprockets references +=== Remove Sprockets references The completely remove Sprockets references from your application: @@ -154,7 +173,7 @@ To prevent Zeitwerk issues trying to autoload the non-ruby application folders, Decidim.register_assets_path File.expand_path("app/packs", Rails.application.root) --- -== Deployment +=== Deployment The deployment needs to be updated to manually run `npm install` before assets are precompiled. diff --git a/docs/modules/develop/pages/guide_semver.adoc b/docs/modules/develop/pages/guide_semver.adoc deleted file mode 100644 index 5542e66c85b1f..0000000000000 --- a/docs/modules/develop/pages/guide_semver.adoc +++ /dev/null @@ -1,7 +0,0 @@ -= Semantic Versioning - -For releases we follow https://semver.org/[Semantic Versioning recommendations]. Some details in our case: - -* Until v1 there could be changes in the API. We'll let you know on the Release Notes for a given version -* Upgrading on patch versions should be safe (for instance from 0.20.0 to 0.20.1). The only things that we add are bug fixes and new languages. - diff --git a/docs/modules/develop/pages/machine_translations.adoc b/docs/modules/develop/pages/machine_translations.adoc index fc0b074173b9c..8514d50b25adf 100644 --- a/docs/modules/develop/pages/machine_translations.adoc +++ b/docs/modules/develop/pages/machine_translations.adoc @@ -1,6 +1,6 @@ = Using machine translations -For multilingual organizations, Decidim includes a way to integrate with amachine translation service. The aim of this integration is to provide machine translations for any user-generated content. +For multilingual organizations, Decidim includes a way to integrate with a machine translation service. The aim of this integration is to provide machine translations for any user-generated content. == Flow description @@ -16,6 +16,8 @@ This workflow will only start if the machine translation service is configured i == Create your own machine translation service You can use the `Decidim::Dev::DummyTranslator` service as a base. Any new translator service will need to implement the same API as this class. +In order to test the `Decidim::Dev::DummyTranslator` you will need to add at the top of `config/initializers/decidim.rb` the following line: +`require "decidim/dev/dummy_translator"` == Integrating with async services @@ -33,10 +35,14 @@ This is an option in the Decidim initializer: ---- config.enable_machine_translations = true config.machine_translation_service = "MyApp::MyOwnTranslationService" +config.machine_translation_delay = 0.seconds ---- The class will need to be implemented, or reuse one from the community. Check the docs on how to implement a machine translation service. == Enabling the integration, organization-wise -Each organization will be able to enable/disable machine translations if they want to. They can do that from the organization configuration. +Each organization will be able to enable / disable the machine translations if they want to. The administrators of the organization perform the action from `Settings` -> `Configuration` admin menu, where they can enable or disable the machine translation system, and also they can select the priority. + +* Original text first means that the platform will always display the original content as it has been added by contributors +* Translated text first means that the platform will always display the translation first. diff --git a/docs/modules/develop/pages/modules.adoc b/docs/modules/develop/pages/modules.adoc index 7649ccb3463a0..bc28128446eb0 100644 --- a/docs/modules/develop/pages/modules.adoc +++ b/docs/modules/develop/pages/modules.adoc @@ -1,11 +1,114 @@ = Modules -Modules are subapplications that are run as application plugins. -They're used to define pieces of functionality that are pluggable to Decidim. - -Decidim's modules are no more than Ruby on Rails engines that should be required in the application's `Gemfile`. - -You can see some of our more popular modules at https://decidim.org/modules[Decidim's Modules]. +Decidim provides plenty of features, but sometimes you will want to customize or change the default behavior of some +of them. Usually, there are two ways to do that: + +. Creating overrides in your application +. Creating a new module + +The first option is ideal to start hacking with your Decidim implementation but, if you want to create something that others +can benefit, the best is to create a module in a gem of its own that can be installed anywhere. + +NOTE: There's also a third possibility and create a module that is in a sub-folder of the application itself. This approach +simplifies a little the integration with your app and facilitates a future extraction to a proper external gem. You can +see some examples of this in the https://github.com/AjuntamentdeBarcelona/decidim-barcelona/tree/master/decidim-census_sms?rgh-link-date=2021-07-23T09%3A19%3A08Z[Ajuntament of Barcelona] +in the folders `decidim-census_sms`, `decidim-dataviz`, `decidim-ephemeral_participation`, or `decidim-stats`. +However, we don't recommend this unless you are more in a testing phase and not sure if your work is going to be released +more generically (most of the times this is the first approach for isolating the features). See more details about the sub-folder approach +at xref:customize:code.adoc[Code customization]. + +By creating a new module, you can override almost anything or provide new functionalities. +The best way to proceed is to first decide what you need, then take a look at how similar things have been done previously in: + +- Other external modules +- Other Decidim instances, and from there extract the feature to a module +- Decidim source code itself: take into account that Decidim is a bunch of separated modules, so there's much to be learned by looking at the code). +- Other Rails applications or documentation, because yes, this is Ruby on Rails in the end. + +Regarding the type of features you want to develop, these are some typical cases: + +- Create a new component or a new participatory space: For this task, Decidim is well prepared already, and when creating a new module by default (running decidim --component my-new-module), it creates a scaffolding for it. +- Add new routes without many relations to existing features. Then just follow standard guides for creating engines for Ruby on Rails. +- Creating a verification handler: very typical scenario. Some verification methods are worth extracting to a module as can be very standard. +- Add content blocks. Content blocks are used currently in the homepage and processes groups, they can transform the user experience quite a lot! +- xref:customize:views.adoc[Override existing view]: This is quite common but more delicate, it consists of creating the same app/view/some-decidim-view-file file in your module to replace the original one. It's easy but you need to define a strategy for updating your overridden file every time the original in Decidim source code is changed. Some people use the gem Deface for that too. +- xref:customize:code.adoc[Override other classes or modules in Decidim]: Similar as before, but instead of just overriding files you usually take advantage of the technique of "monkey patching", something that the Ruby language is especially well suited for. Again, you need to be careful between Decidim upgrades if the original files change. + +Note also that the two last ones might have conflicts with other modules, so it is worth having a nice suite of tests, both in modules and specific Decidim implementations. + +There's a https://decidim.org/modules/[list of modules] that it is updated from time to time, but if you are looking for technology implementations, take a look at these (please contribute to this list if you are implementing something new!): + +. Payment gateways: https://github.com/decidiamo/decidim-module-donations[decidiamo/decidim-module-donations] +. Generic verification handlers: +.. https://github.com/mainio/decidim-module-access_requests[mainio/decidim-module-access_requests] +.. https://github.com/Platoniq/decidim-verifications-direct_verifications[Platoniq/decidim-verifications-direct_verifications] +.. https://github.com/CodiTramuntana/decidim-verifications-custom_csv_census[CodiTramuntana/decidim-verifications-custom_csv_census] +.. https://github.com/belighted/decidim-module-verifications_omniauth[belighted/decidim-module-verifications_omniauth] +. New components: +.. https://github.com/Platoniq/decidim-module-time_tracker[Platoniq/decidim-module-time_tracker] +.. https://github.com/alabs/decidim-module-calendar[alabs/decidim-module-calendar] +.. https://github.com/AjuntamentdeBarcelona/decidim-barcelona/tree/master/decidim-dataviz[AjuntamentdeBarcelona/decidim-barcelona] +. New participatory spaces: None yet! be the first! +. Using ActionCable (WebSockets): https://github.com/Platoniq/decidim-module-notify[Platoniq/decidim-module-notify] +. Overriding some core Rails features (i18n locale processing) and make use of advanced strategies like cache: https://github.com/mainio/decidim-module-term_customizer[mainio/decidim-module-term_customizer] +. Simple hacks to add/improve generic functionalities: +.. https://github.com/PopulateTools/decidim-module-anonymous_proposals[PopulateTools/decidim-module-anonymous_proposals] +.. https://github.com/PopulateTools/decidim-module-extra_user_fields[PopulateTools/decidim-module-extra_user_fields] +.. https://github.com/OpenSourcePolitics/decidim-module-question_captcha[OpenSourcePolitics/decidim-module-question_captcha] +. Content blocks: +.. https://github.com/Platoniq/decidim-module-navigation_maps[Platoniq/decidim-module-navigation_maps] +.. https://github.com/Platoniq/decidim-module-alternative_landing[Platoniq/decidim-module-alternative_landing] +.. https://github.com/mainio/decidim-module-process_groups_content_block[mainio/decidim-module-process_groups_content_block] +. New admin zones: +.. https://github.com/Platoniq/decidim-module-comparative_stats[Platoniq/decidim-module-comparative_stats] +.. https://github.com/digidemlab/decidim-module-analytics[digidemlab/decidim-module-analytics] +. Technical hacks (are intended to be used by a developer while customizing a Decidim instance): +.. https://github.com/mainio/decidim-module-tags[mainio/decidim-module-tags] +.. https://github.com/mainio/decidim-module-feedback[mainio/decidim-module-feedback] +. Wild hacks (the implement a variety of techniques to change Decidim existing features): +.. https://github.com/mainio/decidim-module-simple_proposal[mainio/decidim-module-simple_proposal] +.. https://github.com/coopdevs/decidim-module-action_delegator[coopdevs/decidim-module-action_delegator] +.. https://github.com/Platoniq/decidim-module-decidim_awesome[Platoniq/decidim-module-decidim_awesome] + +In the case of dealing with more advanced overrides, we recommend implementing some tests that take into account the original files from which the override was created and run it every time a Decidim version is upgraded. Take this https://github.com/coopdevs/decidim-module-action_delegator/blob/master/spec/lib/overrides_spec.rb[checksum checker] as an example. + +== Recommendations + +First and foremost, don't be afraid to try and start hacking. Once you feel confident enough, read the recommendations +and best practices below. Remember also that this is free software, so you can do whatever you want in the end. +These are some opinions on how to improve the quality of the software, but they are not hard rules. + +* To be programmed in English (variables, method and class names, comments, etc) +* To have tests and continuous integration with good test coverage +* To have documentation in English, explaining: + . all the available commands (rake tasks and such) + . screenshots of the admin and participant UI + . steps to install it + . feel free to add in the README if you want who's developing/sponsoring it: + - The gem has been developed by $Your_Employer + - Development of this gem has been sponsored by $Your_Customer + . steps to run the tests locally + . how do you want to accept contributions +* To follow our same rules regarding https://github.com/decidim/decidim/blob/develop/.rubocop.yml[code styling] +* To have a license file that's compatible with Decidim license (GPL Affero 3) +* To have a valid .gemspec file +* To follow the Decidim Social Contract +* To have a description and other metadata (ie tags) on GitHub or another platform, so it's more discoverable +* Has good i18 support (all the strings that could be translated are in config/locales/en.yml) +* If you upload it to GitHub, do it with the naming *decidim-module-*, so it's easier to find on +the https://github.com/decidim/decidim/network/dependents[dependency graph]. See discussion at https://github.com/decidim/decidim/issues/2396[GitHub]. +* To use Decidim features and APIs when relevant: + . Using the Admin panel + . Generate logs on Admin panel if admins can operate on it + . GraphQL API + . Data Portability + . Endorsable + . Followable + . Embeddable + . Notifications + . If it's a new space, then it should be compatible with the "Context help" +* Upload the Gem to Rubygems.org so it's easier to deploy to other apps +* To https://decidim.org/contact/[contact us] so we can publish it at https://decidim.org/modules/[Modules page] == Types diff --git a/docs/modules/develop/pages/security.adoc b/docs/modules/develop/pages/security.adoc index da0a9b26e2f46..3d5b8834dae96 100644 --- a/docs/modules/develop/pages/security.adoc +++ b/docs/modules/develop/pages/security.adoc @@ -5,15 +5,7 @@ Until we have the version 1.0 we support only the last minor and major version with security updates. -|=== -| Version | Supported - -| 0.21.x -| :white_check_mark: - -| \<= 0.20 -| :x: -|=== +https://github.com/decidim/decidim/blob/doc/security-keyserver/SECURITY.adoc[See the last supported version]. == Reporting a Vulnerability @@ -29,5 +21,5 @@ is `C1BD 8981 D83C 23F9 D419 FE42 149A D0F9 84B9 35C4`. To download our key: [source,bash] ---- -gpg --keyserver pgp.key-server.io --recv 84B935C4 +gpg --keyserver pgp.mit.edu --recv 84B935C4 ---- diff --git a/docs/modules/install/pages/manual.adoc b/docs/modules/install/pages/manual.adoc index 12f6e9fd19c8d..67bb9e4f35902 100644 --- a/docs/modules/install/pages/manual.adoc +++ b/docs/modules/install/pages/manual.adoc @@ -4,17 +4,17 @@ In order to develop on decidim, you'll need: * *Git* 2.15+ * *PostgreSQL* 12.7+ -* *Ruby* 2.7.1 +* *Ruby* 2.7.5 * *NodeJS* 16.9.x * *Npm* 7.21.x * *ImageMagick* * *Chrome* browser and https://sites.google.com/a/chromium.org/chromedriver/[chromedriver]. -We're starting with an Ubuntu 20.04 LTS. This is an opinionated guide, so you're free to use the technology that you are most comfortable. If you have any doubts and you're blocked you can go and ask on https://gitter.im/decidim/decidim[our Gitter]. +We're starting with an Ubuntu 20.04.2 LTS. This is an opinionated guide, so you're free to use the technology that you are most comfortable. If you have any doubts and you're blocked you can go and ask on https://matrix.to/#/#decidimdevs:matrix.org[our Matrix.org chat room for developers]. We recommend to have at least some basic proficiency in Ruby on Rails (a good starting point is http://guides.rubyonrails.org/getting_started.html[Getting Started with Ruby on Rails]) and have some knowledge on how gems work. -In this guide, we'll see how to install rbenv, PostgreSQL and, Decidim, and how to configure everything together. +In this guide, we'll see how to install rbenv, PostgreSQL, Node.js and, Decidim, and how to configure everything together for a development environment. Mind that if you want to make a production deployment with real users this guide isn't enough, you should configure a web server (like nginx), backups, monitoring, etc. This is out of the scope of this guide, but you can follow the https://platoniq.github.io/decidim-install/[Platoniq guide]. == 1. Installing rbenv @@ -23,14 +23,14 @@ First, we're going to install https://github.com/rbenv/rbenv[rbenv], for managin [source,bash] ---- sudo apt update -sudo apt install -y build-essential git libssl-dev zlib1g-dev +sudo apt install -y build-essential curl git libssl-dev zlib1g-dev git clone https://github.com/rbenv/rbenv.git ~/.rbenv echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc echo 'eval "$(rbenv init -)"' >> ~/.bashrc source ~/.bashrc git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build -rbenv install 2.7.1 -rbenv global 2.7.1 +rbenv install 2.7.5 +rbenv global 2.7.5 ---- == 2. Installing PostgreSQL @@ -45,13 +45,26 @@ sudo -u postgres psql -c "CREATE USER decidim_app WITH SUPERUSER CREATEDB NOCREA You need to change the password (in this example is "thepassword") and save it somewhere to configure it later with the application. -== 3. Installing Decidim +== 3. Installing Node.js + +An important component for Decidim is Node.js and Yarn. With this commands you will install them: + +[source,bash] +---- +curl -sL https://deb.nodesource.com/setup_16.x | sudo -E bash - +sudo apt-get install -y nodejs +curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | sudo tee /usr/share/keyrings/yarnkey.gpg >/dev/null +echo "deb [signed-by=/usr/share/keyrings/yarnkey.gpg] https://dl.yarnpkg.com/debian stable main" | sudo tee /etc/apt/sources.list.d/yarn.list +sudo apt-get update && sudo apt-get install -y yarn +---- + +== 4. Installing Decidim Next, we need to install the `decidim` gem with its dependencies: [source,bash] ---- -sudo apt install -y libicu-dev nodejs imagemagick +sudo apt install -y libicu-dev imagemagick gem install decidim ---- @@ -71,43 +84,34 @@ git add . git commit -m "Initial commit. Generated with Decidim https://decidim.org" ---- -== 4. Configure the database +== 5. Configure the database -Modify your secrets (see `config/database.yml`). For this you can use https://github.com/laserlemon/figaro[figaro], https://github.com/bkeepers/dotenv[dotenv] or https://github.com/rbenv/rbenv-vars[rbenv-vars]. You should always be careful of not uploading your plain secrets on git or your version control system. You can also upload the encrypted secrets, using the sekrets gem or if you're on Ruby on Rails greater than 5.1 you can do it natively. +Modify your secrets (see `config/database.yml`). For this you can use https://github.com/laserlemon/figaro[figaro], https://github.com/bkeepers/dotenv[dotenv] or https://github.com/rbenv/rbenv-vars[rbenv-vars]. You +should always be careful of not uploading your plain secrets on git or your version control system. You can also upload the encrypted secrets, using the sekrets gem or if you're on Ruby on Rails greater than 5.1 you can do it natively. -For instance, for working with figaro, add this to your `Gemfile`: +For a development environment, and if you are using rbenv, we strongly recommend you to use the https://github.com/rbenv/rbenv-vars[rbenv-vars] to facilitate the edition of ENV vars. -[source,ruby] ----- -gem "figaro" ----- - -Then install it: +First you'll need to install the rbenv-vars plugin: [source,bash] ---- -bundle install -bundle exec figaro install +git clone https://github.com/rbenv/rbenv-vars.git "$(rbenv root)"/plugins/rbenv-vars ---- -Next, add this to your `config/application.yml`, using the setup PostgreSQL database name, user and, password that you've configured before. - -[source,yaml] ----- -DATABASE_HOST: localhost -DATABASE_USERNAME: decidim_app -DATABASE_PASSWORD: thepassword ----- - -Finally, save it all to git: +Then, in **any folder above your decidim generated application**, you need to create a file named `.rbenv-vars` and put your variables there: [source,bash] ---- -git add . -git commit -m "Add figaro configuration management" +cat << EOF > .rbenv-vars +DATABASE_HOST=localhost +DATABASE_USERNAME=decidim_app +DATABASE_PASSWORD=thepassword +EOF ---- -== 5. Initializing your app for local development +Be careful where you put the `.rbenv-vars` file, as if you put it in the same folder of your decidim generated application, and if you use a version control system (like `git`, which we strongly recommend), then you should ignore this file (ie with the `.gitignore` file). + +== 6. Initializing your app for local development We should now create your database: @@ -119,7 +123,7 @@ bin/rails db:seed This will also create some default data so you can start testing the app, with an administrator account with email admin@example.org and password `decidim123456` -== 6. Start your web server +== 7. Start your web server You can now start your server! diff --git a/lib/decidim.rb b/lib/decidim.rb index 304a14c261d15..11eb5b2c96c0e 100644 --- a/lib/decidim.rb +++ b/lib/decidim.rb @@ -15,8 +15,8 @@ require "decidim/pages" require "decidim/comments" -require "decidim/meetings" require "decidim/proposals" +require "decidim/meetings" require "decidim/budgets" require "decidim/surveys" require "decidim/accountability" diff --git a/lib/decidim/gem_manager.rb b/lib/decidim/gem_manager.rb index d76f5406bb719..f742ed283b9a0 100644 --- a/lib/decidim/gem_manager.rb +++ b/lib/decidim/gem_manager.rb @@ -132,20 +132,31 @@ def uninstall_all(out: $stdout) def run_all(command, out: $stdout, include_root: true) all_dirs(include_root: include_root) do |dir| - status = new(dir).run(command, out: out) + status = run_at(dir, command, out: out) - break unless status || ENV["FAIL_FAST"] == "false" + break if !status && fail_fast? end end def run_packages(command, out: $stdout) package_dirs do |dir| - status = new(dir).run(command, out: out) + status = run_at(dir, command, out: out) - break unless status || ENV["FAIL_FAST"] == "false" + break if !status && fail_fast? end end + def run_at(dir, command, out: $stdout) + attempts = 0 + until (status = new(dir).run(command, out: out)) + attempts += 1 + + break if attempts > Decidim::GemManager.retry_times + end + + status + end + def version @version ||= File.read(version_file).strip end @@ -177,6 +188,14 @@ def semver_friendly_version(a_version) a_version.gsub(/\.pre/, "-pre").gsub(/\.dev/, "-dev").gsub(/.rc(\d*)/, "-rc\\1") end + def fail_fast? + ENV.fetch("FAIL_FAST", nil) != "false" + end + + def retry_times + ENV.fetch("RETRY_TIMES", 10).to_i + end + private def root diff --git a/lib/decidim/version.rb b/lib/decidim/version.rb index 58e2a09210729..2bcc88ede72ff 100644 --- a/lib/decidim/version.rb +++ b/lib/decidim/version.rb @@ -3,6 +3,6 @@ # This holds the decidim version and the faker version it uses. module Decidim def self.version - "0.25.2" + "0.26.4" end end diff --git a/lib/tasks/common_passwords_tasks.rake b/lib/tasks/common_passwords_tasks.rake new file mode 100644 index 0000000000000..e15715ba3d124 --- /dev/null +++ b/lib/tasks/common_passwords_tasks.rake @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +require "decidim/common_passwords" + +namespace :decidim do + namespace :common_passwords do + desc "Update common passwords list" + task :update do + Decidim::CommonPasswords.update_passwords! + end + end +end diff --git a/package-lock.json b/package-lock.json index bd87c26d7f77b..9d5beaabb0b6e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,7 +5,6 @@ "packages": { "": { "name": "a-decidim-app", - "license": "AGPL-3.0", "dependencies": { "@decidim/browserslist-config": "file:packages/browserslist-config", "@decidim/core": "file:packages/core", @@ -1710,31 +1709,6 @@ "node": ">=0.1.95" } }, - "node_modules/@codegram/decidim-bulletin_board": { - "version": "0.21.2", - "resolved": "https://registry.npmjs.org/@codegram/decidim-bulletin_board/-/decidim-bulletin_board-0.21.2.tgz", - "integrity": "sha512-o4eqR46lqtF/y+VyaV1elsLXLWnMEjMN1eCw27cDhvZHY4L+5Ec68w1HzC+brzLf5v5847DyS91kpxWIoi9C4A==", - "dependencies": { - "@apollo/client": "^3.2.7", - "core-js": "^3.8.3", - "graphql": "^15.4.0", - "node-jose": "^2.0.0", - "regenerator-runtime": "^0.13.7", - "rxjs": "^6.6.3", - "webpack": "^5.11.0", - "webpack-cli": "^4.2.0" - } - }, - "node_modules/@codegram/voting_schemes-dummy": { - "version": "0.21.2", - "resolved": "https://registry.npmjs.org/@codegram/voting_schemes-dummy/-/voting_schemes-dummy-0.21.2.tgz", - "integrity": "sha512-zwrBPIO8Escg54vxaqYqz4dgTbXq3xacu5h1u52mzABoYgniWLVzmsjTm6fKIzXs/RASgpxVmsIRgqiUDlHgCg==" - }, - "node_modules/@codegram/voting_schemes-electionguard": { - "version": "0.21.2", - "resolved": "https://registry.npmjs.org/@codegram/voting_schemes-electionguard/-/voting_schemes-electionguard-0.21.2.tgz", - "integrity": "sha512-BcAzcPVlC1glH8WRpyjeNZ804KAjbn3khUuzyNiOPnvFqYZoUhjcrKhB13S1YJNIk6v8NsGFDpkZq+s+irJQ/g==" - }, "node_modules/@csstools/convert-colors": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@csstools/convert-colors/-/convert-colors-1.4.0.tgz", @@ -1751,6 +1725,21 @@ "resolved": "packages/core", "link": true }, + "node_modules/@decidim/decidim-bulletin_board": { + "version": "0.22.3", + "resolved": "https://registry.npmjs.org/@decidim/decidim-bulletin_board/-/decidim-bulletin_board-0.22.3.tgz", + "integrity": "sha512-LN7wIK9IB9Zegr++fvEY2vAWdUvReLPCe3sbPMGadX3b2aurrx/SK3B38OfRdN2eqblksMzyNYtXALszA9dU2w==", + "dependencies": { + "@apollo/client": "^3.2.7", + "core-js": "^3.8.3", + "graphql": "^15.4.0", + "node-jose": "^2.0.0", + "regenerator-runtime": "^0.13.7", + "rxjs": "^6.6.3", + "webpack": "^5.11.0", + "webpack-cli": "^4.2.0" + } + }, "node_modules/@decidim/dev": { "resolved": "packages/dev", "link": true @@ -1767,6 +1756,16 @@ "resolved": "packages/stylelint-config", "link": true }, + "node_modules/@decidim/voting_schemes-dummy": { + "version": "0.22.3", + "resolved": "https://registry.npmjs.org/@decidim/voting_schemes-dummy/-/voting_schemes-dummy-0.22.3.tgz", + "integrity": "sha512-Z5CwSUJNYW2KkoE5anAqAIwHnQHqpgGL4Xu2I7YqEn3thThlbWlY9U9Eq0O6fq7/pfBQLiAFFiBBAnCDv0HC2g==" + }, + "node_modules/@decidim/voting_schemes-electionguard": { + "version": "0.22.3", + "resolved": "https://registry.npmjs.org/@decidim/voting_schemes-electionguard/-/voting_schemes-electionguard-0.22.3.tgz", + "integrity": "sha512-RZn/1GO5PM6a2SuN8h/SoS4EeLYnHPWw6/tl2M26ms/Xzf1ewJIgBSiByxk4qHoqvE892rccH4+G56h6iVrIqg==" + }, "node_modules/@decidim/webpacker": { "resolved": "packages/webpacker", "link": true @@ -3129,6 +3128,13 @@ "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", "dev": true }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "optional": true, + "peer": true + }, "node_modules/accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -3274,6 +3280,16 @@ "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=" }, + "node_modules/amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.4.2" + } + }, "node_modules/ansi-colors": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", @@ -3340,6 +3356,50 @@ "node": ">= 8" } }, + "node_modules/aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "optional": true, + "peer": true + }, + "node_modules/are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "optional": true, + "peer": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "node_modules/are-we-there-yet/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "optional": true, + "peer": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/are-we-there-yet/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, + "peer": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -3389,6 +3449,16 @@ "node": ">=0.10.0" } }, + "node_modules/array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -3558,6 +3628,16 @@ "lodash": "^4.17.14" } }, + "node_modules/async-foreach": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", + "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=", + "optional": true, + "peer": true, + "engines": { + "node": "*" + } + }, "node_modules/async-limiter": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", @@ -4380,6 +4460,14 @@ "ieee754": "^1.1.13" } }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "engines": { + "node": "*" + } + }, "node_modules/buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", @@ -4499,11 +4587,35 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, + "devOptional": true, "engines": { "node": ">=6" } }, + "node_modules/camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "optional": true, + "peer": true, + "dependencies": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/camelcase-keys/node_modules/camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/caniuse-api": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", @@ -5094,6 +5206,13 @@ "node": ">=0.8" } }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "optional": true, + "peer": true + }, "node_modules/content-disposition": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", @@ -5728,6 +5847,19 @@ "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", "dev": true }, + "node_modules/currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "optional": true, + "peer": true, + "dependencies": { + "array-find-index": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/d3": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/d3/-/d3-5.4.0.tgz", @@ -6230,6 +6362,13 @@ "node": ">=0.4.0" } }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "optional": true, + "peer": true + }, "node_modules/denque": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.0.tgz", @@ -6549,6 +6688,16 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "optional": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, "node_modules/envinfo": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", @@ -6739,6 +6888,14 @@ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" }, + "node_modules/es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "dependencies": { + "es6-promise": "^4.0.3" + } + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -8084,6 +8241,80 @@ "node": ">=0.10.0" } }, + "node_modules/extract-zip": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", + "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==", + "dependencies": { + "concat-stream": "^1.6.2", + "debug": "^2.6.9", + "mkdirp": "^0.5.4", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + } + }, + "node_modules/extract-zip/node_modules/concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "engines": [ + "node >= 0.8" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/extract-zip/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/extract-zip/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/extract-zip/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/extract-zip/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/extract-zip/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", @@ -8161,6 +8392,14 @@ "bser": "2.1.1" } }, + "node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dependencies": { + "pend": "~1.2.0" + } + }, "node_modules/file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -8347,9 +8586,12 @@ "integrity": "sha1-bciR8/ZCICghn3QoTRaEVIqMpL8=" }, "node_modules/foundation-sites": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/foundation-sites/-/foundation-sites-6.7.1.tgz", - "integrity": "sha512-Qr+9oQUItVInQG4wK2PKL53RwPe1eyx1irmgTkTGfm1CM0snQuenCRl7OtD8MfMykqw4NOU9JQGDLgV8oz0jxg==", + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/foundation-sites/-/foundation-sites-6.7.0.tgz", + "integrity": "sha512-dajdL/7i5rn5F70I2FMnfDOlgXD5klCw8OS9a+Y3rM2fyj9f8JZkJ50eYukmeEM4zVnj+Xo6rJfciLxN/QEYWQ==", + "dependencies": { + "puppeteer": "^1.11.0" + }, "engines": { "node": ">=12.0" }, @@ -8484,6 +8726,87 @@ "resolved": "https://registry.npmjs.org/fuzzysort/-/fuzzysort-1.1.4.tgz", "integrity": "sha512-JzK/lHjVZ6joAg3OnCjylwYXYVjRiwTY6Yb25LvfpJHK8bjisfnZJ5bY8aVWwTwCXgxPNgLAtmHL+Hs5q1ddLQ==" }, + "node_modules/gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "optional": true, + "peer": true, + "dependencies": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "node_modules/gauge/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "optional": true, + "peer": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "optional": true, + "peer": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gauge/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "optional": true, + "peer": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/gaze": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", + "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", + "optional": true, + "peer": true, + "dependencies": { + "globule": "^1.0.0" + }, + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -8496,7 +8819,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, + "devOptional": true, "engines": { "node": "6.* || 8.* || >= 10.*" } @@ -8523,6 +8846,16 @@ "node": ">=8.0.0" } }, + "node_modules/get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/get-stream": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", @@ -8673,6 +9006,21 @@ "dev": true, "peer": true }, + "node_modules/globule": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.2.tgz", + "integrity": "sha512-7IDTQTIu2xzXkT+6mlluidnWo+BypnbSoEVVQCGfzqnl5Ik8d3e1d4wycb8Rj9tWW+Z39uPWsdlquqiqPCd/pA==", + "optional": true, + "peer": true, + "dependencies": { + "glob": "~7.1.1", + "lodash": "~4.17.10", + "minimatch": "~3.0.2" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/gonzales-pe": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz", @@ -9168,6 +9516,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "optional": true, + "peer": true + }, "node_modules/has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -9973,6 +10328,19 @@ "node": ">=0.10.0" } }, + "node_modules/is-finite": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", + "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -11928,6 +12296,13 @@ "node": ">=4.2" } }, + "node_modules/js-base64": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", + "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==", + "optional": true, + "peer": true + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -12504,6 +12879,20 @@ "loose-envify": "cli.js" } }, + "node_modules/loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "optional": true, + "peer": true, + "dependencies": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -12562,7 +12951,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true, + "devOptional": true, "peer": true, "engines": { "node": ">=0.10.0" @@ -12722,6 +13111,142 @@ "node": ">= 4.0.0" } }, + "node_modules/meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "optional": true, + "peer": true, + "dependencies": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/meow/node_modules/find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "optional": true, + "peer": true, + "dependencies": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/meow/node_modules/load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "optional": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/meow/node_modules/parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "optional": true, + "peer": true, + "dependencies": { + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/meow/node_modules/path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "optional": true, + "peer": true, + "dependencies": { + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/meow/node_modules/path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "optional": true, + "peer": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/meow/node_modules/read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "optional": true, + "peer": true, + "dependencies": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/meow/node_modules/read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "optional": true, + "peer": true, + "dependencies": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/meow/node_modules/strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "optional": true, + "peer": true, + "dependencies": { + "is-utf8": "^0.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -13079,6 +13604,13 @@ "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=" }, + "node_modules/nan": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", + "optional": true, + "peer": true + }, "node_modules/nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -13155,6 +13687,47 @@ "node": ">= 6.0.0" } }, + "node_modules/node-gyp": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz", + "integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==", + "optional": true, + "peer": true, + "dependencies": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.3", + "nopt": "^5.0.0", + "npmlog": "^4.1.2", + "request": "^2.88.2", + "rimraf": "^3.0.2", + "semver": "^7.3.2", + "tar": "^6.0.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": ">= 10.12.0" + } + }, + "node_modules/node-gyp/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "optional": true, + "peer": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -13231,6 +13804,127 @@ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.75.tgz", "integrity": "sha512-Qe5OUajvqrqDSy6wrWFmMwfJ0jVgwiw4T3KqmbTcZ62qW0gQkheXYhcFM1+lOVcGUoRxcEcfyvFMAnDgaF1VWw==" }, + "node_modules/node-sass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-5.0.0.tgz", + "integrity": "sha512-opNgmlu83ZCF792U281Ry7tak9IbVC+AKnXGovcQ8LG8wFaJv6cLnRlc6DIHlmNxWEexB5bZxi9SZ9JyUuOYjw==", + "hasInstallScript": true, + "optional": true, + "peer": true, + "dependencies": { + "async-foreach": "^0.1.3", + "chalk": "^1.1.1", + "cross-spawn": "^7.0.3", + "gaze": "^1.0.0", + "get-stdin": "^4.0.1", + "glob": "^7.0.3", + "lodash": "^4.17.15", + "meow": "^3.7.0", + "mkdirp": "^0.5.1", + "nan": "^2.13.2", + "node-gyp": "^7.1.0", + "npmlog": "^4.0.0", + "request": "^2.88.0", + "sass-graph": "2.2.5", + "stdout-stream": "^1.4.0", + "true-case-path": "^1.0.2" + }, + "bin": { + "node-sass": "bin/node-sass" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-sass/node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-sass/node_modules/ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-sass/node_modules/chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "optional": true, + "peer": true, + "dependencies": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-sass/node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "optional": true, + "peer": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/node-sass/node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "optional": true, + "peer": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/node-sass/node_modules/supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "optional": true, + "peer": true, + "dependencies": { + "abbrev": "1" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -13292,6 +13986,19 @@ "node": ">=8" } }, + "node_modules/npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "optional": true, + "peer": true, + "dependencies": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, "node_modules/nth-check": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz", @@ -13920,6 +14627,11 @@ "node": ">=8" } }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" + }, "node_modules/performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -15447,7 +16159,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "peer": true, "engines": { "node": ">=0.4.0" } @@ -15503,6 +16214,11 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -15526,6 +16242,86 @@ "node": ">=6" } }, + "node_modules/puppeteer": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.20.0.tgz", + "integrity": "sha512-bt48RDBy2eIwZPrkgbcwHtb51mj2nKvHOPMaSH2IsWiv7lOG9k9zhaRzpDZafrk05ajMc3cu+lSQYYOfH2DkVQ==", + "hasInstallScript": true, + "dependencies": { + "debug": "^4.1.0", + "extract-zip": "^1.6.6", + "https-proxy-agent": "^2.2.1", + "mime": "^2.0.3", + "progress": "^2.0.1", + "proxy-from-env": "^1.0.0", + "rimraf": "^2.6.1", + "ws": "^6.1.0" + }, + "engines": { + "node": ">=6.4.0" + } + }, + "node_modules/puppeteer/node_modules/agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "dependencies": { + "es6-promisify": "^5.0.0" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/puppeteer/node_modules/https-proxy-agent": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", + "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", + "dependencies": { + "agent-base": "^4.3.0", + "debug": "^3.1.0" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/puppeteer/node_modules/https-proxy-agent/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/puppeteer/node_modules/mime": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/puppeteer/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/puppeteer/node_modules/ws": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "dependencies": { + "async-limiter": "~1.0.0" + } + }, "node_modules/q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", @@ -15860,6 +16656,33 @@ "node": ">= 0.10" } }, + "node_modules/redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "optional": true, + "peer": true, + "dependencies": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/redent/node_modules/indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "optional": true, + "peer": true, + "dependencies": { + "repeating": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/redis": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/redis/-/redis-3.1.2.tgz", @@ -16093,6 +16916,19 @@ "node": ">=0.10" } }, + "node_modules/repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "optional": true, + "peer": true, + "dependencies": { + "is-finite": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", @@ -16179,7 +17015,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true + "devOptional": true }, "node_modules/requires-port": { "version": "1.0.0", @@ -16662,6 +17498,181 @@ "node": ">=8.9.0" } }, + "node_modules/sass-graph": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.5.tgz", + "integrity": "sha512-VFWDAHOe6mRuT4mZRd4eKE+d8Uedrk6Xnh7Sh9b4NGufQLQjOrvf/MQoOdx+0s92L89FeyUUNfU597j/3uNpag==", + "optional": true, + "peer": true, + "dependencies": { + "glob": "^7.0.0", + "lodash": "^4.0.0", + "scss-tokenizer": "^0.2.3", + "yargs": "^13.3.2" + } + }, + "node_modules/sass-graph/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "optional": true, + "peer": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/sass-graph/node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "optional": true, + "peer": true, + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/sass-graph/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "optional": true, + "peer": true + }, + "node_modules/sass-graph/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "optional": true, + "peer": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sass-graph/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "optional": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/sass-graph/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "optional": true, + "peer": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sass-graph/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "optional": true, + "peer": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sass-graph/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "optional": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/sass-graph/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "optional": true, + "peer": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sass-graph/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "optional": true, + "peer": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sass-graph/node_modules/wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "optional": true, + "peer": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/sass-graph/node_modules/yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "optional": true, + "peer": true, + "dependencies": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "node_modules/sass-graph/node_modules/yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "optional": true, + "peer": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, "node_modules/sass-loader": { "version": "11.1.1", "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-11.1.1.tgz", @@ -16738,6 +17749,30 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/scss-tokenizer": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", + "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", + "optional": true, + "peer": true, + "dependencies": { + "js-base64": "^2.1.8", + "source-map": "^0.4.2" + } + }, + "node_modules/scss-tokenizer/node_modules/source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "optional": true, + "peer": true, + "dependencies": { + "amdefine": ">=0.0.4" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/select": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", @@ -17597,6 +18632,42 @@ "node": ">= 0.6" } }, + "node_modules/stdout-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz", + "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==", + "optional": true, + "peer": true, + "dependencies": { + "readable-stream": "^2.0.1" + } + }, + "node_modules/stdout-stream/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "optional": true, + "peer": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/stdout-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, + "peer": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -17748,6 +18819,22 @@ "node": ">=6" } }, + "node_modules/strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "optional": true, + "peer": true, + "dependencies": { + "get-stdin": "^4.0.1" + }, + "bin": { + "strip-indent": "cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -18738,6 +19825,16 @@ "resolved": "https://registry.npmjs.org/tributejs/-/tributejs-5.1.3.tgz", "integrity": "sha512-B5CXihaVzXw+1UHhNFyAwUTMDk1EfoLP5Tj1VhD9yybZ1I8DZJEv8tZ1l0RJo0t0tk9ZhR8eG5tEsaCvRigmdQ==" }, + "node_modules/trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "optional": true, + "peer": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/trough": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", @@ -18749,6 +19846,16 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/true-case-path": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz", + "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==", + "optional": true, + "peer": true, + "dependencies": { + "glob": "^7.1.2" + } + }, "node_modules/tryer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", @@ -18899,8 +20006,7 @@ "node_modules/typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, "node_modules/typedarray-to-buffer": { "version": "3.1.5", @@ -20044,7 +21150,64 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true + "devOptional": true + }, + "node_modules/wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "optional": true, + "peer": true, + "dependencies": { + "string-width": "^1.0.2 || 2" + } + }, + "node_modules/wide-align/node_modules/ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "optional": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "optional": true, + "peer": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align/node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "optional": true, + "peer": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/wide-align/node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "optional": true, + "peer": true, + "dependencies": { + "ansi-regex": "^3.0.0" + }, + "engines": { + "node": ">=4" + } }, "node_modules/wildcard": { "version": "2.0.0", @@ -20179,7 +21342,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true + "devOptional": true }, "node_modules/yallist": { "version": "4.0.0", @@ -20238,6 +21401,15 @@ "node": ">=6" } }, + "node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", @@ -20267,12 +21439,12 @@ }, "packages/browserslist-config": { "name": "@decidim/browserslist-config", - "version": "0.25.2", + "version": "0.26.4", "license": "AGPL-3.0" }, "packages/core": { "name": "@decidim/core", - "version": "0.25.2", + "version": "0.26.4", "license": "AGPL-3.0", "dependencies": { "@joeattardi/emoji-button": "^4.6.0", @@ -20327,7 +21499,7 @@ }, "packages/dev": { "name": "@decidim/dev", - "version": "0.25.2", + "version": "0.26.4", "dev": true, "license": "AGPL-3.0", "dependencies": { @@ -20336,17 +21508,17 @@ }, "packages/elections": { "name": "@decidim/elections", - "version": "0.25.2", + "version": "0.26.4", "license": "AGPL-3.0", "dependencies": { - "@codegram/decidim-bulletin_board": "0.21.2", - "@codegram/voting_schemes-dummy": "0.21.2", - "@codegram/voting_schemes-electionguard": "0.21.2" + "@decidim/decidim-bulletin_board": "0.22.3", + "@decidim/voting_schemes-dummy": "0.22.3", + "@decidim/voting_schemes-electionguard": "0.22.3" } }, "packages/eslint-config": { "name": "@decidim/eslint-config", - "version": "0.25.2", + "version": "0.26.4", "dev": true, "license": "AGPL-3.0", "peerDependencies": { @@ -20363,7 +21535,7 @@ }, "packages/stylelint-config": { "name": "@decidim/stylelint-config", - "version": "0.25.2", + "version": "0.26.4", "dev": true, "license": "AGPL-3.0", "peerDependencies": { @@ -20372,7 +21544,7 @@ }, "packages/webpacker": { "name": "@decidim/webpacker", - "version": "0.25.2", + "version": "0.26.4", "license": "AGPL-3.0", "dependencies": { "@babel/core": "^7.13.13", @@ -21544,31 +22716,6 @@ "minimist": "^1.2.0" } }, - "@codegram/decidim-bulletin_board": { - "version": "0.21.2", - "resolved": "https://registry.npmjs.org/@codegram/decidim-bulletin_board/-/decidim-bulletin_board-0.21.2.tgz", - "integrity": "sha512-o4eqR46lqtF/y+VyaV1elsLXLWnMEjMN1eCw27cDhvZHY4L+5Ec68w1HzC+brzLf5v5847DyS91kpxWIoi9C4A==", - "requires": { - "@apollo/client": "^3.2.7", - "core-js": "^3.8.3", - "graphql": "^15.4.0", - "node-jose": "^2.0.0", - "regenerator-runtime": "^0.13.7", - "rxjs": "^6.6.3", - "webpack": "^5.11.0", - "webpack-cli": "^4.2.0" - } - }, - "@codegram/voting_schemes-dummy": { - "version": "0.21.2", - "resolved": "https://registry.npmjs.org/@codegram/voting_schemes-dummy/-/voting_schemes-dummy-0.21.2.tgz", - "integrity": "sha512-zwrBPIO8Escg54vxaqYqz4dgTbXq3xacu5h1u52mzABoYgniWLVzmsjTm6fKIzXs/RASgpxVmsIRgqiUDlHgCg==" - }, - "@codegram/voting_schemes-electionguard": { - "version": "0.21.2", - "resolved": "https://registry.npmjs.org/@codegram/voting_schemes-electionguard/-/voting_schemes-electionguard-0.21.2.tgz", - "integrity": "sha512-BcAzcPVlC1glH8WRpyjeNZ804KAjbn3khUuzyNiOPnvFqYZoUhjcrKhB13S1YJNIk6v8NsGFDpkZq+s+irJQ/g==" - }, "@csstools/convert-colors": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@csstools/convert-colors/-/convert-colors-1.4.0.tgz", @@ -21624,6 +22771,21 @@ } } }, + "@decidim/decidim-bulletin_board": { + "version": "0.22.3", + "resolved": "https://registry.npmjs.org/@decidim/decidim-bulletin_board/-/decidim-bulletin_board-0.22.3.tgz", + "integrity": "sha512-LN7wIK9IB9Zegr++fvEY2vAWdUvReLPCe3sbPMGadX3b2aurrx/SK3B38OfRdN2eqblksMzyNYtXALszA9dU2w==", + "requires": { + "@apollo/client": "^3.2.7", + "core-js": "^3.8.3", + "graphql": "^15.4.0", + "node-jose": "^2.0.0", + "regenerator-runtime": "^0.13.7", + "rxjs": "^6.6.3", + "webpack": "^5.11.0", + "webpack-cli": "^4.2.0" + } + }, "@decidim/dev": { "version": "file:packages/dev", "requires": { @@ -21633,9 +22795,9 @@ "@decidim/elections": { "version": "file:packages/elections", "requires": { - "@codegram/decidim-bulletin_board": "0.21.2", - "@codegram/voting_schemes-dummy": "0.21.2", - "@codegram/voting_schemes-electionguard": "0.21.2" + "@decidim/decidim-bulletin_board": "0.22.3", + "@decidim/voting_schemes-dummy": "0.22.3", + "@decidim/voting_schemes-electionguard": "0.22.3" } }, "@decidim/eslint-config": { @@ -21646,6 +22808,16 @@ "version": "file:packages/stylelint-config", "requires": {} }, + "@decidim/voting_schemes-dummy": { + "version": "0.22.3", + "resolved": "https://registry.npmjs.org/@decidim/voting_schemes-dummy/-/voting_schemes-dummy-0.22.3.tgz", + "integrity": "sha512-Z5CwSUJNYW2KkoE5anAqAIwHnQHqpgGL4Xu2I7YqEn3thThlbWlY9U9Eq0O6fq7/pfBQLiAFFiBBAnCDv0HC2g==" + }, + "@decidim/voting_schemes-electionguard": { + "version": "0.22.3", + "resolved": "https://registry.npmjs.org/@decidim/voting_schemes-electionguard/-/voting_schemes-electionguard-0.22.3.tgz", + "integrity": "sha512-RZn/1GO5PM6a2SuN8h/SoS4EeLYnHPWw6/tl2M26ms/Xzf1ewJIgBSiByxk4qHoqvE892rccH4+G56h6iVrIqg==" + }, "@decidim/webpacker": { "version": "file:packages/webpacker", "requires": { @@ -22805,6 +23977,13 @@ "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", "dev": true }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "optional": true, + "peer": true + }, "accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -22912,6 +24091,13 @@ "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=" }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", + "optional": true, + "peer": true + }, "ansi-colors": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", @@ -22954,6 +24140,52 @@ "picomatch": "^2.0.4" } }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "optional": true, + "peer": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "optional": true, + "peer": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "optional": true, + "peer": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, + "peer": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -22991,6 +24223,13 @@ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", "dev": true }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "optional": true, + "peer": true + }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -23115,6 +24354,13 @@ "lodash": "^4.17.14" } }, + "async-foreach": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", + "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=", + "optional": true, + "peer": true + }, "async-limiter": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", @@ -23777,6 +25023,11 @@ "ieee754": "^1.1.13" } }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" + }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", @@ -23874,7 +25125,27 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true + "devOptional": true + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "optional": true, + "peer": true, + "requires": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "optional": true, + "peer": true + } + } }, "caniuse-api": { "version": "3.0.0", @@ -24343,6 +25614,13 @@ "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==" }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "optional": true, + "peer": true + }, "content-disposition": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", @@ -24811,6 +26089,16 @@ } } }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "optional": true, + "peer": true, + "requires": { + "array-find-index": "^1.0.1" + } + }, "d3": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/d3/-/d3-5.4.0.tgz", @@ -25239,6 +26527,13 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "optional": true, + "peer": true + }, "denque": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.0.tgz", @@ -25484,6 +26779,13 @@ "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==" }, + "env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "optional": true, + "peer": true + }, "envinfo": { "version": "7.8.1", "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", @@ -25634,6 +26936,14 @@ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "requires": { + "es6-promise": "^4.0.3" + } + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -26674,6 +27984,73 @@ } } }, + "extract-zip": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", + "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==", + "requires": { + "concat-stream": "^1.6.2", + "debug": "^2.6.9", + "mkdirp": "^0.5.4", + "yauzl": "^2.10.0" + }, + "dependencies": { + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", @@ -26742,6 +28119,14 @@ "bser": "2.1.1" } }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "requires": { + "pend": "~1.2.0" + } + }, "file-entry-cache": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", @@ -26880,10 +28265,12 @@ "integrity": "sha1-bciR8/ZCICghn3QoTRaEVIqMpL8=" }, "foundation-sites": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/foundation-sites/-/foundation-sites-6.7.1.tgz", - "integrity": "sha512-Qr+9oQUItVInQG4wK2PKL53RwPe1eyx1irmgTkTGfm1CM0snQuenCRl7OtD8MfMykqw4NOU9JQGDLgV8oz0jxg==", - "requires": {} + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/foundation-sites/-/foundation-sites-6.7.0.tgz", + "integrity": "sha512-dajdL/7i5rn5F70I2FMnfDOlgXD5klCw8OS9a+Y3rM2fyj9f8JZkJ50eYukmeEM4zVnj+Xo6rJfciLxN/QEYWQ==", + "requires": { + "puppeteer": "^1.11.0" + } }, "fragment-cache": { "version": "0.2.1", @@ -26982,6 +28369,74 @@ "resolved": "https://registry.npmjs.org/fuzzysort/-/fuzzysort-1.1.4.tgz", "integrity": "sha512-JzK/lHjVZ6joAg3OnCjylwYXYVjRiwTY6Yb25LvfpJHK8bjisfnZJ5bY8aVWwTwCXgxPNgLAtmHL+Hs5q1ddLQ==" }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "optional": true, + "peer": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "optional": true, + "peer": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "optional": true, + "peer": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "optional": true, + "peer": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "optional": true, + "peer": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "gaze": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz", + "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", + "optional": true, + "peer": true, + "requires": { + "globule": "^1.0.0" + } + }, "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -26991,7 +28446,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true + "devOptional": true }, "get-intrinsic": { "version": "1.1.1", @@ -27009,6 +28464,13 @@ "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "optional": true, + "peer": true + }, "get-stream": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", @@ -27124,6 +28586,18 @@ "dev": true, "peer": true }, + "globule": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.2.tgz", + "integrity": "sha512-7IDTQTIu2xzXkT+6mlluidnWo+BypnbSoEVVQCGfzqnl5Ik8d3e1d4wycb8Rj9tWW+Z39uPWsdlquqiqPCd/pA==", + "optional": true, + "peer": true, + "requires": { + "glob": "~7.1.1", + "lodash": "~4.17.10", + "minimatch": "~3.0.2" + } + }, "gonzales-pe": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz", @@ -27499,6 +28973,13 @@ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==" }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "optional": true, + "peer": true + }, "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -28107,6 +29588,13 @@ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" }, + "is-finite": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", + "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", + "optional": true, + "peer": true + }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", @@ -29559,6 +31047,13 @@ "resolved": "https://registry.npmjs.org/jquery.autocomplete/-/jquery.autocomplete-1.2.0.tgz", "integrity": "sha512-aoJC3KVrPpRGaZBUo9UxhwznYmQ0UuYd+FfjP9RAKmyB+1T3OLIjuQImT8pKX6eKpBt1z9JmD48GiD2Dx303bA==" }, + "js-base64": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", + "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==", + "optional": true, + "peer": true + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -30029,6 +31524,17 @@ "js-tokens": "^3.0.0 || ^4.0.0" } }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "optional": true, + "peer": true, + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + } + }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -30072,7 +31578,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true, + "devOptional": true, "peer": true }, "map-visit": { @@ -30190,6 +31696,117 @@ "fs-monkey": "1.0.3" } }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "optional": true, + "peer": true, + "requires": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.0.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "optional": true, + "peer": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "load-json-file": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", + "optional": true, + "peer": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "optional": true, + "peer": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "optional": true, + "peer": true, + "requires": { + "pinkie-promise": "^2.0.0" + } + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "optional": true, + "peer": true, + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "optional": true, + "peer": true, + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.0" + } + }, + "read-pkg-up": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", + "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", + "optional": true, + "peer": true, + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "optional": true, + "peer": true, + "requires": { + "is-utf8": "^0.2.0" + } + } + } + }, "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", @@ -30442,6 +32059,13 @@ "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=" }, + "nan": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", + "optional": true, + "peer": true + }, "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", @@ -30499,6 +32123,37 @@ "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz", "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==" }, + "node-gyp": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-7.1.2.tgz", + "integrity": "sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==", + "optional": true, + "peer": true, + "requires": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.3", + "nopt": "^5.0.0", + "npmlog": "^4.1.2", + "request": "^2.88.2", + "rimraf": "^3.0.2", + "semver": "^7.3.2", + "tar": "^6.0.2", + "which": "^2.0.2" + }, + "dependencies": { + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "optional": true, + "peer": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -30566,6 +32221,98 @@ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.75.tgz", "integrity": "sha512-Qe5OUajvqrqDSy6wrWFmMwfJ0jVgwiw4T3KqmbTcZ62qW0gQkheXYhcFM1+lOVcGUoRxcEcfyvFMAnDgaF1VWw==" }, + "node-sass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-5.0.0.tgz", + "integrity": "sha512-opNgmlu83ZCF792U281Ry7tak9IbVC+AKnXGovcQ8LG8wFaJv6cLnRlc6DIHlmNxWEexB5bZxi9SZ9JyUuOYjw==", + "optional": true, + "peer": true, + "requires": { + "async-foreach": "^0.1.3", + "chalk": "^1.1.1", + "cross-spawn": "^7.0.3", + "gaze": "^1.0.0", + "get-stdin": "^4.0.1", + "glob": "^7.0.3", + "lodash": "^4.17.15", + "meow": "^3.7.0", + "mkdirp": "^0.5.1", + "nan": "^2.13.2", + "node-gyp": "^7.1.0", + "npmlog": "^4.0.0", + "request": "^2.88.0", + "sass-graph": "2.2.5", + "stdout-stream": "^1.4.0", + "true-case-path": "^1.0.2" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "optional": true, + "peer": true + }, + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "optional": true, + "peer": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "optional": true, + "peer": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "optional": true, + "peer": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "optional": true, + "peer": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "optional": true, + "peer": true + } + } + }, + "nopt": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", + "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", + "optional": true, + "peer": true, + "requires": { + "abbrev": "1" + } + }, "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -30614,6 +32361,19 @@ "path-key": "^3.0.0" } }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "optional": true, + "peer": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, "nth-check": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.0.tgz", @@ -31068,6 +32828,11 @@ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=" + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -32330,8 +34095,7 @@ "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "peer": true + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" }, "promise-inflight": { "version": "1.0.1", @@ -32378,6 +34142,11 @@ "ipaddr.js": "1.9.1" } }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -32398,6 +34167,71 @@ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, + "puppeteer": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.20.0.tgz", + "integrity": "sha512-bt48RDBy2eIwZPrkgbcwHtb51mj2nKvHOPMaSH2IsWiv7lOG9k9zhaRzpDZafrk05ajMc3cu+lSQYYOfH2DkVQ==", + "requires": { + "debug": "^4.1.0", + "extract-zip": "^1.6.6", + "https-proxy-agent": "^2.2.1", + "mime": "^2.0.3", + "progress": "^2.0.1", + "proxy-from-env": "^1.0.0", + "rimraf": "^2.6.1", + "ws": "^6.1.0" + }, + "dependencies": { + "agent-base": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", + "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", + "requires": { + "es6-promisify": "^5.0.0" + } + }, + "https-proxy-agent": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", + "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", + "requires": { + "agent-base": "^4.3.0", + "debug": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "mime": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==" + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + } + }, + "ws": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, "q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", @@ -32653,6 +34487,29 @@ "resolve": "^1.9.0" } }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "optional": true, + "peer": true, + "requires": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + }, + "dependencies": { + "indent-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", + "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "optional": true, + "peer": true, + "requires": { + "repeating": "^2.0.0" + } + } + } + }, "redis": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/redis/-/redis-3.1.2.tgz", @@ -32830,6 +34687,16 @@ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", "dev": true }, + "repeating": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", + "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", + "optional": true, + "peer": true, + "requires": { + "is-finite": "^1.0.0" + } + }, "request": { "version": "2.88.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", @@ -32898,7 +34765,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true + "devOptional": true }, "requires-port": { "version": "1.0.0", @@ -33273,6 +35140,156 @@ "chokidar": ">=3.0.0 <4.0.0" } }, + "sass-graph": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.5.tgz", + "integrity": "sha512-VFWDAHOe6mRuT4mZRd4eKE+d8Uedrk6Xnh7Sh9b4NGufQLQjOrvf/MQoOdx+0s92L89FeyUUNfU597j/3uNpag==", + "optional": true, + "peer": true, + "requires": { + "glob": "^7.0.0", + "lodash": "^4.0.0", + "scss-tokenizer": "^0.2.3", + "yargs": "^13.3.2" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "optional": true, + "peer": true + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "optional": true, + "peer": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "optional": true, + "peer": true + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "optional": true, + "peer": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "optional": true, + "peer": true + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "optional": true, + "peer": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "optional": true, + "peer": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "optional": true, + "peer": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "optional": true, + "peer": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "optional": true, + "peer": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "optional": true, + "peer": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "optional": true, + "peer": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "optional": true, + "peer": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, "sass-loader": { "version": "11.1.1", "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-11.1.1.tgz", @@ -33315,6 +35332,29 @@ "ajv-keywords": "^3.5.2" } }, + "scss-tokenizer": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", + "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", + "optional": true, + "peer": true, + "requires": { + "js-base64": "^2.1.8", + "source-map": "^0.4.2" + }, + "dependencies": { + "source-map": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", + "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "optional": true, + "peer": true, + "requires": { + "amdefine": ">=0.0.4" + } + } + } + }, "select": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", @@ -34052,6 +36092,44 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" }, + "stdout-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz", + "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==", + "optional": true, + "peer": true, + "requires": { + "readable-stream": "^2.0.1" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "optional": true, + "peer": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "optional": true, + "peer": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } + } + }, "string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -34158,6 +36236,16 @@ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==" }, + "strip-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "optional": true, + "peer": true, + "requires": { + "get-stdin": "^4.0.1" + } + }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -34918,6 +37006,13 @@ "resolved": "https://registry.npmjs.org/tributejs/-/tributejs-5.1.3.tgz", "integrity": "sha512-B5CXihaVzXw+1UHhNFyAwUTMDk1EfoLP5Tj1VhD9yybZ1I8DZJEv8tZ1l0RJo0t0tk9ZhR8eG5tEsaCvRigmdQ==" }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "optional": true, + "peer": true + }, "trough": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", @@ -34925,6 +37020,16 @@ "dev": true, "peer": true }, + "true-case-path": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz", + "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==", + "optional": true, + "peer": true, + "requires": { + "glob": "^7.1.2" + } + }, "tryer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", @@ -35042,8 +37147,7 @@ "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, "typedarray-to-buffer": { "version": "3.1.5", @@ -35868,7 +37972,54 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true + "devOptional": true + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "optional": true, + "peer": true, + "requires": { + "string-width": "^1.0.2 || 2" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "optional": true, + "peer": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "optional": true, + "peer": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "optional": true, + "peer": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "optional": true, + "peer": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } }, "wildcard": { "version": "2.0.0", @@ -35967,7 +38118,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true + "devOptional": true }, "yallist": { "version": "4.0.0", @@ -36017,6 +38168,15 @@ "decamelize": "^1.2.0" } }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index e17f3a666de2a..836b0e80e2773 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,7 @@ { "name": "a-decidim-app", - "description": "The participatory democracy framework", - "repository": { - "url": "git@github.com:decidim/decidim.git", - "type": "git" - }, - "author": "Marc Riera ", - "license": "AGPL-3.0", + "description": "Note: this is not a package, just the dependencies for the project in the dev environment.", + "private": true, "engines": { "node": "^16.9.1", "npm": "^7.21.1" diff --git a/packages/browserslist-config/package.json b/packages/browserslist-config/package.json index 3627d00953dbe..036979a3b8d61 100644 --- a/packages/browserslist-config/package.json +++ b/packages/browserslist-config/package.json @@ -1,7 +1,7 @@ { "name": "@decidim/browserslist-config", "description": "The Browserslist configuration for Decidim", - "version": "0.25.2", + "version": "0.26.4", "repository": { "url": "git@github.com:decidim/decidim.git", "type": "git", diff --git a/packages/core/package.json b/packages/core/package.json index aa44fc0a4dcbc..028cc4436b852 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,7 +1,7 @@ { "name": "@decidim/core", "description": "The core dependencies for Decidim", - "version": "0.25.2", + "version": "0.26.4", "repository": { "url": "git@github.com:decidim/decidim.git", "type": "git", diff --git a/packages/dev/package.json b/packages/dev/package.json index 6fc2e61a20fb7..5d7e41d108ba9 100644 --- a/packages/dev/package.json +++ b/packages/dev/package.json @@ -1,7 +1,7 @@ { "name": "@decidim/dev", "description": "The dev dependencies for Decidim", - "version": "0.25.2", + "version": "0.26.4", "repository": { "url": "git@github.com:decidim/decidim.git", "type": "git", diff --git a/packages/elections/package.json b/packages/elections/package.json index 9190b6351e7ed..792013cb0df5d 100644 --- a/packages/elections/package.json +++ b/packages/elections/package.json @@ -1,7 +1,7 @@ { "name": "@decidim/elections", "description": "The elections and votings dependencies for Decidim", - "version": "0.25.2", + "version": "0.26.4", "repository": { "url": "git@github.com:decidim/decidim.git", "type": "git", @@ -10,8 +10,8 @@ "author": "Decidim Contributors", "license": "AGPL-3.0", "dependencies": { - "@codegram/decidim-bulletin_board": "0.21.2", - "@codegram/voting_schemes-dummy": "0.21.2", - "@codegram/voting_schemes-electionguard": "0.21.2" + "@decidim/decidim-bulletin_board": "0.22.3", + "@decidim/voting_schemes-dummy": "0.22.3", + "@decidim/voting_schemes-electionguard": "0.22.3" } -} +} \ No newline at end of file diff --git a/packages/eslint-config/package.json b/packages/eslint-config/package.json index 722fec48bedf0..df75dded763a3 100644 --- a/packages/eslint-config/package.json +++ b/packages/eslint-config/package.json @@ -1,7 +1,7 @@ { "name": "@decidim/eslint-config", "description": "The eslint configuration for Decidim", - "version": "0.25.2", + "version": "0.26.4", "repository": { "url": "git@github.com:decidim/decidim.git", "type": "git", diff --git a/packages/stylelint-config/package.json b/packages/stylelint-config/package.json index 139a19d1559a1..e1fce92515b18 100644 --- a/packages/stylelint-config/package.json +++ b/packages/stylelint-config/package.json @@ -1,7 +1,7 @@ { "name": "@decidim/stylelint-config", "description": "The stylelint configuration for Decidim", - "version": "0.25.2", + "version": "0.26.4", "repository": { "url": "git@github.com:decidim/decidim.git", "type": "git", diff --git a/packages/webpacker/package.json b/packages/webpacker/package.json index 7c57597e0f3a0..9f4da510d2b29 100644 --- a/packages/webpacker/package.json +++ b/packages/webpacker/package.json @@ -1,7 +1,7 @@ { "name": "@decidim/webpacker", "description": "The webpacker dependencies for Decidim", - "version": "0.25.2", + "version": "0.26.4", "repository": { "url": "git@github.com:decidim/decidim.git", "type": "git",
<%= t("models.user_group.fields.name", scope: "decidim.admin") %><%= t("models.user_group.fields.document_number", scope: "decidim.admin") %><%= t("models.user_group.fields.phone", scope: "decidim.admin") %><%= t("models.user_group.fields.users_count", scope: "decidim.admin") %><%= t("models.user_group.fields.created_at", scope: "decidim.admin") %><%= t("models.user_group.fields.state", scope: "decidim.admin") %><%= sort_link(query, :name, t("models.user_group.fields.name", scope: "decidim.admin"), default_order: :desc) %><%= sort_link(query, :document_number, t("models.user_group.fields.document_number", scope: "decidim.admin"), default_order: :desc) %><%= sort_link(query, :phone, t("models.user_group.fields.phone", scope: "decidim.admin"), default_order: :desc) %><%= sort_link(query, :users_count, t("models.user_group.fields.users_count", scope: "decidim.admin"), default_order: :desc) %><%= sort_link(query, :created_at, t("models.user_group.fields.created_at", scope: "decidim.admin"), default_order: :desc) %><%= sort_link(query, :state, t("models.user_group.fields.state", scope: "decidim.admin"), default_order: :desc) %> <%= t("models.user_group.fields.actions", scope: "decidim.admin") %>
<% if assembly.promoted? %> - "> + "> <%= icon "star", role: "img", "aria-hidden": true %> <% end %> diff --git a/decidim-assemblies/app/views/decidim/assemblies/admin/assembly_members/_form.html.erb b/decidim-assemblies/app/views/decidim/assemblies/admin/assembly_members/_form.html.erb index 51e032b442ec7..c71c9bb96ffbe 100644 --- a/decidim-assemblies/app/views/decidim/assemblies/admin/assembly_members/_form.html.erb +++ b/decidim-assemblies/app/views/decidim/assemblies/admin/assembly_members/_form.html.erb @@ -15,6 +15,10 @@ <%= form.text_field :full_name, autofocus: true %> +
+ <%= form.upload :non_user_avatar, help_i18n_messages: ["non_user_avatar_help", "image_guide"], help_i18n_scope: "decidim.assemblies.admin.assembly_members.form" %> +
+
<% prompt_options = { url: decidim_admin.user_entities_organization_url, placeholder: t(".select_user") } %> <%= form.autocomplete_select(:user_id, form.object.user.presence, { multiple: false }, prompt_options) do |user| @@ -41,10 +45,6 @@ <%= form.date_field :designation_date %>
-
- <%= form.text_field :designation_mode %> -
-
<%= form.date_field :ceased_date %>
diff --git a/decidim-assemblies/app/views/decidim/assemblies/admin/assembly_user_roles/index.html.erb b/decidim-assemblies/app/views/decidim/assemblies/admin/assembly_user_roles/index.html.erb index e8ec25b11ccf5..07af391f0dccc 100644 --- a/decidim-assemblies/app/views/decidim/assemblies/admin/assembly_user_roles/index.html.erb +++ b/decidim-assemblies/app/views/decidim/assemblies/admin/assembly_user_roles/index.html.erb @@ -7,17 +7,18 @@ <% end %> + <%= admin_filter_selector %>
- +
- - - - - + + + + + diff --git a/decidim-assemblies/app/views/decidim/assemblies/assemblies/_promoted_assembly.html.erb b/decidim-assemblies/app/views/decidim/assemblies/assemblies/_promoted_assembly.html.erb index 7336c4e2ebb77..ebe64841b1504 100644 --- a/decidim-assemblies/app/views/decidim/assemblies/assemblies/_promoted_assembly.html.erb +++ b/decidim-assemblies/app/views/decidim/assemblies/assemblies/_promoted_assembly.html.erb @@ -5,7 +5,7 @@ <%= link_to assembly_path(promoted_assembly), class: "card__link" do %>

<%= translated_attribute promoted_assembly.title %>

<% end %> - <%= decidim_sanitize html_truncate(translated_attribute(promoted_assembly.short_description), length: 630, separator: "...") %> + <%= decidim_sanitize_editor html_truncate(translated_attribute(promoted_assembly.short_description), length: 630, separator: "...") %> <%= link_to assembly_path(promoted_assembly), class: "button small hollow card__button" do %> <%= t("assemblies.promoted_assembly.more_info", scope: "layouts.decidim") %> <% end %> @@ -13,7 +13,7 @@
+ style="background-image:url('<%= promoted_assembly.attached_uploader(:hero_image).path %>')">
<%= link_to assembly_path(promoted_assembly), class: "button expanded button--sc" do %> diff --git a/decidim-assemblies/app/views/decidim/assemblies/assemblies/show.html.erb b/decidim-assemblies/app/views/decidim/assemblies/assemblies/show.html.erb index 678511a56a2bd..04c3009ab89cd 100644 --- a/decidim-assemblies/app/views/decidim/assemblies/assemblies/show.html.erb +++ b/decidim-assemblies/app/views/decidim/assemblies/assemblies/show.html.erb @@ -35,10 +35,11 @@ edit_link(
+

<%= t(".title") %>

- <%= decidim_sanitize translated_attribute(current_participatory_space.short_description) %> + <%= decidim_sanitize_editor translated_attribute(current_participatory_space.short_description) %>
- <%= decidim_sanitize translated_attribute(current_participatory_space.description) %> + <%= decidim_sanitize_editor translated_attribute(current_participatory_space.description) %> <% if current_participatory_space.private_space? %> <%= assembly_features(current_participatory_space) %> @@ -56,21 +57,21 @@ edit_link( <% if translated_attribute(current_participatory_space.purpose_of_action).present? %>

<%= t("purpose_of_action", scope: "decidim.assemblies.show") %>

- <%= decidim_sanitize translated_attribute(current_participatory_space.purpose_of_action) %> + <%= decidim_sanitize_editor translated_attribute(current_participatory_space.purpose_of_action) %>
<% end %> <% if translated_attribute(current_participatory_space.internal_organisation).present? %>

<%= t("internal_organisation", scope: "decidim.assemblies.show") %>

- <%= decidim_sanitize translated_attribute(current_participatory_space.internal_organisation) %> + <%= decidim_sanitize_editor translated_attribute(current_participatory_space.internal_organisation) %>
<% end %> <% if translated_attribute(current_participatory_space.composition).present? %>

<%= t("composition", scope: "decidim.assemblies.show") %>

- <%= decidim_sanitize translated_attribute(current_participatory_space.composition) %> + <%= decidim_sanitize_editor translated_attribute(current_participatory_space.composition) %>
<% end %>
@@ -85,7 +86,7 @@ edit_link( <%= render_hook(:participatory_space_highlighted_elements) %> - <% if current_participatory_space.children.visible_for(current_user).count.positive? %> + <% if current_participatory_space.children.visible_for(current_user).published.count.positive? %>

<%= t("children", scope: "decidim.assemblies.show") %>

@@ -203,7 +204,7 @@ edit_link( <%= t("closing_date", scope: "decidim.assemblies.show") %> <%= l(current_participatory_space.closing_date, format: :decidim_short) %>
- <%= decidim_sanitize translated_attribute(current_participatory_space.closing_date_reason) %> + <%= decidim_sanitize_editor translated_attribute(current_participatory_space.closing_date_reason) %>
<% end %> diff --git a/decidim-assemblies/app/views/decidim/assemblies/assembly_members/index.html.erb b/decidim-assemblies/app/views/decidim/assemblies/assembly_members/index.html.erb index 3b696f6ea70ef..1b33b09dbfdf5 100644 --- a/decidim-assemblies/app/views/decidim/assemblies/assembly_members/index.html.erb +++ b/decidim-assemblies/app/views/decidim/assemblies/assembly_members/index.html.erb @@ -1,5 +1,14 @@ <% add_decidim_meta_tags(title: t("assembly_members.index.title", scope: "decidim")) %> +<% +edit_link( + decidim_admin_assemblies.assembly_members_path(current_participatory_space.slug), + :update, + :assembly, + assembly: current_participatory_space +) +%> +

<%= t(".members") %> (<%= collection.size %>)

diff --git a/decidim-assemblies/app/views/layouts/decidim/_assembly_header.html.erb b/decidim-assemblies/app/views/layouts/decidim/_assembly_header.html.erb index a584a1f486bb8..cac71db405cc4 100644 --- a/decidim-assemblies/app/views/layouts/decidim/_assembly_header.html.erb +++ b/decidim-assemblies/app/views/layouts/decidim/_assembly_header.html.erb @@ -1,7 +1,7 @@
+ style="background-image:url('<%= current_participatory_space.attached_uploader(:banner_image).path %>');">
@@ -11,14 +11,14 @@
-

+

<% if current_participatory_space.hashtag.present? %> - <%= link_to "##{current_participatory_space.hashtag}", "https://twitter.com/hashtag/#{current_participatory_space.hashtag}", target: "_blank" %> + <%= link_to "##{current_participatory_space.hashtag}", twitter_hashtag_url(current_participatory_space.hashtag), target: "_blank" %> <% end %> <%= translated_attribute(current_participatory_space.subtitle) %> -

+

diff --git a/decidim-assemblies/app/views/layouts/decidim/admin/assembly_members.html.erb b/decidim-assemblies/app/views/layouts/decidim/admin/assembly_members.html.erb new file mode 100644 index 0000000000000..c76125f8a841b --- /dev/null +++ b/decidim-assemblies/app/views/layouts/decidim/admin/assembly_members.html.erb @@ -0,0 +1,18 @@ +<% add_decidim_page_title(translated_attribute(current_participatory_space.title)) %> +<% content_for :sidebar_menu_nav do %> + <%= sidebar_menu(:admin_assembly_menu).render do + public_page_link decidim_assemblies.assembly_assembly_members_path(current_participatory_space) + end %> +<% end %> + +<%= render "layouts/decidim/admin/application" do %> +
+
+ <%= link_to translated_attribute(current_participatory_space.title), decidim_assemblies.assembly_path(current_participatory_space), target: "_blank" %> +
+
+ +
+ <%= yield %> +
+<% end %> diff --git a/decidim-assemblies/config/locales/ar.yml b/decidim-assemblies/config/locales/ar.yml index 443adfdbf3d0a..abc21eea8fb43 100644 --- a/decidim-assemblies/config/locales/ar.yml +++ b/decidim-assemblies/config/locales/ar.yml @@ -56,9 +56,9 @@ ar: birthplace: مكان الازدياد ceased_date: تاريخ التوقف designation_date: تاريخ التعيين - designation_mode: وضع التعيين full_name: الاسم الكامل gender: الجنس + non_user_avatar: الصورة الرمزية position: الموقع user_id: مستخدم أو مجموعة assembly_user_role: diff --git a/decidim-assemblies/config/locales/ca.yml b/decidim-assemblies/config/locales/ca.yml index cbd65dbf169b8..76bf43086277b 100644 --- a/decidim-assemblies/config/locales/ca.yml +++ b/decidim-assemblies/config/locales/ca.yml @@ -59,9 +59,9 @@ ca: birthplace: Lloc de naixement ceased_date: Data de cessament designation_date: Data de designació - designation_mode: Mode de designació full_name: Nom complet gender: Gènere + non_user_avatar: Avatar position: Posició user_id: Participant o grup assembly_user_role: @@ -182,6 +182,9 @@ ca: update: error: S'ha produït un error en actualitzar una administradora per a aquesta assemblea. success: L'administradora s'ha actualitzat correctament per a aquesta assemblea. + filters: + decidim_assemblies_type_id_eq: + label: Tipus d'assemblea menu: assemblies: Assemblees assemblies_settings: Configuració @@ -296,7 +299,10 @@ ca: assembly_members: form: existing_user: Participant existent + explanation: 'Instruccions per a la imatge:' + image_guide: Preferiblement una imatge apaïsada que no tingui cap text. non_user: No participant + non_user_avatar_help: Cal tenir el consentiment de la persona abans publicar-la com a membre. select_a_position: Selecciona una posició select_user: Selecciona una participant user_type: Tipus de participant @@ -313,6 +319,9 @@ ca: new_import: accepted_types: json: JSON + assemblies: + show: + title: Sobre aquesta assemblea assembly_members: index: members: Membres @@ -380,7 +389,7 @@ ca: related_participatory_processes: Processos participatius relacionats scope: Àmbit social_networks: Xarxes socials - social_networks_title: Compartir aquesta assemblea a + social_networks_title: Visita l'assemblea a target: Qui participa assembly_members: assembly_member: @@ -391,7 +400,7 @@ ca: assemblies: create_assembly_member: email_intro: Una administradora de l'assemblea %{resource_name} t'ha afegit com a un dels seus membres. - email_outro: Reps aquesta notificació perquè t'han convidat a una assemblea. Entra en assembly page per a contribuir-hi! + email_outro: Reps aquesta notificació perquè t'han convidat a una assemblea. Entra en assembly page per a contribuir-hi! email_subject: T'han convidat a ser membre de l'assemblea %{resource_name}! notification_title: T'han registrat com a membre de l'assemblea %{resource_name}. Entra a la pàgina de l'assemblea per a contribuir-hi! assembly: diff --git a/decidim-assemblies/config/locales/cs.yml b/decidim-assemblies/config/locales/cs.yml index 425e94ec502a9..22b8a62185956 100644 --- a/decidim-assemblies/config/locales/cs.yml +++ b/decidim-assemblies/config/locales/cs.yml @@ -59,14 +59,14 @@ cs: birthplace: Rodiště ceased_date: Datum ukončení designation_date: Datum označení - designation_mode: Režim označení full_name: Celé jméno gender: Rod + non_user_avatar: Avatar position: Pozice user_id: Uživatel assembly_user_role: email: E-mail - name: název + name: Název role: Role errors: models: @@ -136,7 +136,7 @@ cs: success: Typ shromáždění byl úspěšně aktualizován. assembly_copies: new: - copy: kopírovat + copy: Kopírovat select: Vyberte, která data chcete duplikovat title: Zduplikovat shromáždění assembly_imports: @@ -188,6 +188,9 @@ cs: update: error: Při aktualizaci administrátora pro toto shromáždění došlo k chybě. success: Administrátor úspěšně aktualizován pro toto shromáždění. + filters: + decidim_assemblies_type_id_eq: + label: Typ shromáždění menu: assemblies: Shromáždění assemblies_settings: Nastavení @@ -220,18 +223,18 @@ cs: fields: ceased_date: Datum ukončení designation_date: Datum označení - full_name: název + full_name: Název position: Pozice name: Člen positions: - other: jiný + other: Ostatní president: Prezident secretary: Tajemník - vice_president: Víceprezident + vice_president: Místopředseda assembly_user_role: fields: email: E-mail - name: název + name: Název role: Role name: Administrátor shromáždění roles: @@ -272,10 +275,10 @@ cs: duration: Doba trvání duration_help: Pokud je doba trvání tohoto shromáždění omezená, zvolte konečné datum, jinak se objeví jako neurčitá. filters: Filtry - images: snímky + images: Obrázky included_at_help: Vyberte datum, kdy bylo toto shromáždění přidáno do aplikace Decidim. Nemusí to být nutně stejné jako datum vytvoření. metadata: Metadata - other: jiný + other: Ostatní select_a_created_by: Vybrat vytvořeno od select_an_area: Vyberte oblast select_an_assembly_type: Vyberte typ shromáždění @@ -302,7 +305,10 @@ cs: assembly_members: form: existing_user: Existující účastník + explanation: 'Pokyny pro obrázek:' + image_guide: Je vhodnější obrázek na výšku, který nemá žádný text. non_user: Není účastník + non_user_avatar_help: Měli byste získat souhlas osob před jejich zveřejněním jako člena. select_a_position: Vyberte pozici select_user: Vybrat účastníka user_type: Typ účastníka @@ -319,6 +325,9 @@ cs: new_import: accepted_types: json: JSON + assemblies: + show: + title: O tomto shromáždění assembly_members: index: members: Členové @@ -386,7 +395,7 @@ cs: related_participatory_processes: Související participativní procesy scope: Oblast působnosti social_networks: Sociální sítě - social_networks_title: Sdílet toto shromáždění na + social_networks_title: Navštivte shromáždění na target: Kdo se účastní assembly_members: assembly_member: @@ -397,7 +406,7 @@ cs: assemblies: create_assembly_member: email_intro: Administrátor shromáždění %{resource_name} vás přidal jako jednoho z jeho členů. - email_outro: Obdrželi jste toto oznámení, protože jste byli pozváni do shromáždění. Podívejte se na stránku shromáždění a přispějte! + email_outro: Obdrželi jste toto oznámení, protože jste byli pozváni do shromáždění. Podívejte se na stránku shromáždění a přispějte! email_subject: Byli jste pozváni k členství ve shromáždění %{resource_name}! notification_title: Byli jste zaregistrováni jako člen shromáždění %{resource_name}. Podívejte se na stránku shromáždění a přispějte! assembly: diff --git a/decidim-assemblies/config/locales/de.yml b/decidim-assemblies/config/locales/de.yml index 8c5b1eacc3f39..fa185dc1b119e 100644 --- a/decidim-assemblies/config/locales/de.yml +++ b/decidim-assemblies/config/locales/de.yml @@ -59,9 +59,9 @@ de: birthplace: Geburtsort ceased_date: Aufgegebenes Datum designation_date: Datum der Benennung - designation_mode: Bezeichnungsmodus full_name: Vollständiger Name gender: Geschlecht + non_user_avatar: Profilbild position: Position user_id: User assembly_user_role: @@ -182,6 +182,9 @@ de: update: error: Bei einem Fehler ist ein Benutzer für diese Assembly aktualisiert worden. success: Der Benutzer wurde für diese Assembly erfolgreich aktualisiert. + filters: + decidim_assemblies_type_id_eq: + label: Versammlungstyp menu: assemblies: Gremien assemblies_settings: Einstellungen @@ -296,7 +299,10 @@ de: assembly_members: form: existing_user: Existierender Benutzer + explanation: 'Hinweise für das Bild:' + image_guide: Vorzugsweise ein Bild im Querformat, das keinen Text enthält. non_user: Nichtbenutzer + non_user_avatar_help: Sie sollten die Zustimmung der Personen einholen, bevor Sie sie als Mitglied veröffentlichen. select_a_position: Wählen Sie eine Position select_user: Wählen Sie einen Benutzer aus user_type: Benutzertyp @@ -313,6 +319,9 @@ de: new_import: accepted_types: json: JSON + assemblies: + show: + title: Über dieses Gremium assembly_members: index: members: Mitglieder @@ -380,7 +389,7 @@ de: related_participatory_processes: Ähnliche Beteiligungsprozesse scope: Umfang social_networks: Soziale Netzwerke - social_networks_title: Diese Versammlung auf teilen + social_networks_title: Gremium besuchen unter target: Wer nimmt teil? assembly_members: assembly_member: @@ -391,7 +400,7 @@ de: assemblies: create_assembly_member: email_intro: Ein Administrator des Gremiums %{resource_name} hat Sie als Mitglied eingeladen. - email_outro: Sie haben diese Benachrichtigung erhalten, weil Sie zu einer Versammlung eingeladen wurden. Gehen Sie zur Versammlungsseite, um daran teilzunehmen! + email_outro: Sie haben diese Benachrichtigung erhalten, weil Sie zu einem Gremium eingeladen wurden. Gehen Sie zur Gremiumsseite, um mitzumachen! email_subject: Sie wurden als Mitglied des Gremiums %{resource_name} eingeladen! notification_title: Sie wurden als Mitglied des Gremiums %{resource_name} registriert. Gehen Sie zur Gremiumsseite, um mitzuwirken! assembly: diff --git a/decidim-assemblies/config/locales/el.yml b/decidim-assemblies/config/locales/el.yml index cab5063bc4147..82b85c820f051 100644 --- a/decidim-assemblies/config/locales/el.yml +++ b/decidim-assemblies/config/locales/el.yml @@ -59,7 +59,6 @@ el: birthplace: Τόπος γέννησης ceased_date: Ημερομηνία παύσης designation_date: Ημερομηνία διορισμού - designation_mode: Λειτουργία διορισμού full_name: Ονοματεπώνυμο gender: Φύλο position: Θέση @@ -377,7 +376,6 @@ el: related_participatory_processes: Σχετικές διαδικασίες συμμετοχής scope: Πεδίο εφαρμογής social_networks: Κοινωνικά δίκτυα - social_networks_title: Κοινοποίηση αυτής της συνέλευσης σε target: Ποιος συμμετέχει assembly_members: assembly_member: @@ -388,7 +386,6 @@ el: assemblies: create_assembly_member: email_intro: Ένας διαχειριστής της συνέλευσης %{resource_name} σας πρόσθεσε ως ένα από τα μέλη της. - email_outro: Λάβατε αυτήν την ειδοποίηση επειδή έχετε προσκληθεί σε συνέλευση. Ελέγξτε τη σελίδα συνέλευσης για να συνεισφέρετε! email_subject: Έχετε προσκληθεί να γίνετε μέλος της συνέλευσης %{resource_name}! notification_title: Έχετε εγγραφεί ως μέλος της Συνέλευσης %{resource_name}. Ελέγξτε τη σελίδα συνέλευσης για να συνεισφέρετε! assembly: diff --git a/decidim-assemblies/config/locales/en.yml b/decidim-assemblies/config/locales/en.yml index 47ab39d6cb524..48eb77a822c5b 100644 --- a/decidim-assemblies/config/locales/en.yml +++ b/decidim-assemblies/config/locales/en.yml @@ -4,7 +4,10 @@ en: attributes: assemblies_setting: enable_organization_chart: Enable organization chart + assemblies_type: + title: Title assembly: + announcement: Announcement area_id: Area assembly_type: Assembly type assembly_type_other: Assembly type other @@ -23,12 +26,16 @@ en: decidim_scope_id: Scope description: Description developer_group: Promoter group + document: Document domain: Domain duration: Duration facebook: Facebook github: GitHub hashtag: Hashtag hero_image: Home image + import_attachments: Import attachments + import_categories: Import categories + import_components: Import components included_at: Included at instagram: Instagram internal_organisation: Internal organisation @@ -60,11 +67,12 @@ en: birthplace: Birthplace ceased_date: Ceased date designation_date: Designation date - designation_mode: Designation mode full_name: Full name gender: Gender + non_user_avatar: Avatar position: Position user_id: User or group + weight: Order position assembly_user_role: email: Email name: Name @@ -183,6 +191,9 @@ en: update: error: There was a problem updating an admin for this assembly. success: Admin updated successfully for this assembly. + filters: + decidim_assemblies_type_id_eq: + label: Assembly type menu: assemblies: Assemblies assemblies_settings: Settings @@ -297,7 +308,10 @@ en: assembly_members: form: existing_user: Existing participant + explanation: 'Guidance for image:' + image_guide: Preferrably a portrait image that does not have any text. non_user: Non participant + non_user_avatar_help: You should get the consent of the persons before publishing them as a member. select_a_position: Select a position select_user: Select a participant user_type: Participant type @@ -314,6 +328,9 @@ en: new_import: accepted_types: json: JSON + assemblies: + show: + title: About this assembly assembly_members: index: members: Members @@ -381,7 +398,7 @@ en: related_participatory_processes: Related participatory processes scope: Scope social_networks: Social Networks - social_networks_title: Share this assembly on + social_networks_title: Visit assembly on target: Who participates assembly_members: assembly_member: @@ -392,7 +409,7 @@ en: assemblies: create_assembly_member: email_intro: An admin of the %{resource_name} assembly has added you as one of its members. - email_outro: You have received this notification because you have been invited to an assembly. Check the assembly page to contribute! + email_outro: You have received this notification because you have been invited to an assembly. Check the assembly page to contribute! email_subject: You have been invited to be a member of the %{resource_name} assembly! notification_title: You have been registered as a member of Assembly %{resource_name}. Check the assembly page to contribute! assembly: diff --git a/decidim-assemblies/config/locales/es-MX.yml b/decidim-assemblies/config/locales/es-MX.yml index 105d442b6aded..dd85c3865f6b8 100644 --- a/decidim-assemblies/config/locales/es-MX.yml +++ b/decidim-assemblies/config/locales/es-MX.yml @@ -59,9 +59,9 @@ es-MX: birthplace: Lugar de nacimiento ceased_date: Fecha de vencimiento designation_date: Fecha de designación - designation_mode: Modo de designación full_name: Nombre completo gender: Género + non_user_avatar: Avatar position: Posición user_id: Usuaria assembly_user_role: @@ -182,6 +182,9 @@ es-MX: update: error: Ha habido un error al actualizar un usuario para esta asamblea. success: Usuario actualizado con éxito para esta asamblea. + filters: + decidim_assemblies_type_id_eq: + label: Tipo de asamblea menu: assemblies: Asambleas assemblies_settings: Configuración @@ -296,7 +299,10 @@ es-MX: assembly_members: form: existing_user: Usuario existente + explanation: 'Instrucciones para la imagen:' + image_guide: Preferiblemente una imagen en formato horizontal que no contenga texto. non_user: No usuario + non_user_avatar_help: Debes obtener el consentimiento de las personas antes de publicarles como miembros. select_a_position: Selecciona una posición select_user: Selecciona un usuario user_type: Tipo de usuario @@ -313,6 +319,9 @@ es-MX: new_import: accepted_types: json: JSON + assemblies: + show: + title: Acerca de esta asamblea assembly_members: index: members: Miembros @@ -380,7 +389,7 @@ es-MX: related_participatory_processes: Procesos participativos relacionados scope: Ámbito social_networks: Redes sociales - social_networks_title: Compartir esta asamblea en + social_networks_title: Visita la asamblea en target: Quién participa assembly_members: assembly_member: @@ -391,7 +400,7 @@ es-MX: assemblies: create_assembly_member: email_intro: Una administradora de la asamblea %{resource_name} te ha añadido como uno de sus miembros. - email_outro: Recibes esta notificación porque te han invitado a una asamblea. ¡Entra en assembly page para contribuir! + email_outro: Recibiste esta notificación porque has sido invitado a una asamblea. ¡Entra a la página de la asamblea para contribuir! email_subject: '¡Te han invitado a ser miembro de la asamblea %{resource_name}!' notification_title: Te han registrado como miembro de la asamblea%{resource_name}. ¡Entra en assembly page para contribuir! assembly: diff --git a/decidim-assemblies/config/locales/es-PY.yml b/decidim-assemblies/config/locales/es-PY.yml index c34d9b05bcb19..7956cb840c527 100644 --- a/decidim-assemblies/config/locales/es-PY.yml +++ b/decidim-assemblies/config/locales/es-PY.yml @@ -59,9 +59,9 @@ es-PY: birthplace: Lugar de nacimiento ceased_date: Fecha de vencimiento designation_date: Fecha de designación - designation_mode: Modo de designación full_name: Nombre completo gender: Género + non_user_avatar: Avatar position: Posición user_id: Usuaria assembly_user_role: @@ -182,6 +182,9 @@ es-PY: update: error: Ha habido un error al actualizar un usuario para esta asamblea. success: Usuario actualizado con éxito para esta asamblea. + filters: + decidim_assemblies_type_id_eq: + label: Tipo de asamblea menu: assemblies: Asambleas assemblies_settings: Configuración @@ -296,7 +299,10 @@ es-PY: assembly_members: form: existing_user: Usuario existente + explanation: 'Instrucciones para la imagen:' + image_guide: Preferiblemente una imagen apaisada que no tenga ningún texto. non_user: No usuario + non_user_avatar_help: Debes obtener el consentimiento de las personas antes de publicarlas como miembros. select_a_position: Selecciona una posición select_user: Selecciona un usuario user_type: Tipo de usuario @@ -313,6 +319,9 @@ es-PY: new_import: accepted_types: json: JSON + assemblies: + show: + title: Acerca de esta asamblea assembly_members: index: members: Miembros @@ -380,7 +389,7 @@ es-PY: related_participatory_processes: Procesos participativos relacionados scope: Ámbito social_networks: Redes sociales - social_networks_title: Compartir esta asamblea en + social_networks_title: Visita la asamblea en target: Quién participa assembly_members: assembly_member: @@ -391,7 +400,7 @@ es-PY: assemblies: create_assembly_member: email_intro: Una administradora de la asamblea %{resource_name} te ha añadido como uno de sus miembros. - email_outro: Recibes esta notificación porque te han invitado a una asamblea. ¡Entra en assembly page para contribuir! + email_outro: Recibes esta notificación porque te han invitado a una asamblea. ¡Entra en assembly page para contribuir! email_subject: '¡Te han invitado a ser miembro de la asamblea %{resource_name}!' notification_title: Te han registrado como miembro de la asamblea%{resource_name}. ¡Entra en assembly page para contribuir! assembly: diff --git a/decidim-assemblies/config/locales/es.yml b/decidim-assemblies/config/locales/es.yml index 4dd8499cc1db2..0c60b05c9e2a7 100644 --- a/decidim-assemblies/config/locales/es.yml +++ b/decidim-assemblies/config/locales/es.yml @@ -59,9 +59,9 @@ es: birthplace: Lugar de nacimiento ceased_date: Fecha de cese designation_date: Fecha de designación - designation_mode: Modo de designación full_name: Nombre completo gender: Género + non_user_avatar: Avatar position: Posición user_id: Participante o grupo assembly_user_role: @@ -182,6 +182,9 @@ es: update: error: Se ha producido un error al actualizar una administradora para esta asamblea. success: Administradora actualizada correctamente para esta asamblea. + filters: + decidim_assemblies_type_id_eq: + label: Tipo de asamblea menu: assemblies: Asambleas assemblies_settings: Configuración @@ -296,7 +299,10 @@ es: assembly_members: form: existing_user: Participante existente + explanation: 'Instrucciones para la imagen:' + image_guide: Preferiblemente una imagen apaisada que no tenga ningún texto. non_user: No participante + non_user_avatar_help: Debes obtener el consentimiento de las personas antes de publicarlas como miembros. select_a_position: Selecciona una posición select_user: Selecciona una participante user_type: Tipo de participante @@ -313,6 +319,9 @@ es: new_import: accepted_types: json: JSON + assemblies: + show: + title: Acerca de esta asamblea assembly_members: index: members: Miembros @@ -380,7 +389,7 @@ es: related_participatory_processes: Procesos participativos relacionados scope: Ámbito social_networks: Redes sociales - social_networks_title: Compartir esta asamblea en + social_networks_title: Visita la asamblea en target: Quién participa assembly_members: assembly_member: @@ -391,7 +400,7 @@ es: assemblies: create_assembly_member: email_intro: Una administradora de la asamblea %{resource_name} te ha añadido como uno de sus miembros. - email_outro: Recibes esta notificación porque te han invitado a una asamblea. ¡Entra en assembly page para contribuir! + email_outro: Recibes esta notificación porque te han invitado a una asamblea. ¡Entra en assembly page para contribuir! email_subject: '¡Te han invitado a ser miembro de la asamblea %{resource_name}!' notification_title: Te han registrado como miembro de la asamblea%{resource_name}. ¡Entra en la página de la asamblea para contribuir! assembly: diff --git a/decidim-assemblies/config/locales/eu.yml b/decidim-assemblies/config/locales/eu.yml index c19b12c3a073a..4cbaaea08fdf6 100644 --- a/decidim-assemblies/config/locales/eu.yml +++ b/decidim-assemblies/config/locales/eu.yml @@ -59,9 +59,9 @@ eu: birthplace: sorlekua ceased_date: Data amaitua designation_date: Deuseztapen data - designation_mode: Izendapen modua full_name: Izen osoa gender: Generoa + non_user_avatar: Abatar position: Kargua user_id: Parte-hartzailea edo taldea assembly_user_role: @@ -182,6 +182,9 @@ eu: update: error: Errore bat gertatu da muntaketa honetarako erabiltzailea. success: Erabiltzaileari behar bezala eguneratu da muntaia honetarako. + filters: + decidim_assemblies_type_id_eq: + label: Batzar mota menu: assemblies: Biltzarrak assemblies_settings: Ezarpenak @@ -296,7 +299,10 @@ eu: assembly_members: form: existing_user: Erabiltzaile existentea + explanation: 'Jarraibideak irudirako:' + image_guide: Ahal izanez gero, irudi bertikal bat testurik gabe. non_user: Erabiltzailea ez + non_user_avatar_help: Pertsonen baimena lortu beharko zenuke, kide gisa argitaratubaino lehen. select_a_position: Aukeratu posizio bat select_user: Aukeratu erabiltzaile bat user_type: Erabiltzaile mota @@ -380,7 +386,6 @@ eu: related_participatory_processes: Partaidetza prozesu erlazionatuak scope: Esparrua social_networks: Sare sozialak - social_networks_title: Partekatu batzar hau hemen target: Nor parte hartzen du assembly_members: assembly_member: @@ -391,7 +396,6 @@ eu: assemblies: create_assembly_member: email_intro: %{resource_name} batzarraren administratzaile batek bere kide bezala gehitu zaitu. - email_outro: Jakinarazpen hau jaso duzu batzar batera gonbidatu zaituztelako. Sartu hemen assembly page laguntza emateko! email_subject: Gonbidatu zaituzte %{resource_name} batzarraren kidea izatera! notification_title: Erregistratu zaituzte %{resource_name} batzarraren kide bezala. Sartu hemen batzarraren orrian laguntza emateko! assembly: diff --git a/decidim-assemblies/config/locales/fi-plain.yml b/decidim-assemblies/config/locales/fi-plain.yml index bdc7479131c81..0b3ec44020de0 100644 --- a/decidim-assemblies/config/locales/fi-plain.yml +++ b/decidim-assemblies/config/locales/fi-plain.yml @@ -59,9 +59,9 @@ fi-pl: birthplace: Syntymäpaikka ceased_date: Päättymispäivä designation_date: Nimityspäivä - designation_mode: Nimitystila full_name: Koko nimi gender: Sukupuoli + non_user_avatar: Avatar position: Asema user_id: Käyttäjä tai ryhmä assembly_user_role: @@ -182,6 +182,9 @@ fi-pl: update: error: Ryhmän käyttäjän päivityksessä tapahtui virhe. success: Ryhmän käyttäjä päivitetty onnistuneesti. + filters: + decidim_assemblies_type_id_eq: + label: Ryhmän tyyppi menu: assemblies: Ryhmät assemblies_settings: Asetukset @@ -296,7 +299,10 @@ fi-pl: assembly_members: form: existing_user: Olemassa oleva käyttäjä + explanation: 'Kuvan ohjeistus:' + image_guide: Käytä mieluiten vaakasuuntaista kuvaa, jossa ei ole tekstiä. non_user: Ei käyttäjä + non_user_avatar_help: Sinun pitäisi hankkia henkilöiden suostumus ennen kuin julkaiset heidän jäsenyytensä. select_a_position: Valitse asema select_user: Valitse käyttäjä user_type: Käyttäjätyyppi @@ -313,6 +319,9 @@ fi-pl: new_import: accepted_types: json: JSON + assemblies: + show: + title: Tietoa tästä ryhmästä assembly_members: index: members: Jäsenet @@ -380,7 +389,7 @@ fi-pl: related_participatory_processes: Liittyvät osallisuusprosessit scope: Teema social_networks: Sosiaalinen media - social_networks_title: Jaa tämä ryhmä + social_networks_title: Vieraile ryhmän sivulla palvelussa target: Kuka osallistuu assembly_members: assembly_member: @@ -391,7 +400,7 @@ fi-pl: assemblies: create_assembly_member: email_intro: Ryhmän %{resource_name} hallintakäyttäjä on lisännyt sinut ryhmän jäseneksi. - email_outro: Tämä viesti on lähetetty sinulle, koska sinut on kutsuttu ryhmään. Tutustu ryhmän sivuun osallistuaksesi! + email_outro: Tämä viesti on lähetetty sinulle, koska sinut on kutsuttu ryhmään. Tutustu ryhmän sivuun osallistuaksesi! email_subject: Sinut on kutsuttu jäseneksi ryhmään %{resource_name}! notification_title: Sinut on lisätty ryhmän %{resource_name} jäseneksi. Tutustu ryhmän sivuun osallistuaksesi! assembly: diff --git a/decidim-assemblies/config/locales/fi.yml b/decidim-assemblies/config/locales/fi.yml index 4174f18745841..1a91c87c6517c 100644 --- a/decidim-assemblies/config/locales/fi.yml +++ b/decidim-assemblies/config/locales/fi.yml @@ -59,9 +59,9 @@ fi: birthplace: Syntymäpaikka ceased_date: Päättymispäivä designation_date: Nimityspäivä - designation_mode: Nimitystila full_name: Koko nimi gender: Sukupuoli + non_user_avatar: Avatar position: Asema user_id: Käyttäjä tai ryhmä assembly_user_role: @@ -182,6 +182,9 @@ fi: update: error: Ryhmän hallintakäyttäjän päivitys epäonnistui. success: Ryhmän hallintakäyttäjän päivitys onnistui. + filters: + decidim_assemblies_type_id_eq: + label: Ryhmän tyyppi menu: assemblies: Ryhmät assemblies_settings: Asetukset @@ -296,7 +299,10 @@ fi: assembly_members: form: existing_user: Olemassa oleva käyttäjä + explanation: 'Kuvan ohjeistus:' + image_guide: Käytä mieluiten vaakasuuntaista kuvaa, jossa ei ole tekstiä. non_user: Ei käyttäjä + non_user_avatar_help: Sinun pitäisi hankkia henkilöiden suostumus ennen kuin julkaiset heidän jäsenyytensä. select_a_position: Valitse asema select_user: Valitse käyttäjä user_type: Käyttäjätyyppi @@ -313,6 +319,9 @@ fi: new_import: accepted_types: json: JSON + assemblies: + show: + title: Tietoa tästä ryhmästä assembly_members: index: members: Jäsenet @@ -380,7 +389,7 @@ fi: related_participatory_processes: Liittyvät osallistumisprosessit scope: Teema social_networks: Sosiaalinen media - social_networks_title: Jaa tämä ryhmä + social_networks_title: Vieraile ryhmän sivulla palvelussa target: Kuka osallistuu assembly_members: assembly_member: @@ -391,7 +400,7 @@ fi: assemblies: create_assembly_member: email_intro: Ryhmän %{resource_name} hallintakäyttäjä on lisännyt sinut ryhmän jäseneksi. - email_outro: Tämä viesti on lähetetty sinulle, koska sinut on kutsuttu ryhmään. Tutustu ryhmän sivuun osallistuaksesi! + email_outro: Tämä viesti on lähetetty sinulle, koska sinut on kutsuttu ryhmään. Tutustu ryhmän sivuun osallistuaksesi! email_subject: Sinut on kutsuttu jäseneksi ryhmään %{resource_name}! notification_title: Sinut on lisätty ryhmän %{resource_name} jäseneksi. Tutustu ryhmän sivuun osallistuaksesi! assembly: diff --git a/decidim-assemblies/config/locales/fr-CA.yml b/decidim-assemblies/config/locales/fr-CA.yml index a9c66649dae7b..8fc9f31a618dc 100644 --- a/decidim-assemblies/config/locales/fr-CA.yml +++ b/decidim-assemblies/config/locales/fr-CA.yml @@ -59,9 +59,9 @@ fr-CA: birthplace: Lieu de naissance ceased_date: Date de radiation designation_date: Date de désignation - designation_mode: Mode de désignation full_name: Nom et prénom gender: Genre + non_user_avatar: Avatar position: Statut user_id: Utilisateur assembly_user_role: @@ -182,6 +182,9 @@ fr-CA: update: error: Une erreur s'est produite lors de la mise à jour d'un utilisateur pour cette assemblée. success: Utilisateur mis à jour avec succès pour cette assemblée. + filters: + decidim_assemblies_type_id_eq: + label: Type d'assemblée menu: assemblies: Assemblées assemblies_settings: Paramètres @@ -296,7 +299,10 @@ fr-CA: assembly_members: form: existing_user: Utilisateur existant + explanation: 'Instruction concernant l’image:' + image_guide: De préférence une image en format portrait sans texte. non_user: Utilisateur inconnu + non_user_avatar_help: Vous devriez obtenir le consentement des personnes avant de les publier en tant que membre. select_a_position: Sélectionnez un statut select_user: Sélectionnez un utilisateur user_type: Type d'utilisateur @@ -313,6 +319,9 @@ fr-CA: new_import: accepted_types: json: JSON + assemblies: + show: + title: À propos de cette assemblée assembly_members: index: members: Membres @@ -380,7 +389,7 @@ fr-CA: related_participatory_processes: Concertations associées scope: Périmètre d'application social_networks: Réseaux sociaux - social_networks_title: Partager cette assemblée sur + social_networks_title: Visiter l'assemblée sur target: Participants assembly_members: assembly_member: @@ -391,7 +400,7 @@ fr-CA: assemblies: create_assembly_member: email_intro: Un administrateur de l'assemblée %{resource_name} vous y a ajouté en tant que membre. - email_outro: Vous avez reçu cette notification parce que vous avez été invité à rejoindre une assemblée. Consultez la page de l'assemblée pour y contribuer ! + email_outro: Vous avez reçu cette notification parce que vous avez été invité à rejoindre une assemblée. Consultez la page de l'assemblée pour y contribuer ! email_subject: Vous avez été invité à être membre de l'assemblée %{resource_name}! notification_title: Vous avez été inscrit en tant que membre de l'assemblée %{resource_name}. Consultez la page de l'assemblée pour contribuer ! assembly: diff --git a/decidim-assemblies/config/locales/fr.yml b/decidim-assemblies/config/locales/fr.yml index d366bdf993541..29a8040041dd0 100644 --- a/decidim-assemblies/config/locales/fr.yml +++ b/decidim-assemblies/config/locales/fr.yml @@ -59,9 +59,9 @@ fr: birthplace: Lieu de naissance ceased_date: Date de radiation designation_date: Date de désignation - designation_mode: Mode de désignation full_name: Nom et prénom gender: Genre + non_user_avatar: Avatar position: Statut user_id: Utilisateur ou groupe assembly_user_role: @@ -182,6 +182,9 @@ fr: update: error: Une erreur s'est produite lors de la mise à jour d'un utilisateur pour cette assemblée. success: Utilisateur mis à jour avec succès pour cette assemblée. + filters: + decidim_assemblies_type_id_eq: + label: Type d'assemblée menu: assemblies: Assemblées assemblies_settings: Paramètres @@ -296,7 +299,10 @@ fr: assembly_members: form: existing_user: Utilisateur existant + explanation: 'Instruction concernant l’image :' + image_guide: De préférence une image en format portrait sans texte. non_user: Utilisateur inconnu + non_user_avatar_help: Vous devriez obtenir le consentement de l'utilisateur avant d'ajouter une image à son profil. select_a_position: Sélectionnez un statut select_user: Sélectionnez un utilisateur user_type: Type d'utilisateur @@ -313,6 +319,9 @@ fr: new_import: accepted_types: json: JSON + assemblies: + show: + title: À propos de cette assemblée assembly_members: index: members: Membres @@ -380,7 +389,7 @@ fr: related_participatory_processes: Concertations associées scope: Périmètre d'application social_networks: Réseaux sociaux - social_networks_title: Partager cette assemblée sur + social_networks_title: Visiter l'assemblée sur target: Participants assembly_members: assembly_member: @@ -391,7 +400,7 @@ fr: assemblies: create_assembly_member: email_intro: Un administrateur de l'assemblée %{resource_name} vous y a ajouté en tant que membre. - email_outro: Vous avez reçu cette notification parce que vous avez été invité à rejoindre une assemblée. Consultez la page de l'assemblée pour y contribuer ! + email_outro: Vous avez reçu cette notification parce que vous avez été invité à rejoindre une assemblée. Consultez la page de l'assemblée pour y contribuer ! email_subject: Vous avez été invité à être membre de l'assemblée %{resource_name}! notification_title: Vous avez été inscrit en tant que membre de l'assemblée %{resource_name}. Consultez la page de l'assemblée pour contribuer ! assembly: diff --git a/decidim-assemblies/config/locales/gl.yml b/decidim-assemblies/config/locales/gl.yml index d58339f5ed85f..aa3a0c276138b 100644 --- a/decidim-assemblies/config/locales/gl.yml +++ b/decidim-assemblies/config/locales/gl.yml @@ -59,9 +59,9 @@ gl: birthplace: Lugar de nacemento ceased_date: Data de suspensión designation_date: Data de designación - designation_mode: Modo de designación full_name: Nome completo gender: Xénero + non_user_avatar: Avatar position: Posición user_id: Usuario assembly_user_role: @@ -182,6 +182,9 @@ gl: update: error: Houbo un erro actualizado por un usuario para este conxunto. success: O usuario actualizouse con éxito para este conxunto. + filters: + decidim_assemblies_type_id_eq: + label: Tipo de xuntanza menu: assemblies: Asembleas assemblies_settings: Axustes @@ -295,7 +298,10 @@ gl: assembly_members: form: existing_user: Usuario existente + explanation: 'Instrucións para a imaxe:' + image_guide: É preferíbel unha imaxe apaisada sen ningún texto. non_user: Non usuario + non_user_avatar_help: Tes que obter o consentimento das persoas antes de publicalas coma membros. select_a_position: Seleccione unha posición select_user: Selecciona un usuario user_type: Tipo de usuario @@ -312,6 +318,9 @@ gl: new_import: accepted_types: json: JSON + assemblies: + show: + title: Sobre esta xuntanza assembly_members: index: members: Membros @@ -379,7 +388,6 @@ gl: related_participatory_processes: Procesos participativos relacionados scope: Alcance social_networks: Redes Sociais - social_networks_title: Compartir esta xuntanza en target: Quen participa assembly_members: assembly_member: @@ -390,7 +398,6 @@ gl: assemblies: create_assembly_member: email_intro: Un administrador da xuntanza %{resource_name} engadiute coma un dos seus membros. - email_outro: Recibiches esta notificación porque fuches convidado a unha xuntanza. Entra na páxina da xuntaza para contribuír! help: participatory_spaces: assemblies: diff --git a/decidim-assemblies/config/locales/gn-PY.yml b/decidim-assemblies/config/locales/gn-PY.yml new file mode 100644 index 0000000000000..bd442b0ad85de --- /dev/null +++ b/decidim-assemblies/config/locales/gn-PY.yml @@ -0,0 +1 @@ +gn: diff --git a/decidim-assemblies/config/locales/hu.yml b/decidim-assemblies/config/locales/hu.yml index 42c52a9b8a540..fef28e86bacfc 100644 --- a/decidim-assemblies/config/locales/hu.yml +++ b/decidim-assemblies/config/locales/hu.yml @@ -59,9 +59,9 @@ hu: birthplace: Születési hely ceased_date: Megszűnés dátuma designation_date: Kijelölés dátuma - designation_mode: Kijelölés módszere full_name: Teljes név gender: Neme + non_user_avatar: Profilkép position: Pozíció user_id: Felhasználó vagy csoport assembly_user_role: @@ -182,6 +182,9 @@ hu: update: error: Hiba történt a gyűlés adminjának frissítése során. success: Gyűlés adminjának frissítése sikeres. + filters: + decidim_assemblies_type_id_eq: + label: Gyűlés típusa menu: assemblies: Gyűlések assemblies_settings: Beállítások @@ -296,7 +299,10 @@ hu: assembly_members: form: existing_user: Meglévő résztvevő + explanation: 'Útmutató a képhez:' + image_guide: Olyan fekvő képek használata ajánlott, amelyek nem tartalmaznak szöveget. non_user: Nem résztvevő + non_user_avatar_help: A tagként való szerepléshez hozzájárulást kell szerezni a személyektől. select_a_position: Válassz pozíciót select_user: Válasszon ki egy résztvevőt user_type: Résztvevő típusa @@ -313,6 +319,9 @@ hu: new_import: accepted_types: json: JSON + assemblies: + show: + title: Erről a gyűlésről assembly_members: index: members: Tagok @@ -380,7 +389,7 @@ hu: related_participatory_processes: Kapcsolódó részvételi folyamatok scope: Hatáskör social_networks: Közösségi háló - social_networks_title: Ennek a gyűlésnek a megosztása + social_networks_title: Látogasd meg a gyűlést itt target: Ki vesz részt benne assembly_members: assembly_member: @@ -391,6 +400,7 @@ hu: assemblies: create_assembly_member: email_intro: A(z) %{resource_name} gyűlés adminisztrátora hozzáadta tagként. + email_outro: Ön azért kapta ezt az értesítést, mert meghívták egy gyűlésbe. Látogasson el a gyűlés oldalára a részvételhez! email_subject: Ön meghívást kapott, hogy a(z) %{resource_name} gyűlés tagja legyen! notification_title: Ön regisztrált a(z) %{resource_name} gyűlés tagjaként. Látogasson el a gyűlés oldalára a részvételhez! assembly: diff --git a/decidim-assemblies/config/locales/id-ID.yml b/decidim-assemblies/config/locales/id-ID.yml index 14d659d944214..57effaaadc116 100644 --- a/decidim-assemblies/config/locales/id-ID.yml +++ b/decidim-assemblies/config/locales/id-ID.yml @@ -56,7 +56,6 @@ id: birthplace: Tempat lahir ceased_date: Tanggal berhenti designation_date: Tanggal penunjukan - designation_mode: Mode penunjukan full_name: Nama lengkap gender: Jenis kelamin position: Posisi diff --git a/decidim-assemblies/config/locales/is-IS.yml b/decidim-assemblies/config/locales/is-IS.yml index f01fd292098ef..b722738cb8ca5 100644 --- a/decidim-assemblies/config/locales/is-IS.yml +++ b/decidim-assemblies/config/locales/is-IS.yml @@ -51,7 +51,6 @@ is-IS: birthplace: Fæðingarstaður ceased_date: Hættudagur designation_date: Tilnefningardagur - designation_mode: Tilnefningarmáti full_name: Fullt nafn gender: Kyn position: Staða diff --git a/decidim-assemblies/config/locales/it.yml b/decidim-assemblies/config/locales/it.yml index 2262cfa7a6d15..afcd4d06464a5 100644 --- a/decidim-assemblies/config/locales/it.yml +++ b/decidim-assemblies/config/locales/it.yml @@ -59,9 +59,9 @@ it: birthplace: Luogo di nascita ceased_date: Data di termine designation_date: Data di designazione - designation_mode: Modalità di designazione full_name: Nome e cognome gender: Genere + non_user_avatar: Avatar position: Posizione user_id: Utente assembly_user_role: @@ -182,6 +182,9 @@ it: update: error: Si è verificato un errore durante l'aggiornamento di un amministratore per questa assemblea. success: Admin aggiornato correttamente per questa assemblea. + filters: + decidim_assemblies_type_id_eq: + label: Tipo di assemblea menu: assemblies: Assemblee assemblies_settings: Impostazioni @@ -296,7 +299,10 @@ it: assembly_members: form: existing_user: Utente esistente + explanation: 'Guida per l''immagine:' + image_guide: È preferibile un'immagine verticale priva di testo. non_user: Non utente + non_user_avatar_help: Si dovrebbe ottenere il consenso delle persone prima di renderle pubbliche come membri dell'assemblea. select_a_position: Seleziona una posizione select_user: Seleziona un utente user_type: Tipologia di utente @@ -313,6 +319,9 @@ it: new_import: accepted_types: json: JSON + assemblies: + show: + title: Su questa assemblea assembly_members: index: members: Utenti @@ -380,7 +389,6 @@ it: related_participatory_processes: Processi partecipativi correlati scope: Ambito social_networks: Social Networks - social_networks_title: Condividi questa assemblea su target: Chi partecipa assembly_members: assembly_member: @@ -391,7 +399,6 @@ it: assemblies: create_assembly_member: email_intro: Un amministratore dell'assemblea %{resource_name} ti ha aggiunto come membro. - email_outro: Hai ricevuto questa notifica perché sei stato invitato ad una Assemblea. Controlla la pagina per contribuire! email_subject: Ti invitano a far parte dell'Assemblea %{resource_name}! notification_title: Sei stato registrato come membro dell'Assemblea %{resource_name}. Controlla la pagina dell'assemblea per contribuire! assembly: diff --git a/decidim-assemblies/config/locales/ja.yml b/decidim-assemblies/config/locales/ja.yml index e788582e44a6b..f5555d0a12730 100644 --- a/decidim-assemblies/config/locales/ja.yml +++ b/decidim-assemblies/config/locales/ja.yml @@ -59,9 +59,9 @@ ja: birthplace: 出生地 ceased_date: 終了日 designation_date: 指定日 - designation_mode: 指定方法 full_name: フルネーム gender: 性別 + non_user_avatar: アバター position: ポジション user_id: ユーザー assembly_user_role: @@ -179,6 +179,9 @@ ja: update: error: この参加スペースの管理者を更新中に問題が発生しました。 success: 管理者はこの参加スペースの更新に成功しました。 + filters: + decidim_assemblies_type_id_eq: + label: 参加スペース種別 menu: assemblies: 参加スペース assemblies_settings: 設定 @@ -293,7 +296,10 @@ ja: assembly_members: form: existing_user: 既存の参加者 + explanation: '画像のガイダンス:' + image_guide: テキストを持たない人物の画像を使用する必要があります。 non_user: 参加者がいません + non_user_avatar_help: メンバーとして公開する前に同意を得る必要があります。 select_a_position: ポジションを選択 select_user: 参加者を選択 user_type: 参加者の種類 @@ -310,6 +316,9 @@ ja: new_import: accepted_types: json: JSON + assemblies: + show: + title: この参加スペースについて assembly_members: index: members: メンバー @@ -377,7 +386,7 @@ ja: related_participatory_processes: 関連する参加型プロセス scope: スコープ social_networks: ソーシャル ネットワーク - social_networks_title: この参加スペースを共有 + social_networks_title: 参加スペースを訪問 target: 参加者 assembly_members: assembly_member: @@ -388,7 +397,7 @@ ja: assemblies: create_assembly_member: email_intro: %{resource_name} 参加スペースの管理者があなたをメンバーの一人として追加しました。 - email_outro: 参加スペースに招待されたため、この通知を受け取りました。 参加スペースページ を確認して貢献してください! + email_outro: 参加スペースに招待されたため、この通知を受け取りました。 参加スペースのページ を確認して協力してください! email_subject: あなたは %{resource_name} 参加スペースのメンバーに招待されています! notification_title: 参加スペース %{resource_name}のメンバーとして登録されました。貢献するには 参加スペースページ を確認してください! assembly: diff --git a/decidim-assemblies/config/locales/lb-LU.yml b/decidim-assemblies/config/locales/lb-LU.yml index 823df018114f4..ed27fd1173dbc 100644 --- a/decidim-assemblies/config/locales/lb-LU.yml +++ b/decidim-assemblies/config/locales/lb-LU.yml @@ -1 +1,397 @@ lb: + activemodel: + attributes: + assemblies_setting: + enable_organization_chart: Organisationsdiagramm aktivieren + assembly: + area_id: Bereich + assembly_type: Versammlungstyp + assembly_type_other: Sonstiger Versammlungstyp + banner_image: Banner-Bild + closing_date: Einsendeschluss + closing_date_reason: Schlussdatums Grund + composition: Zusammensetzung + copy_categories: Kategorien kopieren + copy_components: Komponenten kopieren + copy_features: Funktionen kopieren + created_by: Erstellt von + created_by_other: Erstellt von anderen + creation_date: Datum erstellt + decidim_area_id: Bereich + decidim_assemblies_type_id: Versammlungstyp + decidim_scope_id: Umfang + description: Beschreibung + developer_group: Promoter-Gruppe + domain: Domain + duration: Dauer + facebook: Facebook + github: GitHub + hashtag: Hashtag + hero_image: Hauptbild + included_at: Inbegriffen bei + instagram: Instagram + internal_organisation: Interne Organisation + is_transparent: Ist transparent + local_area: Organisationsbereich + meta_scope: Bereichs-Metadaten + parent_id: Haupt Versammlung + participatory_processes_ids: Ähnliche Beteiligungsprozesse + participatory_scope: Was wird entschieden? + participatory_structure: Wie wird es entschieden? + private_space: Privatsphäre + promoted: Hervorgehoben + published_at: Veröffentlicht am + purpose_of_action: Zweck der Aktion + scope_id: Umfang + scopes_enabled: Bereiche aktiviert + short_description: Kurze Beschreibung + show_statistics: Zeige Statistiken + slug: URL-Block + special_features: Besondere Merkmale + subtitle: Untertitel + target: Wer nimmt teil? + title: Titel + twitter: Twitter + weight: Bestellposition + youtube: Youtube + assembly_member: + birthday: Geburtstag + birthplace: Geburtsort + ceased_date: Aufgegebenes Datum + designation_date: Datum der Benennung + designation_mode: Bezeichnungsmodus + full_name: Vollständiger Name + gender: Geschlecht + position: Position + user_id: User + assembly_user_role: + email: Email + name: Name + role: Rolle + errors: + models: + assembly: + attributes: + document: + invalid_document_type: 'Ungültiger Dokumenttyp. Zulässige Formate sind: %{valid_mime_types}' + activerecord: + models: + decidim/assembly: + one: Gre­mi­um + other: Gremien + decidim/assembly_member: + one: Gremienmitglieder + other: Mitglieder der Versammlung + decidim/assembly_user_role: + one: Assembly-Benutzerrolle + other: Zusammenbau von Benutzerrollen + decidim: + admin: + actions: + import_assembly: Importieren + new_assembly: Neues Gremium + new_assembly_type: Neuer Gremiumtyp + assemblies: + create: + error: Beim Erstellen eines neuen Gremiums ist ein Fehler aufgetreten. + success: Das Gremium wurde erfolgreich erstellt. + edit: + update: Aktualisieren + index: + not_published: Nicht veröffentlicht + private: Privat + public: Öffentlich + published: Veröffentlicht + new: + create: Erstellen + title: Neues Gremium + update: + error: Beim Aktualisieren dieses Gremiums ist ein Fehler aufgetreten. + success: Das Gremium wurde erfolgreich aktualisiert. + assemblies_copies: + create: + error: Beim Duplizieren dieses Gremiums ist ein Fehler aufgetreten. + success: Das Gremium wurde erfolgreich dupliziert. + assemblies_settings: + update: + error: Beim Aktualisieren der Einstellungen ist ein Fehler aufgetreten. + success: Einstellungen wurden erfolgreich aktualisiert. + assemblies_types: + create: + error: Beim Erstellen eines neuen Gremiumtyps ist ein Fehler aufgetreten. + success: Gremiumtyp wurde erfolgreich erstellt. + destroy: + success: Gremiumtyp wurde erfolgreich gelöscht. + new: + create: Erstellen + title: Neuer Gremiumtyp + update: + error: Beim Aktualisieren dieses Gremiumtyps ist ein Fehler aufgetreten. + success: Gremiumtyp wurde erfolgreich aktualisiert. + assembly_copies: + new: + copy: Kopieren + select: Wählen Sie die Daten aus, die Sie duplizieren möchten + title: Doppelte Montage + assembly_imports: + create: + error: Beim Importieren dieses Gremiums ist ein Fehler aufgetreten. + success: Gremium wurde erfolgreich importiert. + new: + import: Importieren + select: Wählen Sie aus, welche Daten Sie importieren möchten + title: Gremium importieren + assembly_members: + create: + error: Beim Hinzufügen eines Mitglieds zu diesem Gremium ist ein Fehler aufgetreten. + success: Mitglied wurde diesem Gremium erfolgreich hinzugefügt. + destroy: + success: Mitglied wurde erfolgreich aus diesem Gremium entfernt. + edit: + title: Aktualisieren Sie die Versammlungsmitglieder. + update: Aktualisieren + index: + assembly_members_title: Gremienmitglieder + new: + create: Erstellen + title: Neues Gremienmitglied. + update: + error: Beim Aktualisieren des Mitglieds dieses Gremiums ist ein Fehler aufgetreten. + success: Mitglied dieses Gremiums erfolgreich aktualisiert. + assembly_publications: + create: + error: Beim Veröffentlichen dieses Gremiums ist ein Fehler aufgetreten. + success: Gremium erfolgreich veröffentlicht. + destroy: + error: Beim Aufheben der Veröffentlichung dieser Assembly ist ein Fehler aufgetreten. + success: Die Assembly wurde nicht veröffentlicht. + assembly_user_roles: + create: + error: Beim Hinzufügen eines Benutzers für diese Assembly ist ein Fehler aufgetreten. + success: Der Administrator wurde dieser Versammlung erfolgreich hinzugefügt. + destroy: + success: Benutzer wurde erfolgreich von dieser Assembly entfernt. + edit: + title: Aktualisiere den Benutzer der Baugruppe + update: Aktualisieren + index: + assembly_admins_title: Assembly Benutzer + new: + create: Erstellen + title: Neuer Assembly-Benutzer + update: + error: Bei einem Fehler ist ein Benutzer für diese Assembly aktualisiert worden. + success: Der Benutzer wurde für diese Assembly erfolgreich aktualisiert. + menu: + assemblies: Gremien + assemblies_settings: Einstellungen + assemblies_submenu: + assembly_admins: Assembly Benutzer + assembly_members: Mitglieder + attachment_collections: Ordner + attachment_files: Dateien + categories: Kategorien + components: Komponenten + info: Info + moderations: Moderationen + private_users: Private Benutzer + assemblies_types: Versammlungstypen + models: + assemblies_types: + fields: + created_at: Hergestellt in + title: Titel + assembly: + fields: + created_at: Hergestellt in + private: Privat + promoted: Hervorgehoben + published: Veröffentlicht + title: Titel + name: Gremium + assembly_member: + fields: + ceased_date: Aufgegebenes Datum + designation_date: Datum der Benennung + full_name: Name + position: Position + name: Mitglied + positions: + other: Andere + president: Präsident + secretary: Sekretär + vice_president: Vizepräsident + assembly_user_role: + fields: + email: Email + name: Name + assemblies: + admin: + assemblies_types: + form: + title: Titel + assembly_copies: + form: + slug_help: 'URL-Slugs werden zum Generieren der URLs verwendet, die auf diese Assembly verweisen. Akzeptiert nur Buchstaben, Zahlen und Bindestriche und muss mit einem Buchstaben beginnen. Beispiel: %{url}' + assembly_imports: + form: + document_legend: Dokument hinzufügen + slug_help: 'URL-Slugs werden zum Generieren der URLs verwendet, die auf diese Versammlung verweisen. Akzeptiert nur Buchstaben, Zahlen und Bindestriche und muss mit einem Buchstaben beginnen. Beispiel: %{url}' + assembly_members: + form: + existing_user: Existierender Benutzer + non_user: Nichtbenutzer + select_a_position: Wählen Sie eine Position + select_user: Wählen Sie einen Benutzer aus + user_type: Benutzertyp + index: + filter: + all: Alle + ceased: Aufgegeben + not_ceased: Nicht aufgehört + filter_by: Filtern nach + search: Suche + content_blocks: + highlighted_assemblies: + max_results: Maximale Anzahl der Elemente, die angezeigt werden sollen + new_import: + accepted_types: + json: JSON + assembly_members: + index: + members: Mitglieder + assembly_types: + commission: Kommission + consultative_advisory: Beratende / Beratende + executive: Exekutive + government: Regierung + others: Andere + participatory: Teilnehmend + working_group: Arbeitsgruppe + content_blocks: + highlighted_assemblies: + name: Hervorgehobene Gremien + created_by: + city_council: Stadtrat + others: Andere + public: Öffentlich + filter: + all: Alle Typen + commission: Kommission + consultative_advisory: Beratung / Beratung + executive: Executive + government: Regierung + help: 'Anzeigen:' + others: Andere + participatory: Partizipativ + working_group: Arbeitsgruppe + index: + title: Gremien + last_activity: + new_assembly: Neues Gremium + pages: + home: + highlighted_assemblies: + active_assemblies: Aktive Gremien + assemblies_button_title: Verknüpfung zu der Versammlungsseite mit einem Überblick aller Versammlungen + see_all_assemblies: Alle Gremien anzeigen + user_profile: + member_of: + member_of: Mitglied von + show: + area: Bereich + assembly_type: Montageart + children: Gremien + closing_date: Einsendeschluss + composition: Zusammensetzung + created_by: Erstellt von + creation_date: Datum erstellt + developer_group: Promoter-Gruppe + duration: Dauer + included_at: Inbegriffen bei + indefinite_duration: Unbestimmt + internal_organisation: Interne Organisation + is_transparent: + 'false': undurchsichtig + 'true': transparent + local_area: Organisationsbereich + participatory_scope: Was ist entschieden? + participatory_structure: Wie ist es entschieden? + private_space: Dies ist eine private Versammlung + purpose_of_action: Zweck der Aktion + read_less: Lese weniger + read_more: Weiterlesen + related_participatory_processes: Procesos participativos relacionados + scope: Umfang + social_networks: Soziale Netzwerke + social_networks_title: Diese Versammlung auf teilen + target: Wer nimmt teil? + assembly_members: + assembly_member: + designated_on: Bezeichnet am + index: + title: Mitglieder + events: + assemblies: + create_assembly_member: + email_intro: Ein Administrator des Gremiums %{resource_name} hat Sie als Mitglied eingeladen. + email_outro: Sie haben diese Benachrichtigung erhalten, weil Sie zu einer Versammlung eingeladen wurden. Gehen Sie zur Versammlungsseite, um daran teilzunehmen! + email_subject: Sie wurden als Mitglied des Gremiums %{resource_name} eingeladen! + notification_title: Sie wurden als Mitglied des Gremiums %{resource_name} registriert. Gehen Sie zur Gremiumsseite, um mitzuwirken! + assembly: + role_assigned: + email_intro: Sie wurden als %{role} für die Versammlung "%{resource_title}" ausgewählt. + email_outro: Sie haben diese Benachrichtigung erhalten, weil Sie ein %{role} der Versammlung "%{resource_title}" sind. + email_subject: Sie wurden als %{role} für "%{resource_title}" ausgewählt. + notification_title: Sie wurden als %{role} für die Versammlung %{resource_title} ausgewählt. + help: + participatory_spaces: + assemblies: + contextual: "

Eine Versammlung ist eine Gruppe von Mitgliedern einer Organisation, die sich regelmäßig treffen, um Entscheidungen über einen bestimmten Bereich oder einen bestimmten Bereich der Organisation zu treffen.

Versammlungen halten Meetings ab, einige sind privat und andere sind offen. Wenn sie offen sind, ist es möglich, an ihnen teilzunehmen (z. B. Teilnahme, wenn die Kapazität es erlaubt, Punkte auf die Tagesordnung setzen oder Vorschläge und Entscheidungen dieses Organs kommentieren).

Beispiele: Eine Generalversammlung (die einmal im Jahr zusammentritt, um die wichtigsten Aktionslinien der Organisation sowie ihre Exekutivorgane per Abstimmung festzulegen), ein Gleichstellungsbeirat (der alle zwei Monate zusammentritt, um Vorschläge zur Verbesserung der Geschlechterbeziehungen vorzulegen In der Organisation sind eine Evaluierungskommission (die sich jeden Monat zur Überwachung eines Prozesses trifft) oder eine Garantieeinrichtung (die Vorfälle, Missbräuche oder Vorschläge zur Verbesserung der Entscheidungsverfahren sammelt) Beispiele für Versammlungen.

\n" + page: "

Eine Versammlung ist eine Gruppe von Mitgliedern einer Organisation, die sich regelmäßig treffen, um Entscheidungen über einen bestimmten Bereich oder einen bestimmten Bereich der Organisation zu treffen.

Versammlungen halten Meetings ab, einige sind privat und andere sind offen. Wenn sie offen sind, ist es möglich, an ihnen teilzunehmen (z. B. Teilnahme, wenn die Kapazität es erlaubt, Punkte auf die Tagesordnung setzen oder Vorschläge und Entscheidungen dieses Organs kommentieren).

Beispiele: Eine Generalversammlung (die einmal im Jahr zusammentritt, um die wichtigsten Aktionslinien der Organisation sowie ihre Exekutivorgane per Abstimmung festzulegen), ein Gleichstellungsbeirat (der alle zwei Monate zusammentritt, um Vorschläge zur Verbesserung der Geschlechterbeziehungen vorzulegen In der Organisation sind eine Evaluierungskommission (die sich jeden Monat zur Überwachung eines Prozesses trifft) oder eine Garantieeinrichtung (die Vorfälle, Missbräuche oder Vorschläge zur Verbesserung der Entscheidungsverfahren sammelt) Beispiele für Versammlungen.

\n" + title: Was sind Gremien? + log: + value_types: + assembly_presenter: + not_found: 'Die Assembly wurde nicht in der Datenbank gefunden (ID: %{id})' + assembly_type_presenter: + not_found: 'Der Versammlungstyp wurde nicht in der Datenbank gefunden (ID: %{id})' + menu: + assemblies: Gremien + metrics: + assemblies: + description: Anzahl der erstellten Gremien + object: Gremien + title: Gremien + participatory_processes: + show: + related_assemblies: Ähnliche Versammlungen + statistics: + assemblies_count: Gremien + errors: + messages: + cannot_be_blank: darf nicht leer sein + layouts: + decidim: + assemblies: + assembly: + more_info: Mehr Informationen + take_part: Teilnehmen + index: + children: 'Versammlungen:' + organizational_chart: Organigramm + promoted_assemblies: Hervorgehobene Gremien + reset_chart: Zurücksetzen + order_by_assemblies: + assemblies: + one: "%{count} Gremien" + other: "%{count} Gremien" + promoted_assembly: + more_info: Mehr Informationen + take_part: Teilnehmen + assembly_navigation: + assembly_member_menu_item: Mitglieder + assembly_menu_item: Das Gremium + assembly_widgets: + show: + take_part: Teilnehmen diff --git a/decidim-assemblies/config/locales/lb.yml b/decidim-assemblies/config/locales/lb.yml index ed27fd1173dbc..7a4acce00badb 100644 --- a/decidim-assemblies/config/locales/lb.yml +++ b/decidim-assemblies/config/locales/lb.yml @@ -59,9 +59,9 @@ lb: birthplace: Geburtsort ceased_date: Aufgegebenes Datum designation_date: Datum der Benennung - designation_mode: Bezeichnungsmodus full_name: Vollständiger Name gender: Geschlecht + non_user_avatar: Profil-Bild position: Position user_id: User assembly_user_role: @@ -324,7 +324,6 @@ lb: related_participatory_processes: Procesos participativos relacionados scope: Umfang social_networks: Soziale Netzwerke - social_networks_title: Diese Versammlung auf teilen target: Wer nimmt teil? assembly_members: assembly_member: @@ -335,7 +334,6 @@ lb: assemblies: create_assembly_member: email_intro: Ein Administrator des Gremiums %{resource_name} hat Sie als Mitglied eingeladen. - email_outro: Sie haben diese Benachrichtigung erhalten, weil Sie zu einer Versammlung eingeladen wurden. Gehen Sie zur Versammlungsseite, um daran teilzunehmen! email_subject: Sie wurden als Mitglied des Gremiums %{resource_name} eingeladen! notification_title: Sie wurden als Mitglied des Gremiums %{resource_name} registriert. Gehen Sie zur Gremiumsseite, um mitzuwirken! assembly: diff --git a/decidim-assemblies/config/locales/lo-LA.yml b/decidim-assemblies/config/locales/lo-LA.yml new file mode 100644 index 0000000000000..27a02bfece429 --- /dev/null +++ b/decidim-assemblies/config/locales/lo-LA.yml @@ -0,0 +1 @@ +lo: diff --git a/decidim-assemblies/config/locales/lt.yml b/decidim-assemblies/config/locales/lt.yml index fe8cd61fc48d1..c4381fce95fbb 100644 --- a/decidim-assemblies/config/locales/lt.yml +++ b/decidim-assemblies/config/locales/lt.yml @@ -59,9 +59,9 @@ lt: birthplace: Gimimo vieta ceased_date: Nutraukimo data designation_date: Paskyrimo data - designation_mode: Paskyrimo būdas full_name: Vardas, pavardė gender: Lytis + non_user_avatar: Avataras position: Pozicija user_id: Vartotojas arba grupė assembly_user_role: @@ -188,6 +188,9 @@ lt: update: error: Atnaujinant asamblėjos administratorių kilo problema. success: Šios asamblėjos administratorius sėkmingai atnaujintas. + filters: + decidim_assemblies_type_id_eq: + label: Asamblėjos tipas menu: assemblies: Asamblėjos assemblies_settings: Nustatymai @@ -302,7 +305,10 @@ lt: assembly_members: form: existing_user: Egzistuojantis dalyvis + explanation: 'Paveikslėliui skirtos gairės:' + image_guide: Pageidautina, kad tai būtų vertikalaus formato paveikslėlis be teksto. non_user: Neturintis dalyvio statuso subjektas + non_user_avatar_help: Turite gauti naudotojų sutikimą prieš publikuodami juos kaip narius. select_a_position: Pasirinkti poziciją select_user: Pasirinkti dalyvį user_type: Dalyvio tipas @@ -319,6 +325,9 @@ lt: new_import: accepted_types: json: JSON + assemblies: + show: + title: Apie šią asamblėją assembly_members: index: members: Nariai @@ -386,7 +395,7 @@ lt: related_participatory_processes: Susiję dalyvaujamieji procesai scope: Apimtis social_networks: Socialiniai tinklai - social_networks_title: Bendrinti šią asamblėją + social_networks_title: Aplankyti asamblėją target: Kas dalyvauja assembly_members: assembly_member: @@ -397,7 +406,7 @@ lt: assemblies: create_assembly_member: email_intro: %{resource_name} asamblėjos administratorius įtraukė jus kaip vieną iš jos narių. - email_outro: Šį pranešimą gavote dėl to, kad esate pakviestas į asamblėją. Norėdami prisidėti, apsilankykite asamblėjos puslapyje ! + email_outro: Šį pranešimą gavote dėl to, kad esate pakviestas į asamblėją. Norėdami prisidėti, apsilankykite asamblėjos puslapyje ! email_subject: Esate pakviestas tapti %{resource_name} asamblėjos nariu! notification_title: Jūs registravotės kaip Asamblėjos %{resource_name} narys. Peržiūrėkite asamblėjos puslapį, kad prisidėti! assembly: diff --git a/decidim-assemblies/config/locales/lv.yml b/decidim-assemblies/config/locales/lv.yml index b322cc42c9ad0..d5d4407c2ac0b 100644 --- a/decidim-assemblies/config/locales/lv.yml +++ b/decidim-assemblies/config/locales/lv.yml @@ -51,7 +51,6 @@ lv: birthplace: Dzimšanas vieta ceased_date: Beigu datums designation_date: Iecelšanas datums - designation_mode: Iecelšanas veids full_name: Vārds, uzvārds gender: Dzimums position: Pozīcija @@ -350,7 +349,6 @@ lv: related_participatory_processes: Saistītie līdzdalības procesi scope: Darbības tvērums social_networks: Sociālie tīkli - social_networks_title: Dalīties ar šo asambleju target: Kas piedalās assembly_members: assembly_member: @@ -361,7 +359,6 @@ lv: assemblies: create_assembly_member: email_intro: Asamblejas %{resource_name} administrators pievienojis jūs kā vienu no dalībniekiem. - email_outro: Jūs esat saņēmis šo paziņojumu, jo esat uzaicināts uz asambleju. Apskatiet asamblejas lapu, lai sniegtu ieguldījumu! email_subject: Jūs esat uzaicināts būt par dalībnieku asamblejā %{resource_name} ! notification_title: Jūs esat reģistrēts kā asamblejas %{resource_name} dalībnieks. Apskatiet asamblejas lapu, lai sniegtu ieguldījumu! assembly: diff --git a/decidim-assemblies/config/locales/nl.yml b/decidim-assemblies/config/locales/nl.yml index 7ed34cb40f175..f6d4dc02be292 100644 --- a/decidim-assemblies/config/locales/nl.yml +++ b/decidim-assemblies/config/locales/nl.yml @@ -59,9 +59,9 @@ nl: birthplace: Geboorteplaats ceased_date: Sluitingsdatum designation_date: Ontwerpdatum - designation_mode: Ontwerpdatum full_name: Volledige naam gender: Geslacht + non_user_avatar: Profielfoto position: Positie user_id: Gebruiker of gebruikersgroep assembly_user_role: @@ -182,6 +182,9 @@ nl: update: error: Er is een fout opgetreden bij het bijwerken van een admin voor deze groep. success: Admin is succesvol bijgewerkt voor deze groep. + filters: + decidim_assemblies_type_id_eq: + label: Groepstype menu: assemblies: Groepen assemblies_settings: Instellingen @@ -296,7 +299,10 @@ nl: assembly_members: form: existing_user: Bestaande deelnemer + explanation: 'Eigenschappen afbeelding:' + image_guide: Bij voorkeur een afbeelding in 'portretmodus' (staand) die geen tekst bevat. non_user: Niet deelnemer + non_user_avatar_help: Je hebt de toestemming nodig van de personen voordat je ze als lid publiceert. select_a_position: Selecteer een positie select_user: Selecteer een deelnemer user_type: Type deelnemer @@ -313,6 +319,9 @@ nl: new_import: accepted_types: json: JSON + assemblies: + show: + title: Over deze groep assembly_members: index: members: Leden @@ -380,7 +389,7 @@ nl: related_participatory_processes: Verwante inspraakprocessen scope: Scope social_networks: Sociale netwerken - social_networks_title: Deze groep delen op + social_networks_title: Bezoek groep op target: Wie doet mee assembly_members: assembly_member: @@ -391,7 +400,7 @@ nl: assemblies: create_assembly_member: email_intro: Een beheerder van de %{resource_name} groep heeft je toegevoegd als een van haar leden. - email_outro: Je hebt deze melding ontvangen omdat je uitgenodigd bent voor een vergadering. Bekijk de vergaderpagina om bij te dragen! + email_outro: Je hebt dit bericht ontvangen omdat je bent uitgenodigd voor een groep. Bekijk de pagina van de groep om bij te dragen! email_subject: Je bent uitgenodigd om lid te worden van de groep %{resource_name} notification_title: Je bent geregistreerd als lid van de groep %{resource_name}. Bekijk de pagina om bij te dragen! assembly: diff --git a/decidim-assemblies/config/locales/no.yml b/decidim-assemblies/config/locales/no.yml index 8b92783cecdb4..ab6838498df9d 100644 --- a/decidim-assemblies/config/locales/no.yml +++ b/decidim-assemblies/config/locales/no.yml @@ -59,9 +59,9 @@ birthplace: Fødested ceased_date: Opphørt dato designation_date: Valgdato - designation_mode: Valgform full_name: Fullt navn gender: Kjønn + non_user_avatar: Profilbilde position: Stilling user_id: Bruker eller gruppe assembly_user_role: @@ -182,6 +182,9 @@ update: error: Det oppstod et problem med å oppdatere en administrator for denne forsamlingen. success: Admin ble oppdatert for denne forsamlingen. + filters: + decidim_assemblies_type_id_eq: + label: Forsamlingstype menu: assemblies: Forsamlinger assemblies_settings: Innstillinger @@ -296,7 +299,10 @@ assembly_members: form: existing_user: Eksisterende deltaker + explanation: 'Veiledning for bilde:' + image_guide: Helst et portrettbilde uten tekst. non_user: Ingen deltakende + non_user_avatar_help: Du bør få samtykke fra personene før du offentliggjør dem som medlem. select_a_position: Velg en posisjon select_user: Velg en deltaker user_type: Deltakertype @@ -380,7 +386,6 @@ related_participatory_processes: Relaterte deltakerprosesser scope: Tema social_networks: Sosiale nettverk - social_networks_title: Del denne forsamlingen på target: Hvem deltar assembly_members: assembly_member: @@ -391,7 +396,6 @@ assemblies: create_assembly_member: email_intro: En administrator av %{resource_name} forsamlingen har lagt deg til som en av dets medlemmer. - email_outro: Du har mottatt dette varselet fordi du er invitert til en forsamling. Sjekk monteringsside for å bidra! email_subject: Du har blitt invitert til å være medlem av forsamlingen %{resource_name}! notification_title: Du har blitt registrert som medlem av forsamling %{resource_name}. Sjekk forsamlingssiden for å bidra! assembly: diff --git a/decidim-assemblies/config/locales/oc-FR.yml b/decidim-assemblies/config/locales/oc-FR.yml new file mode 100644 index 0000000000000..325b348894124 --- /dev/null +++ b/decidim-assemblies/config/locales/oc-FR.yml @@ -0,0 +1 @@ +oc: diff --git a/decidim-assemblies/config/locales/pl.yml b/decidim-assemblies/config/locales/pl.yml index 8a5dafaea6f32..3dcf49ec9e8d1 100644 --- a/decidim-assemblies/config/locales/pl.yml +++ b/decidim-assemblies/config/locales/pl.yml @@ -59,9 +59,9 @@ pl: birthplace: Miejsce urodzenia ceased_date: Data zakończenia designation_date: Data wyboru - designation_mode: Tryb wyboru full_name: Pełne imię i nazwisko gender: Płeć + non_user_avatar: Awatar position: Pozycja user_id: Użytkownik assembly_user_role: @@ -188,6 +188,9 @@ pl: update: error: Wystąpił błąd podczas aktualizacji administratora tego zespołu. success: Administrator zespołu został zaktualizowany pomyślnie. + filters: + decidim_assemblies_type_id_eq: + label: Typ zespołu menu: assemblies: Zespoły assemblies_settings: Ustawienia @@ -303,6 +306,7 @@ pl: form: existing_user: Istniejący użytkownik non_user: Brak użytkownika + non_user_avatar_help: Powinieneś uzyskać zgodę osób przed opublikowaniem ich jako członka. select_a_position: Wybierz pozycję select_user: Wybierz użytkownika user_type: Rodzaj użytkownika @@ -386,7 +390,6 @@ pl: related_participatory_processes: Powiązane procesy partycypacyjne scope: Zakres social_networks: Portale społecznościowe - social_networks_title: Odwiedź zespół na target: Do kogo kierowane assembly_members: assembly_member: @@ -397,7 +400,6 @@ pl: assemblies: create_assembly_member: email_intro: Administrator zespołu %{resource_name} ustanowił Cię jego członkiem. - email_outro: Otrzymujesz to powiadomienie, ponieważ zaproszono Cię do zespołu. Sprawdź stronę zespołu, aby dołączyć! email_subject: Zaproszono Cię do grona członków zespołu %{resource_name}! notification_title: Zarejestrowano Cię jako członka Zespołu %{resource_name}. Sprawdź stronę zespołu, aby wnieść swój wkład! assembly: diff --git a/decidim-assemblies/config/locales/pt-BR.yml b/decidim-assemblies/config/locales/pt-BR.yml index 1ad903c0ec36d..8d3e6012c303f 100644 --- a/decidim-assemblies/config/locales/pt-BR.yml +++ b/decidim-assemblies/config/locales/pt-BR.yml @@ -59,7 +59,6 @@ pt-BR: birthplace: Berço ceased_date: Data de cessação designation_date: Data de designação - designation_mode: Modo de designação full_name: Nome completo gender: Gênero position: Posição @@ -380,7 +379,6 @@ pt-BR: related_participatory_processes: Processos participativos relacionados scope: Âmbito social_networks: Redes sociais - social_networks_title: Compartilhar esta assembleia em target: Quem pode participar assembly_members: assembly_member: @@ -391,7 +389,6 @@ pt-BR: assemblies: create_assembly_member: email_intro: Um administrador da assembleia%{resource_name} adicionou você como um de seus membros. - email_outro: Você recebeu esta notificação porque foi convidado para um assembleia. Verifique a página de assembleia para contribuir! email_subject: Você foi convidado para ser um membro da assembleia %{resource_name}! notification_title: Você foi registrado como um membro da Assembleia %{resource_name}. Verifique a página do assembleia para contribuir! assembly: diff --git a/decidim-assemblies/config/locales/pt.yml b/decidim-assemblies/config/locales/pt.yml index fae2928e7b25b..9ea910f8b3d24 100644 --- a/decidim-assemblies/config/locales/pt.yml +++ b/decidim-assemblies/config/locales/pt.yml @@ -59,9 +59,9 @@ pt: birthplace: Local de Nascimento ceased_date: Data de cessação designation_date: Data de designação - designation_mode: Modo de designação full_name: Nome completo gender: Género + non_user_avatar: Avatar position: Posição user_id: Utilizador ou grupo assembly_user_role: @@ -182,6 +182,9 @@ pt: update: error: Ocorreu um problema ao atualizar um administrador para esta reunião. success: Administrador atualizador corretamente para esta reunião. + filters: + decidim_assemblies_type_id_eq: + label: Tipo de assembleia menu: assemblies: Reuniões assemblies_settings: Definições @@ -296,7 +299,10 @@ pt: assembly_members: form: existing_user: Participante existente + explanation: 'Orientações para imagem:' + image_guide: De preferência uma imagem em formato paisagem sem texto algum. non_user: Não participante + non_user_avatar_help: Deve obter o consentimento das pessoas antes de as publicar como membros. select_a_position: Selecione uma posição select_user: Selecione um participante user_type: Tipo de participante @@ -380,7 +386,6 @@ pt: related_participatory_processes: Processos participativos relacionados scope: Âmbito social_networks: Redes sociais - social_networks_title: Partilhar esta reunião em target: Quem participa assembly_members: assembly_member: @@ -391,7 +396,6 @@ pt: assemblies: create_assembly_member: email_intro: Um administrador da reunião %{resource_name} adicionou-o como um dos seus membros. - email_outro: Recebeu esta notificação porque foi convidado para uma reunião. Consulte a página da reunião para contribuir! email_subject: Foi convidado para ser membro da reunião %{resource_name}! notification_title: Foi registado como membro da Reunião %{resource_name}. Consulte a página da reunião para contribuir! assembly: diff --git a/decidim-assemblies/config/locales/ro-RO.yml b/decidim-assemblies/config/locales/ro-RO.yml index c5671c60eaed0..292a3627a8917 100644 --- a/decidim-assemblies/config/locales/ro-RO.yml +++ b/decidim-assemblies/config/locales/ro-RO.yml @@ -59,9 +59,9 @@ ro: birthplace: Locul nașterii ceased_date: Data încetării designation_date: Data desemnării - designation_mode: Modul de desemnare full_name: Numele complet gender: Sexul + non_user_avatar: Avatar position: Poziție user_id: Utilizator sau grup assembly_user_role: @@ -185,6 +185,9 @@ ro: update: error: A apărut o eroare la actualizarea unui administrator pentru acest grup de lucru. success: Administratorul a fost actualizat cu succes pentru acest grup de lucru. + filters: + decidim_assemblies_type_id_eq: + label: Tipul grupului de lucru menu: assemblies: Grupuri de lucru assemblies_settings: Setări @@ -299,7 +302,10 @@ ro: assembly_members: form: existing_user: Participant existent + explanation: 'Îndrumare pentru imagine:' + image_guide: Este de preferat o imagine pe format orizontal care să nu conțină text deloc. non_user: Non participant + non_user_avatar_help: Ar trebui să obţii consimţământul persoanelor înainte de a îi publica drept membri. select_a_position: Selectaţi o poziţie select_user: Selectați un participant user_type: Tipul participantului @@ -316,6 +322,9 @@ ro: new_import: accepted_types: json: JSON + assemblies: + show: + title: Despre această adunare assembly_members: index: members: Membri @@ -383,7 +392,7 @@ ro: related_participatory_processes: Procese participative asociate scope: Domeniu de interes social_networks: Rețele sociale - social_networks_title: Distribuie aceast grup de lucru pe + social_networks_title: Vizitează adunarea pe target: Cine participă assembly_members: assembly_member: @@ -394,7 +403,6 @@ ro: assemblies: create_assembly_member: email_intro: Un administrator al grupului de lucru %{resource_name} te-a adăugat ca unul dintre membrii săi. - email_outro: Ai primit această notificare deoarece ai fost invitat la un grup de lucru. Verifică pagina organizației pentru a colabora! email_subject: Ai primit invitație drept membru al grupului de lucru %{resource_name}! notification_title: Ai fost înregistrat ca membru al grupului de lucru %{resource_name}. Verificați pagina grupului de lucru pentru a accepta! assembly: diff --git a/decidim-assemblies/config/locales/ru.yml b/decidim-assemblies/config/locales/ru.yml index 6c554bdea6c7a..49998a1cf24ce 100644 --- a/decidim-assemblies/config/locales/ru.yml +++ b/decidim-assemblies/config/locales/ru.yml @@ -55,7 +55,6 @@ ru: birthplace: Место рождения ceased_date: Дата прекращения полномочий designation_date: Дата предоставления полномочий - designation_mode: Вид полномочий full_name: Полное имя gender: Пол position: Должность diff --git a/decidim-assemblies/config/locales/sk.yml b/decidim-assemblies/config/locales/sk.yml index 1a7e54270c980..beef21bcc966a 100644 --- a/decidim-assemblies/config/locales/sk.yml +++ b/decidim-assemblies/config/locales/sk.yml @@ -56,7 +56,6 @@ sk: birthplace: Miesto narodenia ceased_date: Dátum ukončenia designation_date: Dátum konania - designation_mode: Spôsob konania full_name: Meno a priezvisko gender: Pohlavie position: Pozícia @@ -143,8 +142,6 @@ sk: home: highlighted_assemblies: assemblies_button_title: Odkaz na stránku Zhromaždenia, zobrazujúcu všetky zhromaždenia - show: - social_networks_title: Zdieľať toto zhromaždenie na events: assemblies: create_assembly_member: diff --git a/decidim-assemblies/config/locales/sl.yml b/decidim-assemblies/config/locales/sl.yml index cd7b52d791c3a..68adb9b536dc9 100644 --- a/decidim-assemblies/config/locales/sl.yml +++ b/decidim-assemblies/config/locales/sl.yml @@ -52,7 +52,6 @@ sl: birthplace: Rojstni kraj ceased_date: Datum prenehanja designation_date: Datum imenovanja - designation_mode: Način imenovanja full_name: Polno ime gender: Spol position: Položaj diff --git a/decidim-assemblies/config/locales/sr-CS.yml b/decidim-assemblies/config/locales/sr-CS.yml index acc2f5a43e34c..a033cd2e6a03a 100644 --- a/decidim-assemblies/config/locales/sr-CS.yml +++ b/decidim-assemblies/config/locales/sr-CS.yml @@ -33,13 +33,10 @@ sr: home: highlighted_assemblies: assemblies_button_title: Veza ka strani Veća koja prikazuje sva veća - show: - social_networks_title: Podelite ovo veće na events: assemblies: create_assembly_member: email_intro: Administrator veća %{resource_name} vas je dodao u to veće. - email_outro: Dobili ste ovo obaveštenje jer ste pozvani u jedno veće. Pogledajte stranicu veća da bi doprineli njegovom radu! email_subject: Pozvani ste da postanete član veća %{resource_name}! notification_title: Registrovani ste kao član Veća %{resource_name}. Pogledajte stranicu veća da bi doprineli njegovom radu! assembly: diff --git a/decidim-assemblies/config/locales/sv.yml b/decidim-assemblies/config/locales/sv.yml index 6c22774777017..41c90419ca037 100644 --- a/decidim-assemblies/config/locales/sv.yml +++ b/decidim-assemblies/config/locales/sv.yml @@ -59,9 +59,9 @@ sv: birthplace: Födelseort ceased_date: Slutade datum designation_date: Utnämningsdatum - designation_mode: Utnämningsläge full_name: Fullständigt namn gender: Kön + non_user_avatar: Profilbild position: Befattning user_id: Användare assembly_user_role: @@ -182,6 +182,9 @@ sv: update: error: Det gick inte att uppdatera en administratör för gruppen. success: Administratören för gruppen har uppdaterats. + filters: + decidim_assemblies_type_id_eq: + label: Typ av grupp menu: assemblies: Grupper assemblies_settings: Inställningar @@ -296,7 +299,10 @@ sv: assembly_members: form: existing_user: Befintlig deltagare + explanation: 'Vägledning för bild:' + image_guide: Helst en porträttbild utan text. non_user: Ej deltagande + non_user_avatar_help: Du bör få samtycke av personerna innan du publicerar dem som medlem. select_a_position: Välj en position select_user: Välj en deltagare user_type: Typ av deltagare @@ -313,6 +319,9 @@ sv: new_import: accepted_types: json: JSON + assemblies: + show: + title: Om den här gruppen assembly_members: index: members: Medlemmar @@ -380,7 +389,6 @@ sv: related_participatory_processes: Relaterade dialoger scope: Omfång social_networks: Sociala nätverk - social_networks_title: Dela denna grupp på target: Vilka deltar assembly_members: assembly_member: @@ -391,7 +399,7 @@ sv: assemblies: create_assembly_member: email_intro: En administratör för församlingen %{resource_name} har lagt till dig som en av dess medlemmar. - email_outro: Du har fått det här meddelandet eftersom du har blivit inbjuden till en församling. Kolla samlingssidan för att bidra! + email_outro: Du har fått denna avisering eftersom du har bjudits in till en grupp. Ta en titt på gruppsidan för att bidra! email_subject: Du har blivit inbjuden att vara medlem i församlingen %{resource_name}! notification_title: Du har blivit registrerad som medlem i församlingen %{resource_name}. Kolla mötessidan för att bidra! assembly: diff --git a/decidim-assemblies/config/locales/tr-TR.yml b/decidim-assemblies/config/locales/tr-TR.yml index 3d46e90781cbd..dc4cd2bc33da4 100644 --- a/decidim-assemblies/config/locales/tr-TR.yml +++ b/decidim-assemblies/config/locales/tr-TR.yml @@ -58,7 +58,6 @@ tr: birthplace: DogumYeri ceased_date: Bitiş tarihi designation_date: Atama tarihi - designation_mode: Atama modu full_name: Ad Soyad gender: Cinsiyet position: Pozisyon @@ -377,7 +376,6 @@ tr: related_participatory_processes: İlgili katılımcı süreçleri scope: Kapsam social_networks: Sosyal ağlar - social_networks_title: Bu kurulu paylaş target: Katılanlar assembly_members: assembly_member: @@ -388,7 +386,6 @@ tr: assemblies: create_assembly_member: email_intro: %{resource_name} kurulun bir yöneticisi sizi üyelerinden biri olarak ekledi. - email_outro: Bu bildirimi bir toplantıya davet edildiğiniz için aldınız. Katkıda bulunmak için kurul sayfasını kontrol edin! email_subject: '%{resource_name} kuruluna üye olmak için davet edildiniz!' notification_title: %{resource_name} Kurulu üyesi olarak kaydoldunuz. Katkıda bulunmak için kurul sayfasını kontrol edin! assembly: diff --git a/decidim-assemblies/config/locales/uk.yml b/decidim-assemblies/config/locales/uk.yml index 252072ab04454..af861445c3c2c 100644 --- a/decidim-assemblies/config/locales/uk.yml +++ b/decidim-assemblies/config/locales/uk.yml @@ -55,7 +55,6 @@ uk: birthplace: Місце народження ceased_date: Дата припинення повноважень designation_date: Дата надання повноважень - designation_mode: Різновид повноважень full_name: Повне ім'я gender: Стать position: Посада diff --git a/decidim-assemblies/config/locales/zh-CN.yml b/decidim-assemblies/config/locales/zh-CN.yml index 956f0fce16e2a..07ca0b4338f44 100644 --- a/decidim-assemblies/config/locales/zh-CN.yml +++ b/decidim-assemblies/config/locales/zh-CN.yml @@ -56,7 +56,6 @@ zh-CN: birthplace: 出生地点 ceased_date: 缓存日期 designation_date: 指定日期 - designation_mode: 设计模式 full_name: 全名 gender: 两性平等 position: 位置 @@ -368,7 +367,6 @@ zh-CN: related_participatory_processes: 相关的参与进程 scope: 范围 social_networks: 社交网络 - social_networks_title: 分享此程序集 target: 谁参与 assembly_members: assembly_member: @@ -379,7 +377,6 @@ zh-CN: assemblies: create_assembly_member: email_intro: %{resource_name} 程序集的管理员已将您添加为其成员之一。 - email_outro: 您收到此通知是因为您已被邀请参加组装。检查 组装页面 来做出贡献! email_subject: 您已被邀请成为 %{resource_name} 个集会的成员! notification_title: 您已注册为程序集 %{resource_name}成员。检查 程序页面 以便做出贡献! assembly: diff --git a/decidim-assemblies/db/migrate/20210907120249_remove_designation_mode_from_assembly_members.rb b/decidim-assemblies/db/migrate/20210907120249_remove_designation_mode_from_assembly_members.rb new file mode 100644 index 0000000000000..83990b71fb823 --- /dev/null +++ b/decidim-assemblies/db/migrate/20210907120249_remove_designation_mode_from_assembly_members.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class RemoveDesignationModeFromAssemblyMembers < ActiveRecord::Migration[6.0] + def change + remove_column :decidim_assembly_members, :designation_mode, :string + end +end diff --git a/decidim-assemblies/lib/decidim/api/assembly_member_type.rb b/decidim-assemblies/lib/decidim/api/assembly_member_type.rb index 1d325b707ee08..5f0c9c18d9082 100644 --- a/decidim-assemblies/lib/decidim/api/assembly_member_type.rb +++ b/decidim-assemblies/lib/decidim/api/assembly_member_type.rb @@ -20,7 +20,6 @@ class AssemblyMemberType < Decidim::Api::Types::BaseObject # field :birthday, Decidim::Core::DateType, "Birthday date of the member" # non-public currently field :birthplace, GraphQL::Types::String, "Birthplace of the member", null: true field :designation_date, Decidim::Core::DateType, "Date of designation of the member", null: true - # field :designationMode, types.String, "Mode in which the member was designated", property: :designation_mode # non-public currently field :position_other, GraphQL::Types::String, "Custom position name", null: true field :ceased_date, Decidim::Core::DateType, "Date of cease for the member", null: true end diff --git a/decidim-assemblies/lib/decidim/assemblies/admin_engine.rb b/decidim-assemblies/lib/decidim/assemblies/admin_engine.rb index 6f314e51d7d55..df93295e46c0e 100644 --- a/decidim-assemblies/lib/decidim/assemblies/admin_engine.rb +++ b/decidim-assemblies/lib/decidim/assemblies/admin_engine.rb @@ -50,7 +50,9 @@ class AdminEngine < ::Rails::Engine get :share end resources :exports, only: :create - resources :imports, only: [:new, :create] + resources :imports, only: [:new, :create] do + get :example, on: :collection + end end resources :moderations do @@ -98,7 +100,9 @@ class AdminEngine < ::Rails::Engine decidim_admin_assemblies.assemblies_path, icon_name: "dial", position: 2.2, - active: :inclusive, + active: is_active_link?(decidim_admin_assemblies.assemblies_path) || + is_active_link?(decidim_admin_assemblies.assemblies_types_path) || + is_active_link?(decidim_admin_assemblies.edit_assemblies_settings_path), if: allowed_to?(:enter, :space_area, space_name: :assemblies) end end diff --git a/decidim-assemblies/lib/decidim/assemblies/participatory_space.rb b/decidim-assemblies/lib/decidim/assemblies/participatory_space.rb index 02dcbfea0e55a..7c705ea3d2de2 100644 --- a/decidim-assemblies/lib/decidim/assemblies/participatory_space.rb +++ b/decidim-assemblies/lib/decidim/assemblies/participatory_space.rb @@ -30,7 +30,7 @@ participatory_space.exports :assemblies do |export| export.collection do |assembly| - Decidim::Assembly.where(id: assembly.id) + Decidim::Assembly.where(id: assembly.id).includes(:area, :scope, :attachment_collections, :categories) end export.serializer Decidim::Assemblies::AssemblySerializer @@ -248,7 +248,6 @@ birthday: Faker::Date.birthday(min_age: 18, max_age: 65), birthplace: Faker::Demographic.demonym, designation_date: Faker::Date.between(from: 1.year.ago, to: 1.month.ago), - designation_mode: Faker::Lorem.word, position: position, position_other: position == "other" ? Faker::Job.position : nil, assembly: current_assembly @@ -261,7 +260,6 @@ birthday: Faker::Date.birthday(min_age: 18, max_age: 65), birthplace: Faker::Demographic.demonym, designation_date: Faker::Date.between(from: 1.year.ago, to: 1.month.ago), - designation_mode: Faker::Lorem.word, position: "other", position_other: Faker::Job.position, assembly: current_assembly diff --git a/decidim-assemblies/lib/decidim/assemblies/test/factories.rb b/decidim-assemblies/lib/decidim/assemblies/test/factories.rb index 542ab1ba6ec2a..e71909aa5a435 100644 --- a/decidim-assemblies/lib/decidim/assemblies/test/factories.rb +++ b/decidim-assemblies/lib/decidim/assemblies/test/factories.rb @@ -168,7 +168,6 @@ birthplace { Faker::Lorem.word } position { Decidim::AssemblyMember::POSITIONS.first } designation_date { Faker::Date.between(from: 1.year.ago, to: 1.month.ago) } - designation_mode { Faker::Lorem.word } trait :ceased do ceased_date { Faker::Date.between(from: 1.day.ago, to: 5.days.ago) } diff --git a/decidim-assemblies/lib/decidim/assemblies/version.rb b/decidim-assemblies/lib/decidim/assemblies/version.rb index 2cd479f8b29c8..d8e1bc97ed4f2 100644 --- a/decidim-assemblies/lib/decidim/assemblies/version.rb +++ b/decidim-assemblies/lib/decidim/assemblies/version.rb @@ -4,7 +4,7 @@ module Decidim # This holds the decidim-assemblies version. module Assemblies def self.version - "0.25.2" + "0.26.4" end end end diff --git a/decidim-assemblies/spec/commands/create_assembly_member_spec.rb b/decidim-assemblies/spec/commands/create_assembly_member_spec.rb index 30364b587ad98..ff38c86b69763 100644 --- a/decidim-assemblies/spec/commands/create_assembly_member_spec.rb +++ b/decidim-assemblies/spec/commands/create_assembly_member_spec.rb @@ -9,13 +9,18 @@ module Decidim::Assemblies let(:assembly) { create(:assembly) } let(:user_entity) { nil } let!(:current_user) { create :user, :confirmed, organization: assembly.organization } - let(:form) do - instance_double( - Admin::AssemblyMemberForm, - invalid?: invalid, - full_name: "Full name", - user: user_entity, - attributes: { + let(:existing_user) { false } + let(:non_user_avatar) do + ActiveStorage::Blob.create_after_upload!( + io: File.open(Decidim::Dev.asset("avatar.jpg")), + filename: "avatar.jpeg", + content_type: "image/jpeg" + ) + end + let(:form_klass) { Admin::AssemblyMemberForm } + let(:form_params) do + { + assembly_member: { weight: 0, full_name: "Full name", gender: Faker::Lorem.word, @@ -23,20 +28,45 @@ module Decidim::Assemblies birthplace: Faker::Demographic.demonym, ceased_date: nil, designation_date: Time.current, - designation_mode: "designation mode", position: Decidim::AssemblyMember::POSITIONS.sample, - position_other: "other" + position_other: "other", + existing_user: existing_user, + non_user_avatar: non_user_avatar, + user_id: user_entity&.id } + } + end + let(:form) do + form_klass.from_params( + form_params + ).with_context( + current_user: current_user, + current_organization: assembly.organization ) end - let(:invalid) { false } context "when the form is not valid" do - let(:invalid) { true } + let(:existing_user) { true } it "is not valid" do expect { subject.call }.to broadcast(:invalid) end + + context "when image is invalid" do + let(:existing_user) { false } + let(:non_user_avatar) do + ActiveStorage::Blob.create_after_upload!( + io: File.open(Decidim::Dev.asset("invalid.jpeg")), + filename: "avatar.jpeg", + content_type: "image/jpeg" + ) + end + + it "prevents uploading" do + expect { subject.call }.not_to raise_error + expect { subject.call }.to broadcast(:invalid) + end + end end context "when everything is ok" do @@ -68,6 +98,7 @@ module Decidim::Assemblies context "with an existing user in the platform" do let!(:user_entity) { create(:user, organization: assembly.organization) } + let(:existing_user) { true } it "sets the user" do subject.call @@ -94,6 +125,7 @@ module Decidim::Assemblies let!(:member1) { create(:user, organization: assembly.organization) } let!(:member2) { create(:user, organization: assembly.organization) } let!(:user_entity) { create(:user_group, :verified, users: [member1, member2], organization: assembly.organization) } + let(:existing_user) { true } it "sets the group" do subject.call diff --git a/decidim-assemblies/spec/commands/create_assembly_spec.rb b/decidim-assemblies/spec/commands/create_assembly_spec.rb index db46249157e8d..fb758e6ac18b0 100644 --- a/decidim-assemblies/spec/commands/create_assembly_spec.rb +++ b/decidim-assemblies/spec/commands/create_assembly_spec.rb @@ -19,6 +19,8 @@ module Decidim::Assemblies organization: organization ) end + let(:related_process_ids) { [participatory_processes.map(&:id)] } + let(:form) do instance_double( Admin::AssemblyForm, @@ -47,7 +49,7 @@ module Decidim::Assemblies parent: nil, private_space: false, errors: errors, - participatory_processes_ids: participatory_processes.map(&:id), + participatory_processes_ids: related_process_ids, show_statistics: false, purpose_of_action: { en: "purpose of action" }, composition: { en: "composition of internal working groups" }, @@ -189,6 +191,19 @@ module Decidim::Assemblies linked_participatory_processes = assembly.linked_participatory_space_resources(:participatory_processes, "included_participatory_processes") expect(linked_participatory_processes).to match_array(participatory_processes) end + + context "when sorting by weight" do + let!(:process_one) { create :participatory_process, organization: organization, weight: 2 } + let!(:process_two) { create :participatory_process, organization: organization, weight: 1 } + let(:related_process_ids) { [process_one.id, process_two.id] } + + it "links processes in right way" do + subject.call + + linked_processes = assembly.linked_participatory_space_resources(:participatory_process, "included_participatory_processes") + expect(linked_processes.first).to eq(process_two) + end + end end end end diff --git a/decidim-assemblies/spec/commands/decidim/assemblies/admin/import_assembly_spec.rb b/decidim-assemblies/spec/commands/decidim/assemblies/admin/import_assembly_spec.rb index a3e3772900fb6..3463942d6dc5e 100644 --- a/decidim-assemblies/spec/commands/decidim/assemblies/admin/import_assembly_spec.rb +++ b/decidim-assemblies/spec/commands/decidim/assemblies/admin/import_assembly_spec.rb @@ -4,6 +4,8 @@ module Decidim::Assemblies::Admin describe ImportAssembly do + include Decidim::ComponentTestHelpers + subject { described_class.new(form) } let(:organization) { create :organization } @@ -38,7 +40,28 @@ module Decidim::Assemblies::Admin let(:import_attachments) { false } let(:import_categories) { false } + def stub_calls_to_external_files + stub_get_request_with_format( + "http://localhost:3000/uploads/decidim/assembly/hero_image/1/city.jpeg", + "image/jpeg" + ) + stub_get_request_with_format( + "http://localhost:3000/uploads/decidim/assembly/banner_image/1/city2.jpeg", + "image/jpeg" + ) + stub_get_request_with_format( + "http://localhost:3000/uploads/decidim/attachment/file/31/Exampledocument.pdf", + "application/pdf" + ) + stub_get_request_with_format( + "http://localhost:3000/uploads/decidim/attachment/file/32/city.jpeg", + "image/jpeg" + ) + end + shared_examples "import assembly succeeds" do + before { stub_calls_to_external_files } + it "broadcasts ok and create the assembly" do expect { subject.call }.to( broadcast(:ok) && @@ -80,6 +103,8 @@ module Decidim::Assemblies::Admin let(:import_categories) { true } it "imports an assembly and the categories" do + stub_calls_to_external_files + expect { subject.call }.to change { Decidim::Category.count }.by(8) expect(Decidim::Category.distinct.select(:decidim_participatory_space_id).count).to eq 1 @@ -98,6 +123,8 @@ module Decidim::Assemblies::Admin context "when attachment collections exists" do it "imports a assembly and the collections" do + stub_calls_to_external_files + expect { subject.call }.to change { Decidim::AttachmentCollection.count }.by(1) imported_assembly_collection = Decidim::AttachmentCollection.first expect(imported_assembly_collection.name).to eq("ca" => "deleniti", "en" => "laboriosam", "es" => "quia") diff --git a/decidim-assemblies/spec/commands/update_assembly_member_spec.rb b/decidim-assemblies/spec/commands/update_assembly_member_spec.rb index b9023cd324d66..c7f17d12ccda1 100644 --- a/decidim-assemblies/spec/commands/update_assembly_member_spec.rb +++ b/decidim-assemblies/spec/commands/update_assembly_member_spec.rb @@ -10,14 +10,18 @@ module Decidim::Assemblies let(:assembly_member) { create :assembly_member, :with_user, assembly: assembly } let!(:current_user) { create :user, :confirmed, organization: assembly.organization } let(:user) { nil } - let(:form) do - instance_double( - Admin::AssemblyMemberForm, - invalid?: invalid, - current_user: current_user, - full_name: "New name", - user: user, - attributes: { + let(:existing_user) { false } + let(:non_user_avatar) do + ActiveStorage::Blob.create_after_upload!( + io: File.open(Decidim::Dev.asset("avatar.jpg")), + filename: "avatar.jpeg", + content_type: "image/jpeg" + ) + end + let(:form_klass) { Admin::AssemblyMemberForm } + let(:form_params) do + { + assembly_member: { weight: 0, full_name: "New name", gender: Faker::Lorem.word, @@ -25,20 +29,45 @@ module Decidim::Assemblies birthplace: Faker::Demographic.demonym, ceased_date: nil, designation_date: Time.current, - designation_mode: "designation mode", position: Decidim::AssemblyMember::POSITIONS.sample, - position_other: "" + position_other: Faker::Lorem.word, + existing_user: existing_user, + non_user_avatar: non_user_avatar, + user_id: user&.id } + } + end + let(:form) do + form_klass.from_params( + form_params + ).with_context( + current_user: current_user, + current_organization: assembly.organization ) end - let(:invalid) { false } context "when the form is not valid" do - let(:invalid) { true } + let(:existing_user) { true } it "is not valid" do expect { subject.call }.to broadcast(:invalid) end + + context "when image is invalid" do + let(:existing_user) { false } + let(:non_user_avatar) do + ActiveStorage::Blob.create_after_upload!( + io: File.open(Decidim::Dev.asset("invalid.jpeg")), + filename: "avatar.jpeg", + content_type: "image/jpeg" + ) + end + + it "prevents uploading" do + expect { subject.call }.not_to raise_error + expect { subject.call }.to broadcast(:invalid) + end + end end context "when everything is ok" do @@ -65,6 +94,7 @@ module Decidim::Assemblies context "when is an existing user in the platform" do let!(:user) { create :user, organization: assembly.organization } + let(:existing_user) { true } it "sets the user" do expect do diff --git a/decidim-assemblies/spec/controllers/admin/imports_controller_spec.rb b/decidim-assemblies/spec/controllers/admin/imports_controller_spec.rb index eebad9847f1cf..448cc7a9ce0d3 100644 --- a/decidim-assemblies/spec/controllers/admin/imports_controller_spec.rb +++ b/decidim-assemblies/spec/controllers/admin/imports_controller_spec.rb @@ -8,38 +8,15 @@ module Admin describe ImportsController, type: :controller do routes { Decidim::Assemblies::AdminEngine.routes } - let!(:organization) { create(:organization) } - let!(:assembly) { create :assembly, organization: organization } - let!(:user) { create(:user, :admin, :confirmed, organization: organization) } - let!(:component) { create(:component, participatory_space: assembly, manifest_name: "dummy") } - let(:creator) { Decidim::Admin::Import::Creator.new({ id: 1, "title/en": "My title for abstract creator" }) } + it_behaves_like "admin imports controller" do + let!(:participatory_space) { create :assembly, organization: organization } + let(:extra_params) { { assembly_slug: participatory_space.slug } } - let(:file) do - Rack::Test::UploadedFile.new( - Decidim::Dev.test_file("import_proposals.csv", "text/csv"), - "text/csv" - ) - end - - let(:params) do - { - file: file, - component_id: component.id, - assembly_slug: assembly.slug, - creator: "Decidim::Admin::Import::Creator" - } - end - - before do - request.env["decidim.current_organization"] = organization - sign_in user, scope: :user - end - - describe "POST create with abstract creator" do - it "raises NotImplementedError" do - expect do - post(:create, params: params) - end.to raise_error(NotImplementedError) + let(:file) do + Rack::Test::UploadedFile.new( + Decidim::Dev.test_file("import_proposals.csv", "text/csv"), + "text/csv" + ) end end end diff --git a/decidim-assemblies/spec/events/decidim/assemblies/create_assembly_member_event_spec.rb b/decidim-assemblies/spec/events/decidim/assemblies/create_assembly_member_event_spec.rb index f69a68d833e60..f1ff70b3e8ceb 100644 --- a/decidim-assemblies/spec/events/decidim/assemblies/create_assembly_member_event_spec.rb +++ b/decidim-assemblies/spec/events/decidim/assemblies/create_assembly_member_event_spec.rb @@ -27,7 +27,7 @@ describe "email_outro" do it "is generated correctly" do expect(subject.email_outro) - .to eq(%(You have received this notification because you have been invited to an assembly. Check the assembly page to contribute!)) + .to eq(%(You have received this notification because you have been invited to an assembly. Check the assembly page to contribute!)) end end diff --git a/decidim-assemblies/spec/events/decidim/role_assigned_to_assembly_event_spec.rb b/decidim-assemblies/spec/events/decidim/role_assigned_to_assembly_event_spec.rb index f7a255f0d345d..517288ded457a 100644 --- a/decidim-assemblies/spec/events/decidim/role_assigned_to_assembly_event_spec.rb +++ b/decidim-assemblies/spec/events/decidim/role_assigned_to_assembly_event_spec.rb @@ -5,7 +5,7 @@ describe Decidim::RoleAssignedToAssemblyEvent do include_context "when a simple event" - let(:resource) { create :assembly } + let(:resource) { create :assembly, title: { en: "It's my assembly" } } let(:event_name) { "decidim.events.assembly.role_assigned" } let(:role) { create :assembly_user_role, user: user, assembly: resource, role: :admin } let(:extra) { { role: role } } diff --git a/decidim-assemblies/spec/forms/assembly_member_form_spec.rb b/decidim-assemblies/spec/forms/assembly_member_form_spec.rb index cc2199e540e8f..dfe88496587d5 100644 --- a/decidim-assemblies/spec/forms/assembly_member_form_spec.rb +++ b/decidim-assemblies/spec/forms/assembly_member_form_spec.rb @@ -20,6 +20,7 @@ module Admin let(:gender) { ::Faker::Lorem.word } let(:position) { Decidim::AssemblyMember::POSITIONS.first } let(:existing_user) { false } + let(:non_user_avatar) { fixture_file_upload(File.open(Decidim::Dev.asset("city.jpeg")), "image/jpeg") } let(:user_id) { nil } let(:attributes) do @@ -31,6 +32,7 @@ module Admin "position" => position, "birthday" => Time.current, "existing_user" => existing_user, + "non_user_avatar" => non_user_avatar, "user_id" => user_id } } diff --git a/decidim-assemblies/spec/presenters/decidim/assembly_member_presenter_spec.rb b/decidim-assemblies/spec/presenters/decidim/assembly_member_presenter_spec.rb index 7a68115ef9673..322cce4e86b88 100644 --- a/decidim-assemblies/spec/presenters/decidim/assembly_member_presenter_spec.rb +++ b/decidim-assemblies/spec/presenters/decidim/assembly_member_presenter_spec.rb @@ -8,9 +8,10 @@ module Decidim let(:day_offset) { 0 } let(:today) { ::Time.zone.today } let(:birthday) { Time.zone.today - age.years + day_offset.days } + let(:non_user_avatar) { nil } let(:assembly_member) do - build(:assembly_member, full_name: "Full name", birthday: birthday) + build(:assembly_member, full_name: "Full name", birthday: birthday, non_user_avatar: non_user_avatar) end describe "name" do @@ -110,5 +111,26 @@ module Decidim end end end + + describe "non_user_avatar_path" do + subject { described_class.new(assembly_member).non_user_avatar_path } + + context "when no image is attached" do + it { is_expected.to include "default-avatar" } + end + + context "when a image is attached" do + let(:non_user_avatar) do + ActiveStorage::Blob.create_after_upload!( + io: File.open(Decidim::Dev.asset("avatar.jpg")), + filename: "avatar.jpeg", + content_type: "image/jpeg" + ) + end + let(:avatar_path) { Rails.application.routes.url_helpers.rails_blob_url(non_user_avatar, only_path: true) } + + it { is_expected.to eq avatar_path } + end + end end end diff --git a/decidim-assemblies/spec/shared/manage_assembly_members_examples.rb b/decidim-assemblies/spec/shared/manage_assembly_members_examples.rb index fbd84f49397c2..6e3c572751eb5 100644 --- a/decidim-assemblies/spec/shared/manage_assembly_members_examples.rb +++ b/decidim-assemblies/spec/shared/manage_assembly_members_examples.rb @@ -18,11 +18,15 @@ find(".datepicker-days .active").click within ".new_assembly_member" do + expect(page).to have_content("You should get the consent of the persons before publishing them as a member") + fill_in( :assembly_member_full_name, with: "Daisy O'connor" ) + attach_file "Avatar", Decidim::Dev.asset("avatar.jpg") + select "President", from: :assembly_member_position find("*[type=submit]").click diff --git a/decidim-assemblies/spec/system/admin/admin_filters_assemblies_user_roles_spec.rb b/decidim-assemblies/spec/system/admin/admin_filters_assemblies_user_roles_spec.rb new file mode 100644 index 0000000000000..62a921bd43c25 --- /dev/null +++ b/decidim-assemblies/spec/system/admin/admin_filters_assemblies_user_roles_spec.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe "Admin filters user_roles", type: :system do + let(:organization) { create(:organization) } + let!(:admin) { create(:user, :admin, :confirmed, organization: organization) } + let(:assembly) { create(:assembly, organization: organization) } + + let(:resource_controller) { Decidim::Assemblies::Admin::AssemblyUserRolesController } + let(:name) { "Dummy Name" } + let(:email) { "dummy_email@example.org" } + + let!(:invited_user_1) { create(:assembly_valuator, name: name, assembly: assembly) } + let!(:invited_user_2) { create(:assembly_valuator, email: email, assembly: assembly) } + + before do + invited_user_2.update!(invitation_sent_at: Time.current - 1.day, invitation_accepted_at: Time.current, last_sign_in_at: Time.current) + + switch_to_host(organization.host) + login_as admin, scope: :user + visit decidim_admin_assemblies.assembly_user_roles_path(assembly_slug: assembly.slug) + end + + include_context "with filterable context" + + include_examples "filterable participatory space user roles" + include_examples "searchable participatory space user roles" + context "when sorting" do + include_examples "sortable participatory space user roles" do + let!(:collection) do + create_list(:assembly_collaborator, 100, assembly: assembly, + last_sign_in_at: 2.days.ago, + invitation_accepted_at: 1.day.ago) + end + let!(:user) do + create(:assembly_valuator, + name: "ZZZupper user", + assembly: assembly, + last_sign_in_at: 30.seconds.ago, + invitation_accepted_at: Time.current) + end + + before do + visit decidim_admin_assemblies.assembly_user_roles_path(assembly_slug: assembly.slug, q: { s: sort_by }) + end + end + end + + it_behaves_like "paginating a collection" do + let!(:collection) { create_list(:assembly_valuator, 100, assembly: assembly) } + + before do + switch_to_host(organization.host) + login_as admin, scope: :user + visit decidim_admin_assemblies.assembly_user_roles_path(assembly_slug: assembly.slug) + end + end +end diff --git a/decidim-assemblies/spec/system/admin/admin_imports_assembly_spec.rb b/decidim-assemblies/spec/system/admin/admin_imports_assembly_spec.rb index 6989c5a35ef5c..af31d427790d0 100644 --- a/decidim-assemblies/spec/system/admin/admin_imports_assembly_spec.rb +++ b/decidim-assemblies/spec/system/admin/admin_imports_assembly_spec.rb @@ -11,8 +11,25 @@ visit decidim_admin_assemblies.assemblies_path end - context "with context" do - before "Imports the assembly with the basic fields" do + context "when importing the assembly with basic fields" do + before do + stub_get_request_with_format( + "http://localhost:3000/uploads/decidim/assembly/hero_image/1/city.jpeg", + "image/jpeg" + ) + stub_get_request_with_format( + "http://localhost:3000/uploads/decidim/assembly/banner_image/1/city2.jpeg", + "image/jpeg" + ) + stub_get_request_with_format( + "http://localhost:3000/uploads/decidim/attachment/file/31/Exampledocument.pdf", + "application/pdf" + ) + stub_get_request_with_format( + "http://localhost:3000/uploads/decidim/attachment/file/32/city.jpeg", + "image/jpeg" + ) + click_link "Import", match: :first within ".import_assembly" do diff --git a/decidim-assemblies/spec/system/admin/admin_manages_assemblies_spec.rb b/decidim-assemblies/spec/system/admin/admin_manages_assemblies_spec.rb index f56528a61433e..e9c269267145e 100644 --- a/decidim-assemblies/spec/system/admin/admin_manages_assemblies_spec.rb +++ b/decidim-assemblies/spec/system/admin/admin_manages_assemblies_spec.rb @@ -85,6 +85,37 @@ describe "listing parent assemblies" do it_behaves_like "filtering collection by published/unpublished" it_behaves_like "filtering collection by private/public" + + context "when filtering by assemblies type" do + include_context "with filterable context" + + let!(:assemblies_type_1) { create(:assemblies_type) } + let!(:assemblies_type_2) { create(:assemblies_type) } + + Decidim::AssembliesType.all.each do |assemblies_type| + i18n_assemblies_type = assemblies_type.name[I18n.locale.to_s] + + context "filtering collection by assemblies_type: #{i18n_assemblies_type}" do + let!(:assembly_1) { create(:assembly, organization: organization, assemblies_type: assemblies_type_1) } + let!(:assembly_2) { create(:assembly, organization: organization, assemblies_type: assemblies_type_2) } + + it_behaves_like "a filtered collection", options: "Assembly type", filter: i18n_assemblies_type do + let(:in_filter) { translated(assembly_with_type(type).title) } + let(:not_in_filter) { translated(assembly_without_type(type).title) } + end + end + end + + it_behaves_like "paginating a collection" + + def assembly_with_type(type) + Decidim::Assembly.find_by(decidim_assemblies_type_id: type) + end + + def assembly_without_type(type) + Decidim::Assembly.where.not(decidim_assemblies_type_id: type).sample + end + end end end diff --git a/decidim-assemblies/spec/system/admin/valuator_checks_components_spec.rb b/decidim-assemblies/spec/system/admin/valuator_checks_components_spec.rb index 759b7649ba357..0789e0b71bd05 100644 --- a/decidim-assemblies/spec/system/admin/valuator_checks_components_spec.rb +++ b/decidim-assemblies/spec/system/admin/valuator_checks_components_spec.rb @@ -10,7 +10,7 @@ decidim_admin_assemblies.components_path(assembly) end let(:components_path) { participatory_space_path } - let!(:user) { create :user, organization: organization } + let!(:user) { create :user, :confirmed, organization: organization } let!(:valuator_role) { create :assembly_user_role, role: :valuator, user: user, assembly: assembly } let(:another_component) { create :component, participatory_space: assembly } diff --git a/decidim-assemblies/spec/types/integration_schema_spec.rb b/decidim-assemblies/spec/types/integration_schema_spec.rb index 0fad4bcbd9b52..38f11e41102e3 100644 --- a/decidim-assemblies/spec/types/integration_schema_spec.rb +++ b/decidim-assemblies/spec/types/integration_schema_spec.rb @@ -64,19 +64,6 @@ "showStatistics" => assembly.show_statistics?, "slug" => assembly.slug, "specialFeatures" => { "translation" => assembly.special_features[locale] }, - "stats" => [ - { "name" => "dummies_count_high", "value" => 0 }, - { "name" => "pages_count", "value" => 0 }, - { "name" => "meetings_count", "value" => 0 }, - { "name" => "proposals_count", "value" => 0 }, - { "name" => "budgets_count", "value" => 0 }, - { "name" => "surveys_count", "value" => 0 }, - { "name" => "results_count", "value" => 0 }, - { "name" => "debates_count", "value" => 0 }, - { "name" => "sortitions_count", "value" => 0 }, - { "name" => "posts_count", "value" => 0 }, - { "name" => "elections_count", "value" => 0 } - ], "subtitle" => { "translation" => assembly.subtitle[locale] }, "target" => { "translation" => assembly.target[locale] }, "title" => { "translation" => assembly.title[locale] }, @@ -200,10 +187,6 @@ specialFeatures { translation(locale:"#{locale}") } - stats{ - name - value - } subtitle { translation(locale:"#{locale}") } @@ -234,9 +217,23 @@ expect { response }.not_to raise_error end - it "has hashtags" do + it "returns the correct response" do expect(response["assemblies"].first).to eq(assembly_data) end + + it_behaves_like "implements stats type" do + let(:assemblies) do + %( + assemblies{ + stats{ + name + value + } + } + ) + end + let(:stats_response) { response["assemblies"].first["stats"] } + end end describe "single assembly" do @@ -353,10 +350,6 @@ specialFeatures { translation(locale:"#{locale}") } - stats{ - name - value - } subtitle { translation(locale:"#{locale}") } @@ -378,8 +371,22 @@ expect { response }.not_to raise_error end - it "has hashtags" do + it "returns the correct response" do expect(response["assembly"]).to eq(assembly_data) end + + it_behaves_like "implements stats type" do + let(:assemblies) do + %( + assembly(id: #{assembly.id}){ + stats{ + name + value + } + } + ) + end + let(:stats_response) { response["assembly"]["stats"] } + end end end diff --git a/decidim-blogs/app/views/decidim/blogs/admin/posts/_form.html.erb b/decidim-blogs/app/views/decidim/blogs/admin/posts/_form.html.erb index 22d1978db3af0..815135b9c0cb8 100644 --- a/decidim-blogs/app/views/decidim/blogs/admin/posts/_form.html.erb +++ b/decidim-blogs/app/views/decidim/blogs/admin/posts/_form.html.erb @@ -12,7 +12,7 @@ <%= form.translated :text_field, :title, autofocus: true %>
- <%= form.translated :editor, :body, toolbar: :full, lines: 30, label: t("models.components.body", scope: "decidim.blogs.admin") %> + <%= form.translated :editor, :body, toolbar: :full, lines: 30 %>
diff --git a/decidim-blogs/app/views/decidim/blogs/admin/posts/index.html.erb b/decidim-blogs/app/views/decidim/blogs/admin/posts/index.html.erb index a6a105951c986..41132668edbd3 100644 --- a/decidim-blogs/app/views/decidim/blogs/admin/posts/index.html.erb +++ b/decidim-blogs/app/views/decidim/blogs/admin/posts/index.html.erb @@ -26,7 +26,7 @@ <%= translated_attribute(post.title) %>
+ <%= icon "circle-x" %> + <%= icon "circle-x" %> + <%= icon "circle-x" %> + <%= icon "circle-x" %>
<%= t("models.assembly_user_role.fields.name", scope: "decidim.admin") %><%= t("models.assembly_user_role.fields.email", scope: "decidim.admin") %><%= t("models.user.fields.invitation_sent_at", scope: "decidim.admin") %><%= t("models.user.fields.invitation_accepted_at", scope: "decidim.admin") %><%= t("models.assembly_user_role.fields.role", scope: "decidim.admin") %><%= sort_link(query, :name,t("models.assembly_user_role.fields.name", scope: "decidim.admin"), default_order: :desc) %><%= sort_link(query, :email, t("models.assembly_user_role.fields.email", scope: "decidim.admin"), default_order: :desc) %><%= sort_link(query, :last_sign_in_at, t("models.user.fields.last_sign_in_at", scope: "decidim.admin"), default_order: :desc) %><%= sort_link(query, :invitation_accepted_at, t("models.user.fields.invitation_accepted_at", scope: "decidim.admin"), default_order: :desc) %><%= sort_link(query, :role, t("models.assembly_user_role.fields.role", scope: "decidim.admin"), default_order: :desc) %>
- <%= decidim_sanitize post_description_admin(post) %> + <%= decidim_sanitize_editor post_description_admin(post) %> <%= post.try(:author).try(:name) %> diff --git a/decidim-blogs/app/views/decidim/blogs/posts/_posts.html.erb b/decidim-blogs/app/views/decidim/blogs/posts/_posts.html.erb index fc0bb46250518..b29ef1ae3a6ba 100644 --- a/decidim-blogs/app/views/decidim/blogs/posts/_posts.html.erb +++ b/decidim-blogs/app/views/decidim/blogs/posts/_posts.html.erb @@ -7,15 +7,15 @@
<%= link_to post, class: "card__link" do %> -

+

<%= translated_attribute post.title %> -

+ <% end %>
<%= cell "decidim/author", present(post.author), from: post, has_actions: true %>
- <%= decidim_sanitize post_description(post) %> + <%= decidim_sanitize_editor post_description(post) %>
<% end %> diff --git a/decidim-blogs/app/views/decidim/blogs/posts/show.html.erb b/decidim-blogs/app/views/decidim/blogs/posts/show.html.erb index ec86e2d8fae33..f4074e131d476 100644 --- a/decidim-blogs/app/views/decidim/blogs/posts/show.html.erb +++ b/decidim-blogs/app/views/decidim/blogs/posts/show.html.erb @@ -50,7 +50,7 @@ <% end %>
">
- <%= decidim_sanitize translated_attribute post.body %> + <%= decidim_sanitize_editor translated_attribute post.body %>
<%= cell "decidim/endorsers_list", post %>
diff --git a/decidim-blogs/config/locales/en.yml b/decidim-blogs/config/locales/en.yml index 297b1debad7b7..90ace0a5a1e60 100644 --- a/decidim-blogs/config/locales/en.yml +++ b/decidim-blogs/config/locales/en.yml @@ -1,6 +1,12 @@ --- en: activemodel: + attributes: + post: + body: Body + decidim_author_id: Author + published_at: Publish time + title: Title models: decidim/blogs/create_post_event: New blog post activerecord: @@ -19,8 +25,6 @@ en: user_group_id: Create post as admin: models: - components: - body: Body post: name: Post posts: @@ -48,7 +52,7 @@ en: author: Author body: Body created_at: Created at - title: title + title: Title posts: show: back: Back to list @@ -61,8 +65,10 @@ en: components: blogs: actions: + comment: Comment create: Create destroy: Delete + endorse: Endorse update: Update name: Blog settings: diff --git a/decidim-blogs/config/locales/gn-PY.yml b/decidim-blogs/config/locales/gn-PY.yml new file mode 100644 index 0000000000000..bd442b0ad85de --- /dev/null +++ b/decidim-blogs/config/locales/gn-PY.yml @@ -0,0 +1 @@ +gn: diff --git a/decidim-blogs/config/locales/lb-LU.yml b/decidim-blogs/config/locales/lb-LU.yml index 823df018114f4..bfea98f871973 100644 --- a/decidim-blogs/config/locales/lb-LU.yml +++ b/decidim-blogs/config/locales/lb-LU.yml @@ -1 +1,82 @@ lb: + activemodel: + models: + decidim/blogs/create_post_event: Neuer Blogeintrag + activerecord: + models: + decidim/blogs/post: + one: Post + other: Beiträge + decidim: + blogs: + actions: + confirm_destroy: Möchten Sie diesen Beitrag wirklich löschen? + destroy: Löschen + edit: Bearbeiten + new: Neuer Beitrag + title: Aktionen + user_group_id: Beitrag erstellen als + admin: + models: + components: + body: Haupttext + post: + name: Post + posts: + create: + invalid: Beim Erstellen dieses Posts ist ein Problem aufgetreten + success: Post erfolgreich erstellt + destroy: + success: Beitrag wurde erfolgreich gelöscht + edit: + save: Aktualisieren + title: Post bearbeiten + index: + title: Beiträge + new: + create: Erstellen + title: Post erstellen + update: + invalid: Beim Speichern des Posts sind Fehler aufgetreten. + success: Beitrag wurde erfolgreich gespeichert + last_activity: + new_post_at_html: "Neuer Beitrag bei %{link}" + models: + post: + fields: + author: Autor + body: Haupttext + created_at: Hergestellt in + title: Titel + posts: + show: + back: Zurück zur Liste + comments: Kommentare + view: Anzeigen + sidebar_blog: + comments: Bemerkungen + most_commented_posts: Meist kommentierte Posts + read_more: Weiterlesen + components: + blogs: + actions: + comment: Kommentar + endorse: Bestätigen + name: Blog + settings: + global: + announcement: Ankündigung + comments_enabled: Kommentare aktiviert + comments_max_length: Maximale Länge der Kommentare (0 für Standardwert) + step: + announcement: Ankündigung + comments_blocked: Kommentare blockiert + endorsements_blocked: Unterstützung deaktiviert + endorsements_enabled: Unterstützung aktiviert + events: + blogs: + post_created: + email_intro: Der Beitrag "%{resource_title}" wurde in "%{participatory_space_title}" veröffentlicht, dem Sie folgen. + email_outro: Sie haben diese Benachrichtigung erhalten, weil Sie "%{participatory_space_title}" folgen. Falls Sie keine solchen Benachrichtigungen mehr erhalten möchten, besuchen Sie den obigen Link. + email_subject: Neuer Beitrag in %{participatory_space_title} + notification_title: Der Beitrag %{resource_title} wurde in %{participatory_space_title} veröffentlicht diff --git a/decidim-blogs/config/locales/lo-LA.yml b/decidim-blogs/config/locales/lo-LA.yml new file mode 100644 index 0000000000000..27a02bfece429 --- /dev/null +++ b/decidim-blogs/config/locales/lo-LA.yml @@ -0,0 +1 @@ +lo: diff --git a/decidim-blogs/config/locales/oc-FR.yml b/decidim-blogs/config/locales/oc-FR.yml new file mode 100644 index 0000000000000..325b348894124 --- /dev/null +++ b/decidim-blogs/config/locales/oc-FR.yml @@ -0,0 +1 @@ +oc: diff --git a/decidim-blogs/lib/decidim/blogs/component.rb b/decidim-blogs/lib/decidim/blogs/component.rb index 74270732199cb..327b51edb58d6 100644 --- a/decidim-blogs/lib/decidim/blogs/component.rb +++ b/decidim-blogs/lib/decidim/blogs/component.rb @@ -36,7 +36,7 @@ component.register_resource(:blogpost) do |resource| resource.model_class_name = "Decidim::Blogs::Post" resource.card = "decidim/blogs/post" - resource.actions = %w(endorse vote amend comment) + resource.actions = %w(endorse comment) resource.searchable = true end diff --git a/decidim-blogs/lib/decidim/blogs/version.rb b/decidim-blogs/lib/decidim/blogs/version.rb index b75d67fab2a93..1593e669e8efa 100644 --- a/decidim-blogs/lib/decidim/blogs/version.rb +++ b/decidim-blogs/lib/decidim/blogs/version.rb @@ -4,7 +4,7 @@ module Decidim # This holds the decidim-pages version. module Blogs def self.version - "0.25.2" + "0.26.4" end end end diff --git a/decidim-blogs/spec/events/decidim/blogs/create_post_event_spec.rb b/decidim-blogs/spec/events/decidim/blogs/create_post_event_spec.rb index 48ada08df08a7..e4ab01ab7b199 100644 --- a/decidim-blogs/spec/events/decidim/blogs/create_post_event_spec.rb +++ b/decidim-blogs/spec/events/decidim/blogs/create_post_event_spec.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true require "spec_helper" -require "decidim/core/test/shared_examples/simple_event" describe Decidim::Blogs::CreatePostEvent do let(:resource) { create :post } @@ -11,6 +10,14 @@ it_behaves_like "a simple event" describe "email_subject" do + let(:assembly) { create(:assembly, organization: organization, title: { en: "It's a test" }) } + let(:blogs_component) { create :component, :published, name: { en: "Blogs" }, participatory_space: assembly, manifest_name: :blogs } + + before do + resource.component = blogs_component + resource.save! + end + it "is generated correctly" do expect(subject.email_subject).to eq("New post published in #{participatory_space_title}") end diff --git a/decidim-blogs/spec/events/decidim/resource_endorsed_event_spec.rb b/decidim-blogs/spec/events/decidim/resource_endorsed_event_spec.rb new file mode 100644 index 0000000000000..2d978f92779ab --- /dev/null +++ b/decidim-blogs/spec/events/decidim/resource_endorsed_event_spec.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe Decidim::ResourceEndorsedEvent do + let(:resource) { create :post, title: { en: "My blog post" } } + let(:resource_type) { "Post" } + let(:resource_text) { resource.body } + + it_behaves_like "resource endorsed event" +end diff --git a/decidim-blogs/spec/models/decidim/blogs/post_spec.rb b/decidim-blogs/spec/models/decidim/blogs/post_spec.rb index 151eb7ec59ed3..bf6d4206ccff6 100644 --- a/decidim-blogs/spec/models/decidim/blogs/post_spec.rb +++ b/decidim-blogs/spec/models/decidim/blogs/post_spec.rb @@ -12,6 +12,7 @@ module Decidim::Blogs let(:current_component) { create :component, participatory_space: participatory_process, manifest_name: "blogs" } let(:post) { create(:post, component: current_component, author: current_user) } + include_examples "endorsable" include_examples "has component" include_examples "resourceable" @@ -60,37 +61,6 @@ module Decidim::Blogs end end - describe "#endorsed_by?" do - let(:user) { create(:user, organization: subject.organization) } - - context "with User endorsement" do - it "returns false if the post is not endorsed by the given user" do - expect(subject).not_to be_endorsed_by(user) - end - - it "returns true if the post is not endorsed by the given user" do - create(:endorsement, resource: subject, author: user) - expect(subject).to be_endorsed_by(user) - end - end - - context "with Organization endorsement" do - let!(:user_group) { create(:user_group, verified_at: Time.current, organization: user.organization) } - let!(:membership) { create(:user_group_membership, user: user, user_group: user_group) } - - before { user_group.reload } - - it "returns false if the post is not endorsed by the given organization" do - expect(subject).not_to be_endorsed_by(user, user_group) - end - - it "returns true if the post is not endorsed by the given organization" do - create(:endorsement, resource: subject, author: user, user_group: user_group) - expect(subject).to be_endorsed_by(user, user_group) - end - end - end - describe "#users_to_notify_on_comment_created" do let!(:follows) { create_list(:follow, 3, followable: subject) } let(:followers) { follows.map(&:user) } diff --git a/decidim-blogs/spec/system/endorse_posts_spec.rb b/decidim-blogs/spec/system/endorse_posts_spec.rb new file mode 100644 index 0000000000000..9168c4a03b9cb --- /dev/null +++ b/decidim-blogs/spec/system/endorse_posts_spec.rb @@ -0,0 +1,113 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe "endorse posts", type: :system do + include_context "with a component" + let(:manifest_name) { "blogs" } + let(:organization) { create(:organization) } + let(:author) { create(:user, :confirmed, name: "Tester", organization: organization) } + let!(:post) { create(:post, component: component, title: { en: "Blog post title" }) } + + before do + sign_in author + visit_component + click_link "Blog post title" + end + + context "when endorsing the post without belonging to a user group" do + it "endorses the post" do + click_button("Endorse") + expect(page).to have_content("ENDORSED") + end + end + + context "when endorsing the post while being a part of a group" do + let!(:user_group) do + create( + :user_group, + :verified, + name: "Tester's Organization", + nickname: "test_org", + email: "t.mail.org@example.org", + users: [author], + organization: organization + ) + end + + it "opens a modal where you select identity as a user or a group" do + visit page.current_path + click_button("Endorse") + expect(page).to have_content("SELECT IDENTITY") + expect(page).to have_content("Tester's Organization") + expect(page).to have_content("Tester") + end + + def add_endorsements + click_button "Endorse" + within "#user-identities" do + find("li", text: /\ATester's Organization\z/).click + find("li", text: /\ATester\z/).click + expect(page).to have_css(".selected", count: 2) + click_button "Done" + end + visit current_path + click_button "Endorse" + end + + context "when both identities picked" do + it "endorses the post as a group and a user" do + visit page.current_path + + add_endorsements + + within "#user-identities" do + expect(page).to have_css(".selected", count: 2) + end + end + end + + context "when endorsement cancelled as a user" do + it "doesn't cancel group endorsement" do + visit page.current_path + + add_endorsements + within "#user-identities" do + find(".selected", match: :first).click + expect(page).to have_css(".selected", count: 1) + click_button "Done" + end + visit current_path + click_button "Endorse" + + within "#user-identities" do + expect(page).to have_css(".selected", count: 1) + within ".selected" do + expect(page).to have_text("Tester's Organization", exact: true) + end + end + end + end + + context "when endorsement cancelled as a group" do + it "doesn't cancel user endorsement" do + visit page.current_path + + add_endorsements + within "#user-identities" do + page.all(".selected")[1].click + click_button "Done" + end + visit current_path + click_button "Endorse" + + within "#user-identities" do + expect(page).to have_css(".selected", count: 1) + within ".selected" do + expect(page).to have_text("Tester", exact: true) + end + end + end + end + end +end diff --git a/decidim-blogs/spec/system/explore_posts_spec.rb b/decidim-blogs/spec/system/explore_posts_spec.rb index 6b09e2f9ebc3e..7c6d1d389d668 100644 --- a/decidim-blogs/spec/system/explore_posts_spec.rb +++ b/decidim-blogs/spec/system/explore_posts_spec.rb @@ -36,6 +36,11 @@ expect(page).to have_selector('a[title="endorsements"]', text: "endorsement".pluralize(old_post.endorsements.count)) end + it "shows images" do + visit_component + expect(page).to have_selector(".card--post img.card__image") + end + context "when paginating" do let(:collection_size) { 10 } let!(:collection) { create_list :post, collection_size, component: component } diff --git a/decidim-budgets/app/assets/stylesheets/decidim/budgets/budget/_budget-vote-button.scss b/decidim-budgets/app/assets/stylesheets/decidim/budgets/budget/_budget-vote-button.scss new file mode 100644 index 0000000000000..ce0a23b79487b --- /dev/null +++ b/decidim-budgets/app/assets/stylesheets/decidim/budgets/budget/_budget-vote-button.scss @@ -0,0 +1,22 @@ +.budget-vote-button.expanded{ + display: flex; + text-align: left; + justify-content: space-between; + align-items: center; + + span{ + font-size: 1rem; + } + + &.added{ + background-color: tint($success, 80%); + color: $body-font-color; + } + + &:not(.added){ + .budget-list__action{ + border-color: white; + color: white; + } + } +} diff --git a/decidim-budgets/app/cells/decidim/budgets/budget_information_modal/show.erb b/decidim-budgets/app/cells/decidim/budgets/budget_information_modal/show.erb index 26a8e819745d4..79bc6634e6554 100644 --- a/decidim-budgets/app/cells/decidim/budgets/budget_information_modal/show.erb +++ b/decidim-budgets/app/cells/decidim/budgets/budget_information_modal/show.erb @@ -1,10 +1,10 @@ - -
+
-

<%= decidim_sanitize(component_name) %>

+

<%= decidim_sanitize(component_name) %>

diff --git a/decidim-budgets/app/cells/decidim/budgets/budget_list_item/show.erb b/decidim-budgets/app/cells/decidim/budgets/budget_list_item/show.erb index 280ff42439b69..2cb1828c124af 100644 --- a/decidim-budgets/app/cells/decidim/budgets/budget_list_item/show.erb +++ b/decidim-budgets/app/cells/decidim/budgets/budget_list_item/show.erb @@ -1,22 +1,38 @@ -
-
+
+
<%= link_to budget_path(budget), class: link_class do %> - <% if voted? && !voting_finished? %> - - <%= translated_attribute(title) %> - - - <%= icon "check", class: "icon--small", role: "img", aria_label: t("decidim.budgets.budget_list_item.voting_finished") %> - - <% else %> +

<%= translated_attribute(title) %> +

+ <% end %> + +
+ + <%= budget_to_currency(total_budget) %> + +
+ + <%= decidim_sanitize html_truncate(translated_attribute(description), length: 140) %> +
- <% if progress? && !voting_finished? %> - - <%= icon "bookmark", class: "icon--small", role: "img", aria_label: t("decidim.budgets.budget_list_item.voting_started") %> - - <% end %> + <% if !voting_finished? %> +
+ <% if voted? %> + + <%= icon "check", class: "icon--small", role: "img", aria_label: t("decidim.budgets.budget_list_item.voting_finished") %> + + <% elsif progress? %> + + <%= icon "bookmark", class: "icon--small", role: "img", aria_label: t("decidim.budgets.budget_list_item.voting_started") %> + <% end %> +
+ <% end %> + +
+ <%= link_to budget_path(budget), class: "button button--sc expanded #{button_class} mb-none" do %> + <%= button_text %> + <%= icon "chevron-right", class: "icon--small", role: "img" %> <% end %>
diff --git a/decidim-budgets/app/cells/decidim/budgets/budget_list_item_cell.rb b/decidim-budgets/app/cells/decidim/budgets/budget_list_item_cell.rb index 2716b347e418c..5d31b532d3c86 100644 --- a/decidim-budgets/app/cells/decidim/budgets/budget_list_item_cell.rb +++ b/decidim-budgets/app/cells/decidim/budgets/budget_list_item_cell.rb @@ -4,9 +4,15 @@ module Decidim module Budgets # This cell renders the budget item list in the budgets list class BudgetListItemCell < BaseCell + include Decidim::SanitizeHelper + include Decidim::ApplicationHelper + include ActiveSupport::NumberHelper + include Decidim::Budgets::ProjectsHelper + delegate :voting_finished?, to: :controller + delegate :highlighted, to: :current_workflow - property :title + property :title, :description, :total_budget alias budget model private @@ -17,6 +23,7 @@ def card_class list << "card--list__data-added" if voted? list << "card--list__data-progress" if progress? end + list << "budget--highlighted" if highlighted? end.join(" ") end @@ -32,9 +39,31 @@ def progress? current_user && status == :progress end + def highlighted? + highlighted.include?(budget) + end + def status @status ||= current_workflow.status(budget) end + + def button_class + "hollow" if voted? || !highlighted? + end + + def button_text + key = if current_workflow.vote_allowed?(budget) && !voted? + progress? ? :progress : :vote + else + :show + end + + t(key, scope: i18n_scope) + end + + def i18n_scope + "decidim.budgets.budgets_list" + end end end end diff --git a/decidim-budgets/app/cells/decidim/budgets/budgets_header/show.erb b/decidim-budgets/app/cells/decidim/budgets/budgets_header/show.erb index 12fe6b4a64731..4b0d50d17e416 100644 --- a/decidim-budgets/app/cells/decidim/budgets/budgets_header/show.erb +++ b/decidim-budgets/app/cells/decidim/budgets/budgets_header/show.erb @@ -1,7 +1,7 @@
- <%= decidim_sanitize(landing_page_content) %> + <%= decidim_sanitize_editor(landing_page_content) %>
diff --git a/decidim-budgets/app/cells/decidim/budgets/budgets_list/card_list.erb b/decidim-budgets/app/cells/decidim/budgets/budgets_list/card_list.erb index 8cbbe75b3a228..e22c514657368 100644 --- a/decidim-budgets/app/cells/decidim/budgets/budgets_list/card_list.erb +++ b/decidim-budgets/app/cells/decidim/budgets/budgets_list/card_list.erb @@ -1,7 +1,18 @@ -
- <% budgets.each do |budget| %> - <% next if highlighted.include?(budget) && !voting_finished? %> +<%# show highlighted budgets first %> +<% if highlighted.any? %> +
+ <% highlighted.each do |budget| %> + <%= cell("decidim/budgets/budget_list_item", budget) %> + <% end %> +
+<% end %> - <%= cell("decidim/budgets/budget_list_item", budget) %> - <% end %> -
+<% non_highlighted = (budgets - highlighted - voted) %> + +<% if non_highlighted.any? %> +
+ <% non_highlighted.each do |budget| %> + <%= cell("decidim/budgets/budget_list_item", budget) %> + <% end %> +
+<% end %> diff --git a/decidim-budgets/app/cells/decidim/budgets/budgets_list/highlighted.erb b/decidim-budgets/app/cells/decidim/budgets/budgets_list/highlighted.erb deleted file mode 100644 index e680002273126..0000000000000 --- a/decidim-budgets/app/cells/decidim/budgets/budgets_list/highlighted.erb +++ /dev/null @@ -1,11 +0,0 @@ -<% if highlighted? %> -

- <% highlighted.each do |budget| %> - <%= link_to( - t("highlighted_cta", scope: i18n_scope, - name: translated_attribute(budget.title)), - resource_locator(budget).path, - class: :button ) %> - <% end %> -

-<% end %> diff --git a/decidim-budgets/app/cells/decidim/budgets/budgets_list/show.erb b/decidim-budgets/app/cells/decidim/budgets/budgets_list/show.erb index 51d5a1ffa0054..6971999cb9990 100644 --- a/decidim-budgets/app/cells/decidim/budgets/budgets_list/show.erb +++ b/decidim-budgets/app/cells/decidim/budgets/budgets_list/show.erb @@ -1,18 +1,17 @@
- <% if !voting_finished? && (highlighted? || voted?) %> + <% if !voting_finished? && (voted?) %>
-

+

<%= t(:my_budgets, scope: i18n_scope) %> -

+ - <%= render :highlighted %> <%= render :voted %>
<% end %>
-
+
<%= render :card_list %>
diff --git a/decidim-budgets/app/cells/decidim/budgets/budgets_list/voted.erb b/decidim-budgets/app/cells/decidim/budgets/budgets_list/voted.erb index 0ca04f4acdef2..8ff0d6b5dcc41 100644 --- a/decidim-budgets/app/cells/decidim/budgets/budgets_list/voted.erb +++ b/decidim-budgets/app/cells/decidim/budgets/budgets_list/voted.erb @@ -4,6 +4,12 @@ <%= t(:voted_on, scope: i18n_scope, links: budgets_link_list(voted)) %>

+
+ <% voted.each do |budget| %> + <%= cell("decidim/budgets/budget_list_item", budget) %> + <% end %> +
+ <% if finished? %>

<%= t(:finished_message, scope: i18n_scope) %> diff --git a/decidim-budgets/app/cells/decidim/budgets/project_list_item/project_data.erb b/decidim-budgets/app/cells/decidim/budgets/project_list_item/project_data.erb index 53abf5cf3d717..e6f3b53350d61 100644 --- a/decidim-budgets/app/cells/decidim/budgets/project_list_item/project_data.erb +++ b/decidim-budgets/app/cells/decidim/budgets/project_list_item/project_data.erb @@ -14,6 +14,6 @@ <%= cell("decidim/budgets/project_voted_hint", model, class: "display-block margin-top-1") if current_order_checked_out? && resource_added? %> - <%= render :project_data_vote_button if !current_order_checked_out? && voting_open? %> + <%= cell("decidim/budgets/project_vote_button", model) if !current_order_checked_out? && voting_open? %> <% end %>

diff --git a/decidim-budgets/app/cells/decidim/budgets/project_list_item/project_text.erb b/decidim-budgets/app/cells/decidim/budgets/project_list_item/project_text.erb index 6e4d5e7e61b93..08730b3246096 100644 --- a/decidim-budgets/app/cells/decidim/budgets/project_list_item/project_text.erb +++ b/decidim-budgets/app/cells/decidim/budgets/project_list_item/project_text.erb @@ -1,11 +1,11 @@
<%= link_to resource_path, class: "card__link" do %> -
+

<%= cell("decidim/budgets/project_selected_status", model) %> <%= resource_title %> -

+ <% end %>
diff --git a/decidim-budgets/app/cells/decidim/budgets/project_list_item_cell.rb b/decidim-budgets/app/cells/decidim/budgets/project_list_item_cell.rb index 2de429ae8de9c..b6a176136bea3 100644 --- a/decidim-budgets/app/cells/decidim/budgets/project_list_item_cell.rb +++ b/decidim-budgets/app/cells/decidim/budgets/project_list_item_cell.rb @@ -17,7 +17,7 @@ class ProjectListItemCell < Decidim::ViewModel private def resource_path - resource_locator([model.budget, model]).path(filter_link_params) + resource_locator([model.budget, model]).path end def resource_title diff --git a/decidim-budgets/app/cells/decidim/budgets/project_list_item/project_data_vote_button.erb b/decidim-budgets/app/cells/decidim/budgets/project_vote_button/show.erb similarity index 93% rename from decidim-budgets/app/cells/decidim/budgets/project_list_item/project_data_vote_button.erb rename to decidim-budgets/app/cells/decidim/budgets/project_vote_button/show.erb index b2b13e701ebb9..5b9bfe600528f 100644 --- a/decidim-budgets/app/cells/decidim/budgets/project_list_item/project_data_vote_button.erb +++ b/decidim-budgets/app/cells/decidim/budgets/project_vote_button/show.erb @@ -3,6 +3,7 @@ method: vote_button_method, remote: true, class: "button tiny budget-list__action #{vote_button_class}", + id: "project-vote-button-#{model.id}", data: { add: !resource_added?, disable: true, diff --git a/decidim-budgets/app/cells/decidim/budgets/project_vote_button_cell.rb b/decidim-budgets/app/cells/decidim/budgets/project_vote_button_cell.rb new file mode 100644 index 0000000000000..bd4d9d6d43c76 --- /dev/null +++ b/decidim-budgets/app/cells/decidim/budgets/project_vote_button_cell.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module Decidim + module Budgets + # This cell renders an authorized_action button + # to vote a given instance of a Project in a budget list + class ProjectVoteButtonCell < ProjectListItemCell + end + end +end diff --git a/decidim-budgets/app/commands/decidim/budgets/add_line_item.rb b/decidim-budgets/app/commands/decidim/budgets/add_line_item.rb index ab2f512ceb520..388fc87a78f8f 100644 --- a/decidim-budgets/app/commands/decidim/budgets/add_line_item.rb +++ b/decidim-budgets/app/commands/decidim/budgets/add_line_item.rb @@ -23,7 +23,7 @@ def initialize(current_order, project, current_user) # Returns nothing. def call transaction do - return broadcast(:invalid) if voting_not_enabled? || order.checked_out? + return broadcast(:invalid) if voting_not_enabled? || order.checked_out? || exceeds_budget? add_line_item broadcast(:ok, order) @@ -44,6 +44,10 @@ def add_line_item end end + def exceeds_budget? + order.allocation_for(project) + order.total > order.available_allocation + end + def voting_not_enabled? project.component.current_settings.votes != "enabled" end diff --git a/decidim-budgets/app/commands/decidim/budgets/admin/import_proposals_to_budgets.rb b/decidim-budgets/app/commands/decidim/budgets/admin/import_proposals_to_budgets.rb index c31057163a7c2..97addf67f1c75 100644 --- a/decidim-budgets/app/commands/decidim/budgets/admin/import_proposals_to_budgets.rb +++ b/decidim-budgets/app/commands/decidim/budgets/admin/import_proposals_to_budgets.rb @@ -81,7 +81,10 @@ def origin_component end def proposal_already_copied?(original_proposal) - original_proposal.linked_resources(:projects, "included_proposals").any? do |project| + # Note: we are including also projects from unpublished components + # because otherwise duplicates could be created until the component is + # published. + original_proposal.linked_resources(:projects, "included_proposals", component_published: false).any? do |project| project.budget == form.budget end end diff --git a/decidim-budgets/app/controllers/concerns/decidim/budgets/admin/filterable.rb b/decidim-budgets/app/controllers/concerns/decidim/budgets/admin/filterable.rb new file mode 100644 index 0000000000000..44ecade318b64 --- /dev/null +++ b/decidim-budgets/app/controllers/concerns/decidim/budgets/admin/filterable.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +require "active_support/concern" + +module Decidim + module Budgets + module Admin + module Filterable + extend ActiveSupport::Concern + + included do + include Decidim::Admin::Filterable + + helper Decidim::Budgets::Admin::FilterableHelper + + private + + def base_query + collection + end + + def search_field_predicate + :id_string_or_title_cont + end + + def filters + [ + :scope_id_eq, + :category_id_eq, + :selected_at_null + ] + end + + def filters_with_values + { + scope_id_eq: scope_ids_hash(scopes.top_level), + category_id_eq: category_ids_hash(categories.first_class), + selected_at_null: [true, false] + } + end + + # Can't user `super` here, because it does not belong to a superclass + # but to a concern. + def dynamically_translated_filters + [:scope_id_eq, :category_id_eq] + end + end + end + end + end +end diff --git a/decidim-budgets/app/controllers/decidim/budgets/admin/projects_controller.rb b/decidim-budgets/app/controllers/decidim/budgets/admin/projects_controller.rb index 2ea82beb3ff1c..6c75ad6ed2e9e 100644 --- a/decidim-budgets/app/controllers/decidim/budgets/admin/projects_controller.rb +++ b/decidim-budgets/app/controllers/decidim/budgets/admin/projects_controller.rb @@ -7,9 +7,14 @@ module Admin class ProjectsController < Admin::ApplicationController include Decidim::ApplicationHelper include Decidim::Proposals::Admin::Picker if Decidim::Budgets.enable_proposal_linking + include Decidim::Budgets::Admin::Filterable helper_method :projects, :finished_orders, :pending_orders, :present + def collection + @collection ||= budget.projects.page(params[:page]).per(15) + end + def new enforce_permission_to :create, :project @form = form(ProjectForm).from_params( @@ -72,7 +77,7 @@ def destroy private def projects - @projects ||= budget.projects.page(params[:page]).per(15) + @projects ||= filtered_collection end def orders diff --git a/decidim-budgets/app/controllers/decidim/budgets/line_items_controller.rb b/decidim-budgets/app/controllers/decidim/budgets/line_items_controller.rb index 227612c0b8a4b..f81b01e2f3ed9 100644 --- a/decidim-budgets/app/controllers/decidim/budgets/line_items_controller.rb +++ b/decidim-budgets/app/controllers/decidim/budgets/line_items_controller.rb @@ -20,7 +20,7 @@ def create end on(:invalid) do - render nothing: true, status: :unprocessable_entity + format.js { render "update_budget", status: :unprocessable_entity } end end end @@ -35,7 +35,7 @@ def destroy end on(:invalid) do - render nothing: true, status: :unprocessable_entity + format.js { render "update_budget", status: :unprocessable_entity } end end end diff --git a/decidim-budgets/app/controllers/decidim/budgets/projects_controller.rb b/decidim-budgets/app/controllers/decidim/budgets/projects_controller.rb index df750638e5f93..7a6ed8283c8f4 100644 --- a/decidim-budgets/app/controllers/decidim/budgets/projects_controller.rb +++ b/decidim-budgets/app/controllers/decidim/budgets/projects_controller.rb @@ -28,8 +28,8 @@ def budget def projects return @projects if @projects - @projects = search.results.page(params[:page]).per(current_component.settings.projects_per_page) - @projects = reorder(@projects) + @projects = reorder(search.results) + @projects = @projects.page(params[:page]).per(current_component.settings.projects_per_page) end def project diff --git a/decidim-budgets/app/helpers/decidim/budgets/admin/filterable_helper.rb b/decidim-budgets/app/helpers/decidim/budgets/admin/filterable_helper.rb new file mode 100644 index 0000000000000..4fd84104eb78d --- /dev/null +++ b/decidim-budgets/app/helpers/decidim/budgets/admin/filterable_helper.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module Decidim + module Budgets + module Admin + module FilterableHelper + end + end + end +end diff --git a/decidim-budgets/app/models/decidim/budgets/project.rb b/decidim-budgets/app/models/decidim/budgets/project.rb index 70e1e0b7cdc8b..913fbd85a4dce 100644 --- a/decidim-budgets/app/models/decidim/budgets/project.rb +++ b/decidim-budgets/app/models/decidim/budgets/project.rb @@ -46,7 +46,8 @@ def self.ordered_ids(ids) # delimiter. Otherwise e.g. ID 2 would match ID "26" in the original # array. This is why we search for match ",2," instead to get the actual # position for ID 2. - order(Arel.sql("position(concat(',', id::text, ',') in ',#{ids.join(",")},')")) + concat_ids = connection.quote(",#{ids.join(",")},") + order(Arel.sql("position(concat(',', id::text, ',') in #{concat_ids})")) end def self.log_presenter_class_for(_log) @@ -92,6 +93,32 @@ def selected? def attachment_context :admin end + + ransacker :id_string do + Arel.sql(%{cast("decidim_budgets_projects"."id" as text)}) + end + + # Allow ransacker to search for a key in a hstore column (`title`.`en`) + ransacker :title do |parent| + Arel::Nodes::InfixOperation.new("->>", parent.table[:title], Arel::Nodes.build_quoted(I18n.locale.to_s)) + end + + ransacker :selected do + Arel.sql(%{("decidim_budgets_projects"."selected_at")::text}) + end + + ransacker :confirmed_orders_count do + query = <<-SQL.squish + ( + SELECT COUNT(decidim_budgets_line_items.decidim_order_id) + FROM decidim_budgets_line_items + LEFT JOIN decidim_budgets_orders ON decidim_budgets_orders.id = decidim_budgets_line_items.decidim_order_id + WHERE decidim_budgets_orders.checked_out_at IS NOT NULL + AND decidim_budgets_projects.id = decidim_budgets_line_items.decidim_project_id + ) + SQL + Arel.sql(query) + end end end end diff --git a/decidim-budgets/app/packs/entrypoints/decidim_budgets.js b/decidim-budgets/app/packs/entrypoints/decidim_budgets.js index 2d160a6963293..0591c186a438c 100644 --- a/decidim-budgets/app/packs/entrypoints/decidim_budgets.js +++ b/decidim-budgets/app/packs/entrypoints/decidim_budgets.js @@ -1,5 +1,6 @@ import "src/decidim/budgets/projects" import "src/decidim/budgets/progressFixed" +import "src/decidim/budgets/exit_handler" // Images require.context("../images", true) diff --git a/decidim-budgets/app/packs/src/decidim/budgets/exit_handler.js b/decidim-budgets/app/packs/src/decidim/budgets/exit_handler.js new file mode 100644 index 0000000000000..b0c20aa2f434a --- /dev/null +++ b/decidim-budgets/app/packs/src/decidim/budgets/exit_handler.js @@ -0,0 +1,100 @@ +const currentAllocationZero = () => { + const $budgetSummary = $(".budget-summary__progressbox"); + return parseInt($budgetSummary.attr("data-current-allocation"), 10) === 0; +} + +const isSafeUrl = (exitUrl) => { + if (!exitUrl) { + return false + } + + const safeUrls = [ + $(".budget-summary").attr("data-safe-url").split("?")[0], + `${location.pathname}#`, + `${location.href}#`, + "#" + ]; + + let safe = false; + safeUrls.forEach((url) => { + if (exitUrl.startsWith(url)) { + safe = true + } + }); + + return safe; +} + +const allowExitFrom = ($el) => { + if (currentAllocationZero()) { + return true + } else if ($el.attr("target") === "_blank") { + return true; + } else if ($el.parents("#loginModal").length > 0) { + return true; + } else if ($el.parents("#authorizationModal").length > 0) { + return true; + } else if ($el.attr("id") === "exit-notification-link") { + return true; + } else if ($el.parents(".voting-wrapper").length > 0) { + return true; + } else if (isSafeUrl($el.attr("href"))) { + return true + } + + return false; +} + +$(() => { + const $exitNotification = $("#exit-notification"); + const $exitLink = $("#exit-notification-link"); + const defaultExitUrl = $exitLink.attr("href"); + const defaultExitLinkText = $exitLink.text(); + let exitLinkText = defaultExitLinkText; + + if ($exitNotification.length < 1) { + // Do not apply when not inside the voting pipeline + return; + } + + const openExitNotification = (url, method = null) => { + if (method && method !== "get") { + $exitLink.attr("data-method", method); + } else { + $exitLink.removeAttr("data-method"); + } + + $exitLink.attr("href", url); + $exitLink.html(exitLinkText); + $exitNotification.foundation("open"); + }; + + $(document).on("click", "a", (event) => { + exitLinkText = defaultExitLinkText; + + const $link = $(event.currentTarget); + if (!allowExitFrom($link)) { + event.preventDefault(); + openExitNotification($link.attr("href"), $link.data("method")); + } + }); + // Custom handling for the header sign out so that it won't trigger the + // logout form submit and so that it changes the exit link text. This does + // not trigger the document link click listener because it has the + // data-method attribute to trigger a form submit event. + $(".header a.sign-out-link").on("click", (event) => { + event.preventDefault(); + event.stopPropagation(); + + const $link = $(event.currentTarget); + exitLinkText = $link.text(); + openExitNotification($link.attr("href"), $link.data("method")); + }); + // Custom handling for the exit link which needs to change the exit link + // text to the default text as this is not handled by the document click + // listener. + $("a[data-open='exit-notification']").on("click", () => { + exitLinkText = defaultExitLinkText; + openExitNotification(defaultExitUrl); + }); +}); diff --git a/decidim-budgets/app/packs/src/decidim/budgets/projects.js b/decidim-budgets/app/packs/src/decidim/budgets/projects.js index 00f4f8a9b45c3..a73d2141bdd65 100644 --- a/decidim-budgets/app/packs/src/decidim/budgets/projects.js +++ b/decidim-budgets/app/packs/src/decidim/budgets/projects.js @@ -3,28 +3,28 @@ $(() => { const $budgetSummaryTotal = $(".budget-summary__total"); const $budgetExceedModal = $("#budget-excess"); const $budgetSummary = $(".budget-summary__progressbox"); + const $voteButton = $(".budget-vote-button"); const totalAllocation = parseInt($budgetSummaryTotal.attr("data-total-allocation"), 10); const cancelEvent = (event) => { + $(event.currentTarget).removeClass("loading-spinner"); event.stopPropagation(); event.preventDefault(); }; - const allowExitFrom = ($el) => { - if ($el.parents("#loginModal").length > 0) { - return true; - } else if ($el.parents("#authorizationModal").length > 0) { - return true; - } - - return false; - } + $voteButton.on("click", "span", () => { + $(".budget-list__action").click(); + }); $projects.on("click", ".budget-list__action", (event) => { const currentAllocation = parseInt($budgetSummary.attr("data-current-allocation"), 10); const $currentTarget = $(event.currentTarget); const projectAllocation = parseInt($currentTarget.attr("data-allocation"), 10); + if (!$currentTarget.attr("data-open")) { + $currentTarget.addClass("loading-spinner"); + } + if ($currentTarget.attr("disabled")) { cancelEvent(event); } else if (($currentTarget.attr("data-add") === "true") && ((currentAllocation + projectAllocation) > totalAllocation)) { @@ -32,34 +32,4 @@ $(() => { cancelEvent(event); } }); - - if ($("#order-progress [data-toggle=budget-confirm]").length > 0) { - const safeUrl = $(".budget-summary").attr("data-safe-url").split("?")[0]; - $(document).on("click", "a", (event) => { - if (allowExitFrom($(event.currentTarget))) { - window.exitUrl = null; - } else { - window.exitUrl = event.currentTarget.href; - } - }); - $(document).on("submit", "form", (event) => { - if (allowExitFrom($(event.currentTarget))) { - window.exitUrl = null; - } else { - window.exitUrl = event.currentTarget.action; - } - }); - - window.addEventListener("beforeunload", (event) => { - const currentAllocation = parseInt($budgetSummary.attr("data-current-allocation"), 10); - const exitUrl = window.exitUrl; - window.exitUrl = null; - - if (currentAllocation === 0 || (exitUrl && exitUrl.startsWith(safeUrl))) { - return; - } - - event.returnValue = true; - }); - } }); diff --git a/decidim-budgets/app/packs/stylesheets/decidim/budgets/budget/_budget-list.scss b/decidim-budgets/app/packs/stylesheets/decidim/budgets/budget/_budget-list.scss index 9e76d1f8f9fa4..bfe6c4a1fbc25 100644 --- a/decidim-budgets/app/packs/stylesheets/decidim/budgets/budget/_budget-list.scss +++ b/decidim-budgets/app/packs/stylesheets/decidim/budgets/budget/_budget-list.scss @@ -19,6 +19,26 @@ border-bottom-right-radius: $card-border-radius; border-bottom: $border; } + + &-cell{ + display: grid; + grid-template-columns: 1fr 40px; + + .budget-list__data{ + grid-column: span 2; + background: none; + } + + @include breakpoint(medium){ + grid-template-columns: 1fr 40px 15em; + grid-template-rows: 1fr; + + .budget-list__data{ + background: $card-secondary-bg; + grid-column: 3; + } + } + } } &__image{ @@ -54,6 +74,11 @@ padding: $card-padding; display: flex; align-items: center; + + &.flex-horizontal{ + flex-direction: column; + align-items: flex-start; + } } .card__text--status{ @@ -79,10 +104,19 @@ min-width: 7rem; flex-direction: row; justify-content: flex-end; - flex-basis: 12rem; + flex-basis: 14rem; padding: 1rem $card-padding; } + .loading-spinner{ + margin: 0 !important; + position: relative; + + &::before{ + position: absolute; + } + } + &:last-child{ margin-bottom: 0; } diff --git a/decidim-budgets/app/views/decidim/budgets/admin/projects/index.html.erb b/decidim-budgets/app/views/decidim/budgets/admin/projects/index.html.erb index fbdb64f4da722..10015c8207324 100644 --- a/decidim-budgets/app/views/decidim/budgets/admin/projects/index.html.erb +++ b/decidim-budgets/app/views/decidim/budgets/admin/projects/index.html.erb @@ -15,24 +15,36 @@
+ <%= admin_filter_selector(:projects) %>
- - - - <%= th_resource_scope_label %> + + + <%= th_scope_sort_link %> + + <% projects.each do |project| %> + + + <%= td_resource_scope_for(project.scope) %> @@ -43,7 +55,6 @@ <%= content_tag :span, "×", class: "text-muted" %> <% end %> - <%= td_resource_scope_for(project.scope) %> + <%= icon "pencil" %> + <%= icon "circle-x" %> + <%= icon "pencil" %> + <%= icon "circle-x" %>
<%= t("models.project.fields.title", scope: "decidim.budgets") %><%= t("index.confirmed_orders_count") %><%= t(".selected") %><%= sort_link(query, :id, t("models.project.fields.id", scope: "decidim.budgets"), default_order: :desc) %> + <%= sort_link(query, :title, t("models.project.fields.title", scope: "decidim.budgets")) %><%= sort_link(query, :category_name, t("models.project.fields.category", scope: "decidim.budgets") ) %><%= sort_link(query, :confirmed_orders_count, t("index.confirmed_orders_count")) %><%= sort_link(query, :selected, t(".selected")) %> <%= t("actions.title", scope: "decidim.budgets") %>
+ <%= project.id %>
+
<%= translated_attribute(project.title) %>
+ <% if project.category %> + <%= translated_attribute project.category.name %> + <% end %> + <%= project.confirmed_orders_count %> <%= icon_link_to "eye", resource_locator([budget, project]).path, t("actions.preview", scope: "decidim.budgets"), target: :blank, class: "action-icon--preview" %> diff --git a/decidim-budgets/app/views/decidim/budgets/admin/proposals_imports/new.html.erb b/decidim-budgets/app/views/decidim/budgets/admin/proposals_imports/new.html.erb index c743fa5b2b76c..12aa8686b62f5 100644 --- a/decidim-budgets/app/views/decidim/budgets/admin/proposals_imports/new.html.erb +++ b/decidim-budgets/app/views/decidim/budgets/admin/proposals_imports/new.html.erb @@ -7,7 +7,7 @@
- <%= f.select :origin_component_id, @form.origin_components_collection, prompt: t(".select_component") %> + <%= f.select :origin_component_id, @form.origin_components_collection, prompt: t(".select_component"), label: t(".origin_component_id") %>
<% if current_component.scopes_enabled? %>
@@ -15,10 +15,10 @@
<% end %>
- <%= f.number_field :default_budget %> + <%= f.number_field :default_budget, label: t(".default_budget") %>
- <%= f.check_box :import_all_accepted_proposals %> + <%= f.check_box :import_all_accepted_proposals, label: t(".import_all_accepted_proposals") %>
diff --git a/decidim-budgets/app/views/decidim/budgets/projects/_budget_summary.html.erb b/decidim-budgets/app/views/decidim/budgets/projects/_budget_summary.html.erb index 60db9a5412ea8..c465b51d242bd 100644 --- a/decidim-budgets/app/views/decidim/budgets/projects/_budget_summary.html.erb +++ b/decidim-budgets/app/views/decidim/budgets/projects/_budget_summary.html.erb @@ -2,9 +2,9 @@
-

+

<%= t(".rules.title") %> -

+
    <%= raw current_rule_explanation %>
@@ -16,23 +16,23 @@
<% if include_heading %> <% if current_order_checked_out? %> -

+

<%= t(".checked_out.title") %> <% unless current_workflow.single? %> <%= translated_attribute(budget.title) %> <% end %> -

+

<%= raw t(".checked_out.description", cancel_link: link_to(t(".cancel_order"), budget_order_path(return_to: "budget"), method: :delete, class: "cancel-order", data: { confirm: t(".are_you_sure") })) %>

<% else %> -

+

<% if current_workflow.single? %> <%= t(".title") %> <% else %> <%= translated_attribute(budget.title) %> <% end %> -

+

<%= raw current_rule_description %>

diff --git a/decidim-budgets/app/views/decidim/budgets/projects/_exit_modal.html.erb b/decidim-budgets/app/views/decidim/budgets/projects/_exit_modal.html.erb new file mode 100644 index 0000000000000..378368a0ba408 --- /dev/null +++ b/decidim-budgets/app/views/decidim/budgets/projects/_exit_modal.html.erb @@ -0,0 +1,22 @@ +<% if current_user && current_component.current_settings.votes == "enabled" && !current_workflow.voted?(budget) %> + +<% end %> diff --git a/decidim-budgets/app/views/decidim/budgets/projects/_filters_small_view.html.erb b/decidim-budgets/app/views/decidim/budgets/projects/_filters_small_view.html.erb index 07947e889cafb..68eaa97ecf370 100644 --- a/decidim-budgets/app/views/decidim/budgets/projects/_filters_small_view.html.erb +++ b/decidim-budgets/app/views/decidim/budgets/projects/_filters_small_view.html.erb @@ -1,13 +1,13 @@
-
-
+
- <%= present(meeting).title %>
+ <%= present(meeting).title(html_escape: true) %>
<% if meeting.start_time %> diff --git a/decidim-meetings/app/views/decidim/meetings/directory/meetings/_filters.html.erb b/decidim-meetings/app/views/decidim/meetings/directory/meetings/_filters.html.erb new file mode 100644 index 0000000000000..0280c870a46d6 --- /dev/null +++ b/decidim-meetings/app/views/decidim/meetings/directory/meetings/_filters.html.erb @@ -0,0 +1,34 @@ +<%= render partial: "decidim/shared/filter_form_help", locals: { skip_to_id: "meetings" } %> + +<%= filter_form_for filter do |form| %> +
+ +
+ + <% unless @forced_past_meetings %> + <%= form.collection_radio_buttons :date, filter_date_values, :first, :last, legend_title: t("decidim.meetings.meetings.filters.date") %> + <% end %> + + <%= form.check_boxes_tree :type, filter_type_values, legend_title: t("decidim.meetings.meetings.filters.type") %> + + <%= form.check_boxes_tree :scope_id, directory_filter_scopes_values, legend_title: t("decidim.meetings.meetings.filters.scope") %> + + <%= form.check_boxes_tree :category_id, directory_filter_categories_values, legend_title: t("decidim.meetings.meetings.filters.category") %> + + <%= form.check_boxes_tree :origin, directory_filter_origin_values, legend_title: t("decidim.meetings.meetings.filters.origin") %> + + <%= form.check_boxes_tree :space, directory_meeting_spaces_values, legend_title: t("decidim.meetings.directory.meetings.index.space_type") %> + + <% if current_user %> + <%= form.collection_radio_buttons :activity, activity_filter_values, :first, :last, { legend_title: t("decidim.meetings.meetings.filters.activity") }, "aria-controls": "meetings" %> + <% end %> +<% end %> diff --git a/decidim-meetings/app/views/decidim/meetings/directory/meetings/index.html.erb b/decidim-meetings/app/views/decidim/meetings/directory/meetings/index.html.erb index 6a1730fc1c1d5..848406aeb84dd 100644 --- a/decidim-meetings/app/views/decidim/meetings/directory/meetings/index.html.erb +++ b/decidim-meetings/app/views/decidim/meetings/directory/meetings/index.html.erb @@ -10,24 +10,7 @@
- <%= render partial: "decidim/shared/filter_form_help", locals: { skip_to_id: "meetings" } %> - <%= filter_form_for filter, meetings_directory.root_path do |form| %> -
- -
- - <%= form.collection_radio_buttons :date, [["upcoming", t(".upcoming")], ["past", t(".past")]], :first, :last, legend_title: t(".date") %> - <%= form.collection_radio_buttons :space, @meeting_spaces, :first, :last, legend_title: t(".space_type") %> - <% end %> + <%= render partial: "filters" %>
diff --git a/decidim-meetings/app/views/decidim/meetings/layouts/live_event.html.erb b/decidim-meetings/app/views/decidim/meetings/layouts/live_event.html.erb index b5a0bde0801c6..61a86d078c066 100644 --- a/decidim-meetings/app/views/decidim/meetings/layouts/live_event.html.erb +++ b/decidim-meetings/app/views/decidim/meetings/layouts/live_event.html.erb @@ -8,6 +8,7 @@ + <%= render partial: "layouts/decidim/timeout_modal" %>
<% if current_user && poll %>
diff --git a/decidim-meetings/app/views/decidim/meetings/meetings/_filters.html.erb b/decidim-meetings/app/views/decidim/meetings/meetings/_filters.html.erb index 9d137c03d4550..ee7121455ad87 100644 --- a/decidim-meetings/app/views/decidim/meetings/meetings/_filters.html.erb +++ b/decidim-meetings/app/views/decidim/meetings/meetings/_filters.html.erb @@ -14,8 +14,10 @@
+ <%= form.hidden_field "state", value: params.dig("filter", "state") %> + <% unless @forced_past_meetings %> - <%= form.check_boxes_tree :date, filter_date_values, legend_title: t(".date") %> + <%= form.collection_radio_buttons :date, filter_date_values, :first, :last, legend_title: t(".date") %> <% end %> <%= form.check_boxes_tree :type, filter_type_values, legend_title: t(".type") %> diff --git a/decidim-meetings/app/views/decidim/meetings/meetings/_filters_small_view.html.erb b/decidim-meetings/app/views/decidim/meetings/meetings/_filters_small_view.html.erb index 07947e889cafb..68eaa97ecf370 100644 --- a/decidim-meetings/app/views/decidim/meetings/meetings/_filters_small_view.html.erb +++ b/decidim-meetings/app/views/decidim/meetings/meetings/_filters_small_view.html.erb @@ -1,13 +1,13 @@
-
-
+
diff --git a/decidim-meetings/app/views/decidim/meetings/meetings/_meetings.html.erb b/decidim-meetings/app/views/decidim/meetings/meetings/_meetings.html.erb index c4881acb25d91..b64145ced68e5 100644 --- a/decidim-meetings/app/views/decidim/meetings/meetings/_meetings.html.erb +++ b/decidim-meetings/app/views/decidim/meetings/meetings/_meetings.html.erb @@ -1,3 +1,11 @@ +<% if params.dig("filter", "state").present? && params["filter"]["state"] == "withdrawn" %> +
+ <%= t("decidim.meetings.meetings.index.text_banner", + go_back_link: link_to(t("decidim.meetings.meetings.index.click_here"), meetings_path("filter[state]" => nil)), + ).html_safe %> +
+<% end %> + <% if @forced_past_meetings %>
<%= t ".upcoming_meetings_warning" %> @@ -23,3 +31,13 @@ <% end %>
<%= decidim_paginate meetings, order_start_time: params[:order_start_time], scope_id: params[:scope_id] %> + +
+
+ <% if params.dig("filter", "state").present? && params["filter"]["state"] == "withdrawn" %> + <%= link_to t("decidim.meetings.meetings.index.see_all"), meetings_path("filter[state]" => nil) %> + <% else %> + <%= link_to t("decidim.meetings.meetings.index.see_all_withdrawn"), meetings_path("filter[state]" => "withdrawn") %> + <% end %> +
+
diff --git a/decidim-meetings/app/views/decidim/meetings/meetings/index.html.erb b/decidim-meetings/app/views/decidim/meetings/meetings/index.html.erb index a14e74ed25328..c4db8b10ac063 100644 --- a/decidim-meetings/app/views/decidim/meetings/meetings/index.html.erb +++ b/decidim-meetings/app/views/decidim/meetings/meetings/index.html.erb @@ -6,9 +6,9 @@
-

+

<%= render partial: "count" %> -

+ <% if allowed_to?(:create, :meeting) %> <%= action_authorized_link_to :create, new_meeting_path, class: "title-action__action button small", data: { "redirect_url" => new_meeting_path } do %> @@ -27,6 +27,7 @@
+ <%= render partial: "meetings" %>
diff --git a/decidim-meetings/app/views/decidim/meetings/meetings/index.js.erb b/decidim-meetings/app/views/decidim/meetings/meetings/index.js.erb index f0a3a09e4a202..a7588f69add44 100644 --- a/decidim-meetings/app/views/decidim/meetings/meetings/index.js.erb +++ b/decidim-meetings/app/views/decidim/meetings/meetings/index.js.erb @@ -1,12 +1,18 @@ var $meetings = $('#meetings'); var $meetingsCount = $('#meetings-count'); +// make sure that calendar modal will use the updated filter values +var $calendarShare = $('#calendarShare'); +$calendarShare.remove(); + $meetings.html('<%= j(render partial: "meetings").strip.html_safe %>'); $meetingsCount.html('<%= j(render partial: "count").strip.html_safe %>'); var $dropdownMenu = $('.dropdown.menu', $meetings); $dropdownMenu.foundation(); +$("#calendarShare").foundation(); // initialize export calendar on the page + var markerData = JSON.parse('<%= escape_javascript meetings_data_for_map(search.results.select(&:geocoded_and_valid?)).to_json.html_safe %>'); var $map = $("#map"); diff --git a/decidim-meetings/app/views/decidim/meetings/meetings/show.html.erb b/decidim-meetings/app/views/decidim/meetings/meetings/show.html.erb index 38b0fc6a69993..55855f8bba916 100644 --- a/decidim-meetings/app/views/decidim/meetings/meetings/show.html.erb +++ b/decidim-meetings/app/views/decidim/meetings/meetings/show.html.erb @@ -17,7 +17,7 @@ edit_link(
- <%= link_to meetings_path(filter_link_params), class: "small hollow" do %> + <%= link_to meetings_path, class: "small hollow js-back-to-list" do %> <%= icon "chevron-left", class: "icon--small", role: "img", "aria-hidden": true %> <%= t(".back") %> <% end %> @@ -37,7 +37,8 @@ edit_link( <% end %> <% if allowed_to?(:close, :meeting, meeting: meeting) %> - <%= link_to t(".close_meeting"), edit_meeting_meeting_close_path(meeting_id: meeting.id, id: meeting.id), class: "button hollow expanded button-sc button--icon follow-button" %> + <% caption = meeting.closed? ? t(".edit_close_meeting") : t(".close_meeting") %> + <%= link_to caption, edit_meeting_meeting_close_path(meeting_id: meeting.id, id: meeting.id), class: "button hollow expanded button-sc button--icon follow-button" %> <% end %>
@@ -118,13 +119,18 @@ edit_link( <%= t("transparent", scope: "decidim.meetings.types") %> <% end %> + <% if meeting.withdrawn? %> + label proposal-status"> + <%= t("withdraw", scope: "decidim.meetings.types") %> + + <% end %> <%= render_meeting_body(@meeting) %> <% if meeting.maps_enabled? && !meeting.online_meeting? %> <%= render partial: "decidim/shared/static_map", locals: { icon_name: "meetings", geolocalizable: meeting } %> <% end %> - <% unless meeting.in_person_meeting? %> + <% unless meeting.in_person_meeting? || meeting.withdrawn? %> <%= cell "decidim/meetings/online_meeting_link", meeting %> <% end %> @@ -156,7 +162,7 @@ edit_link( <% if meeting.closed? && meeting.closing_visible? %>

<%= t(".meeting_minutes") %>

- <%= decidim_sanitize translated_attribute meeting.closing_report %> + <%= decidim_sanitize_editor translated_attribute meeting.closing_report %>
<% end %> diff --git a/decidim-meetings/config/locales/ar.yml b/decidim-meetings/config/locales/ar.yml index cbb578cb6efa6..e1303e2b1eb2a 100644 --- a/decidim-meetings/config/locales/ar.yml +++ b/decidim-meetings/config/locales/ar.yml @@ -31,10 +31,6 @@ ar: transparent: شفاف errors: models: - meeting: - attributes: - show_embedded_iframe: - not_embeddable: لا يمكن تضمين هذا الرابط meeting_agenda: attributes: base: @@ -257,7 +253,6 @@ ar: update: تحديث form: registration_email_help: سيظهر هذا النص في منتصف البريد الإلكتروني الخاص بتأكيد التسجيل مباشرة بعد رمز التسجيل. - show_embedded_iframe_help: سواء تم تضمين أو عدم تضمين الإطار iframe لعنوان الرابط URL الخاص بمؤتمر الفيديو. تسمح بعض الخِدْمَات فقط بتضمينه (مثل Youtube، Twitch...) index: title: اجتماعات new: @@ -318,23 +313,21 @@ ar: value_types: organizer_presenter: not_found: 'لم يتم العثور على المنظم في قاعدة البيانات (المعرف: %{id})' + application_helper: + filter_category_values: + all: الكل calendar_modal: calendar_url: العنوان الشبكي للتقويم close_window: أغلق النافذة export_calendar: تصدير التقويم conference_venues: أماكن المؤتمر content_blocks: - upcoming_events: - name: الأحداث القادمة - upcoming_events: الاجتماعات القادمة - view_all_events: عرض الكل + upcoming_meetings: + view_all_meetings: عرض الكل directory: meetings: index: - all: الكل - date: تاريخ meetings: اجتماعات - search: بحث space_type: الفضاء التشاركي last_activity: new_meeting_at_html: "اجتماع جديد في %{link}" @@ -361,7 +354,6 @@ ar: unfold: كشف form: select_a_category: يُرجى اختيار فئة - show_embedded_iframe_help: سواء تم تضمين أو عدم تضمين الإطار iframe لعنوان الرابط URL الخاص بمؤتمر الفيديو. تسمح بعض الخِدْمَات فقط بتضمينه (مثل Youtube، Twitch...) meeting_minutes: related_information: معلومات ذات صله meetings: diff --git a/decidim-meetings/config/locales/ca.yml b/decidim-meetings/config/locales/ca.yml index 8a8a99620f26f..344a399babedc 100644 --- a/decidim-meetings/config/locales/ca.yml +++ b/decidim-meetings/config/locales/ca.yml @@ -44,8 +44,8 @@ ca: models: meeting: attributes: - show_embedded_iframe: - not_embeddable: Aquest URL no es pot incrustar + iframe_embed_type: + not_embeddable: Aquesta adreça URL no es pot incrustar a la pàgina de la trobada o de l'esdeveniment en directe meeting_agenda: attributes: base: @@ -100,7 +100,7 @@ ca: type_eq: label: Tipus de trobada values: - hybrid: Ambdues + hybrid: Híbrida in_person: Presencial online: En línia meeting_copies: @@ -184,7 +184,7 @@ ca: notification_title: La trobada %{resource_title} començarà en menys de 48 hores. forms: meetings: - attendees_count_help_text: No oblidis incloure el nombre total d'assistents a la teva trobada, ja sigui presencial, en línia o híbrida. + attendees_count_help_text: No t'oblidis d'afegir el número total d'assistents a la trobada, sigui presencial, en línia o híbrida. gamification: badges: attended_meetings: @@ -312,7 +312,8 @@ ca: registration_url_help: 'Enllaç: permetre a les participants anar al servei extern que estàs utilitzant per a les inscripcions' select_a_meeting_type: Si us plau selecciona un tipus de trobada select_a_registration_type: Si us plau selecciona un tipus d'inscripció - show_embedded_iframe_help: Incrustar o no un iframe per a aquesta URL de videoconferència. Només alguns serveis permeten la incrustació (per exemple, Youtube, Twitch, etc.) + select_an_iframe_access_level: Si us plau, selecciona el nivell d'accés a l'iframe + show_embedded_iframe_help: Només uns quants serveis es poden incrustar a una trobada o esdeveniment en directe (YouTube, Twitch i Jitsi) index: title: Trobades new: @@ -382,26 +383,37 @@ ca: value_types: organizer_presenter: not_found: 'L''organitzador no s''ha trobat a la base de dades (identificació: %{id})' + application_helper: + filter_category_values: + all: Totes + filter_meeting_space_values: + all: Totes + filter_scope_values: + all: Totes calendar_modal: calendar_url: URL del calendari close_window: Tanca la finestra export_calendar: Exporta el calendari conference_venues: Seus de les jornades content_blocks: - upcoming_events: - name: Propers trobades - upcoming_events: Properes trobades - view_all_events: Veure-ho tot + upcoming_meetings: + name: Properes trobades + upcoming_meetings: Properes trobades + view_all_meetings: Veure-ho tot directory: meetings: index: - all: Totes - date: Data meetings: Trobades - past: Passades - search: Cerca space_type: Espai participatiu - upcoming: Properes + iframe_access_level: + all: Totes les visites + registered: Participants inscrites a aquesta trobada + signed_in: Només participants registrades + iframe_embed_type: + embed_in_meeting_page: Incrustar a la pàgina de la trobada + none: Cap + open_in_live_event_page: Obrir a la pàgina de l'esdeveniment en directe (amb opció d'enquestes) + open_in_new_tab: Obrir en una nova pestanya last_activity: meeting_updated_at_html: "Trobada actualitzada el %{link}" new_meeting_at_html: "Nova trobada a %{link}" @@ -464,7 +476,7 @@ ca: type: Tipus type_values: all: Totes - hybrid: Ambdues + hybrid: Híbrida in_person: Presencial online: En línia filters_small_view: @@ -484,9 +496,14 @@ ca: select_a_category: Si us plau, selecciona una categoria select_a_meeting_type: Si us plau selecciona un tipus de trobada select_a_registration_type: Si us plau selecciona un tipus d'inscripció - show_embedded_iframe_help: Incrustar o no un iframe per a aquesta URL de videoconferència. Només alguns serveis permeten la incrustació (per exemple, Youtube, Twitch, etc.) + select_an_iframe_access_level: Si us plau, selecciona el nivell d'accés a l'iframe + show_embedded_iframe_help: Només uns quants serveis es poden incrustar a una trobada o esdeveniment en directe (YouTube, Twitch i Jitsi) index: + click_here: Veure totes les trobades new_meeting: Nova trobada + see_all: Veure totes les trobades + see_all_withdrawn: Veure totes les trobades cancel·lades + text_banner: Estàs veient un llistat de trobades cancel·lades per les seves autores. %{go_back_link}. meeting_minutes: related_information: Informació relacionada meetings: @@ -505,6 +522,7 @@ ca: close_meeting: Tancar trobada contributions: Nombre d'aportacions date: Data + edit_close_meeting: Editeu l'informe de la reunió edit_meeting: Editar la trobada going: T'has inscrit en aquesta trobada join: Unir-se a la trobada @@ -526,6 +544,9 @@ ca: other: "%{count} places restants" view: Veure visit_finished: Veure trobada passada + withdraw_btn_hint: Pots cancel·lar la teva trobada si canvies de parer. La trobada no s'elimina, apareixerà al llistat de trobades cancel·lades. + withdraw_confirmation_html: Segur que vols cancel·lar aquesta trobada?

Aquesta acció no es pot desfer! + withdraw_meeting: Cancel·lar trobada update: invalid: Hi ha hagut un problema en actualitzar aquesta trobada. success: Has actualitzat la trobada amb èxit. @@ -546,7 +567,7 @@ ca: fields: closed: Tancada end_time: Data de finalització - id: Id + id: ID map: Mapa official_meeting: Trobada oficial start_time: Data d'inici @@ -597,14 +618,18 @@ ca: invalid: S'ha produït un error en abandonar aquesta trobada. success: Has abandonat la trobada amb èxit. type_of_meeting: - hybrid: Ambdues + hybrid: Híbrida in_person: Presencial online: Online types: private_meeting: Trobada privada transparent: Transparent + withdraw: Cancel·lada versions: back_to_resource: Tornar a la trobada + withdraw: + error: S'ha produït un error al cancel·lar la trobada + success: La trobada s'ha cancel·lat correctament metrics: meetings: description: Nombre de trobades creades diff --git a/decidim-meetings/config/locales/cs.yml b/decidim-meetings/config/locales/cs.yml index 72dd62c0b6adc..a6802a59f410e 100644 --- a/decidim-meetings/config/locales/cs.yml +++ b/decidim-meetings/config/locales/cs.yml @@ -35,7 +35,7 @@ cs: registration_terms: Podmínky registrace registration_url: URL registrace registrations_enabled: Registrace povoleny - show_embedded_iframe: Zobrazit vloženou iframe pro tuto URL + show_embedded_iframe: Zobrazit vložený iframe pro tuto URL start_time: Čas zahájení title: Název transparent: Transparentní @@ -44,8 +44,8 @@ cs: models: meeting: attributes: - show_embedded_iframe: - not_embeddable: Tato adresa URL nemůže být vložena + iframe_embed_type: + not_embeddable: Tato adresa URL nemůže být vložena do stránky schůzky nebo živé události meeting_agenda: attributes: base: @@ -106,7 +106,7 @@ cs: type_eq: label: Typ schůzky values: - hybrid: Obojí + hybrid: Hybridní in_person: Osobně online: Online meeting_copies: @@ -164,7 +164,7 @@ cs: meeting_registration_confirmed: notification_title: Vaše registrace pro schůzku %{resource_title} byla potvrzena. Váš registrační kód je %{registration_code}. meeting_registrations_over_percentage: - email_intro: Počet schůzek obsazených schůzem "%{resource_title}" je vyšší než %{percentage}%. + email_intro: Přidělených míst pro schůzku "%{resource_title}" je více než %{percentage}%. email_outro: Toto oznámení jste obdrželi, protože jste administrátor participačního prostoru schůzky. email_subject: Schůzky obsazené schůzkou "%{resource_title}" jsou nad %{percentage}% notification_title: Počet obsazených slotů %{resource_title} je vyšší než %{percentage}%. @@ -190,7 +190,7 @@ cs: notification_title: Setkání %{resource_title} bude zahájeno za méně než 48 hodin. forms: meetings: - attendees_count_help_text: Nezapomeňte uvést celkový počet účastníků vaší akce. Ať už jde o osobní, kombinovanou nebo on-line, je důležité, abychom věděli, kolik lidí je zapojeno. + attendees_count_help_text: Nezapomeňte uvést celkový počet účastníků na vaší schůzce, ať už osobní, online nebo smíšené. gamification: badges: attended_meetings: @@ -228,7 +228,7 @@ cs: agenda_item: add_agenda_item_child: Přidání položky agendy dítěte agenda_item: Položka agendy - agenda_item_children: Agenda Item Childs + agenda_item_children: Dílčí body programu down: Dolů remove: Odstranit up: Nahoru @@ -322,7 +322,8 @@ cs: registration_url_help: 'Odkaz: umožnit účastníkům jít na externí službu, kterou používáte pro registrace' select_a_meeting_type: Vyberte prosím typ schůzky select_a_registration_type: Vyberte prosím typ registrace - show_embedded_iframe_help: Rozhodněte o vložení URL iframe pro tuto videokonferenci. Pouze některé služby umožňují vložení (např. Youtube, Twitch...) + select_an_iframe_access_level: Vyberte prosím úroveň přístupu iframe + show_embedded_iframe_help: Pouze pár služeb umožňuje vložení do schůzky nebo živé události (YouTube, Twitch a Jitsi) index: title: Setkání new: @@ -394,26 +395,37 @@ cs: value_types: organizer_presenter: not_found: 'Organizátor nebyl nalezen v databázi (ID: %{id})' + application_helper: + filter_category_values: + all: Vše + filter_meeting_space_values: + all: Vše + filter_scope_values: + all: Vše calendar_modal: calendar_url: Adresa URL kalendáře close_window: Zavřete okno export_calendar: Exportovat kalendář conference_venues: Konferenční prostory content_blocks: - upcoming_events: - name: Připravované akce - upcoming_events: Nadcházející schůzky - view_all_events: Zobrazit vše + upcoming_meetings: + name: Nadcházející schůzky + upcoming_meetings: Nadcházející schůzky + view_all_meetings: Zobrazit vše directory: meetings: index: - all: Vše - date: Datum meetings: Setkání - past: Minulé - search: Vyhledávání space_type: Účastní prostor - upcoming: Nadcházející + iframe_access_level: + all: Všichni návštěvníci + registered: Registrovaní účastníci této schůzky + signed_in: Pouze přihlášení účastníci + iframe_embed_type: + embed_in_meeting_page: Vložit do stránky schůzky + none: Žádný + open_in_live_event_page: Otevřít na stránce živé události (s volitelnými anketami) + open_in_new_tab: Otevřít URL v nové kartě last_activity: meeting_updated_at_html: "Schůzka aktualizována na %{link}" new_meeting_at_html: "Nové setkání v %{link}" @@ -478,7 +490,7 @@ cs: type: Typ type_values: all: Vše - hybrid: Obojí + hybrid: Hybridní in_person: Osobně online: Online filters_small_view: @@ -498,9 +510,14 @@ cs: select_a_category: Vyberte prosím kategorii select_a_meeting_type: Vyberte prosím typ schůzky select_a_registration_type: Vyberte prosím typ registrace - show_embedded_iframe_help: Rozhodněte o vložení URL iframe pro tuto videokonferenci. Pouze některé služby umožňují vložení (např. Youtube, Twitch...) + select_an_iframe_access_level: Vyberte prosím úroveň přístupu iframe + show_embedded_iframe_help: Pouze pár služeb umožňuje vložení do schůzky nebo živé události (YouTube, Twitch a Jitsi) index: + click_here: Zobrazit všechny schůzky new_meeting: Nová schůzka + see_all: Zobrazit všechny schůzky + see_all_withdrawn: Zobrazit všechny stažené schůzky + text_banner: Zobrazujete seznam schůzek stažených jejich autory. %{go_back_link}. meeting_minutes: related_information: Související informace meetings: @@ -519,6 +536,7 @@ cs: close_meeting: Ukončit schůzku contributions: Počet příspěvků date: Datum + edit_close_meeting: Upravit zprávu schůzky edit_meeting: Upravit schůzku going: Přihlásili jste se k této schůzce join: Připojte se k setkání @@ -542,6 +560,9 @@ cs: other: "%{count} zbývajících bloků" view: Zobrazit visit_finished: Zobrazit minulou schůzku + withdraw_btn_hint: Schůzku můžete stáhnout, pokud změníte názor. Schůzka není smazána, objeví se v seznamu stažených schůzek. + withdraw_confirmation_html: Opravdu chcete tuto schůzku stáhnout?

Tuto akci nelze zrušit! + withdraw_meeting: Stažení schůzky update: invalid: Při aktualizaci schůzky došlo k chybě. success: Úspěšně jste aktualizovali schůzku. @@ -562,7 +583,7 @@ cs: fields: closed: Zavřeno end_time: Datum ukončení - id: Id + id: ID map: Mapa official_meeting: Oficiální schůzka start_time: Datum zahájení @@ -575,7 +596,7 @@ cs: empty_questions: Během této schůzky budou zaslány některé dotazy a vy na ně budete moci odpovědět. Zobrazí se zde. index_admin: admin_dashboard: Řídicí panel administrace - edit: Upravit v administraci + edit: Upravit v panelu administrace question: Otázka received_answer: přijatá odpověď received_answers: přijaté odpovědi @@ -615,14 +636,18 @@ cs: invalid: Při setkání došlo k problému. success: Zasedání jste úspěšně opustili. type_of_meeting: - hybrid: Obojí + hybrid: Hybridní in_person: Osobně online: Online types: private_meeting: Privátní setkání transparent: Průhledný + withdraw: Staženo versions: back_to_resource: Přejít zpět na schůzku + withdraw: + error: Došlo k chybě při stahování schůzky + success: Schůzka byla úspěšně stažena metrics: meetings: description: Počet vytvořených schůzek diff --git a/decidim-meetings/config/locales/de.yml b/decidim-meetings/config/locales/de.yml index 0edd4edd1acbe..8988b0303014f 100644 --- a/decidim-meetings/config/locales/de.yml +++ b/decidim-meetings/config/locales/de.yml @@ -42,10 +42,6 @@ de: type_of_meeting: Art errors: models: - meeting: - attributes: - show_embedded_iframe: - not_embeddable: Diese URL kann nicht eingebettet werden meeting_agenda: attributes: base: @@ -100,7 +96,7 @@ de: type_eq: label: Art des Treffens values: - hybrid: Beides + hybrid: Hybrid in_person: Persönlich online: Online meeting_copies: @@ -184,7 +180,7 @@ de: notification_title: Die Sitzung %{resource_title} beginnt in weniger als 48 Stunden. forms: meetings: - attendees_count_help_text: 'Vergessen Sie nicht, die Gesamtzahl der Teilnehmer Ihrer Veranstaltung anzugeben. Ob offline, hybrid oder online: es ist wichtig, dass wir wissen, wie viele Menschen beteiligt waren.' + attendees_count_help_text: Vergessen Sie nicht, die Gesamtzahl der Teilnehmer an Ihrem Meeting anzugeben, egal ob dies persönlich, online oder hybrid stattgefunden hat. gamification: badges: attended_meetings: @@ -312,7 +308,7 @@ de: registration_url_help: 'Link: Erlaubt den Teilnehmern den externen Service zu nutzen, den Sie für die Registrierung verwenden' select_a_meeting_type: Bitte eine Meeting-Typ auswählen select_a_registration_type: Bitte wählen Sie eine Registrierungsart aus - show_embedded_iframe_help: Gibt an, ob das iFrame für diese Videokonferenz-URL eingebettet werden soll. Nur wenige Dienste erlauben das Einbetten (bspw. Youtube, Twitch...) + show_embedded_iframe_help: Nur wenige Dienste erlauben das Einbetten einer Veranstaltung oder eines Livestreams (Youtube, Twitch und Jitsi) index: title: Meetings new: @@ -379,26 +375,37 @@ de: value_types: organizer_presenter: not_found: 'Der Organisator wurde nicht in der Datenbank gefunden (ID: %{id})' + application_helper: + filter_category_values: + all: Alle + filter_meeting_space_values: + all: Alle + filter_scope_values: + all: Alle calendar_modal: calendar_url: Kalender-URL close_window: Fenster schließen export_calendar: Kalender exportieren conference_venues: Tagungsstätten content_blocks: - upcoming_events: - name: Kommende Veranstaltungen - upcoming_events: Bevorstehende Treffen - view_all_events: Alle ansehen + upcoming_meetings: + name: Bevorstehende Treffen + upcoming_meetings: Bevorstehende Treffen + view_all_meetings: Alle ansehen directory: meetings: index: - all: Alle - date: Datum meetings: Meetings - past: Vergangene - search: Suche space_type: Partizipativer Raum - upcoming: Bevorstehende + iframe_access_level: + all: Alle Besucher + registered: Registrierte Teilnehmer zu diesem Meeting + signed_in: Nur angemeldete Teilnehmer + iframe_embed_type: + embed_in_meeting_page: In Meeting-Seite einbetten + none: Keiner + open_in_live_event_page: In Live-Event-Seite öffnen (mit optionalen Umfragen) + open_in_new_tab: Link in neuem Tab öffnen last_activity: meeting_updated_at_html: "Besprechung aktualisiert unter %{link}" new_meeting_at_html: "Neues Treffen um %{link}" @@ -461,7 +468,7 @@ de: type: Art type_values: all: Alle - hybrid: Beides + hybrid: Hybrid in_person: Persönlich online: Online filters_small_view: @@ -481,9 +488,12 @@ de: select_a_category: Bitte wählen sie eine Kategorie select_a_meeting_type: Bitte eine Meeting-Art auswählen select_a_registration_type: Bitte wählen Sie eine Registrierungsart aus - show_embedded_iframe_help: Gibt an, ob das iFrame für diese Videokonferenz-URL eingebettet werden soll. Nur wenige Dienste erlauben das Einbetten (bspw. Youtube, Twitch...) + show_embedded_iframe_help: Nur wenige Dienste erlauben das Einbetten einer Veranstaltung oder eines Livestreams (Youtube, Twitch und Jitsi) index: + click_here: Alle Treffen anzeigen new_meeting: Neue Besprechung + see_all: Alle Treffen anzeigen + see_all_withdrawn: Alle zurückgezogenen Treffen ansehen meeting_minutes: related_information: Zugehörige Informationen meetings: @@ -522,6 +532,8 @@ de: other: "Noch %{count} Slots" view: Anzeigen visit_finished: Vergangene Treffen anzeigen + withdraw_btn_hint: Sie können Ihr Treffen zurückziehen, wenn Sie Ihre Meinung ändern. Das Meeting wird nicht gelöscht, es wird in der Liste der zurückgezogenen Meetings angezeigt. + withdraw_meeting: Treffen zurückziehen update: invalid: Beim Aktualisieren der Besprechung ist ein Fehler aufgetreten. success: Sie haben die Sitzung erfolgreich aktualisiert. @@ -589,14 +601,18 @@ de: invalid: Beim Verlassen dieses Meetings ist ein Problem aufgetreten. success: Sie haben das Meeting erfolgreich verlassen. type_of_meeting: - hybrid: Beides + hybrid: Hybrid in_person: In Person online: Online types: private_meeting: Private Sitzung transparent: Transparent + withdraw: Zurückgezogen versions: back_to_resource: Zurück zur Besprechung + withdraw: + error: Beim Zurückziehen des Meetings ist ein Fehler aufgetreten + success: Das Meeting wurde erfolgreich zurückgezogen metrics: meetings: description: Anzahl der erstellten Meetings diff --git a/decidim-meetings/config/locales/el.yml b/decidim-meetings/config/locales/el.yml index e32592f668d37..641787312a250 100644 --- a/decidim-meetings/config/locales/el.yml +++ b/decidim-meetings/config/locales/el.yml @@ -294,17 +294,12 @@ el: export_calendar: Εξαγωγή ημερολογίου conference_venues: Χώροι διασκέψεων content_blocks: - upcoming_events: - name: Προσεχείς εκδηλώσεις - upcoming_events: Προσεχείς συσκέψεις - view_all_events: Προβολή όλων + upcoming_meetings: + view_all_meetings: Προβολή όλων directory: meetings: index: - all: Όλα - date: Ημερομηνία meetings: Συσκέψεις - search: Αναζήτηση space_type: Χώρος συμμετοχής last_activity: new_meeting_at_html: "Νέα σύσκεψη σε %{link}" diff --git a/decidim-meetings/config/locales/en.yml b/decidim-meetings/config/locales/en.yml index fd4b96555ee86..963d11f93c00f 100644 --- a/decidim-meetings/config/locales/en.yml +++ b/decidim-meetings/config/locales/en.yml @@ -2,10 +2,6 @@ en: activemodel: attributes: - agenda: - description: Description - duration: Duration - title: Title close_meeting: attendees_count: Number of attendees attending_organizations: List of organizations that attended @@ -23,8 +19,9 @@ en: decidim_scope_id: Scope decidim_user_group_id: User group description: Description - end_time: End Time + end_time: End time id: ID + iframe_embed_type: Iframe embed type location: Location location_hints: Location hints online_meeting_url: Online meeting URL @@ -34,19 +31,32 @@ en: registration_email_custom_content: Registration email custom content registration_form_enabled: Registration form enabled registration_terms: Registration terms + registration_type: Registration type registration_url: Registration URL registrations_enabled: Registrations enabled - show_embedded_iframe: Show embedded iframe for this URL - start_time: Start Time + reserved_slots: Reserved slots for this meeting + start_time: Start time title: Title transparent: Transparent type_of_meeting: Type + meeting_agenda: + title: Title + visible: Visible + meeting_agenda_items: + description: Description + duration: Duration + title: Title + meeting_registration_invite: + email: Email + name: Name + validate_registration_code: + code: Code errors: models: meeting: attributes: - show_embedded_iframe: - not_embeddable: This URL can't be embedded + iframe_embed_type: + not_embeddable: This URL can't be embedded in meeting or live event page meeting_agenda: attributes: base: @@ -101,7 +111,7 @@ en: type_eq: label: Type of meeting values: - hybrid: Both + hybrid: Hybrid in_person: In Person online: Online meeting_copies: @@ -185,7 +195,7 @@ en: notification_title: The %{resource_title} meeting will start in less than 48h. forms: meetings: - attendees_count_help_text: Don’t forget to include the total number of participants at your event. Whether in person, hybrid, or online, it’s important that we know how many people are involved. + attendees_count_help_text: Don't forget to include the total number of attendees at your meeting, whether in person, online or hybrid. gamification: badges: attended_meetings: @@ -313,7 +323,8 @@ en: registration_url_help: 'Link: allow participants to go on the external service you are using for registrations' select_a_meeting_type: Please select a meeting type select_a_registration_type: Please select a registration type - show_embedded_iframe_help: Whether or not embed the iframe for this videoconference URL. Only a few services allow embedding (i.e. Youtube, Twitch...) + select_an_iframe_access_level: Please select an iframe access level + show_embedded_iframe_help: Only a few services allow embedding in meeting or live event (YouTube, Twitch and Jitsi) index: title: Meetings new: @@ -383,26 +394,37 @@ en: value_types: organizer_presenter: not_found: 'The organizer was not found on the database (ID: %{id})' + application_helper: + filter_category_values: + all: All + filter_meeting_space_values: + all: All + filter_scope_values: + all: All calendar_modal: calendar_url: Calendar URL close_window: Close window export_calendar: Export calendar conference_venues: Conference Venues content_blocks: - upcoming_events: - name: Upcoming events - upcoming_events: Upcoming meetings - view_all_events: View all + upcoming_meetings: + name: Upcoming meetings + upcoming_meetings: Upcoming meetings + view_all_meetings: View all directory: meetings: index: - all: All - date: Date meetings: Meetings - past: Past - search: Search space_type: Participatory space - upcoming: Upcoming + iframe_access_level: + all: All visitors + registered: Registered participants to this meeting + signed_in: Only signed-in participants + iframe_embed_type: + embed_in_meeting_page: Embed in meeting page + none: None + open_in_live_event_page: Open in live event page (with optional polls) + open_in_new_tab: Open URL in a new tab last_activity: meeting_updated_at_html: "Meeting updated at %{link}" new_meeting_at_html: "New meeting at %{link}" @@ -465,7 +487,7 @@ en: type: Type type_values: all: All - hybrid: Both + hybrid: Hybrid in_person: In-person online: Online filters_small_view: @@ -485,9 +507,14 @@ en: select_a_category: Please select a category select_a_meeting_type: Please select a meeting type select_a_registration_type: Please select a registration type - show_embedded_iframe_help: Whether or not embed the iframe for this videoconference URL. Only a few services allow embedding (i.e. Youtube, Twitch...) + select_an_iframe_access_level: Please select an iframe access level + show_embedded_iframe_help: Only a few services allow embedding in meeting or live event (YouTube, Twitch and Jitsi) index: + click_here: See all meetings new_meeting: New meeting + see_all: See all meetings + see_all_withdrawn: See all withdrawn meetings + text_banner: You are viewing the list of meetings withdrawn by their authors. %{go_back_link}. meeting_minutes: related_information: Related Information meetings: @@ -506,6 +533,7 @@ en: close_meeting: Close meeting contributions: Contributions count date: Date + edit_close_meeting: Edit meeting report edit_meeting: Edit meeting going: You have signed up for this meeting join: Join meeting @@ -527,6 +555,9 @@ en: other: "%{count} slots remaining" view: View visit_finished: View past meeting + withdraw_btn_hint: You can withdraw your meeting if you change your mind. The meeting is not deleted, it will appear in the list of withdrawn meetings. + withdraw_confirmation_html: Are you sure you want to withdraw this meeting?

This action cannot be cancelled! + withdraw_meeting: Withdraw meeting update: invalid: There was a problem updating the meeting. success: You have updated the meeting successfully. @@ -547,7 +578,7 @@ en: fields: closed: Closed end_time: End date - id: Id + id: ID map: Map official_meeting: Official meeting start_time: Start date @@ -560,7 +591,7 @@ en: empty_questions: Throughout this meeting, some questions will be sent and you will be able to answer them. They will be displayed here. index_admin: admin_dashboard: Administrator dashboard - edit: Edit in the admin + edit: Edit in the admin panel question: Question received_answer: received answer received_answers: received answers @@ -598,14 +629,18 @@ en: invalid: There was a problem leaving this meeting. success: You have left the meeting successfully. type_of_meeting: - hybrid: Both + hybrid: Hybrid in_person: In person online: Online types: private_meeting: Private meeting transparent: Transparent + withdraw: Withdrawn versions: back_to_resource: Go back to meeting + withdraw: + error: An error ocurred while withdrawing the meeting + success: The meeting has been withdrawn successfully metrics: meetings: description: Number of meetings created diff --git a/decidim-meetings/config/locales/es-MX.yml b/decidim-meetings/config/locales/es-MX.yml index a91c598673601..1bb79667f19dd 100644 --- a/decidim-meetings/config/locales/es-MX.yml +++ b/decidim-meetings/config/locales/es-MX.yml @@ -44,8 +44,8 @@ es-MX: models: meeting: attributes: - show_embedded_iframe: - not_embeddable: Esta URL no puede ser incrustada + iframe_embed_type: + not_embeddable: Esta URL no puede ser incrustada en la página de encuentro o evento en directo meeting_agenda: attributes: base: @@ -100,7 +100,7 @@ es-MX: type_eq: label: Tipo de encuentro values: - hybrid: Ambos + hybrid: Híbrido in_person: Presencial online: Online meeting_copies: @@ -184,7 +184,7 @@ es-MX: notification_title: El encuentro %{resource_title} comenzará en menos de 48 h. forms: meetings: - attendees_count_help_text: No olvides incluir el número total de asistentes a tu encuentro, ya sea presencial, en línea o híbrido. + attendees_count_help_text: No te olvides de añadir el número total de asistentes a la reunión, ya sea en persona, en línea o híbrido. gamification: badges: attended_meetings: @@ -312,7 +312,8 @@ es-MX: registration_url_help: 'Enlace: permitir a las participantes ir al servicio externo que estás utilizando para las inscripciones' select_a_meeting_type: Por favor, selecciona un tipo de encuentro select_a_registration_type: Por favor, seleccione un tipo de inscripción - show_embedded_iframe_help: Incrustar o no el iframe para esta URL de videoconferencia. Sólo algunos servicios permiten incrustar (por ejemplo, Youtube, Twitch, etc.) + select_an_iframe_access_level: Por favor, seleccione un nivel de acceso iframe + show_embedded_iframe_help: Sólo unos pocos servicios se pueden incrustar en un encuentro o evento en vivo (YouTube, Twitch y Jitsi) index: title: Encuentros new: @@ -382,26 +383,37 @@ es-MX: value_types: organizer_presenter: not_found: 'El organizador no se encontró en la base de datos (ID: %{id})' + application_helper: + filter_category_values: + all: Todas + filter_meeting_space_values: + all: Todos + filter_scope_values: + all: Todos calendar_modal: calendar_url: URL del calendario close_window: Cerrar ventana export_calendar: Exportar calendario conference_venues: Sedes de las jornadas content_blocks: - upcoming_events: + upcoming_meetings: name: Próximos encuentros - upcoming_events: Próximos encuentros - view_all_events: Ver todo + upcoming_meetings: Próximos encuentros + view_all_meetings: Ver todo directory: meetings: index: - all: Todas - date: Fecha meetings: Encuentros - past: Pasadas - search: Buscar space_type: Espacio participativo - upcoming: Próximas + iframe_access_level: + all: Todos los visitantes + registered: Participantes inscritas en este encuentro + signed_in: Sólo participantes registradas + iframe_embed_type: + embed_in_meeting_page: Incrustar en la página del encuentro + none: Ninguno + open_in_live_event_page: Abrir en la página del evento en directo (con encuestas opcionales) + open_in_new_tab: Abrir en nueva pestaña last_activity: meeting_updated_at_html: "Encuentro actualizado a las %{link}" new_meeting_at_html: "Nuevo encuentro en %{link}" @@ -464,7 +476,7 @@ es-MX: type: Tipo type_values: all: Todos - hybrid: Ambos + hybrid: Híbrida in_person: Presencial online: Online filters_small_view: @@ -484,9 +496,14 @@ es-MX: select_a_category: Por favor, selecciona una categoría select_a_meeting_type: Por favor, selecciona un tipo de encuentro select_a_registration_type: Por favor, selecciona un tipo de inscripción - show_embedded_iframe_help: Incrustar o no el iframe para esta URL de videoconferencia. Sólo algunos servicios permiten incrustar (por ejemplo, Youtube, Twitch, etc.) + select_an_iframe_access_level: Por favor, selecciona un nivel de acceso iframe + show_embedded_iframe_help: Sólo unos pocos servicios se pueden incrustar en un encuentro o evento en vivo (YouTube, Twitch y Jitsi) index: + click_here: Ver todos los encuentros new_meeting: Nuevo encuentro + see_all: Ver todos los encuentros + see_all_withdrawn: Ver todos los encuentros retirados + text_banner: Estás viendo la lista de encuentros retirados por sus autores. %{go_back_link}. meeting_minutes: related_information: Información relacionada meetings: @@ -505,6 +522,7 @@ es-MX: close_meeting: Cerrar encuentro contributions: Número de contribuciones date: Fecha + edit_close_meeting: Editar informe del encuentro edit_meeting: Editar el encuentro going: Te has inscrito en este encuentro join: Inscribirse al encuentro @@ -526,6 +544,9 @@ es-MX: other: "%{count} plazas restantes" view: Ver visit_finished: Ver encuentro pasado + withdraw_btn_hint: Puedes retirar tu encuentro si cambias de opinión. El encuentro no será eliminado, aparecerá en la lista de encuentros retirados. + withdraw_confirmation_html: '¿Seguro que quieres retirar este encuentro?

¡Esta acción no se puede cancelar!' + withdraw_meeting: Retirar encuentro update: invalid: Se ha producido un error al actualizar este encuentro. success: Has actualizado el encuentro con éxito. @@ -546,7 +567,7 @@ es-MX: fields: closed: Cerrado end_time: Fecha de finalización - id: Id + id: ID map: Mapa official_meeting: Encuentro oficial start_time: Fecha de inicio @@ -597,14 +618,18 @@ es-MX: invalid: Ha habido un problema al salir de esta encuentro. success: Has salido del encuentro con éxito. type_of_meeting: - hybrid: Ambos + hybrid: Híbrido in_person: Presencial online: En línea types: private_meeting: Encuentro privado transparent: Transparente + withdraw: Retirado versions: back_to_resource: Volver al encuentro + withdraw: + error: Se ha producido un error al retirar el encuentro + success: El encuentro se ha retirado con éxito metrics: meetings: description: Número de encuentros creados diff --git a/decidim-meetings/config/locales/es-PY.yml b/decidim-meetings/config/locales/es-PY.yml index e4c7a089dfd62..81adebf2e3ec2 100644 --- a/decidim-meetings/config/locales/es-PY.yml +++ b/decidim-meetings/config/locales/es-PY.yml @@ -44,8 +44,8 @@ es-PY: models: meeting: attributes: - show_embedded_iframe: - not_embeddable: Esta URL no puede ser incrustada + iframe_embed_type: + not_embeddable: Esta URL no puede ser incrustada en la página de encuentro o evento en directo meeting_agenda: attributes: base: @@ -100,7 +100,7 @@ es-PY: type_eq: label: Tipo de encuentro values: - hybrid: Ambos + hybrid: Híbrido in_person: Presencial online: Online meeting_copies: @@ -184,7 +184,7 @@ es-PY: notification_title: El encuentro %{resource_title} comenzará en menos de 48 h. forms: meetings: - attendees_count_help_text: No olvides incluir el número total de asistentes a tu encuentro, ya sea presencial, en línea o híbrido. + attendees_count_help_text: No te olvides de añadir el número total de asistentes a la reunión, ya sea en persona, en línea o híbrido. gamification: badges: attended_meetings: @@ -312,7 +312,8 @@ es-PY: registration_url_help: 'Enlace: permitir a las participantes ir al servicio externo que estás utilizando para las inscripciones' select_a_meeting_type: Por favor, selecciona un tipo de encuentro select_a_registration_type: Por favor, seleccione un tipo de inscripción - show_embedded_iframe_help: Incrustar o no el iframe para esta URL de videoconferencia. Sólo algunos servicios permiten incrustar (por ejemplo, Youtube, Twitch, etc.) + select_an_iframe_access_level: Por favor, seleccione un nivel de acceso iframe + show_embedded_iframe_help: Solo unos pocos servicios se pueden incrustar en encuentros o eventos en directo (YouTube, Twitch y Jitsi) index: title: Encuentros new: @@ -382,26 +383,37 @@ es-PY: value_types: organizer_presenter: not_found: 'El organizador no se encontró en la base de datos (ID: %{id})' + application_helper: + filter_category_values: + all: Todas + filter_meeting_space_values: + all: Todos + filter_scope_values: + all: Todos calendar_modal: calendar_url: URL del calendario close_window: Cerrar ventana export_calendar: Exportar calendario conference_venues: Lugares de conferencia content_blocks: - upcoming_events: - name: Próximos Eventos - upcoming_events: Próximos encuentros - view_all_events: Ver todo + upcoming_meetings: + name: Próximos encuentros + upcoming_meetings: Próximos encuentros + view_all_meetings: Ver todo directory: meetings: index: - all: Todas - date: Fecha meetings: Reuniones - past: Pasadas - search: Buscar space_type: Espacio participativo - upcoming: Próximas + iframe_access_level: + all: Todos los visitantes + registered: Participantes inscritas en este encuentro + signed_in: Sólo participantes registradas + iframe_embed_type: + embed_in_meeting_page: Incrustar en la página del encuentro + none: Ninguno + open_in_live_event_page: Abrir en la página del evento en directo (con encuestas opcionales) + open_in_new_tab: Abrir en nueva pestaña last_activity: meeting_updated_at_html: "Encuentro actualizado a las %{link}" new_meeting_at_html: "Nueva reunión en %{link}" @@ -464,7 +476,7 @@ es-PY: type: Tipo type_values: all: Todos - hybrid: Ambos + hybrid: Híbrida in_person: Presencial online: Online filters_small_view: @@ -484,9 +496,14 @@ es-PY: select_a_category: Por favor, selecciona una categoría select_a_meeting_type: Por favor, selecciona un tipo de encuentro select_a_registration_type: Por favor, selecciona un tipo de inscripción - show_embedded_iframe_help: Incrustar o no el iframe para esta URL de videoconferencia. Sólo algunos servicios permiten incrustar (por ejemplo, Youtube, Twitch, etc.) + select_an_iframe_access_level: Por favor, selecciona un nivel de acceso iframe + show_embedded_iframe_help: Solo unos pocos servicios se pueden incrustar en encuentros o eventos en directo (YouTube, Twitch y Jitsi) index: + click_here: Ver todos los encuentros new_meeting: Nuevo encuentro + see_all: Ver todos los encuentros + see_all_withdrawn: Ver todos los encuentros retirados + text_banner: Estás viendo la lista de encuentros retirados por sus autores. %{go_back_link}. meeting_minutes: related_information: Información relacionada meetings: @@ -505,6 +522,7 @@ es-PY: close_meeting: Cerrar encuentro contributions: Número de contribuciones date: Fecha + edit_close_meeting: Editar informe del encuentro edit_meeting: Editar el encuentro going: Te has inscrito en este encuentro join: Inscribirse al encuentro @@ -526,6 +544,9 @@ es-PY: other: "%{count} ranuras restantes" view: Ver visit_finished: Ver encuentro pasado + withdraw_btn_hint: Puedes retirar tu encuentro si cambias de opinión. El encuentro no será eliminado, aparecerá en la lista de encuentros retirados. + withdraw_confirmation_html: '¿Seguro que quieres retirar este encuentro?

¡Esta acción no se puede cancelar!' + withdraw_meeting: Retirar encuentro update: invalid: Se ha producido un error al actualizar este encuentro. success: Has actualizado el encuentro con éxito. @@ -546,7 +567,7 @@ es-PY: fields: closed: Cerrado end_time: Fecha de finalización - id: Id + id: ID map: Mapa official_meeting: Encuentro oficial start_time: Fecha de inicio @@ -597,14 +618,18 @@ es-PY: invalid: Ha habido un problema al salir de esta encuentro. success: Has salido del encuentro con éxito. type_of_meeting: - hybrid: Ambos + hybrid: Híbrido in_person: Presencial online: En línea types: private_meeting: Encuentro privado transparent: Transparente + withdraw: Retirado versions: back_to_resource: Volver al encuentro + withdraw: + error: Se ha producido un error al retirar el encuentro + success: El encuentro se ha retirado con éxito metrics: meetings: description: Número de reuniones creadas diff --git a/decidim-meetings/config/locales/es.yml b/decidim-meetings/config/locales/es.yml index faf86a7a5ae65..095f416f4dbf3 100644 --- a/decidim-meetings/config/locales/es.yml +++ b/decidim-meetings/config/locales/es.yml @@ -44,8 +44,8 @@ es: models: meeting: attributes: - show_embedded_iframe: - not_embeddable: Esta URL no puede ser incrustada + iframe_embed_type: + not_embeddable: Esta URL no puede ser incrustada en la página de encuentro o evento en directo meeting_agenda: attributes: base: @@ -100,7 +100,7 @@ es: type_eq: label: Tipo de encuentro values: - hybrid: Ambos + hybrid: Híbrido in_person: Presencial online: Online meeting_copies: @@ -184,7 +184,7 @@ es: notification_title: El encuentro %{resource_title} empezará en menos de 48 h. forms: meetings: - attendees_count_help_text: No olvides incluir el número total de asistentes a tu encuentro, ya sea presencial, en línea o híbrido. + attendees_count_help_text: No te olvides de añadir el número total de asistentes a la reunión, ya sea en persona, en línea o híbrido. gamification: badges: attended_meetings: @@ -312,7 +312,8 @@ es: registration_url_help: 'Enlace: permitir a las participantes ir al servicio externo que estás utilizando para las inscripciones' select_a_meeting_type: Por favor, selecciona un tipo de encuentro select_a_registration_type: Por favor, seleccione un tipo de inscripción - show_embedded_iframe_help: Incrustar o no el iframe para esta URL de videoconferencia. Sólo algunos servicios permiten incrustar (por ejemplo, Youtube, Twitch, etc.) + select_an_iframe_access_level: Por favor, seleccione un nivel de acceso iframe + show_embedded_iframe_help: Solo unos pocos servicios se pueden incrustar en encuentros o eventos en directo (YouTube, Twitch y Jitsi) index: title: Encuentros new: @@ -382,26 +383,37 @@ es: value_types: organizer_presenter: not_found: 'El organizador no se encontró en la base de datos (ID: %{id})' + application_helper: + filter_category_values: + all: Todas + filter_meeting_space_values: + all: Todos + filter_scope_values: + all: Todos calendar_modal: calendar_url: URL del calendario close_window: Cerrar ventana export_calendar: Exportar calendario conference_venues: Sedes de las jornadas content_blocks: - upcoming_events: + upcoming_meetings: name: Próximos encuentros - upcoming_events: Próximos encuentros - view_all_events: Ver todo + upcoming_meetings: Próximos encuentros + view_all_meetings: Ver todo directory: meetings: index: - all: Todas - date: Fecha meetings: Encuentros - past: Pasados - search: Buscar space_type: Espacio participativo - upcoming: Próximos + iframe_access_level: + all: Todos los visitantes + registered: Participantes inscritas en este encuentro + signed_in: Sólo participantes registradas + iframe_embed_type: + embed_in_meeting_page: Incrustar en la página del encuentro + none: Ninguno + open_in_live_event_page: Abrir en la página del evento en directo (con encuestas opcionales) + open_in_new_tab: Abrir en nueva pestaña last_activity: meeting_updated_at_html: "Encuentro actualizado a las %{link}" new_meeting_at_html: "Nuevo encuentro en %{link}" @@ -464,7 +476,7 @@ es: type: Tipo type_values: all: Todos - hybrid: Ambos + hybrid: Híbrida in_person: Presencial online: Online filters_small_view: @@ -484,9 +496,14 @@ es: select_a_category: Por favor, selecciona una categoría select_a_meeting_type: Por favor, selecciona un tipo de encuentro select_a_registration_type: Por favor, selecciona un tipo de inscripción - show_embedded_iframe_help: Incrustar o no el iframe para esta URL de videoconferencia. Sólo algunos servicios permiten incrustar (por ejemplo, Youtube, Twitch, etc.) + select_an_iframe_access_level: Por favor, selecciona un nivel de acceso iframe + show_embedded_iframe_help: Solo unos pocos servicios se pueden incrustar en encuentros o eventos en directo (YouTube, Twitch y Jitsi) index: + click_here: Ver todos los encuentros new_meeting: Nuevo encuentro + see_all: Ver todos los encuentros + see_all_withdrawn: Ver todos los encuentros retirados + text_banner: Estás viendo la lista de encuentros retirados por sus autores. %{go_back_link}. meeting_minutes: related_information: Información relacionada meetings: @@ -505,6 +522,7 @@ es: close_meeting: Cerrar encuentro contributions: Número de aportaciones date: Fecha + edit_close_meeting: Editar informe del encuentro edit_meeting: Editar el encuentro going: Te has inscrito en este encuentro join: Unirse al encuentro @@ -526,6 +544,9 @@ es: other: "%{count} plazas restantes" view: Ver visit_finished: Ver encuentro pasado + withdraw_btn_hint: Puedes retirar tu encuentro si cambias de opinión. El encuentro no será eliminado, aparecerá en la lista de encuentros retirados. + withdraw_confirmation_html: '¿Seguro que quieres retirar este encuentro?

¡Esta acción no se puede cancelar!' + withdraw_meeting: Retirar encuentro update: invalid: Se ha producido un error al actualizar este encuentro. success: Has actualizado el encuentro correctamente. @@ -546,7 +567,7 @@ es: fields: closed: Cerrado end_time: Fecha de finalización - id: Id + id: ID map: Mapa official_meeting: Encuentro oficial start_time: Fecha de inicio @@ -597,14 +618,18 @@ es: invalid: Se ha producido un error al salir de este encuentro. success: Has salido del encuentro con éxito. type_of_meeting: - hybrid: Ambos + hybrid: Híbrido in_person: Presencial online: En línea types: private_meeting: Encuentro privado transparent: Transparente + withdraw: Retirado versions: back_to_resource: Volver al encuentro + withdraw: + error: Se ha producido un error al retirar el encuentro + success: El encuentro se ha retirado con éxito metrics: meetings: description: Número de encuentros creados diff --git a/decidim-meetings/config/locales/eu.yml b/decidim-meetings/config/locales/eu.yml index c97176988ea13..1ce5c7cb2416f 100644 --- a/decidim-meetings/config/locales/eu.yml +++ b/decidim-meetings/config/locales/eu.yml @@ -42,10 +42,6 @@ eu: type_of_meeting: Mota errors: models: - meeting: - attributes: - show_embedded_iframe: - not_embeddable: URL hau ezin da txertatu meeting_agenda: attributes: base: @@ -100,7 +96,6 @@ eu: type_eq: label: Topaketa mota values: - hybrid: Biok in_person: Aurrez aurre online: Lineakoa meeting_copies: @@ -182,9 +177,6 @@ eu: email_outro: Jakinarazpen hori jaso duzu "%{resource_title}" bilera jarraitzen duzulako. Aurreko esteka estekan jarrai dezakezu. email_subject: '"%{resource_title}" topaketa 48 ordu baino gutxiagotan hasiko da.' notification_title: %{resource_title} topaketa 48 ordu baino gutxiagoan hasiko da. - forms: - meetings: - attendees_count_help_text: Ez ahaztu zure topaketara joandako guztien kopurua sartzea, bai aurrez aurre, bai linean edo hibridoan. gamification: badges: attended_meetings: @@ -309,7 +301,6 @@ eu: registration_url_help: 'Lotura: parte-hartzaileei aukera ematea izena emateko erabiltzen ari zaren kanpoko zerbitzura joateko' select_a_meeting_type: Mesedez, hautatu topaketa mota bat select_a_registration_type: Mesedez, hautatu erregistro mota bat - show_embedded_iframe_help: Sartu edo ez iframea bideokonferentziako URL honetarako. Zerbitzu batzuek baino ez dute aukera ematen (adibidez, Youtube, Twitch, etab.) index: title: Topaketa-zerrenda new: @@ -379,26 +370,26 @@ eu: value_types: organizer_presenter: not_found: 'Antolatzailea ez da aurkitu datu-basean (ID: %{id})' + application_helper: + filter_category_values: + all: Guztiak + filter_meeting_space_values: + all: Guztiak + filter_scope_values: + all: Guztiak calendar_modal: calendar_url: Egutegiaren URLa close_window: Itxi leihoa export_calendar: Esportatu egutegia conference_venues: Hitzaldi aretoak content_blocks: - upcoming_events: - name: Hurrengo ekitaldiak - upcoming_events: Hurrengo topaketak - view_all_events: Ikusi dena + upcoming_meetings: + view_all_meetings: Ikusi dena directory: meetings: index: - all: guztiak - date: Data meetings: Bilerak - past: Aurrekoak - search: Search space_type: Partaidetza espazioa - upcoming: Hurrengoak last_activity: meeting_updated_at_html: "eztabaida ordu honetan %{link} eguneratuta" new_meeting_at_html: "Bilera berria %{link}" @@ -461,7 +452,6 @@ eu: type: Mota type_values: all: Denak - hybrid: Biok in_person: Aurrez aurre online: Lineakoa filters_small_view: @@ -481,9 +471,12 @@ eu: select_a_category: Mesedez, hautatu kategoria bat select_a_meeting_type: Mesedez, hautatu topaketa mota bat select_a_registration_type: Mesedez, hautatu erregistro mota bat - show_embedded_iframe_help: Sartu edo ez iframea bideokonferentziako URL honetarako. Zerbitzu batzuek baino ez dute aukera ematen (adibidez, Youtube, Twitch, etab.) index: + click_here: Ikusi topaketa guztiak new_meeting: Topaketa berria + see_all: Ikusi topaketa guztiak + see_all_withdrawn: Ikusi bertan behera utzitako topaketa guztiak + text_banner: Ikusten ari zara egileek bertan behera utzitako topaketak %{go_back_link}. meeting_minutes: related_information: Lotutako informazioa meetings: @@ -502,6 +495,7 @@ eu: close_meeting: Itxi topaketa contributions: Ekarpen-kopurua date: Data + edit_close_meeting: Editatu bileraren txostena edit_meeting: Editatu topaketa going: Topaketa honetan eman duzu izena join: Izena eman topaketan @@ -523,6 +517,7 @@ eu: other: "%{count} slot geratzen dira" view: ikusi visit_finished: Ikusi egindako topaketa + withdraw_meeting: Bertan behera utzi topaketa update: invalid: Arazo bat izan da topaketa hau eguneratzean. success: Topaketa zuzen eguneratu duzu. @@ -543,7 +538,6 @@ eu: fields: closed: Itxita end_time: Bukaera-data - id: Id map: Mapa official_meeting: Topaketa ofiziala start_time: Hasiera-data @@ -556,7 +550,6 @@ eu: empty_questions: Topaketa honetan zehar, galdera batzuk bidaliko dira eta erantzun ahal izango dituzu. Hemen erakutsiko dira. index_admin: admin_dashboard: Administrazio-panela - edit: Editatu administrazio-panelean question: Galdera received_answer: jasotako erantzuna received_answers: jasotako erantzunak @@ -591,14 +584,17 @@ eu: invalid: Arazo bat izan da topaketa honetatik ateratzean. success: Topaketatik ongi atera zara. type_of_meeting: - hybrid: Biok in_person: Aurrez aurre online: Lineakoa types: private_meeting: Bilera pribatua transparent: gardena + withdraw: Kenduta versions: back_to_resource: Itzuli topaketara + withdraw: + error: Arazo bat izan da topaketa bertan behera uztean + success: Topaketa zuzen utzi da bertan behera metrics: meetings: description: Bilera kopurua sortu da diff --git a/decidim-meetings/config/locales/fi-plain.yml b/decidim-meetings/config/locales/fi-plain.yml index 73ca9bf6a1b11..351a9cbcb0a65 100644 --- a/decidim-meetings/config/locales/fi-plain.yml +++ b/decidim-meetings/config/locales/fi-plain.yml @@ -44,8 +44,8 @@ fi-pl: models: meeting: attributes: - show_embedded_iframe: - not_embeddable: Tätä URL-osoitetta ei voi upottaa + iframe_embed_type: + not_embeddable: Tätä URL-osoitetta ei voi upottaa tapaamisen sivulle tai reaaliaikaisen tapahtuman sivulle meeting_agenda: attributes: base: @@ -100,7 +100,7 @@ fi-pl: type_eq: label: Tapaamisen tyyppi values: - hybrid: Molemmat + hybrid: Hybridi in_person: Fyysinen online: Verkossa meeting_copies: @@ -184,7 +184,7 @@ fi-pl: notification_title: Tapahtuma %{resource_title} alkaa alle 48 tuntin kuluttua. forms: meetings: - attendees_count_help_text: Älä unohda ilmoittaa tapahtuman osallistujamäärää. Tapahtuman tyypistä riippumatta, meille on tärkeä tietää, kuinka moni osallistui tapahtumaan. + attendees_count_help_text: Älä unohda merkitä tapaamisesi osallistujien kokonaismäärää, olipa kyse fyysisestä, verkko- tai hybriditapaamisesta. gamification: badges: attended_meetings: @@ -312,7 +312,8 @@ fi-pl: registration_url_help: 'Linkki: salli käyttäjien siirtyminen käytettyyn ulkoiseen ilmoittautumispalveluun' select_a_meeting_type: Valitse tapaamisen tyyppi select_a_registration_type: Valitse ilmoittautumisten tyyppi - show_embedded_iframe_help: Määrittää, upotetaanko tämän videotapaamisen URL tapaamisen sivulle. Ainoastaan muutamat palvelut sallivat upotuksen ulkopuolisiin palveluihin (esim. YouTube, Twitch...) + select_an_iframe_access_level: Valitse iframe-upotusten käyttöoikeustaso + show_embedded_iframe_help: Vain harvat palvelut sallivat tapaamisen upottamisen reaaliaikaisesti tapahtumasivulle (YouTube, Twitch ja Jitsi) index: title: Tapahtumat new: @@ -382,26 +383,37 @@ fi-pl: value_types: organizer_presenter: not_found: 'Järjestäjää ei löytynyt tietokannasta (ID: %{id})' + application_helper: + filter_category_values: + all: Kaikki + filter_meeting_space_values: + all: Kaikki + filter_scope_values: + all: Kaikki calendar_modal: calendar_url: Kalenterin URL close_window: Sulje ikkuna export_calendar: Vie kalenterin tiedot conference_venues: Tapahtumapaikat content_blocks: - upcoming_events: - name: Tulevat tapahtumat - upcoming_events: Tulevat tapahtumat - view_all_events: Näytä kaikki + upcoming_meetings: + name: Tulevat tapaamiset + upcoming_meetings: Tulevat tapaamiset + view_all_meetings: Näytä kaikki directory: meetings: index: - all: Kaikki - date: Päivämäärä meetings: Tapahtumat - past: Menneet - search: Hae space_type: Osallisuustila - upcoming: Tulevat + iframe_access_level: + all: Kaikki kävijät + registered: Tähän tapaamiseen ilmoittautuneet osallistujat + signed_in: Vain sisäänkirjautuneet osallistujat + iframe_embed_type: + embed_in_meeting_page: Upota tapaamisen sivulle + none: Ei mitään + open_in_live_event_page: Avaa upotus tapahtuman sivulla reaaliajassa (liitä vapaaehtoisia mielipidekyselyjä) + open_in_new_tab: Avaa uudessa välilehdessä last_activity: meeting_updated_at_html: "Tapaaminen päivitetty osoitteessa %{link}" new_meeting_at_html: "Uusi tapahtuma osoitteessa %{link}" @@ -464,7 +476,7 @@ fi-pl: type: Tyyppi type_values: all: Kaikki - hybrid: Molemmat + hybrid: Hybridi in_person: Fyysinen online: Verkossa filters_small_view: @@ -484,9 +496,14 @@ fi-pl: select_a_category: Valitse aihepiiri select_a_meeting_type: Valitse tapaamisen tyyppi select_a_registration_type: Valitse ilmoittautumisten tyyppi - show_embedded_iframe_help: Määrittää, upotetaanko tämän videotapaamisen URL tapaamisen sivulle. Ainoastaan muutamat palvelut sallivat upotuksen ulkopuolisiin palveluihin (esim. YouTube, Twitch...) + select_an_iframe_access_level: Valitse iframe-upotusten käyttöoikeustaso + show_embedded_iframe_help: Vain harvat palvelut sallivat tapaamisen upottamisen reaaliaikaisesti tapahtumasivulle (YouTube, Twitch ja Jitsi) index: + click_here: Näytä kaikki tapahtumat new_meeting: Uusi tapahtuma + see_all: Näytä kaikki tapahtumat + see_all_withdrawn: Näytä kaikki peruutetut tapahtumat + text_banner: Katselet peruutettuja tapahtumia, jotka niiden tekijät ovat peruuttaneet. %{go_back_link}. meeting_minutes: related_information: Liittyviä tietoja meetings: @@ -505,6 +522,7 @@ fi-pl: close_meeting: Sulje tapaaminen contributions: Kontribuutioiden määrä date: Päivämäärä + edit_close_meeting: Muokkaa tapahtumaraporttia edit_meeting: Muokkaa tapahtumaa going: Olet ilmoittautunut tähän tapaamiseen join: Liity tapahtumaan @@ -526,6 +544,9 @@ fi-pl: other: "%{count} paikkaa jäljellä" view: Näytä visit_finished: Näytä mennyt tapaaminen + withdraw_btn_hint: Voit peruuttaa tapahtumasi, jos muutat mieltäsi. Tapahtumaa ei poisteta kokonaan, eli se löytyy edelleen peruutettujen tapahtumien listasta. + withdraw_confirmation_html: Haluatko varmasti peruuttaa tämän tapahtuman?

Tätä toimintoa ei voi peruuttaa! + withdraw_meeting: Peruuta tapahtuma update: invalid: Tapahtuman luonti epäonnistui. success: Tapahtuman luonti onnistui. @@ -546,7 +567,7 @@ fi-pl: fields: closed: Suljettu end_time: Päättymispäivä - id: Id + id: ID map: Kartta official_meeting: Virallinen tapahtuma start_time: Alkamispäivä @@ -597,14 +618,18 @@ fi-pl: invalid: Tapahtumasta poistumisessa on tapahtunut virhe. success: Olet poistunut tapahtumasta onnistuneesti. type_of_meeting: - hybrid: Molemmat + hybrid: Hybridi in_person: Fyysinen online: Verkossa types: private_meeting: Yksityinen tapahtuma transparent: Läpinäkyvä + withdraw: Peruutettu versions: back_to_resource: Takaisin tapahtumaan + withdraw: + error: Tapahtuman peruuttaminen epäonnistui + success: Tapahtuman peruuttaminen onnistui metrics: meetings: description: Tapahtumien määrä diff --git a/decidim-meetings/config/locales/fi.yml b/decidim-meetings/config/locales/fi.yml index cbffec81d6802..8579da7a3a404 100644 --- a/decidim-meetings/config/locales/fi.yml +++ b/decidim-meetings/config/locales/fi.yml @@ -44,8 +44,8 @@ fi: models: meeting: attributes: - show_embedded_iframe: - not_embeddable: Tätä URL-osoitetta ei voi upottaa + iframe_embed_type: + not_embeddable: Tätä URL-osoitetta ei voi upottaa tapaamisen sivulle tai reaaliaikaisen tapahtuman sivulle meeting_agenda: attributes: base: @@ -100,7 +100,7 @@ fi: type_eq: label: Tapaamisen tyyppi values: - hybrid: Molemmat + hybrid: Hybridi in_person: Fyysinen online: Verkossa meeting_copies: @@ -184,7 +184,7 @@ fi: notification_title: Tapaaminen %{resource_title} alkaa alle 48 tuntin kuluttua. forms: meetings: - attendees_count_help_text: Älä unohda ilmoittaa tapahtuman osallistujamäärää. Tapahtuman tyypistä riippumatta, meille on tärkeä tietää, kuinka moni osallistui tapahtumaan. + attendees_count_help_text: Älä unohda merkitä tapaamisesi osallistujien kokonaismäärää, olipa kyse fyysisestä, verkko- tai hybriditapaamisesta. gamification: badges: attended_meetings: @@ -312,7 +312,8 @@ fi: registration_url_help: 'Linkki: salli käyttäjien siirtyminen käytettyyn ulkoiseen ilmoittautumispalveluun' select_a_meeting_type: Valitse tapaamisen tyyppi select_a_registration_type: Valitse ilmoittautumisten tyyppi - show_embedded_iframe_help: Määrittää, upotetaanko tämän videotapaamisen URL tapaamisen sivulle. Ainoastaan muutamat palvelut sallivat upotuksen ulkopuolisiin palveluihin (esim. YouTube, Twitch...) + select_an_iframe_access_level: Valitse iframe-upotusten käyttöoikeustaso + show_embedded_iframe_help: Vain harvat palvelut sallivat tapaamisen upottamisen reaaliaikaisesti tapahtumasivulle (YouTube, Twitch ja Jitsi) index: title: Tapaamiset new: @@ -382,26 +383,37 @@ fi: value_types: organizer_presenter: not_found: 'Järjestäjää ei löytynyt tietokannasta (ID: %{id})' + application_helper: + filter_category_values: + all: Kaikki + filter_meeting_space_values: + all: Kaikki + filter_scope_values: + all: Kaikki calendar_modal: calendar_url: Kalenterin URL close_window: Sulje ikkuna export_calendar: Vie kalenteriin conference_venues: Tapahtumapaikat content_blocks: - upcoming_events: - name: Tulevat tapahtumat - upcoming_events: Tulevat tapaamiset - view_all_events: Näytä kaikki + upcoming_meetings: + name: Tulevat tapaamiset + upcoming_meetings: Tulevat tapaamiset + view_all_meetings: Näytä kaikki directory: meetings: index: - all: Kaikki - date: Päivämäärä meetings: Tapaamiset - past: Menneet - search: Hae space_type: Osallistumistila - upcoming: Tulevat + iframe_access_level: + all: Kaikki kävijät + registered: Tähän tapaamiseen ilmoittautuneet osallistujat + signed_in: Vain sisäänkirjautuneet osallistujat + iframe_embed_type: + embed_in_meeting_page: Upota tapaamisen sivulle + none: Ei mitään + open_in_live_event_page: Avaa upotus tapahtuman sivulla reaaliajassa (liitä vapaaehtoisia mielipidekyselyjä) + open_in_new_tab: Avaa uudessa välilehdessä last_activity: meeting_updated_at_html: "Tapaaminen päivitetty osoitteessa %{link}" new_meeting_at_html: "Uusi tapaaminen osoitteessa %{link}" @@ -464,7 +476,7 @@ fi: type: Tyyppi type_values: all: Kaikki - hybrid: Molemmat + hybrid: Hybridi in_person: Fyysinen online: Verkossa filters_small_view: @@ -484,9 +496,14 @@ fi: select_a_category: Valitse aihepiiri select_a_meeting_type: Valitse tapaamisen tyyppi select_a_registration_type: Valitse ilmoittautumisten tyyppi - show_embedded_iframe_help: Määrittää, upotetaanko tämän videotapaamisen URL tapaamisen sivulle. Ainoastaan muutamat palvelut sallivat upotuksen ulkopuolisiin palveluihin (esim. YouTube, Twitch...) + select_an_iframe_access_level: Valitse iframe-upotusten käyttöoikeustaso + show_embedded_iframe_help: Vain harvat palvelut sallivat tapaamisen upottamisen reaaliaikaisesti tapahtumasivulle (YouTube, Twitch ja Jitsi) index: + click_here: Näytä kaikki tapahtumat new_meeting: Uusi tapaaminen + see_all: Näytä kaikki tapahtumat + see_all_withdrawn: Näytä kaikki peruutetut tapahtumat + text_banner: Katselet peruutettuja tapahtumia, jotka niiden tekijät ovat peruuttaneet. %{go_back_link}. meeting_minutes: related_information: Liittyviä tietoja meetings: @@ -505,6 +522,7 @@ fi: close_meeting: Sulje tapaaminen contributions: Kontribuutioiden määrä date: Päivämäärä + edit_close_meeting: Muokkaa tapahtumaraporttia edit_meeting: Muokkaa tapaamista going: Olet ilmoittautunut tähän tapaamiseen join: Ilmoittaudu tapaamiseen @@ -526,6 +544,9 @@ fi: other: "%{count} paikkaa jäljellä" view: Näytä visit_finished: Näytä mennyt tapaaminen + withdraw_btn_hint: Voit peruuttaa tapahtumasi, jos muutat mieltäsi. Tapahtumaa ei poisteta kokonaan, eli se löytyy edelleen peruutettujen tapahtumien listasta. + withdraw_confirmation_html: Haluatko varmasti peruuttaa tämän tapahtuman?

Tätä toimintoa ei voi peruuttaa! + withdraw_meeting: Peruuta tapahtuma update: invalid: Tapaamisen luonti epäonnistui. success: Tapaamisen luonti onnistui. @@ -546,7 +567,7 @@ fi: fields: closed: Suljettu end_time: Päättymispäivä - id: Id + id: ID map: Kartta official_meeting: Virallinen tapaaminen start_time: Alkamispäivä @@ -597,14 +618,18 @@ fi: invalid: Tapaamisesta poistuminen epäonnistui. success: Olet poistunut tapaamisesta onnistuneesti. type_of_meeting: - hybrid: Molemmat + hybrid: Hybridi in_person: Fyysinen online: Verkossa types: private_meeting: Yksityinen tapaaminen transparent: Läpinäkyvä + withdraw: Peruutettu versions: back_to_resource: Takaisin tapaamiseen + withdraw: + error: Tapahtuman peruuttaminen epäonnistui + success: Tapahtuman peruuttaminen onnistui metrics: meetings: description: Tapaamisten määrä diff --git a/decidim-meetings/config/locales/fr-CA.yml b/decidim-meetings/config/locales/fr-CA.yml index af5003a116ce1..fd2ee3de643d5 100644 --- a/decidim-meetings/config/locales/fr-CA.yml +++ b/decidim-meetings/config/locales/fr-CA.yml @@ -44,8 +44,8 @@ fr-CA: models: meeting: attributes: - show_embedded_iframe: - not_embeddable: Cette URL ne peut pas être intégrée + iframe_embed_type: + not_embeddable: Cette URL ne peut pas être intégrée dans la page de rencontre ou d'événement en direct meeting_agenda: attributes: base: @@ -184,7 +184,7 @@ fr-CA: notification_title: La rencontre %{resource_title} débutera dans moins de 48h. forms: meetings: - attendees_count_help_text: N’oubliez pas d’inclure le nombre total de participants à votre événement, que ce soit en présentiel, en ligne ou en hybride. + attendees_count_help_text: N'oubliez pas d'inclure le nombre total de participants à votre réunion, que ce soit en personne, en ligne ou en hybride. gamification: badges: attended_meetings: @@ -312,7 +312,8 @@ fr-CA: registration_url_help: 'Lien : permet aux participants de partir sur le service externe que vous utilisez pour les inscriptions' select_a_meeting_type: Veuillez sélectionner un type de rencontre select_a_registration_type: Veuillez sélectionner un type d'inscription - show_embedded_iframe_help: Intégrer ou non l'iframe correspondant à cette URL de vidéoconférence. Seuls quelques services permettent l'intégration (c.-à-d. Youtube, Twitch...) + select_an_iframe_access_level: Veuillez sélectionner un niveau d'accès iframe + show_embedded_iframe_help: Seuls quelques services permettent d'intégrer des rencontres ou des événements en direct (YouTube, Twitch et Jitsi) index: title: Rencontres new: @@ -382,26 +383,37 @@ fr-CA: value_types: organizer_presenter: not_found: 'L''organisateur n''a pas été trouvé dans la base de données (ID: %{id})' + application_helper: + filter_category_values: + all: Tous + filter_meeting_space_values: + all: Tous + filter_scope_values: + all: Tous calendar_modal: calendar_url: URL du calendrier close_window: Fermer la fenêtre export_calendar: Calendrier d'exportation conference_venues: Salles de conférence content_blocks: - upcoming_events: - name: Évènements à venir - upcoming_events: Rencontres à venir - view_all_events: Voir tout + upcoming_meetings: + name: Rencontres à venir + upcoming_meetings: Rencontres à venir + view_all_meetings: Voir tout directory: meetings: index: - all: Tout - date: Date meetings: Rencontres - past: Passé - search: Chercher space_type: Espace participatif - upcoming: À venir + iframe_access_level: + all: Tous les visiteurs + registered: Participants inscrits à cette rencontre + signed_in: Les participants connectés seulement + iframe_embed_type: + embed_in_meeting_page: Intégrer à la page de la rencontre + none: Aucun + open_in_live_event_page: Ouvrir dans la page de l'événement en direct (avec sondages facultatifs) + open_in_new_tab: Ouvrir le lien dans un nouvel onglet last_activity: meeting_updated_at_html: "Débat mis à jour à %{link}" new_meeting_at_html: "Nouvelle réunion à %{link}" @@ -484,9 +496,14 @@ fr-CA: select_a_category: Veuillez sélectionner une catégorie select_a_meeting_type: Veuillez sélectionner un type de rencontre select_a_registration_type: Veuillez sélectionner un type d'inscription - show_embedded_iframe_help: Intégrer ou non l'iframe correspondant à cette URL de vidéoconférence. Seuls quelques services permettent l'intégration (c.-à-d. Youtube, Twitch...) + select_an_iframe_access_level: Veuillez sélectionner un niveau d'accès iframe + show_embedded_iframe_help: Seuls quelques services permettent d'intégrer des rencontres ou des événements en direct (YouTube, Twitch et Jitsi) index: + click_here: Voir toutes les réunions new_meeting: Nouvelle réunion + see_all: Voir toutes les réunions + see_all_withdrawn: Voir toutes les réunions annulées + text_banner: Vous consultez la liste des réunions annulées par leurs auteurs. %{go_back_link}. meeting_minutes: related_information: Informations liées meetings: @@ -505,6 +522,7 @@ fr-CA: close_meeting: Clore la rencontre contributions: Décompte des contributions date: Date + edit_close_meeting: Modifier le rapport de la rencontre edit_meeting: Modifier la réunion going: Vous vous êtes inscrit à cette rencontre join: Participer à la rencontre @@ -526,6 +544,9 @@ fr-CA: other: "Il reste %{count} places" view: Voir visit_finished: Consulter l’historique des rencontres + withdraw_btn_hint: Vous pouvez annuler votre réunion si vous changez d'avis. La réunion n'est pas supprimée, elle apparaîtra dans la liste des réunions retirées. + withdraw_confirmation_html: Êtes-vous sûr de vouloir annuler cette réunion ?

Cette action ne peut pas être annulée ! + withdraw_meeting: Annuler la réunion update: invalid: Une erreur s'est produite lors de la mise à jour de la réunion. success: La réunion a été mise à jour avec succès. @@ -546,7 +567,7 @@ fr-CA: fields: closed: Fermée end_time: Date de fin - id: Id + id: ID map: Carte official_meeting: Réunion officielle start_time: Date de début @@ -559,7 +580,7 @@ fr-CA: empty_questions: Tout au long de cette rencontre, certaines questions seront envoyées et vous pourrez y répondre. Elles seront affichées ici. index_admin: admin_dashboard: Tableau de bord d'administration - edit: Modifier dans le panneau Admin + edit: Modifier dans le panneau d'administration question: Question received_answer: réponse reçue received_answers: réponses reçues @@ -603,8 +624,12 @@ fr-CA: types: private_meeting: Rencontre privée transparent: Visible par les non-membres + withdraw: Retirée versions: back_to_resource: Revenir à la réunion + withdraw: + error: Une erreur s'est produite lors de l'annulation de la réunion + success: La réunion a été annulée avec succès metrics: meetings: description: Nombre de rencontres créées diff --git a/decidim-meetings/config/locales/fr.yml b/decidim-meetings/config/locales/fr.yml index 03013d7811679..3f4b0bbf52fcf 100644 --- a/decidim-meetings/config/locales/fr.yml +++ b/decidim-meetings/config/locales/fr.yml @@ -44,8 +44,8 @@ fr: models: meeting: attributes: - show_embedded_iframe: - not_embeddable: Cette URL ne peut pas être intégrée + iframe_embed_type: + not_embeddable: Cette URL ne peut pas être intégrée dans la page de rencontre ou d'événement en direct meeting_agenda: attributes: base: @@ -184,7 +184,7 @@ fr: notification_title: La rencontre %{resource_title} débutera dans moins de 48h. forms: meetings: - attendees_count_help_text: N’oubliez pas d’inclure le nombre total de participants à votre événement, que ce soit en présentiel, en ligne ou en hybride. + attendees_count_help_text: N'oubliez pas d'inclure le nombre total de participants à votre réunion, que ce soit en personne, en ligne ou en hybride. gamification: badges: attended_meetings: @@ -312,7 +312,8 @@ fr: registration_url_help: 'Lien : permet aux participants de partir sur le service externe que vous utilisez pour les inscriptions' select_a_meeting_type: Veuillez sélectionner un type de rencontre select_a_registration_type: Veuillez sélectionner un type d'inscription - show_embedded_iframe_help: Intégrer ou non l'iframe correspondant à cette URL de vidéoconférence. Seuls quelques services permettent l'intégration (c.-à-d. Youtube, Twitch...) + select_an_iframe_access_level: Veuillez sélectionner un niveau d'accès iframe + show_embedded_iframe_help: Seuls quelques services permettent d'intégrer des rencontres ou des événements en direct (YouTube, Twitch et Jitsi) index: title: Rencontres new: @@ -382,26 +383,37 @@ fr: value_types: organizer_presenter: not_found: 'L''organisateur n''a pas été trouvé dans la base de données (ID: %{id})' + application_helper: + filter_category_values: + all: Tout + filter_meeting_space_values: + all: Tout + filter_scope_values: + all: Tout calendar_modal: calendar_url: URL du calendrier close_window: Fermer la fenêtre export_calendar: Calendrier d'exportation conference_venues: Salles de conférence content_blocks: - upcoming_events: - name: Évènements à venir - upcoming_events: Rencontres à venir - view_all_events: Voir tout + upcoming_meetings: + name: Rencontres à venir + upcoming_meetings: Rencontres à venir + view_all_meetings: Voir tout directory: meetings: index: - all: Tout - date: Date meetings: Rencontres - past: Passées - search: Chercher space_type: Espace participatif - upcoming: À venir + iframe_access_level: + all: Tous les visiteurs + registered: Participants inscrits à cette rencontre + signed_in: Les participants inscrits uniquement + iframe_embed_type: + embed_in_meeting_page: Intégrer à la page de la rencontre + none: Aucun + open_in_live_event_page: Ouvrir dans la page de l'événement en direct (avec sondages facultatifs) + open_in_new_tab: Ouvrir le lien dans un nouvel onglet last_activity: meeting_updated_at_html: "Rencontre mise à jour à %{link}" new_meeting_at_html: "Nouvelle rencontre dans %{link}" @@ -484,9 +496,14 @@ fr: select_a_category: Veuillez sélectionner une catégorie select_a_meeting_type: Veuillez sélectionner un type de rencontre select_a_registration_type: Veuillez sélectionner un type d'inscription - show_embedded_iframe_help: Intégrer ou non l'iframe correspondant à cette URL de vidéoconférence. Seuls quelques services permettent l'intégration (c.-à-d. Youtube, Twitch...) + select_an_iframe_access_level: Veuillez sélectionner un niveau d'accès iframe + show_embedded_iframe_help: Seuls quelques services permettent d'intégrer des rencontres ou des événements en direct (YouTube, Twitch et Jitsi) index: + click_here: Voir toutes les rencontres new_meeting: Nouvelle rencontre + see_all: Voir toutes les rencontres + see_all_withdrawn: Voir toutes les rencontres annulées + text_banner: Vous consultez la liste des rencontres annulées par leurs auteurs. %{go_back_link}. meeting_minutes: related_information: Informations liées meetings: @@ -505,6 +522,7 @@ fr: close_meeting: Clore la rencontre contributions: Décompte des contributions date: Date + edit_close_meeting: Modifier le compte-rendu de la rencontre edit_meeting: Modifier la rencontre going: Vous vous êtes inscrit à cette rencontre join: Participer à la rencontre @@ -526,6 +544,9 @@ fr: other: "Il reste %{count} places" view: Voir visit_finished: Consulter l’historique des rencontres + withdraw_btn_hint: Vous pouvez annuler votre rencontre si vous changez d'avis. La rencontre n'est pas supprimée, elle apparaîtra dans la liste des rencontres retirées. + withdraw_confirmation_html: Êtes-vous sûr de vouloir annuler cette rencontre ?

Cette action ne peut pas être annulée ! + withdraw_meeting: Annuler la rencontre update: invalid: Une erreur s'est produite lors de la mise à jour de la rencontre. success: La rencontre a été mise à jour avec succès. @@ -546,7 +567,7 @@ fr: fields: closed: Fermée end_time: Date de fin - id: Id + id: ID map: Carte official_meeting: Rencontre officielle start_time: Date de début @@ -559,7 +580,7 @@ fr: empty_questions: Tout au long de cette rencontre, certaines questions seront envoyées et vous pourrez y répondre. Elles seront affichées ici. index_admin: admin_dashboard: Administration du sondage - edit: Modifier le sondage dans le panneau d'administration (attention, une fois qu'une question a commencé à recevoir des réponses, vous ne pouvez plus modifier le sondage) + edit: Modifier dans le panneau d'administration question: Question received_answer: réponse reçue received_answers: réponses reçues @@ -603,8 +624,12 @@ fr: types: private_meeting: Rencontre privée transparent: Visible par les non-membres + withdraw: Retirée versions: back_to_resource: Revenir à la rencontre + withdraw: + error: Une erreur s'est produite lors de l'annulation de la rencontre + success: La réunion a été annulée avec succès metrics: meetings: description: Nombre de rencontres créées diff --git a/decidim-meetings/config/locales/ga-IE.yml b/decidim-meetings/config/locales/ga-IE.yml index 9d6d0263f86ca..70b59c5a0ca0e 100644 --- a/decidim-meetings/config/locales/ga-IE.yml +++ b/decidim-meetings/config/locales/ga-IE.yml @@ -44,7 +44,6 @@ ga: label: Scóip type_eq: values: - hybrid: Araon online: Ar líne meeting_copies: new: @@ -126,17 +125,12 @@ ga: form: invites: Cuirí content_blocks: - upcoming_events: - view_all_events: Amharc ar uile + upcoming_meetings: + view_all_meetings: Amharc ar uile directory: meetings: index: - all: Uile - date: Dáta meetings: Cruinnithe - past: Roimhe - search: Cuardaigh - upcoming: Le teacht layouts: live_event: close: dún @@ -167,7 +161,6 @@ ga: type: Cineál type_values: all: Uile - hybrid: Araon online: Ar líne filters_small_view: filter: Scag @@ -196,7 +189,6 @@ ga: fields: closed: Dúnta end_time: Dáta deiridh - id: Id map: Léarscáil title: Teideal polls: @@ -209,7 +201,6 @@ ga: published_question: question: Ceist type_of_meeting: - hybrid: Araon online: Ar líne metrics: meetings: diff --git a/decidim-meetings/config/locales/gl.yml b/decidim-meetings/config/locales/gl.yml index 4b91be6ae8d57..a75cce708ee6a 100644 --- a/decidim-meetings/config/locales/gl.yml +++ b/decidim-meetings/config/locales/gl.yml @@ -295,24 +295,32 @@ gl: value_types: organizer_presenter: not_found: 'O organizador non se atopou na base de datos (ID: %{id})' + application_helper: + filter_category_values: + all: Todas + filter_meeting_space_values: + all: Todas + filter_scope_values: + all: Todas calendar_modal: calendar_url: URL do calendario close_window: Pechar ventá export_calendar: Calendario de exportación conference_venues: Lugares de conferencias content_blocks: - upcoming_events: - name: Próximos eventos - upcoming_events: Próximas reunións - view_all_events: Ver todo + upcoming_meetings: + name: Vindeiras xuntanzas + upcoming_meetings: Vindeiras xuntanzas + view_all_meetings: Ver todo directory: meetings: index: - all: Todo - date: Data meetings: Reunións - search: Busca space_type: Espazo participativo + iframe_access_level: + all: Todos os visitantes + iframe_embed_type: + open_in_new_tab: Abrir ligazón nunha nova lapela last_activity: meeting_updated_at_html: "Xuntanza actualizada en %{link}" new_meeting_at_html: "Nova reunión en %{link}" @@ -347,6 +355,13 @@ gl: filter: Filtro filter_by: Filtrar por unfold: Despregar + form: + select_an_iframe_access_level: Por favor, selecciona o nivel de acceso ao iframe + index: + click_here: Ver todas as xuntanzas + see_all: Ver todas as xuntanzas + see_all_withdrawn: Ver todas as xuntanzas anuladas + text_banner: Estás a ver todas as xuntanzas anuladas polos seus autores. %{go_back_link}. meeting_minutes: related_information: Información relacionada meetings: @@ -358,6 +373,7 @@ gl: show: attendees: Os asistentes contan contributions: Contribucións contar + edit_close_meeting: Editar o informe da xuntanza going: Inscribícheste nesta xuntaza join: Únete a reunión leave: Cancelar a túa inscrición @@ -373,6 +389,9 @@ gl: one: "%{count} slot restante" other: "%{count} slots restantes" view: Ver + withdraw_btn_hint: Podes anular a túa xuntanza se mudas de parecer. A xuntanza non está anulada, aparecerá na listaxe de xuntanzas anuladas. + withdraw_confirmation_html: Estás certo/a de querer anular esta xuntanza?

Esta acción non pode ser cancelada! + withdraw_meeting: Anular xuntanza meetings_map: view_meeting: Ver reunión models: @@ -429,6 +448,10 @@ gl: types: private_meeting: Encontro privado transparent: Transparente + withdraw: Anular + withdraw: + error: Produciuse un erro ao anular a xuntanza + success: Xuntanza anulada con éxito metrics: meetings: description: Número de reunións creadas diff --git a/decidim-meetings/config/locales/gn-PY.yml b/decidim-meetings/config/locales/gn-PY.yml new file mode 100644 index 0000000000000..bd442b0ad85de --- /dev/null +++ b/decidim-meetings/config/locales/gn-PY.yml @@ -0,0 +1 @@ +gn: diff --git a/decidim-meetings/config/locales/hu.yml b/decidim-meetings/config/locales/hu.yml index c466fc49a2031..c440c73a2fe5e 100644 --- a/decidim-meetings/config/locales/hu.yml +++ b/decidim-meetings/config/locales/hu.yml @@ -44,8 +44,8 @@ hu: models: meeting: attributes: - show_embedded_iframe: - not_embeddable: Ez az URL nem ágyazható be + iframe_embed_type: + not_embeddable: Ez az URL nem ágyazható be az értekezlet vagy az élő esemény oldalába meeting_agenda: attributes: base: @@ -90,7 +90,6 @@ hu: 'false': Előzmények 'true': Közelgő origin_eq: - label: Származás values: citizen: Polgár official: Hivatalos @@ -100,7 +99,7 @@ hu: type_eq: label: Értekezlet típusa values: - hybrid: Mindkettő + hybrid: Hibrid in_person: Személyesen online: Online meeting_copies: @@ -184,7 +183,7 @@ hu: notification_title: A(z) %{resource_title} találkozó kevesebb, mint 48 óra múlva kezdődik. forms: meetings: - attendees_count_help_text: Ne felejtse el megadni az eseményen résztvevők teljes számát. Akár személyesen, akár hibrid, akár online, fontos, hogy tudjuk, hányan vesznek részt. + attendees_count_help_text: Ne felejtse el megadni a találkozón részt vevők teljes számát, akár személyesen, akár online, akár vegyesen. gamification: badges: attended_meetings: @@ -312,7 +311,8 @@ hu: registration_url_help: 'Link: lehetővé teszi a résztvevők számára, hogy a regisztrációhoz a külső szolgáltatást használják' select_a_meeting_type: Válassza ki a találkozó típusát select_a_registration_type: Kérjük, válassza ki a regisztráció típusát - show_embedded_iframe_help: Beágyazza-e az iframe-et ehhez a videokonferencia URL-hez. Csak néhány szolgáltatás engedélyezi a beágyazást (például Youtube, Twitch...) + select_an_iframe_access_level: Kérjük, válassz iframe hozzáférési szintet + show_embedded_iframe_help: Csak néhány szolgáltatás engedélyezi a beágyazást megbeszélésekbe vagy élő eseményekbe (YouTube, Twitch és Jitsi) index: title: Találkozók new: @@ -382,26 +382,37 @@ hu: value_types: organizer_presenter: not_found: 'A szervező nem található az adatbázisban (ID: %{id})' + application_helper: + filter_category_values: + all: Összes + filter_meeting_space_values: + all: Összes + filter_scope_values: + all: Összes calendar_modal: calendar_url: Naptár URL close_window: Ablak bezárása export_calendar: Naptár exportálása conference_venues: Konferencia helyszínek content_blocks: - upcoming_events: - name: Közelgő események - upcoming_events: Közelgő találkozók - view_all_events: Összes megtekintése + upcoming_meetings: + name: Közelgő találkozók + upcoming_meetings: Közelgő találkozók + view_all_meetings: Összes megtekintése directory: meetings: index: - all: Összes - date: Dátum meetings: találkozók - past: Korábban - search: Keresés space_type: Részvételi hely - upcoming: Közelgő + iframe_access_level: + all: Minden látogató + registered: A találkozó regisztrált résztvevői + signed_in: Csak bejelentkezett résztvevők + iframe_embed_type: + embed_in_meeting_page: Beágyazás az értekezlet oldalába + none: Nincs + open_in_live_event_page: Megnyitás az élő esemény oldalán (opcionális szavazásokkal) + open_in_new_tab: Megnyitás új fülön last_activity: meeting_updated_at_html: "Találkozó frissítve %{link}" new_meeting_at_html: "Új találkozó %{link}kor" @@ -459,7 +470,7 @@ hu: type: Típus type_values: all: Összes - hybrid: Mindkettő + hybrid: Hibrid in_person: Személyes online: Online filters_small_view: @@ -471,7 +482,7 @@ hu: address_help: 'Cím: Geocoder használata a helymeghatározáshoz' available_slots_help: Hagyd "0" értéken, ha a jelentkezők száma korlátlan create_as: Ülés létrehozása mint - show_embedded_iframe_help: Beágyazza-e az iframe-et ehhez a videokonferencia URL-hez. Csak néhány szolgáltatás engedélyezi a beágyazást (például Youtube, Twitch...) + show_embedded_iframe_help: Csak néhány szolgáltatás engedélyezi a beágyazást megbeszélésekbe vagy élő eseményekbe (YouTube, Twitch és Jitsi) meeting_minutes: related_information: Kapcsolódó információ meetings: @@ -513,14 +524,11 @@ hu: fields: closed: Lezárt end_time: Befejezés dátuma - id: Id map: Térkép start_time: Kezdő dátum title: Cím polls: questions: - index_admin: - edit: Szerkesztés az admin felületen published_question: question_replied: Kérdés megválaszolva reply_question: Válasz a kérdésre @@ -547,14 +555,18 @@ hu: invalid: Probléma történt a találkozó elhagyása közben. success: Sikeresen elhagytad a találkozót. type_of_meeting: - hybrid: Mindkettő + hybrid: Hibrid in_person: Személyesen online: Online types: private_meeting: Privát találkozó transparent: Átlátszó + withdraw: Visszavonva versions: back_to_resource: Vissza a találkozóhoz + withdraw: + error: A találkozó visszavonása során hiba történt + success: A találkozó visszavonása sikeres metrics: meetings: description: A létrehozott találkozók száma diff --git a/decidim-meetings/config/locales/id-ID.yml b/decidim-meetings/config/locales/id-ID.yml index 623abe8872206..2ba53fcd38ce8 100644 --- a/decidim-meetings/config/locales/id-ID.yml +++ b/decidim-meetings/config/locales/id-ID.yml @@ -285,17 +285,12 @@ id: export_calendar: Ekspor kalender conference_venues: Tempat Konferensi content_blocks: - upcoming_events: - name: Acara Mendatang - upcoming_events: Pertemuan yang akan datang - view_all_events: Lihat semua + upcoming_meetings: + view_all_meetings: Lihat semua directory: meetings: index: - all: Semua - date: Tanggal meetings: Rapat - search: Pencarian space_type: Ruang partisipatif last_activity: new_meeting_at_html: "Pertemuan baru jam %{link}" diff --git a/decidim-meetings/config/locales/it.yml b/decidim-meetings/config/locales/it.yml index bb690bf196969..96823d93f3a7e 100644 --- a/decidim-meetings/config/locales/it.yml +++ b/decidim-meetings/config/locales/it.yml @@ -42,10 +42,6 @@ it: type_of_meeting: Tipo errors: models: - meeting: - attributes: - show_embedded_iframe: - not_embeddable: Questo URL non può essere incorporato meeting_agenda: attributes: base: @@ -100,7 +96,6 @@ it: type_eq: label: Tipologia di incontro values: - hybrid: Entrambi in_person: Fisiche online: Online meeting_copies: @@ -182,9 +177,6 @@ it: email_outro: Hai ricevuto questa notifica perché stai seguendo la riunione "%{resource_title}". Puoi smettere di seguirlo dal link precedente. email_subject: La riunione "%{resource_title}" inizierà tra meno di 48 ore. notification_title: La riunione %{resource_title} inizierà tra meno di 48 ore. - forms: - meetings: - attendees_count_help_text: Non dimenticare di includere il numero totale di partecipanti al tuo evento. Sia fisiche, ibrido o online, è importante sapere quante persone sono coinvolte. gamification: badges: attended_meetings: @@ -309,7 +301,6 @@ it: registration_url_help: 'Link: consentire ai partecipanti di accedere al servizio esterno che stai utilizzando per le iscrizioni' select_a_meeting_type: Seleziona un tipo di riunione select_a_registration_type: Seleziona un tipo di registrazione - show_embedded_iframe_help: Indica se incorporare o meno l'iframe per questo URL della videoconferenza. Solo alcuni servizi consentono l'incorporazione (es. Youtube, Twitch...) index: title: Incontri new: @@ -385,20 +376,13 @@ it: export_calendar: Esporta il calendario conference_venues: Sale per conferenze content_blocks: - upcoming_events: - name: Prossimi eventi - upcoming_events: Prossimi incontri - view_all_events: Guarda tutto + upcoming_meetings: + view_all_meetings: Guarda tutto directory: meetings: index: - all: Tutti - date: Data meetings: Incontri - past: Passata - search: Ricerca space_type: Spazio partecipativo - upcoming: Imminente last_activity: meeting_updated_at_html: "Dibattito aggiornato su %{link}" new_meeting_at_html: "Nuovo incontro al %{link}" @@ -461,7 +445,6 @@ it: type: Tipo type_values: all: Tutti - hybrid: Entrambi in_person: Faccia a faccia online: Online filters_small_view: @@ -481,7 +464,6 @@ it: select_a_category: Scegli una categoria select_a_meeting_type: Seleziona un tipo di riunione select_a_registration_type: Seleziona un tipo di registrazione - show_embedded_iframe_help: Indica se incorporare o meno l'iframe per questo URL della videoconferenza. Solo alcuni servizi consentono l'incorporazione (es. Youtube, Twitch...) index: new_meeting: Nuova riunione meeting_minutes: @@ -502,6 +484,7 @@ it: close_meeting: Chiusura meeting contributions: Conteggio dei contributi date: Data + edit_close_meeting: Modifica rapporto riunione edit_meeting: Modifica la riunione going: Ti sei iscritto a questa riunione join: Partecipa alla riunione @@ -543,7 +526,6 @@ it: fields: closed: Chiuso end_time: Data di fine - id: Id map: Mappa official_meeting: Riunione ufficiale start_time: Data di inizio @@ -556,7 +538,6 @@ it: empty_questions: Durante questa riunione, alcune domande saranno inviate e sarete in grado di rispondere. Verranno visualizzate qui. index_admin: admin_dashboard: Pannello di amministrazione - edit: Modifica nell'amministratore question: Domanda received_answer: risposta ricevuta received_answers: risposte ricevute @@ -594,7 +575,6 @@ it: invalid: C'è stato un problema lasciare questa riunione. success: Hai lasciato l'incontro con successo. type_of_meeting: - hybrid: Entrambi in_person: Di persona online: Online types: diff --git a/decidim-meetings/config/locales/ja.yml b/decidim-meetings/config/locales/ja.yml index f0c02de9970a8..056b99ed3e665 100644 --- a/decidim-meetings/config/locales/ja.yml +++ b/decidim-meetings/config/locales/ja.yml @@ -44,8 +44,8 @@ ja: models: meeting: attributes: - show_embedded_iframe: - not_embeddable: このURLは埋め込めません + iframe_embed_type: + not_embeddable: このURLはミーティングまたはライブイベントページに埋め込むことができません meeting_agenda: attributes: base: @@ -181,7 +181,7 @@ ja: notification_title: %{resource_title} のミーティングは48時間以内に開始されます. forms: meetings: - attendees_count_help_text: イベントに参加者の合計数を含めることを忘れないでください。 対面、ハイブリッド、オンラインに関わらず、何人が関わっているかを知ることが重要です。 + attendees_count_help_text: 会議に出席者の総数に、対面・オンライン・ハイブリッドを含めることを忘れないでください gamification: badges: attended_meetings: @@ -307,7 +307,8 @@ ja: registration_url_help: 'リンク: 参加者が登録に使用している外部サービスにアクセスできるようにします' select_a_meeting_type: ミーティング種別を選択してください select_a_registration_type: 登録種別を選択してください - show_embedded_iframe_help: このビデオ会議URLのiframeを埋め込むかどうか。いくつかのサービスのみが埋め込めます (例:YouTube、Twitchなど) 。 + select_an_iframe_access_level: Iframeアクセスレベルを選択してください + show_embedded_iframe_help: ミーティングやライブイベント( YouTube、Twitch、Jitsi) に埋め込むことができるサービスは限られたもののみです。 index: title: ミーティング new: @@ -376,26 +377,37 @@ ja: value_types: organizer_presenter: not_found: '主催者がデータベース上に見つかりませんでした (ID: %{id})' + application_helper: + filter_category_values: + all: すべて + filter_meeting_space_values: + all: すべて + filter_scope_values: + all: すべて calendar_modal: calendar_url: カレンダー URL close_window: ウィンドウを閉じる export_calendar: カレンダーをエクスポート conference_venues: カンファレンス会場 content_blocks: - upcoming_events: - name: 今後の予定 - upcoming_events: 今後のミーティング - view_all_events: すべて表示 + upcoming_meetings: + name: これからのミーティング + upcoming_meetings: これからのミーティング + view_all_meetings: すべて表示 directory: meetings: index: - all: すべて - date: 日付 meetings: ミーティング - past: 過去 - search: 検索 space_type: 参加型スペース - upcoming: 近日公開 + iframe_access_level: + all: すべての訪問者 + registered: このミーティングに参加者を登録しました + signed_in: ログイン済みの参加者のみ + iframe_embed_type: + embed_in_meeting_page: ミーティングページに埋め込む + none: なし + open_in_live_event_page: ライブイベントページで開く (オプションの投票付き) + open_in_new_tab: URLを新しいタブで開く last_activity: meeting_updated_at_html: "ミーティングが %{link} に更新されました" new_meeting_at_html: " %{link}に新しいミーティング" @@ -477,9 +489,14 @@ ja: select_a_category: カテゴリを選択してください select_a_meeting_type: ミーティング種別を選択してください select_a_registration_type: 登録種別を選択してください - show_embedded_iframe_help: このビデオ会議URLのiframeを埋め込むかどうか。いくつかのサービスのみが埋め込めます (例:YouTube、Twitchなど) 。 + select_an_iframe_access_level: iframeアクセスレベルを選択してください + show_embedded_iframe_help: ミーティングやライブイベント(YouTube、Twitch、Jitsi)に埋め込むことができるサービスは限られたもののみです。 index: + click_here: すべてのミーティングを見る new_meeting: 新しいミーティング + see_all: すべてのミーティングを見る + see_all_withdrawn: 撤回されたすべてのミーティングを見る + text_banner: 作成者が取り消したミーティングの一覧を表示しています. %{go_back_link} meeting_minutes: related_information: 関連情報 meetings: @@ -498,6 +515,7 @@ ja: close_meeting: ミーティングを閉じる contributions: コントリビューション数 date: 日付 + edit_close_meeting: ミーティングレポートを編集 edit_meeting: ミーティングを編集 going: このミーティングにログインしました join: ミーティングに参加 @@ -518,6 +536,9 @@ ja: other: "残り%{count} スロット" view: 表示 visit_finished: 過去のミーティングを表示 + withdraw_btn_hint: 気が変わった場合はミーティングを取り消せます.ミーティングは削除されません.取り消されたミーティングのリストに表示されます. + withdraw_confirmation_html: このミーティングを取り消してもよろしいですか?

この操作はキャンセルできません! + withdraw_meeting: ミーティングを撤回する update: invalid: ミーティングの更新に問題がありました。 success: ミーティングを更新しました. @@ -594,8 +615,12 @@ ja: types: private_meeting: プライベートミーティング transparent: 透明性 + withdraw: 取り消し versions: back_to_resource: ミーティングに戻る + withdraw: + error: ミーティングの取り消し中にエラーが発生しました + success: ミーティングは正常に取り消されました metrics: meetings: description: 作成されたミーティング数 diff --git a/decidim-meetings/config/locales/lb-LU.yml b/decidim-meetings/config/locales/lb-LU.yml index 823df018114f4..017be73579f2a 100644 --- a/decidim-meetings/config/locales/lb-LU.yml +++ b/decidim-meetings/config/locales/lb-LU.yml @@ -1 +1,211 @@ lb: + activemodel: + attributes: + agenda: + description: Beschreibung + duration: Dauer + title: Titel + close_meeting: + attendees_count: Anzahl der Teilnehmer + attending_organizations: Liste der Organisationen, die teilgenommen haben + audio_url: Audio-URL + closing_report: Protokoll + closing_visible: Ist sichtbar + contributions_count: Anzahl der Beiträge + proposal_ids: An der Sitzung entstandene Vorschläge + video_url: Video-URL + meeting: + address: Adresse + available_slots: Verfügbare Slots für dieses Meeting + decidim: + admin: + filters: + meetings: + type_eq: + values: + online: Online + meeting_copies: + create: + error: Es gab einen Fehler beim Duplizieren dieses Meetings. + success: Dupliziertes Meeting erfolgreich + new: + copy: Kopieren + select: Wählen Sie die Daten aus, die Sie duplizieren möchten + title: Doppelte Besprechung + components: + meetings: + actions: + comment: Kommentar + join: Beitreten + name: Meetings + settings: + global: + announcement: Ankündigung + comments_enabled: Kommentare aktiviert + comments_max_length: Maximale Länge der Kommentare (0 für Standardwert) + creation_enabled_for_participants: Teilnehmer können Besprechungen erstellen + default_registration_terms: Standard-Registrierungsbedingungen + enable_pads_creation: Aktivieren Sie die Pads-Erstellung + registration_code_enabled: Registrierungscode aktiviert + resources_permissions_enabled: Aktionsberechtigungen können für jedes Meeting festgelegt werden + scope_id: Bereich + scopes_enabled: Bereiche aktiviert + terms_and_conditions_url_for_meeting_creators: Nutzungsbedingungen URL für Meeting-Ersteller + step: + announcement: Ankündigung + comments_blocked: Kommentare blockiert + creation_enabled_for_participants: Besprechung-Erstellung durch Teilnehmer aktiviert + creation_enabled_for_user_groups: Besprechung-Erstellung durch Benutzergruppen aktiviert + events: + meetings: + meeting_closed: + affected_user: + email_intro: 'Ihre Sitzung "%{resource_title}" wurde geschlossen. Sie können die Ergebnisse auf dieser Seite lesen:' + email_outro: Sie haben diese Benachrichtigung erhalten, weil Sie die Sitzung "%{resource_title}" organisiert haben. + email_subject: Die Sitzung "%{resource_title}" wurde geschlossen + notification_title: Die Sitzung %{resource_title} wurde geschlossen. + follower: + email_intro: 'Die Sitzung "%{resource_title}" wurde geschlossen. Sie können die Ergebnisse auf dieser Seite lesen:' + email_outro: Sie haben diese Benachrichtigung erhalten, weil Sie der Sitzung "%{resource_title}" folgen. Falls Sie keine solchen Benachrichtigungen mehr erhalten möchten, besuchen Sie den obigen Link. + email_subject: Die Sitzung "%{resource_title}" wurde geschlossen + notification_title: Die Sitzung %{resource_title} wurde geschlossen. + meeting_created: + email_intro: Die Sitzung "%{resource_title}" wurde zu "%{participatory_space_title}" hinzugefügt, welchem Sie folgen. + email_outro: Sie haben diese Benachrichtigung erhalten, weil Sie "%{participatory_space_title}" folgen. Falls Sie keine solchen Benachrichtigungen mehr erhalten möchten, besuchen Sie den obigen Link. + email_subject: Neue Sitzung zu %{participatory_space_title} hinzugefügt + notification_title: Die Sitzung %{resource_title} wurde zu %{participatory_space_title} hinzugefügt + meeting_registration_confirmed: + notification_title: Ihre Anmeldung zur Sitzung %{resource_title} wurde bestätigt. Ihr Registrierungscode ist %{registration_code}. + meeting_registrations_over_percentage: + email_intro: Die Slots der Sitzung "%{resource_title}" sind zu über %{percentage}% belegt. + email_outro: Sie haben diese Benachrichtigung erhalten, weil Sie ein Administrator des Teilnahmebereichs der Besprechung sind. + email_subject: Slots der Sitzung "%{resource_title}" über %{percentage}% belegt + notification_title: Die Slots der Sitzung %{resource_title} sind zu über %{percentage}% belegt. + meeting_updated: + email_intro: 'Die Sitzung "%{resource_title}" wurde aktualisiert. Sie können die neue Version auf der Sitzungs-Seite lesen:' + email_outro: Sie haben diese Benachrichtigung erhalten, weil Sie der Sitzung "%{resource_title}" folgen. Falls Sie keine solchen Benachrichtigungen mehr erhalten möchten, besuchen Sie den obigen Link. + email_subject: Die Sitzung "%{resource_title}" wurde aktualisiert + notification_title: Die Sitzung %{resource_title} wurde aktualisiert. + registration_code_validated: + email_intro: Ihr Registrierungscode "%{registration_code}" für die Sitzung "%{resource_title}" wurde bestätigt. + meetings: + admin: + agenda: + edit: + update: Aktualiséieren + form: + add_agenda_item: Tagesordnungspunkt hinzufügen + agenda_items: Tagesordnungspunkte + end_date: Enddatum + start_date: Startdatum + new: + create: Erstellen + title: Neue Agenda + update: + invalid: Beim Aktualisieren dieser Agenda ist ein Problem aufgetreten + success: Agenda erfolgreich aktualisiert + exports: + meeting_comments: Kommentare + meetings: Treffen + registrations: Anmeldungen + invite_join_meeting_mailer: + invite: + decline: Einladung ablehnen + invited_you_to_join_a_meeting: "%{invited_by} hat Sie eingeladen, an einem Meeting um %{application}. Sie können dies über die unten stehenden Links ablehnen oder akzeptieren." + join: Trete dem Meeting '%{meeting_title}' bei + invites: + create: + error: Beim Einladen des Nutzers in das Meeting ist ein Problem aufgetreten. + success: Der Benutzer wurde erfolgreich zum Meeting eingeladen. + form: + attendee_type: Teilnehmertyp + existing_user: Existierender Benutzer + invite: Einladen + invite_explanation: Der Benutzer wird eingeladen, dem Meeting und der Organisation beizutreten. + non_user: Nicht existierender Benutzer + select_user: Nutzer wählen + index: + filter: + accepted: Akzeptiert + all: Alle + rejected: Abgelehnt + sent: Geschickt + filter_by: Filtern nach + invite_attendee: Teilnehmer einladen + invites: Lädt ein + registrations_disabled: Sie können keinen Teilnehmer einladen, da die Registrierungen deaktiviert sind. + search: Suche + meeting_closes: + edit: + close: Schließen + title: Sitzung beenden + meetings: + close: + invalid: Beim Schließen dieses Meetings ist ein Problem aufgetreten + success: Sitzung erfolgreich abgeschlossen + create: + invalid: Beim Erstellen dieses Meetings ist ein Problem aufgetreten + success: Sitzung erfolgreich erstellt. Beachten Sie, dass dies noch nicht veröffentlicht wurde. Sie müssen es manuell veröffentlichen. + destroy: + invalid: + proposals_count: + one: Die Besprechung kann nicht gelöscht werden, da %{count} Vorschlag mit dieser verbunden ist + other: Die Besprechung kann nicht gelöscht werden, da %{count} Vorschläge mit dieser verbunden sind + success: Das Meeting wurde erfolgreich gelöscht + edit: + title: Meeting bearbeiten + update: Aktualisieren + form: + address_help: 'Adresse: wird von Geocoder zur Lokalisierung verwendet' + available_slots_help: Belassen Sie es auf 0, wenn Sie unbegrenzte Plätze zur Verfügung haben + disclaimer: 'Haftungsausschluss: Durch Verwendung eines externen Registrierungssystems wissen Sie, dass die Organisatoren von %{organization} nicht für die Daten verantwortlich sind, welche die Benutzer dem externen Dienst zur Verfügung stellen.' + location_help: 'Ort: an die Benutzer gerichtete Nachricht mit dem Treffpunkt' + location_hints_help: 'Hinweise zum Standort: Zusätzliche Informationen. Beispiel: das Stockwerk im Gebäude wenn es eine Sitzung vor Ort ist, oder das Passwort wenn es eine Online-Sitzung mit eingeschränktem Zugriff ist.' + online_meeting_url_help: 'Link: Erlaubt Teilnehmern, sich direkt mit Ihrem Meeting zu verbinden' + registration_email_help: Dieser Text erscheint in der Mitte der Registrierungs-E-Mail, direkt nach dem Registrierungscode. + calendar_modal: + calendar_url: Kalender-URL + close_window: Fenster schließen + export_calendar: Kalender exportieren + conference_venues: Tagungsstätten + content_blocks: + upcoming_events: + name: Kommende Veranstaltungen + upcoming_events: Bevorstehende Treffen + view_all_events: Alle ansehen + directory: + meetings: + index: + all: Alle + date: Datum + meetings: Meetings + past: Vergangenheit + search: Suche + space_type: Partizipativer Raum + upcoming: Bevorstehende + last_activity: + meeting_updated_at_html: "Besprechung aktualisiert unter %{link}" + new_meeting_at_html: "Neues Treffen um %{link}" + layouts: + live_event: + close: schließen + questions: Fragen + mailer: + invite_join_meeting_mailer: + invite: + subject: Einladung, an einem Meeting teilzunehmen + registration_mailer: + confirmation: + subject: Die Registrierung Ihrer Konferenz wurde bestätigt + meeting: + not_allowed: Sie dürfen dieses Meeting nicht sehen + meeting_closes: + edit: + back: Zurück + close: Sitzung beenden + title: Sitzung beenden + meetings: + calendar_modal: + add_to_calendar: An de Kalenner androen + show: + meeting_minutes: Sitzungsprotokolle diff --git a/decidim-meetings/config/locales/lb.yml b/decidim-meetings/config/locales/lb.yml index 0851005cb7714..162486c43cdd7 100644 --- a/decidim-meetings/config/locales/lb.yml +++ b/decidim-meetings/config/locales/lb.yml @@ -235,7 +235,6 @@ lb: registration_url_help: 'Link: Erlaubt den Teilnehmern den externen Service zu nutzen, den Sie für die Registrierung verwenden' select_a_meeting_type: Bitte eine Meeting-Typ auswählen select_a_registration_type: Bitte wählen Sie eine Registrierungsart aus - show_embedded_iframe_help: Intégrer ou non l'iframe correspondant à cette URL de vidéoconférence. Seuls quelques services permettent l'intégration (c.-à-d. Youtube, Twitch...) index: title: Versammlungen new: @@ -302,15 +301,12 @@ lb: export_calendar: Kalender exportieren conference_venues: Tagungsstätten content_blocks: - upcoming_events: - name: Kommende Veranstaltungen - view_all_events: Alle ansehen + upcoming_meetings: + view_all_meetings: Alle ansehen directory: meetings: index: - all: Alle meetings: Meetings - search: Suche space_type: Partizipativer Raum last_activity: meeting_updated_at_html: "Besprechung aktualisiert unter %{link}" @@ -391,7 +387,6 @@ lb: fields: closed: Geschlossen end_time: Schlussdatum - id: Id map: Kaart official_meeting: Offizielle Besprechung start_time: Ufanksdatum diff --git a/decidim-meetings/config/locales/lo-LA.yml b/decidim-meetings/config/locales/lo-LA.yml new file mode 100644 index 0000000000000..27a02bfece429 --- /dev/null +++ b/decidim-meetings/config/locales/lo-LA.yml @@ -0,0 +1 @@ +lo: diff --git a/decidim-meetings/config/locales/lt.yml b/decidim-meetings/config/locales/lt.yml index a686e52c3af0b..7bc6993388d32 100644 --- a/decidim-meetings/config/locales/lt.yml +++ b/decidim-meetings/config/locales/lt.yml @@ -44,8 +44,8 @@ lt: models: meeting: attributes: - show_embedded_iframe: - not_embeddable: Šis URL negali būti pridėtas + iframe_embed_type: + not_embeddable: Šio URL negalima įterpti į susitikimo ar tiesioginio įvykio puslapį meeting_agenda: attributes: base: @@ -106,7 +106,7 @@ lt: type_eq: label: Susitikimo tipas values: - hybrid: Abu + hybrid: Hibridiniai in_person: Fizinis online: Virtualūs meeting_copies: @@ -190,7 +190,7 @@ lt: notification_title: %{resource_title} Susirinkimas prasidės už mažiau nei 48 val. forms: meetings: - attendees_count_help_text: Nepamirškite nurodyti viso renginio dalyvių skaičiaus. Nesvarbu, ar tai būtų fizinis dalyvavimas, ar hibridas, ar internetu, svarbu žinoti, kiek žmonių dalyvauja. + attendees_count_help_text: Nepamirškite įrašyti dalyvių susirinkime skaičiaus (tiek dalyvaujančių gyvai, tiek nuotoliniu būdu). gamification: badges: attended_meetings: @@ -322,7 +322,8 @@ lt: registration_url_help: 'Nuoroda: leisti dalyviams eiti į išorinę registracijos sistemą' select_a_meeting_type: Prašome pasirinkti susirinkimo tipą select_a_registration_type: Prašome pasirinkti registracijos tipą - show_embedded_iframe_help: Ar įterpti šio vaizdo konferencijos URL „iframe“? Tik kelios paslaugos leidžia įterpimą (pvz., Youtube, Twitch...) + select_an_iframe_access_level: Pasirinkite iframe prieigos lygį + show_embedded_iframe_help: Tik kelios paslaugos gali būti integruotos susitikimuose (YouTube, Twitch, Jitsi) index: title: Susirinkimai new: @@ -394,26 +395,37 @@ lt: value_types: organizer_presenter: not_found: 'Organizatorius duomenų bazėje nerastas (ID: %{id})' + application_helper: + filter_category_values: + all: Visi + filter_meeting_space_values: + all: Visi + filter_scope_values: + all: Visi calendar_modal: calendar_url: Kalendoriaus URL close_window: Uždaryti langą export_calendar: Eksportuoti kalendorių conference_venues: Konferencijos vietos content_blocks: - upcoming_events: - name: Būsimi renginiai - upcoming_events: Artėjantys susirinkimai - view_all_events: Peržiūrėti visus + upcoming_meetings: + name: Artėjantys susirinkimai + upcoming_meetings: Artėjantys susirinkimai + view_all_meetings: Peržiūrėti visus directory: meetings: index: - all: Visi - date: Data meetings: Susirinkimai - past: Praėję - search: Ieškoti space_type: Dalyvaujamoji erdvė - upcoming: Artėjantys + iframe_access_level: + all: Visi lankytojai + registered: Registruoti dalyviai + signed_in: Tik prisijungę dalyviai + iframe_embed_type: + embed_in_meeting_page: Integruoti į susirinkimo puslapį + none: Nėra + open_in_live_event_page: Atidaryti renginio puslapyje (pasirinktinai - su apklausomis) + open_in_new_tab: Atidaryti naujame skirtuke last_activity: meeting_updated_at_html: "Diskusija atnaujinta %{link}" new_meeting_at_html: "Naujas susirinkimas %{link}" @@ -478,7 +490,7 @@ lt: type: Tipas type_values: all: Visi - hybrid: Abu + hybrid: Hibridiniai in_person: Fiziniai online: Virtualūs filters_small_view: @@ -498,9 +510,14 @@ lt: select_a_category: Pasirinkite kategoriją select_a_meeting_type: Pasirinkite susitikimo tipą select_a_registration_type: Pasirinkite registracijos tipą - show_embedded_iframe_help: Ar įterpti šio vaizdo konferencijos URL „iframe“? Tik kelios paslaugos leidžia įterpimą (pvz., Youtube, Twitch...) + select_an_iframe_access_level: Pasirinkite iframe prieigos lygį + show_embedded_iframe_help: Tik kelios paslaugos gali būti integruotos susitikimuose (YouTube, Twitch, Jitsi) index: + click_here: Žiūrėti visus susitikimus new_meeting: Naujas susitikimas + see_all: Žiūrėti visus susitikimus + see_all_withdrawn: Žiūrėti visus atšauktus susitikimus + text_banner: Jūs žiūrite susitikimų, kuriuos atšaukė jų autoriai, sąrašą. %{go_back_link}. meeting_minutes: related_information: Susijusi informacija meetings: @@ -519,6 +536,7 @@ lt: close_meeting: Uždaryti susitikimą contributions: Nuomonių skaičius date: Data + edit_close_meeting: Redaguoti susitikimo ataskaitą edit_meeting: Redaguoti susitikimą going: Jūs užsiregistravote šiame susitikime join: Prisijunkite prie susitikimo @@ -542,6 +560,9 @@ lt: other: "Liko %{count} vietos" view: Peržiūrėti visit_finished: Peržiūrėti susirinkimą + withdraw_btn_hint: Galite išimti susirinkimą jei apsigalvojoje. Susirinkimas nebus ištrintas - jis atsidurs išimtų susirinkimų sąraše. + withdraw_confirmation_html: Ar tikrai norite išimti šį susirinkimą?

Šio veiksmo atšaukti negalima! + withdraw_meeting: Išimti susirinkimą update: invalid: Atnaujinant susirinkimą iškilo problema. success: Sėkmingai atnaujinote susirinkimą. @@ -562,7 +583,7 @@ lt: fields: closed: Uždaryta end_time: Pabaigos data - id: Id + id: ID map: Žemėlapis official_meeting: Oficialus susirinkimas start_time: Pradžios data @@ -615,14 +636,18 @@ lt: invalid: Paliekant šį susirinkimą iškilo problema. success: Sėkmingai palikote susirinkimą. type_of_meeting: - hybrid: Abu + hybrid: Hibridinis in_person: Fizinis online: Virtualus types: private_meeting: Uždaras posėdis transparent: Skaidrus + withdraw: Atsiimta versions: back_to_resource: Grįžti į susirinkimą + withdraw: + error: Išimant susirinkimą įvyko klaida + success: Susirinkimas sėkmingai išimtas metrics: meetings: description: Sukurtų susirinkimų skaičius diff --git a/decidim-meetings/config/locales/lv.yml b/decidim-meetings/config/locales/lv.yml index f7abc6cbc892b..dc9c14503be0c 100644 --- a/decidim-meetings/config/locales/lv.yml +++ b/decidim-meetings/config/locales/lv.yml @@ -298,17 +298,12 @@ lv: export_calendar: Eksportēt kalendāru conference_venues: Konferenču norises vietas content_blocks: - upcoming_events: - name: Gaidāmie notikumi - upcoming_events: Gaidāmās sanāksmes - view_all_events: Skatīt visu + upcoming_meetings: + view_all_meetings: Skatīt visu directory: meetings: index: - all: Visi - date: Datums meetings: Sanāksmes - search: Meklēt space_type: Līdzdalības telpa last_activity: new_meeting_at_html: "Jauna sanāksme plkst. %{link}" diff --git a/decidim-meetings/config/locales/nl.yml b/decidim-meetings/config/locales/nl.yml index d2f90178bf5fc..adc9dfce80b8e 100644 --- a/decidim-meetings/config/locales/nl.yml +++ b/decidim-meetings/config/locales/nl.yml @@ -42,6 +42,10 @@ nl: type_of_meeting: Type errors: models: + meeting: + attributes: + iframe_embed_type: + not_embeddable: Deze URL kan niet worden ingesloten in vergadering of live evenement pagina meeting_agenda: attributes: base: @@ -96,7 +100,7 @@ nl: type_eq: label: Type vergadering values: - hybrid: Beide + hybrid: Hybride in_person: Fysiek online: Online meeting_copies: @@ -180,7 +184,7 @@ nl: notification_title: Het %{resource_title} event begint over minder dan 48 uur. forms: meetings: - attendees_count_help_text: Vergeet niet het totale aantal deelnemers op je evenement toe te voegen. Of het nu een fysieke, hybride of online bijeenkomst is, het is handig om het aantal mensen te kennen. + attendees_count_help_text: Vergeet niet om het totale aantal deelnemers aan je vergadering toe te voegen, of het nu een fysieke, online of hybride bijeenkomst is. gamification: badges: attended_meetings: @@ -308,6 +312,7 @@ nl: registration_url_help: 'Link: verleen deelnemers toegang tot de externe dienst die je gebruikt voor registraties' select_a_meeting_type: Selecteer een vergaderingstype select_a_registration_type: Selecteer een registratietype + select_an_iframe_access_level: Selecteer een iframe toegangsniveau index: title: Events new: @@ -377,26 +382,37 @@ nl: value_types: organizer_presenter: not_found: 'De organisator is niet gevonden in de database (ID: %{id})' + application_helper: + filter_category_values: + all: Alle + filter_meeting_space_values: + all: Alle + filter_scope_values: + all: Alle calendar_modal: calendar_url: Agenda-URL close_window: Venster sluiten export_calendar: Kalender exporteren conference_venues: Vergaderlocaties content_blocks: - upcoming_events: - name: Aankomende evenementen - upcoming_events: Aankomende vergaderingen - view_all_events: Bekijk alles + upcoming_meetings: + name: Geplande vergaderingen + upcoming_meetings: Geplande vergaderingen + view_all_meetings: Bekijk alles directory: meetings: index: - all: Alle - date: Datum meetings: vergaderingen - past: Voorbij - search: Zoeken space_type: Participatieve ruimte - upcoming: Toekomstige + iframe_access_level: + all: Alle bezoekers + registered: Geregistreerde deelnemers aan deze vergadering + signed_in: Alleen ingelogde deelnemers + iframe_embed_type: + embed_in_meeting_page: Insluiten in vergaderpagina + none: Geen + open_in_live_event_page: Open in live event pagina (met optionele polls) + open_in_new_tab: Open link in een nieuw tabblad last_activity: meeting_updated_at_html: "Vergadering bijgewerkt op %{link}" new_meeting_at_html: "Nieuwe vergadering op %{link}" @@ -459,7 +475,7 @@ nl: type: Type type_values: all: Alle - hybrid: Beide + hybrid: Hybride in_person: Fysiek online: Online filters_small_view: @@ -479,8 +495,13 @@ nl: select_a_category: Selecteer een categorie select_a_meeting_type: Selecteer een vergaderingstype select_a_registration_type: Selecteer een registratietype + select_an_iframe_access_level: Selecteer een iframe toegangsniveau index: + click_here: Alle vergaderingen bekijken new_meeting: Nieuwe vergadering + see_all: Alle vergaderingen bekijken + see_all_withdrawn: Bekijk alle afgelaste vergaderingen + text_banner: Je bekijkt de lijst van vergaderingen die zijn afgelast door hun maker. %{go_back_link}. meeting_minutes: related_information: Gerelateerde informatie meetings: @@ -499,6 +520,7 @@ nl: close_meeting: Vergadering sluiten contributions: Aantal bijdragen date: Datum + edit_close_meeting: Bewerk vergaderverslag edit_meeting: Vergadering bewerken going: Je hebt je ingeschreven voor deze vergadering join: Deelnemen aan bijeenkomst @@ -520,6 +542,9 @@ nl: other: "%{count} resterende plaatsen" view: Bekijk visit_finished: Bekijk voorbije vergadering + withdraw_btn_hint: Je kunt je vergadering afgelasten indien nodig. De vergadering wordt niet verwijderd, deze verschijnt in de lijst met afgelaste vergaderingen. + withdraw_confirmation_html: Weet je zeker dat je deze vergadering wil afgelasten?

Deze actie kan niet worden ongedaan gemaakt + withdraw_meeting: Vergadering afgelasten update: invalid: Er was een probleem bij het bijwerken van de vergadering. success: De vergadering is succesvol bijgewerkt. @@ -540,7 +565,7 @@ nl: fields: closed: Gesloten end_time: Einddatum - id: Id + id: ID map: Kaart official_meeting: Officiële vergadering start_time: Startdatum @@ -591,14 +616,18 @@ nl: invalid: Er is een probleem opgetreden bij het verlaten van deze vergadering. success: U heeft de vergadering succesvol verlaten. type_of_meeting: - hybrid: Beide + hybrid: Hybride in_person: Fysiek online: Online types: private_meeting: Privé vergadering transparent: Transparant + withdraw: Afgelasten versions: back_to_resource: Ga terug naar de vergadering + withdraw: + error: Er is een fout opgetreden tijdens het afgelasten van de vergadering + success: De vergadering is met succes afgelast metrics: meetings: description: Aantal gemaakte vergaderingen diff --git a/decidim-meetings/config/locales/no.yml b/decidim-meetings/config/locales/no.yml index 8b419d1e628b1..26ffbb598a8d6 100644 --- a/decidim-meetings/config/locales/no.yml +++ b/decidim-meetings/config/locales/no.yml @@ -43,8 +43,8 @@ models: meeting: attributes: - show_embedded_iframe: - not_embeddable: Denne URL-adressen kan ikke legges til + iframe_embed_type: + not_embeddable: Denne URL-adressen kan ikke bygges inn i møte eller arrangementsside meeting_agenda: attributes: base: @@ -99,7 +99,6 @@ type_eq: label: Type møte values: - hybrid: Begge in_person: Tilstede online: Digitalt meeting_copies: @@ -181,9 +180,6 @@ email_outro: Du har mottatt denne varslingen fordi du følger "%{resource_title}" møte. Du kan slutte å følge den fra den forrige lenken. email_subject: '"%{resource_title}" møtet starter om mindre enn 48 timer.' notification_title: %{resource_title} møtet starter om mindre enn 48 timer. - forms: - meetings: - attendees_count_help_text: Ikke glem å inkludere det totale antallet deltakere ved arrangementet. Hvorvidt det skal være fysisk, hybrid, eller på nett, er det viktig at vi vet hvor mange som er involvert. gamification: badges: attended_meetings: @@ -311,7 +307,8 @@ registration_url_help: 'Lenke: La deltakerne gå på den eksterne tjenesten du bruker for registreringer' select_a_meeting_type: Vennligst velg en møtetype select_a_registration_type: Velg en registreringstype - show_embedded_iframe_help: Gjerne legg til en iframe for denne videokonferansens URL. Kun noen få tjenester tillater innbygging (dvs. YouTube, Twitch...) + select_an_iframe_access_level: Velg et tilgangsnivå for iframe + show_embedded_iframe_help: Kun noen få tjenester tillater integrering i møte eller direktearrangement (YouTube, Twitch og Jitsi) index: title: Møter new: @@ -380,26 +377,36 @@ value_types: organizer_presenter: not_found: 'Arrangøren ble ikke funnet i databasen (ID: %{id})' + application_helper: + filter_category_values: + all: Alle + filter_meeting_space_values: + all: Alle + filter_scope_values: + all: Alle calendar_modal: calendar_url: Kalender URL close_window: Lukk vindu export_calendar: Eksporter kalender conference_venues: Konferanse Arenaer content_blocks: - upcoming_events: - name: Kommende hendelser - upcoming_events: Kommende møter - view_all_events: Vis alle + upcoming_meetings: + name: Kommende møter + upcoming_meetings: Kommende møter + view_all_meetings: Vis alle directory: meetings: index: - all: Alle - date: Dato meetings: Møter - past: Tidligere - search: Søk space_type: Deltakerområde - upcoming: Kommende + iframe_access_level: + all: Alle besøkende + registered: Registrerte deltakere til dette møtet + signed_in: Bare påloggede deltakere + iframe_embed_type: + embed_in_meeting_page: Bygg inn på møteside + none: Ingen + open_in_live_event_page: Åpne på siden for direktearrangement (med valgfri meningsmåling) last_activity: new_meeting_at_html: "Nytt møte på %{link}" layouts: @@ -461,7 +468,6 @@ type: Type type_values: all: Alle - hybrid: Begge in_person: Fysisk online: Digitalt filters_small_view: @@ -476,8 +482,9 @@ select_a_category: Velg en kategori select_a_meeting_type: Velg en møtetype select_a_registration_type: Velg en registreringstype - show_embedded_iframe_help: Gjerne legg til en iframe for denne videokonferansens URL. Kun noen få tjenester tillater innbygging (dvs. YouTube, Twitch...) + select_an_iframe_access_level: Velg et tilgangsnivå for iframe index: + click_here: Se alle møter new_meeting: Nytt møte meeting_minutes: related_information: Relatert Informasjon @@ -534,7 +541,6 @@ empty_questions: Gjennom dette møtet stilles noen spørsmål, og du vil kunne svare på dem. De vil bli vist her. index_admin: admin_dashboard: Administrators dashbord - edit: Rediger i admin question: Spørsmål received_answer: mottatt svar received_answers: mottatt svar diff --git a/decidim-meetings/config/locales/oc-FR.yml b/decidim-meetings/config/locales/oc-FR.yml new file mode 100644 index 0000000000000..325b348894124 --- /dev/null +++ b/decidim-meetings/config/locales/oc-FR.yml @@ -0,0 +1 @@ +oc: diff --git a/decidim-meetings/config/locales/pl.yml b/decidim-meetings/config/locales/pl.yml index 28fb59b27bb72..9e848c7bd243c 100644 --- a/decidim-meetings/config/locales/pl.yml +++ b/decidim-meetings/config/locales/pl.yml @@ -90,7 +90,6 @@ pl: official: Oficjalny type_eq: values: - hybrid: Oba online: Online meeting_copies: create: @@ -297,6 +296,7 @@ pl: registration_url_help: 'Link: zezwól użytkownikom na korzystanie z usługi zewnętrznej, której używasz do rejestracji' select_a_meeting_type: Wybierz typ spotkania select_a_registration_type: Wybierz typ rejestracji + show_embedded_iframe_help: Tylko kilka usług pozwala na osadzanie w spotkaniu lub wydarzeniu na żywo (YouTube, Twitch i Jitsi) index: title: Spotkania new: @@ -371,20 +371,13 @@ pl: export_calendar: Eksportuj kalendarz conference_venues: Sale konferencyjne content_blocks: - upcoming_events: - name: Nadchodzące wydarzenia - upcoming_events: Nadchodzące spotkania - view_all_events: Pokaż wszystkie + upcoming_meetings: + view_all_meetings: Pokaż wszystkie directory: meetings: index: - all: Wszystko - date: Data meetings: Spotkania - past: Przeszłe - search: Szukaj space_type: Przestrzeń partycypacyjna - upcoming: Nadchodzące last_activity: meeting_updated_at_html: "Spotkanie zaktualizowane o %{link}" new_meeting_at_html: "Nowe spotkanie %{link}" @@ -443,7 +436,6 @@ pl: type: Typ type_values: all: Wszystko - hybrid: Oba in_person: Osobiście online: Online filters_small_view: @@ -463,6 +455,7 @@ pl: select_a_category: Wybierz kategorię select_a_meeting_type: Wybierz typ spotkania select_a_registration_type: Wybierz typ rejestracji + show_embedded_iframe_help: Tylko kilka usług pozwala na osadzanie w spotkaniu lub wydarzeniu na żywo (YouTube, Twitch i Jitsi) index: new_meeting: Nowe spotkanie meeting_minutes: @@ -553,7 +546,7 @@ pl: invalid: Wystąpił błąd podczas próby opuszczenia tego spotkania. success: Opuściłeś spotkanie. type_of_meeting: - hybrid: Oba + hybrid: Hybrydowe in_person: Osobiście online: Online types: diff --git a/decidim-meetings/config/locales/pt-BR.yml b/decidim-meetings/config/locales/pt-BR.yml index ee478324e9080..8fd3179b4b930 100644 --- a/decidim-meetings/config/locales/pt-BR.yml +++ b/decidim-meetings/config/locales/pt-BR.yml @@ -77,7 +77,6 @@ pt-BR: official: Oficial type_eq: values: - hybrid: Ambos online: On-line meeting_copies: create: @@ -356,20 +355,13 @@ pt-BR: export_calendar: Calendário de exportação conference_venues: Locais de conferência content_blocks: - upcoming_events: - name: Próximos eventos - upcoming_events: Próximas reuniões - view_all_events: Ver tudo + upcoming_meetings: + view_all_meetings: Ver tudo directory: meetings: index: - all: Tudo - date: Data meetings: Reuniões - past: Passado - search: Pesquisar space_type: Espaço participativo - upcoming: Próximos last_activity: meeting_updated_at_html: "Novo debate em %{link}" new_meeting_at_html: "Nova reunião em %{link}" @@ -432,7 +424,6 @@ pt-BR: type: Tipo type_values: all: Tudo - hybrid: Ambos in_person: Pessoalmente online: On-line filters_small_view: @@ -521,7 +512,6 @@ pt-BR: empty_questions: Durante esta reunião, algumas perguntas serão enviadas e você poderá respondê-las. Elas serão exibidas aqui. index_admin: admin_dashboard: Painel de administração - edit: Editar no admin question: Pergunta received_answer: resposta recebida received_answers: respostas recebidas @@ -559,7 +549,6 @@ pt-BR: invalid: Tem havido um problema ao sair desta reunião. success: Você saiu da reunião com sucesso. type_of_meeting: - hybrid: Ambos in_person: Pessoalmente online: On-line types: diff --git a/decidim-meetings/config/locales/pt.yml b/decidim-meetings/config/locales/pt.yml index 75b0545c69004..fe835b57ad6d4 100644 --- a/decidim-meetings/config/locales/pt.yml +++ b/decidim-meetings/config/locales/pt.yml @@ -42,10 +42,6 @@ pt: type_of_meeting: Tipo errors: models: - meeting: - attributes: - show_embedded_iframe: - not_embeddable: Este URL não pode ser embutido meeting_agenda: attributes: base: @@ -100,7 +96,6 @@ pt: type_eq: label: Tipo de reunião values: - hybrid: Ambos in_person: Presencialmente online: On-line meeting_copies: @@ -182,9 +177,6 @@ pt: email_outro: Recebeu esta notificação porque segue a reunião "%{resource_title}". Pode deixar de segui-la a partir da hiperligação anterior. email_subject: A reunião "%{resource_title}" começará em menos de 48h. notification_title: A reunião %{resource_title} começará em menos de 48h. - forms: - meetings: - attendees_count_help_text: Não se esquece de incluir o número total de participantes no seu evento. Seja presencialmente, híbrido, ou on-line, o importante é saber quantas pessoas estão envolvidas. gamification: badges: attended_meetings: @@ -309,7 +301,6 @@ pt: registration_url_help: 'Ligação: permitir aos participantes dirigirem-se ao serviço externo que está a usar para os registos' select_a_meeting_type: Por favor seleccione um tipo de reunião select_a_registration_type: Por favor seleccione um tipo de registo - show_embedded_iframe_help: URL para embutir ou não um iframe para esta video conferência. Só alguns serviços permitem ser embutidos (por exemplo, Youtube, Twitch...) index: title: Reuniões new: @@ -385,20 +376,13 @@ pt: export_calendar: Exportar calendário conference_venues: Locais da Conferência content_blocks: - upcoming_events: - name: Próximos eventos - upcoming_events: Próximas reuniões - view_all_events: Ver todos + upcoming_meetings: + view_all_meetings: Ver todos directory: meetings: index: - all: Todos - date: Data meetings: Reuniões - past: Passado - search: Pesquisar space_type: Espaço participativo - upcoming: Próximas last_activity: meeting_updated_at_html: "Proposta actualizada em %{link}" new_meeting_at_html: "Nova reunião em %{link}" @@ -461,7 +445,6 @@ pt: type: Tipo type_values: all: Todos - hybrid: Ambos in_person: Presencial online: On-line filters_small_view: @@ -481,7 +464,6 @@ pt: select_a_category: Por favor selecione uma categoria select_a_meeting_type: Por favor seleccione um tipo de reunião select_a_registration_type: Por favor seleccione um tipo de registo - show_embedded_iframe_help: URL para embutir ou não um iframe para esta video conferência. Só alguns serviços permitem ser embutidos (por exemplo, Youtube, Twitch...) index: new_meeting: Nova reunião meeting_minutes: @@ -543,7 +525,6 @@ pt: fields: closed: Encerradas end_time: Data final - id: Identificação map: Mapa official_meeting: Reunião oficial start_time: Data de início @@ -556,7 +537,6 @@ pt: empty_questions: Durante esta reunião irão ser-lhe enviadas algumas questões e poderá responder-lhes. Serão exibidas aqui. index_admin: admin_dashboard: Painel de controlo de administrador - edit: Editar administrador question: Questão received_answer: resposta recebida received_answers: respostas recebidas @@ -594,7 +574,6 @@ pt: invalid: Ocorreu um problema ao sair desta reunião. success: Saiu da reunião corretamente. type_of_meeting: - hybrid: Ambos in_person: Presencial online: On-line types: diff --git a/decidim-meetings/config/locales/ro-RO.yml b/decidim-meetings/config/locales/ro-RO.yml index 057e5978ac0de..3c247c428089d 100644 --- a/decidim-meetings/config/locales/ro-RO.yml +++ b/decidim-meetings/config/locales/ro-RO.yml @@ -44,8 +44,8 @@ ro: models: meeting: attributes: - show_embedded_iframe: - not_embeddable: Acest URL nu poate fi încorporat + iframe_embed_type: + not_embeddable: Această adresă URL nu poate fi încorporată în ședință sau în pagina de evenimente live meeting_agenda: attributes: base: @@ -103,7 +103,7 @@ ro: type_eq: label: Tip de întâlnire values: - hybrid: Ambele + hybrid: Hibrid in_person: În persoană online: Online meeting_copies: @@ -187,7 +187,7 @@ ro: notification_title: Ședința %{resource_title} va începe în mai puțin de 48 de ore. forms: meetings: - attendees_count_help_text: Nu uita să incluzi numărul total de participanți la evenimentul tău. Indiferent dacă întâlnirea este în persoană, hibridă sau online, este important să ştim câţi oameni sunt implicaţi. + attendees_count_help_text: Nu uitați să includeți numărul total de participanți la întâlnire, fie că este vorba de persoane fizice, online sau hibride. gamification: badges: attended_meetings: @@ -317,7 +317,7 @@ ro: registration_url_help: 'Link: permite participanților să acceseze serviciul extern pe care îl utilizezi pentru înregistrare' select_a_meeting_type: Te rugăm să selectezi un tip de ședință select_a_registration_type: Te rugăm să selectezi un tip de înregistrare - show_embedded_iframe_help: Indiferent dacă iframe este încorporat sau nu în acest URL pentru videoconferință. Doar câteva servicii permit încorporarea (de exemplu, Youtube, Twitch...) + select_an_iframe_access_level: Vă rugăm să selectați un nivel de acces iframe index: title: Întâlniri new: @@ -388,26 +388,36 @@ ro: value_types: organizer_presenter: not_found: 'Organizatorul nu a fost găsit în baza de date (ID: %{id})' + application_helper: + filter_category_values: + all: Toate + filter_meeting_space_values: + all: Toate + filter_scope_values: + all: Toate calendar_modal: calendar_url: URL Calendar close_window: Închide fereastra export_calendar: Exportă calendarul conference_venues: Locuri ale conferinței content_blocks: - upcoming_events: - name: Evenimente viitoare - upcoming_events: Întâlniri viitoare - view_all_events: Vezi toate + upcoming_meetings: + name: Şedinţe viitoare + upcoming_meetings: Şedinţe viitoare + view_all_meetings: Vezi toate directory: meetings: index: - all: Toate - date: Data meetings: Întâlniri - past: Trecute - search: Caută space_type: Spaţiu participativ - upcoming: Viitoare + iframe_access_level: + all: Toți vizitatorii + registered: Participanții înregistrați la acest eveniment + iframe_embed_type: + embed_in_meeting_page: Incorporează în pagina de şedinţe + none: Niciunul + open_in_live_event_page: Deschide în pagina de evenimente live (cu sondaje opționale) + open_in_new_tab: Deschideți în filă nouă last_activity: meeting_updated_at_html: "Întâlnire actualizată la %{link}" new_meeting_at_html: "O nouă ședință la %{link}" @@ -471,7 +481,7 @@ ro: type: Tip type_values: all: Toate - hybrid: Ambele + hybrid: Hibrid in_person: În persoană online: Online filters_small_view: @@ -491,9 +501,12 @@ ro: select_a_category: Te rugăm să selectezi o categorie select_a_meeting_type: Te rugăm să selectezi un tip de ședință select_a_registration_type: Te rugăm să selectezi un tip de înregistrare - show_embedded_iframe_help: Indiferent dacă iframe este încorporat sau nu în acest URL pentru videoconferință. Doar câteva servicii permit încorporarea (de exemplu, Youtube, Twitch...) index: + click_here: Vezi toate întâlnirile new_meeting: Întâlnire nouă + see_all: Vezi toate întâlnirile + see_all_withdrawn: Afișează toate întâlnirile anulate + text_banner: Vizualizezi lista de întâlniri anulate de autorii lor. %{go_back_link}. meeting_minutes: related_information: Informații asociate meetings: @@ -512,6 +525,7 @@ ro: close_meeting: Închide ședința contributions: Număr de contribuții date: Data + edit_close_meeting: Editează raportul întâlnirii edit_meeting: Editează întâlnirea going: Te-ai înregistrat pentru această întâlnire join: Participă la întâlnire @@ -534,6 +548,9 @@ ro: other: "%{count} sloturi rămase" view: Vizualizare visit_finished: Arată întâlniri deja desfășurate + withdraw_btn_hint: Poți să anulezi întâlnirea dacă te răzgândești. Întâlnirea nu va fi ștearsă, ci va apărea în lista de întâlniri anulate. + withdraw_confirmation_html: Sigur dorești să retragi această întâlnire?

Această acțiune nu poate fi anulată! + withdraw_meeting: Anulează întâlnirea update: invalid: A apărut o eroare la actualizarea ședinței. success: Ai actualizat întâlnirea cu succes. @@ -554,7 +571,6 @@ ro: fields: closed: Închis end_time: Data de încheiere - id: Id map: Hartă official_meeting: Întâlnire publică start_time: Data de început @@ -567,7 +583,7 @@ ro: empty_questions: Pe parcursul acestei întâlniri, vor fi trimise câteva întrebări și vei putea răspunde la acestea. Acestea vor fi afișate aici. index_admin: admin_dashboard: Panou de administrare - edit: Editează în admin + edit: Editează în panoul de administrare question: Întrebare received_answer: răspuns primit received_answers: răspunsuri primite @@ -606,14 +622,18 @@ ro: invalid: A existat o problemă la părăsirea acestei reuniuni. success: Ai părăsit şedinţa cu succes. type_of_meeting: - hybrid: Ambele + hybrid: Hibrid in_person: În persoană online: Online types: private_meeting: Întâlnire privată transparent: Transparent + withdraw: Retrasă versions: back_to_resource: Intră din nou în întâlnire + withdraw: + error: S-a produs o eroare la retragerea întâlnirii + success: Întâlnirea a fost anulată metrics: meetings: description: Numărul de întâlniri create diff --git a/decidim-meetings/config/locales/ru.yml b/decidim-meetings/config/locales/ru.yml index eb057648e2c6f..792e2d1f44361 100644 --- a/decidim-meetings/config/locales/ru.yml +++ b/decidim-meetings/config/locales/ru.yml @@ -289,17 +289,10 @@ ru: calendar_url: Ссылка на календарь close_window: Закрыть окно export_calendar: Экспорт календаря - content_blocks: - upcoming_events: - name: Предстоящие события - upcoming_events: Предстоящие встречи directory: meetings: index: - all: Все - date: Дата meetings: Встречи - search: Поиск last_activity: new_meeting_at_html: "Новая встреча в %{link}" mailer: diff --git a/decidim-meetings/config/locales/sk.yml b/decidim-meetings/config/locales/sk.yml index 34b990a6187d4..ade89d576003d 100644 --- a/decidim-meetings/config/locales/sk.yml +++ b/decidim-meetings/config/locales/sk.yml @@ -302,17 +302,12 @@ sk: export_calendar: Exportovať kalendár conference_venues: Konferenčné priestory content_blocks: - upcoming_events: - name: Pripravované akcie - upcoming_events: Nadchádzajúce schôdzky - view_all_events: Zobraziť všetko + upcoming_meetings: + view_all_meetings: Zobraziť všetko directory: meetings: index: - all: Všetko - date: dátum meetings: Stretnutie - search: Vyhľadávanie space_type: Zúčastňujú priestor last_activity: new_meeting_at_html: " Nové stretnutie v %{link} " diff --git a/decidim-meetings/config/locales/sv.yml b/decidim-meetings/config/locales/sv.yml index acd4b231eb25b..a0e467a5fa82f 100644 --- a/decidim-meetings/config/locales/sv.yml +++ b/decidim-meetings/config/locales/sv.yml @@ -44,8 +44,8 @@ sv: models: meeting: attributes: - show_embedded_iframe: - not_embeddable: URL:en kan inte integreras + iframe_embed_type: + not_embeddable: Denna URL kan inte bäddas in på ett mötes- eller liveevenemangssida meeting_agenda: attributes: base: @@ -100,7 +100,7 @@ sv: type_eq: label: Mötestyp values: - hybrid: Båda + hybrid: Hybrid in_person: Fysiska online: Online meeting_copies: @@ -182,9 +182,6 @@ sv: email_outro: Du har fått det här meddelandet eftersom du följer mötet "%{resource_title}". Du kan sluta följa det på föregående länk. email_subject: Mötet "%{resource_title}" börjar om färre än 48 timmar. notification_title: Mötet %{resource_title} startar inom mindre än 48 timmar. - forms: - meetings: - attendees_count_help_text: Glöm inte att inkludera det totala antalet deltagare på ditt evenemang. Det är viktigt att hålla koll på hur många människor, oavsett om de deltog fysiskt eller online. gamification: badges: attended_meetings: @@ -312,7 +309,8 @@ sv: registration_url_help: 'Länk: tillåt deltagare att registrera sig på en extern tjänst' select_a_meeting_type: Välj mötestyp select_a_registration_type: Välj en registreringsmetod - show_embedded_iframe_help: Välj om adressen ska integreras som iframe. Endast ett fåtal tjänster tillåter integrering (t.ex. Youtube, Twitch...) + select_an_iframe_access_level: Välj vem får tillgång till denna iframe + show_embedded_iframe_help: Endast ett fåtal tjänster tillåter inbäddning i möten eller live-event (t.ex. YouTube, Twitch och Jitsi) index: title: Möten new: @@ -382,26 +380,37 @@ sv: value_types: organizer_presenter: not_found: 'Arrangören hittades inte i databasen (ID: %{id})' + application_helper: + filter_category_values: + all: Alla + filter_meeting_space_values: + all: Alla + filter_scope_values: + all: Alla calendar_modal: calendar_url: Kalender-URL close_window: Stäng fönster export_calendar: Exportera kalender conference_venues: Konferenslokaler content_blocks: - upcoming_events: - name: Kommande händelser - upcoming_events: Kommande möten - view_all_events: Visa alla + upcoming_meetings: + name: Kommande möten + upcoming_meetings: Kommande möten + view_all_meetings: Visa alla directory: meetings: index: - all: Allt - date: Datum meetings: Möten - past: Tidigare - search: Sök space_type: Deltagarutrymme - upcoming: Kommande + iframe_access_level: + all: Alla besökare + registered: Registrerade deltagare till detta möte + signed_in: Endast registrerade deltagare + iframe_embed_type: + embed_in_meeting_page: Bädda in på mötessidan + none: Ingen + open_in_live_event_page: Öppna i live event sida (med valfria omröstningar) + open_in_new_tab: Öppna länk i ny flik last_activity: meeting_updated_at_html: "Mötet uppdaterades på %{link}" new_meeting_at_html: "Nytt möte på %{link}" @@ -464,7 +473,7 @@ sv: type: Typ type_values: all: Allt - hybrid: Båda + hybrid: Hybrid in_person: Fysiska online: Online filters_small_view: @@ -484,9 +493,14 @@ sv: select_a_category: Välj en kategori select_a_meeting_type: Välj mötestyp select_a_registration_type: Välj en registreringsmetod - show_embedded_iframe_help: Välj om adressen ska integreras som iframe. Endast ett fåtal tjänster tillåter integrering (t.ex. Youtube, Twitch...) + select_an_iframe_access_level: Välj vem får tillgång till denna iframe + show_embedded_iframe_help: Endast ett fåtal tjänster tillåter inbäddning i möten eller live-event (t.ex. YouTube, Twitch och Jitsi) index: + click_here: Se alla möten new_meeting: Nytt möte + see_all: Se alla möten + see_all_withdrawn: Se alla tillbakadragna möten + text_banner: Du tittar på listan över möten som dragits tillbaka av sina författare. %{go_back_link}. meeting_minutes: related_information: Relaterad information meetings: @@ -505,6 +519,7 @@ sv: close_meeting: Avsluta möte contributions: Antal bidrag date: Datum + edit_close_meeting: Redigera mötesrapport edit_meeting: Redigera möte going: Du har anmält dig för detta möte join: Gå med i mötet @@ -526,6 +541,9 @@ sv: other: "%{count} platser kvar" view: Visa visit_finished: Visa tidigare möten + withdraw_btn_hint: Du kan dra tillbaka ditt möte om du ändrar dig. Mötet raderas inte utan kommer att synas i listan över möten som dragits tillbaka. + withdraw_confirmation_html: Är du säker på att du vill dra tillbaka det här mötet?

Den här åtgärden kan inte ångras! + withdraw_meeting: Dra tillbaka möte update: invalid: Det gick inte att uppdatera mötet. success: Du har uppdaterat mötet. @@ -546,7 +564,7 @@ sv: fields: closed: Stängd end_time: Slutdatum - id: Id + id: ID map: Karta official_meeting: Officiellt möte start_time: Startdatum @@ -559,7 +577,6 @@ sv: empty_questions: Under hela mötet kommer några frågor att skickas och du kommer kunna svara på dem. De kommer att visas här. index_admin: admin_dashboard: Adminpanel - edit: Redigera i adminpanelen question: Fråga received_answer: mottaget svar received_answers: mottagna svar @@ -597,14 +614,18 @@ sv: invalid: Det gick inte att lämna mötet. success: Du har lämnat mötet. type_of_meeting: - hybrid: Båda + hybrid: Hybrid in_person: Fysiska online: Online types: private_meeting: Privat möte transparent: Transparent + withdraw: Tillbakadragna versions: back_to_resource: Gå tillbaka till mötet + withdraw: + error: Det gick inte att dra tillbaka mötet + success: Mötet har dragits tillbaka metrics: meetings: description: Antal skapade möten diff --git a/decidim-meetings/config/locales/tr-TR.yml b/decidim-meetings/config/locales/tr-TR.yml index 74d4bc27b929f..4e7c6b5a99a79 100644 --- a/decidim-meetings/config/locales/tr-TR.yml +++ b/decidim-meetings/config/locales/tr-TR.yml @@ -75,7 +75,6 @@ tr: official: Resmi type_eq: values: - hybrid: Her ikisi online: Çevrimiçi meeting_copies: create: @@ -336,20 +335,13 @@ tr: export_calendar: Takvimi dışa aktar conference_venues: Konferans Mekanları content_blocks: - upcoming_events: - name: Yaklaşan Etkinlikler - upcoming_events: Yaklaşan toplantılar - view_all_events: Hepsini gör + upcoming_meetings: + view_all_meetings: Hepsini gör directory: meetings: index: - all: Tümü - date: Tarih meetings: Toplantılar - past: Geçmiş - search: Arama space_type: Katılımcı alan - upcoming: Yaklaşan last_activity: new_meeting_at_html: "%{link} adresinde yeni toplantı" mailer: @@ -396,7 +388,6 @@ tr: type: Türü type_values: all: Tümü - hybrid: Her ikisi in_person: Şahsen online: Çevrimiçi filters_small_view: @@ -494,7 +485,6 @@ tr: invalid: Bu toplantıdan ayrılırken bir sorun oluştu. success: Toplantıdan başarıyla ayrıldınız. type_of_meeting: - hybrid: Her ikisi in_person: Şahsen online: Çevrimiçi types: diff --git a/decidim-meetings/config/locales/zh-CN.yml b/decidim-meetings/config/locales/zh-CN.yml index 895a4001ea385..1706edafb1ac7 100644 --- a/decidim-meetings/config/locales/zh-CN.yml +++ b/decidim-meetings/config/locales/zh-CN.yml @@ -310,20 +310,13 @@ zh-CN: export_calendar: 导出日历 conference_venues: 会议地点 content_blocks: - upcoming_events: - name: 即将到来的事件 - upcoming_events: 即将举行的会议 - view_all_events: 查看全部 + upcoming_meetings: + view_all_meetings: 查看全部 directory: meetings: index: - all: 所有的 - date: 日期 meetings: 会议 - past: 过去的 - search: 搜索 space_type: 参与空间 - upcoming: 即将到来的 last_activity: new_meeting_at_html: "在 %{link}的新会议" mailer: diff --git a/decidim-meetings/db/migrate/20210512100333_drop_decidim_meetings_minutes_table.rb b/decidim-meetings/db/migrate/20210512100333_drop_decidim_meetings_minutes_table.rb index ec3fec780abf9..1702087150c46 100644 --- a/decidim-meetings/db/migrate/20210512100333_drop_decidim_meetings_minutes_table.rb +++ b/decidim-meetings/db/migrate/20210512100333_drop_decidim_meetings_minutes_table.rb @@ -21,6 +21,7 @@ def up ActionLog.where(resource_type: "Decidim::Meetings::Minutes").each do |action_log| minutes = Minutes.find_by(id: action_log.resource_id) version = Version.find_by(id: action_log.version_id) + next unless minutes && version version_updates = { item_type: "Decidim::Meetings::Meeting", diff --git a/decidim-meetings/db/migrate/20210519133705_add_comments_availability_columns_to_meetings_table.rb b/decidim-meetings/db/migrate/20210519133705_add_comments_availability_columns_to_meetings_table.rb new file mode 100644 index 0000000000000..5c7fe60f74adc --- /dev/null +++ b/decidim-meetings/db/migrate/20210519133705_add_comments_availability_columns_to_meetings_table.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +class AddCommentsAvailabilityColumnsToMeetingsTable < ActiveRecord::Migration[6.0] + def change + add_column :decidim_meetings_meetings, :comments_enabled, :boolean, default: true + add_column :decidim_meetings_meetings, :comments_start_time, :datetime + add_column :decidim_meetings_meetings, :comments_end_time, :datetime + reversible do |dir| + dir.up do + execute "UPDATE decidim_meetings_meetings set comments_enabled = true" + end + end + end +end diff --git a/decidim-meetings/db/migrate/20210727085318_add_state_field_to_meeting.rb b/decidim-meetings/db/migrate/20210727085318_add_state_field_to_meeting.rb new file mode 100644 index 0000000000000..b45eb85705417 --- /dev/null +++ b/decidim-meetings/db/migrate/20210727085318_add_state_field_to_meeting.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class AddStateFieldToMeeting < ActiveRecord::Migration[6.0] + def change + add_column :decidim_meetings_meetings, :state, :string, index: true + end +end diff --git a/decidim-meetings/db/migrate/20210903143040_add_iframe_access_level_to_decidim_meetings.rb b/decidim-meetings/db/migrate/20210903143040_add_iframe_access_level_to_decidim_meetings.rb new file mode 100644 index 0000000000000..4f79b2510039e --- /dev/null +++ b/decidim-meetings/db/migrate/20210903143040_add_iframe_access_level_to_decidim_meetings.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class AddIframeAccessLevelToDecidimMeetings < ActiveRecord::Migration[6.0] + def change + add_column :decidim_meetings_meetings, :iframe_access_level, :integer, default: 0 + end +end diff --git a/decidim-meetings/db/migrate/20210922140454_transform_show_embedded_iframe_column.rb b/decidim-meetings/db/migrate/20210922140454_transform_show_embedded_iframe_column.rb new file mode 100644 index 0000000000000..fc2b0023aa130 --- /dev/null +++ b/decidim-meetings/db/migrate/20210922140454_transform_show_embedded_iframe_column.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +class TransformShowEmbeddedIframeColumn < ActiveRecord::Migration[6.0] + def up + add_column :decidim_meetings_meetings, :iframe_embed_type, :integer, default: 0 + execute "UPDATE decidim_meetings_meetings SET iframe_embed_type = 1 WHERE show_embedded_iframe = 't'" + remove_column :decidim_meetings_meetings, :show_embedded_iframe + end + + def down + add_column :decidim_meetings_meetings, :show_embedded_iframe, :boolean, default: false + execute "UPDATE decidim_meetings_meetings SET show_embedded_iframe = 't' WHERE iframe_embed_type = 1" + remove_column :decidim_meetings_meetings, :iframe_embed_type + end +end diff --git a/decidim-meetings/db/migrate/20210928095036_rename_upcoming_events_content_block_to_upcoming_meetings.rb b/decidim-meetings/db/migrate/20210928095036_rename_upcoming_events_content_block_to_upcoming_meetings.rb new file mode 100644 index 0000000000000..3abee3c827ed3 --- /dev/null +++ b/decidim-meetings/db/migrate/20210928095036_rename_upcoming_events_content_block_to_upcoming_meetings.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +class RenameUpcomingEventsContentBlockToUpcomingMeetings < ActiveRecord::Migration[6.0] + class ContentBlock < ApplicationRecord + self.table_name = :decidim_content_blocks + end + + def change + # rubocop:disable Rails/SkipsModelValidations + ContentBlock.where(manifest_name: "upcoming_events").update_all(manifest_name: "upcoming_meetings") + # rubocop:enable Rails/SkipsModelValidations + end +end diff --git a/decidim-meetings/lib/decidim/api/linked_resources_interface.rb b/decidim-meetings/lib/decidim/api/linked_resources_interface.rb index 0b111bd03c473..cdb55d5ba58a1 100644 --- a/decidim-meetings/lib/decidim/api/linked_resources_interface.rb +++ b/decidim-meetings/lib/decidim/api/linked_resources_interface.rb @@ -5,7 +5,7 @@ module Meetings # This interface represents all linked resources available in the module meetings module LinkedResourcesInterface include Decidim::Api::Types::BaseInterface - graphql_name "MeetinsLinkedResourcewInterface" + graphql_name "MeetingsLinkedResourcesInterface" description "An interface that can be used with Resourceable models." if Decidim::Meetings.enable_proposal_linking diff --git a/decidim-meetings/lib/decidim/api/meeting_type.rb b/decidim-meetings/lib/decidim/api/meeting_type.rb index 437de79cd9f91..af382ca47a27d 100644 --- a/decidim-meetings/lib/decidim/api/meeting_type.rb +++ b/decidim-meetings/lib/decidim/api/meeting_type.rb @@ -11,7 +11,7 @@ class MeetingType < Decidim::Api::Types::BaseObject implements Decidim::Core::AttachableInterface implements Decidim::Core::TimestampsInterface implements Decidim::Meetings::ServicesInterface - implements Decidim::Meetings::LinkedResourcesInterface + implements Decidim::Meetings::LinkedResourcesInterface if Decidim::Meetings.enable_proposal_linking implements Decidim::Forms::QuestionnaireEntityInterface field :id, GraphQL::Types::ID, "ID of this meeting", null: false @@ -28,6 +28,7 @@ def agenda end field :closed, GraphQL::Types::Boolean, "Whether this meeting is closed or not.", method: :closed?, null: false + field :isWithdrawn, GraphQL::Types::Boolean, "Whether this meeting is withdrawn or not.", method: :withdrawn?, null: false field :closing_report, Decidim::Core::TranslatedFieldType, "The closing report of this meeting.", null: true field :video_url, GraphQL::Types::String, "URL for the video of the session, if any", null: true field :audio_url, GraphQL::Types::String, "URL for the audio of the session, if any", null: true @@ -72,7 +73,7 @@ def coordinates end field :type_of_meeting, GraphQL::Types::String, "The type of the meeting (online or in-person)", null: false field :online_meeting_url, GraphQL::Types::String, "The URL of the meeting (when the type is online)", null: false - field :show_embedded_iframe, GraphQL::Types::Boolean, "Whether show or not the iframe", null: false + field :iframe_embed_type, GraphQL::Types::String, "The type of displaying of the online meeting URL", null: true end end end diff --git a/decidim-meetings/lib/decidim/content_parsers/meeting_parser.rb b/decidim-meetings/lib/decidim/content_parsers/meeting_parser.rb new file mode 100644 index 0000000000000..2a9deed90ea97 --- /dev/null +++ b/decidim-meetings/lib/decidim/content_parsers/meeting_parser.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module Decidim + module ContentParsers + # A parser that searches mentions of Meetings in content. + # + # @see BaseParser Examples of how to use a content parser + class MeetingParser < ResourceParser + private + + def url_regex + %r{#{URL_REGEX_SCHEME}#{URL_REGEX_CONTENT}/meetings/#{URL_REGEX_END_CHAR}+}i + end + + def model_class + "Decidim::Meetings::Meeting" + end + end + end +end diff --git a/decidim-meetings/lib/decidim/content_renderers/meeting_renderer.rb b/decidim-meetings/lib/decidim/content_renderers/meeting_renderer.rb new file mode 100644 index 0000000000000..18d2f9d2fb8ff --- /dev/null +++ b/decidim-meetings/lib/decidim/content_renderers/meeting_renderer.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Decidim + module ContentRenderers + # A renderer that searches Global IDs representing meetings in content + # and replaces it with a link to their show page. + # + # e.g. gid:///Decidim::Meetings::Meeting/1 + # + # @see BaseRenderer Examples of how to use a content renderer + class MeetingRenderer < ResourceRenderer + def regex + %r{gid://([\w-]*/Decidim::Meetings::Meeting/(\d+))}i + end + end + end +end diff --git a/decidim-meetings/lib/decidim/meetings.rb b/decidim-meetings/lib/decidim/meetings.rb index 1d06418aa2e01..f9bb475f597bb 100644 --- a/decidim-meetings/lib/decidim/meetings.rb +++ b/decidim-meetings/lib/decidim/meetings.rb @@ -23,5 +23,18 @@ module Meetings config_accessor :enable_proposal_linking do Decidim.const_defined?("Proposals") end + + # Public Setting that defines the interval when the upcoming meeting will be sent + config_accessor :upcoming_meeting_notification do + 2.days + end + end + + module ContentParsers + autoload :MeetingParser, "decidim/content_parsers/meeting_parser" + end + + module ContentRenderers + autoload :MeetingRenderer, "decidim/content_renderers/meeting_renderer" end end diff --git a/decidim-meetings/lib/decidim/meetings/component.rb b/decidim-meetings/lib/decidim/meetings/component.rb index d519c47c8050f..89974ef98be24 100644 --- a/decidim-meetings/lib/decidim/meetings/component.rb +++ b/decidim-meetings/lib/decidim/meetings/component.rb @@ -25,7 +25,7 @@ end component.register_stat :meetings_count, primary: true, priority: Decidim::StatsRegistry::MEDIUM_PRIORITY do |components, start_at, end_at| - meetings = Decidim::Meetings::FilteredMeetings.for(components, start_at, end_at) + meetings = Decidim::Meetings::FilteredMeetings.for(components, start_at, end_at).except_withdrawn meetings.count end @@ -42,11 +42,10 @@ component.exports :meetings do |exports| exports.collection do |component_instance| Decidim::Meetings::Meeting - .published .not_hidden .visible .where(component: component_instance) - .includes(component: { participatory_space: :organization }) + .includes(:scope, :category, :attachments, component: { participatory_space: :organization }) end exports.include_in_open_data = true @@ -58,7 +57,7 @@ exports.collection do |component_instance| Decidim::Comments::Export.comments_for_resource( Decidim::Meetings::Meeting, component_instance - ) + ).includes(:author, :user_group, root_commentable: { component: { participatory_space: :organization } }) end exports.include_in_open_data = true @@ -128,7 +127,7 @@ end 2.times do - start_time = [rand(1..20).weeks.from_now, rand(1..20).weeks.ago].sample + start_time = Faker::Date.between(from: 20.weeks.ago, to: 20.weeks.from_now) end_time = start_time + [rand(1..4).hours, rand(1..20).days].sample params = { component: component, @@ -157,14 +156,22 @@ _hybrid_meeting = Decidim.traceability.create!( Decidim::Meetings::Meeting, admin_user, - params.merge(type_of_meeting: :hybrid, online_meeting_url: "http://example.org"), + params.merge( + title: Decidim::Faker::Localized.sentence(word_count: 2), + type_of_meeting: :hybrid, + online_meeting_url: "http://example.org" + ), visibility: "all" ) _online_meeting = Decidim.traceability.create!( Decidim::Meetings::Meeting, admin_user, - params.merge(type_of_meeting: :online, online_meeting_url: "http://example.org"), + params.merge( + title: Decidim::Faker::Localized.sentence(word_count: 2), + type_of_meeting: :online, + online_meeting_url: "http://example.org" + ), visibility: "all" ) @@ -200,8 +207,8 @@ user = Decidim::User.find_or_initialize_by(email: email) user.update!( - password: "password1234", - password_confirmation: "password1234", + password: "decidim123456", + password_confirmation: "decidim123456", name: name, nickname: Faker::Twitter.unique.screen_name, organization: component.organization, @@ -275,7 +282,7 @@ author = user_group.users.sample end - start_time = [rand(1..20).weeks.from_now, rand(1..20).weeks.ago].sample + start_time = Faker::Date.between(from: 20.weeks.ago, to: 20.weeks.from_now) params = { component: component, scope: Faker::Boolean.boolean(true_ratio: 0.5) ? global : scopes.sample, diff --git a/decidim-meetings/lib/decidim/meetings/directory_engine.rb b/decidim-meetings/lib/decidim/meetings/directory_engine.rb index 143231c29b55f..08f81ae74b69b 100644 --- a/decidim-meetings/lib/decidim/meetings/directory_engine.rb +++ b/decidim-meetings/lib/decidim/meetings/directory_engine.rb @@ -22,9 +22,9 @@ def load_seed end initializer "decidim.meetings.content_blocks" do - Decidim.content_blocks.register(:homepage, :upcoming_events) do |content_block| - content_block.cell = "decidim/meetings/content_blocks/upcoming_events" - content_block.public_name_key = "decidim.meetings.content_blocks.upcoming_events.name" + Decidim.content_blocks.register(:homepage, :upcoming_meetings) do |content_block| + content_block.cell = "decidim/meetings/content_blocks/upcoming_meetings" + content_block.public_name_key = "decidim.meetings.content_blocks.upcoming_meetings.name" content_block.default! end end diff --git a/decidim-meetings/lib/decidim/meetings/engine.rb b/decidim-meetings/lib/decidim/meetings/engine.rb index ed272d69dc8dd..96b3e8cd97329 100644 --- a/decidim-meetings/lib/decidim/meetings/engine.rb +++ b/decidim-meetings/lib/decidim/meetings/engine.rb @@ -13,7 +13,10 @@ class Engine < ::Rails::Engine isolate_namespace Decidim::Meetings routes do - resources :meetings, only: [:index, :show, :new, :create, :edit, :update] do + resources :meetings, only: [:index, :show, :new, :create, :edit, :update, :withdraw] do + member do + put :withdraw + end resources :meeting_closes, only: [:edit, :update] do get :proposals_picker, on: :collection end @@ -39,6 +42,12 @@ class Engine < ::Rails::Engine end end + initializer "decidim.content_processors" do |_app| + Decidim.configure do |config| + config.content_processors += [:meeting] + end + end + initializer "decidim_meetings.view_hooks" do Decidim.view_hooks.register(:participatory_space_highlighted_elements, priority: Decidim::ViewHooks::HIGH_PRIORITY) do |view_context| view_context.cell("decidim/meetings/highlighted_meetings", view_context.current_participatory_space) diff --git a/decidim-meetings/lib/decidim/meetings/meeting_serializer.rb b/decidim-meetings/lib/decidim/meetings/meeting_serializer.rb index 80708b2a4c348..1b2ef352faa1e 100644 --- a/decidim-meetings/lib/decidim/meetings/meeting_serializer.rb +++ b/decidim-meetings/lib/decidim/meetings/meeting_serializer.rb @@ -41,11 +41,12 @@ def serialize location: meeting.location, reference: meeting.reference, comments: meeting.comments_count, - attachments: meeting.attachments.count, - followers: meeting.followers.count, + attachments: meeting.attachments.size, + followers: meeting.follows.size, url: url, related_proposals: related_proposals, - related_results: related_results + related_results: related_results, + published: meeting.published_at.present? } end diff --git a/decidim-meetings/lib/decidim/meetings/test/factories.rb b/decidim-meetings/lib/decidim/meetings/test/factories.rb index f1c39bdf8e8a1..559abfae6fa72 100644 --- a/decidim-meetings/lib/decidim/meetings/test/factories.rb +++ b/decidim-meetings/lib/decidim/meetings/test/factories.rb @@ -37,7 +37,8 @@ registration_type { :on_this_platform } type_of_meeting { :in_person } component { build(:component, manifest_name: "meetings") } - show_embedded_iframe { false } + iframe_access_level { :all } + iframe_embed_type { :none } author do component.try(:organization) @@ -47,6 +48,10 @@ published_at { Time.current } end + trait :withdrawn do + state { "withdrawn" } + end + trait :in_person do type_of_meeting { :in_person } end @@ -135,8 +140,30 @@ published_at { Time.current } end - trait :show_embedded_iframe do - show_embedded_iframe { true } + trait :signed_in_iframe_access_level do + iframe_access_level { :signed_in } + end + + trait :registered_iframe_access_level do + iframe_access_level { :registered } + end + + trait :embed_in_meeting_page_iframe_embed_type do + iframe_embed_type { :embed_in_meeting_page } + end + + trait :open_in_live_event_page_iframe_embed_type do + iframe_embed_type { :open_in_live_event_page } + end + + trait :open_in_new_tab_iframe_embed_type do + iframe_embed_type { :open_in_new_tab } + end + + trait :moderated do + after(:create) do |meeting, _evaluator| + create(:moderation, reportable: meeting, hidden_at: 2.days.ago) + end end end diff --git a/decidim-meetings/lib/decidim/meetings/test/notifications_handling.rb b/decidim-meetings/lib/decidim/meetings/test/notifications_handling.rb new file mode 100644 index 0000000000000..ca1c4f2b4fbe6 --- /dev/null +++ b/decidim-meetings/lib/decidim/meetings/test/notifications_handling.rb @@ -0,0 +1,39 @@ +# frozen_string_literal: true + +shared_examples_for "emits an upcoming notificaton" do + context "when it's a future meeting" do + let(:future_start_date) { 3.days.from_now } + + before do + meeting.start_time = future_start_date + end + + it "schedules a upcoming meeting notification job 48h before start time" do + expect(Decidim::Meetings::UpcomingMeetingNotificationJob) + .to receive(:generate_checksum).and_return "1234" + + expect(Decidim::Meetings::UpcomingMeetingNotificationJob) + .to receive_message_chain(:set, :perform_later) # rubocop:disable RSpec/MessageChain + .with(set: meeting.start_time - Decidim::Meetings.upcoming_meeting_notification) + .with(kind_of(Integer), "1234") + + subject.call + end + end + + context "when it's a past meeting" do + let(:past_start_date) { 1.day.ago } + + before do + meeting.start_time = past_start_date + end + + it "doesn't schedule an upcoming meeting notification" do + expect(Decidim::Meetings::UpcomingMeetingNotificationJob).not_to receive(:generate_checksum) + expect(Decidim::Meetings::UpcomingMeetingNotificationJob).not_to receive(:set) + expect(Decidim::Meetings::UpcomingMeetingNotificationJob).not_to receive(:perform_later) + + subject.call + end + end +end diff --git a/decidim-meetings/lib/decidim/meetings/test/translated_event.rb b/decidim-meetings/lib/decidim/meetings/test/translated_event.rb new file mode 100644 index 0000000000000..8d761b07d7d86 --- /dev/null +++ b/decidim-meetings/lib/decidim/meetings/test/translated_event.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +shared_examples_for "a translated meeting event" do + describe "translated notifications" do + let(:en_body) { "This is Sparta!" } + let(:body) { { "en": en_body, "machine_translations": { "ca": "C'est Sparta!" } } } + let(:participatory_process) { create :participatory_process, organization: organization } + let(:meeting_component) { create(:meeting_component, participatory_space: participatory_process) } + let(:translatable) { true } + let(:en_version) { resource.description["en"] } + let(:machine_translated) { resource.description["machine_translations"]["ca"] } + + let(:resource) do + create :meeting, + component: meeting_component, + title: { "en": "A nice event", "machine_translations": { "ca": "Une belle event" } }, + description: body + end + + it_behaves_like "a translated event" + end +end diff --git a/decidim-meetings/lib/decidim/meetings/version.rb b/decidim-meetings/lib/decidim/meetings/version.rb index e26202582effb..857fad944e0df 100644 --- a/decidim-meetings/lib/decidim/meetings/version.rb +++ b/decidim-meetings/lib/decidim/meetings/version.rb @@ -4,7 +4,7 @@ module Decidim # This holds the decidim-meetings version. module Meetings def self.version - "0.25.2" + "0.26.4" end end end diff --git a/decidim-meetings/spec/cells/decidim/meetings/content_blocks/upcoming_events_cell_spec.rb b/decidim-meetings/spec/cells/decidim/meetings/content_blocks/upcoming_meetings_cell_spec.rb similarity index 75% rename from decidim-meetings/spec/cells/decidim/meetings/content_blocks/upcoming_events_cell_spec.rb rename to decidim-meetings/spec/cells/decidim/meetings/content_blocks/upcoming_meetings_cell_spec.rb index bffd65fc75500..dc6cd111218de 100644 --- a/decidim-meetings/spec/cells/decidim/meetings/content_blocks/upcoming_events_cell_spec.rb +++ b/decidim-meetings/spec/cells/decidim/meetings/content_blocks/upcoming_meetings_cell_spec.rb @@ -5,10 +5,10 @@ module Decidim module Meetings module ContentBlocks - describe UpcomingEventsCell, type: :cell do + describe UpcomingMeetingsCell, type: :cell do controller Decidim::Meetings::Directory::MeetingsController - let(:html) { cell("decidim/meetings/content_blocks/upcoming_events").call } + let(:html) { cell("decidim/meetings/content_blocks/upcoming_meetings").call } let(:organization) { create(:organization) } let(:current_user) { create :user, :confirmed, organization: organization } @@ -16,16 +16,16 @@ module ContentBlocks expect(controller).to receive(:current_organization).at_least(:once).and_return(organization) end - context "with events" do + context "with meetings" do let(:organization) { meeting.organization } let(:meeting) { create(:meeting, :published, start_time: 1.week.from_now) } - it "renders the events" do + it "renders the meetings" do expect(html).to have_css(".card", count: 1) end - describe "upcoming events" do - subject { cell.upcoming_events } + describe "upcoming meetings" do + subject { cell.upcoming_meetings } let(:cell) { described_class.new(nil, context: { controller: controller }) } let!(:past_meeting) do @@ -34,10 +34,18 @@ module ContentBlocks let!(:second_meeting) do create(:meeting, :published, start_time: meeting.start_time.advance(weeks: 1), component: meeting.component) end + let!(:moderated_meeting) do + create(:meeting, :moderated, :published, start_time: meeting.start_time.advance(weeks: 1), component: meeting.component) + end + let!(:unpublished_meeting) do + create(:meeting, start_time: 2.weeks.from_now, component: meeting.component) + end + it { is_expected.not_to include(moderated_meeting) } it { is_expected.not_to include(past_meeting) } it { is_expected.to include(meeting) } it { is_expected.to include(second_meeting) } + it { is_expected.not_to include(unpublished_meeting) } it "orders them correctly" do expect(subject.length).to eq(2) @@ -45,7 +53,7 @@ module ContentBlocks expect(subject.last).to eq(second_meeting) end - context "with upcoming private events" do + context "with upcoming private meetings" do let!(:meeting) do create(:meeting, :published, start_time: 1.week.from_now, private_meeting: true, transparent: false) end @@ -58,7 +66,7 @@ module ContentBlocks end end - context "with upcoming private events but invited user" do + context "with upcoming private meetings but invited user" do let!(:meeting) do create(:meeting, :published, start_time: 1.week.from_now, private_meeting: true, transparent: false) end @@ -76,9 +84,9 @@ module ContentBlocks end end - context "with no events" do + context "with no meetings" do it "renders nothing" do - expect(html).to have_no_css(".upcoming-events") + expect(html).to have_no_css(".upcoming-meetings") end end end diff --git a/decidim-meetings/spec/cells/decidim/meetings/meeting_highlighted_list_item_cell_spec.rb b/decidim-meetings/spec/cells/decidim/meetings/meeting_highlighted_list_item_cell_spec.rb new file mode 100644 index 0000000000000..03628480cfe62 --- /dev/null +++ b/decidim-meetings/spec/cells/decidim/meetings/meeting_highlighted_list_item_cell_spec.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +require "spec_helper" + +module Decidim::Meetings + describe MeetingHighlightedListItemCell, type: :cell do + controller Decidim::Meetings::MeetingsController + + subject { my_cell.call } + + let!(:meeting) { create(:meeting, :published) } + let(:my_cell) { cell("decidim/meetings/meeting_highlighted_list_item", meeting) } + + context "when rendering" do + it "renders the card" do + expect(subject).to have_css(".card") + end + end + + context "when title contains special html entities" do + let!(:original_title) { meeting.title["en"] } + + before do + meeting.update!(title: { en: "#{original_title} &'<" }) + meeting.reload + end + + it "escapes them correctly" do + expect(subject.to_s).to include("<strong>#{original_title}</strong> &'<") + end + end + end +end diff --git a/decidim-meetings/spec/cells/decidim/meetings/meeting_list_item_cell_spec.rb b/decidim-meetings/spec/cells/decidim/meetings/meeting_list_item_cell_spec.rb index c19c5d974817a..79ec0adbb1f88 100644 --- a/decidim-meetings/spec/cells/decidim/meetings/meeting_list_item_cell_spec.rb +++ b/decidim-meetings/spec/cells/decidim/meetings/meeting_list_item_cell_spec.rb @@ -4,12 +4,27 @@ module Decidim::Meetings describe MeetingListItemCell, type: :cell do + subject { my_cell.call } + let!(:meeting) { create(:meeting, :published) } + let(:my_cell) { cell("decidim/meetings/meeting_list_item", meeting) } context "when rendering" do it "renders the card" do - html = cell("decidim/meetings/meeting_list_item", meeting).call - expect(html).to have_css(".card--list__item") + expect(subject).to have_css(".card--list__item") + end + end + + context "when title contains special html entities" do + let!(:original_title) { meeting.title["en"] } + + before do + meeting.update!(title: { en: "#{original_title} &'<" }) + meeting.reload + end + + it "escapes them correctly" do + expect(subject.to_s).to include("<strong>#{original_title}</strong> &'<") end end end diff --git a/decidim-meetings/spec/cells/decidim/meetings/meeting_m_cell_spec.rb b/decidim-meetings/spec/cells/decidim/meetings/meeting_m_cell_spec.rb index a544c23357270..998d02ec2b1dd 100644 --- a/decidim-meetings/spec/cells/decidim/meetings/meeting_m_cell_spec.rb +++ b/decidim-meetings/spec/cells/decidim/meetings/meeting_m_cell_spec.rb @@ -16,6 +16,8 @@ module Decidim::Meetings context "when rendering" do let(:show_space) { false } + it_behaves_like "m-cell", :meeting + it "renders the card" do expect(cell_html).to have_css(".card--meeting") end @@ -25,10 +27,21 @@ module Decidim::Meetings expect(cell_html).to have_no_content(I18n.l(meeting.created_at.to_date, format: :decidim_short)) end - context "when an image is attached to the meeting" do + context "when there are long descriptions" do + before do + meeting.update!(description: { en: "A really long text" * 800 }) + end + + it "truncates the description" do + truncated_description_length = cell_html.find(".card__text--paragraph").text.strip.length + expect(truncated_description_length).to be < 130 + end + end + + context "with attached image" do let!(:attachment) { create(:attachment, attached_to: meeting) } - it "renders the picture" do + it "renders the image" do expect(cell_html).to have_css(".card__image") end end @@ -43,8 +56,8 @@ module Decidim::Meetings meeting.reload end - it "escapes them correclty" do - expect(the_cell.title).not_to eq("#{@original_title} &'<") + it "escapes them correctly" do + expect(the_cell.title).to eq("#{@original_title} &'<") # as the `cell` test helper wraps content in a Capybara artifact that already converts html entities # we should compare with the expected visual result, as we were checking the DOM instead of the html expect(cell_html).to have_content("#{@original_title} &'<") diff --git a/decidim-meetings/spec/commands/admin/copy_meeting_spec.rb b/decidim-meetings/spec/commands/admin/copy_meeting_spec.rb index 92a872fe0db2d..f4002671c2fcf 100644 --- a/decidim-meetings/spec/commands/admin/copy_meeting_spec.rb +++ b/decidim-meetings/spec/commands/admin/copy_meeting_spec.rb @@ -6,7 +6,7 @@ module Decidim::Meetings describe Admin::CopyMeeting do subject { described_class.new(form, meeting) } - let(:meeting) { create :meeting } + let!(:meeting) { create :meeting } let(:current_user) { create :user, :admin, :confirmed, organization: meeting.organization } let(:address) { "address" } @@ -43,7 +43,16 @@ module Decidim::Meetings private_meeting: meeting.private_meeting, transparent: meeting.transparent, current_organization: current_user.organization, - current_component: meeting.component + current_component: meeting.component, + online_meeting_url: meeting.online_meeting_url, + iframe_embed_type: meeting.iframe_embed_type, + iframe_access_level: meeting.iframe_access_level, + comments_enabled: meeting.comments_enabled, + comments_start_time: meeting.comments_start_time, + comments_end_time: meeting.comments_end_time, + registration_type: :on_this_platform, + registration_url: meeting.registration_url, + type_of_meeting: meeting.type_of_meeting ) end @@ -57,9 +66,9 @@ module Decidim::Meetings context "when everything is ok" do it "duplicates a meeting" do - expect { subject.call }.to change(Meeting, :count).by(2) + expect { subject.call }.to change(Meeting, :count).by(1) - old_meeting = Meeting.first + old_meeting = meeting new_meeting = Meeting.last expect(new_meeting.title["en"]).to eq("title") @@ -78,6 +87,40 @@ module Decidim::Meetings it "broadcasts ok" do expect { subject.call }.to broadcast(:ok) end + + context "and saves the correct meeting type" do + context "with in_person meeting type" do + let!(:meeting) { create :meeting, :in_person } + + it "duplicates an in_person meeting" do + expect { subject.call }.to change(Meeting, :count).by(1) + new_meeting = Meeting.last + expect(new_meeting.type_of_meeting).to eq(meeting.type_of_meeting) + end + end + + context "with online meeting type" do + let!(:meeting) { create :meeting, :online } + + it "duplicates an online meeting" do + expect { subject.call }.to change(Meeting, :count).by(1) + new_meeting = Meeting.last + expect(new_meeting.type_of_meeting).to eq(meeting.type_of_meeting) + expect(new_meeting.online_meeting_url).to eq(meeting.online_meeting_url) + end + end + + context "with hybrid meeting type" do + let!(:meeting) { create :meeting, :hybrid } + + it "duplicates a hybrid meeting" do + expect { subject.call }.to change(Meeting, :count).by(1) + new_meeting = Meeting.last + expect(new_meeting.type_of_meeting).to eq(meeting.type_of_meeting) + expect(new_meeting.online_meeting_url).to eq(meeting.online_meeting_url) + end + end + end end describe "events" do diff --git a/decidim-meetings/spec/commands/admin/create_meeting_spec.rb b/decidim-meetings/spec/commands/admin/create_meeting_spec.rb index ca7c2e6f5a509..61ca54989f124 100644 --- a/decidim-meetings/spec/commands/admin/create_meeting_spec.rb +++ b/decidim-meetings/spec/commands/admin/create_meeting_spec.rb @@ -25,7 +25,8 @@ module Decidim::Meetings let(:registration_url) { "http://decidim.org" } let(:registration_type) { "on_this_platform" } let(:available_slots) { 0 } - let(:show_embedded_iframe) { true } + let(:iframe_embed_type) { "embed_in_meeting_page" } + let(:iframe_access_level) { "all" } let(:services) do [ { @@ -71,7 +72,11 @@ module Decidim::Meetings online_meeting_url: online_meeting_url, customize_registration_email: customize_registration_email, registration_email_custom_content: registration_email_custom_content, - show_embedded_iframe: show_embedded_iframe + iframe_embed_type: iframe_embed_type, + comments_enabled: true, + comments_start_time: nil, + comments_end_time: nil, + iframe_access_level: iframe_access_level ) end @@ -149,10 +154,16 @@ module Decidim::Meetings expect(meeting.reload.followers).to include(current_user) end - it "sets show_embedded_iframe" do + it "sets iframe_embed_type" do subject.call - expect(meeting).to be_show_embedded_iframe + expect(meeting.iframe_embed_type).to eq(iframe_embed_type) + end + + it "sets iframe_access_level" do + subject.call + + expect(meeting.iframe_access_level).to eq(iframe_access_level) end it "traces the action", versioning: true do diff --git a/decidim-meetings/spec/commands/admin/publish_meeting_spec.rb b/decidim-meetings/spec/commands/admin/publish_meeting_spec.rb index f425e5ba9258f..086b926f7a5e7 100644 --- a/decidim-meetings/spec/commands/admin/publish_meeting_spec.rb +++ b/decidim-meetings/spec/commands/admin/publish_meeting_spec.rb @@ -40,16 +40,9 @@ module Admin expect(action_log.version).to be_present end - it "schedules a upcoming meeting notification job 48h before start time" do - expect(UpcomingMeetingNotificationJob) - .to receive(:generate_checksum).and_return "1234" - - expect(UpcomingMeetingNotificationJob) - .to receive_message_chain(:set, :perform_later) # rubocop:disable RSpec/MessageChain - .with(set: meeting.start_time - 2.days) - .with(kind_of(Integer), "1234") - - subject.call + it_behaves_like "emits an upcoming notificaton" do + let(:future_start_date) { 1.day.from_now + Decidim::Meetings.upcoming_meeting_notification } + let(:past_start_date) { 1.day.ago } end it "sends a notification to the participatory space followers" do diff --git a/decidim-meetings/spec/commands/admin/update_meeting_spec.rb b/decidim-meetings/spec/commands/admin/update_meeting_spec.rb index 6e5d4e3fe4be1..d366446edfdef 100644 --- a/decidim-meetings/spec/commands/admin/update_meeting_spec.rb +++ b/decidim-meetings/spec/commands/admin/update_meeting_spec.rb @@ -31,7 +31,8 @@ module Decidim::Meetings let(:available_slots) { 0 } let(:customize_registration_email) { true } let(:registration_email_custom_content) { { "en" => "The registration email custom content." } } - let(:show_embedded_iframe) { false } + let(:iframe_embed_type) { "none" } + let(:iframe_access_level) { nil } let(:form) do double( @@ -59,7 +60,11 @@ module Decidim::Meetings online_meeting_url: online_meeting_url, customize_registration_email: customize_registration_email, registration_email_custom_content: registration_email_custom_content, - show_embedded_iframe: show_embedded_iframe + iframe_embed_type: iframe_embed_type, + comments_enabled: true, + comments_start_time: nil, + comments_end_time: nil, + iframe_access_level: iframe_access_level ) end @@ -113,6 +118,12 @@ module Decidim::Meetings expect(meeting.registration_email_custom_content).to eq(registration_email_custom_content) end + it "sets iframe_access_level" do + subject.call + + expect(meeting.iframe_access_level).to eq(iframe_access_level) + end + it "traces the action", versioning: true do expect(Decidim.traceability) .to receive(:update!) @@ -156,7 +167,11 @@ module Decidim::Meetings online_meeting_url: online_meeting_url, customize_registration_email: customize_registration_email, registration_email_custom_content: registration_email_custom_content, - show_embedded_iframe: show_embedded_iframe + iframe_embed_type: iframe_embed_type, + comments_enabled: true, + comments_start_time: nil, + comments_end_time: nil, + iframe_access_level: iframe_access_level ) end @@ -207,15 +222,9 @@ module Decidim::Meetings subject.call end - it "schedules a upcoming meeting notification job 48h before start time" do - expect(UpcomingMeetingNotificationJob) - .to receive(:generate_checksum).and_return "1234" - - expect(UpcomingMeetingNotificationJob) - .to receive_message_chain(:set, :perform_later) # rubocop:disable RSpec/MessageChain - .with(set: start_time - 2.days).with(meeting.id, "1234") - - subject.call + it_behaves_like "emits an upcoming notificaton" do + let(:future_start_date) { 1.day.from_now + Decidim::Meetings.upcoming_meeting_notification } + let(:past_start_date) { 1.day.ago } end end diff --git a/decidim-meetings/spec/commands/create_meeting_spec.rb b/decidim-meetings/spec/commands/create_meeting_spec.rb index 404d8a1279910..a43ac5397a308 100644 --- a/decidim-meetings/spec/commands/create_meeting_spec.rb +++ b/decidim-meetings/spec/commands/create_meeting_spec.rb @@ -21,7 +21,8 @@ module Decidim::Meetings let(:type_of_meeting) { "online" } let(:registration_url) { "http://decidim.org" } let(:online_meeting_url) { "http://decidim.org" } - let(:show_embedded_iframe) { true } + let(:iframe_embed_type) { "embed_in_meeting_page" } + let(:iframe_access_level) { "all" } let(:registration_type) { "on_this_platform" } let(:registrations_enabled) { true } let(:available_slots) { 0 } @@ -51,7 +52,8 @@ module Decidim::Meetings registrations_enabled: registrations_enabled, clean_type_of_meeting: type_of_meeting, online_meeting_url: online_meeting_url, - show_embedded_iframe: show_embedded_iframe + iframe_embed_type: iframe_embed_type, + iframe_access_level: iframe_access_level ) end @@ -117,10 +119,10 @@ module Decidim::Meetings expect(meeting).to be_published end - it "sets show_embedded_iframe" do + it "sets iframe_embed_type" do subject.call - expect(meeting).to be_show_embedded_iframe + expect(meeting.iframe_embed_type).to eq(iframe_embed_type) end context "when the author is a user_group" do @@ -168,7 +170,25 @@ module Decidim::Meetings expect(UpcomingMeetingNotificationJob) .to receive_message_chain(:set, :perform_later) # rubocop:disable RSpec/MessageChain - .with(set: start_time - 2.days).with(1, "1234") + .with(set: start_time - Decidim::Meetings.upcoming_meeting_notification).with(1, "1234") + + allow(Decidim::EventsManager).to receive(:publish).and_return(true) + + subject.call + end + + it "doesn't schedule an upcoming meeting notification if start time is in the past" do + meeting = instance_double(Meeting, id: 1, start_time: 2.days.ago, participatory_space: participatory_process) + expect(Decidim.traceability) + .to receive(:create!) + .and_return(meeting) + + expect(meeting).to receive(:valid?) + expect(meeting).to receive(:publish!) + expect(meeting).to receive(:to_signed_global_id).and_return "gid://Decidim::Meetings::Meeting/1" + + expect(UpcomingMeetingNotificationJob).not_to receive(:generate_checksum) + expect(UpcomingMeetingNotificationJob).not_to receive(:set) allow(Decidim::EventsManager).to receive(:publish).and_return(true) diff --git a/decidim-meetings/spec/commands/update_meeting_spec.rb b/decidim-meetings/spec/commands/update_meeting_spec.rb index b9befe283b095..1ed153b6af23e 100644 --- a/decidim-meetings/spec/commands/update_meeting_spec.rb +++ b/decidim-meetings/spec/commands/update_meeting_spec.rb @@ -24,7 +24,8 @@ module Decidim::Meetings let(:registration_type) { "on_this_platform" } let(:available_slots) { 0 } let(:registration_url) { "http://decidim.org" } - let(:show_embedded_iframe) { false } + let(:iframe_embed_type) { "none" } + let(:iframe_access_level) { nil } let(:form) do double( invalid?: invalid, @@ -49,7 +50,8 @@ module Decidim::Meetings registrations_enabled: true, clean_type_of_meeting: type_of_meeting, online_meeting_url: online_meeting_url, - show_embedded_iframe: show_embedded_iframe + iframe_embed_type: iframe_embed_type, + iframe_access_level: iframe_access_level ) end @@ -147,7 +149,8 @@ module Decidim::Meetings registrations_enabled: true, clean_type_of_meeting: type_of_meeting, online_meeting_url: online_meeting_url, - show_embedded_iframe: show_embedded_iframe + iframe_embed_type: iframe_embed_type, + iframe_access_level: iframe_access_level ) end @@ -198,15 +201,9 @@ module Decidim::Meetings subject.call end - it "schedules a upcoming meeting notification job 48h before start time" do - expect(UpcomingMeetingNotificationJob) - .to receive(:generate_checksum).and_return "1234" - - expect(UpcomingMeetingNotificationJob) - .to receive_message_chain(:set, :perform_later) # rubocop:disable RSpec/MessageChain - .with(set: start_time - 2.days).with(meeting.id, "1234") - - subject.call + it_behaves_like "emits an upcoming notificaton" do + let(:future_start_date) { 1.day.from_now + Decidim::Meetings.upcoming_meeting_notification } + let(:past_start_date) { 1.day.ago } end end diff --git a/decidim-meetings/spec/commands/withdraw_meeting_spec.rb b/decidim-meetings/spec/commands/withdraw_meeting_spec.rb new file mode 100644 index 0000000000000..ffe0571d1b70e --- /dev/null +++ b/decidim-meetings/spec/commands/withdraw_meeting_spec.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require "spec_helper" + +module Decidim + module Meetings + describe WithdrawMeeting do + let(:meeting) { create(:meeting) } + + before do + meeting.save! + end + + context "when current user IS the author of the meeting" do + let(:current_user) { meeting.author } + let(:command) { described_class.new(meeting, current_user) } + + it "withdraws the meeting" do + expect { command.call }.to broadcast(:ok) + expect(meeting.state).to eq("withdrawn") + end + end + + context "when current user IS NOT the author of the meeting" do + let(:current_user) { create(:user, :admin) } + let(:command) { described_class.new(meeting, current_user) } + + it "does not withdraw the meeting" do + expect { command.call }.to broadcast(:invalid) + expect(meeting.state).to be(nil) + end + end + end + end +end diff --git a/decidim-meetings/spec/controllers/decidim/meetings/meetings_controller_spec.rb b/decidim-meetings/spec/controllers/decidim/meetings/meetings_controller_spec.rb index 863cf3ab6b48c..fa4ffd9047360 100644 --- a/decidim-meetings/spec/controllers/decidim/meetings/meetings_controller_spec.rb +++ b/decidim-meetings/spec/controllers/decidim/meetings/meetings_controller_spec.rb @@ -7,7 +7,7 @@ let(:organization) { create(:organization) } let(:participatory_process) { create :participatory_process, organization: organization } - let(:meeting_component) { create(:meeting_component, participatory_space: participatory_process) } + let(:meeting_component) { create(:meeting_component, :with_creation_enabled, participatory_space: participatory_process) } let(:meeting) { create :meeting, :published, component: meeting_component } before do @@ -43,6 +43,46 @@ end end + describe "withdraw a meeting" do + let(:user) { create(:user, :confirmed, organization: meeting_component.organization) } + + let(:meeting_params) do + { + component_id: meeting_component.id + } + end + let(:params) { { meeting: meeting_params } } + + before { sign_in user } + + context "when an authorized user is withdrawing a meeting" do + let(:meeting) { create(:meeting, component: meeting_component, author: user) } + + it "withdraws the meeting" do + put :withdraw, params: params.merge(id: meeting.id) + + expect(flash[:notice]).to eq("The meeting has been withdrawn successfully") + expect(response).to have_http_status(:found) + meeting.reload + expect(meeting.withdrawn?).to be true + end + end + + context "when current user is NOT the author of the meeting" do + let(:current_user) { create(:user, organization: meeting_component.organization) } + let(:meeting) { create(:meeting, component: meeting_component, author: current_user) } + + it "is not able to withdraw the meeting" do + put :withdraw, params: params.merge(id: meeting.id) + + expect(flash[:alert]).to eq("You are not authorized to perform this action") + expect(response).to have_http_status(:found) + meeting.reload + expect(meeting.withdrawn?).to be false + end + end + end + describe "#show" do context "when user is not logged in" do it "can access non private meetings" do diff --git a/decidim-meetings/spec/controllers/decidim/meetings/versions_controller_spec.rb b/decidim-meetings/spec/controllers/decidim/meetings/versions_controller_spec.rb new file mode 100644 index 0000000000000..d31a6c4d1562b --- /dev/null +++ b/decidim-meetings/spec/controllers/decidim/meetings/versions_controller_spec.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require "spec_helper" + +module Decidim + module Meetings + describe VersionsController, versioning: true, type: :controller do + routes { Decidim::Meetings::Engine.routes } + + let(:resource) { create(:meeting) } + + it_behaves_like "versions controller" + end + end +end diff --git a/decidim-meetings/spec/events/decidim/meetings/close_meeting_event_spec.rb b/decidim-meetings/spec/events/decidim/meetings/close_meeting_event_spec.rb index c6ca1790e0931..2f6a7c5498929 100644 --- a/decidim-meetings/spec/events/decidim/meetings/close_meeting_event_spec.rb +++ b/decidim-meetings/spec/events/decidim/meetings/close_meeting_event_spec.rb @@ -3,11 +3,19 @@ require "spec_helper" describe Decidim::Meetings::CloseMeetingEvent do - let(:resource) { create :meeting } + let(:resource) { create :meeting, title: { en: "It's my overdue meeting" } } + let(:resource_title) { translated(resource.title) } let(:event_name) { "decidim.events.meetings.meeting_closed" } include_context "when a simple event" it_behaves_like "a simple event" + it_behaves_like "a translated meeting event" + + describe "email_subject" do + it "is generated correctly" do + expect(subject.email_subject).to eq("The \"#{resource_title}\" meeting was closed") + end + end describe "resource_text" do it "returns the meeting description" do diff --git a/decidim-meetings/spec/events/decidim/meetings/create_meeting_event_spec.rb b/decidim-meetings/spec/events/decidim/meetings/create_meeting_event_spec.rb index 6e8e336c2fc75..453babf21b1f0 100644 --- a/decidim-meetings/spec/events/decidim/meetings/create_meeting_event_spec.rb +++ b/decidim-meetings/spec/events/decidim/meetings/create_meeting_event_spec.rb @@ -10,6 +10,7 @@ include_context "when a simple event" it_behaves_like "a simple event" + it_behaves_like "a translated meeting event" describe "email_subject" do it "is generated correctly" do diff --git a/decidim-meetings/spec/events/decidim/meetings/meeting_registrations_enabled_event_spec.rb b/decidim-meetings/spec/events/decidim/meetings/meeting_registrations_enabled_event_spec.rb index 987189d615cc6..365992b2708f9 100644 --- a/decidim-meetings/spec/events/decidim/meetings/meeting_registrations_enabled_event_spec.rb +++ b/decidim-meetings/spec/events/decidim/meetings/meeting_registrations_enabled_event_spec.rb @@ -3,11 +3,19 @@ require "spec_helper" describe Decidim::Meetings::MeetingRegistrationsEnabledEvent do - let(:resource) { create :meeting } + let(:resource) { create :meeting, title: { en: "It's my meeting" } } + let(:resource_title) { translated(resource.title) } let(:event_name) { "decidim.events.meetings.registrations_enabled" } include_context "when a simple event" it_behaves_like "a simple event" + it_behaves_like "a translated meeting event" + + describe "email_subject" do + it "is generated correctly" do + expect(subject.email_subject).to eq("The \"#{resource_title}\" meeting has enabled registrations.") + end + end describe "resource_text" do it "returns the meeting description" do diff --git a/decidim-meetings/spec/events/decidim/meetings/meeting_registrations_over_percentage_event_spec.rb b/decidim-meetings/spec/events/decidim/meetings/meeting_registrations_over_percentage_event_spec.rb index 33029f7f3369b..12bd450199c26 100644 --- a/decidim-meetings/spec/events/decidim/meetings/meeting_registrations_over_percentage_event_spec.rb +++ b/decidim-meetings/spec/events/decidim/meetings/meeting_registrations_over_percentage_event_spec.rb @@ -10,6 +10,7 @@ let(:extra) { { percentage: 1.1 } } it_behaves_like "a simple event" + it_behaves_like "a translated meeting event" describe "resource_text" do it "returns the meeting description" do diff --git a/decidim-meetings/spec/events/decidim/meetings/registration_code_validated_event_spec.rb b/decidim-meetings/spec/events/decidim/meetings/registration_code_validated_event_spec.rb index 66b1480c396fc..b7982a9029fa4 100644 --- a/decidim-meetings/spec/events/decidim/meetings/registration_code_validated_event_spec.rb +++ b/decidim-meetings/spec/events/decidim/meetings/registration_code_validated_event_spec.rb @@ -12,6 +12,7 @@ let(:extra) { { registration: registration } } it_behaves_like "a simple event" + it_behaves_like "a translated meeting event" describe "resource_text" do it "returns the meeting description" do diff --git a/decidim-meetings/spec/events/decidim/meetings/upcoming_meeting_event_spec.rb b/decidim-meetings/spec/events/decidim/meetings/upcoming_meeting_event_spec.rb index ccaab7115ad2d..55c101c9ea821 100644 --- a/decidim-meetings/spec/events/decidim/meetings/upcoming_meeting_event_spec.rb +++ b/decidim-meetings/spec/events/decidim/meetings/upcoming_meeting_event_spec.rb @@ -3,11 +3,19 @@ require "spec_helper" describe Decidim::Meetings::UpcomingMeetingEvent do - let(:resource) { create :meeting } + let(:resource) { create :meeting, title: { en: "It's my meeting" } } + let(:resource_title) { translated(resource.title) } let(:event_name) { "decidim.events.meetings.upcoming_meeting" } include_context "when a simple event" it_behaves_like "a simple event" + it_behaves_like "a translated meeting event" + + describe "email_subject" do + it "is generated correctly" do + expect(subject.email_subject).to eq("The \"#{resource_title}\" meeting will start in less than 48h.") + end + end describe "resource_text" do it "returns the meeting description" do diff --git a/decidim-meetings/spec/events/decidim/meetings/update_meeting_event_spec.rb b/decidim-meetings/spec/events/decidim/meetings/update_meeting_event_spec.rb index 531255fdf9a6e..40abab2fd9cbc 100644 --- a/decidim-meetings/spec/events/decidim/meetings/update_meeting_event_spec.rb +++ b/decidim-meetings/spec/events/decidim/meetings/update_meeting_event_spec.rb @@ -3,11 +3,19 @@ require "spec_helper" describe Decidim::Meetings::UpdateMeetingEvent do - let(:resource) { create :meeting } + let(:resource) { create :meeting, title: { en: "It's my meeting" } } + let(:resource_title) { translated(resource.title) } let(:event_name) { "decidim.events.meetings.meeting_updated" } include_context "when a simple event" it_behaves_like "a simple event" + it_behaves_like "a translated meeting event" + + describe "email_subject" do + it "is generated correctly" do + expect(subject.email_subject).to eq("The \"#{resource_title}\" meeting was updated") + end + end describe "resource_text" do it "returns the meeting description" do diff --git a/decidim-meetings/spec/forms/admin/meeting_copy_form_spec.rb b/decidim-meetings/spec/forms/admin/meeting_copy_form_spec.rb deleted file mode 100644 index a79e7e2f5c3b5..0000000000000 --- a/decidim-meetings/spec/forms/admin/meeting_copy_form_spec.rb +++ /dev/null @@ -1,188 +0,0 @@ -# frozen_string_literal: true - -require "spec_helper" - -module Decidim::Meetings - describe Admin::MeetingCopyForm do - subject(:form) { described_class.from_params(attributes).with_context(context) } - - let(:organization) { create(:organization, available_locales: [:en]) } - let(:context) do - { - current_organization: organization, - current_component: current_component, - current_participatory_space: participatory_process - } - end - let(:participatory_process) { create :participatory_process, organization: organization } - let(:current_component) { create :component, participatory_space: participatory_process, manifest_name: "meetings" } - let(:title) do - Decidim::Faker::Localized.sentence(word_count: 3) - end - let(:description) do - Decidim::Faker::Localized.sentence(word_count: 3) - end - let(:location) do - Decidim::Faker::Localized.sentence(word_count: 3) - end - let(:location_hints) do - Decidim::Faker::Localized.sentence(word_count: 3) - end - let(:service_objects) do - build_list(:service, 2) - end - let(:services) do - service_objects.map(&:attributes) - end - let(:address) { "Carrer Pic de Peguera 15, 17003 Girona" } - let(:latitude) { 40.1234 } - let(:longitude) { 2.1234 } - let(:start_time) { 2.days.from_now } - let(:end_time) { 2.days.from_now + 4.hours } - let(:private_meeting) { false } - let(:transparent) { true } - let(:type_of_meeting) { :in_person } - let(:online_meeting_url) { nil } - let(:attributes) do - { - title_en: title[:en], - description_en: description[:en], - location_en: location[:en], - location_hints_en: location_hints[:en], - address: address, - start_time: start_time, - end_time: end_time, - private_meeting: private_meeting, - transparent: transparent, - services: services, - type_of_meeting: type_of_meeting, - online_meeting_url: online_meeting_url - } - end - - before do - stub_geocoding(address, [latitude, longitude]) - end - - it { is_expected.to be_valid } - - describe "when title is missing" do - let(:title) { { en: nil } } - - it { is_expected.not_to be_valid } - end - - describe "when description is missing" do - let(:description) { { en: nil } } - - it { is_expected.not_to be_valid } - end - - describe "when location is missing in an in person meeting" do - let(:location) { { en: nil } } - - it { is_expected.not_to be_valid } - end - - describe "when location is missing in an hybrid meeting" do - let(:location) { { en: nil } } - let(:type_of_meeting) { :hybrid } - - it { is_expected.not_to be_valid } - end - - describe "when location is missing in an online meeting" do - let(:location) { { en: nil } } - let(:type_of_meeting) { :online } - - it { is_expected.to be_valid } - end - - describe "when address is missing in an in person meeting" do - let(:address) { nil } - - it { is_expected.not_to be_valid } - end - - describe "when address is missing in an hybrid meeting" do - let(:address) { nil } - let(:type_of_meeting) { :hybrid } - - it { is_expected.not_to be_valid } - end - - describe "when address is missing in an online meeting" do - let(:address) { nil } - let(:type_of_meeting) { :online } - - it { is_expected.to be_valid } - end - - describe "when start_time is missing" do - let(:start_time) { nil } - - it { is_expected.not_to be_valid } - end - - describe "when end_time is missing" do - let(:end_time) { nil } - - it { is_expected.not_to be_valid } - end - - describe "when start_time is after end_time" do - let(:start_time) { end_time + 3.days } - - it { is_expected.not_to be_valid } - end - - describe "when end_time is before start_time" do - let(:end_time) { start_time - 3.days } - - it { is_expected.not_to be_valid } - end - - describe "when start_time is equal to start_time" do - let(:start_time) { end_time } - - it { is_expected.not_to be_valid } - end - - it "validates address and store its coordinates" do - expect(subject).to be_valid - expect(subject.latitude).to eq(latitude) - expect(subject.longitude).to eq(longitude) - end - - it "properly maps services from model" do - meeting = create(:meeting, :with_services, services: service_objects) - - services = described_class.from_model(meeting).services - expect(services).to all be_an(Admin::MeetingServiceForm) - expect(services.map(&:title_en)).to eq(services.map(&:title_en)) - end - - describe "services_to_persist" do - subject { form.services_to_persist } - - let(:services) do - [ - { title: { en: "First service" }, description: { en: "First description" } }, - { title: { en: "Second service" }, description: { en: "Second description" }, deleted: true }, - { title: { en: "Third service" }, description: { en: "Third description" } } - ] - end - - it "only returns non deleted services" do - expect(subject.size).to eq(2) - expect(subject.map(&:title_en)).to eq(["First service", "Third service"]) - end - end - - describe "number_of_services" do - subject { form.number_of_services } - - it { is_expected.to eq(services.size) } - end - end -end diff --git a/decidim-meetings/spec/forms/admin/meeting_form_spec.rb b/decidim-meetings/spec/forms/admin/meeting_form_spec.rb index 9115155a6018b..5f05fd782bc0d 100644 --- a/decidim-meetings/spec/forms/admin/meeting_form_spec.rb +++ b/decidim-meetings/spec/forms/admin/meeting_form_spec.rb @@ -54,7 +54,7 @@ module Decidim::Meetings let(:registration_url) { "http://decidim.org" } let(:registration_type) { "on_this_platform" } let(:available_slots) { 0 } - let(:show_embedded_iframe) { false } + let(:iframe_embed_type) { "none" } let(:attributes) do { decidim_scope_id: scope_id, @@ -75,7 +75,7 @@ module Decidim::Meetings registration_url: registration_url, type_of_meeting: type_of_meeting, online_meeting_url: online_meeting_url, - show_embedded_iframe: show_embedded_iframe + iframe_embed_type: iframe_embed_type } end @@ -233,7 +233,7 @@ module Decidim::Meetings describe "when online meeting url is present and the meeting is embedded and the url can't be embedded" do let(:online_meeting_url) { "https://meet.jit.si/decidim" } - let(:show_embedded_iframe) { true } + let(:iframe_embed_type) { "embed_in_meeting_page" } it { is_expected.not_to be_valid } end diff --git a/decidim-meetings/spec/forms/close_meeting_form_spec.rb b/decidim-meetings/spec/forms/close_meeting_form_spec.rb index 87983e6c6e1a9..58c4e40cd78a4 100644 --- a/decidim-meetings/spec/forms/close_meeting_form_spec.rb +++ b/decidim-meetings/spec/forms/close_meeting_form_spec.rb @@ -44,6 +44,18 @@ module Decidim::Meetings it { is_expected.not_to be_valid } end + describe "when attendees_count is greater than 999" do + let(:attendees_count) { 10_000 } + + it { is_expected.not_to be_valid } + end + + describe "when attendees_count is less than 0" do + let(:attendees_count) { -10 } + + it { is_expected.not_to be_valid } + end + describe "when attendees_count is invalid" do let(:attendees_count) { "a" } diff --git a/decidim-meetings/spec/forms/meeting_form_spec.rb b/decidim-meetings/spec/forms/meeting_form_spec.rb index bea428dedc917..a639a38a60b2b 100644 --- a/decidim-meetings/spec/forms/meeting_form_spec.rb +++ b/decidim-meetings/spec/forms/meeting_form_spec.rb @@ -38,7 +38,7 @@ module Decidim::Meetings let(:available_slots) { 0 } let(:registration_url) { "http://decidim.org" } let(:online_meeting_url) { "http://decidim.org" } - let(:show_embedded_iframe) { false } + let(:iframe_embed_type) { "none" } let(:registration_terms) { Faker::Lorem.sentence(word_count: 3) } let(:attributes) do { @@ -61,7 +61,7 @@ module Decidim::Meetings registration_terms: registration_terms, registrations_enabled: true, registration_url: registration_url, - show_embedded_iframe: show_embedded_iframe + iframe_embed_type: iframe_embed_type } end @@ -189,8 +189,8 @@ module Decidim::Meetings end describe "when online meeting url is present and the meeting is embedded and the url can't be embedded" do - let(:online_meeting_url) { "https://meet.jit.si/decidim" } - let(:show_embedded_iframe) { true } + let(:online_meeting_url) { "https://example.org/decidim" } + let(:iframe_embed_type) { "embed_in_meeting_page" } it { is_expected.not_to be_valid } end diff --git a/decidim-meetings/spec/jobs/decidim/meetings/upcoming_meeting_notification_job_spec.rb b/decidim-meetings/spec/jobs/decidim/meetings/upcoming_meeting_notification_job_spec.rb index 3a0a34759ada0..7a7949a5598c3 100644 --- a/decidim-meetings/spec/jobs/decidim/meetings/upcoming_meeting_notification_job_spec.rb +++ b/decidim-meetings/spec/jobs/decidim/meetings/upcoming_meeting_notification_job_spec.rb @@ -39,4 +39,26 @@ subject.perform_now(meeting.id, checksum) end end + + context "when the meeting is hidden" do + let!(:moderation) { create(:moderation, reportable: meeting, report_count: 1, hidden_at: Time.current) } + + it "doesn't notify the upcoming meeting" do + expect(Decidim::EventsManager) + .not_to receive(:publish) + + subject.perform_now(meeting.id, checksum) + end + end + + context "when the meeting is withdrawn" do + let(:meeting) { create :meeting, :withdrawn, start_time: start_time } + + it "doesn't notify the upcoming meeting" do + expect(Decidim::EventsManager) + .not_to receive(:publish) + + subject.perform_now(meeting.id, checksum) + end + end end diff --git a/decidim-meetings/spec/lib/decidim/content_parsers/meeting_parser_spec.rb b/decidim-meetings/spec/lib/decidim/content_parsers/meeting_parser_spec.rb new file mode 100644 index 0000000000000..aaf9bbc8afef7 --- /dev/null +++ b/decidim-meetings/spec/lib/decidim/content_parsers/meeting_parser_spec.rb @@ -0,0 +1,154 @@ +# frozen_string_literal: true + +require "spec_helper" + +module Decidim + module ContentParsers + describe MeetingParser do + let(:organization) { create(:organization, host: "my.host") } + let(:component) { create(:meeting_component, organization: organization) } + let(:context) { { current_organization: organization } } + let!(:parser) { Decidim::ContentParsers::MeetingParser.new(content, context) } + + describe "ContentParser#parse is invoked" do + let(:content) { "" } + + it "must call MeetingParser.parse" do + allow(described_class).to receive(:new).with(content, context).and_return(parser) + + result = Decidim::ContentProcessor.parse(content, context) + + expect(result.rewrite).to eq "" + expect(result.metadata[:meeting].class).to eq Decidim::ContentParsers::MeetingParser::Metadata + end + end + + describe "on parse" do + subject { parser.rewrite } + + context "when content is nil" do + let(:content) { nil } + + it { is_expected.to eq("") } + end + + context "when content is empty string" do + let(:content) { "" } + + it { is_expected.to eq("") } + end + + context "when content has no links" do + let(:content) { "whatever content with @mentions but no links." } + + it { is_expected.to eq(content) } + end + + context "when content has a link with a different host" do + let(:meeting) { create(:meeting, component: component) } + let(:content) do + url = changed_meeting_url(meeting) + "This content references meeting #{url}." + end + + it { is_expected.to eq("This content references meeting #{changed_meeting_url(meeting)}.") } + end + + context "when content links to an organization different from current" do + let(:meeting) { create(:meeting, component: component) } + let(:other_component) { create(:meeting_component, organization: create(:organization)) } + let(:external_meeting) { create(:meeting, component: other_component) } + let(:content) do + url = meeting_url(external_meeting) + "This content references meeting #{url}." + end + + it { is_expected.to eq(content) } + end + + context "when content has one link" do + let(:meeting) { create(:meeting, component: component) } + let(:content) do + url = meeting_url(meeting) + "This content references meeting #{url}." + end + + it { is_expected.to eq("This content references meeting #{meeting.to_global_id}.") } + end + + context "when content has one link that is a simple domain" do + let(:link) { "aaa:bbb" } + let(:content) do + "This content contains #{link} which is not a URI." + end + + it { is_expected.to eq(content) } + end + + context "when content has many links" do + let(:meeting1) { create(:meeting, component: component) } + let(:meeting2) { create(:meeting, component: component) } + let(:meeting3) { create(:meeting, component: component) } + let(:content) do + url1 = meeting_url(meeting1) + url2 = meeting_url(meeting2) + url3 = meeting_url(meeting3) + "This content references the following meetings: #{url1}, #{url2} and #{url3}. Great?I like them!" + end + + it { is_expected.to eq("This content references the following meetings: #{meeting1.to_global_id}, #{meeting2.to_global_id} and #{meeting3.to_global_id}. Great?I like them!") } + end + + context "when content has a link that is not in a meeting component" do + let(:meeting) { create(:meeting, component: component) } + let(:content) do + url = meeting_url(meeting).sub(%r{/meetings/}, "/something-else/") + "This content references a non-meeting with same ID as a meeting #{url}." + end + + it { is_expected.to eq(content) } + end + + context "when content has words similar to links but not links" do + let(:similars) do + %w(AA:aaa AA:sss aa:aaa aa:sss aaa:sss aaaa:sss aa:ssss aaa:ssss) + end + let(:content) do + "This content has similars to links: #{similars.join}. Great! Now are not treated as links" + end + + it { is_expected.to eq(content) } + end + + context "when meeting in content does not exist" do + let(:meeting) { create(:meeting, component: component) } + let(:url) { meeting_url(meeting) } + let(:content) do + meeting.destroy + "This content references meeting #{url}." + end + + it { is_expected.to eq("This content references meeting #{url}.") } + end + + context "when meeting is linked via ID" do + let(:meeting) { create(:meeting, component: component) } + let(:content) { "This content references meeting ~#{meeting.id}." } + + it { is_expected.to eq("This content references meeting #{meeting.to_global_id}.") } + end + end + + def meeting_url(meeting) + Decidim::ResourceLocatorPresenter.new(meeting).url + end + + def changed_meeting_url(meeting) + url = meeting_url(meeting) + regex = %r{http(s)?://my.host/(.*)} + url_path = regex.match(url)[2] + "http://my.another.host/#{url_path}" + end + end + end +end diff --git a/decidim-meetings/spec/lib/decidim/content_renderers/meeting_renderer_spec.rb b/decidim-meetings/spec/lib/decidim/content_renderers/meeting_renderer_spec.rb new file mode 100644 index 0000000000000..5f8e171af41d9 --- /dev/null +++ b/decidim-meetings/spec/lib/decidim/content_renderers/meeting_renderer_spec.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +require "spec_helper" + +module Decidim + module ContentRenderers + describe MeetingRenderer do + let!(:renderer) { Decidim::ContentRenderers::MeetingRenderer.new(content) } + + describe "on parse" do + subject { renderer.render } + + context "when content is nil" do + let(:content) { nil } + + it { is_expected.to eq("") } + end + + context "when content is empty string" do + let(:content) { "" } + + it { is_expected.to eq("") } + end + + context "when content has no gids" do + let(:content) { "whatever content with @mentions but no gids." } + + it { is_expected.to eq(content) } + end + + context "when content has one gid" do + let(:meeting) { create(:meeting) } + let(:content) do + "This content references meeting #{meeting.to_global_id}." + end + + it { is_expected.to eq("This content references meeting #{resource_as_html_link(meeting)}.") } + end + + context "when content has many links" do + let(:meeting_1) { create(:meeting) } + let(:meeting_2) { create(:meeting) } + let(:meeting_3) { create(:meeting) } + let(:content) do + gid1 = meeting_1.to_global_id + gid2 = meeting_2.to_global_id + gid3 = meeting_3.to_global_id + "This content references the following proposals: #{gid1}, #{gid2} and #{gid3}. Great?I like them!" + end + + it { is_expected.to eq("This content references the following proposals: #{resource_as_html_link(meeting_1)}, #{resource_as_html_link(meeting_2)} and #{resource_as_html_link(meeting_3)}. Great?I like them!") } + end + end + + def resource_url(resource) + Decidim::ResourceLocatorPresenter.new(resource).path + end + + def resource_as_html_link(resource) + href = resource_url(resource) + title = translated(resource.title) + %(#{title}) + end + end + end +end diff --git a/decidim-meetings/spec/lib/decidim/meetings/component_spec.rb b/decidim-meetings/spec/lib/decidim/meetings/component_spec.rb index 56230892ec0f2..7b65bd1b83aa4 100644 --- a/decidim-meetings/spec/lib/decidim/meetings/component_spec.rb +++ b/decidim-meetings/spec/lib/decidim/meetings/component_spec.rb @@ -61,6 +61,15 @@ expect(Decidim::Meetings::Meeting.where(component: component).count).to eq 3 expect(subject).to eq 2 end + + context "when having withdrawn meeting" do + let!(:withdrawn_meeting) { create :meeting, :withdrawn, component: component } + + it "will exclude the withdrawn one" do + expect(Decidim::Meetings::Meeting.where(component: component).count).to eq 4 + expect(subject).to eq 2 + end + end end describe "endorsements_count" do @@ -111,6 +120,7 @@ let!(:first_meeting) { create :meeting, :published } let(:component) { first_meeting.component } let!(:second_meeting) { create :meeting, :published, component: component } + let!(:unpublished_meeting) { create :meeting, component: component } let(:participatory_process) { component.participatory_space } let(:organization) { participatory_process.organization } @@ -118,7 +128,7 @@ let!(:user) { create :user, admin: true, organization: organization } it "exports all meetings from the component" do - expect(subject).to match_array([first_meeting, second_meeting]) + expect(subject).to match_array([first_meeting, second_meeting, unpublished_meeting]) end end end diff --git a/decidim-meetings/spec/lib/decidim/meetings/meeting_serializer_spec.rb b/decidim-meetings/spec/lib/decidim/meetings/meeting_serializer_spec.rb index a72e48fac353a..859b88db21d58 100644 --- a/decidim-meetings/spec/lib/decidim/meetings/meeting_serializer_spec.rb +++ b/decidim-meetings/spec/lib/decidim/meetings/meeting_serializer_spec.rb @@ -9,7 +9,7 @@ module Meetings described_class.new(meeting) end - let!(:meeting) { create(:meeting, contributions_count: 5, attendees_count: 10, attending_organizations: "Some organization") } + let!(:meeting) { create(:meeting, :published, contributions_count: 5, attendees_count: 10, attending_organizations: "Some organization") } let!(:category) { create(:category, participatory_space: component.participatory_space) } let!(:scope) { create(:scope, organization: component.participatory_space.organization) } let(:participatory_process) { component.participatory_space } @@ -122,6 +122,10 @@ module Meetings expect(serialized[:related_results].length).to eq(2) expect(serialized[:related_results].first).to match(%r{http.*/results}) end + + it "serialized the published column" do + expect(serialized).to include(published: meeting.published?) + end end end end diff --git a/decidim-meetings/spec/models/decidim/meetings/agenda_item_spec.rb b/decidim-meetings/spec/models/decidim/meetings/agenda_item_spec.rb index f7ee67c17ef9a..0ac3248f6f63c 100644 --- a/decidim-meetings/spec/models/decidim/meetings/agenda_item_spec.rb +++ b/decidim-meetings/spec/models/decidim/meetings/agenda_item_spec.rb @@ -30,6 +30,7 @@ module Meetings it "has an associated agenda" do expect(agenda_item.agenda).to be_a(Decidim::Meetings::Agenda) + expect(Decidim::Meetings::AgendaItem.last.agenda).to be_a(Decidim::Meetings::Agenda) end describe ".first_class" do diff --git a/decidim-meetings/spec/models/meeting_spec.rb b/decidim-meetings/spec/models/meeting_spec.rb index 59f9507024f41..e0ecdbc32b855 100644 --- a/decidim-meetings/spec/models/meeting_spec.rb +++ b/decidim-meetings/spec/models/meeting_spec.rb @@ -18,6 +18,7 @@ module Decidim::Meetings include_examples "has reference" include_examples "resourceable" include_examples "reportable" + include_examples "has comments availability attributes" it "has an association with one agenda" do subject.agenda = build_stubbed(:agenda) @@ -65,6 +66,35 @@ module Decidim::Meetings end end + describe "#visible_meeting_for" do + subject { Decidim::Meetings::Meeting.visible_meeting_for(user) } + + let(:meeting) { create :meeting, :published } + let(:user) { create :user, organization: meeting.component.organization } + + it "returns published meetings" do + expect(subject).to include(meeting) + end + + context "when the meeting is not published" do + let(:meeting) { create :meeting } + + it "does not returns the meeting" do + expect(subject).not_to include(meeting) + end + end + + context "when some participatory space does not have a model" do + before do + allow(Decidim::Assembly).to receive(:table_name).and_return(nil) + end + + it "does not return an exception" do + expect(subject).to include(meeting) + end + end + end + describe "#can_be_joined_by?" do subject { meeting.can_be_joined_by?(user) } @@ -99,6 +129,53 @@ module Decidim::Meetings end end + describe "#withdrawn?" do + context "when meeting is withdrawn" do + let(:meeting) { build :meeting, :withdrawn } + + it { is_expected.to be_withdrawn } + end + + context "when meeting is not withdrawn" do + let(:meeting) { build :meeting } + + it { is_expected.not_to be_withdrawn } + end + end + + describe "#withdrawable_by" do + let(:organization) { create :organization, available_locales: [:en] } + let(:participatory_process) { create :participatory_process, organization: organization } + let(:component) { create :component, participatory_space: participatory_process, manifest_name: "meetings" } + let(:author) { create(:user, organization: organization) } + + context "when user is author" do + let(:meeting) { create :meeting, component: component, author: author, created_at: Time.current } + + it { is_expected.to be_withdrawable_by(author) } + end + + context "when user is admin" do + let(:admin) { build(:user, :admin, organization: organization) } + let(:meeting) { build :meeting, author: author, created_at: Time.current } + + it { is_expected.not_to be_withdrawable_by(admin) } + end + + context "when user is not the author" do + let(:someone_else) { build(:user, organization: organization) } + let(:meeting) { build :meeting, author: author, created_at: Time.current } + + it { is_expected.not_to be_withdrawable_by(someone_else) } + end + + context "when meeting is already withdrawn" do + let(:meeting) { build :meeting, :withdrawn, author: author, created_at: Time.current } + + it { is_expected.not_to be_withdrawable_by(author) } + end + end + describe "#can_register_invitation?" do subject { meeting.can_register_invitation?(user) } @@ -231,7 +308,7 @@ module Decidim::Meetings end describe "pad_is_visible?" do - let(:pad) { instance_double(EtherpadLite::Pad, id: "pad-id", read_only_id: "read-only-id") } + let(:pad) { instance_double(Decidim::Etherpad::Pad, id: "pad-id", read_only_id: "read-only-id") } before do allow(meeting).to receive(:pad).and_return(pad) @@ -277,7 +354,7 @@ module Decidim::Meetings end describe "pad_is_writable?" do - let(:pad) { instance_double(EtherpadLite::Pad, id: "pad-id", read_only_id: "read-only-id") } + let(:pad) { instance_double(Decidim::Etherpad::Pad, id: "pad-id", read_only_id: "read-only-id") } before do allow(meeting).to receive(:pad).and_return(pad) diff --git a/decidim-meetings/spec/permissions/decidim/meetings/permissions_spec.rb b/decidim-meetings/spec/permissions/decidim/meetings/permissions_spec.rb index 0eaf6f92047c7..425011d5748af 100644 --- a/decidim-meetings/spec/permissions/decidim/meetings/permissions_spec.rb +++ b/decidim-meetings/spec/permissions/decidim/meetings/permissions_spec.rb @@ -132,6 +132,24 @@ end end + context "when withdrawing a meeting" do + let(:action) do + { scope: :public, action: :withdraw, subject: :meeting } + end + + context "when meeting author is the user trying to withdraw" do + let(:meeting) { create :meeting, author: user, component: meeting_component } + + it { is_expected.to eq true } + end + + context "when trying by another user" do + let(:user) { build :user } + + it { is_expected.to eq false } + end + end + context "when leaving a meeting" do let(:action) do { scope: :public, action: :leave, subject: :meeting } diff --git a/decidim-meetings/spec/presenters/decidim/meetings/meeting_presenter_spec.rb b/decidim-meetings/spec/presenters/decidim/meetings/meeting_presenter_spec.rb index 85989f1c6eae7..76c9ec996ce74 100644 --- a/decidim-meetings/spec/presenters/decidim/meetings/meeting_presenter_spec.rb +++ b/decidim-meetings/spec/presenters/decidim/meetings/meeting_presenter_spec.rb @@ -86,8 +86,17 @@ module Decidim::Meetings expect(meeting.description["machine_translations"]["es"]).to match(/gid:/) presented_description = presented_meeting.description(all_locales: true) - expect(presented_description["en"]).to eq("Description #description") - expect(presented_description["machine_translations"]["es"]).to eq("Description in Spanish #description") + expect(presented_description["en"]).to eq("
Description #description
") + expect(presented_description["machine_translations"]["es"]).to eq("
Description in Spanish #description
") + end + + context "when sanitizes any HTML input" do + let(:description1) { %(XSS via target in a tag) } + + it "removes the html input" do + presented_description = presented_meeting.description(all_locales: true, strip_tags: true) + expect(presented_description["en"]).to eq("XSS via target in a tag") + end end context "when sanitizes any HTML input" do diff --git a/decidim-meetings/spec/services/decidim/meetings/diff_renderer_spec.rb b/decidim-meetings/spec/services/decidim/meetings/diff_renderer_spec.rb index fdc5e0310cbe5..ef1c4a1a9bb79 100644 --- a/decidim-meetings/spec/services/decidim/meetings/diff_renderer_spec.rb +++ b/decidim-meetings/spec/services/decidim/meetings/diff_renderer_spec.rb @@ -98,8 +98,8 @@ location_en: "Location (English)", location_hints_ca: "Location hints (Català)", location_hints_en: "Location hints (English)", - start_time: "Start Time", - end_time: "End Time", + start_time: "Start time", + end_time: "End time", decidim_scope_id: "Scope" } labels = subject.map { |attribute, data| [attribute.to_sym, data[:label]] }.to_h @@ -128,8 +128,8 @@ location_en: "Location (English)", location_hints_ca: "Location hints (ca)", location_hints_en: "Location hints (English)", - start_time: "Start Time", - end_time: "End Time", + start_time: "Start time", + end_time: "End time", decidim_scope_id: "Scope" } labels = subject.map { |attribute, data| [attribute.to_sym, data[:label]] }.to_h diff --git a/decidim-meetings/spec/services/directory/meeting_search_spec.rb b/decidim-meetings/spec/services/directory/meeting_search_spec.rb new file mode 100644 index 0000000000000..a8ca6d8acf545 --- /dev/null +++ b/decidim-meetings/spec/services/directory/meeting_search_spec.rb @@ -0,0 +1,78 @@ +# frozen_string_literal: true + +require "spec_helper" + +module Decidim::Meetings::Directory + describe MeetingSearch do + subject { described_class.new(params).results } + + let!(:component) { create_list(:component, 3, manifest_name: "meetings") } + let(:user) { create :user, organization: component.first.organization } + let(:default_params) { { component: component, organization: component.first.organization, user: user } } + let(:params) { default_params } + + describe "a resource search with categories" do + let(:participatory_process) { component.first.participatory_space } + let(:params) { default_params.merge(category_id: category_ids) } + + describe "results" do + let!(:category1) { create :category, participatory_space: participatory_process } + let!(:category2) { create :category, participatory_space: participatory_process } + let!(:child_category) { create :category, participatory_space: participatory_process, parent: category2 } + let!(:meeting1) { create(:meeting, :published, component: component.first) } + let!(:meeting2) { create(:meeting, :published, component: component.first, category: category1) } + let!(:meeting3) { create(:meeting, :published, component: component.first, category: category2) } + let!(:meeting4) { create(:meeting, :published, component: component.first, category: child_category) } + + context "when no category filter is present" do + let(:category_ids) { nil } + + it "includes all resources" do + expect(subject).to match_array [meeting1, meeting2, meeting3, meeting4] + end + end + + context "when a category is selected" do + let(:category_ids) { [category2.id] } + + it "includes only resources for that category and its children" do + expect(subject).to match_array [meeting3, meeting4] + end + end + + context "when a participatory process is selected" do + let(:value) { participatory_process.class.name.gsub("::", "__") + participatory_process.id.to_s } + let(:category_ids) { [value] } + + it "includes only resources for that participatory_process - all categories and sub-categories" do + expect(subject).to match_array [meeting2, meeting3, meeting4] + end + end + + context "when a subcategory is selected" do + let(:category_ids) { [child_category.id] } + + it "includes only resources for that category" do + expect(subject).to eq [meeting4] + end + end + + context "when `without` is being sent" do + let(:category_ids) { ["without"] } + + it "returns resources without a category" do + expect(subject).to eq [meeting1] + end + end + + context "when `without` and some category id is being sent" do + let(:category_ids) { ["without", category1.id] } + + it "returns resources without a category and with the selected category" do + expect(subject).to match_array [meeting1, meeting2] + end + end + end + end + end +end diff --git a/decidim-meetings/spec/services/meeting_iframe_embedder_spec.rb b/decidim-meetings/spec/services/meeting_iframe_embedder_spec.rb index 3c8c6943ab7f9..ec09737fb08c8 100644 --- a/decidim-meetings/spec/services/meeting_iframe_embedder_spec.rb +++ b/decidim-meetings/spec/services/meeting_iframe_embedder_spec.rb @@ -69,7 +69,7 @@ module Meetings end context "with a not recognized streaming URL" do - let(:url) { "https://meet.jit.si/decidim-meeting" } + let(:url) { "https://example.org/decidim-meeting" } it "is not embeddable" do expect(subject).not_to be_embeddable @@ -85,6 +85,7 @@ module Meetings expect(embed_code).to include(subject.embed_transformed_url(request_host)) expect(embed_code).to include("title" }) + visit current_path + end + + it "displays the correct title" do + expect(page.html).to include("Meeting <strong>title</strong>") + end + end end describe "admin form" do @@ -364,7 +375,7 @@ expect(page).to have_no_field(:meeting_location_en) expect(page).to have_field("Online meeting URL") - select "Both", from: :meeting_type_of_meeting + select "Hybrid", from: :meeting_type_of_meeting expect(page).to have_field("Address") expect(page).to have_field(:meeting_location_en) expect(page).to have_field("Online meeting URL") @@ -443,6 +454,14 @@ end end + it "doesn't display error message when opening meeting's create form" do + find(".card-title a.button").click + + within "label[for='meeting_registration_type']" do + expect(page).to have_no_content("There's an error in this field.") + end + end + it "creates a new meeting", :slow do find(".card-title a.button").click diff --git a/decidim-meetings/spec/system/explore_meeting_directory_spec.rb b/decidim-meetings/spec/system/explore_meeting_directory_spec.rb index 57444ad0927bc..dabb82df17fff 100644 --- a/decidim-meetings/spec/system/explore_meeting_directory_spec.rb +++ b/decidim-meetings/spec/system/explore_meeting_directory_spec.rb @@ -3,16 +3,15 @@ require "spec_helper" describe "Explore meeting directory", type: :system do - let(:directory) do - Decidim::Meetings::DirectoryEngine.routes.url_helpers.root_path - end + let(:directory) { Decidim::Meetings::DirectoryEngine.routes.url_helpers.root_path } let(:organization) { create(:organization) } + let(:participatory_process) { create :participatory_process, organization: organization } let(:components) do create_list(:meeting_component, 3, organization: organization) end let!(:meetings) do components.flat_map do |component| - create_list(:meeting, 2, :published, component: component) + create_list(:meeting, 2, :published, :not_official, component: component) end end @@ -21,26 +20,264 @@ visit directory end - it "shows all the upcoming meetings" do - within "#meetings" do - expect(page).to have_css(".card--meeting", count: 6) + describe "with default filter" do + let!(:past_meeting) { create(:meeting, :published, start_time: 2.weeks.ago, component: components.first) } + let!(:upcoming_meeting) { create(:meeting, :published, :not_official, component: components.first) } + + it "shows all the upcoming meetings" do + visit directory + + within ".date_collection_radio_buttons_filter" do + expect(find("input[value='upcoming']").checked?).to be(true) + end + + within "#meetings" do + expect(page).to have_css(".card--meeting", count: 7) + end + + expect(page).to have_css("#meetings-count", text: "7 MEETINGS") + expect(page).to have_content(translated(upcoming_meeting.title)) end - expect(page).to have_css("#meetings-count", text: "6 MEETINGS") + it "doesn't show past meetings" do + within "#meetings" do + expect(page).not_to have_content(translated(past_meeting.title)) + end + end end - context "when there's a past meeting" do - let!(:past_meeting) do - create(:meeting, :published, component: components.last, start_time: 1.week.ago) + describe "text filter" do + it "updates the current URL" do + create(:meeting, :published, component: components[0], title: { en: "Foobar meeting" }) + create(:meeting, :published, component: components[1], title: { en: "Another meeting" }) + visit directory + + within "form.new_filter" do + fill_in("filter[search_text]", with: "foobar") + click_button "Search" + end + + within ".origin_check_boxes_tree_filter" do + uncheck "Citizens" + end + + expect(page).not_to have_content("Another meeting") + expect(page).to have_content("Foobar meeting") + + filter_params = CGI.parse(URI.parse(page.current_url).query) + expect(filter_params["filter[search_text]"]).to eq(["foobar"]) end + end - it "allows filtering by past events" do - within ".filters" do - choose "Past" + describe "category filter" do + context "with a category" do + let!(:category1) do + create(:category, participatory_space: participatory_process, name: { "en": "Category1" }) + end + let!(:meeting) do + meeting = meetings.first + meeting.category = category1 + meeting.save + meeting end - expect(page).to have_content(past_meeting.title["en"]) - expect(page).to have_css("#meetings-count", text: "1 MEETING") + it "shows tags for category" do + visit directory + + expect(page).to have_selector("ul.tags.tags--meeting") + within "ul.tags.tags--meeting" do + expect(page).to have_content(translated(meeting.category.name)) + end + end + + it "allows filtering by category" do + visit directory + + within ".category_id_check_boxes_tree_filter" do + check "All" + check translated(participatory_process.title) + end + + expect(page).to have_content(translated(participatory_process.title)) + expect(page).to have_content(translated(meeting.category.name)) + end + end + end + + context "with a scope" do + let!(:scope) { create(:scope, organization: organization) } + let!(:meeting) do + meeting = meetings.first + meeting.scope = scope + meeting.save + meeting + end + + it "allows filtering by scope" do + visit directory + + within ".scope_id_check_boxes_tree_filter" do + check "All" + check translated(meeting.scope.name) + end + + expect(page).to have_content(translated(meeting.scope.name)) + end + end + + describe "origin filter" do + context "with 'official'" do + let!(:official_meeting) { create(:meeting, :published, :official, component: components.first, author: organization) } + + it "lists the filtered meetings" do + visit directory + + within ".origin_check_boxes_tree_filter" do + uncheck "All" + check "Official" + end + + expect(page).to have_content("1 MEETING") + expect(page).to have_css(".card--meeting", count: 1) + + within ".card--meeting" do + expect(page).to have_content("Official meeting") + end + end + end + + context "with 'groups' origin" do + let!(:user_group_meeting) { create(:meeting, :published, :user_group_author, component: components.first) } + + it "lists the filtered meetings" do + visit directory + + within ".origin_check_boxes_tree_filter" do + uncheck "All" + check "Groups" + end + + expect(page).to have_content("1 MEETING") + expect(page).to have_css(".card--meeting", count: 1) + within ".card--meeting" do + expect(page).to have_content(user_group_meeting.normalized_author.name) + end + end + end + + context "with 'citizens' origin" do + it "lists the filtered meetings" do + visit directory + + within ".origin_check_boxes_tree_filter" do + uncheck "All" + check "Citizens" + end + + expect(page).to have_css(".card--meeting", count: 6) + expect(page).to have_content("6 MEETINGS") + end + end + end + + describe "type filter" do + context "when there are only online meetings" do + let!(:online_meeting1) { create(:meeting, :published, :online, component: components.last) } + let!(:online_meeting2) { create(:meeting, :published, :online, component: components.last) } + + it "allows filtering by type 'online'" do + within ".type_check_boxes_tree_filter" do + uncheck "All" + check "Online" + end + + expect(page).to have_content(online_meeting1.title["en"]) + expect(page).to have_content(online_meeting2.title["en"]) + expect(page).to have_css("#meetings-count", text: "2 MEETINGS") + end + end + + context "when there are only in-person meetings" do + let!(:in_person_meeting) { create(:meeting, :published, :in_person, component: components.last) } + + it "allows filtering by type 'in-person'" do + within ".type_check_boxes_tree_filter" do + uncheck "All" + check "In-person" + end + + expect(page).to have_content(in_person_meeting.title["en"]) + expect(page).to have_css("#meetings-count", text: "7 MEETINGS") # default meeting component it's with type "in-person" + end + end + + context "when there are hybrid meetings" do + let!(:online_meeting) { create(:meeting, :published, :hybrid, component: components.last) } + + it "allows filtering by type 'both'" do + within ".type_check_boxes_tree_filter" do + uncheck "All" + check "Hybrid" + end + + expect(page).to have_css("#meetings-count", text: "1 MEETING") + end + end + end + + describe "date filter" do + let!(:past_meeting1) { create(:meeting, :published, component: components.last, start_time: 1.week.ago) } + let!(:past_meeting2) { create(:meeting, :published, component: components.last, start_time: 3.months.ago) } + let!(:past_meeting3) { create(:meeting, :published, component: components.last, start_time: 2.days.ago) } + let!(:upcoming_meeting1) { create(:meeting, :published, component: components.last, start_time: 1.week.from_now) } + let!(:upcoming_meeting2) { create(:meeting, :published, component: components.last, start_time: 3.months.from_now) } + let!(:upcoming_meeting3) { create(:meeting, :published, component: components.last, start_time: 2.days.from_now) } + + context "with all meetings" do + it "orders them by start date" do + visit directory + + within ".date_collection_radio_buttons_filter" do + choose "All" + end + + expect(page).to have_css("#meetings-count", text: "12 MEETINGS") + + result = page.find("#meetings .card-grid").text + expect(result.index(translated(past_meeting2.title))).to be < result.index(translated(past_meeting1.title)) + expect(result.index(translated(past_meeting1.title))).to be < result.index(translated(past_meeting3.title)) + expect(result.index(translated(past_meeting2.title))).to be < result.index(translated(upcoming_meeting1.title)) + expect(result.index(translated(upcoming_meeting3.title))).to be < result.index(translated(upcoming_meeting1.title)) + expect(result.index(translated(upcoming_meeting1.title))).to be < result.index(translated(upcoming_meeting2.title)) + end + end + + context "with past meetings" do + it "orders them by start date" do + visit directory + + within ".date_collection_radio_buttons_filter" do + choose "Past" + end + + expect(page).to have_css("#meetings-count", text: "3 MEETINGS") + + result = page.find("#meetings .card-grid").text + expect(result.index(translated(past_meeting3.title))).to be < result.index(translated(past_meeting1.title)) + expect(result.index(translated(past_meeting1.title))).to be < result.index(translated(past_meeting2.title)) + end + end + + context "with upcoming meetings" do + it "orders them by start date" do + visit directory + + expect(page).to have_css("#meetings-count", text: "9 MEETINGS") + + result = page.find("#meetings .card-grid").text + expect(result.index(translated(upcoming_meeting3.title))).to be < result.index(translated(upcoming_meeting1.title)) + expect(result.index(translated(upcoming_meeting1.title))).to be < result.index(translated(upcoming_meeting2.title)) + end end end @@ -66,14 +303,17 @@ # have_content to wait for the card list to change. This is a hack to # reset the contents to no meetings at all, and then showing only the upcoming # assembly meetings. - within ".filters" do + within ".date_collection_radio_buttons_filter" do choose "Past" end expect(page).to have_no_css(".card--meeting") + within(all(".filters__section")[7]) do + uncheck "All" + check "Assemblies" + end - within ".filters" do - choose "Assemblies" + within ".date_collection_radio_buttons_filter" do choose "Upcoming" end diff --git a/decidim-meetings/spec/system/explore_meetings_spec.rb b/decidim-meetings/spec/system/explore_meetings_spec.rb index 0e5ebe8ba9056..370b6ba2130c4 100644 --- a/decidim-meetings/spec/system/explore_meetings_spec.rb +++ b/decidim-meetings/spec/system/explore_meetings_spec.rb @@ -27,6 +27,66 @@ end end + context "with default filter" do + let!(:past_meeting) { create(:meeting, :published, start_time: 2.weeks.ago, component: component) } + let!(:upcoming_meeting) { create(:meeting, :published, :not_official, component: component) } + + it "shows all the upcoming meetings" do + visit_component + within ".date_collection_radio_buttons_filter" do + expect(find("input[value='upcoming']").checked?).to be(true) + end + + within "#meetings" do + expect(page).to have_css(".card--meeting", count: 6) + end + + expect(page).to have_css("#meetings-count", text: "6 MEETINGS") + expect(page).to have_content(translated(upcoming_meeting.title)) + end + + it "doesn't show past meetings" do + visit_component + within "#meetings" do + expect(page).not_to have_content(translated(past_meeting.title)) + end + end + end + + context "when checking withdrawn meetings" do + context "when there are no withrawn meetings" do + let!(:meeting) { create_list(:meeting, 3, :published, component: component) } + + before do + visit_component + click_link "See all withdrawn meetings" + end + + it "shows an empty page with a message" do + expect(page).to have_content("No meetings match your search criteria or there isn't any meeting scheduled.") + within ".callout.warning", match: :first do + expect(page).to have_content("You are viewing the list of meetings withdrawn by their authors.") + end + end + end + + context "when there are withrawn meetings" do + let!(:withdrawn_meetings) { create_list(:meeting, 3, :withdrawn, :published, component: component) } + + before do + visit_component + click_link "See all withdrawn meetings" + end + + it "shows all the withdrawn meetings" do + expect(page).to have_css(".card--meeting.alert", count: 3) + within ".callout.warning", match: :first do + expect(page).to have_content("You are viewing the list of meetings withdrawn by their authors.") + end + end + end + end + context "with hidden meetings" do let(:meeting) { meetings.last } @@ -62,6 +122,29 @@ end context "when filtering" do + context "when filtering by text" do + it "updates the current URL" do + create(:meeting, :published, component: component, title: { en: "Foobar meeting" }) + create(:meeting, :published, component: component, title: { en: "Another meeting" }) + visit_component + + within "form.new_filter" do + fill_in("filter[search_text]", with: "foobar") + click_button "Search" + end + + within ".category_id_check_boxes_tree_filter" do + uncheck "All" + end + + expect(page).not_to have_content("Another meeting") + expect(page).to have_content("Foobar meeting") + + filter_params = CGI.parse(URI.parse(page.current_url).query) + expect(filter_params["filter[search_text]"]).to eq(["foobar"]) + end + end + context "when filtering by origin" do let!(:component) do create(:meeting_component, @@ -143,24 +226,123 @@ expect(page).to have_content(translated(meetings.first.title)) end - it "allows filtering by date" do + context "when filtering by date" do + let!(:past_meeting1) { create(:meeting, :published, component: component, start_time: 1.week.ago) } + let!(:past_meeting2) { create(:meeting, :published, component: component, start_time: 3.months.ago) } + let!(:past_meeting3) { create(:meeting, :published, component: component, start_time: 2.days.ago) } + let!(:upcoming_meeting1) { create(:meeting, :published, component: component, start_time: 1.week.from_now) } + let!(:upcoming_meeting2) { create(:meeting, :published, component: component, start_time: 3.months.from_now) } + let!(:upcoming_meeting3) { create(:meeting, :published, component: component, start_time: 2.days.from_now) } + + it "lists filtered meetings" do + visit_component + + within ".date_collection_radio_buttons_filter" do + choose "Past" + end + + expect(page).to have_css(".card--meeting", count: 3) + expect(page).to have_content(translated(past_meeting1.title)) + expect(page).not_to have_content(translated(upcoming_meeting1.title)) + + within ".date_collection_radio_buttons_filter" do + choose "Upcoming" + end + + expect(page).to have_content(translated(upcoming_meeting1.title)) + expect(page).not_to have_content(translated(past_meeting1.title)) + + expect(page).to have_css(".card--meeting", count: 8) + + within ".date_collection_radio_buttons_filter" do + choose "All" + end + + expect(page).to have_css(".card--meeting", count: 8) + expect(page).to have_content(translated(past_meeting1.title)) + expect(page).to have_content(translated(upcoming_meeting1.title)) + end + + context "when there are multiple past meetings" do + it "orders them by start date" do + visit_component + within ".date_collection_radio_buttons_filter" do + choose "Past" + end + + expect(page).to have_css("#meetings-count", text: "3 MEETINGS") + + result = page.find("#meetings .card-grid").text + expect(result.index(translated(past_meeting3.title))).to be < result.index(translated(past_meeting1.title)) + expect(result.index(translated(past_meeting1.title))).to be < result.index(translated(past_meeting2.title)) + end + end + + context "when there are multiple upcoming meetings" do + it "orders them by start date" do + visit_component + within ".date_collection_radio_buttons_filter" do + choose "Upcoming" + end + + expect(page).to have_css("#meetings-count", text: "8 MEETINGS") + + result = page.find("#meetings .card-grid").text + expect(result.index(translated(upcoming_meeting3.title))).to be < result.index(translated(upcoming_meeting1.title)) + expect(result.index(translated(upcoming_meeting1.title))).to be < result.index(translated(upcoming_meeting2.title)) + end + end + + context "when there are multiple meetings" do + it "orders them by start date" do + visit_component + within ".date_collection_radio_buttons_filter" do + choose "All" + end + + expect(page).to have_css("#meetings-count", text: "11 MEETINGS") + + result = page.find("#meetings .card-grid").text + expect(result.index(translated(past_meeting2.title))).to be < result.index(translated(past_meeting1.title)) + expect(result.index(translated(past_meeting1.title))).to be < result.index(translated(past_meeting3.title)) + expect(result.index(translated(past_meeting2.title))).to be < result.index(translated(upcoming_meeting1.title)) + expect(result.index(translated(upcoming_meeting3.title))).to be < result.index(translated(upcoming_meeting1.title)) + expect(result.index(translated(upcoming_meeting1.title))).to be < result.index(translated(upcoming_meeting2.title)) + end + end + end + + it "allows linking to the filtered view using a short link" do past_meeting = create(:meeting, :published, component: component, start_time: 1.day.ago) visit_component - within ".date_check_boxes_tree_filter" do - uncheck "All" - check "Past" + within ".date_collection_radio_buttons_filter" do + choose "Past" end expect(page).to have_css(".card--meeting", count: 1) expect(page).to have_content(translated(past_meeting.title)) - within ".date_check_boxes_tree_filter" do - uncheck "All" - check "Upcoming" + filter_params = CGI.parse(URI.parse(page.current_url).query) + base_url = "http://#{organization.host}" + + click_button "Export calendar" + expect(page).to have_content("Calendar URL:") + expect(page).to have_css("#calendarShare", visible: :visible) + share_url = nil + within "#calendarShare" do + input = find("input[readonly]") + share_url = input.value + expect(share_url).to match(%r{^#{base_url}:[0-9]+/processes/#{participatory_process.slug}/f/#{component.id}/calendar$}) end - expect(page).to have_css(".card--meeting", count: 5) + visit share_url + expect(page).to have_css(".card--meeting", count: 1) + expect(page).to have_content(translated(past_meeting.title)) + expect(page).to have_current_path(/^#{main_component_path(component)}/) + + current_params = CGI.parse(URI.parse(page.current_url).query) + expect(current_params).to eq(filter_params) end it "allows filtering by scope" do @@ -179,6 +361,28 @@ expect(page).to have_css(".card--meeting", count: 1) end + + it "works with 'back to list' link" do + scope = create(:scope, organization: organization) + meeting = meetings.first + meeting.scope = scope + meeting.save + + visit_component + + within ".scope_id_check_boxes_tree_filter" do + check "All" + uncheck "All" + check translated(scope.name) + end + + expect(page).to have_css(".card--meeting", count: 1) + + find(".card--meeting .card__link").click + click_link "Back to list" + + expect(page).to have_css(".card--meeting", count: 1) + end end context "when no upcoming meetings scheduled" do diff --git a/decidim-meetings/spec/system/explore_versions_spec.rb b/decidim-meetings/spec/system/explore_versions_spec.rb index d9077a79bd655..ef53720914f33 100644 --- a/decidim-meetings/spec/system/explore_versions_spec.rb +++ b/decidim-meetings/spec/system/explore_versions_spec.rb @@ -70,6 +70,8 @@ end end + it_behaves_like "accessible page" + it "shows the version number" do expect(page).to have_content("VERSION NUMBER\n2 out of 2") end diff --git a/decidim-meetings/spec/system/live_meeting_access_spec.rb b/decidim-meetings/spec/system/live_meeting_access_spec.rb index 5f7cee8519076..a9b2a22c592f5 100644 --- a/decidim-meetings/spec/system/live_meeting_access_spec.rb +++ b/decidim-meetings/spec/system/live_meeting_access_spec.rb @@ -20,16 +20,216 @@ def visit_meeting end context "when online meeting is live" do - let(:meeting) { create :meeting, :published, :online, :live, component: component } + shared_examples "iframe access levels" do |embedding_type| + context "when the iframe access level is for all visitors" do + before do + meeting.iframe_access_level_all! + end - it "shows the link to the live meeting streaming" do - visit_meeting + context "and user is signed in" do + before do + login_as user, scope: :user + end + + it "shows the meeting link embedded" do + visit_meeting + + expect(page).to have_content("This meeting is happening right now") + case embedding_type + when :embedded + expect(page).to have_css("iframe") + else + expect(page).to have_content("JOIN MEETING") + end + end + end + end + + context "and the iframe access level is for signed in visitors" do + before do + meeting.iframe_access_level_signed_in! + end + + context "and user is not signed in" do + it "doesn't show the meeting link embedded" do + visit_meeting + + expect(page).to have_no_content("This meeting is happening right now") + case embedding_type + when :embedded + expect(page).to have_no_css("iframe") + else + expect(page).to have_no_content("JOIN MEETING") + end + end + end + + context "and user is signed in" do + before do + login_as user, scope: :user + end + + it "shows the meeting link embedded" do + visit_meeting + + expect(page).to have_content("This meeting is happening right now") + case embedding_type + when :embedded + expect(page).to have_css("iframe") + else + expect(page).to have_content("JOIN MEETING") + end + end + end + end + + context "and the iframe access level is for registered visitors" do + before do + meeting.iframe_access_level_registered! + end + + let!(:registered_user) { create :user, :confirmed, organization: organization } + let!(:registration) { create :registration, meeting: meeting, user: registered_user } + + context "and user is not signed in" do + it "doesn't show the meeting link embedded" do + visit_meeting + + expect(page).to have_no_content("This meeting is happening right now") + case embedding_type + when :embedded + expect(page).to have_no_css("iframe") + else + expect(page).to have_no_content("JOIN MEETING") + end + end + end + + context "and not registered user is signed in" do + before do + login_as user, scope: :user + end + + it "doesn't show the meeting link embedded" do + visit_meeting + + expect(page).to have_no_content("This meeting is happening right now") + case embedding_type + when :embedded + expect(page).to have_no_css("iframe") + else + expect(page).to have_no_content("JOIN MEETING") + end + end + end + + context "and registered user is signed in" do + before do + login_as registered_user, scope: :user + end + + it "shows the meeting link embedded" do + visit_meeting + + expect(page).to have_content("This meeting is happening right now") + case embedding_type + when :embedded + expect(page).to have_css("iframe") + else + expect(page).to have_content("JOIN MEETING") + end + end + end + end + end + + shared_examples "belonging to an assembly which is a transparent private space" do + let(:assembly) { create(:assembly, :private, :transparent, organization: organization) } + let(:participatory_space) { assembly } + let(:admin) { create :user, :confirmed, :admin, organization: organization } + let(:private_user) { create :user, :confirmed, organization: organization } + let!(:assembly_private_user) { create :assembly_private_user, user: private_user, privatable_to: assembly } + + context "when user is not signed in" do + it "doesn't show the meeting link embedded" do + visit_meeting + + expect(page).to have_no_content("This meeting is happening right now") + end + end + + context "when user is signed in" do + before do + login_as user, scope: :user + end + + it "doesn't show the meeting link embedded" do + visit_meeting + + expect(page).to have_no_content("This meeting is happening right now") + end + end + + context "when private user is signed in" do + before do + login_as private_user, scope: :user + end + + it "shows the meeting link embedded" do + visit_meeting + + expect(page).to have_content("This meeting is happening right now") + end + end + + context "when admin user is signed in" do + before do + login_as admin, scope: :user + end - expect(page).to have_content("This meeting is happening right now") + it "shows the meeting link embedded" do + visit_meeting + + expect(page).to have_content("This meeting is happening right now") + end + end + end + + context "and the iframe_embed_type is none" do + let(:meeting) { create :meeting, :published, :online, :live, component: component } + + it "doesn't show the link to the live meeting streaming" do + visit_meeting + + expect(page).to have_no_content("This meeting is happening right now") + end + end + + context "and the iframe_embed_type is 'embed_in_meeting_page'" do + let(:meeting) { create :meeting, :published, :embed_in_meeting_page_iframe_embed_type, :online, :embeddable, :live, component: component } + + context "and the meeting URL is not embeddable" do + let(:meeting) { create :meeting, :published, :embed_in_meeting_page_iframe_embed_type, :online, :live, component: component } + + it "shows the link to the live meeting streaming" do + visit_meeting + + expect(page).to have_content("This meeting is happening right now") + end + end + + it "shows the meeting link embedded" do + visit_meeting + + expect(page).to have_css("iframe") + end + + it_behaves_like "iframe access levels", :embedded + it_behaves_like "belonging to an assembly which is a transparent private space" end - context "when the meeting is configured to not embed the iframe" do - let(:meeting) { create :meeting, :published, :online, :live, :embeddable, component: component } + context "and the iframe_embed_type is 'open_in_live_event_page'" do + let(:meeting) { create :meeting, :published, :online, :open_in_live_event_page_iframe_embed_type, :live, :embeddable, component: component } it "shows the link to the live meeting streaming" do visit_meeting @@ -40,12 +240,29 @@ def visit_meeting expect(page).to have_current_path(meeting_live_event_path) end end + + context "and the meeting URL is not embeddable" do + let(:meeting) { create :meeting, :published, :online, :open_in_live_event_page_iframe_embed_type, :live, component: component } + + it "shows the link to the external streaming service" do + visit_meeting + + # Join the meeting displays a warning to users because + # is redirecting to a different domain + click_link "Join meeting" + + expect(page).to have_content("Open external link") + end + end + + it_behaves_like "iframe access levels", :live_event_page + it_behaves_like "belonging to an assembly which is a transparent private space" end - context "when the meeting is configured to not embed the iframe and is not embeddable" do - let(:meeting) { create :meeting, :published, :online, :live, component: component } + context "and the iframe_embed_type is 'open_in_new_tab'" do + let(:meeting) { create :meeting, :published, :online, :open_in_new_tab_iframe_embed_type, :live, component: component } - it "shows the link to the external streaming service" do + it "shows the link to the meeting URL" do visit_meeting # Join the meeting displays a warning to users because @@ -54,16 +271,8 @@ def visit_meeting expect(page).to have_content("Open external link") end - end - - context "when the meeting is configured to show the iframe embedded" do - let(:meeting) { create :meeting, :published, :show_embedded_iframe, :online, :embeddable, :live, component: component } - it "shows the meeting link embedded" do - visit_meeting - - expect(page).to have_css("iframe") - end + it_behaves_like "belonging to an assembly which is a transparent private space" end end @@ -78,17 +287,17 @@ def visit_meeting end context "when online meeting is not live and is not embedded" do - let(:meeting) { create :meeting, :published, :show_embedded_iframe, :online, :embeddable, component: component } + let(:meeting) { create :meeting, :published, :embed_in_meeting_page_iframe_embed_type, :online, :embeddable, component: component } - it "shows the meeting link embedded" do + it "doesn't show the meeting link embedded" do visit_meeting - expect(page).to have_css("iframe") + expect(page).to have_no_css("iframe") end end describe "live meeting access" do - let(:meeting) { create :meeting, :published, :online, component: component } + let(:meeting) { create :meeting, :published, :online, :embed_in_meeting_page_iframe_embed_type, component: component } let(:start_time) { meeting.start_time } let(:end_time) { meeting.end_time } diff --git a/decidim-meetings/spec/system/live_meeting_spec.rb b/decidim-meetings/spec/system/live_meeting_spec.rb index 9c475fa516fb2..23dd20bec7935 100644 --- a/decidim-meetings/spec/system/live_meeting_spec.rb +++ b/decidim-meetings/spec/system/live_meeting_spec.rb @@ -37,4 +37,37 @@ click_link "close" expect(page).to have_current_path meeting_path end + + context "when user is logged and session is about to timeout" do + before do + allow(Decidim.config).to receive(:expire_session_after).and_return(2.minutes) + allow(Decidim.config).to receive(:session_timeout_interval).and_return(1.second) + switch_to_host(organization.host) + login_as user, scope: :user + visit meeting_live_event_path + end + + context "when meeting is live" do + let(:meeting) { create(:meeting, :published, :online, :embed_in_meeting_page_iframe_embed_type, component: component, start_time: 1.minute.ago, end_time: end_time) } + let(:end_time) { Time.current + 1.hour } + + it "does not timeout user" do + travel 5.minutes + expect(page).to have_selector("[aria-label='User account: #{user.name}']") + expect(page).not_to have_content("If you continue being inactive", wait: 4) + expect(page).not_to have_content("You were inactive for too long") + end + + context "and ends soon" do + let(:end_time) { Time.current + 15.seconds } + + it "logouts user" do + travel 1.minute + expect(page).to have_content("If you continue being inactive", wait: 30) + allow(Time).to receive(:current).and_return(Time.current + 1.minute) + expect(page).to have_content("You are not allowed to view this meeting") + end + end + end + end end diff --git a/decidim-meetings/spec/system/meeting_registrations_spec.rb b/decidim-meetings/spec/system/meeting_registrations_spec.rb index be13f49a462f5..048d1c730d3a2 100644 --- a/decidim-meetings/spec/system/meeting_registrations_spec.rb +++ b/decidim-meetings/spec/system/meeting_registrations_spec.rb @@ -37,6 +37,9 @@ def questionnaire_public_path available_slots: available_slots, registration_terms: registration_terms ) + + # Make static map requests not to fail with HTTP 500 (causes JS error) + stub_request(:get, Regexp.new(Decidim.maps.fetch(:static).fetch(:url))).to_return(body: "") end context "when meeting registrations are not enabled" do @@ -134,7 +137,7 @@ def questionnaire_public_path end within ".card.extra" do - click_button "Inscriu-te a la trobada" + click_button "Unir-se a la trobada" end within "#loginModal" do @@ -315,6 +318,51 @@ def questionnaire_public_path expect(page).to have_button("Submit") end end + + context "when the registration form has file question and file is invalid" do + let!(:question) { create(:questionnaire_question, questionnaire: questionnaire, position: 0, question_type: :files) } + + before do + login_as user, scope: :user + end + + it "shows errors for invalid file" do + visit questionnaire_public_path + + input_element = find("input[type='file']", visible: :all) + input_element.attach_file(Decidim::Dev.asset("verify_user_groups.csv")) + + expect(page).to have_field("public_participation", checked: false) + find(".tos-agreement").set(true) + click_button "Submit" + + within ".confirm-modal-footer" do + find("a.button[data-confirm-ok]").click + end + + expect(page).to have_content("Needs to be reattached") + end + + context "and the announcement for the meeting is configured" do + before do + component.update!( + settings: { + announcement: { + en: "An important announcement", + es: "Un aviso muy importante", + ca: "Un avís molt important" + } + } + ) + end + + it "the user should not see it" do + visit questionnaire_public_path + + expect(page).not_to have_content("An important announcement") + end + end + end end context "and the user is going to the meeting" do diff --git a/decidim-meetings/spec/system/meeting_spec.rb b/decidim-meetings/spec/system/meeting_spec.rb index 194435c95b6af..f5a0d27f3c81f 100644 --- a/decidim-meetings/spec/system/meeting_spec.rb +++ b/decidim-meetings/spec/system/meeting_spec.rb @@ -127,21 +127,66 @@ def visit_meeting it "doesn't show the year" do visit_meeting - within ".extra__date" do + within ".extra__date-container" do expect(page).to have_no_content(meeting.start_time.year) end end end context "when the meeting is different from the current year" do - let(:meeting) { create(:meeting, :published, component: component, start_time: 1.year.ago) } + let(:meeting) { create(:meeting, :published, component: component, start_time: 1.year.ago, end_time: 1.year.ago + 7.days) } it "shows the year" do visit_meeting - within ".extra__date" do + within ".extra__date-container" do expect(page).to have_content(meeting.start_time.year) end end end + + context "when user is logged and session is about to timeout" do + before do + allow(Decidim.config).to receive(:expire_session_after).and_return(2.minutes) + allow(Decidim.config).to receive(:session_timeout_interval).and_return(1.second) + login_as user, scope: :user + end + + context "when meeting is live" do + let(:meeting) { create(:meeting, :published, component: component, start_time: 1.minute.ago, end_time: Time.current + 1.hour) } + + it "does not timeout user" do + visit_meeting + travel 1.minute + expect(page).not_to have_content("If you continue being inactive", wait: 4) + expect(page).not_to have_content("You were inactive for too long") + end + end + + context "when meeting is in future" do + let(:meeting) { create(:meeting, :published, component: component, start_time: Time.current + 1.day, end_time: Time.current + 1.day + 2.hours) } + + it "timeouts user normally" do + visit_meeting + travel 1.minute + expect(page).to have_content("You were inactive for too long") + end + + context "when comments are enabled" do + let(:comment) { create(:comment, commentable: meeting) } + + before do + component.settings[:comments_enabled] = true + end + + it "fetching comments doesnt prevent timeout" do + visit_meeting + comment + expect(page).to have_content(translated(comment.body), wait: 30) + expect(page).to have_content("If you continue being inactive", wait: 30) + expect(page).to have_content("You were inactive for too long", wait: 30) + end + end + end + end end diff --git a/decidim-meetings/spec/system/participatory_processes_view_hooks_spec.rb b/decidim-meetings/spec/system/participatory_processes_view_hooks_spec.rb index 73eb55a1fe143..9a6b092fa5ba8 100644 --- a/decidim-meetings/spec/system/participatory_processes_view_hooks_spec.rb +++ b/decidim-meetings/spec/system/participatory_processes_view_hooks_spec.rb @@ -8,6 +8,7 @@ let(:meetings_count) { 5 } context "when there are only past meetings" do + let!(:moderated_meeting) { create(:meeting, :moderated, :published, :past, component: component, end_time: 5.hours.ago) } let!(:past_meetings) do create_list(:meeting, meetings_count, :published, :past, component: component) end @@ -16,6 +17,8 @@ visit resource_locator(participatory_process).path expect(page).to have_css(".past_meetings .card--list__item", count: 3) + expect(page).not_to have_content(/#{translated(moderated_meeting.title)}/i) + past_meetings.sort_by { |m| [m.end_time, m.start_time] }.last(3).each do |meeting| expect(page).to have_content(/#{translated(meeting.title)}/i) end @@ -26,11 +29,14 @@ let!(:upcoming_meetings) do create_list(:meeting, meetings_count, :published, :upcoming, component: component) end + let!(:moderated_meeting) { create(:meeting, :moderated, :published, :upcoming, component: component) } it "shows the first three upcoming meetings" do visit resource_locator(participatory_process).path expect(page).to have_css(".upcoming_meetings .card--list__item", count: 3) + expect(page).not_to have_content(/#{translated(moderated_meeting.title)}/i) + upcoming_meetings.sort_by { |m| [m.start_time, m.end_time] }.first(3).each do |meeting| expect(page).to have_content(/#{translated(meeting.title)}/i) end diff --git a/decidim-meetings/spec/system/user_close_meeting_spec.rb b/decidim-meetings/spec/system/user_close_meeting_spec.rb index 03a06e53425fa..250f8d699fdde 100644 --- a/decidim-meetings/spec/system/user_close_meeting_spec.rb +++ b/decidim-meetings/spec/system/user_close_meeting_spec.rb @@ -30,6 +30,7 @@ describe "closing my own meeting" do let(:closing_report) { "The meeting went pretty well, yep." } + let(:edit_closing_report) { "The meeting went pretty well, yep." } before do login_as user, scope: :user @@ -58,6 +59,43 @@ expect(meeting.reload.closed_at).not_to be nil end + context "when updates the meeting report" do + let!(:meeting) do + create(:meeting, + :published, + :past, + :closed, + title: { en: "Meeting title with #hashtag" }, + description: { en: "Meeting description" }, + author: user, + attendees_count: nil, + attending_organizations: nil, + component: component) + end + + it "updates the meeting report" do + visit_component + + click_link translated(meeting.title) + click_link "Edit meeting report" + + expect(page).to have_content "CLOSE MEETING" + + within "form.edit_close_meeting" do + expect(page).to have_content "Choose proposals" + fill_in :close_meeting_attendees_count, with: 10 + fill_in :close_meeting_closing_report, with: edit_closing_report + + click_button "Close meeting" + end + + expect(page).to have_content(edit_closing_report) + expect(page).not_to have_content "Close meeting" + expect(page).not_to have_content "ATTENDING ORGANIZATIONS" + expect(meeting.reload.closed_at).not_to be nil + end + end + context "when proposal linking is disabled" do before do allow(Decidim::Meetings).to receive(:enable_proposal_linking).and_return(false) diff --git a/decidim-meetings/spec/system/user_creates_meeting_spec.rb b/decidim-meetings/spec/system/user_creates_meeting_spec.rb index 40500035b7cd1..d24c9a12677b1 100644 --- a/decidim-meetings/spec/system/user_creates_meeting_spec.rb +++ b/decidim-meetings/spec/system/user_creates_meeting_spec.rb @@ -277,7 +277,7 @@ expect(page).to have_no_field(:meeting_location) expect(page).to have_field("Online meeting URL") - select "Both", from: :meeting_type_of_meeting + select "Hybrid", from: :meeting_type_of_meeting expect(page).to have_field("Address") expect(page).to have_field(:meeting_location) expect(page).to have_field("Online meeting URL") diff --git a/decidim-meetings/spec/system/user_edit_meeting_spec.rb b/decidim-meetings/spec/system/user_edit_meeting_spec.rb index a3f6fe322d226..7d42806ad3519 100644 --- a/decidim-meetings/spec/system/user_edit_meeting_spec.rb +++ b/decidim-meetings/spec/system/user_edit_meeting_spec.rb @@ -87,6 +87,28 @@ expect(page).to have_content("problem updating") end end + + context "when rich_text_editor_in_public_views is disabled" do + before { organization.update(rich_text_editor_in_public_views: false) } + + it "displays the description not wrapped in ql-editor div" do + visit_component + + click_link translated(meeting.title) + click_link "Edit meeting" + + expect(page).to have_content "EDIT YOUR MEETING" + + within "form.edit_meeting" do + expect(page).to have_no_css("div.ql-editor") + end + + within "textarea#meeting_description" do + expect(page).to have_content translated(meeting.description) + expect(page).to have_no_content '
' + end + end + end end describe "editing someone else's meeting" do diff --git a/decidim-meetings/spec/types/integration_schema_spec.rb b/decidim-meetings/spec/types/integration_schema_spec.rb index f3ff2c9ba0ac8..9b6976d6f3b91 100644 --- a/decidim-meetings/spec/types/integration_schema_spec.rb +++ b/decidim-meetings/spec/types/integration_schema_spec.rb @@ -9,7 +9,7 @@ let(:component_type) { "Meetings" } let!(:current_component) { create :meeting_component, participatory_space: participatory_process } - let!(:meeting) { create(:meeting, :published, :not_official, :with_services, :closed_with_minutes, closing_visible: closing_visible, component: current_component, category: category) } + let!(:meeting) { create(:meeting, :published, :withdrawn, :not_official, :with_services, :closed_with_minutes, closing_visible: closing_visible, component: current_component, category: category) } let!(:agenda) { create(:agenda, :with_agenda_items, meeting: meeting) } let!(:invite) { create(:invite, :accepted, meeting: meeting) } let(:closing_visible) { true } @@ -26,6 +26,7 @@ "category" => { "id" => meeting.category.id.to_s }, "closed" => true, "closingReport" => closing_visible ? { "translation" => meeting.closing_report[locale] } : nil, + "isWithdrawn" => true, "videoUrl" => closing_visible ? meeting.video_url : nil, "audioUrl" => closing_visible ? meeting.audio_url : nil, "comments" => [], @@ -107,6 +108,7 @@ closingReport { translation(locale: "#{locale}") } + isWithdrawn videoUrl audioUrl comments { @@ -202,6 +204,7 @@ closingReport { translation(locale: "#{locale}") } + isWithdrawn videoUrl audioUrl comments { diff --git a/decidim-meetings/spec/types/meeting_type_spec.rb b/decidim-meetings/spec/types/meeting_type_spec.rb index 2f404c9a71bce..9dcfc99c56aa2 100644 --- a/decidim-meetings/spec/types/meeting_type_spec.rb +++ b/decidim-meetings/spec/types/meeting_type_spec.rb @@ -72,6 +72,26 @@ module Meetings end end + describe "isWithdrawn" do + let(:query) { "{ isWithdrawn }" } + + context "when meetings is withdrawn" do + let(:model) { create(:meeting, :withdrawn, component: component) } + + it "returns true" do + expect(response["isWithdrawn"]).to be true + end + end + + context "when meetings is not withdrawn" do + let(:model) { create(:meeting, component: component) } + + it "returns false" do + expect(response["isWithdrawn"]).to be false + end + end + end + describe "closed" do let(:query) { "{ closed closingReport { translation(locale: \"ca\") } }" } diff --git a/decidim-pages/app/serializers/decidim/pages/data_importer.rb b/decidim-pages/app/serializers/decidim/pages/data_importer.rb new file mode 100644 index 0000000000000..473f3fc2fde20 --- /dev/null +++ b/decidim-pages/app/serializers/decidim/pages/data_importer.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module Decidim + module Pages + # Importer for Pages specific data (i.e. its page content). + class DataImporter < Decidim::Importers::Importer + def initialize(component) + @component = component + end + + # Creates a new Decidim::Pages::Page associated to the given **component** + # for the serialized page object. + # + # @param serialized [Hash] The serialized data read from the import file. + # @param _user [Decidim::User] The user performing the import. + # @return [Decidim::Pages::Page] The imported page + def import(serialized, _user) + return unless serialized + + Page.create!( + component: @component, + body: serialized["body"] + ) + end + end + end +end diff --git a/decidim-pages/app/serializers/decidim/pages/data_serializer.rb b/decidim-pages/app/serializers/decidim/pages/data_serializer.rb new file mode 100644 index 0000000000000..9c4cbe4a85bf8 --- /dev/null +++ b/decidim-pages/app/serializers/decidim/pages/data_serializer.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module Decidim + module Pages + # This class serializes the specific data in each Page. This is the page + # data outside of the component settings. + class DataSerializer < Decidim::Exporters::Serializer + include Decidim::TranslationsHelper + + # Serializes the page data for this component. + # + # @return [Hash] The serialized data + def serialize + page = Page.find_by(component: resource) + + { + body: page&.body || empty_translatable + } + end + end + end +end diff --git a/decidim-pages/app/views/decidim/pages/application/show.html.erb b/decidim-pages/app/views/decidim/pages/application/show.html.erb index 4be5170ce18ab..59345ee38db82 100644 --- a/decidim-pages/app/views/decidim/pages/application/show.html.erb +++ b/decidim-pages/app/views/decidim/pages/application/show.html.erb @@ -8,7 +8,7 @@
- <%= decidim_sanitize translated_attribute(@page.body) %> + <%= decidim_sanitize_editor translated_attribute(@page.body) %>
diff --git a/decidim-pages/config/locales/ca.yml b/decidim-pages/config/locales/ca.yml index c5788fe0e4df7..85d0f563fee57 100644 --- a/decidim-pages/config/locales/ca.yml +++ b/decidim-pages/config/locales/ca.yml @@ -30,6 +30,6 @@ ca: success: Pàgina desada correctament. home: hero: - participate_title: Participa als processos de la plataforma + participate_title: Participa en els processos de la plataforma sub_hero: register_title: Registra't per tenir un compte diff --git a/decidim-pages/config/locales/de.yml b/decidim-pages/config/locales/de.yml index a73a407ff14af..d0e0fb5f576cb 100644 --- a/decidim-pages/config/locales/de.yml +++ b/decidim-pages/config/locales/de.yml @@ -30,6 +30,6 @@ de: success: Seite erfolgreich gespeichert home: hero: - participate_title: An den Prozessen der Plattform teilnehmen + participate_title: Beteiligen Sie sich an den Prozessen auf dieser Plattform sub_hero: register_title: Registrieren diff --git a/decidim-pages/config/locales/en.yml b/decidim-pages/config/locales/en.yml index b2dd124f4ce78..e28d0229c2342 100644 --- a/decidim-pages/config/locales/en.yml +++ b/decidim-pages/config/locales/en.yml @@ -31,6 +31,6 @@ en: success: Page successfully saved. home: hero: - participate_title: Participate to the platform's processes + participate_title: Participate in the platform's processes sub_hero: register_title: Sign up to create an account diff --git a/decidim-pages/config/locales/es-MX.yml b/decidim-pages/config/locales/es-MX.yml index a7a816c65f3d2..e7298d4f6f483 100644 --- a/decidim-pages/config/locales/es-MX.yml +++ b/decidim-pages/config/locales/es-MX.yml @@ -30,6 +30,6 @@ es-MX: success: Página guardada correctamente. home: hero: - participate_title: Participar en los procesos de la plataforma + participate_title: Participa en los procesos de la plataforma sub_hero: register_title: Regístrate para tener una cuenta diff --git a/decidim-pages/config/locales/es-PY.yml b/decidim-pages/config/locales/es-PY.yml index 9ee312df3122d..2d47b1ff03c87 100644 --- a/decidim-pages/config/locales/es-PY.yml +++ b/decidim-pages/config/locales/es-PY.yml @@ -30,6 +30,6 @@ es-PY: success: Página guardada correctamente. home: hero: - participate_title: Participar en los procesos de la plataforma + participate_title: Participa en los procesos de la plataforma sub_hero: register_title: Regístrate para tener una cuenta diff --git a/decidim-pages/config/locales/es.yml b/decidim-pages/config/locales/es.yml index 1c91722c752cc..0b0ffef6c2742 100644 --- a/decidim-pages/config/locales/es.yml +++ b/decidim-pages/config/locales/es.yml @@ -30,6 +30,6 @@ es: success: Página guardada correctamente. home: hero: - participate_title: Participar en los procesos de la plataforma + participate_title: Participa en los procesos de la plataforma sub_hero: register_title: Regístrate para tener una cuenta diff --git a/decidim-pages/config/locales/eu.yml b/decidim-pages/config/locales/eu.yml index 3c93330d81dbc..65964466243cc 100644 --- a/decidim-pages/config/locales/eu.yml +++ b/decidim-pages/config/locales/eu.yml @@ -29,7 +29,5 @@ eu: invalid: Erroreak gertatu dira orria gordetzean. success: Orria zuzen gorde da. home: - hero: - participate_title: Parte hartu plataformako prozesuetan sub_hero: register_title: Erregistratu kontu bat edukitzeko diff --git a/decidim-pages/config/locales/fi-plain.yml b/decidim-pages/config/locales/fi-plain.yml index 094cdb26bdf72..95ed2f5eee78f 100644 --- a/decidim-pages/config/locales/fi-plain.yml +++ b/decidim-pages/config/locales/fi-plain.yml @@ -30,6 +30,6 @@ fi-pl: success: Sivu tallennettu onnistuneesti. home: hero: - participate_title: Osallistu prosesseihin alustalla + participate_title: Osallistu alustan prosesseihin sub_hero: register_title: Luo oma tili alustalle diff --git a/decidim-pages/config/locales/fi.yml b/decidim-pages/config/locales/fi.yml index 523ecc9993ead..9dfca439fa243 100644 --- a/decidim-pages/config/locales/fi.yml +++ b/decidim-pages/config/locales/fi.yml @@ -30,6 +30,6 @@ fi: success: Sivun tallentaminen onnistui. home: hero: - participate_title: Osallistu prosesseihin alustalla + participate_title: Osallistu alustan prosesseihin sub_hero: register_title: Luo oma tili alustalle diff --git a/decidim-pages/config/locales/fr-CA.yml b/decidim-pages/config/locales/fr-CA.yml index ba30876db75eb..79e2e1080ce34 100644 --- a/decidim-pages/config/locales/fr-CA.yml +++ b/decidim-pages/config/locales/fr-CA.yml @@ -30,6 +30,6 @@ fr-CA: success: Page enregistrée avec succès. home: hero: - participate_title: Participer aux processus de la plateforme + participate_title: Participer aux concertations de la plateforme sub_hero: register_title: Inscrivez-vous pour créer un compte diff --git a/decidim-pages/config/locales/gl.yml b/decidim-pages/config/locales/gl.yml index 791e4be1bb7ff..842c8958577c6 100644 --- a/decidim-pages/config/locales/gl.yml +++ b/decidim-pages/config/locales/gl.yml @@ -29,7 +29,5 @@ gl: invalid: Produciuse un erro ao gardar a páxina. success: A páxina gardouse correctamente. home: - hero: - participate_title: Participar nos procesos da plataforma sub_hero: register_title: Rexistrarse para crear unha conta diff --git a/decidim-pages/config/locales/gn-PY.yml b/decidim-pages/config/locales/gn-PY.yml new file mode 100644 index 0000000000000..bd442b0ad85de --- /dev/null +++ b/decidim-pages/config/locales/gn-PY.yml @@ -0,0 +1 @@ +gn: diff --git a/decidim-pages/config/locales/it.yml b/decidim-pages/config/locales/it.yml index ffcab4b938356..fe69e48d4cffa 100644 --- a/decidim-pages/config/locales/it.yml +++ b/decidim-pages/config/locales/it.yml @@ -29,7 +29,5 @@ it: invalid: C'è stato un errore durante il salvataggio della pagina. success: La pagina è stata salvata correttamente. home: - hero: - participate_title: Partecipa ai processi della piattaforma sub_hero: register_title: Registrati e crea un account diff --git a/decidim-pages/config/locales/lb-LU.yml b/decidim-pages/config/locales/lb-LU.yml index 823df018114f4..784c95ee1f204 100644 --- a/decidim-pages/config/locales/lb-LU.yml +++ b/decidim-pages/config/locales/lb-LU.yml @@ -1 +1,35 @@ lb: + activerecord: + models: + decidim/pages/page: + one: Seite + other: Seiten + decidim: + admin_log: + page: + update: "%{user_name} hat die Seite %{resource_name} in %{space_name} aktualisiert" + components: + pages: + name: Seite + settings: + global: + announcement: Ankündigung + step: + announcement: Ankündigung + pages: + admin: + models: + components: + body: Haupttext + pages: + edit: + save: Aktualisieren + title: Seite bearbeiten + update: + invalid: Beim Speichern der Seite sind Fehler aufgetreten. + success: Seite erfolgreich gespeichert + home: + hero: + participate_title: An den Prozessen der Plattform teilnehmen + sub_hero: + register_title: Registrieren diff --git a/decidim-pages/config/locales/lb.yml b/decidim-pages/config/locales/lb.yml index 784c95ee1f204..40c788d6cd462 100644 --- a/decidim-pages/config/locales/lb.yml +++ b/decidim-pages/config/locales/lb.yml @@ -29,7 +29,5 @@ lb: invalid: Beim Speichern der Seite sind Fehler aufgetreten. success: Seite erfolgreich gespeichert home: - hero: - participate_title: An den Prozessen der Plattform teilnehmen sub_hero: register_title: Registrieren diff --git a/decidim-pages/config/locales/lo-LA.yml b/decidim-pages/config/locales/lo-LA.yml new file mode 100644 index 0000000000000..27a02bfece429 --- /dev/null +++ b/decidim-pages/config/locales/lo-LA.yml @@ -0,0 +1 @@ +lo: diff --git a/decidim-pages/config/locales/nl.yml b/decidim-pages/config/locales/nl.yml index 4fa287210c290..9bdb7d7029c2e 100644 --- a/decidim-pages/config/locales/nl.yml +++ b/decidim-pages/config/locales/nl.yml @@ -29,7 +29,5 @@ nl: invalid: Er zijn fouten opgetreden bij het opslaan van de pagina. success: Pagina is succesvol opgeslagen. home: - hero: - participate_title: Neem deel aan de processen van het platform sub_hero: register_title: Meld je aan voor een account diff --git a/decidim-pages/config/locales/no.yml b/decidim-pages/config/locales/no.yml index 1b73182d64559..c60942485a822 100644 --- a/decidim-pages/config/locales/no.yml +++ b/decidim-pages/config/locales/no.yml @@ -29,7 +29,5 @@ invalid: Det oppsto et problem med å lagre denne siden. success: Siden ble lagret. home: - hero: - participate_title: Delta i plattformens prosesser sub_hero: register_title: Registrer deg for å opprette en konto diff --git a/decidim-pages/config/locales/oc-FR.yml b/decidim-pages/config/locales/oc-FR.yml new file mode 100644 index 0000000000000..325b348894124 --- /dev/null +++ b/decidim-pages/config/locales/oc-FR.yml @@ -0,0 +1 @@ +oc: diff --git a/decidim-pages/config/locales/pl.yml b/decidim-pages/config/locales/pl.yml index a585702f5e23f..4b6eff1f0e158 100644 --- a/decidim-pages/config/locales/pl.yml +++ b/decidim-pages/config/locales/pl.yml @@ -31,7 +31,5 @@ pl: invalid: Podczas zapisywania strony wystąpił błąd. success: Strona została zapisana. home: - hero: - participate_title: Weź udział w procesach udostępnionych na platformie sub_hero: register_title: Zarejestruj się, aby utworzyć konto diff --git a/decidim-pages/config/locales/pt-BR.yml b/decidim-pages/config/locales/pt-BR.yml index 3ffae97cfe5c9..9a9ef44ae2b3c 100644 --- a/decidim-pages/config/locales/pt-BR.yml +++ b/decidim-pages/config/locales/pt-BR.yml @@ -29,7 +29,5 @@ pt-BR: invalid: Ocorreu erros ao salvar a página. success: Página salva com sucesso. home: - hero: - participate_title: Participar dos processos da plataforma sub_hero: register_title: Cadastre-se para criar uma conta diff --git a/decidim-pages/config/locales/pt.yml b/decidim-pages/config/locales/pt.yml index 5b67e72828baa..61f599e00627f 100644 --- a/decidim-pages/config/locales/pt.yml +++ b/decidim-pages/config/locales/pt.yml @@ -29,7 +29,5 @@ pt: invalid: Ocorreu um problema ao guardar a página. success: Pagina guardada com êxito. home: - hero: - participate_title: Participe nos processos da plataforma sub_hero: register_title: Registre para criar conta diff --git a/decidim-pages/config/locales/sv.yml b/decidim-pages/config/locales/sv.yml index 1fc5c2cd81b1d..97e317d8bdf08 100644 --- a/decidim-pages/config/locales/sv.yml +++ b/decidim-pages/config/locales/sv.yml @@ -29,7 +29,5 @@ sv: invalid: Det gick inte att spara sidan. success: Sidan sparades framgångsrikt. home: - hero: - participate_title: Delta i plattformens dialoger sub_hero: register_title: Skapa ett konto diff --git a/decidim-pages/lib/decidim/pages/component.rb b/decidim-pages/lib/decidim/pages/component.rb index f17c7e4ae4060..ccee39c862347 100644 --- a/decidim-pages/lib/decidim/pages/component.rb +++ b/decidim-pages/lib/decidim/pages/component.rb @@ -6,6 +6,9 @@ component.engine = Decidim::Pages::Engine component.admin_engine = Decidim::Pages::AdminEngine component.icon = "media/images/decidim_pages.svg" + component.serializes_specific_data = true + component.specific_data_serializer_class_name = "Decidim::Pages::DataSerializer" + component.specific_data_importer_class_name = "Decidim::Pages::DataImporter" component.permissions_class_name = "Decidim::Pages::Permissions" component.query_type = "Decidim::Pages::PagesType" diff --git a/decidim-pages/lib/decidim/pages/version.rb b/decidim-pages/lib/decidim/pages/version.rb index 6986792e3e63f..bdde9b730b52e 100644 --- a/decidim-pages/lib/decidim/pages/version.rb +++ b/decidim-pages/lib/decidim/pages/version.rb @@ -4,7 +4,7 @@ module Decidim # This holds the decidim-pages version. module Pages def self.version - "0.25.2" + "0.26.4" end end end diff --git a/decidim-pages/spec/serializers/decidim/pages/data_importer_spec.rb b/decidim-pages/spec/serializers/decidim/pages/data_importer_spec.rb new file mode 100644 index 0000000000000..b46cee7f32425 --- /dev/null +++ b/decidim-pages/spec/serializers/decidim/pages/data_importer_spec.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +require "spec_helper" + +module Decidim::Pages + describe DataImporter do + let(:importer) { described_class.new(component) } + + let(:organization) { create(:organization) } + let(:user) { create(:user, :admin, :confirmed, organization: organization) } + let(:participatory_process) { create(:participatory_process, organization: organization) } + let(:component) { create(:component, manifest_name: "pages", participatory_space: participatory_process) } + + describe "#import" do + subject { importer.import(as_json, user) } + + context "with body" do + let(:as_json) do + JSON.parse( + <<~JSON + { + "body": { + "en": "English content", + "ca": "Catalan content", + "es": "Spanish content" + } + } + JSON + ) + end + + it "imports the page" do + expect(subject).to be_a(Decidim::Pages::Page) + expect(subject.id).to eq(Page.find_by(component: component).id) + expect(subject.body).to eq( + { + "en" => "English content", + "ca" => "Catalan content", + "es" => "Spanish content" + } + ) + end + end + + context "without body" do + let(:as_json) { nil } + + it "doesn't import the page" do + expect(subject).to be_nil + end + end + end + end +end diff --git a/decidim-pages/spec/serializers/decidim/pages/data_serializer_spec.rb b/decidim-pages/spec/serializers/decidim/pages/data_serializer_spec.rb new file mode 100644 index 0000000000000..2fde0b376386e --- /dev/null +++ b/decidim-pages/spec/serializers/decidim/pages/data_serializer_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require "spec_helper" + +module Decidim::Pages + describe DataSerializer do + let!(:page) { create(:page) } + let(:serializer) { described_class.new(page.component) } + + describe "#serialize" do + subject { serializer.serialize } + + it "serializes the page data" do + expect(subject).to eq({ body: page.body }) + end + end + end +end diff --git a/decidim-participatory_processes/app/cells/decidim/participatory_process_groups/content_blocks/highlighted_participatory_processes/filters_small_view.erb b/decidim-participatory_processes/app/cells/decidim/participatory_process_groups/content_blocks/highlighted_participatory_processes/filters_small_view.erb index 08b8d56e6b0ae..4d4c44865b944 100644 --- a/decidim-participatory_processes/app/cells/decidim/participatory_process_groups/content_blocks/highlighted_participatory_processes/filters_small_view.erb +++ b/decidim-participatory_processes/app/cells/decidim/participatory_process_groups/content_blocks/highlighted_participatory_processes/filters_small_view.erb @@ -1,13 +1,13 @@
-
-
+
<% if group.promoted? %> - "> + "> <%= icon "star" %> <% end %> diff --git a/decidim-participatory_processes/app/views/decidim/participatory_processes/admin/participatory_process_groups/show.html.erb b/decidim-participatory_processes/app/views/decidim/participatory_processes/admin/participatory_process_groups/show.html.erb deleted file mode 100644 index 40314d1887433..0000000000000 --- a/decidim-participatory_processes/app/views/decidim/participatory_processes/admin/participatory_process_groups/show.html.erb +++ /dev/null @@ -1,30 +0,0 @@ -
- <%= display_for participatory_process_group, - :title, - :description, - :hashtag, - :group_url, - :developer_group, - :local_area, - :meta_scope, - :target, - :participatory_scope, - :participatory_structure %> - -
<%= display_label(participatory_process_group, :participatory_processes) %>
- <% if participatory_process_group.participatory_processes.any? %> -
-
    - <% participatory_process_group.participatory_processes.each do |participatory_process| %> -
  • <%= translated_attribute participatory_process.title %>
  • - <% end %> -
-
- <% end %> -
<%= display_label(participatory_process_group, :hero_image) %>
-
- <% if participatory_process_group.hero_image.attached? %> - <%= image_tag participatory_process_group.attached_uploader(:hero_image).path %> - <% end %> -
-
diff --git a/decidim-participatory_processes/app/views/decidim/participatory_processes/admin/participatory_process_user_roles/index.html.erb b/decidim-participatory_processes/app/views/decidim/participatory_processes/admin/participatory_process_user_roles/index.html.erb index 0a99451262fc4..d299e0c9f3651 100644 --- a/decidim-participatory_processes/app/views/decidim/participatory_processes/admin/participatory_process_user_roles/index.html.erb +++ b/decidim-participatory_processes/app/views/decidim/participatory_processes/admin/participatory_process_user_roles/index.html.erb @@ -9,17 +9,17 @@ <% end %> - + <%= admin_filter_selector %>
- +
- - - - - + + + + + diff --git a/decidim-participatory_processes/app/views/decidim/participatory_processes/admin/participatory_processes/index.html.erb b/decidim-participatory_processes/app/views/decidim/participatory_processes/admin/participatory_processes/index.html.erb index 74f3756a944b3..4a5a0b43f748f 100644 --- a/decidim-participatory_processes/app/views/decidim/participatory_processes/admin/participatory_processes/index.html.erb +++ b/decidim-participatory_processes/app/views/decidim/participatory_processes/admin/participatory_processes/index.html.erb @@ -70,7 +70,7 @@ diff --git a/decidim_app-design/app/views/admin/old/component-proposals.html.erb b/decidim_app-design/app/views/admin/old/component-proposals.html.erb index dc5666d4f1a10..7ac6ad37e2a58 100644 --- a/decidim_app-design/app/views/admin/old/component-proposals.html.erb +++ b/decidim_app-design/app/views/admin/old/component-proposals.html.erb @@ -37,8 +37,8 @@ Responder @@ -51,8 +51,8 @@ Aprobado @@ -65,8 +65,8 @@ Rechazado diff --git a/decidim_app-design/app/views/admin/pages.html.erb b/decidim_app-design/app/views/admin/pages.html.erb index dc0298fe75031..18f299e3be21c 100644 --- a/decidim_app-design/app/views/admin/pages.html.erb +++ b/decidim_app-design/app/views/admin/pages.html.erb @@ -28,9 +28,9 @@ Información FAQ @@ -38,9 +38,9 @@ Información Términos y Condiciones @@ -48,9 +48,9 @@ Información Accesibilidad diff --git a/decidim_app-design/app/views/admin/process-admin.html.erb b/decidim_app-design/app/views/admin/process-admin.html.erb index b69c58094a900..9e6d02d0b7f40 100644 --- a/decidim_app-design/app/views/admin/process-admin.html.erb +++ b/decidim_app-design/app/views/admin/process-admin.html.erb @@ -34,8 +34,8 @@ lorena@decidim.org diff --git a/decidim_app-design/app/views/admin/process-categories.html.erb b/decidim_app-design/app/views/admin/process-categories.html.erb index ecc79acbe2f78..27dbaaac2d1f2 100644 --- a/decidim_app-design/app/views/admin/process-categories.html.erb +++ b/decidim_app-design/app/views/admin/process-categories.html.erb @@ -31,8 +31,8 @@ Categoría 1 @@ -40,8 +40,8 @@ Categoría 2 diff --git a/decidim_app-design/app/views/admin/process-docs.html.erb b/decidim_app-design/app/views/admin/process-docs.html.erb index 03f0f21ea9fb6..7185923d5a84a 100644 --- a/decidim_app-design/app/views/admin/process-docs.html.erb +++ b/decidim_app-design/app/views/admin/process-docs.html.erb @@ -35,8 +35,8 @@ PDF @@ -47,8 +47,8 @@ JPG diff --git a/decidim_app-design/app/views/admin/process-moderations.html.erb b/decidim_app-design/app/views/admin/process-moderations.html.erb index 69194d461fc41..c6576f4d56808 100644 --- a/decidim_app-design/app/views/admin/process-moderations.html.erb +++ b/decidim_app-design/app/views/admin/process-moderations.html.erb @@ -40,8 +40,8 @@ diff --git a/decidim_app-design/app/views/admin/process-pages.html.erb b/decidim_app-design/app/views/admin/process-pages.html.erb index 88df9086e0aef..9740882fe78a3 100644 --- a/decidim_app-design/app/views/admin/process-pages.html.erb +++ b/decidim_app-design/app/views/admin/process-pages.html.erb @@ -30,9 +30,9 @@ Información de la votación diff --git a/decidim_app-design/app/views/admin/process-steps.html.erb b/decidim_app-design/app/views/admin/process-steps.html.erb index 408d1ab259b50..c8ffa7594459b 100644 --- a/decidim_app-design/app/views/admin/process-steps.html.erb +++ b/decidim_app-design/app/views/admin/process-steps.html.erb @@ -39,13 +39,13 @@ 15/01/17 @@ -72,8 +72,8 @@ 12/09/17 diff --git a/decidim_app-design/app/views/admin/processes.html.erb b/decidim_app-design/app/views/admin/processes.html.erb index 75660cfb3c6d8..380f6f396ef75 100644 --- a/decidim_app-design/app/views/admin/processes.html.erb +++ b/decidim_app-design/app/views/admin/processes.html.erb @@ -26,7 +26,7 @@ @@ -49,8 +49,8 @@ Sin publicar @@ -63,8 +63,8 @@ Borrador @@ -77,8 +77,8 @@ Publicado diff --git a/decidim_app-design/app/views/admin/scope-browse.html.erb b/decidim_app-design/app/views/admin/scope-browse.html.erb index 9f4e1ebf400da..8ba93ed800704 100644 --- a/decidim_app-design/app/views/admin/scope-browse.html.erb +++ b/decidim_app-design/app/views/admin/scope-browse.html.erb @@ -34,7 +34,7 @@ diff --git a/decidim_app-design/app/views/admin/scope-sub-browse.html.erb b/decidim_app-design/app/views/admin/scope-sub-browse.html.erb index 375698173ddc1..5508ec9ec52c8 100644 --- a/decidim_app-design/app/views/admin/scope-sub-browse.html.erb +++ b/decidim_app-design/app/views/admin/scope-sub-browse.html.erb @@ -35,8 +35,8 @@ subdistrito + <%= link_to page_path("scope-edit"), class: "action-icon", data: { :tooltip => true, :'disable-hover' => "false" }, title: "Editar" do %><%= icon "pencil" %><% end %> + <%= icon "circle-x" %> + <%= icon "circle-x" %>
<%= t("models.participatory_process_user_role.fields.name", scope: "decidim.admin") %><%= t("models.participatory_process_user_role.fields.email", scope: "decidim.admin") %><%= t("models.user.fields.invitation_sent_at", scope: "decidim.admin") %><%= t("models.user.fields.invitation_accepted_at", scope: "decidim.admin") %><%= t("models.participatory_process_user_role.fields.role", scope: "decidim.admin") %><%= sort_link(query, :name,t("models.participatory_process_user_role.fields.name", scope: "decidim.admin"), default_order: :desc) %><%= sort_link(query, :email, t("models.participatory_process_user_role.fields.email", scope: "decidim.admin"), default_order: :desc) %><%= sort_link(query, :last_sign_in_at, t("models.user.fields.last_sign_in_at", scope: "decidim.admin"), default_order: :desc) %><%= sort_link(query, :invitation_accepted_at, t("models.user.fields.invitation_accepted_at", scope: "decidim.admin"), default_order: :desc) %><%= sort_link(query, :role, t("models.participatory_process_user_role.fields.role", scope: "decidim.admin"), default_order: :desc) %>
<% if process.promoted? %> - "> + "> <%= icon "star" %> <% end %> diff --git a/decidim-participatory_processes/app/views/decidim/participatory_processes/participatory_process_steps/index.html.erb b/decidim-participatory_processes/app/views/decidim/participatory_processes/participatory_process_steps/index.html.erb index c4397cf6afd05..0b71eb064bd95 100644 --- a/decidim-participatory_processes/app/views/decidim/participatory_processes/participatory_process_steps/index.html.erb +++ b/decidim-participatory_processes/app/views/decidim/participatory_processes/participatory_process_steps/index.html.erb @@ -10,7 +10,7 @@ <%= t(".back_to_process") %> <% end %> -

<%= t("participatory_process_steps.index.process_steps", scope: "decidim") %>

+

<%= t("participatory_process_steps.index.process_steps", scope: "decidim") %>

<%= render partial: "timeline" %> diff --git a/decidim-participatory_processes/app/views/decidim/participatory_processes/participatory_processes/_promoted_process.html.erb b/decidim-participatory_processes/app/views/decidim/participatory_processes/participatory_processes/_promoted_process.html.erb index d41c2967a63a9..a8fc9e5d428d9 100644 --- a/decidim-participatory_processes/app/views/decidim/participatory_processes/participatory_processes/_promoted_process.html.erb +++ b/decidim-participatory_processes/app/views/decidim/participatory_processes/participatory_processes/_promoted_process.html.erb @@ -5,7 +5,7 @@ <%= link_to participatory_process_path(promoted_process), class: "card__link" do %>

<%= decidim_html_escape(translated_attribute(promoted_process.title)).html_safe %>

<% end %> - <%= decidim_sanitize html_truncate(translated_attribute(promoted_process.short_description), length: 630, separator: "...") %> + <%= decidim_sanitize_editor html_truncate(translated_attribute(promoted_process.short_description), length: 630, separator: "...") %> <%= link_to participatory_process_path(promoted_process), class: "button small hollow card__button" do %> <%= decidim_html_escape(translated_attribute(promoted_process.title)) %> <%= t("participatory_processes.promoted_process.more_info", scope: "layouts.decidim") %> @@ -14,7 +14,7 @@
+ style="background-image:url('<%= promoted_process.attached_uploader(:hero_image).path %>')">
<%= link_to participatory_process_cta_path(promoted_process), class: "button expanded button--sc" do %> diff --git a/decidim-participatory_processes/app/views/decidim/participatory_processes/participatory_processes/_promoted_process_group.html.erb b/decidim-participatory_processes/app/views/decidim/participatory_processes/participatory_processes/_promoted_process_group.html.erb index fb3a9221ceede..ae79dd36d43bd 100644 --- a/decidim-participatory_processes/app/views/decidim/participatory_processes/participatory_processes/_promoted_process_group.html.erb +++ b/decidim-participatory_processes/app/views/decidim/participatory_processes/participatory_processes/_promoted_process_group.html.erb @@ -4,9 +4,9 @@
<%= link_to participatory_process_group_path(promoted_process_group), class: "card__link" do %> -

<%= decidim_html_escape(translated_attribute(promoted_process_group.title)) %>

+

<%= decidim_html_escape(translated_attribute(promoted_process_group.title)).html_safe %>

<% end %> - <%= decidim_sanitize html_truncate(translated_attribute(promoted_process_group.description), length: 630, separator: "...") %> + <%= decidim_sanitize_editor html_truncate(translated_attribute(promoted_process_group.description), length: 630, separator: "...") %> <%= link_to participatory_process_group_path(promoted_process_group), class: "button small hollow card__button" do %> <%= decidim_html_escape(translated_attribute(promoted_process_group.title)) %> <%= t("participatory_processes.promoted_process_group.more_info", scope: "layouts.decidim") %> @@ -14,7 +14,7 @@
-
+
<% if cta_settings.present? %>
diff --git a/decidim-participatory_processes/app/views/decidim/participatory_processes/participatory_processes/show.html.erb b/decidim-participatory_processes/app/views/decidim/participatory_processes/participatory_processes/show.html.erb index 6403f56e73621..89691bcd0f455 100644 --- a/decidim-participatory_processes/app/views/decidim/participatory_processes/participatory_processes/show.html.erb +++ b/decidim-participatory_processes/app/views/decidim/participatory_processes/participatory_processes/show.html.erb @@ -27,13 +27,14 @@
+

<%= t(".title") %>

<% if participatory_process_group.present? %> <%= render partial: "participatory_process_group" %> <% end %>
- <%= decidim_sanitize translated_attribute(current_participatory_space.short_description) %> + <%= decidim_sanitize_editor translated_attribute(current_participatory_space.short_description) %>
- <%= decidim_sanitize translated_attribute(current_participatory_space.description) %> + <%= decidim_sanitize_editor translated_attribute(current_participatory_space.description) %>
<%= attachments_for current_participatory_space %> <%= render_hook(:participatory_space_highlighted_elements) %> @@ -143,7 +144,7 @@
<% if current_participatory_space.show_statistics? %> - <%= cell "decidim/statistics", stats.collection %> + <%= cell "decidim/statistics", stats.collection %> <% end %> <% if current_participatory_space.show_metrics? %> diff --git a/decidim-participatory_processes/app/views/layouts/decidim/_process_header.html.erb b/decidim-participatory_processes/app/views/layouts/decidim/_process_header.html.erb index bdb4fcb2d5433..6322a9c69fc29 100644 --- a/decidim-participatory_processes/app/views/layouts/decidim/_process_header.html.erb +++ b/decidim-participatory_processes/app/views/layouts/decidim/_process_header.html.erb @@ -1,7 +1,7 @@
+ style="background-image:url('<%= current_participatory_space.attached_uploader(:banner_image).path %>');">
@@ -11,14 +11,14 @@
-

+

<% if current_participatory_space.hashtag.present? %> - <%= link_to "##{decidim_html_escape(current_participatory_space.hashtag)}", "https://twitter.com/hashtag/#{decidim_html_escape(current_participatory_space.hashtag)}", target: "_blank" %> + <%= link_to "##{decidim_html_escape(current_participatory_space.hashtag)}", twitter_hashtag_url(decidim_html_escape(current_participatory_space.hashtag)), target: "_blank" %> <% end %> <%= translated_attribute(current_participatory_space.subtitle) %> -

+

<%= render partial: "layouts/decidim/process_header_steps", locals: { participatory_process: current_participatory_space } %> diff --git a/decidim-participatory_processes/config/locales/ca.yml b/decidim-participatory_processes/config/locales/ca.yml index a8bafe68bb76c..b37d7b5459698 100644 --- a/decidim-participatory_processes/config/locales/ca.yml +++ b/decidim-participatory_processes/config/locales/ca.yml @@ -435,6 +435,8 @@ ca: see: Veure index: loading: Carregant resultats... + show: + title: Quant a aquest procés show: area: Àrea belongs_to_group: Aquest procés pertany a diff --git a/decidim-participatory_processes/config/locales/cs.yml b/decidim-participatory_processes/config/locales/cs.yml index c64e33dbd8332..5294cf9d663de 100644 --- a/decidim-participatory_processes/config/locales/cs.yml +++ b/decidim-participatory_processes/config/locales/cs.yml @@ -305,7 +305,7 @@ cs: email_subject: Aktualizace na %{participatory_space_title} notification_title: Krok %{resource_title} je nyní aktivní pro %{participatory_space_title} step_changed: - email_intro: 'Byly aktualizovány datumy pro krok %{resource_title} v %{participatory_space_title}. Můžete je vidět z této stránky:' + email_intro: 'Data pro %{resource_title} fáze na %{participatory_space_title} byly aktualizovány. Můžete si je prohlédnout na této stránce:' email_outro: Toto oznámení jste obdrželi, protože jste sledovali %{participatory_space_title}. Po předchozím propojení můžete přestat přijímat oznámení. email_subject: Aktualizace na %{participatory_space_title} notification_title: Byly aktualizovány data pro krok %{resource_title} ve %{participatory_space_title}. @@ -386,9 +386,9 @@ cs: announcement_help: Text, který zde zadáte, se uživateli zobrazí přímo pod informacemi o procesu. duration: Doba trvání filters: Filtry - images: snímky + images: Obrázky metadata: Metadata - other: jiný + other: Ostatní related_processes: Související procesy scope_type_max_depth_help: Omezit hloubku filtru rozsahu. Filtr se zobrazí od obecného k vybranému typu rozsahu. select_an_area: Vyberte oblast @@ -451,6 +451,8 @@ cs: see: Vidět index: loading: Načítání výsledků... + show: + title: O tomto procesu show: area: Oblast belongs_to_group: Tento proces patří do diff --git a/decidim-participatory_processes/config/locales/de.yml b/decidim-participatory_processes/config/locales/de.yml index 059c6eb10ea5f..65070c945e8c7 100644 --- a/decidim-participatory_processes/config/locales/de.yml +++ b/decidim-participatory_processes/config/locales/de.yml @@ -435,6 +435,8 @@ de: see: Sehen index: loading: Ergebnisse werden geladen ... + show: + title: Über diesen Prozess show: area: Bereich belongs_to_group: Dieser Prozess gehört zu diff --git a/decidim-participatory_processes/config/locales/en.yml b/decidim-participatory_processes/config/locales/en.yml index c26e5b9709dfe..d09e7cc8f3426 100644 --- a/decidim-participatory_processes/config/locales/en.yml +++ b/decidim-participatory_processes/config/locales/en.yml @@ -12,15 +12,22 @@ en: decidim_area_id: Area description: Description developer_group: Promoter group + document: Document domain: Domain end_date: End date hashtag: Hashtag hero_image: Home image + import_attachments: Import attachments + import_categories: Import categories + import_components: Import components + import_steps: Import steps local_area: Organization area meta_scope: Scope metadata participatory_process_group_id: Processes group + participatory_process_type_id: Processes type participatory_scope: What is decided participatory_structure: How is it decided + private_space: Private process promoted: Promoted published_at: Published at related_process_ids: Related processes @@ -436,6 +443,8 @@ en: see: See index: loading: Loading results... + show: + title: About this process show: area: Area belongs_to_group: This process belongs to diff --git a/decidim-participatory_processes/config/locales/es-MX.yml b/decidim-participatory_processes/config/locales/es-MX.yml index d58c02e0f94bd..8c561b422b8ba 100644 --- a/decidim-participatory_processes/config/locales/es-MX.yml +++ b/decidim-participatory_processes/config/locales/es-MX.yml @@ -435,6 +435,8 @@ es-MX: see: Ver index: loading: Cargando resultados... + show: + title: Acerca de este proceso show: area: Área belongs_to_group: Este proceso pertenece a diff --git a/decidim-participatory_processes/config/locales/es-PY.yml b/decidim-participatory_processes/config/locales/es-PY.yml index 7480afdf1d7ae..b947e01390b72 100644 --- a/decidim-participatory_processes/config/locales/es-PY.yml +++ b/decidim-participatory_processes/config/locales/es-PY.yml @@ -435,6 +435,8 @@ es-PY: see: Ver index: loading: Cargando resultados... + show: + title: Acerca de este proceso show: area: Área belongs_to_group: Este proceso pertenece a diff --git a/decidim-participatory_processes/config/locales/es.yml b/decidim-participatory_processes/config/locales/es.yml index 18f54d0f66f71..6f8fa27aae365 100644 --- a/decidim-participatory_processes/config/locales/es.yml +++ b/decidim-participatory_processes/config/locales/es.yml @@ -435,6 +435,8 @@ es: see: Ver index: loading: Cargando resultados... + show: + title: Acerca de este proceso show: area: Área belongs_to_group: Este proceso pertenece a diff --git a/decidim-participatory_processes/config/locales/fi-plain.yml b/decidim-participatory_processes/config/locales/fi-plain.yml index 2f283a8d82542..550a229698ea4 100644 --- a/decidim-participatory_processes/config/locales/fi-plain.yml +++ b/decidim-participatory_processes/config/locales/fi-plain.yml @@ -435,6 +435,8 @@ fi-pl: see: Katso index: loading: Ladataan tulokset... + show: + title: Tietoa tästä prosessista show: area: Alue belongs_to_group: Tämä prosessi kuuluu ryhmään diff --git a/decidim-participatory_processes/config/locales/fi.yml b/decidim-participatory_processes/config/locales/fi.yml index 5bdf65da7f967..35c8a332780bd 100644 --- a/decidim-participatory_processes/config/locales/fi.yml +++ b/decidim-participatory_processes/config/locales/fi.yml @@ -435,6 +435,8 @@ fi: see: Näytä index: loading: Ladataan tulokset... + show: + title: Tietoa tästä prosessista show: area: Alue belongs_to_group: Tämä prosessi kuuluu ryhmään diff --git a/decidim-participatory_processes/config/locales/fr-CA.yml b/decidim-participatory_processes/config/locales/fr-CA.yml index 48ae3e96840c2..ddc244e80703e 100644 --- a/decidim-participatory_processes/config/locales/fr-CA.yml +++ b/decidim-participatory_processes/config/locales/fr-CA.yml @@ -435,6 +435,8 @@ fr-CA: see: Voir index: loading: Chargement des résultats... + show: + title: A propos de cette concertation show: area: Périmètre d'assemblée belongs_to_group: Cette concertation appartient à diff --git a/decidim-participatory_processes/config/locales/fr.yml b/decidim-participatory_processes/config/locales/fr.yml index e4f6faa4236b9..6820a5ff9dfbe 100644 --- a/decidim-participatory_processes/config/locales/fr.yml +++ b/decidim-participatory_processes/config/locales/fr.yml @@ -435,6 +435,8 @@ fr: see: Voir index: loading: Chargement des résultats... + show: + title: A propos de cette concertation show: area: Périmètre d'assemblée belongs_to_group: Cette concertation appartient à diff --git a/decidim-participatory_processes/config/locales/gl.yml b/decidim-participatory_processes/config/locales/gl.yml index 13b602ca0e3db..239997295027f 100644 --- a/decidim-participatory_processes/config/locales/gl.yml +++ b/decidim-participatory_processes/config/locales/gl.yml @@ -415,6 +415,8 @@ gl: see: Ver index: loading: Cargando resultados ... + show: + title: Sobre este proceso show: area: Área belongs_to_group: Este proceso pertence a diff --git a/decidim-participatory_processes/config/locales/gn-PY.yml b/decidim-participatory_processes/config/locales/gn-PY.yml new file mode 100644 index 0000000000000..bd442b0ad85de --- /dev/null +++ b/decidim-participatory_processes/config/locales/gn-PY.yml @@ -0,0 +1 @@ +gn: diff --git a/decidim-participatory_processes/config/locales/hu.yml b/decidim-participatory_processes/config/locales/hu.yml index 0106929ac9bbd..15859342e4d81 100644 --- a/decidim-participatory_processes/config/locales/hu.yml +++ b/decidim-participatory_processes/config/locales/hu.yml @@ -432,6 +432,8 @@ hu: see: Lásd index: loading: Eredmények betöltése... + show: + title: Erről a folyamatról show: area: Terület belongs_to_group: Ide tartozik ez a folyamat diff --git a/decidim-participatory_processes/config/locales/it.yml b/decidim-participatory_processes/config/locales/it.yml index c1ceffb289d19..d980431afbef1 100644 --- a/decidim-participatory_processes/config/locales/it.yml +++ b/decidim-participatory_processes/config/locales/it.yml @@ -435,6 +435,8 @@ it: see: Vedi tutto index: loading: Caricamento risultati... + show: + title: Informazioni su questo processo show: area: Area belongs_to_group: Questo processo appartiene a diff --git a/decidim-participatory_processes/config/locales/ja.yml b/decidim-participatory_processes/config/locales/ja.yml index fde52b7bb595d..dd01a4601ef2e 100644 --- a/decidim-participatory_processes/config/locales/ja.yml +++ b/decidim-participatory_processes/config/locales/ja.yml @@ -427,6 +427,8 @@ ja: see: 見る index: loading: 結果を読み込み中... + show: + title: このプロセスについて show: area: エリア belongs_to_group: このプロセスの所属グループ diff --git a/decidim-participatory_processes/config/locales/lb-LU.yml b/decidim-participatory_processes/config/locales/lb-LU.yml index 823df018114f4..db476e1a31404 100644 --- a/decidim-participatory_processes/config/locales/lb-LU.yml +++ b/decidim-participatory_processes/config/locales/lb-LU.yml @@ -1 +1,109 @@ lb: + activemodel: + attributes: + participatory_process: + announcement: Ukënnegung + area_id: Bereich + banner_image: Banner-Bild + copy_categories: Kategorien kopieren + copy_components: Komponenten kopieren + copy_steps: Phasen kopieren + decidim_area_id: Bereich + description: Beschreibung + developer_group: Promoter-Gruppe + domain: Domäne + end_date: Enddatum + hashtag: Hashtag + hero_image: Hauptbild + local_area: Organisationsbereich + meta_scope: Bereichs-Metadaten + participatory_process_group_id: Prozessgruppe + participatory_scope: Was wird entschieden + participatory_structure: Wie wird es entschieden + promoted: Hervorgehoben + published_at: Veröffentlicht unter + related_process_ids: Ähnliche Beteiligungsprozesse + scope_id: Themenbereich + scope_type_max_depth_id: Umfang-Filtertiefe + scopes_enabled: Themenbereiche aktiviert + short_description: Kurzbeschreibung + show_metrics: Metriken anzeigen + show_statistics: Statistiken anzeigen + slug: URL-Slug + start_date: Ufanksdatum + subtitle: Ënnertitel + target: Wer nimmt teil + title: Titel + weight: Bestellposition + participatory_process_group: + description: Beschreibung + developer_group: Gruppe der Unterstützer + group_url: Website + hashtag: Hashtag + hero_image: Bild + local_area: Organisationsbereich + meta_scope: Informationen zum Bereich + participatory_process_ids: Ähnliche Beteiligungsprozesse + participatory_scope: Was wird entschieden + participatory_structure: Wie wird es entschieden + target: Wer nimmt teil + title: Titel + participatory_process_step: + cta_path: '"Call to Action"-Pfad' + cta_text: Call to Action-Text + description: Beschreibung + end_date: Enddatum + short_description: Kurzbeschreibung + decidim: + admin: + models: + participatory_process_step: + fields: + end_date: Enddatum + start_date: Ufanksdatum + title: Titel + name: Beteiligungsprozess Phase + participatory_process_user_role: + fields: + email: E-Mail + name: Numm + role: Rolle + name: Partizipativer Prozessbenutzer + roles: + admin: Administrator + collaborator: Mitarbeiter + moderator: Moderator + valuator: Schätzer + user: + fields: + invitation_accepted_at: Einladung akzeptiert am + invitation_sent_at: Einladung gesendet am + participatory_process_copies: + new: + copy: Kopieren + select: Wählen Sie aus, welche Daten Sie duplizieren möchten + title: Beteiligungsprozess duplizieren + participatory_process_group_landing_page: + edit: + active_content_blocks: Aktive Inhaltsblöcke + inactive_content_blocks: Inaktive Inhaltsblöcke + participatory_process_group_landing_page_content_blocks: + edit: + update: Aktualisieren + participatory_process_groups: + destroy: + error: Beim Löschen der Beteiligungsprozessgruppe ist ein Fehler aufgetreten. + success: Beteiligungsprozess erfolgreich gelöscht. + edit: + title: Prozessgruppe bearbeiten + update: Aktualisieren + new: + create: Erstellen + title: Neue Prozessgruppe + update: + error: Beim Aktualisieren dieser partizipativen Prozessgruppe ist ein Fehler aufgetreten. + success: Partizipative Prozessgruppe wurde erfolgreich aktualisiert. + participatory_process_groups: + content_blocks: + stats: + name: Aktivität diff --git a/decidim-participatory_processes/config/locales/lo-LA.yml b/decidim-participatory_processes/config/locales/lo-LA.yml new file mode 100644 index 0000000000000..27a02bfece429 --- /dev/null +++ b/decidim-participatory_processes/config/locales/lo-LA.yml @@ -0,0 +1 @@ +lo: diff --git a/decidim-participatory_processes/config/locales/lt.yml b/decidim-participatory_processes/config/locales/lt.yml index 0d5f4f14fc38e..05f6e5ff0ae52 100644 --- a/decidim-participatory_processes/config/locales/lt.yml +++ b/decidim-participatory_processes/config/locales/lt.yml @@ -451,6 +451,8 @@ lt: see: Žiūrėti index: loading: Įkeliami rezultatai... + show: + title: Apie šį procesą show: area: Aplinka belongs_to_group: Šis procesas priklauso diff --git a/decidim-participatory_processes/config/locales/no.yml b/decidim-participatory_processes/config/locales/no.yml index 3141a88132315..55a51873399dc 100644 --- a/decidim-participatory_processes/config/locales/no.yml +++ b/decidim-participatory_processes/config/locales/no.yml @@ -435,6 +435,8 @@ see: Se index: loading: Laster inn resultater... + show: + title: Om denne prosessen show: area: Område belongs_to_group: Denne prosessen tilhører diff --git a/decidim-participatory_processes/config/locales/oc-FR.yml b/decidim-participatory_processes/config/locales/oc-FR.yml new file mode 100644 index 0000000000000..325b348894124 --- /dev/null +++ b/decidim-participatory_processes/config/locales/oc-FR.yml @@ -0,0 +1 @@ +oc: diff --git a/decidim-participatory_processes/lib/decidim/participatory_processes/admin_engine.rb b/decidim-participatory_processes/lib/decidim/participatory_processes/admin_engine.rb index f79e2b8cf81e2..973bef444dd4c 100644 --- a/decidim-participatory_processes/lib/decidim/participatory_processes/admin_engine.rb +++ b/decidim-participatory_processes/lib/decidim/participatory_processes/admin_engine.rb @@ -56,7 +56,9 @@ class AdminEngine < ::Rails::Engine get :share end resources :exports, only: :create - resources :imports, only: [:new, :create] + resources :imports, only: [:new, :create] do + get :example, on: :collection + end end resources :moderations do diff --git a/decidim-participatory_processes/lib/decidim/participatory_processes/engine.rb b/decidim-participatory_processes/lib/decidim/participatory_processes/engine.rb index 937d6cc2bcfa5..d68351cbf9410 100644 --- a/decidim-participatory_processes/lib/decidim/participatory_processes/engine.rb +++ b/decidim-participatory_processes/lib/decidim/participatory_processes/engine.rb @@ -145,7 +145,7 @@ class Engine < ::Rails::Engine Decidim.content_blocks.register(:participatory_process_group_homepage, :highlighted_meetings) do |content_block| content_block.cell = "decidim/meetings/content_blocks/highlighted_meetings" - content_block.public_name_key = "decidim.meetings.content_blocks.upcoming_events.name" + content_block.public_name_key = "decidim.meetings.content_blocks.upcoming_meetings.name" content_block.default! end diff --git a/decidim-participatory_processes/lib/decidim/participatory_processes/test/factories.rb b/decidim-participatory_processes/lib/decidim/participatory_processes/test/factories.rb index 78c4bc3a6ab19..65cc785e67bf1 100644 --- a/decidim-participatory_processes/lib/decidim/participatory_processes/test/factories.rb +++ b/decidim-participatory_processes/lib/decidim/participatory_processes/test/factories.rb @@ -134,6 +134,7 @@ end organization { participatory_process.organization } + admin_terms_accepted_at { Time.current } after(:create) do |user, evaluator| create :participatory_process_user_role, diff --git a/decidim-participatory_processes/lib/decidim/participatory_processes/version.rb b/decidim-participatory_processes/lib/decidim/participatory_processes/version.rb index 850186882d4a0..c6d9857c53f7d 100644 --- a/decidim-participatory_processes/lib/decidim/participatory_processes/version.rb +++ b/decidim-participatory_processes/lib/decidim/participatory_processes/version.rb @@ -4,7 +4,7 @@ module Decidim # This holds the decidim-participatory_processes version. module ParticipatoryProcesses def self.version - "0.25.2" + "0.26.4" end end end diff --git a/decidim-participatory_processes/spec/cells/decidim/participatory_process_groups/content_blocks/title_cell_spec.rb b/decidim-participatory_processes/spec/cells/decidim/participatory_process_groups/content_blocks/title_cell_spec.rb index 7bfc30b0fc4d3..fd584bff7717a 100644 --- a/decidim-participatory_processes/spec/cells/decidim/participatory_process_groups/content_blocks/title_cell_spec.rb +++ b/decidim-participatory_processes/spec/cells/decidim/participatory_process_groups/content_blocks/title_cell_spec.rb @@ -47,7 +47,7 @@ it "shows some meta attributes" do expect(subject).to have_selector("svg.icon--twitter") - expect(subject).to have_link("#hashtag", href: "https://twitter.com/hashtag/hashtag") + expect(subject).to have_link("#hashtag", href: "https://twitter.com/hashtag/hashtag?src=hash") expect(subject).to have_selector("svg.icon--external-link") expect(subject).to have_link("www.example.org/group", href: group_url) expect(subject).to have_selector("svg.icon--globe") @@ -69,5 +69,14 @@ expect(subject).to have_no_selector("svg.icon--globe") end end + + context "when there are unpublished processes in the group" do + let!(:published_processes) { create_list(:participatory_process, 2, :published, organization: organization, participatory_process_group: participatory_process_group) } + let!(:unpublished_processes) { create_list(:participatory_process, 2, :unpublished, organization: organization, participatory_process_group: participatory_process_group) } + + it "shows correct participatory processes count" do + expect(subject).to have_content("2 processes") + end + end end end diff --git a/decidim-participatory_processes/spec/commands/create_participatory_process_spec.rb b/decidim-participatory_processes/spec/commands/create_participatory_process_spec.rb index 960daf3a2d9f6..005a91c2d3bda 100644 --- a/decidim-participatory_processes/spec/commands/create_participatory_process_spec.rb +++ b/decidim-participatory_processes/spec/commands/create_participatory_process_spec.rb @@ -45,7 +45,10 @@ module Decidim::ParticipatoryProcesses area: area, errors: errors, related_process_ids: related_process_ids, - participatory_process_group: participatory_process_group + participatory_process_group: participatory_process_group, + show_statistics: false, + show_metrics: false, + announcement: { en: "message" } ) end let(:invalid) { false } @@ -116,6 +119,12 @@ module Decidim::ParticipatoryProcesses expect(process.steps.first).to be_active end + it "doesn't enable by default stats and metrics" do + subject.call + expect(process.show_statistics).to eq(false) + expect(process.show_metrics).to eq(false) + end + it "adds the admins as followers" do subject.call expect(current_user.follows?(process)).to be true @@ -131,6 +140,19 @@ module Decidim::ParticipatoryProcesses linked_processes = process.linked_participatory_space_resources(:participatory_process, "related_processes") expect(linked_processes).to match_array([another_process]) end + + context "when sorting by weight" do + let!(:process_one) { create :participatory_process, organization: organization, weight: 2 } + let!(:process_two) { create :participatory_process, organization: organization, weight: 1 } + let(:related_process_ids) { [process_one.id, process_two.id] } + + it "links processes in right way" do + subject.call + + linked_processes = process.linked_participatory_space_resources(:participatory_process, "related_processes") + expect(linked_processes.first).to eq(process_two) + end + end end end end diff --git a/decidim-participatory_processes/spec/commands/decidim/participatory_processes/admin/import_participatory_process_spec.rb b/decidim-participatory_processes/spec/commands/decidim/participatory_processes/admin/import_participatory_process_spec.rb index 516415dfe1a4e..94c88b325978e 100644 --- a/decidim-participatory_processes/spec/commands/decidim/participatory_processes/admin/import_participatory_process_spec.rb +++ b/decidim-participatory_processes/spec/commands/decidim/participatory_processes/admin/import_participatory_process_spec.rb @@ -4,6 +4,8 @@ module Decidim::ParticipatoryProcesses describe Admin::ImportParticipatoryProcess do + include Decidim::ComponentTestHelpers + subject { described_class.new(form) } let(:organization) { create :organization } @@ -38,7 +40,14 @@ module Decidim::ParticipatoryProcesses let(:import_attachments) { false } let(:import_categories) { false } + def stub_calls_to_external_files + stub_get_request_with_format("http://localhost:3000/uploads/decidim/participatory_process/hero_image/1/city.jpeg", "image/jpeg") + stub_get_request_with_format("http://localhost:3000/uploads/decidim/participatory_process/banner_image/1/city2.jpeg", "image/jpeg") + end + shared_examples "import participatory_process succeeds" do + before { stub_calls_to_external_files } + it "broadcasts ok and create the process" do expect { subject.call }.to( broadcast(:ok) && @@ -80,6 +89,7 @@ module Decidim::ParticipatoryProcesses let(:import_components) { true } it "imports a participatory process and the steps" do + stub_calls_to_external_files expect { subject.call }.to change { Decidim::Component.count }.by(3) expect(Decidim::Component.where(participatory_space_id: Decidim::ParticipatoryProcess.last).count).to eq 3 end @@ -95,6 +105,7 @@ module Decidim::ParticipatoryProcesses let(:import_steps) { true } it "imports a participatory process and the steps" do + stub_calls_to_external_files expect { subject.call }.to change { Decidim::ParticipatoryProcessStep.count }.by(1) expect(Decidim::ParticipatoryProcessStep.distinct.pluck(:decidim_participatory_process_id).count).to eq 1 @@ -115,6 +126,8 @@ module Decidim::ParticipatoryProcesses let(:import_categories) { true } it "imports a participatory process and the categories" do + stub_calls_to_external_files + expect { subject.call }.to change { Decidim::Category.count }.by(8) expect(Decidim::Category.unscoped.distinct.pluck(:decidim_participatory_space_id).count).to eq 1 @@ -139,6 +152,8 @@ module Decidim::ParticipatoryProcesses context "when attachment collections exists" do it "imports a participatory process and the collections" do + stub_calls_to_external_files + expect { subject.call }.to change { Decidim::AttachmentCollection.count }.by(1) imported_participatory_process_collection = Decidim::AttachmentCollection.first expect(imported_participatory_process_collection.name).to eq("ca" => "assumenda", "en" => "cumque", "es" => "rem") diff --git a/decidim-participatory_processes/spec/controllers/admin/imports_controller_spec.rb b/decidim-participatory_processes/spec/controllers/admin/imports_controller_spec.rb index 0ebdba6cd3a11..ed523e728a22a 100644 --- a/decidim-participatory_processes/spec/controllers/admin/imports_controller_spec.rb +++ b/decidim-participatory_processes/spec/controllers/admin/imports_controller_spec.rb @@ -8,38 +8,15 @@ module Admin describe ImportsController, type: :controller do routes { Decidim::ParticipatoryProcesses::AdminEngine.routes } - let!(:organization) { create(:organization) } - let!(:participatory_process) { create :participatory_process, organization: organization } - let!(:user) { create(:user, :admin, :confirmed, organization: organization) } - let!(:component) { create(:component, participatory_space: participatory_process, manifest_name: "dummy") } - let(:creator) { Decidim::Admin::Import::Creator.new({ id: 1, "title/en": "My title for abstract creator" }) } + it_behaves_like "admin imports controller" do + let!(:participatory_space) { create :participatory_process, organization: organization } + let(:extra_params) { { participatory_process_slug: participatory_space.slug } } - let(:file) do - Rack::Test::UploadedFile.new( - Decidim::Dev.test_file("import_proposals.csv", "text/csv"), - "text/csv" - ) - end - - let(:params) do - { - file: file, - component_id: component.id, - participatory_process_slug: participatory_process.slug, - creator: "Decidim::Admin::Import::Creator" - } - end - - before do - request.env["decidim.current_organization"] = organization - sign_in user, scope: :user - end - - describe "POST create with abstract creator" do - it "raises NotImplementedError" do - expect do - post(:create, params: params) - end.to raise_error(NotImplementedError) + let(:file) do + Rack::Test::UploadedFile.new( + Decidim::Dev.test_file("import_proposals.csv", "text/csv"), + "text/csv" + ) end end end diff --git a/decidim-participatory_processes/spec/helpers/decidim/participatory_processes/participatory_process_helper_spec.rb b/decidim-participatory_processes/spec/helpers/decidim/participatory_processes/participatory_process_helper_spec.rb index 73d4b3d75310d..c3ca810997fc1 100644 --- a/decidim-participatory_processes/spec/helpers/decidim/participatory_processes/participatory_process_helper_spec.rb +++ b/decidim-participatory_processes/spec/helpers/decidim/participatory_processes/participatory_process_helper_spec.rb @@ -20,7 +20,7 @@ module ParticipatoryProcesses describe "when both dates are present" do it "returns the formatted dates" do result = helper.step_dates(participatory_process) - expect(result).to eq("2016-01-01 - 2016-02-05") + expect(result).to eq("01/01/2016 - 05/02/2016") end end @@ -29,7 +29,7 @@ module ParticipatoryProcesses it "fills it in with an interrogation mark" do result = helper.step_dates(participatory_process) - expect(result).to eq("? - 2016-02-05") + expect(result).to eq("? - 05/02/2016") end end @@ -38,7 +38,7 @@ module ParticipatoryProcesses it "fills it in with an interrogation mark" do result = helper.step_dates(participatory_process) - expect(result).to eq("2016-01-01 - ?") + expect(result).to eq("01/01/2016 - ?") end end end diff --git a/decidim-participatory_processes/spec/presenters/decidim/participatory_processes/participatory_process_stats_presenter_spec.rb b/decidim-participatory_processes/spec/presenters/decidim/participatory_processes/participatory_process_stats_presenter_spec.rb index 147c69490d93f..bed819e8cc60f 100644 --- a/decidim-participatory_processes/spec/presenters/decidim/participatory_processes/participatory_process_stats_presenter_spec.rb +++ b/decidim-participatory_processes/spec/presenters/decidim/participatory_processes/participatory_process_stats_presenter_spec.rb @@ -51,7 +51,7 @@ module Decidim end end - describe "comments count stat" do + describe "count stats from multiple components" do let(:manifest_proposals) do Decidim::ComponentManifest.new.tap do |manifest| manifest.name = "proposals" @@ -66,14 +66,17 @@ module Decidim before do manifest_meetings.stats.register :comments_count, tag: :comments, &proc { 10 } + manifest_meetings.stats.register :endorsements_count, tag: :endorsements, priority: Decidim::StatsRegistry::MEDIUM_PRIORITY, &proc { 5 } manifest_proposals.stats.register :comments_count, tag: :comments, &proc { 5 } + manifest_proposals.stats.register :endorsements_count, tag: :endorsements, priority: Decidim::StatsRegistry::MEDIUM_PRIORITY, &proc { 3 } I18n.backend.store_translations( :en, decidim: { participatory_processes: { statistics: { - comments_count: "Comments" + comments_count: "Comments", + endorsements_count: "Endorsements" } } } @@ -82,16 +85,20 @@ module Decidim allow(Decidim).to receive(:component_manifests).and_return([manifest_meetings, manifest_proposals]) end - it "return the sum of all the comments from proposals and meetings" do - data = subject.collection.first + it "returns the sum of all the comments from proposals and meetings" do + data = subject.collection.find { |stat| stat[:stat_title] == :comments_count } expect(data).not_to be_nil - expect(data[:stat_title]).to eq :comments_count expect(data[:stat_number]).to eq 15 end - it "contains only one stat" do - data = subject.collection.second - expect(data).to be_nil + it "returns the sum of all the endorsements from proposals and meetings" do + data = subject.collection.find { |stat| stat[:stat_title] == :endorsements_count } + expect(data).not_to be_nil + expect(data[:stat_number]).to eq 8 + end + + it "contains only two stats" do + expect(subject.collection.count).to be(2) end end end diff --git a/decidim-participatory_processes/spec/serializers/decidim/participatory_processes/participatory_process_importer_spec.rb b/decidim-participatory_processes/spec/serializers/decidim/participatory_processes/participatory_process_importer_spec.rb new file mode 100644 index 0000000000000..e0ddfae1b103d --- /dev/null +++ b/decidim-participatory_processes/spec/serializers/decidim/participatory_processes/participatory_process_importer_spec.rb @@ -0,0 +1,99 @@ +# frozen_string_literal: true + +require "spec_helper" + +module Decidim::ParticipatoryProcesses + describe ParticipatoryProcessImporter do + subject { importer } + + let(:organization) { create(:organization) } + let(:user) { create(:user, :confirmed, :admin, organization: organization) } + let(:importer) { described_class.new(organization, user) } + + describe "#import" do + subject { importer.import(import_data, user, options) } + + let(:options) do + { + title: generate_localized_title, + slug: "imported" + } + end + let(:import_data) do + { + "subtitle" => Decidim::Faker::Localized.sentence(word_count: 3), + "hashtag" => "hashtag", + "description" => Decidim::Faker::Localized.wrapped("

", "

") { generate_localized_title }, + "short_description" => Decidim::Faker::Localized.wrapped("

", "

") { generate_localized_title }, + "promoted" => false, + "developer_group" => Decidim::Faker::Localized.sentence(word_count: 3), + "local_area" => Decidim::Faker::Localized.sentence(word_count: 3), + "target" => Decidim::Faker::Localized.sentence(word_count: 3), + "participatory_scope" => Decidim::Faker::Localized.sentence(word_count: 3), + "participatory_structure" => Decidim::Faker::Localized.sentence(word_count: 3), + "meta_scope" => Decidim::Faker::Localized.sentence(word_count: 3), + "start_date" => "2022-08-01", + "end_date" => "2023-08-01", + "announcement" => Decidim::Faker::Localized.wrapped("

", "

") { generate_localized_title }, + "private_space" => false, + "scopes_enabled" => false, + "participatory_process_group" => group_data + } + end + let(:group_data) do + { + "title" => generate_localized_title, + "description" => Decidim::Faker::Localized.wrapped("

", "

") { generate_localized_title } + } + end + + it "imports the process correctly" do + expect { subject }.to change(Decidim::ParticipatoryProcess, :count).by(1) + + expect(subject.title).to eq(options[:title]) + expect(subject.slug).to eq(options[:slug]) + expect(subject.subtitle).to eq(import_data["subtitle"]) + expect(subject.hashtag).to eq(import_data["hashtag"]) + expect(subject.description).to eq(import_data["description"]) + expect(subject.short_description).to eq(import_data["short_description"]) + expect(subject.promoted).to eq(import_data["promoted"]) + expect(subject.developer_group).to eq(import_data["developer_group"]) + expect(subject.local_area).to eq(import_data["local_area"]) + expect(subject.target).to eq(import_data["target"]) + expect(subject.participatory_scope).to eq(import_data["participatory_scope"]) + expect(subject.participatory_structure).to eq(import_data["participatory_structure"]) + expect(subject.meta_scope).to eq(import_data["meta_scope"]) + expect(subject.start_date).to eq(Date.parse(import_data["start_date"])) + expect(subject.end_date).to eq(Date.parse(import_data["end_date"])) + expect(subject.announcement).to eq(import_data["announcement"]) + expect(subject.private_space).to eq(import_data["private_space"]) + expect(subject.participatory_process_group).to be_a(Decidim::ParticipatoryProcessGroup) + end + + it "imports the process group correctly" do + expect { subject }.to change(Decidim::ParticipatoryProcessGroup, :count).by(1) + + group = subject.participatory_process_group + expect(group.organization).to eq(subject.organization) + expect(group.title).to eq(group_data["title"]) + expect(group.description).to eq(group_data["description"]) + end + + context "when the process group title is defined with the name key" do + let(:group_data) do + { + "name" => generate_localized_title, + "description" => Decidim::Faker::Localized.wrapped("

", "

") { generate_localized_title } + } + end + + it "imports the process group correctly" do + expect { subject }.to change(Decidim::ParticipatoryProcessGroup, :count).by(1) + + group = subject.participatory_process_group + expect(group.title).to eq(group_data["name"]) + end + end + end + end +end diff --git a/decidim-participatory_processes/spec/system/admin/admin_filters_participatory_process_user_roles_spec.rb b/decidim-participatory_processes/spec/system/admin/admin_filters_participatory_process_user_roles_spec.rb new file mode 100644 index 0000000000000..adfd737441cb0 --- /dev/null +++ b/decidim-participatory_processes/spec/system/admin/admin_filters_participatory_process_user_roles_spec.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +require "spec_helper" + +describe "Admin filters user_roles", type: :system do + let(:organization) { create(:organization) } + let!(:admin) { create(:user, :admin, :confirmed, organization: organization) } + let(:participatory_process) { create(:participatory_process, organization: organization) } + + let(:resource_controller) { Decidim::Conferences::Admin::ConferenceUserRolesController } + let(:name) { "Dummy Name" } + let(:email) { "dummy_email@example.org" } + + let!(:invited_user_1) { create(:process_valuator, name: name, participatory_process: participatory_process) } + let!(:invited_user_2) { create(:process_valuator, email: email, participatory_process: participatory_process) } + + before do + invited_user_2.update!(invitation_sent_at: Time.current - 1.day, invitation_accepted_at: Time.current, last_sign_in_at: Time.current) + + switch_to_host(organization.host) + login_as admin, scope: :user + visit decidim_admin_participatory_processes.participatory_process_user_roles_path(participatory_process_slug: participatory_process.slug) + end + + include_context "with filterable context" + + include_examples "filterable participatory space user roles" + include_examples "searchable participatory space user roles" + context "when sorting" do + include_examples "sortable participatory space user roles" do + let!(:collection) do + create_list(:process_collaborator, 100, participatory_process: participatory_process, + last_sign_in_at: 2.days.ago, + invitation_accepted_at: 1.day.ago) + end + let!(:user) do + create(:process_valuator, + name: "ZZZupper user", + participatory_process: participatory_process, + last_sign_in_at: 30.seconds.ago, + invitation_accepted_at: Time.current) + end + + before do + visit decidim_admin_participatory_processes.participatory_process_user_roles_path(participatory_process_slug: participatory_process.slug, q: { s: sort_by }) + end + end + end + + it_behaves_like "paginating a collection" do + let!(:collection) { create_list(:process_valuator, 100, participatory_process: participatory_process) } + + before do + switch_to_host(organization.host) + login_as admin, scope: :user + visit decidim_admin_participatory_processes.participatory_process_user_roles_path(participatory_process_slug: participatory_process.slug) + end + end +end diff --git a/decidim-participatory_processes/spec/system/admin/admin_import_participatory_process_spec.rb b/decidim-participatory_processes/spec/system/admin/admin_import_participatory_process_spec.rb index 586151f188aa1..3ebeb253a1a71 100644 --- a/decidim-participatory_processes/spec/system/admin/admin_import_participatory_process_spec.rb +++ b/decidim-participatory_processes/spec/system/admin/admin_import_participatory_process_spec.rb @@ -27,6 +27,9 @@ attach_file :participatory_process_document, Decidim::Dev.asset("participatory_processes.json") end + stub_get_request_with_format("http://localhost:3000/uploads/decidim/participatory_process/hero_image/1/city.jpeg", "image/jpeg") + stub_get_request_with_format("http://localhost:3000/uploads/decidim/participatory_process/banner_image/1/city2.jpeg", "image/jpeg") + click_button "Import" end diff --git a/decidim-participatory_processes/spec/system/admin/admin_manages_participatory_process_groups_spec.rb b/decidim-participatory_processes/spec/system/admin/admin_manages_participatory_process_groups_spec.rb index c385c0292eac2..ce19041ed64cd 100644 --- a/decidim-participatory_processes/spec/system/admin/admin_manages_participatory_process_groups_spec.rb +++ b/decidim-participatory_processes/spec/system/admin/admin_manages_participatory_process_groups_spec.rb @@ -52,11 +52,11 @@ end expect(page).to have_admin_callout("successfully") - expect(page).to have_content("My group") - expect(page).to have_content("hashtag") - expect(page).to have_content("http://example.org") - expect(page).to have_content("X corporation") - expect(page).to have_content(participatory_processes.first.title["en"]) + expect(page).to have_field(:participatory_process_group_title_en, with: "My group") + expect(page).to have_field(:participatory_process_group_hashtag, with: "hashtag") + expect(page).to have_field(:participatory_process_group_group_url, with: "http://example.org") + expect(page).to have_field(:participatory_process_group_developer_group_en, with: "X corporation") + expect(page).to have_select("Related processes", selected: participatory_processes.first.title["en"]) expect(page).to have_css("img[src*='#{image1_filename}']") end @@ -107,12 +107,12 @@ end expect(page).to have_admin_callout("successfully") - expect(page).to have_content("My old group") + expect(page).to have_field(:participatory_process_group_title_en, with: "My old group") expect(page).to have_content("New description") - expect(page).to have_content("new_hashtag") - expect(page).to have_content("http://new-example.org") - expect(page).to have_content("Z corporation") - expect(page).to have_content(participatory_processes.last.title["en"]) + expect(page).to have_field(:participatory_process_group_hashtag, with: "new_hashtag") + expect(page).to have_field(:participatory_process_group_group_url, with: "http://new-example.org") + expect(page).to have_field(:participatory_process_group_developer_group_en, with: "Z corporation") + expect(page).to have_select("Related processes", selected: participatory_processes.last.title["en"]) expect(page).to have_css("img[src*='#{image2_filename}']") end diff --git a/decidim-participatory_processes/spec/system/admin/invite_process_admin_spec.rb b/decidim-participatory_processes/spec/system/admin/invite_process_admin_spec.rb index 29b6e98634d96..6245a7ef5d81f 100644 --- a/decidim-participatory_processes/spec/system/admin/invite_process_admin_spec.rb +++ b/decidim-participatory_processes/spec/system/admin/invite_process_admin_spec.rb @@ -21,8 +21,8 @@ within "form.new_user" do fill_in :invitation_user_nickname, with: "caballo_loco" - fill_in :invitation_user_password, with: "123456" - fill_in :invitation_user_password_confirmation, with: "123456" + fill_in :invitation_user_password, with: "decidim123456" + fill_in :invitation_user_password_confirmation, with: "decidim123456" check :invitation_user_tos_agreement find("*[type=submit]").click end @@ -32,7 +32,7 @@ visit decidim_admin.admin_terms_show_path - find_button("I agree with the following terms").click + find_button("I agree with the terms").click click_link "Processes" diff --git a/decidim-participatory_processes/spec/system/admin/invite_process_collaborator_spec.rb b/decidim-participatory_processes/spec/system/admin/invite_process_collaborator_spec.rb index 9634a45407905..c135da62933b5 100644 --- a/decidim-participatory_processes/spec/system/admin/invite_process_collaborator_spec.rb +++ b/decidim-participatory_processes/spec/system/admin/invite_process_collaborator_spec.rb @@ -20,8 +20,8 @@ within "form.new_user" do fill_in :invitation_user_nickname, with: "caballo_loco" - fill_in :invitation_user_password, with: "123456" - fill_in :invitation_user_password_confirmation, with: "123456" + fill_in :invitation_user_password, with: "decidim123456" + fill_in :invitation_user_password_confirmation, with: "decidim123456" check :invitation_user_tos_agreement find("*[type=submit]").click end @@ -30,7 +30,7 @@ expect(page).to have_content("Dashboard") visit decidim_admin.admin_terms_show_path - find_button("I agree with the following terms").click + find_button("I agree with the terms").click click_link "Processes" diff --git a/decidim-participatory_processes/spec/system/admin/invite_process_moderator_spec.rb b/decidim-participatory_processes/spec/system/admin/invite_process_moderator_spec.rb index 8246ff9cd71fb..6fe9723de6519 100644 --- a/decidim-participatory_processes/spec/system/admin/invite_process_moderator_spec.rb +++ b/decidim-participatory_processes/spec/system/admin/invite_process_moderator_spec.rb @@ -19,8 +19,8 @@ within "form.new_user" do fill_in :invitation_user_nickname, with: "caballo_loco" - fill_in :invitation_user_password, with: "123456" - fill_in :invitation_user_password_confirmation, with: "123456" + fill_in :invitation_user_password, with: "decidim123456" + fill_in :invitation_user_password_confirmation, with: "decidim123456" check :invitation_user_tos_agreement find("*[type=submit]").click end @@ -29,7 +29,7 @@ expect(page).to have_content("Dashboard") visit decidim_admin.admin_terms_show_path - find_button("I agree with the following terms").click + find_button("I agree with the terms").click click_link "Processes" diff --git a/decidim-participatory_processes/spec/system/participatory_processes_spec.rb b/decidim-participatory_processes/spec/system/participatory_processes_spec.rb index 28b12644b263e..ec9e7e38d157b 100644 --- a/decidim-participatory_processes/spec/system/participatory_processes_spec.rb +++ b/decidim-participatory_processes/spec/system/participatory_processes_spec.rb @@ -236,6 +236,8 @@ let(:promoted_items_titles) { page.all("#highlighted-processes .card__title").map(&:text) } before do + promoted_group.title["en"] = "D'Artagnan #{promoted_group.title["en"]}" + promoted_group.save! visit decidim_participatory_processes.participatory_processes_path end @@ -248,6 +250,13 @@ expect(promoted_items_titles).not_to include(translated(group.title, locale: :en)) end + it "lists all the highlighted process groups" do + within "#highlighted-processes" do + expect(page).to have_content(translated(promoted_group.title, locale: :en)) + expect(page).to have_selector(".card--full", count: 2) + end + end + context "and promoted group has defined a CTA content block" do let(:cta_settings) do { diff --git a/decidim-participatory_processes/spec/types/integration_schema_spec.rb b/decidim-participatory_processes/spec/types/integration_schema_spec.rb new file mode 100644 index 0000000000000..0e1b5ecb29dba --- /dev/null +++ b/decidim-participatory_processes/spec/types/integration_schema_spec.rb @@ -0,0 +1,225 @@ +# frozen_string_literal: true + +require "spec_helper" +require "decidim/api/test/type_context" + +describe "Decidim::Api::QueryType" do + include_context "with a graphql class type" + let(:schema) { Decidim::Api::Schema } + + let(:locale) { "en" } + + let(:participatory_process) { create(:participatory_process, organization: current_organization) } + + let(:participatory_process_query) do + %( + participatoryProcess { + announcement{ + translation(locale: "#{locale}") + locales + } + attachments{ + url + type + thumbnail + } + bannerImage + categories{ + id + name{ + translation(locale: "#{locale}") + } + parent { + id + } + subcategories{ + id + } + } + components{ + id + name { + translation(locale: "#{locale}") + } + weight + __typename + } + + createdAt + description { + translation(locale: "#{locale}") + } + developerGroup{ + translation(locale: "#{locale}") + } + endDate + hashtag + heroImage + id + linkedParticipatorySpaces{ + fromType + id + name + participatorySpace{ + id + } + toType + } + localArea { + translation(locale: "#{locale}") + } + metaScope { + translation(locale: "#{locale}") + } + participatoryProcessGroup { + description { + translation(locale: "#{locale}") + } + heroImage + id + title{ + translation(locale: "#{locale}") + } + participatoryProcesses { + id + } + } + participatoryScope { + translation(locale: "#{locale}") + } + participatoryStructure { + translation(locale: "#{locale}") + } + promoted + publishedAt + reference + scope { + children { + id + } + id + name { + translation(locale: "#{locale}") + } + parent { + id + } + } + scopesEnabled + shortDescription { + translation(locale: "#{locale}") + } + showMetrics + showStatistics + slug + startDate + steps { + active + callToActionPath + callToActionText{ + translation(locale: "#{locale}") + } + description{ + translation(locale: "#{locale}") + } + endDate + id + participatoryProcess { + id + } + position + startDate + title { + translation(locale: "#{locale}") + } + } + subtitle { + translation(locale: "#{locale}") + } + target{ + translation(locale: "#{locale}") + } + title{ + translation(locale: "#{locale}") + } + type + updatedAt + } + ) + end + + let(:components) { [] } + let!(:participatory_process_response) do + { + "announcement" => { + "locales" => ( + participatory_process.announcement.keys.excluding("machine_translations") + + participatory_process.announcement["machine_translations"].keys + ).sort, + "translation" => participatory_process.announcement[locale] + }, + "attachments" => [], + "bannerImage" => participatory_process.attached_uploader(:banner_image).path.sub(Rails.root.join("public").to_s, ""), + "categories" => [], + "components" => components, + "createdAt" => participatory_process.created_at.iso8601.to_s.gsub("Z", "+00:00"), + "description" => { "translation" => participatory_process.description[locale] }, + "developerGroup" => { "translation" => participatory_process.developer_group[locale] }, + "endDate" => participatory_process.end_date.to_s, + "hashtag" => "", + "heroImage" => participatory_process.attached_uploader(:hero_image).path.sub(Rails.root.join("public").to_s, ""), + "id" => participatory_process.id.to_s, + "linkedParticipatorySpaces" => [], + "localArea" => { "translation" => participatory_process.local_area[locale] }, + "metaScope" => { "translation" => participatory_process.meta_scope[locale] }, + "participatoryProcessGroup" => nil, + "participatoryScope" => { "translation" => participatory_process.participatory_scope[locale] }, + "participatoryStructure" => { "translation" => participatory_process.participatory_structure[locale] }, + "promoted" => false, + "publishedAt" => participatory_process.published_at.iso8601.to_s.gsub("Z", "+00:00"), + "reference" => participatory_process.reference, + "scope" => participatory_process.scope, + "scopesEnabled" => participatory_process.scopes_enabled, + "shortDescription" => { "translation" => participatory_process.short_description[locale] }, + "showMetrics" => participatory_process.show_metrics, + "showStatistics" => participatory_process.show_statistics, + "slug" => participatory_process.slug, + "startDate" => participatory_process.start_date.to_s, + "steps" => participatory_process.steps.to_a, + "subtitle" => { "translation" => participatory_process.subtitle[locale] }, + "target" => { "translation" => participatory_process.target[locale] }, + "title" => { "translation" => participatory_process.title[locale] }, + "type" => "Decidim::ParticipatoryProcess", + "updatedAt" => participatory_process.updated_at.iso8601.to_s.gsub("Z", "+00:00") + } + end + let(:query) do + %( + query { + #{participatory_process_query} + } + ) + end + + describe "valid query" do + it "executes sucessfully" do + expect { response }.not_to raise_error(StandardError) + end + + it { expect(response["participatoryProcess"]).to eq(participatory_process_response) } + + it_behaves_like "implements stats type" do + let(:participatory_process_query) do + %( + participatoryProcess{ + stats{ + name + value + } + } + ) + end + let(:stats_response) { response["participatoryProcess"]["stats"] } + end + end +end diff --git a/decidim-participatory_processes/spec/types/participatory_process_step_type_spec.rb b/decidim-participatory_processes/spec/types/participatory_process_step_type_spec.rb index 7c7d34380f65b..392ce9bb71c40 100644 --- a/decidim-participatory_processes/spec/types/participatory_process_step_type_spec.rb +++ b/decidim-participatory_processes/spec/types/participatory_process_step_type_spec.rb @@ -36,7 +36,8 @@ module ParticipatoryProcesses let(:query) { '{ title { locales translation(locale:"en") } }' } it "returns its title" do - expect(response["title"]["locales"]).to include(*model.title.keys) + expected_keys = (model.description.keys.excluding("machine_translations") + model.description["machine_translations"].keys).sort + expect(response["title"]["locales"]).to include(*expected_keys) expect(response["title"]["translation"]).to eq(model.title["en"]) end end @@ -45,7 +46,8 @@ module ParticipatoryProcesses let(:query) { '{ description { locales translation(locale:"en") } }' } it "returns its description" do - expect(response["description"]["locales"]).to include(*model.description.keys) + expected_keys = (model.description.keys.excluding("machine_translations") + model.description["machine_translations"].keys).sort + expect(response["description"]["locales"]).to include(*expected_keys) expect(response["description"]["translation"]).to eq(model.description["en"]) end end diff --git a/decidim-proposals/app/cells/decidim/proposals/collaborative_draft_cell.rb b/decidim-proposals/app/cells/decidim/proposals/collaborative_draft_cell.rb index 157a00ce9fc4a..212e899172ac0 100644 --- a/decidim-proposals/app/cells/decidim/proposals/collaborative_draft_cell.rb +++ b/decidim-proposals/app/cells/decidim/proposals/collaborative_draft_cell.rb @@ -22,7 +22,7 @@ def card_size end def resource_path - resource_locator(model).path(filter_link_params) + resource_locator(model).path end def current_participatory_space diff --git a/decidim-proposals/app/cells/decidim/proposals/collaborative_draft_m_cell.rb b/decidim-proposals/app/cells/decidim/proposals/collaborative_draft_m_cell.rb index fe08611621f33..581bdd747d1ca 100644 --- a/decidim-proposals/app/cells/decidim/proposals/collaborative_draft_m_cell.rb +++ b/decidim-proposals/app/cells/decidim/proposals/collaborative_draft_m_cell.rb @@ -23,7 +23,7 @@ def title end def description - decidim_sanitize(present(model).body.truncate(100, separator: /\s/)) + decidim_sanitize_editor(present(model).body.truncate(100, separator: /\s/)) end def has_badge? diff --git a/decidim-proposals/app/cells/decidim/proposals/cost_report_cell.rb b/decidim-proposals/app/cells/decidim/proposals/cost_report_cell.rb index a2d51be9c67cb..f414b2c9e7d6e 100644 --- a/decidim-proposals/app/cells/decidim/proposals/cost_report_cell.rb +++ b/decidim-proposals/app/cells/decidim/proposals/cost_report_cell.rb @@ -18,7 +18,7 @@ def cost end def cost_report - decidim_sanitize(translated_attribute(model.cost_report).html_safe) + decidim_sanitize_editor(translated_attribute(model.cost_report).html_safe) end def needs_text_toggle? @@ -26,7 +26,7 @@ def needs_text_toggle? end def cost_report_short - decidim_sanitize( + decidim_sanitize_editor( html_truncate( translated_attribute(model.cost_report).html_safe, length: 200 @@ -35,7 +35,7 @@ def cost_report_short end def execution_period - decidim_sanitize(translated_attribute(model.execution_period).html_safe) + decidim_sanitize_editor(translated_attribute(model.execution_period).html_safe) end end end diff --git a/decidim-proposals/app/cells/decidim/proposals/participatory_text_proposal_cell.rb b/decidim-proposals/app/cells/decidim/proposals/participatory_text_proposal_cell.rb index 7f4935739379e..ee89b316f62ae 100644 --- a/decidim-proposals/app/cells/decidim/proposals/participatory_text_proposal_cell.rb +++ b/decidim-proposals/app/cells/decidim/proposals/participatory_text_proposal_cell.rb @@ -35,11 +35,11 @@ def body return unless model.participatory_text_level == "article" formatted = simple_format(present(model).body) - decidim_sanitize(strip_links(formatted)) + decidim_sanitize_editor(strip_links(formatted)) end def resource_path - resource_locator(model).path(filter_link_params) + resource_locator(model).path end def amend_resource_path diff --git a/decidim-proposals/app/cells/decidim/proposals/proposal_cell.rb b/decidim-proposals/app/cells/decidim/proposals/proposal_cell.rb index 3ec7e0bd9affc..8510fade4f773 100644 --- a/decidim-proposals/app/cells/decidim/proposals/proposal_cell.rb +++ b/decidim-proposals/app/cells/decidim/proposals/proposal_cell.rb @@ -22,7 +22,7 @@ def card_size end def resource_path - resource_locator(model).path(filter_link_params) + resource_locator(model).path end def current_participatory_space diff --git a/decidim-proposals/app/cells/decidim/proposals/proposal_m_cell.rb b/decidim-proposals/app/cells/decidim/proposals/proposal_m_cell.rb index 127692a8398f2..07097c62f212e 100644 --- a/decidim-proposals/app/cells/decidim/proposals/proposal_m_cell.rb +++ b/decidim-proposals/app/cells/decidim/proposals/proposal_m_cell.rb @@ -21,11 +21,11 @@ def preview? end def title - decidim_html_escape(present(model).title) + present(model).title(html_escape: true) end def body - decidim_sanitize(present(model).body) + decidim_sanitize_editor(present(model).body) end def has_state? @@ -118,16 +118,15 @@ def endorsements_visible? end def has_image? - @has_image ||= model.component.settings.allow_card_image && model.attachments.find_by("content_type like '%image%'").present? + @has_image ||= model.attachments.map(&:image?).any? end def resource_image_path - @resource_image_path ||= has_image? ? model.attachments.find_by("content_type like '%image%'").url : nil + @resource_image_path ||= has_image? ? model.attachments.find_by("content_type like '%image%'").thumbnail_url : nil end def cache_hash hash = [] - hash << "decidim/proposals/proposal_m" hash << I18n.locale.to_s hash << model.cache_key_with_version hash << model.proposal_votes_count @@ -143,9 +142,11 @@ def cache_hash hash << model.follows_count hash << Digest::MD5.hexdigest(model.authors.map(&:cache_key_with_version).to_s) hash << (model.must_render_translation?(model.organization) ? 1 : 0) if model.respond_to?(:must_render_translation?) - hash << model.component.participatory_space.active_step.id if model.component.participatory_space.has_steps? + hash << model.component.participatory_space.active_step.id if model.component.participatory_space.try(:active_step) + hash << has_footer? + hash << has_actions? - hash.join("/") + hash.join(Decidim.cache_key_separator) end end end diff --git a/decidim-proposals/app/cells/decidim/proposals/proposals_picker_cell.rb b/decidim-proposals/app/cells/decidim/proposals/proposals_picker_cell.rb index cba57cee5d72c..3fe14bd353b2c 100644 --- a/decidim-proposals/app/cells/decidim/proposals/proposals_picker_cell.rb +++ b/decidim-proposals/app/cells/decidim/proposals/proposals_picker_cell.rb @@ -63,6 +63,7 @@ def proposals @proposals ||= Decidim.find_resource_manifest(:proposals).try(:resource_scope, component) &.includes(:component) &.published + &.not_hidden &.order(id: :asc) end diff --git a/decidim-proposals/app/commands/decidim/proposals/admin/answer_proposal.rb b/decidim-proposals/app/commands/decidim/proposals/admin/answer_proposal.rb index f3261a5e43025..8b2e00127c987 100644 --- a/decidim-proposals/app/commands/decidim/proposals/admin/answer_proposal.rb +++ b/decidim-proposals/app/commands/decidim/proposals/admin/answer_proposal.rb @@ -46,13 +46,18 @@ def answer_proposal attributes = { state: form.state, answer: form.answer, - answered_at: Time.current, cost: form.cost, cost_report: form.cost_report, execution_period: form.execution_period } - attributes[:state_published_at] = Time.current if !initial_has_state_published && form.publish_answer? + if form.state == "not_answered" + attributes[:answered_at] = nil + attributes[:state_published_at] = nil + else + attributes[:answered_at] = Time.current + attributes[:state_published_at] = Time.current if !initial_has_state_published && form.publish_answer? + end proposal.update!(attributes) end diff --git a/decidim-proposals/app/commands/decidim/proposals/admin/create_proposal.rb b/decidim-proposals/app/commands/decidim/proposals/admin/create_proposal.rb index 868790a27c334..71f8a03c33b45 100644 --- a/decidim-proposals/app/commands/decidim/proposals/admin/create_proposal.rb +++ b/decidim-proposals/app/commands/decidim/proposals/admin/create_proposal.rb @@ -40,9 +40,10 @@ def call create_attachment if process_attachments? create_gallery if process_gallery? link_author_meeeting if form.created_in_meeting? - send_notification end + send_notification + broadcast(:ok, proposal) end @@ -61,7 +62,7 @@ def create_proposal def attributes parsed_title = Decidim::ContentProcessor.parse_with_processor(:hashtag, form.title, current_organization: form.current_organization).rewrite - parsed_body = Decidim::ContentProcessor.parse_with_processor(:hashtag, form.body, current_organization: form.current_organization).rewrite + parsed_body = Decidim::ContentProcessor.parse(form.body, current_organization: form.current_organization).rewrite { title: parsed_title, body: parsed_body, @@ -81,11 +82,13 @@ def link_author_meeeting end def send_notification + return unless proposal + Decidim::EventsManager.publish( event: "decidim.events.proposals.proposal_published", event_class: Decidim::Proposals::PublishProposalEvent, resource: proposal, - followers: @proposal.participatory_space.followers, + followers: proposal.participatory_space.followers, extra: { participatory_space: true } diff --git a/decidim-proposals/app/commands/decidim/proposals/admin/import_proposals.rb b/decidim-proposals/app/commands/decidim/proposals/admin/import_proposals.rb index 1b86753fbbf55..3dc06e7dd5a8a 100644 --- a/decidim-proposals/app/commands/decidim/proposals/admin/import_proposals.rb +++ b/decidim-proposals/app/commands/decidim/proposals/admin/import_proposals.rb @@ -76,7 +76,10 @@ def target_component end def proposal_already_copied?(original_proposal, target_component) - original_proposal.linked_resources(:proposals, "copied_from_component").any? do |proposal| + # Note: we are including also proposals from unpublished components + # because otherwise duplicates could be created until the component is + # published. + original_proposal.linked_resources(:proposals, "copied_from_component", component_published: false).any? do |proposal| proposal.component == target_component end end diff --git a/decidim-proposals/app/commands/decidim/proposals/admin/update_proposal.rb b/decidim-proposals/app/commands/decidim/proposals/admin/update_proposal.rb index e263afa3896e4..87fb3ac7e21b5 100644 --- a/decidim-proposals/app/commands/decidim/proposals/admin/update_proposal.rb +++ b/decidim-proposals/app/commands/decidim/proposals/admin/update_proposal.rb @@ -59,7 +59,7 @@ def call def update_proposal parsed_title = Decidim::ContentProcessor.parse_with_processor(:hashtag, form.title, current_organization: form.current_organization).rewrite - parsed_body = Decidim::ContentProcessor.parse_with_processor(:hashtag, form.body, current_organization: form.current_organization).rewrite + parsed_body = Decidim::ContentProcessor.parse(form.body, current_organization: form.current_organization).rewrite Decidim.traceability.update!( proposal, form.current_user, diff --git a/decidim-proposals/app/commands/decidim/proposals/hashtags_methods.rb b/decidim-proposals/app/commands/decidim/proposals/hashtags_methods.rb index 9e93371ce8609..b62eae16b41d0 100644 --- a/decidim-proposals/app/commands/decidim/proposals/hashtags_methods.rb +++ b/decidim-proposals/app/commands/decidim/proposals/hashtags_methods.rb @@ -13,7 +13,7 @@ def title_with_hashtags def body_with_hashtags @body_with_hashtags ||= begin - ret = Decidim::ContentProcessor.parse_with_processor(:hashtag, form.body, current_organization: form.current_organization).rewrite.strip + ret = Decidim::ContentProcessor.parse(form.body, current_organization: form.current_organization).rewrite.strip ret += "\n#{body_extra_hashtags.strip}" unless body_extra_hashtags.empty? ret end diff --git a/decidim-proposals/app/commands/decidim/proposals/update_proposal.rb b/decidim-proposals/app/commands/decidim/proposals/update_proposal.rb index b0c82aa4faf6d..3c71d7bdc5365 100644 --- a/decidim-proposals/app/commands/decidim/proposals/update_proposal.rb +++ b/decidim-proposals/app/commands/decidim/proposals/update_proposal.rb @@ -45,11 +45,12 @@ def call else update_proposal end - create_gallery if process_gallery? - create_attachments if process_attachments? photo_cleanup! document_cleanup! + + create_gallery if process_gallery? + create_attachments if process_attachments? end broadcast(:ok, proposal) diff --git a/decidim-proposals/app/controllers/concerns/decidim/proposals/orderable.rb b/decidim-proposals/app/controllers/concerns/decidim/proposals/orderable.rb index 37ac67335906b..3a35f2c2f2c22 100644 --- a/decidim-proposals/app/controllers/concerns/decidim/proposals/orderable.rb +++ b/decidim-proposals/app/controllers/concerns/decidim/proposals/orderable.rb @@ -15,19 +15,32 @@ module Orderable # Available orders based on enabled settings def available_orders - @available_orders ||= begin - available_orders = %w(random recent) - available_orders << "most_voted" if most_voted_order_available? - available_orders << "most_endorsed" if current_settings.endorsements_enabled? - available_orders << "most_commented" if component_settings.comments_enabled? - available_orders << "most_followed" << "with_more_authors" - available_orders + @available_orders ||= [default_order] + possible_orders.excluding(default_order) + end + + def possible_orders + @possible_orders ||= begin + possible_orders = %w(random recent) + possible_orders << "most_voted" if most_voted_order_available? + possible_orders << "most_endorsed" if current_settings.endorsements_enabled? + possible_orders << "most_commented" if component_settings.comments_enabled? + possible_orders << "most_followed" << "with_more_authors" + possible_orders end end def default_order + @default_order ||= begin + default_order = current_settings.default_sort_order.presence || component_settings.default_sort_order + return order_by_default if default_order == "default" + + possible_orders.include?(default_order) ? default_order : order_by_default + end + end + + def order_by_default if order_by_votes? - detect_order("most_voted") + "most_voted" else "random" end diff --git a/decidim-proposals/app/controllers/decidim/proposals/admin/proposals_merges_controller.rb b/decidim-proposals/app/controllers/decidim/proposals/admin/proposals_merges_controller.rb index 1e4290e609f0d..a3e13712c82d6 100644 --- a/decidim-proposals/app/controllers/decidim/proposals/admin/proposals_merges_controller.rb +++ b/decidim-proposals/app/controllers/decidim/proposals/admin/proposals_merges_controller.rb @@ -16,7 +16,10 @@ def create end on(:invalid) do - flash[:alert] = I18n.t("proposals_merges.create.invalid", scope: "decidim.proposals.admin") + flash[:alert_html] = Decidim::ValidationErrorsPresenter.new( + I18n.t("proposals_merges.create.invalid", scope: "decidim.proposals.admin"), + @form + ).message redirect_to EngineRouter.admin_proxy(current_component).root_path end end diff --git a/decidim-proposals/app/controllers/decidim/proposals/admin/proposals_splits_controller.rb b/decidim-proposals/app/controllers/decidim/proposals/admin/proposals_splits_controller.rb index c4e5eb69674ca..1ff85de37de48 100644 --- a/decidim-proposals/app/controllers/decidim/proposals/admin/proposals_splits_controller.rb +++ b/decidim-proposals/app/controllers/decidim/proposals/admin/proposals_splits_controller.rb @@ -16,7 +16,10 @@ def create end on(:invalid) do - flash.now[:alert] = I18n.t("proposals_splits.create.invalid", scope: "decidim.proposals.admin") + flash[:alert_html] = Decidim::ValidationErrorsPresenter.new( + I18n.t("proposals_splits.create.invalid", scope: "decidim.proposals.admin"), + @form + ).message redirect_to EngineRouter.admin_proxy(current_component).root_path end end diff --git a/decidim-proposals/app/controllers/decidim/proposals/collaborative_drafts_controller.rb b/decidim-proposals/app/controllers/decidim/proposals/collaborative_drafts_controller.rb index 16eb83177c701..3ec6a3b103d52 100644 --- a/decidim-proposals/app/controllers/decidim/proposals/collaborative_drafts_controller.rb +++ b/decidim-proposals/app/controllers/decidim/proposals/collaborative_drafts_controller.rb @@ -30,8 +30,8 @@ def index .includes(:category) .includes(:scope) - @collaborative_drafts = paginate(@collaborative_drafts) @collaborative_drafts = reorder(@collaborative_drafts) + @collaborative_drafts = paginate(@collaborative_drafts) end def show @@ -63,7 +63,7 @@ def create on(:invalid) do flash.now[:alert] = I18n.t("proposals.collaborative_drafts.create.error", scope: "decidim") - render :complete + render :new end end end diff --git a/decidim-proposals/app/controllers/decidim/proposals/proposals_controller.rb b/decidim-proposals/app/controllers/decidim/proposals/proposals_controller.rb index 40ccb5d4cb2e2..84e011ae544f8 100644 --- a/decidim-proposals/app/controllers/decidim/proposals/proposals_controller.rb +++ b/decidim-proposals/app/controllers/decidim/proposals/proposals_controller.rb @@ -32,7 +32,7 @@ def index .published .not_hidden .only_amendables - .includes(:category, :scope) + .includes(:category, :scope, :attachments, :coauthorships) .order(position: :asc) render "decidim/proposals/proposals/participatory_texts/participatory_text" else @@ -41,7 +41,7 @@ def index .published .not_hidden - @proposals = @base_query.includes(:component, :coauthorships) + @proposals = @base_query.includes(:component, :coauthorships, :attachments) @all_geocoded_proposals = @base_query.geocoded @voted_proposals = if current_user @@ -52,8 +52,8 @@ def index else [] end - @proposals = paginate(@proposals) @proposals = reorder(@proposals) + @proposals = paginate(@proposals) end end diff --git a/decidim-proposals/app/events/decidim/proposals/admin/proposal_note_created_event.rb b/decidim-proposals/app/events/decidim/proposals/admin/proposal_note_created_event.rb index e169c50f12bab..c12f5600977b6 100644 --- a/decidim-proposals/app/events/decidim/proposals/admin/proposal_note_created_event.rb +++ b/decidim-proposals/app/events/decidim/proposals/admin/proposal_note_created_event.rb @@ -13,7 +13,7 @@ def admin_proposal_info_path end def admin_proposal_info_url - decidim_admin_participatory_process_proposals.proposal_url(resource, resource.component.mounted_params) + send(resource.component.mounted_admin_engine).proposal_url(resource, resource.component.mounted_params) end private diff --git a/decidim-proposals/app/events/decidim/proposals/collaborative_draft_withdrawn_event.rb b/decidim-proposals/app/events/decidim/proposals/collaborative_draft_withdrawn_event.rb index ef8d175d89c7b..cc568831a3852 100644 --- a/decidim-proposals/app/events/decidim/proposals/collaborative_draft_withdrawn_event.rb +++ b/decidim-proposals/app/events/decidim/proposals/collaborative_draft_withdrawn_event.rb @@ -3,7 +3,7 @@ module Decidim module Proposals class CollaborativeDraftWithdrawnEvent < Decidim::Events::SimpleEvent - i18n_attributes :author_nickname, :author_name, :author_path + i18n_attributes :author_nickname, :author_name, :author_path, :author_url delegate :nickname, :name, to: :author, prefix: true @@ -15,6 +15,10 @@ def author_path author.profile_path end + def author_url + author.profile_url + end + private def author diff --git a/decidim-proposals/app/events/decidim/proposals/proposal_mentioned_event.rb b/decidim-proposals/app/events/decidim/proposals/proposal_mentioned_event.rb index 85c1caafaeb04..27ba3b3d823ae 100644 --- a/decidim-proposals/app/events/decidim/proposals/proposal_mentioned_event.rb +++ b/decidim-proposals/app/events/decidim/proposals/proposal_mentioned_event.rb @@ -7,6 +7,14 @@ class ProposalMentionedEvent < Decidim::Events::SimpleEvent i18n_attributes :mentioned_proposal_title + def safe_resource_translated_text + resource_text + end + + def perform_translation? + false + end + private def mentioned_proposal_title diff --git a/decidim-proposals/app/events/decidim/proposals/publish_proposal_event.rb b/decidim-proposals/app/events/decidim/proposals/publish_proposal_event.rb index 8c37c4b9321df..3a91d39bafaa5 100644 --- a/decidim-proposals/app/events/decidim/proposals/publish_proposal_event.rb +++ b/decidim-proposals/app/events/decidim/proposals/publish_proposal_event.rb @@ -4,11 +4,45 @@ module Decidim module Proposals class PublishProposalEvent < Decidim::Events::SimpleEvent include Decidim::Events::CoauthorEvent + include Decidim::Core::Engine.routes.url_helpers + include ActionView::Helpers::UrlHelper + include Decidim::Events::MachineTranslatedEvent def resource_text resource.body end + def i18n_options + return super if author.blank? + + author_path = link_to("@#{author.nickname}", profile_path(author.nickname)) + author_string = "#{author.name} #{author_path}" + super.merge({ author: author_string }) + end + + def translatable_resource + resource + end + + def translatable_text + resource.body + end + + def safe_resource_text + locale = resource.respond_to?(:content_original_language) ? resource.content_original_language : I18n.locale + I18n.with_locale(locale) { translated_attribute(resource_text).to_s.html_safe } + end + + def safe_resource_translated_text + I18n.with_locale(I18n.locale) { translated_attribute(resource_text, nil, true).to_s.html_safe } + end + + def notification_title + i18n_key = resource.official? ? "notification_title_official" : "notification_title" + + I18n.t(i18n_key, **i18n_options).html_safe + end + private def i18n_scope diff --git a/decidim-proposals/app/forms/decidim/proposals/admin/proposal_answer_form.rb b/decidim-proposals/app/forms/decidim/proposals/admin/proposal_answer_form.rb index b162fb84cbb8e..86b4ab98133f3 100644 --- a/decidim-proposals/app/forms/decidim/proposals/admin/proposal_answer_form.rb +++ b/decidim-proposals/app/forms/decidim/proposals/admin/proposal_answer_form.rb @@ -14,7 +14,7 @@ class ProposalAnswerForm < Decidim::Form attribute :cost, Float attribute :internal_state, String - validates :internal_state, presence: true, inclusion: { in: %w(accepted rejected evaluating) } + validates :internal_state, presence: true, inclusion: { in: %w(not_answered accepted rejected evaluating) } validates :answer, translatable_presence: true, if: ->(form) { form.state == "rejected" } with_options if: :costs_required? do diff --git a/decidim-proposals/app/forms/decidim/proposals/admin/proposal_base_form.rb b/decidim-proposals/app/forms/decidim/proposals/admin/proposal_base_form.rb index f30befc7eddcc..73453b6e78e29 100644 --- a/decidim-proposals/app/forms/decidim/proposals/admin/proposal_base_form.rb +++ b/decidim-proposals/app/forms/decidim/proposals/admin/proposal_base_form.rb @@ -82,7 +82,7 @@ def geocoded? # Finds the Meetings of the current participatory space def meetings @meetings ||= Decidim.find_resource_manifest(:meetings).try(:resource_scope, current_component) - &.order(title: :asc) + &.published&.order(title: :asc) end # Return the meeting as author diff --git a/decidim-proposals/app/forms/decidim/proposals/admin/proposals_file_import_form.rb b/decidim-proposals/app/forms/decidim/proposals/admin/proposals_file_import_form.rb new file mode 100644 index 0000000000000..3ee7746c5863e --- /dev/null +++ b/decidim-proposals/app/forms/decidim/proposals/admin/proposals_file_import_form.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +module Decidim + module Proposals + module Admin + # A form object to be used when admin users want to import proposals from + # a file. + class ProposalsFileImportForm < Decidim::Admin::ImportForm + attribute :user_group_id, Integer + + def user_groups + Decidim::UserGroups::ManageableUserGroups.for(current_user).verified + end + + protected + + def user_group + @user_group ||= Decidim::UserGroup.find_by( + organization: current_organization, + id: user_group_id.to_i + ) + end + + def importer_context + context[:user_group] = user_group + context + end + end + end + end +end diff --git a/decidim-proposals/app/forms/decidim/proposals/admin/proposals_fork_form.rb b/decidim-proposals/app/forms/decidim/proposals/admin/proposals_fork_form.rb index 7994156323c2d..7001dec134967 100644 --- a/decidim-proposals/app/forms/decidim/proposals/admin/proposals_fork_form.rb +++ b/decidim-proposals/app/forms/decidim/proposals/admin/proposals_fork_form.rb @@ -30,14 +30,19 @@ def same_component? private + def errors_set + @errors_set ||= Set[] + end + def mergeable_to_same_component return true unless same_component? - public_proposals = proposals.any? do |proposal| - !proposal.official? || proposal.votes.any? || proposal.endorsements.any? + proposals.each do |proposal| + errors_set << :not_official unless proposal.official? + errors_set << :supported if proposal.votes.any? || proposal.endorsements.any? end - errors.add(:proposal_ids, :invalid) if public_proposals + errors_set.each { |error| errors.add(:base, error) } if errors_set.any? end def same_participatory_space diff --git a/decidim-proposals/app/helpers/decidim/proposals/application_helper.rb b/decidim-proposals/app/helpers/decidim/proposals/application_helper.rb index ad190657dc39d..2278f0b08f3d3 100644 --- a/decidim-proposals/app/helpers/decidim/proposals/application_helper.rb +++ b/decidim-proposals/app/helpers/decidim/proposals/application_helper.rb @@ -102,7 +102,7 @@ def safe_content? # If the content is safe, HTML tags are sanitized, otherwise, they are stripped. def render_proposal_body(proposal) - render_sanitized_content(proposal, :body) + Decidim::ContentProcessor.render(render_sanitized_content(proposal, :body), "div") end # Returns :text_area or :editor based on the organization' settings. diff --git a/decidim-proposals/app/helpers/decidim/proposals/map_helper.rb b/decidim-proposals/app/helpers/decidim/proposals/map_helper.rb index 6639408f97262..2de60568d680c 100644 --- a/decidim-proposals/app/helpers/decidim/proposals/map_helper.rb +++ b/decidim-proposals/app/helpers/decidim/proposals/map_helper.rb @@ -19,7 +19,7 @@ def proposal_data_for_map(proposal) .slice(:latitude, :longitude, :address) .merge( title: decidim_html_escape(present(proposal).title), - body: html_truncate(decidim_sanitize(present(proposal).body), length: 100), + body: html_truncate(decidim_sanitize_editor(present(proposal).body), length: 100), icon: icon("proposals", width: 40, height: 70, remove_icon_class: true), link: proposal_path(proposal) ) diff --git a/decidim-proposals/app/helpers/decidim/proposals/proposals_helper.rb b/decidim-proposals/app/helpers/decidim/proposals/proposals_helper.rb index 87f738aa8390f..a97f7346a8b68 100644 --- a/decidim-proposals/app/helpers/decidim/proposals/proposals_helper.rb +++ b/decidim-proposals/app/helpers/decidim/proposals/proposals_helper.rb @@ -7,7 +7,7 @@ module ProposalsHelper def proposal_reason_callout_announcement { title: proposal_reason_callout_title, - body: decidim_sanitize(translated_attribute(@proposal.answer)) + body: decidim_sanitize_editor(translated_attribute(@proposal.answer)) } end diff --git a/decidim-proposals/app/jobs/decidim/proposals/notify_proposals_mentioned_job.rb b/decidim-proposals/app/jobs/decidim/proposals/notify_proposals_mentioned_job.rb index 9a22f108b83a8..1d39f67d5f774 100644 --- a/decidim-proposals/app/jobs/decidim/proposals/notify_proposals_mentioned_job.rb +++ b/decidim-proposals/app/jobs/decidim/proposals/notify_proposals_mentioned_job.rb @@ -8,7 +8,7 @@ def perform(comment_id, linked_proposals) linked_proposals.each do |proposal_id| proposal = Proposal.find(proposal_id) - affected_users = proposal.notifiable_identities + affected_users = proposal.notifiable_identities - [comment.author] Decidim::EventsManager.publish( event: "decidim.events.proposals.proposal_mentioned", diff --git a/decidim-proposals/app/models/decidim/proposals/proposal.rb b/decidim-proposals/app/models/decidim/proposals/proposal.rb index 1bdac3041e16c..e07f29d1322e8 100644 --- a/decidim-proposals/app/models/decidim/proposals/proposal.rb +++ b/decidim-proposals/app/models/decidim/proposals/proposal.rb @@ -70,12 +70,13 @@ class Proposal < Proposals::ApplicationRecord scope :except_drafts, -> { where.not(published_at: nil) } scope :published, -> { where.not(published_at: nil) } scope :order_by_most_recent, -> { order(created_at: :desc) } + scope :sort_by_valuation_assignments_count_asc, lambda { - order("#{sort_by_valuation_assignments_count_nulls_last_query}ASC NULLS FIRST") + order(Arel.sql("#{sort_by_valuation_assignments_count_nulls_last_query} ASC NULLS FIRST").to_s) } scope :sort_by_valuation_assignments_count_desc, lambda { - order("#{sort_by_valuation_assignments_count_nulls_last_query}DESC NULLS LAST") + order(Arel.sql("#{sort_by_valuation_assignments_count_nulls_last_query} DESC NULLS LAST").to_s) } def self.with_valuation_assigned_to(user, space) @@ -228,6 +229,12 @@ def reported_content_url ResourceLocatorPresenter.new(self).url end + # Returns the presenter for this author, to be used in the views. + # Required by ResourceRenderer. + def presenter + Decidim::Proposals::ProposalPresenter.new(self) + end + # Public: Overrides the `reported_attributes` Reportable concern method. def reported_attributes [:title, :body] diff --git a/decidim-proposals/app/permissions/decidim/proposals/admin/permissions.rb b/decidim-proposals/app/permissions/decidim/proposals/admin/permissions.rb index 0ea1f80d25b47..f64a1f14d109d 100644 --- a/decidim-proposals/app/permissions/decidim/proposals/admin/permissions.rb +++ b/decidim-proposals/app/permissions/decidim/proposals/admin/permissions.rb @@ -120,7 +120,10 @@ def can_create_proposal_note? # Proposals can only be created from the admin when the # corresponding setting is enabled. + # This setting is incompatible with participatory texts. def can_create_proposal_from_admin? + return disallow! if participatory_texts_are_enabled? && permission_action.subject == :proposal + toggle_allow(admin_creation_is_enabled?) if permission_action.subject == :proposal end diff --git a/decidim-proposals/app/queries/decidim/proposals/similar_proposals.rb b/decidim-proposals/app/queries/decidim/proposals/similar_proposals.rb index b487b6cbb6aa3..bc3c990c58e71 100644 --- a/decidim-proposals/app/queries/decidim/proposals/similar_proposals.rb +++ b/decidim-proposals/app/queries/decidim/proposals/similar_proposals.rb @@ -31,7 +31,7 @@ def query .published .not_hidden .where( - "GREATEST(#{title_similarity}, #{body_similarity}) >= ?", + Arel.sql("GREATEST(#{title_similarity}, #{body_similarity}) >= ?").to_s, *similarity_params, Decidim::Proposals.similarity_threshold ) diff --git a/decidim-proposals/app/services/decidim/proposals/proposal_search.rb b/decidim-proposals/app/services/decidim/proposals/proposal_search.rb index dc5d6ed22ade6..c48b13ddaeedf 100644 --- a/decidim-proposals/app/services/decidim/proposals/proposal_search.rb +++ b/decidim-proposals/app/services/decidim/proposals/proposal_search.rb @@ -12,8 +12,9 @@ class ProposalSearch < ResourceSearch # page - The page number to paginate the results. # per_page - The number of proposals to return per page. def initialize(options = {}) - base = options[:state]&.member?("withdrawn") ? Proposal.withdrawn : Proposal.except_withdrawn - super(base, options) + options[:scope] = options.fetch(:scope, Proposal) + options[:scope] = options[:state_withdraw] == "withdrawn" ? options[:scope].withdrawn : options[:scope].except_withdrawn + super(options[:scope], options) end # Handle the activity filter @@ -34,10 +35,14 @@ def search_activity end end + def search_state_withdraw + return query if state_withdraw == "withdrawn" + + query.except_withdrawn + end + # Handle the state filter def search_state - return query if state.member? "withdrawn" - apply_scopes(%w(accepted rejected evaluating state_not_published), state) end diff --git a/decidim-proposals/app/validators/proposal_length_validator.rb b/decidim-proposals/app/validators/proposal_length_validator.rb index 8214deae66e91..3c0feaece627e 100644 --- a/decidim-proposals/app/validators/proposal_length_validator.rb +++ b/decidim-proposals/app/validators/proposal_length_validator.rb @@ -5,11 +5,14 @@ # allows the minimum and maximum values to be lambdas allowing us to fetch the # maximum length dynamically for each proposals component. class ProposalLengthValidator < ActiveModel::EachValidator + include ActionView::Helpers::SanitizeHelper + def validate_each(record, attribute, value) return if value.blank? - validate_min_length(record, attribute, value) - validate_max_length(record, attribute, value) + text_value = strip_tags(value) + validate_min_length(record, attribute, text_value) + validate_max_length(record, attribute, text_value) end private diff --git a/decidim-proposals/app/views/decidim/proposals/admin/imports/_proposals_fields.html.erb b/decidim-proposals/app/views/decidim/proposals/admin/imports/_proposals_fields.html.erb new file mode 100644 index 0000000000000..1340623dc413d --- /dev/null +++ b/decidim-proposals/app/views/decidim/proposals/admin/imports/_proposals_fields.html.erb @@ -0,0 +1,11 @@ +<% if current_organization.user_groups_enabled? && form.object.user_groups.any? %> +
+ <%= form.select( + :user_group_id, + form.object.user_groups.map { |g| [g.name, g.id] }, + selected: form.object.user_group_id.presence, + include_blank: current_user.name, + label: true + ) %> +
+<% end %> diff --git a/decidim-proposals/app/views/decidim/proposals/admin/proposal_answers/_form.html.erb b/decidim-proposals/app/views/decidim/proposals/admin/proposal_answers/_form.html.erb index aafefa7f29025..279585ff412b6 100644 --- a/decidim-proposals/app/views/decidim/proposals/admin/proposal_answers/_form.html.erb +++ b/decidim-proposals/app/views/decidim/proposals/admin/proposal_answers/_form.html.erb @@ -6,7 +6,7 @@
- <%= f.collection_radio_buttons :internal_state, [["accepted", t(".accepted")], ["rejected", t(".rejected")], ["evaluating", t(".evaluating")]], :first, :last, prompt: true %> + <%= f.collection_radio_buttons :internal_state, [["not_answered", t(".not_answered")], ["accepted", t(".accepted")], ["rejected", t(".rejected")], ["evaluating", t(".evaluating")]], :first, :last, prompt: true %>
diff --git a/decidim-proposals/app/views/decidim/proposals/admin/proposals/_bulk-actions.html.erb b/decidim-proposals/app/views/decidim/proposals/admin/proposals/_bulk-actions.html.erb index 0c481beaab486..a8fac8d67b177 100644 --- a/decidim-proposals/app/views/decidim/proposals/admin/proposals/_bulk-actions.html.erb +++ b/decidim-proposals/app/views/decidim/proposals/admin/proposals/_bulk-actions.html.erb @@ -12,8 +12,13 @@ <% if allowed_to? :import, :proposals %> <%= import_dropdown do %> - <% content_tag :li do %> - <% link_to t("actions.import", scope: "decidim.proposals", name: t("models.proposal.name", scope: "decidim.proposals.admin")), new_proposals_import_path %> +
  • + <%= link_to t("actions.import", scope: "decidim.proposals", name: t("models.proposal.name", scope: "decidim.proposals.admin")), new_proposals_import_path %> +
  • + <% current_component.manifest.import_manifests.each do |import_manifest| %> +
  • + <%= link_to import_manifest.message(:label, self), admin_imports_path(current_component, name: import_manifest.name) %> +
  • <% end %> <% end %> <% end %> diff --git a/decidim-proposals/app/views/decidim/proposals/admin/proposals/_proposal-tr.html.erb b/decidim-proposals/app/views/decidim/proposals/admin/proposals/_proposal-tr.html.erb index c58629868095b..bd153f2faf79a 100644 --- a/decidim-proposals/app/views/decidim/proposals/admin/proposals/_proposal-tr.html.erb +++ b/decidim-proposals/app/views/decidim/proposals/admin/proposals/_proposal-tr.html.erb @@ -7,8 +7,8 @@
    <%= link_to( - decidim_html_escape(present(proposal).title).html_safe, - proposal_path(proposal) + present(proposal).title(html_escape: true), + proposal_path(proposal) ) %>
    diff --git a/decidim-proposals/app/views/decidim/proposals/collaborative_drafts/_edit_form_fields.html.erb b/decidim-proposals/app/views/decidim/proposals/collaborative_drafts/_edit_form_fields.html.erb index 97e1f8b114160..eca54e984f19e 100644 --- a/decidim-proposals/app/views/decidim/proposals/collaborative_drafts/_edit_form_fields.html.erb +++ b/decidim-proposals/app/views/decidim/proposals/collaborative_drafts/_edit_form_fields.html.erb @@ -61,7 +61,7 @@ <% end %> <% if component_settings.attachments_allowed? %> -
    +
    <%= t("attachment_legend", scope: "decidim.proposals.collaborative_drafts.edit") %> <%= form.fields_for :attachment, @form.attachment do |nested_form| %>
    diff --git a/decidim-proposals/app/views/decidim/proposals/collaborative_drafts/_filters_small_view.html.erb b/decidim-proposals/app/views/decidim/proposals/collaborative_drafts/_filters_small_view.html.erb index 07947e889cafb..68eaa97ecf370 100644 --- a/decidim-proposals/app/views/decidim/proposals/collaborative_drafts/_filters_small_view.html.erb +++ b/decidim-proposals/app/views/decidim/proposals/collaborative_drafts/_filters_small_view.html.erb @@ -1,13 +1,13 @@
    -
    -
    +
    -
    - <%= icon "pencil" %> - <%= icon "eye" %> - <%= icon "circle-x" %> + <%= icon "pencil" %> + <%= icon "eye" %> + <%= icon "circle-x" %>
    - <%= icon "pencil" %> - <%= icon "eye" %> + <%= icon "pencil" %> + <%= icon "eye" %>
    - <%= icon "pencil" %> - <%= icon "eye" %> + <%= icon "pencil" %> + <%= icon "eye" %>
    - <%= icon "pencil" %> - <%= icon "eye" %> + <%= icon "pencil" %> + <%= icon "eye" %>
    - <%= icon "pencil" %> - <%= icon "eye" %> - <%= icon "circle-x" %> + <%= icon "pencil" %> + <%= icon "eye" %> + <%= icon "circle-x" %>
    - <%= icon "pencil" %> - <%= icon "eye" %> - <%= icon "circle-x" %> + <%= icon "pencil" %> + <%= icon "eye" %> + <%= icon "circle-x" %>
    - <%= icon "pencil" %> - <%= icon "eye" %> - <%= icon "circle-x" %> + <%= icon "pencil" %> + <%= icon "eye" %> + <%= icon "circle-x" %>
    - <%= icon "pencil" %> - <%= icon "circle-x" %> + <%= icon "pencil" %> + <%= icon "circle-x" %>
    - <%= icon "pencil" %> - <%= icon "circle-x" %> + <%= icon "pencil" %> + <%= icon "circle-x" %>
    - <%= icon "pencil" %> - <%= icon "circle-x" %> + <%= icon "pencil" %> + <%= icon "circle-x" %>
    - <%= icon "pencil" %> - <%= icon "circle-x" %> + <%= icon "pencil" %> + <%= icon "circle-x" %>
    - <%= icon "pencil" %> - <%= icon "circle-x" %> + <%= icon "pencil" %> + <%= icon "circle-x" %>
    1 - <%= icon "action-undo" %> - <%= icon "eye" %> + <%= icon "action-undo" %> + <%= icon "eye" %>
    - <%= icon "pencil" %> - <%= icon "eye" %> - <%= icon "circle-x" %> + <%= icon "pencil" %> + <%= icon "eye" %> + <%= icon "circle-x" %>
    - <%= icon "pencil" %> - <%= icon "circle-x" %> + <%= icon "pencil" %> + <%= icon "circle-x" %>
    - + Fase 2: Recogida de propuestas @@ -57,8 +57,8 @@ 08/06/17 - <%= icon "pencil" %> - <%= icon "circle-x" %> + <%= icon "pencil" %> + <%= icon "circle-x" %>
    - <%= icon "pencil" %> - <%= icon "circle-x" %> + <%= icon "pencil" %> + <%= icon "circle-x" %>
    - <%= icon "star" %> + <%= icon "star" %> <%= link_to page_path("process-info") do %> Proposa, prioritza i decideix sobre el pressupost del districte de l’Eixample <% end %> @@ -35,8 +35,8 @@ Publicado - <%= icon "pencil" %> - <%= icon "eye" %> + <%= icon "pencil" %> + <%= icon "eye" %>
    - <%= icon "pencil" %> - <%= icon "eye" %> + <%= icon "pencil" %> + <%= icon "eye" %>
    - <%= icon "pencil" %> - <%= icon "eye" %> + <%= icon "pencil" %> + <%= icon "eye" %>
    - <%= icon "pencil" %> - <%= icon "eye" %> + <%= icon "pencil" %> + <%= icon "eye" %>
    <%= link_to page_path("scope-edit"), class: "action-icon", data: { :tooltip => true, :haspopup => true, :'disable-hover' => false }, title: "Editar" do %><%= icon "pencil" %><% end %> - <%= icon "circle-x" %> + <%= icon "circle-x" %>
    - <%= link_to page_path("scope-edit"), class: "action-icon", data: { :tooltip => true, :'aria-haspopup' => "true", :'disable-hover' => "false" }, title: "Editar" do %><%= icon "pencil" %><% end %> - <%= icon "circle-x" %>
    @@ -47,7 +47,7 @@ <%= link_to page_path("scope-edit"), class: "action-icon", data: { :tooltip => true, :haspopup => true, :'disable-hover' => false }, title: "Editar" do %><%= icon "pencil" %><% end %> - <%= icon "circle-x" %>
    diff --git a/decidim_app-design/app/views/admin/settings-scope-types.html.erb b/decidim_app-design/app/views/admin/settings-scope-types.html.erb index c9e166c42f0dc..70f74c953dc10 100644 --- a/decidim_app-design/app/views/admin/settings-scope-types.html.erb +++ b/decidim_app-design/app/views/admin/settings-scope-types.html.erb @@ -33,8 +33,8 @@ provincias
    - <%= icon "pencil" %> - <%= icon "circle-x" %>
    @@ -44,8 +44,8 @@ distritos - <%= icon "pencil" %> - <%= icon "circle-x" %>
    diff --git a/decidim_app-design/app/views/admin/settings-scopes.html.erb b/decidim_app-design/app/views/admin/settings-scopes.html.erb index 09260c20824ba..a66f53228c5ae 100644 --- a/decidim_app-design/app/views/admin/settings-scopes.html.erb +++ b/decidim_app-design/app/views/admin/settings-scopes.html.erb @@ -34,7 +34,7 @@
    <%= link_to page_path("scope-edit"), class: "action-icon", data: { :tooltip => true, :haspopup => true, :'disable-hover' => false }, title: "Editar" do %><%= icon "pencil" %><% end %> - <%= icon "circle-x" %>
    @@ -45,7 +45,7 @@ <%= link_to page_path("scope-edit"), class: "action-icon", data: { :tooltip => true, :haspopup => true, :'disable-hover' => false }, title: "Editar" do %><%= icon "pencil" %><% end %> - <%= icon "circle-x" %>
    @@ -56,7 +56,7 @@ <%= link_to page_path("scope-edit"), class: "action-icon", data: { :tooltip => true, :haspopup => true, :'disable-hover' => false }, title: "Editar" do %><%= icon "pencil" %><% end %> - <%= icon "circle-x" %>
    @@ -67,7 +67,7 @@ <%= link_to page_path("scope-edit"), class: "action-icon", data: { :tooltip => true, :haspopup => true, :'disable-hover' => false }, title: "Editar" do %><%= icon "pencil" %><% end %> - <%= icon "circle-x" %>
    diff --git a/decidim_app-design/app/views/admin/users.html.erb b/decidim_app-design/app/views/admin/users.html.erb index 658bc084eccab..c2daf88c93326 100644 --- a/decidim_app-design/app/views/admin/users.html.erb +++ b/decidim_app-design/app/views/admin/users.html.erb @@ -37,7 +37,7 @@ 12/01/17
    - <%= icon "circle-x" %> + <%= icon "circle-x" %>