mirror of
https://github.com/rickbarrette/redmine_qbo_vehicles.git
synced 2026-04-02 07:01:59 -04:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a709fecd0c | |||
| 6db87dd551 | |||
| a73b6cd438 | |||
| f163f6518b | |||
| a89f9881a6 | |||
| ed38584ab2 | |||
| dba8381913 | |||
| d4fa314011 | |||
| be2effb1b4 | |||
| 4bcccbd2f1 | |||
| 92cc7222fb | |||
| c5318a3528 | |||
| 9315433cb1 | |||
| 82e25314f3 | |||
| 5cad4a6856 |
@@ -50,9 +50,10 @@ class Vehicle < ActiveRecord::Base
|
||||
write_attribute(:vin, val)
|
||||
end
|
||||
|
||||
# search for a vin
|
||||
def self.search(search)
|
||||
where("vin LIKE ?", "%#{search}%")
|
||||
# search for a vehicle by vin, make, model, or year
|
||||
def self.search(query)
|
||||
q = sanitize_sql_like(query)
|
||||
where("vin LIKE ? OR make LIKE ? OR model LIKE ? OR year LIKE ?", "%#{q}%", "%#{q}%", "%#{q}%", "%#{q}%")
|
||||
end
|
||||
|
||||
# decodes a vin and updates self
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<h4><%=t(:field_vehicles)%>:</h4>
|
||||
<%= render partial: 'vehicles/list', locals: { vehicles: customer.vehicles.paginate(page: params[:page]) } %>
|
||||
<%= render partial: 'vehicles/list', locals: { vehicles: customer.vehicles.paginate(page: params[:page]), show_customer: false, show_checkbox: false } %>
|
||||
<div style="float: right;">
|
||||
<%= button_to t(:button_new_vehice), new_customer_vehicle_path(customer), method: :get %>
|
||||
<%= button_to t(:button_new_vehicle), new_customer_vehicle_path(customer), method: :get %>
|
||||
</div>
|
||||
@@ -1,14 +1,17 @@
|
||||
<div class="vehicle attribute">
|
||||
<div class="label"><span><%=t(:field_vehicle)%></span>:</div>
|
||||
<div class="label"><%=t(:field_vehicle)%>:</div>
|
||||
<div class="value"><%= vehicle %></div>
|
||||
</div>
|
||||
|
||||
<div class="vehicle_vin attribute">
|
||||
<div class="label"><span><%=t(:field_vin)%></span>:</div>
|
||||
<div class="value"><%=split_vin[0] if split_vin%><b><%=split_vin[1] if split_vin%></b></div>
|
||||
<div class="label"><%=t(:field_vin)%>:</div>
|
||||
<div class="value" id="vin">
|
||||
<div id="copyLink" onclick="handleCopy(event)"><%=split_vin[0] if split_vin%><b><%=split_vin[1] if split_vin%></b></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="vehicle_notes attribute">
|
||||
<div class="label"><span><%=t(:field_notes)%></span>:</div>
|
||||
<div class="label"><%=t(:field_notes)%>:</div>
|
||||
<pre class="value" id="note-display" style="text-align: left; white-space: pre-wrap; font-family: inherit; "><%=notes%></pre>
|
||||
</div>
|
||||
@@ -18,7 +18,9 @@
|
||||
|
||||
<tr>
|
||||
<th><%= t(:field_vin) %></th>
|
||||
<td><%= @vin[0] if @vin %><b><%=@vin[1] if @vin%></b></td>
|
||||
<td>
|
||||
<div onclick="handleCopy(event)"><%= @vin[0] if @vin %><b><%=@vin[1] if @vin%></b></div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<th><%= t(:label_trim) %></th>
|
||||
|
||||
@@ -5,14 +5,23 @@
|
||||
|
||||
<div class="container">
|
||||
|
||||
<%= check_box_tag "vehicle_ids[]", vehicle.id, false, onchange: "updateLink()", data: { url: vehicle_path(vehicle).html_safe, text: vehicle.to_s }, class: "appointment checkbox" %>
|
||||
|
||||
<% if show_checkbox %>
|
||||
<%= check_box_tag "vehicle_ids[]", vehicle.id, false, onchange: "updateLink()", data: { url: vehicle_path(vehicle).html_safe, text: vehicle.to_s }, class: "appointment checkbox" %>
|
||||
<% else %>
|
||||
<div class='checkbox'>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class='label-main'>
|
||||
<%= link_to vehicle.to_s, vehicle_path(vehicle) %>
|
||||
</div>
|
||||
|
||||
<div class="label-sub">
|
||||
<%= vehicle.vin.scan(/.{1,9}/)[0] if vehicle.vin %><b><%=vehicle.vin.scan(/.{1,9}/)[1] if vehicle.vin%></b>
|
||||
<div onclick="handleCopy(event)"><%= vehicle.vin.scan(/.{1,9}/)[0] if vehicle.vin %><b><%=vehicle.vin.scan(/.{1,9}/)[1] if vehicle.vin%></b></div>
|
||||
<% if show_customer %>
|
||||
<br/>
|
||||
<%= vehicle.customer %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<%= form_tag(vehicles_path, method: "get", id: "search-form") do %>
|
||||
<%= text_field_tag :search, params[:search], placeholder: t(:label_search_vin), autocomplete: "off" %>
|
||||
<%= text_field_tag :search, params[:search], placeholder: t(:label_search), autocomplete: "off" %>
|
||||
<%= submit_tag t(:label_search) %>
|
||||
<% end %>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<h2><%=t(:label_cusomer_vehicles)%> <span style="float:right"> <%= render partial: 'vehicles/search' %> </span> </h2>
|
||||
<h2><%=t(:label_customer_vehicles)%> <span style="float:right"> <%= render partial: 'vehicles/search' %> </span> </h2>
|
||||
<br/>
|
||||
|
||||
<%= render partial: 'vehicles/list', locals: {vehicles: @vehicles} %>
|
||||
<%= render partial: 'vehicles/list', locals: {vehicles: @vehicles, show_customer: true, show_checkbox: false} %>
|
||||
|
||||
40
assets/javascripts/copy.js
Normal file
40
assets/javascripts/copy.js
Normal file
@@ -0,0 +1,40 @@
|
||||
async function handleCopy(event) {
|
||||
console.log("Copy link clicked");
|
||||
|
||||
let text;
|
||||
let link;
|
||||
// Grab the text from our clicked link
|
||||
if(event.target.tagName.toLowerCase() === 'b'){
|
||||
text = event.target.parentElement.innerText;
|
||||
link = event.target.parentElement;
|
||||
} else {
|
||||
text = event.target.innerText;
|
||||
link = event.target;
|
||||
}
|
||||
|
||||
try {
|
||||
// Write to clipboard
|
||||
await navigator.clipboard.writeText(text);
|
||||
|
||||
// Update the UI to show it worked
|
||||
const originalText = link.innerText;
|
||||
link.innerHTML = "<b>Copied!</b>";
|
||||
link.style.color = "#4CAF50"; // Turn green
|
||||
|
||||
// Reset after 2 seconds
|
||||
setTimeout(() => {
|
||||
// Check if the text is long enough to prevent errors
|
||||
if (originalText.length >= 8) {
|
||||
const firstPart = originalText.slice(0, -8);
|
||||
const lastEight = originalText.slice(-8);
|
||||
link.innerHTML = `${firstPart}<b>${lastEight}</b>`;
|
||||
} else {
|
||||
link.innerText = originalText;
|
||||
}
|
||||
link.style.color = "";
|
||||
}, 2000);
|
||||
|
||||
} catch (err) {
|
||||
console.error('Unable to copy', err);
|
||||
}
|
||||
}
|
||||
@@ -10,27 +10,27 @@
|
||||
|
||||
# English strings go here for Rails i18n
|
||||
# Usage I18n.t(:label)
|
||||
|
||||
en:
|
||||
field_vehicles: "Vehicles"
|
||||
field_vehicle: "Vehicle"
|
||||
field_vin: "VIN"
|
||||
label_edit: "Edit"
|
||||
label_year: "Year"
|
||||
label_make: " Make"
|
||||
label_model: "Model"
|
||||
label_no_vehicles: "There are no vehicles containing the term(s)"
|
||||
label_search_vin: "Search Vehicles by VIN"
|
||||
label_edit_customer_vehicle: "Edit Customer Vehicle"
|
||||
label_cusomer_vehicles: "Customer Vehicles"
|
||||
label_new_vehicle: "New Customer Vehicle"
|
||||
button_new_vehice: "New Vehicle"
|
||||
notice_vehicle_created: "Vehicle was successfully created."
|
||||
notice_vehicle_updated: "Vehicle was successfully updated."
|
||||
notice_vehicle_deleted: "Vehicle was successfully deleted."
|
||||
alert_vehicle_not_found: "Vehicle not found."
|
||||
alert_vehicle_not_deleted: "Vehicle could not be deleted."
|
||||
alert_no_customer: "Customer no longer exists, check for merged customers or deleted customers in QuickBooks Online."
|
||||
alert_vehicle_not_created: "Vehicle could not be created."
|
||||
alert_vehicle_not_deleted: "Vehicle could not be deleted."
|
||||
alert_vehicle_not_found: "Vehicle not found."
|
||||
alert_vehicle_not_updated: "Vehicle could not be updated."
|
||||
button_new_vehicle: "New Vehicle"
|
||||
field_vehicle: "Vehicle"
|
||||
field_vehicles: "Vehicles"
|
||||
field_vin: "VIN"
|
||||
label_customer_vehicles: "Customer Vehicles"
|
||||
label_edit: "Edit"
|
||||
label_edit_customer_vehicle: "Edit Customer Vehicle"
|
||||
label_make: "Make"
|
||||
label_model: "Model"
|
||||
label_new_vehicle: "New Customer Vehicle"
|
||||
label_no_vehicles: "There are no vehicles containing the term(s)"
|
||||
label_search: "Search Vehicles"
|
||||
label_year: "Year"
|
||||
no_customer: "Customer no longer exists"
|
||||
alert_no_customer: "Customer no longer exists, check for merged customers or deleted customers in Quick Books Online."
|
||||
|
||||
notice_vehicle_created: "Vehicle was successfully created."
|
||||
notice_vehicle_deleted: "Vehicle was successfully deleted."
|
||||
notice_vehicle_updated: "Vehicle was successfully updated."
|
||||
2
init.rb
2
init.rb
@@ -14,7 +14,7 @@ Redmine::Plugin.register :redmine_qbo_vehicles do
|
||||
name 'Redmine QBO Vehicles plugin'
|
||||
author 'Rick Barrette'
|
||||
description 'This is a plugin for Redmine to intergrate with the redmine_qbo plugin to provide vehicle data tracking'
|
||||
version '2026.2.2'
|
||||
version '2026.2.5'
|
||||
url 'https://github.com/rickbarrette/redmine_qbo_vehicles'
|
||||
author_url 'https://barrettefabrication.com'
|
||||
requires_redmine version_or_higher: '6.1.0'
|
||||
|
||||
@@ -14,7 +14,8 @@ module Vehicles
|
||||
|
||||
def view_layouts_base_html_head(context = {})
|
||||
safe_join([
|
||||
stylesheet_link_tag('style', plugin: :redmine_qbo_vehicles, media: :all)
|
||||
stylesheet_link_tag('style', plugin: :redmine_qbo_vehicles, media: :all),
|
||||
javascript_include_tag('copy', plugin: :redmine_qbo_vehicles)
|
||||
])
|
||||
end
|
||||
|
||||
|
||||
BIN
screenshots/customer_details.png
Normal file
BIN
screenshots/customer_details.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 564 KiB |
BIN
screenshots/issue.png
Normal file
BIN
screenshots/issue.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 724 KiB |
BIN
screenshots/issue_form.png
Normal file
BIN
screenshots/issue_form.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 534 KiB |
BIN
screenshots/vehicle_details.png
Normal file
BIN
screenshots/vehicle_details.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 540 KiB |
Reference in New Issue
Block a user