mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-07 21:55:20 +08:00
Add reorder form fields [SCI-11343]
This commit is contained in:
parent
29f59293f4
commit
9d92679c58
6 changed files with 37 additions and 22 deletions
|
@ -36,7 +36,7 @@ class FormFieldsController < ApplicationController
|
|||
|
||||
def destroy
|
||||
ActiveRecord::Base.transaction do
|
||||
if @form_field.discard
|
||||
if @form_field.destroy
|
||||
render json: {}
|
||||
else
|
||||
render json: { error: @form_field.errors.full_messages }, status: :unprocessable_entity
|
||||
|
|
|
@ -34,17 +34,29 @@
|
|||
<div class="p-6 border-transparent border-r-sn-sleepy-grey border-solid border-r">
|
||||
<h3 class="mb-3">{{ i18n.t('forms.show.build_form') }}</h3>
|
||||
<div class="mb-3 flex flex-col gap-3">
|
||||
<div v-for="(field) in fields"
|
||||
@click="activeField = field"
|
||||
:key="field.id"
|
||||
class="font-bold p-3 rounded-lg flex items-center gap-2 border-sn-grey-100 cursor-pointer border"
|
||||
:class="{ '!border-sn-blue bg-sn-super-light-blue': activeField.id === field.id }"
|
||||
>
|
||||
<i class="sn-icon rounded text-sn-blue bg-sn-super-light-blue p-1" :class="fieldIcon[field.attributes.data.type]"></i>
|
||||
{{ field.attributes.name }}
|
||||
</div>
|
||||
<Draggable
|
||||
v-model="fields"
|
||||
class="flex flex-col gap-3"
|
||||
handle=".element-grip"
|
||||
item-key="id"
|
||||
@end="saveOrder"
|
||||
>
|
||||
<template #item="{element, index}">
|
||||
<div class="flex items-center relative group -ml-6 w-[calc(100%_+_24px)]">
|
||||
<i class="sn-icon sn-icon-drag text-sn-grey element-grip cursor-grab opacity-0 group-hover:opacity-100"></i>
|
||||
<div @click="activeField = element"
|
||||
:key="element.id"
|
||||
class="font-bold relative grow p-2 rounded-lg overflow-hidden flex items-center gap-2 border-sn-grey-100 cursor-pointer border"
|
||||
:class="{ '!border-sn-blue bg-sn-super-light-blue': activeField.id === element.id }"
|
||||
>
|
||||
<i class="sn-icon rounded text-sn-blue bg-sn-super-light-blue p-1" :class="fieldIcon[element.attributes.data.type]"></i>
|
||||
<span class="truncate">{{ element.attributes.name }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Draggable>
|
||||
</div>
|
||||
<GeneralDropdown>
|
||||
<GeneralDropdown ref="addFieldDropdown">
|
||||
<template v-slot:field>
|
||||
<button class="btn btn-secondary w-full">
|
||||
<i class="sn-icon sn-icon-new-task"></i>
|
||||
|
@ -76,6 +88,7 @@
|
|||
|
||||
<script>
|
||||
|
||||
import Draggable from 'vuedraggable';
|
||||
import InlineEdit from '../shared/inline_edit.vue';
|
||||
import axios from '../../packs/custom_axios.js';
|
||||
import GeneralDropdown from '../shared/general_dropdown.vue';
|
||||
|
@ -89,7 +102,8 @@ export default {
|
|||
components: {
|
||||
InlineEdit,
|
||||
GeneralDropdown,
|
||||
EditField
|
||||
EditField,
|
||||
Draggable
|
||||
},
|
||||
computed: {
|
||||
canManage() {
|
||||
|
@ -129,6 +143,7 @@ export default {
|
|||
axios.get(this.formUrl).then((response) => {
|
||||
this.form = response.data.data;
|
||||
this.fields = response.data.included || [];
|
||||
this.fields = this.fields.sort((a, b) => a.attributes.position - b.attributes.position);
|
||||
if (this.fields.length > 0) {
|
||||
[this.activeField] = this.fields;
|
||||
}
|
||||
|
@ -147,6 +162,7 @@ export default {
|
|||
if (this.fields.length === 1) {
|
||||
[this.activeField] = this.fields;
|
||||
}
|
||||
this.$refs.addFieldDropdown.isOpen = false;
|
||||
});
|
||||
},
|
||||
updateName(name) {
|
||||
|
@ -166,6 +182,11 @@ export default {
|
|||
this.fields.splice(index, 1, response.data.data);
|
||||
});
|
||||
},
|
||||
saveOrder() {
|
||||
axios.post(this.form.attributes.urls.reorder_fields, {
|
||||
form_field_positions: this.fields.map((f, i) => ({ id: f.id, position: i }))
|
||||
});
|
||||
},
|
||||
deleteField(field) {
|
||||
const index = this.fields.findIndex((f) => f.id === field.id);
|
||||
axios.delete(field.attributes.urls.show).then(() => {
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class FormField < ApplicationRecord
|
||||
include Discard::Model
|
||||
|
||||
default_scope -> { kept }
|
||||
|
||||
belongs_to :form
|
||||
belongs_to :created_by, class_name: 'User'
|
||||
|
@ -13,6 +10,6 @@ class FormField < ApplicationRecord
|
|||
validates :description, length: { maximum: Constants::NAME_MAX_LENGTH }
|
||||
validates :position, presence: true, uniqueness: { scope: :form }
|
||||
|
||||
acts_as_list scope: [:form, discarded_at: nil], top_of_list: 0, sequential_updates: true
|
||||
acts_as_list scope: :form, top_of_list: 0, sequential_updates: true
|
||||
|
||||
end
|
||||
|
|
|
@ -8,8 +8,7 @@ class FormSerializer < ActiveModel::Serializer
|
|||
|
||||
has_many :form_fields,
|
||||
key: :form_fields,
|
||||
serializer: FormFieldSerializer,
|
||||
order: :position
|
||||
serializer: FormFieldSerializer
|
||||
|
||||
def published_by
|
||||
object.published_by&.full_name
|
||||
|
@ -26,7 +25,8 @@ class FormSerializer < ActiveModel::Serializer
|
|||
def urls
|
||||
{
|
||||
show: form_path(object),
|
||||
create_field: form_form_fields_path(object)
|
||||
create_field: form_form_fields_path(object),
|
||||
reorder_fields: reorder_form_form_fields_path(object)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -31,7 +31,6 @@ class CreateForms < ActiveRecord::Migration[7.0]
|
|||
t.boolean :required, default: false, null: false
|
||||
t.boolean :allow_not_applicable, default: false, null: false
|
||||
t.string :uid
|
||||
t.datetime :discarded_at, index: true
|
||||
|
||||
t.timestamps
|
||||
end
|
||||
|
|
|
@ -235,11 +235,9 @@ ActiveRecord::Schema[7.0].define(version: 2024_12_09_074134) do
|
|||
t.boolean "required", default: false, null: false
|
||||
t.boolean "allow_not_applicable", default: false, null: false
|
||||
t.string "uid"
|
||||
t.datetime "discarded_at"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["created_by_id"], name: "index_form_fields_on_created_by_id"
|
||||
t.index ["discarded_at"], name: "index_form_fields_on_discarded_at"
|
||||
t.index ["form_id"], name: "index_form_fields_on_form_id"
|
||||
t.index ["last_modified_by_id"], name: "index_form_fields_on_last_modified_by_id"
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue