Load available units from system config

I'm not sure what's the best way to load data into javascript.. this works.
This commit is contained in:
David Cook
2024-03-26 17:12:26 +11:00
parent 1d8ed67b0b
commit 924701e161
4 changed files with 37 additions and 86 deletions

View File

@@ -8,6 +8,9 @@
%li#new_product_link
= button_link_to t(:new_product), "/admin/products/new", { :icon => 'icon-plus', :id => 'admin_new_product' }
%script= render partial: "admin/shared/global_var_ofn", formats: :js,
locals: { name: :available_units_sorted, value: WeightsAndMeasures.available_units_sorted }
= render partial: 'spree/admin/shared/product_sub_menu'
#products_v3_page{ "data-controller": "products" }

View File

@@ -0,0 +1 @@
var ofn_<%= name %> = <%= value.to_json.html_safe %>;

View File

@@ -4,6 +4,7 @@ import VariantUnitManager from "js/services/variant_unit_manager";
export default class OptionValueNamer {
constructor(variant) {
this.variant = variant;
this.variantUnitManager = new VariantUnitManager();
}
name() {
@@ -79,15 +80,15 @@ export default class OptionValueNamer {
// If there is none available where this is true, use the smallest
// available unit.
const product = this.variant.product;
const scales = VariantUnitManager.compatibleUnitScales(product.variant_unit_scale, product.variant_unit);
const scales = this.variantUnitManager.compatibleUnitScales(product.variant_unit_scale, product.variant_unit);
const variantUnitValue = this.variant.unit_value;
// sets largestScale = last element in filtered scales array
const largestScale = scales.filter(s => variantUnitValue / s >= 1).slice(-1)[0];
if (largestScale) {
return [largestScale, VariantUnitManager.getUnitName(largestScale, product.variant_unit)];
return [largestScale, this.variantUnitManager.getUnitName(largestScale, product.variant_unit)];
} else {
return [scales[0], VariantUnitManager.getUnitName(scales[0], product.variant_unit)];
return [scales[0], this.variantUnitManager.getUnitName(scales[0], product.variant_unit)];
}
}
}

View File

@@ -1,68 +1,11 @@
// todo load availableUnits. Hmm why not just load from the dropdown?
export default class VariantUnitManager {
static availableUnits = 'g,kg,T,mL,L,gal,kL';
// todo: load units from Ruby also?
static units = {
weight: {
0.001: {
name: 'mg',
system: 'metric'
},
1.0: {
name: 'g',
system: 'metric'
},
1000.0: {
name: 'kg',
system: 'metric'
},
1000000.0: {
name: 'T',
system: 'metric'
},
453.6: {
name: 'lb',
system: 'imperial'
},
28.35: {
name: 'oz',
system: 'imperial'
}
},
volume: {
0.001: {
name: 'mL',
system: 'metric'
},
0.01: {
name: 'cL',
system: 'metric'
},
0.1: {
name: 'dL',
system: 'metric'
},
1.0: {
name: 'L',
system: 'metric'
},
1000.0: {
name: 'kL',
system: 'metric'
},
4.54609: {
name: 'gal',
system: 'metric'
}
},
items: {
1: {
name: 'items'
}
}
};
// Requires global variable from page: ofn_available_units_sorted
static getUnitName = (scale, unitType) => {
export default class VariantUnitManager {
constructor() {
this.units = this.#loadUnits(ofn_available_units_sorted);
}
getUnitName(scale, unitType) {
if (this.units[unitType][scale]) {
return this.units[unitType][scale]['name'];
} else {
@@ -70,24 +13,27 @@ export default class VariantUnitManager {
}
};
// filter by system and format
static compatibleUnitScales = (scale, unitType) => {
// Filter by measurement system
compatibleUnitScales(scale, unitType) {
const scaleSystem = this.units[unitType][scale]['system'];
if (this.availableUnits) {
const available = this.availableUnits.split(",");
return Object.entries(this.units[unitType])
.filter(([scale, scaleInfo]) => {
return scaleInfo['system'] == scaleSystem && available.includes(scaleInfo['name']);
})
.map(([scale, _]) => parseFloat(scale))
.sort((a, b) => a - b);
} else {
return Object.entries(this.units[unitType])
.filter(([scale, scaleInfo]) => {
return scaleInfo['system'] == scaleSystem;
})
.map(([scale, _]) => parseFloat(scale))
.sort((a, b) => a - b);
}
};
return Object.entries(this.units[unitType])
.filter(([scale, scaleInfo]) => {
return scaleInfo['system'] == scaleSystem;
})
.map(([scale, _]) => scale);
}
// private
#loadUnits(units) {
// Transform unit scale to a JS Number for compatibility. This would be way simpler in Ruby or Coffeescript!!
const unitsTransformed = Object.entries(units).map(([measurement, measurementInfo]) => {
const measurementInfoTransformed = Object.fromEntries(Object.entries(measurementInfo).map(([scale, unitInfo]) =>
[ parseFloat(scale), unitInfo ]
));
return [ measurement, measurementInfoTransformed ];
});
return Object.fromEntries(unitsTransformed);
}
}