Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dataset select #8397

Merged
merged 3 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion app/assets/stylesheets/responsive/_global_style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ form button {
padding: 2px 6px 3px;
transition: none;
&:hover, &:focus {
background: none;
background-color: inherit;
color: inherit;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,41 +294,57 @@
}

#project-key-set {
.project-key-set__key {
&.project-key-set__key--removed {
display: none;
}
padding-bottom: 1em;

width: 75%;
.project-key-set__key {
padding: 1em;
margin-bottom: 1em;

display: flex;
flex-flow: row nowrap;
justify-content: space-between;

border-radius: 5px;
box-shadow: rgba(0, 0, 0, 0.05) 0px 6px 24px 0px, rgba(0, 0, 0, 0.08) 0px 0px 0px 1px;

&.project-key-set__key--removed {
display: none;
}

.project-key-set__key__drag-handle {
text-indent: -9999px;
background-image: image-url("drag.svg");
background-repeat: no-repeat;
background-position: center center;
background-position: center 2em;
cursor: grab;
width: 24px;
}

.project-key-set__key__title,
.project-key-set__key__format {
width: 35%;
input,
select {
width: 100%;
}
.project-key-set__key__attributes {
width: 100%;
margin: 0 1em;

display: flex;
flex-flow: row wrap;
justify-content: space-between;

.project-key-set__key__value {
width: 50%;
padding-right: 1em;

input[type='text'], select {
width: 100%;
}

.fieldWithErrors {
padding: 0;
.fieldWithErrors {
padding: 0;
}
}
}

.project-key-set__key__remove-question {
padding-top: 1.2em;
button { width: max-content; }
}
}
}
Expand Down
6 changes: 5 additions & 1 deletion app/controllers/alaveteli_pro/projects_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,11 @@ def project_params
when 'edit_key_set', 'update_key_set'
params.fetch(:project, {}).permit(
key_set_attributes: [
:id, keys_attributes: %i[id title format order _destroy]
:id, keys_attributes: [
:id, :title, :format, :order, :_destroy, options: [
:select_allow_blank, :select_allow_muliple, { select_options: [] }
]
]
]
)
when 'edit_contributors', 'update_contributors'
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/projects/extracts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@

def extract_params
params.require(:extract).permit(
:dataset_key_set_id, values_attributes: [:dataset_key_id, :value]
:dataset_key_set_id, values_attributes: [:dataset_key_id, :value, value: []]

Check warning on line 74 in app/controllers/projects/extracts_controller.rb

View workflow job for this annotation

GitHub Actions / build

[rubocop] reported by reviewdog 🐶 Line is too long. [82/80] (https://rubystyle.guide#max-line-length) Raw Output: app/controllers/projects/extracts_controller.rb:74:81: C: Layout/LineLength: Line is too long. [82/80] (https://rubystyle.guide#max-line-length)
)
end

Expand Down
24 changes: 24 additions & 0 deletions app/javascript/controllers/projects/key_set/select_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Controller } from "@hotwired/stimulus";
import { streamUpdate } from "helpers/stream_update";

export default class extends Controller {
static targets = ["newInput"];
static values = { name: String };

addOption(event) {
event.preventDefault();

const newValue = this.newInputTarget.value;
if (!newValue) return;

const form = this.element.closest("form");
streamUpdate(form, { [this.nameValue]: newValue });
}

removeOption(event) {
event.preventDefault();

const li = event.target.closest("li");
if (li) li.remove();
}
}
4 changes: 4 additions & 0 deletions app/javascript/controllers/projects/key_set_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ export default class extends Controller {
streamUpdate(this.element);
}

updateKey(event) {
streamUpdate(this.element);
}

updateOrder() {
this.element
.querySelectorAll('[name*="[order]"]')
Expand Down
16 changes: 15 additions & 1 deletion app/models/dataset/key.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# == Schema Information
# Schema version: 20210114161442
# Schema version: 20240926164308
#
# Table name: dataset_keys
#
Expand All @@ -10,6 +10,7 @@
# order :integer
# created_at :datetime not null
# updated_at :datetime not null
# options :jsonb
#

##
Expand All @@ -24,6 +25,7 @@ class Dataset::Key < ApplicationRecord

FORMATS = {
text: { title: _('Text'), regexp: /\A.*\z/m },
select: { title: _('Select'), regexp: /\A.*\z/m },
numeric: { title: _('Numeric'), regexp: /\A[0-9,%\+\-\s]*\z/ },
boolean: { title: _('Yes/No'), regexp: /\A(0|1)\z/ }
}.freeze
Expand All @@ -40,4 +42,16 @@ def self.format_options
def format_regexp
FORMATS[format.to_sym][:regexp]
end

def select_options
options.fetch('select_options', [])
end

def select_allow_blank?
options.fetch('select_allow_blank', '0').to_i == 1
end

def select_allow_muliple?
options.fetch('select_allow_muliple', '0').to_i == 1
end
end
9 changes: 9 additions & 0 deletions app/models/dataset/value.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@ def title
key.title
end

def value=(new_value)
case key.format
when 'select'
super(Array(new_value).reject(&:blank?).join(', '))
else
super
end
end

def mapped_value
case key.format
when 'boolean'
Expand Down
46 changes: 28 additions & 18 deletions app/views/alaveteli_pro/projects/_key_set.html.erb
Original file line number Diff line number Diff line change
@@ -1,29 +1,39 @@
<%= f.fields_for :key_set, @key_set do |key_set_fields| %>
<%= key_set_fields.fields_for :keys, @keys do |key_fields| %>
<div class="row project-key-set__key<% if key_fields.object.marked_for_destruction? %> project-key-set__key--removed<% end %>">
<%= form.fields_for :key_set, @key_set do |key_set_fields| %>
<%= key_set_fields.fields_for :keys, @keys do |f| %>
<% key = f.object %>
<div class="row project-key-set__key<% if key.marked_for_destruction? %> project-key-set__key--removed<% end %>">
<div class="project-key-set__key__drag-handle">
<%= key_fields.hidden_field :order %>
<%= f.hidden_field :order %>
Drag to reorder
</div>

<div class="project-key-set__key__title">
<%= key_fields.label :title %>
<%= key_fields.text_field :title, autocomplete: false %>
</div>
<div class="project-key-set__key__attributes">
<div class="project-key-set__key__value">
<%= f.label :title %>
<%= f.text_field :title, autocomplete: 'off' %>
</div>

<div class="project-key-set__key__value">
<%= f.label :format %>
<%= f.select :format,
options_for_select(
Dataset::Key.format_options,
key.format
),
{},
data: { action: 'change->projects--key-set#updateKey' },
autocomplete: 'off' %>
</div>

<div class="project-key-set__key__format">
<%= key_fields.label :format %>
<%= key_fields.select :format,
options_for_select(
Dataset::Key.format_options,
key_fields.object.format
), {}, autocomplete: false %>
<% if lookup_context.exists?("alaveteli_pro/projects/_#{key.format}_key") %>
<%= render partial: "alaveteli_pro/projects/#{key.format}_key",
locals: { form: f, key: key } %>
<% end %>
</div>

<div class="project-key-set__key__remove-question">
<%= key_fields.hidden_field :_destroy %>
<%= link_to _('Remove question'), nil, class: 'button-tertiary',
data: { action: 'click->projects--key-set#removeKey' } %>
<%= f.hidden_field :_destroy %>
<%= button_tag _('Remove question'), class: 'button-tertiary', data: { action: 'click->projects--key-set#removeKey' } %>
</div>
</div>
<% end %>
Expand Down
41 changes: 41 additions & 0 deletions app/views/alaveteli_pro/projects/_select_key.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<%= form.fields_for :options, key.options do |f| %>
<div class="project-key-set__key__value">
<%= f.label :select_allow_blank do %>
<%= f.check_box :select_allow_blank, checked: key.select_allow_blank?, autocomplete: 'off' %>
<%= _('Allow blank') %>
<% end %>
</div>

<div class="project-key-set__key__value">
<%= f.label :select_allow_muliple do %>
<%= f.check_box :select_allow_muliple, checked: key.select_allow_muliple?, autocomplete: 'off' %>
<%= _('Allow muliple') %>
<% end %>
</div>

<%= content_tag(:div, class: "project-key-set__key__value", data: {
controller: "projects--key-set--select",
projects__key_set__select_name_value: "#{f.object_name}[select_options][]"
}) do %>
<%= f.label :select_options, _('Options') %>
<ul>
<% key.select_options.each_with_index do |option, index| %>
<li>
<%= option %>
<%= hidden_field_tag "#{f.object_name}[select_options][]", option %>
<%= button_tag class: 'button-unstyled', data: { action: 'click->projects--key-set--select#removeOption' } do %>
<%= _('Remove') %>
<% end %>
</li>
<% end %>
</ul>
<div class="row collapse postfix-radius">
<div class="small-10 columns">
<%= text_field_tag "select_option", nil, data: { projects__key_set__select_target: 'newInput' } %>
</div>
<div class="small-2 columns">
<%= button_tag _('Add'), class: 'button-tertiary postfix', data: { action: 'click->projects--key-set--select#addOption' } %>
</div>
</div>
<% end %>
<% end %>
6 changes: 2 additions & 4 deletions app/views/alaveteli_pro/projects/edit_key_set.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,11 @@
<%= hidden_field_tag :step, current_step %>

<div id="project-key-set" data-projects--key-set-target="keySet">
<%= render partial: 'key_set', locals: { f: f } %>
<%= render partial: 'key_set', locals: { form: f } %>
</div>

<div>
<%= link_to _('Add question'), nil, class: 'button-tertiary', data: {
action: 'click->projects--key-set#addKey'
} %>
<%= button_tag _('Add question'), class: 'button-tertiary', data: { action: 'click->projects--key-set#addKey' } %>
</div>

<div class="form_button">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<%= form_for @project, html: { id: 'temp' } do |f| %>
<div id="project-key-set">
<%= turbo_stream.update 'project-key-set', partial: 'key_set', locals: { f: f } %>
<%= turbo_stream.update 'project-key-set', partial: 'key_set', locals: { form: f } %>
</div>
<% end %>

Expand Down
4 changes: 4 additions & 0 deletions app/views/projects/dataset/keys/_select_key.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<div class="dataset-key">
<%= f.label :value, key.title %>
<%= f.select :value, key.select_options, { include_blank: key.select_allow_blank? }, multiple: key.select_allow_muliple? %>
</div>
5 changes: 5 additions & 0 deletions db/migrate/20240926164308_add_options_to_dataset_key.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddOptionsToDatasetKey < ActiveRecord::Migration[7.0]
def change
add_column :dataset_keys, :options, :jsonb, default: {}
end
end
1 change: 1 addition & 0 deletions doc/CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Highlighted Features

* Add project dataset question "select" format (Graeme Porteous)
* Fix script/mailin when multiple EXCEPTION_NOTIFICATIONS_TO addresses are
specified (Graeme Porteous)
* Add example logrotate configuration (Graeme Porteous)
Expand Down
7 changes: 6 additions & 1 deletion spec/factories/dataset_keys.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# == Schema Information
# Schema version: 20210114161442
# Schema version: 20240926164308
#
# Table name: dataset_keys
#
Expand All @@ -10,6 +10,7 @@
# order :integer
# created_at :datetime not null
# updated_at :datetime not null
# options :jsonb
#

FactoryBot.define do
Expand All @@ -24,6 +25,10 @@
format { 'text' }
end

trait :select do
format { 'select' }
end

trait :numeric do
format { 'numeric' }
end
Expand Down
Loading
Loading