Workflow status creation (extra forms)
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
.workflow-statuses-batch-update-fieldsets {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, auto) min-content;
|
||||
gap: 0.5em;
|
||||
|
||||
> .fieldset {
|
||||
display: grid;
|
||||
grid-column: 1 / -1;
|
||||
grid-template-columns: subgrid;
|
||||
|
||||
.buttons {
|
||||
align-items: flex-end;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ module ProjectAdmin
|
||||
end
|
||||
|
||||
@form = ProjectAdmin::Workflows::Statuses::BatchUpdate.new(form_params)
|
||||
if @form.perform(@workflow)
|
||||
if @form.call(@workflow)
|
||||
redirect_to project_admin_workflow_path(@project, @workflow)
|
||||
else
|
||||
render :edit
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
import { Controller } from '@hotwired/stimulus'
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = ['template', 'container', 'subform']
|
||||
static values = {
|
||||
fieldName: String,
|
||||
fieldTemplate: String,
|
||||
indexTemplate: String,
|
||||
count: Number
|
||||
}
|
||||
|
||||
connect() {
|
||||
this.extraFieldsCount = 0
|
||||
}
|
||||
|
||||
addForm() {
|
||||
this.countValue++;
|
||||
this.extraFieldsCount++;
|
||||
const content = document.importNode(this.templateTarget.content, true)
|
||||
for (let element of content.querySelectorAll('label, input, select, textarea')) {
|
||||
this._replaceAttr(element, 'name')
|
||||
this._replaceAttr(element, 'id')
|
||||
this._replaceAttr(element, 'for')
|
||||
}
|
||||
|
||||
let idInput = content.querySelector('input[name$="[id]"]')
|
||||
if (idInput) {
|
||||
idInput.value = `_${this.extraFieldsCount}`
|
||||
}
|
||||
|
||||
this._subformsContainer.insertAdjacentElement('beforeend', content.children[0])
|
||||
}
|
||||
|
||||
toggleSubform(event) {
|
||||
// TODO: maybe extract into a separate controller
|
||||
let target = event.currentTarget
|
||||
let subform = this._findSubform(target)
|
||||
let disabled = subform.toggleAttribute('data-disabled')
|
||||
for (let input of subform.querySelectorAll('input:not([type="hidden"]), select, textarea')) {
|
||||
input.toggleAttribute('disabled', disabled)
|
||||
}
|
||||
let destroyInput = subform.querySelector('input[name$="[_destroy]"]')
|
||||
if(destroyInput) { destroyInput.value = disabled ? 'true' : '' }
|
||||
if(target.tagName == 'BUTTON') {
|
||||
target.setAttribute('aria-pressed', disabled ? 'true' : 'false')
|
||||
}
|
||||
}
|
||||
|
||||
deleteSubform(event) {
|
||||
let subform = this._findSubform(event.currentTarget)
|
||||
subform.remove()
|
||||
}
|
||||
|
||||
get _subformsContainer() {
|
||||
if(this.hasContainerTarget) { return this.containerTarget }
|
||||
|
||||
return this.element
|
||||
}
|
||||
|
||||
_findSubform(element) {
|
||||
for (let subform of this.subformTargets) {
|
||||
if(subform.contains(element)) { return subform }
|
||||
}
|
||||
}
|
||||
|
||||
_replaceAttr(element, attr) {
|
||||
let value = element.getAttribute(attr)
|
||||
if(value == null) return;
|
||||
|
||||
value = value.replace(this.fieldTemplateValue, this.fieldNameValue).replace(this.indexTemplateValue, this.countValue)
|
||||
element.setAttribute(attr, value)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,27 +28,45 @@ module ProjectAdmin
|
||||
@task_statuses = Array(attributes).map { |e| TaskStatus.new(e) }
|
||||
end
|
||||
|
||||
def perform(workflow)
|
||||
def call(workflow)
|
||||
@workflow = workflow
|
||||
task_status_models = @workflow.task_statuses.index_by(&:id)
|
||||
|
||||
@workflow.transaction(requires_new: true) do
|
||||
task_statuses.each do |ts|
|
||||
model = task_status_models.fetch(ts.id.to_i)
|
||||
if ts.id.start_with?('_')
|
||||
create_model!(ts)
|
||||
else
|
||||
model = task_status_models.fetch(Integer(ts.id))
|
||||
if ts._destroy
|
||||
model.destroy!
|
||||
else
|
||||
model.update!(
|
||||
name: ts.name,
|
||||
icon: ts.icon,
|
||||
color: ts.color
|
||||
)
|
||||
update_model!(model, ts)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def update_model!(model, form)
|
||||
model.update!(
|
||||
name: form.name,
|
||||
icon: form.icon,
|
||||
color: form.color
|
||||
)
|
||||
end
|
||||
|
||||
def create_model!(form)
|
||||
@workflow.task_statuses.create!(
|
||||
name: form.name,
|
||||
icon: form.icon,
|
||||
color: form.color
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
- with_destroy ||= false
|
||||
|
||||
div.fieldset data-dynamic-forms-target="subform"
|
||||
= ff.hidden_field :id
|
||||
- if with_destroy
|
||||
= ff.hidden_field :_destroy
|
||||
.field
|
||||
= ff.label :name
|
||||
= ff.text_field :name
|
||||
.field
|
||||
= ff.label :color
|
||||
= ff.select :color, TaskStatus.colors
|
||||
.field
|
||||
= ff.label :icon
|
||||
= ff.select :icon, TaskStatus.icons
|
||||
.buttons
|
||||
= button_tag 'Destroy', type: :button, class: 'danger', data: { action: (with_destroy ? 'dynamic-forms#toggleSubform' : 'dynamic-forms#deleteSubform') }
|
||||
@@ -1,16 +1,14 @@
|
||||
= form_with model: @form, scope: 'workflow', url: project_admin_workflow_statuses_path(@project, @workflow), method: :put do |f|
|
||||
= form_with model: @form, scope: 'workflow', url: project_admin_workflow_statuses_path(@project, @workflow), method: :put, data: {controller: 'dynamic-forms', 'dynamic-forms-field-name-value': 'task_statuses_attributes', 'dynamic-forms-field-template-value': '_extra_form', 'dynamic-forms-index-template-value': '__index__', 'dynamic-forms-count-value': @form.task_statuses.count} do |f|
|
||||
section.workflow-statuses-batch-update-fieldsets data-dynamic-forms-target="container"
|
||||
= f.fields_for :task_statuses, include_id: false do |tsf|
|
||||
fieldset
|
||||
= tsf.hidden_field :id
|
||||
= tsf.hidden_field :_destroy
|
||||
.field
|
||||
= tsf.label :name
|
||||
= tsf.text_field :name
|
||||
.field
|
||||
= tsf.label :color
|
||||
= tsf.select :color, TaskStatus.colors
|
||||
.field
|
||||
= tsf.label :icon
|
||||
= tsf.select :icon, TaskStatus.icons
|
||||
= render 'batch_update_fieldset', ff: tsf, with_destroy: true
|
||||
|
||||
.buttons
|
||||
button.success type="button" data-action="dynamic-forms#addForm" Add status
|
||||
|
||||
= f.fields_for :'_extra_form', index: '__index__' do |exf|
|
||||
template data-dynamic-forms-target="template"
|
||||
= render 'batch_update_fieldset', ff: exf
|
||||
|
||||
.submit
|
||||
= f.submit
|
||||
|
||||
Reference in New Issue
Block a user