use hash for field options

pull/142/head
Pete Matsyburka 2 years ago
parent a25022532e
commit 1066131143

@ -57,7 +57,7 @@ module Api
schema: [%i[attachment_uuid name]], schema: [%i[attachment_uuid name]],
submitters: [%i[name uuid]], submitters: [%i[name uuid]],
fields: [[:uuid, :submitter_uuid, :name, :type, :required, :readonly, :default_value, fields: [[:uuid, :submitter_uuid, :name, :type, :required, :readonly, :default_value,
{ options: [], areas: [%i[x y w h cell_w attachment_uuid page]] }]] { options: [%i[value uuid]], areas: [%i[x y w h cell_w attachment_uuid option_uuid page]] }]]
) )
end end
end end

@ -99,12 +99,12 @@
{{ t('select_your_option') }} {{ t('select_your_option') }}
</option> </option>
<option <option
v-for="(option, index) in currentField.options" v-for="option in currentField.options"
:key="index" :key="option.uuid"
:selected="values[currentField.uuid] == option" :selected="values[currentField.uuid] == option.value"
:value="option" :value="option.value"
> >
{{ option }} {{ option.value }}
</option> </option>
</select> </select>
</div> </div>
@ -119,24 +119,24 @@
<div class="flex w-full"> <div class="flex w-full">
<div class="space-y-3.5 mx-auto"> <div class="space-y-3.5 mx-auto">
<div <div
v-for="(option, index) in currentField.options" v-for="option in currentField.options"
:key="index" :key="option.uuid"
> >
<label <label
:for="currentField.uuid + option" :for="option.uuid"
class="flex items-center space-x-3" class="flex items-center space-x-3"
> >
<input <input
:id="currentField.uuid + option" :id="option.uuid"
v-model="values[currentField.uuid]" v-model="values[currentField.uuid]"
type="radio" type="radio"
class="base-radio !h-7 !w-7" class="base-radio !h-7 !w-7"
:name="`values[${currentField.uuid}]`" :name="`values[${currentField.uuid}]`"
:value="option" :value="option.value"
:required="currentField.required" :required="currentField.required"
> >
<span class="text-xl"> <span class="text-xl">
{{ option }} {{ option.value }}
</span> </span>
</label> </label>
</div> </div>

@ -7,25 +7,25 @@
<div class="flex w-full"> <div class="flex w-full">
<div class="space-y-3.5 mx-auto"> <div class="space-y-3.5 mx-auto">
<div <div
v-for="(option, index) in field.options" v-for="option in field.options"
:key="index" :key="option.uuid"
> >
<label <label
:for="field.uuid + option" :for="option.uuid"
class="flex items-center space-x-3" class="flex items-center space-x-3"
> >
<input <input
:id="field.uuid + option" :id="option.uuid"
:ref="setInputRef" :ref="setInputRef"
type="checkbox" type="checkbox"
:name="`values[${field.uuid}][]`" :name="`values[${field.uuid}][]`"
:value="option" :value="option.value"
class="base-checkbox !h-7 !w-7" class="base-checkbox !h-7 !w-7"
:checked="(modelValue || []).includes(option)" :checked="(modelValue || []).includes(option.value)"
@change="onChange" @change="onChange"
> >
<span class="text-xl"> <span class="text-xl">
{{ option }} {{ option.value }}
</span> </span>
</label> </label>
</div> </div>

@ -140,6 +140,7 @@ import FieldSubmitter from './field_submitter'
import FieldType from './field_type' import FieldType from './field_type'
import Field from './field' import Field from './field'
import { IconX } from '@tabler/icons-vue' import { IconX } from '@tabler/icons-vue'
import { v4 } from 'uuid'
export default { export default {
name: 'FieldArea', name: 'FieldArea',
@ -303,7 +304,7 @@ export default {
} }
if (['select', 'multiple', 'radio'].includes(this.field.type)) { if (['select', 'multiple', 'radio'].includes(this.field.type)) {
this.field.options ||= [''] this.field.options ||= [{ value: '', uuid: v4() }]
} }
(this.field.areas || []).forEach((area) => { (this.field.areas || []).forEach((area) => {

@ -429,7 +429,7 @@ export default {
} }
if (['select', 'multiple', 'radio'].includes(type)) { if (['select', 'multiple', 'radio'].includes(type)) {
field.options = [''] field.options = [{ value: '', uuid: v4() }]
} }
this.drawField = field this.drawField = field
@ -592,7 +592,7 @@ export default {
} }
if (['select', 'multiple', 'radio'].includes(field.type)) { if (['select', 'multiple', 'radio'].includes(field.type)) {
field.options = [''] field.options = [{ value: '', uuid: v4() }]
} }
const fieldArea = { const fieldArea = {

@ -194,17 +194,19 @@
<div <div
v-if="field.options" v-if="field.options"
class="border-t border-base-300 mx-2 pt-2 space-y-1.5" class="border-t border-base-300 mx-2 pt-2 space-y-1.5"
draggable="true"
@dragstart.prevent.stop
> >
<div <div
v-for="(option, index) in field.options" v-for="(option, index) in field.options"
:key="index" :key="option.uuid"
class="flex space-x-1.5 items-center" class="flex space-x-1.5 items-center"
> >
<span class="text-sm w-3.5"> <span class="text-sm w-3.5">
{{ index + 1 }}. {{ index + 1 }}.
</span> </span>
<input <input
v-model="field.options[index]" v-model="option.value"
class="w-full input input-primary input-xs text-sm bg-transparent" class="w-full input input-primary input-xs text-sm bg-transparent"
type="text" type="text"
required required
@ -220,7 +222,7 @@
<button <button
v-if="field.options" v-if="field.options"
class="text-center text-sm w-full pb-1" class="text-center text-sm w-full pb-1"
@click="[field.options.push(''), save()]" @click="addOption"
> >
+ Add option + Add option
</button> </button>
@ -233,6 +235,7 @@
import Contenteditable from './contenteditable' import Contenteditable from './contenteditable'
import FieldType from './field_type' import FieldType from './field_type'
import { IconShape, IconNewSection, IconTrashX, IconCopy, IconSettings } from '@tabler/icons-vue' import { IconShape, IconNewSection, IconTrashX, IconCopy, IconSettings } from '@tabler/icons-vue'
import { v4 } from 'uuid'
export default { export default {
name: 'TemplateField', name: 'TemplateField',
@ -309,6 +312,11 @@ export default {
closeDropdown () { closeDropdown () {
document.activeElement.blur() document.activeElement.blur()
}, },
addOption () {
this.field.options.push({ value: '', uuid: v4() })
this.save()
},
maybeUpdateOptions () { maybeUpdateOptions () {
delete this.field.default_value delete this.field.default_value
@ -317,7 +325,7 @@ export default {
} }
if (['radio', 'multiple', 'select'].includes(this.field.type)) { if (['radio', 'multiple', 'select'].includes(this.field.type)) {
this.field.options ||= [''] this.field.options ||= [{ value: '', uuid: v4() }]
} }
(this.field.areas || []).forEach((area) => { (this.field.areas || []).forEach((area) => {

@ -252,7 +252,7 @@ export default {
} }
if (['select', 'multiple', 'radio'].includes(type)) { if (['select', 'multiple', 'radio'].includes(type)) {
field.options = [''] field.options = [{ value: '', uuid: v4() }]
} }
this.fields.push(field) this.fields.push(field)

@ -0,0 +1,51 @@
# frozen_string_literal: true
class UpdateFieldOptions < ActiveRecord::Migration[7.0]
class MigrationTemplate < ApplicationRecord
self.table_name = 'templates'
end
class MigrationSubmission < ApplicationRecord
self.table_name = 'submissions'
end
# rubocop:disable Metrics
def up
MigrationTemplate.find_each do |template|
next if template.fields.blank?
template_fields = JSON.parse(template.fields)
new_fields = template_fields.deep_dup
new_fields.each do |field|
if field['options'].present? && !field['options'].first.is_a?(Hash)
field['options'] = field['options'].map { |o| { value: o || '', uuid: SecureRandom.uuid } }
end
end
template.update_columns(fields: new_fields.to_json) if template_fields != new_fields
end
MigrationSubmission.find_each do |submission|
next if submission.template_fields.blank?
template_fields = JSON.parse(submission.template_fields)
new_fields = template_fields.deep_dup
new_fields.each do |field|
if field['options'].present? && !field['options'].first.is_a?(Hash)
field['options'] = field['options'].map { |o| { value: o || '', uuid: SecureRandom.uuid } }
end
end
submission.update_columns(template_fields: new_fields.to_json) if template_fields != new_fields
end
end
# rubocop:enable Metrics
def down
nil
end
end

@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.0].define(version: 2023_11_02_171817) do ActiveRecord::Schema[7.0].define(version: 2023_11_12_224432) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"

Loading…
Cancel
Save