diff --git a/.codeclimate.yml b/.codeclimate.yml index 1e5b76981c..65826a4e12 100644 --- a/.codeclimate.yml +++ b/.codeclimate.yml @@ -55,4 +55,11 @@ exclude_paths: - "decidim-dataviz/app/packs/src/vendor/**/*" - "packages/eslint-config/index.js" - "packages/webpacker/src/override-config.js" +- "packages/webpacker/src/loaders/decidim-sass-loader.js" - "app/assets/stylesheets/decidim/email.css" +- "app/views/static/api/docs/assets/style.css" +- "config/initializers/origami_date.rb" +- "config/initializers/decidim.rb" +- "decidim-ephemeral_participation/app/permissions/decidim/ephemeral_participation/ephemeral_participation_permissions.rb" +- "app/services/decidim_legacy_routes.rb" +- "app/helpers/concerns/decidim/paginate_helper_override.rb" diff --git a/.csslintrc b/.csslintrc new file mode 100644 index 0000000000..aacba956e5 --- /dev/null +++ b/.csslintrc @@ -0,0 +1,2 @@ +--exclude-exts=.min.css +--ignore=adjoining-classes,box-model,ids,order-alphabetical,unqualified-attributes diff --git a/.erb-lint.yml b/.erb-lint.yml new file mode 100644 index 0000000000..3321adde4e --- /dev/null +++ b/.erb-lint.yml @@ -0,0 +1,30 @@ +--- + +linters: + ExtraNewline: + enabled: true + + FinalNewline: + enabled: true + + SpaceAroundErbTag: + enabled: true + + AllowedScriptType: + enabled: true + allowed_types: + - text/javascript + - text/template + + Rubocop: + enabled: true + + rubocop_config: + AllCops: + DisabledByDefault: true + + Style/StringLiterals: + EnforcedStyle: double_quotes + + Layout/SpaceInsideHashLiteralBraces: + Enabled: true diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000000..8b2cdbe92b --- /dev/null +++ b/.eslintignore @@ -0,0 +1,13 @@ +**/*{.,-}min.js +decidim-*/vendor/**/*.js +**/node_modules/** +bundle.js +karma.conf.js +webpack.config.js +webpack.config.babel.js +entry.test.js +entry.js +*_manifest.js +coverage +vendor/bundle +**/vendor/**/*.js diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000000..08de8c7f32 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "@decidim" +} diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 6b903f8bd6..ac04d6d69c 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,31 +1,12 @@ - +#### :tophat: User Story -# This is a (Bug Report / Feature Proposal) -#### :tophat: Description +#### :clipboard: Related documentation -For bug reports: -* What went wrong? -* What did you expect should have happened? -* What was the config you used? -* What stacktrace or error message from your provider did you see? -For feature proposals: -* What is the use case that should be solved. The more detail you describe this in the easier it is to understand for us. -* If there is additional config how would it look +#### :dart: Acceptance criteria + #### :pushpin: Related issues -* #12345 -#### :clipboard: Additional Data -* ***Decidim deployment where you found the issue***: -* ***Browser & version***: -* ***Screenshot***: -* ***Error messages***: -* ***URL to reproduce the error***: diff --git a/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md similarity index 100% rename from PULL_REQUEST_TEMPLATE.md rename to .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000000..3608c94c9d --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,39 @@ +name: Lint +on: [push] + +env: + RUBY_VERSION: 3.1.1 + NODE_VERSION: 18.17.1 + +jobs: + lint: + name: Lint code + runs-on: ubuntu:22.04 + env: + DATABASE_USERNAME: postgres + DATABASE_PASSWORD: postgres + DATABASE_HOST: localhost + RAILS_ENV: test + steps: + - 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@master + with: + node-version: ${{ env.NODE_VERSION }} + - run: npm ci + name: Install JS deps + - run: bundle exec rubocop -P + name: Lint Ruby files + - run: bundle exec mdl *.md + name: Lint Markdown files + - run: bundle exec erblint {decidim-census_sms/,decidim-dataviz/,decidim-ephemeral_participation/,decidim-stats/,decidim-valid_auth/}app/{cells,views}/**/*.erb + name: Lint ERB files + - run: npm run stylelint + name: Lint SCSS files + - run: npm run lint + name: Lint JS files diff --git a/.github/workflows/decidim_ci.yml b/.github/workflows/test.yml similarity index 80% rename from .github/workflows/decidim_ci.yml rename to .github/workflows/test.yml index 1d40151b81..7a216af1a4 100644 --- a/.github/workflows/decidim_ci.yml +++ b/.github/workflows/test.yml @@ -1,14 +1,14 @@ -name: "[CI] Decidim" +name: Test on: [push] env: - RUBY_VERSION: 2.7.5 - NODE_VERSION: 16.9.1 + RUBY_VERSION: 3.1.1 + NODE_VERSION: 18.17.1 jobs: - tests: - name: Tests - runs-on: ubuntu-latest + test: + name: Test + runs-on: ubuntu:22.04 services: postgres: image: postgres:11 @@ -36,13 +36,14 @@ jobs: with: ruby-version: ${{ env.RUBY_VERSION }} bundler-cache: true - - run: bundle exec rubocop -P - name: Lint Ruby files + - uses: nanasess/setup-chromedriver@v2 - run: bundle exec rake db:test:prepare name: Setup database - name: Precompile assets run: | npm install bundle exec rake assets:precompile - - run: bundle exec rspec + - run: | + mkdir node_modules + bundle exec rspec name: Run specs diff --git a/.github/workflows/test_census_sms.yml b/.github/workflows/test_census_sms.yml new file mode 100644 index 0000000000..3156d4f79b --- /dev/null +++ b/.github/workflows/test_census_sms.yml @@ -0,0 +1,49 @@ +name: Test Census SMS +on: [push] + +env: + RUBY_VERSION: 3.1.1 + NODE_VERSION: 18.17.1 + +jobs: + test: + name: Test Census SMS + runs-on: ubuntu:22-04 + 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 + redis: + image: redis:3.2-alpine + ports: ["6379:6379"] + env: + DATABASE_USERNAME: postgres + DATABASE_PASSWORD: postgres + DATABASE_HOST: localhost + RAILS_ENV: test + steps: + - 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: nanasess/setup-chromedriver@v2 + - run: bundle exec rake db:test:prepare + name: Setup database + - name: Precompile assets + run: | + npm install + bundle exec rake assets:precompile + - run: | + mkdir node_modules + bundle exec rspec decidim-census_sms + name: Run specs diff --git a/.github/workflows/test_stats.yml b/.github/workflows/test_stats.yml new file mode 100644 index 0000000000..fe33e7c72d --- /dev/null +++ b/.github/workflows/test_stats.yml @@ -0,0 +1,49 @@ +name: Test Stats +on: [push] + +env: + RUBY_VERSION: 3.1.1 + NODE_VERSION: 18.17.1 + +jobs: + test: + name: Test Stats + runs-on: ubuntu:22.04 + 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 + redis: + image: redis:3.2-alpine + ports: ["6379:6379"] + env: + DATABASE_USERNAME: postgres + DATABASE_PASSWORD: postgres + DATABASE_HOST: localhost + RAILS_ENV: test + steps: + - 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: nanasess/setup-chromedriver@v2 + - run: bundle exec rake db:test:prepare + name: Setup database + - name: Precompile assets + run: | + npm install + bundle exec rake assets:precompile + - run: | + mkdir node_modules + bundle exec rspec decidim-stats + name: Run specs diff --git a/.github/workflows/test_valid_auth.yml b/.github/workflows/test_valid_auth.yml new file mode 100644 index 0000000000..b471870701 --- /dev/null +++ b/.github/workflows/test_valid_auth.yml @@ -0,0 +1,49 @@ +name: Test Valid Auth +on: [push] + +env: + RUBY_VERSION: 3.1.1 + NODE_VERSION: 18.17.1 + +jobs: + test: + name: Test Valid Auth + runs-on: ubuntu:22-04 + 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 + redis: + image: redis:3.2-alpine + ports: ["6379:6379"] + env: + DATABASE_USERNAME: postgres + DATABASE_PASSWORD: postgres + DATABASE_HOST: localhost + RAILS_ENV: test + steps: + - 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: nanasess/setup-chromedriver@v2 + - run: bundle exec rake db:test:prepare + name: Setup database + - name: Precompile assets + run: | + npm install + bundle exec rake assets:precompile + - run: | + mkdir node_modules + bundle exec rspec decidim-valid_auth + name: Run specs diff --git a/.gitignore b/.gitignore index ff28a0f51b..c52db995e7 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,10 @@ node_modules yarn-debug.log* .yarn-integrity .rbenv-vars + +public/sw.js* + +coverage/ + +.nvmrc +tailwind.config.js diff --git a/.mdl_style.rb b/.mdl_style.rb new file mode 100644 index 0000000000..5f530cc7fe --- /dev/null +++ b/.mdl_style.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +all + +exclude_rule "first-line-h1" + +exclude_rule "line-length" + +exclude_rule "no-bare-urls" + +exclude_rule "no-inline-html" + +rule "no-trailing-punctuation", punctuation: ".,;:!" diff --git a/.mdlrc b/.mdlrc new file mode 100644 index 0000000000..27f388245f --- /dev/null +++ b/.mdlrc @@ -0,0 +1 @@ +style ".mdl_style.rb" diff --git a/.node-version b/.node-version new file mode 100644 index 0000000000..4a1f488b6c --- /dev/null +++ b/.node-version @@ -0,0 +1 @@ +18.17.1 diff --git a/.rubocop.yml b/.rubocop.yml index 870c0b9fff..c80dd735d8 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,3 +1,26 @@ -inherit_from: - - .rubocop_ruby.yml - - .rubocop_rails.yml +inherit_from: .rubocop_todo.yml + +inherit_gem: + decidim-dev: rubocop-decidim.yml + +inherit_mode: + merge: + - Exclude + +AllCops: + Include: + - "**/*.rb" + - "**/*.rake" + - "**/*.ru" + - "**/Gemfile" + - "**/Rakefile" + Exclude: + - "spec/decidim_dummy_app/**/*" + - "**/spec/decidim_dummy_app/**/*" + - "bin/**/*" + - "node_modules/**/*" + - "**/node_modules/**/*" + - "db/schema.rb" + - "db/migrate/*" + - "vendor/**/*" + - "**/vendor/**/*" diff --git a/.rubocop_rails.yml b/.rubocop_rails.yml deleted file mode 100644 index 0cf3b441c1..0000000000 --- a/.rubocop_rails.yml +++ /dev/null @@ -1,87 +0,0 @@ -require: rubocop-rails - -Rails: - Enabled: true - -Rails/ActionFilter: - Include: - - app/controllers/**/*.rb - -Rails/ContentTag: - Enabled: false - -Rails/CreateTableWithTimestamps: - Enabled: false - -Rails/EnumUniqueness: - Include: - - app/models/**/*.rb - -Rails/Exit: - Include: - - app/**/*.rb - - config/**/*.rb - - lib/**/*.rb - Exclude: - - lib/**/*.rake - -Rails/FindBy: - Include: - - "**/*.rb" - -Rails/FindEach: - Include: - - app/models/**/*.rb - -Rails/HasAndBelongsToMany: - Include: - - app/models/**/*.rb - -Rails/HasManyOrHasOneDependent: - Include: - - app/models/**/*.rb - -Rails/InverseOf: - Enabled: false - -Rails/LexicallyScopedActionFilter: - Include: - - app/controllers/**/*.rb - -Rails/NotNullColumn: - Enabled: false - -Rails/Output: - Include: - - app/**/*.rb - - config/**/*.rb - - db/**/*.rb - - lib/**/*.rb - Exclude: - - db/seeds.rb -Rails/OutputSafety: - Enabled: false - -Rails/Pluck: - Enabled: false - -Rails/RakeEnvironment: - Enabled: false - -Rails/ReadWriteAttribute: - Include: - - app/models/**/*.rb - -Rails/ReversibleMigration: - Enabled: false - -Rails/ScopeArgs: - Include: - - app/models/**/*.rb - -Rails/SkipsModelValidations: - Enabled: true - -Rails/Validation: - Include: - - app/models/**/*.rb diff --git a/.rubocop_ruby.yml b/.rubocop_ruby.yml deleted file mode 100644 index f8d98c6a7d..0000000000 --- a/.rubocop_ruby.yml +++ /dev/null @@ -1,1756 +0,0 @@ -require: - - rubocop-rspec - - rubocop-faker - -# Common configuration. -AllCops: - Include: - - .simplecov - - "**/*.rb" - - "**/*.rake" - - "**/*.gemspec" - - "**/*.ru" - - "**/Gemfile" - - "**/Rakefile" - Exclude: - - "**/vendor/**/*" - - "development_app/**/*" - - "spec/decidim_dummy_app/**/*" - - "node_modules/**/*" - - "db/migrate/*" - - "db/schema.rb" - # Default formatter will be used if no -f/--format option is given. - DefaultFormatter: progress - # Cop names are not displayed in offense messages by default. Change behavior - # by overriding DisplayCopNames, or by giving the -D/--display-cop-names - # option. - DisplayCopNames: true - # Style guide URLs are not displayed in offense messages by default. Change - # behavior by overriding DisplayStyleGuide, or by giving the - # -S/--display-style-guide option. - DisplayStyleGuide: false - # Extra details are not displayed in offense messages by default. Change - # behavior by overriding ExtraDetails, or by giving the - # -E/--extra-details option. - ExtraDetails: false - NewCops: enable - # Additional cops that do not reference a style guide rule may be enabled by - # default. Change behavior by overriding StyleGuideCopsOnly, or by giving - # the --only-guide-cops option. - StyleGuideCopsOnly: false - # All cops except the ones in disabled.yml are enabled by default. Change - # this behavior by overriding DisabledByDefault. When DisabledByDefault is - # true, all cops in the default configuration are disabled, and and only cops - # in user configuration are enabled. This makes cops opt-in instead of - # opt-out. Note that when DisabledByDefault is true, cops in user - # configuration will be enabled even if they don't set the Enabled parameter. - DisabledByDefault: false - # Enables the result cache if true. Can be overridden by the --cache command - # line option. - UseCache: true - # Threshold for how many files can be stored in the result cache before some - # of the files are automatically removed. - MaxFilesInCache: 20000 - # The cache will be stored in "rubocop_cache" under this directory. The name - # "/tmp" is special and will be converted to the system temporary directory, - # which is "/tmp" on Unix-like systems, but could be something else on other - # systems. - CacheRootDirectory: /tmp - # The default cache root directory is /tmp, which on most systems is - # writable by any system user. This means that it is possible for a - # malicious user to anticipate the location of Rubocop's cache directory, - # and create a symlink in its place that could cause Rubocop to overwrite - # unintended files, or read malicious input. If you are certain that your - # cache location is secure from this kind of attack, and wish to use a - # symlinked cache location, set this value to "true". - AllowSymlinksInCacheRootDirectory: true - # What MRI version of the Ruby interpreter is the inspected code intended to - # run on? (If there is more than one, set this to the lowest version.) - # If a value is specified for TargetRubyVersion then it is used. - # Else if .ruby-version exists and it contains an MRI version it is used. - # Otherwise we fallback to the oldest officially supported Ruby version (2.0). - TargetRubyVersion: 2.7 - - RSpec: - Patterns: - - "(?:^|/)spec/" - - "(?:^|/)test/" - -# Indent private/protected/public as deep as method definitions -Layout/AccessModifierIndentation: - EnforcedStyle: indent - SupportedStyles: - - outdent - - indent - # By default, the indentation width from Style/IndentationWidth is used - # But it can be overridden by setting this parameter - IndentationWidth: ~ - -Style/Alias: - EnforcedStyle: prefer_alias - SupportedStyles: - - prefer_alias - - prefer_alias_method - -# Align the elements of a hash literal if they span more than one line. -Layout/HashAlignment: - # Alignment of entries using hash rocket as separator. Valid values are: - # - # key - left alignment of keys - # "a" => 2 - # "bb" => 3 - # separator - alignment of hash rockets, keys are right aligned - # "a" => 2 - # "bb" => 3 - # table - left alignment of keys, hash rockets, and values - # "a" => 2 - # "bb" => 3 - EnforcedHashRocketStyle: key - # Alignment of entries using colon as separator. Valid values are: - # - # key - left alignment of keys - # a: 0 - # bb: 1 - # separator - alignment of colons, keys are right aligned - # a: 0 - # bb: 1 - # table - left alignment of keys and values - # a: 0 - # bb: 1 - EnforcedColonStyle: key - # Select whether hashes that are the last argument in a method call should be - # inspected? Valid values are: - # - # always_inspect - Inspect both implicit and explicit hashes. - # Registers an offense for: - # function(a: 1, - # b: 2) - # Registers an offense for: - # function({a: 1, - # b: 2}) - # always_ignore - Ignore both implicit and explicit hashes. - # Accepts: - # function(a: 1, - # b: 2) - # Accepts: - # function({a: 1, - # b: 2}) - # ignore_implicit - Ignore only implicit hashes. - # Accepts: - # function(a: 1, - # b: 2) - # Registers an offense for: - # function({a: 1, - # b: 2}) - # ignore_explicit - Ignore only explicit hashes. - # Accepts: - # function({a: 1, - # b: 2}) - # Registers an offense for: - # function(a: 1, - # b: 2) - EnforcedLastArgumentHashStyle: always_inspect - SupportedLastArgumentHashStyles: - - always_inspect - - always_ignore - - ignore_implicit - - ignore_explicit - -Layout/ParameterAlignment: - # Alignment of parameters in multi-line method calls. - # - # The `with_first_parameter` style aligns the following lines along the same - # column as the first parameter. - # - # method_call(a, - # b) - # - # The `with_fixed_indentation` style aligns the following lines with one - # level of indentation relative to the start of the line with the method call. - # - # method_call(a, - # b) - EnforcedStyle: with_first_parameter - SupportedStyles: - - with_first_parameter - - with_fixed_indentation - # By default, the indentation width from Style/IndentationWidth is used - # But it can be overridden by setting this parameter - IndentationWidth: ~ - -Style/AndOr: - # Whether `and` and `or` are banned only in conditionals (conditionals) - # or completely (always). - EnforcedStyle: always - SupportedStyles: - - always - - conditionals - -Style/AsciiComments: - Enabled: false - -# Checks if usage of %() or %Q() matches configuration. -Style/BarePercentLiterals: - EnforcedStyle: bare_percent - SupportedStyles: - - percent_q - - bare_percent - -Style/BlockDelimiters: - EnforcedStyle: line_count_based - SupportedStyles: - # The `line_count_based` style enforces braces around single line blocks and - # do..end around multi-line blocks. - - line_count_based - # The `semantic` style enforces braces around functional blocks, where the - # primary purpose of the block is to return a value and do..end for - # procedural blocks, where the primary purpose of the block is its - # side-effects. - # - # This looks at the usage of a block's method to determine its type (e.g. is - # the result of a `map` assigned to a variable or passed to another - # method) but exceptions are permitted in the `ProceduralMethods`, - # `FunctionalMethods` and `IgnoredMethods` sections below. - - semantic - # The `braces_for_chaining` style enforces braces around single line blocks - # and do..end around multi-line blocks, except for multi-line blocks whose - # return value is being chained with another method (in which case braces - # are enforced). - - braces_for_chaining - ProceduralMethods: - # Methods that are known to be procedural in nature but look functional from - # their usage, e.g. - # - # time = Benchmark.realtime do - # foo.bar - # end - # - # Here, the return value of the block is discarded but the return value of - # `Benchmark.realtime` is used. - - benchmark - - bm - - bmbm - - create - - each_with_object - - measure - - new - - realtime - - tap - - with_object - FunctionalMethods: - # Methods that are known to be functional in nature but look procedural from - # their usage, e.g. - # - # let(:foo) { Foo.new } - # - # Here, the return value of `Foo.new` is used to define a `foo` helper but - # doesn't appear to be used from the return value of `let`. - - let - - let! - - subject - - watch - IgnoredMethods: - # Methods that can be either procedural or functional and cannot be - # categorised from their usage alone, e.g. - # - # foo = lambda do |x| - # puts "Hello, #{x}" - # end - # - # foo = lambda do |x| - # x * 100 - # end - # - # Here, it is impossible to tell from the return value of `lambda` whether - # the inner block's return value is significant. - - lambda - - proc - - it - -Style/ExplicitBlockArgument: - Enabled: false - -Style/HashEachMethods: - Enabled: false - -Style/HashLikeCase: - MinBranchesCount: 5 - -# Indentation of `when`. -Layout/CaseIndentation: - EnforcedStyle: case - SupportedStyles: - - case - - end - IndentOneStep: false - # By default, the indentation width from Style/IndentationWidth is used - # But it can be overridden by setting this parameter - # This only matters if IndentOneStep is true - IndentationWidth: ~ - -Style/ClassAndModuleChildren: - Enabled: false - # Checks the style of children definitions at classes and modules. - # - # Basically there are two different styles: - # - # `nested` - have each child on a separate line - # class Foo - # class Bar - # end - # end - # - # `compact` - combine definitions as much as possible - # class Foo::Bar - # end - # - # The compact style is only forced, for classes / modules with one child. - EnforcedStyle: nested - SupportedStyles: - - nested - - compact - -Style/ClassCheck: - EnforcedStyle: is_a? - SupportedStyles: - - is_a? - - kind_of? - -# Align with the style guide. -Style/CollectionMethods: - # Mapping from undesired method to desired_method - # e.g. to use `detect` over `find`: - # - # CollectionMethods: - # PreferredMethods: - # find: detect - PreferredMethods: - collect: "map" - collect!: "map!" - inject: "reduce" - detect: "find" - find_all: "select" - -# Use ` or %x around command literals. -Style/CommandLiteral: - EnforcedStyle: backticks - # backticks: Always use backticks. - # percent_x: Always use %x. - # mixed: Use backticks on single-line commands, and %x on multi-line commands. - SupportedStyles: - - backticks - - percent_x - - mixed - # If false, the cop will always recommend using %x if one or more backticks - # are found in the command string. - AllowInnerBackticks: false - -# Checks formatting of special comments -Style/CommentAnnotation: - Keywords: - - TODO - - FIXME - - OPTIMIZE - - HACK - - REVIEW - -Style/ConditionalAssignment: - EnforcedStyle: assign_to_condition - SupportedStyles: - - assign_to_condition - - assign_inside_condition - # When configured to `assign_to_condition`, `SingleLineConditionsOnly` - # will only register an offense when all branches of a condition are - # a single line. - # When configured to `assign_inside_condition`, `SingleLineConditionsOnly` - # will only register an offense for assignment to a condition that has - # at least one multiline branch. - SingleLineConditionsOnly: true - -# Checks that you have put a copyright in a comment before any code. -# -# You can override the default Notice in your .rubocop.yml file. -# -# In order to use autocorrect, you must supply a value for the -# AutocorrectNotice key that matches the regexp Notice. A blank -# AutocorrectNotice will cause an error during autocorrect. -# -# Autocorrect will add a copyright notice in a comment at the top -# of the file immediately after any shebang or encoding comments. -# -# Example rubocop.yml: -# -# Style/Copyright: -# Enabled: true -# Notice: 'Copyright (\(c\) )?2015 Yahoo! Inc' -# AutocorrectNotice: "# Copyright (c) 2015 Yahoo! Inc." -# -Style/Copyright: - Notice: '^Copyright (\(c\) )?2[0-9]{3} .+' - AutocorrectNotice: "" - -Style/DocumentationMethod: - RequireForNonPublicMethods: false - -# Multi-line method chaining should be done with leading dots. -Layout/DotPosition: - EnforcedStyle: leading - SupportedStyles: - - leading - - trailing - -# Warn on empty else statements -# empty - warn only on empty else -# nil - warn on else with nil in it -# both - warn on empty else and else with nil in it -Style/EmptyElse: - EnforcedStyle: both - SupportedStyles: - - empty - - nil - - both - -# Use empty lines between defs. -Layout/EmptyLineBetweenDefs: - # If true, this parameter means that single line method definitions don't - # need an empty line between them. - AllowAdjacentOneLineDefs: false - -Layout/EmptyLinesAroundBlockBody: - EnforcedStyle: no_empty_lines - SupportedStyles: - - empty_lines - - no_empty_lines - -Layout/EmptyLinesAroundClassBody: - EnforcedStyle: no_empty_lines - SupportedStyles: - - empty_lines - - no_empty_lines - -Layout/EmptyLinesAroundModuleBody: - EnforcedStyle: no_empty_lines - SupportedStyles: - - empty_lines - - no_empty_lines - -# Checks whether the source file has a utf-8 encoding comment or not -# AutoCorrectEncodingComment must match the regex -# /#.*coding\s?[:=]\s?(?:UTF|utf)-8/ -Style/Encoding: - Enabled: true - -Layout/ExtraSpacing: - # When true, allows most uses of extra spacing if the intent is to align - # things with the previous or next line, not counting empty lines or comment - # lines. - AllowForAlignment: false - # When true, forces the alignment of = in assignments on consecutive lines. - ForceEqualSignAlignment: false - -Naming/FileName: - Exclude: - - "**/Gemfile" - - "**/Rakefile" - - "**/*.gemspec" - # When true, requires that each source file should define a class or module - # with a name which matches the file name (converted to ... case). - # It further expects it to be nested inside modules which match the names - # of subdirectories in its path. - ExpectMatchingDefinition: false - # If non-nil, expect all source file names to match the following regex. - # Only the file name itself is matched, not the entire file path. - # Use anchors as necessary if you want to match the entire name rather than - # just a part of it. - Regex: ~ - # With `IgnoreExecutableScripts` set to `true`, this cop does not - # report offending filenames for executable scripts (i.e. source - # files with a shebang in the first line). - IgnoreExecutableScripts: true - -Layout/FirstArgumentIndentation: - EnforcedStyle: special_for_inner_method_call_in_parentheses - SupportedStyles: - # The first parameter should always be indented one step more than the - # preceding line. - - consistent - # The first parameter should normally be indented one step more than the - # preceding line, but if it's a parameter for a method call that is itself - # a parameter in a method call, then the inner parameter should be indented - # relative to the inner method. - - special_for_inner_method_call - # Same as special_for_inner_method_call except that the special rule only - # applies if the outer method call encloses its arguments in parentheses. - - special_for_inner_method_call_in_parentheses - # By default, the indentation width from Style/IndentationWidth is used - # But it can be overridden by setting this parameter - IndentationWidth: ~ - -# Checks use of for or each in multiline loops. -Style/For: - EnforcedStyle: each - SupportedStyles: - - for - - each - -# Enforce the method used for string formatting. -Style/FormatString: - EnforcedStyle: format - SupportedStyles: - - format - - sprintf - - percent - -Style/FormatStringToken: - EnforcedStyle: template - -Style/FrozenStringLiteralComment: - EnforcedStyle: always - SupportedStyles: - - never - # `always` will always add the frozen string literal comment to a file - # regardless of the Ruby version or if `freeze` or `<<` are called on a - # string literal. If you run code against multiple versions of Ruby, it is - # possible that this will create errors in Ruby 2.3.0+. - - always - -# Built-in global variables are allowed by default. -Style/GlobalVars: - AllowedVariables: [] - -# `MinBodyLength` defines the number of lines of the a body of an if / unless -# needs to have to trigger this cop -Style/GuardClause: - MinBodyLength: 6 - -Style/HashSyntax: - EnforcedStyle: ruby19 - SupportedStyles: - # checks for 1.9 syntax (e.g. {a: 1}) for all symbol keys - - ruby19 - # checks for hash rocket syntax for all hashes - - hash_rockets - # forbids mixed key syntaxes (e.g. {a: 1, :b => 2}) - - no_mixed_keys - # enforces both ruby19 and no_mixed_keys styles - - ruby19_no_mixed_keys - # Force hashes that have a symbol value to use hash rockets - UseHashRocketsWithSymbolValues: false - # Do not suggest { a?: 1 } over { :a? => 1 } in ruby19 style - PreferHashRocketsForNonAlnumEndingSymbols: false - -Layout/IndentationConsistency: - # The difference between `rails` and `normal` is that the `rails` style - # prescribes that in classes and modules the `protected` and `private` - # modifier keywords shall be indented the same as public methods and that - # protected and private members shall be indented one step more than the - # modifiers. Other than that, both styles mean that entities on the same - # logical depth shall have the same indentation. - EnforcedStyle: normal - SupportedStyles: - - normal - - rails - -Layout/IndentationWidth: - # Number of spaces for each indentation level. - Width: 2 - -# Checks the indentation of the first element in an array literal. -Layout/FirstArrayElementIndentation: - # The value `special_inside_parentheses` means that array literals with - # brackets that have their opening bracket on the same line as a surrounding - # opening round parenthesis, shall have their first element indented relative - # to the first position inside the parenthesis. - # - # The value `consistent` means that the indentation of the first element shall - # always be relative to the first position of the line where the opening - # bracket is. - # - # The value `align_brackets` means that the indentation of the first element - # shall always be relative to the position of the opening bracket. - EnforcedStyle: special_inside_parentheses - SupportedStyles: - - special_inside_parentheses - - consistent - - align_brackets - # By default, the indentation width from Style/IndentationWidth is used - # But it can be overridden by setting this parameter - IndentationWidth: ~ - -# Checks the indentation of assignment RHS, when on a different line from LHS -Layout/AssignmentIndentation: - # By default, the indentation width from Style/IndentationWidth is used - # But it can be overridden by setting this parameter - IndentationWidth: ~ - -# Checks the indentation of the first key in a hash literal. -Layout/FirstHashElementIndentation: - # The value `special_inside_parentheses` means that hash literals with braces - # that have their opening brace on the same line as a surrounding opening - # round parenthesis, shall have their first key indented relative to the - # first position inside the parenthesis. - # - # The value `consistent` means that the indentation of the first key shall - # always be relative to the first position of the line where the opening - # brace is. - # - # The value `align_braces` means that the indentation of the first key shall - # always be relative to the position of the opening brace. - EnforcedStyle: special_inside_parentheses - SupportedStyles: - - special_inside_parentheses - - consistent - - align_braces - # By default, the indentation width from Style/IndentationWidth is used - # But it can be overridden by setting this parameter - IndentationWidth: ~ - -Style/Lambda: - EnforcedStyle: line_count_dependent - SupportedStyles: - - line_count_dependent - - lambda - - literal - Exclude: - - "**/types/**/*" - - "**/*_interface.rb" - -Style/LambdaCall: - EnforcedStyle: call - SupportedStyles: - - call - - braces - -Style/Next: - # With `always` all conditions at the end of an iteration needs to be - # replaced by next - with `skip_modifier_ifs` the modifier if like this one - # are ignored: [1, 2].each { |a| return "yes" if a == 1 } - EnforcedStyle: skip_modifier_ifs - # `MinBodyLength` defines the number of lines of the a body of an if / unless - # needs to have to trigger this cop - MinBodyLength: 3 - SupportedStyles: - - skip_modifier_ifs - - always - -Style/NonNilCheck: - # With `IncludeSemanticChanges` set to `true`, this cop reports offenses for - # `!x.nil?` and autocorrects that and `x != nil` to solely `x`, which is - # **usually** OK, but might change behavior. - # - # With `IncludeSemanticChanges` set to `false`, this cop does not report - # offenses for `!x.nil?` and does no changes that might change behavior. - IncludeSemanticChanges: false - -Style/NumericPredicate: - EnforcedStyle: predicate - SupportedStyles: - - predicate - - comparison - -Style/MethodDefParentheses: - EnforcedStyle: require_parentheses - SupportedStyles: - - require_parentheses - - require_no_parentheses - - require_no_parentheses_except_multiline - -Naming/MethodName: - EnforcedStyle: snake_case - SupportedStyles: - - snake_case - - camelCase - -Style/ModuleFunction: - EnforcedStyle: module_function - SupportedStyles: - - module_function - - extend_self - -Layout/MultilineArrayBraceLayout: - EnforcedStyle: symmetrical - SupportedStyles: - # symmetrical: closing brace is positioned in same way as opening brace - # new_line: closing brace is always on a new line - # same_line: closing brace is always on the same line as last element - - symmetrical - - new_line - - same_line - -Layout/MultilineAssignmentLayout: - # The types of assignments which are subject to this rule. - SupportedTypes: - - block - - case - - class - - if - - kwbegin - - module - EnforcedStyle: new_line - SupportedStyles: - # Ensures that the assignment operator and the rhs are on the same line for - # the set of supported types. - - same_line - # Ensures that the assignment operator and the rhs are on separate lines - # for the set of supported types. - - new_line - -Layout/MultilineHashBraceLayout: - EnforcedStyle: symmetrical - SupportedStyles: - # symmetrical: closing brace is positioned in same way as opening brace - # new_line: closing brace is always on a new line - # same_line: closing brace is always on same line as last element - - symmetrical - - new_line - - same_line - -Layout/MultilineMethodCallBraceLayout: - EnforcedStyle: symmetrical - SupportedStyles: - # symmetrical: closing brace is positioned in same way as opening brace - # new_line: closing brace is always on a new line - # same_line: closing brace is always on the same line as last argument - - symmetrical - - new_line - - same_line - -Layout/MultilineMethodCallIndentation: - EnforcedStyle: aligned - SupportedStyles: - - aligned - - indented - - indented_relative_to_receiver - # By default, the indentation width from Style/IndentationWidth is used - # But it can be overridden by setting this parameter - IndentationWidth: ~ - -Layout/MultilineMethodDefinitionBraceLayout: - EnforcedStyle: symmetrical - SupportedStyles: - # symmetrical: closing brace is positioned in same way as opening brace - # new_line: closing brace is always on a new line - # same_line: closing brace is always on the same line as last parameter - - symmetrical - - new_line - - same_line - -Layout/MultilineOperationIndentation: - EnforcedStyle: aligned - SupportedStyles: - - aligned - - indented - # By default, the indentation width from Style/IndentationWidth is used - # But it can be overridden by setting this parameter - IndentationWidth: ~ - -Style/NumericLiterals: - MinDigits: 5 - -Style/NumericLiteralPrefix: - EnforcedOctalStyle: zero_with_o - SupportedOctalStyles: - - zero_with_o - - zero_only - -Style/OptionHash: - # A list of parameter names that will be flagged by this cop. - SuspiciousParamNames: - - options - - opts - - args - - params - - parameters - -# Allow safe assignment in conditions. -Style/ParenthesesAroundCondition: - AllowSafeAssignment: true - -Style/PercentLiteralDelimiters: - PreferredDelimiters: - "%": () - "%i": () - "%q": () - "%Q": () - "%r": "{}" - "%s": () - "%w": () - "%W": () - "%x": () - -Style/PercentQLiterals: - EnforcedStyle: lower_case_q - SupportedStyles: - - lower_case_q # Use %q when possible, %Q when necessary - - upper_case_q # Always use %Q - -Style/SlicingWithRange: - Enabled: false - -Naming/PredicateName: - # Predicate name prefixes. - NamePrefix: - - is_ - - has_ - - have_ - # Predicate name prefixes that should be removed. - ForbiddenPrefixes: - - is_ - - have_ - # Predicate names which, despite having a blacklisted prefix, or no ?, - # should still be accepted - AllowedMethods: - - is_a? - # Exclude Rspec specs because there is a strong convetion to write spec - # helpers in the form of `have_something` or `be_something`. - Exclude: - - "**/spec/**/*" - - "**/test/**/*" - -Style/PreferredHashMethods: - Enabled: true - EnforcedStyle: verbose - -Style/DateTime: - Enabled: true - -Style/Documentation: - Enabled: false - -Style/RaiseArgs: - EnforcedStyle: exploded - SupportedStyles: - - compact # raise Exception.new(msg) - - exploded # raise Exception, msg - -Style/RedundantReturn: - # When true allows code like `return x, y`. - AllowMultipleReturnValues: false - -# Use / or %r around regular expressions. -Style/RegexpLiteral: - EnforcedStyle: slashes - # slashes: Always use slashes. - # percent_r: Always use %r. - # mixed: Use slashes on single-line regexes, and %r on multi-line regexes. - SupportedStyles: - - slashes - - percent_r - - mixed - # If false, the cop will always recommend using %r if one or more slashes - # are found in the regexp string. - AllowInnerSlashes: false - -Style/SafeNavigation: - Enabled: false - -Style/Semicolon: - # Allow ; to separate several expressions on the same line. - AllowAsExpressionSeparator: false - -Style/SignalException: - EnforcedStyle: only_raise - SupportedStyles: - - only_raise - - only_fail - - semantic - -Style/SingleLineBlockParams: - Methods: - - reduce: - - a - - e - - inject: - - a - - e - -Style/SingleLineMethods: - AllowIfMethodIsEmpty: true - -Layout/SpaceBeforeFirstArg: - # When true, allows most uses of extra spacing if the intent is to align - # things with the previous or next line, not counting empty lines or comment - # lines. - AllowForAlignment: true - -Style/SpecialGlobalVars: - EnforcedStyle: use_english_names - SupportedStyles: - - use_perl_names - - use_english_names - -Style/StabbyLambdaParentheses: - EnforcedStyle: require_parentheses - SupportedStyles: - - require_parentheses - - require_no_parentheses - -Style/StringLiterals: - EnforcedStyle: double_quotes - SupportedStyles: - - single_quotes - - double_quotes - # If true, strings which span multiple lines using \ for continuation must - # use the same type of quotes on each line. - ConsistentQuotesInMultiline: false - -Style/StringLiteralsInInterpolation: - EnforcedStyle: double_quotes - SupportedStyles: - - single_quotes - - double_quotes - -Style/StringMethods: - # Mapping from undesired method to desired_method - # e.g. to use `to_sym` over `intern`: - # - # StringMethods: - # PreferredMethods: - # intern: to_sym - PreferredMethods: - intern: to_sym - -Layout/SpaceAroundBlockParameters: - EnforcedStyleInsidePipes: no_space - -Layout/SpaceAroundEqualsInParameterDefault: - EnforcedStyle: space - SupportedStyles: - - space - - no_space - -Layout/SpaceAroundOperators: - # When true, allows most uses of extra spacing if the intent is to align - # with an operator on the previous or next line, not counting empty lines - # or comment lines. - AllowForAlignment: true - -Layout/SpaceBeforeBlockBraces: - EnforcedStyle: space - SupportedStyles: - - space - - no_space - -Layout/SpaceInsideBlockBraces: - EnforcedStyle: space - SupportedStyles: - - space - - no_space - # Valid values are: space, no_space - EnforcedStyleForEmptyBraces: no_space - # Space between { and |. Overrides EnforcedStyle if there is a conflict. - SpaceBeforeBlockParameters: true - -Layout/SpaceInsideHashLiteralBraces: - EnforcedStyle: space - EnforcedStyleForEmptyBraces: no_space - SupportedStyles: - - space - - no_space - # "compact" normally requires a space inside hash braces, with the exception - # that successive left braces or right braces are collapsed together - - compact - -Layout/SpaceInsideStringInterpolation: - EnforcedStyle: no_space - SupportedStyles: - - space - - no_space - -Style/AccessModifierDeclarations: - Enabled: false - -Style/SymbolArray: - EnforcedStyle: brackets - SupportedStyles: - - percent - - brackets - -Style/SymbolProc: - # A list of method names to be ignored by the check. - # The names should be fairly unique, otherwise you'll end up ignoring lots of code. - IgnoredMethods: - - respond_to - - define_method - -Style/TernaryParentheses: - EnforcedStyle: require_no_parentheses - SupportedStyles: - - require_parentheses - - require_no_parentheses - AllowSafeAssignment: true - -Layout/TrailingEmptyLines: - EnforcedStyle: final_newline - SupportedStyles: - - final_newline - - final_blank_line - -Style/TrailingCommaInArguments: - # If `comma`, the cop requires a comma after the last argument, but only for - # parenthesized method calls where each argument is on its own line. - # If `consistent_comma`, the cop requires a comma after the last argument, - # for all parenthesized method calls with arguments. - EnforcedStyleForMultiline: no_comma - -Style/TrailingCommaInArrayLiteral: - # If `comma`, the cop requires a comma after the last item in an array or - # hash, but only when each item is on its own line. - # If `consistent_comma`, the cop requires a comma after the last item of all - # non-empty array and hash literals. - EnforcedStyleForMultiline: no_comma - -Style/TrailingCommaInHashLiteral: - # If `comma`, the cop requires a comma after the last item in an array or - # hash, but only when each item is on its own line. - # If `consistent_comma`, the cop requires a comma after the last item of all - # non-empty array and hash literals. - EnforcedStyleForMultiline: no_comma - -# TrivialAccessors requires exact name matches and doesn't allow -# predicated methods by default. -Style/TrivialAccessors: - # When set to false the cop will suggest the use of accessor methods - # in situations like: - # - # def name - # @other_name - # end - # - # This way you can uncover "hidden" attributes in your code. - ExactNameMatch: true - AllowPredicates: true - # Allows trivial writers that don't end in an equal sign. e.g. - # - # def on_exception(action) - # @on_exception=action - # end - # on_exception :restart - # - # Commonly used in DSLs - AllowDSLWriters: false - IgnoreClassMethods: false - AllowedMethods: - - to_ary - - to_a - - to_c - - to_enum - - to_h - - to_hash - - to_i - - to_int - - to_io - - to_open - - to_path - - to_proc - - to_r - - to_regexp - - to_str - - to_s - - to_sym - -Naming/VariableName: - EnforcedStyle: snake_case - SupportedStyles: - - snake_case - - camelCase - -Naming/VariableNumber: - EnforcedStyle: normalcase - SupportedStyles: - - snake_case - - normalcase - - non_integer - -# WordArray enforces how array literals of word-like strings should be expressed. -Style/WordArray: - EnforcedStyle: percent - SupportedStyles: - # percent style: %w(word1 word2) - - percent - # bracket style: ["word1", "word2"] - - brackets - # The MinSize option causes the WordArray rule to be ignored for arrays - # smaller than a certain size. The rule is only applied to arrays - # whose element count is greater than or equal to MinSize. - MinSize: 2 - # The regular expression WordRegex decides what is considered a word. - WordRegex: !ruby/regexp '/\A[\p{Word}\n\t]+\z/' - -##################### Metrics ################################## - -Metrics/AbcSize: - # The ABC size is a calculated magnitude, so this number can be an Integer or - # a Float. - Max: 15 - Enabled: false - -Metrics/BlockNesting: - Max: 3 - -Metrics/ClassLength: - CountComments: false # count full line comments? - Max: 100 - Enabled: false - -Metrics/ModuleLength: - CountComments: false # count full line comments? - Max: 100 - Enabled: false - -# Avoid complex methods. -Metrics/CyclomaticComplexity: - Max: 9 - Exclude: - - "bin/bundle" - - "decidim-admin/app/queries/decidim/admin/newsletter_recipients.rb" - - "**/*/dummy_authorization_handler.rb" - - "**/*/permissions.rb" - - "**/*/permissions_override.rb" - -Metrics/MethodLength: - CountComments: false # count full line comments? - Max: 15 - Enabled: false - -Metrics/ParameterLists: - Max: 5 - CountKeywordArgs: true - Exclude: - - "decidim-core/lib/decidim/filter_form_builder.rb" - -Metrics/PerceivedComplexity: - Max: 10 - Exclude: - - "decidim-admin/app/queries/decidim/admin/newsletter_recipients.rb" - - "**/*/dummy_authorization_handler.rb" - - "**/*/permissions.rb" - - "**/*/permissions_override.rb" - -##################### Lint ################################## - -Lint/AmbiguousBlockAssociation: - Enabled: true - Exclude: - - "**/abilities/**/*" - -# Allow safe assignment in conditions. -Lint/AssignmentInCondition: - AllowSafeAssignment: true - -Lint/ConstantDefinitionInBlock: - Enabled: false - -# Call super to initialize state of the parent class. -Lint/MissingSuper: - Enabled: false - -# checks whether the end keywords are aligned properly for `do` `end` blocks. -Layout/BlockAlignment: - # The value `start_of_block` means that the `end` should be aligned with line - # where the `do` keyword appears. - # The value `start_of_line` means it should be aligned with the whole - # expression's starting line. - # The value `either` means both are allowed. - EnforcedStyleAlignWith: either - -# Align ends correctly. -Layout/EndAlignment: - # The value `keyword` means that `end` should be aligned with the matching - # keyword (if, while, etc.). - # The value `variable` means that in assignments, `end` should be aligned - # with the start of the variable on the left hand side of `=`. In all other - # situations, `end` should still be aligned with the keyword. - # The value `start_of_line` means that `end` should be aligned with the start - # of the line which the matching keyword appears on. - EnforcedStyleAlignWith: keyword - AutoCorrect: false - -Layout/DefEndAlignment: - # The value `def` means that `end` should be aligned with the def keyword. - # The value `start_of_line` means that `end` should be aligned with method - # calls like `private`, `public`, etc, if present in front of the `def` - # keyword on the same line. - EnforcedStyleAlignWith: start_of_line - AutoCorrect: false - -Lint/InheritException: - # The default base class in favour of `Exception`. - EnforcedStyle: runtime_error - SupportedStyles: - - runtime_error - - standard_error - -Layout/LineLength: - Max: 180 - # To make it possible to copy or click on URIs in the code, we allow lines - # containing a URI to be longer than Max. - AllowHeredoc: true - AllowURI: true - URISchemes: - - http - - https - Exclude: - - "**/spec/**/*" - -# Checks for unused block arguments -Lint/UnusedBlockArgument: - IgnoreEmptyBlocks: true - AllowUnusedKeywordArguments: false - -# Checks for unused method arguments. -Lint/UnusedMethodArgument: - AllowUnusedKeywordArguments: false - IgnoreEmptyMethods: true - -##################### Performance ############################ - -Metrics/BlockLength: - Enabled: false - -RSpec/BeforeAfterAll: - Enabled: true - -RSpec/ContextWording: - Enabled: true - Prefixes: - - when - - with - - without - - and - -RSpec/DescribeClass: - Exclude: - - spec/gemfiles_spec.rb - - spec/js_bundles_spec.rb - - spec/i18n_spec.rb - - "**/*/spec/**/*_badge_spec.rb" - - decidim-core/spec/lib/global_engines_spec.rb - - "**/tasks/**/*" - -RSpec/EmptyExampleGroup: - Exclude: - - decidim-core/spec/lib/participatory_space_manifest_spec.rb - -RSpec/ExampleLength: - Max: 49 - -RSpec/ExpectInHook: - Enabled: false - -RSpec/IteratedExpectation: - Enabled: true - -RSpec/LetSetup: - Enabled: false - -RSpec/MessageSpies: - Enabled: false - -RSpec/MultipleExpectations: - Enabled: false - -RSpec/MultipleMemoizedHelpers: - Max: 35 - -RSpec/NestedGroups: - Max: 7 - -RSpec/NamedSubject: - Enabled: false - -RSpec/RepeatedExampleGroupDescription: - Enabled: false - -RSpec/RepeatedExampleGroupBody: - Enabled: false -RSpec/VerifiedDoubles: - Enabled: false - -RSpec/LeakyConstantDeclaration: - Enabled: false - -RSpec/DescribedClass: - Enabled: false - -# This is the default configuration file. - -Faker/DeprecatedArguments: - Description: 'Checks that Faker arguments style is based on Faker 2.' - Enabled: true - VersionAdded: '0.1' - Reference: 'https://github.com/faker-ruby/faker/blob/master/CHANGELOG.md#v20-2019-31-07' - ArgumentKeywords: - # - # FakerClassName: - # method_name: - # - keyword_name_for_first_argument - # - keyword_name_for_second_argument - # - keyword_name_for_third_argument - # - Faker::Dune: - quote: - - character - saying: - - source - Faker::Books::Lovecraft: - fhtagn: - - number - sentence: - - word_count - - random_words_to_add - words: - - number - - spaces_allowed - sentences: - - number - paragraph: - - sentence_count - - random_sentences_to_add - paragraphs: - - number - paragraph_by_chars: - - characters - Faker::Address: - city: - - options - street_address: - - include_secondary - zip_code: - - state_abbreviation - country_by_code: - - code - country_name_to_code: - - name - Faker::Alphanumeric: - alpha: - - number - alphanumeric: - - number - Faker::App: - semantic_version: - - major - - minor - - patch - Faker::Avatar: - image: - - slug - - size - - format - - set - - bgset - Faker::Bank: - account_number: - - digits - iban: - - country_code - Faker::Boolean: - boolean: - - true_ratio - Faker::ChileRut: - rut: - - min_rut - - fixed - full_rut: - - min_rut - - fixed - Faker::Code: - isbn: - - base - ean: - - base - nric: - - min_age - - max_age - Faker::Commerce: - promotion_code: - - digits - department: - - max - - fixed_amount - price: - - range - - as_string - Faker::Company: - polish_register_of_national_economy: - - length - brazilian_company_number: - - formatted - Faker::CryptoCoin: - coin_name: - - coin - acronym: - - coin - url_logo: - - coin - Faker::Date: - between: - - from - - to - between_except: - - from - - to - - excepted - forward: - - days - backward: - - days - birthday: - - min_age - - max_age - Faker::Demographic: - height: - - unit - Faker::DrivingLicence: - british_driving_licence: - - last_name - - initials - - gender - - date_of_birth - Faker::File: - dir: - - segment_count - - root - - directory_separator - file_name: - - dir - - name - - ext - - directory_separator - Faker::Fillmurray: - image: - - grayscale - - width - - height - Faker::Finance: - vat_number: - - country - Faker::Hipster: - words: - - number - - supplemental - - spaces_allowed - sentence: - - word_count - - supplemental - - random_words_to_add - sentences: - - number - - supplemental - paragraph: - - sentence_count - - supplemental - - random_sentences_to_add - paragraphs: - - number - - supplemental - paragraph_by_chars: - - characters - - supplemental - Faker::IDNumber: - brazilian_citizen_number: - - formatted - brazilian_id: - - formatted - Faker::Internet: - email: - - name - - separators - free_email: - - name - safe_email: - - name - username: - - specifier - - separators - password: - - min_length - - max_length - - mix_case - - special_characters - domain_name: - - subdomain - fix_umlauts: - - string - mac_address: - - prefix - url: - - host - - path - - scheme - slug: - - words - - glue - user_agent: - - vendor - Faker::Invoice: - amount_between: - - from - - to - creditor_reference: - - ref - reference: - - ref - Faker::Json: - shallow_json: - - width - - options - add_depth_to_json: - - json - - width - - options - Faker::Lorem: - words: - - number - - supplemental - characters: - - number - sentence: - - word_count - - supplemental - - random_words_to_add - sentences: - - number - - supplemental - paragraph: - - sentence_count - - supplemental - - random_sentences_to_add - paragraphs: - - number - - supplemental - paragraph_by_chars: - - number - - supplemental - question: - - word_count - - supplemental - - random_words_to_add - questions: - - number - - supplemental - Faker::LoremFlickr: - image: - - size - - search_terms - - match_all - grayscale_image: - - size - - search_terms - - match_all - pixelated_image: - - size - - search_terms - - match_all - colorized_image: - - size - - color - - search_terms - - match_all - Faker::LoremPixel: - image: - - size - - is_gray - - category - - number - - text - - secure - Faker::Markdown: - sandwich: - - sentences - - repeat - Faker::Measurement: - height: - - amount - length: - - amount - volume: - - amount - weight: - - amount - metric_height: - - amount - metric_length: - - amount - metric_volume: - - amount - metric_weight: - - amount - Faker::Name: - initials: - - number - Faker::NationalHealthService: - check_digit: - - number - Faker::Number: - number: - - digits - leading_zero_number: - - digits - decimal_part: - - digits - decimal: - - l_digits - - r_digits - hexadecimal: - - digits - normal: - - mean - - standard_deviation - between: - - from - - to - within: - - range - positive: - - from - - to - negative: - - from - - to - Faker::Omniauth: - google: - - name - - email - - uid - facebook: - - name - - email - - username - - uid - twitter: - - name - - nickname - - uid - linkedin: - - name - - email - - uid - github: - - name - - email - - uid - Faker::PhoneNumber: - subscriber_number: - - length - Faker::Placeholdit: - image: - - size - - format - - background_color - - text_color - - text - Faker::Relationship: - familial: - - connection - Faker::Source: - hello_world: - - lang - print: - - str - - lang - print_1_to_10: - - lang - Faker::String: - random: - - length - Faker::Stripe: - valid_card: - - card_type - valid_token: - - card_type - invalid_card: - - card_error - ccv: - - card_type - Faker::Time: - between: - - from - - to - - format - between_dates: - - from - - to - - period - - format - forward: - - days - - period - - format - backward: - - days - - period - - format - Faker::Twitter: - user: - - include_status - - include_email - status: - - include_user - - include_photo - status_entities: - - include_photo - Faker::Types: - rb_string: - - words - rb_integer: - - from - - to - rb_hash: - - number - - type - complex_rb_hash: - - number - rb_array: - - len - Faker::Vehicle: - model: - - make_of_model - mileage: - - min - - max - license_plate: - - state_abbreviation - Faker::WorldCup: - group: - - group - roster: - - country - - type - Faker::Dota: - quote: - - hero - Faker::Movies::StarWars: - quote: - - character - Decidim::Faker::Localized: - words: - - number - - supplemental - characters: - - number - sentence: - - word_count - - supplemental - - random_words_to_add - sentences: - - number - - supplemental - paragraph: - - sentence_count - - supplemental - - random_sentences_to_add - paragraphs: - - number - - supplemental - paragraph_by_chars: - - number - - supplemental - question: - - word_count - - supplemental - - random_words_to_add - questions: - - number - - supplemental - diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml new file mode 100644 index 0000000000..5445d7832f --- /dev/null +++ b/.rubocop_todo.yml @@ -0,0 +1,24 @@ +Metrics/CyclomaticComplexity: + Exclude: + - 'app/permissions/concerns/decidim/initiatives/admin/permissions_override.rb' + +Metrics/PerceivedComplexity: + Exclude: + - 'app/permissions/concerns/decidim/initiatives/admin/permissions_override.rb' + +RSpec/DescribeClass: + Exclude: + - 'decidim-census_sms/spec/system/census_sms_authorization_spec.rb' + - 'decidim-ephemeral_participation/spec/system/user/complete_registration_spec.rb' + - 'decidim-ephemeral_participation/spec/system/user/ephemeral_participation_button_spec.rb' + - 'decidim-ephemeral_participation/spec/system/user/flash_messages_spec.rb' + - 'decidim-ephemeral_participation/spec/system/user/session_spec.rb' + - 'decidim-ephemeral_participation/spec/system/user/successful_verification_spec.rb' + - 'decidim-ephemeral_participation/spec/system/user/user_menu_spec.rb' + - 'decidim-ephemeral_participation/spec/system/user/verification_conflicts_spec.rb' + - 'spec/system/census16_authorization_spec.rb' + +RSpec/PendingWithoutReason: + Exclude: + - 'spec/system/budgets_ephemeral_participation_spec.rb' + - 'spec/system/budget_spec.rb' diff --git a/.ruby-version b/.ruby-version index a603bb50a2..94ff29cc4d 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.7.5 +3.1.1 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 65c05c5748..01b8644f13 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -19,4 +19,4 @@ This code of conduct applies both within project spaces and in public spaces whe Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers. -This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/) \ No newline at end of file +This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/) diff --git a/Dockerfile b/Dockerfile index a2bed34030..e590c36c7f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,16 +1,9 @@ -# Decidim Application Dockerfile -# This is an image to start an application based on Decidim (https://decidim.org) -# -# +FROM ruby:3.1.1 - -# Starts with a clean ruby image from Debian (slim) -FROM ruby:2.6.6 - -LABEL maintainer="hola@decidim.org" - -# Installs system dependencies ENV DEBIAN_FRONTEND noninteractive +ENV NODE_MAJOR=18 + +# Install system dependencies RUN apt-get update -qq && apt-get install -y \ build-essential \ graphviz \ @@ -20,7 +13,15 @@ RUN apt-get update -qq && apt-get install -y \ nodejs \ && rm -rf /var/lib/apt/lists/* -# Sets workdir as /app +# Install node +RUN mkdir -p /etc/apt/keyrings +RUN curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg +RUN echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" | tee /etc/apt/sources.list.d/nodesource.list +RUN apt-get update -qq && apt-get install -y \ + nodejs \ + && rm -rf /var/lib/apt/lists/* + +# Create workdir RUN mkdir /app WORKDIR /app @@ -35,11 +36,17 @@ ENV PATH="${BUNDLE_BIN}:${PATH}" # Copy Gemfile and install bundler dependencies ADD Gemfile Gemfile.lock /app/ +ADD ./decidim-census_sms/decidim-census_sms.gemspec /app/decidim-census_sms/decidim-census_sms.gemspec ADD ./decidim-dataviz/decidim-dataviz.gemspec /app/decidim-dataviz/decidim-dataviz.gemspec +ADD ./decidim-ephemeral_participation/decidim-ephemeral_participation.gemspec /app/decidim-ephemeral_participation/decidim-ephemeral_participation.gemspec ADD ./decidim-stats/decidim-stats.gemspec /app/decidim-stats/decidim-stats.gemspec ADD ./decidim-valid_auth/decidim-valid_auth.gemspec /app/decidim-valid_auth/decidim-valid_auth.gemspec -RUN gem install bundler:2.0.1 +RUN gem install bundler:2.4.14 RUN bundle install # Copy all the code to /app ADD . /app + +# Compile assets +RUN npm i +RUN npm i -g yarn diff --git a/Gemfile b/Gemfile index b134e93cda..b518f8f550 100644 --- a/Gemfile +++ b/Gemfile @@ -2,78 +2,76 @@ source "https://rubygems.org" -DECIDIM_VERSION = { git: "https://github.com/AjuntamentdeBarcelona/decidim", branch: "release/0.26-stable-bcn" }.freeze +DECIDIM_VERSION = "0.28.4" ruby RUBY_VERSION -gem "decidim", DECIDIM_VERSION -gem "decidim-census_sms", path: "decidim-census_sms" -gem "decidim-dataviz", path: "decidim-dataviz" -gem "decidim-ephemeral_participation", path: "decidim-ephemeral_participation" +# gem "decidim", DECIDIM_VERSION +gem "decidim", github: "ajuntamentdeBarcelona/decidim", branch: "bcn/0.28-branch" gem "decidim-initiatives", DECIDIM_VERSION -gem "decidim-navigation_maps", "~> 1.3.3" +gem "decidim-internal_evaluation", github: "AjuntamentdeBarcelona/decidim-internal-evaluation-module", branch: "release/0.28-stable" gem "decidim-sortitions", DECIDIM_VERSION +gem "decidim-templates", DECIDIM_VERSION + +gem "decidim-census_sms", path: "decidim-census_sms" +gem "decidim-dataviz", path: "decidim-dataviz" +gem "decidim-ephemeral_participation", path: "decidim-ephemeral_participation" # Installed but not used anymore gem "decidim-stats", path: "decidim-stats" gem "decidim-valid_auth", path: "decidim-valid_auth" -# Change term_customizer dependency to ruby-gems' when term-customizer is compatible with DECIDIM_VERSION -gem "decidim-decidim_awesome", "~> 0.8.3" -gem "decidim-term_customizer", git: "https://github.com/mainio/decidim-module-term_customizer", branch: "release/0.26-stable" +gem "decidim-decidim_awesome", git: "https://github.com/decidim-ice/decidim-module-decidim_awesome" +gem "decidim-kids", git: "https://github.com/AjuntamentdeBarcelona/decidim-module-kids" +gem "decidim-navigation_maps", git: "https://github.com/Platoniq/decidim-module-navigation_maps" +gem "decidim-term_customizer", git: "https://github.com/mainio/decidim-module-term_customizer" -gem "virtus-multiparams" -gem "wicked_pdf" +gem "origami" +gem "wicked_pdf", "< 2.8" gem "wkhtmltopdf-binary" -gem "deface" -gem "lograge" -gem "origami" gem "progressbar" gem "puma" -gem "uglifier" - -# Needed to be able to debug Puma status -gem "barnes" group :development, :test do gem "bootsnap" gem "byebug", platform: :mri gem "decidim-dev", DECIDIM_VERSION gem "dotenv-rails" - gem "faker", "~> 2.14" + gem "faker" + gem "mdl" gem "rubocop-faker" end group :development do + gem "foreman" gem "letter_opener_web" gem "listen" - gem "rubocop", "~> 0.92.0" - gem "spring" - gem "spring-commands-rspec" - gem "spring-watcher-listen" + gem "rubocop" gem "web-console" end group :production do - # Used to restart puma workers every 6h and free memory - gem "puma_worker_killer" - # Let's kill long-running requests after the Heroku router has responded to. - # https://devcenter.heroku.com/articles/h12-request-timeout-in-ruby-mri#rack-timeout gem "aws-sdk-s3", require: false + gem "barnes" # Needed to be able to debug Puma status gem "dalli" - gem "fog-aws" # to remove once image migration is complete + gem "lograge" + gem "matrix" + gem "puma_worker_killer" # Used to restart puma workers every 6h and free memory gem "rack_password" gem "rack-ssl-enforcer" - gem "rack-timeout" + gem "rack-timeout" # Let's kill long-running requests after the Heroku router has responded to gem "rails_12factor" gem "rails_autoscale_agent" + gem "rexml" gem "scout_apm" gem "sentry-rails" gem "sentry-ruby" gem "sentry-sidekiq" gem "sidekiq" + gem "stackprof" end group :test do + gem "codecov", require: false gem "database_cleaner" gem "rspec" end diff --git a/Gemfile.lock b/Gemfile.lock index 582fd67fd9..0136fecf8f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,263 +1,254 @@ GIT - remote: https://github.com/AjuntamentdeBarcelona/decidim - revision: f7e6972f63436b6c9be82498a341d5abb36bb283 - branch: release/0.26-stable-bcn + remote: https://github.com/AjuntamentdeBarcelona/decidim-internal-evaluation-module.git + revision: cf5eb7f00f957881ade8360a69655e92d95ceff0 + branch: release/0.28-stable specs: - decidim (0.26.7) - decidim-accountability (= 0.26.7) - decidim-admin (= 0.26.7) - decidim-api (= 0.26.7) - decidim-assemblies (= 0.26.7) - decidim-blogs (= 0.26.7) - decidim-budgets (= 0.26.7) - decidim-comments (= 0.26.7) - decidim-core (= 0.26.7) - decidim-debates (= 0.26.7) - decidim-forms (= 0.26.7) - decidim-generators (= 0.26.7) - decidim-meetings (= 0.26.7) - decidim-pages (= 0.26.7) - decidim-participatory_processes (= 0.26.7) - decidim-proposals (= 0.26.7) - decidim-sortitions (= 0.26.7) - decidim-surveys (= 0.26.7) - decidim-system (= 0.26.7) - decidim-templates (= 0.26.7) - decidim-verifications (= 0.26.7) - decidim-accountability (0.26.7) - decidim-comments (= 0.26.7) - decidim-core (= 0.26.7) - decidim-admin (0.26.7) + decidim-internal_evaluation (0.0.1) + decidim-core (~> 0.28.0) + decidim-proposals (~> 0.28.0) + decidim-templates (~> 0.28.0) + deface (~> 1.9) + +GIT + remote: https://github.com/AjuntamentdeBarcelona/decidim-module-kids + revision: df16cf4de13c306348761d850d19815c8221874e + specs: + decidim-kids (0.2.0) + decidim-core (>= 0.28, < 0.29) + decidim-system (>= 0.28, < 0.29) + decidim-verifications (>= 0.28, < 0.29) + deface (>= 1.5) + +GIT + remote: https://github.com/Platoniq/decidim-module-navigation_maps + revision: 7fd50e1368bae4c7955c0ba8ec5ee395273a5329 + specs: + decidim-navigation_maps (1.5.0) + decidim-admin (>= 0.28, < 0.29) + decidim-core (>= 0.28, < 0.29) + +GIT + remote: https://github.com/ajuntamentdeBarcelona/decidim.git + revision: 9c78c1c36bb6c44a855c02acd6f58c70345853c4 + branch: bcn/0.28-branch + specs: + decidim (0.28.4) + decidim-accountability (= 0.28.4) + decidim-admin (= 0.28.4) + decidim-api (= 0.28.4) + decidim-assemblies (= 0.28.4) + decidim-blogs (= 0.28.4) + decidim-budgets (= 0.28.4) + decidim-comments (= 0.28.4) + decidim-core (= 0.28.4) + decidim-debates (= 0.28.4) + decidim-forms (= 0.28.4) + decidim-generators (= 0.28.4) + decidim-meetings (= 0.28.4) + decidim-pages (= 0.28.4) + decidim-participatory_processes (= 0.28.4) + decidim-proposals (= 0.28.4) + decidim-sortitions (= 0.28.4) + decidim-surveys (= 0.28.4) + decidim-system (= 0.28.4) + decidim-verifications (= 0.28.4) + decidim-accountability (0.28.4) + decidim-comments (= 0.28.4) + decidim-core (= 0.28.4) + decidim-admin (0.28.4) active_link_to (~> 1.0) - decidim-core (= 0.26.7) + decidim-core (= 0.28.4) devise (~> 4.7) devise-i18n (~> 1.2) - devise_invitable (~> 2.0) - decidim-api (0.26.7) - graphql (~> 1.12, < 1.13) + devise_invitable (~> 2.0, >= 2.0.9) + decidim-api (0.28.4) + commonmarker (~> 0.23.0, >= 0.23.9) + decidim-core (= 0.28.4) + graphql (~> 2.0.0) + graphql-docs (~> 3.0.1) rack-cors (~> 1.0) + decidim-assemblies (0.28.4) + decidim-core (= 0.28.4) + decidim-blogs (0.28.4) + decidim-admin (= 0.28.4) + decidim-comments (= 0.28.4) + decidim-core (= 0.28.4) + decidim-budgets (0.28.4) + decidim-comments (= 0.28.4) + decidim-core (= 0.28.4) + decidim-comments (0.28.4) + decidim-core (= 0.28.4) redcarpet (~> 3.5, >= 3.5.1) - decidim-assemblies (0.26.7) - decidim-core (= 0.26.7) - decidim-blogs (0.26.7) - decidim-admin (= 0.26.7) - decidim-comments (= 0.26.7) - decidim-core (= 0.26.7) - decidim-budgets (0.26.7) - decidim-comments (= 0.26.7) - decidim-core (= 0.26.7) - decidim-comments (0.26.7) - decidim-core (= 0.26.7) - redcarpet (~> 3.5, >= 3.5.1) - decidim-core (0.26.7) + decidim-core (0.28.4) active_link_to (~> 1.0) - acts_as_list (~> 0.9) + acts_as_list (~> 1.0) batch-loader (~> 1.2) browser (~> 2.7) - carrierwave (~> 2.2.1) + carrierwave (~> 2.2.5, >= 2.2.5) cells-erb (~> 0.1.0) cells-rails (~> 0.1.3) charlock_holmes (~> 0.7) - date_validator (~> 0.9.0) - decidim-api (= 0.26.7) + date_validator (~> 0.12.0) devise (~> 4.7) - devise-i18n (~> 1.2) + devise-i18n (~> 1.2, < 1.11.1) diffy (~> 3.3) - doorkeeper (~> 5.1) + doorkeeper (~> 5.6, >= 5.6.6) doorkeeper-i18n (~> 4.0) - file_validators (~> 2.1) + file_validators (~> 3.0) fog-local (~> 0.6) - foundation_rails_helper - geocoder (~> 1.7.5) + foundation_rails_helper (~> 4.0) + geocoder (~> 1.8) hashdiff (>= 0.4.0, < 2.0.0) invisible_captcha (~> 0.12) kaminari (~> 1.2, >= 1.2.1) - loofah (~> 2.3.1) + loofah (~> 2.19, >= 2.19.1) mime-types (>= 1.16, < 4.0) mini_magick (~> 4.9) - mustache (~> 1.1.0) + net-smtp (~> 0.3.1) omniauth (~> 2.0) omniauth-facebook (~> 5.0) omniauth-google-oauth2 (~> 1.0) omniauth-rails_csrf_protection (~> 1.0) omniauth-twitter (~> 1.4) paper_trail (~> 12.0) - pg (~> 1.1.4, < 2) + pg (~> 1.4.0, < 2) pg_search (~> 2.2) premailer-rails (~> 1.10) - rack (~> 2.2, >= 2.2.3) + psych (~> 4.0) + rack (~> 2.2, >= 2.2.6.4) rack-attack (~> 6.0) - rails (~> 6.0.4) + rails (~> 6.1.7, >= 6.1.7.4) rails-i18n (~> 6.0) - ransack (~> 2.4.1) - rectify (~> 0.13.0) + ransack (~> 3.2.1) redis (~> 4.1) request_store (~> 1.5.0) rubyXL (~> 3.4) rubyzip (~> 2.0) - searchlight (~> 4.1) - seven_zip_ruby (~> 1.3) - social-share-button (~> 1.2, >= 1.2.1) - valid_email2 (~> 2.1) - webpacker (= 6.0.0.rc.5) + shakapacker (~> 7.1.0) + valid_email2 (~> 4.0) + web-push (~> 3.0) wisper (~> 2.0) - decidim-debates (0.26.7) - decidim-comments (= 0.26.7) - decidim-core (= 0.26.7) - decidim-dev (0.26.7) - axe-core-rspec (~> 4.1.0) - byebug (~> 11.0) - capybara (~> 3.24) - db-query-matchers (~> 0.10.0) - decidim (= 0.26.7) - erb_lint (~> 0.0.35) - factory_bot_rails (~> 4.8) - i18n-tasks (~> 0.9.18) - mdl (~> 0.5) - nokogiri (~> 1.12) - puma (~> 5.0) - rails-controller-testing (~> 1.0) - rspec-cells (~> 0.3.4) - rspec-html-matchers (~> 0.9.1) - rspec-rails (~> 4.0) - rspec-retry (~> 0.6.2) - rspec_junit_formatter (~> 0.3.0) - rubocop (~> 0.92.0) - rubocop-rails (~> 2.8) - rubocop-rspec (= 1.43.2) - selenium-webdriver (~> 3.142) - simplecov (~> 0.19.0) - simplecov-cobertura (~> 1.3.1) - system_test_html_screenshots (~> 0.2) - w3c_rspec_validators (~> 0.3.0) - webmock (~> 3.6) - wisper-rspec (~> 1.0) - decidim-forms (0.26.7) - decidim-core (= 0.26.7) - wicked_pdf (~> 2.1) - wkhtmltopdf-binary (~> 0.12) - decidim-generators (0.26.7) - decidim-core (= 0.26.7) - decidim-initiatives (0.26.7) - decidim-admin (= 0.26.7) - decidim-comments (= 0.26.7) - decidim-core (= 0.26.7) - decidim-verifications (= 0.26.7) - origami (~> 2.1) - virtus-multiparams (~> 0.1) - wicked (~> 1.3) + decidim-debates (0.28.4) + decidim-comments (= 0.28.4) + decidim-core (= 0.28.4) + decidim-forms (0.28.4) + decidim-core (= 0.28.4) wicked_pdf (~> 2.1) wkhtmltopdf-binary (~> 0.12) - decidim-meetings (0.26.7) - decidim-core (= 0.26.7) - decidim-forms (= 0.26.7) + decidim-generators (0.28.4) + decidim-core (= 0.28.4) + decidim-meetings (0.28.4) + decidim-core (= 0.28.4) + decidim-forms (= 0.28.4) icalendar (~> 2.5) - decidim-pages (0.26.7) - decidim-core (= 0.26.7) - decidim-participatory_processes (0.26.7) - decidim-core (= 0.26.7) - decidim-proposals (0.26.7) - decidim-comments (= 0.26.7) - decidim-core (= 0.26.7) - doc2text (~> 0.4.4) + decidim-pages (0.28.4) + decidim-core (= 0.28.4) + decidim-participatory_processes (0.28.4) + decidim-core (= 0.28.4) + decidim-proposals (0.28.4) + decidim-comments (= 0.28.4) + decidim-core (= 0.28.4) + doc2text (~> 0.4.6) redcarpet (~> 3.5, >= 3.5.1) - decidim-sortitions (0.26.7) - decidim-admin (= 0.26.7) - decidim-comments (= 0.26.7) - decidim-core (= 0.26.7) - decidim-proposals (= 0.26.7) - decidim-surveys (0.26.7) - decidim-core (= 0.26.7) - decidim-forms (= 0.26.7) - decidim-templates (= 0.26.7) - decidim-system (0.26.7) + decidim-surveys (0.28.4) + decidim-core (= 0.28.4) + decidim-forms (= 0.28.4) + decidim-system (0.28.4) active_link_to (~> 1.0) - decidim-core (= 0.26.7) + decidim-core (= 0.28.4) devise (~> 4.7) devise-i18n (~> 1.2) - devise_invitable (~> 2.0) - decidim-templates (0.26.7) - decidim-core (= 0.26.7) - decidim-forms (= 0.26.7) - decidim-verifications (0.26.7) - decidim-core (= 0.26.7) + devise_invitable (~> 2.0, >= 2.0.9) + decidim-verifications (0.28.4) + decidim-core (= 0.28.4) + +GIT + remote: https://github.com/decidim-ice/decidim-module-decidim_awesome + revision: 84374037d34a3ac80dc18406834169c65869f11b + specs: + decidim-decidim_awesome (0.11.2) + decidim-admin (>= 0.28.0, < 0.29) + decidim-core (>= 0.28.0, < 0.29) + deface (>= 1.5) + sassc (~> 2.3) GIT remote: https://github.com/mainio/decidim-module-term_customizer - revision: f0d720710822f1231ea249dd71f978143d38a6c4 - branch: release/0.26-stable + revision: 03e6c98e85a00fe47f8db2726f1a1a98e808efda specs: - decidim-term_customizer (0.26.0) - decidim-admin (~> 0.26.0) - decidim-core (~> 0.26.0) + decidim-term_customizer (0.28.0) + decidim-admin (~> 0.28.0) + decidim-core (~> 0.28.0) PATH remote: decidim-census_sms specs: - decidim-census_sms (0.0.1) - decidim-core + decidim-census_sms (0.0.3) + decidim-core (~> 0.28.0) PATH remote: decidim-dataviz specs: - decidim-dataviz (0.0.1) - decidim-core + decidim-dataviz (0.0.3) + decidim-core (~> 0.28.0) PATH remote: decidim-ephemeral_participation specs: - decidim-ephemeral_participation (0.0.2) - decidim-verifications + decidim-ephemeral_participation (0.0.4) + decidim-verifications (~> 0.28.0) PATH remote: decidim-stats specs: - decidim-stats (0.0.1) - decidim-comments - decidim-core - decidim-proposals + decidim-stats (0.0.3) + decidim-comments (~> 0.28.0) + decidim-core (~> 0.28.0) + decidim-proposals (~> 0.28.0) PATH remote: decidim-valid_auth specs: - decidim-valid_auth (0.0.1) - decidim-verifications + decidim-valid_auth (0.0.3) + decidim-verifications (~> 0.28.0) GEM remote: https://rubygems.org/ specs: - actioncable (6.0.6.1) - actionpack (= 6.0.6.1) + actioncable (6.1.7.9) + actionpack (= 6.1.7.9) + activesupport (= 6.1.7.9) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (6.0.6.1) - actionpack (= 6.0.6.1) - activejob (= 6.0.6.1) - activerecord (= 6.0.6.1) - activestorage (= 6.0.6.1) - activesupport (= 6.0.6.1) + actionmailbox (6.1.7.9) + actionpack (= 6.1.7.9) + activejob (= 6.1.7.9) + activerecord (= 6.1.7.9) + activestorage (= 6.1.7.9) + activesupport (= 6.1.7.9) mail (>= 2.7.1) - actionmailer (6.0.6.1) - actionpack (= 6.0.6.1) - actionview (= 6.0.6.1) - activejob (= 6.0.6.1) + actionmailer (6.1.7.9) + actionpack (= 6.1.7.9) + actionview (= 6.1.7.9) + activejob (= 6.1.7.9) + activesupport (= 6.1.7.9) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (6.0.6.1) - actionview (= 6.0.6.1) - activesupport (= 6.0.6.1) - rack (~> 2.0, >= 2.0.8) + actionpack (6.1.7.9) + actionview (= 6.1.7.9) + activesupport (= 6.1.7.9) + rack (~> 2.0, >= 2.0.9) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (6.0.6.1) - actionpack (= 6.0.6.1) - activerecord (= 6.0.6.1) - activestorage (= 6.0.6.1) - activesupport (= 6.0.6.1) + actiontext (6.1.7.9) + actionpack (= 6.1.7.9) + activerecord (= 6.1.7.9) + activestorage (= 6.1.7.9) + activesupport (= 6.1.7.9) nokogiri (>= 1.8.5) - actionview (6.0.6.1) - activesupport (= 6.0.6.1) + actionview (6.1.7.9) + activesupport (= 6.1.7.9) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) @@ -265,86 +256,82 @@ GEM active_link_to (1.0.5) actionpack addressable - activejob (6.0.6.1) - activesupport (= 6.0.6.1) + activejob (6.1.7.9) + activesupport (= 6.1.7.9) globalid (>= 0.3.6) - activemodel (6.0.6.1) - activesupport (= 6.0.6.1) - activerecord (6.0.6.1) - activemodel (= 6.0.6.1) - activesupport (= 6.0.6.1) - activestorage (6.0.6.1) - actionpack (= 6.0.6.1) - activejob (= 6.0.6.1) - activerecord (= 6.0.6.1) + activemodel (6.1.7.9) + activesupport (= 6.1.7.9) + activerecord (6.1.7.9) + activemodel (= 6.1.7.9) + activesupport (= 6.1.7.9) + activestorage (6.1.7.9) + actionpack (= 6.1.7.9) + activejob (= 6.1.7.9) + activerecord (= 6.1.7.9) + activesupport (= 6.1.7.9) marcel (~> 1.0) - activesupport (6.0.6.1) + mini_mime (>= 1.1.0) + activesupport (6.1.7.9) concurrent-ruby (~> 1.0, >= 1.0.2) - i18n (>= 0.7, < 2) - minitest (~> 5.1) - tzinfo (~> 1.1) - zeitwerk (~> 2.2, >= 2.2.2) - acts_as_list (0.9.19) - activerecord (>= 3.0) - addressable (2.8.4) - public_suffix (>= 2.0.2, < 6.0) + i18n (>= 1.6, < 2) + minitest (>= 5.1) + tzinfo (~> 2.0) + zeitwerk (~> 2.3) + acts_as_list (1.2.3) + activerecord (>= 6.1) + activesupport (>= 6.1) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) ast (2.4.2) - aws-eventstream (1.2.0) - aws-partitions (1.665.0) - aws-sdk-core (3.168.1) - aws-eventstream (~> 1, >= 1.0.2) + aws-eventstream (1.3.0) + aws-partitions (1.896.0) + aws-sdk-core (3.191.3) + aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.651.0) - aws-sigv4 (~> 1.5) + aws-sigv4 (~> 1.8) jmespath (~> 1, >= 1.6.1) - aws-sdk-kms (1.59.0) - aws-sdk-core (~> 3, >= 3.165.0) + aws-sdk-kms (1.77.0) + aws-sdk-core (~> 3, >= 3.191.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.117.1) - aws-sdk-core (~> 3, >= 3.165.0) + aws-sdk-s3 (1.143.0) + aws-sdk-core (~> 3, >= 3.191.0) aws-sdk-kms (~> 1) - aws-sigv4 (~> 1.4) - aws-sigv4 (1.5.2) + aws-sigv4 (~> 1.8) + aws-sigv4 (1.8.0) aws-eventstream (~> 1, >= 1.0.2) - axe-core-api (4.7.0) - dumb_delegator - virtus - axe-core-rspec (4.1.0) - axe-core-api - dumb_delegator - virtus - axiom-types (0.1.1) - descendants_tracker (~> 0.0.4) - ice_nine (~> 0.11.0) - thread_safe (~> 0.3, >= 0.3.1) barnes (0.0.9) multi_json (~> 1) statsd-ruby (~> 1.1) + base64 (0.2.0) batch-loader (1.5.0) - bcrypt (3.1.19) - better_html (1.0.16) - actionview (>= 4.0) - activesupport (>= 4.0) + bcrypt (3.1.20) + better_html (2.1.1) + actionview (>= 6.0) + activesupport (>= 6.0) ast (~> 2.0) erubi (~> 1.4) - html_tokenizer (~> 0.0.6) parser (>= 2.4) smart_properties + bigdecimal (3.1.8) bindex (0.8.1) - bootsnap (1.14.0) + bootsnap (1.18.3) msgpack (~> 1.2) browser (2.7.1) - builder (3.2.4) + builder (3.3.0) + bullet (7.2.0) + activesupport (>= 3.0.0) + uniform_notifier (~> 1.11) byebug (11.1.3) - capybara (3.39.2) + capybara (3.40.0) addressable matrix mini_mime (>= 0.1.3) - nokogiri (~> 1.8) + nokogiri (~> 1.11) rack (>= 1.6.0) rack-test (>= 0.6.3) regexp_parser (>= 1.5, < 3.0) xpath (~> 3.2) - carrierwave (2.2.4) + carrierwave (2.2.6) activemodel (>= 5.0.0) activesupport (>= 5.0.0) addressable (~> 2.6) @@ -363,48 +350,83 @@ GEM cells-rails (0.1.5) actionpack (>= 5.0) cells (>= 4.1.6, < 5.0.0) - charlock_holmes (0.7.7) - chef-utils (18.2.7) + charlock_holmes (0.7.9) + chef-utils (18.1.0) concurrent-ruby - childprocess (3.0.0) - coercible (1.0.0) - descendants_tracker (~> 0.0.1) - coffee-rails (5.0.0) - coffee-script (>= 2.2.0) - railties (>= 5.2.0) - coffee-script (2.4.1) - coffee-script-source - execjs - coffee-script-source (1.12.2) + cmdparse (3.0.7) + codecov (0.2.12) + json + simplecov colorize (0.8.1) - concurrent-ruby (1.2.2) - connection_pool (2.3.0) - crack (0.4.5) + commonmarker (0.23.10) + concurrent-ruby (1.3.4) + connection_pool (2.4.1) + crack (1.0.0) + bigdecimal rexml crass (1.0.6) - css_parser (1.14.0) + css_parser (1.19.1) addressable - dalli (3.2.3) - database_cleaner (2.0.1) - database_cleaner-active_record (~> 2.0.0) - database_cleaner-active_record (2.0.1) + csv (3.3.0) + dalli (3.2.8) + database_cleaner (2.0.2) + database_cleaner-active_record (>= 2, < 3) + database_cleaner-active_record (2.1.0) activerecord (>= 5.a) database_cleaner-core (~> 2.0.0) database_cleaner-core (2.0.1) - date (3.3.3) - date_validator (0.9.0) - activemodel - activesupport - db-query-matchers (0.10.0) - activesupport (>= 4.0, < 7) - rspec (~> 3.0) - decidim-decidim_awesome (0.8.3) - decidim-admin (>= 0.25.0, < 0.27) - decidim-core (>= 0.25.0, < 0.27) - sassc (~> 2.3) - decidim-navigation_maps (1.3.4) - decidim-admin (>= 0.25, < 0.27) - decidim-core (>= 0.25, < 0.27) + date (3.3.4) + date_validator (0.12.0) + activemodel (>= 3) + activesupport (>= 3) + decidim-dev (0.28.4) + bullet (~> 7.0) + byebug (~> 11.0) + capybara (~> 3.39) + decidim (= 0.28.4) + erb_lint (~> 0.4.0) + factory_bot_rails (~> 6.2) + faker (~> 3.2) + i18n-tasks (~> 1.0) + nokogiri (~> 1.14, >= 1.14.3) + parallel_tests (~> 4.2) + puma (~> 6.2, >= 6.3.1) + rails-controller-testing (~> 1.0) + rspec (~> 3.12) + rspec-cells (~> 0.3.7) + rspec-html-matchers (~> 0.10) + rspec-rails (~> 6.0) + rspec-retry (~> 0.6.2) + rspec_junit_formatter (~> 0.6.0) + rubocop (~> 1.50.0) + rubocop-faker (~> 1.1) + rubocop-rails (~> 2.19) + rubocop-rspec (~> 2.20) + selenium-webdriver (~> 4.9) + simplecov (~> 0.22.0) + simplecov-cobertura (~> 2.1.0) + spring (~> 2.0) + spring-watcher-listen (~> 2.0) + w3c_rspec_validators (~> 0.3.0) + webmock (~> 3.18) + wisper-rspec (~> 1.0) + decidim-initiatives (0.28.4) + decidim-admin (= 0.28.4) + decidim-comments (= 0.28.4) + decidim-core (= 0.28.4) + decidim-verifications (= 0.28.4) + hexapdf (~> 0.32.0) + wicked_pdf (~> 2.1) + wkhtmltopdf-binary (~> 0.12) + decidim-sortitions (0.28.4) + decidim-admin (= 0.28.4) + decidim-comments (= 0.28.4) + decidim-core (= 0.28.4) + decidim-proposals (= 0.28.4) + decidim-templates (0.28.4) + decidim-core (= 0.28.4) + decidim-forms (= 0.28.4) + decidim-proposals (= 0.28.4) declarative-builder (0.1.0) declarative-option (< 0.2.0) declarative-option (0.1.0) @@ -414,9 +436,7 @@ GEM polyglot railties (>= 5.2) rainbow (>= 2.1.0) - descendants_tracker (0.0.4) - thread_safe (~> 0.3, >= 0.3.1) - devise (4.9.2) + devise (4.9.4) bcrypt (~> 3.0) orm_adapter (~> 0.1) railties (>= 4.1.0) @@ -424,110 +444,124 @@ GEM warden (~> 1.2.3) devise-i18n (1.11.0) devise (>= 4.9.0) - devise_invitable (2.0.8) + devise_invitable (2.0.9) actionmailer (>= 5.0) devise (>= 4.6) - diff-lcs (1.5.0) + diff-lcs (1.5.1) diffy (3.4.2) - doc2text (0.4.6) - nokogiri (>= 1.13.2, < 1.15.0) + doc2text (0.4.7) + nokogiri (>= 1.13.2, < 1.17.0) rubyzip (~> 2.3.0) docile (1.4.0) - doorkeeper (5.6.6) + doorkeeper (5.7.1) railties (>= 5) doorkeeper-i18n (4.0.1) - dotenv (2.8.1) - dotenv-rails (2.8.1) - dotenv (= 2.8.1) - railties (>= 3.2) - dumb_delegator (1.0.0) - equalizer (0.0.11) - erb_lint (0.0.37) + dotenv (3.1.0) + dotenv-rails (3.1.0) + dotenv (= 3.1.0) + railties (>= 6.1) + erb_lint (0.4.0) activesupport - better_html (~> 1.0.7) - html_tokenizer + better_html (>= 2.0.1) parser (>= 2.7.1.4) rainbow rubocop smart_properties erbse (0.1.4) temple - erubi (1.12.0) - excon (0.100.0) - execjs (2.8.1) - factory_bot (4.11.1) - activesupport (>= 3.0.0) - factory_bot_rails (4.11.1) - factory_bot (~> 4.11.1) - railties (>= 3.0.0) - faker (2.23.0) + erubi (1.13.0) + escape_utils (1.2.2) + excon (0.112.0) + extended-markdown-filter (0.7.0) + html-pipeline (~> 2.9) + factory_bot (6.5.0) + activesupport (>= 5.0.0) + factory_bot_rails (6.4.3) + factory_bot (~> 6.4) + railties (>= 5.0.0) + faker (3.2.3) i18n (>= 1.8.11, < 2) - faraday (2.7.10) - faraday-net_http (>= 2.0, < 3.1) - ruby2_keywords (>= 0.0.4) - faraday-net_http (3.0.2) - ffi (1.15.5) - file_validators (2.3.0) + faraday (2.12.0) + faraday-net_http (>= 2.0, < 3.4) + json + logger + faraday-net_http (3.3.0) + net-http + ffi (1.16.3) + file_validators (3.0.0) activemodel (>= 3.2) mime-types (>= 1.0) - fog-aws (3.15.0) - fog-core (~> 2.1) - fog-json (~> 1.1) - fog-xml (~> 0.1) - fog-core (2.3.0) + fog-core (2.5.0) builder excon (~> 0.71) formatador (>= 0.2, < 2.0) mime-types - fog-json (1.2.0) - fog-core - multi_json (~> 1.10) fog-local (0.8.0) fog-core (>= 1.27, < 3.0) - fog-xml (0.1.4) - fog-core - nokogiri (>= 1.5.11, < 2.0.0) + foreman (0.87.2) formatador (1.1.0) foundation_rails_helper (4.0.1) actionpack (>= 4.1, < 7.1) activemodel (>= 4.1, < 7.1) activesupport (>= 4.1, < 7.1) railties (>= 4.1, < 7.1) - geocoder (1.7.5) + gemoji (3.0.1) + geocoder (1.8.3) + base64 (>= 0.1.0) + csv (>= 3.0.0) + geom2d (0.4.1) get_process_mem (0.2.7) ffi (~> 1.0) - globalid (1.1.0) - activesupport (>= 5.0) - graphql (1.12.24) - hashdiff (1.0.1) + globalid (1.2.1) + activesupport (>= 6.1) + graphql (2.0.31) + base64 + graphql-docs (3.0.1) + commonmarker (~> 0.16) + escape_utils (~> 1.2.2) + extended-markdown-filter (~> 0.4) + gemoji (~> 3.0) + graphql (~> 2.0) + html-pipeline (~> 2.9) + sass (~> 3.4) + hashdiff (1.1.1) hashie (5.0.0) - highline (2.1.0) - html_tokenizer (0.0.7) + hexapdf (0.32.2) + cmdparse (~> 3.0, >= 3.0.3) + geom2d (~> 0.3) + openssl (>= 2.2.1) + highline (3.1.1) + reline + html-pipeline (2.14.3) + activesupport (>= 2) + nokogiri (>= 1.4) htmlentities (4.3.4) - i18n (1.14.1) + i18n (1.14.6) concurrent-ruby (~> 1.0) - i18n-tasks (0.9.37) + i18n-tasks (1.0.14) activesupport (>= 4.0.2) ast (>= 2.1.0) erubi highline (>= 2.0.0) i18n - parser (>= 2.2.3.0) + parser (>= 3.2.2.1) rails-i18n rainbow (>= 2.2.2, < 4.0) terminal-table (>= 1.5.1) - icalendar (2.8.0) + icalendar (2.10.3) ice_cube (~> 0.16) - ice_cube (0.16.4) - ice_nine (0.11.2) - image_processing (1.12.2) + ostruct + ice_cube (0.17.0) + image_processing (1.13.0) mini_magick (>= 4.9.5, < 5) ruby-vips (>= 2.0.17, < 3) invisible_captcha (0.13.0) rails (>= 3.2.0) - jmespath (1.6.1) - json (2.6.3) - jwt (2.7.1) + io-console (0.7.2) + jmespath (1.6.2) + json (2.7.2) + jwt (2.9.3) + base64 kaminari (1.2.2) activesupport (>= 4.1.0) kaminari-actionview (= 1.2.2) @@ -544,32 +578,33 @@ GEM rexml kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) - launchy (2.5.0) - addressable (~> 2.7) - letter_opener (1.8.1) + launchy (2.5.2) + addressable (~> 2.8) + letter_opener (1.9.0) launchy (>= 2.2, < 3) letter_opener_web (2.0.0) actionmailer (>= 5.2) letter_opener (~> 1.7) railties (>= 5.2) rexml - listen (3.7.1) + listen (3.9.0) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) - lograge (0.12.0) + logger (1.6.1) + lograge (0.14.0) actionpack (>= 4) activesupport (>= 4) railties (>= 4) request_store (~> 1.0) - loofah (2.3.1) + loofah (2.22.0) crass (~> 1.0.2) - nokogiri (>= 1.5.9) + nokogiri (>= 1.12.0) mail (2.8.1) mini_mime (>= 0.1.1) net-imap net-pop net-smtp - marcel (1.0.2) + marcel (1.0.4) matrix (0.4.2) mdl (0.12.0) kramdown (~> 2.3) @@ -577,35 +612,39 @@ GEM mixlib-cli (~> 2.1, >= 2.1.1) mixlib-config (>= 2.2.1, < 4) mixlib-shellout - method_source (1.0.0) - mime-types (3.4.1) + method_source (1.1.0) + mime-types (3.6.0) + logger mime-types-data (~> 3.2015) - mime-types-data (3.2023.0218.1) - mini_magick (4.12.0) - mini_mime (1.1.2) - minitest (5.18.1) + mime-types-data (3.2024.1001) + mini_magick (4.13.2) + mini_mime (1.1.5) + minitest (5.25.1) mixlib-cli (2.1.8) mixlib-config (3.0.27) tomlrb mixlib-shellout (3.2.7) chef-utils - msgpack (1.6.0) + msgpack (1.7.2) multi_json (1.15.0) multi_xml (0.6.0) - mustache (1.1.1) - net-imap (0.3.6) + net-http (0.4.1) + uri + net-imap (0.4.17) date net-protocol net-pop (0.1.2) net-protocol - net-protocol (0.2.1) + net-protocol (0.2.2) timeout - net-smtp (0.3.3) + net-smtp (0.3.4) net-protocol - nio4r (2.5.9) - nokogiri (1.14.5-arm64-darwin) + nio4r (2.7.3) + nokogiri (1.16.7-aarch64-linux) racc (~> 1.4) - nokogiri (1.14.5-x86_64-linux) + nokogiri (1.16.7-arm64-darwin) + racc (~> 1.4) + nokogiri (1.16.7-x86_64-linux) racc (~> 1.4) oauth (1.1.0) oauth-tty (~> 1.0, >= 1.0.1) @@ -620,98 +659,108 @@ GEM rack (>= 1.2, < 4) snaky_hash (~> 2.0) version_gem (~> 1.1) - omniauth (2.1.1) + omniauth (2.1.2) hashie (>= 3.4.6) rack (>= 2.2.3) rack-protection omniauth-facebook (5.0.0) omniauth-oauth2 (~> 1.2) - omniauth-google-oauth2 (1.1.1) - jwt (>= 2.0) - oauth2 (~> 2.0.6) + omniauth-google-oauth2 (1.2.0) + jwt (>= 2.9) + oauth2 (~> 2.0) omniauth (~> 2.0) - omniauth-oauth2 (~> 1.8.0) - omniauth-oauth (1.2.0) + omniauth-oauth2 (~> 1.8) + omniauth-oauth (1.2.1) oauth omniauth (>= 1.0, < 3) + rack (>= 1.6.2, < 4) omniauth-oauth2 (1.8.0) oauth2 (>= 1.4, < 3) omniauth (~> 2.0) - omniauth-rails_csrf_protection (1.0.1) + omniauth-rails_csrf_protection (1.0.2) actionpack (>= 4.2) omniauth (~> 2.0) omniauth-twitter (1.4.0) omniauth-oauth (~> 1.1) rack + openssl (3.2.0) origami (2.1.0) colorize (~> 0.7) orm_adapter (0.5.0) + ostruct (0.6.0) paper_trail (12.3.0) activerecord (>= 5.2) request_store (~> 1.1) - parallel (1.22.1) - parser (3.1.2.1) + parallel (1.26.3) + parallel_tests (4.7.2) + parallel + parser (3.3.5.0) ast (~> 2.4.1) - pg (1.1.4) - pg_search (2.3.6) - activerecord (>= 5.2) - activesupport (>= 5.2) + racc + pg (1.4.6) + pg_search (2.3.7) + activerecord (>= 6.1) + activesupport (>= 6.1) polyglot (0.3.5) - premailer (1.21.0) + premailer (1.27.0) addressable - css_parser (>= 1.12.0) + css_parser (>= 1.19.0) htmlentities (>= 4.0.0) premailer-rails (1.12.0) actionmailer (>= 3) net-smtp premailer (~> 1.7, >= 1.7.9) - progressbar (1.11.0) - public_suffix (5.0.3) - puma (5.6.5) + progressbar (1.13.0) + psych (4.0.6) + stringio + public_suffix (6.0.1) + puma (6.4.2) nio4r (~> 2.0) puma_worker_killer (0.3.1) get_process_mem (~> 0.2) puma (>= 2.7) - racc (1.7.1) - rack (2.2.7) - rack-attack (6.6.1) - rack (>= 1.0, < 3) + racc (1.8.1) + rack (2.2.10) + rack-attack (6.7.0) + rack (>= 1.0, < 4) rack-cors (1.1.1) rack (>= 2.0.0) - rack-protection (3.0.6) - rack - rack-proxy (0.7.6) + rack-protection (3.2.0) + base64 (>= 0.1.0) + rack (~> 2.2, >= 2.2.4) + rack-proxy (0.7.7) rack rack-ssl-enforcer (0.2.9) rack-test (2.1.0) rack (>= 1.3) rack-timeout (0.6.3) rack_password (1.3) - rails (6.0.6.1) - actioncable (= 6.0.6.1) - actionmailbox (= 6.0.6.1) - actionmailer (= 6.0.6.1) - actionpack (= 6.0.6.1) - actiontext (= 6.0.6.1) - actionview (= 6.0.6.1) - activejob (= 6.0.6.1) - activemodel (= 6.0.6.1) - activerecord (= 6.0.6.1) - activestorage (= 6.0.6.1) - activesupport (= 6.0.6.1) - bundler (>= 1.3.0) - railties (= 6.0.6.1) + rails (6.1.7.9) + actioncable (= 6.1.7.9) + actionmailbox (= 6.1.7.9) + actionmailer (= 6.1.7.9) + actionpack (= 6.1.7.9) + actiontext (= 6.1.7.9) + actionview (= 6.1.7.9) + activejob (= 6.1.7.9) + activemodel (= 6.1.7.9) + activerecord (= 6.1.7.9) + activestorage (= 6.1.7.9) + activesupport (= 6.1.7.9) + bundler (>= 1.15.0) + railties (= 6.1.7.9) sprockets-rails (>= 2.0.0) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) activesupport (>= 5.0.1.rc1) - rails-dom-testing (2.1.1) + rails-dom-testing (2.2.0) activesupport (>= 5.0.0) minitest nokogiri (>= 1.6) - rails-html-sanitizer (1.4.3) - loofah (~> 2.3) + rails-html-sanitizer (1.6.0) + loofah (~> 2.21) + nokogiri (~> 1.14) rails-i18n (6.0.0) i18n (>= 0.7, < 2) railties (>= 6.0.0, < 7) @@ -721,174 +770,177 @@ GEM rails_autoscale_agent (0.12.0) rails_serve_static_assets (0.0.5) rails_stdout_logging (0.0.5) - railties (6.0.6.1) - actionpack (= 6.0.6.1) - activesupport (= 6.0.6.1) + railties (6.1.7.9) + actionpack (= 6.1.7.9) + activesupport (= 6.1.7.9) method_source - rake (>= 0.8.7) - thor (>= 0.20.3, < 2.0) + rake (>= 12.2) + thor (~> 1.0) rainbow (3.1.1) - rake (13.0.6) - ransack (2.4.2) - activerecord (>= 5.2.4) - activesupport (>= 5.2.4) + rake (13.2.1) + ransack (3.2.1) + activerecord (>= 6.1.5) + activesupport (>= 6.1.5) i18n rb-fsevent (0.11.2) - rb-inotify (0.10.1) + rb-inotify (0.11.1) ffi (~> 1.0) - rectify (0.13.0) - activemodel (>= 4.1.0) - activerecord (>= 4.1.0) - activesupport (>= 4.1.0) - virtus (~> 1.0.5) - wisper (>= 1.6.1) redcarpet (3.6.0) redis (4.8.1) - redis-client (0.11.2) + redis-client (0.21.0) connection_pool - regexp_parser (2.6.1) + regexp_parser (2.9.2) + reline (0.5.10) + io-console (~> 0.5) request_store (1.5.1) rack (>= 1.4) - responders (3.1.0) + responders (3.1.1) actionpack (>= 5.2) railties (>= 5.2) - rexml (3.2.5) - rspec (3.12.0) - rspec-core (~> 3.12.0) - rspec-expectations (~> 3.12.0) - rspec-mocks (~> 3.12.0) - rspec-cells (0.3.8) + rexml (3.3.8) + rspec (3.13.0) + rspec-core (~> 3.13.0) + rspec-expectations (~> 3.13.0) + rspec-mocks (~> 3.13.0) + rspec-cells (0.3.9) cells (>= 4.0.0, < 6.0.0) - rspec-rails (>= 3.0.0, < 6.1.0) - rspec-core (3.12.0) - rspec-support (~> 3.12.0) - rspec-expectations (3.12.0) + rspec-rails (>= 3.0.0, < 6.2.0) + rspec-core (3.13.0) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) - rspec-html-matchers (0.9.4) + rspec-support (~> 3.13.0) + rspec-html-matchers (0.10.0) nokogiri (~> 1) - rspec (>= 3.0.0.a, < 4) - rspec-mocks (3.12.0) + rspec (>= 3.0.0.a) + rspec-mocks (3.13.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.12.0) - rspec-rails (4.1.2) - actionpack (>= 4.2) - activesupport (>= 4.2) - railties (>= 4.2) - rspec-core (~> 3.10) - rspec-expectations (~> 3.10) - rspec-mocks (~> 3.10) - rspec-support (~> 3.10) + rspec-support (~> 3.13.0) + rspec-rails (6.1.5) + actionpack (>= 6.1) + activesupport (>= 6.1) + railties (>= 6.1) + rspec-core (~> 3.13) + rspec-expectations (~> 3.13) + rspec-mocks (~> 3.13) + rspec-support (~> 3.13) rspec-retry (0.6.2) rspec-core (> 3.3) - rspec-support (3.12.0) - rspec_junit_formatter (0.3.0) + rspec-support (3.13.1) + rspec_junit_formatter (0.6.0) rspec-core (>= 2, < 4, != 2.12.0) - rubocop (0.92.0) + rubocop (1.50.2) + json (~> 2.3) parallel (~> 1.10) - parser (>= 2.7.1.5) + parser (>= 3.2.0.0) rainbow (>= 2.2.2, < 4.0) - regexp_parser (>= 1.7) - rexml - rubocop-ast (>= 0.5.0) + regexp_parser (>= 1.8, < 3.0) + rexml (>= 3.2.5, < 4.0) + rubocop-ast (>= 1.28.0, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (>= 1.4.0, < 2.0) - rubocop-ast (1.23.0) - parser (>= 3.1.1.0) + unicode-display_width (>= 2.4.0, < 3.0) + rubocop-ast (1.32.3) + parser (>= 3.3.1.0) + rubocop-capybara (2.21.0) + rubocop (~> 1.41) rubocop-faker (1.1.0) faker (>= 2.12.0) rubocop (>= 0.82.0) - rubocop-rails (2.9.1) + rubocop-rails (2.25.1) activesupport (>= 4.2.0) rack (>= 1.1) - rubocop (>= 0.90.0, < 2.0) - rubocop-rspec (1.43.2) - rubocop (~> 0.87) - ruby-progressbar (1.11.0) - ruby-vips (2.1.4) + rubocop (>= 1.33.0, < 2.0) + rubocop-ast (>= 1.31.1, < 2.0) + rubocop-rspec (2.20.0) + rubocop (~> 1.33) + rubocop-capybara (~> 2.17) + ruby-progressbar (1.13.0) + ruby-vips (2.2.2) ffi (~> 1.12) - ruby2_keywords (0.0.5) - rubyXL (3.4.25) + logger + rubyXL (3.4.27) nokogiri (>= 1.10.8) rubyzip (>= 1.3.0) rubyzip (2.3.2) + sass (3.7.4) + sass-listen (~> 4.0.0) + sass-listen (4.0.0) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) sassc (2.4.0) ffi (~> 1.9) - scout_apm (5.3.2) + scout_apm (5.3.7) parser - searchlight (4.1.0) - selenium-webdriver (3.142.7) - childprocess (>= 0.5, < 4.0) - rubyzip (>= 1.2.2) + selenium-webdriver (4.25.0) + base64 (~> 0.2) + logger (~> 1.4) + rexml (~> 3.2, >= 3.2.5) + rubyzip (>= 1.2.2, < 3.0) + websocket (~> 1.0) semantic_range (3.0.0) - sentry-rails (5.6.0) + sentry-rails (5.16.1) railties (>= 5.0) - sentry-ruby (~> 5.6.0) - sentry-ruby (5.6.0) + sentry-ruby (~> 5.16.1) + sentry-ruby (5.16.1) concurrent-ruby (~> 1.0, >= 1.0.2) - sentry-sidekiq (5.6.0) - sentry-ruby (~> 5.6.0) + sentry-sidekiq (5.16.1) + sentry-ruby (~> 5.16.1) sidekiq (>= 3.0) - seven_zip_ruby (1.3.0) - sidekiq (7.0.1) + shakapacker (7.1.0) + activesupport (>= 5.2) + rack-proxy (>= 0.6.1) + railties (>= 5.2) + semantic_range (>= 2.3.0) + sidekiq (7.2.2) concurrent-ruby (< 2) connection_pool (>= 2.3.0) rack (>= 2.2.4) - redis-client (>= 0.9.0) - simplecov (0.19.1) + redis-client (>= 0.19.0) + simplecov (0.22.0) docile (~> 1.1) simplecov-html (~> 0.11) - simplecov-cobertura (1.3.1) - simplecov (~> 0.8) + simplecov_json_formatter (~> 0.1) + simplecov-cobertura (2.1.0) + rexml + simplecov (~> 0.19) simplecov-html (0.12.3) + simplecov_json_formatter (0.1.4) 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 (4.1.0) - spring-commands-rspec (1.0.4) - spring (>= 0.9.1) - spring-watcher-listen (2.1.0) + spring (2.1.1) + spring-watcher-listen (2.0.1) listen (>= 2.7, < 4.0) - spring (>= 4) - sprockets (4.2.0) + spring (>= 1.2, < 3.0) + sprockets (4.2.1) concurrent-ruby (~> 1.0) rack (>= 2.2.4, < 4) - sprockets-rails (3.4.2) - actionpack (>= 5.2) - activesupport (>= 5.2) + sprockets-rails (3.5.2) + actionpack (>= 6.1) + activesupport (>= 6.1) sprockets (>= 3.0.0) - ssrf_filter (1.1.1) + ssrf_filter (1.1.2) + stackprof (0.2.26) statsd-ruby (1.5.0) - system_test_html_screenshots (0.2.0) - actionpack (>= 5.2, < 6.1.a) - temple (0.10.2) + stringio (3.1.1) + temple (0.10.3) terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) - thor (1.2.2) - thread_safe (0.3.6) - tilt (2.2.0) - timeout (0.4.0) + thor (1.3.2) + tilt (2.4.0) + timeout (0.4.1) tomlrb (2.0.3) - tzinfo (1.2.11) - thread_safe (~> 0.1) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) uber (0.1.0) - uglifier (4.2.0) - execjs (>= 0.3.0, < 3) - unicode-display_width (1.8.0) - valid_email2 (2.3.1) + unicode-display_width (2.6.0) + uniform_notifier (1.16.0) + uri (0.13.1) + valid_email2 (4.0.6) activemodel (>= 3.2) mail (~> 2.5) - version_gem (1.1.3) - virtus (1.0.5) - axiom-types (~> 0.1) - coercible (~> 1.0) - descendants_tracker (~> 0.0, >= 0.0.3) - equalizer (~> 0.0, >= 0.0.9) - virtus-multiparams (0.1.1) - virtus (~> 1.0) + version_gem (1.1.4) w3c_rspec_validators (0.3.0) rails rspec @@ -899,36 +951,35 @@ GEM rexml (~> 3.2) warden (1.2.9) rack (>= 2.0.9) - web-console (4.2.0) + web-console (4.2.1) actionview (>= 6.0.0) activemodel (>= 6.0.0) bindex (>= 0.4.0) railties (>= 6.0.0) - webmock (3.18.1) + web-push (3.0.1) + jwt (~> 2.0) + openssl (~> 3.0) + webmock (3.24.0) addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) - webpacker (6.0.0.rc.5) - activesupport (>= 5.2) - rack-proxy (>= 0.6.1) - railties (>= 5.2) - semantic_range (>= 2.3.0) - websocket-driver (0.7.5) + websocket (1.2.11) + websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) - wicked (1.4.0) - railties (>= 3.0.7) - wicked_pdf (2.6.3) + wicked_pdf (2.7.0) activesupport wisper (2.0.1) wisper-rspec (1.1.0) wkhtmltopdf-binary (0.12.6.6) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.6.8) + zeitwerk (2.6.18) PLATFORMS + aarch64-linux arm64-darwin-21 + arm64-darwin-23 x86_64-linux DEPENDENCIES @@ -936,27 +987,32 @@ DEPENDENCIES barnes bootsnap byebug + codecov dalli database_cleaner decidim! decidim-census_sms! decidim-dataviz! - decidim-decidim_awesome (~> 0.8.3) - decidim-dev! + decidim-decidim_awesome! + decidim-dev (= 0.28.4) decidim-ephemeral_participation! - decidim-initiatives! - decidim-navigation_maps (~> 1.3.3) - decidim-sortitions! + decidim-initiatives (= 0.28.4) + decidim-internal_evaluation! + decidim-kids! + decidim-navigation_maps! + decidim-sortitions (= 0.28.4) decidim-stats! + decidim-templates (= 0.28.4) decidim-term_customizer! decidim-valid_auth! - deface dotenv-rails - faker (~> 2.14) - fog-aws + faker + foreman letter_opener_web listen lograge + matrix + mdl origami progressbar puma @@ -966,25 +1022,22 @@ DEPENDENCIES rack_password rails_12factor rails_autoscale_agent + rexml rspec - rubocop (~> 0.92.0) + rubocop rubocop-faker scout_apm sentry-rails sentry-ruby sentry-sidekiq sidekiq - spring - spring-commands-rspec - spring-watcher-listen - uglifier - virtus-multiparams + stackprof web-console - wicked_pdf + wicked_pdf (< 2.8) wkhtmltopdf-binary RUBY VERSION - ruby 2.7.5p203 + ruby 3.1.1p18 BUNDLED WITH - 2.3.5 + 2.4.14 diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md deleted file mode 100644 index ac04d6d69c..0000000000 --- a/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,12 +0,0 @@ -#### :tophat: User Story - - -#### :clipboard: Related documentation - - -#### :dart: Acceptance criteria - - -#### :pushpin: Related issues - - diff --git a/Procfile.dev b/Procfile.dev new file mode 100644 index 0000000000..01fcc9f183 --- /dev/null +++ b/Procfile.dev @@ -0,0 +1,2 @@ +web: bin/rails server -b 0.0.0.0 -p 3000 +shakapacker: bin/shakapacker-dev-server diff --git a/README.md b/README.md index 5e4adebbc3..e0f0df906a 100644 --- a/README.md +++ b/README.md @@ -4,25 +4,23 @@ --- -Citizen Participation and Open Government Application. - -[![Build Status](https://img.shields.io/travis/AjuntamentdeBarcelona/decidim-barcelona/master.svg)](https://travis-ci.org/AjuntamentdeBarcelona/decidim-barcelona) -[![codecov](https://codecov.io/gh/AjuntamentdeBarcelona/decidim-barcelona/branch/master/graph/badge.svg)](https://codecov.io/gh/AjuntamentdeBarcelona/decidim-barcelona) +Citizen Participation and Open Government Application. + +[![[CI] Lint](https://github.com/AjuntamentdeBarcelona/decidim-barcelona/actions/workflows/lint.yml/badge.svg)](https://github.com/AjuntamentdeBarcelona/decidim-barcelona/actions/workflows/lint.yml) +[![[CI] Test](https://github.com/AjuntamentdeBarcelona/decidim-barcelona/actions/workflows/test.yml/badge.svg)](https://github.com/AjuntamentdeBarcelona/decidim-barcelona/actions/workflows/test.yml) +[![[CI] Test Census SMS](https://github.com/AjuntamentdeBarcelona/decidim-barcelona/actions/workflows/test_census_sms.yml/badge.svg)](https://github.com/AjuntamentdeBarcelona/decidim-barcelona/actions/workflows/test_census_sms.yml) +[![[CI] Test Ephemeral Participation](https://github.com/AjuntamentdeBarcelona/decidim-barcelona/actions/workflows/test_ephemeral_participation.yml/badge.svg)](https://github.com/AjuntamentdeBarcelona/decidim-barcelona/actions/workflows/test_ephemeral_participation.yml) +[![[CI] Test Stats](https://github.com/AjuntamentdeBarcelona/decidim-barcelona/actions/workflows/test_stats.yml/badge.svg)](https://github.com/AjuntamentdeBarcelona/decidim-barcelona/actions/workflows/test_stats.yml) +[![[CI] Test Valid Auth](https://github.com/AjuntamentdeBarcelona/decidim-barcelona/actions/workflows/test_valid_auth.yml/badge.svg)](https://github.com/AjuntamentdeBarcelona/decidim-barcelona/actions/workflows/test_valid_auth.yml) [![Code Climate](https://codeclimate.com/github/AjuntamentdeBarcelona/decidim-barcelona/badges/gpa.svg)](https://codeclimate.com/github/AjuntamentdeBarcelona/decidim-barcelona) -[![Dependency Status](https://gemnasium.com/AjuntamentdeBarcelona/decidim-barcelona.svg)](https://gemnasium.com/AjuntamentdeBarcelona/decidim-barcelona) This is the opensource code repository for "decidim-barcelona", based on [Decidim](https://github.com/AjuntamentdeBarcelona/decidim). -## Upgrade notes - -- `app/views/layouts/decidim/widget.html.erb` modify the embed to remove organization's logo. -- `app/stylesheets/decidim/email.css`, customizes the email template style of Decidim. Be careful in later updates to prevent changes in style. - ## Development environment setup You can setup everything with Docker & Docker compose, run: -``` +```bash docker-compose build docker-compose run --rm app bundle exec rake db:create db:schema:load db:seed docker-compose up diff --git a/Rakefile b/Rakefile index db2ebc6e47..bf012913fa 100644 --- a/Rakefile +++ b/Rakefile @@ -68,7 +68,7 @@ namespace :decidim_surveys_patch do puts "Migrating question #{survey_question.id}..." question = Decidim::Forms::Question.create!( - questionnaire: questionnaire, + questionnaire:, position: survey_question.position, question_type: survey_question.question_type, mandatory: survey_question.mandatory, @@ -84,7 +84,7 @@ namespace :decidim_surveys_patch do AnswerOption.where(decidim_survey_question_id: survey_question.id).find_each do |survey_answer_option| answer_option_mapping[survey_answer_option.id] = Decidim::Forms::AnswerOption.create!( - question: question, + question:, body: survey_answer_option.body, free_text: survey_answer_option.free_text ) @@ -92,8 +92,8 @@ namespace :decidim_surveys_patch do Answer.where(decidim_survey_id: survey.id, decidim_survey_question_id: survey_question.id).find_each do |survey_answer| answer = Decidim::Forms::Answer.new( - questionnaire: questionnaire, - question: question, + questionnaire:, + question:, decidim_user_id: survey_answer.decidim_user_id, body: survey_answer.body, created_at: survey_answer.created_at, diff --git a/app.json b/app.json deleted file mode 100644 index 32a957ed0f..0000000000 --- a/app.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "decidim-barcelona", - "description": "TODO: Add a short description about decidim-barcelona", - "keywords": [], - "addons": [ - "heroku-postgresql:hobby-dev", - "heroku-redis:hobby-dev", - "sendgrid:starter" - ], - "stack": "heroku-18", - "scripts": { - "postdeploy":"DISABLE_DATABASE_ENVIRONMENT_CHECK=1 bundle exec rake db:schema:load db:migrate db:seed" - }, - "env": { - "SECRET_KEY_BASE": { - "description": "A secret used by Rails to identify sessions", - "generator": "secret" - }, - "CENSUS_URL": { - "required": true - }, - "AWS_ACCESS_KEY_ID": { - "required": true - }, - "AWS_SECRET_ACCESS_KEY": { - "required": true - }, - "ANALYTICS": { - "required": true - }, - "HERE_API_KEY": { - "required": true - }, - "HEROKU_APP_NAME": { - "required": true - } - } -} diff --git a/app/cells/census_kids_authorization_metadata_cell.rb b/app/cells/census_kids_authorization_metadata_cell.rb new file mode 100644 index 0000000000..9d01d6bb96 --- /dev/null +++ b/app/cells/census_kids_authorization_metadata_cell.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +# This cell is to render the census authorization metadata in the renew modal +class CensusKidsAuthorizationMetadataCell < CensusAuthorizationMetadataCell +end diff --git a/app/cells/census_sarria_sant_gervasi_authorization_metadata_cell.rb b/app/cells/census_sarria_sant_gervasi_authorization_metadata_cell.rb new file mode 100644 index 0000000000..037a51041c --- /dev/null +++ b/app/cells/census_sarria_sant_gervasi_authorization_metadata_cell.rb @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +# This cell is to render the census authorization metadata in the renew modal +class CensusSarriaSantGervasiAuthorizationMetadataCell < CensusAuthorizationMetadataCell +end diff --git a/app/cells/concerns/decidim/accountability/status_cell_override.rb b/app/cells/concerns/decidim/accountability/status_cell_override.rb new file mode 100644 index 0000000000..f1bc7b4f07 --- /dev/null +++ b/app/cells/concerns/decidim/accountability/status_cell_override.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module Decidim + module Accountability + module StatusCellOverride + extend ActiveSupport::Concern + + included do + include Decidim::Accountability::ApplicationHelper + include Decidim::Accountability::BreadcrumbHelper + + def scope + current_scope.presence if defined?(current_scope) + end + end + end + end +end diff --git a/app/cells/concerns/decidim/activities_cell_override.rb b/app/cells/concerns/decidim/activities_cell_override.rb index 4b8d69112a..83a53e0691 100644 --- a/app/cells/concerns/decidim/activities_cell_override.rb +++ b/app/cells/concerns/decidim/activities_cell_override.rb @@ -7,7 +7,17 @@ module ActivitiesCellOverride included do def activities @activities ||= last_activities.select do |activity| - activity.visible_for?(current_user) && (!activity.respond_to?(:component) || activity.component&.published?) + !activity.respond_to?(:component) || activity.component&.published? + end + end + + def last_activities + @last_activities ||= model.map do |activity| + activity.organization_lazy + activity.resource_lazy + activity.participatory_space_lazy + activity.component_lazy + activity end end end diff --git a/app/cells/concerns/decidim/initiatives/initiative_metadata_g_cell_override.rb b/app/cells/concerns/decidim/initiatives/initiative_metadata_g_cell_override.rb new file mode 100644 index 0000000000..fdb428a0a1 --- /dev/null +++ b/app/cells/concerns/decidim/initiatives/initiative_metadata_g_cell_override.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module Decidim + module Initiatives + module InitiativeMetadataGCellOverride + extend ActiveSupport::Concern + + included do + def progress_bar_item + return if %w(created validating discarded).include?(initiative.state) + + type_scope = initiative.votable_initiative_type_scopes[0] + + { + cell: "decidim/progress_bar", + args: [initiative.supports_count_for(type_scope.scope), { + total: initiative.supports_required_for(type_scope.scope), + element_id: "initiative-#{initiative.id}-votes-count", + class: "progress-bar__sm" + }], + icon: nil + } + end + end + end + end +end diff --git a/app/cells/concerns/decidim/user_profile_cell_override.rb b/app/cells/concerns/decidim/user_profile_cell_override.rb new file mode 100644 index 0000000000..c32f9a8493 --- /dev/null +++ b/app/cells/concerns/decidim/user_profile_cell_override.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Decidim + module UserProfileCellOverride + extend ActiveSupport::Concern + + included do + def resource_path + return "#" if user.nickname.blank? + + user.try(:profile_url) || decidim.profile_path(user.nickname) + end + end + end +end diff --git a/app/cells/decidim/accountability/result_l/extra_data.erb b/app/cells/decidim/accountability/result_l/extra_data.erb new file mode 100644 index 0000000000..bdd9e082dc --- /dev/null +++ b/app/cells/decidim/accountability/result_l/extra_data.erb @@ -0,0 +1,3 @@ +<% if component_settings.try(:display_progress_enabled?) && result.progress.present? && !Decidim::Accountability::Result.not_computable_results.include?(result.id) %> +
<%= display_percentage result.progress %>
+<% end %> diff --git a/app/cells/decidim/accountability/status/status.erb b/app/cells/decidim/accountability/status/status.erb new file mode 100644 index 0000000000..1f871a5812 --- /dev/null +++ b/app/cells/decidim/accountability/status/status.erb @@ -0,0 +1,20 @@ +<% if options[:show_category_image] %> + <%= image_pack_tag("media/images/category-#{model.id}.jpg") %> +<% end %> + +

<%= title %>

+ +<% if component_settings.display_progress_enabled? && progress.present? %> +
" aria-valuenow="<%= number_with_precision(progress, separator: ".", precision: 1) %>" aria-valuemin="0" aria-valuemax="100" aria-valuetext="<%= number_to_percentage(progress, precision: 1) %>"> +
+
+<% end %> + +
+ <% if progress.present? %> + <%= display_percentage progress %> + <% end %> + <% if count %> + <%= count %> + <% end %> +
diff --git a/app/cells/decidim/budgets/project_list_item/project_data.erb b/app/cells/decidim/budgets/project_list_item/project_data.erb deleted file mode 100644 index 9948bc4e2f..0000000000 --- a/app/cells/decidim/budgets/project_list_item/project_data.erb +++ /dev/null @@ -1,23 +0,0 @@ -
- <% if voting_finished? %> -
-
- <%= t("decidim.budgets.projects.show.budget") %> - <%= budget_to_currency model.budget_amount %> -
- - <%= cell("decidim/budgets/project_votes_count", model) %> - <%= cell("decidim/budgets/project_voted_hint", model, class: "display-block margin-top-1") %> -
- <% else %> - - <%= budget_to_currency(model.budget_amount) %> - - <%= cell("decidim/budgets/project_votes_count", model, layout: :one_line, class: "display-inline-block") %> - - <%= cell("decidim/budgets/project_voted_hint", model, class: "display-block margin-top-1") if current_order_checked_out? && resource_added? %> - - - <%= cell("decidim/budgets/project_vote_button", model) if !current_order_checked_out? && voting_open? %> - <% end %> -
diff --git a/app/cells/decidim/budgets/project_list_item/project_text.erb b/app/cells/decidim/budgets/project_list_item/project_text.erb deleted file mode 100644 index 662c95e5a2..0000000000 --- a/app/cells/decidim/budgets/project_list_item/project_text.erb +++ /dev/null @@ -1,22 +0,0 @@ -
-
- <%= link_to resource_path, class: "card__link" do %> -
- <%= cell("decidim/budgets/project_selected_status", model) %> - - <%= resource_title %> -
- <% end %> - -
- <%= cell "decidim/budgets/project_tags", model, context: { extra_classes: ["tags--project"] } %> -
- -
- <%= cell("decidim/budgets/project_votes_count", model, layout: :one_line) %> - <%= budget_to_currency(model.budget_amount) %> - - <%= cell("decidim/budgets/project_voted_hint", model, class: "margin-left-1") if current_order_checked_out? && resource_added? %> -
-
-
diff --git a/app/cells/decidim/initiatives/initiative_m/footer.erb b/app/cells/decidim/initiatives/initiative_m/footer.erb deleted file mode 100644 index 7edc001085..0000000000 --- a/app/cells/decidim/initiatives/initiative_m/footer.erb +++ /dev/null @@ -1,28 +0,0 @@ - diff --git a/app/cells/decidim/initiatives_votes/vote/show.erb b/app/cells/decidim/initiatives_votes/vote/show.erb index c04dfd4690..5541f8bb39 100644 --- a/app/cells/decidim/initiatives_votes/vote/show.erb +++ b/app/cells/decidim/initiatives_votes/vote/show.erb @@ -6,18 +6,20 @@
<%= initiative_title %>
-
- <%= name_and_surname %> -
-
- <%= document_number %> -
-
- <%= date_of_birth %> -
-
- <%= postal_code %> -
+ <% if collect_user_extra_fields %> +
+ <%= name_and_surname %> +
+
+ <%= document_number %> +
+
+ <%= date_of_birth %> +
+
+ <%= postal_code %> +
+ <% end %>
<%= time_and_date %>
diff --git a/app/cells/decidim/meetings/join_meeting_button/show.erb b/app/cells/decidim/meetings/join_meeting_button/show.erb index f379f98d09..80ef1e302e 100644 --- a/app/cells/decidim/meetings/join_meeting_button/show.erb +++ b/app/cells/decidim/meetings/join_meeting_button/show.erb @@ -1,19 +1,5 @@ <% if model.can_be_joined_by?(current_user) %> - <% if model.has_registration_for? current_user %> - - <%= icon("check", class: "icon--small") %> - <%= t("going", scope: "decidim.meetings.meetings.show") %> - - <%= action_authorized_button_to( - :join, - t("leave", scope: "decidim.meetings.meetings.show"), - meeting_registration_path(model), - resource: model, - method: :delete, - class: button_classes, - data: { disable: true, confirm: t("leave_confirmation", scope: "decidim.meetings.meetings.show") } - ) %> - <% else %> + <% unless model.has_registration_for? current_user %> <% if model.registration_form_enabled? %> <%= action_authorized_link_to( :join, @@ -23,19 +9,19 @@ disabled: !model.has_available_slots?, ) %> <% else %> - <%= render :registration_confirm %> + <%= render :registration_modal %> <%= action_authorized_button_to( :join, i18n_join_text, "#", class: button_classes, disabled: !model.has_available_slots?, - data: { open: current_user.present? ? "meeting-registration-confirm-#{model.id}" : "loginModal" } + data: { "dialog-open": current_user.present? ? "meeting-registration-confirm-#{model.id}" : "loginModal" } ) %> <% end %> <% end %> <% if shows_remaining_slots? %> - <%= t("remaining_slots", scope: "decidim.meetings.meetings.show", count: model.remaining_slots) %> + <%= render :remaining_slots %> <% end %> <% elsif model.on_different_platform? %> <%= link_to( diff --git a/app/cells/decidim/meetings/online_meeting_link/show.erb b/app/cells/decidim/meetings/online_meeting_link/show.erb index cf689fc4e7..0bdc526da5 100644 --- a/app/cells/decidim/meetings/online_meeting_link/show.erb +++ b/app/cells/decidim/meetings/online_meeting_link/show.erb @@ -1,44 +1,21 @@ -<% if online_meeting_url? %> - <% if live? || future? %> -
-
- <% if live? %> -
- <%= icon "audio", class: "heading4" %> -
-
- <%= t("live_event", scope: "decidim.meetings.meetings.show") %> - <% unless show_embed? %> -

<%= t("micro_camera_permissions_warning", scope: "decidim.meetings.meetings.show") %>

- <% end %> -
- <% end %> +
+ <%= icon "broadcast-line", class: "w-14 h-14 fill-current #{live? && online_meeting_url? ? "text-tertiary" : "text-gray"}" %> - <% if show_embed? && live? %> -
absolutes aspect-ratio-16-9" style="<%= "height: 1100px" if bcn_iframe? %>"> - <%== embed_code(request.host) %> -
- <% elsif live? || future? %> -
- <% if live? %> - <%= link_to t("join", scope: "decidim.meetings.meetings.show"), live_event_url, target: "_blank", class: "button button--sc" %> - <% elsif future? %> - <%= t("link_closed", scope: "decidim.meetings.meetings.show") %> - <% end %> -
- <% end %> + <% if !online_meeting_url? %> +

<%= t("link_available_soon", scope: "decidim.meetings.meetings.show") %>

+ <% elsif future? %> +

<%= t("link_closed", scope: "decidim.meetings.meetings.show") %>

+ <% elsif live? %> +

<%= t("live_event", scope: "decidim.meetings.meetings.show") %>

+ + <% if show_embed? %> + -
+ <% else %> +

<%= t("micro_camera_permissions_warning", scope: "decidim.meetings.meetings.show") %>

+ <% end %> + + <%= link_to t("join_meeting", scope: "decidim.meetings.meetings.meeting"), live_event_url, target: "_blank", class: "button button__xl button__secondary", data: { external_link: "text-only", external_domain_link: false } %> <% end %> -<% else %> -
-
-
- <%= icon "timer", role: "img", "aria-hidden": true, remove_icon_class: true, width: 40, height: 70 %> -
- <%= t("link_available_soon", scope: "decidim.meetings.meetings.show") %> -
-
-
-
-<% end %> +
diff --git a/app/commands/decidim/admin/publish_component.rb b/app/commands/decidim/admin/publish_component.rb new file mode 100644 index 0000000000..de18bb2dd9 --- /dev/null +++ b/app/commands/decidim/admin/publish_component.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +module Decidim + module Admin + # This command gets called when a component is published from the admin panel. + class PublishComponent < Decidim::Command + # Public: Initializes the command. + # + # component - The component to publish. + # current_user - the user performing the action + def initialize(component, current_user) + @component = component + @current_user = current_user + end + + # Public: Publishes the Component. + # + # Broadcasts :ok if published, :invalid otherwise. + def call + publish_component + publish_event + + broadcast(:ok) + end + + private + + attr_reader :component, :current_user + + def publish_component + Decidim.traceability.perform_action!( + :publish, + component, + current_user, + visibility: "all" + ) do + component.publish! + component + end + end + + def publish_event + Decidim::EventsManager.publish( + event: "decidim.events.components.component_published", + event_class: Decidim::ComponentPublishedEvent, + resource: component, + followers: component.participatory_space.followers + ) + end + end + end +end diff --git a/app/controllers/concerns/decidim/assemblies/assemblies_controller_override.rb b/app/controllers/concerns/decidim/assemblies/assemblies_controller_override.rb new file mode 100644 index 0000000000..cee4182e69 --- /dev/null +++ b/app/controllers/concerns/decidim/assemblies/assemblies_controller_override.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module Decidim + module Assemblies + module AssembliesControllerOverride + extend ActiveSupport::Concern + + included do + def per_page + if Decidim::Paginable::OPTIONS.include?(params[:per_page]) + params[:per_page].to_i + elsif params[:per_page] + sorted = Decidim::Paginable::OPTIONS.sort + params[:per_page].to_i.clamp(sorted.first, sorted.last) + else + 25 + end + end + end + end + end +end diff --git a/app/controllers/decidim/accountability/admin/import_results_controller.rb b/app/controllers/decidim/accountability/admin/import_results_controller.rb index 1a566d232b..3675ee5431 100644 --- a/app/controllers/decidim/accountability/admin/import_results_controller.rb +++ b/app/controllers/decidim/accountability/admin/import_results_controller.rb @@ -13,7 +13,7 @@ def create @csv_file = params[:csv_file] redirect_to(new_import_path) && return if @csv_file.blank? - Decidim::Accountability::Admin::ImportResultsCSVJob.perform_later(current_user, current_component, @csv_file.read.force_encoding("utf-8").encode("utf-8")) + Decidim::Accountability::Admin::ImportResultsCsvJob.perform_later(current_user, current_component, @csv_file.read.force_encoding("utf-8").encode("utf-8")) flash[:notice] = I18n.t("imports.create.success", scope: "decidim.accountability.admin") redirect_to Rails.application.routes.url_helpers.import_results_path(current_participatory_process, current_component) diff --git a/app/controllers/export_results_controller.rb b/app/controllers/export_results_controller.rb index 2a43f3619e..3ccfdf934d 100644 --- a/app/controllers/export_results_controller.rb +++ b/app/controllers/export_results_controller.rb @@ -2,7 +2,7 @@ class ExportResultsController < ApplicationController def csv - send_data Decidim::Accountability::ResultsCSVExporter.new(current_component).export, filename: "results.csv", disposition: "attachment" + send_data Decidim::Accountability::ResultsCsvExporter.new(current_component).export, filename: "results.csv", disposition: "attachment" end private diff --git a/app/controllers/static_controller.rb b/app/controllers/static_controller.rb index 3eae5998f0..b4fb1efbed 100644 --- a/app/controllers/static_controller.rb +++ b/app/controllers/static_controller.rb @@ -1,7 +1,29 @@ # frozen_string_literal: true class StaticController < Decidim::ApplicationController + helper_method :current_section, :sections + before_action :check_section, only: :accountability_sections + def accountability; end def accountability_sections; end + + private + + def check_section + raise ActiveRecord::RecordNotFound unless sections.has_key?(current_section.to_sym) + end + + def current_section + @current_section ||= params[:section] + end + + def sections + @sections ||= { + planificacio: 3, + economia: 4, + serveis: 1, + etica: 4 + } + end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index b96cff096d..c49df86785 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -5,7 +5,6 @@ module ApplicationHelper include Decidim::LayoutHelper include Decidim::TranslationsHelper include Decidim::MetaTagsHelper - include Decidim::CookiesHelper include Decidim::LanguageChooserHelper include Decidim::DecidimFormHelper end diff --git a/app/helpers/concerns/decidim/paginate_helper_override.rb b/app/helpers/concerns/decidim/paginate_helper_override.rb new file mode 100644 index 0000000000..441ded557d --- /dev/null +++ b/app/helpers/concerns/decidim/paginate_helper_override.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module Decidim + module PaginateHelperOverride + extend ActiveSupport::Concern + + included do + # Include a condition to force hiding the results per page using a parameter in the paginate_params + def decidim_paginate(collection, paginate_params = {}) + return if collection.total_pages <= 1 + + per_page = (params[:per_page] || paginate_params[:per_page] || Decidim::Paginable::OPTIONS.first).to_i + + content_tag :div, class: "flex flex-col-reverse md:flex-row items-center justify-between gap-1 py-8 md:py-16", data: { pagination: "" } do + template = "" + if collection.total_pages.positive? && !paginate_params.delete(:hide_results_per_page_selector) + template += render partial: "decidim/shared/results_per_page", locals: { per_page: }, formats: [:html] + end + template += paginate collection, window: 2, outer_window: 1, theme: "decidim", params: paginate_params + template.html_safe + end + end + end + end +end diff --git a/app/helpers/concerns/decidim/proposals/application_helper_override.rb b/app/helpers/concerns/decidim/proposals/application_helper_override.rb new file mode 100644 index 0000000000..0ba1f0674b --- /dev/null +++ b/app/helpers/concerns/decidim/proposals/application_helper_override.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +module Decidim + module Proposals + module ApplicationHelperOverride + extend ActiveSupport::Concern + + included do + # rubocop:disable Rails/HelperInstanceVariable + def safe_content_admin? + ((@proposal.official? || @proposal.official_meeting?) && not_from_participatory_text(@proposal)) || safe_content_allowed_user? + end + + private + + def safe_content_allowed_user? + @proposal.authored_by?(safe_content_allowed_users) + end + + def safe_content_allowed_users + @safe_content_allowed_users ||= Decidim::User.where(id: ENV.fetch("PROPOSAL_SAFE_CONTENT_ALLOWED_USERS", "").split(",")) + end + # rubocop:enable Rails/HelperInstanceVariable + end + end + end +end diff --git a/app/jobs/decidim/accountability/admin/import_results_csv_job.rb b/app/jobs/decidim/accountability/admin/import_results_csv_job.rb index 58b9d38426..bffe3b7d0e 100644 --- a/app/jobs/decidim/accountability/admin/import_results_csv_job.rb +++ b/app/jobs/decidim/accountability/admin/import_results_csv_job.rb @@ -3,11 +3,11 @@ module Decidim module Accountability module Admin - class ImportResultsCSVJob < ApplicationJob + class ImportResultsCsvJob < ApplicationJob queue_as :default def perform(current_user, current_component, csv_file) - importer = Decidim::Accountability::ResultsCSVImporter.new(current_component, csv_file, current_user) + importer = Decidim::Accountability::ResultsCsvImporter.new(current_component, csv_file, current_user) errors = importer.import! diff --git a/app/lib/decidim/overrides/forms/user_answers_serializer.rb b/app/lib/decidim/overrides/forms/user_answers_serializer.rb new file mode 100644 index 0000000000..d1e03bb42a --- /dev/null +++ b/app/lib/decidim/overrides/forms/user_answers_serializer.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +module Decidim + module Overrides + module Forms + module UserAnswersSerializer + private + + def hash_for(answer) + { + answer_translated_attribute_name(:id) => answer&.session_token, + answer_translated_attribute_name(:user_status) => answer_translated_attribute_name(answer&.decidim_user_id.present? ? "registered" : "unregistered"), + answer_translated_attribute_name(:ip_hash) => answer&.ip_hash, + answer_translated_attribute_name(:created_at) => answer&.created_at + } + end + + def questions_hash + questionnaire_id = @answers.first&.decidim_questionnaire_id + return {} unless questionnaire_id + + questions = Decidim::Forms::Question.where(decidim_questionnaire_id: questionnaire_id).order(:position) + return {} if questions.none? + + questions.each.inject({}) do |serialized, question| + serialized.update( + translated_question_key(question.position, question.body) => "" + ) + end + end + end + end + end +end diff --git a/app/lib/decidim/overrides/initiatives/initiative_m_cell.rb b/app/lib/decidim/overrides/initiatives/initiative_m_cell.rb deleted file mode 100644 index e4f7161621..0000000000 --- a/app/lib/decidim/overrides/initiatives/initiative_m_cell.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true - -module Decidim - module Overrides - module Initiatives - # This cell overrides the Medium (:m) initiative card - # for an given instance of an Initiative - module InitiativeMCell - def statuses - [:creation_date, :comments_count] - end - end - end - end -end diff --git a/app/lib/decidim/overrides/search_resource_fields_mapper.rb b/app/lib/decidim/overrides/search_resource_fields_mapper.rb new file mode 100644 index 0000000000..fd78629598 --- /dev/null +++ b/app/lib/decidim/overrides/search_resource_fields_mapper.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module Decidim + module Overrides + module SearchResourceFieldsMapper + # Override this method to avoid an error trying to remove a comment with a nil commentable + # as it tries to get the organization of a nil organization + def retrieve_organization(resource) + if @declared_fields[:organization_id].present? + organization_id = read_field(resource, @declared_fields, :organization_id) + Decidim::Organization.find_by(id: organization_id) + else + participatory_space(resource)&.organization || Decidim::Organization.first + end + end + end + end +end diff --git a/app/overrides/decidim/accountability/admin/results/_form/external_id.html.erb.deface b/app/overrides/decidim/accountability/admin/results/_form/external_id.html.erb.deface deleted file mode 100644 index e4b8bc19f2..0000000000 --- a/app/overrides/decidim/accountability/admin/results/_form/external_id.html.erb.deface +++ /dev/null @@ -1,7 +0,0 @@ - -
- <%= form.text_field :external_id %> -
-
- <%= form.text_field :weight %> -
diff --git a/app/overrides/decidim/accountability/admin/results/index/import_csv.html.erb.deface b/app/overrides/decidim/accountability/admin/results/index/import_csv.html.erb.deface deleted file mode 100644 index 5efcd21d15..0000000000 --- a/app/overrides/decidim/accountability/admin/results/index/import_csv.html.erb.deface +++ /dev/null @@ -1,2 +0,0 @@ - -<%= link_to t("decidim.accountability.admin.shared.subnav.import_csv"), Rails.application.routes.url_helpers.import_results_path(current_participatory_space, current_component), class: 'button tiny button--simple' %> diff --git a/app/overrides/decidim/accountability/results/_home_header/download_button.html.erb.deface b/app/overrides/decidim/accountability/results/_home_header/download_button.html.erb.deface deleted file mode 100644 index 203bba427c..0000000000 --- a/app/overrides/decidim/accountability/results/_home_header/download_button.html.erb.deface +++ /dev/null @@ -1,6 +0,0 @@ - -
-
- <%= link_to t(".csv_download"), Rails.application.routes.url_helpers.export_results_path(current_participatory_space, current_component) %> -
-
diff --git a/app/packs/images/category-1460.jpg b/app/packs/images/category-1460.jpg new file mode 100644 index 0000000000..6d7b16b096 Binary files /dev/null and b/app/packs/images/category-1460.jpg differ diff --git a/app/packs/images/category-1461.jpg b/app/packs/images/category-1461.jpg new file mode 100644 index 0000000000..5f16134370 Binary files /dev/null and b/app/packs/images/category-1461.jpg differ diff --git a/app/packs/images/category-1462.jpg b/app/packs/images/category-1462.jpg new file mode 100644 index 0000000000..95c2f91905 Binary files /dev/null and b/app/packs/images/category-1462.jpg differ diff --git a/app/packs/src/decidim/.keep b/app/packs/src/decidim/.keep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/app/packs/stylesheets/_global_accountability.scss b/app/packs/stylesheets/_global_accountability.scss deleted file mode 100644 index 2e90de5aaf..0000000000 --- a/app/packs/stylesheets/_global_accountability.scss +++ /dev/null @@ -1,138 +0,0 @@ -.global-accountability { - .row.column { - margin: 0 auto; - - .page-title { - margin-bottom: 1rem; - } - - .section:not(:last-child) { - border-bottom: 1px solid rgba($medium-gray, .5); - padding-bottom: 3rem; - } - - .centered--text { - text-align: left; - margin: 0 auto; - max-width: 600px; - padding-bottom: 2rem; - } - .centered--text.text-center { - text-align: center; - } - - .intro--text { - @include breakpoint(medium) { - font-size: 1.25rem; - } - } - - .card--accountability { - text-align: left; - - h4 { - padding: 1.5rem 1.5rem 1rem 1.5rem; - border-bottom: 1px solid $medium-gray; - - .icon { - margin-right: 0.25rem; - } - } - .card__content { - padding: 0 1.5rem 1.5rem 1.5rem; - - ul { - list-style: none; - border-left: 1px solid $medium-gray; - margin-top: 1rem; - padding-left: 1rem; - margin-left: 0; - - a { - color: $secondary; - - &:hover, - &:focus, - &:active { - color: #4d848f; - } - } - } - } - } - - .card--mini .card__content{ - padding: 1.5rem 0.5rem; - } - - .accountability--graphic { - width: 100%; - height: auto; - max-width: 780px; - } - - .tabbed-container { - .programme--section { - margin-bottom: 1.5rem; - } - .icon { - margin-right: 0.25rem; - fill: $secondary; - } - } - } -} -.accountability .categories .categories--group .card__link .category--scope--line { - background-color: white; - border: 1px solid #ddd; - border-radius: 4px; - min-height: 9rem; - padding: 0; - margin-bottom: 1.875rem; - position: relative; - - strong { - font-size: 1.5rem; - padding-bottom: 0.5rem; - display: block; - } - - .progress-info { - display: flex; - justify-content: space-between; - align-items: flex-end; - } -} - -.accountability .categories .categories--group .card__link .category--without--children { - height: 11rem; - - strong { - min-height: 5rem; - } -} - -.accountability .categories .categories--group .card__link .category--scope--line .scope--inner { - padding: 1rem; -} - -.accountability .categories a.block--scope:hover { - background: inherit; - text-decoration: inherit; -} - -.accountability .categories .categories--group .card__link:hover .category--count { - color: inherit; -} - -.accountability .categories .categories--group .card__link .category--line .category--count { - color: #ABA5B3; -} - -.accountability .categories .categories--group .card__link .category--line strong { - color: #182B71; -} - -.accountability .categories .categories--group .category--title p.heading3 { - font-weight: normal; -} diff --git a/app/packs/stylesheets/barcelona.scss b/app/packs/stylesheets/barcelona.scss deleted file mode 100644 index 5ab323f409..0000000000 --- a/app/packs/stylesheets/barcelona.scss +++ /dev/null @@ -1,10 +0,0 @@ -@import "theme-barcelona/variables"; -@import "theme-barcelona/footer"; -@import "theme-barcelona/navbar"; -@import "theme-barcelona/process-nav"; -@import "theme-barcelona/section-heading"; -@import "theme-barcelona/cards"; -@import "theme-barcelona/hero-custom"; -@import "theme-barcelona/event-days"; -@import "theme-barcelona/special-process"; -@import "theme-barcelona/budgets"; diff --git a/app/packs/stylesheets/decidim/.keep b/app/packs/stylesheets/decidim/.keep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/app/packs/stylesheets/decidim/decidim_application.scss b/app/packs/stylesheets/decidim/decidim_application.scss index 18e96c8638..d0561d3f31 100644 --- a/app/packs/stylesheets/decidim/decidim_application.scss +++ b/app/packs/stylesheets/decidim/decidim_application.scss @@ -6,5 +6,108 @@ // // By default this is empty. -@import "stylesheets/barcelona"; -@import "stylesheets/global_accountability"; \ No newline at end of file +// Fix for the confirm modal showing behind the modal who generates it +#confirm-modal { + z-index: 100; +} + +.accountability_without_children { + &__grid { + @apply grid md:grid-cols-3 items-start gap-x-10 gap-y-8 md:gap-y-16; + + /* display the titles only for the first row in desktop */ + & > :nth-child(1) &-title { + @apply md:block; + } + + &-title { + @apply block md:hidden mb-8 text-gray-2 uppercase font-semibold; + } + + .flash { + @apply m-0; + } + } +} + +.main-header__language-container > #trigger-dropdown-language-chooser { + gap: 0.1rem !important; + flex-direction: column; + padding: 0.25rem 0.5rem; + + span { + display: block; + font-weight: 400; + color: rgb(var(--secondary-rgb) / 1); + font-size: 14px; + } + + svg { + fill: rgb(var(--secondary-rgb) / 1); + } +} + +.main-footer__language { + z-index: 1000; +} + +.main-header__language-container > #trigger-dropdown-language-chooser:hover { + background-color: #f3f4f7 !important; + border-radius: 0.25rem; + text-decoration: underline; + text-decoration-color: rgb(var(--secondary-rgb) / 1); +} + +#dropdown-menu-language-chooser { + margin-left: 0 !important; + margin-right: 0 !important; + align-items: center !important; +} + +#dropdown-menu-language-chooser > ul > li > a { + font-size: 14px; + padding: 0.5rem; +} + +.mobile_menu__language-container { + padding-top: 12px; + padding-bottom: 12px; +} + +@media (min-width: 768px) { + .main-header__language-container > #trigger-dropdown-language-chooser { + display: flex !important; + } +} + +@media (max-width: 1023px) { + .main-header__language-container > #trigger-dropdown-language-chooser { + flex-direction: row !important; + } + + #trigger-dropdown-language-chooser > svg { + display: none; + } + + #trigger-dropdown-language-chooser > div > svg { + display: none; + } + + #dropdown-menu-main-mobile > div.main-header__language-container { + display: flex; + flex-direction: row; + width: 10rem; + margin: auto; + color: rgb(168 44 44) !important; + font-weight: 600 !important; + } + + #dropdown-menu-language-chooser > ul > li > a, + #dropdown-menu-language-chooser > ul > li, + #trigger-dropdown-language-chooser > div > span, + #trigger-dropdown-language-chooser { + padding: 0 !important; + font-size: 1rem !important; + font-weight: 600 !important; + } +} diff --git a/app/packs/stylesheets/email.scss b/app/packs/stylesheets/email.scss index a90e5fea77..dd53605842 100644 --- a/app/packs/stylesheets/email.scss +++ b/app/packs/stylesheets/email.scss @@ -1,4 +1,4 @@ -@import "stylesheets/decidim/variables"; +@import "stylesheets/decidim/legacy/variables"; /* Index: 1 - Foundation settings @@ -7,15 +7,15 @@ /* 1 - Foundation settings --------- */ -.wrapper{ +.wrapper { width: 100%; } -#outlook a{ +#outlook a { padding: 0; } -body{ +body { width: 100% !important; min-width: 100%; -webkit-text-size-adjust: 100%; @@ -25,9 +25,16 @@ body{ -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; + + &.preview { + .see-on-website, + .unsubscribe { + cursor: not-allowed; + } + } } -.ExternalClass{ +.ExternalClass { width: 100%; } @@ -36,18 +43,18 @@ body{ .ExternalClass span, .ExternalClass font, .ExternalClass td, -.ExternalClass div{ +.ExternalClass div { line-height: 100%; } -#backgroundTable{ +#backgroundTable { margin: 0; padding: 0; width: 100% !important; line-height: 100% !important; } -img{ +img { outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; @@ -57,25 +64,25 @@ img{ display: block; } -center{ +center { width: 100%; min-width: 580px; } -a img{ +a img { border: none; } -p{ +p { margin: 0 0 0 10px; } -table{ +table { border-spacing: 0; border-collapse: collapse; } -td{ +td { word-wrap: break-word; -webkit-hyphens: auto; -moz-hyphens: auto; @@ -85,55 +92,55 @@ td{ table, tr, -td{ +td { padding: 0; vertical-align: top; text-align: left; } -@media only screen{ - html{ +@media only screen { + html { min-height: 100%; background: #f3f3f3; } } -table.body{ +table.body { background: #f3f3f3; height: 100%; width: 100%; } -table.container{ +table.container { width: 580px; margin: 0 auto; text-align: inherit; } -table.row{ +table.row { padding: 0; width: 100%; position: relative; } -table.spacer{ +table.spacer { width: 100%; } /* stylelint-disable property-no-unknown */ -table.spacer td{ +table.spacer td { mso-line-height-rule: exactly; } /* stylelint-enable property-no-unknown */ -table.container table.row{ +table.container table.row { display: table; } td.columns, td.column, th.columns, -th.column{ +th.column { margin: 0 auto; padding-right: 16px; padding-left: 16px; @@ -147,7 +154,7 @@ td.column .columns, th.columns .column, th.columns .columns, th.column .column, -th.column .columns{ +th.column .columns { padding-left: 0 !important; padding-right: 0 !important; } @@ -159,43 +166,43 @@ td.column .columns center, th.columns .column center, th.columns .columns center, th.column .column center, -th.column .columns center{ +th.column .columns center { min-width: none !important; } td.columns.last, td.column.last, th.columns.last, -th.column.last{ +th.column.last { padding-right: 16px; } td.columns table:not(.button), td.column table:not(.button), th.columns table:not(.button), -th.column table:not(.button){ +th.column table:not(.button) { width: 100%; } td.large-1, -th.large-1{ +th.large-1 { width: 32.33333px; padding-left: 8px; padding-right: 8px; } td.large-1.first, -th.large-1.first{ +th.large-1.first { padding-left: 16px; } td.large-1.last, -th.large-1.last{ +th.large-1.last { padding-right: 16px; } .collapse > tbody > tr > td.large-1, -.collapse > tbody > tr > th.large-1{ +.collapse > tbody > tr > th.large-1 { padding-right: 0; padding-left: 0; width: 48.33333px; @@ -204,41 +211,41 @@ th.large-1.last{ .collapse td.large-1.first, .collapse th.large-1.first, .collapse td.large-1.last, -.collapse th.large-1.last{ +.collapse th.large-1.last { width: 56.33333px; } td.large-1 center, -th.large-1 center{ - min-width: .33333px; +th.large-1 center { + min-width: 0.33333px; } .body .columns td.large-1, .body .column td.large-1, .body .columns th.large-1, -.body .column th.large-1{ +.body .column th.large-1 { width: 8.33333%; } td.large-2, -th.large-2{ +th.large-2 { width: 80.66667px; padding-left: 8px; padding-right: 8px; } td.large-2.first, -th.large-2.first{ +th.large-2.first { padding-left: 16px; } td.large-2.last, -th.large-2.last{ +th.large-2.last { padding-right: 16px; } .collapse > tbody > tr > td.large-2, -.collapse > tbody > tr > th.large-2{ +.collapse > tbody > tr > th.large-2 { padding-right: 0; padding-left: 0; width: 96.66667px; @@ -247,41 +254,41 @@ th.large-2.last{ .collapse td.large-2.first, .collapse th.large-2.first, .collapse td.large-2.last, -.collapse th.large-2.last{ +.collapse th.large-2.last { width: 104.66667px; } td.large-2 center, -th.large-2 center{ +th.large-2 center { min-width: 48.66667px; } .body .columns td.large-2, .body .column td.large-2, .body .columns th.large-2, -.body .column th.large-2{ +.body .column th.large-2 { width: 16.66667%; } td.large-3, -th.large-3{ +th.large-3 { width: 129px; padding-left: 8px; padding-right: 8px; } td.large-3.first, -th.large-3.first{ +th.large-3.first { padding-left: 16px; } td.large-3.last, -th.large-3.last{ +th.large-3.last { padding-right: 16px; } .collapse > tbody > tr > td.large-3, -.collapse > tbody > tr > th.large-3{ +.collapse > tbody > tr > th.large-3 { padding-right: 0; padding-left: 0; width: 145px; @@ -290,41 +297,41 @@ th.large-3.last{ .collapse td.large-3.first, .collapse th.large-3.first, .collapse td.large-3.last, -.collapse th.large-3.last{ +.collapse th.large-3.last { width: 153px; } td.large-3 center, -th.large-3 center{ +th.large-3 center { min-width: 97px; } .body .columns td.large-3, .body .column td.large-3, .body .columns th.large-3, -.body .column th.large-3{ +.body .column th.large-3 { width: 25%; } td.large-4, -th.large-4{ +th.large-4 { width: 177.33333px; padding-left: 8px; padding-right: 8px; } td.large-4.first, -th.large-4.first{ +th.large-4.first { padding-left: 16px; } td.large-4.last, -th.large-4.last{ +th.large-4.last { padding-right: 16px; } .collapse > tbody > tr > td.large-4, -.collapse > tbody > tr > th.large-4{ +.collapse > tbody > tr > th.large-4 { padding-right: 0; padding-left: 0; width: 193.33333px; @@ -333,41 +340,41 @@ th.large-4.last{ .collapse td.large-4.first, .collapse th.large-4.first, .collapse td.large-4.last, -.collapse th.large-4.last{ +.collapse th.large-4.last { width: 201.33333px; } td.large-4 center, -th.large-4 center{ +th.large-4 center { min-width: 145.33333px; } .body .columns td.large-4, .body .column td.large-4, .body .columns th.large-4, -.body .column th.large-4{ +.body .column th.large-4 { width: 33.33333%; } td.large-5, -th.large-5{ +th.large-5 { width: 225.66667px; padding-left: 8px; padding-right: 8px; } td.large-5.first, -th.large-5.first{ +th.large-5.first { padding-left: 16px; } td.large-5.last, -th.large-5.last{ +th.large-5.last { padding-right: 16px; } .collapse > tbody > tr > td.large-5, -.collapse > tbody > tr > th.large-5{ +.collapse > tbody > tr > th.large-5 { padding-right: 0; padding-left: 0; width: 241.66667px; @@ -376,41 +383,41 @@ th.large-5.last{ .collapse td.large-5.first, .collapse th.large-5.first, .collapse td.large-5.last, -.collapse th.large-5.last{ +.collapse th.large-5.last { width: 249.66667px; } td.large-5 center, -th.large-5 center{ +th.large-5 center { min-width: 193.66667px; } .body .columns td.large-5, .body .column td.large-5, .body .columns th.large-5, -.body .column th.large-5{ +.body .column th.large-5 { width: 41.66667%; } td.large-6, -th.large-6{ +th.large-6 { width: 274px; padding-left: 8px; padding-right: 8px; } td.large-6.first, -th.large-6.first{ +th.large-6.first { padding-left: 16px; } td.large-6.last, -th.large-6.last{ +th.large-6.last { padding-right: 16px; } .collapse > tbody > tr > td.large-6, -.collapse > tbody > tr > th.large-6{ +.collapse > tbody > tr > th.large-6 { padding-right: 0; padding-left: 0; width: 290px; @@ -419,41 +426,41 @@ th.large-6.last{ .collapse td.large-6.first, .collapse th.large-6.first, .collapse td.large-6.last, -.collapse th.large-6.last{ +.collapse th.large-6.last { width: 298px; } td.large-6 center, -th.large-6 center{ +th.large-6 center { min-width: 242px; } .body .columns td.large-6, .body .column td.large-6, .body .columns th.large-6, -.body .column th.large-6{ +.body .column th.large-6 { width: 50%; } td.large-7, -th.large-7{ +th.large-7 { width: 322.33333px; padding-left: 8px; padding-right: 8px; } td.large-7.first, -th.large-7.first{ +th.large-7.first { padding-left: 16px; } td.large-7.last, -th.large-7.last{ +th.large-7.last { padding-right: 16px; } .collapse > tbody > tr > td.large-7, -.collapse > tbody > tr > th.large-7{ +.collapse > tbody > tr > th.large-7 { padding-right: 0; padding-left: 0; width: 338.33333px; @@ -462,41 +469,41 @@ th.large-7.last{ .collapse td.large-7.first, .collapse th.large-7.first, .collapse td.large-7.last, -.collapse th.large-7.last{ +.collapse th.large-7.last { width: 346.33333px; } td.large-7 center, -th.large-7 center{ +th.large-7 center { min-width: 290.33333px; } .body .columns td.large-7, .body .column td.large-7, .body .columns th.large-7, -.body .column th.large-7{ +.body .column th.large-7 { width: 58.33333%; } td.large-8, -th.large-8{ +th.large-8 { width: 370.66667px; padding-left: 8px; padding-right: 8px; } td.large-8.first, -th.large-8.first{ +th.large-8.first { padding-left: 16px; } td.large-8.last, -th.large-8.last{ +th.large-8.last { padding-right: 16px; } .collapse > tbody > tr > td.large-8, -.collapse > tbody > tr > th.large-8{ +.collapse > tbody > tr > th.large-8 { padding-right: 0; padding-left: 0; width: 386.66667px; @@ -505,41 +512,41 @@ th.large-8.last{ .collapse td.large-8.first, .collapse th.large-8.first, .collapse td.large-8.last, -.collapse th.large-8.last{ +.collapse th.large-8.last { width: 394.66667px; } td.large-8 center, -th.large-8 center{ +th.large-8 center { min-width: 338.66667px; } .body .columns td.large-8, .body .column td.large-8, .body .columns th.large-8, -.body .column th.large-8{ +.body .column th.large-8 { width: 66.66667%; } td.large-9, -th.large-9{ +th.large-9 { width: 419px; padding-left: 8px; padding-right: 8px; } td.large-9.first, -th.large-9.first{ +th.large-9.first { padding-left: 16px; } td.large-9.last, -th.large-9.last{ +th.large-9.last { padding-right: 16px; } .collapse > tbody > tr > td.large-9, -.collapse > tbody > tr > th.large-9{ +.collapse > tbody > tr > th.large-9 { padding-right: 0; padding-left: 0; width: 435px; @@ -548,41 +555,41 @@ th.large-9.last{ .collapse td.large-9.first, .collapse th.large-9.first, .collapse td.large-9.last, -.collapse th.large-9.last{ +.collapse th.large-9.last { width: 443px; } td.large-9 center, -th.large-9 center{ +th.large-9 center { min-width: 387px; } .body .columns td.large-9, .body .column td.large-9, .body .columns th.large-9, -.body .column th.large-9{ +.body .column th.large-9 { width: 75%; } td.large-10, -th.large-10{ +th.large-10 { width: 467.33333px; padding-left: 8px; padding-right: 8px; } td.large-10.first, -th.large-10.first{ +th.large-10.first { padding-left: 16px; } td.large-10.last, -th.large-10.last{ +th.large-10.last { padding-right: 16px; } .collapse > tbody > tr > td.large-10, -.collapse > tbody > tr > th.large-10{ +.collapse > tbody > tr > th.large-10 { padding-right: 0; padding-left: 0; width: 483.33333px; @@ -591,41 +598,41 @@ th.large-10.last{ .collapse td.large-10.first, .collapse th.large-10.first, .collapse td.large-10.last, -.collapse th.large-10.last{ +.collapse th.large-10.last { width: 491.33333px; } td.large-10 center, -th.large-10 center{ +th.large-10 center { min-width: 435.33333px; } .body .columns td.large-10, .body .column td.large-10, .body .columns th.large-10, -.body .column th.large-10{ +.body .column th.large-10 { width: 83.33333%; } td.large-11, -th.large-11{ +th.large-11 { width: 515.66667px; padding-left: 8px; padding-right: 8px; } td.large-11.first, -th.large-11.first{ +th.large-11.first { padding-left: 16px; } td.large-11.last, -th.large-11.last{ +th.large-11.last { padding-right: 16px; } .collapse > tbody > tr > td.large-11, -.collapse > tbody > tr > th.large-11{ +.collapse > tbody > tr > th.large-11 { padding-right: 0; padding-left: 0; width: 531.66667px; @@ -634,41 +641,41 @@ th.large-11.last{ .collapse td.large-11.first, .collapse th.large-11.first, .collapse td.large-11.last, -.collapse th.large-11.last{ +.collapse th.large-11.last { width: 539.66667px; } td.large-11 center, -th.large-11 center{ +th.large-11 center { min-width: 483.66667px; } .body .columns td.large-11, .body .column td.large-11, .body .columns th.large-11, -.body .column th.large-11{ +.body .column th.large-11 { width: 91.66667%; } td.large-12, -th.large-12{ +th.large-12 { width: 564px; padding-left: 8px; padding-right: 8px; } td.large-12.first, -th.large-12.first{ +th.large-12.first { padding-left: 16px; } td.large-12.last, -th.large-12.last{ +th.large-12.last { padding-right: 16px; } .collapse > tbody > tr > td.large-12, -.collapse > tbody > tr > th.large-12{ +.collapse > tbody > tr > th.large-12 { padding-right: 0; padding-left: 0; width: 580px; @@ -677,19 +684,19 @@ th.large-12.last{ .collapse td.large-12.first, .collapse th.large-12.first, .collapse td.large-12.last, -.collapse th.large-12.last{ +.collapse th.large-12.last { width: 588px; } td.large-12 center, -th.large-12 center{ +th.large-12 center { min-width: 532px; } .body .columns td.large-12, .body .column td.large-12, .body .columns th.large-12, -.body .column th.large-12{ +.body .column th.large-12 { width: 100%; } @@ -698,7 +705,7 @@ td.large-offset-1.first, td.large-offset-1.last, th.large-offset-1, th.large-offset-1.first, -th.large-offset-1.last{ +th.large-offset-1.last { padding-left: 64.33333px; } @@ -707,7 +714,7 @@ td.large-offset-2.first, td.large-offset-2.last, th.large-offset-2, th.large-offset-2.first, -th.large-offset-2.last{ +th.large-offset-2.last { padding-left: 112.66667px; } @@ -716,7 +723,7 @@ td.large-offset-3.first, td.large-offset-3.last, th.large-offset-3, th.large-offset-3.first, -th.large-offset-3.last{ +th.large-offset-3.last { padding-left: 161px; } @@ -725,7 +732,7 @@ td.large-offset-4.first, td.large-offset-4.last, th.large-offset-4, th.large-offset-4.first, -th.large-offset-4.last{ +th.large-offset-4.last { padding-left: 209.33333px; } @@ -734,7 +741,7 @@ td.large-offset-5.first, td.large-offset-5.last, th.large-offset-5, th.large-offset-5.first, -th.large-offset-5.last{ +th.large-offset-5.last { padding-left: 257.66667px; } @@ -743,7 +750,7 @@ td.large-offset-6.first, td.large-offset-6.last, th.large-offset-6, th.large-offset-6.first, -th.large-offset-6.last{ +th.large-offset-6.last { padding-left: 306px; } @@ -752,7 +759,7 @@ td.large-offset-7.first, td.large-offset-7.last, th.large-offset-7, th.large-offset-7.first, -th.large-offset-7.last{ +th.large-offset-7.last { padding-left: 354.33333px; } @@ -761,7 +768,7 @@ td.large-offset-8.first, td.large-offset-8.last, th.large-offset-8, th.large-offset-8.first, -th.large-offset-8.last{ +th.large-offset-8.last { padding-left: 402.66667px; } @@ -770,7 +777,7 @@ td.large-offset-9.first, td.large-offset-9.last, th.large-offset-9, th.large-offset-9.first, -th.large-offset-9.last{ +th.large-offset-9.last { padding-left: 451px; } @@ -779,7 +786,7 @@ td.large-offset-10.first, td.large-offset-10.last, th.large-offset-10, th.large-offset-10.first, -th.large-offset-10.last{ +th.large-offset-10.last { padding-left: 499.33333px; } @@ -788,57 +795,57 @@ td.large-offset-11.first, td.large-offset-11.last, th.large-offset-11, th.large-offset-11.first, -th.large-offset-11.last{ +th.large-offset-11.last { padding-left: 547.66667px; } td.expander, -th.expander{ +th.expander { visibility: hidden; width: 0; padding: 0 !important; } -table.container.radius{ +table.container.radius { border-radius: 0; border-collapse: separate; } -.block-grid{ +.block-grid { width: 100%; max-width: 580px; } -.block-grid td{ +.block-grid td { display: inline-block; padding: 8px; } -.up-2 td{ +.up-2 td { width: 274px !important; } -.up-3 td{ +.up-3 td { width: 177px !important; } -.up-4 td{ +.up-4 td { width: 129px !important; } -.up-5 td{ +.up-5 td { width: 100px !important; } -.up-6 td{ +.up-6 td { width: 80px !important; } -.up-7 td{ +.up-7 td { width: 66px !important; } -.up-8 td{ +.up-8 td { width: 56px !important; } @@ -852,7 +859,7 @@ h4.text-center, h5.text-center, h6.text-center, p.text-center, -span.text-center{ +span.text-center { text-align: center; } @@ -866,7 +873,7 @@ h4.text-left, h5.text-left, h6.text-left, p.text-left, -span.text-left{ +span.text-left { text-align: left; } @@ -880,48 +887,48 @@ h4.text-right, h5.text-right, h6.text-right, p.text-right, -span.text-right{ +span.text-right { text-align: right; } -span.text-center{ +span.text-center { display: block; width: 100%; text-align: center; } -@media only screen and (max-width: 596px){ - .small-float-center{ +@media only screen and (max-width: 596px) { + .small-float-center { margin: 0 auto !important; float: none !important; text-align: center !important; } - .small-text-center{ + .small-text-center { text-align: center !important; } - .small-text-left{ + .small-text-left { text-align: left !important; } - .small-text-right{ + .small-text-right { text-align: right !important; } } -img.float-left{ +img.float-left { float: left; text-align: left; } -img.float-right{ +img.float-right { float: right; text-align: right; } img.float-center, -img.text-center{ +img.text-center { margin: 0 auto; float: none; text-align: center; @@ -929,20 +936,20 @@ img.text-center{ table.float-center, td.float-center, -th.float-center{ +th.float-center { margin: 0 auto; float: none; text-align: center; } -th.float-right{ +th.float-right { margin: 0 auto; float: right; text-align: center; } /* stylelint-disable property-no-unknown */ -.hide-for-large{ +.hide-for-large { display: none !important; mso-hide: all; overflow: hidden; @@ -953,8 +960,8 @@ th.float-right{ } /* stylelint-enable property-no-unknown */ -@media only screen and (max-width: 596px){ - .hide-for-large{ +@media only screen and (max-width: 596px) { + .hide-for-large { display: block !important; width: auto !important; overflow: visible !important; @@ -965,29 +972,29 @@ th.float-right{ } /* stylelint-disable property-no-unknown */ -table.body table.container .hide-for-large *{ +table.body table.container .hide-for-large * { mso-hide: all; } /* stylelint-enable property-no-unknown */ -@media only screen and (max-width: 596px){ +@media only screen and (max-width: 596px) { table.body table.container .hide-for-large, - table.body table.container .row.hide-for-large{ + table.body table.container .row.hide-for-large { display: table !important; width: 100% !important; } } -@media only screen and (max-width: 596px){ - table.body table.container .callout-inner.hide-for-large{ +@media only screen and (max-width: 596px) { + table.body table.container .callout-inner.hide-for-large { display: table-cell !important; width: 100% !important; } } /* stylelint-disable property-no-unknown */ -@media only screen and (max-width: 596px){ - table.body table.container .show-for-large{ +@media only screen and (max-width: 596px) { + table.body table.container .show-for-large { display: none !important; width: 0; mso-hide: all; @@ -1007,7 +1014,7 @@ h6, p, td, th, -a{ +a { color: #0a0a0a; font-family: Helvetica, Arial, sans-serif; font-weight: normal; @@ -1022,7 +1029,7 @@ h2, h3, h4, h5, -h6{ +h6 { color: inherit; word-wrap: normal; font-family: Helvetica, Arial, sans-serif; @@ -1030,27 +1037,27 @@ h6{ margin-bottom: 10px; } -h1{ +h1 { font-size: 34px; } -h2{ +h2 { font-size: 30px; } -h3{ +h3 { font-size: 28px; } -h4{ +h4 { font-size: 24px; } -h5{ +h5 { font-size: 20px; } -h6{ +h6 { font-size: 18px; } @@ -1058,21 +1065,21 @@ body, table.body, p, td, -th{ +th { font-size: 16px; line-height: 1.3; } -p{ +p { margin-bottom: 10px; } -p.lead{ +p.lead { font-size: 20px; line-height: 1.6; } -p.subheader{ +p.subheader { margin-top: 4px; margin-bottom: 8px; font-weight: normal; @@ -1080,25 +1087,25 @@ p.subheader{ color: #8a8a8a; } -small{ +small { font-size: 80%; color: #cacaca; } -a{ +a { color: #5295ad; text-decoration: none; } -a:hover{ +a:hover { color: #147dc2; } -a:active{ +a:active { color: #147dc2; } -a:visited{ +a:visited { color: #5295ad; } @@ -1113,34 +1120,34 @@ h4 a:visited, h5 a, h5 a:visited, h6 a, -h6 a:visited{ +h6 a:visited { color: #5295ad; } -pre{ +pre { background: #f3f3f3; margin: 30px 0; } -pre code{ +pre code { color: #cacaca; } -pre code span.callout{ +pre code span.callout { color: #8a8a8a; font-weight: bold; } -pre code span.callout-strong{ +pre code span.callout-strong { color: #ff6908; font-weight: bold; } -table.hr{ +table.hr { width: 100%; } -table.hr th{ +table.hr th { height: 0; max-width: 580px; border-top: 0; @@ -1151,17 +1158,17 @@ table.hr th{ clear: both; } -.stat{ +.stat { font-size: 40px; line-height: 1; } -p + .stat{ +p + .stat { margin-top: -16px; } /* stylelint-disable property-no-unknown */ -span.preheader{ +span.preheader { display: none !important; visibility: hidden; mso-hide: all !important; @@ -1175,19 +1182,19 @@ span.preheader{ } /* stylelint-enable property-no-unknown */ -table.button{ +table.button { width: auto; margin: 0 0 16px; } -table.button table td{ +table.button table td { text-align: left; color: #fefefe; background: #c24b29; border: 2px solid #c24b29; } -table.button table td a{ +table.button table td a { font-family: Helvetica, Arial, sans-serif; font-size: 16px; color: #fefefe; @@ -1198,12 +1205,12 @@ table.button table td a{ border-radius: 3px; } -table.button.radius table td{ +table.button.radius table td { border-radius: 3px; border: none; } -table.button.rounded table td{ +table.button.rounded table td { border-radius: 500px; border: none; } @@ -1219,56 +1226,56 @@ table.button.small:active table tr td a, table.button.small table tr td a:visited, table.button.large:hover table tr td a, table.button.large:active table tr td a, -table.button.large table tr td a:visited{ +table.button.large table tr td a:visited { color: #fefefe; } table.button.tiny table td, -table.button.tiny table a{ +table.button.tiny table a { padding: 4px 8px; } -table.button.tiny table a{ +table.button.tiny table a { font-size: 10px; font-weight: normal; } table.button.small table td, -table.button.small table a{ +table.button.small table a { padding: 5px 10px; font-size: 12px; } -table.button.large table a{ +table.button.large table a { padding: 10px 20px; font-size: 20px; } table.button.expand, -table.button.expanded{ +table.button.expanded { width: 100%; } // Fix for Outlook to center the button table.button.expand > tr > td, -table.button.expanded > tr > td{ +table.button.expanded > tr > td { text-align: center; } table.button.expand table, -table.button.expanded table{ +table.button.expanded table { width: 50%; margin: auto; } // Fix for Outlook to center the button link text table.button.expand table > tr > td, -table.button.expanded table > tr > td{ +table.button.expanded table > tr > td { text-align: center; } table.button.expand table a, -table.button.expanded table a{ +table.button.expanded table a { text-align: center; width: 100%; padding-left: 0; @@ -1276,150 +1283,150 @@ table.button.expanded table a{ } table.button.expand center, -table.button.expanded center{ +table.button.expanded center { min-width: 0; } table.button:hover table td, table.button:visited table td, -table.button:active table td{ +table.button:active table td { background: #147dc2; color: #fefefe; } table.button:hover table a, table.button:visited table a, -table.button:active table a{ +table.button:active table a { border: 0 solid #147dc2; } -table.button.secondary table td{ +table.button.secondary table td { background: #777; color: #fefefe; border: 0 solid #777; } -table.button.secondary table a{ +table.button.secondary table a { color: #fefefe; border: 0 solid #777; } -table.button.secondary:hover table td{ +table.button.secondary:hover table td { background: #919191; color: #fefefe; } -table.button.secondary:hover table a{ +table.button.secondary:hover table a { border: 0 solid #919191; } -table.button.secondary:hover table td a{ +table.button.secondary:hover table td a { color: #fefefe; } -table.button.secondary:active table td a{ +table.button.secondary:active table td a { color: #fefefe; } -table.button.secondary table td a:visited{ +table.button.secondary table td a:visited { color: #fefefe; } -table.button.success table td{ +table.button.success table td { background: #3adb76; border: 0 solid #3adb76; } -table.button.success table a{ +table.button.success table a { border: 0 solid #3adb76; } -table.button.success:hover table td{ +table.button.success:hover table td { background: #23bf5d; } -table.button.success:hover table a{ +table.button.success:hover table a { border: 0 solid #23bf5d; } -table.button.alert table td{ +table.button.alert table td { background: #ec5840; border: 0 solid #ec5840; } -table.button.alert table a{ +table.button.alert table a { border: 0 solid #ec5840; } -table.button.alert:hover table td{ +table.button.alert:hover table td { background: #e23317; } -table.button.alert:hover table a{ +table.button.alert:hover table a { border: 0 solid #e23317; } -table.button.warning table td{ +table.button.warning table td { background: #ffae00; border: 0 solid #ffae00; } -table.button.warning table a{ +table.button.warning table a { border: 0 solid #ffae00; } -table.button.warning:hover table td{ +table.button.warning:hover table td { background: #cc8b00; } -table.button.warning:hover table a{ +table.button.warning:hover table a { border: 0 solid #cc8b00; } -table.callout{ +table.callout { margin-bottom: 16px; } -th.callout-inner{ +th.callout-inner { width: 100%; border: 1px solid #cbcbcb; padding: 10px; background: #fefefe; } -th.callout-inner.primary{ +th.callout-inner.primary { background: #def0fc; border: 1px solid #444; color: #0a0a0a; } -th.callout-inner.secondary{ +th.callout-inner.secondary { background: #ebebeb; border: 1px solid #444; color: #0a0a0a; } -th.callout-inner.success{ +th.callout-inner.success { background: #e1faea; border: 1px solid #1b9448; color: #fefefe; } -th.callout-inner.warning{ +th.callout-inner.warning { background: #fff3d9; border: 1px solid #996800; color: #fefefe; } -th.callout-inner.alert{ +th.callout-inner.alert { background: #fce6e2; border: 1px solid #b42912; color: #fefefe; } -.thumbnail{ +.thumbnail { border: solid 4px #fefefe; - box-shadow: 0 0 0 1px rgba(10, 10, 10, .2); + box-shadow: 0 0 0 1px rgba(10, 10, 10, 0.2); display: inline-block; line-height: 0; max-width: 100%; @@ -1429,72 +1436,72 @@ th.callout-inner.alert{ } .thumbnail:hover, -.thumbnail:focus{ - box-shadow: 0 0 6px 1px rgba(33, 153, 232, .5); +.thumbnail:focus { + box-shadow: 0 0 6px 1px rgba(33, 153, 232, 0.5); } -table.menu{ +table.menu { width: 580px; } table.menu td.menu-item, -table.menu th.menu-item{ +table.menu th.menu-item { padding: 10px; padding-right: 10px; } table.menu td.menu-item a, -table.menu th.menu-item a{ +table.menu th.menu-item a { color: #5295ad; } table.menu.vertical td.menu-item, -table.menu.vertical th.menu-item{ +table.menu.vertical th.menu-item { padding: 10px; padding-right: 0; display: block; } table.menu.vertical td.menu-item a, -table.menu.vertical th.menu-item a{ +table.menu.vertical th.menu-item a { width: 100%; } table.menu.vertical td.menu-item table.menu.vertical td.menu-item, table.menu.vertical td.menu-item table.menu.vertical th.menu-item, table.menu.vertical th.menu-item table.menu.vertical td.menu-item, -table.menu.vertical th.menu-item table.menu.vertical th.menu-item{ +table.menu.vertical th.menu-item table.menu.vertical th.menu-item { padding-left: 10px; } -table.menu.text-center a{ +table.menu.text-center a { text-align: center; } -.menu[align="center"]{ +.menu[align="center"] { width: auto !important; } -body.outlook p{ +body.outlook p { display: inline !important; } -@media only screen and (max-width: 596px){ - table.body img{ +@media only screen and (max-width: 596px) { + table.body img { width: auto; height: auto; } - table.body center{ + table.body center { min-width: 0 !important; } - table.body .container{ + table.body .container { width: 95% !important; } table.body .columns, - table.body .column{ + table.body .column { height: auto !important; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; @@ -1506,85 +1513,85 @@ body.outlook p{ table.body .columns .column, table.body .columns .columns, table.body .column .column, - table.body .column .columns{ + table.body .column .columns { padding-left: 0 !important; padding-right: 0 !important; } table.body .collapse .columns, - table.body .collapse .column{ + table.body .collapse .column { padding-left: 0 !important; padding-right: 0 !important; } td.small-1, - th.small-1{ + th.small-1 { display: inline-block !important; width: 8.33333% !important; } td.small-2, - th.small-2{ + th.small-2 { display: inline-block !important; width: 16.66667% !important; } td.small-3, - th.small-3{ + th.small-3 { display: inline-block !important; width: 25% !important; } td.small-4, - th.small-4{ + th.small-4 { display: inline-block !important; width: 33.33333% !important; } td.small-5, - th.small-5{ + th.small-5 { display: inline-block !important; width: 41.66667% !important; } td.small-6, - th.small-6{ + th.small-6 { display: inline-block !important; width: 50% !important; } td.small-7, - th.small-7{ + th.small-7 { display: inline-block !important; width: 58.33333% !important; } td.small-8, - th.small-8{ + th.small-8 { display: inline-block !important; width: 66.66667% !important; } td.small-9, - th.small-9{ + th.small-9 { display: inline-block !important; width: 75% !important; } td.small-10, - th.small-10{ + th.small-10 { display: inline-block !important; width: 83.33333% !important; } td.small-11, - th.small-11{ + th.small-11 { display: inline-block !important; width: 91.66667% !important; } td.small-12, - th.small-12{ + th.small-12 { display: inline-block !important; width: 100% !important; } @@ -1592,87 +1599,87 @@ body.outlook p{ .columns td.small-12, .column td.small-12, .columns th.small-12, - .column th.small-12{ + .column th.small-12 { display: block !important; width: 100% !important; } table.body td.small-offset-1, - table.body th.small-offset-1{ + table.body th.small-offset-1 { margin-left: 8.33333% !important; } table.body td.small-offset-2, - table.body th.small-offset-2{ + table.body th.small-offset-2 { margin-left: 16.66667% !important; } table.body td.small-offset-3, - table.body th.small-offset-3{ + table.body th.small-offset-3 { margin-left: 25% !important; } table.body td.small-offset-4, - table.body th.small-offset-4{ + table.body th.small-offset-4 { margin-left: 33.33333% !important; } table.body td.small-offset-5, - table.body th.small-offset-5{ + table.body th.small-offset-5 { margin-left: 41.66667% !important; } table.body td.small-offset-6, - table.body th.small-offset-6{ + table.body th.small-offset-6 { margin-left: 50% !important; } table.body td.small-offset-7, - table.body th.small-offset-7{ + table.body th.small-offset-7 { margin-left: 58.33333% !important; } table.body td.small-offset-8, - table.body th.small-offset-8{ + table.body th.small-offset-8 { margin-left: 66.66667% !important; } table.body td.small-offset-9, - table.body th.small-offset-9{ + table.body th.small-offset-9 { margin-left: 75% !important; } table.body td.small-offset-10, - table.body th.small-offset-10{ + table.body th.small-offset-10 { margin-left: 83.33333% !important; } table.body td.small-offset-11, - table.body th.small-offset-11{ + table.body th.small-offset-11 { margin-left: 91.66667% !important; } table.body table.columns td.expander, - table.body table.columns th.expander{ + table.body table.columns th.expander { display: none !important; } table.body .right-text-pad, - table.body .text-pad-right{ + table.body .text-pad-right { padding-left: 10px !important; } table.body .left-text-pad, - table.body .text-pad-left{ + table.body .text-pad-left { padding-right: 10px !important; } - table.menu{ + table.menu { width: 100% !important; } table.menu td, - table.menu th{ + table.menu th { width: auto !important; display: inline-block !important; } @@ -1680,26 +1687,26 @@ body.outlook p{ table.menu.vertical td, table.menu.vertical th, table.menu.small-vertical td, - table.menu.small-vertical th{ + table.menu.small-vertical th { display: block !important; } - table.menu[align="center"]{ + table.menu[align="center"] { width: auto !important; } table.button.small-expand, - table.button.small-expanded{ + table.button.small-expanded { width: 100% !important; } table.button.small-expand table, - table.button.small-expanded table{ + table.button.small-expanded table { width: 100%; } table.button.small-expand table a, - table.button.small-expanded table a{ + table.button.small-expanded table a { text-align: center !important; width: 100% !important; padding-left: 0 !important; @@ -1707,7 +1714,7 @@ body.outlook p{ } table.button.small-expand center, - table.button.small-expanded center{ + table.button.small-expanded center { min-width: 0; } } @@ -1715,69 +1722,135 @@ body.outlook p{ /* 2 - Custom styles --------- */ table.body th.decidim-bar, -table.body td.decidim-bar{ +table.body td.decidim-bar { padding: 10px 0; background-color: #f3f3f3; } -table.body{ +table.body { background-color: #f3f3f3; margin: 20px 0; } -.decidim-logo{ +.decidim-logo { margin-top: 16px; } -.decidim-logo a{ +.decidim-logo a { display: inline-block; height: 30px; } -.cityhall-bar{ +.cityhall-bar { background-color: #2c2930; } -.cityhall-logo{ +.cityhall-logo { width: 150px; margin-top: 16px; } .footnote, -.headnote{ +.headnote { padding-top: 10px; color: #666; font-size: 12px; } -table.container.main{ +table.container.main { background: #fefefe; } -.custom-button{ +.custom-button { display: block; text-align: center; border-radius: 4px; line-height: 1; - padding: .58em 1em; + padding: 0.58em 1em; background: red; } -.button--sc{ - letter-spacing: .05em; +.button--sc { + letter-spacing: 0.05em; font-weight: 600; text-transform: uppercase; - &.large{ + &.large { font-size: 1rem; } } -table.content.image img{ +table.content.image img { width: 100%; } th, -td{ +td { box-sizing: border-box; } + +.email-notifications-digest { + .email-header { + margin-bottom: 32px; + font-size: 16px; + font-weight: bold; + color: #2c2930; + display: inline-block; + width: 49%; + + &--right { + text-align: right; + } + } + + .email-intro { + font-size: 16px; + line-height: 21px; + } + + .email-content-notifications { + background-color: #f4f4f4; + border-radius: 5px; + border: 1px #e5e5e5; + padding: 16px; + margin: 32px 0; + } + + .email-content-notification { + p a { + color: #327f9b; + font-weight: bold; + text-decoration: underline; + } + } + + .email-element-separator { + margin: 24px 0; + color: #e5e5e5; + border-color: #e5e5e5; + height: 0; + border-style: solid; + border-width: 1px; + } + + .email-notification-date { + color: #666d7a; + display: block; + margin-bottom: 10px; + } + + .email-closing { + font-size: 14px; + } + + .email-btn { + border: solid 1px; + margin: 0 33% 30px; + width: 33%; + text-align: center; + display: inline-block; + padding: 10px; + color: #5295ad; + text-decoration: none; + } +} diff --git a/app/packs/stylesheets/theme-barcelona/_budgets.scss b/app/packs/stylesheets/theme-barcelona/_budgets.scss deleted file mode 100644 index 47da24379b..0000000000 --- a/app/packs/stylesheets/theme-barcelona/_budgets.scss +++ /dev/null @@ -1,16 +0,0 @@ -.budget-progress { - .progress-meter { - &:not(&--minimum) { - background-color: $red-light; - } - } -} - -#project .card.extra .button_to[action="/follow"] { - display: none; -} - -/* for budgets callouts to not hide text */ -.card__content .callout.flash{ - margin-bottom: 1rem; -} diff --git a/app/packs/stylesheets/theme-barcelona/_cards.scss b/app/packs/stylesheets/theme-barcelona/_cards.scss deleted file mode 100644 index 72f83786c4..0000000000 --- a/app/packs/stylesheets/theme-barcelona/_cards.scss +++ /dev/null @@ -1,44 +0,0 @@ -//Process cards - home and processes -.card--full__image { - &:after { - content: ""; - display: block; - width: 100%; - height: 100%; - position: absolute; - top: 0; - left: 0; - background: url("images/pattern-big.svg") no-repeat left top; - z-index: 0; - background-size: 32px; - @include breakpoint(medium) { - background-size: 90px; - } - @include breakpoint(mediumlarge) { - background-size: 160px; - } - @include breakpoint(large) { - background-size: 120px; - } - } -} - -.card--process .card__image-top { - position: relative; - &:after { - content: ""; - display: block; - width: 100%; - height: 100%; - position: absolute; - top: 0; - left: 0; - background: url("images/pattern.svg") no-repeat left bottom; - z-index: 0; - background-size: 40px; - } -} - -.card--process.card--mini .card__image-top:after { - background-size: 32px; -} diff --git a/app/packs/stylesheets/theme-barcelona/_event-days.scss b/app/packs/stylesheets/theme-barcelona/_event-days.scss deleted file mode 100644 index f3df803742..0000000000 --- a/app/packs/stylesheets/theme-barcelona/_event-days.scss +++ /dev/null @@ -1,82 +0,0 @@ -.event-days { - margin-top: 2rem; - @include breakpoint(mediumlarge) { - display: flex; - justify-content: space-between; - } - - &__day { - background-color: $medium-gray; - padding: 1.5rem 2rem; - display: flex; - flex-direction: column; - min-height: 12rem; - margin-bottom: 2rem; - &:last-child { - margin-bottom: 0; - } - @include breakpoint(mediumlarge) { - flex-basis: 25rem; - min-height: 15rem; - padding: 2rem; - margin: 0 1rem; - &:first-child { - margin-left: 0; - } - &:last-child { - margin-right: 0; - } - } - @include breakpoint(large) { - margin: 0 2rem; - } - - &--current { - background-color: #22398e; - color: #c2c9e0; - } - } - - &__date { - text-transform: uppercase; - font-size: 1rem; - display: flex; - } - - &__info { - margin-top: auto; - margin-bottom: 0; - font-size: 1.5rem; - line-height: 1.2; - } - - &__number-month { - margin-right: 0.5rem; - } - - &__number { - font-size: 3rem; - line-height: 0.6; - } - - &__month { - text-decoration: none; - border-bottom: 0 !important; - display: block; - font-size: 1rem; - letter-spacing: 0.05em; - line-height: 1; - font-weight: 600; - cursor: default !important; - opacity: 0.6; - } - - &__separator { - font-size: 1rem; - line-height: 1; - font-weight: 600; - margin-right: 0.4rem; - opacity: 0.6; - margin-top: 0.5em; - } -} diff --git a/app/packs/stylesheets/theme-barcelona/_footer.scss b/app/packs/stylesheets/theme-barcelona/_footer.scss deleted file mode 100644 index e5794d8936..0000000000 --- a/app/packs/stylesheets/theme-barcelona/_footer.scss +++ /dev/null @@ -1,119 +0,0 @@ -//Vars -$main-footer-bg: $medium-gray; -$mini-footer-bg: $dark-gray; - -//Common - -.main-footer, -.mini-footer { -} - -//Main footer -.main-footer { - background-color: $main-footer-bg; - position: relative; - padding: 1.5rem 0; - min-height: 76px; - color: $medium-gray; - - a { - color: darken($medium-gray, 60%); - - &:hover { - color: darken($medium-gray, 40%); - } - } -} - -.main-footer__badge { - display: block; - width: 140px; - - @include breakpoint(large) { - position: absolute; - margin-top: -0.25rem; - } -} - -.main__footer__nav { - text-align: center; - - @include breakpoint(medium) { - text-align: left; - } - - @include breakpoint(large) { - text-align: center; - } -} - -.footer-nav { - list-style: none; - padding-top: 0.5rem; - margin: 0 0 0 -1rem; - - li { - display: inline-block; - padding: 0 1rem; - } - - @include breakpoint(large) { - margin-left: 0; - } -} - -.main__footer__social { - text-align: center; - - @include breakpoint(medium) { - text-align: right; - } -} - -.footer-social { - list-style: none; - padding-top: 0.5rem; - margin: 0; - - li { - display: inline-block; - padding-left: 1rem; - - &:first-child { - padding-left: 0; - } - } -} - -.footer-social__icon .icon { - width: 16px; - height: 16px; -} - -//Mini footer -.mini-footer { - padding: 2rem 0 1.5rem; - background-color: $mini-footer-bg; - color: $medium-gray; - a { - color: darken($medium-gray, 40%); - &:hover { - color: darken($medium-gray, 20%); - } - } -} - -.cc-badge { - margin-right: 0.5rem; -} - -.decidim-logo { - display: block; - width: 140px; - margin-right: auto; - margin-left: auto; - @include breakpoint(medium) { - margin-top: -9px; - margin-right: 0; - } -} diff --git a/app/packs/stylesheets/theme-barcelona/_hero-custom.scss b/app/packs/stylesheets/theme-barcelona/_hero-custom.scss deleted file mode 100644 index c728e8def8..0000000000 --- a/app/packs/stylesheets/theme-barcelona/_hero-custom.scss +++ /dev/null @@ -1,52 +0,0 @@ -.hero::after { - background-color: rgba(26, 24, 29, 0.2); -} - -.hero-custom { - background-size: contain; - background-repeat: no-repeat; - background-color: $white; - - &__container { - position: relative; - z-index: 1; - padding: 3rem 0; - - @include breakpoint(medium) { - padding: 4rem 0; - } - - @include breakpoint(mediumlarge) { - padding: 5rem 0; - } - - @include breakpoint(large) { - padding: 6rem 0; - } - } - - &__main { - @include breakpoint(mediumlarge) { - display: flex; - align-items: center; - margin-bottom: 4rem; - } - } - - &__heading { - margin-bottom: 2rem; - font-weight: 800; - } - - &__cta { - padding: 1.2rem 1rem; - margin-top: 2rem; - min-width: 16rem; - } - - &__image { - min-height: 400px; - background-size: contain; - background-repeat: no-repeat; - } -} diff --git a/app/packs/stylesheets/theme-barcelona/_navbar.scss b/app/packs/stylesheets/theme-barcelona/_navbar.scss deleted file mode 100644 index a5e7eb6b25..0000000000 --- a/app/packs/stylesheets/theme-barcelona/_navbar.scss +++ /dev/null @@ -1,468 +0,0 @@ -/* Variables */ - -$navbar-bg: $white; //$dark-gray; -$navbar-bg-hover: rgba(white, 0.02); -$navbar-color: $dark-gray; //rgba(white, 0.85); -$navbar-color-hover: $dark-gray; //$white; -$navbar-active-color: $dark-gray; //$white; -$navbar-active-bg: $navbar-bg-hover; -$navbar-active-shadow-small: inset -4px 0 0 0 var(--primary); -$navbar-active-shadow-medium: inset 0 -4px 0 0 var(--primary); - -$titlebar-bg: $white; - -/* Navigation */ - -.navbar { - padding-top: 0.5rem; - background: $navbar-bg; - border-bottom: 2px solid rgba(black, 0.075); - font-weight: 600; - .main-nav { - margin-bottom: -2px; - } -} - -/* Title bar */ - -.title-bar { - background-color: $titlebar-bg; - color: $body-font-color; - position: relative; - - @include breakpoint(smallmedium down) { - border-top: 2.125rem solid $titlebar-bg; - } -} - -.logo-cityhall { - position: absolute; - z-index: 1; - right: 0; - top: 0; - margin-top: -1.95rem; - text-align: right; - - img { - width: auto; - height: 22px !important; - } - - @include breakpoint(medium) { - top: 50%; - margin-top: -19px; - - img { - height: 38px !important; - } - } -} - -.topbar__search { - position: relative; - - input, - input:focus { - color: $navbar-color-hover; - border: 0; - padding-left: $input-padding * 4; - box-shadow: none; - background: $navbar-active-bg; - &::placeholder { - color: $navbar-color; - } - - @include breakpoint(medium) { - background: $medium-gray; - color: $body-font-color; - &::placeholder { - color: $dark-gray; - } - } - } - - svg { - color: $navbar-color; - position: absolute; - top: 50%; - left: $input-padding; - transform: translateY(-50%); - opacity: 0.5; - @include breakpoint(medium) { - color: $dark-gray; - } - } -} - -/* Top bar */ -.topbar { - display: flex; - align-items: center; - justify-content: flex-end; -} - -.logo-wrapper.logo-wrapper { - display: inline-block; - line-height: 0; - flex-grow: 1; - - a { - display: inline-block; - } - - img { - display: block; - max-height: 33px; - - @include breakpoint(mediumlarge) { - max-height: 45px; - } - } - - span { - color: $navbar-color; - &::before { - border-color: $navbar-color; - } - } -} - -/* Dropmenus in topbar */ -.topbar__dropmenu { - display: inline-block; - vertical-align: middle; - padding-top: 0; - margin-left: 2rem; - - .dropdown > li > a { - padding-left: 0; - } - - .dropdown { - display: inline-block; - vertical-align: middle; - } - - .is-dropdown-submenu { - z-index: 701; - text-align: left; - padding: 0; - background-color: $white; - border: 1px solid $light-gray; - border-radius: 4px; - box-shadow: 0 3px 5px rgba(0, 0, 0, 0.3); - min-width: 150px; - - &::after, - &::before { - bottom: 100%; - left: 50%; - border: solid transparent; - content: " "; - height: 0; - width: 0; - position: absolute; - pointer-events: none; - } - - &::after { - border-color: rgba($light-gray, 0); - border-bottom-color: $white; - border-width: 10px; - margin-left: -10px; - } - - &::before { - border-color: rgba($light-gray, 0); - border-bottom-color: $white; - border-width: 11px; - margin-left: -11px; - } - - li { - padding: $global-padding * 0.5; - - a { - padding: 0.5rem; - color: $anchor-color; - - &:hover { - color: lighten($body-font-color, 20); - } - } - - &:not(:last-child) { - border-bottom: $border; - } - - &:hover { - cursor: pointer; - background-color: rgba(var(--secondary-rgb), 0.05); - } - } - } - - // Arrow center position - #topbar__language-choose .is-dropdown-submenu { - transform: translateX(-12%); - top: 110%; - } - - #topbar__user-notifications .is-dropdown-submenu { - transform: translateX(-47%); - top: 110%; - } - - #topbar__user-profile .is-dropdown-submenu { - transform: translateX(-40%); - top: 110%; - } -} - -//Foundation overwrites -.topbar__dropmenu > ul > li > a { - color: $body-font-color; - - &::after { - margin-top: -1px !important; - border-top-color: $dark-gray !important; - } -} - -.language-choose { - @include breakpoint(smallmedium down) { - font-size: 0.8rem; - position: absolute; - top: -2.2rem; - left: 0.5rem; - margin-left: 0; - - .dropdown.menu > li.is-dropdown-submenu-parent > a::after { - border-width: 3px; - right: 10px; - margin-top: 0; - } - } -} - -.topbar__user { - display: inline-block; - padding-right: 2.5rem; - margin-left: 2rem; - - @media (min-width: calc(1300 / 16) + em) { - padding-right: 0; - } -} - -.topbar__user__logged { - text-align: right; - padding-right: 2.5rem; - display: none; - - @include breakpoint(medium) { - display: block; - } - - @media (min-width: calc(1300 / 16) + em) { - padding-right: 0; - } - - // hide caret down - .dropdown.menu > li.is-dropdown-submenu-parent > a::after { - display: none; - } -} - -.topbar__user__logged__picture { - width: 2rem; - height: 2rem; - border-radius: 50%; - border: $border; - object-fit: cover; -} - -.topbar__user__logged__name { - color: $body-font-color; - - > * { - display: block; - } -} - -.topbar__notifications, -.topbar__conversations { - margin-right: 1rem; - vertical-align: -4px; - - .icon { - fill: $white; - opacity: 0.3; - } - - &.is-active .icon { - fill: $warning; - opacity: 1; - } -} - -.topbar__notifications__item { - display: flex; - align-items: center; - justify-content: space-between; - color: $muted; - width: 250px; - - @include flexgap(1rem); - - strong { - color: $anchor-color; - } - - :last-child { - flex: 1; - - > * { - display: block; - } - } -} - -.topbar__notifications__item--more { - text-align: center; - background-color: $light-gray-dark; - color: $anchor-color; - font-size: 90%; -} - -.topbar__user__login { - text-align: right; - line-height: 1.2; - - a { - font-weight: 600; - color: $navbar-color; - &:hover { - color: $navbar-color-hover; - } - @include breakpoint(medium) { - color: $body-font-color; - &:hover { - color: $anchor-color; - } - } - } - - a::before { - content: ""; - margin-left: 0.5rem; - margin-right: 0.5rem; - display: inline-block; - width: 1px; - height: 2px; - border-left: $border; - vertical-align: middle; - } - - a:first-of-type::before { - display: none; - } -} - -/* Menu icon and off-canvas */ -.topbar__menu { - text-align: right; - font-size: 20px; - margin-right: 0.1rem; - - button { - color: inherit; - } -} - -.topbar__edit__link a { - color: $medium-gray; - - &:hover { - background: $navbar-bg-hover; - color: $navbar-color-hover; - } -} - -.usermenu-off-canvas-holder .usermenu-off-canvas { - border-top: 1px solid; - border-bottom: 1px solid; - - &.is-dropdown-submenu { - display: block; - position: static; - background: transparent; - border-left: 0; - border-right: 0; - } - - a { - display: block; - padding: 1em 2em; - color: $navbar-color; - - &:hover { - background: $navbar-bg-hover; - color: $navbar-color-hover; - } - } -} - -.off-canvas .topbar__user__login { - text-align: center; - margin-top: 1rem; - padding-top: 1rem; - padding-bottom: 1rem; - border-top: 1px solid; - border-bottom: 1px solid; -} - -/* Main nav */ -.main-nav ul { - padding: 0; - margin: 0; - list-style: none; - overflow-x: auto; - - @include breakpoint(medium) { - -webkit-overflow-scrolling: touch; - white-space: nowrap; - display: flex; - - > li { - display: inline-block; - flex: 1; - text-align: center; - } - } -} - -.main-nav__link a { - display: block; - padding: 1em 2em; - color: $navbar-color; - - &:hover { - background: $navbar-bg-hover; - color: $navbar-color-hover; - } - - @include breakpoint(medium) { - padding: 0.75em 2em; - } -} - -.main-nav__link--active a { - box-shadow: $navbar-active-shadow-small; - color: $navbar-active-color; - background: $navbar-active-bg; - - @include breakpoint(medium) { - box-shadow: $navbar-active-shadow-medium; - } -} diff --git a/app/packs/stylesheets/theme-barcelona/_process-nav.scss b/app/packs/stylesheets/theme-barcelona/_process-nav.scss deleted file mode 100644 index 3507497eb0..0000000000 --- a/app/packs/stylesheets/theme-barcelona/_process-nav.scss +++ /dev/null @@ -1,179 +0,0 @@ -$nav-border-width: 3px; - -.process-nav { - background-color: $white; - padding: 0.75rem $container-padding-y; - box-shadow: none; - - ul { - margin: 0; - list-style: none; - } - - .about-link { - font-size: 80%; - } - - @include breakpoint(medium) { - padding: 0; - - ul { - overflow-x: auto; - -webkit-overflow-scrolling: touch; - white-space: nowrap; - display: flex; - align-items: center; - flex-wrap: wrap; - justify-content: space-between; - flex-grow: 1; - } - - ul::-webkit-scrollbar { - display: none; - } - - ul::after { - display: inline-block; - flex-grow: 1; - content: ""; - } - - li { - display: inline-block; - padding: 0.75rem; - } - - .about-link { - float: right; - margin-right: 0; - margin-left: auto; - } - } -} - -.process-nav__trigger { - display: block; - width: 100%; - text-align: left; - position: relative; -} - -.process-nav__trigger__icon { - position: absolute; - right: 0.5rem; - top: 0.55rem; -} - -.process-nav__content { - @include breakpoint(smallmedium down) { - display: none; - } - - &.is-active { - display: block; - } - - display: flex; - justify-content: space-between; - align-items: baseline; -} - -.process-nav__content li { - @include breakpoint(smallmedium down) { - margin-top: 1rem; - } - - &.is-active { - box-shadow: inset 0 (-1 * ($nav-border-width + 1px)) 0 0 var(--primary); - - @include breakpoint(smallmedium down) { - display: none; - } - } -} - -.process-nav__more { - margin: 0; - color: var(--primary); - background-color: rgba(var(--primary-rgb), 0.1); - text-transform: uppercase; - font-weight: $global-weight-bold; - font-size: rem-calc(14); - - i { - @include square(5px); - - border-radius: 100%; - background-color: var(--primary); - display: inline-block; - vertical-align: middle; - margin-bottom: 0.1rem; - - &:not(:last-child) { - margin-right: 0.1rem; - } - } -} - -.process-nav__hidden-content { - background-color: $white; - box-shadow: 0 0 4px 0 rgba($black, 0.08); - padding: 0; - - ul { - padding: $global-padding * 0.5 0; - } - - li { - width: 100%; - padding: $global-padding * 0.5 $global-padding; - } -} - -.process-nav__hidden-content__more { - @extend .process-nav__more; - - background-color: transparent; - text-align: right; - border-bottom: $border; - padding: $global-padding * 0.5 $global-padding; -} - -.process-nav__link { - color: var(--primary); - text-transform: uppercase; - font-weight: $global-weight-bold; - display: flex; - align-items: center; - - svg { - margin-right: 0.4em; - width: 25px; - height: 25px; - fill: $muted; - - .stroked-shape { - fill: none; - fill-opacity: 1; - stroke-width: 2.01957917; - stroke-miterlimit: 4; - stroke-dasharray: none; - stroke-dashoffset: 0; - stroke: $muted; - } - } -} - -@include breakpoint(medium) { - .process-nav__link.is-active { - color: var(--primary); - - svg { - fill: var(--primary); - - .stroked-shape { - stroke: var(--primary); - } - } - } -} diff --git a/app/packs/stylesheets/theme-barcelona/_section-heading.scss b/app/packs/stylesheets/theme-barcelona/_section-heading.scss deleted file mode 100644 index 4c24162560..0000000000 --- a/app/packs/stylesheets/theme-barcelona/_section-heading.scss +++ /dev/null @@ -1,9 +0,0 @@ -//Section heading -.section-heading.section-heading:before { - //double selector to increase specificity - background: url("images/heading-icon.svg") no-repeat center; - width: 0.9rem; - height: 0.9rem; - margin-right: 0.3rem; - margin-bottom: -0.11rem; -} diff --git a/app/packs/stylesheets/theme-barcelona/_special-process.scss b/app/packs/stylesheets/theme-barcelona/_special-process.scss deleted file mode 100644 index 903e44ff63..0000000000 --- a/app/packs/stylesheets/theme-barcelona/_special-process.scss +++ /dev/null @@ -1,54 +0,0 @@ -.special-process { - @include breakpoint(mediumlarge) { - display: flex; - justify-content: center; - padding-left: 4rem; - padding-right: 4rem; - } - - &__element { - flex-grow: 1; - min-height: 400px; - display: flex; - flex-direction: column; - justify-content: flex-end; - color: $white; - transition: color 0.3s; - background-size: cover; - background-position: center 10%; - &:hover, - &:focus { - color: rgba($white, 0.8); - } - - @include breakpoint(mediumlarge) { - max-width: 50%; - } - } - - &__heading { - font-size: 1.6rem; - font-weight: 800; - line-height: 1.2; - } - - &__cta { - &::after { - content: ""; - display: inline-block; - width: 0.5em; - height: 0.5em; - border-top: 0.2em solid; - border-right: 0.2em solid; - transform: rotate(45deg); - vertical-align: 0.05em; - } - } - &__content { - background-color: rgba(#22398e, 0.9); - padding: 1rem 2rem; - &--alt { - background-color: rgba(#e63016, 0.9); - } - } -} diff --git a/app/packs/stylesheets/theme-barcelona/_variables.scss b/app/packs/stylesheets/theme-barcelona/_variables.scss deleted file mode 100644 index 1f7e836cfa..0000000000 --- a/app/packs/stylesheets/theme-barcelona/_variables.scss +++ /dev/null @@ -1,4 +0,0 @@ -// Additional colors -$red-light: #f9c5be; -$black-warm: #2c120e; -$gray-warm: #f4eeed; diff --git a/app/permissions/concerns/decidim/initiatives/admin/permissions_override.rb b/app/permissions/concerns/decidim/initiatives/admin/permissions_override.rb index 120300f752..aa227f763a 100644 --- a/app/permissions/concerns/decidim/initiatives/admin/permissions_override.rb +++ b/app/permissions/concerns/decidim/initiatives/admin/permissions_override.rb @@ -12,12 +12,10 @@ def initiative_admin_user_action? case permission_action.action when :read toggle_allow(Decidim::Initiatives.print_enabled) - when :publish + when :publish, :discard toggle_allow(initiative.validating?) when :unpublish toggle_allow(initiative.published?) - when :discard - toggle_allow(initiative.validating?) when :export_pdf_signatures toggle_allow(initiative.published? || initiative.accepted? || initiative.rejected?) when :export_votes diff --git a/app/presenters/concerns/decidim/deleted_author_presenter.rb b/app/presenters/concerns/decidim/deleted_author_presenter.rb new file mode 100644 index 0000000000..3075f974fe --- /dev/null +++ b/app/presenters/concerns/decidim/deleted_author_presenter.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module Decidim + # + # A dummy presenter to abstract out a deleted author. + # + class DeletedAuthorPresenter < Decidim::OfficialAuthorPresenter + def name + I18n.t("decidim.profile.deleted") + end + end +end diff --git a/app/presenters/concerns/decidim/proposals/proposal_presenter_override.rb b/app/presenters/concerns/decidim/proposals/proposal_presenter_override.rb new file mode 100644 index 0000000000..1b05a5db3e --- /dev/null +++ b/app/presenters/concerns/decidim/proposals/proposal_presenter_override.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module Decidim + module Proposals + module ProposalPresenterOverride + extend ActiveSupport::Concern + + included do + def author + @author ||= if official? + Decidim::Proposals::OfficialAuthorPresenter.new + else + coauthorship = coauthorships.includes(:author, :user_group).first + return coauthorship.user_group.presenter if coauthorship&.user_group + return coauthorship.author.presenter if coauthorship&.author + + Decidim::DeletedAuthorPresenter.new + end + end + end + end + end +end diff --git a/app/queries/concerns/decidim/forms/questionnaire_user_answers_override.rb b/app/queries/concerns/decidim/forms/questionnaire_user_answers_override.rb new file mode 100644 index 0000000000..25c5a08947 --- /dev/null +++ b/app/queries/concerns/decidim/forms/questionnaire_user_answers_override.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module Decidim + module Forms + module QuestionnaireUserAnswersOverride + extend ActiveSupport::Concern + + included do + # Override method sorting answers by created_at to match the order of the admin page + def query + answers = Answer.not_separator + .not_title_and_description + .joins(:question) + .where(questionnaire: @questionnaire) + + answers.sort_by { |answer| answer.question.position }.group_by { |a| a.user || a.session_token }.values + .sort_by { |question_answers| question_answers.map(&:created_at).min } + end + end + end + end +end diff --git a/app/services/census16_authorization_handler.rb b/app/services/census16_authorization_handler.rb index 421933fb4a..c7b2406668 100644 --- a/app/services/census16_authorization_handler.rb +++ b/app/services/census16_authorization_handler.rb @@ -6,8 +6,6 @@ # This class performs a check against the official census database in order # to verify the citizen's residence. class Census16AuthorizationHandler < CensusAuthorizationHandler - include Virtus::Multiparams - def age_limit errors.add(:date_of_birth, I18n.t("census16_authorization_handler.age_under", min_age: 16)) unless age && age >= 16 end diff --git a/app/services/census_authorization_handler.rb b/app/services/census_authorization_handler.rb index 8f7856ed13..41eb625cce 100644 --- a/app/services/census_authorization_handler.rb +++ b/app/services/census_authorization_handler.rb @@ -7,7 +7,6 @@ # to verify the citizen's residence. class CensusAuthorizationHandler < Decidim::AuthorizationHandler include ActionView::Helpers::SanitizeHelper - include Virtus::Multiparams AVAILABLE_GENDERS = %w(man woman non_binary).freeze @@ -36,18 +35,18 @@ class CensusAuthorizationHandler < Decidim::AuthorizationHandler def metadata super.merge( date_of_birth: date_of_birth&.strftime("%Y-%m-%d"), - postal_code: postal_code, - scope: scope.name["ca"], - scope_id: scope.id, - scope_code: scope.code, + postal_code:, + scope: scope_name, + scope_id: scope&.id, + scope_code: scope&.code, extras: { - gender: gender + gender: } ) end def scope - Decidim::Scope.find(scope_id) + @scope ||= Decidim::Scope.find_by(id: scope_id) end def census_document_types @@ -78,6 +77,12 @@ def document_number private + def scope_name + return nil unless scope + + scope.name["ca"] + end + def sanitized_document_type case document_type&.to_sym when :dni diff --git a/app/services/census_kids_authorization_handler.rb b/app/services/census_kids_authorization_handler.rb new file mode 100644 index 0000000000..d436f583e4 --- /dev/null +++ b/app/services/census_kids_authorization_handler.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +# Checks the authorization against the census for Barcelona. +require "digest/md5" + +# This class performs a check against the official census database in order +# to verify the citizen's residence. +class CensusKidsAuthorizationHandler < CensusAuthorizationHandler + def age_limit + errors.add(:date_of_birth, I18n.t("census_kids_authorization_handler.age_under", min_age: 8)) unless age && age >= 8 + end +end diff --git a/app/services/census_sarria_sant_gervasi_authorization_handler.rb b/app/services/census_sarria_sant_gervasi_authorization_handler.rb new file mode 100644 index 0000000000..1fbbd246a8 --- /dev/null +++ b/app/services/census_sarria_sant_gervasi_authorization_handler.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +# Checks the authorization against the census for Barcelona. +require "digest/md5" + +# This class performs a check against the official census database in order +# to verify the citizen's residence. +class CensusSarriaSantGervasiAuthorizationHandler < CensusAuthorizationHandler + def scope_id + 5 + end +end diff --git a/app/services/decidim/accountability/results_csv_exporter.rb b/app/services/decidim/accountability/results_csv_exporter.rb index 26ceddc54d..b888194230 100644 --- a/app/services/decidim/accountability/results_csv_exporter.rb +++ b/app/services/decidim/accountability/results_csv_exporter.rb @@ -6,7 +6,7 @@ module Decidim module Accountability # This class handles exporting results to a CSV file. # Needs a `current_component` param with a `Decidim::Component` - class ResultsCSVExporter + class ResultsCsvExporter # Public: Initializes the service. # component - A Decidim::component to import the results into. def initialize(component) @@ -66,7 +66,7 @@ def row_for_result(result, available_locales) result.decidim_accountability_status_id, result.progress, result.resource_links_from.select { |link| link.to_type == "Decidim::Proposals::Proposal" }.map(&:to_id).sort.join(";"), - result.weight * 100.0 + (result.weight || 0) * 100.0 ] available_locales.each do |locale| row << result.title[locale] diff --git a/app/services/decidim/accountability/results_csv_importer.rb b/app/services/decidim/accountability/results_csv_importer.rb index 3a47474b92..1176dc3be6 100644 --- a/app/services/decidim/accountability/results_csv_importer.rb +++ b/app/services/decidim/accountability/results_csv_importer.rb @@ -13,7 +13,7 @@ module Accountability # This class handles importing results from a CSV file. # Needs a `current_component` param with a `Decidim::component` # in order to import the results in that component. - class ResultsCSVImporter + class ResultsCsvImporter include Decidim::FormFactory # Public: Initializes the service. @@ -26,7 +26,7 @@ def initialize(component, csv_file, current_user) @extra_context = { current_component: component, current_organization: component.organization, - current_user: current_user, + current_user:, current_participatory_space: component.participatory_space } end diff --git a/app/services/decidim_legacy_routes.rb b/app/services/decidim_legacy_routes.rb index ca6585097f..3a88e3a5cf 100644 --- a/app/services/decidim_legacy_routes.rb +++ b/app/services/decidim_legacy_routes.rb @@ -7,7 +7,6 @@ def initialize(component_translations) @component_translations = component_translations end - # rubocop:disable Rails/FindBy def call(params, _request) process = Decidim::ParticipatoryProcess.find_by(slug: params[:process_slug]) || Decidim::ParticipatoryProcess.find(params[:process_slug]) @@ -15,18 +14,17 @@ def call(params, _request) component_manifest_name = component_translation[0] component = Decidim::Component.published.find_by( - manifest_name: component_manifest_name, + manifest_name: component_manifest_name == :results ? :accountability : component_manifest_name, participatory_space: process ) if params[:resource_id] resource_class = component_translation[1] - resource = resource_class.where("extra->>'slug' = ?", params[:resource_id]).first || resource_class.find(params[:resource_id]) + resource = resource_class.find_by(id: params[:resource_id]) || resource_class.where("extra->>'slug' = ?", params[:resource_id]).first - "/processes/#{process.id}/f/#{component.id}/#{component_manifest_name}/#{resource.id}" + "/processes/#{process.slug}/f/#{component.id}/#{component_manifest_name}/#{resource.id}" else - "/processes/#{process.id}/f/#{component.id}" + "/processes/#{process.slug}/f/#{component.id}" end end - # rubocop:enable Rails/FindBy end diff --git a/app/services/pdf_signature_barcelona.rb b/app/services/pdf_signature_barcelona.rb index 6c948b7980..015710900d 100644 --- a/app/services/pdf_signature_barcelona.rb +++ b/app/services/pdf_signature_barcelona.rb @@ -26,23 +26,21 @@ def initialize(args = {}) def signed_pdf return pdf if missing_configuration? - @signed_pdf ||= begin - StringIO.open(pdf) do |stream| - parsed_pdf = Origami::PDF.read(stream) - parsed_pdf.append_page do |page| - page.add_annotation(signature_annotation) - parsed_pdf.sign( - certificate, - private_key.key, - method: "adbe.pkcs7.detached", - annotation: signature_annotation, - location: location, - contact: contact, - issuer: issuer - ) - end - extract_signed_pdf(parsed_pdf) + @signed_pdf ||= StringIO.open(pdf) do |stream| + parsed_pdf = Origami::PDF.read(stream) + parsed_pdf.append_page do |page| + page.add_annotation(signature_annotation) + parsed_pdf.sign( + certificate, + private_key.key, + method: "adbe.pkcs7.detached", + annotation: signature_annotation, + location:, + contact:, + issuer: + ) end + extract_signed_pdf(parsed_pdf) end end @@ -75,7 +73,7 @@ def text_annotation(options = {}) annotation.set_indirect(true) annotation.Matrix = [1, 0, 0, 1, 0, 0] annotation.BBox = [0, 0, width, height] - annotation.write(caption, x: size, y: (height / 2) - (size / 2), size: size) + annotation.write(caption, x: size, y: (height / 2) - (size / 2), size:) end end @@ -87,7 +85,7 @@ def signature_annotation(options = {}) Origami::Annotation::Widget::Signature.new.tap do |annotation| annotation.set_indirect(true) annotation.Rect = Origami::Rectangle[llx: height, lly: width + height, urx: width + height, ury: width] - annotation.set_normal_appearance(text_annotation(width: width, height: height)) + annotation.set_normal_appearance(text_annotation(width:, height:)) end end end diff --git a/app/services/sms_gateway.rb b/app/services/sms_gateway.rb index c1eebe5b5b..c8e762538c 100644 --- a/app/services/sms_gateway.rb +++ b/app/services/sms_gateway.rb @@ -2,11 +2,12 @@ # A Service to send SMS to Barcelona's provider so users can be verified by SMS. class SmsGateway - attr_reader :mobile_phone_number, :code + attr_reader :mobile_phone_number, :code, :context - def initialize(mobile_phone_number, code) + def initialize(mobile_phone_number, code, context = {}) @mobile_phone_number = mobile_phone_number @code = code + @context = context end def deliver_code @@ -32,7 +33,7 @@ def response end def text - I18n.t("decidim.sms.text", code: code) + I18n.t("decidim.sms.text", code:) end private diff --git a/app/views/census16_authorization/_form.html.erb b/app/views/census16_authorization/_form.html.erb index 47d975f0f1..e81b7e8c5f 100644 --- a/app/views/census16_authorization/_form.html.erb +++ b/app/views/census16_authorization/_form.html.erb @@ -1,33 +1,35 @@ -
- <%= form.select :document_type, handler.census_document_types, prompt: true %> -
+
+
+ <%= form.select :document_type, handler.census_document_types, prompt: true %> +
-
- <%= form.text_field :document_number %> -
+
+ <%= form.text_field :document_number %> +
-
- <%= form.date_select :date_of_birth, start_year: 1900, end_year: 16.years.ago.year, default: 35.years.ago, prompt: { day: t(".date_select.day"), month: t(".date_select.month"), year: t(".date_select.year") } %> -
+
+ <%= form.date_select :date_of_birth, start_year: 1900, end_year: 16.years.ago.year, default: 35.years.ago, prompt: { day: t(".date_select.day"), month: t(".date_select.month"), year: t(".date_select.year") } %> +
-
- <%= form.text_field :postal_code %> -
+
+ <%= form.text_field :postal_code %> +
-
- <% parent_scope = Decidim::Scope.where("name->>'ca' = 'Ciutat'").first %> - <%= form.collection_select :scope_id, current_organization.scopes.where(parent: parent_scope), :id, ->(scope){ translated_attribute(scope.name) }, prompt: t(".scope_prompt") %> -
+
+ <% parent_scope = Decidim::Scope.where("name->>'ca' = 'Ciutat'").first %> + <%= form.collection_select :scope_id, current_organization.scopes.where(parent: parent_scope), :id, ->(scope){ translated_attribute(scope.name) }, prompt: t(".scope_prompt") %> +
-
- <%= form.collection_select( - :gender, - Census16AuthorizationHandler::AVAILABLE_GENDERS, - :to_s, - ->(gender) { t(".genders.#{gender}") }, - prompt: t(".gender_prompt") - ) %> -

<%= t ".gender_help" %>

-
+
+ <%= form.collection_select( + :gender, + Census16AuthorizationHandler::AVAILABLE_GENDERS, + :to_s, + ->(gender) { t(".genders.#{gender}") }, + prompt: t(".gender_prompt") + ) %> +

<%= t ".gender_help" %>

+
-<%= form.hidden_field :handler_name %> + <%= form.hidden_field :handler_name %> +
diff --git a/app/views/census_authorization/_form.html.erb b/app/views/census_authorization/_form.html.erb index 66444b1c1f..a8f4bb6318 100644 --- a/app/views/census_authorization/_form.html.erb +++ b/app/views/census_authorization/_form.html.erb @@ -1,33 +1,35 @@ -
- <%= form.select :document_type, handler.census_document_types, prompt: true %> -
+
+
+ <%= form.select :document_type, handler.census_document_types, prompt: true %> +
-
- <%= form.text_field :document_number %> -
+
+ <%= form.text_field :document_number %> +
-
- <%= form.date_select :date_of_birth, start_year: 1900, end_year: 14.years.ago.year, default: 35.years.ago, prompt: { day: t(".date_select.day"), month: t(".date_select.month"), year: t(".date_select.year") } %> -
+
+ <%= form.date_select :date_of_birth, start_year: 1900, end_year: 14.years.ago.year, default: 35.years.ago, prompt: { day: t(".date_select.day"), month: t(".date_select.month"), year: t(".date_select.year") } %> +
-
- <%= form.text_field :postal_code %> -
+
+ <%= form.text_field :postal_code %> +
-
- <% parent_scope = Decidim::Scope.where("name->>'ca' = 'Ciutat'").first %> - <%= form.collection_select :scope_id, current_organization.scopes.where(parent: parent_scope), :id, ->(scope){ translated_attribute(scope.name) }, prompt: t(".scope_prompt") %> -
+
+ <% parent_scope = Decidim::Scope.where("name->>'ca' = 'Ciutat'").first %> + <%= form.collection_select :scope_id, current_organization.scopes.where(parent: parent_scope), :id, ->(scope){ translated_attribute(scope.name) }, prompt: t(".scope_prompt") %> +
-
- <%= form.collection_select( - :gender, - CensusAuthorizationHandler::AVAILABLE_GENDERS, - :to_s, - ->(gender) { t(".genders.#{gender}") }, - prompt: t(".gender_prompt") - ) %> -

<%= t ".gender_help" %>

-
+
+ <%= form.collection_select( + :gender, + CensusAuthorizationHandler::AVAILABLE_GENDERS, + :to_s, + ->(gender) { t(".genders.#{gender}") }, + prompt: t(".gender_prompt") + ) %> +

<%= t ".gender_help" %>

+
-<%= form.hidden_field :handler_name %> + <%= form.hidden_field :handler_name %> +
diff --git a/app/views/census_kids_authorization/_form.html.erb b/app/views/census_kids_authorization/_form.html.erb new file mode 100644 index 0000000000..c94e9f2aa9 --- /dev/null +++ b/app/views/census_kids_authorization/_form.html.erb @@ -0,0 +1,35 @@ +
+
+ <%= form.select :document_type, handler.census_document_types, prompt: true %> +
+ +
+ <%= form.text_field :document_number %> +
+ +
+ <%= form.date_select :date_of_birth, start_year: 20.years.ago.year, end_year: 8.years.ago.year, default: 12.years.ago, prompt: { day: t(".date_select.day"), month: t(".date_select.month"), year: t(".date_select.year") } %> +
+ +
+ <%= form.text_field :postal_code %> +
+ +
+ <% parent_scope = Decidim::Scope.where("name->>'ca' = 'Ciutat'").first %> + <%= form.collection_select :scope_id, current_organization.scopes.where(parent: parent_scope), :id, ->(scope){ translated_attribute(scope.name) }, prompt: t(".scope_prompt") %> +
+ +
+ <%= form.collection_select( + :gender, + CensusKidsAuthorizationHandler::AVAILABLE_GENDERS, + :to_s, + ->(gender) { t(".genders.#{gender}") }, + prompt: t(".gender_prompt") + ) %> +

<%= t ".gender_help" %>

+
+ + <%= form.hidden_field :handler_name %> +
diff --git a/app/views/census_sarria_sant_gervasi_authorization/_form.html.erb b/app/views/census_sarria_sant_gervasi_authorization/_form.html.erb new file mode 100644 index 0000000000..85ca37d588 --- /dev/null +++ b/app/views/census_sarria_sant_gervasi_authorization/_form.html.erb @@ -0,0 +1,28 @@ +
+ <%= form.select :document_type, handler.census_document_types, prompt: true %> +
+ +
+ <%= form.text_field :document_number %> +
+ +
+ <%= form.date_select :date_of_birth, start_year: 1900, end_year: 14.years.ago.year, default: 35.years.ago, prompt: { day: t(".date_select.day"), month: t(".date_select.month"), year: t(".date_select.year") } %> +
+ +
+ <%= form.text_field :postal_code %> +
+ +
+ <%= form.collection_select( + :gender, + CensusAuthorizationHandler::AVAILABLE_GENDERS, + :to_s, + ->(gender) { t(".genders.#{gender}") }, + prompt: t(".gender_prompt") + ) %> +

<%= t ".gender_help" %>

+
+ +<%= form.hidden_field :handler_name %> diff --git a/app/views/decidim/accountability/admin/import_results/new.html.erb b/app/views/decidim/accountability/admin/import_results/new.html.erb index 0bc9efcd21..35ece2e69c 100644 --- a/app/views/decidim/accountability/admin/import_results/new.html.erb +++ b/app/views/decidim/accountability/admin/import_results/new.html.erb @@ -1,19 +1,28 @@ -<%= form_tag(Rails.application.routes.url_helpers.import_results_path(current_participatory_space, current_component), multipart: true, class: "form new_import") do %> -
-
-

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

-
+<% add_decidim_page_title(t(".title")) %> +
+

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

+
-
-
- <%= file_field_tag :csv_file %> +
+
+ <%= form_tag(Rails.application.routes.url_helpers.import_results_path(current_participatory_space, current_component), multipart: true, class: "form new_import") do %> +
+
+
+
+ <%= file_field_tag :csv_file %> +
+
+
-
-
-
- <%= submit_tag t(".import"), class: "button" %> +
+
+ <%= submit_tag t(".import"), class: "button button__sm button__secondary" %> +
+
+ <% end %>
-<% end %> +
diff --git a/app/views/decidim/accountability/admin/results/_form.html.erb b/app/views/decidim/accountability/admin/results/_form.html.erb new file mode 100644 index 0000000000..94714ec9b4 --- /dev/null +++ b/app/views/decidim/accountability/admin/results/_form.html.erb @@ -0,0 +1,79 @@ +
+
+ +
+
+ <%= form.translated :text_field, :title, autofocus: true, aria: { label: :title } %> +
+ +
+ <%= form.translated :editor, :description, aria: { label: :description } %> +
+ + <% if @form.parent_id %> + +
+ <%= form.select :parent_id, parent_results.map { |result| [translated_attribute(result.title), result.id] }, include_blank: true %> +
+ + <% else %> + + <% if current_component.has_subscopes? %> +
+ <%= scopes_select_field form, :decidim_scope_id, root: current_component.scope %> +
+ <% end %> + +
+ <%= form.categories_select :decidim_category_id, current_participatory_space.categories, include_blank: true, disable_parents: false %> +
+ + <% end %> + +
+
+ <%= form.date_field :start_date %> +
+ +
+ <%= form.date_field :end_date %> +
+
+ +
+
+ <%= form.select :decidim_accountability_status_id, statuses.map { |status| [translated_attribute(status.name), status.id, { "data-progress" => status.progress }] }, include_blank: true %> +
+ +
+ <%= form.number_field :progress %> +
+
+ + <% if Decidim::Accountability.enable_proposal_linking %> +
+ <%= render partial: "decidim/proposals/proposals/proposals_picker", locals: { form:, field: :proposals } %> +
+ <% end %> + +
+ <% if @form.projects %> + <%= form.select :project_ids, + @form.projects, + {}, + { multiple: true, class: "chosen-select" } %> + <% end %> +
+ +
+ <%= form.text_field :external_id %> +
+ +
+ <%= form.text_field :weight %> +
+ +
+
+ +
diff --git a/app/views/decidim/accountability/admin/results/index.html.erb b/app/views/decidim/accountability/admin/results/index.html.erb new file mode 100644 index 0000000000..7a3cf4a664 --- /dev/null +++ b/app/views/decidim/accountability/admin/results/index.html.erb @@ -0,0 +1,131 @@ +<% add_decidim_page_title(t(".title")) %> +
+
+

+ <% if parent_result %> + <%= "#{translated_attribute(parent_result.title)} > " %> + <% end %> + <%= t(".title") %> + + <%= export_dropdowns(query) %> + <%= import_dropdown do %> + <% if allowed_to?(:create, :result) && parent_result.nil? %> + <%= link_to new_projects_import_path do %> +
  • + <%= t("actions.import", scope: "decidim.accountability", name: t("models.result.name", scope: "decidim.accountability.admin")) %> +
  • + <% end %> + <% end %> + <% if allowed_to? :create, :result %> + <%= link_to import_results_path do %> +
  • + <%= t("actions.import_csv", scope: "decidim.accountability") %> +
  • + <% end %> + <% end %> + <% end %> + <%= link_to t("decidim.accountability.admin.shared.subnav.import_csv"), Rails.application.routes.url_helpers.import_results_path(current_participatory_space, current_component), class: "button button__sm button__secondary" %> + <%= render partial: "decidim/accountability/admin/shared/subnav" unless parent_result %> + <%= link_to t("actions.new_result", scope: "decidim.accountability"), new_result_path(parent_id: parent_result), class: "button button__sm button__secondary" if allowed_to? :create, :result %> + <%= render partial: "decidim/admin/components/resource_action" %> +

    +
    + + <%= admin_filter_selector(:results) %> +
    + + + + + + + <% if resource_with_scopes_enabled? %> + + <% end %> + + + + + + + + <% results.each do |result| %> + + + + + <%= td_resource_scope_for(result.scope) %> + + + + + + + <% end %> + +
    + <%= sort_link(query, :id, t("models.result.fields.id", scope: "decidim.accountability"), default_order: :desc ) %> + + <%= sort_link(query, :title, t("models.result.fields.title", scope: "decidim.accountability")) %> + + <%= sort_link(query, :category_name, t("models.result.fields.category", scope: "decidim.accountability") ) %> + + <%= sort_link(query, :scope_name, t("models.result.fields.scope", scope: "decidim.accountability") ) %> + + <%= sort_link(query, :status_name, t("models.result.fields.status", scope: "decidim.accountability") ) %> + + <%= sort_link(query, :progress, t("models.result.fields.progress", scope: "decidim.accountability") ) %> + + <%= sort_link(query, :created_at, t("models.result.fields.created_at", scope: "decidim.accountability") ) %> + <%= t("actions.title", scope: "decidim.accountability") %>
    + <%= result.id %>
    +
    + <% if result.parent_id.nil? %> + <%= link_to translated_attribute(result.title), results_path(parent_id: result.id) %>
    + <% else %> + <%= translated_attribute(result.title) %> + <% end %> +
    + <% if result.category %> + <%= translated_attribute result.category.name %> + <% end %> + + <% if result.status %> + <%= translated_attribute result.status.name %> + <% end %> + + <%= result.progress&.to_i %> + + <%= l result.created_at, format: :decidim_short %> + + <% if allowed_to? :update, :result, result: result %> + <%= icon_link_to "pencil-line", edit_result_path(result), t("actions.edit", scope: "decidim.accountability"), class: "action-icon--edit" %> + <% end %> + + <% if allowed_to? :create_children, :result, result: result %> + <%= icon_link_to "add-line", results_path(parent_id: result.id), t("actions.new_result", scope: "decidim.accountability"), class: "action-icon--plus" %> + <% end %> + + <% if allowed_to? :update, :result, result: result %> + <%= icon_link_to "time-line", result_timeline_entries_path(result), t("actions.timeline_entries", scope: "decidim.accountability"), class: "action-icon--clock" %> + <% end %> + + <% if allowed_to? :update, :result, result: result %> + <%= icon_link_to "folder-line", result_attachment_collections_path(result), t("actions.attachment_collections", scope: "decidim.accountability"), class: "action-icon--attachment_collections" %> + <% end %> + + <% if allowed_to? :update, :result, result: result %> + <%= icon_link_to "attachment-line", result_attachments_path(result), t("actions.attachments", scope: "decidim.accountability"), class: "action-icon--attachments" %> + <% end %> + + <%= icon_link_to "eye-line", resource_locator(result).path, t("actions.preview", scope: "decidim.accountability"), class: "action-icon--preview", target: :blank, data: { "external-link": false } %> + + <%= resource_permissions_link(result) %> + + <% if allowed_to? :destroy, :result, result: result %> + <%= icon_link_to "delete-bin-line", result_path(result), t("actions.destroy", scope: "decidim.accountability"), class: "action-icon--remove", method: :delete, data: { confirm: t("actions.confirm_destroy", scope: "decidim.accountability", name: t("models.result.name", scope: "decidim.accountability.admin")) } %> + <% end %> +
    +
    +
    +<%= decidim_paginate results %> diff --git a/app/views/decidim/accountability/import_mailer/import.html.erb b/app/views/decidim/accountability/import_mailer/import.html.erb index fa79310bb1..9a756ca139 100644 --- a/app/views/decidim/accountability/import_mailer/import.html.erb +++ b/app/views/decidim/accountability/import_mailer/import.html.erb @@ -23,5 +23,3 @@ <% end %> <% end %> - - diff --git a/app/views/decidim/accountability/results/_home_categories.html.erb b/app/views/decidim/accountability/results/_home_categories.html.erb index bb83d44d9f..7ef6946e8c 100644 --- a/app/views/decidim/accountability/results/_home_categories.html.erb +++ b/app/views/decidim/accountability/results/_home_categories.html.erb @@ -1,157 +1,46 @@ -<% - categories_with_children = first_class_categories.select { |category| category.subcategories.any? } - categories_without_children = first_class_categories.reject { |category| category.subcategories.any? } -%> -
    -
    -
    -
    - <%= icon("arrow-bottom", class: "icon", aria_label: categories_label, role: "img") %> - <%= categories_label %> -
    -
    - <% if categories_with_children.any? %> - <%= icon("arrow-bottom", class: "icon", aria_label: subcategories_label, role: "img") %> - <%= subcategories_label %> - <% end %> - -
    - <%= render partial: "search" %> -
    - -
    +<% unless children %> + + <%= categories_label %> + +<% end %> + +
    __grid"> + <% first_class_categories.each do |category| %> + <% category_results_count = count_calculator(current_scope, category) %> + <% next if category_results_count == 0 %> + + <% subelements = cell( + "decidim/accountability/status", + category, + show_category_image:, + extra_classes: "accountability__status__background", + url: results_path(filter: { with_category: category, with_scope: current_scope }), + render_blank: true + ) %> + +
    + <%= categories_label %> + <%= subelements.call %>
    -
    -
    -
    -
    - <% if categories_with_children.any? %> -
    - <% categories_without_children.each do |category| %> - <% category_results_count = count_calculator(current_scope, category) %> - <% next if category_results_count == 0 %> -
    - <% progress = progress_calculator(current_scope, category) %> - <%= link_to results_path(filter: { category_id: category, scope_id: current_scope }), class: "medium-4 columns end card__link card__link--block block--scope" do %> -
    - <% if show_category_image %> - <%= image_pack_tag("media/images/category-#{category.id}.jpg") %> - <% end %> -

    <%= translated_attribute(category.name) %>

    - -
    -
    -
    - - <% if component_settings.display_progress_enabled? && progress.present? %> -
    -
    - <%= display_percentage progress %> -
    -
    - <%= display_count category_results_count %> -
    -
    - <% end %> -
    -
    - <% end %> + <% if children %> +
    + <%= subcategories_label %> + <% if subelements.has_results? %> +
    + <% category.subcategories.each do |subcategory| %> + <%= cell( + "decidim/accountability/status", + subcategory, + extra_classes: "accountability__status__border", + url: results_path(filter: { with_category: subcategory, with_scope: current_scope }) + ) %> <% end %>
    <% else %> -
    -
    -
    - <% categories_without_children.each do |category| %> - <% category_results_count = count_calculator(current_scope, category) %> - <% next if category_results_count == 0 %> - <% progress = progress_calculator(current_scope, category) %> - <%= link_to results_path(filter: { category_id: category, scope_id: current_scope }), class: "medium-4 columns end card__link card__link--block block--scope" do %> -
    -
    - <% if show_category_image %> - <%= image_pack_tag("media/images/category-#{category.id}.jpg") %> - <% end %> - <%= translated_attribute(category.name) %> - -
    -
    -
    - - <% if component_settings.display_progress_enabled? && progress.present? %> -
    -
    - <%= display_percentage progress %> -
    -
    - <%= display_count category_results_count %> -
    -
    - <% end %> -
    -
    - <% end %> - <% end %> -
    -
    -
    - <% end %> - - <% categories_with_children.each do |category| %> - <% next if (category_results_count = count_calculator(current_scope, category.id)) == 0 %> -
    -
    -
    -

    - <%= link_to translated_attribute(category.name),results_path(filter: { category_id: category, scope_id: current_scope }) %>

    - - <% if component_settings.display_progress_enabled? && progress_calculator(current_scope, category.id).present? %> -
    -
    -
    - <% end %> - -
    - <% if component_settings.display_progress_enabled? && progress_calculator(current_scope, category.id).present? %> -
    - <%= display_percentage progress_calculator(current_scope, category.id) %> -
    - <% end %> -
    - <%= display_count(category_results_count) if category_results_count && category_results_count > 0 %> -
    -
    -
    -
    - -
    -
    - <% category.subcategories.each do |subcategory| %> - <% if (subcategory_results_count = count_calculator(current_scope, subcategory.id)) > 0 %> - <%= link_to results_path(filter: { category_id: subcategory, scope_id: current_scope }), class: "medium-4 columns end card__link card__link--block" do %> -
    - <%= translated_attribute(subcategory.name) %> - - <% if component_settings.display_progress_enabled? && progress_calculator(current_scope, subcategory.id).present? %> -
    - <%= display_percentage progress_calculator(current_scope, subcategory.id) %> -
    - <% end %> - -
    - <%= display_count subcategory_results_count %> -
    -
    - <% end %> - <% end %> - <% end %> - -
    -
    -
    + <%= cell("decidim/announcement", t("no_results", scope: "decidim.accountability.results")) %> <% end %>
    -
    -
    + <% end %> + <% end %>
    diff --git a/app/views/decidim/accountability/results/_home_scopes.html.erb b/app/views/decidim/accountability/results/_home_scopes.html.erb index e473065fad..fcbe8f5a0e 100644 --- a/app/views/decidim/accountability/results/_home_scopes.html.erb +++ b/app/views/decidim/accountability/results/_home_scopes.html.erb @@ -1,41 +1,23 @@ -
    -
    -
    -
    -
    -
    -
    - <% current_participatory_space.subscopes.order(Arel.sql("code::INTEGER ASC")).each do |scope| %> - <% scope_results_count = count_calculator(scope.id, 'all') %> - <% progress = progress_calculator(scope.id, 'all') %> - <%= link_to results_path(filter: { scope_id: scope.id }), class: "medium-4 columns end card__link card__link--block block--scope" do %> -
    - <%= image_pack_tag("media/images/districte-#{scope.id}.jpg") %> -
    - <%= translated_attribute(scope.name) %> - -
    -
    -
    - - <% if component_settings.display_progress_enabled? && progress.present? %> -
    -
    - <%= display_percentage progress %> -
    -
    - <%= display_count scope_results_count %> -
    -
    - <% end %> -
    -
    - <% end %> - <% end %> -
    +
    +
    + <% current_participatory_space.subscopes.order(Arel.sql("code::INTEGER ASC")).each do |scope| %> + <% scope_results_count = count_calculator(scope.id, "all") %> + <% progress = progress_calculator(scope.id, "all") %> +
    + <%= link_to results_path(filter: { with_scope: scope.id }), class: "accountability__status accountability__status__background" do %> + <%= image_pack_tag("media/images/districte-#{scope.id}.jpg") %> +

    <%= translated_attribute(scope.name) %>

    +
    +
    -
    + <% if component_settings.display_progress_enabled? && progress.present? %> +
    + <%= display_percentage progress %> + <%= display_count scope_results_count %> +
    + <% end %> + <% end %>
    -
    + <% end %>
    diff --git a/app/views/decidim/accountability/results/_results_leaf.html.erb b/app/views/decidim/accountability/results/_results_leaf.html.erb deleted file mode 100644 index 2d0194ad23..0000000000 --- a/app/views/decidim/accountability/results/_results_leaf.html.erb +++ /dev/null @@ -1,47 +0,0 @@ -
    -

    - <%= heading_leaf_level_results(total_count) %> -

    -
    - -
    -
    -
    - <% results.each do |result| %> -
    - <%= icon "actions", class: "card--list__icon", role: "img", "aria-hidden": true, remove_icon_class: true %> - - <%= link_to result_path(result), class: "card--list__text card__link card__link--block" do %> -

    - <%= translated_attribute(result.title) %> -

    - -
    - <% if result.start_date %> - <%= t("models.result.fields.start_date", scope: "decidim.accountability") %> - <%= l result.start_date, format: :decidim_short %> - <% end %> - - <% if result.end_date %> - <%= t("models.result.fields.end_date", scope: "decidim.accountability") %> - <%= l result.end_date, format: :decidim_short %> - <% end %> - - <% if result.status %> - <%= t("models.result.fields.status", scope: "decidim.accountability") %> - <%= translated_attribute(result.status.name) %> - <% end %> -
    - <% end %> - - <% if component_settings.display_progress_enabled? && result.progress.present? && !Decidim::Accountability::Result.not_computable_results.include?(result.id) %> -
    - <%= display_percentage result.progress %> -
    - <% end %> -
    - <% end %> -
    - <%= decidim_paginate results, order_start_time: params[:order_start_time], scope_id: params[:scope_id] %> -
    -
    diff --git a/app/views/decidim/accountability/results/_scope_filters.html.erb b/app/views/decidim/accountability/results/_scope_filters.html.erb new file mode 100644 index 0000000000..7c648c9d6f --- /dev/null +++ b/app/views/decidim/accountability/results/_scope_filters.html.erb @@ -0,0 +1,32 @@ +<% hide_subscopes ||= false %> +<% items = filter_items_for(participatory_space: current_participatory_space, category:) %> +
    + <%= render partial: "search" %> + + <% if current_component.has_subscopes? && !hide_subscopes %> +
    + + +
    + <% end %> +
    diff --git a/app/views/decidim/accountability/results/_show_leaf.html.erb b/app/views/decidim/accountability/results/_show_leaf.html.erb deleted file mode 100644 index e8637a198f..0000000000 --- a/app/views/decidim/accountability/results/_show_leaf.html.erb +++ /dev/null @@ -1,83 +0,0 @@ -
    -
    - <%= render partial: "decidim/accountability/results/nav_breadcrumb", locals: { category: result.parent.try(:category) || result.category } %> -
    -
    -
    - <%= icon("proposals", class: "icon", aria_label: t("models.result.fields.title", scope: "decidim.accountability"), role: "img") %> -

    <%= translated_attribute result.title %>

    -
    - -
    - <% if component_settings.display_progress_enabled? && result.progress.present? %> -
    - <% unless Decidim::Accountability::Result.not_computable_results.include?(result.id) %> -
    -
    - <%= t("models.result.fields.progress", scope: "decidim.accountability") %>: - - <%= display_percentage result.progress %> - -
    - -
    -
    -
    -
    - <% end %> -
    - <% end %> - -
    "> -
    -
    - <% if result.start_date %> -
    <%= t("models.result.fields.start_date", scope: "decidim.accountability") %>
    -
    <%= l result.start_date, format: :decidim_short %>
    - <% end %> -
    - -
    - <% if result.end_date %> -
    <%= t("models.result.fields.end_date", scope: "decidim.accountability") %>
    -
    <%= l result.end_date, format: :decidim_short %>
    - <% end %> -
    - -
    - <% if result.status %> -
    <%= t("models.result.fields.status", scope: "decidim.accountability") %>
    -
    <%= translated_attribute(result.status.name) %>
    - <% end %> -
    - -
    - <% if result.status && translated_attribute(result.status.description).present? %> -
    <%= t("models.status.fields.description", scope: "decidim.accountability") %>
    -
    <%= translated_attribute(result.status.description) %>
    - <% end %> -
    -
    -
    - -
    - -
    -
    - <%== translated_attribute result.description %> - <%= cell "decidim/tags", result, context: { extra_classes: ["tags--result"] } %> -
    -
    - - <%= render partial: "stats_box" %> - - <%= render partial: "timeline", locals: { result: result } if result.timeline_entries.any? %> - - <%= attachments_for result %> -
    -
    - - <%= render partial: "stats" %> -
    - -<%= comments_for result %> \ No newline at end of file diff --git a/app/views/decidim/accountability/results/_stats_box.html.erb b/app/views/decidim/accountability/results/_stats_box.html.erb new file mode 100644 index 0000000000..592c0decc8 --- /dev/null +++ b/app/views/decidim/accountability/results/_stats_box.html.erb @@ -0,0 +1,79 @@ +
    + + <% if result.children.any? && component_settings.display_progress_enabled? && result.progress.present? && !Decidim::Accountability::Result.not_computable_results.include?(result.id) %> +
    +
    + <%= t("models.result.fields.progress", scope: "decidim.accountability") %>: + + <%= display_percentage result.progress %> + +
    + +
    +
    +
    +
    + <% end %> + + <% if result.versions.any? || result.linked_resources(:proposals, "included_proposals").any? %> +
    +
    + <% if result.versions.any? %> +
    +
    + <%= resource_version_number(result.versions_count) %> + + <%= resource_version_of(result.versions_count) %> + +
    + +
    + + <%= link_to_other_resource_versions(result_versions_path(result)) %> + +
    +
    + <% if result.last_editor.present? %> +
    + <%= t("results.show.stats.last_edited_by", scope: "decidim.accountability") %> + <%= render_resource_last_editor(result) %> +
    + <% end %> +
    + <%= t("results.show.stats.last_updated_at", scope: "decidim.accountability") %> + <%= l result.versions.last.created_at, format: :decidim_short %> +
    + <% end %> + <% if result.linked_resources(:proposals, "included_proposals").any? %> +
    + <%= t("results.show.stats.proposals", scope: "decidim.accountability") %> + <%= stats_calculator.proposals_count %> +
    +
    + <%= t("results.show.stats.meetings", scope: "decidim.accountability") %> + <%= stats_calculator.meetings_count %> +
    +
    + <%= t("results.show.stats.comments", scope: "decidim.accountability") %> + <%= stats_calculator.comments_count %> +
    +
    + <%= t("results.show.stats.attendees", scope: "decidim.accountability") %> + <%= stats_calculator.attendees_count %> +
    +
    + <%= t("results.show.stats.votes", scope: "decidim.accountability") %> + <%= stats_calculator.votes_count %> +
    +
    + <%= t("results.show.stats.contributions", scope: "decidim.accountability") %> + <%= stats_calculator.contributions_count %> +
    + <% end %> +
    +
    + <% end %> + + <%= resource_reference(result) %> + <%= render partial: "decidim/shared/share_modal" %> +
    diff --git a/app/views/decidim/accountability/results/home.html.erb b/app/views/decidim/accountability/results/home.html.erb index 2b959d0530..19b0758f6e 100644 --- a/app/views/decidim/accountability/results/home.html.erb +++ b/app/views/decidim/accountability/results/home.html.erb @@ -1,27 +1,52 @@ -
    -
    - <%= render partial: "home_header" %> +<% add_decidim_page_title component_name %> +<%= append_javascript_pack_tag "decidim_accountability" %> +<%= append_stylesheet_pack_tag "decidim_accountability" %> + +<% content_for :aside do %> +

    <%= component_name %>

    + + <% if component_settings.display_progress_enabled? %> + <%= cell( + "decidim/accountability/status", + nil, + title: t("decidim.accountability.results.home_header.global_status"), + progress: progress_calculator(current_scope, nil).presence, + extra_classes: "accountability__status__home" + ) %> + <% end %> + + <%= render partial: "scope_filters", locals: { hide_subscopes: current_participatory_space.slug.to_s == "PressupostosParticipatius" } %> + + <%= link_to t("decidim.accountability.results.home_header.csv_download"), Rails.application.routes.url_helpers.export_results_path(current_participatory_space, current_component), class: "button button__sm button__secondary" %> +<% end %> + +<%= render layout: "layouts/decidim/shared/layout_two_col" do %> + +
    +
    <%= decidim_sanitize_admin translated_attribute(component_settings.intro) %>
    +
    + +
    <% if (ENV["PARTICIPATORY_SPACES_WITH_ACCOUNTABILITY_RESULTS"] || "").split(',').include?(current_participatory_space.slug.to_s) %> -
    - <%= render partial: "search" %> -
    -
    - <%= render partial: "scope_filters", locals: { url_method: :results_path } %> -
    -
    - <% if results.any?{|r| r.children_count > 0 } %> - <%= render partial: "results_parent", locals: { results: results, total_count: results.total_count } %> - <% else %> - <%= render partial: "results_leaf", locals: { results: results, total_count: results.total_count } %> - <% end %> -
    + <%= cell "decidim/accountability/results", results %> + <%= decidim_paginate results, order_start_time: params[:order_start_time], with_scope: params.dig(:filter, :with_scope), hide_results_per_page_selector: true %> <% else %> + + <% if first_class_categories.empty? %> + <%= cell("decidim/announcement", + params[:filter].present? ? + t("empty_filters", scope: "decidim.accountability.results.home") : + t("empty", scope: "decidim.accountability.results.home")) %> + <% end %> + <% if current_participatory_space.slug.to_s == "PressupostosParticipatius" %> <%= render partial: "home_scopes" %> <% end %> - <%= render partial: "home_categories", locals: { show_category_image: current_participatory_space.slug.to_s == "forumjoveBCN" } %> + + <%= render partial: "home_categories", + locals: { children: first_class_categories.select { |category| category.subcategories.any? }.any?, + show_category_image: (ENV["PARTICIPATORY_SPACES_WITH_CATEGORY_IMAGES"] || "").split(",").include?(current_participatory_space.slug.to_s) } %> <% end %> -
    -
    + -<%= javascript_pack_tag "decidim_accountability" %> +<% end %> diff --git a/app/views/decidim/accountability/results/index.html.erb b/app/views/decidim/accountability/results/index.html.erb new file mode 100644 index 0000000000..dc27a5397d --- /dev/null +++ b/app/views/decidim/accountability/results/index.html.erb @@ -0,0 +1,17 @@ +<%= append_javascript_pack_tag "decidim_accountability" %> +<%= append_stylesheet_pack_tag "decidim_accountability" %> + +<% content_for :aside do %> + <%= render partial: "projects_aside", locals: { main_action: true } %> +<% end %> + +<%= render layout: "layouts/decidim/shared/layout_two_col" do %> +
    +

    <%= category.present? ? decidim_escape_translated(category.name) : t("decidim.accountability.results.home_header.global_status") %>

    +
    + +
    + <%= cell "decidim/accountability/results", results %> + <%= decidim_paginate results, order_start_time: params[:order_start_time], with_scope: params.dig(:filter, :with_scope), hide_results_per_page_selector: true %> +
    +<% end %> diff --git a/app/views/decidim/forms/admin/questionnaires/answers/show.html.erb b/app/views/decidim/forms/admin/questionnaires/answers/show.html.erb new file mode 100644 index 0000000000..78a5e2aebf --- /dev/null +++ b/app/views/decidim/forms/admin/questionnaires/answers/show.html.erb @@ -0,0 +1,43 @@ +
    +
    +

    + <%= t ".title", number: current_idx + 1 %> + + <%= link_to t("actions.next", scope: "decidim.forms.admin.questionnaires.answers").html_safe, next_url, rel: "next", class: "button button__sm button__secondary next" unless last? %> + <%= link_to t("actions.previous", scope: "decidim.forms.admin.questionnaires.answers").html_safe, prev_url, rel: "prev", class: "button button__sm button__secondary prev" unless first? %> + <%= link_to t("actions.export", scope: "decidim.forms.admin.questionnaires.answers"), questionnaire_export_response_url(@participant.session_token), class: "button button__sm button__secondary export" %> + <%= link_to t("actions.back", scope: "decidim.forms.admin.questionnaires.answers"), questionnaire_participants_url, class: "button button__sm button__secondary back" %> +

    +
    +
    +
    + + + + + + + + + + + + + + + + + + + + +
    <%= t("session_token", scope: "decidim.forms.user_answers_serializer") %><%= t("user_status", scope: "decidim.forms.user_answers_serializer") %><%= t("ip_hash", scope: "decidim.forms.user_answers_serializer") %><%= t("completion", scope: "decidim.forms.user_answers_serializer") %><%= t("created_at", scope: "decidim.forms.user_answers_serializer") %>
    <%= @participant.session_token %><%= @participant.status %><%= @participant.ip_hash %><%= display_percentage(@participant.completion) %><%= l @participant.answered_at, format: :short %>
    +
    +
    + <% @participant.answers.each do |answer| %> +
    <%= answer.question %>
    +
    <%= answer.body %>
    + <% end %> +
    +
    +
    diff --git a/app/views/decidim/initiatives/admin/initiatives/_signatures.html.erb b/app/views/decidim/initiatives/admin/initiatives/_signatures.html.erb new file mode 100644 index 0000000000..4f76a8fee7 --- /dev/null +++ b/app/views/decidim/initiatives/admin/initiatives/_signatures.html.erb @@ -0,0 +1,85 @@ +<% style_initiative_title = "border: 1pt solid black; margin: 15pt 0; font-size: 12pt; font-weight: bold; text-transform: uppercase; text-align: center;" %> +<% style_initiatives_votes_table = "width: 100%; display: block; border: 1pt solid black;" %> +<% style_initiatives_votes_table_header = "background-color: lightgray; display: inline-block; width: 100%; font-size: 12pt; font-weight: bold; border-bottom: 1pt solid black;" %> +<% style_initiatives_votes_table_row = "width: 100%; display: inline-block; min-height: 33pt;" %> +<% style_initiatives_votes_table_cell = "width: 19%; padding-left: 5pt; word-wrap: break-word; display: inline-block; float: left; min-height: 36pt;" %> +
    + <%= translated_attribute(initiative.title) %> +
    +
    +
    +
    + <%= t("models.initiatives_votes.fields.initiative_id", scope: "decidim.admin") %> +
    +
    + <%= t("models.initiatives_votes.fields.initiative_title", scope: "decidim.admin") %> +
    +
    + <%= t("models.initiatives_votes.fields.initiative_start_date", scope: "decidim.admin") %> +
    +
    + <%= t("models.initiatives_votes.fields.initiative_end_date", scope: "decidim.admin") %> +
    +
    + <%= t("models.initiatives_votes.fields.initiative_signatures_count", scope: "decidim.admin") %> +
    +
    +
    +
    + <%= initiative.reference %> +
    +
    + <%= translated_attribute(initiative.title) %> +
    +
    + <%= initiative.signature_start_date %> +
    +
    + <%= initiative.signature_end_date %> +
    +
    + <%= votes.count %> +
    +
    +
    +
    +
    +
    +
    +
    + <%= t("models.initiatives_votes.fields.initiative_id", scope: "decidim.admin") %> +
    +
    + <%= t("models.initiatives_votes.fields.initiative_title", scope: "decidim.admin") %> +
    + <% if collect_user_extra_fields %> +
    + <%= t("models.initiatives_votes.fields.name_and_surname", scope: "decidim.admin") %> +
    +
    + <%= t("models.initiatives_votes.fields.document_number", scope: "decidim.admin") %> +
    +
    + <%= t("models.initiatives_votes.fields.date_of_birth", scope: "decidim.admin") %> +
    +
    + <%= t("models.initiatives_votes.fields.postal_code", scope: "decidim.admin") %> +
    + <% end %> +
    + <%= t("models.initiatives_votes.fields.time_and_date", scope: "decidim.admin") %> +
    +
    + <%= t("models.initiatives_votes.fields.timestamp", scope: "decidim.admin") %> +
    +
    + <%= t("models.initiatives_votes.fields.hash", scope: "decidim.admin") %> +
    +
    + <%= t("models.initiatives_votes.fields.scope", scope: "decidim.admin") %> +
    +
    + <% votes.each do |vote| %> + <%= cell "decidim/initiatives_votes/vote", vote %> + <% end %> +
    diff --git a/app/views/decidim/initiatives/admin/initiatives/export_pdf_signatures.pdf.erb b/app/views/decidim/initiatives/admin/initiatives/export_pdf_signatures.pdf.erb deleted file mode 100644 index 96226e0c92..0000000000 --- a/app/views/decidim/initiatives/admin/initiatives/export_pdf_signatures.pdf.erb +++ /dev/null @@ -1,78 +0,0 @@ -
    - <%= translated_attribute(current_initiative.title) %> -
    -
    -
    -
    - <%= t("models.initiatives_votes.fields.initiative_id", scope: "decidim.admin") %> -
    -
    - <%= t("models.initiatives_votes.fields.initiative_title", scope: "decidim.admin") %> -
    -
    - <%= t("models.initiatives_votes.fields.initiative_start_date", scope: "decidim.admin") %> -
    -
    - <%= t("models.initiatives_votes.fields.initiative_end_date", scope: "decidim.admin") %> -
    -
    - <%= t("models.initiatives_votes.fields.initiative_signatures_count", scope: "decidim.admin") %> -
    -
    -
    -
    - <%= current_initiative.reference %> -
    -
    - <%= translated_attribute(current_initiative.title) %> -
    -
    - <%= current_initiative.signature_start_date %> -
    -
    - <%= current_initiative.signature_end_date %> -
    -
    - <%= @votes.count %> -
    -
    -
    -
    -
    -
    -
    -
    - <%= t("models.initiatives_votes.fields.initiative_id", scope: "decidim.admin") %> -
    -
    - <%= t("models.initiatives_votes.fields.initiative_title", scope: "decidim.admin") %> -
    -
    - <%= t("models.initiatives_votes.fields.name_and_surname", scope: "decidim.admin") %> -
    -
    - <%= t("models.initiatives_votes.fields.document_number", scope: "decidim.admin") %> -
    -
    - <%= t("models.initiatives_votes.fields.date_of_birth", scope: "decidim.admin") %> -
    -
    - <%= t("models.initiatives_votes.fields.postal_code", scope: "decidim.admin") %> -
    -
    - <%= t("models.initiatives_votes.fields.time_and_date", scope: "decidim.admin") %> -
    -
    - <%= t("models.initiatives_votes.fields.timestamp", scope: "decidim.admin") %> -
    -
    - <%= t("models.initiatives_votes.fields.hash", scope: "decidim.admin") %> -
    -
    - <%= t("models.initiatives_votes.fields.scope", scope: "decidim.admin") %> -
    -
    - <% @votes.each do |vote| %> - <%= cell "decidim/initiatives_votes/vote", vote %> - <% end %> -
    diff --git a/app/views/decidim/initiatives/initiative_signatures/fill_personal_data.html.erb b/app/views/decidim/initiatives/initiative_signatures/fill_personal_data.html.erb index 9159bbb4aa..310d69f7f3 100644 --- a/app/views/decidim/initiatives/initiative_signatures/fill_personal_data.html.erb +++ b/app/views/decidim/initiatives/initiative_signatures/fill_personal_data.html.erb @@ -1,44 +1,33 @@ -
    -

    -<%= t ".help" %> -

    -
    -

    <%= t(step, scope: "layouts.decidim.initiative_signature_creation_header") %>

    +<%= cell("decidim/announcement", t("decidim.initiatives.initiative_signatures.fill_personal_data.help"), callout_class: "secondary") %> -<%= render partial: "wizard_steps" %> +<%= decidim_form_for(@form, url: fill_personal_data_initiative_signatures_path, method: :put) do |f| %> + <%= form_required_explanation %> +
    +
    + <%= f.text_field :name_and_surname, autofocus: true, required: true %> +
    -
    -
    - <%= decidim_form_for(@form, url: next_wizard_path, method: :put, html: { class: "form user_personal_data_signature_form" }) do |f| %> - <%= form_required_explanation %> -
    -
    - <%= f.text_field :name_and_surname, autofocus: true, required: true %> -
    +
    + <%= f.text_field :document_number, required: true %> +
    <%= t(".document_hint") %>
    +
    -
    - <%= f.text_field :document_number, required: true %> -

    <%= t('.document_hint') %>

    -
    +
    + <%= f.date_field :date_of_birth, min: 120.years.ago.to_date, max: 16.years.ago.to_date, value: 35.years.ago.to_date %> +
    -
    - <%= f.date_select :date_of_birth, start_year: 1900, end_year: 16.years.ago.year, default: 35.years.ago, prompt: { day: t(".date_select.day"), month: t(".date_select.month"), year: t(".date_select.year") } %> -
    +
    + <%= f.text_field :postal_code, required: true %> +
    -
    - <%= f.text_field :postal_code, required: true %> -
    - -
    - - <%= decidim_sanitize_editor translated_attribute(extra_data_legal_information) %> - -
    -
    +
    + + <%= decidim_sanitize_editor translated_attribute(extra_data_legal_information) %> + +
    +
    -
    - <%= f.submit t(".continue"), class: "button expanded" %> -
    - <% end %> +
    + <%= f.submit t(".continue"), class: "button button__sm md:button__lg button__secondary" %>
    -
    +<% end %> diff --git a/app/views/decidim/initiatives/initiatives/_progress_bar.html.erb b/app/views/decidim/initiatives/initiatives/_progress_bar.html.erb index de02dcf357..9d0ee1bfbc 100644 --- a/app/views/decidim/initiatives/initiatives/_progress_bar.html.erb +++ b/app/views/decidim/initiatives/initiatives/_progress_bar.html.erb @@ -2,23 +2,19 @@ <% current_initiative.votable_initiative_type_scopes.each_with_index do |type_scope, index| %> <% if index == 0 %> <%= cell( - "decidim/progress_bar", - current_initiative.supports_count_for(type_scope.scope), - total: current_initiative.supports_required_for(type_scope.scope), - units_name: "decidim.initiatives.initiatives.votes_count.count", - element_id: "initiative-#{current_initiative.id}-votes-count", - subtitle_text: current_initiative.supports_goal_reached? ? t("decidim.initiatives.initiatives.votes_count.most_popular_initiative") : t("decidim.initiatives.initiatives.votes_count.need_more_votes"), - small: false - ) %> + "decidim/progress_bar", + current_initiative.supports_count_for(type_scope.scope), + total: current_initiative.supports_required_for(type_scope.scope), + units_name: "decidim.initiatives.initiatives.votes_count.count", + element_id: "initiative-#{current_initiative.id}-votes-count" + ) %> <% else %> <%= cell( - "decidim/progress_bar", - current_initiative.supports_count_for(type_scope.scope), - total: current_initiative.supports_required_for(type_scope.scope), - subtitle_text: translated_attribute(type_scope.scope_name), - element_id: "initiative-scope-#{type_scope.id}-#{current_initiative.id}-votes-count", - horizontal: true - ) %> + "decidim/progress_bar", + current_initiative.supports_count_for(type_scope.scope), + total: current_initiative.supports_required_for(type_scope.scope), + element_id: "initiative-scope-#{type_scope.id}-#{current_initiative.id}-votes-count" + ) %> <% end %> <% end %>
    diff --git a/app/views/decidim/meetings/meetings/_meeting_agenda.html.erb b/app/views/decidim/meetings/meetings/_meeting_agenda.html.erb index ba04274198..ee7059a1eb 100644 --- a/app/views/decidim/meetings/meetings/_meeting_agenda.html.erb +++ b/app/views/decidim/meetings/meetings/_meeting_agenda.html.erb @@ -1,31 +1,34 @@ -
    -
    -

    <%= translated_attribute(meeting.agenda.title) %>

    +
    +
    + <%= icon "list-ordered" %> +

    <%= translated_attribute(meeting.agenda.title) %>

    -
    -
    - <% agenda_items_times = calculate_start_and_end_time_of_agenda_items(meeting.agenda.agenda_items.first_class, meeting) %> - <% zero_duration = any_zero_duration_event?(meeting.agenda.agenda_items.first_class, meeting) %> - <% meeting.agenda.agenda_items.first_class.each_with_index do |agenda_item, index| %> -
    - <%= translated_attribute(agenda_item.title) %>  - <%= zero_duration ? "" : display_duration_agenda_items(agenda_item.id, index, agenda_items_times) %> -
    -
    -

    <%= translated_attribute(agenda_item.description).html_safe %>

    - <% if agenda_item.agenda_item_children.presence %> - <% parent_start_time = agenda_items_times[index][:start_time] %> - <% agenda_item_children_times = calculate_start_and_end_time_of_agenda_items(agenda_item.agenda_item_children, meeting, parent_start_time) %> - <% agenda_item.agenda_item_children.each_with_index do |agenda_item_child, index_child| %> -
    - <%= translated_attribute(agenda_item_child.title) %>  - <%= zero_duration ? "" : display_duration_agenda_items(agenda_item_child.id, index_child, agenda_item_children_times) %> -
    -

    <%= translated_attribute(agenda_item_child.description).html_safe %>

    - <% end %> + <% agenda_items_times = calculate_start_and_end_time_of_agenda_items(meeting.agenda.agenda_items.first_class, meeting) %> + <% zero_duration = any_zero_duration_event?(meeting.agenda.agenda_items.first_class, meeting) %> + <% meeting.agenda.agenda_items.first_class.each_with_index do |agenda_item, index| %> +
    +

    + <%= translated_attribute(agenda_item.title) %> + <%= zero_duration ? "" : display_duration_agenda_items(agenda_item.id, index, agenda_items_times) %> +

    + +
    <%= decidim_sanitize(translated_attribute(agenda_item.description)).html_safe %>
    + + <% if agenda_item.agenda_item_children.presence %> + <% parent_start_time = agenda_items_times[index][:start_time] %> + <% agenda_item_children_times = calculate_start_and_end_time_of_agenda_items(agenda_item.agenda_item_children, meeting, parent_start_time) %> + + <% agenda_item.agenda_item_children.each_with_index do |agenda_item_child, index_child| %> +
    +

    + <%= translated_attribute(agenda_item_child.title) %> + <%= zero_duration ? "" : display_duration_agenda_items(agenda_item_child.id, index_child, agenda_item_children_times) %> +

    +
    <%= decidim_sanitize(translated_attribute(agenda_item_child.description)).html_safe %>
    +
    <% end %> <% end %>
    -
    -
    + <% end %> +
    diff --git a/app/views/decidim/participatory_spaces/_result.html.erb b/app/views/decidim/participatory_spaces/_result.html.erb new file mode 100644 index 0000000000..65cebbba46 --- /dev/null +++ b/app/views/decidim/participatory_spaces/_result.html.erb @@ -0,0 +1,32 @@ +
    + <%= icon "actions", class: "card--list__icon", role: "img", "aria-hidden": true, remove_icon_class: true %> + + <%= link_to resource_locator(result).path, class: "card--list__text card__link card__link--block" do %> +

    + <%= translated_attribute(result.title) %> +

    + +
    + <% if result.start_date %> + <%= t("models.result.fields.start_date", scope: "decidim.accountability") %> + <%= l result.start_date, format: :short %> + <% end %> + + <% if result.end_date %> + <%= t("models.result.fields.end_date", scope: "decidim.accountability") %> + <%= l result.end_date, format: :short %> + <% end %> + + <% if result.status %> + <%= t("models.result.fields.status", scope: "decidim.accountability") %> + <%= translated_attribute(result.status.name) %> + <% end %> +
    + <% end %> + + <% if result.progress.present? && !Decidim::Accountability::Result.not_computable_results.include?(result.id) %> +
    + <%= display_percentage result.progress %> +
    + <% end %> +
    diff --git a/app/views/layouts/decidim/_head_extra.html.erb b/app/views/layouts/decidim/_head_extra.html.erb deleted file mode 100644 index b57df26e02..0000000000 --- a/app/views/layouts/decidim/_head_extra.html.erb +++ /dev/null @@ -1,17 +0,0 @@ -<% if Rails.application.secrets.analytics %> - - - -<% end %> diff --git a/app/views/layouts/decidim/_initiative_header_steps.html.erb b/app/views/layouts/decidim/_initiative_header_steps.html.erb deleted file mode 100644 index c63f5110ff..0000000000 --- a/app/views/layouts/decidim/_initiative_header_steps.html.erb +++ /dev/null @@ -1,15 +0,0 @@ -<% if initiative.has_signature_interval_defined? %> -
    -
    - - <%= t(".signature_collection_period") %> - - - - <%= l(initiative.signature_start_date, format: :default) %> - → - <%= l(initiative.signature_end_date, format: :default) %> - -
    -
    -<% end %> \ No newline at end of file diff --git a/app/views/layouts/decidim/header/_header_language_selector.html.erb b/app/views/layouts/decidim/header/_header_language_selector.html.erb new file mode 100644 index 0000000000..d51eed46e8 --- /dev/null +++ b/app/views/layouts/decidim/header/_header_language_selector.html.erb @@ -0,0 +1,28 @@ +<% if available_locales.length > 1 %> +
    + + + +
    + <% end %> diff --git a/app/views/layouts/decidim/header/_main.html.erb b/app/views/layouts/decidim/header/_main.html.erb new file mode 100644 index 0000000000..d46c69a7b1 --- /dev/null +++ b/app/views/layouts/decidim/header/_main.html.erb @@ -0,0 +1,39 @@ +
    +
    + + + + + + +
    + <%# Main dropdown mobile %> + + + + + <%# Sticky menu mobile %> + + + <%# Overlay menus mobile %> + <%= render partial: "layouts/decidim/header/main_links_mobile_search" %> + <%= render partial: "layouts/decidim/header/main_links_mobile_account" if current_user %> +
    +
    +
    diff --git a/app/views/layouts/decidim/mailer.html.erb b/app/views/layouts/decidim/mailer.html.erb index 0e4f54c93d..c3ac566262 100644 --- a/app/views/layouts/decidim/mailer.html.erb +++ b/app/views/layouts/decidim/mailer.html.erb @@ -44,17 +44,6 @@ - - - - -
    - <% if @organization.official_img_header.attached? %> - <%= link_to @organization.official_url do %> - <%= image_tag @organization.attached_uploader(:official_img_header).url(host: @organization.host), alt: "", style: "max-height: 50px", class: "float-right" %> - <% end %> - <% end %> -
    @@ -105,7 +94,6 @@ - <% if content_for?(:note) or content_for?(:unsubscribe) %> @@ -126,6 +114,22 @@ + + +
    +
    + + + + + + + +
    + <%= t("decidim.newsletter_mailer.newsletter.no_reply_notice") %> +
    +
    +
    diff --git a/app/views/layouts/decidim/widget.html.erb b/app/views/layouts/decidim/widget.html.erb deleted file mode 100644 index 89107cc693..0000000000 --- a/app/views/layouts/decidim/widget.html.erb +++ /dev/null @@ -1,31 +0,0 @@ - - - - <%= decidim_page_title %> - <%= csrf_meta_tags %> - <%= stylesheet_pack_tag "decidim_core" %> - <%= javascript_pack_tag "decidim_core", defer: false %> - - - - <% if content_for(:header) == "false" %> - <% elsif content_for?(:header) %> - <%= content_for(:header) %> - <% else %> -
    - <%= link_to translated_attribute(current_participatory_space.title), resource_locator(current_participatory_space).path, target: "_blank" %> -
    - <% end %> -
    -
    - - <%= yield %> - -
    -
    - - <%= javascript_pack_tag "decidim_widget" %> - <%= render partial: "layouts/decidim/js_configuration" %> - <%= render partial: "layouts/decidim/cors" if Decidim.cors_enabled %> - - diff --git a/app/views/layouts/mailer.html.erb b/app/views/layouts/mailer.html.erb index cbd34d2e9d..3aac9002ed 100644 --- a/app/views/layouts/mailer.html.erb +++ b/app/views/layouts/mailer.html.erb @@ -1,7 +1,7 @@ - + diff --git a/app/views/pages/home/_extended.html.erb b/app/views/pages/home/_extended.html.erb deleted file mode 100644 index 27b7e2598e..0000000000 --- a/app/views/pages/home/_extended.html.erb +++ /dev/null @@ -1,48 +0,0 @@ -
    -
    -
    -

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

    -
    -
    -
    -
    -
    - <%= icon "meetings" %> -
    -
    -

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

    -

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

    -
    -
    -
    -
    -
    -
    - <%= icon "debates" %> -
    -
    -

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

    -

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

    -
    -
    -
    -
    -
    -
    - <%= icon "proposals" %> -
    -
    -

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

    -

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

    -
    -
    -
    -
    -
    -
    - <%= link_to t(".more_info"), page_path("more-information"), class: "button expanded hollow button--sc" %> -
    -
    -
    -
    diff --git a/app/views/static/_accountability_graph_ca.html.erb b/app/views/static/_accountability_graph_ca.html.erb index 79de7daf68..74d6d813b4 100644 --- a/app/views/static/_accountability_graph_ca.html.erb +++ b/app/views/static/_accountability_graph_ca.html.erb @@ -25,20 +25,20 @@ <%= t("static.accountability.flow_text_4_1") %> <%= t("static.accountability.flow_text_4_2") %> <%= t("static.accountability.flow_text_4_3") %> - - + + - - + + - - + + - - + + diff --git a/app/views/static/_accountability_graph_es.html.erb b/app/views/static/_accountability_graph_es.html.erb index ee59ab5ba4..33ef068784 100644 --- a/app/views/static/_accountability_graph_es.html.erb +++ b/app/views/static/_accountability_graph_es.html.erb @@ -25,20 +25,20 @@ <%= t("static.accountability.flow_text_4_1") %> <%= t("static.accountability.flow_text_4_2") %> <%= t("static.accountability.flow_text_4_3") %> - - + + - - + + - - + + - - + + diff --git a/app/views/static/accountability.html.erb b/app/views/static/accountability.html.erb index bf2d2daf0d..da111dbd4c 100644 --- a/app/views/static/accountability.html.erb +++ b/app/views/static/accountability.html.erb @@ -3,132 +3,118 @@ title: t(".meta_tags.title") }) %> -
    -
    -

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

    -

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

    - -
    -

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

    - -
    -
    -
    - <%= link_to DecidimBarcelona::Application.routes.url_helpers.accountability_sections_path(anchor: "planificacio"), class: "card__link" do %> -

    <%= icon "book" %> <%= t(".section_1_title") %>

    - <% end %> +
    +
    +

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

    +

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

    +
    -
    -
      -
    • <%= link_to DecidimBarcelona::Application.routes.url_helpers.accountability_sections_path(anchor: "planificacio"), class: "card__link" do %><%= t(".section_1_item_1") %><% end %>
    • -
    • <%= link_to DecidimBarcelona::Application.routes.url_helpers.accountability_sections_path(anchor: "planificacio"), class: "card__link" do %><%= t(".section_1_item_2") %><% end %>
    • -
    • <%= link_to DecidimBarcelona::Application.routes.url_helpers.accountability_sections_path(anchor: "planificacio"), class: "card__link" do %><%= t(".section_1_item_3") %><% end %>
    • -
    -
    -
    +
    +

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

    +
    +
    +
    + <%= link_to DecidimBarcelona::Application.routes.url_helpers.accountability_sections_path("planificacio"), class: "card__link", style: "text-decoration: none;" do %> +

    <%= icon "bookmark-line", style: "display: inline;" %> <%= t(".section_1_title") %>

    + <% end %> +
      +
    • <%= t(".section_1_item_1") %>
    • +
    • <%= t(".section_1_item_2") %>
    • +
    • <%= t(".section_1_item_3") %>
    • +
    +
    -
    -
    - <%= link_to DecidimBarcelona::Application.routes.url_helpers.accountability_sections_path(anchor: "economia"), class: "card__link" do %> -

    <%= icon "graph" %> <%= t(".section_2_title") %>

    - <% end %> - -
    -
      -
    • <%= link_to DecidimBarcelona::Application.routes.url_helpers.accountability_sections_path(anchor: "economia"), class: "card__link" do %><%= t(".section_2_item_1") %><% end %>
    • -
    • <%= link_to DecidimBarcelona::Application.routes.url_helpers.accountability_sections_path(anchor: "economia"), class: "card__link" do %><%= t(".section_2_item_2") %><% end %>
    • -
    • <%= link_to DecidimBarcelona::Application.routes.url_helpers.accountability_sections_path(anchor: "economia"), class: "card__link" do %><%= t(".section_2_item_3") %><% end %>
    • -
    -
    -
    +
    +
    + <%= link_to DecidimBarcelona::Application.routes.url_helpers.accountability_sections_path("economia"), class: "card__link", style: "text-decoration: none;" do %> +

    <%= icon "bar-chart-2-line", style: "display: inline;" %> <%= t(".section_2_title") %>

    + <% end %> +
      +
    • <%= t(".section_2_item_1") %>
    • +
    • <%= t(".section_2_item_2") %>
    • +
    • <%= t(".section_2_item_3") %>
    • +
    -
    -
    -
    - <%= link_to DecidimBarcelona::Application.routes.url_helpers.accountability_sections_path(anchor: "serveis"), class: "card__link" do %> -

    <%= icon "key" %> <%= t(".section_3_title") %>

    - <% end %> - -
    -
      -
    • <%= link_to DecidimBarcelona::Application.routes.url_helpers.accountability_sections_path(anchor: "serveis"), class: "card__link" do %><%= t(".section_3_item_1") %><% end %>
    • -
    • <%= link_to DecidimBarcelona::Application.routes.url_helpers.accountability_sections_path(anchor: "serveis"), class: "card__link" do %><%= t(".section_3_item_2") %><% end %>
    • -
    • <%= link_to DecidimBarcelona::Application.routes.url_helpers.accountability_sections_path(anchor: "serveis"), class: "card__link" do %><%= t(".section_3_item_3") %><% end %>
    • -
    -
    -
    +
    +
    + <%= link_to DecidimBarcelona::Application.routes.url_helpers.accountability_sections_path("serveis"), class: "card__link", style: "text-decoration: none;" do %> +

    <%= icon "key-2-line", style: "display: inline;" %> <%= t(".section_3_title") %>

    + <% end %> +
      +
    • <%= t(".section_3_item_1") %>
    • +
    • <%= t(".section_3_item_2") %>
    • +
    • <%= t(".section_3_item_3") %>
    • +
    +
    -
    -
    - <%= link_to DecidimBarcelona::Application.routes.url_helpers.accountability_sections_path(anchor: "etica"), class: "card__link" do %> -

    <%= icon "home" %> <%= t(".section_4_title") %>

    - <% end %> - -
    -
      -
    • <%= link_to DecidimBarcelona::Application.routes.url_helpers.accountability_sections_path(anchor: "etica"), class: "card__link" do %><%= t(".section_4_item_1") %><% end %>
    • -
    • <%= link_to DecidimBarcelona::Application.routes.url_helpers.accountability_sections_path(anchor: "etica"), class: "card__link" do %><%= t(".section_4_item_2") %><% end %>
    • -
    • <%= link_to DecidimBarcelona::Application.routes.url_helpers.accountability_sections_path(anchor: "etica"), class: "card__link" do %><%= t(".section_4_item_3") %><% end %>
    • -
    -
    -
    +
    +
    + <%= link_to DecidimBarcelona::Application.routes.url_helpers.accountability_sections_path("etica"), class: "card__link", style: "text-decoration: none;" do %> +

    <%= icon "home-2-line", style: "display: inline;" %> <%= t(".section_4_title") %>

    + <% end %> +
      +
    • <%= t(".section_4_item_1") %>
    • +
    • <%= t(".section_4_item_2") %>
    • +
    • <%= t(".section_4_item_3") %>
    • +
    -
    - -
    -

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

    -

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

    - - <%= render "accountability_graph_#{I18n.locale}" %> -
    - -
    -

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

    -

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

    - -
    - +
    +
    + +
    +

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

    +
    +

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

    +
    + <%= render "accountability_graph_#{I18n.locale}" %>
    - -
    -
    + +
    +

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

    +
    +

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

    +
    +
    +
    + <%= image_pack_tag "media/images/canals.jpg" %>
    - -
    - -
    - +
    +
    +
    + <%= image_pack_tag "media/images/logo_decidim.png" %> +
    +
    + "> +

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

    +
    + <%== t(".citizens_card_2_text") %> +
    +
    +
    +
    + <%= image_pack_tag "media/images/trobades.jpg" %> +
    +
    + "> +

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

    +
    + <%== t(".citizens_card_3_text") %> +
    +
    -
    -
    +
    +
    diff --git a/app/views/static/accountability_sections.html.erb b/app/views/static/accountability_sections.html.erb index 213b3e0388..08c9caf99a 100644 --- a/app/views/static/accountability_sections.html.erb +++ b/app/views/static/accountability_sections.html.erb @@ -2,141 +2,41 @@ description: t(".meta_tags.description"), title: t(".meta_tags.title") }) %> +
    +
    +

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

    +

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

    +
    -
    -
    -
    -

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

    -

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

    -
    - -
    -
    - -
    -
    -
    -
    -
    -

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

    -
    - <%== t(".tab_1_text_1") %> - - <%= icon "link-intact" %> <%= t(".go_to_link") %> -
    -
    - -
    -

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

    -
    - <%== t(".tab_1_text_2") %> - - <%= icon "link-intact" %> <%= t(".go_to_link") %> -
    -
    - -
    -

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

    -
    - <%== t(".tab_1_text_3") %> - - <%= icon "link-intact" %> <%= t(".go_to_link") %> -
    -
    -
    - -
    -
    -

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

    -
    - <%== t(".tab_2_text_1") %> -
    - -

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

    - -
    - - - -
    -

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

    -
    - <%== t(".tab_2_text_4") %> -
    -
    -
    - -
    -
    -

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

    - - <%== t(".tab_3_text_1") %> -
    - -
    - -
    -
    -

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

    - <%== t(".tab_4_text_1") %> -
    - -
    -

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

    -
    - <%== t(".tab_4_text_2") %> -
    -
    - -
    -

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

    -
    - <%== t(".tab_4_text_3") %> -
    -
    - -
    -

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

    -
    - <%== t(".tab_4_text_4") %> -
    -
    - -
    - -
    +
    + + +
    + <% sections[current_section.to_sym].times do |i| %> +
    +

    <%= t(".#{current_section}.heading_#{i}") %>

    +
    + <%== t(".#{current_section}.text_#{i}") %>
    -
    -
    -
    - + <% unless t(".#{current_section}.link_#{i}", default: "").empty? %> + + <% end %> + + <% end %> +
    diff --git a/app/views/static/api/docs/assets/images/graphiql-headers.png b/app/views/static/api/docs/assets/images/graphiql-headers.png new file mode 100644 index 0000000000..8051704163 Binary files /dev/null and b/app/views/static/api/docs/assets/images/graphiql-headers.png differ diff --git a/app/views/static/api/docs/assets/images/graphiql-variables.png b/app/views/static/api/docs/assets/images/graphiql-variables.png new file mode 100644 index 0000000000..fd7677256e Binary files /dev/null and b/app/views/static/api/docs/assets/images/graphiql-variables.png differ diff --git a/app/views/static/api/docs/assets/images/graphiql.png b/app/views/static/api/docs/assets/images/graphiql.png new file mode 100644 index 0000000000..e647c7955d Binary files /dev/null and b/app/views/static/api/docs/assets/images/graphiql.png differ diff --git a/app/views/static/api/docs/assets/images/menu.png b/app/views/static/api/docs/assets/images/menu.png new file mode 100644 index 0000000000..656353d006 Binary files /dev/null and b/app/views/static/api/docs/assets/images/menu.png differ diff --git a/app/views/static/api/docs/assets/images/navbar.png b/app/views/static/api/docs/assets/images/navbar.png new file mode 100644 index 0000000000..df38e90d87 Binary files /dev/null and b/app/views/static/api/docs/assets/images/navbar.png differ diff --git a/app/views/static/api/docs/assets/style.css b/app/views/static/api/docs/assets/style.css new file mode 100644 index 0000000000..7626413dbc --- /dev/null +++ b/app/views/static/api/docs/assets/style.css @@ -0,0 +1,1115 @@ +@import "//hello.myfonts.net/count/2c4b9d"; +* { + box-sizing: border-box; } + +html, +body, +div, +span, +applet, +object, +iframe, +h1, +h2, +h3, +h4, +h5, +h6, +p, +blockquote, +pre, +a, +abbr, +acronym, +address, +big, +cite, +code, +del, +dfn, +em, +img, +ins, +kbd, +q, +s, +samp, +small, +strike, +strong, +sub, +sup, +tt, +var, +b, +u, +i, +center, +dl, +dt, +dd, +ol, +ul, +li, +fieldset, +form, +label, +legend, +table, +caption, +tbody, +tfoot, +thead, +tr, +th, +td, +article, +aside, +canvas, +details, +embed, +figure, +figcaption, +footer, +header, +hgroup, +menu, +nav, +output, +ruby, +section, +summary, +time, +mark, +audio, +video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; } + +/* HTML5 display-role reset for older browsers */ +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +menu, +nav, +section { + display: block; } + +body { + line-height: 1; } + +ol, +ul { + list-style: none; } + +blockquote, +q { + quotes: none; } + +blockquote:before, +blockquote:after, +q:before, +q:after { + content: ''; + content: none; } + +table { + border-collapse: collapse; + border-spacing: 0; } + +@font-face { + font-family: 'ProximaNova-Light'; + src: url("webfonts/2C4B9D_B_0.eot"); + src: url("webfonts/2C4B9D_B_0.eot?#iefix") format("embedded-opentype"), url("webfonts/2C4B9D_B_0.woff2") format("woff2"), url("webfonts/2C4B9D_B_0.woff") format("woff"), url("webfonts/2C4B9D_B_0.ttf") format("truetype"); } +@font-face { + font-family: 'ProximaNova-Semibold'; + src: url("webfonts/2C4B9D_C_0.eot"); + src: url("webfonts/2C4B9D_C_0.eot?#iefix") format("embedded-opentype"), url("webfonts/2C4B9D_C_0.woff2") format("woff2"), url("webfonts/2C4B9D_C_0.woff") format("woff"), url("webfonts/2C4B9D_C_0.ttf") format("truetype"); } +@font-face { + font-family: 'ProximaNova-Regular'; + src: url("webfonts/2C4B9D_D_0.eot"); + src: url("webfonts/2C4B9D_D_0.eot?#iefix") format("embedded-opentype"), url("webfonts/2C4B9D_D_0.woff2") format("woff2"), url("webfonts/2C4B9D_D_0.woff") format("woff"), url("webfonts/2C4B9D_D_0.ttf") format("truetype"); } +@font-face { + font-family: 'ProximaNova-Bold'; + src: url("webfonts/2C4B9D_E_0.eot"); + src: url("webfonts/2C4B9D_E_0.eot?#iefix") format("embedded-opentype"), url("webfonts/2C4B9D_E_0.woff2") format("woff2"), url("webfonts/2C4B9D_E_0.woff") format("woff"), url("webfonts/2C4B9D_E_0.ttf") format("truetype"); } +body { + font-family: 'Source Sans Pro', 'Helvetica Neue', Helvetica, Arial, sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + font-size: 16px; + font-weight: 400; + color: #444; } + +h1, +h2, +h3, +h4, +h5, +h6 { + font-family: 'ProximaNova-Semibold'; + font-weight: 200; } + +em { + font-style: italic; } + +#wrap { + padding-top: 100px; + padding-left: 300px; + height: 100%; } + +#header { + position: fixed; + z-index: 2; + top: 0; + left: 0; + width: 100%; + height: 100px; + font-family: 'ProximaNova-Semibold'; } + +#top-nav { + height: 30px; + line-height: 30px; + background-color: #27272b; } + #top-nav a { + text-decoration: none; } + +#top-nav-links { + list-style-type: none; + position: absolute; + top: 0; + right: 30px; } + #top-nav-links li { + float: left; + margin-left: 20px; } + #top-nav-links a { + display: inline-block; + height: 30px; + padding: 0 5px; + color: #fff; + font-size: 10px; + letter-spacing: 1.5px; + text-transform: uppercase; } + +#site-nav { + position: relative; + height: 70px; + background-color: #fff; + border-bottom: 1px solid #eee; + padding: 14px 30px; } + #site-nav a { + vertical-align: bottom; } + #site-nav span { + vertical-align: bottom; } + #site-nav select { + vertical-align: bottom; } + #site-nav .sub-title { + margin: 0 8px; + position: relative; + top: 1px; } + #site-nav .logo img { + height: 50px; + margin-bottom: -20px; } + #site-nav .search-box { + position: absolute; + right: 30px; + top: 20px; } + +#sidebar { + background-color: #fff; + position: fixed; + z-index: 2; + top: 30px; + left: 0; + bottom: 0; + width: 300px; + padding: 20px 30px; + overflow-x: hidden; + overflow-y: scroll; + -webkit-overflow-scrolling: touch; + -ms-overflow-style: none; + font-family: 'ProximaNova-Semibold'; + border-right: 1px solid #eee; + font-size: 16px; + line-height: 1.1em; } + #sidebar::-webkit-scrollbar { + width: 0 !important; } + #sidebar li { + margin-bottom: 0.6em; } + #sidebar a { + color: #444; + text-decoration: none; } + #sidebar a:hover { + color: #de4f4f; } + #sidebar a.current { + color: #de4f4f; } + #sidebar a.H2 { + font-weight: bold; } + #sidebar .categories > li > p { + margin-top: 1.5em; + border-top: 1px solid #eee; + text-transform: uppercase; + padding-top: 1.2em; + margin-bottom: 1em; + color: #999; + font-size: 0.8em; } + #sidebar .sub-menu { + font-family: 'ProximaNova-Regular'; + padding-left: 20px; + margin: 0.6em 0; + font-size: 14px; } + #sidebar .sub-menu .active { + position: relative; + color: #de4f4f; } + #sidebar .sub-menu .active:before { + content: ""; + position: absolute; + top: 2px; + left: -15px; + display: inline-block; + width: 0; + height: 0; + border-top: 4px solid transparent; + border-bottom: 4px solid transparent; + border-left: 6px solid #de4f4f; } + +#sidebar-mobile { + display: none; + margin-bottom: 20px; } + #sidebar-mobile .search-box { + width: 200px; + margin-bottom: 20px; } + +#content { + padding: 20px 30px; + max-width: 760px; + margin: 0px auto; + -webkit-text-size-adjust: 100%; } + #content em { + font-style: italic; } + #content strong { + font-family: 'ProximaNova-Bold'; } + #content h1 { + margin: 15px 0; + line-height: 1.4em; + font-size: 2em; + margin-top: 0; + margin-bottom: 30px; } + #content h2 { + margin: 15px 0; + line-height: 1.4em; + font-size: 1.5em; + margin-top: 30px; + padding-bottom: 10px; + border-bottom: 1px solid #eee; + position: relative; } + #content h2 .anchor { + opacity: 0; + position: absolute; + font-size: 16px; + top: 2px; + left: -21px; } + #content h2:hover .anchor { + opacity: 1; } + #content h3 { + margin: 15px 0; + line-height: 1.4em; + font-size: 1.2em; + margin-top: 30px; + position: relative; } + #content h3 .anchor { + opacity: 0; + position: absolute; + font-size: 16px; + top: 2px; + left: -21px; } + #content h3:hover .anchor { + opacity: 1; } + #content h4 { + margin: 15px 0; + line-height: 1.4em; } + #content h5 { + margin: 15px 0; + line-height: 1.4em; } + #content h6 { + margin: 15px 0; + line-height: 1.4em; } + #content p { + margin: 15px 0; + line-height: 1.4em; } + #content ul { + margin: 15px 0; + line-height: 1.4em; + padding-left: 1.5em; + list-style-type: disc; } + #content ul li { + margin-bottom: 5px; } + #content ol { + margin: 15px 0; + line-height: 1.4em; + padding-left: 1.5em; + list-style-type: decimal; } + #content ol li { + margin-bottom: 5px; } + #content figure { + margin: 15px 0; + line-height: 1.4em; } + #content a { + color: #de4f4f; } + #content img { + max-width: 100%; } + #content code { + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; + font-size: 0.8em; + line-height: 1.6em; + padding: 1px 4px; + background-color: #eee; + margin: 0 2px; } + #content blockquote { + padding-left: 1.3em; + border-left: #eee solid 0.2em; + font-style: italic; } + #content blockquote.warning { + border-color: #f00; + color: #f00; } + #content dl { + margin-left: 1.5em; } + #content dl dt .name { + font-family: monospace; } + #content dl dt .type { + margin-left: 0.5em; } + #content dl dd { + margin-left: 1.5em; } + #content .edit-discuss-links { + margin-top: -25px; + margin-bottom: 40px; } + #content table { + margin-top: 10px; } + #content table th { + text-align: left; + padding: 0 25px 0 25px; } + #content table thead th:first-child { + padding: 0; } + #content table td p { + padding: 0 25px 0 25px; } + #content pre { + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; + line-height: 1.6em; + margin: 20px 0; + overflow-x: auto; + position: relative; + padding: 20px 30px; } + #content pre table { + width: 100%; + border-collapse: collapse; + padding: 0; + margin: 0; } + #content pre tr { + width: 100%; + border-collapse: collapse; + padding: 0; + margin: 0; } + #content pre td { + width: 100%; + border-collapse: collapse; + padding: 0; + margin: 0; } + #content pre code { + background-color: #272822; + padding: 0; + margin: 0; } + #content pre .gutter { + user-select: none; + width: 1.5em; + padding-right: 30px; } + #content .highlight.html .code:after { + font-family: 'ProximaNova-Semibold'; + position: absolute; + top: 0; + right: 0; + color: #ccc; + text-align: right; + font-size: 0.75em; + padding: 5px 10px 0; + letter-spacing: 1.5px; + line-height: 15px; + height: 15px; + font-weight: 600; } + #content .highlight.js .code:after { + font-family: 'ProximaNova-Semibold'; + position: absolute; + top: 0; + right: 0; + color: #ccc; + text-align: right; + font-size: 0.75em; + padding: 5px 10px 0; + letter-spacing: 1.5px; + line-height: 15px; + height: 15px; + font-weight: 600; } + #content .highlight.bash .code:after { + font-family: 'ProximaNova-Semibold'; + position: absolute; + top: 0; + right: 0; + color: #ccc; + text-align: right; + font-size: 0.75em; + padding: 5px 10px 0; + letter-spacing: 1.5px; + line-height: 15px; + height: 15px; + font-weight: 600; } + #content .highlight.css .code:after { + font-family: 'ProximaNova-Semibold'; + position: absolute; + top: 0; + right: 0; + color: #ccc; + text-align: right; + font-size: 0.75em; + padding: 5px 10px 0; + letter-spacing: 1.5px; + line-height: 15px; + height: 15px; + font-weight: 600; } + #content .highlight.jsx .code:after { + font-family: 'ProximaNova-Semibold'; + position: absolute; + top: 0; + right: 0; + color: #ccc; + text-align: right; + font-size: 0.75em; + padding: 5px 10px 0; + letter-spacing: 1.5px; + line-height: 15px; + height: 15px; + font-weight: 600; } + #content .highlight.html.html .code:after { + content: 'HTML'; } + #content .highlight.js.html .code:after { + content: 'HTML'; } + #content .highlight.bash.html .code:after { + content: 'HTML'; } + #content .highlight.css.html .code:after { + content: 'HTML'; } + #content .highlight.jsx.html .code:after { + content: 'HTML'; } + #content .highlight.html.js .code:after { + content: 'JS'; } + #content .highlight.js.js .code:after { + content: 'JS'; } + #content .highlight.bash.js .code:after { + content: 'JS'; } + #content .highlight.css.js .code:after { + content: 'JS'; } + #content .highlight.jsx.js .code:after { + content: 'JS'; } + #content .highlight.html.bash .code:after { + content: 'Shell'; } + #content .highlight.js.bash .code:after { + content: 'Shell'; } + #content .highlight.bash.bash .code:after { + content: 'Shell'; } + #content .highlight.css.bash .code:after { + content: 'Shell'; } + #content .highlight.jsx.bash .code:after { + content: 'Shell'; } + #content .highlight.html.css .code:after { + content: 'CSS'; } + #content .highlight.js.css .code:after { + content: 'CSS'; } + #content .highlight.bash.css .code:after { + content: 'CSS'; } + #content .highlight.css.css .code:after { + content: 'CSS'; } + #content .highlight.jsx.css .code:after { + content: 'CSS'; } + #content .highlight.html.jsx .code:after { + content: 'JSX'; } + #content .highlight.js.jsx .code:after { + content: 'JSX'; } + #content .highlight.bash.jsx .code:after { + content: 'JSX'; } + #content .highlight.css.jsx .code:after { + content: 'JSX'; } + #content .highlight.jsx.jsx .code:after { + content: 'JSX'; } + #content > table { + width: 100%; + margin: 20px 0; } + #content > table tr { + border-top: 1px solid #eee; } + #content > table tr:nth-child(2n) { + background-color: #f8f8f8; } + #content > table th { + font-family: 'ProximaNova-Semibold'; + padding: 12px 13px; + border: 1px solid #eee; + vertical-align: middle; + text-align: left; } + #content > table td { + border: 1px solid #eee; + vertical-align: middle; + padding: 6px 13px; + font-family: Menlo, Monaco, Consolas, "Courier New", monospace; + font-size: 0.8em; + line-height: 1.6em; } + #content .bottom-nav { + height: 44px; + margin: 30px 0 25px; + border-bottom: 1px solid #eee; + padding-bottom: 25px; } + #content .bottom-nav a { + font-family: 'ProximaNova-Semibold'; + margin: 0 5px; } + #content .edit-link { + text-align: center; } + #content .edit-link a { + color: #aaa; + font-family: 'ProximaNova-Semibold'; } + #content .edit-link a:before { + content: ''; + display: inline-block; + width: 16px; + height: 16px; + background-size: 16px; + opacity: 0.3; + margin-right: 8px; + position: relative; + top: 2px; } + #content .field-name { + font-weight: bold; } + #content .field-entry { + margin-bottom: 4rem; } + #content .description-wrapper > p { + padding-left: 1rem; + margin-bottom: 1rem; } + +#mobile-header { + z-index: 3; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 40px; + background-color: #fff; + display: none; + box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); } + #mobile-header .menu-button { + position: absolute; + width: 24px; + height: 24px; + top: 8px; + left: 12px; + background: url("../assets/images/menu.png") center center no-repeat; + background-size: 24px; + opacity: 0.5; } + #mobile-header .logo { + position: absolute; + top: 5px; + left: 50%; + margin-left: -15px; + background-size: 30px; } + #mobile-header .logo img { + width: 30px; + height: 30px; } + +#mobile-shade { + z-index: 1; + display: none; + pointer-events: none; + opacity: 0; + transition: opacity 0.3s ease; + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.4); } + +@media screen and (max-width: 560px) { + body { + font-size: 14px; } + + body.sidebar-open #sidebar { + transform: translate3d(0, 0, 0); } + body.sidebar-open #mobile-shade { + opacity: 1; + pointer-events: auto; } + + #header { + height: 40px; } + + #top-nav { + display: none; } + + #site-nav { + display: none; } + + #mobile-header { + display: block; } + + #mobile-shade { + display: block; } + + #sidebar-mobile { + display: block; } + + #wrap { + padding-top: 40px; + padding-left: 0; } + + #sidebar { + top: 0; + left: 0; + padding-top: 60px; + border-right: none; + box-shadow: 0 0 4px rgba(0, 0, 0, 0.25); + transition: transform 0.3s ease; + transform: translate3d(-120%, 0, 0); + display: block; } } +.api { + background: #fafafa; } + .api h3 { + padding: 5px 10px; } + .api h3.api-title { + margin: 0; + overflow: auto; } + .api h4 { + font-weight: normal; + font-style: italic; + margin-bottom: 0.25em; + text-decoration: underline; + margin-left: 20px; } + .api dl { + margin-top: 0.25em; } + .api dl.args { + margin-left: 40px; } + .api dl.constants { + margin-left: 20px; } + .api dt { + margin-top: 1em; } + .api dt .name { + font-weight: bold; } + .api dt .type { + margin-left: 15px; + font-size: 0.9em; + font-weight: 200; + color: #000; } + .api dd { + margin-bottom: 1em; + margin-left: 0; } + .api .desc { + margin: 1em; } + .api pre { + margin-right: 10px; } + +h3.api-title { + padding: 5px 10px; + margin-top: 2em; } + +.api-title .locus { + float: right; + font-weight: normal; + padding-right: 5px; + font-style: italic; } +.api-title .subtext { + font-size: 11px; + text-align: left; + clear: both; + display: block; + font-weight: normal; } + .api-title .subtext > code { + font-size: 11px; + margin-right: 12px; } +.api-title .src-code { + color: #20338a !important; + border-bottom: none !important; } + +.gutter pre { + color: #999; } + +pre { + color: #525252; } + pre .function .keyword { + color: #0092db; } + pre .constant { + color: #0092db; } + pre .keyword { + color: #e96900; } + pre .attribute { + color: #e96900; } + pre .number { + color: #ae81ff; } + pre .literal { + color: #ae81ff; } + pre .tag { + color: #2973b7; } + pre .tag .title { + color: #2973b7; } + pre .tag .value { + color: #90a959; } + pre .change { + color: #2973b7; } + pre .winutils { + color: #2973b7; } + pre .flow { + color: #2973b7; } + pre .lisp .title { + color: #2973b7; } + pre .clojure .built_in { + color: #2973b7; } + pre .nginx .title { + color: #2973b7; } + pre .tex .special { + color: #2973b7; } + pre .tex .command { + color: #90a959; } + pre .tex .formula { + color: #b3b3b3; + opacity: 0.5; } + pre .class .title { + color: #4077bf; } + pre .symbol { + color: #90a959; } + pre .symbol .string { + color: #90a959; } + pre .value { + color: #90a959; } + pre .regexp { + color: #90a959; } + pre .title { + color: #a6e22e; } + pre .string { + color: #90a959; } + pre .subst { + color: #90a959; } + pre .haskell .type { + color: #90a959; } + pre .preprocessor { + color: #90a959; } + pre .ruby .class .parent { + color: #90a959; } + pre .built_in { + color: #90a959; } + pre .sql .aggregate { + color: #90a959; } + pre .django .template_tag { + color: #90a959; } + pre .django .variable { + color: #90a959; } + pre .django .filter .argument { + color: #90a959; } + pre .smalltalk .class { + color: #90a959; } + pre .smalltalk .localvars { + color: #90a959; } + pre .smalltalk .array { + color: #90a959; } + pre .javadoc { + color: #90a959; } + pre .attr_selector { + color: #90a959; } + pre .pseudo { + color: #90a959; } + pre .addition { + color: #90a959; } + pre .stream { + color: #90a959; } + pre .envvar { + color: #90a959; } + pre .apache .tag { + color: #90a959; } + pre .apache .cbracket { + color: #90a959; } + pre .apache .sqbracket { + color: #b3b3b3; } + pre .prompt { + color: #90a959; } + pre .comment { + color: #b3b3b3; } + pre .java .annotation { + color: #b3b3b3; } + pre .python .decorator { + color: #b3b3b3; } + pre .template_comment { + color: #b3b3b3; } + pre .pi { + color: #b3b3b3; } + pre .doctype { + color: #b3b3b3; } + pre .deletion { + color: #b3b3b3; } + pre .shebang { + color: #b3b3b3; } + pre .coffeescript .javascript { + opacity: 0.5; } + pre .javascript .xml { + opacity: 0.5; } + pre .xml .javascript { + opacity: 0.5; } + pre .xml .vbscript { + opacity: 0.5; } + pre .xml .css { + opacity: 0.5; } + pre .xml .cdata { + opacity: 0.5; } + +.highlight .hll { + background-color: #49483e; } + +pre { + background: #272822; + color: #f8f8f2; } + +.highlight .c { + color: #75715e; } + +/* Comment */ +.highlight .err { + color: #960050; + background-color: #1e0010; } + +/* Error */ +.highlight .k { + color: #66d9ef; } + +/* Keyword */ +.highlight .l { + color: #ae81ff; } + +/* Literal */ +.highlight .n { + color: #f8f8f2; } + +/* Name */ +.highlight .o { + color: #f92672; } + +/* Operator */ +.highlight .p { + color: #f8f8f2; } + +/* Punctuation */ +.highlight .cm { + color: #75715e; } + +/* Comment.Multiline */ +.highlight .cp { + color: #75715e; } + +/* Comment.Preproc */ +.highlight .c1 { + color: #75715e; } + +/* Comment.Single */ +.highlight .cs { + color: #75715e; } + +/* Comment.Special */ +.highlight .ge { + font-style: italic; } + +/* Generic.Emph */ +.highlight .gs { + font-weight: bold; } + +/* Generic.Strong */ +.highlight .kc { + color: #66d9ef; } + +/* Keyword.Constant */ +.highlight .kd { + color: #66d9ef; } + +/* Keyword.Declaration */ +.highlight .kn { + color: #f92672; } + +/* Keyword.Namespace */ +.highlight .kp { + color: #66d9ef; } + +/* Keyword.Pseudo */ +.highlight .kr { + color: #66d9ef; } + +/* Keyword.Reserved */ +.highlight .kt { + color: #66d9ef; } + +/* Keyword.Type */ +.highlight .ld { + color: #e6db74; } + +/* Literal.Date */ +.highlight .m { + color: #ae81ff; } + +/* Literal.Number */ +.highlight .s { + color: #e6db74; } + +/* Literal.String */ +.highlight .na { + color: #a6e22e; } + +/* Name.Attribute */ +.highlight .nb { + color: #f8f8f2; } + +/* Name.Builtin */ +.highlight .nc { + color: #a6e22e; } + +/* Name.Class */ +.highlight .no { + color: #66d9ef; } + +/* Name.Constant */ +.highlight .nd { + color: #a6e22e; } + +/* Name.Decorator */ +.highlight .ni { + color: #f8f8f2; } + +/* Name.Entity */ +.highlight .ne { + color: #a6e22e; } + +/* Name.Exception */ +.highlight .nf { + color: #a6e22e; } + +/* Name.Function */ +.highlight .nl { + color: #f8f8f2; } + +/* Name.Label */ +.highlight .nn { + color: #f8f8f2; } + +/* Name.Namespace */ +.highlight .nx { + color: #a6e22e; } + +/* Name.Other */ +.highlight .py { + color: #f8f8f2; } + +/* Name.Property */ +.highlight .nt { + color: #f92672; } + +/* Name.Tag */ +.highlight .nv { + color: #f8f8f2; } + +/* Name.Variable */ +.highlight .ow { + color: #f92672; } + +/* Operator.Word */ +.highlight .w { + color: #f8f8f2; } + +/* Text.Whitespace */ +.highlight .mf { + color: #ae81ff; } + +/* Literal.Number.Float */ +.highlight .mh { + color: #ae81ff; } + +/* Literal.Number.Hex */ +.highlight .mi { + color: #ae81ff; } + +/* Literal.Number.Integer */ +.highlight .mo { + color: #ae81ff; } + +/* Literal.Number.Oct */ +.highlight .sb { + color: #e6db74; } + +/* Literal.String.Backtick */ +.highlight .sc { + color: #e6db74; } + +/* Literal.String.Char */ +.highlight .sd { + color: #e6db74; } + +/* Literal.String.Doc */ +.highlight .s2 { + color: #e6db74; } + +/* Literal.String.Double */ +.highlight .se { + color: #ae81ff; } + +/* Literal.String.Escape */ +.highlight .sh { + color: #e6db74; } + +/* Literal.String.Heredoc */ +.highlight .si { + color: #e6db74; } + +/* Literal.String.Interpol */ +.highlight .sx { + color: #e6db74; } + +/* Literal.String.Other */ +.highlight .sr { + color: #e6db74; } + +/* Literal.String.Regex */ +.highlight .s1 { + color: #e6db74; } + +/* Literal.String.Single */ +.highlight .ss { + color: #e6db74; } + +/* Literal.String.Symbol */ +.highlight .bp { + color: #f8f8f2; } + +/* Name.Builtin.Pseudo */ +.highlight .vc { + color: #f8f8f2; } + +/* Name.Variable.Class */ +.highlight .vg { + color: #f8f8f2; } + +/* Name.Variable.Global */ +.highlight .vi { + color: #f8f8f2; } + +/* Name.Variable.Instance */ +.highlight .il { + color: #ae81ff; } + +/* Literal.Number.Integer.Long */ +.deprecation-notice { + padding-left: 5px; + border-left: 2px solid #e8400d; + background: #fdf2ec; } + .deprecation-notice span { + font-weight: bold; } diff --git a/app/views/static/api/docs/assets/webfonts/2C4B9D_B_0.eot b/app/views/static/api/docs/assets/webfonts/2C4B9D_B_0.eot new file mode 100644 index 0000000000..4ce4d6afe5 Binary files /dev/null and b/app/views/static/api/docs/assets/webfonts/2C4B9D_B_0.eot differ diff --git a/app/views/static/api/docs/assets/webfonts/2C4B9D_B_0.ttf b/app/views/static/api/docs/assets/webfonts/2C4B9D_B_0.ttf new file mode 100644 index 0000000000..c99f970be9 Binary files /dev/null and b/app/views/static/api/docs/assets/webfonts/2C4B9D_B_0.ttf differ diff --git a/app/views/static/api/docs/assets/webfonts/2C4B9D_B_0.woff b/app/views/static/api/docs/assets/webfonts/2C4B9D_B_0.woff new file mode 100644 index 0000000000..36b8633aee Binary files /dev/null and b/app/views/static/api/docs/assets/webfonts/2C4B9D_B_0.woff differ diff --git a/app/views/static/api/docs/assets/webfonts/2C4B9D_B_0.woff2 b/app/views/static/api/docs/assets/webfonts/2C4B9D_B_0.woff2 new file mode 100644 index 0000000000..0710e2f97e Binary files /dev/null and b/app/views/static/api/docs/assets/webfonts/2C4B9D_B_0.woff2 differ diff --git a/app/views/static/api/docs/assets/webfonts/2C4B9D_C_0.eot b/app/views/static/api/docs/assets/webfonts/2C4B9D_C_0.eot new file mode 100644 index 0000000000..07a0c559e6 Binary files /dev/null and b/app/views/static/api/docs/assets/webfonts/2C4B9D_C_0.eot differ diff --git a/app/views/static/api/docs/assets/webfonts/2C4B9D_C_0.ttf b/app/views/static/api/docs/assets/webfonts/2C4B9D_C_0.ttf new file mode 100644 index 0000000000..42d2218a38 Binary files /dev/null and b/app/views/static/api/docs/assets/webfonts/2C4B9D_C_0.ttf differ diff --git a/app/views/static/api/docs/assets/webfonts/2C4B9D_C_0.woff b/app/views/static/api/docs/assets/webfonts/2C4B9D_C_0.woff new file mode 100644 index 0000000000..35c7c9767c Binary files /dev/null and b/app/views/static/api/docs/assets/webfonts/2C4B9D_C_0.woff differ diff --git a/app/views/static/api/docs/assets/webfonts/2C4B9D_C_0.woff2 b/app/views/static/api/docs/assets/webfonts/2C4B9D_C_0.woff2 new file mode 100644 index 0000000000..b06af829ed Binary files /dev/null and b/app/views/static/api/docs/assets/webfonts/2C4B9D_C_0.woff2 differ diff --git a/app/views/static/api/docs/assets/webfonts/2C4B9D_D_0.eot b/app/views/static/api/docs/assets/webfonts/2C4B9D_D_0.eot new file mode 100644 index 0000000000..c3cb30824c Binary files /dev/null and b/app/views/static/api/docs/assets/webfonts/2C4B9D_D_0.eot differ diff --git a/app/views/static/api/docs/assets/webfonts/2C4B9D_D_0.ttf b/app/views/static/api/docs/assets/webfonts/2C4B9D_D_0.ttf new file mode 100644 index 0000000000..58a76d585b Binary files /dev/null and b/app/views/static/api/docs/assets/webfonts/2C4B9D_D_0.ttf differ diff --git a/app/views/static/api/docs/assets/webfonts/2C4B9D_D_0.woff b/app/views/static/api/docs/assets/webfonts/2C4B9D_D_0.woff new file mode 100644 index 0000000000..83c7a01e5b Binary files /dev/null and b/app/views/static/api/docs/assets/webfonts/2C4B9D_D_0.woff differ diff --git a/app/views/static/api/docs/assets/webfonts/2C4B9D_D_0.woff2 b/app/views/static/api/docs/assets/webfonts/2C4B9D_D_0.woff2 new file mode 100644 index 0000000000..0267b947c2 Binary files /dev/null and b/app/views/static/api/docs/assets/webfonts/2C4B9D_D_0.woff2 differ diff --git a/app/views/static/api/docs/assets/webfonts/2C4B9D_E_0.eot b/app/views/static/api/docs/assets/webfonts/2C4B9D_E_0.eot new file mode 100644 index 0000000000..294d4d6534 Binary files /dev/null and b/app/views/static/api/docs/assets/webfonts/2C4B9D_E_0.eot differ diff --git a/app/views/static/api/docs/assets/webfonts/2C4B9D_E_0.ttf b/app/views/static/api/docs/assets/webfonts/2C4B9D_E_0.ttf new file mode 100644 index 0000000000..7c5f2243c4 Binary files /dev/null and b/app/views/static/api/docs/assets/webfonts/2C4B9D_E_0.ttf differ diff --git a/app/views/static/api/docs/assets/webfonts/2C4B9D_E_0.woff b/app/views/static/api/docs/assets/webfonts/2C4B9D_E_0.woff new file mode 100644 index 0000000000..70bef2ca02 Binary files /dev/null and b/app/views/static/api/docs/assets/webfonts/2C4B9D_E_0.woff differ diff --git a/app/views/static/api/docs/assets/webfonts/2C4B9D_E_0.woff2 b/app/views/static/api/docs/assets/webfonts/2C4B9D_E_0.woff2 new file mode 100644 index 0000000000..62b6610e52 Binary files /dev/null and b/app/views/static/api/docs/assets/webfonts/2C4B9D_E_0.woff2 differ diff --git a/app/views/static/api/docs/directive/deprecated/index.html b/app/views/static/api/docs/directive/deprecated/index.html new file mode 100644 index 0000000000..7d9070e5a5 --- /dev/null +++ b/app/views/static/api/docs/directive/deprecated/index.html @@ -0,0 +1,1106 @@ +

    +deprecated

    +

    Marks an element of a GraphQL schema as no longer supported.

    +

    +Locations

    +
      +
    • FIELD_DEFINITION
    • +
    • ENUM_VALUE
    • +
    • ARGUMENT_DEFINITION
    • +
    • INPUT_FIELD_DEFINITION
    • +
    +

    +Arguments

    + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    reason + String + +

    Explains why this element was deprecated, usually also including a suggestion for how to access supported similar data. Formatted in Markdown.

    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/directive/include/index.html b/app/views/static/api/docs/directive/include/index.html new file mode 100644 index 0000000000..ba0d8195dd --- /dev/null +++ b/app/views/static/api/docs/directive/include/index.html @@ -0,0 +1,1105 @@ +

    +include

    +

    Directs the executor to include this field or fragment only when the if argument is true.

    +

    +Locations

    +
      +
    • FIELD
    • +
    • FRAGMENT_SPREAD
    • +
    • INLINE_FRAGMENT
    • +
    +

    +Arguments

    + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    if + Boolean! + +

    Included when true.

    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/directive/index.html b/app/views/static/api/docs/directive/index.html new file mode 100644 index 0000000000..db99564ed3 --- /dev/null +++ b/app/views/static/api/docs/directive/index.html @@ -0,0 +1,1077 @@ +

    +Directives

    +

    Directives provide a way to describe alternate runtime execution and type validation behavior in a GraphQL document.

    +

    For more information, see the GraphQL spec.

    + + + +
    + +
    diff --git a/app/views/static/api/docs/directive/oneof/index.html b/app/views/static/api/docs/directive/oneof/index.html new file mode 100644 index 0000000000..f624cd0a92 --- /dev/null +++ b/app/views/static/api/docs/directive/oneof/index.html @@ -0,0 +1,1081 @@ +

    +oneOf

    +

    Requires that exactly one field must be supplied and that field must not be null.

    +

    +Locations

    +
      +
    • INPUT_OBJECT
    • +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/directive/skip/index.html b/app/views/static/api/docs/directive/skip/index.html new file mode 100644 index 0000000000..c5a4ff8ffa --- /dev/null +++ b/app/views/static/api/docs/directive/skip/index.html @@ -0,0 +1,1105 @@ +

    +skip

    +

    Directs the executor to skip this field or fragment when the if argument is true.

    +

    +Locations

    +
      +
    • FIELD
    • +
    • FRAGMENT_SPREAD
    • +
    • INLINE_FRAGMENT
    • +
    +

    +Arguments

    + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    if + Boolean! + +

    Skipped when true.

    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/enum/__directivelocation/index.html b/app/views/static/api/docs/enum/__directivelocation/index.html new file mode 100644 index 0000000000..b3cc651342 --- /dev/null +++ b/app/views/static/api/docs/enum/__directivelocation/index.html @@ -0,0 +1,1173 @@ +

    +__DirectiveLocation

    +

    A Directive can be adjacent to many parts of the GraphQL language, a __DirectiveLocation describes one such possible adjacencies.

    +

    +Values

    +

    +QUERY

    +
    +

    Location adjacent to a query operation.

    +
    +

    +MUTATION

    +
    +

    Location adjacent to a mutation operation.

    +
    +

    +SUBSCRIPTION

    +
    +

    Location adjacent to a subscription operation.

    +
    +

    +FIELD

    +
    +

    Location adjacent to a field.

    +
    +

    +FRAGMENT_DEFINITION

    +
    +

    Location adjacent to a fragment definition.

    +
    +

    +FRAGMENT_SPREAD

    +
    +

    Location adjacent to a fragment spread.

    +
    +

    +INLINE_FRAGMENT

    +
    +

    Location adjacent to an inline fragment.

    +
    +

    +SCHEMA

    +
    +

    Location adjacent to a schema definition.

    +
    +

    +SCALAR

    +
    +

    Location adjacent to a scalar definition.

    +
    +

    +OBJECT

    +
    +

    Location adjacent to an object type definition.

    +
    +

    +FIELD_DEFINITION

    +
    +

    Location adjacent to a field definition.

    +
    +

    +ARGUMENT_DEFINITION

    +
    +

    Location adjacent to an argument definition.

    +
    +

    +INTERFACE

    +
    +

    Location adjacent to an interface definition.

    +
    +

    +UNION

    +
    +

    Location adjacent to a union definition.

    +
    +

    +ENUM

    +
    +

    Location adjacent to an enum definition.

    +
    +

    +ENUM_VALUE

    +
    +

    Location adjacent to an enum value definition.

    +
    +

    +INPUT_OBJECT

    +
    +

    Location adjacent to an input object type definition.

    +
    +

    +INPUT_FIELD_DEFINITION

    +
    +

    Location adjacent to an input object field definition.

    +
    +

    +VARIABLE_DEFINITION

    +
    +

    Location adjacent to a variable definition.

    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/enum/__typekind/index.html b/app/views/static/api/docs/enum/__typekind/index.html new file mode 100644 index 0000000000..a40302a228 --- /dev/null +++ b/app/views/static/api/docs/enum/__typekind/index.html @@ -0,0 +1,1118 @@ +

    +__TypeKind

    +

    An enum describing what kind of type a given __Type is.

    +

    +Values

    +

    +SCALAR

    +
    +

    Indicates this type is a scalar.

    +
    +

    +OBJECT

    +
    +

    Indicates this type is an object. fields and interfaces are valid fields.

    +
    +

    +INTERFACE

    +
    +

    Indicates this type is an interface. fields and possibleTypes are valid fields.

    +
    +

    +UNION

    +
    +

    Indicates this type is a union. possibleTypes is a valid field.

    +
    +

    +ENUM

    +
    +

    Indicates this type is an enum. enumValues is a valid field.

    +
    +

    +INPUT_OBJECT

    +
    +

    Indicates this type is an input object. inputFields is a valid field.

    +
    +

    +LIST

    +
    +

    Indicates this type is a list. ofType is a valid field.

    +
    +

    +NON_NULL

    +
    +

    Indicates this type is a non-null. ofType is a valid field.

    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/enum/index.html b/app/views/static/api/docs/enum/index.html new file mode 100644 index 0000000000..e335eebaae --- /dev/null +++ b/app/views/static/api/docs/enum/index.html @@ -0,0 +1,1077 @@ +

    +Enums

    +

    Enums represent a possible set of values for a field. For example, the Issue object has a field called state. The state of an issue may be OPEN or CLOSED.

    +

    For more information, see the GraphQL spec.

    + + + +
    + +
    diff --git a/app/views/static/api/docs/index.html b/app/views/static/api/docs/index.html new file mode 100644 index 0000000000..d8c3afd318 --- /dev/null +++ b/app/views/static/api/docs/index.html @@ -0,0 +1,1574 @@ +
    +

    +About the GraphQL API

    +

    Decidim comes with an API that follows the GraphQL specification. It has a comprehensive coverage of all the public content that can be found on the website.

    +

    Currently, it is read-only (except for posting comments) but intends to cover anything that is published on the regular website.

    +

    Typically (although some particular installations may change that) you will find 3 relevant folders:

    +
      +
    • +URL/api The route where to make requests. Request are usually in the POST format.
    • +
    • +URL/api/docs This documentation, every Decidim site should provide one.
    • +
    • +URL/api/graphiql GraphiQL is a in-browser IDE for exploring GraphQL APIs. Some Decidim installations may choose to remove access to this tool. In that case you can use a standalone version and use any URL/api as the endpoint
    • +
    +

    +Using the GraphQL APi

    +

    The GraphQL format is a JSON formatted text that is specified in a query. Response is a JSON object as well. For details about specification check the official GraphQL site.

    +

    Exercise caution when utilizing the output of this API, as it may include HTML that has not been escaped. Take particular care in handling this data, specially if you intend to render it on a webpage.

    +

    For instance, you can check the version of a Decidim installation by using curl in the terminal:

    +
    curl -sSH "Content-Type: application/json" \
    +-d '{"query": "{ decidim { version } }"}' \
    +https://www.decidim.barcelona/api/
    +
    +

    Note that Content-Type needs to be specified.

    +

    The query can also be used in GraphiQL, in that case you can skip the "query" text:

    +
    {
    +  decidim {
    +    version
    +  }
    +}
    +
    +

    Response (formatted) should look something like this:

    +
    {
    +  "data": {
    +    "decidim": {
    +      "version": "0.18.1"
    +    }
    +  }
    +}
    +
    +

    The most practical way to experiment with GraphQL, however, is just to use the in-browser IDE GraphiQL. It provides access to the documentation and auto-complete (use CTRL-Space) for writing queries.

    +

    From now on, we will skip the "query" keyword for the purpose of readability. You can skip it too if you are using GraphiQL, if you are querying directly (by using CURL for instance) you will need to include it.

    +

    +Usage limits

    +

    Decidim is just a Rails application, meaning that any particular installation may implement custom limits in order to access the API (and the application in general).

    +

    By default (particular installations may change that), API uses the same limitations as the whole Decidim website, provided by the Gem Rack::Attack. These are 100 maximum requests per minute per IP to prevent DoS attacks

    +

    +Decidim structure, Types, collections and Polymorphism

    +

    There are no endpoints in the GraphQL specification, instead objects are organized according to their "Type".

    +

    These objects can be grouped in a single, complex query. Also, objects may accept parameters, which are "Types" as well.

    +

    Each "Type" is just a pre-defined structure with fields, or just an Scalar (Strings, Integers, Booleans, ...).

    +

    For instance, to obtain all the participatory processes in a Decidim installation published since January 2018 and order them by published date, we could execute the next query:

    +
    {
    +  participatoryProcesses(filter: {publishedSince: "2018-01-01"}, order: {publishedAt: "asc"}) {
    +    slug
    +    title {
    +      translation(locale: "en")
    +    }
    +  }
    +}
    +
    +

    Response should look like:

    +
    {
    +  "data": {
    +    "participatoryProcesses": [
    +      {
    +        "slug": "consectetur-at",
    +        "title": {
    +          "translation": "Soluta consectetur quos fugit aut."
    +        }
    +      },
    +      {
    +        "slug": "nostrum-earum",
    +        "title": {
    +          "translation": "Porro hic ipsam cupiditate reiciendis."
    +        }
    +      }
    +    ]
    +  }
    +}
    +
    +

    +What happened?

    +

    In the former query, each keyword represents a type, the words publishedSince, publishedAt, slug, locale are scalars, all of them Strings.

    +

    The other keywords however, are objects representing certain entities:

    +
      +
    • +participatoryProcesses is a type that represents a collection of participatory spaces. It accepts arguments (filter and order), which are other object types as well. slug and title are the fields of the participatory process we are interested in, there are "Types" too.
    • +
    • +filter is a ParticipatoryProcessFilter* input type, it has several properties that allows us to refine our search. One of them is the publishedSince property with the initial date from which to list entries.
    • +
    • +order is a ParticipatoryProcessSort type, works the same way as the filter but with the goal of ordering the results.
    • +
    • +title is a TranslatedField type, which allows us to deal with multi-language fields.
    • +
    +

    Finally, note that the returned object is an array, each item of which is a representation of the object we requested.

    +
    +

    *About how filters and sorting are organized

    +

    There are two types of objects to filter and ordering collections in Decidim, they all work in a similar fashion. The type involved in filtering always have the suffix "Filter", for ordering it has the suffix "Sort".

    +

    The types used to filter participatory spaces are: ParticipatoryProcessFilter, AssemblyFilter, and so on.

    +

    Other collections (or connections) may have their own filters (i.e. ComponentFilter).

    +

    Each filter has its own properties, you should check any object in particular for details. The way they work with multi-languages fields, however, is the same:

    +

    We can say we have some searchable object with a multi-language field called title, and we have a filter that allows us to search through this field. How should it work? Should we look up content for every language in the field? or should we stick to a specific language?

    +

    In our case, we have decided to search only one particular language of a multi-language field but we let you choose which language to search. +If no language is specified, the configured as default in the organization will be used. The keyword to specify the language is locale, and it should be provided in the 2 letters ISO 639-1 format (en = English, es = Spanish, ...).

    +

    Example (this is not a real Decidim query):

    +
     some_collection(filter: { locale: "en", title: "ideas"}) {
    +   id
    + }
    +
    +

    The same applies to sorting (ParticipatoryProcessSort, AssemblySort, etc.)

    +

    In this case, the content of the field (title) only allows 2 values: ASC and DESC.

    +

    Example of ordering alphabetically by the title content in French language:

    +
    some_collection(order: { locale: "en", title: "asc"}) {
    +  id
    +}
    +
    +

    Of course, you can combine both filter and order. Also remember to check availability of this type of behaviour for any particular filter/sort.

    +
    +

    +Decidim main types

    +

    Decidim has 2 main types of objects through which content is provided. These are Participatory Spaces and Components.

    +

    A participatory space is the first level, currently there are 5 officially supported: Participatory Processes, Assemblies, Conferences and Initiatives. For each participatory process there will correspond a collection type and a "single item" type.

    +

    The previous example uses the collection type for participatory processes. You can try assemblies, conferences, or initiatives for the others. Note that each collection can implement their own filter and order types with different properties.

    +

    As an example for a single item query, you can run:

    +
    {
    +  participatoryProcess(slug: "consectetur-at") {
    +    slug
    +    title {
    +      translation(locale: "en")
    +    }
    +  }
    +}
    +
    +

    And the response will be:

    +
    {
    +  "data": {
    +    "participatoryProcess": {
    +      "slug": "consectetur-at",
    +      "title": {
    +        "translation": "Soluta consectetur quos fugit aut."
    +      }
    +    }
    +  }
    +}
    +
    +

    +What is different?

    +

    First, note that we are querying, in singular, the type participatoryProcess, with a different parameter, slug*, (a String). We can use the id instead if we know it.

    +

    Second, the response is not an Array, it is just the object we requested. We can expect to return null if the object is not found.

    +
    +

    * The slug is a convenient way to find a participatory space as is (usually) in the URL.

    +

    For instance, consider this real case from Barcelona:

    +

    https://www.decidim.barcelona/processes/patrimonigracia

    +

    The word patrimonigracia indicates the "slug".

    +
    +

    +Components

    +

    Every participatory space may (and should) have some components. There are 9 official components, these are Proposals, Page, Meetings, Budgets, Surveys, Accountability, Debates, Sortitions and Blog. Plugins may add their own components.

    +

    If you know the id* of a specific component you can obtain it by querying it directly:

    +
    {
    +  component(id:2) {
    +    id
    +    name {
    +      translation(locale:"en")
    +    }
    +    __typename
    +    participatorySpace {
    +      id
    +      type
    +    }
    +  }
    +}
    +
    +

    Response:

    +
    {
    +  "data": {
    +    "component": {
    +      "id": "2",
    +      "name": {
    +        "translation": "Meetings"
    +      },
    +      "__typename": "Meetings",
    +      "participatorySpace": {
    +        "id": "1",
    +        "type": "Decidim::ParticipatoryProcess"
    +      }
    +    }
    +  }
    +}
    +
    +

    The process is analogue as what has been explained in the case of searching for one specific participatory process.

    +
    +

    *Note that the id of a component is present also in the URL after the letter "f":

    +

    https://www.decidim.barcelona/processes/patrimonigracia/f/3257/

    +

    In this case, 3257.

    +
    +
    +What about component's collections?
    +

    Glad you asked, component's collections cannot be retrieved directly, the are available in the context of a participatory space.

    +

    For instance, we can query all the components in an particular Assembly as follows:

    +
    {
    +  assembly(id: 3) {
    +    components {
    +      id
    +      name {
    +        translation(locale: "en")
    +      }
    +      __typename
    +    }
    +  }
    +}
    +
    +

    The response will be similar to:

    +
    {
    +  "data": {
    +    "assembly": {
    +      "components": [
    +        {
    +          "id": "42",
    +          "name": {
    +            "translation": "Accountability"
    +          },
    +          "__typename": "Component"
    +        },
    +        {
    +          "id": "38",
    +          "name": {
    +            "translation": "Meetings"
    +          },
    +          "__typename": "Meetings"
    +        },
    +        {
    +          "id": "37",
    +          "name": {
    +            "translation": "Page"
    +          },
    +          "__typename": "Pages"
    +        },
    +        {
    +          "id": "39",
    +          "name": {
    +            "translation": "Proposals"
    +          },
    +          "__typename": "Proposals"
    +        }
    +      ]
    +    }
    +  }
    +}
    +
    +

    We can also apply some filters by using the ComponentFilter type. In the next query we would like to find all the components with geolocation enabled in the assembly with id=2:

    +
    {
    +  assembly(id: 2) {
    +    components(filter: {withGeolocationEnabled: true}) {
    +      id
    +      name {
    +        translation(locale: "en")
    +      }
    +      __typename
    +    }
    +  }
    +}
    +
    +

    The response:

    +
    {
    +  "data": {
    +    "assembly": {
    +      "components": [
    +        {
    +          "id": "39",
    +          "name": {
    +            "translation": "Meetings"
    +          },
    +          "__typename": "Meetings"
    +        }
    +      ]
    +    }
    +  }
    +}
    +
    +

    Note that, in this case, there is only one component returned, "Meetings". In some cases Proposals can be geolocated too therefore would be returned in this query.

    +

    +Polymorphism and connections

    +

    Many relationships between tables in Decidim are polymorphic, this means that the related object can belong to different classes and share just a few properties in common.

    +

    For instance, components in a participatory space are polymorphic, while the concept of component is generic and all of them share properties like published date, name or weight, they differ in the rest. Proposals have the status field while Meetings have an agenda.

    +

    Another example are the case of linked resources, these are properties that may link objects of different nature between components or participatory spaces.

    +

    In a very simplified way (to know more please refer to the official guide), GraphQL polymorphism is handled through the operator ... on. You will know when a field is polymorphic because the property __typename, which tells you the type of that particular object, will change accordingly.

    +

    In the previous examples we have queried for this property:

    +

    Response fragment:

    +
          "components": [
    +        {
    +          "id": "38",
    +          "name": {
    +            "translation": "Meetings"
    +          },
    +          "__typename": "Meetings"
    +        }
    +
    +

    So, if we want to access the rest of the properties in a polymorphic object, we should do it through the ... on operator as follows:

    +
    {
    +  assembly(id: 2) {
    +    components {
    +      id
    +      ... on Proposals {
    +
    +      }
    +    }
    +  }
    +}
    +
    +

    Consider this query:

    +
    {
    +  assembly(id: 3) {
    +    components(filter: {type: "Proposals"}) {
    +      id
    +      name {
    +        translation(locale: "en")
    +      }
    +      ... on Proposals {
    +        proposals(order: {endorsementCount: "desc"}, first: 2) {
    +          edges {
    +            node {
    +              id
    +              endorsements {
    +                name
    +              }
    +            }
    +          }
    +        }
    +      }
    +    }
    +  }
    +}
    +
    +

    The response:

    +
    {
    +  "data": {
    +    "assembly": {
    +      "components": [
    +        {
    +          "id": "39",
    +          "name": {
    +            "translation": "Proposals"
    +          },
    +          "proposals": {
    +            "edges": [
    +              {
    +                "node": {
    +                  "id": "35",
    +                  "endorsements": [
    +                    {
    +                      "name": "Ms. Johnathon Schaefer"
    +                    },
    +                    {
    +                      "name": "Linwood Lakin PhD 3 4 endr1"
    +                    },
    +                    {
    +                      "name": "Gracie Emmerich"
    +                    },
    +                    {
    +                      "name": "Randall Rath 3 4 endr3"
    +                    },
    +                    {
    +                      "name": "Jolene Schmitt MD"
    +                    },
    +                    {
    +                      "name": "Clarence Hammes IV 3 4 endr5"
    +                    },
    +                    {
    +                      "name": "Omar Mayer"
    +                    },
    +                    {
    +                      "name": "Raymundo Jaskolski 3 4 endr7"
    +                    }
    +                  ]
    +                }
    +              },
    +              {
    +                "node": {
    +                  "id": "33",
    +                  "endorsements": [
    +                    {
    +                      "name": "Spring Brakus"
    +                    },
    +                    {
    +                      "name": "Reiko Simonis IV 3 2 endr1"
    +                    },
    +                    {
    +                      "name": "Dr. Jim Denesik"
    +                    },
    +                    {
    +                      "name": "Dr. Mack Schoen 3 2 endr3"
    +                    }
    +                  ]
    +                }
    +              }
    +            ]
    +          }
    +        }
    +      ]
    +    }
    +  }
    +}
    +
    +

    +What is going on?

    +

    Until the ... on Proposals line, there is nothing new. We are requesting the Assembly participatory space identified by the id=3, then listing all its components with the type "Proposals". All the components share the id and name properties, so we can just add them at the query.

    +

    After that, we want content specific from the Proposals type. In order to do that we must tell the server that the content we will request shall only be executed if the types matches Proposals. We do that by wrapping the rest of the query in the ... on Proposals clause.

    +

    The next line is just a property of the type Proposals which is a type of collection called a "connection". A connection works similar as normal collection (such as components) but it can handle more complex cases.

    +

    Typically, a connection is used to paginate long results, for this purpose the results are not directly available but encapsulated inside the list edges in several node results. Also there are more arguments available in order to navigate between pages. This are the arguments:

    +
      +
    • +first: Returns the first n elements from the list
    • +
    • +after: Returns the elements in the list that come after the specified cursor +
    • +
    • +last: Returns the last n elements from the list
    • +
    • +before: Returns the elements in the list that come before the specified cursor +
    • +
    +

    Example:

    +
    {
    +  assembly(id: 3) {
    +    components(filter: {type: "Proposals"}) {
    +      id
    +      name {
    +        translation(locale: "en")
    +      }
    +      ... on Proposals {
    +        proposals(first:2,after:"Mg") {
    +          pageInfo {
    +            endCursor
    +            startCursor
    +            hasPreviousPage
    +            hasNextPage
    +          }
    +          edges {
    +            node {
    +              id
    +              endorsements {
    +                name
    +              }
    +            }
    +          }
    +        }
    +      }
    +    }
    +  }
    +}
    +
    +

    Being the response:

    +
    {
    +  "data": {
    +    "assembly": {
    +      "components": [
    +        {
    +          "id": "39",
    +          "name": {
    +            "translation": "Proposals"
    +          },
    +          "proposals": {
    +            "pageInfo": {
    +              "endCursor": "NA",
    +              "startCursor": "Mw",
    +              "hasPreviousPage": false,
    +              "hasNextPage": true
    +            },
    +            "edges": [
    +              {
    +                "node": {
    +                  "id": "32",
    +                  "endorsements": []
    +                }
    +              },
    +              {
    +                "node": {
    +                  "id": "31",
    +                  "endorsements": [
    +                    {
    +                      "name": "Mr. Nicolas Raynor"
    +                    },
    +                    {
    +                      "name": "Gerry Fritsch PhD 3 1 endr1"
    +                    }
    +                  ]
    +                }
    +              }
    +            ]
    +          }
    +        }
    +      ]
    +    }
    +  }
    +}
    +
    +

    As you can see, a part from the edges list, you can access to the object pageInfo which gives you the information needed to navigate through the different pages.

    +

    For more info on how connections work, you can check the official guide:

    +

    https://graphql.org/learn/pagination/

    + + + +
    + +
    diff --git a/app/views/static/api/docs/input_object/categoryfilter/index.html b/app/views/static/api/docs/input_object/categoryfilter/index.html new file mode 100644 index 0000000000..212fd1cad5 --- /dev/null +++ b/app/views/static/api/docs/input_object/categoryfilter/index.html @@ -0,0 +1,1084 @@ +

    +CategoryFilter

    +

    A type used for filtering any category objects

    +

    +Input Fields

    +
    + parentId ([ID]) +
    +

    Returns the sub-categories for the given parent category or top-level categories if set to null

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/input_object/componentfilter/index.html b/app/views/static/api/docs/input_object/componentfilter/index.html new file mode 100644 index 0000000000..d80a00c6c3 --- /dev/null +++ b/app/views/static/api/docs/input_object/componentfilter/index.html @@ -0,0 +1,1120 @@ +

    +ComponentFilter

    +

    A type used for filtering any component parent objects

    +

    +Input Fields

    +
    + publishedBefore (String) +
    +

    List result published before (and excluding) this date. Expected format YYYY-MM-DD

    +
    +
    +
    + publishedSince (String) +
    +

    List result published after (and including) this date. Expected format YYYY-MM-DD

    +
    +
    +
    + locale (String) +
    +

    Specify the locale to use when searching translated fields, otherwise default organization language will be used

    +
    +
    +
    + type (String) +
    +

    Filters by type of component

    +
    +
    +
    + name (String) +
    +

    Filters by name of the component, additional locale parameter can be provided to specify in which to search

    +
    +
    +
    + withGeolocationEnabled (Boolean) +
    +

    Returns components with geolocation activated (may be Proposals or Meetings)

    +
    +
    +
    + withCommentsEnabled (Boolean) +
    +

    Returns components with comments enabled globally (can still be deactivated in the current step if the component has steps)

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/input_object/componentsort/index.html b/app/views/static/api/docs/input_object/componentsort/index.html new file mode 100644 index 0000000000..698468ba38 --- /dev/null +++ b/app/views/static/api/docs/input_object/componentsort/index.html @@ -0,0 +1,1108 @@ +

    +ComponentSort

    +

    A type used for sorting any component parent objects

    +

    +Input Fields

    +
    + locale (String) +
    +

    Specify the locale to use when ordering translated fields, otherwise default organization language will be used

    +
    +
    +
    + id (String) +
    +

    Sort by ID, valid values are ASC or DESC

    +
    +
    +
    + weight (String) +
    +

    Sort by weight (order in the website), valid values are ASC or DESC

    +
    +
    +
    + type (String) +
    +

    Sort by type of component, alphabetically, valid values are ASC or DESC

    +
    +
    +
    + name (String) +
    +

    Sort by name of the component, alphabetically, valid values are ASC or DESC

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/input_object/index.html b/app/views/static/api/docs/input_object/index.html new file mode 100644 index 0000000000..2068388d82 --- /dev/null +++ b/app/views/static/api/docs/input_object/index.html @@ -0,0 +1,1077 @@ +

    +Input Objects

    +

    Input objects are best described as "composable objects" in that they contain a set of input fields that define a particular object. For example, the AuthorInput takes a field called emails. Providing a value for emails will transform the AuthorInput into a list of User objects which contain that email address/

    +

    For more information, see the GraphQL spec.

    + + + +
    + +
    diff --git a/app/views/static/api/docs/input_object/participatoryprocessfilter/index.html b/app/views/static/api/docs/input_object/participatoryprocessfilter/index.html new file mode 100644 index 0000000000..4da1b3c5e2 --- /dev/null +++ b/app/views/static/api/docs/input_object/participatoryprocessfilter/index.html @@ -0,0 +1,1096 @@ +

    +ParticipatoryProcessFilter

    +

    A type used for filtering participatory processes

    +

    +Input Fields

    +
    + publishedBefore (String) +
    +

    List result published before (and excluding) this date. Expected format YYYY-MM-DD

    +
    +
    +
    + publishedSince (String) +
    +

    List result published after (and including) this date. Expected format YYYY-MM-DD

    +
    +
    +
    + hashtag (String) +
    +

    List result having this hashtag

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/input_object/participatoryprocesssort/index.html b/app/views/static/api/docs/input_object/participatoryprocesssort/index.html new file mode 100644 index 0000000000..efd3e1ef26 --- /dev/null +++ b/app/views/static/api/docs/input_object/participatoryprocesssort/index.html @@ -0,0 +1,1096 @@ +

    +ParticipatoryProcessSort

    +

    A type used for sorting participatory processess

    +

    +Input Fields

    +
    + publishedAt (String) +
    +

    Sort by date of publication, valid values are ASC or DESC

    +
    +
    +
    + id (String) +
    +

    Sort by ID, valid values are ASC or DESC

    +
    +
    +
    + startDate (String) +
    +

    Sort by participatory process starting date, valid values are ASC or DESC

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/input_object/postfilter/index.html b/app/views/static/api/docs/input_object/postfilter/index.html new file mode 100644 index 0000000000..aec4a1555b --- /dev/null +++ b/app/views/static/api/docs/input_object/postfilter/index.html @@ -0,0 +1,1115 @@ +

    +PostFilter

    +

    A type used for filtering posts inside a participatory space.

    +

    A typical query would look like:

    +
      {
    +  participatoryProcesses {
    +    components {
    +      ...on Blogs {
    +        posts(filter:{ createdBefore: "2020-01-01" }) {
    +          id
    +        }
    +      }
    +    }
    +  }
    +  }
    +
    +

    +Input Fields

    +
    + createdBefore (String) +
    +

    List result created before (and excluding) this date. Expected format YYYY-MM-DD

    +
    +
    +
    + createdSince (String) +
    +

    List result created after (and including) this date. Expected format YYYY-MM-DD

    +
    +
    +
    + updatedBefore (String) +
    +

    List result updated before (and excluding) this date. Expected format YYYY-MM-DD

    +
    +
    +
    + updatedSince (String) +
    +

    List result updated after (and including) this date. Expected format YYYY-MM-DD

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/input_object/postsort/index.html b/app/views/static/api/docs/input_object/postsort/index.html new file mode 100644 index 0000000000..a429353432 --- /dev/null +++ b/app/views/static/api/docs/input_object/postsort/index.html @@ -0,0 +1,1102 @@ +

    +PostSort

    +

    A type used for sorting blog posts

    +

    +Input Fields

    +
    + createdAt (String) +
    +

    Sort by date of creation, valid values are ASC or DESC

    +
    +
    +
    + updatedAt (String) +
    +

    Sort by date of last modification, valid values are ASC or DESC

    +
    +
    +
    + endorsementCount (String) +
    +

    Sort by number of endorsements, valid values are ASC or DESC

    +
    +
    +
    + id (String) +
    +

    Sort by ID, valid values are ASC or DESC

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/input_object/proposalfilter/index.html b/app/views/static/api/docs/input_object/proposalfilter/index.html new file mode 100644 index 0000000000..23aa4f75fd --- /dev/null +++ b/app/views/static/api/docs/input_object/proposalfilter/index.html @@ -0,0 +1,1103 @@ +

    +ProposalFilter

    +

    A type used for filtering proposals inside a participatory space.

    +

    A typical query would look like:

    +
      {
    +  participatoryProcesses {
    +    components {
    +      ...on Proposals {
    +        proposals(filter:{ publishedBefore: "2020-01-01" }) {
    +          id
    +        }
    +      }
    +    }
    +  }
    +  }
    +
    +

    +Input Fields

    +
    + publishedBefore (String) +
    +

    List result published before (and excluding) this date. Expected format YYYY-MM-DD

    +
    +
    +
    + publishedSince (String) +
    +

    List result published after (and including) this date. Expected format YYYY-MM-DD

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/input_object/proposalsort/index.html b/app/views/static/api/docs/input_object/proposalsort/index.html new file mode 100644 index 0000000000..797b4cbd0b --- /dev/null +++ b/app/views/static/api/docs/input_object/proposalsort/index.html @@ -0,0 +1,1102 @@ +

    +ProposalSort

    +

    A type used for sorting proposals

    +

    +Input Fields

    +
    + publishedAt (String) +
    +

    Sort by date of publication, valid values are ASC or DESC

    +
    +
    +
    + endorsementCount (String) +
    +

    Sort by number of endorsements, valid values are ASC or DESC

    +
    +
    +
    + id (String) +
    +

    Sort by ID, valid values are ASC or DESC

    +
    +
    +
    + voteCount (String) +
    +

    Sort by number of votes, valid values are ASC or DESC. Will be ignored if votes are hidden

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/input_object/userentityfilter/index.html b/app/views/static/api/docs/input_object/userentityfilter/index.html new file mode 100644 index 0000000000..6884cf691a --- /dev/null +++ b/app/views/static/api/docs/input_object/userentityfilter/index.html @@ -0,0 +1,1110 @@ +

    +UserEntityFilter

    +

    A type used for filtering any user or group +A typical query would look like: +{ users(filter:{wildcard:"sandy", excludeIds:[2,10,11]}) { id ...on User { groups { name } } ...on UserGroup { members { name } } } }

    +

    +Input Fields

    +
    + type (String) +
    +

    Filters by type of entity (User or UserGroup)

    +
    +
    +
    + name (String) +
    +

    Filters by name of the user entity. Searches (case insensitive) any fragment of the provided string

    +
    +
    +
    + nickname (String) +
    +

    Filters by nickname of the user entity. Searches (case insensitive) any fragment of the provided string

    +
    +
    +
    + wildcard (String) +
    +

    Filters by nickname or name of the user entity. Searches (case insensitive) any fragment of the provided string

    +
    +
    +
    + excludeIds ([ID!]) +
    +

    Excludes users contained in given ids. Valid values are one or more IDs (passed as an array)

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/input_object/userentitysort/index.html b/app/views/static/api/docs/input_object/userentitysort/index.html new file mode 100644 index 0000000000..feae0fc524 --- /dev/null +++ b/app/views/static/api/docs/input_object/userentitysort/index.html @@ -0,0 +1,1102 @@ +

    +UserEntitySort

    +

    A type used for sorting any component parent objects

    +

    +Input Fields

    +
    + id (String) +
    +

    Sort by ID, valid values are ASC or DESC

    +
    +
    +
    + type (String) +
    +

    Sort by type of user entity (user or group), alphabetically, valid values are ASC or DESC

    +
    +
    +
    + name (String) +
    +

    Sort by name of the user entity (user or group), alphabetically, valid values are ASC or DESC

    +
    +
    +
    + nickname (String) +
    +

    Sort by nickname of the user entity (user or group), alphabetically, valid values are ASC or DESC

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/interface/amendableentityinterface/index.html b/app/views/static/api/docs/interface/amendableentityinterface/index.html new file mode 100644 index 0000000000..016bedda73 --- /dev/null +++ b/app/views/static/api/docs/interface/amendableentityinterface/index.html @@ -0,0 +1,1089 @@ +

    +AmendableEntityInterface

    +

    An interface that can be used in objects with amendments

    +

    +Implemented by

    + +

    +Fields

    +
    + id (ID!) +
    +

    ID of this entity

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/interface/amendableinterface/index.html b/app/views/static/api/docs/interface/amendableinterface/index.html new file mode 100644 index 0000000000..77a5cda304 --- /dev/null +++ b/app/views/static/api/docs/interface/amendableinterface/index.html @@ -0,0 +1,1089 @@ +

    +AmendableInterface

    +

    An interface that can be used in objects with amendments

    +

    +Implemented by

    + +

    +Fields

    +
    + amendments ([Amendment]!) +
    +

    This object's amendments

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/interface/attachableinterface/index.html b/app/views/static/api/docs/interface/attachableinterface/index.html new file mode 100644 index 0000000000..23c703246a --- /dev/null +++ b/app/views/static/api/docs/interface/attachableinterface/index.html @@ -0,0 +1,1095 @@ +

    +AttachableInterface

    +

    An interface that can be used in objects with attachments

    +

    +Implemented by

    + +

    +Fields

    +
    + attachments ([Attachment]!) +
    +

    This object's attachments

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/interface/author/index.html b/app/views/static/api/docs/interface/author/index.html new file mode 100644 index 0000000000..5574f3414a --- /dev/null +++ b/app/views/static/api/docs/interface/author/index.html @@ -0,0 +1,1132 @@ +

    +Author

    +

    An author

    +

    +Implemented by

    + +

    +Fields

    +
    + id (ID!) +
    +

    The author ID

    +
    +
    +
    + name (String!) +
    +

    The author's name

    +
    +
    +
    + nickname (String!) +
    +

    The author's nickname

    +
    +
    +
    + avatarUrl (String!) +
    +

    The author's avatar url

    +
    +
    +
    + profilePath (String!) +
    +

    The author's profile path

    +
    +
    +
    + badge (String!) +
    +

    The author's badge icon

    +
    +
    +
    + organizationName (String!) +
    +

    The authors's organization name

    +
    +
    +
    + deleted (Boolean!) +
    +

    Whether the author's account has been deleted or not

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/interface/authorableinterface/index.html b/app/views/static/api/docs/interface/authorableinterface/index.html new file mode 100644 index 0000000000..b46677b314 --- /dev/null +++ b/app/views/static/api/docs/interface/authorableinterface/index.html @@ -0,0 +1,1092 @@ +

    +AuthorableInterface

    +

    An interface that can be used in authorable objects.

    +

    +Implemented by

    + +

    +Fields

    +
    + author (Author) +
    +

    The resource author

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/interface/categoriescontainerinterface/index.html b/app/views/static/api/docs/interface/categoriescontainerinterface/index.html new file mode 100644 index 0000000000..aa3afa4f6f --- /dev/null +++ b/app/views/static/api/docs/interface/categoriescontainerinterface/index.html @@ -0,0 +1,1110 @@ +

    +CategoriesContainerInterface

    +

    An interface that can be used in objects that contain categories.

    +

    +Implemented by

    + +

    +Fields

    +
    + categories ([Category]!) +
    +

    Categories for this space

    + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    filter + CategoryFilter + +

    Provides several methods to filter the results

    +
    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/interface/categorizableinterface/index.html b/app/views/static/api/docs/interface/categorizableinterface/index.html new file mode 100644 index 0000000000..04ab631f12 --- /dev/null +++ b/app/views/static/api/docs/interface/categorizableinterface/index.html @@ -0,0 +1,1094 @@ +

    +CategorizableInterface

    +

    An interface that can be used in categorizable objects.

    +

    +Implemented by

    + +

    +Fields

    +
    + category (Category) +
    +

    The object's category

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/interface/coauthorableinterface/index.html b/app/views/static/api/docs/interface/coauthorableinterface/index.html new file mode 100644 index 0000000000..ce9e7fc5cc --- /dev/null +++ b/app/views/static/api/docs/interface/coauthorableinterface/index.html @@ -0,0 +1,1101 @@ +

    +CoauthorableInterface

    +

    An interface that can be used in coauthorable objects.

    +

    +Implemented by

    + +

    +Fields

    +
    + authorsCount (Int) +
    +

    The total amount of co-authors that contributed to the entity. Note that this field may include also non-user authors like meetings or the organization

    +
    +
    +
    + author (Author) +
    +

    The resource author. Note that this can be null on official proposals or meeting-proposals

    +
    +
    +
    + authors ([Author]!) +
    +

    The resource co-authors. Include only users or groups of users

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/interface/commentableinterface/index.html b/app/views/static/api/docs/interface/commentableinterface/index.html new file mode 100644 index 0000000000..c9f46bf0e6 --- /dev/null +++ b/app/views/static/api/docs/interface/commentableinterface/index.html @@ -0,0 +1,1173 @@ +

    +CommentableInterface

    +

    A commentable interface

    +

    +Implemented by

    + +

    +Fields

    +
    + id (ID!) +
    +

    The commentable's ID

    +
    +
    +
    + type (String!) +
    +

    The commentable's class name. i.e. Decidim::ParticipatoryProcess

    +
    +
    +
    + acceptsNewComments (Boolean!) +
    +

    Whether the object can have new comments or not

    +
    +
    +
    + commentsHaveAlignment (Boolean!) +
    +

    Whether the object comments have alignment or not

    +
    +
    +
    + commentsHaveVotes (Boolean!) +
    +

    Whether the object comments have votes or not

    +
    +
    +
    + comments ([Comment!]!) +
    + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    orderBy + String + +

    Order the comments

    +
    singleCommentId + String + +

    ID of the single comment to look at

    +
    +
    +
    +
    + totalCommentsCount (Int!) +
    +

    The number of comments in all levels this resource holds

    +
    +
    +
    + hasComments (Boolean!) +
    +

    Check if the commentable has comments

    +
    +
    +
    + userAllowedToComment (Boolean!) +
    +

    Check if the current user can comment

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/interface/componentinterface/index.html b/app/views/static/api/docs/interface/componentinterface/index.html new file mode 100644 index 0000000000..7513b04824 --- /dev/null +++ b/app/views/static/api/docs/interface/componentinterface/index.html @@ -0,0 +1,1116 @@ +

    +ComponentInterface

    +

    This interface is implemented by all components that belong into a Participatory Space

    +

    +Implemented by

    + +

    +Fields

    +
    + id (ID!) +
    +

    The Component's unique ID

    +
    +
    +
    + name (TranslatedField!) +
    +

    The name of this component.

    +
    +
    +
    + weight (Int!) +
    +

    The weight of the component

    +
    +
    +
    + participatorySpace (ParticipatorySpace!) +
    +

    The participatory space in which this component belongs to.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/interface/endorsableinterface/index.html b/app/views/static/api/docs/interface/endorsableinterface/index.html new file mode 100644 index 0000000000..7a0672c051 --- /dev/null +++ b/app/views/static/api/docs/interface/endorsableinterface/index.html @@ -0,0 +1,1096 @@ +

    +EndorsableInterface

    +

    An interface that can be used in objects with endorsements

    +

    +Implemented by

    + +

    +Fields

    +
    + endorsements ([Author]!) +
    +

    The endorsements of this object.

    +
    +
    +
    + endorsementsCount (Int) +
    +

    The total amount of endorsements the object has received

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/interface/fingerprintinterface/index.html b/app/views/static/api/docs/interface/fingerprintinterface/index.html new file mode 100644 index 0000000000..a8e3f88d59 --- /dev/null +++ b/app/views/static/api/docs/interface/fingerprintinterface/index.html @@ -0,0 +1,1089 @@ +

    +FingerprintInterface

    +

    An interface that can be used in fingerprintable objects.

    +

    +Implemented by

    + +

    +Fields

    +
    + fingerprint (Fingerprint!) +
    +

    This object's fingerprint

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/interface/index.html b/app/views/static/api/docs/interface/index.html new file mode 100644 index 0000000000..dcdf0714c8 --- /dev/null +++ b/app/views/static/api/docs/interface/index.html @@ -0,0 +1,1077 @@ +

    +Interfaces

    +

    GraphQL Interfaces are a sort of "parent object" from which other objects can "inherit" from. For example, Stars is considered an interface, because both Repository and Gist can be starred. An interface has its own list of named fields that are shared by implementing objects.

    +

    For more information, see the GraphQL spec.

    + + + +
    + +
    diff --git a/app/views/static/api/docs/interface/initiativetypeinterface/index.html b/app/views/static/api/docs/interface/initiativetypeinterface/index.html new file mode 100644 index 0000000000..20bd68c7ca --- /dev/null +++ b/app/views/static/api/docs/interface/initiativetypeinterface/index.html @@ -0,0 +1,1089 @@ +

    +InitiativeTypeInterface

    +

    An interface that can be used in Initiative objects.

    +

    +Implemented by

    + +

    +Fields

    +
    + initiativeType (InitiativeType) +
    +

    The object's initiative type

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/interface/meetingslinkedresourcesinterface/index.html b/app/views/static/api/docs/interface/meetingslinkedresourcesinterface/index.html new file mode 100644 index 0000000000..ed101ea272 --- /dev/null +++ b/app/views/static/api/docs/interface/meetingslinkedresourcesinterface/index.html @@ -0,0 +1,1089 @@ +

    +MeetingsLinkedResourcesInterface

    +

    An interface that can be used with Resourceable models.

    +

    +Implemented by

    + +

    +Fields

    +
    + proposalsFromMeeting ([Proposal]!) +
    +

    Proposals created in this meeting

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/interface/participatoryspaceinterface/index.html b/app/views/static/api/docs/interface/participatoryspaceinterface/index.html new file mode 100644 index 0000000000..39463f6179 --- /dev/null +++ b/app/views/static/api/docs/interface/participatoryspaceinterface/index.html @@ -0,0 +1,1150 @@ +

    +ParticipatorySpaceInterface

    +

    The interface that all participatory spaces should implement.

    +

    +Implemented by

    + +

    +Fields

    +
    + id (ID!) +
    +

    The participatory space's unique ID

    +
    +
    +
    + title (TranslatedField!) +
    +

    The graphql_name of this participatory space.

    +
    +
    +
    + type (String!) +
    +

    The participatory space class name. i.e. Decidim::ParticipatoryProcess

    +
    +
    +
    + manifest (ParticipatorySpaceManifest!) +
    +

    The manifest information for the participatory space.

    +
    +
    +
    + components ([ComponentInterface!]) +
    +

    Lists the components this space contains.

    + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    filter + ComponentFilter + +

    Provides several methods to filter the results

    +
    order + ComponentSort + +

    Provides several methods to order the results

    +
    +
    +
    +
    + stats ([Statistic]) +
    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/interface/participatoryspaceresourceableinterface/index.html b/app/views/static/api/docs/interface/participatoryspaceresourceableinterface/index.html new file mode 100644 index 0000000000..4c7cccce7d --- /dev/null +++ b/app/views/static/api/docs/interface/participatoryspaceresourceableinterface/index.html @@ -0,0 +1,1090 @@ +

    +ParticipatorySpaceResourceableInterface

    +

    An interface that can be used in objects with participatorySpaceResourceable

    +

    +Implemented by

    + +

    +Fields

    +
    + linkedParticipatorySpaces ([ParticipatorySpaceLink!]!) +
    +

    Lists all linked participatory spaces in a polymorphic way

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/interface/questionnaireentityinterface/index.html b/app/views/static/api/docs/interface/questionnaireentityinterface/index.html new file mode 100644 index 0000000000..961ea6b558 --- /dev/null +++ b/app/views/static/api/docs/interface/questionnaireentityinterface/index.html @@ -0,0 +1,1089 @@ +

    +QuestionnaireEntityInterface

    +

    An interface that can be used in objects with questionnaires

    +

    +Implemented by

    + +

    +Fields

    +
    + id (ID!) +
    +

    ID of this entity

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/interface/scopableinterface/index.html b/app/views/static/api/docs/interface/scopableinterface/index.html new file mode 100644 index 0000000000..291c9c00aa --- /dev/null +++ b/app/views/static/api/docs/interface/scopableinterface/index.html @@ -0,0 +1,1096 @@ +

    +ScopableInterface

    +

    An interface that can be used in scopable objects.

    +

    +Implemented by

    + +

    +Fields

    +
    + scope (Scope) +
    +

    The object's scope

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/interface/servicesinterface/index.html b/app/views/static/api/docs/interface/servicesinterface/index.html new file mode 100644 index 0000000000..aae0cdf187 --- /dev/null +++ b/app/views/static/api/docs/interface/servicesinterface/index.html @@ -0,0 +1,1089 @@ +

    +ServicesInterface

    +

    An interface that can be used with services.

    +

    +Implemented by

    + +

    +Fields

    +
    + services ([MeetingService]!) +
    +

    The object's services

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/interface/timestampsinterface/index.html b/app/views/static/api/docs/interface/timestampsinterface/index.html new file mode 100644 index 0000000000..ea822f1d5b --- /dev/null +++ b/app/views/static/api/docs/interface/timestampsinterface/index.html @@ -0,0 +1,1100 @@ +

    +TimestampsInterface

    +

    An interface that can be used in objects with created_at and updated_at attributes

    +

    +Implemented by

    + +

    +Fields

    +
    + createdAt (DateTime) +
    +

    The date and time this object was created

    +
    +
    +
    + updatedAt (DateTime) +
    +

    The date and time this object was updated

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/interface/traceableinterface/index.html b/app/views/static/api/docs/interface/traceableinterface/index.html new file mode 100644 index 0000000000..0d6954e4ff --- /dev/null +++ b/app/views/static/api/docs/interface/traceableinterface/index.html @@ -0,0 +1,1097 @@ +

    +TraceableInterface

    +

    An interface that can be used in objects with traceability (versions)

    +

    +Implemented by

    + +

    +Fields

    +
    + versionsCount (Int!) +
    +

    Total number of versions

    +
    +
    +
    + versions ([TraceVersion]!) +
    +

    This object's versions

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/mutation/comment/index.html b/app/views/static/api/docs/mutation/comment/index.html new file mode 100644 index 0000000000..8afb624217 --- /dev/null +++ b/app/views/static/api/docs/mutation/comment/index.html @@ -0,0 +1,1114 @@ +

    +comment

    +

    A comment

    +

    +Input fields

    +
    + id (ID!) +
    +

    The comment's id

    +
    +
    +
    + locale (String) +
    +

    The locale for which to get the comments text

    +
    +
    +
    + toggleTranslations (Boolean) +
    +

    Whether the user asked to toggle the machine translations or not.

    +
    +
    +

    +Return fields

    +
    + id (ID!) +
    +

    The Comment's unique ID

    +
    +
    +
    + upVote (Comment) +
    +
    +
    +
    + downVote (Comment) +
    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/mutation/commentable/index.html b/app/views/static/api/docs/mutation/commentable/index.html new file mode 100644 index 0000000000..7dc8000c63 --- /dev/null +++ b/app/views/static/api/docs/mutation/commentable/index.html @@ -0,0 +1,1155 @@ +

    +commentable

    +

    A commentable

    +

    +Input fields

    +
    + id (String!) +
    +

    The commentable's ID

    +
    +
    +
    + type (String!) +
    +

    The commentable's class name. i.e. Decidim::ParticipatoryProcess

    +
    +
    +
    + locale (String) +
    +

    The locale for which to get the comments text

    +
    +
    +
    + toggleTranslations (Boolean) +
    +

    Whether the user asked to toggle the machine translations or not.

    +
    +
    +

    +Return fields

    +
    + id (ID!) +
    +

    The Commentable's unique ID

    +
    +
    +
    + addComment (Comment) +
    +

    Add a new comment to a commentable

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    body + String! + +

    The comments's body

    +
    alignment + Int + +

    The comment's alignment. Can be 0 (neutral), 1 (in favor) or -1 (against)'

    +

    The default value is 0.

    +
    userGroupId + ID + +

    The comment's user group id. Replaces the author.

    +
    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/__directive/index.html b/app/views/static/api/docs/object/__directive/index.html new file mode 100644 index 0000000000..2011650c9d --- /dev/null +++ b/app/views/static/api/docs/object/__directive/index.html @@ -0,0 +1,1151 @@ +

    +__Directive

    +

    A Directive provides a way to describe alternate runtime execution and type validation behavior in a GraphQL document.

    +

    In some cases, you need to provide options to alter GraphQL's execution behavior in ways field arguments will not suffice, such as conditionally including or skipping a field. Directives provide this by describing additional information to the executor.

    +

    +Fields

    +
    + name (String!) +
    +
    +
    +
    + description (String) +
    +
    +
    +
    + locations ([__DirectiveLocation!]!) +
    +
    +
    +
    + args ([__InputValue!]!) +
    + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    includeDeprecated + Boolean + +

    The default value is false.

    +
    +
    +
    +
    + onOperation (Boolean!) +
    +
    + Deprecation notice +

    Use locations.

    +
    +
    +
    +
    + onFragment (Boolean!) +
    +
    + Deprecation notice +

    Use locations.

    +
    +
    +
    +
    + onField (Boolean!) +
    +
    + Deprecation notice +

    Use locations.

    +
    +
    +
    +
    + isRepeatable (Boolean) +
    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/__enumvalue/index.html b/app/views/static/api/docs/object/__enumvalue/index.html new file mode 100644 index 0000000000..16a54d3d4b --- /dev/null +++ b/app/views/static/api/docs/object/__enumvalue/index.html @@ -0,0 +1,1098 @@ +

    +__EnumValue

    +

    One possible value for a given Enum. Enum values are unique values, not a placeholder for a string or numeric value. However an Enum value is returned in a JSON response as a string.

    +

    +Fields

    +
    + name (String!) +
    +
    +
    +
    + description (String) +
    +
    +
    +
    + isDeprecated (Boolean!) +
    +
    +
    +
    + deprecationReason (String) +
    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/__field/index.html b/app/views/static/api/docs/object/__field/index.html new file mode 100644 index 0000000000..7b65e14084 --- /dev/null +++ b/app/views/static/api/docs/object/__field/index.html @@ -0,0 +1,1128 @@ +

    +__Field

    +

    Object and Interface types are described by a list of Fields, each of which has a name, potentially a list of arguments, and a return type.

    +

    +Fields

    +
    + name (String!) +
    +
    +
    +
    + description (String) +
    +
    +
    +
    + args ([__InputValue!]!) +
    + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    includeDeprecated + Boolean + +

    The default value is false.

    +
    +
    +
    +
    + type (__Type!) +
    +
    +
    +
    + isDeprecated (Boolean!) +
    +
    +
    +
    + deprecationReason (String) +
    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/__inputvalue/index.html b/app/views/static/api/docs/object/__inputvalue/index.html new file mode 100644 index 0000000000..0e419c631b --- /dev/null +++ b/app/views/static/api/docs/object/__inputvalue/index.html @@ -0,0 +1,1109 @@ +

    +__InputValue

    +

    Arguments provided to Fields or Directives and the input fields of an InputObject are represented as Input Values which describe their type and optionally a default value.

    +

    +Fields

    +
    + name (String!) +
    +
    +
    +
    + description (String) +
    +
    +
    +
    + type (__Type!) +
    +
    +
    +
    + defaultValue (String) +
    +

    A GraphQL-formatted string representing the default value for this input value.

    +
    +
    +
    + isDeprecated (Boolean!) +
    +
    +
    +
    + deprecationReason (String) +
    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/__schema/index.html b/app/views/static/api/docs/object/__schema/index.html new file mode 100644 index 0000000000..9a1a50ed5e --- /dev/null +++ b/app/views/static/api/docs/object/__schema/index.html @@ -0,0 +1,1113 @@ +

    +__Schema

    +

    A GraphQL Schema defines the capabilities of a GraphQL server. It exposes all available types and directives on the server, as well as the entry points for query, mutation, and subscription operations.

    +

    +Fields

    +
    + types ([__Type!]!) +
    +

    A list of all types supported by this server.

    +
    +
    +
    + queryType (__Type!) +
    +

    The type that query operations will be rooted at.

    +
    +
    +
    + mutationType (__Type) +
    +

    If this server supports mutation, the type that mutation operations will be rooted at.

    +
    +
    +
    + subscriptionType (__Type) +
    +

    If this server support subscription, the type that subscription operations will be rooted at.

    +
    +
    +
    + directives ([__Directive!]!) +
    +

    A list of all directives supported by this server.

    +
    +
    +
    + description (String) +
    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/__type/index.html b/app/views/static/api/docs/object/__type/index.html new file mode 100644 index 0000000000..d78c29fbb3 --- /dev/null +++ b/app/views/static/api/docs/object/__type/index.html @@ -0,0 +1,1194 @@ +

    +__Type

    +

    The fundamental unit of any GraphQL Schema is the type. There are many kinds of types in GraphQL as represented by the __TypeKind enum.

    +

    Depending on the kind of a type, certain fields describe information about that type. Scalar types provide no information beyond a name and description, while Enum types provide their values. Object and Interface types provide the fields they describe. Abstract types, Union and Interface, provide the Object types possible at runtime. List and NonNull types compose other types.

    +

    +Fields

    +
    + kind (__TypeKind!) +
    +
    +
    +
    + name (String) +
    +
    +
    +
    + description (String) +
    +
    +
    +
    + fields ([__Field!]) +
    + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    includeDeprecated + Boolean + +

    The default value is false.

    +
    +
    +
    +
    + interfaces ([__Type!]) +
    +
    +
    +
    + possibleTypes ([__Type!]) +
    +
    +
    +
    + enumValues ([__EnumValue!]) +
    + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    includeDeprecated + Boolean + +

    The default value is false.

    +
    +
    +
    +
    + inputFields ([__InputValue!]) +
    + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    includeDeprecated + Boolean + +

    The default value is false.

    +
    +
    +
    +
    + ofType (__Type) +
    +
    +
    +
    + specifiedByURL (String) +
    +
    +
    +
    + isOneOf (Boolean!) +
    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/accountability/index.html b/app/views/static/api/docs/object/accountability/index.html new file mode 100644 index 0000000000..b1158d378d --- /dev/null +++ b/app/views/static/api/docs/object/accountability/index.html @@ -0,0 +1,1185 @@ +

    +Accountability

    +

    An accountability component of a participatory space.

    +

    +Implements

    + +

    +Connections

    +
    + results (ResultConnection) +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    after + String + +

    Returns the elements in the list that come after the specified cursor.

    +
    before + String + +

    Returns the elements in the list that come before the specified cursor.

    +
    first + Int + +

    Returns the first n elements from the list.

    +
    last + Int + +

    Returns the last n elements from the list.

    +
    +
    +
    +

    +Fields

    +
    + result (Result) +
    + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    id + ID! + +
    +
    +
    +
    + id (ID!) +
    +

    The Component's unique ID

    +
    +
    +
    + name (TranslatedField!) +
    +

    The name of this component.

    +
    +
    +
    + weight (Int!) +
    +

    The weight of the component

    +
    +
    +
    + participatorySpace (ParticipatorySpace!) +
    +

    The participatory space in which this component belongs to.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/amendment/index.html b/app/views/static/api/docs/object/amendment/index.html new file mode 100644 index 0000000000..7145a94918 --- /dev/null +++ b/app/views/static/api/docs/object/amendment/index.html @@ -0,0 +1,1120 @@ +

    +Amendment

    +

    An amendment

    +

    +Fields

    +
    + id (ID!) +
    +

    The id of this amendment

    +
    +
    +
    + state (String!) +
    +

    The status of this amendment

    +
    +
    +
    + amender (Author!) +
    +

    The author of this amendment

    +
    +
    +
    + amendableType (String!) +
    +

    Type of the amendable object

    +
    +
    +
    + emendationType (String!) +
    +

    Type of the emendation object

    +
    +
    +
    + amendable (AmendableEntityInterface!) +
    +

    The original amended resource (currently, a proposal only)

    +
    +
    +
    + emendation (AmendableEntityInterface!) +
    +

    The emendation (currently, a proposal only)

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/answeroption/index.html b/app/views/static/api/docs/object/answeroption/index.html new file mode 100644 index 0000000000..687b6a32ff --- /dev/null +++ b/app/views/static/api/docs/object/answeroption/index.html @@ -0,0 +1,1096 @@ +

    +AnswerOption

    +

    An answer option for a multi-choice question in a questionnaire

    +

    +Fields

    +
    + id (ID!) +
    +

    ID of this answer option

    +
    +
    +
    + body (TranslatedField!) +
    +

    The text answer response option.

    +
    +
    +
    + freeText (Boolean!) +
    +

    Whether if this answer accepts any free text from the user.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/area/index.html b/app/views/static/api/docs/object/area/index.html new file mode 100644 index 0000000000..56a0dae044 --- /dev/null +++ b/app/views/static/api/docs/object/area/index.html @@ -0,0 +1,1108 @@ +

    +Area

    +

    An area.

    +

    +Fields

    +
    + id (ID!) +
    +

    Internal ID for this area

    +
    +
    +
    + name (TranslatedField!) +
    +

    The graphql_name of this area.

    +
    +
    +
    + areaType (AreaType) +
    +

    The area type of this area

    +
    +
    +
    + createdAt (DateTime!) +
    +

    The time this assembly was created

    +
    +
    +
    + updatedAt (DateTime!) +
    +

    The time this assembly was updated

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/areatype/index.html b/app/views/static/api/docs/object/areatype/index.html new file mode 100644 index 0000000000..3c5f4bc562 --- /dev/null +++ b/app/views/static/api/docs/object/areatype/index.html @@ -0,0 +1,1096 @@ +

    +AreaType

    +

    An area type.

    +

    +Fields

    +
    + id (ID!) +
    +

    Internal ID for this area type

    +
    +
    +
    + name (TranslatedField!) +
    +

    The name of this area type.

    +
    +
    +
    + plural (TranslatedField!) +
    +

    The plural name of this area type

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/assembliestype/index.html b/app/views/static/api/docs/object/assembliestype/index.html new file mode 100644 index 0000000000..e31746971f --- /dev/null +++ b/app/views/static/api/docs/object/assembliestype/index.html @@ -0,0 +1,1108 @@ +

    +AssembliesType

    +

    An assemblies type

    +

    +Fields

    +
    + id (ID!) +
    +

    The assemblies type's unique ID

    +
    +
    +
    + title (TranslatedField!) +
    +

    The title of this assemblies type.

    +
    +
    +
    + createdAt (DateTime!) +
    +

    The time this assemblies type was created

    +
    +
    +
    + updatedAt (DateTime!) +
    +

    The time this assemblies type was updated

    +
    +
    +
    + assemblies ([Assembly]!) +
    +

    Assemblies with this assemblies type

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/assembly/index.html b/app/views/static/api/docs/object/assembly/index.html new file mode 100644 index 0000000000..f8b2dfd49c --- /dev/null +++ b/app/views/static/api/docs/object/assembly/index.html @@ -0,0 +1,1464 @@ +

    +Assembly

    +

    An assembly

    +

    +Implements

    + +

    +Fields

    +
    + id (ID!) +
    +

    The internal ID for this assembly

    +
    +
    +
    + subtitle (TranslatedField) +
    +

    The subtitle of this assembly

    +
    +
    +
    + shortDescription (TranslatedField) +
    +

    The sort description of this assembly

    +
    +
    +
    + description (TranslatedField) +
    +

    The description of this assembly

    +
    +
    +
    + slug (String!) +
    +

    The slug of this assembly

    +
    +
    +
    + hashtag (String) +
    +

    The hashtag for this assembly

    +
    +
    +
    + createdAt (DateTime!) +
    +

    The time this assembly was created

    +
    +
    +
    + updatedAt (DateTime!) +
    +

    The time this assembly was updated

    +
    +
    +
    + publishedAt (DateTime!) +
    +

    The time this assembly was published

    +
    +
    +
    + reference (String!) +
    +

    Reference for this assembly

    +
    +
    +
    + heroImage (String) +
    +

    The hero image for this assembly

    +
    +
    +
    + bannerImage (String) +
    +

    The banner image for this assembly

    +
    +
    +
    + +
    +

    If this assembly is promoted (therefore in the homepage)

    +
    +
    +
    + developerGroup (TranslatedField) +
    +

    The promoter group of this assembly

    +
    +
    +
    + metaScope (TranslatedField) +
    +

    The scope metadata of this assembly

    +
    +
    +
    + localArea (TranslatedField) +
    +

    The organization area of this assembly

    +
    +
    +
    + target (TranslatedField) +
    +

    Who participates in this assembly

    +
    +
    +
    + participatoryScope (TranslatedField) +
    +

    What is decided on this assembly

    +
    +
    +
    + participatoryStructure (TranslatedField) +
    +

    How it is decided on this assembly

    +
    +
    +
    + showStatistics (Boolean) +
    +

    If this assembly should show statistics

    +
    +
    +
    + scopesEnabled (Boolean) +
    +

    If this assembly has scopes enabled

    +
    +
    +
    + privateSpace (Boolean) +
    +

    If this assembly is a private space

    +
    +
    +
    + area (Area) +
    +

    Area of this assembly

    +
    +
    +
    + parent (Assembly) +
    +

    The parent assembly of this assembly

    +
    +
    +
    + parentsPath (String) +
    +

    Assembly hierarchy representation

    +
    +
    +
    + childrenCount (Int) +
    +

    Number of children assemblies

    +
    +
    +
    + purposeOfAction (TranslatedField) +
    +

    Purpose of action

    +
    +
    +
    + composition (TranslatedField) +
    +

    Composition of this assembly

    +
    +
    +
    + assemblyType (AssembliesType) +
    +

    Type of the assembly

    +
    +
    +
    + creationDate (Date) +
    +

    Creation date of this assembly

    +
    +
    +
    + createdBy (String) +
    +

    The creator of this assembly

    +
    +
    +
    + createdByOther (TranslatedField) +
    +

    Custom creator

    +
    +
    +
    + duration (Date) +
    +

    Duration of this assembly

    +
    +
    +
    + includedAt (Date) +
    +

    Included at

    +
    +
    +
    + closingDate (Date) +
    +

    Closing date of the assembly

    +
    +
    +
    + closingDateReason (TranslatedField) +
    +

    Closing date reason of this assembly

    +
    +
    +
    + internalOrganisation (TranslatedField) +
    +

    Internal organisation of this assembly

    +
    +
    +
    + isTransparent (Boolean) +
    +

    If this assembly is transparent

    +
    +
    +
    + specialFeatures (TranslatedField) +
    +

    Special features of this assembly

    +
    +
    +
    + twitterHandler (String) +
    +

    Twitter handler

    +
    +
    +
    + instagramHandler (String) +
    +

    Instagram handler

    +
    +
    +
    + facebookHandler (String) +
    +

    Facebook handler

    +
    +
    +
    + youtubeHandler (String) +
    +

    Youtube handler

    +
    +
    +
    + githubHandler (String) +
    +

    Github handler

    +
    +
    +
    + announcement (TranslatedField) +
    +

    Highlighted announcement for this assembly

    +
    +
    +
    + members ([AssemblyMember]!) +
    +

    Members of this assembly

    +
    +
    +
    + children ([Assembly]!) +
    +

    Childrens of this assembly

    +
    +
    +
    + categories ([Category]!) +
    +

    Categories for this space

    + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    filter + CategoryFilter + +

    Provides several methods to filter the results

    +
    +
    +
    +
    + linkedParticipatorySpaces ([ParticipatorySpaceLink!]!) +
    +

    Lists all linked participatory spaces in a polymorphic way

    +
    +
    +
    + attachments ([Attachment]!) +
    +

    This object's attachments

    +
    +
    +
    + title (TranslatedField!) +
    +

    The graphql_name of this participatory space.

    +
    +
    +
    + type (String!) +
    +

    The participatory space class name. i.e. Decidim::ParticipatoryProcess

    +
    +
    +
    + manifest (ParticipatorySpaceManifest!) +
    +

    The manifest information for the participatory space.

    +
    +
    +
    + components ([ComponentInterface!]) +
    +

    Lists the components this space contains.

    + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    filter + ComponentFilter + +

    Provides several methods to filter the results

    +
    order + ComponentSort + +

    Provides several methods to order the results

    +
    +
    +
    +
    + stats ([Statistic]) +
    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/assemblymember/index.html b/app/views/static/api/docs/object/assemblymember/index.html new file mode 100644 index 0000000000..9fa69668e2 --- /dev/null +++ b/app/views/static/api/docs/object/assemblymember/index.html @@ -0,0 +1,1150 @@ +

    +AssemblyMember

    +

    An assembly member

    +

    +Fields

    +
    + id (ID!) +
    +

    Internal ID of the member

    +
    +
    +
    + fullName (String) +
    +

    Full name of the member

    +
    +
    +
    + position (String) +
    +

    Position of the member in the assembly

    +
    +
    +
    + user (User) +
    +

    The corresponding decidim user

    +
    +
    +
    + createdAt (DateTime) +
    +

    The time this member was created

    +
    +
    +
    + updatedAt (DateTime) +
    +

    The time this member was updated

    +
    +
    +
    + weight (Int) +
    +

    Order of appearance in which it should be represented

    +
    +
    +
    + gender (String) +
    +

    Gender of the member

    +
    +
    +
    + birthplace (String) +
    +

    Birthplace of the member

    +
    +
    +
    + designationDate (Date) +
    +

    Date of designation of the member

    +
    +
    +
    + positionOther (String) +
    +

    Custom position name

    +
    +
    +
    + ceasedDate (Date) +
    +

    Date of cease for the member

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/attachment/index.html b/app/views/static/api/docs/object/attachment/index.html new file mode 100644 index 0000000000..83dc13137c --- /dev/null +++ b/app/views/static/api/docs/object/attachment/index.html @@ -0,0 +1,1108 @@ +

    +Attachment

    +

    A file attachment

    +

    +Fields

    +
    + title (TranslatedField!) +
    +

    The title of this attachment.

    +
    +
    +
    + description (TranslatedField!) +
    +

    The description of this attachment.

    +
    +
    +
    + url (String!) +
    +

    The url of this attachment

    +
    +
    +
    + type (String!) +
    +

    The type of this attachment

    +
    +
    +
    + thumbnail (String) +
    +

    A thumbnail of this attachment, if it is an image.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/blogs/index.html b/app/views/static/api/docs/object/blogs/index.html new file mode 100644 index 0000000000..299525a90a --- /dev/null +++ b/app/views/static/api/docs/object/blogs/index.html @@ -0,0 +1,1206 @@ +

    +Blogs

    +

    A blogs component of a participatory space.

    +

    +Implements

    + +

    +Connections

    +
    + posts (PostConnection!) +
    +

    List all posts

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    after + String + +

    Returns the elements in the list that come after the specified cursor.

    +
    before + String + +

    Returns the elements in the list that come before the specified cursor.

    +
    first + Int + +

    Returns the first n elements from the list.

    +
    last + Int + +

    Returns the last n elements from the list.

    +
    order + PostSort + +

    Provides several methods to order the results

    +
    filter + PostFilter + +

    Provides several methods to filter the results

    +
    +
    +
    +

    +Fields

    +
    + post (Post) +
    +

    Finds one post

    + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    id + ID! + +

    The ID of the post

    +
    +
    +
    +
    + id (ID!) +
    +

    The Component's unique ID

    +
    +
    +
    + name (TranslatedField!) +
    +

    The name of this component.

    +
    +
    +
    + weight (Int!) +
    +

    The weight of the component

    +
    +
    +
    + participatorySpace (ParticipatorySpace!) +
    +

    The participatory space in which this component belongs to.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/budget/index.html b/app/views/static/api/docs/object/budget/index.html new file mode 100644 index 0000000000..d0f603e3ae --- /dev/null +++ b/app/views/static/api/docs/object/budget/index.html @@ -0,0 +1,1144 @@ +

    +Budget

    +

    A budget

    +

    +Implements

    + +

    +Fields

    +
    + id (ID!) +
    +

    The internal ID of this budget

    +
    +
    +
    + title (TranslatedField!) +
    +

    The title for this budget

    +
    +
    +
    + description (TranslatedField!) +
    +

    The description for this budget

    +
    +
    +
    + total_budget (Int!) +
    +

    The total budget

    +
    +
    +
    + createdAt (DateTime) +
    +

    When this budget was created

    +
    +
    +
    + updatedAt (DateTime) +
    +

    When this budget was updated

    +
    +
    +
    + projects ([Project]!) +
    +

    The projects for this budget

    +
    +
    +
    + versionsCount (Int!) +
    +

    Total number of versions

    +
    +
    +
    + versions ([TraceVersion]!) +
    +

    This object's versions

    +
    +
    +
    + scope (Scope) +
    +

    The object's scope

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/budgetconnection/index.html b/app/views/static/api/docs/object/budgetconnection/index.html new file mode 100644 index 0000000000..a547cc5405 --- /dev/null +++ b/app/views/static/api/docs/object/budgetconnection/index.html @@ -0,0 +1,1096 @@ +

    +BudgetConnection

    +

    The connection type for Budget.

    +

    +Fields

    +
    + edges ([BudgetEdge]) +
    +

    A list of edges.

    +
    +
    +
    + nodes ([Budget]) +
    +

    A list of nodes.

    +
    +
    +
    + pageInfo (PageInfo!) +
    +

    Information to aid in pagination.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/budgetedge/index.html b/app/views/static/api/docs/object/budgetedge/index.html new file mode 100644 index 0000000000..dd798704b3 --- /dev/null +++ b/app/views/static/api/docs/object/budgetedge/index.html @@ -0,0 +1,1090 @@ +

    +BudgetEdge

    +

    An edge in a connection.

    +

    +Fields

    +
    + node (Budget) +
    +

    The item at the end of the edge.

    +
    +
    +
    + cursor (String!) +
    +

    A cursor for use in pagination.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/budgets/index.html b/app/views/static/api/docs/object/budgets/index.html new file mode 100644 index 0000000000..8211ebb57d --- /dev/null +++ b/app/views/static/api/docs/object/budgets/index.html @@ -0,0 +1,1185 @@ +

    +Budgets

    +

    A budget component of a participatory space.

    +

    +Implements

    + +

    +Connections

    +
    + budgets (BudgetConnection) +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    after + String + +

    Returns the elements in the list that come after the specified cursor.

    +
    before + String + +

    Returns the elements in the list that come before the specified cursor.

    +
    first + Int + +

    Returns the first n elements from the list.

    +
    last + Int + +

    Returns the last n elements from the list.

    +
    +
    +
    +

    +Fields

    +
    + budget (Budget) +
    + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    id + ID! + +
    +
    +
    +
    + id (ID!) +
    +

    The Component's unique ID

    +
    +
    +
    + name (TranslatedField!) +
    +

    The name of this component.

    +
    +
    +
    + weight (Int!) +
    +

    The weight of the component

    +
    +
    +
    + participatorySpace (ParticipatorySpace!) +
    +

    The participatory space in which this component belongs to.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/category/index.html b/app/views/static/api/docs/object/category/index.html new file mode 100644 index 0000000000..f063b5fd25 --- /dev/null +++ b/app/views/static/api/docs/object/category/index.html @@ -0,0 +1,1101 @@ +

    +Category

    +

    A category that can be applied to other resources.

    +

    +Fields

    +
    + id (ID!) +
    +
    +
    +
    + name (TranslatedField!) +
    +

    The name of this category.

    +
    +
    +
    + subcategories ([Category]!) +
    +

    Subcategories of this category.

    +
    +
    +
    + parent (Category) +
    +

    This category's parent category.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/comment/index.html b/app/views/static/api/docs/object/comment/index.html new file mode 100644 index 0000000000..787c8fbfec --- /dev/null +++ b/app/views/static/api/docs/object/comment/index.html @@ -0,0 +1,1237 @@ +

    +Comment

    +

    A comment

    +

    +Implements

    + +

    +Fields

    +
    + author (Author!) +
    +

    The resource author

    +
    +
    +
    + id (ID!) +
    +

    The Comment's unique ID

    +
    +
    +
    + sgid (String!) +
    +

    The Comment's signed global id

    +
    +
    +
    + body (String!) +
    +

    The comment message

    +
    +
    +
    + formattedBody (String!) +
    +

    The comment message ready to display (it is expected to include HTML)

    +
    +
    +
    + createdAt (String!) +
    +

    The creation date of the comment

    +
    +
    +
    + formattedCreatedAt (String!) +
    +

    The creation date of the comment in relative format

    +
    +
    +
    + alignment (Int) +
    +

    The comment's alignment. Can be 0 (neutral), 1 (in favor) or -1 (against)'

    +
    +
    +
    + upVotes (Int!) +
    +

    The number of comment's upVotes

    +
    +
    +
    + upVoted (Boolean!) +
    +

    Check if the current user has upvoted the comment

    +
    +
    +
    + downVotes (Int!) +
    +

    The number of comment's downVotes

    +
    +
    +
    + downVoted (Boolean!) +
    +

    Check if the current user has downvoted the comment

    +
    +
    +
    + hasComments (Boolean!) +
    +

    Check if the commentable has comments

    +
    +
    +
    + alreadyReported (Boolean!) +
    +

    Check if the current user has reported the comment

    +
    +
    +
    + userAllowedToComment (Boolean!) +
    +

    Check if the current user can comment

    +
    +
    +
    + type (String!) +
    +

    The commentable's class name. i.e. Decidim::ParticipatoryProcess

    +
    +
    +
    + acceptsNewComments (Boolean!) +
    +

    Whether the object can have new comments or not

    +
    +
    +
    + commentsHaveAlignment (Boolean!) +
    +

    Whether the object comments have alignment or not

    +
    +
    +
    + commentsHaveVotes (Boolean!) +
    +

    Whether the object comments have votes or not

    +
    +
    +
    + comments ([Comment!]!) +
    + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    orderBy + String + +

    Order the comments

    +
    singleCommentId + String + +

    ID of the single comment to look at

    +
    +
    +
    +
    + totalCommentsCount (Int!) +
    +

    The number of comments in all levels this resource holds

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/commentable/index.html b/app/views/static/api/docs/object/commentable/index.html new file mode 100644 index 0000000000..32ce9186ec --- /dev/null +++ b/app/views/static/api/docs/object/commentable/index.html @@ -0,0 +1,1165 @@ +

    +Commentable

    +

    A commentable object

    +

    +Implements

    + +

    +Fields

    +
    + id (ID!) +
    +

    The commentable's ID

    +
    +
    +
    + type (String!) +
    +

    The commentable's class name. i.e. Decidim::ParticipatoryProcess

    +
    +
    +
    + acceptsNewComments (Boolean!) +
    +

    Whether the object can have new comments or not

    +
    +
    +
    + commentsHaveAlignment (Boolean!) +
    +

    Whether the object comments have alignment or not

    +
    +
    +
    + commentsHaveVotes (Boolean!) +
    +

    Whether the object comments have votes or not

    +
    +
    +
    + comments ([Comment!]!) +
    + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    orderBy + String + +

    Order the comments

    +
    singleCommentId + String + +

    ID of the single comment to look at

    +
    +
    +
    +
    + totalCommentsCount (Int!) +
    +

    The number of comments in all levels this resource holds

    +
    +
    +
    + hasComments (Boolean!) +
    +

    Check if the commentable has comments

    +
    +
    +
    + userAllowedToComment (Boolean!) +
    +

    Check if the current user can comment

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/commentablemutation/index.html b/app/views/static/api/docs/object/commentablemutation/index.html new file mode 100644 index 0000000000..bca16f3376 --- /dev/null +++ b/app/views/static/api/docs/object/commentablemutation/index.html @@ -0,0 +1,1129 @@ +

    +CommentableMutation

    +

    A commentable which includes its available mutations

    +

    +Fields

    +
    + id (ID!) +
    +

    The Commentable's unique ID

    +
    +
    +
    + addComment (Comment) +
    +

    Add a new comment to a commentable

    + + + + + + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    body + String! + +

    The comments's body

    +
    alignment + Int + +

    The comment's alignment. Can be 0 (neutral), 1 (in favor) or -1 (against)'

    +

    The default value is 0.

    +
    userGroupId + ID + +

    The comment's user group id. Replaces the author.

    +
    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/commentmutation/index.html b/app/views/static/api/docs/object/commentmutation/index.html new file mode 100644 index 0000000000..ad63d6e001 --- /dev/null +++ b/app/views/static/api/docs/object/commentmutation/index.html @@ -0,0 +1,1094 @@ +

    +CommentMutation

    +

    A comment which includes its available mutations

    +

    +Fields

    +
    + id (ID!) +
    +

    The Comment's unique ID

    +
    +
    +
    + upVote (Comment) +
    +
    +
    +
    + downVote (Comment) +
    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/component/index.html b/app/views/static/api/docs/object/component/index.html new file mode 100644 index 0000000000..131748537c --- /dev/null +++ b/app/views/static/api/docs/object/component/index.html @@ -0,0 +1,1107 @@ +

    +Component

    +

    A base component with no particular specificities.

    +

    +Implements

    + +

    +Fields

    +
    + id (ID!) +
    +

    The Component's unique ID

    +
    +
    +
    + name (TranslatedField!) +
    +

    The name of this component.

    +
    +
    +
    + weight (Int!) +
    +

    The weight of the component

    +
    +
    +
    + participatorySpace (ParticipatorySpace!) +
    +

    The participatory space in which this component belongs to.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/coordinates/index.html b/app/views/static/api/docs/object/coordinates/index.html new file mode 100644 index 0000000000..c63506ee85 --- /dev/null +++ b/app/views/static/api/docs/object/coordinates/index.html @@ -0,0 +1,1090 @@ +

    +Coordinates

    +

    Physical coordinates for a location

    +

    +Fields

    +
    + latitude (Float!) +
    +

    Latitude of this coordinate

    +
    +
    +
    + longitude (Float!) +
    +

    Longitude of this coordinate

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/debate/index.html b/app/views/static/api/docs/object/debate/index.html new file mode 100644 index 0000000000..e7967a0838 --- /dev/null +++ b/app/views/static/api/docs/object/debate/index.html @@ -0,0 +1,1246 @@ +

    +Debate

    +

    A debate

    +

    +Implements

    + +

    +Fields

    +
    + id (ID!) +
    +

    The internal ID for this debate

    +
    +
    +
    + title (TranslatedField) +
    +

    The title for this debate

    +
    +
    +
    + description (TranslatedField) +
    +

    The description for this debate

    +
    +
    +
    + instructions (TranslatedField) +
    +

    The instructions for this debate

    +
    +
    +
    + startTime (DateTime) +
    +

    The start time for this debate

    +
    +
    +
    + endTime (DateTime) +
    +

    The end time for this debate

    +
    +
    +
    + image (String) +
    +

    The image of this debate

    +
    +
    +
    + createdAt (DateTime) +
    +

    When this debate was created

    +
    +
    +
    + updatedAt (DateTime) +
    +

    When this debate was updated

    +
    +
    +
    + informationUpdates (TranslatedField) +
    +

    The information updates for this debate

    +
    +
    +
    + reference (String) +
    +

    The reference for this debate

    +
    +
    +
    + scope (Scope) +
    +

    The object's scope

    +
    +
    +
    + author (Author) +
    +

    The resource author

    +
    +
    +
    + type (String!) +
    +

    The commentable's class name. i.e. Decidim::ParticipatoryProcess

    +
    +
    +
    + acceptsNewComments (Boolean!) +
    +

    Whether the object can have new comments or not

    +
    +
    +
    + commentsHaveAlignment (Boolean!) +
    +

    Whether the object comments have alignment or not

    +
    +
    +
    + commentsHaveVotes (Boolean!) +
    +

    Whether the object comments have votes or not

    +
    +
    +
    + comments ([Comment!]!) +
    + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    orderBy + String + +

    Order the comments

    +
    singleCommentId + String + +

    ID of the single comment to look at

    +
    +
    +
    +
    + totalCommentsCount (Int!) +
    +

    The number of comments in all levels this resource holds

    +
    +
    +
    + hasComments (Boolean!) +
    +

    Check if the commentable has comments

    +
    +
    +
    + userAllowedToComment (Boolean!) +
    +

    Check if the current user can comment

    +
    +
    +
    + category (Category) +
    +

    The object's category

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/debateconnection/index.html b/app/views/static/api/docs/object/debateconnection/index.html new file mode 100644 index 0000000000..928e51ffa2 --- /dev/null +++ b/app/views/static/api/docs/object/debateconnection/index.html @@ -0,0 +1,1096 @@ +

    +DebateConnection

    +

    The connection type for Debate.

    +

    +Fields

    +
    + edges ([DebateEdge]) +
    +

    A list of edges.

    +
    +
    +
    + nodes ([Debate]) +
    +

    A list of nodes.

    +
    +
    +
    + pageInfo (PageInfo!) +
    +

    Information to aid in pagination.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/debateedge/index.html b/app/views/static/api/docs/object/debateedge/index.html new file mode 100644 index 0000000000..611233cec1 --- /dev/null +++ b/app/views/static/api/docs/object/debateedge/index.html @@ -0,0 +1,1090 @@ +

    +DebateEdge

    +

    An edge in a connection.

    +

    +Fields

    +
    + node (Debate) +
    +

    The item at the end of the edge.

    +
    +
    +
    + cursor (String!) +
    +

    A cursor for use in pagination.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/debates/index.html b/app/views/static/api/docs/object/debates/index.html new file mode 100644 index 0000000000..9740376f7a --- /dev/null +++ b/app/views/static/api/docs/object/debates/index.html @@ -0,0 +1,1185 @@ +

    +Debates

    +

    A debates component of a participatory space.

    +

    +Implements

    + +

    +Connections

    +
    + debates (DebateConnection) +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    after + String + +

    Returns the elements in the list that come after the specified cursor.

    +
    before + String + +

    Returns the elements in the list that come before the specified cursor.

    +
    first + Int + +

    Returns the first n elements from the list.

    +
    last + Int + +

    Returns the last n elements from the list.

    +
    +
    +
    +

    +Fields

    +
    + debate (Debate) +
    + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    id + ID! + +
    +
    +
    +
    + id (ID!) +
    +

    The Component's unique ID

    +
    +
    +
    + name (TranslatedField!) +
    +

    The name of this component.

    +
    +
    +
    + weight (Int!) +
    +

    The weight of the component

    +
    +
    +
    + participatorySpace (ParticipatorySpace!) +
    +

    The participatory space in which this component belongs to.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/decidim/index.html b/app/views/static/api/docs/object/decidim/index.html new file mode 100644 index 0000000000..e422def34c --- /dev/null +++ b/app/views/static/api/docs/object/decidim/index.html @@ -0,0 +1,1090 @@ +

    +Decidim

    +

    Decidim's framework-related properties.

    +

    +Fields

    +
    + version (String!) +
    +

    The current decidim's version of this deployment.

    +
    +
    +
    + applicationName (String!) +
    +

    The current installation's name.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/fingerprint/index.html b/app/views/static/api/docs/object/fingerprint/index.html new file mode 100644 index 0000000000..10f091b445 --- /dev/null +++ b/app/views/static/api/docs/object/fingerprint/index.html @@ -0,0 +1,1090 @@ +

    +Fingerprint

    +

    A fingerprint object

    +

    +Fields

    +
    + value (String!) +
    +

    The the hash value for the fingerprint

    +
    +
    +
    + source (String!) +
    +

    Returns the source String (usually a json) from which the fingerprint is generated.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/hashtagtype/index.html b/app/views/static/api/docs/object/hashtagtype/index.html new file mode 100644 index 0000000000..d07c014b9e --- /dev/null +++ b/app/views/static/api/docs/object/hashtagtype/index.html @@ -0,0 +1,1084 @@ +

    +HashtagType

    +

    hashtags list

    +

    +Fields

    +
    + name (String!) +
    +

    The hashtag's name

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/index.html b/app/views/static/api/docs/object/index.html new file mode 100644 index 0000000000..c28dfde872 --- /dev/null +++ b/app/views/static/api/docs/object/index.html @@ -0,0 +1,1077 @@ +

    +Objects

    +

    Objects in GraphQL represent the resources that you can access. Objects can contain a list of fields, which are specifically typed. For example, the Repository object has a field called name, which is a String.

    +

    For more information, see the GraphQL spec.

    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/initiative/index.html b/app/views/static/api/docs/object/initiative/index.html new file mode 100644 index 0000000000..21d9d9820c --- /dev/null +++ b/app/views/static/api/docs/object/initiative/index.html @@ -0,0 +1,1277 @@ +

    +Initiative

    +

    A initiative

    +

    +Implements

    + +

    +Fields

    +
    + description (TranslatedField) +
    +

    The description of this initiative.

    +
    +
    +
    + slug (String!) +
    +
    +
    +
    + hashtag (String) +
    +

    The hashtag for this initiative

    +
    +
    +
    + publishedAt (DateTime!) +
    +

    The time this initiative was published

    +
    +
    +
    + reference (String!) +
    +

    Reference prefix for this initiative

    +
    +
    +
    + state (String) +
    +

    Current status of the initiative

    +
    +
    +
    + signatureType (String) +
    +

    Signature type of the initiative

    +
    +
    +
    + signatureStartDate (Date!) +
    +

    The signature start date

    +
    +
    +
    + signatureEndDate (Date!) +
    +

    The signature end date

    +
    +
    +
    + offlineVotes (Int) +
    +

    The number of offline votes in this initiative

    +
    +
    +
    + onlineVotes (Int) +
    +

    The number of online votes in this initiative

    +
    +
    +
    + initiativeVotesCount (Int) +
    +
    + Deprecation notice +

    initiativeVotesCount has been collapsed in onlineVotes parameter

    +
    +

    The number of votes in this initiative

    +
    +
    +
    + initiativeSupportsCount (Int) +
    +
    + Deprecation notice +

    initiativeSupportsCount has been collapsed in onlineVotes parameter

    +
    +

    The number of supports in this initiative

    +
    +
    +
    + author (Author!) +
    +

    The initiative author

    +
    +
    +
    + committeeMembers ([InitiativeCommitteeMemberType]) +
    +
    +
    +
    + createdAt (DateTime) +
    +

    The date and time this object was created

    +
    +
    +
    + updatedAt (DateTime) +
    +

    The date and time this object was updated

    +
    +
    +
    + initiativeType (InitiativeType) +
    +

    The object's initiative type

    +
    +
    +
    + attachments ([Attachment]!) +
    +

    This object's attachments

    +
    +
    +
    + scope (Scope) +
    +

    The object's scope

    +
    +
    +
    + id (ID!) +
    +

    The participatory space's unique ID

    +
    +
    +
    + title (TranslatedField!) +
    +

    The graphql_name of this participatory space.

    +
    +
    +
    + type (String!) +
    +

    The participatory space class name. i.e. Decidim::ParticipatoryProcess

    +
    +
    +
    + manifest (ParticipatorySpaceManifest!) +
    +

    The manifest information for the participatory space.

    +
    +
    +
    + components ([ComponentInterface!]) +
    +

    Lists the components this space contains.

    + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    filter + ComponentFilter + +

    Provides several methods to filter the results

    +
    order + ComponentSort + +

    Provides several methods to order the results

    +
    +
    +
    +
    + stats ([Statistic]) +
    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/initiativecommitteemembertype/index.html b/app/views/static/api/docs/object/initiativecommitteemembertype/index.html new file mode 100644 index 0000000000..20b0d3b8a4 --- /dev/null +++ b/app/views/static/api/docs/object/initiativecommitteemembertype/index.html @@ -0,0 +1,1108 @@ +

    +InitiativeCommitteeMemberType

    +

    An initiative committee member

    +

    +Fields

    +
    + id (ID!) +
    +

    Internal ID for this member of the committee

    +
    +
    +
    + user (User) +
    +

    The decidim user for this initiative committee member

    +
    +
    +
    + state (String) +
    +

    Type of the committee member

    +
    +
    +
    + createdAt (DateTime) +
    +

    The date this initiative committee member was created

    +
    +
    +
    + updatedAt (DateTime) +
    +

    The date this initiative committee member was updated

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/initiativetype/index.html b/app/views/static/api/docs/object/initiativetype/index.html new file mode 100644 index 0000000000..c64a790fb9 --- /dev/null +++ b/app/views/static/api/docs/object/initiativetype/index.html @@ -0,0 +1,1162 @@ +

    +InitiativeType

    +

    An initiative type

    +

    +Fields

    +
    + id (ID!) +
    +

    The internal ID for this initiative type

    +
    +
    +
    + title (TranslatedField) +
    +

    Initiative type name

    +
    +
    +
    + description (TranslatedField) +
    +

    This is the initiative type description

    +
    +
    +
    + createdAt (DateTime) +
    +

    The date this initiative type was created

    +
    +
    +
    + updatedAt (DateTime) +
    +

    The date this initiative type was updated

    +
    +
    +
    + bannerImage (String) +
    +

    Banner image

    +
    +
    +
    + collectUserExtraFields (Boolean) +
    +

    Collect participant personal data on signature

    +
    +
    +
    + extraFieldsLegalInformation (String) +
    +

    Legal information about the collection of personal data

    +
    +
    +
    + minimumCommitteeMembers (Int) +
    +

    Minimum of committee members

    +
    +
    +
    + validateSmsCodeOnVotes (Boolean) +
    +

    Add SMS code validation step to signature process

    +
    +
    +
    + undoOnlineSignaturesEnabled (Boolean) +
    +

    Enable participants to undo their online signatures

    +
    +
    +
    + promotingComitteeEnabled (Boolean) +
    +

    If promoting committee is enabled

    +
    +
    +
    + signatureType (String) +
    +

    Signature type of the initiative

    +
    +
    +
    + initiatives ([Initiative]!) +
    +

    The initiatives that have this type

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/localizedcustomfields/index.html b/app/views/static/api/docs/object/localizedcustomfields/index.html new file mode 100644 index 0000000000..b6fa8b6aef --- /dev/null +++ b/app/views/static/api/docs/object/localizedcustomfields/index.html @@ -0,0 +1,1096 @@ +

    +LocalizedCustomFields

    +

    Represents a particular translation of a LocalizedCustomFieldsType

    +

    +Fields

    +
    + locale (String!) +
    +

    The standard locale of this translation.

    +
    +
    +
    + fields (JSON) +
    +

    The fields of this translation.

    +
    +
    +
    + machineTranslated (Boolean!) +
    +

    Whether this string is machine translated or not.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/localizedstring/index.html b/app/views/static/api/docs/object/localizedstring/index.html new file mode 100644 index 0000000000..c9ca11edd5 --- /dev/null +++ b/app/views/static/api/docs/object/localizedstring/index.html @@ -0,0 +1,1096 @@ +

    +LocalizedString

    +

    Represents a particular translation of a LocalizedStringType

    +

    +Fields

    +
    + locale (String!) +
    +

    The standard locale of this translation.

    +
    +
    +
    + text (String) +
    +

    The content of this translation.

    +
    +
    +
    + machineTranslated (Boolean!) +
    +

    Whether this string is machine translated or not.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/meeting/index.html b/app/views/static/api/docs/object/meeting/index.html new file mode 100644 index 0000000000..8bd05e9239 --- /dev/null +++ b/app/views/static/api/docs/object/meeting/index.html @@ -0,0 +1,1389 @@ +

    +Meeting

    +

    A meeting

    +

    +Implements

    + +

    +Fields

    +
    + id (ID!) +
    +

    ID of this meeting

    +
    +
    +
    + reference (String!) +
    +

    Reference for this meeting

    +
    +
    +
    + title (TranslatedField!) +
    +

    The title of this meeting.

    +
    +
    +
    + description (TranslatedField) +
    +

    The description of this meeting.

    +
    +
    +
    + startTime (DateTime!) +
    +

    The time this meeting starts

    +
    +
    +
    + endTime (DateTime!) +
    +

    The time this meeting ends

    +
    +
    +
    + agenda (MeetingAgenda) +
    +

    Agenda for this meeting, if available

    +
    +
    +
    + closed (Boolean!) +
    +

    Whether this meeting is closed or not.

    +
    +
    +
    + isWithdrawn (Boolean!) +
    +

    Whether this meeting is withdrawn or not.

    +
    +
    +
    + closingReport (TranslatedField) +
    +

    The closing report of this meeting.

    +
    +
    +
    + videoUrl (String) +
    +

    URL for the video of the session, if any

    +
    +
    +
    + audioUrl (String) +
    +

    URL for the audio of the session, if any

    +
    +
    +
    + createdAt (DateTime) +
    +

    The date and time this minutes was created

    +
    +
    +
    + updatedAt (DateTime) +
    +

    The date and time this minutes was updated

    +
    +
    +
    + attendingOrganizations (String) +
    +

    list of attending organizations

    +
    +
    +
    + attendeeCount (Int) +
    +

    Amount of attendees to this meeting

    +
    +
    +
    + contributionCount (Int) +
    +

    Amount of contributions to this meeting

    +
    +
    +
    + privateMeeting (Boolean!) +
    +

    Whether the meeting is private or not (it can only be true if transparent)

    +
    +
    +
    + transparent (Boolean!) +
    +

    For private meetings, information is public if transparent

    +
    +
    +
    + registrationsEnabled (Boolean!) +
    +

    Whether the registrations are enabled or not

    +
    +
    +
    + registrationTerms (TranslatedField) +
    +

    The registration terms

    +
    +
    +
    + remainingSlots (Int) +
    +

    Amount of slots available for this meeting

    +
    +
    +
    + registrationFormEnabled (Boolean!) +
    +

    Whether the registrations have a form or not

    +
    +
    +
    + registrationForm (Questionnaire) +
    +

    If registration requires to fill a form, this is the questionnaire

    +
    +
    +
    + location (TranslatedField) +
    +

    The location of this meeting (free format)

    +
    +
    +
    + locationHints (TranslatedField) +
    +

    The location of this meeting (free format)

    +
    +
    +
    + address (String) +
    +

    The physical address of this meeting (used for geolocation)

    +
    +
    +
    + coordinates (Coordinates) +
    +

    Physical coordinates for this meeting

    +
    +
    +
    + typeOfMeeting (String!) +
    +

    The type of the meeting (online or in-person)

    +
    +
    +
    + onlineMeetingUrl (String!) +
    +

    The URL of the meeting (when the type is online)

    +
    +
    +
    + iframeEmbedType (String) +
    +

    The type of displaying of the online meeting URL

    +
    +
    +
    + proposalsFromMeeting ([Proposal]!) +
    +

    Proposals created in this meeting

    +
    +
    +
    + services ([MeetingService]!) +
    +

    The object's services

    +
    +
    +
    + attachments ([Attachment]!) +
    +

    This object's attachments

    +
    +
    +
    + scope (Scope) +
    +

    The object's scope

    +
    +
    +
    + category (Category) +
    +

    The object's category

    +
    +
    +
    + author (Author) +
    +

    The resource author

    +
    +
    +
    + type (String!) +
    +

    The commentable's class name. i.e. Decidim::ParticipatoryProcess

    +
    +
    +
    + acceptsNewComments (Boolean!) +
    +

    Whether the object can have new comments or not

    +
    +
    +
    + commentsHaveAlignment (Boolean!) +
    +

    Whether the object comments have alignment or not

    +
    +
    +
    + commentsHaveVotes (Boolean!) +
    +

    Whether the object comments have votes or not

    +
    +
    +
    + comments ([Comment!]!) +
    + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    orderBy + String + +

    Order the comments

    +
    singleCommentId + String + +

    ID of the single comment to look at

    +
    +
    +
    +
    + totalCommentsCount (Int!) +
    +

    The number of comments in all levels this resource holds

    +
    +
    +
    + hasComments (Boolean!) +
    +

    Check if the commentable has comments

    +
    +
    +
    + userAllowedToComment (Boolean!) +
    +

    Check if the current user can comment

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/meetingagenda/index.html b/app/views/static/api/docs/object/meetingagenda/index.html new file mode 100644 index 0000000000..abc53922b4 --- /dev/null +++ b/app/views/static/api/docs/object/meetingagenda/index.html @@ -0,0 +1,1108 @@ +

    +MeetingAgenda

    +

    A meeting agenda

    +

    +Fields

    +
    + id (ID!) +
    +

    The ID for the agenda

    +
    +
    +
    + title (TranslatedField) +
    +

    The title for the agenda

    +
    +
    +
    + items ([MeetingAgendaItem]!) +
    +

    Items and sub-items of the agenda

    +
    +
    +
    + createdAt (DateTime) +
    +

    The date and time this agenda was created

    +
    +
    +
    + updatedAt (DateTime) +
    +

    The date and time this agenda was updated

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/meetingagendaitem/index.html b/app/views/static/api/docs/object/meetingagendaitem/index.html new file mode 100644 index 0000000000..fa9ae9fa8e --- /dev/null +++ b/app/views/static/api/docs/object/meetingagendaitem/index.html @@ -0,0 +1,1138 @@ +

    +MeetingAgendaItem

    +

    A meeting agenda item

    +

    +Fields

    +
    + id (ID!) +
    +

    The ID for this agenda item

    +
    +
    +
    + title (TranslatedField) +
    +

    The title for this agenda item

    +
    +
    +
    + description (TranslatedField) +
    +

    The description for this agenda item

    +
    +
    +
    + items ([MeetingAgendaItem]!) +
    +

    Sub-items (children) of this agenda item

    +
    +
    +
    + parent (MeetingAgendaItem) +
    +

    Parent agenda item, if available

    +
    +
    +
    + agenda (MeetingAgenda) +
    +

    Belonging agenda

    +
    +
    +
    + duration (Int!) +
    +

    Duration in number of minutes for this item in this agenda

    +
    +
    +
    + position (Int!) +
    +

    Order position for this agenda item

    +
    +
    +
    + createdAt (DateTime) +
    +

    The date and time this agenda item was created

    +
    +
    +
    + updatedAt (DateTime) +
    +

    The date and time this agenda item was updated

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/meetingconnection/index.html b/app/views/static/api/docs/object/meetingconnection/index.html new file mode 100644 index 0000000000..8e9beed8b3 --- /dev/null +++ b/app/views/static/api/docs/object/meetingconnection/index.html @@ -0,0 +1,1096 @@ +

    +MeetingConnection

    +

    The connection type for Meeting.

    +

    +Fields

    +
    + edges ([MeetingEdge]) +
    +

    A list of edges.

    +
    +
    +
    + nodes ([Meeting]) +
    +

    A list of nodes.

    +
    +
    +
    + pageInfo (PageInfo!) +
    +

    Information to aid in pagination.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/meetingedge/index.html b/app/views/static/api/docs/object/meetingedge/index.html new file mode 100644 index 0000000000..3121855a04 --- /dev/null +++ b/app/views/static/api/docs/object/meetingedge/index.html @@ -0,0 +1,1090 @@ +

    +MeetingEdge

    +

    An edge in a connection.

    +

    +Fields

    +
    + node (Meeting) +
    +

    The item at the end of the edge.

    +
    +
    +
    + cursor (String!) +
    +

    A cursor for use in pagination.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/meetings/index.html b/app/views/static/api/docs/object/meetings/index.html new file mode 100644 index 0000000000..5d0900d718 --- /dev/null +++ b/app/views/static/api/docs/object/meetings/index.html @@ -0,0 +1,1185 @@ +

    +Meetings

    +

    A meetings component of a participatory space.

    +

    +Implements

    + +

    +Connections

    +
    + meetings (MeetingConnection) +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    after + String + +

    Returns the elements in the list that come after the specified cursor.

    +
    before + String + +

    Returns the elements in the list that come before the specified cursor.

    +
    first + Int + +

    Returns the first n elements from the list.

    +
    last + Int + +

    Returns the last n elements from the list.

    +
    +
    +
    +

    +Fields

    +
    + meeting (Meeting) +
    + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    id + ID! + +
    +
    +
    +
    + id (ID!) +
    +

    The Component's unique ID

    +
    +
    +
    + name (TranslatedField!) +
    +

    The name of this component.

    +
    +
    +
    + weight (Int!) +
    +

    The weight of the component

    +
    +
    +
    + participatorySpace (ParticipatorySpace!) +
    +

    The participatory space in which this component belongs to.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/meetingservice/index.html b/app/views/static/api/docs/object/meetingservice/index.html new file mode 100644 index 0000000000..61dd9fcc5e --- /dev/null +++ b/app/views/static/api/docs/object/meetingservice/index.html @@ -0,0 +1,1090 @@ +

    +MeetingService

    +

    A meeting service

    +

    +Fields

    +
    + title (TranslatedField) +
    +

    The title for the service

    +
    +
    +
    + description (TranslatedField) +
    +

    The description for the service

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/metric/index.html b/app/views/static/api/docs/object/metric/index.html new file mode 100644 index 0000000000..fd4e46caea --- /dev/null +++ b/app/views/static/api/docs/object/metric/index.html @@ -0,0 +1,1096 @@ +

    +Metric

    +

    Metric data

    +

    +Fields

    +
    + name (String!) +
    +

    The graphql_name of the metric

    +
    +
    +
    + count (Int!) +
    +

    The last value of the metric

    +
    +
    +
    + history ([MetricHistory]!) +
    +

    The historic values for this metric

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/metrichistory/index.html b/app/views/static/api/docs/object/metrichistory/index.html new file mode 100644 index 0000000000..c11494ce65 --- /dev/null +++ b/app/views/static/api/docs/object/metrichistory/index.html @@ -0,0 +1,1089 @@ +

    +MetricHistory

    +

    +Fields

    +
    + key (String!) +
    +

    The key value

    +
    +
    +
    + value (Int!) +
    +

    The value for each key

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/organization/index.html b/app/views/static/api/docs/object/organization/index.html new file mode 100644 index 0000000000..e458a08864 --- /dev/null +++ b/app/views/static/api/docs/object/organization/index.html @@ -0,0 +1,1090 @@ +

    +Organization

    +

    The current organization

    +

    +Fields

    +
    + name (String) +
    +

    The name of the current organization

    +
    +
    +
    + stats ([Statistic]) +
    +

    The statistics associated to this object

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/page/index.html b/app/views/static/api/docs/object/page/index.html new file mode 100644 index 0000000000..c610146cea --- /dev/null +++ b/app/views/static/api/docs/object/page/index.html @@ -0,0 +1,1107 @@ +

    +Page

    +

    A page

    +

    +Fields

    +
    + id (ID!) +
    +
    +
    +
    + title (TranslatedField!) +
    +

    The title of this page (same as the component name).

    +
    +
    +
    + body (TranslatedField) +
    +

    The body of this page.

    +
    +
    +
    + createdAt (DateTime!) +
    +

    The time this page was created

    +
    +
    +
    + updatedAt (DateTime!) +
    +

    The time this page was updated

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/pageconnection/index.html b/app/views/static/api/docs/object/pageconnection/index.html new file mode 100644 index 0000000000..80179140a7 --- /dev/null +++ b/app/views/static/api/docs/object/pageconnection/index.html @@ -0,0 +1,1096 @@ +

    +PageConnection

    +

    The connection type for Page.

    +

    +Fields

    +
    + edges ([PageEdge]) +
    +

    A list of edges.

    +
    +
    +
    + nodes ([Page]) +
    +

    A list of nodes.

    +
    +
    +
    + pageInfo (PageInfo!) +
    +

    Information to aid in pagination.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/pageedge/index.html b/app/views/static/api/docs/object/pageedge/index.html new file mode 100644 index 0000000000..e3e408a061 --- /dev/null +++ b/app/views/static/api/docs/object/pageedge/index.html @@ -0,0 +1,1090 @@ +

    +PageEdge

    +

    An edge in a connection.

    +

    +Fields

    +
    + node (Page) +
    +

    The item at the end of the edge.

    +
    +
    +
    + cursor (String!) +
    +

    A cursor for use in pagination.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/pageinfo/index.html b/app/views/static/api/docs/object/pageinfo/index.html new file mode 100644 index 0000000000..1ebe97ff2c --- /dev/null +++ b/app/views/static/api/docs/object/pageinfo/index.html @@ -0,0 +1,1102 @@ +

    +PageInfo

    +

    Information about pagination in a connection.

    +

    +Fields

    +
    + hasNextPage (Boolean!) +
    +

    When paginating forwards, are there more items?

    +
    +
    +
    + hasPreviousPage (Boolean!) +
    +

    When paginating backwards, are there more items?

    +
    +
    +
    + startCursor (String) +
    +

    When paginating backwards, the cursor to continue.

    +
    +
    +
    + endCursor (String) +
    +

    When paginating forwards, the cursor to continue.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/pages/index.html b/app/views/static/api/docs/object/pages/index.html new file mode 100644 index 0000000000..c6276c00ff --- /dev/null +++ b/app/views/static/api/docs/object/pages/index.html @@ -0,0 +1,1185 @@ +

    +Pages

    +

    A pages component of a participatory space.

    +

    +Implements

    + +

    +Connections

    +
    + pages (PageConnection) +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    after + String + +

    Returns the elements in the list that come after the specified cursor.

    +
    before + String + +

    Returns the elements in the list that come before the specified cursor.

    +
    first + Int + +

    Returns the first n elements from the list.

    +
    last + Int + +

    Returns the last n elements from the list.

    +
    +
    +
    +

    +Fields

    +
    + page (Page) +
    + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    id + ID! + +
    +
    +
    +
    + id (ID!) +
    +

    The Component's unique ID

    +
    +
    +
    + name (TranslatedField!) +
    +

    The name of this component.

    +
    +
    +
    + weight (Int!) +
    +

    The weight of the component

    +
    +
    +
    + participatorySpace (ParticipatorySpace!) +
    +

    The participatory space in which this component belongs to.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/participatoryprocess/index.html b/app/views/static/api/docs/object/participatoryprocess/index.html new file mode 100644 index 0000000000..39a272f8a6 --- /dev/null +++ b/app/views/static/api/docs/object/participatoryprocess/index.html @@ -0,0 +1,1350 @@ +

    +ParticipatoryProcess

    +

    A participatory process

    +

    +Implements

    + +

    +Fields

    +
    + id (ID!) +
    +

    The internal ID for this participatory process

    +
    +
    +
    + slug (String!) +
    +
    +
    +
    + hashtag (String) +
    +

    The hashtag for this participatory process

    +
    +
    +
    + createdAt (DateTime!) +
    +

    The time this page was created

    +
    +
    +
    + updatedAt (DateTime!) +
    +

    The time this page was updated

    +
    +
    +
    + publishedAt (DateTime!) +
    +

    The time this page was published

    +
    +
    +
    + subtitle (TranslatedField) +
    +

    The subtitle of this participatory process.

    +
    +
    +
    + description (TranslatedField) +
    +

    The description of this participatory process.

    +
    +
    +
    + shortDescription (TranslatedField) +
    +

    The short description of this participatory process.

    +
    +
    +
    + startDate (Date) +
    +

    This participatory process' start date.

    +
    +
    +
    + endDate (Date) +
    +

    This participatory process' end date.

    +
    +
    +
    + bannerImage (String) +
    +

    The banner image for this participatory process

    +
    +
    +
    + heroImage (String) +
    +

    The hero image for this participatory process

    +
    +
    +
    + +
    +

    If this participatory process is promoted (therefore in the homepage)

    +
    +
    +
    + developerGroup (TranslatedField) +
    +

    The promoter group of this participatory process.

    +
    +
    +
    + metaScope (TranslatedField) +
    +

    The scope metadata of this participatory process.

    +
    +
    +
    + localArea (TranslatedField) +
    +

    The organization area of this participatory process.

    +
    +
    +
    + target (TranslatedField) +
    +

    Who participates in this participatory process.

    +
    +
    +
    + participatoryScope (TranslatedField) +
    +

    What is decided on this participatory process.

    +
    +
    +
    + participatoryStructure (TranslatedField) +
    +

    How it is decided on this participatory process.

    +
    +
    +
    + showMetrics (Boolean) +
    +

    If this participatory process should show metrics

    +
    +
    +
    + showStatistics (Boolean) +
    +

    If this participatory process should show statistics

    +
    +
    +
    + scopesEnabled (Boolean) +
    +

    If this participatory process has scopes enabled

    +
    +
    +
    + announcement (TranslatedField) +
    +

    Highlighted announcement for this participatory process.

    +
    +
    +
    + reference (String) +
    +

    Reference prefix for this participatory process

    +
    +
    +
    + steps ([ParticipatoryProcessStep]!) +
    +

    All the steps of this process.

    +
    +
    +
    + participatoryProcessGroup (ParticipatoryProcessGroup) +
    +

    The participatory process group in which this process belong to

    +
    +
    +
    + categories ([Category]!) +
    +

    Categories for this space

    + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    filter + CategoryFilter + +

    Provides several methods to filter the results

    +
    +
    +
    +
    + attachments ([Attachment]!) +
    +

    This object's attachments

    +
    +
    +
    + scope (Scope) +
    +

    The object's scope

    +
    +
    +
    + linkedParticipatorySpaces ([ParticipatorySpaceLink!]!) +
    +

    Lists all linked participatory spaces in a polymorphic way

    +
    +
    +
    + title (TranslatedField!) +
    +

    The graphql_name of this participatory space.

    +
    +
    +
    + type (String!) +
    +

    The participatory space class name. i.e. Decidim::ParticipatoryProcess

    +
    +
    +
    + manifest (ParticipatorySpaceManifest!) +
    +

    The manifest information for the participatory space.

    +
    +
    +
    + components ([ComponentInterface!]) +
    +

    Lists the components this space contains.

    + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    filter + ComponentFilter + +

    Provides several methods to filter the results

    +
    order + ComponentSort + +

    Provides several methods to order the results

    +
    +
    +
    +
    + stats ([Statistic]) +
    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/participatoryprocessgroup/index.html b/app/views/static/api/docs/object/participatoryprocessgroup/index.html new file mode 100644 index 0000000000..37629467fd --- /dev/null +++ b/app/views/static/api/docs/object/participatoryprocessgroup/index.html @@ -0,0 +1,1108 @@ +

    +ParticipatoryProcessGroup

    +

    A participatory process group

    +

    +Fields

    +
    + id (ID!) +
    +

    ID of this participatory process group

    +
    +
    +
    + title (TranslatedField) +
    +

    The title of this participatory process group

    +
    +
    +
    + description (TranslatedField) +
    +

    The description of this participatory process group

    +
    +
    +
    + participatoryProcesses ([ParticipatoryProcess]!) +
    +

    Lists all the participatory processes belonging to this group

    +
    +
    +
    + heroImage (String) +
    +

    The hero image for this participatory process group

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/participatoryprocessstep/index.html b/app/views/static/api/docs/object/participatoryprocessstep/index.html new file mode 100644 index 0000000000..67868f9d8c --- /dev/null +++ b/app/views/static/api/docs/object/participatoryprocessstep/index.html @@ -0,0 +1,1138 @@ +

    +ParticipatoryProcessStep

    +

    A participatory process step

    +

    +Fields

    +
    + id (ID!) +
    +

    The unique ID of this step.

    +
    +
    +
    + participatoryProcess (ParticipatoryProcess!) +
    +

    The participatory process in which this step belongs to.

    +
    +
    +
    + title (TranslatedField!) +
    +

    The title of this step

    +
    +
    +
    + description (TranslatedField) +
    +

    The description of this step

    +
    +
    +
    + startDate (DateTime) +
    +

    This step's start date

    +
    +
    +
    + endDate (DateTime) +
    +

    This step's end date

    +
    +
    +
    + callToActionPath (String) +
    +

    A call to action URL for this step

    +
    +
    +
    + callToActionText (TranslatedField) +
    +

    The call to action text for this step

    +
    +
    +
    + active (Boolean) +
    +

    If this step is the active one

    +
    +
    +
    + position (Int) +
    +

    Ordering position among all the steps

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/participatoryprocesstype/index.html b/app/views/static/api/docs/object/participatoryprocesstype/index.html new file mode 100644 index 0000000000..f9c06959a4 --- /dev/null +++ b/app/views/static/api/docs/object/participatoryprocesstype/index.html @@ -0,0 +1,1108 @@ +

    +ParticipatoryProcessType

    +

    A participatory process type

    +

    +Fields

    +
    + id (ID!) +
    +

    Unique ID of this participatory process type

    +
    +
    +
    + title (TranslatedField) +
    +

    The title of this participatory process type

    +
    +
    +
    + createdAt (DateTime!) +
    +

    The time this participatory process type was created

    +
    +
    +
    + updatedAt (DateTime!) +
    +

    The time this participatory process type was updated

    +
    +
    +
    + processes ([ParticipatoryProcess]!) +
    +

    Lists all the participatory processes belonging to this type

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/participatoryspace/index.html b/app/views/static/api/docs/object/participatoryspace/index.html new file mode 100644 index 0000000000..cff697c30b --- /dev/null +++ b/app/views/static/api/docs/object/participatoryspace/index.html @@ -0,0 +1,1147 @@ +

    +ParticipatorySpace

    +

    A participatory space

    +

    +Implements

    + +

    +Fields

    +
    + id (ID!) +
    +

    The participatory space's unique ID

    +
    +
    +
    + title (TranslatedField!) +
    +

    The graphql_name of this participatory space.

    +
    +
    +
    + type (String!) +
    +

    The participatory space class name. i.e. Decidim::ParticipatoryProcess

    +
    +
    +
    + manifest (ParticipatorySpaceManifest!) +
    +

    The manifest information for the participatory space.

    +
    +
    +
    + components ([ComponentInterface!]) +
    +

    Lists the components this space contains.

    + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    filter + ComponentFilter + +

    Provides several methods to filter the results

    +
    order + ComponentSort + +

    Provides several methods to order the results

    +
    +
    +
    +
    + stats ([Statistic]) +
    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/participatoryspacelink/index.html b/app/views/static/api/docs/object/participatoryspacelink/index.html new file mode 100644 index 0000000000..ac9cb8fdae --- /dev/null +++ b/app/views/static/api/docs/object/participatoryspacelink/index.html @@ -0,0 +1,1108 @@ +

    +ParticipatorySpaceLink

    +

    A link representation between participatory spaces

    +

    +Fields

    +
    + id (ID!) +
    +

    The id of this participatory space link

    +
    +
    +
    + fromType (String!) +
    +

    The origin participatory space type for this participatory space link

    +
    +
    +
    + toType (String!) +
    +

    The destination participatory space type for this participatory space link

    +
    +
    +
    + name (String!) +
    +

    The name (purpose) of this participatory space link

    +
    +
    +
    + participatorySpace (ParticipatorySpaceInterface!) +
    +

    The linked participatory space (polymorphic)

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/participatoryspacemanifest/index.html b/app/views/static/api/docs/object/participatoryspacemanifest/index.html new file mode 100644 index 0000000000..2c814fb025 --- /dev/null +++ b/app/views/static/api/docs/object/participatoryspacemanifest/index.html @@ -0,0 +1,1090 @@ +

    +ParticipatorySpaceManifest

    +

    A participatory manifest

    +

    +Fields

    +
    + name (String!) +
    +

    The name of the manifest

    +
    +
    +
    + humanName (QuantifiableTranslatedField!) +
    +

    The human readable name for the manifest

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/post/index.html b/app/views/static/api/docs/object/post/index.html new file mode 100644 index 0000000000..92b189cb57 --- /dev/null +++ b/app/views/static/api/docs/object/post/index.html @@ -0,0 +1,1236 @@ +

    +Post

    +

    A post

    +

    +Implements

    + +

    +Fields

    +
    + id (ID!) +
    +

    The internal ID of this post

    +
    +
    +
    + title (TranslatedField) +
    +

    The title for this post

    +
    +
    +
    + body (TranslatedField) +
    +

    The body of this post

    +
    +
    +
    + publishedAt (DateTime!) +
    +

    The time this page was published

    +
    +
    +
    + createdAt (DateTime) +
    +

    The date and time this object was created

    +
    +
    +
    + updatedAt (DateTime) +
    +

    The date and time this object was updated

    +
    +
    +
    + endorsements ([Author]!) +
    +

    The endorsements of this object.

    +
    +
    +
    + endorsementsCount (Int) +
    +

    The total amount of endorsements the object has received

    +
    +
    +
    + versionsCount (Int!) +
    +

    Total number of versions

    +
    +
    +
    + versions ([TraceVersion]!) +
    +

    This object's versions

    +
    +
    +
    + author (Author) +
    +

    The resource author

    +
    +
    +
    + attachments ([Attachment]!) +
    +

    This object's attachments

    +
    +
    +
    + type (String!) +
    +

    The commentable's class name. i.e. Decidim::ParticipatoryProcess

    +
    +
    +
    + acceptsNewComments (Boolean!) +
    +

    Whether the object can have new comments or not

    +
    +
    +
    + commentsHaveAlignment (Boolean!) +
    +

    Whether the object comments have alignment or not

    +
    +
    +
    + commentsHaveVotes (Boolean!) +
    +

    Whether the object comments have votes or not

    +
    +
    +
    + comments ([Comment!]!) +
    + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    orderBy + String + +

    Order the comments

    +
    singleCommentId + String + +

    ID of the single comment to look at

    +
    +
    +
    +
    + totalCommentsCount (Int!) +
    +

    The number of comments in all levels this resource holds

    +
    +
    +
    + hasComments (Boolean!) +
    +

    Check if the commentable has comments

    +
    +
    +
    + userAllowedToComment (Boolean!) +
    +

    Check if the current user can comment

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/postconnection/index.html b/app/views/static/api/docs/object/postconnection/index.html new file mode 100644 index 0000000000..243c710e19 --- /dev/null +++ b/app/views/static/api/docs/object/postconnection/index.html @@ -0,0 +1,1096 @@ +

    +PostConnection

    +

    The connection type for Post.

    +

    +Fields

    +
    + edges ([PostEdge]) +
    +

    A list of edges.

    +
    +
    +
    + nodes ([Post]) +
    +

    A list of nodes.

    +
    +
    +
    + pageInfo (PageInfo!) +
    +

    Information to aid in pagination.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/postedge/index.html b/app/views/static/api/docs/object/postedge/index.html new file mode 100644 index 0000000000..da8c20ec67 --- /dev/null +++ b/app/views/static/api/docs/object/postedge/index.html @@ -0,0 +1,1090 @@ +

    +PostEdge

    +

    An edge in a connection.

    +

    +Fields

    +
    + node (Post) +
    +

    The item at the end of the edge.

    +
    +
    +
    + cursor (String!) +
    +

    A cursor for use in pagination.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/project/index.html b/app/views/static/api/docs/object/project/index.html new file mode 100644 index 0000000000..9f3b3451e5 --- /dev/null +++ b/app/views/static/api/docs/object/project/index.html @@ -0,0 +1,1228 @@ +

    +Project

    +

    A project

    +

    +Implements

    + +

    +Fields

    +
    + id (ID!) +
    +

    The internal ID for this project

    +
    +
    +
    + title (TranslatedField) +
    +

    The title for this project

    +
    +
    +
    + description (TranslatedField) +
    +

    The description for this project

    +
    +
    +
    + budget_amount (Int) +
    +

    The budget amount for this project

    +
    +
    +
    + selected (Boolean) +
    +

    Whether this proposal is selected or not

    +
    +
    +
    + createdAt (DateTime) +
    +

    When this project was created

    +
    +
    +
    + updatedAt (DateTime) +
    +

    When this project was updated

    +
    +
    +
    + reference (String) +
    +

    The reference for this project

    +
    +
    +
    + category (Category) +
    +

    The object's category

    +
    +
    +
    + type (String!) +
    +

    The commentable's class name. i.e. Decidim::ParticipatoryProcess

    +
    +
    +
    + acceptsNewComments (Boolean!) +
    +

    Whether the object can have new comments or not

    +
    +
    +
    + commentsHaveAlignment (Boolean!) +
    +

    Whether the object comments have alignment or not

    +
    +
    +
    + commentsHaveVotes (Boolean!) +
    +

    Whether the object comments have votes or not

    +
    +
    +
    + comments ([Comment!]!) +
    + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    orderBy + String + +

    Order the comments

    +
    singleCommentId + String + +

    ID of the single comment to look at

    +
    +
    +
    +
    + totalCommentsCount (Int!) +
    +

    The number of comments in all levels this resource holds

    +
    +
    +
    + hasComments (Boolean!) +
    +

    Check if the commentable has comments

    +
    +
    +
    + userAllowedToComment (Boolean!) +
    +

    Check if the current user can comment

    +
    +
    +
    + attachments ([Attachment]!) +
    +

    This object's attachments

    +
    +
    +
    + scope (Scope) +
    +

    The object's scope

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/proposal/index.html b/app/views/static/api/docs/object/proposal/index.html new file mode 100644 index 0000000000..bfab716f02 --- /dev/null +++ b/app/views/static/api/docs/object/proposal/index.html @@ -0,0 +1,1372 @@ +

    +Proposal

    +

    A proposal

    +

    +Implements

    + +

    +Fields

    +
    + id (ID!) +
    +
    +
    +
    + title (TranslatedField) +
    +

    The title for this title

    +
    +
    +
    + body (TranslatedField) +
    +

    The description for this body

    +
    +
    +
    + address (String) +
    +

    The physical address (location) of this proposal

    +
    +
    +
    + coordinates (Coordinates) +
    +

    Physical coordinates for this proposal

    +
    +
    +
    + reference (String) +
    +

    This proposal's unique reference

    +
    +
    +
    + state (String) +
    +

    The answer status in which proposal is in

    +
    +
    +
    + answer (TranslatedField) +
    +

    The answer feedback for the status for this proposal

    +
    +
    +
    + answeredAt (DateTime) +
    +

    The date and time this proposal was answered

    +
    +
    +
    + publishedAt (DateTime) +
    +

    The date and time this proposal was published

    +
    +
    +
    + participatoryTextLevel (String) +
    +

    If it is a participatory text, the level indicates the type of paragraph

    +
    +
    +
    + position (Int) +
    +

    Position of this proposal in the participatory text

    +
    +
    +
    + official (Boolean) +
    +

    Whether this proposal is official or not

    +
    +
    +
    + createdInMeeting (Boolean) +
    +

    Whether this proposal comes from a meeting or not

    +
    +
    +
    + meeting (Meeting) +
    +

    If the proposal comes from a meeting, the related meeting

    +
    +
    +
    + withdrawnAt (DateTime) +
    +

    The date and time this proposal was withdrawn

    +
    +
    +
    + withdrawn (Boolean) +
    +

    Whether this proposal has been withdrawn or not

    +
    +
    +
    + voteCount (Int) +
    +

    The total amount of votes the proposal has received

    +
    +
    +
    + bodyFields (TranslatedCustomFields) +
    +

    Custom fields for this proposal

    +
    +
    +
    + voteWeights (JSON) +
    +

    The corresponding weights count to the proposal votes

    +
    +
    +
    + createdAt (DateTime) +
    +

    The date and time this object was created

    +
    +
    +
    + updatedAt (DateTime) +
    +

    The date and time this object was updated

    +
    +
    +
    + endorsements ([Author]!) +
    +

    The endorsements of this object.

    +
    +
    +
    + endorsementsCount (Int) +
    +

    The total amount of endorsements the object has received

    +
    +
    +
    + versionsCount (Int!) +
    +

    Total number of versions

    +
    +
    +
    + versions ([TraceVersion]!) +
    +

    This object's versions

    +
    +
    +
    + amendments ([Amendment]!) +
    +

    This object's amendments

    +
    +
    +
    + fingerprint (Fingerprint!) +
    +

    This object's fingerprint

    +
    +
    +
    + attachments ([Attachment]!) +
    +

    This object's attachments

    +
    +
    +
    + scope (Scope) +
    +

    The object's scope

    +
    +
    +
    + category (Category) +
    +

    The object's category

    +
    +
    +
    + authorsCount (Int) +
    +

    The total amount of co-authors that contributed to the entity. Note that this field may include also non-user authors like meetings or the organization

    +
    +
    +
    + author (Author) +
    +

    The resource author. Note that this can be null on official proposals or meeting-proposals

    +
    +
    +
    + authors ([Author]!) +
    +

    The resource co-authors. Include only users or groups of users

    +
    +
    +
    + type (String!) +
    +

    The commentable's class name. i.e. Decidim::ParticipatoryProcess

    +
    +
    +
    + acceptsNewComments (Boolean!) +
    +

    Whether the object can have new comments or not

    +
    +
    +
    + commentsHaveAlignment (Boolean!) +
    +

    Whether the object comments have alignment or not

    +
    +
    +
    + commentsHaveVotes (Boolean!) +
    +

    Whether the object comments have votes or not

    +
    +
    +
    + comments ([Comment!]!) +
    + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    orderBy + String + +

    Order the comments

    +
    singleCommentId + String + +

    ID of the single comment to look at

    +
    +
    +
    +
    + totalCommentsCount (Int!) +
    +

    The number of comments in all levels this resource holds

    +
    +
    +
    + hasComments (Boolean!) +
    +

    Check if the commentable has comments

    +
    +
    +
    + userAllowedToComment (Boolean!) +
    +

    Check if the current user can comment

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/proposalconnection/index.html b/app/views/static/api/docs/object/proposalconnection/index.html new file mode 100644 index 0000000000..5ea70ba285 --- /dev/null +++ b/app/views/static/api/docs/object/proposalconnection/index.html @@ -0,0 +1,1096 @@ +

    +ProposalConnection

    +

    The connection type for Proposal.

    +

    +Fields

    +
    + edges ([ProposalEdge]) +
    +

    A list of edges.

    +
    +
    +
    + nodes ([Proposal]) +
    +

    A list of nodes.

    +
    +
    +
    + pageInfo (PageInfo!) +
    +

    Information to aid in pagination.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/proposaledge/index.html b/app/views/static/api/docs/object/proposaledge/index.html new file mode 100644 index 0000000000..40462c60e7 --- /dev/null +++ b/app/views/static/api/docs/object/proposaledge/index.html @@ -0,0 +1,1090 @@ +

    +ProposalEdge

    +

    An edge in a connection.

    +

    +Fields

    +
    + node (Proposal) +
    +

    The item at the end of the edge.

    +
    +
    +
    + cursor (String!) +
    +

    A cursor for use in pagination.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/proposals/index.html b/app/views/static/api/docs/object/proposals/index.html new file mode 100644 index 0000000000..154a3e6aa1 --- /dev/null +++ b/app/views/static/api/docs/object/proposals/index.html @@ -0,0 +1,1206 @@ +

    +Proposals

    +

    A proposals component of a participatory space.

    +

    +Implements

    + +

    +Connections

    +
    + proposals (ProposalConnection) +
    +

    List all proposals

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    after + String + +

    Returns the elements in the list that come after the specified cursor.

    +
    before + String + +

    Returns the elements in the list that come before the specified cursor.

    +
    first + Int + +

    Returns the first n elements from the list.

    +
    last + Int + +

    Returns the last n elements from the list.

    +
    order + ProposalSort + +

    Provides several methods to order the results

    +
    filter + ProposalFilter + +

    Provides several methods to filter the results

    +
    +
    +
    +

    +Fields

    +
    + proposal (Proposal) +
    +

    Finds one proposal

    + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    id + ID! + +

    The ID of the proposal

    +
    +
    +
    +
    + id (ID!) +
    +

    The Component's unique ID

    +
    +
    +
    + name (TranslatedField!) +
    +

    The name of this component.

    +
    +
    +
    + weight (Int!) +
    +

    The weight of the component

    +
    +
    +
    + participatorySpace (ParticipatorySpace!) +
    +

    The participatory space in which this component belongs to.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/quantifiabletranslatedfield/index.html b/app/views/static/api/docs/object/quantifiabletranslatedfield/index.html new file mode 100644 index 0000000000..47a4dd1394 --- /dev/null +++ b/app/views/static/api/docs/object/quantifiabletranslatedfield/index.html @@ -0,0 +1,1090 @@ +

    +QuantifiableTranslatedField

    +

    A quantifiable translated field with singular and plural formats

    +

    +Fields

    +
    + single (TranslatedField!) +
    +

    The singular format.

    +
    +
    +
    + plural (TranslatedField!) +
    +

    The plural format.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/question/index.html b/app/views/static/api/docs/object/question/index.html new file mode 100644 index 0000000000..487bcbdbad --- /dev/null +++ b/app/views/static/api/docs/object/question/index.html @@ -0,0 +1,1149 @@ +

    +Question

    +

    A question in a questionnaire

    +

    +Implements

    + +

    +Fields

    +
    + id (ID!) +
    +

    ID of this question

    +
    +
    +
    + body (TranslatedField!) +
    +

    What is being asked in this question.

    +
    +
    +
    + description (TranslatedField) +
    +

    The description of this question.

    +
    +
    +
    + mandatory (Boolean!) +
    +

    Whether if this question is mandatory.

    +
    +
    +
    + position (Int) +
    +

    Order position of the question in the questionnaire

    +
    +
    +
    + maxChoices (Int) +
    +

    On questions with answer options, maximum number of choices the user has

    +
    +
    +
    + maxCharacters (Int!) +
    +

    On questions with free text answers, maximum number of characters the answer can have (0 if no limit)

    +
    +
    +
    + questionType (String) +
    +

    Type of question.

    +
    +
    +
    + answerOptions ([AnswerOption]!) +
    +

    List of answer options in multi-choice questions.

    +
    +
    +
    + createdAt (DateTime) +
    +

    The date and time this object was created

    +
    +
    +
    + updatedAt (DateTime) +
    +

    The date and time this object was updated

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/questionnaire/index.html b/app/views/static/api/docs/object/questionnaire/index.html new file mode 100644 index 0000000000..18180c3734 --- /dev/null +++ b/app/views/static/api/docs/object/questionnaire/index.html @@ -0,0 +1,1137 @@ +

    +Questionnaire

    +

    A questionnaire

    +

    +Implements

    + +

    +Fields

    +
    + id (ID!) +
    +

    ID of this questionnaire

    +
    +
    +
    + title (TranslatedField!) +
    +

    The title of this questionnaire.

    +
    +
    +
    + description (TranslatedField) +
    +

    The description of this questionnaire.

    +
    +
    +
    + tos (TranslatedField) +
    +

    The Terms of Service for this questionnaire.

    +
    +
    +
    + forType (String) +
    +

    Type of entity using this questionnaire.

    +
    +
    +
    + forEntity (QuestionnaireEntityInterface) +
    +

    Entity using this questionnaire.

    +
    +
    +
    + questions ([Question]!) +
    +

    Questions in this questionnaire.

    +
    +
    +
    + createdAt (DateTime) +
    +

    The date and time this object was created

    +
    +
    +
    + updatedAt (DateTime) +
    +

    The date and time this object was updated

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/result/index.html b/app/views/static/api/docs/object/result/index.html new file mode 100644 index 0000000000..011380aa45 --- /dev/null +++ b/app/views/static/api/docs/object/result/index.html @@ -0,0 +1,1269 @@ +

    +Result

    +

    A result

    +

    +Implements

    + +

    +Fields

    +
    + id (ID!) +
    +

    The internal ID for this result

    +
    +
    +
    + title (TranslatedField) +
    +

    The title for this result

    +
    +
    +
    + description (TranslatedField) +
    +

    The description for this result

    +
    +
    +
    + reference (String) +
    +

    The reference for this result

    +
    +
    +
    + startDate (Date) +
    +

    The start date for this result

    +
    +
    +
    + endDate (Date) +
    +

    The end date for this result

    +
    +
    +
    + progress (Float) +
    +

    The progress for this result

    +
    +
    +
    + createdAt (DateTime) +
    +

    When this result was created

    +
    +
    +
    + updatedAt (DateTime) +
    +

    When this result was updated

    +
    +
    +
    + childrenCount (Int) +
    +

    The number of children results

    +
    +
    +
    + weight (Int!) +
    +

    The order of this result

    +
    +
    +
    + externalId (String) +
    +

    The external ID for this result

    +
    +
    +
    + children ([Result]) +
    +

    The childrens results

    +
    +
    +
    + parent (Result) +
    +

    The parent result

    +
    +
    +
    + status (Status) +
    +

    The status for this result

    +
    +
    +
    + timelineEntries ([TimelineEntry]) +
    +

    The timeline entries for this result

    +
    +
    +
    + scope (Scope) +
    +

    The object's scope

    +
    +
    +
    + type (String!) +
    +

    The commentable's class name. i.e. Decidim::ParticipatoryProcess

    +
    +
    +
    + acceptsNewComments (Boolean!) +
    +

    Whether the object can have new comments or not

    +
    +
    +
    + commentsHaveAlignment (Boolean!) +
    +

    Whether the object comments have alignment or not

    +
    +
    +
    + commentsHaveVotes (Boolean!) +
    +

    Whether the object comments have votes or not

    +
    +
    +
    + comments ([Comment!]!) +
    + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    orderBy + String + +

    Order the comments

    +
    singleCommentId + String + +

    ID of the single comment to look at

    +
    +
    +
    +
    + totalCommentsCount (Int!) +
    +

    The number of comments in all levels this resource holds

    +
    +
    +
    + hasComments (Boolean!) +
    +

    Check if the commentable has comments

    +
    +
    +
    + userAllowedToComment (Boolean!) +
    +

    Check if the current user can comment

    +
    +
    +
    + category (Category) +
    +

    The object's category

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/resultconnection/index.html b/app/views/static/api/docs/object/resultconnection/index.html new file mode 100644 index 0000000000..2345865d84 --- /dev/null +++ b/app/views/static/api/docs/object/resultconnection/index.html @@ -0,0 +1,1096 @@ +

    +ResultConnection

    +

    The connection type for Result.

    +

    +Fields

    +
    + edges ([ResultEdge]) +
    +

    A list of edges.

    +
    +
    +
    + nodes ([Result]) +
    +

    A list of nodes.

    +
    +
    +
    + pageInfo (PageInfo!) +
    +

    Information to aid in pagination.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/resultedge/index.html b/app/views/static/api/docs/object/resultedge/index.html new file mode 100644 index 0000000000..bdef2d5edc --- /dev/null +++ b/app/views/static/api/docs/object/resultedge/index.html @@ -0,0 +1,1090 @@ +

    +ResultEdge

    +

    An edge in a connection.

    +

    +Fields

    +
    + node (Result) +
    +

    The item at the end of the edge.

    +
    +
    +
    + cursor (String!) +
    +

    A cursor for use in pagination.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/scope/index.html b/app/views/static/api/docs/object/scope/index.html new file mode 100644 index 0000000000..d5187630bb --- /dev/null +++ b/app/views/static/api/docs/object/scope/index.html @@ -0,0 +1,1101 @@ +

    +Scope

    +

    A scope

    +

    +Fields

    +
    + id (ID!) +
    +
    +
    +
    + name (TranslatedField!) +
    +

    The graphql_name of this scope.

    +
    +
    +
    + children ([Scope]!) +
    +

    Descendants of this scope

    +
    +
    +
    + parent (Scope) +
    +

    This scope's parent scope.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/session/index.html b/app/views/static/api/docs/object/session/index.html new file mode 100644 index 0000000000..37104ec257 --- /dev/null +++ b/app/views/static/api/docs/object/session/index.html @@ -0,0 +1,1090 @@ +

    +Session

    +

    The current session

    +

    +Fields

    +
    + user (User) +
    +

    The current user

    +
    +
    +
    + verifiedUserGroups ([UserGroup!]!) +
    +

    The current user verified user groups

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/sortition/index.html b/app/views/static/api/docs/object/sortition/index.html new file mode 100644 index 0000000000..f0a670e0b2 --- /dev/null +++ b/app/views/static/api/docs/object/sortition/index.html @@ -0,0 +1,1263 @@ +

    +Sortition

    +

    A sortition

    +

    +Implements

    + +

    +Fields

    +
    + id (ID!) +
    +

    The internal ID for this sortition

    +
    +
    +
    + dice (Int) +
    +

    The dice for this sortition

    +
    +
    +
    + targetItems (Int) +
    +

    The target items for this sortition

    +
    +
    +
    + requestTimestamp (Date) +
    +

    The request time stamp for this request

    +
    +
    +
    + selectedProposals ([Int]) +
    +

    The selected proposals for this sortition

    +
    +
    +
    + createdAt (DateTime) +
    +

    When this sortition was created

    +
    +
    +
    + updatedAt (DateTime) +
    +

    When this sortition was updated

    +
    +
    +
    + witnesses (TranslatedField) +
    +

    The witnesses for this sortition

    +
    +
    +
    + additionalInfo (TranslatedField) +
    +

    The additional info for this sortition

    +
    +
    +
    + reference (String) +
    +

    The reference for this sortition

    +
    +
    +
    + title (TranslatedField) +
    +

    The title for this sortition

    +
    +
    +
    + cancelReason (TranslatedField) +
    +

    The cancel reason for this sortition

    +
    +
    +
    + cancelledOn (Date) +
    +

    When this sortition was cancelled

    +
    +
    +
    + cancelledByUser (User) +
    +

    Who cancelled this sortition

    +
    +
    +
    + candidateProposals ([Int]) +
    +

    The candidate proposal for this sortition

    +
    +
    +
    + category (Category) +
    +

    The object's category

    +
    +
    +
    + type (String!) +
    +

    The commentable's class name. i.e. Decidim::ParticipatoryProcess

    +
    +
    +
    + acceptsNewComments (Boolean!) +
    +

    Whether the object can have new comments or not

    +
    +
    +
    + commentsHaveAlignment (Boolean!) +
    +

    Whether the object comments have alignment or not

    +
    +
    +
    + commentsHaveVotes (Boolean!) +
    +

    Whether the object comments have votes or not

    +
    +
    +
    + comments ([Comment!]!) +
    + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    orderBy + String + +

    Order the comments

    +
    singleCommentId + String + +

    ID of the single comment to look at

    +
    +
    +
    +
    + totalCommentsCount (Int!) +
    +

    The number of comments in all levels this resource holds

    +
    +
    +
    + hasComments (Boolean!) +
    +

    Check if the commentable has comments

    +
    +
    +
    + userAllowedToComment (Boolean!) +
    +

    Check if the current user can comment

    +
    +
    +
    + author (Author) +
    +

    The resource author

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/sortitionconnection/index.html b/app/views/static/api/docs/object/sortitionconnection/index.html new file mode 100644 index 0000000000..f62ba98852 --- /dev/null +++ b/app/views/static/api/docs/object/sortitionconnection/index.html @@ -0,0 +1,1096 @@ +

    +SortitionConnection

    +

    The connection type for Sortition.

    +

    +Fields

    +
    + edges ([SortitionEdge]) +
    +

    A list of edges.

    +
    +
    +
    + nodes ([Sortition]) +
    +

    A list of nodes.

    +
    +
    +
    + pageInfo (PageInfo!) +
    +

    Information to aid in pagination.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/sortitionedge/index.html b/app/views/static/api/docs/object/sortitionedge/index.html new file mode 100644 index 0000000000..6a7f50e9a7 --- /dev/null +++ b/app/views/static/api/docs/object/sortitionedge/index.html @@ -0,0 +1,1090 @@ +

    +SortitionEdge

    +

    An edge in a connection.

    +

    +Fields

    +
    + node (Sortition) +
    +

    The item at the end of the edge.

    +
    +
    +
    + cursor (String!) +
    +

    A cursor for use in pagination.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/sortitions/index.html b/app/views/static/api/docs/object/sortitions/index.html new file mode 100644 index 0000000000..c8662edb94 --- /dev/null +++ b/app/views/static/api/docs/object/sortitions/index.html @@ -0,0 +1,1185 @@ +

    +Sortitions

    +

    A sortition component of a participatory space.

    +

    +Implements

    + +

    +Connections

    +
    + sortitions (SortitionConnection) +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    after + String + +

    Returns the elements in the list that come after the specified cursor.

    +
    before + String + +

    Returns the elements in the list that come before the specified cursor.

    +
    first + Int + +

    Returns the first n elements from the list.

    +
    last + Int + +

    Returns the last n elements from the list.

    +
    +
    +
    +

    +Fields

    +
    + sortition (Sortition) +
    + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    id + ID! + +
    +
    +
    +
    + id (ID!) +
    +

    The Component's unique ID

    +
    +
    +
    + name (TranslatedField!) +
    +

    The name of this component.

    +
    +
    +
    + weight (Int!) +
    +

    The weight of the component

    +
    +
    +
    + participatorySpace (ParticipatorySpace!) +
    +

    The participatory space in which this component belongs to.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/statistic/index.html b/app/views/static/api/docs/object/statistic/index.html new file mode 100644 index 0000000000..2a0d211009 --- /dev/null +++ b/app/views/static/api/docs/object/statistic/index.html @@ -0,0 +1,1090 @@ +

    +Statistic

    +

    Represents a single statistic

    +

    +Fields

    +
    + name (String!) +
    +

    The name of the statistic

    +
    +
    +
    + value (Int!) +
    +

    The actual value of the statistic

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/status/index.html b/app/views/static/api/docs/object/status/index.html new file mode 100644 index 0000000000..56ff415474 --- /dev/null +++ b/app/views/static/api/docs/object/status/index.html @@ -0,0 +1,1126 @@ +

    +Status

    +

    A status

    +

    +Fields

    +
    + id (ID!) +
    +

    The internal ID for this status

    +
    +
    +
    + key (String) +
    +

    The key for this status

    +
    +
    +
    + name (TranslatedField) +
    +

    The name for this status

    +
    +
    +
    + createdAt (Date) +
    +

    When this status was created

    +
    +
    +
    + updatedAt (Date) +
    +

    When this status was updated

    +
    +
    +
    + description (TranslatedField) +
    +

    The description for this status

    +
    +
    +
    + progress (Int) +
    +

    The progress for this status

    +
    +
    +
    + results ([Result]) +
    +

    The results for this status

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/survey/index.html b/app/views/static/api/docs/object/survey/index.html new file mode 100644 index 0000000000..d0a53a9a9d --- /dev/null +++ b/app/views/static/api/docs/object/survey/index.html @@ -0,0 +1,1102 @@ +

    +Survey

    +

    A survey

    +

    +Fields

    +
    + id (ID!) +
    +

    The internal ID for this survey

    +
    +
    +
    + createdAt (DateTime) +
    +

    The time this survey was created

    +
    +
    +
    + updatedAt (DateTime) +
    +

    The time this survey was updated

    +
    +
    +
    + questionnaire (Questionnaire) +
    +

    The questionnaire for this survey

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/surveyconnection/index.html b/app/views/static/api/docs/object/surveyconnection/index.html new file mode 100644 index 0000000000..9a49f3cf92 --- /dev/null +++ b/app/views/static/api/docs/object/surveyconnection/index.html @@ -0,0 +1,1096 @@ +

    +SurveyConnection

    +

    The connection type for Survey.

    +

    +Fields

    +
    + edges ([SurveyEdge]) +
    +

    A list of edges.

    +
    +
    +
    + nodes ([Survey]) +
    +

    A list of nodes.

    +
    +
    +
    + pageInfo (PageInfo!) +
    +

    Information to aid in pagination.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/surveyedge/index.html b/app/views/static/api/docs/object/surveyedge/index.html new file mode 100644 index 0000000000..b11bc11bb3 --- /dev/null +++ b/app/views/static/api/docs/object/surveyedge/index.html @@ -0,0 +1,1090 @@ +

    +SurveyEdge

    +

    An edge in a connection.

    +

    +Fields

    +
    + node (Survey) +
    +

    The item at the end of the edge.

    +
    +
    +
    + cursor (String!) +
    +

    A cursor for use in pagination.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/surveys/index.html b/app/views/static/api/docs/object/surveys/index.html new file mode 100644 index 0000000000..ceb5924e2a --- /dev/null +++ b/app/views/static/api/docs/object/surveys/index.html @@ -0,0 +1,1185 @@ +

    +Surveys

    +

    A surveys component of a participatory space.

    +

    +Implements

    + +

    +Connections

    +
    + surveys (SurveyConnection) +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    after + String + +

    Returns the elements in the list that come after the specified cursor.

    +
    before + String + +

    Returns the elements in the list that come before the specified cursor.

    +
    first + Int + +

    Returns the first n elements from the list.

    +
    last + Int + +

    Returns the last n elements from the list.

    +
    +
    +
    +

    +Fields

    +
    + survey (Survey) +
    + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    id + ID! + +
    +
    +
    +
    + id (ID!) +
    +

    The Component's unique ID

    +
    +
    +
    + name (TranslatedField!) +
    +

    The name of this component.

    +
    +
    +
    + weight (Int!) +
    +

    The weight of the component

    +
    +
    +
    + participatorySpace (ParticipatorySpace!) +
    +

    The participatory space in which this component belongs to.

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/timelineentry/index.html b/app/views/static/api/docs/object/timelineentry/index.html new file mode 100644 index 0000000000..8540e962b4 --- /dev/null +++ b/app/views/static/api/docs/object/timelineentry/index.html @@ -0,0 +1,1120 @@ +

    +TimelineEntry

    +

    A Timeline Entry

    +

    +Fields

    +
    + id (ID!) +
    +

    The internal ID for this timeline entry

    +
    +
    +
    + entryDate (Date) +
    +

    The entry date for this timeline entry

    +
    +
    +
    + title (TranslatedField) +
    +

    The title for this timeline entry

    +
    +
    +
    + description (TranslatedField) +
    +

    The description for this timeline entry

    +
    +
    +
    + createdAt (DateTime) +
    +

    When this timeline entry was created

    +
    +
    +
    + updatedAt (DateTime) +
    +

    When this timeline entry was updated

    +
    +
    +
    + result (Result) +
    +

    The result for this timeline entry

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/traceversion/index.html b/app/views/static/api/docs/object/traceversion/index.html new file mode 100644 index 0000000000..48ebddca2a --- /dev/null +++ b/app/views/static/api/docs/object/traceversion/index.html @@ -0,0 +1,1102 @@ +

    +TraceVersion

    +

    A trace version type

    +

    +Fields

    +
    + id (ID!) +
    +

    The ID of the version

    +
    +
    +
    + createdAt (DateTime) +
    +

    The date and time this version was created

    +
    +
    +
    + editor (Author) +
    +

    The editor/author of this version

    +
    +
    +
    + changeset (JSON) +
    +

    Object with the changes in this version

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/translatedcustomfields/index.html b/app/views/static/api/docs/object/translatedcustomfields/index.html new file mode 100644 index 0000000000..52f96148b8 --- /dev/null +++ b/app/views/static/api/docs/object/translatedcustomfields/index.html @@ -0,0 +1,1136 @@ +

    +TranslatedCustomFields

    +

    A translated field

    +

    +Fields

    +
    + locales ([String]) +
    +

    Lists all the locales in which this translation is available

    +
    +
    +
    + translations ([LocalizedCustomFields]!) +
    +

    All the localized custom fields for this translation.

    + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    locales + [String!] + +

    A list of locales to scope the translations to.

    +
    +
    +
    +
    + translation (JSON) +
    +

    Returns a single translation given a locale.

    + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    locale + String! + +

    A locale to search for

    +
    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/translatedfield/index.html b/app/views/static/api/docs/object/translatedfield/index.html new file mode 100644 index 0000000000..4514a47048 --- /dev/null +++ b/app/views/static/api/docs/object/translatedfield/index.html @@ -0,0 +1,1136 @@ +

    +TranslatedField

    +

    A translated field

    +

    +Fields

    +
    + locales ([String]) +
    +

    Lists all the locales in which this translation is available

    +
    +
    +
    + translations ([LocalizedString]!) +
    +

    All the localized strings for this translation.

    + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    locales + [String!] + +

    A list of locales to scope the translations to.

    +
    +
    +
    +
    + translation (String) +
    +

    Returns a single translation given a locale.

    + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    locale + String! + +

    A locale to search for

    +
    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/user/index.html b/app/views/static/api/docs/object/user/index.html new file mode 100644 index 0000000000..e97fc2e424 --- /dev/null +++ b/app/views/static/api/docs/object/user/index.html @@ -0,0 +1,1143 @@ +

    +User

    +

    A user

    +

    +Implements

    + +

    +Fields

    +
    + id (ID!) +
    +

    The user's id

    +
    +
    +
    + name (String!) +
    +

    The user's name

    +
    +
    +
    + nickname (String!) +
    +

    The user's nickname

    +
    +
    +
    + avatarUrl (String!) +
    +

    The user's avatar url

    +
    +
    +
    + profilePath (String!) +
    +

    The user's profile url

    +
    +
    +
    + directMessagesEnabled (String!) +
    +

    If the user making the request is logged in, it will return whether this recipient accepts a conversation or not. It will return false for non-logged requests.

    +
    +
    +
    + organizationName (String!) +
    +

    The user's organization name

    +
    +
    +
    + deleted (Boolean!) +
    +

    Whether the user's account has been deleted or not

    +
    +
    +
    + badge (String!) +
    +

    A badge for the user group

    +
    +
    +
    + groups ([UserGroup]!) +
    +

    Groups where this user belongs

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/object/usergroup/index.html b/app/views/static/api/docs/object/usergroup/index.html new file mode 100644 index 0000000000..4278127437 --- /dev/null +++ b/app/views/static/api/docs/object/usergroup/index.html @@ -0,0 +1,1143 @@ +

    +UserGroup

    +

    A user group

    +

    +Implements

    + +

    +Fields

    +
    + id (ID!) +
    +

    The user group's id

    +
    +
    +
    + name (String!) +
    +

    The user group's name

    +
    +
    +
    + nickname (String!) +
    +

    The user group nickname

    +
    +
    +
    + avatarUrl (String!) +
    +

    The user's avatar url

    +
    +
    +
    + profilePath (String!) +
    +

    The user group's profile url

    +
    +
    +
    + organizationName (String!) +
    +

    The user group's organization name

    +
    +
    +
    + deleted (Boolean!) +
    +

    Whether the user group's has been deleted or not

    +
    +
    +
    + badge (String!) +
    +

    A badge for the user group

    +
    +
    +
    + members ([User]!) +
    +

    Members of this group

    +
    +
    +
    + membersCount (Int!) +
    +

    Number of members in this group

    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/operation/mutation/index.html b/app/views/static/api/docs/operation/mutation/index.html new file mode 100644 index 0000000000..135a9715a2 --- /dev/null +++ b/app/views/static/api/docs/operation/mutation/index.html @@ -0,0 +1,1078 @@ +

    +Mutations

    +

    Every GraphQL schema has a root type for both queries and mutations.

    +

    The mutation type defines how GraphQL operations change data. It is analogous to performing HTTP verbs such as POST, PATCH, and DELETE.

    +

    For more information, see the GraphQL spec.

    + + + +
    + +
    diff --git a/app/views/static/api/docs/operation/query/index.html b/app/views/static/api/docs/operation/query/index.html new file mode 100644 index 0000000000..83818d6c07 --- /dev/null +++ b/app/views/static/api/docs/operation/query/index.html @@ -0,0 +1,1633 @@ +

    +Query

    +

    Every GraphQL schema has a root type for both queries and mutations. The query type defines GraphQL operations that retrieve data from the server.

    +

    +Fields

    +
    + participatoryProcesses ([ParticipatoryProcess!]) +
    +

    Lists all participatory_processes

    + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    filter + ParticipatoryProcessFilter + +

    This argument lets you filter the results

    +
    order + ParticipatoryProcessSort + +

    This argument lets you order the results

    +
    +
    +
    +
    + participatoryProcess (ParticipatoryProcess) +
    +

    Finds a participatory_process

    + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    id + ID + +

    The ID of the participatory space

    +
    slug + String + +

    The slug of the participatory process

    +
    +
    +
    +
    + component (ComponentInterface) +
    +

    Lists the components this space contains.

    + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    id + ID! + +

    The ID of the component to be found

    +
    +
    +
    +
    + session (Session) +
    +

    Return's information about the logged in user

    +
    +
    +
    + decidim (Decidim) +
    +

    Decidim's framework properties.

    +
    +
    +
    + organization (Organization) +
    +

    The current organization

    +
    +
    +
    + hashtags ([HashtagType!]) +
    +

    The hashtags for current organization

    + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    name + String + +

    The name of the hashtag

    +
    +
    +
    +
    + metrics ([Metric!]) +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    names + [String!] + +

    The names of the metrics you want to retrieve

    +
    space_type + String + +

    The type of ParticipatorySpace you want to filter with

    +
    space_id + Int + +

    The ID of ParticipatorySpace you want to filter with

    +
    +
    +
    +
    + user (Author) +
    +

    A participant (user or group) in the current organization

    + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    id + ID + +

    The ID of the participant

    +
    nickname + String + +

    The @nickname of the participant

    +
    +
    +
    +
    + users ([Author!]) +
    +

    The participants (users or groups) for the current organization

    + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    order + UserEntitySort + +

    Provides several methods to order the results

    +
    filter + UserEntityFilter + +

    Provides several methods to filter the results

    +
    +
    +
    +
    + participatoryProcessGroups ([ParticipatoryProcessGroup!]!) +
    +

    Lists all participatory process groups

    +
    +
    +
    + participatoryProcessGroup (ParticipatoryProcessGroup) +
    +

    Finds a participatory process group

    + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    id + ID! + +

    The ID of the Participatory process group

    +
    +
    +
    +
    + participatoryProcessTypes ([ParticipatoryProcessType!]!) +
    +

    List all participatory process types

    +
    +
    +
    + participatoryProcessType (ParticipatoryProcessType) +
    +

    Finds a participatory process type

    + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    id + ID! + +

    The ID of the participatory process type

    +
    +
    +
    +
    + assembliesTypes ([AssembliesType!]!) +
    +

    Lists all assemblies types

    +
    +
    +
    + assembliesType (AssembliesType) +
    +

    Finds an assemblies type group

    + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    id + ID! + +

    The ID of the Assemblies type

    +
    +
    +
    +
    + assemblies ([Assembly!]) +
    +

    Lists all assemblies

    + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    filter + ParticipatoryProcessFilter + +

    This argument lets you filter the results

    +
    order + ParticipatoryProcessSort + +

    This argument lets you order the results

    +
    +
    +
    +
    + assembly (Assembly) +
    +

    Finds an assembly

    + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    id + ID + +

    The ID of the participatory space

    +
    +
    +
    +
    + commentable (Commentable!) +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    id + String! + +

    The commentable's ID

    +
    type + String! + +

    The commentable's class name. i.e. Decidim::ParticipatoryProcess

    +
    locale + String! + +

    The locale for which to get the comments text

    +
    toggleTranslations + Boolean! + +

    Whether the user asked to toggle the machine translations or not.

    +
    +
    +
    +
    + initiativesTypes ([InitiativeType!]!) +
    +

    Lists all initiative types

    +
    +
    +
    + initiativesType (InitiativeType) +
    +

    Finds an initiative type

    + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    id + ID! + +

    The ID of the initiative type

    +
    +
    +
    +
    + initiatives ([Initiative!]) +
    +

    Lists all initiatives

    + + + + + + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    filter + ParticipatoryProcessFilter + +

    This argument lets you filter the results

    +
    order + ParticipatoryProcessSort + +

    This argument lets you order the results

    +
    +
    +
    +
    + initiative (Initiative) +
    +

    Finds an initiative

    + + + + + + + + + + + + + + + +
    ArgumentTypeDescription
    id + ID + +

    The ID of the participatory space

    +
    +
    +
    + + + +
    + +
    diff --git a/app/views/static/api/docs/scalar/boolean/index.html b/app/views/static/api/docs/scalar/boolean/index.html new file mode 100644 index 0000000000..4022ab7c69 --- /dev/null +++ b/app/views/static/api/docs/scalar/boolean/index.html @@ -0,0 +1,1076 @@ +

    +Boolean

    +

    Represents true or false values.

    + + + +
    + +
    diff --git a/app/views/static/api/docs/scalar/date/index.html b/app/views/static/api/docs/scalar/date/index.html new file mode 100644 index 0000000000..3e42e3f1cc --- /dev/null +++ b/app/views/static/api/docs/scalar/date/index.html @@ -0,0 +1,1076 @@ +

    +Date

    +

    An ISO8601 date

    + + + +
    + +
    diff --git a/app/views/static/api/docs/scalar/datetime/index.html b/app/views/static/api/docs/scalar/datetime/index.html new file mode 100644 index 0000000000..02a4c915f7 --- /dev/null +++ b/app/views/static/api/docs/scalar/datetime/index.html @@ -0,0 +1,1076 @@ +

    +DateTime

    +

    An ISO8601 date with time

    + + + +
    + +
    diff --git a/app/views/static/api/docs/scalar/float/index.html b/app/views/static/api/docs/scalar/float/index.html new file mode 100644 index 0000000000..7b17c6164f --- /dev/null +++ b/app/views/static/api/docs/scalar/float/index.html @@ -0,0 +1,1076 @@ +

    +Float

    +

    Represents signed double-precision fractional values as specified by IEEE 754.

    + + + +
    + +
    diff --git a/app/views/static/api/docs/scalar/id/index.html b/app/views/static/api/docs/scalar/id/index.html new file mode 100644 index 0000000000..8b1120a0f4 --- /dev/null +++ b/app/views/static/api/docs/scalar/id/index.html @@ -0,0 +1,1076 @@ +

    +ID

    +

    Represents a unique identifier that is Base64 obfuscated. It is often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as "VXNlci0xMA==") or integer (such as 4) input value will be accepted as an ID.

    + + + +
    + +
    diff --git a/app/views/static/api/docs/scalar/index.html b/app/views/static/api/docs/scalar/index.html new file mode 100644 index 0000000000..c6f969c9cb --- /dev/null +++ b/app/views/static/api/docs/scalar/index.html @@ -0,0 +1,1077 @@ +

    +Scalars

    +

    Scalars are primitive values such as Int or String.

    +

    For more information, see the GraphQL spec.

    + + + +
    + +
    diff --git a/app/views/static/api/docs/scalar/int/index.html b/app/views/static/api/docs/scalar/int/index.html new file mode 100644 index 0000000000..3e0ce8ae92 --- /dev/null +++ b/app/views/static/api/docs/scalar/int/index.html @@ -0,0 +1,1076 @@ +

    +Int

    +

    Represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.

    + + + +
    + +
    diff --git a/app/views/static/api/docs/scalar/json/index.html b/app/views/static/api/docs/scalar/json/index.html new file mode 100644 index 0000000000..0ec570f9d3 --- /dev/null +++ b/app/views/static/api/docs/scalar/json/index.html @@ -0,0 +1,1076 @@ +

    +JSON

    +

    Represents untyped JSON

    + + + +
    + +
    diff --git a/app/views/static/api/docs/scalar/string/index.html b/app/views/static/api/docs/scalar/string/index.html new file mode 100644 index 0000000000..99fee64776 --- /dev/null +++ b/app/views/static/api/docs/scalar/string/index.html @@ -0,0 +1,1076 @@ +

    +String

    +

    Represents textual data as UTF-8 character sequences. This type is most often used by GraphQL to represent free-form human-readable text.

    + + + +
    + +
    diff --git a/app/views/static/api/docs/union/index.html b/app/views/static/api/docs/union/index.html new file mode 100644 index 0000000000..c754b32213 --- /dev/null +++ b/app/views/static/api/docs/union/index.html @@ -0,0 +1,1077 @@ +

    +Unions

    +

    A union is a type of object that can represent one of many kinds of objects. For example, a field marked as a ReactableUnion could be a CommitComment, an Issue, an IssueComment, or a PullRequestReviewComment, because each of those objects can be reacted on.

    +

    For more information, see the GraphQL spec.

    + + + +
    + +
    diff --git a/babel.config.json b/babel.config.json index e5811e1aec..86a38f89c3 100644 --- a/babel.config.json +++ b/babel.config.json @@ -20,11 +20,6 @@ "corejs": false } ], - [ - "@babel/plugin-transform-regenerator", - { - "async": false - } - ] + ["@babel/plugin-transform-regenerator", { "async": false }] ] } diff --git a/bin/bundle b/bin/bundle index 7d5effb010..5ae9979931 100755 --- a/bin/bundle +++ b/bin/bundle @@ -19,7 +19,7 @@ m = Module.new do end def env_var_version - ENV["BUNDLER_VERSION"] + ENV.fetch("BUNDLER_VERSION", nil) end def cli_arg_version @@ -39,7 +39,7 @@ m = Module.new do end def gemfile - gemfile = ENV["BUNDLE_GEMFILE"] + gemfile = ENV.fetch("BUNDLE_GEMFILE", nil) return gemfile if gemfile && !gemfile.empty? File.expand_path("../Gemfile", __dir__) @@ -64,10 +64,8 @@ m = Module.new do end def bundler_version - @bundler_version ||= begin - env_var_version || cli_arg_version || - lockfile_version || "#{Gem::Requirement.default}.a" - end + @bundler_version ||= env_var_version || cli_arg_version || + lockfile_version || "#{Gem::Requirement.default}.a" end def load_bundler! diff --git a/bin/decidim_update b/bin/decidim_update deleted file mode 100755 index a976176a7d..0000000000 --- a/bin/decidim_update +++ /dev/null @@ -1 +0,0 @@ -bundle update --source decidim decidim-initiatives decidim-sortitions decidim-dev decidim-term_customizer && bundle exec rake decidim:upgrade && bundle exec rake db:migrate diff --git a/bin/dev b/bin/dev new file mode 100755 index 0000000000..74ade16641 --- /dev/null +++ b/bin/dev @@ -0,0 +1,8 @@ +#!/usr/bin/env sh + +if ! gem list foreman -i --silent; then + echo "Installing foreman..." + gem install foreman +fi + +exec foreman start -f Procfile.dev "$@" diff --git a/bin/shakapacker b/bin/shakapacker new file mode 100755 index 0000000000..0513f209fa --- /dev/null +++ b/bin/shakapacker @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +ENV["RAILS_ENV"] ||= "development" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) + +require "bundler/setup" + +# Add the Decidim override load path to override webpacker functionality +$LOAD_PATH.unshift "#{Gem.loaded_specs["decidim-core"].full_gem_path}/lib/gem_overrides" +require "shakapacker" +require "shakapacker/webpack_runner" + +APP_ROOT = File.expand_path("..", __dir__) +Dir.chdir(APP_ROOT) do + Shakapacker::WebpackRunner.run(ARGV) +end diff --git a/bin/shakapacker-dev-server b/bin/shakapacker-dev-server new file mode 100755 index 0000000000..1416541af7 --- /dev/null +++ b/bin/shakapacker-dev-server @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +ENV["RAILS_ENV"] ||= "development" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) + +require "bundler/setup" + +# Add the Decidim override load path to override webpacker functionality +$LOAD_PATH.unshift "#{Gem.loaded_specs["decidim-core"].full_gem_path}/lib/gem_overrides" +require "shakapacker" +require "shakapacker/dev_server_runner" + +APP_ROOT = File.expand_path("..", __dir__) +Dir.chdir(APP_ROOT) do + Shakapacker::DevServerRunner.run(ARGV) +end diff --git a/bin/webpack b/bin/webpack deleted file mode 100755 index 42c74e1f5d..0000000000 --- a/bin/webpack +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true - -ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development" -ENV["NODE_ENV"] ||= "development" - -require "pathname" -ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", - Pathname.new(__FILE__).realpath) - -require "bundler/setup" - -# Add the Decidim override load path to override webpacker functionality -$LOAD_PATH.unshift "#{Gem.loaded_specs["decidim-core"].full_gem_path}/lib/gem_overrides" - -require "webpacker" -require "webpacker/webpack_runner" - -APP_ROOT = File.expand_path("..", __dir__) -Dir.chdir(APP_ROOT) do - Webpacker::WebpackRunner.run(ARGV) -end diff --git a/bin/webpack-dev-server b/bin/webpack-dev-server deleted file mode 100755 index 7f9e64a020..0000000000 --- a/bin/webpack-dev-server +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env ruby -# frozen_string_literal: true - -ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development" -ENV["NODE_ENV"] ||= "development" - -require "pathname" -ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", - Pathname.new(__FILE__).realpath) - -require "bundler/setup" - -# Add the Decidim override load path to override webpacker functionality -$LOAD_PATH.unshift "#{Gem.loaded_specs["decidim-core"].full_gem_path}/lib/gem_overrides" - -require "webpacker" -require "webpacker/dev_server_runner" - -APP_ROOT = File.expand_path("..", __dir__) -Dir.chdir(APP_ROOT) do - Webpacker::DevServerRunner.run(ARGV) -end diff --git a/config/application.rb b/config/application.rb index 1a3457ec97..3e26f82881 100644 --- a/config/application.rb +++ b/config/application.rb @@ -17,9 +17,10 @@ class Application < Rails::Application # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers # -- all .rb files in that directory are automatically loaded. + config.autoloader = :zeitwerk # Locales - config.i18n.available_locales = %w(ca es) + config.i18n.available_locales = [:ca, :es] config.i18n.default_locale = :ca end end diff --git a/config/database.yml b/config/database.yml index 1070086fba..0241b38962 100644 --- a/config/database.yml +++ b/config/database.yml @@ -28,6 +28,7 @@ development: <<: *default database: <%= ENV.fetch("DATABASE_NAME") { "decidim-barcelona_development" } %> statement_limit: <%= ENV['PREPARED_STATEMENTS_LIMIT'] ? ENV['PREPARED_STATEMENTS_LIMIT'].to_i : 200 %> + gssencmode: disable # The specified database role being used to connect to postgres. # To create additional roles in postgres see `$ createuser --help`. @@ -62,6 +63,7 @@ development: test: <<: *default database: <%= ENV.fetch("DATABASE_NAME") { "decidim-barcelona_test" } %> + gssencmode: disable # As with config/secrets.yml, you never want to store sensitive information, # like your database password, in your source code. If your source code is diff --git a/config/environments/development.rb b/config/environments/development.rb index 6480e7ca38..893609d87d 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -1,10 +1,12 @@ # frozen_string_literal: true +require "active_support/core_ext/integer/time" + Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. - # In the development environment your application's code is reloaded on - # every request. This slows down response time but is perfect for development + # In the development environment your application's code is reloaded any time + # it changes. This slows down response time but is perfect for development # since you don't have to restart the web server when you make code changes. config.cache_classes = false @@ -15,6 +17,7 @@ config.consider_all_requests_local = true # Enable/disable caching. By default caching is disabled. + # Run rails dev:cache to toggle caching. if Rails.root.join("tmp/caching-dev.txt").exist? config.action_controller.perform_caching = true config.action_controller.enable_fragment_cache_logging = true @@ -29,13 +32,13 @@ config.cache_store = :null_store end + # Store uploaded files on the local file system (see config/storage.yml for options). config.active_storage.service = :local # Don't care if the mailer can't send. config.action_mailer.raise_delivery_errors = false - config.action_mailer.delivery_method = :letter_opener_web - config.action_mailer.default_url_options = { host: "localhost:3000" } + config.action_mailer.default_url_options = { host: "localhost", port: 3000 } config.action_mailer.asset_host = "http://localhost:3000" config.action_mailer.perform_deliveries = true @@ -44,16 +47,34 @@ # Print deprecation notices to the Rails logger. config.active_support.deprecation = :log + # Raise exceptions for disallowed deprecations. + config.active_support.disallowed_deprecation = :raise + + # Tell Active Support which deprecation messages to disallow. + config.active_support.disallowed_deprecation_warnings = [] + # Raise an error on page load if there are pending migrations. config.active_record.migration_error = :page_load # Highlight code that triggered database queries in logs. config.active_record.verbose_query_logs = true - # Raises error for missing translations - # config.action_view.raise_on_missing_translations = true + # Debug mode disables concatenation and preprocessing of assets. + # This option may cause significant delays in view rendering with a large + # number of complex assets. + + # Suppress logger output for asset requests. + + # Raises error for missing translations. + # config.i18n.raise_on_missing_translations = true + + # Annotate rendered view with file names. + # config.action_view.annotate_rendered_view_with_filenames = true # Use an evented file watcher to asynchronously detect changes in source code, # routes, locales, etc. This feature depends on the listen gem. config.file_watcher = ActiveSupport::EventedFileUpdateChecker + + # Uncomment if you wish to allow Action Cable access from any origin. + # config.action_cable.disable_request_forgery_protection = true end diff --git a/config/environments/production.rb b/config/environments/production.rb index eebf7411b5..e05b237e01 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require "active_support/core_ext/integer/time" + Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. @@ -16,37 +18,45 @@ config.consider_all_requests_local = false config.action_controller.perform_caching = true + # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"] + # or in config/master.key. This key is used to decrypt credentials (and other encrypted files). + # config.require_master_key = true + # Disable serving static files from the `/public` folder by default since # Apache or NGINX already handles this. config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? + # Compress CSS using a preprocessor. + + # Do not fallback to assets pipeline if a precompiled asset is missed. + # Enable serving of images, stylesheets, and JavaScripts from an asset server. - # config.action_controller.asset_host = 'http://assets.example.com' + config.asset_host = ENV.fetch("RAILS_ASSET_HOST", nil) if ENV["RAILS_ASSET_HOST"].present? # Specifies the header that your server uses for sending files. # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX - # Mount Action Cable outside main process or domain + # Store uploaded files on the local file system (see config/storage.yml for options). + config.active_storage.service = Rails.application.secrets.dig(:storage, :provider) || :local + + # Mount Action Cable outside main process or domain. # config.action_cable.mount_path = nil # config.action_cable.url = 'wss://example.com/cable' # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ] - # Store uploaded files on the local file system (see config/storage.yml for options) - config.active_storage.service = :amazon - # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. config.force_ssl = true config.middleware.use Rack::SslEnforcer, except_hosts: ENV["EXCEPT_SSL_HOSTS"].to_s.split(",") if ENV["STAGING_PASSWORD"].present? # Block users that do not know a given password - config.middleware.use RackPassword::Block, auth_codes: [ENV["STAGING_PASSWORD"]] + config.middleware.use RackPassword::Block, auth_codes: [ENV.fetch("STAGING_PASSWORD", nil)] end - # Use the lowest log level to ensure availability of diagnostic information - # when problems arise. - config.log_level = :info + # Include generic and useful information about system operation, but avoid logging too much + # information to avoid inadvertent exposure of personally identifiable information (PII). + config.log_level = %w(debug info warn error fatal).include?(ENV.fetch("RAILS_LOG_LEVEL", nil)) ? ENV.fetch("RAILS_LOG_LEVEL", nil) : :info # Prepend all log lines with the following tags. config.log_tags = [:request_id] @@ -54,9 +64,10 @@ # Use a different cache store in production. # config.cache_store = :mem_cache_store - # Use a real queuing backend for Active Job (and separate queues per environment) - # config.active_job.queue_adapter = :resque - # config.active_job.queue_name_prefix = "decidim-barcelona_#{Rails.env}" + # Use a real queuing backend for Active Job (and separate queues per environment). + config.active_job.queue_adapter = :sidekiq + # config.active_job.queue_name_prefix = "decidim_barcelona_production" + config.action_mailer.perform_caching = false # Ignore bad email addresses and do not raise email delivery errors. @@ -70,9 +81,14 @@ # Send deprecation notices to registered listeners. config.active_support.deprecation = :notify - # Use default logging formatter so that PID and timestamp are not suppressed. - config.log_formatter = ::Logger::Formatter.new + # Log disallowed deprecations. + config.active_support.disallowed_deprecation = :log + + # Tell Active Support which deprecation messages to disallow. + config.active_support.disallowed_deprecation_warnings = [] + # Use default logging formatter so that PID and timestamp are not suppressed. + config.log_formatter = Logger::Formatter.new config.action_mailer.smtp_settings = { address: Rails.application.secrets.smtp_address, port: Rails.application.secrets.smtp_port, @@ -84,6 +100,40 @@ openssl_verify_mode: "none" } + # Use a different logger for distributed setups. + # require 'syslog/logger' + # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name') + + if ENV["RAILS_LOG_TO_STDOUT"].present? + logger = ActiveSupport::Logger.new($stdout) + logger.formatter = config.log_formatter + config.logger = ActiveSupport::TaggedLogging.new(logger) + end + + # Do not dump schema after migrations. + config.active_record.dump_schema_after_migration = false + + # Inserts middleware to perform automatic connection switching. + # The `database_selector` hash is used to pass options to the DatabaseSelector + # middleware. The `delay` is used to determine how long to wait after a write + # to send a subsequent read to the primary. + # + # The `database_resolver` class is used by the middleware to determine which + # database is appropriate to use based on the time delay. + # + # The `database_resolver_context` class is used by the middleware to set + # timestamps for the last write to the primary. The resolver uses the context + # class timestamps to determine how long to wait before reading from the + # replica. + # + # By default Rails will store a last write timestamp in the session. The + # DatabaseSelector middleware is designed as such you can define your own + # strategy for connection switching and pass that into the middleware through + # these configuration options. + # config.active_record.database_selector = { delay: 2.seconds } + # config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver + # config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session + if Rails.application.secrets.sendgrid config.action_mailer.default_options = { "X-SMTPAPI" => { @@ -97,24 +147,10 @@ if ENV["MEMCACHEDCLOUD_SERVERS"] config.cache_store = :mem_cache_store, ENV["MEMCACHEDCLOUD_SERVERS"].split(","), { - username: ENV["MEMCACHEDCLOUD_USERNAME"], password: ENV["MEMCACHEDCLOUD_PASSWORD"] + username: ENV.fetch("MEMCACHEDCLOUD_USERNAME", nil), password: ENV.fetch("MEMCACHEDCLOUD_PASSWORD", nil) } end - # Use a different logger for distributed setups. - # require 'syslog/logger' - # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name') - - if ENV["RAILS_LOG_TO_STDOUT"].present? - logger = ActiveSupport::Logger.new($stdout) - logger.formatter = config.log_formatter - config.logger = ActiveSupport::TaggedLogging.new(logger) - end - - # Do not dump schema after migrations. - config.active_record.dump_schema_after_migration = false - config.active_job.queue_adapter = :sidekiq - config.lograge.enabled = true config.lograge.formatter = Lograge::Formatters::Json.new config.lograge.custom_options = lambda do |event| diff --git a/config/environments/staging.rb b/config/environments/staging.rb deleted file mode 100644 index 835f03b9fa..0000000000 --- a/config/environments/staging.rb +++ /dev/null @@ -1,121 +0,0 @@ -# frozen_string_literal: true - -Rails.application.configure do - # Settings specified here will take precedence over those in config/application.rb. - - # Code is not reloaded between requests. - config.cache_classes = true - - # Eager load code on boot. This eager loads most of Rails and - # your application in memory, allowing both threaded web servers - # and those relying on copy on write to perform better. - # Rake tasks automatically ignore this option for performance. - config.eager_load = true - - # Full error reports are disabled and caching is turned on. - config.consider_all_requests_local = false - config.action_controller.perform_caching = true - - # Disable serving static files from the `/public` folder by default since - # Apache or NGINX already handles this. - config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? - - # Enable serving of images, stylesheets, and JavaScripts from an asset server. - # config.action_controller.asset_host = 'http://assets.example.com' - - # Specifies the header that your server uses for sending files. - # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache - # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX - - # Mount Action Cable outside main process or domain - # config.action_cable.mount_path = nil - # config.action_cable.url = 'wss://example.com/cable' - # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ] - - # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. - config.force_ssl = true - config.middleware.use Rack::SslEnforcer, except_hosts: ENV["EXCEPT_SSL_HOSTS"].to_s.split(",") - - # Use the lowest log level to ensure availability of diagnostic information - # when problems arise. - config.log_level = :info - - # Prepend all log lines with the following tags. - config.log_tags = [:request_id] - - # Use a different cache store in production. - # config.cache_store = :mem_cache_store - - # Use a real queuing backend for Active Job (and separate queues per environment) - # config.active_job.queue_adapter = :resque - # config.active_job.queue_name_prefix = "decidim-barcelona_#{Rails.env}" - config.action_mailer.perform_caching = false - - # Ignore bad email addresses and do not raise email delivery errors. - # Set this to true and configure the email server for immediate delivery to raise delivery errors. - # config.action_mailer.raise_delivery_errors = false - - # Enable locale fallbacks for I18n (makes lookups for any locale fall back to - # the I18n.default_locale when a translation cannot be found). - config.i18n.fallbacks = [:en] - - # Send deprecation notices to registered listeners. - config.active_support.deprecation = :notify - - # Use default logging formatter so that PID and timestamp are not suppressed. - config.log_formatter = ::Logger::Formatter.new - - config.action_mailer.smtp_settings = { - address: Rails.application.secrets.smtp_address, - port: Rails.application.secrets.smtp_port, - authentication: Rails.application.secrets.smtp_authentication, - user_name: Rails.application.secrets.smtp_username, - password: Rails.application.secrets.smtp_password, - domain: Rails.application.secrets.smtp_domain, - enable_starttls_auto: Rails.application.secrets.smtp_starttls_auto, - openssl_verify_mode: "none" - } - - if Rails.application.secrets.sendgrid - config.action_mailer.default_options = { - "X-SMTPAPI" => { - filters: { - clicktrack: { settings: { enable: 0 } }, - opentrack: { settings: { enable: 0 } } - } - }.to_json - } - end - - if ENV["MEMCACHEDCLOUD_SERVERS"] - config.cache_store = :mem_cache_store, ENV["MEMCACHEDCLOUD_SERVERS"].split(","), { - username: ENV["MEMCACHEDCLOUD_USERNAME"], password: ENV["MEMCACHEDCLOUD_PASSWORD"] - } - end - - # Use a different logger for distributed setups. - # require 'syslog/logger' - # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name') - - if ENV["RAILS_LOG_TO_STDOUT"].present? - logger = ActiveSupport::Logger.new($stdout) - logger.formatter = config.log_formatter - config.logger = ActiveSupport::TaggedLogging.new(logger) - end - - # Do not dump schema after migrations. - config.active_record.dump_schema_after_migration = false - config.active_job.queue_adapter = :sidekiq - - config.lograge.enabled = true - config.lograge.formatter = Lograge::Formatters::Json.new - config.lograge.custom_options = lambda do |event| - { - remote_ip: event.payload[:remote_ip], - params: event.payload[:params].except("controller", "action", "format", "utf8"), - user_id: event.payload[:user_id], - organization_id: event.payload[:organization_id], - referer: event.payload[:referer] - } - end -end diff --git a/config/environments/test.rb b/config/environments/test.rb index 80643d6688..4b992ba9d2 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -1,18 +1,17 @@ # frozen_string_literal: true -Rails.application.configure do - # Settings specified here will take precedence over those in config/application.rb. +require "active_support/core_ext/integer/time" - config.time_zone = "UTC" +# The test environment is used exclusively to run your application's +# test suite. You never need to work with it otherwise. Remember that +# your test database is "scratch space" for the test suite and is wiped +# and recreated between test runs. Don't rely on the data there! - # The test environment is used exclusively to run your application's - # test suite. You never need to work with it otherwise. Remember that - # your test database is "scratch space" for the test suite and is wiped - # and recreated between test runs. Don't rely on the data there! - config.cache_classes = true +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. - # Store uploaded files on the local file system in a temporary directory - config.active_storage.service = :test + config.cache_classes = false + config.action_view.cache_template_loading = true # Do not eager load code on boot. This avoids loading your whole application # just for the purpose of running a single test. If you are using a tool that @@ -28,12 +27,17 @@ # Show full error reports and disable caching. config.consider_all_requests_local = true config.action_controller.perform_caching = false + config.cache_store = :null_store # Raise exceptions instead of rendering exception templates. config.action_dispatch.show_exceptions = false # Disable request forgery protection in test environment. config.action_controller.allow_forgery_protection = false + + # Store uploaded files on the local file system in a temporary directory. + config.active_storage.service = :test + config.action_mailer.perform_caching = false # Tell Action Mailer not to deliver emails to the real world. @@ -44,6 +48,17 @@ # Print deprecation notices to the stderr. config.active_support.deprecation = :stderr - # Raises error for missing translations - # config.action_view.raise_on_missing_translations = true + # Raise exceptions for disallowed deprecations. + config.active_support.disallowed_deprecation = :raise + + # Tell Active Support which deprecation messages to disallow. + config.active_support.disallowed_deprecation_warnings = [] + + # Raises error for missing translations. + # config.i18n.raise_on_missing_translations = true + + # Annotate rendered view with file names. + # config.action_view.annotate_rendered_view_with_filenames = true + + config.time_zone = "UTC" end diff --git a/config/initializers/carrierwave.rb b/config/initializers/carrierwave.rb deleted file mode 100644 index 0216c18810..0000000000 --- a/config/initializers/carrierwave.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -# Default CarrierWave setup. -# -CarrierWave.configure do |config| - config.permissions = 0o666 - config.directory_permissions = 0o777 - config.storage = :file - config.enable_processing = !Rails.env.test? -end - -if Rails.application.secrets.aws_access_key_id.present? - require "carrierwave/storage/fog" - - region = "eu-west-1" - CarrierWave.configure do |config| - config.storage = :fog - config.fog_provider = "fog/aws" # required - config.fog_credentials = { - provider: "AWS", # required - aws_access_key_id: Rails.application.secrets.aws_access_key_id, # required - aws_secret_access_key: Rails.application.secrets.aws_secret_access_key, # required - region: region, # optional, defaults to 'us-east-1' - host: "s3.#{region}.amazonaws.com" # optional, defaults to nil - } - config.fog_directory = ENV.fetch("AWS_BUCKET_NAME", "decidim-barcelona-new") # required - config.fog_attributes = { "Cache-Control" => "max-age=#{365.days.to_i}" } # optional, defaults to {} - end -end diff --git a/config/initializers/decidim.rb b/config/initializers/decidim.rb index 3e410bed9b..38d39eae73 100644 --- a/config/initializers/decidim.rb +++ b/config/initializers/decidim.rb @@ -1,22 +1,392 @@ # frozen_string_literal: true Decidim.configure do |config| - config.application_name = "Decidim Barcelona" - config.mailer_sender = Rails.application.secrets.email - config.maximum_attachment_size = 150.megabytes + # The name of the application + config.application_name = Rails.application.secrets.decidim[:application_name] - config.available_locales = [:ca, :es] - config.default_locale = :ca + # The email that will be used as sender in all emails from Decidim + config.mailer_sender = Rails.application.secrets.decidim[:mailer_sender] - config.base_uploads_path = "#{ENV["HEROKU_APP_NAME"]}/" if ENV["HEROKU_APP_NAME"].present? + # Sets the list of available locales for the whole application. + # + # When an organization is created through the System area, system admins will + # be able to choose the available languages for that organization. That list + # of languages will be equal or a subset of the list in this file. + config.available_locales = Rails.application.secrets.decidim[:available_locales].presence || [:en] + # Or block set it up manually and prevent ENV manipulation: + # config.available_locales = %w(en ca es) - if Rails.application.secrets.geocoder + # Sets the default locale for new organizations. When creating a new + # organization from the System area, system admins will be able to overwrite + # this value for that specific organization. + config.default_locale = Rails.application.secrets.decidim[:default_locale].presence || :en + + # Restrict access to the system part with an authorized ip list. + # You can use a single ip like ("1.2.3.4"), or an ip subnet like ("1.2.3.4/24") + # You may specify multiple ip in an array ["1.2.3.4", "1.2.3.4/24"] + config.system_accesslist_ips = Rails.application.secrets.decidim[:system_accesslist_ips] if Rails.application.secrets.decidim[:system_accesslist_ips].present? + + # Defines a list of custom content processors. They are used to parse and + # render specific tags inside some user-provided content. Check the docs for + # more info. + # config.content_processors = [] + + # Whether SSL should be enabled or not. + # if this var is not defined, it is decided automatically per-rails-environment + config.force_ssl = Rails.application.secrets.decidim[:force_ssl].present? unless Rails.application.secrets.decidim[:force_ssl] == "auto" + # or set it up manually and prevent any ENV manipulation: + # config.force_ssl = true + + # Enable the service worker. By default is disabled in development and enabled in the rest of environments + config.service_worker_enabled = Rails.application.secrets.decidim[:service_worker_enabled].present? + + # Map and Geocoder configuration + # + # == HERE Maps == + # config.maps = { + # provider: :here, + # api_key: Rails.application.secrets.maps[:api_key], + # static: { url: "https://image.maps.ls.hereapi.com/mia/1.6/mapview" } + # } + # + # == OpenStreetMap (OSM) services == + # To use the OSM map service providers, you will need a service provider for + # the following map servers or host all of them yourself: + # - A tile server for the dynamic maps + # (https://wiki.openstreetmap.org/wiki/Tile_servers) + # - A Nominatim geocoding server for the geocoding functionality + # (https://wiki.openstreetmap.org/wiki/Nominatim) + # - A static map server for static map images + # (https://github.com/jperelli/osm-static-maps) + # + # When used, please read carefully the terms of service for your service + # provider. + # + # config.maps = { + # provider: :osm, + # api_key: Rails.application.secrets.maps[:api_key], + # dynamic: { + # tile_layer: { + # url: "https://tiles.example.org/{z}/{x}/{y}.png?key={apiKey}&{foo}", + # api_key: true, + # foo: "bar=baz", + # attribution: %( + # © OpenStreetMap contributors + # ).strip + # # Translatable attribution: + # # attribution: -> { I18n.t("tile_layer_attribution") } + # } + # }, + # static: { url: "https://staticmap.example.org/" }, + # geocoding: { host: "nominatim.example.org", use_https: true } + # } + # + # == Combination (OpenStreetMap default + HERE Maps dynamic map tiles) == + # config.maps = { + # provider: :osm, + # api_key: Rails.application.secrets.maps[:api_key], + # dynamic: { + # provider: :here, + # api_key: Rails.application.secrets.maps[:here_api_key] + # }, + # static: { url: "https://staticmap.example.org/" }, + # geocoding: { host: "nominatim.example.org", use_https: true } + # } + + # Geocoder configurations if you want to customize the default geocoding + # settings. The maps configuration will manage which geocoding service to use, + # so that does not need any additional configuration here. Use this only for + # the global geocoder preferences. + # config.geocoder = { + # # geocoding service request timeout, in seconds (default 3): + # timeout: 5, + # # set default units to kilometers: + # units: :km, + # # caching (see https://github.com/alexreisner/geocoder#caching for details): + # cache: Redis.new, + # cache_prefix: "..." + # } + if Rails.application.secrets.maps.present? && Rails.application.secrets.maps[:static_provider].present? + static_provider = Rails.application.secrets.maps[:static_provider] + dynamic_provider = Rails.application.secrets.maps[:dynamic_provider] + dynamic_url = Rails.application.secrets.maps[:dynamic_url] + static_url = Rails.application.secrets.maps[:static_url] + static_url = "https://image.maps.ls.hereapi.com/mia/1.6/mapview" if static_provider == "here" && static_url.blank? config.maps = { - provider: :here, - api_key: Rails.application.secrets.geocoder[:here_api_key], - static: { url: "https://image.maps.ls.hereapi.com/mia/1.6/mapview" } + provider: static_provider, + api_key: Rails.application.secrets.maps[:static_api_key], + static: { url: static_url }, + dynamic: { + provider: dynamic_provider, + api_key: Rails.application.secrets.maps[:dynamic_api_key] + } } + config.maps[:geocoding] = { host: Rails.application.secrets.maps[:geocoding_host], use_https: true } if Rails.application.secrets.maps[:geocoding_host] + config.maps[:dynamic][:tile_layer] = {} + config.maps[:dynamic][:tile_layer][:url] = dynamic_url if dynamic_url + config.maps[:dynamic][:tile_layer][:attribution] = Rails.application.secrets.maps[:attribution] if Rails.application.secrets.maps[:attribution] + if Rails.application.secrets.maps[:extra_vars].present? + vars = URI.decode_www_form(Rails.application.secrets.maps[:extra_vars]) + vars.each do |key, value| + # perform a naive type conversion + config.maps[:dynamic][:tile_layer][key] = case value + when /^true$|^false$/i + value.downcase == "true" + when /\A[-+]?\d+\z/ + value.to_i + else + value + end + end + end + end + + # Custom resource reference generator method. Check the docs for more info. + # config.reference_generator = lambda do |resource, component| + # # Implement your custom method to generate resources references + # "1234-#{resource.id}" + # end + + # Currency unit + config.currency_unit = Rails.application.secrets.decidim[:currency_unit] if Rails.application.secrets.decidim[:currency_unit].present? + + # Workaround to enable SVG assets cors + config.cors_enabled = Rails.application.secrets.decidim[:cors_enabled].present? + + # Defines the quality of image uploads after processing. Image uploads are + # processed by Decidim, this value helps reduce the size of the files. + config.image_uploader_quality = Rails.application.secrets.decidim[:image_uploader_quality].to_i + + config.maximum_attachment_size = Rails.application.secrets.decidim[:maximum_attachment_size].to_i.megabytes + config.maximum_avatar_size = Rails.application.secrets.decidim[:maximum_avatar_size].to_i.megabytes + + # The number of reports which a resource can receive before hiding it + config.max_reports_before_hiding = Rails.application.secrets.decidim[:max_reports_before_hiding].to_i + + # Custom HTML Header snippets + # + # The most common use is to integrate third-party services that require some + # extra JavaScript or CSS. Also, you can use it to add extra meta tags to the + # HTML. Note that this will only be rendered in public pages, not in the admin + # section. + # + # Before enabling this you should ensure that any tracking that might be done + # is in accordance with the rules and regulations that apply to your + # environment and usage scenarios. This component also comes with the risk + # that an organization's administrator injects malicious scripts to spy on or + # take over user accounts. + # + config.enable_html_header_snippets = Rails.application.secrets.decidim[:enable_html_header_snippets].present? + + # Allow organizations admins to track newsletter links. + config.track_newsletter_links = Rails.application.secrets.decidim[:track_newsletter_links].present? unless Rails.application.secrets.decidim[:track_newsletter_links] == "auto" + + # Amount of time that the download your data files will be available in the server. + config.download_your_data_expiry_time = Rails.application.secrets.decidim[:download_your_data_expiry_time].to_i.days + + # Max requests in a time period to prevent DoS attacks. Only applied on production. + config.throttling_max_requests = Rails.application.secrets.decidim[:throttling_max_requests].to_i + + # Time window in which the throttling is applied. + config.throttling_period = Rails.application.secrets.decidim[:throttling_period].to_i.minutes + + # Time window were users can access the website even if their email is not confirmed. + config.unconfirmed_access_for = Rails.application.secrets.decidim[:unconfirmed_access_for].to_i.days + + # A base path for the uploads. If set, make sure it ends in a slash. + # Uploads will be set to `/uploads/`. This can be useful if you + # want to use the same uploads place for both staging and production + # environments, but in different folders. + # + # If not set, it will be ignored. + config.base_uploads_path = Rails.application.secrets.decidim[:base_uploads_path] if Rails.application.secrets.decidim[:base_uploads_path].present? + + # SMS gateway configuration + # + # If you want to verify your users by sending a verification code via + # SMS you need to provide a SMS gateway service class. + # + # An example class would be something like: + # + # class MySMSGatewayService + # attr_reader :mobile_phone_number, :code + # + # def initialize(mobile_phone_number, code) + # @mobile_phone_number = mobile_phone_number + # @code = code + # end + # + # def deliver_code + # # Actual code to deliver the code + # true + # end + # end + # + # config.sms_gateway_service = "MySMSGatewayService" + + # Timestamp service configuration + # + # Provide a class to generate a timestamp for a document. The instances of + # this class are initialized with a hash containing the :document key with + # the document to be timestamped as value. The istances respond to a + # timestamp public method with the timestamp + # + # An example class would be something like: + # + # class MyTimestampService + # attr_accessor :document + # + # def initialize(args = {}) + # @document = args.fetch(:document) + # end + # + # def timestamp + # # Code to generate timestamp + # "My timestamp" + # end + # end + # + # + config.timestamp_service = "TimestampService" + + # PDF signature service configuration + # + # Provide a class to process a pdf and return the document including a + # digital signature. The instances of this class are initialized with a hash + # containing the :pdf key with the pdf file content as value. The instances + # respond to a signed_pdf method containing the pdf with the signature + # + # An example class would be something like: + # + # class MyPDFSignatureService + # attr_accessor :pdf + # + # def initialize(args = {}) + # @pdf = args.fetch(:pdf) + # end + # + # def signed_pdf + # # Code to return the pdf signed + # end + # end + # + config.pdf_signature_service = "PdfSignatureBarcelona" + + # Etherpad configuration + # + # Only needed if you want to have Etherpad integration with Decidim. See + # Decidim docs at https://docs.decidim.org/en/services/etherpad/ in order to set it up. + # + if Rails.application.secrets.etherpad.present? && Rails.application.secrets.etherpad[:server].present? + config.etherpad = { + server: Rails.application.secrets.etherpad[:server], + api_key: Rails.application.secrets.etherpad[:api_key], + api_version: Rails.application.secrets.etherpad[:api_version] + } + end + + # Sets Decidim::Exporters::CSV's default column separator + config.default_csv_col_sep = Rails.application.secrets.decidim[:default_csv_col_sep] if Rails.application.secrets.decidim[:default_csv_col_sep].present? + + # The list of roles a user can have, not considering the space-specific roles. + # config.user_roles = %w(admin user_manager) + + # The list of visibility options for amendments. An Array of Strings that + # serve both as locale keys and values to construct the input collection in + # Decidim::Amendment::VisibilityStepSetting::options. + # + # This collection is used in Decidim::Admin::SettingsHelper to generate a + # radio buttons collection input field form for a Decidim::Component + # step setting :amendments_visibility. + # config.amendments_visibility_options = %w(all participants) + + # Machine Translation Configuration + # + # See Decidim docs at https://docs.decidim.org/en/develop/machine_translations/ + # for more information about how it works and how to set it up. + # + # Enable machine translations + config.enable_machine_translations = false + # + # If you want to enable machine translation you can create your own service + # to interact with third party service to translate the user content. + # + # If you still want to use "Decidim::Dev::DummyTranslator" as translator placeholder, + # add the follwing line at the beginning of this file: + # require "decidim/dev/dummy_translator" + # + # An example class would be something like: + # + # class MyTranslationService + # attr_reader :text, :original_locale, :target_locale + # + # def initialize(text, original_locale, target_locale) + # @text = text + # @original_locale = original_locale + # @target_locale = target_locale + # end + # + # def translate + # # Actual code to translate the text + # end + # end + # + # config.machine_translation_service = "MyTranslationService" + + # Defines the name of the cookie used to check if the user allows Decidim to + # set cookies. + config.consent_cookie_name = Rails.application.secrets.decidim[:consent_cookie_name] if Rails.application.secrets.decidim[:consent_cookie_name].present? + + # Defines data consent categories and the data stored in each category. + # config.consent_categories = [ + # { + # slug: "essential", + # mandatory: true, + # items: [ + # { + # type: "cookie", + # name: "_session_id" + # }, + # { + # type: "cookie", + # name: Decidim.consent_cookie_name + # } + # ] + # }, + # { + # slug: "preferences", + # mandatory: false + # }, + # { + # slug: "analytics", + # mandatory: false + # }, + # { + # slug: "marketing", + # mandatory: false + # } + # ] + + # Admin admin password configurations + Rails.application.secrets.dig(:decidim, :admin_password, :strong).tap do |strong_pw| + # When the strong password is not configured, default to true + config.admin_password_strong = strong_pw.nil? ? true : strong_pw.present? + end + config.admin_password_expiration_days = Rails.application.secrets.dig(:decidim, :admin_password, :expiration_days).presence || 90 + config.admin_password_min_length = Rails.application.secrets.dig(:decidim, :admin_password, :min_length).presence || 15 + config.admin_password_repetition_times = Rails.application.secrets.dig(:decidim, :admin_password, :repetition_times).presence || 5 + + # Additional optional configurations (see decidim-core/lib/decidim/core.rb) + config.cache_key_separator = Rails.application.secrets.decidim[:cache_key_separator] if Rails.application.secrets.decidim[:cache_key_separator].present? + config.expire_session_after = Rails.application.secrets.decidim[:expire_session_after].to_i.minutes if Rails.application.secrets.decidim[:expire_session_after].present? + config.enable_remember_me = Rails.application.secrets.decidim[:enable_remember_me].present? unless Rails.application.secrets.decidim[:enable_remember_me] == "auto" + if Rails.application.secrets.decidim[:session_timeout_interval].present? + config.session_timeout_interval = Rails.application.secrets.decidim[:session_timeout_interval].to_i.seconds end + config.follow_http_x_forwarded_host = Rails.application.secrets.decidim[:follow_http_x_forwarded_host].present? + config.maximum_conversation_message_length = Rails.application.secrets.decidim[:maximum_conversation_message_length].to_i + config.password_blacklist = Rails.application.secrets.decidim[:password_blacklist] if Rails.application.secrets.decidim[:password_blacklist].present? + config.allow_open_redirects = Rails.application.secrets.decidim[:allow_open_redirects] if Rails.application.secrets.decidim[:allow_open_redirects].present? if Rails.application.secrets.sms.values.all?(&:present?) config.sms_gateway_service = "SmsGateway" @@ -28,13 +398,106 @@ auth.ephemerable = true end end +end - config.timestamp_service = "TimestampService" - config.pdf_signature_service = "PdfSignatureBarcelona" +if Decidim.module_installed? :api + Decidim::Api.configure do |config| + config.schema_max_per_page = Rails.application.secrets.dig(:decidim, :api, :schema_max_per_page).presence || 50 + config.schema_max_complexity = Rails.application.secrets.dig(:decidim, :api, :schema_max_complexity).presence || 5000 + config.schema_max_depth = Rails.application.secrets.dig(:decidim, :api, :schema_max_depth).presence || 15 + end +end + +if Decidim.module_installed? :proposals + Decidim::Proposals.configure do |config| + config.similarity_threshold = Rails.application.secrets.dig(:decidim, :proposals, :similarity_threshold).presence || 0.25 + config.similarity_limit = Rails.application.secrets.dig(:decidim, :proposals, :similarity_limit).presence || 10 + config.participatory_space_highlighted_proposals_limit = Rails.application.secrets.dig(:decidim, :proposals, :participatory_space_highlighted_proposals_limit).presence || 4 + config.process_group_highlighted_proposals_limit = Rails.application.secrets.dig(:decidim, :proposals, :process_group_highlighted_proposals_limit).presence || 3 + end +end + +if Decidim.module_installed? :meetings + Decidim::Meetings.configure do |config| + config.upcoming_meeting_notification = Rails.application.secrets.dig(:decidim, :meetings, :upcoming_meeting_notification).to_i.days + if Rails.application.secrets.dig(:decidim, :meetings, :embeddable_services).present? + config.embeddable_services = Rails.application.secrets.dig(:decidim, :meetings, :embeddable_services) + end + unless Rails.application.secrets.dig(:decidim, :meetings, :enable_proposal_linking) == "auto" + config.enable_proposal_linking = Rails.application.secrets.dig(:decidim, :meetings, :enable_proposal_linking).present? + end + end +end - config.etherpad = Rails.application.secrets.etherpad if Rails.application.secrets.etherpad[:server].present? +if Decidim.module_installed? :budgets + Decidim::Budgets.configure do |config| + unless Rails.application.secrets.dig(:decidim, :budgets, :enable_proposal_linking) == "auto" + config.enable_proposal_linking = Rails.application.secrets.dig(:decidim, :budgets, :enable_proposal_linking).present? + end + end end +if Decidim.module_installed? :accountability + Decidim::Accountability.configure do |config| + unless Rails.application.secrets.dig(:decidim, :accountability, :enable_proposal_linking) == "auto" + config.enable_proposal_linking = Rails.application.secrets.dig(:decidim, :accountability, :enable_proposal_linking).present? + end + end +end + +if Decidim.module_installed? :consultations + Decidim::Consultations.configure do |config| + config.stats_cache_expiration_time = Rails.application.secrets.dig(:decidim, :consultations, :stats_cache_expiration_time).to_i.minutes + end +end + +if Decidim.module_installed? :initiatives + Decidim::Initiatives.configure do |config| + unless Rails.application.secrets.dig(:decidim, :initiatives, :creation_enabled) == "auto" + config.creation_enabled = Rails.application.secrets.dig(:decidim, :initiatives, :creation_enabled).present? + end + config.similarity_threshold = Rails.application.secrets.dig(:decidim, :initiatives, :similarity_threshold).presence || 0.25 + config.similarity_limit = Rails.application.secrets.dig(:decidim, :initiatives, :similarity_limit).presence || 5 + config.minimum_committee_members = Rails.application.secrets.dig(:decidim, :initiatives, :minimum_committee_members).presence || 2 + config.default_signature_time_period_length = Rails.application.secrets.dig(:decidim, :initiatives, :default_signature_time_period_length).presence || 120 + config.default_components = Rails.application.secrets.dig(:decidim, :initiatives, :default_components) + config.first_notification_percentage = Rails.application.secrets.dig(:decidim, :initiatives, :first_notification_percentage).presence || 33 + config.second_notification_percentage = Rails.application.secrets.dig(:decidim, :initiatives, :second_notification_percentage).presence || 66 + config.stats_cache_expiration_time = Rails.application.secrets.dig(:decidim, :initiatives, :stats_cache_expiration_time).to_i.minutes + config.max_time_in_validating_state = Rails.application.secrets.dig(:decidim, :initiatives, :max_time_in_validating_state).to_i.days + unless Rails.application.secrets.dig(:decidim, :initiatives, :print_enabled) == "auto" + config.print_enabled = Rails.application.secrets.dig(:decidim, :initiatives, :print_enabled).present? + end + config.do_not_require_authorization = Rails.application.secrets.dig(:decidim, :initiatives, :do_not_require_authorization).present? + end +end + +if Decidim.module_installed? :elections + Decidim::Elections.configure do |config| + config.setup_minimum_hours_before_start = Rails.application.secrets.dig(:elections, :setup_minimum_hours_before_start).presence || 3 + config.start_vote_maximum_hours_before_start = Rails.application.secrets.dig(:elections, :start_vote_maximum_hours_before_start).presence || 6 + config.voter_token_expiration_minutes = Rails.application.secrets.dig(:elections, :voter_token_expiration_minutes).presence || 120 + end + + Decidim::Votings.configure do |config| + config.check_census_max_requests = Rails.application.secrets.dig(:elections, :votings, :check_census_max_requests).presence || 5 + config.throttling_period = Rails.application.secrets.dig(:elections, :votings, :throttling_period).to_i.minutes + end + + Decidim::Votings::Census.configure do |config| + config.census_access_codes_export_expiry_time = Rails.application.secrets.dig(:elections, :votings, :census, :access_codes_export_expiry_time).to_i.days + end +end + +if Decidim.module_installed? :verifications + Decidim::Verifications.configure do |config| + config.document_types = Rails.application.secrets.dig(:verifications, :document_types).presence || %w(identification_number passport) + end +end + +# Inform Decidim about the assets folder +Decidim.register_assets_path File.expand_path("app/packs", Rails.application.root) + Decidim::Verifications.register_workflow(:census_authorization_handler) do |auth| auth.form = "CensusAuthorizationHandler" auth.renewable = true @@ -61,5 +524,23 @@ auth.ephemerable = true end -# Inform Decidim about the assets folder -Decidim.register_assets_path File.expand_path("app/packs", Rails.application.root) +Decidim::Verifications.register_workflow(:census_kids_authorization_handler) do |auth| + auth.form = "CensusKidsAuthorizationHandler" + auth.renewable = true + auth.time_between_renewals = 1.day + auth.metadata_cell = "census_kids_authorization_metadata" +end + +Decidim::Verifications.register_workflow(:census_sarria_sant_gervasi_authorization_handler) do |auth| + auth.form = "CensusSarriaSantGervasiAuthorizationHandler" + auth.renewable = true + auth.time_between_renewals = 1.day + auth.metadata_cell = "census_sarria_sant_gervasi_authorization_metadata" + auth.ephemerable = true +end + +Decidim.icons.register(name: "arrow-bottom", icon: "arrow-bottom", category: "system", description: "", engine: :core) +Decidim.icons.register(name: "audio", icon: "audio", category: "system", description: "", engine: :core) +Decidim.icons.register(name: "fingerprint-2-line", icon: "fingerprint-2-line", category: "system", description: "", engine: :core) +Decidim.icons.register(name: "link-intact", icon: "link-intact", category: "system", description: "", engine: :core) +Decidim.icons.register(name: "route-line", icon: "route-line", category: "system", description: "", engine: :core) diff --git a/config/initializers/decidim_overrides.rb b/config/initializers/decidim_overrides.rb index c9dde75854..2e9fe94632 100644 --- a/config/initializers/decidim_overrides.rb +++ b/config/initializers/decidim_overrides.rb @@ -1,11 +1,15 @@ # frozen_string_literal: true Rails.application.config.to_prepare do + Decidim::PaginateHelper.include(Decidim::PaginateHelperOverride) Decidim::Initiatives::Admin::Permissions.prepend(Decidim::Initiatives::Admin::PermissionsOverride) - Decidim::Initiatives::InitiativeMCell.prepend Decidim::Overrides::Initiatives::InitiativeMCell + Decidim::SearchResourceFieldsMapper.prepend(Decidim::Overrides::SearchResourceFieldsMapper) + Decidim::Initiatives::InitiativeMetadataGCell.include(Decidim::Initiatives::InitiativeMetadataGCellOverride) + Decidim::Forms::UserAnswersSerializer.prepend(Decidim::Overrides::Forms::UserAnswersSerializer) Decidim::Initiative.include(Decidim::InitiativeOverride) Decidim::Accountability::Result.include(Decidim::Accountability::ResultOverride) Decidim::Accountability::ResultsCalculator.include(Decidim::Accountability::ResultsCalculatorOverride) + Decidim::Accountability::StatusCell.include(Decidim::Accountability::StatusCellOverride) Decidim::Meetings::Meeting.include(Decidim::Meetings::MeetingOverride) Decidim::Meetings::MeetingsController.include(Decidim::Meetings::MeetingsControllerOverride) Decidim::Meetings::OnlineMeetingCell.include(Decidim::Meetings::OnlineMeetingCellOverride) @@ -13,4 +17,15 @@ Decidim::Meetings::JoinMeetingButtonCell.include(Decidim::Meetings::JoinMeetingButtonCellOverride) Decidim::ContentBlocks::LastActivityCell.include(Decidim::ContentBlocks::LastActivityCellOverride) Decidim::ActivitiesCell.include(Decidim::ActivitiesCellOverride) + Decidim::UserProfileCell.include(Decidim::UserProfileCellOverride) + Decidim::Proposals::ProposalPresenter.include(Decidim::Proposals::ProposalPresenterOverride) + Decidim::Forms::QuestionnaireUserAnswers.include(Decidim::Forms::QuestionnaireUserAnswersOverride) + Decidim::Proposals::ApplicationHelper.include(Decidim::Proposals::ApplicationHelperOverride) + Decidim::Assemblies::AssembliesController.include(Decidim::Assemblies::AssembliesControllerOverride) + # This last one will be removed once https://github.com/decidim/decidim/pull/13402 is used + Decidim::ViewModel.class_eval do + def cache_expiry_time + 5.minutes + end + end end diff --git a/config/initializers/meetings_override.rb b/config/initializers/meetings_override.rb deleted file mode 100644 index db2bf36c20..0000000000 --- a/config/initializers/meetings_override.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -# Hack to allow custom url for online iframes (Note: create a fix PR for Decidim with a configurable var for this) -Rails.application.config.to_prepare do - Decidim::Meetings::MeetingIframeEmbedder.class_eval do - Decidim::Meetings::MeetingIframeEmbedder.send(:remove_const, :EMBEDDABLE_SERVICES) - Decidim::Meetings::MeetingIframeEmbedder.const_set(:EMBEDDABLE_SERVICES, %( www.youtube.com www.twitch.tv meet.jit.si salavirtual.barcelona.cat )) - end -end diff --git a/config/initializers/origami_date.rb b/config/initializers/origami_date.rb new file mode 100644 index 0000000000..f217daaa1a --- /dev/null +++ b/config/initializers/origami_date.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require "English" + +# Fix error: ArgumentError (wrong number of arguments (given 1, expected 0; required keyword: year)) +# @see https://github.com/gdelugre/origami/issues/80 +module Origami + class Date < LiteralString + def self.parse(str) + raise InvalidDateError, "Not a valid Date string" unless str =~ REGEXP_TOKEN + + date = { year: $LAST_MATCH_INFO["year"].to_i } + + date[:month] = $LAST_MATCH_INFO["month"].to_i if $LAST_MATCH_INFO["month"] + date[:day] = $LAST_MATCH_INFO["day"].to_i if $LAST_MATCH_INFO["day"] + date[:hour] = $LAST_MATCH_INFO["hour"].to_i if $LAST_MATCH_INFO["hour"] + date[:min] = $LAST_MATCH_INFO["min"].to_i if $LAST_MATCH_INFO["min"] + date[:sec] = $LAST_MATCH_INFO["sec"].to_i if $LAST_MATCH_INFO["sec"] + + if %w(+ -).include?($LAST_MATCH_INFO["ut"]) + utc_offset = ($LAST_MATCH_INFO["ut_hour_off"].to_i * 3600) + ($LAST_MATCH_INFO["ut_min_off"].to_i * 60) + utc_offset = -utc_offset if $LAST_MATCH_INFO["ut"] == "-" + + date[:utc_offset] = utc_offset + end + + Origami::Date.new(**date) + end + + def self.now + now = Time.now.utc + + date = { year: now.strftime("%Y").to_i, month: now.strftime("%m").to_i, day: now.strftime("%d").to_i, + hour: now.strftime("%H").to_i, min: now.strftime("%M").to_i, sec: now.strftime("%S").to_i, + utc_offset: now.utc_offset } + + Origami::Date.new(**date) + end + end +end diff --git a/config/initializers/redis.rb b/config/initializers/redis.rb index 26b8b9d7ef..20c03d4321 100644 --- a/config/initializers/redis.rb +++ b/config/initializers/redis.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true # rubocop:disable Style/GlobalVars -$redis = Redis.new(url: ENV["REDIS_URL"], ssl_params: { verify_mode: OpenSSL::SSL::VERIFY_NONE }) if Rails.env.production? +$redis = Redis.new(url: ENV.fetch("REDIS_URL", nil), ssl_params: { verify_mode: OpenSSL::SSL::VERIFY_NONE }) if Rails.env.production? # rubocop:enable Style/GlobalVars diff --git a/config/initializers/sentry.rb b/config/initializers/sentry.rb index fa067b9c58..587535a8ac 100644 --- a/config/initializers/sentry.rb +++ b/config/initializers/sentry.rb @@ -2,7 +2,9 @@ if Rails.application.secrets.sentry_enabled Sentry.init do |config| - config.dsn = ENV["SENTRY_DSN"] + config.dsn = ENV.fetch("SENTRY_DSN", nil) + config.traces_sample_rate = ENV.fetch("SENTRY_TRACES_SAMPLE_RATE", "0.5").to_f + config.profiles_sample_rate = ENV.fetch("SENTRY_PROFILES_SAMPLE_RATE", "0.5").to_f config.environment = ENV["HEROKU_APP_NAME"].presence || "production" config.breadcrumbs_logger = [:active_support_logger] diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb index 0b3bfe9f79..de9f184ac6 100644 --- a/config/initializers/sidekiq.rb +++ b/config/initializers/sidekiq.rb @@ -2,11 +2,11 @@ if Rails.env.production? Sidekiq.configure_server do |config| - config.redis = { url: ENV["REDIS_URL"], ssl_params: { verify_mode: OpenSSL::SSL::VERIFY_NONE } } + config.redis = { url: ENV.fetch("REDIS_URL", nil), ssl_params: { verify_mode: OpenSSL::SSL::VERIFY_NONE } } end Sidekiq.configure_client do |config| - config.redis = { url: ENV["REDIS_URL"], ssl_params: { verify_mode: OpenSSL::SSL::VERIFY_NONE } } + config.redis = { url: ENV.fetch("REDIS_URL", nil), ssl_params: { verify_mode: OpenSSL::SSL::VERIFY_NONE } } end Sidekiq.strict_args!(false) diff --git a/config/initializers/social_share_button.rb b/config/initializers/social_share_button.rb deleted file mode 100644 index 592835b1c5..0000000000 --- a/config/initializers/social_share_button.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true - -# Further information on how to configure the SocialShareButton gem can be -# found here: https://github.com/huacnlee/social-share-button#configure -# -SocialShareButton.configure do |config| - config.allow_sites = %w(twitter facebook whatsapp_app whatsapp_web telegram) -end diff --git a/config/locales/accountability.ca.yml b/config/locales/accountability.ca.yml index 95a2adf710..c86c37c494 100644 --- a/config/locales/accountability.ca.yml +++ b/config/locales/accountability.ca.yml @@ -59,80 +59,87 @@ ca: heading: L’Ajuntament ret comptes intro_text: Estrenem la Rendició de Comptes al Decidim Barcelona. Un espai en què l'Ajuntament de Barcelona ret comptes a la ciutadania sobre els seus objectius i resultats. go_to_link: Anar a la pàgina - tab_1: Planificació i estratègia municipal - tab_2: Recursos econòmics i pressupostos - tab_3: Prestació de serveis i gestió pública - tab_4: Gestió ètica y bon govern - tab_1_heading_1: PAM 2016-2019 - tab_1_text_1: | -

    El Programa d’Actuació Municipal (PAM) és el document i eina de gestió que defineix l'estratègia municipal per a un mandat. En aquest apartat podràs accedir als diferents documents i informació relativa al PAM.

    -
      -
    • Dades quantitatives agregades per eixos, línies, actuacions i projectes
    • -
    • Informació en cada una de las actuacions, propostes i aportacions d’entitats i de la ciutadania, desglossades en projectes, amb l’estat d'execució detallat
    • -
    - tab_1_heading_2: Plans estratègics municipals - tab_1_text_2: | -

    Els plans estratègics són conjunts de mesures polítiques i econòmiques dirigides a resoldre problemes o situacions determinades, que inclouen els mitjans per aconseguir-ho, les responsabilitats i les dates de compliment.

    - tab_1_heading_3: Processos de participació al Decidim - tab_1_text_3: | -

    En aquest apartat podràs accedir als diferents documents i informació relativa a l'execució dels processos acordats al Decidim.

    - tab_2_heading_1: Econòmica i pressupostària - tab_2_text_1: | -

    Informació sobre com s'assignen, gasten i gestionen els recursos econòmics en relació a l'estratègia i prioritats municipals.

    - tab_2_heading_2: Pressupost - tab_2_link_2: http://ajuntament.barcelona.cat/estrategiaifinances/ca/i-pressupost - tab_2_text_2: | -

    El pressupost és el reflex financer de l'estratègia i prioritats municipals, on els recursos s'assignen a aquells programes i actuacions que permeten avançar cap als objectius definits. En aquesta secció podràs consultar l'estat d'execució dels pressupostos així com accedir a documentació relacionada, per exemple:

    -
      -
    • Pressupost obert: Accedeix a la nova web per saber d’on venen els ingressos (impostos i transferències d’altres administracions) i a quines polítiques i projectes es destinen.
    • -
    • Execució pressupostos 2017: En aquesta secció podràs consultar l'estat d'execució dels pressupostos segons diferents visions o classificacions, així com accedir a la documentació més rellevant relacionada amb els pressupostos de l'Ajuntament.
    • -
    • Execució pressupostos anys anteriors 2001-2016: Aquí podràs accedir als diferents documents relatius als pressupostos liquidats d'anys anteriors a l'exercici actual.
    • -
    • Pressupostos per política de despesa: Informació de recursos pressupostaris (despeses corrents) i indicadors de resultats dels programes de les diferents polítiques de despesa.
    • -
    • Costos basats en activitats (ABC): Indicadors de costos unitaris dels diferents equipaments i serveis municipals.
    • -
    - tab_2_heading_3: Resultats i informes financers - tab_2_link_3: http://ajuntament.barcelona.cat/estrategiaifinances/ca/i-compte-de-resultats - tab_2_text_3: | -

    L'Ajuntament s'orienta a l'obtenció de resultats en termes del Sistema Europeu de Comptes, per tal de garantir la solvència, estabilitat i sostenibilitat de les finances municipals. En aquest apartat podràs consultar la previsió del resultat de l'exercici corrent, així com els principals informes financers de l'Ajuntament i la Informació sobre el pagament a empreses proveïdores.

    - tab_2_heading_4: Contratació pública - tab_2_text_4: | -

    Informació sobre els contractes que signa l'Ajuntament, tant concursos i licitacions públiques com contractes menors, entre d'altres:

    - - tab_3_heading_1: Prestació de serveis i gestió pública - tab_3_text_1: | -

    Estem treballant per proporcionar informació sobre l'acompliment de l'Ajuntament respecte als serveis que presta per garantir els drets de la ciutadania. De moment pots accedir a:

    - - tab_4_heading_1: Gestió ètica i bon govern - tab_4_text_1: | -

    Informació sobre les actuacions realitzades i les mesures adoptades per garantir la integritat i la correcta prevenció i gestió de conflictes d'interessos i de males pràctiques.

    - tab_4_heading_2: Informació sobre alts càrrecs - tab_4_text_2: | - - tab_4_heading_3: Transparència - tab_4_text_3: | - - tab_4_heading_4: Prevenció de la corrupció - tab_4_text_4: | -
      -
    • Codi de conducta: El codi recull els principis ètics i els valors de bona governança que han d'informar tota actuació municipal. També regula les normes de conducta i de conflictes d'interessos. El codi determina els mecanismes i procediments per garantir la seva efectivitat, avaluació i impuls.
    • -
    • Bústia Ètica i de Bon Govern: és un canal segur de participació electrònica que neix de la conveniència d'oferir un espai que permeti tenir coneixement de qualsevol acció o omissió contrària als principis de bon govern, com una manera de reforçar la gestió pública.
    • -
    + planificacio: + heading_0: PAM 2016-2019 + heading_1: Plans estratègics municipals + heading_2: Processos de participació al Decidim + link_0: https://www.decidim.barcelona/processes/1 + link_1: https://bcnroc.ajuntament.barcelona.cat/jspui/handle/11703/83559 + link_2: https://www.decidim.barcelona/ + text_0: | +

    El Programa d’Actuació Municipal (PAM) és el document i eina de gestió que defineix l'estratègia municipal per a un mandat. En aquest apartat podràs accedir als diferents documents i informació relativa al PAM.

    +
      +
    • Dades quantitatives agregades per eixos, línies, actuacions i projectes
    • +
    • Informació en cada una de las actuacions, propostes i aportacions d’entitats i de la ciutadania, desglossades en projectes, amb l’estat d'execució detallat
    • +
    + text_1: | +

    Els plans estratègics són conjunts de mesures polítiques i econòmiques dirigides a resoldre problemes o situacions determinades, que inclouen els mitjans per aconseguir-ho, les responsabilitats i les dates de compliment.

    + text_2: | +

    En aquest apartat podràs accedir als diferents documents i informació relativa a l'execució dels processos acordats al Decidim.

    + title: Planificació i estratègia municipal + economia: + heading_0: Econòmica i pressupostària + heading_1: Pressupost + heading_2: Resultats i informes financers + heading_3: Contratació pública + link_1: http://ajuntament.barcelona.cat/estrategiaifinances/ca/i-pressupost + link_2: http://ajuntament.barcelona.cat/estrategiaifinances/ca/i-compte-de-resultats + text_0: | +

    Informació sobre com s'assignen, gasten i gestionen els recursos econòmics en relació a l'estratègia i prioritats municipals.

    + text_1: | +

    El pressupost és el reflex financer de l'estratègia i prioritats municipals, on els recursos s'assignen a aquells programes i actuacions que permeten avançar cap als objectius definits. En aquesta secció podràs consultar l'estat d'execució dels pressupostos així com accedir a documentació relacionada, per exemple:

    +
      +
    • Pressupost obert: Accedeix a la nova web per saber d’on venen els ingressos (impostos i transferències d’altres administracions) i a quines polítiques i projectes es destinen.
    • +
    • Execució pressupostos 2017: En aquesta secció podràs consultar l'estat d'execució dels pressupostos segons diferents visions o classificacions, així com accedir a la documentació més rellevant relacionada amb els pressupostos de l'Ajuntament.
    • +
    • Execució pressupostos anys anteriors 2001-2016: Aquí podràs accedir als diferents documents relatius als pressupostos liquidats d'anys anteriors a l'exercici actual.
    • +
    • Pressupostos per política de despesa: Informació de recursos pressupostaris (despeses corrents) i indicadors de resultats dels programes de les diferents polítiques de despesa.
    • +
    • Costos basats en activitats (ABC): Indicadors de costos unitaris dels diferents equipaments i serveis municipals.
    • +
    + text_2: | +

    L'Ajuntament s'orienta a l'obtenció de resultats en termes del Sistema Europeu de Comptes, per tal de garantir la solvència, estabilitat i sostenibilitat de les finances municipals. En aquest apartat podràs consultar la previsió del resultat de l'exercici corrent, així com els principals informes financers de l'Ajuntament i la Informació sobre el pagament a empreses proveïdores.

    + text_3: | +

    Informació sobre els contractes que signa l'Ajuntament, tant concursos i licitacions públiques com contractes menors, entre d'altres:

    + + title: Recursos econòmics i pressupostos + serveis: + heading_0: Prestació de serveis i gestió pública + text_0: | +

    Estem treballant per proporcionar informació sobre l'acompliment de l'Ajuntament respecte als serveis que presta per garantir els drets de la ciutadania. De moment pots accedir a:

    + + title: Prestació de serveis i gestió pública + etica: + heading_0: Gestió ètica i bon govern + heading_1: Informació sobre alts càrrecs + heading_2: Transparència + heading_3: Prevenció de la corrupció + text_0: | +

    Informació sobre les actuacions realitzades i les mesures adoptades per garantir la integritat i la correcta prevenció i gestió de conflictes d'interessos i de males pràctiques.

    + text_1: | + + text_2: | + + text_3: | +
      +
    • Codi de conducta: El codi recull els principis ètics i els valors de bona governança que han d'informar tota actuació municipal. També regula les normes de conducta i de conflictes d'interessos. El codi determina els mecanismes i procediments per garantir la seva efectivitat, avaluació i impuls.
    • +
    • Bústia Ètica i de Bon Govern: és un canal segur de participació electrònica que neix de la conveniència d'oferir un espai que permeti tenir coneixement de qualsevol acció o omissió contrària als principis de bon govern, com una manera de reforçar la gestió pública.
    • +
    + title: Gestió ètica y bon govern diff --git a/config/locales/accountability.es.yml b/config/locales/accountability.es.yml index 1ca1f64e1f..3af72b3a69 100644 --- a/config/locales/accountability.es.yml +++ b/config/locales/accountability.es.yml @@ -58,82 +58,88 @@ es: heading: El Ajuntament rinde cuentas intro_text: Estrenamos la Rendición de Cuentas al Decidim Barcelona. Un espacio en que el Ajuntament de Barcelona rinde cuentas, sobre sus objetivos y resultados, a la ciudadanía. go_to_link: Ir al sitio - tab_1: Planificación y estrategia municipal - tab_2: Recursos económicos y presupuestos - tab_3: Prestación de servicios y gestión pública - tab_4: Gestión ética y buen gobierno - tab_1_heading_1: PAM 2016-2019 - tab_1_text_1: | -

    El Programa de Actuación Municipal (PAM) es el documento y herramienta de gestión que define la estrategia municipal para un mandato. En este apartado (en breve) podrás acceder a los diferentes documentos e información relativa al PAM.

    -
      -
    • Datos cuantitativos agregados por ejes, líneas, actuaciones, proyectos
    • -
    • Información de cada una de las actuaciones: Propuestas y las aportaciones de entidades y ciudadanía desglosadas en proyectos, con su estado de ejecución detallado.
    • -
    - tab_1_heading_2: Planes estratégicos municipales - tab_1_text_2: | -

    Los planes estratégicos son conjuntos de medidas políticas y económicas dirigidas a resolver problemas o situaciones determinadas, que incluyen los medios para conseguirlo, las responsabilidades y las fechas de cumplimiento.

    - tab_1_heading_3: Procesos de participación en Decidim - tab_1_text_3: | -

    En este apartado podrás acceder a los diferentes documentos e información relativa a la ejecución de los procesos acordados en Decidim.

    - tab_2_heading_1: Económica y presupuestaria - tab_2_link_1: Económica y presupuestaria - tab_2_text_1: | -

    Información sobre cómo se asignan, gastan y gestionan los recursos económicos en relación a la estrategia y prioridades municipales.

    - tab_2_heading_2: Presupuesto - tab_2_link_2: http://ajuntament.barcelona.cat/estrategiaifinances/es/i-pressupost - tab_2_text_2: | -

    El presupuesto es el reflejo financiero de la estrategia y prioridades municipales, donde los recursos se asignan a aquellos programas y actuaciones que permiten avanzar hacia los objetivos definidos. En esta sección podrás consultar el estado de ejecución de los presupuestos del Ajuntament de Barcelona y acceder a documentación relacionada, por ejemplo:

    -
      -
    • Presupuestos abiertos: Accede a la nueva web para saber de dónde vienen los ingresos (impuestos y transferencias de otras administraciones) y a qué políticas y proyectos se destinan los mismos.
    • -
    • Ejecución presupuesto 2017: En esta sección podrás consultar el estado de ejecución del presupuesto según diferentes visiones o clasificaciones, así como acceder a la documentación más relevante relacionada con los presupuestos del Ajuntament
    • -
    • Ejecución presupuesto años anteriores 2001-2016: Aquí podrás acceder a los diferentes documentos relativos a los presupuestos liquidados de años anteriores al ejercicio actual.
    • -
    • Presupuesto por política de gasto: Información de recursos presupuestarios (gastos corrientes) e indicadores de resultados de los programas de las diferentes políticas de gasto.
    • -
    • Costes basados en actividades (ABC): Indicadores de costes unitarios de los diferentes equipamientos y servicios municipales.
    • -
    - tab_2_heading_3: Resultados e informes financieros - tab_2_link_3: http://ajuntament.barcelona.cat/estrategiaifinances/es/i-compte-de-resultats - tab_2_text_3: | -

    El Ajuntament se orienta a la obtención de resultados en términos del Sistema Europeo de Cuentas, con el fin de garantizar la solvencia, estabilidad y sostenibilidad de las finanzas municipales. En este apartado podrás consultar la previsión del resultado del ejercicio corriente, así como los principales informes financieros del Ajuntament y la Información sobre el pago a empresas proveedoras.

    - tab_2_heading_4: Contratación pública - tab_2_text_4: | -

    Información sobre los contratos que firma el Ajuntament, tanto concursos y licitaciones públicas como contratos menores, entre otros:

    - - tab_3_heading_1: Prestación de servicios y gestión pública - tab_3_text_1: | -

    El Ajuntament sigue trabajando para proporcionar información sobre su desempeño respecto a los servicios que presta para garantizar los derechos de la ciudadanía. De momento puedes acceder a:

    - - tab_4_heading_1: Gestión ética y buen gobierno - tab_4_text_1: | -

    Información sobre las actuaciones realizadas y las medidas adoptadas para garantizar la integridad y la correcta prevención y gestión de conflictos de intereses y de malas prácticas.

    - tab_4_heading_2: Información sobre altos cargos - tab_4_text_2: | - - tab_4_heading_3: Transparencia - tab_4_text_3: | - - tab_4_heading_4: Prevención de la corrupción - tab_4_text_4: | -
      -
    • Código de conducta: El código recoge los principios éticos y los valores de buena gobernanza que deben informar toda actuación municipal. Regula las normas de conducta y de conflictos de intereses y determina los mecanismos y procedimientos para garantizar su efectividad, evaluación e impulso.
    • -
    • Buzón Ético y de Buen Gobierno: Es un canal seguro de participación electrónica que nace de la conveniencia de ofrecer un espacio que permita tener conocimiento de cualquier acción u omisión contraria a los principios de buen gobierno, como una manera de reforzar la gestión pública.
    • -
    + planificacio: + heading_0: PAM 2016-2019 + heading_1: Planes estratégicos municipales + heading_2: Procesos de participación en Decidim + link_0: https://www.decidim.barcelona/processes/1 + link_1: https://bcnroc.ajuntament.barcelona.cat/jspui/handle/11703/83559 + link_2: https://www.decidim.barcelona/ + text_0: | +

    El Programa de Actuación Municipal (PAM) es el documento y herramienta de gestión que define la estrategia municipal para un mandato. En este apartado (en breve) podrás acceder a los diferentes documentos e información relativa al PAM.

    +
      +
    • Datos cuantitativos agregados por ejes, líneas, actuaciones, proyectos
    • +
    • Información de cada una de las actuaciones: Propuestas y las aportaciones de entidades y ciudadanía desglosadas en proyectos, con su estado de ejecución detallado.
    • +
    + text_1: | +

    Los planes estratégicos son conjuntos de medidas políticas y económicas dirigidas a resolver problemas o situaciones determinadas, que incluyen los medios para conseguirlo, las responsabilidades y las fechas de cumplimiento.

    + text_2: | +

    En este apartado podrás acceder a los diferentes documentos e información relativa a la ejecución de los procesos acordados en Decidim.

    + title: Planificación y estrategia municipal + economia: + heading_0: Económica y presupuestaria + heading_1: Presupuesto + heading_2: Resultados e informes financieros + heading_3: Contratación pública + link_1: http://ajuntament.barcelona.cat/estrategiaifinances/es/i-pressupost + link_2: http://ajuntament.barcelona.cat/estrategiaifinances/es/i-compte-de-resultats + text_0: | +

    Información sobre cómo se asignan, gastan y gestionan los recursos económicos en relación a la estrategia y prioridades municipales.

    + text_1: | +

    El presupuesto es el reflejo financiero de la estrategia y prioridades municipales, donde los recursos se asignan a aquellos programas y actuaciones que permiten avanzar hacia los objetivos definidos. En esta sección podrás consultar el estado de ejecución de los presupuestos del Ajuntament de Barcelona y acceder a documentación relacionada, por ejemplo:

    +
      +
    • Presupuestos abiertos: Accede a la nueva web para saber de dónde vienen los ingresos (impuestos y transferencias de otras administraciones) y a qué políticas y proyectos se destinan los mismos.
    • +
    • Ejecución presupuesto 2017: En esta sección podrás consultar el estado de ejecución del presupuesto según diferentes visiones o clasificaciones, así como acceder a la documentación más relevante relacionada con los presupuestos del Ajuntament
    • +
    • Ejecución presupuesto años anteriores 2001-2016: Aquí podrás acceder a los diferentes documentos relativos a los presupuestos liquidados de años anteriores al ejercicio actual.
    • +
    • Presupuesto por política de gasto: Información de recursos presupuestarios (gastos corrientes) e indicadores de resultados de los programas de las diferentes políticas de gasto.
    • +
    • Costes basados en actividades (ABC): Indicadores de costes unitarios de los diferentes equipamientos y servicios municipales.
    • +
    + text_2: | +

    El Ajuntament se orienta a la obtención de resultados en términos del Sistema Europeo de Cuentas, con el fin de garantizar la solvencia, estabilidad y sostenibilidad de las finanzas municipales. En este apartado podrás consultar la previsión del resultado del ejercicio corriente, así como los principales informes financieros del Ajuntament y la Información sobre el pago a empresas proveedoras.

    + text_3: | +

    Información sobre los contratos que firma el Ajuntament, tanto concursos y licitaciones públicas como contratos menores, entre otros:

    + + title: Recursos económicos y presupuestos + serveis: + heading_0: Prestación de servicios y gestión pública + text_0: | +

    El Ajuntament sigue trabajando para proporcionar información sobre su desempeño respecto a los servicios que presta para garantizar los derechos de la ciudadanía. De momento puedes acceder a:

    + + title: Prestación de servicios y gestión pública + etica: + heading_0: Gestión ética y buen gobierno + heading_1: Información sobre altos cargos + heading_2: Transparencia + heading_3: Prevención de la corrupción + text_0: | +

    Información sobre las actuaciones realizadas y las medidas adoptadas para garantizar la integridad y la correcta prevención y gestión de conflictos de intereses y de malas prácticas.

    + text_1: | + + text_2: | + + text_3: | +
      +
    • Código de conducta: El código recoge los principios éticos y los valores de buena gobernanza que deben informar toda actuación municipal. Regula las normas de conducta y de conflictos de intereses y determina los mecanismos y procedimientos para garantizar su efectividad, evaluación e impulso.
    • +
    • Buzón Ético y de Buen Gobierno: Es un canal seguro de participación electrónica que nace de la conveniencia de ofrecer un espacio que permita tener conocimiento de cualquier acción u omisión contraria a los principios de buen gobierno, como una manera de reforzar la gestión pública.
    • +
    + title: Gestión ética y buen gobierno diff --git a/config/locales/ca.yml b/config/locales/ca.yml index 4fcadd80db..e5ae8e13ed 100644 --- a/config/locales/ca.yml +++ b/config/locales/ca.yml @@ -16,6 +16,19 @@ ca: gender: Sexe postal_code: Codi postal scope_id: Districte + census_kids_authorization_handler: + date_of_birth: Data de naixement + document_number: Número de document + document_type: Tipus de document + gender: Sexe + postal_code: Codi postal + scope_id: Districte + census_sarria_sant_gervasi_authorization_handler: + date_of_birth: Data de naixement + document_number: Número de document + document_type: Tipus de document + gender: Sexe + postal_code: Codi postal confirmation: verification_code: Codi de verificació mobile_phone: @@ -58,6 +71,43 @@ ca: age_under: Has de ser major de %{min_age} anys per validar-te invalid_document: El número de document, el tipus de document, la data de naixement o el codi postal són incorrectes. Si us plau, revisa aquestes dades. + census_kids_authorization_handler: + age_under: Has de ser major de %{min_age} anys per validar-te + invalid_document: El número de document, el tipus de document, la data de naixement + o el codi postal són incorrectes. Si us plau, revisa aquestes dades. + census_kids_authorization: + form: + date_select: + day: Dia + month: Mes + year: Any + gender_help: Aquestes dades són voluntàries i es demanen en compliment d'allò + disposat a l'article 56 de la LLEI 17/2015, del 21 de juliol, d'igualtat efectiva + de dones i homes. + gender_prompt: Si us plau, selecciona una opció + genders: + man: Home + non_binary: No binari + woman: Dona + scope_prompt: Si us plau, selecciona el teu districte + census_sarria_sant_gervasi_authorization_handler: + age_under: Has de ser major de %{min_age} anys per validar-te + invalid_document: El número de document, el tipus de document, la data de naixement + o el codi postal són incorrectes. Si us plau, revisa aquestes dades. + census_sarria_sant_gervasi_authorization: + form: + date_select: + day: Dia + month: Mes + year: Any + gender_help: Aquestes dades són voluntàries i es demanen en compliment d'allò + disposat a l'article 56 de la LLEI 17/2015, del 21 de juliol, d'igualtat efectiva + de dones i homes. + gender_prompt: Si us plau, selecciona una opció + genders: + man: Home + non_binary: No binari + woman: Dona decidim: accessibility: external_link: Link extern @@ -104,6 +154,44 @@ ca: postal_code: Codi postal time_and_date: Data i hora timestamp: Segell + filters: + proposals: + evaluated_by_user: + label: Avaluació + values: + "false": No avaluat + "true": Avaluat + internal_evaluation: + admin: + internal_evaluations: + create: + error: "Hi ha hagut un problema en crear l'avaluació interna: %{message}" + success: Avaluació interna creada correctament. + form: + save: Desar + status: Estat + title: Avaluació per a %{title} + index: + actions: Accions + counter: "%{count} de %{total} avaluacions" + edit_evaluation: Edita l'avaluació + evaluation: Avaluació + status: Estat + title: Avaluacions internes + updated: Actualitzat + update: + error: "Hi ha hagut un problema en actualitzar l'avaluació interna: %{message}" + success: Avaluació interna actualitzada correctament. + valuation_assignments_evaluations: + edit_evaluation: Edita l'avaluació + proposals: + admin: + exports: + internal_evaluations: Avaluacions internes + models: + proposal: + fields: + valuators: Estat de l'avaluació authorization_handlers: census16_authorization_handler: explanation: Verifica't amb el padró @@ -125,6 +213,25 @@ ca: postal_code: Codi postal scope: Districte name: El padró + census_kids_authorization_handler: + explanation: Verifica't amb el padró + fields: + date_of_birth: Data de naixement + document_number: Número de document + document_type: Tipus de document + gender: Sexe + postal_code: Codi postal + scope: Districte + name: El padró (majors de 8 anys) + census_sarria_sant_gervasi_authorization_handler: + explanation: Verifica't amb el padró de Sarrià-Sant Gervasi + fields: + date_of_birth: Data de naixement + document_number: Número de document + document_type: Tipus de document + gender: Sexe + postal_code: Codi postal + name: El padró (Sarrià-Sant Gervasi) budgets: projects: budget_confirm: @@ -156,6 +263,16 @@ ca: dni: DNI nie: NIE passport: Passaport + census_kids_authorization_handler: + document_types: + dni: DNI + nie: NIE + passport: Passaport + census_sarria_sant_gervasi_authorization_handler: + document_types: + dni: DNI + nie: NIE + passport: Passaport devise: mailer: confirmation_instructions: @@ -194,18 +311,34 @@ ca: project_proposals: 'Propostes incloses en aquest projecte:' sms: text: 'El teu codi per verificar-te a Decidim Barcelona és: %{code}' + system: + organizations: + edit: + title: Edita organització + new: + default: Per defecte? + enabled: Habilitat + locale: Idioma verifications: authorizations: first_login: actions: census16_authorization_handler: Verifica't amb el padró (16+) census_authorization_handler: Verifica't amb el padró + census_kids_authorization_handler: Verifica't amb el padró (8+) + census_sarria_sant_gervasi_authorization_handler: Verifica't amb el padró de Sarrià-Sant Gervasi census_sms_authorization_handler: Verifica't amb el padró i el teu mòbil valid_auth: Valid auth layouts: decidim: initiative_header_steps: signature_collection_period: Recollida de signatures + system: + login_items: + logout: Tancar sessió + locale: + name: Català + name_with_error: Català (¡error!) errors: messages: not_in_district: El codi postal no pertany al districte diff --git a/config/locales/en.yml b/config/locales/en.yml index 25efe5f525..5e81defeeb 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -19,5 +19,8 @@ en: decidim: initiative_header_steps: signature_collection_period: Recollida de signatures + locale: + name: English + name_with_error: English (error!) menu: accountability_static: Accountability diff --git a/config/locales/es.yml b/config/locales/es.yml index 76ba461dca..eee379b228 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -16,6 +16,19 @@ es: gender: Sexo postal_code: Código postal scope_id: Distrito + census_kids_authorization_handler: + date_of_birth: Fecha de nacimiento + document_number: Número de documento + document_type: Tipo de documento + gender: Sexo + postal_code: Código postal + scope_id: Distrito + census_sarria_sant_gervasi_authorization_handler: + date_of_birth: Fecha de nacimiento + document_number: Número de documento + document_type: Tipo de documento + gender: Sexo + postal_code: Código postal confirmation: verification_code: Código de verificación mobile_phone: @@ -58,6 +71,43 @@ es: age_under: Tienes que ser mayor de %{min_age} años para validarte invalid_document: El número de documento, el tipo de documento, la fecha de nacimiento o el código postal son incorrectos. Por favor, revisa estos datos. + census_kids_authorization_handler: + age_under: Tienes que ser mayor de %{min_age} años para validarte + invalid_document: El número de documento, el tipo de documento, la fecha de nacimiento + o el código postal son incorrectos. Por favor, revisa estos datos. + census_kids_authorization: + form: + date_select: + day: Día + month: Mes + year: Año + gender_help: Estos datos son voluntarios y se piden en cumplimento de lo dispuesto + en el articulo 56 de la LEY 17/2015, del 21 de julio, de igualdad efectiva + de mujeres y hombres. + gender_prompt: Por favor, selecciona una opción + genders: + man: Hombre + non_binary: No binario + woman: Mujer + scope_prompt: Por favor, selecciona tu distrito + census_sarria_sant_gervasi_authorization_handler: + age_under: Tienes que ser mayor de %{min_age} años para validarte + invalid_document: El número de documento, el tipo de documento, la fecha de nacimiento + o el código postal son incorrectos. Por favor, revisa estos datos. + census_sarria_sant_gervasi_authorization: + form: + date_select: + day: Día + month: Mes + year: Año + gender_help: Estos datos son voluntarios y se piden en cumplimento de lo dispuesto + en el articulo 56 de la LEY 17/2015, del 21 de julio, de igualdad efectiva + de mujeres y hombres. + gender_prompt: Por favor, selecciona una opción + genders: + man: Hombre + non_binary: No binario + woman: Mujer decidim: accessibility: external_link: Link externo @@ -104,6 +154,44 @@ es: postal_code: Código postal time_and_date: Fecha y hora timestamp: Sello + filters: + proposals: + evaluated_by_user: + label: Evaluación + values: + "false": No evaluado + "true": Evaluado + internal_evaluation: + admin: + internal_evaluations: + create: + error: "Hubo un problema al crear la evaluación interna: %{message}" + success: Evaluación interna creada correctamente. + form: + save: Guardar + status: Estado + title: Evaluación para %{title} + index: + actions: Acciones + counter: "%{count} de %{total} evaluaciones" + edit_evaluation: Editar evaluación + evaluation: Evaluación + status: Estado + title: Evaluaciones internas + updated: Actualizado + update: + error: "Hubo un problema al actualizar la evaluación interna: %{message}" + success: Evaluación interna actualizada correctamente. + valuation_assignments_evaluations: + edit_evaluation: Editar evaluación + proposals: + admin: + exports: + internal_evaluations: Evaluaciones internas + models: + proposal: + fields: + valuators: Estado de la evaluación authorization_handlers: census16_authorization_handler: explanation: Verifícate con el padrón @@ -125,6 +213,26 @@ es: postal_code: Código postal scope_id: Distrito name: El padrón + census_kids_authorization_handler: + explanation: Verifícate con el padrón + fields: + date_of_birth: Fecha de nacimiento + document_number: Número de documento + document_type: Tipo de documento + gender: Sexo + postal_code: Código postal + scope_id: Distrito + name: El padrón (mayores de 8 años) + census_sarria_sant_gervasi_authorization_handler: + explanation: Verifícate con el padrón de Sarrià-Sant Gervasi + fields: + date_of_birth: Fecha de nacimiento + document_number: Número de documento + document_type: Tipo de documento + gender: Sexo + postal_code: Código postal + scope_id: Distrito + name: El padrón (Sarrirà-Sant Gervasi) budgets: projects: budget_confirm: @@ -155,6 +263,16 @@ es: dni: DNI nie: NIE passport: Pasaporte + census_kids_authorization_handler: + document_types: + dni: DNI + nie: NIE + passport: Pasaporte + census_sarria_sant_gervasi_authorization_handler: + document_types: + dni: DNI + nie: NIE + passport: Pasaporte devise: mailer: confirmation_instructions: @@ -188,15 +306,32 @@ es: project_proposals: 'Propuestas incluidas en este proyecto:' sms: text: 'Tu código para verificarte en Decidim Barcelona es: %{code}' + system: + organizations: + edit: + title: Editar organización + new: + default: ¿Por defecto? + enabled: Habilitado + locale: Idioma verifications: authorizations: first_login: actions: + census16_authorization_handler: Verifícate con el padrón (16+) census_authorization_handler: Verifícate con el padrón + census_kids_authorization_handler: Verifícate con el padrón (8+) + census_sarria_sant_gervasi_authorization_handler: Verifícate con el padrón (8+) layouts: decidim: initiative_header_steps: signature_collection_period: Recogida de firmas + system: + login_items: + logout: Cerrar sesión + locale: + name: Castellano + name_with_error: Castellano (¡error!) errors: messages: not_in_district: El código postal no pertenece al distrito diff --git a/config/puma.rb b/config/puma.rb index ae1c77b4ec..6ce5169b9d 100644 --- a/config/puma.rb +++ b/config/puma.rb @@ -1,15 +1,14 @@ # frozen_string_literal: true # avoid workers for development so console and byebug are working -workers Integer(ENV["WEB_CONCURRENCY"] || 2) if ENV["WEB_CONCURRENCY"] -threads_count = Integer(ENV["RAILS_MAX_THREADS"] || 5) +workers Integer(ENV.fetch("WEB_CONCURRENCY", nil) || 2) if ENV["WEB_CONCURRENCY"] +threads_count = Integer(ENV.fetch("RAILS_MAX_THREADS", nil) || 5) threads threads_count, threads_count preload_app! -rackup DefaultRackup -port ENV["PORT"] || 3000 -environment ENV["RACK_ENV"] || "development" +port ENV.fetch("PORT", nil) || 3000 +environment ENV.fetch("RACK_ENV", nil) || "development" before_fork do require "puma_worker_killer" diff --git a/config/routes.rb b/config/routes.rb index 5f731eae92..7427c3e8c1 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -10,7 +10,6 @@ debates: [:debates, Decidim::Debates::Debate] } - # rubocop:disable Rails/FindBy # rubocop:disable Layout/LineLength constraints host: /(www\.)?decidim\.barcelona/ do get "/:process_slug/:step_id/:component_name/(:resource_id)", to: redirect(DecidimLegacyRoutes.new(component_translations)), @@ -33,19 +32,16 @@ end component = resource.component process = component.participatory_space - component_manifest_name = component.manifest_name - "/processes/#{process.id}/f/#{component.id}/#{component_manifest_name}/#{resource.id}" + component_manifest_name = component.manifest_name == "accountability" ? "results" : component.manifest_name + "/processes/#{process.slug}/f/#{component.id}/#{component_manifest_name}/#{resource.id}" }, constraints: { component_name: Regexp.new(component_translations.keys.join("|")), resource_id: %r{(?!meetings)[^/]*} } end - # rubocop:enable Rails/FindBy # rubocop:enable Layout/LineLength - authenticate :user, ->(u) { u.admin? } do - mount Sidekiq::Web => "/sidekiq" - end - get "/accountability", to: "static#accountability", as: :accountability_static - get "/accountability/sections", to: "static#accountability_sections", as: :accountability_sections + get "/accountability/sections/:section", to: "static#accountability_sections", as: :accountability_sections + + get "/pages/faq", to: redirect("/pages/decidim") scope "/processes/:participatory_process_slug/f/:component_id" do get :export_results, to: "export_results#csv" @@ -54,11 +50,12 @@ post :import_results, to: "decidim/accountability/admin/import_results#create" end - get "/pages/faq", to: redirect("/pages/more-information") - mount Decidim::Core::Engine => "/" - # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html + mount Decidim::EphemeralParticipation::Engine, at: "/", as: "decidim_ephemeral_participation" mount LetterOpenerWeb::Engine, at: "/letter_opener" if Rails.env.development? + authenticate :user, ->(u) { u.admin? } do + mount Sidekiq::Web => "/sidekiq" + end - mount Decidim::EphemeralParticipation::Engine, at: "/", as: "decidim_ephemeral_participation" + # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html end diff --git a/config/secrets.yml b/config/secrets.yml index b68d61841d..d7136965c0 100644 --- a/config/secrets.yml +++ b/config/secrets.yml @@ -10,51 +10,174 @@ # Make sure the secrets in this file are kept private # if you're sharing your code publicly. +decidim_default: &decidim_default + application_name: <%= Decidim::Env.new("DECIDIM_APPLICATION_NAME", "Decidim Barcelona").to_json %> + mailer_sender: <%= Decidim::Env.new("DECIDIM_MAILER_SENDER", "info@decidim.barcelona").to_s %> + available_locales: <%= Decidim::Env.new("DECIDIM_AVAILABLE_LOCALES", "ca,es").to_array.to_json %> + default_locale: <%= Decidim::Env.new("DECIDIM_DEFAULT_LOCALE", "ca").to_s %> + force_ssl: <%= Decidim::Env.new("DECIDIM_FORCE_SSL", "auto").default_or_present_if_exists.to_s %> + enable_html_header_snippets: <%= Decidim::Env.new("DECIDIM_ENABLE_HTML_HEADER_SNIPPETS").to_boolean_string %> + currency_unit: <%= Decidim::Env.new("DECIDIM_CURRENCY_UNIT", "€").to_s %> + cors_enabled: <%= Decidim::Env.new("DECIDIM_CORS_ENABLED").to_boolean_string %> + image_uploader_quality: <%= Decidim::Env.new("DECIDIM_IMAGE_UPLOADER_QUALITY", "80").to_i %> + maximum_attachment_size: <%= Decidim::Env.new("DECIDIM_MAXIMUM_ATTACHMENT_SIZE", "150").to_i %> + maximum_avatar_size: <%= Decidim::Env.new("DECIDIM_MAXIMUM_AVATAR_SIZE", "5").to_i %> + max_reports_before_hiding: <%= Decidim::Env.new("DECIDIM_MAX_REPORTS_BEFORE_HIDING", "3").to_i %> + track_newsletter_links: <%= Decidim::Env.new("DECIDIM_TRACK_NEWSLETTER_LINKS", "auto").default_or_present_if_exists.to_s %> + download_your_data_expiry_time: <%= Decidim::Env.new("DECIDIM_DOWNLOAD_YOUR_DATA_EXPIRY_TIME", "7").to_i %> + throttling_max_requests: <%= Decidim::Env.new("DECIDIM_THROTTLING_MAX_REQUESTS", "100").to_i %> + throttling_period: <%= Decidim::Env.new("DECIDIM_THROTTLING_PERIOD", "1").to_i %> + unconfirmed_access_for: <%= Decidim::Env.new("DECIDIM_UNCONFIRMED_ACCESS_FOR", "0").to_i %> + system_accesslist_ips: <%= Decidim::Env.new("DECIDIM_SYSTEM_ACCESSLIST_IPS").to_array.to_json %> + base_uploads_path: <%= Decidim::Env.new("DECIDIM_BASE_UPLOADS_PATH").to_json %> + default_csv_col_sep: <%= Decidim::Env.new("DECIDIM_DEFAULT_CSV_COL_SEP", ";").to_json %> + consent_cookie_name: <%= Decidim::Env.new("DECIDIM_CONSENT_COOKIE_NAME", "decidim-consent").to_json %> + cache_key_separator: <%= Decidim::Env.new("DECIDIM_CACHE_KEY_SEPARATOR", "/").to_json %> + expire_session_after: <%= Decidim::Env.new("DECIDIM_EXPIRE_SESSION_AFTER", "30").to_i %> + session_timeout_interval: <%= Decidim::Env.new("DECIDIM_SESSION_TIMEOUT_INTERVAL", "10").to_i %> + enable_remember_me: <%= Decidim::Env.new("DECIDIM_ENABLE_REMEMBER_ME", "auto").default_or_present_if_exists.to_s %> + follow_http_x_forwarded_host: <%= Decidim::Env.new("DECIDIM_FOLLOW_HTTP_X_FORWARDED_HOST").to_boolean_string %> + maximum_conversation_message_length: <%= Decidim::Env.new("DECIDIM_MAXIMUM_CONVERSATION_MESSAGE_LENGTH", "1000").to_i %> + password_blacklist: <%= Decidim::Env.new("DECIDIM_PASSWORD_BLACKLIST").to_array(separator: ", ").to_json %> + allow_open_redirects: <%= Decidim::Env.new("DECIDIM_ALLOW_OPEN_REDIRECTS").to_boolean_string %> + service_worker_enabled: <%= Decidim::Env.new("DECIDIM_SERVICE_WORKER_ENABLED", Rails.env.exclude?("development")).to_boolean_string %> + admin_password: + expiration_days: <%= Decidim::Env.new("DECIDIM_ADMIN_PASSWORD_EXPIRATION_DAYS", 90).to_i %> + min_length: <%= Decidim::Env.new("DECIDIM_ADMIN_PASSWORD_MIN_LENGTH", 15).to_i %> + repetition_times: <%= Decidim::Env.new("DECIDIM_ADMIN_PASSWORD_REPETITION_TIMES", 5).to_i %> + strong: <%= Decidim::Env.new("DECIDIM_ADMIN_PASSWORD_STRONG", true).to_boolean_string %> + api: + schema_max_per_page: <%= Decidim::Env.new("API_SCHEMA_MAX_PER_PAGE", 50).to_i %> + schema_max_complexity: <%= Decidim::Env.new("API_SCHEMA_MAX_COMPLEXITY", 5000).to_i %> + schema_max_depth: <%= Decidim::Env.new("API_SCHEMA_MAX_DEPTH", 15).to_i %> + proposals: + similarity_threshold: <%= Decidim::Env.new("PROPOSALS_SIMILARITY_THRESHOLD", 0.25).to_f %> + similarity_limit: <%= Decidim::Env.new("PROPOSALS_SIMILARITY_LIMIT", 10).to_i %> + participatory_space_highlighted_proposals_limit: <%= Decidim::Env.new("PROPOSALS_PARTICIPATORY_SPACE_HIGHLIGHTED_PROPOSALS_LIMIT", 4).to_i %> + process_group_highlighted_proposals_limit: <%= Decidim::Env.new("PROPOSALS_PROCESS_GROUP_HIGHLIGHTED_PROPOSALS_LIMIT", 3).to_i %> + meetings: + upcoming_meeting_notification: <%= Decidim::Env.new("MEETINGS_UPCOMING_MEETING_NOTIFICATION", 2).to_i %> + enable_proposal_linking: <%= Decidim::Env.new("MEETINGS_ENABLE_PROPOSAL_LINKING", "auto").default_or_present_if_exists.to_s %> + embeddable_services: <%= Decidim::Env.new("MEETINGS_EMBEDDABLE_SERVICES").to_array(separator: " ").to_json %> + budgets: + enable_proposal_linking: <%= Decidim::Env.new("BUDGETS_ENABLE_PROPOSAL_LINKING", "auto").default_or_present_if_exists.to_s %> + accountability: + enable_proposal_linking: <%= Decidim::Env.new("ACCOUNTABILITY_ENABLE_PROPOSAL_LINKING", "auto").default_or_present_if_exists.to_s %> + consultations: + stats_cache_expiration_time: <%= Decidim::Env.new("CONSULTATIONS_STATS_CACHE_EXPIRATION_TIME", 5).to_i %> + initiatives: + creation_enabled: <%= Decidim::Env.new("INITIATIVES_CREATION_ENABLED", "auto").default_or_present_if_exists.to_s %> + similarity_threshold: <%= Decidim::Env.new("INITIATIVES_SIMILARITY_THRESHOLD", 0.25).to_f %> + similarity_limit: <%= Decidim::Env.new("INITIATIVES_SIMILARITY_LIMIT", 5).to_i %> + minimum_committee_members: <%= Decidim::Env.new("INITIATIVES_MINIMUM_COMMITTEE_MEMBERS", 2).to_i %> + default_signature_time_period_length: <%= Decidim::Env.new("INITIATIVES_DEFAULT_SIGNATURE_TIME_PERIOD_LENGTH", 120).to_i %> + default_components: <%= Decidim::Env.new("INITIATIVES_DEFAULT_COMPONENTS", "pages, meetings").to_array.to_json %> + first_notification_percentage: <%= Decidim::Env.new("INITIATIVES_FIRST_NOTIFICATION_PERCENTAGE", 33).to_i %> + second_notification_percentage: <%= Decidim::Env.new("INITIATIVES_SECOND_NOTIFICATION_PERCENTAGE", 66).to_i %> + stats_cache_expiration_time: <%= Decidim::Env.new("INITIATIVES_STATS_CACHE_EXPIRATION_TIME", 5).to_i %> + max_time_in_validating_state: <%= Decidim::Env.new("INITIATIVES_MAX_TIME_IN_VALIDATING_STATE", 60).to_i %> + print_enabled: <%= Decidim::Env.new("INITIATIVES_PRINT_ENABLED", "auto").default_or_present_if_exists.to_s %> + do_not_require_authorization: <%= Decidim::Env.new("INITIATIVES_DO_NOT_REQUIRE_AUTHORIZATION").to_boolean_string %> + verifications: + document_types: <%%= Decidim::Env.new("VERIFICATIONS_DOCUMENT_TYPES", %w(identification_number passport)).to_array %> + +elections_default: &elections_default + bulletin_board_server: <%= Decidim::Env.new("ELECTIONS_BULLETIN_BOARD_SERVER", 'http://bulletin-board.lvh.me:8000/api').to_s %> + bulletin_board_public_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"} + authority_private_key: {"kty":"RSA","n":"pNgMt8lnPDD3TlWYGhRiV1oZkPQmnLdiUzwyb_-35qKD9k-HU86xo0uSgoOUWkBtnvFscq8zNDPAGAlZVokaN_z9ksZblSce0LEl8lJa3ICgghg7e8vg_7Lz5dyHSQ3PCLgenyFGcL401aglDde1Xo4ujdz33Lklc4U9zoyoLUI2_viYmNOU6n5Mn0sJd30FeICMrLD2gX46pGe3MGug6groT9EvpKcdOoJHKoO5yGSVaeY5-Bo3gngvlgjlS2mfwjCtF4NYwIQSd2al-p4BKnuYAVKRSgr8rYnnjhWfJ4GsCaqiyXNi5NPYRV6gl_cx_1jUcA1rRJqQR32I8c8QbAXm5qNO4URcdaKys9tNcVgXBL1FsSdbrLVVFWen1tfWNfHm-8BjiWCWD79-uk5gI0SjC9tWvTzVvswWXI5weNqqVXqpDydr46AsHE2sG40HRCR3UF3LupT-HwXTcYcOZr5dJClJIsU3Hrvy4wLssub69YSNR1Jxn-KX2vUc06xY8CNIuSMpfufEq5cZopL6O2l1pRsW1FQnF3s078_Y9MaQ1gPyBo0IipLBVUj5IjEIfPuiEk4jxkiUYDeqzf7bAvSFckp94yLkRWTs_pEZs7b_ogwRG6WMHjtcaNYe4CufhIm9ekkKDeAWOPRTHfKNmohRBh09XuvSjqrx5Z7rqb8","e":"AQAB","kid":"b8dba1459df956d60107690c34fa490db681eac4f73ffaf6e4055728c02ddc8e","d":"Uh3KIBe1VJez6pLbBUrYPlmE2N-3CGSWF46qNX62lq6ofB_b8xTJCuaPonJ3iYoE0aPEeVDrefq5m3-0wFXl-LQPgXlMj_1_7UgB9jeuSZ_N1WDK6P2EJPx5YS09O1gkpVxK7Mx_sZQe77wmUUH-eI7tg__qfUrB7E0Yn_cTpBATI2qlYaQsz6-A7e1MVvixq_ilmzVAZvuBrPp5mCZVb6FlXrV_PU9-UPIrD3O1La1lfO6SPBSbSGQkmGHwD2QbkHn9D_R_Vs-z_0TkM_dX71jIPQhrle3pN222KuJ8eQqwr9QP6biQMBuT5eKgr3MVtfUDRpp4sCEq9GIFwSd8LvbmGPrOoz8ueOEQ05nisIBQuOTYiWpYs2CEV062HR1bLFRLDUcSlflGNr0bgiXTUFx4wxRG06OaI-rQ6nG3M8TE0I0phMNCG3c7YyV28z_k2I65oQF9aKtiwFwc0YsUSGPTOFZGWHuCCPLm0lFeebpI_JIYqIv70NJxbSZEBY8DAIqZPqP6y_CRo2_C7piCgsjg9pnF8cp45vz4L6DWZ0Tumc_5aRuqIBkYXXwP9TjqhzxL-2SQHIqUAjj6Y6S35tZT6ekZSbnPIKX_e42y6bDT_Ztf01QfKiTkcx3_I8RwOuh6CzJzr72AykQpU3XKOKF1x1GBtYyrno4jG5LgaGE","p":"1UARZ-rRnpKG5NHKlXTys3irCy-d91edHL3fEIzDKvhMRQCIWh7dt8l0_sIpcBF-EbVilbFKj7yfgZBTr8EkAXHgweayK8rnlMqi2jte1_u-5DBtrGVVUTSQltSLDOZHK5QfUxVK6Bbk8K5ROLvef91oNgnSNWNOeoCZdlS55nMZcAgY_6mxSuuMq54Tgy8o4Ip890-ZEYY6OSFXhU-ieoGO4Jw--c6QzmCa3gGo2oVClidMNaM1jquK4Pj6xaoxR2NWeIX9Ix7k1P2B24pegyHXjSIpQ6JYdn352VViXi2tx7TTJh6ClNVjgoRmL4Gfy_IJNx0GhF5OB3yughUc7w","q":"xePJGBt466qM9F0BPxWFjyWbIs_GNXr-lBGASui0Z94cfgFbsZwqRsWQEf7jDVQsDNVnPSWZ_Wd6UqoQaIxc0tE8gaokPG6A4EUDyoLaZ231ZydDVoWof8FnPDaJwrcPwZ4R6ZLKGmkfytCZuU9I_9B4uuV0dyjEzKfS-Os3UcLumKPlgJ71OZAb49GTqUHuTePcSJjyYOYXx6eE7i_1m8TjU9Ut18BJNQhLqWmerA6X1ijbR2_syY6GXhGSfciSBH8xVkiUnqXb2jt1bE8nwWw-Sam5ikjzNbXqqs978IcCE5HTddQmy99bwuArA8PLqIFj3OOO1CSo8oyn2XDgMQ","dp":"Diky_rOZN-6DBq7nxQT_GOvqb9O5qbMnu8DgDzlJvJDAf9SJOXLTRmEaY9CA7_A5bvOcmFQtn13nObNb20_4FCB7zGSFcGMI_dh2-Ab5RV5yTrTok4onID1dXKbAlRq1ny825U2Eq-TZTyJEQoA3RkZtpSkBzInLrFbd2f3GWodKKSZggpnCLDd4H-1fXlbDYCXSJpoikAdZ1nFgXnnrUDdKRaAajnwpIYtIvXVewSQYR-BULzunUtIRZt8hx_6FRzhRha9gH_TtPTeYZ_vISuz0Y2rhUpx1Q2kaLlR9M8PUxm47l0xvX3LMKN6h6oWxFtn7wq0qwZ-Bjv24mOrOAQ","dq":"nXGD10hURrwk9W7hxP0sjB2Rdnr06iv3THs4JWFL16_h32bZO1BSWoho_chbgYlMmtFXGFFIWVLxAcAI2gWC_MA4cbmapvIMW2LNh1vgxJW5v95_NuGUlECeEEwcAu1-_b7z5XBCmAy3nLem9sbb_5wv0hMpPH0VRvbnZeBO3SBIkO0lddYCqU-8wN9HqkyoexQleSUnAm1O0iy4GIHT2aEmdNaRaKy2EhmNiTZdZeseZueOvyGPtTVONp2ofacMdcN0z39jr22qo9DWtdusd7nVPOpqkllEF6GrGUeHBnGD92n4YjDuxRnqefu8fXxUFrcLav0p8CNSv9ek291woQ","qi":"w6hfKEBLLHRWPkjajgxZyyetj-UFfVkILRT0plOllJ2JV8whcOXRXbiXH2r8zqMeyMFrrMwmuvv4TVQaruKB0ZQOG7Tz5Lw0RZEREOLnBwc3vSi_iLd-jBz01LdExTpqsAHMkaMQR9x62J8DE1ZNxVdn3ELYKik0f1L2r_WErzhvT1uq69HAybUp6WHcFYH0PSqHg4LOneXAdU1_g-ji2Zn9dlA_2oYGQ5S6JXPV7v2IVbEFpxyVD1lPbFT0iKhyZZevictjgD_JGHveIVqsq5w0Csyz08h0oEW9hYEq-4bquMxSf18gjldoS5uQPD7FUECgL8bxsCdc4hP6UEKYGw"} + authority_name: "Decidim Test Authority" + authority_api_key: "89Ht70GZNcicu8WEyagz_rRae6brbqZAGuBEICYBCii-PTV3MAstAtx1aRVe5H5YfODi-JgYPvyf9ZMH7tOeZ15e3mf9B2Ymgw7eknvBFMRP213YFGo1SPn_C4uLK90G" + scheme_name: "dummy" + quorum: 2 + number_of_trustees: 3 + +storage_default: &storage_default + provider: <%= Decidim::Env.new("STORAGE_PROVIDER", "local").to_s %> + cdn_host: <%= ENV["STORAGE_CDN_HOST"] %> + s3: + access_key_id: <%= ENV["AWS_ACCESS_KEY_ID"] %> + secret_access_key: <%= ENV["AWS_SECRET_ACCESS_KEY"] %> + region: <%= ENV["AWS_REGION"] %> + bucket: <%= ENV["AWS_BUCKET"] %> + endpoint: <%= ENV["AWS_ENDPOINT"] %> + azure: + storage_access_key: <%= ENV["AZURE_STORAGE_ACCESS_KEY"] %> + storage_account_name: <%= ENV["AZURE_STORAGE_ACCOUNT_NAME"] %> + container: <%= ENV["AZURE_CONTAINER"] %> + gcs: + project: <%= ENV["GCS_PROJECT"] %> + bucket: <%= ENV["GCS_BUCKET"] %> + type: <%= Decidim::Env.new("GCS_TYPE", "service_account").to_s %> + project_id: <%= Decidim::Env.new("GCS_PROJECT_ID").to_s %> + private_key_id: <%= Decidim::Env.new("GCS_PRIVATE_KEY_ID").to_s %> + private_key: <%= Decidim::Env.new("GCS_PRIVATE_KEY").to_s %> + client_email: <%= Decidim::Env.new("GCS_CLIENT_EMAIL").to_s %> + client_id: <%= Decidim::Env.new("GCS_CLIENT_ID").to_s %> + auth_uri: <%= Decidim::Env.new("GCS_AUTH_URI", "https://accounts.google.com/o/oauth2/auth").to_s %> + token_uri: <%= Decidim::Env.new("GCS_TOKEN_URI", "https://accounts.google.com/o/oauth2/token").to_s %> + auth_provider_x509_cert_url: <%= Decidim::Env.new("GCS_AUTH_PROVIDER_X509_CERT_URL", "https://www.googleapis.com/oauth2/v1/certs").to_s %> + client_x509_cert_url: <%= Decidim::Env.new("GCS_CLIENT_X509_CERT_URL").to_s %> + default: &default - valid_auth_url: "<%= ENV['VALID_URL'] %>" - sentry_enabled: false - census_url: "<%= ENV['CENSUS_URL'] %>" - aws_access_key_id: <%= ENV["AWS_ACCESS_KEY_ID"] %> - aws_secret_access_key: <%= ENV["AWS_SECRET_ACCESS_KEY"] %> - analytics: <%= ENV["ANALYTICS"].present? %> - sms: - service_url: <%= ENV["SMS_SERVICE_URL"] %> - proxy_url: <%= ENV["SMS_PROXY_URL"] %> - username: <%= ENV["SMS_USERNAME"] %> - password: <%= ENV["SMS_PASSWORD"] %> - service_id: "<%= ENV['SMS_SERVICE_ID'] %>" - sub_service_id: "<%= ENV['SMS_SUB_SERVICE_ID'] %>" + decidim: + <<: *decidim_default omniauth: facebook: - # It must be a boolean. Remember ENV variables doesn't support booleans. - enabled: true + enabled: <%= Decidim::Env.new("OMNIAUTH_FACEBOOK_APP_ID").to_boolean_string %> app_id: <%= ENV["OMNIAUTH_FACEBOOK_APP_ID"] %> app_secret: <%= ENV["OMNIAUTH_FACEBOOK_APP_SECRET"] %> twitter: - enabled: true + enabled: <%= Decidim::Env.new("OMNIAUTH_TWITTER_API_KEY").to_boolean_string %> api_key: <%= ENV["OMNIAUTH_TWITTER_API_KEY"] %> api_secret: <%= ENV["OMNIAUTH_TWITTER_API_SECRET"] %> google_oauth2: - enabled: true + enabled: <%= Decidim::Env.new("OMNIAUTH_GOOGLE_CLIENT_ID").to_boolean_string %> + icon_path: decidim/brands/google.svg client_id: <%= ENV["OMNIAUTH_GOOGLE_CLIENT_ID"] %> client_secret: <%= ENV["OMNIAUTH_GOOGLE_CLIENT_SECRET"] %> - geocoder: - here_api_key: <%= ENV["HERE_API_KEY"] %> - timestamp_service_url: "<%= ENV['TIMESTAMP_SERVICE_URL'] %>" - signature_certificate_password: "<%= ENV['SIGNATURE_CERTIFICATE_PASSWORD'] %>" - pdf_certificate: <%= ENV["PDF_CERTIFICATE"].to_s.dump %> - pdf_signer_certificate: <%= ENV["PDF_SIGNER_CERTIFICATE"].to_s.dump %> - pdf_signer_private_key: <%= ENV["PDF_SIGNER_PRIVATE_KEY"].to_s.dump %> + maps: + dynamic_provider: <%= Decidim::Env.new("MAPS_DYNAMIC_PROVIDER", ENV["MAPS_PROVIDER"]).to_s %> + static_provider: <%= Decidim::Env.new("MAPS_STATIC_PROVIDER", ENV["MAPS_PROVIDER"]).to_s %> + static_api_key: <%= Decidim::Env.new("MAPS_STATIC_API_KEY", ENV["MAPS_API_KEY"]).to_s %> + dynamic_api_key: <%= Decidim::Env.new("MAPS_DYNAMIC_API_KEY", ENV["MAPS_API_KEY"]).to_s %> + dynamic_url: <%= ENV["MAPS_DYNAMIC_URL"] %> + static_url: <%= ENV["MAPS_STATIC_URL"] %> + attribution: <%= ENV["MAPS_ATTRIBUTION"].to_json %> + extra_vars: <%= ENV["MAPS_EXTRA_VARS"].to_json %> + geocoding_host: <%= ENV["MAPS_GEOCODING_HOST"] %> etherpad: server: <%= ENV["ETHERPAD_SERVER"] %> api_key: <%= ENV["ETHERPAD_API_KEY"] %> + api_version: <%= Decidim::Env.new("ETHERPAD_API_VERSION", "1.2.1") %> + elections: + <<: *elections_default + storage: + <<: *storage_default + vapid: + enabled: <%= Decidim::Env.new("VAPID_PUBLIC_KEY").to_boolean_string %> + public_key: <%= ENV["VAPID_PUBLIC_KEY"] %> + private_key: <%= ENV["VAPID_PRIVATE_KEY"] %> + analytics: <%= ENV["ANALYTICS"].present? %> + census_url: "<%= ENV['CENSUS_URL'] %>" + pdf_certificate: <%= ENV["PDF_CERTIFICATE"].to_s.dump %> + pdf_signer_certificate: <%= ENV["PDF_SIGNER_CERTIFICATE"].to_s.dump %> + pdf_signer_private_key: <%= ENV["PDF_SIGNER_PRIVATE_KEY"].to_s.dump %> rack_attack_skip: <%= ENV["RACK_ATTACK_SKIP_SECRET"] %> + sentry_enabled: false + signature_certificate_password: "<%= ENV['SIGNATURE_CERTIFICATE_PASSWORD'] %>" + sms: + service_url: <%= ENV["SMS_SERVICE_URL"] %> + proxy_url: <%= ENV["SMS_PROXY_URL"] %> + username: <%= ENV["SMS_USERNAME"] %> + password: <%= ENV["SMS_PASSWORD"] %> + service_id: "<%= ENV['SMS_SERVICE_ID'] %>" + sub_service_id: "<%= ENV['SMS_SUB_SERVICE_ID'] %>" + timestamp_service_url: "<%= ENV['TIMESTAMP_SERVICE_URL'] %>" + valid_auth_url: "<%= ENV['VALID_URL'] %>" development: <<: *default secret_key_base: <%= ENV["SECRET_KEY_BASE"].presence || "e3efe0351af320dda7a3daf90a805a68e94d093cfc57a94bf9c42f3f1732fac32dd4656f435e385f1ea7789ff5e387a6313d1db2a3b11e9dd030293158bfdc9b" %> - geocoder: - here_api_key: 1234123412341234 omniauth: developer: enabled: true @@ -63,8 +186,22 @@ development: test: <<: *default secret_key_base: 4a6fd36ca5634dbf42f63331b1a236a041976561ec314414d1750f33ef691dd3705ff2828a607d98bee0ba492e11281a33e736c71e959ab04c76679e74ecb564 - geocoder: - here_api_key: 1234123412341234 + omniauth: + facebook: + enabled: true + app_id: fake-facebook-app-id + app_secret: fake-facebook-app-secret + twitter: + enabled: true + api_key: fake-twitter-api-key + api_secret: fake-twitter-api-secret + google_oauth2: + enabled: true + client_id: + client_secret: + elections: + <<: *elections_default + bulletin_board_server: <%= Decidim::Env.new("ELECTIONS_BULLETIN_BOARD_SERVER", 'http://bulletin-board.lvh.me:5017/api').to_s %> sms: service_url: http://example.org/sms proxy_url: http://example.org/proxy @@ -73,18 +210,35 @@ test: service_id: "1234" sub_service_id: "1234" + # Do not keep production secrets in the repository, # instead read values from the environment. production: <<: *default - sentry_enabled: true secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> - email: "<%= ENV["EMAIL"] %>" + smtp_username: <%= ENV["SMTP_USERNAME"] %> + smtp_password: <%= ENV["SMTP_PASSWORD"] %> + smtp_address: <%= ENV["SMTP_ADDRESS"] %> + smtp_domain: <%= ENV["SMTP_DOMAIN"] %> + smtp_port: <%= Decidim::Env.new("SMTP_PORT", 587).to_i %> + smtp_starttls_auto: <%= Decidim::Env.new("SMTP_STARTTLS_AUTO").to_boolean_string %> + smtp_authentication: <%= Decidim::Env.new("SMTP_AUTHENTICATION", "plain").to_s %> + elections: + bulletin_board_server: <%= ENV["BULLETIN_BOARD_SERVER"] %> + bulletin_board_public_key: <%= ENV["BULLETIN_BOARD_PUBLIC_KEY"] %> + authority_api_key: <%= ENV["BULLETIN_BOARD_API_KEY"] %> + authority_name: <%= ENV["AUTHORITY_NAME"] %> + authority_private_key: <%= ENV["AUTHORITY_PRIVATE_KEY"] %> + scheme_name: <%= Decidim::Env.new("ELECTIONS_SCHEME_NAME", "electionguard").to_s %> + number_of_trustees: <%= Decidim::Env.new("ELECTIONS_NUMBER_OF_TRUSTEES").to_i %> + quorum: <%= Decidim::Env.new("ELECTIONS_QUORUM").to_i %> + setup_minimum_hours_before_start: <%= Decidim::Env.new("ELECTIONS_SETUP_MINIMUM_HOURS_BEFORE_START", 3).to_i %> + start_vote_maximum_hours_before_start: <%= Decidim::Env.new("ELECTIONS_START_VOTE_MAXIMUM_HOURS_BEFORE_START", 6).to_i %> + voter_token_expiration_minutes: <%= Decidim::Env.new("ELECTIONS_VOTER_TOKEN_EXPIRATION_MINUTES", 120).to_i %> + votings: + check_census_max_requests: <%= Decidim::Env.new("VOTINGS_CHECK_CENSUS_MAX_REQUESTS", 5).to_i %> + throttling_period: <%= Decidim::Env.new("VOTINGS_THROTTLING_PERIOD", 1).to_i %> + census: + access_codes_export_expiry_time: <%= Decidim::Env.new("VOTINGS_CENSUS_ACCESS_CODES_EXPORT_EXPIRY_TIME", 2).to_i %> + sentry_enabled: true sendgrid: <%= !ENV["SENDGRID_USERNAME"].blank? %> - smtp_username: <%= ENV["SMTP_USERNAME"] || ENV["SENDGRID_USERNAME"] %> - smtp_password: <%= ENV["SMTP_PASSWORD"] || ENV["SENDGRID_PASSWORD"] %> - smtp_address: <%= ENV["SMTP_ADDRESS"] || "smtp.sendgrid.net" %> - smtp_domain: <%= ENV["SMTP_DOMAIN"] || "heroku.com" %> - smtp_port: "587" - smtp_starttls_auto: true - smtp_authentication: "plain" diff --git a/config/webpacker.yml b/config/shakapacker.yml similarity index 60% rename from config/webpacker.yml rename to config/shakapacker.yml index 6a1a41f9fc..25fe7e437a 100644 --- a/config/webpacker.yml +++ b/config/shakapacker.yml @@ -4,11 +4,15 @@ default: &default source_path: app/packs source_entry_path: entrypoints - public_output_path: decidim-packs + nested_entries: true + css_extract_ignore_order_warnings: false + public_root_path: public + public_output_path: decidim-packs + cache_path: tmp/shakapacker webpack_compile_output: true - cache_path: tmp/webpacker-cache extract_css: true + shakapacker_precompile: true additional_paths: - node_modules @@ -17,9 +21,24 @@ default: &default # Reload manifest.json on all requests so we reload latest compiled packs cache_manifest: false + # Select loader to use, available options are 'babel' (default), 'swc' or 'esbuild' + webpack_loader: 'babel' + + # Set to true to enable check for matching versions of shakapacker gem and NPM package - will raise an error if there is a mismatch or wildcard versioning is used + ensure_consistent_versioning: true + + # Select whether the compiler will use SHA digest ('digest' option) or most most recent modified timestamp ('mtime') to determine freshness + compiler_strategy: digest + + # Select whether the compiler will always use a content hash and not just in production + # Do not use contentHash except for production for performance + # https://webpack.js.org/guides/build-performance/#avoid-production-specific-tooling + useContentHash: false + development: <<: *default compile: true + compiler_strategy: mtime # Compile test packs to decidim decidim-packs folder # Reference: https://webpack.js.org/configuration/dev-server/ @@ -31,9 +50,11 @@ development: port: 3035 # Hot Module Replacement updates modules while the application is running without a full reload hmr: false + # mini-css-extract-plugin is a required dependency in both cases. + inline_css: true client: # Should we show a full-screen overlay in the browser when there are compiler errors or warnings? - overlay: true + overlay: false # May also be a string # webSocketURL: # hostname: "0.0.0.0" @@ -61,5 +82,8 @@ production: # Production depends on precompilation of packs prior to booting for performance. compile: false + # Use content hash for naming assets. Cannot be overridden by for production. + useContentHash: true + # Cache manifest.json for performance cache_manifest: true diff --git a/config/spring.rb b/config/spring.rb index ff5ba06b6d..50d36abe86 100644 --- a/config/spring.rb +++ b/config/spring.rb @@ -1,5 +1,7 @@ # frozen_string_literal: true +require "decidim/spring" + %w( .ruby-version .rbenv-vars diff --git a/config/storage.yml b/config/storage.yml index 1367fb9085..3f3b93c601 100644 --- a/config/storage.yml +++ b/config/storage.yml @@ -6,9 +6,10 @@ local: service: Disk root: <%= Rails.root.join("storage") %> -amazon: +s3: service: S3 - access_key_id: <%= Rails.application.secrets.aws_access_key_id %> - secret_access_key: <%= Rails.application.secrets.aws_secret_access_key %> - region: eu-west-1 - bucket: <%= ENV.fetch("AWS_BUCKET_NAME", "decidim-barcelona-new") %> \ No newline at end of file + access_key_id: <%= Rails.application.secrets.dig(:storage, :s3, :access_key_id) %> + secret_access_key: <%= Rails.application.secrets.dig(:storage, :s3, :secret_access_key) %> + bucket: <%= Rails.application.secrets.dig(:storage, :s3, :bucket) %> + <%= "region: #{Rails.application.secrets.dig(:storage, :s3, :region)}" if Rails.application.secrets.dig(:storage, :s3, :region) %> + <%= "endpoint: #{Rails.application.secrets.dig(:storage, :s3, :endpoint)}" if Rails.application.secrets.dig(:storage, :s3, :endpoint) %> diff --git a/config/webpack/.modernizrrc b/config/webpack/.modernizrrc new file mode 100644 index 0000000000..b76ce76a48 --- /dev/null +++ b/config/webpack/.modernizrrc @@ -0,0 +1,9 @@ +{ + "minify": true, + "options": [ + "setClasses" + ], + "feature-detects": [ + "css/transitions" + ] +} diff --git a/config/webpack/base.js b/config/webpack/base.js deleted file mode 100644 index 13a710c687..0000000000 --- a/config/webpack/base.js +++ /dev/null @@ -1,6 +0,0 @@ -/* eslint-disable */ - -const { webpackConfig, merge } = require("@decidim/webpacker") -const customConfig = require("./custom") - -module.exports = merge(webpackConfig, customConfig) diff --git a/config/webpack/custom.js b/config/webpack/custom.js index 6c37a831b9..a96bb6a8ee 100644 --- a/config/webpack/custom.js +++ b/config/webpack/custom.js @@ -1,18 +1,11 @@ /* eslint-disable */ - -const path = require("path"); -const { config } = require("@rails/webpacker"); +const { config } = require("shakapacker"); +const { InjectManifest } = require("workbox-webpack-plugin"); +const TerserPlugin = require('terser-webpack-plugin') module.exports = { module: { rules: [ - { - test: require.resolve("quill"), - loader: "expose-loader", - options: { - exposes: ["Quill"] - } - }, { test: require.resolve("jquery"), loader: "expose-loader", @@ -85,13 +78,49 @@ module.exports = { resolve: { extensions: [".js", ".jsx", ".gql", ".graphql"], fallback: { + punycode: false, crypto: false } }, // https://github.com/rails/webpacker/issues/2932 // As Decidim uses multiple packs, we need to enforce a single runtime, to prevent duplication optimization: { - runtimeChunk: false + minimizer: [ + new TerserPlugin({ + parallel: Number.parseInt(process.env.SHAKAPACKER_PARALLEL, 10) || true, + terserOptions: { + parse: { + // Let terser parse ecma 8 code but always output + // ES5 compliant code for older browsers + ecma: 8 + }, + compress: { + ecma: 5, + warnings: false, + comparisons: false + }, + mangle: { safari10: true }, + output: { + ecma: 5, + comments: false, + ascii_only: true + } + } + }) + ].filter(Boolean) }, - entry: config.entrypoints + entry: config.entrypoints, + plugins: [ + new InjectManifest({ + swSrc: "src/decidim/sw/sw.js", + + /** + * NOTE: + * @rails/webpacker outputs to '/packs', + * in order to make the SW run properly + * they must be put at the project's root folder '/' + */ + swDest: "../sw.js" + }) + ] } diff --git a/config/webpack/development.js b/config/webpack/development.js deleted file mode 100644 index 9f67055049..0000000000 --- a/config/webpack/development.js +++ /dev/null @@ -1,7 +0,0 @@ -/* eslint-disable */ - -process.env.NODE_ENV = process.env.NODE_ENV || "development" - -const webpackConfig = require("./base") - -module.exports = webpackConfig diff --git a/config/webpack/production.js b/config/webpack/production.js deleted file mode 100644 index 4c1e712a74..0000000000 --- a/config/webpack/production.js +++ /dev/null @@ -1,7 +0,0 @@ -/* eslint-disable */ - -process.env.NODE_ENV = process.env.NODE_ENV || "production" - -const webpackConfig = require("./base") - -module.exports = webpackConfig diff --git a/config/webpack/test.js b/config/webpack/test.js deleted file mode 100644 index 9f67055049..0000000000 --- a/config/webpack/test.js +++ /dev/null @@ -1,7 +0,0 @@ -/* eslint-disable */ - -process.env.NODE_ENV = process.env.NODE_ENV || "development" - -const webpackConfig = require("./base") - -module.exports = webpackConfig diff --git a/config/webpack/webpack.config.js b/config/webpack/webpack.config.js new file mode 100644 index 0000000000..0b11fe3a5e --- /dev/null +++ b/config/webpack/webpack.config.js @@ -0,0 +1,10 @@ +/* eslint-disable */ +process.env.NODE_ENV ??= "development" + +const { webpackConfig, merge } = require("@decidim/webpacker") +const customConfig = require("./custom") + +webpackConfig.optimization = {} +const combinedConfig = merge(webpackConfig, customConfig) + +module.exports = combinedConfig diff --git a/db/migrate/20230214161259_add_service_name_to_active_storage_blobs.decidim.rb b/db/migrate/20230214161259_add_service_name_to_active_storage_blobs.decidim.rb new file mode 100644 index 0000000000..316952eee9 --- /dev/null +++ b/db/migrate/20230214161259_add_service_name_to_active_storage_blobs.decidim.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true +# This migration comes from decidim (originally 20210831181634) + +# This migration comes from active_storage (originally 20190112182829) +class AddServiceNameToActiveStorageBlobs < ActiveRecord::Migration[6.0] + def up + return if column_exists?(:active_storage_blobs, :service_name) + + add_column :active_storage_blobs, :service_name, :string + # rubocop:disable Lint/AssignmentInCondition + # rubocop:disable Rails/SkipsModelValidations + if configured_service = ActiveStorage::Blob.service.name + ActiveStorage::Blob.unscoped.update_all(service_name: configured_service) + end + # rubocop:enable Lint/AssignmentInCondition + # rubocop:enable Rails/SkipsModelValidations + change_column :active_storage_blobs, :service_name, :string, null: false + end + + def down + remove_column :active_storage_blobs, :service_name + end +end diff --git a/db/migrate/20230214161260_create_active_storage_variant_records.decidim.rb b/db/migrate/20230214161260_create_active_storage_variant_records.decidim.rb new file mode 100644 index 0000000000..ef13a6c387 --- /dev/null +++ b/db/migrate/20230214161260_create_active_storage_variant_records.decidim.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true +# This migration comes from decidim (originally 20210831181635) + +# This migration comes from active_storage (originally 20191206030411) +class CreateActiveStorageVariantRecords < ActiveRecord::Migration[6.0] + def change + create_table :active_storage_variant_records do |t| + t.belongs_to :blob, null: false, index: false + t.string :variation_digest, null: false + + t.index [:blob_id, :variation_digest], name: "index_active_storage_variant_records_uniqueness", unique: true + t.foreign_key :active_storage_blobs, column: :blob_id + end + end +end diff --git a/db/migrate/20230214161261_create_decidim_reminders.decidim.rb b/db/migrate/20230214161261_create_decidim_reminders.decidim.rb new file mode 100644 index 0000000000..c3e7594d82 --- /dev/null +++ b/db/migrate/20230214161261_create_decidim_reminders.decidim.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true +# This migration comes from decidim (originally 20211208155453) + +class CreateDecidimReminders < ActiveRecord::Migration[6.0] + def change + create_table :decidim_reminders do |t| + t.belongs_to :decidim_user, index: true, foreign_key: true, null: false + t.belongs_to :decidim_component, index: true, foreign_key: true + t.timestamps + end + end +end diff --git a/db/migrate/20230214161262_create_decidim_reminder_records.decidim.rb b/db/migrate/20230214161262_create_decidim_reminder_records.decidim.rb new file mode 100644 index 0000000000..63170c9aae --- /dev/null +++ b/db/migrate/20230214161262_create_decidim_reminder_records.decidim.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true +# This migration comes from decidim (originally 20211209121025) + +class CreateDecidimReminderRecords < ActiveRecord::Migration[6.0] + def change + create_table :decidim_reminder_records do |t| + t.string :state, :string, index: true, default: "active" + t.belongs_to :decidim_reminder, index: true, foreign_key: true + t.belongs_to :remindable, polymorphic: true, null: false, index: { name: "index_decidim_reminder_records_remindable" } + end + end +end diff --git a/db/migrate/20230214161263_create_decidim_reminder_deliveries.decidim.rb b/db/migrate/20230214161263_create_decidim_reminder_deliveries.decidim.rb new file mode 100644 index 0000000000..aae6e2a977 --- /dev/null +++ b/db/migrate/20230214161263_create_decidim_reminder_deliveries.decidim.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true +# This migration comes from decidim (originally 20211209121040) + +class CreateDecidimReminderDeliveries < ActiveRecord::Migration[6.0] + def change + create_table :decidim_reminder_deliveries do |t| + t.belongs_to :decidim_reminder, index: true, foreign_key: true + t.timestamps + end + end +end diff --git a/db/migrate/20230214161264_change_required_description_categories.decidim.rb b/db/migrate/20230214161264_change_required_description_categories.decidim.rb new file mode 100644 index 0000000000..65966c9c34 --- /dev/null +++ b/db/migrate/20230214161264_change_required_description_categories.decidim.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true +# This migration comes from decidim (originally 20220118121921) + +class ChangeRequiredDescriptionCategories < ActiveRecord::Migration[6.0] + def change + change_column_null :decidim_categories, :description, true + end +end diff --git a/db/migrate/20230214161265_add_notification_settings_to_users.decidim.rb b/db/migrate/20230214161265_add_notification_settings_to_users.decidim.rb new file mode 100644 index 0000000000..f5d061a8de --- /dev/null +++ b/db/migrate/20230214161265_add_notification_settings_to_users.decidim.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true +# This migration comes from decidim (originally 20220127113419) + +class AddNotificationSettingsToUsers < ActiveRecord::Migration[6.0] + def change + add_column :decidim_users, :notification_settings, :jsonb, default: {} + end +end diff --git a/db/migrate/20230214161266_add_notifications_sending_frequency_to_users.decidim.rb b/db/migrate/20230214161266_add_notifications_sending_frequency_to_users.decidim.rb new file mode 100644 index 0000000000..02ecfe6a10 --- /dev/null +++ b/db/migrate/20230214161266_add_notifications_sending_frequency_to_users.decidim.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true +# This migration comes from decidim (originally 20220203121137) + +class AddNotificationsSendingFrequencyToUsers < ActiveRecord::Migration[6.0] + def change + add_column :decidim_users, :notifications_sending_frequency, :string, default: "daily", index: true + end +end diff --git a/db/migrate/20230214161267_add_digest_sent_at_to_users.decidim.rb b/db/migrate/20230214161267_add_digest_sent_at_to_users.decidim.rb new file mode 100644 index 0000000000..f75a48be01 --- /dev/null +++ b/db/migrate/20230214161267_add_digest_sent_at_to_users.decidim.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true +# This migration comes from decidim (originally 20220215172439) + +class AddDigestSentAtToUsers < ActiveRecord::Migration[6.0] + def change + add_column :decidim_users, :digest_sent_at, :datetime + end +end diff --git a/db/migrate/20230214161268_add_index_to_decidim_users_notifications_sending_frequency.decidim.rb b/db/migrate/20230214161268_add_index_to_decidim_users_notifications_sending_frequency.decidim.rb new file mode 100644 index 0000000000..aaa7996781 --- /dev/null +++ b/db/migrate/20230214161268_add_index_to_decidim_users_notifications_sending_frequency.decidim.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true +# This migration comes from decidim (originally 20220323195258) + +class AddIndexToDecidimUsersNotificationsSendingFrequency < ActiveRecord::Migration[6.0] + def change + add_index :decidim_users, :notifications_sending_frequency + end +end diff --git a/db/migrate/20230214161269_drop_emails_on_notifications_flag_from_user.decidim.rb b/db/migrate/20230214161269_drop_emails_on_notifications_flag_from_user.decidim.rb new file mode 100644 index 0000000000..f5048f88fe --- /dev/null +++ b/db/migrate/20230214161269_drop_emails_on_notifications_flag_from_user.decidim.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true +# This migration comes from decidim (originally 20220427142214) + +class DropEmailsOnNotificationsFlagFromUser < ActiveRecord::Migration[5.1] + class DecidimUser < ApplicationRecord + self.table_name = :decidim_users + end + + def change + # rubocop:disable Rails/SkipsModelValidations + DecidimUser.where(email_on_notification: true).update_all(notifications_sending_frequency: "real_time") + # rubocop:enable Rails/SkipsModelValidations + + remove_column :decidim_users, :email_on_notification + end +end diff --git a/db/migrate/20230214161270_add_previous_passwords_to_users.decidim.rb b/db/migrate/20230214161270_add_previous_passwords_to_users.decidim.rb new file mode 100644 index 0000000000..bbd0d9ffb1 --- /dev/null +++ b/db/migrate/20230214161270_add_previous_passwords_to_users.decidim.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true +# This migration comes from decidim (originally 20220518094535) + +class AddPreviousPasswordsToUsers < ActiveRecord::Migration[6.1] + class User < ApplicationRecord + self.table_name = :decidim_users + end + + def change + add_column :decidim_users, :password_updated_at, :datetime + add_column :decidim_users, :previous_passwords, :string, array: true, default: [] + + reversible do |direction| + direction.up do + # rubocop:disable Rails/SkipsModelValidations + User.update_all("password_updated_at = updated_at") + # rubocop:enable Rails/SkipsModelValidations + end + end + end +end diff --git a/db/migrate/20230214161271_create_decidim_short_links.decidim.rb b/db/migrate/20230214161271_create_decidim_short_links.decidim.rb new file mode 100644 index 0000000000..dbdc8a116d --- /dev/null +++ b/db/migrate/20230214161271_create_decidim_short_links.decidim.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true +# This migration comes from decidim (originally 20220524195530) + +class CreateDecidimShortLinks < ActiveRecord::Migration[6.1] + def change + create_table :decidim_short_links do |t| + t.references :decidim_organization, null: false, index: true + t.references :target, polymorphic: true, null: false, index: true + t.string :identifier, limit: 10, null: false + t.string :mounted_engine_name, index: true + t.string :route_name, index: true + t.jsonb :params + + t.timestamps + end + + add_index( + :decidim_short_links, + [:decidim_organization_id, :identifier], + unique: true, + name: "idx_decidim_short_links_organization_id_identifier" + ) + end +end diff --git a/db/migrate/20230214161272_create_decidim_participatory_process_types.decidim_participatory_processes.rb b/db/migrate/20230214161272_create_decidim_participatory_process_types.decidim_participatory_processes.rb new file mode 100644 index 0000000000..4b741d5812 --- /dev/null +++ b/db/migrate/20230214161272_create_decidim_participatory_process_types.decidim_participatory_processes.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true +# This migration comes from decidim_participatory_processes (originally 20211125202008) + +class CreateDecidimParticipatoryProcessTypes < ActiveRecord::Migration[6.0] + def change + create_table :decidim_participatory_process_types do |t| + t.jsonb :title, null: false + t.references( + :decidim_organization, + foreign_key: true, + index: { name: "index_decidim_process_types_on_decidim_organization_id" } + ) + t.timestamps + end + + add_reference( + :decidim_participatory_processes, + :decidim_participatory_process_type, + foreign_key: true, + index: { name: "index_decidim_processes_on_decidim_process_type_id" } + ) + end +end diff --git a/db/migrate/20230214161273_remove_not_null_on_customize_registration_email.decidim_meetings.rb b/db/migrate/20230214161273_remove_not_null_on_customize_registration_email.decidim_meetings.rb new file mode 100644 index 0000000000..b75856cd17 --- /dev/null +++ b/db/migrate/20230214161273_remove_not_null_on_customize_registration_email.decidim_meetings.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true +# This migration comes from decidim_meetings (originally 20211105115625) + +class RemoveNotNullOnCustomizeRegistrationEmail < ActiveRecord::Migration[6.0] + def change + change_column_null :decidim_meetings_meetings, :customize_registration_email, true + end +end diff --git a/db/migrate/20230214161274_add_geolocalization_fields_to_projects.decidim_budgets.rb b/db/migrate/20230214161274_add_geolocalization_fields_to_projects.decidim_budgets.rb new file mode 100644 index 0000000000..2a7b59f01d --- /dev/null +++ b/db/migrate/20230214161274_add_geolocalization_fields_to_projects.decidim_budgets.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true +# This migration comes from decidim_budgets (originally 20220428072638) + +class AddGeolocalizationFieldsToProjects < ActiveRecord::Migration[6.1] + def change + add_column :decidim_budgets_projects, :address, :text + add_column :decidim_budgets_projects, :latitude, :float + add_column :decidim_budgets_projects, :longitude, :float + end +end diff --git a/db/migrate/20230214161275_add_comments_enabled_to_initiative_types.decidim_initiatives.rb b/db/migrate/20230214161275_add_comments_enabled_to_initiative_types.decidim_initiatives.rb new file mode 100644 index 0000000000..7ad758af30 --- /dev/null +++ b/db/migrate/20230214161275_add_comments_enabled_to_initiative_types.decidim_initiatives.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true +# This migration comes from decidim_initiatives (originally 20220518053612) + +class AddCommentsEnabledToInitiativeTypes < ActiveRecord::Migration[6.1] + def change + add_column :decidim_initiatives_types, :comments_enabled, :boolean, null: false, default: true + end +end diff --git a/db/migrate/20230214161276_create_decidim_initiatives_settings.decidim_initiatives.rb b/db/migrate/20230214161276_create_decidim_initiatives_settings.decidim_initiatives.rb new file mode 100644 index 0000000000..7a3ee440ea --- /dev/null +++ b/db/migrate/20230214161276_create_decidim_initiatives_settings.decidim_initiatives.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true +# This migration comes from decidim_initiatives (originally 20220527130640) + +class CreateDecidimInitiativesSettings < ActiveRecord::Migration[5.2] + def change + create_table :decidim_initiatives_settings do |t| + t.string :initiatives_order, default: "random" + t.references :decidim_organization, foreign_key: true, index: true + end + end +end diff --git a/db/migrate/20230308123422_create_organization_minors_configs.decidim_kids.rb b/db/migrate/20230308123422_create_organization_minors_configs.decidim_kids.rb new file mode 100644 index 0000000000..2cbc97835c --- /dev/null +++ b/db/migrate/20230308123422_create_organization_minors_configs.decidim_kids.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true +# This migration comes from decidim_kids (originally 20221017110422) + +class CreateOrganizationMinorsConfigs < ActiveRecord::Migration[5.2] + def change + create_table :decidim_kids_organization_configs do |t| + t.integer :decidim_organization_id, null: false, index: { name: "index_decidim_kids_organization" } + t.boolean :enable_minors_participation, null: false, default: false + t.integer :minimum_minor_age, null: false, default: 10 + t.integer :maximum_minor_age, null: false, default: 13 + t.string :minors_authorization + t.string :tutors_authorization + t.integer :maximum_minor_accounts, null: false, default: 3 + t.timestamps + end + end +end diff --git a/db/migrate/20230308123423_create_decidim_kids_minor_accounts.decidim_kids.rb b/db/migrate/20230308123423_create_decidim_kids_minor_accounts.decidim_kids.rb new file mode 100644 index 0000000000..d16f4bcf43 --- /dev/null +++ b/db/migrate/20230308123423_create_decidim_kids_minor_accounts.decidim_kids.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true +# This migration comes from decidim_kids (originally 20221024124523) + +class CreateDecidimKidsMinorAccounts < ActiveRecord::Migration[6.1] + def change + create_table :decidim_kids_minor_accounts do |t| + t.references :decidim_tutor, null: false, index: true, foreign_key: { to_table: "decidim_users" } + t.references :decidim_minor, null: false, index: true, foreign_key: { to_table: "decidim_users" } + t.timestamps + end + + add_index :decidim_kids_minor_accounts, [:decidim_tutor_id, :decidim_minor_id], unique: true, name: "decidim_kids_minor_accounts_unique_tutor_and_minor_ids" + end +end diff --git a/db/migrate/20230308123424_create_decidim_kids_minor_data.decidim_kids.rb b/db/migrate/20230308123424_create_decidim_kids_minor_data.decidim_kids.rb new file mode 100644 index 0000000000..25d3962e20 --- /dev/null +++ b/db/migrate/20230308123424_create_decidim_kids_minor_data.decidim_kids.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true +# This migration comes from decidim_kids (originally 20221027211859) + +class CreateDecidimKidsMinorData < ActiveRecord::Migration[6.1] + def change + create_table :decidim_kids_minor_data do |t| + t.references :decidim_user, null: false, index: true + t.string :name # encrypted + t.string :birthday # encrypted + t.string :email # encrypted + t.jsonb :extra_data, null: false, default: {} + t.timestamps + end + end +end diff --git a/db/migrate/20230308123425_create_impersonation_minor_logs.decidim_kids.rb b/db/migrate/20230308123425_create_impersonation_minor_logs.decidim_kids.rb new file mode 100644 index 0000000000..c4e1130e15 --- /dev/null +++ b/db/migrate/20230308123425_create_impersonation_minor_logs.decidim_kids.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true +# This migration comes from decidim_kids (originally 20221127103636) + +class CreateImpersonationMinorLogs < ActiveRecord::Migration[6.1] + def change + create_table :decidim_kids_impersonation_minor_logs do |t| + t.references :decidim_tutor, index: true + t.references :decidim_minor, index: true + t.datetime :started_at + t.datetime :ended_at + t.datetime :expired_at + + t.timestamps + end + end +end diff --git a/db/migrate/20230308123426_create_decidim_kids_participatory_spaces_minors_configs.decidim_kids.rb b/db/migrate/20230308123426_create_decidim_kids_participatory_spaces_minors_configs.decidim_kids.rb new file mode 100644 index 0000000000..228fbb8f35 --- /dev/null +++ b/db/migrate/20230308123426_create_decidim_kids_participatory_spaces_minors_configs.decidim_kids.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true +# This migration comes from decidim_kids (originally 20221220132306) + +class CreateDecidimKidsParticipatorySpacesMinorsConfigs < ActiveRecord::Migration[6.1] + def change + create_table :decidim_kids_participatory_spaces_minors_configs do |t| + t.string :access_type, null: false, default: "all" + t.string :authorization + t.integer :max_age, null: false, default: 16 + t.references :participatory_space, polymorphic: true, index: { name: "index_minor_config_on_space_type_and_id" } + t.timestamps + end + end +end diff --git a/db/migrate/20230728095809_create_decidim_templates.decidim_templates.rb b/db/migrate/20230728095809_create_decidim_templates.decidim_templates.rb new file mode 100644 index 0000000000..1eac5dd88b --- /dev/null +++ b/db/migrate/20230728095809_create_decidim_templates.decidim_templates.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true +# This migration comes from decidim_templates (originally 20200518093819) + +class CreateDecidimTemplates < ActiveRecord::Migration[5.2] + def change + create_table :decidim_templates_templates do |t| + t.integer :decidim_organization_id, null: false, index: { name: "index_decidim_templates_organization" } + t.references :templatable, polymorphic: true, index: { name: "index_decidim_templates_templatable" } + t.jsonb :name, null: false + t.jsonb :description + t.timestamps + end + end +end diff --git a/db/migrate/20240123140327_create_decidim_awesome_vote_weights.decidim_decidim_awesome.rb b/db/migrate/20240123140327_create_decidim_awesome_vote_weights.decidim_decidim_awesome.rb new file mode 100644 index 0000000000..64482b4ed9 --- /dev/null +++ b/db/migrate/20240123140327_create_decidim_awesome_vote_weights.decidim_decidim_awesome.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true +# This migration comes from decidim_decidim_awesome (originally 20231006113837) + +class CreateDecidimAwesomeVoteWeights < ActiveRecord::Migration[6.0] + def change + create_table :decidim_awesome_vote_weights do |t| + # this might be polymorphic in the future (if other types of votes are supported) + t.references :proposal_vote, null: false, index: { name: "decidim_awesome_proposals_weights_vote" } + + t.integer :weight, null: false, default: 1 + t.timestamps + end + end +end diff --git a/db/migrate/20240123140328_create_decidim_awesome_proposal_extra_fields.decidim_decidim_awesome.rb b/db/migrate/20240123140328_create_decidim_awesome_proposal_extra_fields.decidim_decidim_awesome.rb new file mode 100644 index 0000000000..781fd3f069 --- /dev/null +++ b/db/migrate/20240123140328_create_decidim_awesome_proposal_extra_fields.decidim_decidim_awesome.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true +# This migration comes from decidim_decidim_awesome (originally 20231006113841) + +class CreateDecidimAwesomeProposalExtraFields < ActiveRecord::Migration[6.0] + def change + create_table :decidim_awesome_proposal_extra_fields do |t| + # this might be polymorphic in the future (if other types of votes are supported) + t.references :decidim_proposal, null: false, index: { name: "decidim_awesome_extra_fields_on_proposal" } + + t.jsonb :vote_weight_totals + t.integer :weight_total, default: 0 + t.timestamps + end + end +end diff --git a/db/migrate/20240311160646_create_decidim_authorization_transfers.decidim.rb b/db/migrate/20240311160646_create_decidim_authorization_transfers.decidim.rb new file mode 100644 index 0000000000..49f21cfeaa --- /dev/null +++ b/db/migrate/20240311160646_create_decidim_authorization_transfers.decidim.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true +# This migration comes from decidim (originally 20220629194812) + +class CreateDecidimAuthorizationTransfers < ActiveRecord::Migration[6.1] + def change + create_table :decidim_authorization_transfers do |t| + t.references :user, null: false, foreign_key: { to_table: :decidim_users }, index: true + t.references :source_user, null: false, foreign_key: { to_table: :decidim_users }, index: true + t.references :authorization, null: false, foreign_key: { to_table: :decidim_authorizations }, index: true + + t.datetime :created_at, null: false + end + + create_table :decidim_authorization_transfer_records do |t| + t.references :transfer, null: false, foreign_key: { to_table: :decidim_authorization_transfers }, index: true + t.references :resource, polymorphic: true, null: false + + t.datetime :created_at, null: false + end + end +end diff --git a/db/migrate/20240311160647_rename_terms_of_use.decidim.rb b/db/migrate/20240311160647_rename_terms_of_use.decidim.rb new file mode 100644 index 0000000000..5c74f08ef7 --- /dev/null +++ b/db/migrate/20240311160647_rename_terms_of_use.decidim.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true +# This migration comes from decidim (originally 20230322101707) + +class RenameTermsOfUse < ActiveRecord::Migration[6.1] + def change + rename_column :decidim_organizations, :admin_terms_of_use_body, :admin_terms_of_service_body + + # rubocop:disable Rails/SkipsModelValidations + reversible do |dir| + dir.up do + Decidim::StaticPage.where(slug: "terms-and-conditions").update_all( + slug: "terms-of-service" + ) + end + + dir.down do + Decidim::StaticPage.where(slug: "terms-of-service").update_all( + slug: "terms-and-conditions" + ) + end + end + # rubocop:enable Rails/SkipsModelValidations + end +end diff --git a/db/migrate/20240311160648_add_content_policy_to_decidim_organizations.decidim.rb b/db/migrate/20240311160648_add_content_policy_to_decidim_organizations.decidim.rb new file mode 100644 index 0000000000..19c1260279 --- /dev/null +++ b/db/migrate/20240311160648_add_content_policy_to_decidim_organizations.decidim.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true +# This migration comes from decidim (originally 20230409123300) + +class AddContentPolicyToDecidimOrganizations < ActiveRecord::Migration[6.1] + def change + add_column :decidim_organizations, :content_security_policy, :jsonb, default: {} + end +end diff --git a/db/migrate/20240311160649_change_states_on_amendments.decidim.rb b/db/migrate/20240311160649_change_states_on_amendments.decidim.rb new file mode 100644 index 0000000000..1f0af8c7e2 --- /dev/null +++ b/db/migrate/20240311160649_change_states_on_amendments.decidim.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true +# This migration comes from decidim (originally 20230427105700) + +class ChangeStatesOnAmendments < ActiveRecord::Migration[6.1] + class Amendment < ApplicationRecord + self.table_name = :decidim_amendments + STATES = { draft: 0, evaluating: 10, accepted: 20, rejected: 30, withdrawn: -1 }.freeze + end + + def up + rename_column :decidim_amendments, :state, :old_state + add_column :decidim_amendments, :state, :integer, default: 0, null: false + + Amendment.reset_column_information + + Amendment::STATES.each_pair do |status, index| + Amendment.where(old_state: status).update_all(state: index) # rubocop:disable Rails/SkipsModelValidations + end + + remove_column :decidim_amendments, :old_state + end + + def down + rename_column :decidim_amendments, :state, :old_state + add_column :decidim_amendments, :state, :string, default: "draft", null: false + + Amendment.reset_column_information + + Amendment::STATES.each_pair do |status, index| + Amendment.where(old_state: index).update_all(state: status) # rubocop:disable Rails/SkipsModelValidations + end + + remove_column :decidim_amendments, :old_state + end +end diff --git a/db/migrate/20240311160650_change_states_on_reminder_records.decidim.rb b/db/migrate/20240311160650_change_states_on_reminder_records.decidim.rb new file mode 100644 index 0000000000..68d84843a5 --- /dev/null +++ b/db/migrate/20240311160650_change_states_on_reminder_records.decidim.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true +# This migration comes from decidim (originally 20230427105701) + +class ChangeStatesOnReminderRecords < ActiveRecord::Migration[6.1] + class ReminderRecord < ApplicationRecord + self.table_name = :decidim_reminder_records + STATES = { active: 0, pending: 10, completed: 20, deleted: -1 }.freeze + end + + def up + rename_column :decidim_reminder_records, :state, :old_state + add_column :decidim_reminder_records, :state, :integer, default: 0, null: false + + ReminderRecord.reset_column_information + + ReminderRecord::STATES.each_pair do |status, index| + ReminderRecord.where(old_state: status).update_all(state: index) # rubocop:disable Rails/SkipsModelValidations + end + + remove_column :decidim_reminder_records, :old_state + end + + def down + rename_column :decidim_reminder_records, :state, :old_state + add_column :decidim_reminder_records, :state, :string, default: "draft", null: false + ReminderRecord.reset_column_information + + ReminderRecord::STATES.each_pair do |status, index| + ReminderRecord.where(old_state: index).update_all(state: status) # rubocop:disable Rails/SkipsModelValidations + end + + remove_column :decidim_reminder_records, :old_state + end +end diff --git a/db/migrate/20240311160651_change_default_value_for_decidim_endorsements.decidim.rb b/db/migrate/20240311160651_change_default_value_for_decidim_endorsements.decidim.rb new file mode 100644 index 0000000000..8c079d4b2f --- /dev/null +++ b/db/migrate/20240311160651_change_default_value_for_decidim_endorsements.decidim.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true +# This migration comes from decidim (originally 20231027142329) + +class ChangeDefaultValueForDecidimEndorsements < ActiveRecord::Migration[6.1] + def up + change_column_default :decidim_endorsements, :decidim_user_group_id, 0 + end + + def down + change_column_default :decidim_endorsements, :decidim_user_group_id, nil + end +end diff --git a/db/migrate/20240311160652_remove_official_img_header.decidim.rb b/db/migrate/20240311160652_remove_official_img_header.decidim.rb new file mode 100644 index 0000000000..5e418ee5f3 --- /dev/null +++ b/db/migrate/20240311160652_remove_official_img_header.decidim.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true +# This migration comes from decidim (originally 20231123111229) + +class RemoveOfficialImgHeader < ActiveRecord::Migration[6.1] + def up + remove_column :decidim_organizations, :official_img_header + end + + def down + add_column :decidim_organizations, :official_img_header, :string + end +end diff --git a/db/migrate/20240311160653_change_steps_dates_to_datetime.decidim_participatory_processes.rb b/db/migrate/20240311160653_change_steps_dates_to_datetime.decidim_participatory_processes.rb new file mode 100644 index 0000000000..92e4fb79e9 --- /dev/null +++ b/db/migrate/20240311160653_change_steps_dates_to_datetime.decidim_participatory_processes.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true +# This migration comes from decidim_participatory_processes (originally 20220315100140) + +class ChangeStepsDatesToDatetime < ActiveRecord::Migration[6.0] + def change + change_column :decidim_participatory_process_steps, :start_date, :datetime + change_column :decidim_participatory_process_steps, :end_date, :datetime + end +end diff --git a/db/migrate/20240311160654_change_states_on_collaborative_drafts.decidim_proposals.rb b/db/migrate/20240311160654_change_states_on_collaborative_drafts.decidim_proposals.rb new file mode 100644 index 0000000000..225158e378 --- /dev/null +++ b/db/migrate/20240311160654_change_states_on_collaborative_drafts.decidim_proposals.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true +# This migration comes from decidim_proposals (originally 20230427105700) + +class ChangeStatesOnCollaborativeDrafts < ActiveRecord::Migration[6.1] + class CollaborativeDraft < ApplicationRecord + self.table_name = :decidim_proposals_collaborative_drafts + STATES = { open: 0, published: 10, withdrawn: -1 }.freeze + end + + def up + rename_column :decidim_proposals_collaborative_drafts, :state, :old_state + add_column :decidim_proposals_collaborative_drafts, :state, :integer, default: 0, null: false + + CollaborativeDraft.reset_column_information + + CollaborativeDraft::STATES.each_pair do |status, index| + CollaborativeDraft.where(old_state: status).update_all(state: index) # rubocop:disable Rails/SkipsModelValidations + end + + remove_column :decidim_proposals_collaborative_drafts, :old_state + end + + def down + rename_column :decidim_proposals_collaborative_drafts, :state, :old_state + add_column :decidim_proposals_collaborative_drafts, :state, :string + + CollaborativeDraft.reset_column_information + + CollaborativeDraft::STATES.each_pair do |status, index| + CollaborativeDraft.where(old_state: index).update_all(state: status) # rubocop:disable Rails/SkipsModelValidations + end + + remove_column :decidim_proposals_collaborative_drafts, :old_state + end +end diff --git a/db/migrate/20240311160655_change_states_on_proposals.decidim_proposals.rb b/db/migrate/20240311160655_change_states_on_proposals.decidim_proposals.rb new file mode 100644 index 0000000000..7ea1fed870 --- /dev/null +++ b/db/migrate/20240311160655_change_states_on_proposals.decidim_proposals.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true +# This migration comes from decidim_proposals (originally 20230427105700) + +class ChangeStatesOnProposals < ActiveRecord::Migration[6.1] + class Proposal < ApplicationRecord + self.table_name = :decidim_proposals_proposals + STATES = { not_answered: 0, evaluating: 10, accepted: 20, rejected: -10, withdrawn: -20 }.freeze + end + + def up + rename_column :decidim_proposals_proposals, :state, :old_state + add_column :decidim_proposals_proposals, :state, :integer, default: 0, null: false + + Proposal.reset_column_information + + Proposal::STATES.each_pair do |status, index| + Proposal.where(old_state: status).update_all(state: index) # rubocop:disable Rails/SkipsModelValidations + end + + remove_column :decidim_proposals_proposals, :old_state + end + + def down + rename_column :decidim_proposals_proposals, :state, :old_state + add_column :decidim_proposals_proposals, :state, :string + + Proposal.reset_column_information + + Proposal::STATES.each_pair do |status, index| + Proposal.where(old_state: index).update_all(state: status) # rubocop:disable Rails/SkipsModelValidations + end + + remove_column :decidim_proposals_proposals, :old_state + end +end diff --git a/db/migrate/20240311160656_change_types_and_registration_types_on_meetings.decidim_meetings.rb b/db/migrate/20240311160656_change_types_and_registration_types_on_meetings.decidim_meetings.rb new file mode 100644 index 0000000000..5c57e6d61d --- /dev/null +++ b/db/migrate/20240311160656_change_types_and_registration_types_on_meetings.decidim_meetings.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true +# This migration comes from decidim_meetings (originally 20230427105701) + +class ChangeTypesAndRegistrationTypesOnMeetings < ActiveRecord::Migration[6.1] + class Meeting < ApplicationRecord + self.table_name = :decidim_meetings_meetings + + TYPE_OF_MEETING = { in_person: 0, online: 10, hybrid: 20 }.freeze + REGISTRATION_TYPES = { registration_disabled: 0, on_this_platform: 10, on_different_platform: 20 }.freeze + end + + def up + rename_column :decidim_meetings_meetings, :type_of_meeting, :old_type_of_meeting + rename_column :decidim_meetings_meetings, :registration_type, :old_registration_type + add_column :decidim_meetings_meetings, :type_of_meeting, :integer, default: 0, null: false + add_column :decidim_meetings_meetings, :registration_type, :integer, default: 0, null: false + + Meeting.reset_column_information + + Meeting::TYPE_OF_MEETING.each_pair do |status, index| + Meeting.where(old_type_of_meeting: status).update_all(type_of_meeting: index) # rubocop:disable Rails/SkipsModelValidations + end + Meeting::REGISTRATION_TYPES.each_pair do |status, index| + Meeting.where(old_registration_type: status).update_all(registration_type: index) # rubocop:disable Rails/SkipsModelValidations + end + + remove_column :decidim_meetings_meetings, :old_type_of_meeting + remove_column :decidim_meetings_meetings, :old_registration_type + end + + def down + rename_column :decidim_meetings_meetings, :type_of_meeting, :old_type_of_meeting + rename_column :decidim_meetings_meetings, :registration_type, :old_registration_type + + add_column :decidim_meetings_meetings, :type_of_meeting, :string, default: null + add_column :decidim_meetings_meetings, :registration_type, :string, default: null + + Meeting.reset_column_information + + Meeting::TYPE_OF_MEETING.each_pair do |status, index| + Meeting.where(old_type_of_meeting: index).update_all(type_of_meeting: status) # rubocop:disable Rails/SkipsModelValidations + end + Meeting::REGISTRATION_TYPES.each_pair do |status, index| + Meeting.where(old_registration_type: index).update_all(registration_type: status) # rubocop:disable Rails/SkipsModelValidations + end + + remove_column :decidim_meetings_meetings, :old_type_of_meeting + remove_column :decidim_meetings_meetings, :old_registration_type + end +end diff --git a/db/migrate/20240311160657_add_field_values_and_target_to_decidim_templates.decidim_templates.rb b/db/migrate/20240311160657_add_field_values_and_target_to_decidim_templates.decidim_templates.rb new file mode 100644 index 0000000000..fd1afdb631 --- /dev/null +++ b/db/migrate/20240311160657_add_field_values_and_target_to_decidim_templates.decidim_templates.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true +# This migration comes from decidim_templates (originally 20221006055954) + +class AddFieldValuesAndTargetToDecidimTemplates < ActiveRecord::Migration[6.0] + class Template < ApplicationRecord + self.table_name = :decidim_templates_templates + end + + def change + add_column :decidim_templates_templates, :field_values, :json, default: {} + add_column :decidim_templates_templates, :target, :string + + reversible do |direction| + direction.up do + # rubocop:disable Rails/SkipsModelValidations + Template.where(templatable_type: "Decidim::Forms::Questionnaire").update_all(target: "questionnaire") + Template.where(templatable_type: "Decidim::Organization").update_all(target: "user_block") + # rubocop:enable Rails/SkipsModelValidations + end + end + end +end diff --git a/db/migrate/20240311160658_add_published_at_to_decidim_blogs_posts.decidim_blogs.rb b/db/migrate/20240311160658_add_published_at_to_decidim_blogs_posts.decidim_blogs.rb new file mode 100644 index 0000000000..09d06f1b82 --- /dev/null +++ b/db/migrate/20240311160658_add_published_at_to_decidim_blogs_posts.decidim_blogs.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true +# This migration comes from decidim_blogs (originally 20220812122940) + +class AddPublishedAtToDecidimBlogsPosts < ActiveRecord::Migration[6.1] + class Post < ApplicationRecord + self.table_name = :decidim_blogs_posts + end + + def change + add_column :decidim_blogs_posts, :published_at, :datetime + + reversible do |direction| + direction.up do + Post.update_all("published_at = created_at") # rubocop:disable Rails/SkipsModelValidations + end + end + end +end diff --git a/db/migrate/20240327123826_rename_editor_images_awesome_config.decidim_decidim_awesome.rb b/db/migrate/20240327123826_rename_editor_images_awesome_config.decidim_decidim_awesome.rb new file mode 100644 index 0000000000..a556be33f3 --- /dev/null +++ b/db/migrate/20240327123826_rename_editor_images_awesome_config.decidim_decidim_awesome.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true +# This migration comes from decidim_decidim_awesome (originally 20240306175331) + +class RenameEditorImagesAwesomeConfig < ActiveRecord::Migration[6.1] + class AwesomeConfig < ApplicationRecord + self.table_name = :decidim_awesome_config + end + + # rubocop:disable Rails/SkipsModelValidations + def up + AwesomeConfig.where(var: :allow_images_in_full_editor).update_all(var: :allow_images_in_editors) + AwesomeConfig.where(var: :allow_images_in_small_editor).destroy_all + end + + def down + AwesomeConfig.where(var: :allow_images_in_editors).update_all(var: :allow_images_in_full_editor) + end + # rubocop:enable Rails/SkipsModelValidations +end diff --git a/db/migrate/20240611125821_add_comment_vote_counter_cache_to_comments.decidim_comments.rb b/db/migrate/20240611125821_add_comment_vote_counter_cache_to_comments.decidim_comments.rb new file mode 100644 index 0000000000..e4c0f57627 --- /dev/null +++ b/db/migrate/20240611125821_add_comment_vote_counter_cache_to_comments.decidim_comments.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true +# This migration comes from decidim_comments (originally 20240304092558) + +class AddCommentVoteCounterCacheToComments < ActiveRecord::Migration[6.1] + def change + add_column :decidim_comments_comments, :up_votes_count, :integer, null: false, default: 0, index: true + add_column :decidim_comments_comments, :down_votes_count, :integer, null: false, default: 0, index: true + + # We cannot use the reset_counters as up_votes and down_votes are scoped associationws + reversible do |dir| + dir.up do + Decidim::Comments::Comment.reset_column_information + Decidim::Comments::Comment.find_each do |record| + # rubocop:disable Rails/SkipsModelValidations + record.class.update_counters(record.id, up_votes_count: record.up_votes.length) + record.class.update_counters(record.id, down_votes_count: record.down_votes.length) + # rubocop:enable Rails/SkipsModelValidations + end + end + end + end +end diff --git a/db/migrate/20240611125822_add_valuation_assignments_count_to_decidim_proposals_proposals.decidim_proposals.rb b/db/migrate/20240611125822_add_valuation_assignments_count_to_decidim_proposals_proposals.decidim_proposals.rb new file mode 100644 index 0000000000..97a1674473 --- /dev/null +++ b/db/migrate/20240611125822_add_valuation_assignments_count_to_decidim_proposals_proposals.decidim_proposals.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true +# This migration comes from decidim_proposals (originally 20240404202756) + +class AddValuationAssignmentsCountToDecidimProposalsProposals < ActiveRecord::Migration[6.1] + def change + add_column :decidim_proposals_proposals, :valuation_assignments_count, :integer, default: 0 + + reversible do |dir| + dir.up do + Decidim::Proposals::Proposal.reset_column_information + Decidim::Proposals::Proposal.find_each do |record| + Decidim::Proposals::Proposal.reset_counters(record.id, :valuation_assignments) + end + end + end + end +end diff --git a/db/migrate/20240813060358_add_decidim_awesome_proposal_private_fields.decidim_decidim_awesome.rb b/db/migrate/20240813060358_add_decidim_awesome_proposal_private_fields.decidim_decidim_awesome.rb new file mode 100644 index 0000000000..8ebac8029f --- /dev/null +++ b/db/migrate/20240813060358_add_decidim_awesome_proposal_private_fields.decidim_decidim_awesome.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true +# This migration comes from decidim_decidim_awesome (originally 20240531224204) + +class AddDecidimAwesomeProposalPrivateFields < ActiveRecord::Migration[6.0] + class ProposalExtraField < ApplicationRecord + self.table_name = :decidim_awesome_proposal_extra_fields + end + + def change + add_column :decidim_awesome_proposal_extra_fields, :private_body, :string + add_column :decidim_awesome_proposal_extra_fields, :decidim_proposal_type, :string + reversible do |direction| + direction.up do + execute <<~SQL.squish + UPDATE decidim_awesome_proposal_extra_fields + SET decidim_proposal_type = 'Decidim::Proposals::Proposal' + SQL + end + end + + remove_index :decidim_awesome_proposal_extra_fields, name: "decidim_awesome_extra_fields_on_proposal" + add_index :decidim_awesome_proposal_extra_fields, + [:decidim_proposal_id, :decidim_proposal_type], + name: "index_decidim_awesome_proposal_extra_fields_on_decidim_proposal" + + change_column_null :decidim_awesome_proposal_extra_fields, :decidim_proposal_id, false + change_column_null :decidim_awesome_proposal_extra_fields, :decidim_proposal_type, false + ProposalExtraField.reset_column_information + end +end diff --git a/db/migrate/20240813060359_add_decidim_awesome_proposal_private_fields_date.decidim_decidim_awesome.rb b/db/migrate/20240813060359_add_decidim_awesome_proposal_private_fields_date.decidim_decidim_awesome.rb new file mode 100644 index 0000000000..7d6b053c8c --- /dev/null +++ b/db/migrate/20240813060359_add_decidim_awesome_proposal_private_fields_date.decidim_decidim_awesome.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true +# This migration comes from decidim_decidim_awesome (originally 20240729164227) + +class AddDecidimAwesomeProposalPrivateFieldsDate < ActiveRecord::Migration[6.1] + class ProposalExtraField < ApplicationRecord + self.table_name = :decidim_awesome_proposal_extra_fields + end + + def change + add_column :decidim_awesome_proposal_extra_fields, :private_body_updated_at, :datetime + + reversible do |direction| + direction.up do + execute <<~SQL.squish + UPDATE decidim_awesome_proposal_extra_fields + SET private_body_updated_at = updated_at + SQL + end + end + end +end diff --git a/db/migrate/20241014151251_add_withdrawn_at_field_to_proposals.decidim_proposals.rb b/db/migrate/20241014151251_add_withdrawn_at_field_to_proposals.decidim_proposals.rb new file mode 100644 index 0000000000..53d0237000 --- /dev/null +++ b/db/migrate/20241014151251_add_withdrawn_at_field_to_proposals.decidim_proposals.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true +# This migration comes from decidim_proposals (originally 20240110203500) + +class AddWithdrawnAtFieldToProposals < ActiveRecord::Migration[6.1] + class CustomProposal < Decidim::Proposals::ApplicationRecord + self.table_name = "decidim_proposals_proposals" + STATES = { not_answered: 0, evaluating: 10, accepted: 20, rejected: -10, withdrawn: -20 }.freeze + enum state: STATES, _default: "not_answered" + end + + def up + add_column :decidim_proposals_proposals, :withdrawn_at, :datetime + + CustomProposal.withdrawn.find_each do |proposal| + proposal.withdrawn_at = proposal.updated_at + proposal.save! + end + end + + def down + CustomProposal.where.not(withdrawn_at: null).find_each do |proposal| + proposal.state = :withdrawn + proposal.save! + end + + remove_column :decidim_proposals_proposals, :withdrawn_at + end +end diff --git a/db/migrate/20241014151252_create_decidim_proposals_proposal_state.decidim_proposals.rb b/db/migrate/20241014151252_create_decidim_proposals_proposal_state.decidim_proposals.rb new file mode 100644 index 0000000000..8721f69351 --- /dev/null +++ b/db/migrate/20241014151252_create_decidim_proposals_proposal_state.decidim_proposals.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true +# This migration comes from decidim_proposals (originally 20240110203501) + +class CreateDecidimProposalsProposalState < ActiveRecord::Migration[6.1] + def change + create_table :decidim_proposals_proposal_states do |t| + t.jsonb :title + t.jsonb :announcement_title + t.string :token, null: false + t.references :decidim_component, index: true, null: false + t.integer :proposals_count, default: 0, null: false + t.string :bg_color, default: "#F6F8FA", null: false + t.string :text_color, default: "#4B5058", null: false + end + end +end diff --git a/db/migrate/20241014151253_add_state_id_to_decidim_proposals_proposals.decidim_proposals.rb b/db/migrate/20241014151253_add_state_id_to_decidim_proposals_proposals.decidim_proposals.rb new file mode 100644 index 0000000000..c1bc21c6a4 --- /dev/null +++ b/db/migrate/20241014151253_add_state_id_to_decidim_proposals_proposals.decidim_proposals.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true +# This migration comes from decidim_proposals (originally 20240110203502) + +class AddStateIdToDecidimProposalsProposals < ActiveRecord::Migration[6.1] + def up + add_column :decidim_proposals_proposals, :decidim_proposals_proposal_state_id, :integer, index: true + add_foreign_key :decidim_proposals_proposals, :decidim_proposals_proposal_states, column: :decidim_proposals_proposal_state_id + end + + def down + remove_foreign_key :decidim_proposals_proposals, column: :decidim_proposals_proposal_state_id + remove_column :decidim_proposals_proposals, :decidim_proposals_proposal_state_id + end +end diff --git a/db/migrate/20241014151254_remove_state_from_decidim_proposals_proposals.decidim_proposals.rb b/db/migrate/20241014151254_remove_state_from_decidim_proposals_proposals.decidim_proposals.rb new file mode 100644 index 0000000000..0503308e36 --- /dev/null +++ b/db/migrate/20241014151254_remove_state_from_decidim_proposals_proposals.decidim_proposals.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true +# This migration comes from decidim_proposals (originally 20240110203503) + +class RemoveStateFromDecidimProposalsProposals < ActiveRecord::Migration[6.1] + def up + rename_column :decidim_proposals_proposals, :state, :old_state + end + + def down + rename_column :decidim_proposals_proposals, :old_state, :state + end +end diff --git a/db/migrate/20241014151255_create_default_proposal_states.decidim_proposals.rb b/db/migrate/20241014151255_create_default_proposal_states.decidim_proposals.rb new file mode 100644 index 0000000000..f7b802dd9a --- /dev/null +++ b/db/migrate/20241014151255_create_default_proposal_states.decidim_proposals.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true +# This migration comes from decidim_proposals (originally 20240110203504) + +class CreateDefaultProposalStates < ActiveRecord::Migration[6.1] + class CustomProposal < ApplicationRecord + belongs_to :proposal_state, + class_name: "Decidim::Proposals::ProposalState", + foreign_key: "decidim_proposals_proposal_state_id", + inverse_of: :proposals, + optional: true + + self.table_name = :decidim_proposals_proposals + STATES = { not_answered: 0, evaluating: 10, accepted: 20, rejected: -10 }.freeze + enum old_state: STATES, _default: "not_answered" + end + + def up + CustomProposal.reset_column_information + Decidim::Proposals::ProposalState.reset_column_information + Decidim::Component.where(manifest_name: "proposals").find_each do |component| + admin_user = component.organization.admins.first + Decidim::Proposals.create_default_states!(component, admin_user) + + CustomProposal.where(decidim_component_id: component.id).find_each do |proposal| + next if proposal.old_state == "not_answered" + next if proposal.old_state.nil? + + token = I18n.t("decidim.proposals.answers.#{proposal.old_state}").downcase.tr(" ", "_").tr("ó", "o") + proposal.update!(proposal_state: Decidim::Proposals::ProposalState.where(component:, token:).first!) + end + end + end + + def down + raise ActiveRecord::IrreversibleMigration + end +end diff --git a/db/migrate/20241014151256_change_color_fields_on_proposals_states.decidim_proposals.rb b/db/migrate/20241014151256_change_color_fields_on_proposals_states.decidim_proposals.rb new file mode 100644 index 0000000000..b352336886 --- /dev/null +++ b/db/migrate/20241014151256_change_color_fields_on_proposals_states.decidim_proposals.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true +# This migration comes from decidim_proposals (originally 20240209092404) + +class ChangeColorFieldsOnProposalsStates < ActiveRecord::Migration[6.1] + class ProposalState < ApplicationRecord + self.table_name = :decidim_proposals_proposal_states + + def self.colors + { + gray: { + background: "#F6F8FA", + foreground: "#4B5058" + }, + green: { + background: "#E3FCE9", + foreground: "#15602C" + }, + orange: { + background: "#FFF1E5", + foreground: "#BC4C00" + }, + red: { + background: "#FFEBE9", + foreground: "#D1242F" + } + } + end + end + + def up + colors = ProposalState.colors + + # rubocop:disable Rails/SkipsModelValidations + ProposalState.where(token: :accepted).update_all( + bg_color: colors[:green][:background], text_color: colors[:green][:foreground] + ) + ProposalState.where(token: :evaluating).update_all( + bg_color: colors[:orange][:background], text_color: colors[:orange][:foreground] + ) + ProposalState.where(token: :rejected).update_all( + bg_color: colors[:red][:background], text_color: colors[:red][:foreground] + ) + # rubocop:enable Rails/SkipsModelValidations + end + + def down + raise ActiveRecord::IrreversibleMigration + end +end diff --git a/db/migrate/20241015093724_create_decidim_internal_evaluation_internal_evaluations.decidim_internal_evaluation.rb b/db/migrate/20241015093724_create_decidim_internal_evaluation_internal_evaluations.decidim_internal_evaluation.rb new file mode 100644 index 0000000000..f4f05ef2eb --- /dev/null +++ b/db/migrate/20241015093724_create_decidim_internal_evaluation_internal_evaluations.decidim_internal_evaluation.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true +# This migration comes from decidim_internal_evaluation (originally 20240625151452) + +class CreateDecidimInternalEvaluationInternalEvaluations < ActiveRecord::Migration[6.1] + def change + create_table :decidim_internal_evaluation_internal_evaluations do |t| + t.references :decidim_proposal, null: false, index: { name: "index_decidim_internal_evaluations_on_proposal" } + t.references :decidim_proposal_state, index: { name: "index_decidim_internal_evaluations_on_proposal_state" } + t.references :decidim_author, null: false, index: { name: "index_decidim_internal_evaluations_on_author" } + t.jsonb :body + + t.timestamps + end + end +end diff --git a/db/migrate/20241015093725_change_internal_evaluations_body_to_text.decidim_internal_evaluation.rb b/db/migrate/20241015093725_change_internal_evaluations_body_to_text.decidim_internal_evaluation.rb new file mode 100644 index 0000000000..ae4e357954 --- /dev/null +++ b/db/migrate/20241015093725_change_internal_evaluations_body_to_text.decidim_internal_evaluation.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true +# This migration comes from decidim_internal_evaluation (originally 20240715150021) + +class ChangeInternalEvaluationsBodyToText < ActiveRecord::Migration[6.1] + def up + change_column :decidim_internal_evaluation_internal_evaluations, :body, :text + end + + def down + change_column :decidim_internal_evaluation_internal_evaluations, :body, :jsonb + end +end diff --git a/db/schema.rb b/db/schema.rb index 700ca5a082..86d8e8a7e9 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -2,15 +2,15 @@ # of editing this file, please use the migrations feature of Active Record to # incrementally modify your database, and then regenerate this schema definition. # -# This file is the source Rails uses to define your schema when running `rails -# db:schema:load`. When creating a new database, `rails db:schema:load` tends to +# This file is the source Rails uses to define your schema when running `bin/rails +# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to # be faster and is potentially less error prone than running all of your # migrations from scratch. Old migrations may fail to apply correctly if those # migrations use external dependencies or application code. # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2022_05_05_131853) do +ActiveRecord::Schema.define(version: 2024_10_15_093725) do # These are extensions that must be enabled in order to support this database enable_extension "ltree" @@ -36,9 +36,16 @@ t.bigint "byte_size", null: false t.string "checksum", null: false t.datetime "created_at", null: false + t.string "service_name", null: false t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true end + create_table "active_storage_variant_records", force: :cascade do |t| + t.bigint "blob_id", null: false + t.string "variation_digest", null: false + t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true + end + create_table "decidim_accountability_results", id: :serial, force: :cascade do |t| t.jsonb "title" t.jsonb "description" @@ -120,14 +127,13 @@ t.bigint "decidim_amendable_id" t.string "decidim_emendation_type" t.bigint "decidim_emendation_id" - t.string "state" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.integer "state", default: 0, null: false t.index ["decidim_amendable_id", "decidim_amendable_type"], name: "index_on_amendable" t.index ["decidim_emendation_id"], name: "index_decidim_amendments_on_decidim_emendation_id" t.index ["decidim_user_id", "decidim_amendable_id", "decidim_amendable_type"], name: "index_on_amender_and_amendable" t.index ["decidim_user_id"], name: "index_decidim_amendments_on_decidim_user_id" - t.index ["state"], name: "index_decidim_amendments_on_state" end create_table "decidim_area_types", force: :cascade do |t| @@ -273,6 +279,25 @@ t.index ["attachment_collection_id"], name: "index_decidim_attachments_on_attachment_collection_id" end + create_table "decidim_authorization_transfer_records", force: :cascade do |t| + t.bigint "transfer_id", null: false + t.string "resource_type", null: false + t.bigint "resource_id", null: false + t.datetime "created_at", null: false + t.index ["resource_type", "resource_id"], name: "index_decidim_authorization_transfer_records_on_resource" + t.index ["transfer_id"], name: "index_decidim_authorization_transfer_records_on_transfer_id" + end + + create_table "decidim_authorization_transfers", force: :cascade do |t| + t.bigint "user_id", null: false + t.bigint "source_user_id", null: false + t.bigint "authorization_id", null: false + t.datetime "created_at", null: false + t.index ["authorization_id"], name: "index_decidim_authorization_transfers_on_authorization_id" + t.index ["source_user_id"], name: "index_decidim_authorization_transfers_on_source_user_id" + t.index ["user_id"], name: "index_decidim_authorization_transfers_on_user_id" + end + create_table "decidim_authorizations", id: :serial, force: :cascade do |t| t.string "name", null: false t.jsonb "metadata" @@ -318,6 +343,26 @@ t.index ["decidim_organization_id"], name: "decidim_awesome_editor_images_constraint_organization" end + create_table "decidim_awesome_proposal_extra_fields", force: :cascade do |t| + t.bigint "decidim_proposal_id", null: false + t.jsonb "vote_weight_totals" + t.integer "weight_total", default: 0 + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.string "private_body" + t.string "decidim_proposal_type", null: false + t.datetime "private_body_updated_at" + t.index ["decidim_proposal_id", "decidim_proposal_type"], name: "index_decidim_awesome_proposal_extra_fields_on_decidim_proposal" + end + + create_table "decidim_awesome_vote_weights", force: :cascade do |t| + t.bigint "proposal_vote_id", null: false + t.integer "weight", default: 1, null: false + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["proposal_vote_id"], name: "decidim_awesome_proposals_weights_vote" + end + create_table "decidim_blogs_posts", id: :serial, force: :cascade do |t| t.jsonb "title" t.jsonb "body" @@ -330,6 +375,7 @@ t.integer "endorsements_count", default: 0, null: false t.integer "comments_count", default: 0, null: false t.integer "follows_count", default: 0, null: false + t.datetime "published_at" t.index ["decidim_author_id", "decidim_author_type"], name: "index_decidim_blogs_posts_on_decidim_author" t.index ["decidim_component_id"], name: "index_decidim_blogs_posts_on_decidim_component_id" t.index ["decidim_user_group_id"], name: "index_decidim_blogs_posts_on_decidim_user_group_id" @@ -378,13 +424,16 @@ t.date "selected_at" t.integer "comments_count", default: 0, null: false t.integer "follows_count", default: 0, null: false + t.text "address" + t.float "latitude" + t.float "longitude" t.index ["decidim_budgets_budget_id"], name: "index_decidim_budgets_projects_on_decidim_budgets_budget_id" t.index ["decidim_scope_id"], name: "index_decidim_budgets_projects_on_decidim_scope_id" end create_table "decidim_categories", id: :serial, force: :cascade do |t| t.jsonb "name", null: false - t.jsonb "description", null: false + t.jsonb "description" t.integer "parent_id" t.integer "decidim_participatory_space_id" t.string "decidim_participatory_space_type" @@ -446,6 +495,8 @@ t.string "decidim_participatory_space_type" t.integer "decidim_participatory_space_id" t.datetime "deleted_at" + t.integer "up_votes_count", default: 0, null: false + t.integer "down_votes_count", default: 0, null: false t.index ["created_at"], name: "index_decidim_comments_comments_on_created_at" t.index ["decidim_author_id", "decidim_author_type"], name: "index_decidim_comments_comments_on_decidim_author" t.index ["decidim_author_id"], name: "decidim_comments_comment_author" @@ -549,7 +600,7 @@ t.bigint "resource_id" t.string "decidim_author_type" t.bigint "decidim_author_id" - t.integer "decidim_user_group_id" + t.integer "decidim_user_group_id", default: 0 t.datetime "created_at", null: false t.datetime "updated_at", null: false t.index ["decidim_author_type", "decidim_author_id"], name: "idx_endorsements_authors" @@ -743,6 +794,12 @@ t.index ["state"], name: "index_decidim_initiatives_committee_members_on_state" end + create_table "decidim_initiatives_settings", force: :cascade do |t| + t.string "initiatives_order", default: "random" + t.bigint "decidim_organization_id" + t.index ["decidim_organization_id"], name: "index_decidim_initiatives_settings_on_decidim_organization_id" + end + create_table "decidim_initiatives_type_scopes", force: :cascade do |t| t.bigint "decidim_initiatives_types_id" t.bigint "decidim_scopes_id" @@ -773,6 +830,7 @@ t.boolean "area_enabled", default: false, null: false t.boolean "child_scope_threshold_enabled", default: false, null: false t.boolean "only_global_scope_enabled", default: false, null: false + t.boolean "comments_enabled", default: true, null: false t.index ["decidim_organization_id"], name: "index_decidim_initiative_types_on_decidim_organization_id" end @@ -790,6 +848,75 @@ t.index ["hash_id"], name: "index_decidim_initiatives_votes_on_hash_id" end + create_table "decidim_internal_evaluation_internal_evaluations", force: :cascade do |t| + t.bigint "decidim_proposal_id", null: false + t.bigint "decidim_proposal_state_id" + t.bigint "decidim_author_id", null: false + t.text "body" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["decidim_author_id"], name: "index_decidim_internal_evaluations_on_author" + t.index ["decidim_proposal_id"], name: "index_decidim_internal_evaluations_on_proposal" + t.index ["decidim_proposal_state_id"], name: "index_decidim_internal_evaluations_on_proposal_state" + end + + create_table "decidim_kids_impersonation_minor_logs", force: :cascade do |t| + t.bigint "decidim_tutor_id" + t.bigint "decidim_minor_id" + t.datetime "started_at" + t.datetime "ended_at" + t.datetime "expired_at" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["decidim_minor_id"], name: "index_decidim_kids_impersonation_minor_logs_on_decidim_minor_id" + t.index ["decidim_tutor_id"], name: "index_decidim_kids_impersonation_minor_logs_on_decidim_tutor_id" + end + + create_table "decidim_kids_minor_accounts", force: :cascade do |t| + t.bigint "decidim_tutor_id", null: false + t.bigint "decidim_minor_id", null: false + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["decidim_minor_id"], name: "index_decidim_kids_minor_accounts_on_decidim_minor_id" + t.index ["decidim_tutor_id", "decidim_minor_id"], name: "decidim_kids_minor_accounts_unique_tutor_and_minor_ids", unique: true + t.index ["decidim_tutor_id"], name: "index_decidim_kids_minor_accounts_on_decidim_tutor_id" + end + + create_table "decidim_kids_minor_data", force: :cascade do |t| + t.bigint "decidim_user_id", null: false + t.string "name" + t.string "birthday" + t.string "email" + t.jsonb "extra_data", default: {}, null: false + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["decidim_user_id"], name: "index_decidim_kids_minor_data_on_decidim_user_id" + end + + create_table "decidim_kids_organization_configs", force: :cascade do |t| + t.integer "decidim_organization_id", null: false + t.boolean "enable_minors_participation", default: false, null: false + t.integer "minimum_minor_age", default: 10, null: false + t.integer "maximum_minor_age", default: 13, null: false + t.string "minors_authorization" + t.string "tutors_authorization" + t.integer "maximum_minor_accounts", default: 3, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["decidim_organization_id"], name: "index_decidim_kids_organization" + end + + create_table "decidim_kids_participatory_spaces_minors_configs", force: :cascade do |t| + t.string "access_type", default: "all", null: false + t.string "authorization" + t.integer "max_age", default: 16, null: false + t.string "participatory_space_type" + t.bigint "participatory_space_id" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["participatory_space_type", "participatory_space_id"], name: "index_minor_config_on_space_type_and_id" + end + create_table "decidim_meetings_agenda_items", force: :cascade do |t| t.bigint "decidim_agenda_id" t.integer "position" @@ -885,11 +1012,9 @@ t.integer "comments_count", default: 0, null: false t.string "salt" t.string "online_meeting_url" - t.string "type_of_meeting", default: "in_person" - t.string "registration_type", default: "registration_disabled", null: false t.string "registration_url" t.integer "follows_count", default: 0, null: false - t.boolean "customize_registration_email", default: false, null: false + t.boolean "customize_registration_email", default: false t.jsonb "registration_email_custom_content" t.datetime "published_at" t.string "video_url" @@ -901,6 +1026,8 @@ t.string "state" t.integer "iframe_access_level", default: 0 t.integer "iframe_embed_type", default: 0 + t.integer "type_of_meeting", default: 0, null: false + t.integer "registration_type", default: 0, null: false t.index ["decidim_author_id", "decidim_author_type"], name: "index_decidim_meetings_meetings_on_author" t.index ["decidim_author_id"], name: "index_decidim_meetings_meetings_on_decidim_author_id" t.index ["decidim_component_id"], name: "index_decidim_meetings_meetings_on_decidim_component_id" @@ -1095,7 +1222,6 @@ t.string "logo" t.string "twitter_handler" t.string "favicon" - t.string "official_img_header" t.string "official_img_footer" t.string "official_url" t.string "instagram_handler" @@ -1132,7 +1258,7 @@ t.boolean "force_users_to_authenticate_before_access_organization", default: false t.jsonb "omniauth_settings" t.boolean "rich_text_editor_in_public_views", default: false - t.jsonb "admin_terms_of_use_body" + t.jsonb "admin_terms_of_service_body" t.string "time_zone", limit: 255, default: "UTC" t.boolean "enable_machine_translations", default: false t.integer "comments_max_length", default: 1000 @@ -1141,6 +1267,7 @@ t.jsonb "available_authorizations", default: {} t.string "external_domain_whitelist", default: [], array: true t.boolean "enable_participatory_space_filters", default: true + t.jsonb "content_security_policy", default: {} t.index ["host"], name: "index_decidim_organizations_on_host", unique: true t.index ["name"], name: "index_decidim_organizations_on_name", unique: true end @@ -1175,8 +1302,8 @@ create_table "decidim_participatory_process_steps", id: :serial, force: :cascade do |t| t.jsonb "title", null: false t.jsonb "description" - t.date "start_date" - t.date "end_date" + t.datetime "start_date" + t.datetime "end_date" t.integer "decidim_participatory_process_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false @@ -1191,6 +1318,14 @@ t.index ["position"], name: "index_order_by_position_for_steps" end + create_table "decidim_participatory_process_types", force: :cascade do |t| + t.jsonb "title", null: false + t.bigint "decidim_organization_id" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["decidim_organization_id"], name: "index_decidim_process_types_on_decidim_organization_id" + end + create_table "decidim_participatory_process_user_roles", id: :serial, force: :cascade do |t| t.integer "decidim_user_id" t.integer "decidim_participatory_process_id" @@ -1236,10 +1371,12 @@ t.boolean "show_metrics", default: true t.integer "weight", default: 1, null: false t.integer "follows_count", default: 0, null: false + t.bigint "decidim_participatory_process_type_id" t.index ["decidim_area_id"], name: "index_decidim_participatory_processes_on_decidim_area_id" t.index ["decidim_organization_id", "slug"], name: "index_unique_process_slug_and_organization", unique: true t.index ["decidim_organization_id"], name: "index_decidim_processes_on_decidim_organization_id" t.index ["decidim_participatory_process_group_id"], name: "idx_process_on_process_group_id" + t.index ["decidim_participatory_process_type_id"], name: "index_decidim_processes_on_decidim_process_type_id" t.index ["decidim_scope_id"], name: "idx_process_on_scope_id" t.index ["decidim_scope_type_id"], name: "index_decidim_participatory_processes_on_decidim_scope_type_id" end @@ -1280,7 +1417,6 @@ t.text "body", null: false t.integer "decidim_component_id", null: false t.integer "decidim_scope_id" - t.string "state" t.string "reference" t.text "address" t.float "latitude" @@ -1294,10 +1430,10 @@ t.integer "coauthorships_count", default: 0, null: false t.integer "comments_count", default: 0, null: false t.integer "follows_count", default: 0, null: false + t.integer "state", default: 0, null: false t.index ["body"], name: "decidim_proposals_collaborative_draft_body_search" t.index ["decidim_component_id"], name: "decidim_proposals_collaborative_drafts_on_decidim_component_id" t.index ["decidim_scope_id"], name: "decidim_proposals_collaborative_drafts_on_decidim_scope_id" - t.index ["state"], name: "decidim_proposals_collaborative_drafts_on_state" t.index ["title"], name: "decidim_proposals_collaborative_drafts_title_search" t.index ["updated_at"], name: "decidim_proposals_collaborative_drafts_on_updated_at" end @@ -1322,6 +1458,17 @@ t.index ["decidim_proposal_id"], name: "decidim_proposals_proposal_note_proposal" end + create_table "decidim_proposals_proposal_states", force: :cascade do |t| + t.jsonb "title" + t.jsonb "announcement_title" + t.string "token", null: false + t.bigint "decidim_component_id", null: false + t.integer "proposals_count", default: 0, null: false + t.string "bg_color", default: "#F6F8FA", null: false + t.string "text_color", default: "#4B5058", null: false + t.index ["decidim_component_id"], name: "index_decidim_proposals_proposal_states_on_decidim_component_id" + end + create_table "decidim_proposals_proposal_votes", id: :serial, force: :cascade do |t| t.integer "decidim_proposal_id", null: false t.integer "decidim_author_id", null: false @@ -1340,7 +1487,6 @@ t.datetime "updated_at", null: false t.integer "proposal_votes_count", default: 0, null: false t.jsonb "extra" - t.string "state" t.datetime "answered_at" t.jsonb "answer" t.string "reference" @@ -1362,13 +1508,16 @@ t.jsonb "title" t.jsonb "body" t.integer "follows_count", default: 0, null: false + t.integer "old_state", default: 0, null: false + t.integer "valuation_assignments_count", default: 0 + t.datetime "withdrawn_at" + t.integer "decidim_proposals_proposal_state_id" t.index "md5((body)::text)", name: "decidim_proposals_proposal_body_search" t.index "md5((title)::text)", name: "decidim_proposals_proposal_title_search" t.index ["created_at"], name: "index_decidim_proposals_proposals_on_created_at" t.index ["decidim_component_id"], name: "index_decidim_proposals_proposals_on_decidim_component_id" t.index ["decidim_scope_id"], name: "index_decidim_proposals_proposals_on_decidim_scope_id" t.index ["proposal_votes_count"], name: "index_decidim_proposals_proposals_on_proposal_votes_count" - t.index ["state"], name: "index_decidim_proposals_proposals_on_state" end create_table "decidim_proposals_valuation_assignments", force: :cascade do |t| @@ -1381,6 +1530,33 @@ t.index ["valuator_role_type", "valuator_role_id"], name: "decidim_proposals_valuation_assignment_valuator_role" end + create_table "decidim_reminder_deliveries", force: :cascade do |t| + t.bigint "decidim_reminder_id" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["decidim_reminder_id"], name: "index_decidim_reminder_deliveries_on_decidim_reminder_id" + end + + create_table "decidim_reminder_records", force: :cascade do |t| + t.string "string", default: "active" + t.bigint "decidim_reminder_id" + t.string "remindable_type", null: false + t.bigint "remindable_id", null: false + t.integer "state", default: 0, null: false + t.index ["decidim_reminder_id"], name: "index_decidim_reminder_records_on_decidim_reminder_id" + t.index ["remindable_type", "remindable_id"], name: "index_decidim_reminder_records_remindable" + t.index ["string"], name: "index_decidim_reminder_records_on_string" + end + + create_table "decidim_reminders", force: :cascade do |t| + t.bigint "decidim_user_id", null: false + t.bigint "decidim_component_id" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["decidim_component_id"], name: "index_decidim_reminders_on_decidim_component_id" + t.index ["decidim_user_id"], name: "index_decidim_reminders_on_decidim_user_id" + end + create_table "decidim_reports", id: :serial, force: :cascade do |t| t.integer "decidim_moderation_id", null: false t.integer "decidim_user_id", null: false @@ -1474,6 +1650,23 @@ t.index ["token_for_type", "token_for_id"], name: "decidim_share_tokens_token_for" end + create_table "decidim_short_links", force: :cascade do |t| + t.bigint "decidim_organization_id", null: false + t.string "target_type", null: false + t.bigint "target_id", null: false + t.string "identifier", limit: 10, null: false + t.string "mounted_engine_name" + t.string "route_name" + t.jsonb "params" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + t.index ["decidim_organization_id", "identifier"], name: "idx_decidim_short_links_organization_id_identifier", unique: true + t.index ["decidim_organization_id"], name: "index_decidim_short_links_on_decidim_organization_id" + t.index ["mounted_engine_name"], name: "index_decidim_short_links_on_mounted_engine_name" + t.index ["route_name"], name: "index_decidim_short_links_on_route_name" + t.index ["target_type", "target_id"], name: "index_decidim_short_links_on_target" + end + create_table "decidim_sortitions_sortitions", force: :cascade do |t| t.bigint "decidim_component_id" t.integer "decidim_proposals_component_id" @@ -1547,6 +1740,20 @@ t.index ["reset_password_token"], name: "index_decidim_system_admins_on_reset_password_token", unique: true end + create_table "decidim_templates_templates", force: :cascade do |t| + t.integer "decidim_organization_id", null: false + t.string "templatable_type" + t.bigint "templatable_id" + t.jsonb "name", null: false + t.jsonb "description" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.json "field_values", default: {} + t.string "target" + t.index ["decidim_organization_id"], name: "index_decidim_templates_organization" + t.index ["templatable_type", "templatable_id"], name: "index_decidim_templates_templatable" + end + create_table "decidim_term_customizer_constraints", force: :cascade do |t| t.bigint "decidim_organization_id", null: false t.string "subject_type" @@ -1644,7 +1851,6 @@ t.boolean "admin", default: false, null: false t.boolean "managed", default: false, null: false t.string "roles", default: [], array: true - t.boolean "email_on_notification", default: false, null: false t.string "nickname", limit: 20, default: "", null: false t.string "personal_url" t.text "about" @@ -1669,6 +1875,11 @@ t.integer "block_id" t.boolean "email_on_moderations", default: true t.integer "follows_count", default: 0, null: false + t.jsonb "notification_settings", default: {} + t.string "notifications_sending_frequency", default: "daily" + t.datetime "digest_sent_at" + t.datetime "password_updated_at" + t.string "previous_passwords", default: [], array: true t.index ["confirmation_token"], name: "index_decidim_users_on_confirmation_token", unique: true t.index ["decidim_organization_id"], name: "index_decidim_users_on_decidim_organization_id" t.index ["email", "decidim_organization_id"], name: "index_decidim_users_on_email_and_decidim_organization_id", unique: true, where: "((deleted_at IS NULL) AND (managed = false) AND ((type)::text = 'Decidim::User'::text))" @@ -1678,6 +1889,7 @@ t.index ["invited_by_id", "invited_by_type"], name: "index_decidim_users_on_invited_by_id_and_invited_by_type" t.index ["invited_by_id"], name: "index_decidim_users_on_invited_by_id" t.index ["nickname", "decidim_organization_id"], name: "index_decidim_users_on_nickame_and_decidim_organization_id", unique: true, where: "((deleted_at IS NULL) AND (managed = false))" + t.index ["notifications_sending_frequency"], name: "index_decidim_users_on_notifications_sending_frequency" t.index ["officialized_at"], name: "index_decidim_users_on_officialized_at" t.index ["reset_password_token"], name: "index_decidim_users_on_reset_password_token", unique: true t.index ["unlock_token"], name: "index_decidim_users_on_unlock_token", unique: true @@ -1764,12 +1976,17 @@ end add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id" + add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id" add_foreign_key "decidim_area_types", "decidim_organizations" add_foreign_key "decidim_areas", "decidim_area_types", column: "area_type_id" add_foreign_key "decidim_areas", "decidim_organizations" add_foreign_key "decidim_assemblies", "decidim_assemblies_types" add_foreign_key "decidim_assemblies_settings", "decidim_organizations" add_foreign_key "decidim_attachments", "decidim_attachment_collections", column: "attachment_collection_id", name: "fk_decidim_attachments_attachment_collection_id", on_delete: :nullify + add_foreign_key "decidim_authorization_transfer_records", "decidim_authorization_transfers", column: "transfer_id" + add_foreign_key "decidim_authorization_transfers", "decidim_authorizations", column: "authorization_id" + add_foreign_key "decidim_authorization_transfers", "decidim_users", column: "source_user_id" + add_foreign_key "decidim_authorization_transfers", "decidim_users", column: "user_id" add_foreign_key "decidim_authorizations", "decidim_users" add_foreign_key "decidim_awesome_config_constraints", "decidim_awesome_config" add_foreign_key "decidim_awesome_editor_images", "decidim_organizations" @@ -1782,13 +1999,23 @@ add_foreign_key "decidim_editor_images", "decidim_organizations" add_foreign_key "decidim_editor_images", "decidim_users", column: "decidim_author_id" add_foreign_key "decidim_identities", "decidim_organizations" + add_foreign_key "decidim_initiatives_settings", "decidim_organizations" + add_foreign_key "decidim_kids_minor_accounts", "decidim_users", column: "decidim_minor_id" + add_foreign_key "decidim_kids_minor_accounts", "decidim_users", column: "decidim_tutor_id" add_foreign_key "decidim_navigation_maps_blueprint_areas", "decidim_navigation_maps_blueprints" add_foreign_key "decidim_navigation_maps_blueprints", "decidim_content_blocks" add_foreign_key "decidim_navigation_maps_blueprints", "decidim_organizations" add_foreign_key "decidim_newsletters", "decidim_users", column: "author_id" add_foreign_key "decidim_participatory_process_steps", "decidim_participatory_processes" + add_foreign_key "decidim_participatory_process_types", "decidim_organizations" add_foreign_key "decidim_participatory_processes", "decidim_organizations" + add_foreign_key "decidim_participatory_processes", "decidim_participatory_process_types" add_foreign_key "decidim_participatory_processes", "decidim_scope_types" + add_foreign_key "decidim_proposals_proposals", "decidim_proposals_proposal_states" + add_foreign_key "decidim_reminder_deliveries", "decidim_reminders" + add_foreign_key "decidim_reminder_records", "decidim_reminders" + add_foreign_key "decidim_reminders", "decidim_components" + add_foreign_key "decidim_reminders", "decidim_users" add_foreign_key "decidim_scope_types", "decidim_organizations" add_foreign_key "decidim_scopes", "decidim_organizations" add_foreign_key "decidim_scopes", "decidim_scope_types", column: "scope_type_id" diff --git a/db/seeds.rb b/db/seeds.rb index ac4e7e3484..e38eaffd1f 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -10,7 +10,7 @@ # You can remove the 'faker' gem if you don't want Decidim seeds. if ENV["HEROKU_APP_NAME"].present? - ENV["DECIDIM_HOST"] = "#{ENV["HEROKU_APP_NAME"]}.herokuapp.com" + ENV["DECIDIM_HOST"] = "#{ENV.fetch("HEROKU_APP_NAME", nil)}.herokuapp.com" ENV["SEED"] = "true" end Decidim.seed! diff --git a/decidim-census_sms/app/commands/decidim/census_sms/verification/send_code.rb b/decidim-census_sms/app/commands/decidim/census_sms/verification/send_code.rb index 53a74555e9..c83e52e689 100644 --- a/decidim-census_sms/app/commands/decidim/census_sms/verification/send_code.rb +++ b/decidim-census_sms/app/commands/decidim/census_sms/verification/send_code.rb @@ -3,7 +3,7 @@ module Decidim module CensusSms module Verification - class SendCode < Rectify::Command + class SendCode < Decidim::Command # Public: Initializes the command. # # form - A form object with the params. @@ -32,7 +32,7 @@ def update_authorization metadata = @authorization.metadata metadata[:mobile_phone_number] = @form.mobile_phone_number_hash - @authorization.update(metadata: metadata, verification_metadata: verification_metadata) + @authorization.update(metadata:, verification_metadata:) end def verification_metadata diff --git a/decidim-census_sms/app/controllers/decidim/census_sms/verification/authorizations_controller.rb b/decidim-census_sms/app/controllers/decidim/census_sms/verification/authorizations_controller.rb index 184bf70df4..f13937862d 100644 --- a/decidim-census_sms/app/controllers/decidim/census_sms/verification/authorizations_controller.rb +++ b/decidim-census_sms/app/controllers/decidim/census_sms/verification/authorizations_controller.rb @@ -9,13 +9,13 @@ class AuthorizationsController < Decidim::ApplicationController helper_method :authorization, :tos_path def new - enforce_permission_to :create, :authorization, authorization: authorization + enforce_permission_to(:create, :authorization, authorization:) @form = AuthorizationForm.new end def create - enforce_permission_to :create, :authorization, authorization: authorization + enforce_permission_to(:create, :authorization, authorization:) @form = AuthorizationForm.from_params(create_params) @@ -27,7 +27,7 @@ def create on(:ok) do flash[:notice] = t("authorizations.create.success", scope: "decidim.census_sms.verification") authorization_method = Decidim::Verifications::Adapter.from_element(authorization.name) - redirect_to authorization_method.resume_authorization_path(redirect_url: redirect_url) + redirect_to authorization_method.resume_authorization_path(redirect_url:) end on(:invalid) do @@ -45,13 +45,13 @@ def create end def edit - enforce_permission_to :update, :authorization, authorization: authorization + enforce_permission_to(:update, :authorization, authorization:) @form = Decidim::Verifications::Sms::ConfirmationForm.from_params(params) end def update - enforce_permission_to :update, :authorization, authorization: authorization + enforce_permission_to(:update, :authorization, authorization:) @form = Decidim::Verifications::Sms::ConfirmationForm.from_params(params) @@ -69,7 +69,7 @@ def update end def reset - enforce_permission_to :update, :authorization, authorization: authorization + enforce_permission_to(:update, :authorization, authorization:) @form = CodeForm.from_params(params) @@ -79,7 +79,7 @@ def reset on(:ok) do flash[:notice] = t("authorizations.reset.success", scope: "decidim.census_sms.verification") authorization_method = Decidim::Verifications::Adapter.from_element(authorization.name) - redirect_to authorization_method.resume_authorization_path(redirect_url: redirect_url) + redirect_to authorization_method.resume_authorization_path(redirect_url:) end on(:invalid) do @@ -90,7 +90,7 @@ def reset end def destroy - enforce_permission_to :destroy, :authorization, authorization: authorization + enforce_permission_to(:destroy, :authorization, authorization:) authorization.destroy! flash[:notice] = t("authorizations.destroy.success", scope: "decidim.census_sms.verification") @@ -101,7 +101,7 @@ def destroy private def create_params - params[:authorization].merge(user: current_user, date_of_birth: date_of_birth) + params[:authorization].merge(user: current_user, date_of_birth:) end def date_of_birth @@ -120,7 +120,7 @@ def authorization end def tos_path - @tos_path ||= decidim.page_path(Decidim::StaticPage.find_by(slug: "terms-and-conditions", organization: current_organization)) + @tos_path ||= decidim.page_path("terms-and-conditions") end end end diff --git a/decidim-census_sms/app/views/decidim/census_sms/verification/authorizations/edit.html.erb b/decidim-census_sms/app/views/decidim/census_sms/verification/authorizations/edit.html.erb index 5fd88782fa..6858db3d04 100644 --- a/decidim-census_sms/app/views/decidim/census_sms/verification/authorizations/edit.html.erb +++ b/decidim-census_sms/app/views/decidim/census_sms/verification/authorizations/edit.html.erb @@ -1,29 +1,24 @@ -
    -
    -
    -

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

    -
    - -
    -
    - <%= decidim_form_for(@form, url: authorization_path(redirect_url: redirect_url), method: :put) do |form| %> - <%= form_required_explanation %> +
    +
    +

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

    +
    -
    - <%= form.text_field :verification_code %> -
    + <%= decidim_form_for(@form, url: authorization_path(redirect_url: redirect_url), method: :put) do |form| %> + <%= form_required_explanation %> -
    - <%= form.submit t(".send"), class: "button expanded", "data-disable-with" => "#{t('.send')}..." %> -
    - <% end %> +
    +
    + <%= form.text_field :verification_code %>
    -
    -
    - <%= t(".instructions") %> - <%= link_to t(".reset"), reset_authorization_path(id: authorization.id) %> -
    + +
    + <%= form.submit t(".send"), class: "button button__lg button__secondary", "data-disable-with" => "#{t('.send')}..." %>
    -
    -
    + <% end %> + +

    + <%= t(".instructions") %> + <%= link_to t(".reset"), reset_authorization_path(id: authorization.id) %> +

    +
    diff --git a/decidim-census_sms/app/views/decidim/census_sms/verification/authorizations/new.html.erb b/decidim-census_sms/app/views/decidim/census_sms/verification/authorizations/new.html.erb index 82398af77c..46f00c3525 100644 --- a/decidim-census_sms/app/views/decidim/census_sms/verification/authorizations/new.html.erb +++ b/decidim-census_sms/app/views/decidim/census_sms/verification/authorizations/new.html.erb @@ -1,58 +1,54 @@ -
    -
    -
    -

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

    -
    - -
    -
    - <%= decidim_form_for(@form, url: authorization_path(redirect_url: redirect_url)) do |form| %> - <%= form_required_explanation %> - -
    - <%= form.select :document_type, form.object.census_document_types, prompt: true %> -
    - -
    - <%= form.text_field :document_number %> -
    - -
    - <%= form.date_select :date_of_birth, start_year: 1900, end_year: 14.years.ago.year, default: 35.years.ago, prompt: { day: t(".date_select.day"), month: t(".date_select.month"), year: t(".date_select.year") } %> -
    - -
    - <%= form.text_field :postal_code %> -

    - <%== t(".postal_code_help") %> -

    -
    - -
    - <% parent_scope = Decidim::Scope.where("name->>'ca' = 'Ciutat'").first %> - <%= form.collection_select :scope_id, current_organization.scopes.where(parent: parent_scope), :id, ->(scope){ translated_attribute(scope.name) }, prompt: t(".scope_prompt") %> -
    - -
    - <%= form.phone_field :mobile_phone_number %> -
    - -
    - <%= form.label :tos_acceptance do %> - <%= form.check_box :tos_acceptance, label: false %> - <%== t("activemodel.attributes.authorization.tos_acceptance_label", tos_path: tos_path) %> - <% end %> -
    - - <%= form.hidden_field :handler_name %> - -
    - <%= form.submit t(".send"), class: "button expanded", "data-disable-with" => "#{t('.send')}..." %> -
    +
    +
    +

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

    +
    + + <%= decidim_form_for(@form, url: authorization_path(redirect_url: redirect_url)) do |form| %> + <%= form_required_explanation %> + +
    +
    + <%= form.select :document_type, form.object.census_document_types, prompt: true %> +
    + +
    + <%= form.text_field :document_number %> +
    + +
    + <%= form.date_select :date_of_birth, start_year: 1900, end_year: 14.years.ago.year, default: 35.years.ago, prompt: { day: t(".date_select.day"), month: t(".date_select.month"), year: t(".date_select.year") } %> +
    + +
    + <%= form.text_field :postal_code %> +

    + <%== t(".postal_code_help") %> +

    +
    + +
    + <% parent_scope = Decidim::Scope.where("name->>'ca' = 'Ciutat'").first %> + <%= form.collection_select :scope_id, current_organization.scopes.where(parent: parent_scope), :id, ->(scope){ translated_attribute(scope.name) }, prompt: t(".scope_prompt") %> +
    + +
    + <%= form.phone_field :mobile_phone_number %> +
    + +
    + <%= form.label :tos_acceptance do %> + <%= form.check_box :tos_acceptance, label: false %> + <%== t("activemodel.attributes.authorization.tos_acceptance_label", tos_path: tos_path) %> <% end %>
    + + <%= form.hidden_field :handler_name %>
    -
    -
    -<%= stylesheet_pack_tag "decidim_census_sms" %> +
    + <%= form.submit t(".send"), class: "button button__lg button__secondary", "data-disable-with" => "#{t('.send')}..." %> +
    + <% end %> + + +<%= append_stylesheet_pack_tag "decidim_census_sms" %> diff --git a/decidim-census_sms/app/views/decidim/census_sms/verification/authorizations/reset.html.erb b/decidim-census_sms/app/views/decidim/census_sms/verification/authorizations/reset.html.erb index e98fca009c..65cc7292fa 100644 --- a/decidim-census_sms/app/views/decidim/census_sms/verification/authorizations/reset.html.erb +++ b/decidim-census_sms/app/views/decidim/census_sms/verification/authorizations/reset.html.erb @@ -1,23 +1,18 @@ -
    -
    -
    -

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

    -
    - -
    -
    - <%= decidim_form_for(@form, url: reset_authorization_path(id: authorization.id, redirect_url: redirect_url), method: :post) do |form| %> - <%= form_required_explanation %> - -
    - <%= form.text_field :mobile_phone_number, label: t("mobile_phone_number", scope: "activemodel.attributes.authorization") %> -
    +
    +
    +

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

    +
    + <%= decidim_form_for(@form, url: reset_authorization_path(id: authorization.id, redirect_url: redirect_url), method: :post) do |form| %> + <%= form_required_explanation %> -
    - <%= form.submit t(".send"), class: "button expanded", "data-disable-with" => "#{t('.send')}..." %> -
    - <% end %> +
    +
    + <%= form.text_field :mobile_phone_number, label: t("mobile_phone_number", scope: "activemodel.attributes.authorization") %>
    -
    -
    + +
    + <%= form.submit t(".send"), class: "button button__lg button__secondary", "data-disable-with" => "#{t('.send')}..." %> +
    + <% end %> + diff --git a/decidim-census_sms/decidim-census_sms.gemspec b/decidim-census_sms/decidim-census_sms.gemspec index 76db1221eb..384515c4a0 100644 --- a/decidim-census_sms/decidim-census_sms.gemspec +++ b/decidim-census_sms/decidim-census_sms.gemspec @@ -6,14 +6,15 @@ Gem::Specification.new do |s| s.name = "decidim-census_sms" s.summary = "A verification workflow for Decidim Barcelona." s.description = s.summary - s.required_ruby_version = ">= 2.7" - s.version = "0.0.1" + s.required_ruby_version = ">= 3.1" + s.version = "0.0.3" s.authors = ["Vera Rojman"] s.email = ["vera@platoniq.net"] s.files = Dir["{app,config,lib}/**/*", "Rakefile", "README.md"] - s.add_dependency "decidim-core" + s.add_dependency "decidim-core", "~> 0.28.0" - s.add_development_dependency "decidim-dev" + s.add_development_dependency "decidim-dev", "~> 0.28.0" + s.metadata["rubygems_mfa_required"] = "true" end diff --git a/decidim-census_sms/lib/decidim/census_sms/verification/test/shared_examples/with_census_sms_handler.rb b/decidim-census_sms/lib/decidim/census_sms/verification/test/shared_examples/with_census_sms_handler.rb index 40f9d9d635..340686f52a 100644 --- a/decidim-census_sms/lib/decidim/census_sms/verification/test/shared_examples/with_census_sms_handler.rb +++ b/decidim-census_sms/lib/decidim/census_sms/verification/test/shared_examples/with_census_sms_handler.rb @@ -33,16 +33,14 @@ def fill_in_authorization_form # rubocop:disable Naming/AccessorMethodName: def get_verified fill_in_authorization_form - click_button "Verifica't" + click_on "Verifica't" fill_in "confirmation_verification_code", with: code - click_button "Verifica't" + click_on "Verifica't" end # rubocop:enable Naming/AccessorMethodName: before do - # rubocop:disable RSpec/AnyInstance allow_any_instance_of(Decidim::CensusSms::Verification::AuthorizationForm).to receive(:response).and_return(response) - # rubocop:enable RSpec/AnyInstance end end diff --git a/decidim-census_sms/spec/rails_helper.rb b/decidim-census_sms/spec/rails_helper.rb index ee8491ac8b..3bbda0e5ba 100644 --- a/decidim-census_sms/spec/rails_helper.rb +++ b/decidim-census_sms/spec/rails_helper.rb @@ -1,3 +1,3 @@ # frozen_string_literal: true -require "../../spec/rails_helper" +require_relative "../../spec/rails_helper" diff --git a/decidim-census_sms/spec/system/census_sms_authorization_spec.rb b/decidim-census_sms/spec/system/census_sms_authorization_spec.rb index 534fc76ae1..4da16a8622 100644 --- a/decidim-census_sms/spec/system/census_sms_authorization_spec.rb +++ b/decidim-census_sms/spec/system/census_sms_authorization_spec.rb @@ -2,7 +2,7 @@ require "rails_helper" -describe "Census + SMS authorization", type: :system, perform_enqueued: true, with_authorization_workflows: ["census_sms_authorization_handler"] do +describe "Census + SMS authorization", :perform_enqueued, with_authorization_workflows: ["census_sms_authorization_handler"] do let(:organization) do create( :organization, @@ -17,9 +17,9 @@ let(:authorization_name) { "Verificació Pressupostos Participatius" } let(:authorizations) { { "census_sms_authorization_handler" => { "allow_ephemeral_participation" => true } } } let(:code) { user_authorization.verification_metadata["verification_code"] } - let(:user_authorization) { Decidim::Authorization.find_by(user: user, name: "census_sms_authorization_handler") } + let(:user_authorization) { Decidim::Authorization.find_by(user:, name: "census_sms_authorization_handler") } - let!(:scope) { create :scope, organization: organization, code: "1" } + let!(:scope) { create(:scope, organization:, code: "1") } let(:response) do Nokogiri::XML("01").remove_namespaces! @@ -43,10 +43,11 @@ def fill_in_authorization_form allow_any_instance_of(Decidim::CensusSms::Verification::AuthorizationForm).to receive(:response).and_return(response) # rubocop:enable RSpec/AnyInstance: switch_to_host(organization.host) + stub_request(:post, "http://example.org/sms").to_return(status: 200, body: "OK") end context "when visiting authorizations" do - let(:user) { create(:user, :confirmed, organization: organization) } + let(:user) { create(:user, :confirmed, organization:) } before do login_as user, scope: :user @@ -54,20 +55,22 @@ def fill_in_authorization_form end it "allows the user to authorize against available authorizations" do + skip "Capybara driver is not able to handle the form submission in this case" + within_user_menu do - click_link "El meu compte" + click_on "El meu compte" end - click_link "Autoritzacions" - click_link authorization_name + click_on "Autoritzacions" + click_on authorization_name fill_in_authorization_form - click_button "Verifica't" + click_on "Verifica't" expect(page).to have_content("Has completat el primer pas") fill_in "confirmation_verification_code", with: code - click_button "Verifica't" + click_on "Verifica't" expect(page).to have_content("T'has verificat correctament") @@ -75,30 +78,32 @@ def fill_in_authorization_form within ".authorizations-list" do expect(page).to have_content(authorization_name) - expect(page).not_to have_link(authorization_name) + expect(page).to have_no_link(authorization_name) end end it "allows the user to reset the verification code" do + skip "Capybara driver is not able to handle the form submission in this case" + within_user_menu do - click_link "El meu compte" + click_on "El meu compte" end - click_link "Autoritzacions" - click_link authorization_name + click_on "Autoritzacions" + click_on authorization_name fill_in_authorization_form - click_button "Verifica't" + click_on "Verifica't" - click_link "Restableix el codi de verificació" + click_on "Restableix el codi de verificació" fill_in "code[mobile_phone_number]", with: "(+34) 654 321 987" - click_button "Envia'm un nou codi" + click_on "Envia'm un nou codi" expect(page).to have_content("T'hem enviat un nou codi de verificació") fill_in "confirmation_verification_code", with: code - click_button "Verifica't" + click_on "Verifica't" expect(page).to have_content("T'has verificat correctament") @@ -106,45 +111,45 @@ def fill_in_authorization_form within ".authorizations-list" do expect(page).to have_content(authorization_name) - expect(page).not_to have_link(authorization_name) + expect(page).to have_no_link(authorization_name) end end context "when the user has completed the first authorization step" do let!(:code) { "012345" } - let!(:authorization) { create(:authorization, :pending, name: "census_sms_authorization_handler", user: user, verification_metadata: { verification_code: code, code_sent_at: Time.current }) } + let!(:authorization) { create(:authorization, :pending, name: "census_sms_authorization_handler", user:, verification_metadata: { verification_code: code, code_sent_at: Time.current }) } it "can resume the authorization" do visit decidim_verifications.authorizations_path - click_link authorization_name + click_on authorization_name expect(page).to have_content("Introdueix el codi") fill_in "confirmation_verification_code", with: code - click_button "Verifica't" + click_on "Verifica't" expect(page).to have_content("T'has verificat correctament") end end context "when the user has already been authorised" do - let!(:authorization) { create(:authorization, name: "census_sms_authorization_handler", user: user) } + let!(:authorization) { create(:authorization, name: "census_sms_authorization_handler", user:) } it "shows the authorization at their account" do visit decidim_verifications.authorizations_path within ".authorizations-list" do expect(page).to have_content(authorization_name) - expect(page).to have_content(I18n.l(authorization.granted_at, format: :long, locale: :ca)) + expect(page).to have_content(I18n.l(authorization.granted_at, format: :long_with_particles, locale: :ca)) end end end end context "when trying to authorize another user with previously used information" do - let!(:authorization) { create(:authorization, name: "census_sms_authorization_handler", unique_id: unique_id, organization: organization) } - let!(:user) { create(:user, :confirmed, organization: organization) } + let!(:authorization) { create(:authorization, name: "census_sms_authorization_handler", unique_id:, organization:) } + let!(:user) { create(:user, :confirmed, organization:) } let(:unique_id) do Digest::MD5.hexdigest( "#{document_number}-#{Rails.application.secrets.secret_key_base}" @@ -157,12 +162,12 @@ def fill_in_authorization_form end it "throws an error" do - click_link authorization_name + click_on authorization_name fill_in_authorization_form - click_button "Verifica't" + click_on "Verifica't" expect(page).to have_content("Ja hi ha una participant autoritzada amb les mateixes dades") - expect(page).not_to have_content("Restableix el codi de verificació") + expect(page).to have_no_content("Restableix el codi de verificació") end end end diff --git a/decidim-dataviz/app/packs/entrypoints/decidim_dataviz.js b/decidim-dataviz/app/packs/entrypoints/decidim_dataviz.js index a401a40fec..cb60f7634a 100644 --- a/decidim-dataviz/app/packs/entrypoints/decidim_dataviz.js +++ b/decidim-dataviz/app/packs/entrypoints/decidim_dataviz.js @@ -1,3 +1 @@ -import "src/decidim/dataviz/dataviz.js"; -// CSS for compiling import "stylesheets/decidim/dataviz/dataviz.scss"; diff --git a/app/packs/images/.keep b/decidim-dataviz/app/packs/src/.keep similarity index 100% rename from app/packs/images/.keep rename to decidim-dataviz/app/packs/src/.keep diff --git a/decidim-dataviz/app/packs/src/decidim/dataviz/dataviz.js b/decidim-dataviz/app/packs/src/decidim/dataviz/dataviz.js deleted file mode 100644 index 7b07c6d9d6..0000000000 --- a/decidim-dataviz/app/packs/src/decidim/dataviz/dataviz.js +++ /dev/null @@ -1,8 +0,0 @@ -import "src/vendor/jquery.browser"; -import "src/vendor/jquery-iframe-auto-height"; - -$(() => { - $("iframe.autoheight").iframeAutoHeight({ - heightOffset: 150 - }); -}) diff --git a/decidim-dataviz/app/packs/src/vendor/jquery-iframe-auto-height.js b/decidim-dataviz/app/packs/src/vendor/jquery-iframe-auto-height.js deleted file mode 100644 index 15ce50b372..0000000000 --- a/decidim-dataviz/app/packs/src/vendor/jquery-iframe-auto-height.js +++ /dev/null @@ -1,219 +0,0 @@ -/*! jquery-iframe-auto-height - v2.0.0 - * Release on: 2015-06-28 - * Copyright (c) 2015 Jesse House - * Licensed The Unlicense */ -(function (root, factory) { - if (typeof define === 'function' && define.amd) { - // AMD. Register as an anonymous module unless amdModuleId is set - define([], function () { - return (factory()); - }); - } else if (typeof exports === 'object') { - // Node. Does not work with strict CommonJS, but - // only CommonJS-like environments that support module.exports, - // like Node. - module.exports = factory(); - } else { - factory(); - } -}(this, function () { - -(function ($) { - $.fn.iframeAutoHeight = function (spec) { - - var undef; - if ($.browser === undef) { - var message = []; - message.push("WARNING: you appear to be using a newer version of jquery which does not support the $.browser variable."); - message.push("The jQuery iframe auto height plugin relies heavly on the $.browser features."); - message.push("Install jquery-browser: https://raw.github.com/house9/jquery-iframe-auto-height/master/release/jquery.browser.js"); - alert(message.join("\n")); - return $; - } - - // set default option values - var options = $.extend({ - heightOffset: 0, - minHeight: 0, - maxHeight: 0, - callback: function () {}, - animate: false, - debug: false, - diagnostics: false, // used for development only - resetToMinHeight: false, - triggerFunctions: [], - heightCalculationOverrides: [] - }, spec); - - // logging - function debug(message) { - if (options.debug && options.debug === true && window.console) { - console.log(message); - } - } - - // not used by production code - function showDiagnostics(iframe, calledFrom) { - debug("Diagnostics from '" + calledFrom + "'"); - try { - debug(" " + $(iframe, window.parent).contents().find('body')[0].scrollHeight + " for ...find('body')[0].scrollHeight"); - debug(" " + $(iframe.contentWindow.document).height() + " for ...contentWindow.document).height()"); - debug(" " + $(iframe.contentWindow.document.body).height() + " for ...contentWindow.document.body).height()"); - } catch (ex) { - // ie fails when called during for each, ok later on - // probably not an issue if called in a document ready block - debug(" unable to check in this state"); - } - debug("End diagnostics -> results vary by browser and when diagnostics are requested"); - } - - // show all option values - debug(options); - - // ****************************************************** - // iterate over the matched elements passed to the plugin ; return will make it chainable - return this.each(function () { - - // ****************************************************** - // http://api.jquery.com/jQuery.browser/ - var strategyKeys = ['webkit', 'mozilla', 'msie', 'opera', 'chrome']; - var strategies = {}; - strategies['default'] = function (iframe, $iframeBody, options) { - // NOTE: this is how the plugin determines the iframe height, override if you need custom - return $iframeBody[0].scrollHeight + options.heightOffset; - }; - - jQuery.each(strategyKeys, function (index, value) { - // use the default strategy for all browsers, can be overridden if desired - strategies[value] = strategies['default']; - }); - - // override strategies if registered in options - jQuery.each(options.heightCalculationOverrides, function (index, value) { - strategies[value.browser] = value.calculation; - }); - - function findStrategy(browser) { - var strategy = null; - - jQuery.each(strategyKeys, function (index, value) { - if (browser[value]) { - strategy = strategies[value]; - return false; - } - }); - - if (strategy === null) { - strategy = strategies['default']; - } - - return strategy; - } - // ****************************************************** - - // for use by webkit only - var loadCounter = 0; - - var iframeDoc = this.contentDocument || this.contentWindow.document; - - // resizeHeight - function resizeHeight(iframe) { - if (options.diagnostics) { - showDiagnostics(iframe, "resizeHeight"); - } - - // set the iframe size to minHeight so it'll get smaller on resizes in FF and IE - if (options.resetToMinHeight && options.resetToMinHeight === true) { - iframe.style.height = options.minHeight + 'px'; - } - - // get the iframe body height and set inline style to that plus a little - var $body = $(iframe, window.parent).contents().find('body'); - var strategy = findStrategy($.browser); - var newHeight = strategy(iframe, $body, options, $.browser); - debug(newHeight); - - if (newHeight < options.minHeight) { - debug("new height is less than minHeight"); - newHeight = options.minHeight; - } - - if (options.maxHeight > 0 && newHeight > options.maxHeight) { - debug("new height is greater than maxHeight"); - newHeight = options.maxHeight; - } - - newHeight += options.heightOffset; - - debug("New Height: " + newHeight); - if (options.animate) { - $(iframe).animate({height: newHeight + 'px'}, {duration: 500}); - } else { - iframe.style.height = newHeight + 'px'; - } - - options.callback.apply($(iframe), [{newFrameHeight: newHeight}]); - } // END resizeHeight - - // debug me - debug(this); - if (options.diagnostics) { - showDiagnostics(this, "each iframe"); - } - - // if trigger functions are registered, invoke them - if (options.triggerFunctions.length > 0) { - debug(options.triggerFunctions.length + " trigger Functions"); - for (var i = 0; i < options.triggerFunctions.length; i++) { - options.triggerFunctions[i](resizeHeight, this); - } - } - - // Check if browser is Webkit (Safari/Chrome) or Opera - if ($.browser.webkit || $.browser.opera || $.browser.chrome) { - debug("browser is webkit (Safari/Chrome) or opera"); - - // Start timer when loaded. - $(this).load(function () { - var delay = 0; - var iframe = this; - - var delayedResize = function () { - resizeHeight(iframe); - }; - - if (loadCounter === 0) { - // delay the first one - delay = 500; - } else { - // Reset iframe height to 0 to force new frame size to fit window properly - // this is only an issue when going from large to small iframe, not executed on page load - iframe.style.height = options.minHeight + 'px'; - } - - debug("load delay: " + delay); - setTimeout(delayedResize, delay); - loadCounter++; - }); - - // Safari and Opera need a kick-start. - var source = $(this).attr('src'); - $(this).attr('src', ''); - $(this).attr('src', source); - } else { - // For other browsers. - if(iframeDoc.readyState === 'complete') { - resizeHeight(this); - } else { - $(this).load(function () { - resizeHeight(this); - }); - } - } // if browser - - }); // $(this).each(function () { - }; // $.fn.iframeAutoHeight = function (options) { -}(jQuery)); // (function ($) { - - -})); diff --git a/decidim-dataviz/app/packs/src/vendor/jquery.browser.js b/decidim-dataviz/app/packs/src/vendor/jquery.browser.js deleted file mode 100644 index c1acb863a0..0000000000 --- a/decidim-dataviz/app/packs/src/vendor/jquery.browser.js +++ /dev/null @@ -1,39 +0,0 @@ -(function( jQuery ) { - var matched, - userAgent = navigator.userAgent || ""; - - // Use of jQuery.browser is frowned upon. - // More details: http://api.jquery.com/jQuery.browser - // jQuery.uaMatch maintained for back-compat - jQuery.uaMatch = function( ua ) { - ua = ua.toLowerCase(); - - var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) || - /(webkit)[ \/]([\w.]+)/.exec( ua ) || - /(opera)(?:.*version)?[ \/]([\w.]+)/.exec( ua ) || - /(msie) ([\w.]+)/.exec( ua ) || - ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+))?/.exec( ua ) || - []; - - return { - browser: match[ 1 ] || "", - version: match[ 2 ] || "0" - }; - }; - - matched = jQuery.uaMatch( userAgent ); - - jQuery.browser = {}; - - if ( matched.browser ) { - jQuery.browser[ matched.browser ] = true; - jQuery.browser.version = matched.version; - } - - // Deprecated, use jQuery.browser.webkit instead - // Maintained for back-compat only - if ( jQuery.browser.webkit ) { - jQuery.browser.safari = true; - } - -}( jQuery )); \ No newline at end of file diff --git a/decidim-dataviz/app/packs/stylesheets/decidim/dataviz/dataviz.scss b/decidim-dataviz/app/packs/stylesheets/decidim/dataviz/dataviz.scss index e1eb6e6bb4..5f1adc711e 100644 --- a/decidim-dataviz/app/packs/stylesheets/decidim/dataviz/dataviz.scss +++ b/decidim-dataviz/app/packs/stylesheets/decidim/dataviz/dataviz.scss @@ -1,48 +1,6 @@ -@import "stylesheets/decidim/variables"; -@import "stylesheets/decidim/utils/settings"; - -.dataviz{ - margin-top: -2rem; - - .menu{ - margin-bottom: 2rem; - } - - iframe{ - overflow-x:hidden; - overflow-Y:hidden; - } - - .dataviz-embedded{ - &:not(.autoheight){ - height: rem-calc(250px); - @include breakpoint(medium) { - height: rem-calc(450px); - } - - @include breakpoint(large){ - height: rem-calc(800px); - } - } - - &.total_interactions{ - height: rem-calc(600px); - @include breakpoint(medium) { - height: rem-calc(800px); - } - - @include breakpoint(large){ - height: rem-calc(800px); - } - } - +.dataviz { + iframe { + overflow: hidden hidden; width: 100%; - border: 0; - } - - @include breakpoint(large){ - .mobile-devices-alert{ - display: none; - } } -} \ No newline at end of file +} diff --git a/decidim-dataviz/app/views/decidim/dataviz/dataviz/_action_plans.html.erb b/decidim-dataviz/app/views/decidim/dataviz/dataviz/_action_plans.html.erb index 308a43ba9b..eab03e8cfe 100644 --- a/decidim-dataviz/app/views/decidim/dataviz/dataviz/_action_plans.html.erb +++ b/decidim-dataviz/app/views/decidim/dataviz/dataviz/_action_plans.html.erb @@ -1 +1 @@ - + diff --git a/decidim-dataviz/app/views/decidim/dataviz/dataviz/_map.html.erb b/decidim-dataviz/app/views/decidim/dataviz/dataviz/_map.html.erb index 0b32d973fc..2ffdcad043 100644 --- a/decidim-dataviz/app/views/decidim/dataviz/dataviz/_map.html.erb +++ b/decidim-dataviz/app/views/decidim/dataviz/dataviz/_map.html.erb @@ -1 +1 @@ - + diff --git a/decidim-dataviz/app/views/decidim/dataviz/dataviz/_meetings.html.erb b/decidim-dataviz/app/views/decidim/dataviz/dataviz/_meetings.html.erb index a22e084052..73ff433518 100644 --- a/decidim-dataviz/app/views/decidim/dataviz/dataviz/_meetings.html.erb +++ b/decidim-dataviz/app/views/decidim/dataviz/dataviz/_meetings.html.erb @@ -1 +1 @@ - + diff --git a/decidim-dataviz/app/views/decidim/dataviz/dataviz/_open_data.html.erb b/decidim-dataviz/app/views/decidim/dataviz/dataviz/_open_data.html.erb index a54c06d1c0..1290764341 100644 --- a/decidim-dataviz/app/views/decidim/dataviz/dataviz/_open_data.html.erb +++ b/decidim-dataviz/app/views/decidim/dataviz/dataviz/_open_data.html.erb @@ -3,10 +3,10 @@
      <% %w{proposals meetings action_plans}.each do |item| %> -
    • +
    • - <%= link_to asset_url("/dataviz/documents/#{item}.csv"), download: "#{item}.csv" do %> - <%=t ".download-#{item}" %> + <%= link_to asset_url("/dataviz/documents/#{item}.csv"), download: "#{item}.csv", class: "button button__lg button__primary" do %> + <%= t ".download-#{item}" %> <% end %>
    • diff --git a/decidim-dataviz/app/views/decidim/dataviz/dataviz/_proposals.html.erb b/decidim-dataviz/app/views/decidim/dataviz/dataviz/_proposals.html.erb index 0623bbfca7..42fba100c1 100644 --- a/decidim-dataviz/app/views/decidim/dataviz/dataviz/_proposals.html.erb +++ b/decidim-dataviz/app/views/decidim/dataviz/dataviz/_proposals.html.erb @@ -1 +1 @@ - + diff --git a/decidim-dataviz/app/views/decidim/dataviz/dataviz/_summary.html.erb b/decidim-dataviz/app/views/decidim/dataviz/dataviz/_summary.html.erb index eb1cc78341..31dcb545ec 100644 --- a/decidim-dataviz/app/views/decidim/dataviz/dataviz/_summary.html.erb +++ b/decidim-dataviz/app/views/decidim/dataviz/dataviz/_summary.html.erb @@ -1 +1 @@ - + diff --git a/decidim-dataviz/app/views/decidim/dataviz/dataviz/_total_interactions.html.erb b/decidim-dataviz/app/views/decidim/dataviz/dataviz/_total_interactions.html.erb index 746263be08..7a3f401292 100644 --- a/decidim-dataviz/app/views/decidim/dataviz/dataviz/_total_interactions.html.erb +++ b/decidim-dataviz/app/views/decidim/dataviz/dataviz/_total_interactions.html.erb @@ -1 +1 @@ - + diff --git a/decidim-dataviz/app/views/decidim/dataviz/dataviz/show.html.erb b/decidim-dataviz/app/views/decidim/dataviz/dataviz/show.html.erb index 4387080ec5..5acbd2a4e3 100644 --- a/decidim-dataviz/app/views/decidim/dataviz/dataviz/show.html.erb +++ b/decidim-dataviz/app/views/decidim/dataviz/dataviz/show.html.erb @@ -1,28 +1,48 @@ -
      -
      -
      -