@oxyshop/admin 1.3.38 → 1.3.39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.js +431 -61
- package/lib/style.css +214 -214
- package/package.json +1 -1
- package/src/components/customerGroupClientAssigner.js +4 -0
- package/src/components/productVariantPricingGraph.js +86 -0
- package/src/components/productVariantPricingSimulation.js +273 -0
- package/src/index.js +14 -4
package/lib/index.js
CHANGED
|
@@ -25,12 +25,14 @@ import 'semantic-ui-css/components/visibility';
|
|
|
25
25
|
import 'semantic-ui-css/components/visit';
|
|
26
26
|
import 'jquery.dirtyforms/jquery.dirtyforms';
|
|
27
27
|
import 'chart.js/dist/Chart.min';
|
|
28
|
+
import Chart$1 from 'chart.js';
|
|
29
|
+
import { axios } from '@oxyshop/shop/lib/plugins/Axios';
|
|
30
|
+
import axios$1 from 'axios';
|
|
28
31
|
import 'semantic-ui-css/semantic.css';
|
|
29
32
|
import '@oxyshop/admin/scss/main.scss';
|
|
30
33
|
import '@oxyshop/admin/lib/style.css';
|
|
31
34
|
import '@oxyshop/admin/images/logo.png';
|
|
32
35
|
import '@oxyshop/admin/images/admin-logo.svg';
|
|
33
|
-
import { axios } from '@oxyshop/shop/lib/plugins/Axios';
|
|
34
36
|
|
|
35
37
|
window.$ = $$1;
|
|
36
38
|
window.jQuery = $$1;
|
|
@@ -1905,6 +1907,152 @@ class FeedCategorySelect {
|
|
|
1905
1907
|
}
|
|
1906
1908
|
}
|
|
1907
1909
|
|
|
1910
|
+
class ProductVariantPricingGraph {
|
|
1911
|
+
constructor(containerSelector) {
|
|
1912
|
+
this.containerSelector = containerSelector;
|
|
1913
|
+
}
|
|
1914
|
+
|
|
1915
|
+
init() {
|
|
1916
|
+
document.querySelectorAll(this.containerSelector).forEach((componentContainer) => {
|
|
1917
|
+
const graphsData = JSON.parse(componentContainer.getAttribute('data-graph'));
|
|
1918
|
+
|
|
1919
|
+
for (const currencyGraphIndex in graphsData) {
|
|
1920
|
+
const currencyGraph = graphsData[currencyGraphIndex];
|
|
1921
|
+
|
|
1922
|
+
const currencyCodeHeader = document.createElement('h4');
|
|
1923
|
+
currencyCodeHeader.classList.add('ui', 'header');
|
|
1924
|
+
currencyCodeHeader.textContent = currencyGraph.currency;
|
|
1925
|
+
|
|
1926
|
+
const graphCanvas = document.createElement('canvas');
|
|
1927
|
+
graphCanvas.width = 400;
|
|
1928
|
+
graphCanvas.height = 200;
|
|
1929
|
+
|
|
1930
|
+
const graphContainer = document.createElement('div');
|
|
1931
|
+
graphContainer.append(currencyCodeHeader);
|
|
1932
|
+
graphContainer.append(graphCanvas);
|
|
1933
|
+
|
|
1934
|
+
componentContainer.append(graphContainer);
|
|
1935
|
+
|
|
1936
|
+
const graphConfig = this.getGraphConfig(currencyGraph.graph);
|
|
1937
|
+
new Chart$1(graphCanvas.getContext('2d'), graphConfig);
|
|
1938
|
+
}
|
|
1939
|
+
});
|
|
1940
|
+
}
|
|
1941
|
+
|
|
1942
|
+
/** @private */
|
|
1943
|
+
getGraphConfig(rawGraphData) {
|
|
1944
|
+
return {
|
|
1945
|
+
type: 'line',
|
|
1946
|
+
data: {
|
|
1947
|
+
datasets: rawGraphData.datasets.map((rawDataset) => {
|
|
1948
|
+
return {
|
|
1949
|
+
label: rawDataset.label,
|
|
1950
|
+
data: rawDataset.data,
|
|
1951
|
+
borderColor: this.getRandomRgbColor(),
|
|
1952
|
+
fill: false,
|
|
1953
|
+
steppedLine: true,
|
|
1954
|
+
pointRadius: 8,
|
|
1955
|
+
pointHoverRadius: 10,
|
|
1956
|
+
}
|
|
1957
|
+
}),
|
|
1958
|
+
},
|
|
1959
|
+
options: {
|
|
1960
|
+
maintainAspectRatio: true,
|
|
1961
|
+
responsive: true,
|
|
1962
|
+
scales: {
|
|
1963
|
+
xAxes: [
|
|
1964
|
+
{
|
|
1965
|
+
type: 'linear',
|
|
1966
|
+
position: 'bottom',
|
|
1967
|
+
scaleLabel: {
|
|
1968
|
+
display: true,
|
|
1969
|
+
labelString: rawGraphData.xAxisLabel,
|
|
1970
|
+
},
|
|
1971
|
+
},
|
|
1972
|
+
],
|
|
1973
|
+
yAxes: [
|
|
1974
|
+
{
|
|
1975
|
+
scaleLabel: {
|
|
1976
|
+
display: true,
|
|
1977
|
+
labelString: rawGraphData.yAxisLabel,
|
|
1978
|
+
},
|
|
1979
|
+
},
|
|
1980
|
+
],
|
|
1981
|
+
},
|
|
1982
|
+
},
|
|
1983
|
+
}
|
|
1984
|
+
}
|
|
1985
|
+
|
|
1986
|
+
/** @private */
|
|
1987
|
+
getRandomRgbColor() {
|
|
1988
|
+
const r = Math.floor(Math.random() * 255);
|
|
1989
|
+
const g = Math.floor(Math.random() * 255);
|
|
1990
|
+
const b = Math.floor(Math.random() * 255);
|
|
1991
|
+
return `rgb(${r},${g},${b})`
|
|
1992
|
+
}
|
|
1993
|
+
}
|
|
1994
|
+
|
|
1995
|
+
class CustomerGroupClientAssigner {
|
|
1996
|
+
constructor(selector, searchSelector = '.ng-client-search-select', submitSelector = '.ng-client-assign-submit') {
|
|
1997
|
+
this.selector = selector;
|
|
1998
|
+
this.searchSelector = searchSelector;
|
|
1999
|
+
this.submitSelector = submitSelector;
|
|
2000
|
+
|
|
2001
|
+
this.containerElement = null;
|
|
2002
|
+
this.searchElement = null;
|
|
2003
|
+
this.submitElement = null;
|
|
2004
|
+
}
|
|
2005
|
+
|
|
2006
|
+
init() {
|
|
2007
|
+
this.containerElement = document.querySelector(this.selector);
|
|
2008
|
+
if (null === this.containerElement) {
|
|
2009
|
+
return
|
|
2010
|
+
}
|
|
2011
|
+
|
|
2012
|
+
const submitApiEndpoint = this.containerElement.getAttribute('data-assign-customers-url');
|
|
2013
|
+
const redirectAfterUrl = this.containerElement.getAttribute('data-redirect-after-url');
|
|
2014
|
+
|
|
2015
|
+
this.searchElement = this.containerElement.querySelector(this.searchSelector);
|
|
2016
|
+
const searchApiEndpoint = this.searchElement.getAttribute('data-customer-search-url');
|
|
2017
|
+
|
|
2018
|
+
$(this.searchElement).dropdown({
|
|
2019
|
+
apiSettings: {
|
|
2020
|
+
url: `${searchApiEndpoint}/{query}`,
|
|
2021
|
+
cache: false,
|
|
2022
|
+
},
|
|
2023
|
+
|
|
2024
|
+
minCharacters: 2,
|
|
2025
|
+
});
|
|
2026
|
+
|
|
2027
|
+
this.submitElement = this.containerElement.querySelector(this.submitSelector);
|
|
2028
|
+
this.submitElement.addEventListener('click', () => {
|
|
2029
|
+
const selectedCustomersIds = this.getSelectValues(this.searchElement);
|
|
2030
|
+
this.submitCustomers(submitApiEndpoint, selectedCustomersIds, redirectAfterUrl);
|
|
2031
|
+
});
|
|
2032
|
+
}
|
|
2033
|
+
|
|
2034
|
+
getSelectValues(selectElement) {
|
|
2035
|
+
const selected = selectElement.querySelectorAll('option:checked');
|
|
2036
|
+
return Array.from(selected).map((optionElement) => optionElement.value)
|
|
2037
|
+
}
|
|
2038
|
+
|
|
2039
|
+
submitCustomers(apiEndpoint, selectedIds, redirectTo) {
|
|
2040
|
+
this.submitElement.disabled = true;
|
|
2041
|
+
|
|
2042
|
+
axios
|
|
2043
|
+
.post(apiEndpoint, { customers: selectedIds })
|
|
2044
|
+
.then(() => {
|
|
2045
|
+
window.location = redirectTo;
|
|
2046
|
+
})
|
|
2047
|
+
.catch((error) => {
|
|
2048
|
+
console.error(error);
|
|
2049
|
+
})
|
|
2050
|
+
.finally(() => {
|
|
2051
|
+
this.submitElement.disabled = false;
|
|
2052
|
+
});
|
|
2053
|
+
}
|
|
2054
|
+
}
|
|
2055
|
+
|
|
1908
2056
|
class TooltipHelpers {
|
|
1909
2057
|
static init() {
|
|
1910
2058
|
TooltipHelpers.initSyliusShippingMethodTooltip();
|
|
@@ -2038,6 +2186,277 @@ class CustomerGroupingRuleConfiguration {
|
|
|
2038
2186
|
}
|
|
2039
2187
|
}
|
|
2040
2188
|
|
|
2189
|
+
class ProductVariantPricingSimulation {
|
|
2190
|
+
constructor(selector) {
|
|
2191
|
+
this.selector = selector;
|
|
2192
|
+
}
|
|
2193
|
+
|
|
2194
|
+
init() {
|
|
2195
|
+
document.querySelectorAll(this.selector).forEach((element) => {
|
|
2196
|
+
const productVariantId = element.getAttribute('data-product-variant-id');
|
|
2197
|
+
const channels = JSON.parse(element.getAttribute('data-channels'));
|
|
2198
|
+
const searchApiEndpoint = element.getAttribute('data-customer-search-url');
|
|
2199
|
+
const pricingApiEndpoint = element.getAttribute('data-pricing-url');
|
|
2200
|
+
|
|
2201
|
+
this.initElement(element, productVariantId, channels, searchApiEndpoint, pricingApiEndpoint);
|
|
2202
|
+
});
|
|
2203
|
+
}
|
|
2204
|
+
|
|
2205
|
+
initElement(parentElement, productVariantId, channels, searchApiEndpoint, pricingApiEndpoint) {
|
|
2206
|
+
parentElement.innerHTML = '';
|
|
2207
|
+
|
|
2208
|
+
const simulationData = {
|
|
2209
|
+
productVariantId: productVariantId,
|
|
2210
|
+
channelId: null,
|
|
2211
|
+
currencyId: null,
|
|
2212
|
+
customerId: null,
|
|
2213
|
+
};
|
|
2214
|
+
|
|
2215
|
+
const submitButton = document.createElement('button');
|
|
2216
|
+
const currencySelect = document.createElement('select');
|
|
2217
|
+
|
|
2218
|
+
const onChannelSelect = (event) => {
|
|
2219
|
+
const selectedChannelId = parseInt(event.target.value);
|
|
2220
|
+
simulationData.channelId = selectedChannelId;
|
|
2221
|
+
simulationData.currencyId = null;
|
|
2222
|
+
submitButton.disabled = this.isSubmitButtonDisabled(simulationData);
|
|
2223
|
+
|
|
2224
|
+
const selectedChannel = channels.find((channel) => {
|
|
2225
|
+
return channel.id === selectedChannelId
|
|
2226
|
+
});
|
|
2227
|
+
|
|
2228
|
+
currencySelect.innerHTML = '';
|
|
2229
|
+
this.addSelectOptions(currencySelect, selectedChannel.currencies, 'Select currency');
|
|
2230
|
+
};
|
|
2231
|
+
|
|
2232
|
+
const onCurrencySelect = (event) => {
|
|
2233
|
+
simulationData.currencyId = event.target.value;
|
|
2234
|
+
submitButton.disabled = this.isSubmitButtonDisabled(simulationData);
|
|
2235
|
+
};
|
|
2236
|
+
|
|
2237
|
+
const onCustomerSelect = (event) => {
|
|
2238
|
+
simulationData.customerId = event.target.value;
|
|
2239
|
+
submitButton.disabled = this.isSubmitButtonDisabled(simulationData);
|
|
2240
|
+
};
|
|
2241
|
+
|
|
2242
|
+
const graphWrapper = this.createGraphWrapper();
|
|
2243
|
+
|
|
2244
|
+
const onSubmit = () => {
|
|
2245
|
+
const pricingUrl = `${pricingApiEndpoint}?${this.serializeObjectToQuery(simulationData)}`;
|
|
2246
|
+
|
|
2247
|
+
axios$1
|
|
2248
|
+
.get(pricingUrl)
|
|
2249
|
+
.then((response) => {
|
|
2250
|
+
const chartData = response.data;
|
|
2251
|
+
graphWrapper.setAttribute('data-debug-chart', JSON.stringify(chartData)); // For e2e tests
|
|
2252
|
+
this.renderGraph(graphWrapper, chartData);
|
|
2253
|
+
})
|
|
2254
|
+
.catch((error) => {
|
|
2255
|
+
console.error(error);
|
|
2256
|
+
graphWrapper.innerHTML = 'Pricing simulation error';
|
|
2257
|
+
});
|
|
2258
|
+
};
|
|
2259
|
+
|
|
2260
|
+
const wrapper = document.createElement('div');
|
|
2261
|
+
wrapper.setAttribute('style', 'border: solid 1px #ddd; background-color: #fafafa;');
|
|
2262
|
+
|
|
2263
|
+
const filters = this.createFilters(
|
|
2264
|
+
channels,
|
|
2265
|
+
currencySelect,
|
|
2266
|
+
onChannelSelect,
|
|
2267
|
+
onCurrencySelect,
|
|
2268
|
+
onCustomerSelect,
|
|
2269
|
+
onSubmit,
|
|
2270
|
+
submitButton,
|
|
2271
|
+
searchApiEndpoint
|
|
2272
|
+
);
|
|
2273
|
+
filters.setAttribute(
|
|
2274
|
+
'style',
|
|
2275
|
+
'display: grid; grid-template-columns: 1fr 1fr 1fr 60px; grid-gap: 10px; ' +
|
|
2276
|
+
'padding: 15px; border-bottom: solid 1px #ddd;'
|
|
2277
|
+
);
|
|
2278
|
+
|
|
2279
|
+
const graphFiller = this.createGraphFiller();
|
|
2280
|
+
graphWrapper.append(graphFiller);
|
|
2281
|
+
|
|
2282
|
+
wrapper.append(filters, graphWrapper);
|
|
2283
|
+
parentElement.append(wrapper);
|
|
2284
|
+
}
|
|
2285
|
+
|
|
2286
|
+
createFilters(
|
|
2287
|
+
channels,
|
|
2288
|
+
currencySelect,
|
|
2289
|
+
onChannelSelect,
|
|
2290
|
+
onCurrencySelect,
|
|
2291
|
+
onCustomerSelect,
|
|
2292
|
+
onSubmit,
|
|
2293
|
+
submitButton,
|
|
2294
|
+
searchApiEndpoint
|
|
2295
|
+
) {
|
|
2296
|
+
const filtersWrapper = document.createElement('div');
|
|
2297
|
+
|
|
2298
|
+
const channelSelect = document.createElement('select');
|
|
2299
|
+
this.addSelectOptions(channelSelect, channels, 'Select channel');
|
|
2300
|
+
channelSelect.addEventListener('change', onChannelSelect);
|
|
2301
|
+
|
|
2302
|
+
currencySelect.addEventListener('change', onCurrencySelect);
|
|
2303
|
+
|
|
2304
|
+
const customerSelect = document.createElement('select');
|
|
2305
|
+
customerSelect.addEventListener('change', onCustomerSelect);
|
|
2306
|
+
|
|
2307
|
+
// this is delayed to avoid racing conditions
|
|
2308
|
+
setTimeout(() => this.hookClientSearchOnSelect(customerSelect, searchApiEndpoint), 600);
|
|
2309
|
+
|
|
2310
|
+
submitButton.disabled = true;
|
|
2311
|
+
submitButton.setAttribute('class', 'ui icon primary button');
|
|
2312
|
+
submitButton.type = 'button';
|
|
2313
|
+
submitButton.addEventListener('click', onSubmit);
|
|
2314
|
+
|
|
2315
|
+
const playIcon = document.createElement('i');
|
|
2316
|
+
playIcon.setAttribute('class', 'icon play');
|
|
2317
|
+
submitButton.append(playIcon);
|
|
2318
|
+
|
|
2319
|
+
filtersWrapper.append(channelSelect, currencySelect, customerSelect, submitButton);
|
|
2320
|
+
|
|
2321
|
+
return filtersWrapper
|
|
2322
|
+
}
|
|
2323
|
+
|
|
2324
|
+
createGraphWrapper() {
|
|
2325
|
+
const wrapper = document.createElement('div');
|
|
2326
|
+
wrapper.setAttribute('style', 'padding: 15px;');
|
|
2327
|
+
|
|
2328
|
+
return wrapper
|
|
2329
|
+
}
|
|
2330
|
+
|
|
2331
|
+
createGraphFiller() {
|
|
2332
|
+
const filler = document.createElement('div');
|
|
2333
|
+
filler.setAttribute(
|
|
2334
|
+
'style',
|
|
2335
|
+
'border-radius: 7px; background-color: #eee; height: 350px; display: flex; ' +
|
|
2336
|
+
'justify-content: space-around; align-items: center; font-size: 4em;'
|
|
2337
|
+
);
|
|
2338
|
+
|
|
2339
|
+
const chartIcon = document.createElement('i');
|
|
2340
|
+
chartIcon.setAttribute('class', 'icon chart line');
|
|
2341
|
+
filler.append(chartIcon);
|
|
2342
|
+
|
|
2343
|
+
return filler
|
|
2344
|
+
}
|
|
2345
|
+
|
|
2346
|
+
addSelectOptions(select, choices, placeholder = null) {
|
|
2347
|
+
if (placeholder !== null) {
|
|
2348
|
+
const placeholderOption = document.createElement('option');
|
|
2349
|
+
placeholderOption.innerHTML = placeholder;
|
|
2350
|
+
placeholderOption.disabled = true;
|
|
2351
|
+
placeholderOption.selected = true;
|
|
2352
|
+
select.append(placeholderOption);
|
|
2353
|
+
}
|
|
2354
|
+
|
|
2355
|
+
for (const property in choices) {
|
|
2356
|
+
const choice = choices[property];
|
|
2357
|
+
|
|
2358
|
+
const channelOption = document.createElement('option');
|
|
2359
|
+
channelOption.innerHTML = choice.name;
|
|
2360
|
+
channelOption.setAttribute('value', choice.id);
|
|
2361
|
+
select.append(channelOption);
|
|
2362
|
+
}
|
|
2363
|
+
|
|
2364
|
+
return select
|
|
2365
|
+
}
|
|
2366
|
+
|
|
2367
|
+
hookClientSearchOnSelect(selectElement, searchApiEndpoint) {
|
|
2368
|
+
selectElement.setAttribute('class', `${selectElement.getAttribute('class')} search dropdown selection`);
|
|
2369
|
+
|
|
2370
|
+
$(selectElement).dropdown({
|
|
2371
|
+
apiSettings: {
|
|
2372
|
+
url: `${searchApiEndpoint}/{query}`,
|
|
2373
|
+
cache: false,
|
|
2374
|
+
},
|
|
2375
|
+
|
|
2376
|
+
minCharacters: 2,
|
|
2377
|
+
});
|
|
2378
|
+
}
|
|
2379
|
+
|
|
2380
|
+
isSubmitButtonDisabled(simulationData) {
|
|
2381
|
+
return (
|
|
2382
|
+
null === simulationData.productVariantId ||
|
|
2383
|
+
null === simulationData.channelId ||
|
|
2384
|
+
null === simulationData.currencyId ||
|
|
2385
|
+
null === simulationData.customerId
|
|
2386
|
+
)
|
|
2387
|
+
}
|
|
2388
|
+
|
|
2389
|
+
serializeObjectToQuery(object) {
|
|
2390
|
+
const query = [];
|
|
2391
|
+
|
|
2392
|
+
for (const part in object) {
|
|
2393
|
+
if (Object.prototype.hasOwnProperty.call(object, part)) {
|
|
2394
|
+
query.push(`${encodeURIComponent(part)}=${encodeURIComponent(object[part])}`);
|
|
2395
|
+
}
|
|
2396
|
+
}
|
|
2397
|
+
|
|
2398
|
+
return query.join('&')
|
|
2399
|
+
}
|
|
2400
|
+
|
|
2401
|
+
renderGraph(graphWrapper, graphData) {
|
|
2402
|
+
graphWrapper.innerHTML = '';
|
|
2403
|
+
|
|
2404
|
+
const graphCanvas = document.createElement('canvas');
|
|
2405
|
+
graphCanvas.width = 600;
|
|
2406
|
+
graphCanvas.height = 200;
|
|
2407
|
+
|
|
2408
|
+
graphWrapper.append(graphCanvas);
|
|
2409
|
+
|
|
2410
|
+
const graphConfig = this.getGraphConfig(graphData);
|
|
2411
|
+
console.log('graphConfig', graphConfig);
|
|
2412
|
+
new Chart$1(graphCanvas.getContext('2d'), graphConfig);
|
|
2413
|
+
}
|
|
2414
|
+
|
|
2415
|
+
/** @private */
|
|
2416
|
+
getGraphConfig(rawGraphData) {
|
|
2417
|
+
return {
|
|
2418
|
+
type: 'line',
|
|
2419
|
+
data: {
|
|
2420
|
+
datasets: rawGraphData.datasets.map((rawDataset) => {
|
|
2421
|
+
return {
|
|
2422
|
+
label: rawDataset.label,
|
|
2423
|
+
data: rawDataset.data,
|
|
2424
|
+
borderColor: '#0000ff',
|
|
2425
|
+
fill: false,
|
|
2426
|
+
steppedLine: true,
|
|
2427
|
+
pointRadius: 8,
|
|
2428
|
+
pointHoverRadius: 10,
|
|
2429
|
+
}
|
|
2430
|
+
}),
|
|
2431
|
+
},
|
|
2432
|
+
options: {
|
|
2433
|
+
maintainAspectRatio: true,
|
|
2434
|
+
responsive: true,
|
|
2435
|
+
scales: {
|
|
2436
|
+
xAxes: [
|
|
2437
|
+
{
|
|
2438
|
+
type: 'linear',
|
|
2439
|
+
position: 'bottom',
|
|
2440
|
+
scaleLabel: {
|
|
2441
|
+
display: true,
|
|
2442
|
+
labelString: rawGraphData.xAxisLabel,
|
|
2443
|
+
},
|
|
2444
|
+
},
|
|
2445
|
+
],
|
|
2446
|
+
yAxes: [
|
|
2447
|
+
{
|
|
2448
|
+
scaleLabel: {
|
|
2449
|
+
display: true,
|
|
2450
|
+
labelString: rawGraphData.yAxisLabel,
|
|
2451
|
+
},
|
|
2452
|
+
},
|
|
2453
|
+
],
|
|
2454
|
+
},
|
|
2455
|
+
},
|
|
2456
|
+
}
|
|
2457
|
+
}
|
|
2458
|
+
}
|
|
2459
|
+
|
|
2041
2460
|
/**
|
|
2042
2461
|
* CKEditor config
|
|
2043
2462
|
*/
|
|
@@ -2331,63 +2750,6 @@ vendorDescriptionElements.forEach((element) => {
|
|
|
2331
2750
|
|
|
2332
2751
|
})( jQuery );
|
|
2333
2752
|
|
|
2334
|
-
class CustomerGroupClientAssigner {
|
|
2335
|
-
constructor(selector, searchSelector = '.ng-client-search-select', submitSelector = '.ng-client-assign-submit') {
|
|
2336
|
-
this.selector = selector;
|
|
2337
|
-
this.searchSelector = searchSelector;
|
|
2338
|
-
this.submitSelector = submitSelector;
|
|
2339
|
-
|
|
2340
|
-
this.containerElement = null;
|
|
2341
|
-
this.searchElement = null;
|
|
2342
|
-
this.submitElement = null;
|
|
2343
|
-
}
|
|
2344
|
-
|
|
2345
|
-
init() {
|
|
2346
|
-
this.containerElement = document.querySelector(this.selector);
|
|
2347
|
-
const submitApiEndpoint = this.containerElement.getAttribute('data-assign-customers-url');
|
|
2348
|
-
const redirectAfterUrl = this.containerElement.getAttribute('data-redirect-after-url');
|
|
2349
|
-
|
|
2350
|
-
this.searchElement = this.containerElement.querySelector(this.searchSelector);
|
|
2351
|
-
const searchApiEndpoint = this.searchElement.getAttribute('data-customer-search-url');
|
|
2352
|
-
|
|
2353
|
-
$(this.searchElement).dropdown({
|
|
2354
|
-
apiSettings: {
|
|
2355
|
-
url: `${searchApiEndpoint}/{query}`,
|
|
2356
|
-
cache: false,
|
|
2357
|
-
},
|
|
2358
|
-
|
|
2359
|
-
minCharacters: 2,
|
|
2360
|
-
});
|
|
2361
|
-
|
|
2362
|
-
this.submitElement = this.containerElement.querySelector(this.submitSelector);
|
|
2363
|
-
this.submitElement.addEventListener('click', () => {
|
|
2364
|
-
const selectedCustomersIds = this.getSelectValues(this.searchElement);
|
|
2365
|
-
this.submitCustomers(submitApiEndpoint, selectedCustomersIds, redirectAfterUrl);
|
|
2366
|
-
});
|
|
2367
|
-
}
|
|
2368
|
-
|
|
2369
|
-
getSelectValues(selectElement) {
|
|
2370
|
-
const selected = selectElement.querySelectorAll('option:checked');
|
|
2371
|
-
return Array.from(selected).map((optionElement) => optionElement.value)
|
|
2372
|
-
}
|
|
2373
|
-
|
|
2374
|
-
submitCustomers(apiEndpoint, selectedIds, redirectTo) {
|
|
2375
|
-
this.submitElement.disabled = true;
|
|
2376
|
-
|
|
2377
|
-
axios
|
|
2378
|
-
.post(apiEndpoint, { customers: selectedIds })
|
|
2379
|
-
.then(() => {
|
|
2380
|
-
window.location = redirectTo;
|
|
2381
|
-
})
|
|
2382
|
-
.catch((error) => {
|
|
2383
|
-
console.error(error);
|
|
2384
|
-
})
|
|
2385
|
-
.finally(() => {
|
|
2386
|
-
this.submitElement.disabled = false;
|
|
2387
|
-
});
|
|
2388
|
-
}
|
|
2389
|
-
}
|
|
2390
|
-
|
|
2391
2753
|
// Scripts
|
|
2392
2754
|
|
|
2393
2755
|
// Components initializations
|
|
@@ -2403,20 +2765,28 @@ $(document).ready(() => {
|
|
|
2403
2765
|
*/
|
|
2404
2766
|
TooltipHelpers.init();
|
|
2405
2767
|
|
|
2406
|
-
const feedCategorySelect = new FeedCategorySelect('.ng-feed-category-select');
|
|
2407
|
-
feedCategorySelect.init();
|
|
2408
|
-
|
|
2409
2768
|
const customerGroupingRuleConfiguration = new CustomerGroupingRuleConfiguration(
|
|
2410
2769
|
'select.ng-grouping-rule-select',
|
|
2411
2770
|
'.ng-grouping-rule-configuration'
|
|
2412
2771
|
);
|
|
2413
2772
|
customerGroupingRuleConfiguration.init();
|
|
2414
2773
|
|
|
2774
|
+
const feedCategorySelect = new FeedCategorySelect('.ng-feed-category-select');
|
|
2775
|
+
feedCategorySelect.init();
|
|
2776
|
+
|
|
2415
2777
|
// Admin sidebar scroller
|
|
2416
2778
|
const adminSidebarElement = document.getElementById('sidebar');
|
|
2417
2779
|
const adminSidebarScroller = new AdminSidebarScroller(adminSidebarElement, 'a.item');
|
|
2418
2780
|
adminSidebarScroller.scrollToActiveLink();
|
|
2419
2781
|
|
|
2782
|
+
const productVariantPricingGraph = new ProductVariantPricingGraph('.ng-product-variant-pricing-graph');
|
|
2783
|
+
productVariantPricingGraph.init();
|
|
2784
|
+
|
|
2785
|
+
const productVariantPricingSimulation = new ProductVariantPricingSimulation(
|
|
2786
|
+
'.ng-product-variant-pricing-simulation'
|
|
2787
|
+
);
|
|
2788
|
+
productVariantPricingSimulation.init();
|
|
2789
|
+
|
|
2420
2790
|
// Client search select
|
|
2421
2791
|
const clientSearchSelect = new CustomerGroupClientAssigner('.ng-customer-group-client-assigner');
|
|
2422
2792
|
clientSearchSelect.init();
|
package/lib/style.css
CHANGED
|
@@ -1,3 +1,217 @@
|
|
|
1
|
+
.sylius-filters {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-wrap: wrap;
|
|
4
|
+
margin-left: -10px;
|
|
5
|
+
margin-right: -10px; }
|
|
6
|
+
.sylius-filters__field {
|
|
7
|
+
flex-grow: 1;
|
|
8
|
+
min-width: 360px;
|
|
9
|
+
margin-left: 10px;
|
|
10
|
+
margin-right: 10px; }
|
|
11
|
+
.sylius-filters .sylius-filters__group {
|
|
12
|
+
display: flex;
|
|
13
|
+
flex-wrap: wrap;
|
|
14
|
+
align-items: flex-start; }
|
|
15
|
+
.sylius-filters .sylius-filters__group > .field {
|
|
16
|
+
flex-grow: 1; }
|
|
17
|
+
.sylius-filters .sylius-filters__group > input {
|
|
18
|
+
flex-grow: 1;
|
|
19
|
+
width: auto !important; }
|
|
20
|
+
.sylius-filters .sylius-filters__group > .disabled.field {
|
|
21
|
+
flex-grow: 0; }
|
|
22
|
+
.sylius-filters .sylius-filters__group > .disabled.field input {
|
|
23
|
+
width: 40px !important;
|
|
24
|
+
background: #eeeeee;
|
|
25
|
+
text-align: center; }
|
|
26
|
+
.sylius-filters .field {
|
|
27
|
+
margin-bottom: 22px !important; }
|
|
28
|
+
.sylius-filters .field label {
|
|
29
|
+
font-weight: 700 !important; }
|
|
30
|
+
|
|
31
|
+
.sylius-filters select {
|
|
32
|
+
-webkit-appearance: none;
|
|
33
|
+
-moz-appearance: none;
|
|
34
|
+
appearance: none;
|
|
35
|
+
background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' fill='%23444444'><polygon points='0,0 100,0 50,50'/></svg>") no-repeat !important;
|
|
36
|
+
background-size: 8px 12px !important;
|
|
37
|
+
background-position: calc(100% - 10px) calc(50% + 3px) !important; }
|
|
38
|
+
|
|
39
|
+
.sylius-filters .sylius-filters__group input, .sylius-filters .sylius-filters__group select {
|
|
40
|
+
border-radius: 0 !important;
|
|
41
|
+
border-right-width: 0 !important; }
|
|
42
|
+
|
|
43
|
+
.sylius-filters .sylius-filters__group .field:last-child input:last-child,
|
|
44
|
+
.sylius-filters .sylius-filters__group .field:last-child select:last-child {
|
|
45
|
+
border-right-width: 1px !important;
|
|
46
|
+
border-radius: 0 .28571429rem .28571429rem 0 !important; }
|
|
47
|
+
|
|
48
|
+
.sylius-filters .sylius-filters__group .field:first-child input:first-of-type,
|
|
49
|
+
.sylius-filters .sylius-filters__group .field:first-child select:first-of-type {
|
|
50
|
+
border-radius: .28571429rem 0 0 .28571429rem !important; }
|
|
51
|
+
|
|
52
|
+
.overflow-x-auto {
|
|
53
|
+
overflow-x: auto; }
|
|
54
|
+
|
|
55
|
+
#wrapper {
|
|
56
|
+
padding: 54px 0 0 0; }
|
|
57
|
+
|
|
58
|
+
#content {
|
|
59
|
+
padding: 1em; }
|
|
60
|
+
|
|
61
|
+
#sidebar {
|
|
62
|
+
font-size: 1.1em;
|
|
63
|
+
padding-bottom: 30px; }
|
|
64
|
+
|
|
65
|
+
#logo {
|
|
66
|
+
margin-bottom: 1em; }
|
|
67
|
+
|
|
68
|
+
body.pushable .pusher {
|
|
69
|
+
background-color: #f9fAfb; }
|
|
70
|
+
|
|
71
|
+
.ui.visible.left.sidebar ~ .fixed.menu,
|
|
72
|
+
.ui.visible.left.sidebar ~ .pusher {
|
|
73
|
+
padding-right: 260px; }
|
|
74
|
+
|
|
75
|
+
body.centered {
|
|
76
|
+
background-color: #f9fAfb; }
|
|
77
|
+
body.centered .grid {
|
|
78
|
+
height: 100%; }
|
|
79
|
+
body.centered .column {
|
|
80
|
+
padding: 1em;
|
|
81
|
+
max-width: 450px; }
|
|
82
|
+
|
|
83
|
+
select.ui.dropdown[multiple="multiple"] {
|
|
84
|
+
height: 100px; }
|
|
85
|
+
|
|
86
|
+
.ui.segments {
|
|
87
|
+
border: 0; }
|
|
88
|
+
.ui.segments .ui.segment {
|
|
89
|
+
border: 1px solid rgba(34, 36, 38, 0.15) !important; }
|
|
90
|
+
|
|
91
|
+
.ui.breadcrumb {
|
|
92
|
+
margin-top: 1em;
|
|
93
|
+
margin-left: 1em;
|
|
94
|
+
margin-bottom: 1em; }
|
|
95
|
+
|
|
96
|
+
th a {
|
|
97
|
+
color: rgba(0, 0, 0, 0.87); }
|
|
98
|
+
|
|
99
|
+
th a:hover {
|
|
100
|
+
color: rgba(0, 0, 0, 0.87); }
|
|
101
|
+
|
|
102
|
+
th a:visited {
|
|
103
|
+
color: rgba(0, 0, 0, 0.87); }
|
|
104
|
+
|
|
105
|
+
.ui.compact.segment .inline.fields {
|
|
106
|
+
margin: 0; }
|
|
107
|
+
|
|
108
|
+
.ui.hidden.element {
|
|
109
|
+
display: none; }
|
|
110
|
+
|
|
111
|
+
.ui.monster.header {
|
|
112
|
+
font-size: 3em; }
|
|
113
|
+
|
|
114
|
+
.ui.styled.header {
|
|
115
|
+
text-transform: uppercase;
|
|
116
|
+
letter-spacing: 1px;
|
|
117
|
+
background-color: #f9fAfb;
|
|
118
|
+
font-size: 0.9em;
|
|
119
|
+
padding-bottom: 7px; }
|
|
120
|
+
|
|
121
|
+
.ui.input input[readonly] {
|
|
122
|
+
color: #aaa; }
|
|
123
|
+
|
|
124
|
+
.field.loading.transition {
|
|
125
|
+
top: auto;
|
|
126
|
+
left: auto; }
|
|
127
|
+
|
|
128
|
+
.ui.floated.dividing.empty {
|
|
129
|
+
top: 100%;
|
|
130
|
+
bottom: auto;
|
|
131
|
+
padding: 0;
|
|
132
|
+
margin: 0; }
|
|
133
|
+
|
|
134
|
+
.ui.left.floated.dividing.empty ~ .ui.dropdown > .menu {
|
|
135
|
+
right: auto;
|
|
136
|
+
left: 0; }
|
|
137
|
+
|
|
138
|
+
.ui.right.floated.dividing.empty ~ .ui.dropdown > .menu {
|
|
139
|
+
right: 0;
|
|
140
|
+
left: auto; }
|
|
141
|
+
|
|
142
|
+
.sylius-grid-wrapper .sylius-grid-nav .sylius-grid-nav__bulk,
|
|
143
|
+
.sylius-grid-wrapper .sylius-grid-nav .sylius-grid-nav__pagination,
|
|
144
|
+
.sylius-grid-wrapper .sylius-grid-nav .sylius-grid-nav__perpage {
|
|
145
|
+
padding-bottom: 1rem; }
|
|
146
|
+
|
|
147
|
+
.sylius-grid-wrapper .sylius-grid-nav__bulk .ui.red.labeled.icon.button:disabled {
|
|
148
|
+
background: #b9babb !important; }
|
|
149
|
+
|
|
150
|
+
.sylius-grid-wrapper .sylius-grid-table-wrapper {
|
|
151
|
+
overflow-x: auto;
|
|
152
|
+
margin-bottom: 1rem; }
|
|
153
|
+
.sylius-grid-wrapper .sylius-grid-table-wrapper .ui.buttons, .sylius-grid-wrapper .sylius-grid-table-wrapper .ui.label {
|
|
154
|
+
white-space: nowrap; }
|
|
155
|
+
|
|
156
|
+
@media only screen and (min-width: 768px) {
|
|
157
|
+
.sylius-grid-wrapper .sylius-grid-nav {
|
|
158
|
+
display: flex;
|
|
159
|
+
flex-wrap: wrap;
|
|
160
|
+
margin-left: -1rem;
|
|
161
|
+
margin-right: -1rem; }
|
|
162
|
+
.sylius-grid-wrapper .sylius-grid-nav .sylius-grid-nav__bulk,
|
|
163
|
+
.sylius-grid-wrapper .sylius-grid-nav .sylius-grid-nav__pagination,
|
|
164
|
+
.sylius-grid-wrapper .sylius-grid-nav .sylius-grid-nav__perpage {
|
|
165
|
+
padding-left: 1rem;
|
|
166
|
+
padding-right: 1rem; }
|
|
167
|
+
.sylius-grid-wrapper .sylius-grid-nav .sylius-grid-nav__bulk {
|
|
168
|
+
display: flex; }
|
|
169
|
+
.sylius-grid-wrapper .sylius-grid-nav .sylius-grid-nav__bulk .button {
|
|
170
|
+
padding-top: 0.99em !important;
|
|
171
|
+
padding-bottom: 0.99em !important; }
|
|
172
|
+
.sylius-grid-wrapper .sylius-grid-nav .sylius-grid-nav__pagination {
|
|
173
|
+
flex-grow: 1; }
|
|
174
|
+
.sylius-grid-wrapper .pagination {
|
|
175
|
+
flex-wrap: wrap; } }
|
|
176
|
+
|
|
177
|
+
#wrapper.full.height {
|
|
178
|
+
position: relative;
|
|
179
|
+
padding-bottom: 80px !important;
|
|
180
|
+
min-height: 100vh; }
|
|
181
|
+
#wrapper.full.height::after {
|
|
182
|
+
content: '';
|
|
183
|
+
display: block;
|
|
184
|
+
position: absolute;
|
|
185
|
+
bottom: 60px;
|
|
186
|
+
right: 30px;
|
|
187
|
+
width: calc(100% - 60px);
|
|
188
|
+
height: 1px;
|
|
189
|
+
background: #ebebeb; }
|
|
190
|
+
#wrapper.full.height .sylius-footer {
|
|
191
|
+
position: absolute;
|
|
192
|
+
bottom: 20px;
|
|
193
|
+
right: 40px;
|
|
194
|
+
font-size: 13px;
|
|
195
|
+
color: #9a9a9a; }
|
|
196
|
+
|
|
197
|
+
input[type="color"] {
|
|
198
|
+
-webkit-appearance: none;
|
|
199
|
+
border: 1px solid rgba(34, 36, 38, 0.15);
|
|
200
|
+
width: 38px;
|
|
201
|
+
height: 38px;
|
|
202
|
+
padding: 3px;
|
|
203
|
+
border-radius: 99px; }
|
|
204
|
+
|
|
205
|
+
input[type="color"]::-webkit-color-swatch,
|
|
206
|
+
input[type="color"]::-webkit-color-swatch-wrapper {
|
|
207
|
+
border-radius: 99px;
|
|
208
|
+
border: 0;
|
|
209
|
+
padding: 3px; }
|
|
210
|
+
|
|
211
|
+
input[type="color"]::-moz-color-swatch {
|
|
212
|
+
border-radius: 99px;
|
|
213
|
+
border: 0; }
|
|
214
|
+
|
|
1
215
|
.sylius-tree.hidden {
|
|
2
216
|
display: none; }
|
|
3
217
|
|
|
@@ -301,217 +515,3 @@ a {
|
|
|
301
515
|
|
|
302
516
|
.promotion-disabled {
|
|
303
517
|
color: #a0a0a0; }
|
|
304
|
-
|
|
305
|
-
.sylius-filters {
|
|
306
|
-
display: flex;
|
|
307
|
-
flex-wrap: wrap;
|
|
308
|
-
margin-left: -10px;
|
|
309
|
-
margin-right: -10px; }
|
|
310
|
-
.sylius-filters__field {
|
|
311
|
-
flex-grow: 1;
|
|
312
|
-
min-width: 360px;
|
|
313
|
-
margin-left: 10px;
|
|
314
|
-
margin-right: 10px; }
|
|
315
|
-
.sylius-filters .sylius-filters__group {
|
|
316
|
-
display: flex;
|
|
317
|
-
flex-wrap: wrap;
|
|
318
|
-
align-items: flex-start; }
|
|
319
|
-
.sylius-filters .sylius-filters__group > .field {
|
|
320
|
-
flex-grow: 1; }
|
|
321
|
-
.sylius-filters .sylius-filters__group > input {
|
|
322
|
-
flex-grow: 1;
|
|
323
|
-
width: auto !important; }
|
|
324
|
-
.sylius-filters .sylius-filters__group > .disabled.field {
|
|
325
|
-
flex-grow: 0; }
|
|
326
|
-
.sylius-filters .sylius-filters__group > .disabled.field input {
|
|
327
|
-
width: 40px !important;
|
|
328
|
-
background: #eeeeee;
|
|
329
|
-
text-align: center; }
|
|
330
|
-
.sylius-filters .field {
|
|
331
|
-
margin-bottom: 22px !important; }
|
|
332
|
-
.sylius-filters .field label {
|
|
333
|
-
font-weight: 700 !important; }
|
|
334
|
-
|
|
335
|
-
.sylius-filters select {
|
|
336
|
-
-webkit-appearance: none;
|
|
337
|
-
-moz-appearance: none;
|
|
338
|
-
appearance: none;
|
|
339
|
-
background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='100' height='100' fill='%23444444'><polygon points='0,0 100,0 50,50'/></svg>") no-repeat !important;
|
|
340
|
-
background-size: 8px 12px !important;
|
|
341
|
-
background-position: calc(100% - 10px) calc(50% + 3px) !important; }
|
|
342
|
-
|
|
343
|
-
.sylius-filters .sylius-filters__group input, .sylius-filters .sylius-filters__group select {
|
|
344
|
-
border-radius: 0 !important;
|
|
345
|
-
border-right-width: 0 !important; }
|
|
346
|
-
|
|
347
|
-
.sylius-filters .sylius-filters__group .field:last-child input:last-child,
|
|
348
|
-
.sylius-filters .sylius-filters__group .field:last-child select:last-child {
|
|
349
|
-
border-right-width: 1px !important;
|
|
350
|
-
border-radius: 0 .28571429rem .28571429rem 0 !important; }
|
|
351
|
-
|
|
352
|
-
.sylius-filters .sylius-filters__group .field:first-child input:first-of-type,
|
|
353
|
-
.sylius-filters .sylius-filters__group .field:first-child select:first-of-type {
|
|
354
|
-
border-radius: .28571429rem 0 0 .28571429rem !important; }
|
|
355
|
-
|
|
356
|
-
.overflow-x-auto {
|
|
357
|
-
overflow-x: auto; }
|
|
358
|
-
|
|
359
|
-
#wrapper {
|
|
360
|
-
padding: 54px 0 0 0; }
|
|
361
|
-
|
|
362
|
-
#content {
|
|
363
|
-
padding: 1em; }
|
|
364
|
-
|
|
365
|
-
#sidebar {
|
|
366
|
-
font-size: 1.1em;
|
|
367
|
-
padding-bottom: 30px; }
|
|
368
|
-
|
|
369
|
-
#logo {
|
|
370
|
-
margin-bottom: 1em; }
|
|
371
|
-
|
|
372
|
-
body.pushable .pusher {
|
|
373
|
-
background-color: #f9fAfb; }
|
|
374
|
-
|
|
375
|
-
.ui.visible.left.sidebar ~ .fixed.menu,
|
|
376
|
-
.ui.visible.left.sidebar ~ .pusher {
|
|
377
|
-
padding-right: 260px; }
|
|
378
|
-
|
|
379
|
-
body.centered {
|
|
380
|
-
background-color: #f9fAfb; }
|
|
381
|
-
body.centered .grid {
|
|
382
|
-
height: 100%; }
|
|
383
|
-
body.centered .column {
|
|
384
|
-
padding: 1em;
|
|
385
|
-
max-width: 450px; }
|
|
386
|
-
|
|
387
|
-
select.ui.dropdown[multiple="multiple"] {
|
|
388
|
-
height: 100px; }
|
|
389
|
-
|
|
390
|
-
.ui.segments {
|
|
391
|
-
border: 0; }
|
|
392
|
-
.ui.segments .ui.segment {
|
|
393
|
-
border: 1px solid rgba(34, 36, 38, 0.15) !important; }
|
|
394
|
-
|
|
395
|
-
.ui.breadcrumb {
|
|
396
|
-
margin-top: 1em;
|
|
397
|
-
margin-left: 1em;
|
|
398
|
-
margin-bottom: 1em; }
|
|
399
|
-
|
|
400
|
-
th a {
|
|
401
|
-
color: rgba(0, 0, 0, 0.87); }
|
|
402
|
-
|
|
403
|
-
th a:hover {
|
|
404
|
-
color: rgba(0, 0, 0, 0.87); }
|
|
405
|
-
|
|
406
|
-
th a:visited {
|
|
407
|
-
color: rgba(0, 0, 0, 0.87); }
|
|
408
|
-
|
|
409
|
-
.ui.compact.segment .inline.fields {
|
|
410
|
-
margin: 0; }
|
|
411
|
-
|
|
412
|
-
.ui.hidden.element {
|
|
413
|
-
display: none; }
|
|
414
|
-
|
|
415
|
-
.ui.monster.header {
|
|
416
|
-
font-size: 3em; }
|
|
417
|
-
|
|
418
|
-
.ui.styled.header {
|
|
419
|
-
text-transform: uppercase;
|
|
420
|
-
letter-spacing: 1px;
|
|
421
|
-
background-color: #f9fAfb;
|
|
422
|
-
font-size: 0.9em;
|
|
423
|
-
padding-bottom: 7px; }
|
|
424
|
-
|
|
425
|
-
.ui.input input[readonly] {
|
|
426
|
-
color: #aaa; }
|
|
427
|
-
|
|
428
|
-
.field.loading.transition {
|
|
429
|
-
top: auto;
|
|
430
|
-
left: auto; }
|
|
431
|
-
|
|
432
|
-
.ui.floated.dividing.empty {
|
|
433
|
-
top: 100%;
|
|
434
|
-
bottom: auto;
|
|
435
|
-
padding: 0;
|
|
436
|
-
margin: 0; }
|
|
437
|
-
|
|
438
|
-
.ui.left.floated.dividing.empty ~ .ui.dropdown > .menu {
|
|
439
|
-
right: auto;
|
|
440
|
-
left: 0; }
|
|
441
|
-
|
|
442
|
-
.ui.right.floated.dividing.empty ~ .ui.dropdown > .menu {
|
|
443
|
-
right: 0;
|
|
444
|
-
left: auto; }
|
|
445
|
-
|
|
446
|
-
.sylius-grid-wrapper .sylius-grid-nav .sylius-grid-nav__bulk,
|
|
447
|
-
.sylius-grid-wrapper .sylius-grid-nav .sylius-grid-nav__pagination,
|
|
448
|
-
.sylius-grid-wrapper .sylius-grid-nav .sylius-grid-nav__perpage {
|
|
449
|
-
padding-bottom: 1rem; }
|
|
450
|
-
|
|
451
|
-
.sylius-grid-wrapper .sylius-grid-nav__bulk .ui.red.labeled.icon.button:disabled {
|
|
452
|
-
background: #b9babb !important; }
|
|
453
|
-
|
|
454
|
-
.sylius-grid-wrapper .sylius-grid-table-wrapper {
|
|
455
|
-
overflow-x: auto;
|
|
456
|
-
margin-bottom: 1rem; }
|
|
457
|
-
.sylius-grid-wrapper .sylius-grid-table-wrapper .ui.buttons, .sylius-grid-wrapper .sylius-grid-table-wrapper .ui.label {
|
|
458
|
-
white-space: nowrap; }
|
|
459
|
-
|
|
460
|
-
@media only screen and (min-width: 768px) {
|
|
461
|
-
.sylius-grid-wrapper .sylius-grid-nav {
|
|
462
|
-
display: flex;
|
|
463
|
-
flex-wrap: wrap;
|
|
464
|
-
margin-left: -1rem;
|
|
465
|
-
margin-right: -1rem; }
|
|
466
|
-
.sylius-grid-wrapper .sylius-grid-nav .sylius-grid-nav__bulk,
|
|
467
|
-
.sylius-grid-wrapper .sylius-grid-nav .sylius-grid-nav__pagination,
|
|
468
|
-
.sylius-grid-wrapper .sylius-grid-nav .sylius-grid-nav__perpage {
|
|
469
|
-
padding-left: 1rem;
|
|
470
|
-
padding-right: 1rem; }
|
|
471
|
-
.sylius-grid-wrapper .sylius-grid-nav .sylius-grid-nav__bulk {
|
|
472
|
-
display: flex; }
|
|
473
|
-
.sylius-grid-wrapper .sylius-grid-nav .sylius-grid-nav__bulk .button {
|
|
474
|
-
padding-top: 0.99em !important;
|
|
475
|
-
padding-bottom: 0.99em !important; }
|
|
476
|
-
.sylius-grid-wrapper .sylius-grid-nav .sylius-grid-nav__pagination {
|
|
477
|
-
flex-grow: 1; }
|
|
478
|
-
.sylius-grid-wrapper .pagination {
|
|
479
|
-
flex-wrap: wrap; } }
|
|
480
|
-
|
|
481
|
-
#wrapper.full.height {
|
|
482
|
-
position: relative;
|
|
483
|
-
padding-bottom: 80px !important;
|
|
484
|
-
min-height: 100vh; }
|
|
485
|
-
#wrapper.full.height::after {
|
|
486
|
-
content: '';
|
|
487
|
-
display: block;
|
|
488
|
-
position: absolute;
|
|
489
|
-
bottom: 60px;
|
|
490
|
-
right: 30px;
|
|
491
|
-
width: calc(100% - 60px);
|
|
492
|
-
height: 1px;
|
|
493
|
-
background: #ebebeb; }
|
|
494
|
-
#wrapper.full.height .sylius-footer {
|
|
495
|
-
position: absolute;
|
|
496
|
-
bottom: 20px;
|
|
497
|
-
right: 40px;
|
|
498
|
-
font-size: 13px;
|
|
499
|
-
color: #9a9a9a; }
|
|
500
|
-
|
|
501
|
-
input[type="color"] {
|
|
502
|
-
-webkit-appearance: none;
|
|
503
|
-
border: 1px solid rgba(34, 36, 38, 0.15);
|
|
504
|
-
width: 38px;
|
|
505
|
-
height: 38px;
|
|
506
|
-
padding: 3px;
|
|
507
|
-
border-radius: 99px; }
|
|
508
|
-
|
|
509
|
-
input[type="color"]::-webkit-color-swatch,
|
|
510
|
-
input[type="color"]::-webkit-color-swatch-wrapper {
|
|
511
|
-
border-radius: 99px;
|
|
512
|
-
border: 0;
|
|
513
|
-
padding: 3px; }
|
|
514
|
-
|
|
515
|
-
input[type="color"]::-moz-color-swatch {
|
|
516
|
-
border-radius: 99px;
|
|
517
|
-
border: 0; }
|
package/package.json
CHANGED
|
@@ -13,6 +13,10 @@ export default class CustomerGroupClientAssigner {
|
|
|
13
13
|
|
|
14
14
|
init() {
|
|
15
15
|
this.containerElement = document.querySelector(this.selector)
|
|
16
|
+
if (null === this.containerElement) {
|
|
17
|
+
return
|
|
18
|
+
}
|
|
19
|
+
|
|
16
20
|
const submitApiEndpoint = this.containerElement.getAttribute('data-assign-customers-url')
|
|
17
21
|
const redirectAfterUrl = this.containerElement.getAttribute('data-redirect-after-url')
|
|
18
22
|
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import Chart from 'chart.js'
|
|
2
|
+
|
|
3
|
+
export default class ProductVariantPricingGraph {
|
|
4
|
+
constructor(containerSelector) {
|
|
5
|
+
this.containerSelector = containerSelector
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
init() {
|
|
9
|
+
document.querySelectorAll(this.containerSelector).forEach((componentContainer) => {
|
|
10
|
+
const graphsData = JSON.parse(componentContainer.getAttribute('data-graph'))
|
|
11
|
+
|
|
12
|
+
for (const currencyGraphIndex in graphsData) {
|
|
13
|
+
const currencyGraph = graphsData[currencyGraphIndex]
|
|
14
|
+
|
|
15
|
+
const currencyCodeHeader = document.createElement('h4')
|
|
16
|
+
currencyCodeHeader.classList.add('ui', 'header')
|
|
17
|
+
currencyCodeHeader.textContent = currencyGraph.currency
|
|
18
|
+
|
|
19
|
+
const graphCanvas = document.createElement('canvas')
|
|
20
|
+
graphCanvas.width = 400
|
|
21
|
+
graphCanvas.height = 200
|
|
22
|
+
|
|
23
|
+
const graphContainer = document.createElement('div')
|
|
24
|
+
graphContainer.append(currencyCodeHeader)
|
|
25
|
+
graphContainer.append(graphCanvas)
|
|
26
|
+
|
|
27
|
+
componentContainer.append(graphContainer)
|
|
28
|
+
|
|
29
|
+
const graphConfig = this.getGraphConfig(currencyGraph.graph)
|
|
30
|
+
new Chart(graphCanvas.getContext('2d'), graphConfig)
|
|
31
|
+
}
|
|
32
|
+
})
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** @private */
|
|
36
|
+
getGraphConfig(rawGraphData) {
|
|
37
|
+
return {
|
|
38
|
+
type: 'line',
|
|
39
|
+
data: {
|
|
40
|
+
datasets: rawGraphData.datasets.map((rawDataset) => {
|
|
41
|
+
return {
|
|
42
|
+
label: rawDataset.label,
|
|
43
|
+
data: rawDataset.data,
|
|
44
|
+
borderColor: this.getRandomRgbColor(),
|
|
45
|
+
fill: false,
|
|
46
|
+
steppedLine: true,
|
|
47
|
+
pointRadius: 8,
|
|
48
|
+
pointHoverRadius: 10,
|
|
49
|
+
}
|
|
50
|
+
}),
|
|
51
|
+
},
|
|
52
|
+
options: {
|
|
53
|
+
maintainAspectRatio: true,
|
|
54
|
+
responsive: true,
|
|
55
|
+
scales: {
|
|
56
|
+
xAxes: [
|
|
57
|
+
{
|
|
58
|
+
type: 'linear',
|
|
59
|
+
position: 'bottom',
|
|
60
|
+
scaleLabel: {
|
|
61
|
+
display: true,
|
|
62
|
+
labelString: rawGraphData.xAxisLabel,
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
yAxes: [
|
|
67
|
+
{
|
|
68
|
+
scaleLabel: {
|
|
69
|
+
display: true,
|
|
70
|
+
labelString: rawGraphData.yAxisLabel,
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** @private */
|
|
80
|
+
getRandomRgbColor() {
|
|
81
|
+
const r = Math.floor(Math.random() * 255)
|
|
82
|
+
const g = Math.floor(Math.random() * 255)
|
|
83
|
+
const b = Math.floor(Math.random() * 255)
|
|
84
|
+
return `rgb(${r},${g},${b})`
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import axios from 'axios'
|
|
2
|
+
import Chart from 'chart.js'
|
|
3
|
+
|
|
4
|
+
export default class ProductVariantPricingSimulation {
|
|
5
|
+
constructor(selector) {
|
|
6
|
+
this.selector = selector
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
init() {
|
|
10
|
+
document.querySelectorAll(this.selector).forEach((element) => {
|
|
11
|
+
const productVariantId = element.getAttribute('data-product-variant-id')
|
|
12
|
+
const channels = JSON.parse(element.getAttribute('data-channels'))
|
|
13
|
+
const searchApiEndpoint = element.getAttribute('data-customer-search-url')
|
|
14
|
+
const pricingApiEndpoint = element.getAttribute('data-pricing-url')
|
|
15
|
+
|
|
16
|
+
this.initElement(element, productVariantId, channels, searchApiEndpoint, pricingApiEndpoint)
|
|
17
|
+
})
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
initElement(parentElement, productVariantId, channels, searchApiEndpoint, pricingApiEndpoint) {
|
|
21
|
+
parentElement.innerHTML = ''
|
|
22
|
+
|
|
23
|
+
const simulationData = {
|
|
24
|
+
productVariantId: productVariantId,
|
|
25
|
+
channelId: null,
|
|
26
|
+
currencyId: null,
|
|
27
|
+
customerId: null,
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const submitButton = document.createElement('button')
|
|
31
|
+
const currencySelect = document.createElement('select')
|
|
32
|
+
|
|
33
|
+
const onChannelSelect = (event) => {
|
|
34
|
+
const selectedChannelId = parseInt(event.target.value)
|
|
35
|
+
simulationData.channelId = selectedChannelId
|
|
36
|
+
simulationData.currencyId = null
|
|
37
|
+
submitButton.disabled = this.isSubmitButtonDisabled(simulationData)
|
|
38
|
+
|
|
39
|
+
const selectedChannel = channels.find((channel) => {
|
|
40
|
+
return channel.id === selectedChannelId
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
currencySelect.innerHTML = ''
|
|
44
|
+
this.addSelectOptions(currencySelect, selectedChannel.currencies, 'Select currency')
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const onCurrencySelect = (event) => {
|
|
48
|
+
simulationData.currencyId = event.target.value
|
|
49
|
+
submitButton.disabled = this.isSubmitButtonDisabled(simulationData)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const onCustomerSelect = (event) => {
|
|
53
|
+
simulationData.customerId = event.target.value
|
|
54
|
+
submitButton.disabled = this.isSubmitButtonDisabled(simulationData)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const graphWrapper = this.createGraphWrapper()
|
|
58
|
+
|
|
59
|
+
const onSubmit = () => {
|
|
60
|
+
const pricingUrl = `${pricingApiEndpoint}?${this.serializeObjectToQuery(simulationData)}`
|
|
61
|
+
|
|
62
|
+
axios
|
|
63
|
+
.get(pricingUrl)
|
|
64
|
+
.then((response) => {
|
|
65
|
+
const chartData = response.data
|
|
66
|
+
graphWrapper.setAttribute('data-debug-chart', JSON.stringify(chartData)) // For e2e tests
|
|
67
|
+
this.renderGraph(graphWrapper, chartData)
|
|
68
|
+
})
|
|
69
|
+
.catch((error) => {
|
|
70
|
+
console.error(error)
|
|
71
|
+
graphWrapper.innerHTML = 'Pricing simulation error'
|
|
72
|
+
})
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const wrapper = document.createElement('div')
|
|
76
|
+
wrapper.setAttribute('style', 'border: solid 1px #ddd; background-color: #fafafa;')
|
|
77
|
+
|
|
78
|
+
const filters = this.createFilters(
|
|
79
|
+
channels,
|
|
80
|
+
currencySelect,
|
|
81
|
+
onChannelSelect,
|
|
82
|
+
onCurrencySelect,
|
|
83
|
+
onCustomerSelect,
|
|
84
|
+
onSubmit,
|
|
85
|
+
submitButton,
|
|
86
|
+
searchApiEndpoint
|
|
87
|
+
)
|
|
88
|
+
filters.setAttribute(
|
|
89
|
+
'style',
|
|
90
|
+
'display: grid; grid-template-columns: 1fr 1fr 1fr 60px; grid-gap: 10px; ' +
|
|
91
|
+
'padding: 15px; border-bottom: solid 1px #ddd;'
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
const graphFiller = this.createGraphFiller()
|
|
95
|
+
graphWrapper.append(graphFiller)
|
|
96
|
+
|
|
97
|
+
wrapper.append(filters, graphWrapper)
|
|
98
|
+
parentElement.append(wrapper)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
createFilters(
|
|
102
|
+
channels,
|
|
103
|
+
currencySelect,
|
|
104
|
+
onChannelSelect,
|
|
105
|
+
onCurrencySelect,
|
|
106
|
+
onCustomerSelect,
|
|
107
|
+
onSubmit,
|
|
108
|
+
submitButton,
|
|
109
|
+
searchApiEndpoint
|
|
110
|
+
) {
|
|
111
|
+
const filtersWrapper = document.createElement('div')
|
|
112
|
+
|
|
113
|
+
const channelSelect = document.createElement('select')
|
|
114
|
+
this.addSelectOptions(channelSelect, channels, 'Select channel')
|
|
115
|
+
channelSelect.addEventListener('change', onChannelSelect)
|
|
116
|
+
|
|
117
|
+
currencySelect.addEventListener('change', onCurrencySelect)
|
|
118
|
+
|
|
119
|
+
const customerSelect = document.createElement('select')
|
|
120
|
+
customerSelect.addEventListener('change', onCustomerSelect)
|
|
121
|
+
|
|
122
|
+
// this is delayed to avoid racing conditions
|
|
123
|
+
setTimeout(() => this.hookClientSearchOnSelect(customerSelect, searchApiEndpoint), 600)
|
|
124
|
+
|
|
125
|
+
submitButton.disabled = true
|
|
126
|
+
submitButton.setAttribute('class', 'ui icon primary button')
|
|
127
|
+
submitButton.type = 'button'
|
|
128
|
+
submitButton.addEventListener('click', onSubmit)
|
|
129
|
+
|
|
130
|
+
const playIcon = document.createElement('i')
|
|
131
|
+
playIcon.setAttribute('class', 'icon play')
|
|
132
|
+
submitButton.append(playIcon)
|
|
133
|
+
|
|
134
|
+
filtersWrapper.append(channelSelect, currencySelect, customerSelect, submitButton)
|
|
135
|
+
|
|
136
|
+
return filtersWrapper
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
createGraphWrapper() {
|
|
140
|
+
const wrapper = document.createElement('div')
|
|
141
|
+
wrapper.setAttribute('style', 'padding: 15px;')
|
|
142
|
+
|
|
143
|
+
return wrapper
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
createGraphFiller() {
|
|
147
|
+
const filler = document.createElement('div')
|
|
148
|
+
filler.setAttribute(
|
|
149
|
+
'style',
|
|
150
|
+
'border-radius: 7px; background-color: #eee; height: 350px; display: flex; ' +
|
|
151
|
+
'justify-content: space-around; align-items: center; font-size: 4em;'
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
const chartIcon = document.createElement('i')
|
|
155
|
+
chartIcon.setAttribute('class', 'icon chart line')
|
|
156
|
+
filler.append(chartIcon)
|
|
157
|
+
|
|
158
|
+
return filler
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
addSelectOptions(select, choices, placeholder = null) {
|
|
162
|
+
if (placeholder !== null) {
|
|
163
|
+
const placeholderOption = document.createElement('option')
|
|
164
|
+
placeholderOption.innerHTML = placeholder
|
|
165
|
+
placeholderOption.disabled = true
|
|
166
|
+
placeholderOption.selected = true
|
|
167
|
+
select.append(placeholderOption)
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
for (const property in choices) {
|
|
171
|
+
const choice = choices[property]
|
|
172
|
+
|
|
173
|
+
const channelOption = document.createElement('option')
|
|
174
|
+
channelOption.innerHTML = choice.name
|
|
175
|
+
channelOption.setAttribute('value', choice.id)
|
|
176
|
+
select.append(channelOption)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return select
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
hookClientSearchOnSelect(selectElement, searchApiEndpoint) {
|
|
183
|
+
selectElement.setAttribute('class', `${selectElement.getAttribute('class')} search dropdown selection`)
|
|
184
|
+
|
|
185
|
+
$(selectElement).dropdown({
|
|
186
|
+
apiSettings: {
|
|
187
|
+
url: `${searchApiEndpoint}/{query}`,
|
|
188
|
+
cache: false,
|
|
189
|
+
},
|
|
190
|
+
|
|
191
|
+
minCharacters: 2,
|
|
192
|
+
})
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
isSubmitButtonDisabled(simulationData) {
|
|
196
|
+
return (
|
|
197
|
+
null === simulationData.productVariantId ||
|
|
198
|
+
null === simulationData.channelId ||
|
|
199
|
+
null === simulationData.currencyId ||
|
|
200
|
+
null === simulationData.customerId
|
|
201
|
+
)
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
serializeObjectToQuery(object) {
|
|
205
|
+
const query = []
|
|
206
|
+
|
|
207
|
+
for (const part in object) {
|
|
208
|
+
if (Object.prototype.hasOwnProperty.call(object, part)) {
|
|
209
|
+
query.push(`${encodeURIComponent(part)}=${encodeURIComponent(object[part])}`)
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
return query.join('&')
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
renderGraph(graphWrapper, graphData) {
|
|
217
|
+
graphWrapper.innerHTML = ''
|
|
218
|
+
|
|
219
|
+
const graphCanvas = document.createElement('canvas')
|
|
220
|
+
graphCanvas.width = 600
|
|
221
|
+
graphCanvas.height = 200
|
|
222
|
+
|
|
223
|
+
graphWrapper.append(graphCanvas)
|
|
224
|
+
|
|
225
|
+
const graphConfig = this.getGraphConfig(graphData)
|
|
226
|
+
console.log('graphConfig', graphConfig)
|
|
227
|
+
new Chart(graphCanvas.getContext('2d'), graphConfig)
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/** @private */
|
|
231
|
+
getGraphConfig(rawGraphData) {
|
|
232
|
+
return {
|
|
233
|
+
type: 'line',
|
|
234
|
+
data: {
|
|
235
|
+
datasets: rawGraphData.datasets.map((rawDataset) => {
|
|
236
|
+
return {
|
|
237
|
+
label: rawDataset.label,
|
|
238
|
+
data: rawDataset.data,
|
|
239
|
+
borderColor: '#0000ff',
|
|
240
|
+
fill: false,
|
|
241
|
+
steppedLine: true,
|
|
242
|
+
pointRadius: 8,
|
|
243
|
+
pointHoverRadius: 10,
|
|
244
|
+
}
|
|
245
|
+
}),
|
|
246
|
+
},
|
|
247
|
+
options: {
|
|
248
|
+
maintainAspectRatio: true,
|
|
249
|
+
responsive: true,
|
|
250
|
+
scales: {
|
|
251
|
+
xAxes: [
|
|
252
|
+
{
|
|
253
|
+
type: 'linear',
|
|
254
|
+
position: 'bottom',
|
|
255
|
+
scaleLabel: {
|
|
256
|
+
display: true,
|
|
257
|
+
labelString: rawGraphData.xAxisLabel,
|
|
258
|
+
},
|
|
259
|
+
},
|
|
260
|
+
],
|
|
261
|
+
yAxes: [
|
|
262
|
+
{
|
|
263
|
+
scaleLabel: {
|
|
264
|
+
display: true,
|
|
265
|
+
labelString: rawGraphData.yAxisLabel,
|
|
266
|
+
},
|
|
267
|
+
},
|
|
268
|
+
],
|
|
269
|
+
},
|
|
270
|
+
},
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
package/src/index.js
CHANGED
|
@@ -7,9 +7,12 @@ import 'sylius-bundle/AdminBundle/Resources/private/js/app'
|
|
|
7
7
|
// Scripts - components
|
|
8
8
|
import './components/taxonAttributes'
|
|
9
9
|
import FeedCategorySelect from './components/feedCategorySelect'
|
|
10
|
+
import ProductVariantPricingGraph from './components/productVariantPricingGraph'
|
|
11
|
+
import CustomerGroupClientAssigner from './components/customerGroupClientAssigner'
|
|
10
12
|
import TooltipHelpers from './components/tooltipHelpers'
|
|
11
13
|
import AdminSidebarScroller from './components/adminSidebarScroller'
|
|
12
14
|
import CustomerGroupingRuleConfiguration from './components/customerGroupingRuleConfiguration'
|
|
15
|
+
import ProductVariantPricingSimulation from './components/productVariantPricingSimulation'
|
|
13
16
|
|
|
14
17
|
// Scripts - plugin
|
|
15
18
|
import './plugins/ckeditor/index'
|
|
@@ -29,7 +32,6 @@ import '@oxyshop/admin/lib/style.css'
|
|
|
29
32
|
// Images
|
|
30
33
|
import '@oxyshop/admin/images/logo.png'
|
|
31
34
|
import '@oxyshop/admin/images/admin-logo.svg'
|
|
32
|
-
import CustomerGroupClientAssigner from './components/customerGroupClientAssigner'
|
|
33
35
|
|
|
34
36
|
// Components initializations
|
|
35
37
|
$(document).ready(() => {
|
|
@@ -44,20 +46,28 @@ $(document).ready(() => {
|
|
|
44
46
|
*/
|
|
45
47
|
TooltipHelpers.init()
|
|
46
48
|
|
|
47
|
-
const feedCategorySelect = new FeedCategorySelect('.ng-feed-category-select')
|
|
48
|
-
feedCategorySelect.init()
|
|
49
|
-
|
|
50
49
|
const customerGroupingRuleConfiguration = new CustomerGroupingRuleConfiguration(
|
|
51
50
|
'select.ng-grouping-rule-select',
|
|
52
51
|
'.ng-grouping-rule-configuration'
|
|
53
52
|
)
|
|
54
53
|
customerGroupingRuleConfiguration.init()
|
|
55
54
|
|
|
55
|
+
const feedCategorySelect = new FeedCategorySelect('.ng-feed-category-select')
|
|
56
|
+
feedCategorySelect.init()
|
|
57
|
+
|
|
56
58
|
// Admin sidebar scroller
|
|
57
59
|
const adminSidebarElement = document.getElementById('sidebar')
|
|
58
60
|
const adminSidebarScroller = new AdminSidebarScroller(adminSidebarElement, 'a.item')
|
|
59
61
|
adminSidebarScroller.scrollToActiveLink()
|
|
60
62
|
|
|
63
|
+
const productVariantPricingGraph = new ProductVariantPricingGraph('.ng-product-variant-pricing-graph')
|
|
64
|
+
productVariantPricingGraph.init()
|
|
65
|
+
|
|
66
|
+
const productVariantPricingSimulation = new ProductVariantPricingSimulation(
|
|
67
|
+
'.ng-product-variant-pricing-simulation'
|
|
68
|
+
)
|
|
69
|
+
productVariantPricingSimulation.init()
|
|
70
|
+
|
|
61
71
|
// Client search select
|
|
62
72
|
const clientSearchSelect = new CustomerGroupClientAssigner('.ng-customer-group-client-assigner')
|
|
63
73
|
clientSearchSelect.init()
|