mirror of
https://github.com/rickbarrette/redmine_qbo.git
synced 2026-04-02 08:21:57 -04:00
Got the UI working
This commit is contained in:
@@ -9,4 +9,4 @@
|
||||
</p>
|
||||
|
||||
|
||||
<%= render "line_items/issue_form" %>
|
||||
<%= render "line_items/issue_form", f: f %>
|
||||
@@ -1,31 +1,17 @@
|
||||
<%= form_with model: @issue do |f| %>
|
||||
<% @issue.line_items.build if @issue.line_items.empty? %>
|
||||
|
||||
<!-- Existing issue fields -->
|
||||
|
||||
<h3>Invoice Line Items</h3>
|
||||
|
||||
<div
|
||||
data-controller="nested-form"
|
||||
data-nested-form-wrapper-selector-value=".line-item"
|
||||
>
|
||||
<div data-nested-form-target="container">
|
||||
<%= f.fields_for :invoice_line_items do |item_form| %>
|
||||
<%= render "line_items/invoice_line_item_fields", f: item_form %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<template data-nested-form-target="template">
|
||||
<%= f.fields_for :invoice_line_items,
|
||||
LineItem.new,
|
||||
child_index: "NEW_RECORD" do |item_form| %>
|
||||
<%= render "line_items/invoice_line_item_fields", f: item_form %>
|
||||
<% end %>
|
||||
</template>
|
||||
|
||||
<button type="button" data-action="nested-form#add">
|
||||
Add Line Item
|
||||
</button>
|
||||
<div data-nested-form data-wrapper-selector=".line-item">
|
||||
<div data-nested-form-container>
|
||||
<%= f.fields_for :line_items do |item_form| %>
|
||||
<%= render "line_items/line_item_fields", f: item_form %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
<%= f.submit %>
|
||||
<% end %>
|
||||
<template data-nested-form-template>
|
||||
<%= f.fields_for :line_items, LineItem.new, child_index: "NEW_RECORD" do |item_form| %>
|
||||
<%= render "line_items/line_item_fields", f: item_form %>
|
||||
<% end %>
|
||||
</template>
|
||||
|
||||
<button type="button" data-nested-form-add>Add Line Item</button>
|
||||
</div>
|
||||
@@ -2,12 +2,12 @@
|
||||
<%= f.hidden_field :id %>
|
||||
|
||||
<%= f.text_field :description, placeholder: "Description" %>
|
||||
<%= f.number_field :quantity, step: 1 ,placeholder: "Quantity"%>
|
||||
<%= f.number_field :quantity, step: 1, placeholder: "Quantity" %>
|
||||
<%= f.number_field :unit_price, step: 0.01, placeholder: "Unit Price" %>
|
||||
|
||||
<%= f.hidden_field :_destroy %>
|
||||
|
||||
<button type="button" data-action="nested-form#remove">
|
||||
<button type="button" data-nested-form-remove>
|
||||
Remove
|
||||
</button>
|
||||
</div>
|
||||
@@ -1,9 +0,0 @@
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
if (typeof Stimulus === "undefined") {
|
||||
console.error("Stimulus is not loaded. Make sure the UMD script is included first.");
|
||||
return;
|
||||
}
|
||||
|
||||
const application = Stimulus.Application.start();
|
||||
application.register("nested-form", window.NestedFormController);
|
||||
});
|
||||
@@ -1,19 +1,53 @@
|
||||
(function() {
|
||||
class NestedFormController extends Stimulus.Controller {
|
||||
static targets = ["container", "template"]
|
||||
(function () {
|
||||
function initNestedForms() {
|
||||
document.querySelectorAll("[data-nested-form]").forEach(function (wrapper) {
|
||||
if (wrapper.dataset.initialized === "true") return;
|
||||
wrapper.dataset.initialized = "true";
|
||||
|
||||
add(event) {
|
||||
event.preventDefault();
|
||||
const content = this.templateTarget.innerHTML.replace(/NEW_RECORD/g, new Date().getTime());
|
||||
this.containerTarget.insertAdjacentHTML("beforeend", content);
|
||||
}
|
||||
const container = wrapper.querySelector("[data-nested-form-container]");
|
||||
const template = wrapper.querySelector("[data-nested-form-template]");
|
||||
|
||||
remove(event) {
|
||||
event.preventDefault();
|
||||
event.target.closest(".nested-fields").remove();
|
||||
}
|
||||
if (!container || !template) return;
|
||||
|
||||
wrapper.addEventListener("click", function (event) {
|
||||
const addButton = event.target.closest("[data-nested-form-add]");
|
||||
const removeButton = event.target.closest("[data-nested-form-remove]");
|
||||
|
||||
// ADD
|
||||
if (addButton) {
|
||||
event.preventDefault();
|
||||
|
||||
const content = template.innerHTML.replace(
|
||||
/NEW_RECORD/g,
|
||||
Date.now().toString()
|
||||
);
|
||||
|
||||
container.insertAdjacentHTML("beforeend", content);
|
||||
}
|
||||
|
||||
// REMOVE
|
||||
if (removeButton) {
|
||||
event.preventDefault();
|
||||
|
||||
const lineItem = removeButton.closest(wrapper.dataset.wrapperSelector);
|
||||
if (!lineItem) return;
|
||||
|
||||
const destroyField = lineItem.querySelector("input[name*='_destroy']");
|
||||
|
||||
if (destroyField) {
|
||||
destroyField.value = "1";
|
||||
lineItem.style.display = "none";
|
||||
} else {
|
||||
lineItem.remove();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Expose globally so index.js can access it
|
||||
window.NestedFormController = NestedFormController;
|
||||
// Works for full load
|
||||
document.addEventListener("DOMContentLoaded", initNestedForms);
|
||||
|
||||
// Works for Turbo navigation
|
||||
document.addEventListener("turbo:load", initNestedForms);
|
||||
})();
|
||||
File diff suppressed because it is too large
Load Diff
@@ -64,7 +64,8 @@ module RedmineQbo
|
||||
locals: {
|
||||
search_customer: search_customer,
|
||||
customer_id: customer_id,
|
||||
select_estimate: select_estimate
|
||||
select_estimate: select_estimate,
|
||||
f: context[:form]
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@@ -16,11 +16,9 @@ module RedmineQbo
|
||||
# Load the javascript to support the autocomplete forms
|
||||
def view_layouts_base_html_head(context = {})
|
||||
safe_join([
|
||||
'<script src="https://unpkg.com/@hotwired/stimulus/dist/stimulus.umd.js"></script>'.html_safe,
|
||||
javascript_include_tag( 'application.js', plugin: :redmine_qbo),
|
||||
javascript_include_tag( 'autocomplete-rails.js', plugin: :redmine_qbo),
|
||||
javascript_include_tag( 'checkbox_controller.js', plugin: :redmine_qbo),
|
||||
javascript_include_tag( 'index.js', plugin: :redmine_qbo),
|
||||
javascript_include_tag( 'nested_form_controller.js', plugin: :redmine_qbo)
|
||||
])
|
||||
end
|
||||
|
||||
@@ -23,6 +23,8 @@ module RedmineQbo
|
||||
belongs_to :customer_token, primary_key: :id
|
||||
belongs_to :estimate, primary_key: :id
|
||||
has_and_belongs_to_many :invoices
|
||||
has_many :line_items, dependent: :destroy
|
||||
accepts_nested_attributes_for :line_items, allow_destroy: true
|
||||
|
||||
before_save :titlize_subject
|
||||
after_commit :enqueue_billing, on: :update
|
||||
|
||||
Reference in New Issue
Block a user