Files
2026-09-15 10:35:56 +08:00

237 lines
9.7 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
define(['jquery', 'mage/translate'], function ($, $t) {
'use strict';
return function (config, element) {
var $root = $(element),
rawConfig = $root.find('[data-role="parameter-config"]').text(),
data = rawConfig ? JSON.parse(rawConfig) : {},
products = data.products || [],
applicationOptions = data.applicationOptions || [],
messages = data.messages || {},
maximum = 6,
selected = [],
mode = 'key',
keyParameters = [
'Density(g/cm3) (unit to be confirmed)',
'Heat Distortion Temperature(°C)',
'Tensile Strength (XY) (MPa)',
'Elongation at Break (XY) (%)',
'Flexural Strength (XY) (MPa)',
'Flexural Modulus (XY) (MPa)',
'IZOD Impact Strength (XY) (kJ/m²)',
'Extruder Temperature(°C)',
'Bed Temperature(°C)',
'Fan Speed(%)',
'Printing Speed(mm/s) (high-speed printing parameter)',
'Printing Recommendation',
'Drying'
],
$seriesList = $root.find('[data-role="series-list"]'),
$selectedMaterials = $root.find('[data-role="selected-materials"]'),
$notice = $root.find('[data-role="material-notice"]'),
$selectionCount = $root.find('[data-role="selection-count"]'),
$comparisonCount = $root.find('[data-role="comparison-count"]'),
$resultCount = $root.find('[data-role="result-count"]'),
$placeholder = $root.find('[data-role="comparison-placeholder"]'),
$tableWrap = $root.find('[data-role="comparison-table-wrap"]'),
$head = $root.find('[data-role="comparison-head"]'),
$body = $root.find('[data-role="comparison-body"]');
function selectedBase() {
return $root.find('[data-role="base-filter"]:checked').val() || '';
}
function productsForBase() {
var base = selectedBase();
return $.grep(products, function (product) { return product.base === base; });
}
function primaryApplication(product) {
return product.applications && product.applications.length ? product.applications[0] : 'other';
}
function applicationLabel(value) {
var option = applicationOptions.find(function (item) { return item.value === value; });
return option ? option.label : $t('Other Series');
}
function isSelected(id) {
return $.inArray(id, selected) !== -1;
}
function findProduct(id) {
return products.find(function (product) { return product.id === id; });
}
function renderSeries() {
var baseProducts = productsForBase(), groups = {};
$.each(baseProducts, function (_, product) {
var application = primaryApplication(product);
groups[application] = groups[application] || [];
groups[application].push(product);
});
$seriesList.empty();
$.each(applicationOptions, function (_, option) {
var groupProducts = groups[option.value] || [];
if (!groupProducts.length) {
return;
}
renderSeriesRow(option.label, groupProducts);
delete groups[option.value];
});
$.each(groups, function (application, groupProducts) {
renderSeriesRow(applicationLabel(application), groupProducts);
});
$resultCount.text(baseProducts.length);
updateSelection();
}
function renderSeriesRow(label, groupProducts) {
var $row = $('<div/>', {'class': 'esun-parameter-comparison__series-row'}),
$label = $('<div/>', {'class': 'esun-parameter-comparison__series-name'}),
$products = $('<div/>', {'class': 'esun-parameter-comparison__series-products'});
$label.append($('<strong/>', {text: label}), $('<span/>', {text: groupProducts.length}));
$.each(groupProducts, function (_, product) {
$('<button/>', {
type: 'button',
'class': 'esun-parameter-comparison__product' + (isSelected(product.id) ? ' is-selected' : ''),
text: product.name,
title: product.name,
disabled: !isSelected(product.id) && selected.length >= maximum,
'data-role': 'material-option',
'data-id': product.id
}).appendTo($products);
});
$row.append($label, $products).appendTo($seriesList);
}
function updateSelection() {
$selectionCount.text(selected.length);
$comparisonCount.text(selected.length);
$selectedMaterials.empty();
$.each(selected, function (_, id) {
var product = findProduct(id), $pill;
if (!product) {
return;
}
$pill = $('<span/>', {'class': 'esun-parameter-comparison__selected-pill'});
$pill.append(
$('<span/>', {text: product.name}),
$('<button/>', {
type: 'button',
text: '×',
'aria-label': $t('Remove %1').replace('%1', product.name),
'data-role': 'remove-material',
'data-id': id
})
).appendTo($selectedMaterials);
});
renderComparison();
}
function removeMaterial(id) {
selected = $.grep(selected, function (selectedId) { return selectedId !== id; });
$notice.text('');
renderSeries();
}
function parameterIsVisible(name, values) {
if (mode === 'key' && $.inArray(name, keyParameters) === -1) {
return false;
}
if (mode === 'differences') {
return values.filter(function (value, index, array) {
return array.indexOf(value) === index;
}).length > 1;
}
return true;
}
function renderComparison() {
var selectedProducts = $.map(selected, findProduct),
groups = data.parameterGroups || {};
$head.empty();
$body.empty();
if (selectedProducts.length < 1) {
$placeholder.show();
$tableWrap.hide();
return;
}
$tableWrap.toggleClass('is-single', selectedProducts.length === 1);
var $headerRow = $('<tr/>').append($('<th/>', {text: $t('Parameter')}));
$.each(selectedProducts, function (_, product) {
var $name = $('<span/>', {text: product.name}),
$remove = $('<button/>', {
type: 'button', text: '×',
'aria-label': $t('Remove %1').replace('%1', product.name),
'data-role': 'remove-material', 'data-id': product.id
});
$headerRow.append($('<th/>').append($name, $remove));
});
$head.append($headerRow);
$.each(groups, function (groupName, parameters) {
var rows = [];
$.each(parameters, function (_, parameterName) {
var values = $.map(selectedProducts, function (product) {
var value = product.groups[groupName] && product.groups[groupName][parameterName];
return value === undefined || value === null || value === ''
? (messages.missingValue || '—') : String(value);
});
if (!parameterIsVisible(parameterName, values)) {
return;
}
var $row = $('<tr/>').append($('<th/>', {scope: 'row', text: parameterName}));
$.each(values, function (_, value) { $row.append($('<td/>').text(value)); });
rows.push($row);
});
if (rows.length) {
$body.append($('<tr/>', {'class': 'esun-parameter-comparison__group-row'})
.append($('<th/>', {colspan: selectedProducts.length + 1, text: groupName})));
$.each(rows, function (_, row) { $body.append(row); });
}
});
$placeholder.hide();
$tableWrap.show();
}
$root.on('change', '[data-role="base-filter"]', function () {
selected = [];
$notice.text('');
renderSeries();
});
$root.on('click', '[data-role="material-option"]', function () {
var id = $(this).data('id');
if (isSelected(id)) {
removeMaterial(id);
return;
}
if (selected.length >= maximum) {
$notice.text($t('You can compare up to 6 materials.'));
return;
}
selected.push(id);
$notice.text('');
renderSeries();
});
$root.on('click', '[data-role="remove-material"]', function () {
removeMaterial($(this).data('id'));
});
$root.on('click', '[data-role="comparison-mode"]', function () {
mode = $(this).data('mode');
$root.find('[data-role="comparison-mode"]').removeClass('is-active');
$(this).addClass('is-active');
renderComparison();
});
renderSeries();
};
});