@oxyshop/admin 1.3.48 → 1.3.49

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 CHANGED
@@ -25,14 +25,13 @@ 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';
31
28
  import 'semantic-ui-css/semantic.css';
32
29
  import '@oxyshop/admin/scss/main.scss';
33
30
  import '@oxyshop/admin/lib/style.css';
34
31
  import '@oxyshop/admin/images/logo.png';
35
32
  import '@oxyshop/admin/images/admin-logo.svg';
33
+ import '@oxyshop/admin/images/50x50.png';
34
+ import { axios } from '@oxyshop/shop/lib/plugins/Axios';
36
35
 
37
36
  window.$ = $$1;
38
37
  window.jQuery = $$1;
@@ -437,12 +436,13 @@ $$1.fn.extend({
437
436
  $$1(`<div class="item" data-value="${item[choiceValue]}">${item[choiceName]}</div>`)
438
437
  ));
439
438
  });
440
-
441
- element.dropdown('refresh');
442
- element.dropdown('set selected', element.find('input.autocomplete').val().split(',').filter(String));
443
439
  },
444
440
  });
445
441
  }
442
+
443
+ window.setTimeout(() => {
444
+ element.dropdown('set selected', element.find('input.autocomplete').val().split(',').filter(String));
445
+ }, 5000);
446
446
  });
447
447
  },
448
448
  });
@@ -473,12 +473,12 @@ const controlAttributesList = function controlAttributesList() {
473
473
  };
474
474
 
475
475
  const modifyAttributesListOnSelectorElementDelete = function modifyAttributesListOnSelectorElementDelete(removedValue) {
476
- $$1(`#attributesContainer .attributes-group[data-attribute-code="${removedValue}"]`).remove();
476
+ $$1(`#attributesContainer .attribute[data-id="${removedValue}"]`).remove();
477
477
  };
478
478
 
479
479
  const modifySelectorOnAttributesListElementDelete = function modifySelectorOnAttributesListElementDelete() {
480
- $$1('.attributes-group button[data-attribute="delete"]').off('click').on('click', (event) => {
481
- const attributeId = $$1(event.currentTarget).parents('.attributes-group').attr('data-attribute-code');
480
+ $$1('.attribute button').off('click').on('click', (event) => {
481
+ const attributeId = $$1(event.currentTarget).parents('.attribute').attr('data-id');
482
482
 
483
483
  $$1('div#attributeChoice > .ui.dropdown.search').dropdown('remove selected', attributeId);
484
484
  modifyAttributesListOnSelectorElementDelete(attributeId);
@@ -507,31 +507,6 @@ const isInTheAttributesContainer = function isInTheAttributesContainer(attribute
507
507
  return result;
508
508
  };
509
509
 
510
- const copyValueToAllLanguages = function copyValueToAllLanguages() {
511
- $$1('#attributesContainer').on('click', '.attribute [data-attribute="copy"]', (event) => {
512
- event.preventDefault();
513
-
514
- const $attributesContainer = $$1('#attributesContainer');
515
- const $masterAttribute = $$1(event.currentTarget).closest('.attribute');
516
- const attributeID = $masterAttribute.attr('data-id');
517
- const $attributeCollection = $attributesContainer.find(`[data-id="${attributeID}"]`);
518
-
519
- const $masterAttributeInputs = $masterAttribute.find('input:visible, select, textarea');
520
-
521
- $attributeCollection.each((index, attr) => {
522
- const $inputs = $$1(attr).find('input:visible, select, textarea');
523
-
524
- $inputs.each((i, input) => {
525
- if (input.getAttribute('type') === 'checkbox') {
526
- input.checked = $masterAttributeInputs[i].checked;
527
- } else {
528
- input.value = $masterAttributeInputs[i].value;
529
- }
530
- });
531
- });
532
- });
533
- };
534
-
535
510
  const setAttributeChoiceListener = function setAttributeChoiceListener() {
536
511
  const $attributeChoice = $$1('#attributeChoice');
537
512
  $attributeChoice.find('button').on('click', (event) => {
@@ -564,8 +539,8 @@ const setAttributeChoiceListener = function setAttributeChoiceListener() {
564
539
  const attributeFormElements = modifyAttributeFormElements($$1(response));
565
540
 
566
541
  attributeFormElements.each((index, element) => {
567
- $$1(element).find('input[type="hidden"]').last().val();
568
- $$1(`#attributesContainer > div`).append(element);
542
+ const localeCode = $$1(element).find('input[type="hidden"]').last().val();
543
+ $$1(`#attributesContainer > div[data-tab="${localeCode}"]`).append(element);
569
544
  });
570
545
 
571
546
  $$1('#sylius_product_attribute_choice').val('');
@@ -592,7 +567,6 @@ $$1.fn.extend({
592
567
 
593
568
  controlAttributesList();
594
569
  modifySelectorOnAttributesListElementDelete();
595
- copyValueToAllLanguages();
596
570
  },
597
571
  });
598
572
 
@@ -1839,8 +1813,8 @@ $$1(document).ready(() => {
1839
1813
  $$1(document).previewUploadedImage('#add-avatar');
1840
1814
 
1841
1815
  $$1('body').on('DOMNodeInserted', '[data-form-collection="item"]', (event) => {
1842
- if ($$1(event.target).find('.ui.accordion').length > 0) {
1843
- $$1(event.target).find('.ui.accordion').accordion();
1816
+ if ($$1(event.target).find('.accordion').length > 0) {
1817
+ $$1(event.target).find('.accordion').accordion();
1844
1818
  }
1845
1819
  });
1846
1820
 
@@ -1927,156 +1901,11 @@ class FeedCategorySelect {
1927
1901
  cache: false,
1928
1902
  },
1929
1903
  minCharacters: 2,
1930
- clearable: true,
1931
1904
  });
1932
-
1933
- // Workaround for dropdown clear button not showing after loading initial value from the API
1934
- setTimeout(() => {
1935
- $(selectElement).dropdown('restore defaults');
1936
- }, 0);
1937
1905
  });
1938
1906
  }
1939
1907
  }
1940
1908
 
1941
- class ProductVariantPricingGraph {
1942
- constructor(containerSelector) {
1943
- this.containerSelector = containerSelector;
1944
- }
1945
-
1946
- init() {
1947
- document.querySelectorAll(this.containerSelector).forEach((componentContainer) => {
1948
- const graphsData = JSON.parse(componentContainer.getAttribute('data-graph'));
1949
-
1950
- for (const currencyGraphIndex in graphsData) {
1951
- const currencyGraph = graphsData[currencyGraphIndex];
1952
-
1953
- const currencyCodeHeader = document.createElement('h4');
1954
- currencyCodeHeader.classList.add('ui', 'header');
1955
- currencyCodeHeader.textContent = currencyGraph.currency;
1956
-
1957
- const graphCanvas = document.createElement('canvas');
1958
- graphCanvas.width = 400;
1959
- graphCanvas.height = 200;
1960
-
1961
- const graphContainer = document.createElement('div');
1962
- graphContainer.append(currencyCodeHeader);
1963
- graphContainer.append(graphCanvas);
1964
-
1965
- componentContainer.append(graphContainer);
1966
-
1967
- const graphConfig = this.getGraphConfig(currencyGraph.graph);
1968
- new Chart$1(graphCanvas.getContext('2d'), graphConfig);
1969
- }
1970
- });
1971
- }
1972
-
1973
- /** @private */
1974
- getGraphConfig(rawGraphData) {
1975
- return {
1976
- type: 'line',
1977
- data: {
1978
- datasets: rawGraphData.datasets.map((rawDataset) => {
1979
- return {
1980
- label: rawDataset.label,
1981
- data: rawDataset.data,
1982
- borderColor: this.getRandomRgbColor(),
1983
- fill: false,
1984
- steppedLine: true,
1985
- pointRadius: 8,
1986
- pointHoverRadius: 10,
1987
- }
1988
- }),
1989
- },
1990
- options: {
1991
- maintainAspectRatio: true,
1992
- responsive: true,
1993
- scales: {
1994
- xAxes: [
1995
- {
1996
- type: 'linear',
1997
- position: 'bottom',
1998
- scaleLabel: {
1999
- display: true,
2000
- labelString: rawGraphData.xAxisLabel,
2001
- },
2002
- },
2003
- ],
2004
- yAxes: [
2005
- {
2006
- scaleLabel: {
2007
- display: true,
2008
- labelString: rawGraphData.yAxisLabel,
2009
- },
2010
- },
2011
- ],
2012
- },
2013
- },
2014
- }
2015
- }
2016
-
2017
- /** @private */
2018
- getRandomRgbColor() {
2019
- const r = Math.floor(Math.random() * 255);
2020
- const g = Math.floor(Math.random() * 255);
2021
- const b = Math.floor(Math.random() * 255);
2022
- return `rgb(${r},${g},${b})`
2023
- }
2024
- }
2025
-
2026
- class CustomerGroupClientAssigner {
2027
- constructor(selector, searchSelector = '.ng-client-search-select', submitSelector = '.ng-client-assign-submit') {
2028
- this.selector = selector;
2029
- this.searchSelector = searchSelector;
2030
- this.submitSelector = submitSelector;
2031
- }
2032
-
2033
- init() {
2034
- document.querySelectorAll(this.selector).forEach((containerElement) => {
2035
- const submitApiEndpoint = containerElement.getAttribute('data-assign-customers-url');
2036
- const redirectAfterUrl = containerElement.getAttribute('data-redirect-after-url');
2037
-
2038
- const searchElement = containerElement.querySelector(this.searchSelector);
2039
- const searchApiEndpoint = searchElement.getAttribute('data-customer-search-url');
2040
-
2041
- $(searchElement).dropdown({
2042
- apiSettings: {
2043
- url: `${searchApiEndpoint}/{query}`,
2044
- cache: false,
2045
- },
2046
-
2047
- minCharacters: 2,
2048
- });
2049
-
2050
- const submitElement = containerElement.querySelector(this.submitSelector);
2051
- submitElement.addEventListener('click', () => {
2052
- const selectedCustomersIds = this.getSelectValues(searchElement);
2053
- this.submitCustomers(submitElement, submitApiEndpoint, selectedCustomersIds, redirectAfterUrl);
2054
- });
2055
- });
2056
- }
2057
-
2058
- getSelectValues(selectElement) {
2059
- const selected = selectElement.querySelectorAll('option:checked');
2060
- return Array.from(selected).map((optionElement) => optionElement.value)
2061
- }
2062
-
2063
- submitCustomers(submitElement, apiEndpoint, selectedIds, redirectTo) {
2064
- submitElement.disabled = true;
2065
-
2066
- axios
2067
- .post(apiEndpoint, { customers: selectedIds })
2068
- .then(() => {
2069
- window.location = redirectTo;
2070
- })
2071
- .catch((error) => {
2072
- console.error(error);
2073
- })
2074
- .finally(() => {
2075
- submitElement.disabled = false;
2076
- });
2077
- }
2078
- }
2079
-
2080
1909
  class TooltipHelpers {
2081
1910
  static init() {
2082
1911
  TooltipHelpers.initSyliusShippingMethodTooltip();
@@ -2210,557 +2039,6 @@ class CustomerGroupingRuleConfiguration {
2210
2039
  }
2211
2040
  }
2212
2041
 
2213
- class ImageInput {
2214
- constructor(selector) {
2215
- this.selector = selector;
2216
- }
2217
-
2218
- init() {
2219
- document.querySelectorAll(this.selector).forEach((element) => {
2220
- element.querySelectorAll('input[type="file"]').forEach((input) => {
2221
- input.addEventListener('change', () => {
2222
- this.onImageInputChange(input);
2223
- });
2224
- });
2225
- });
2226
- }
2227
-
2228
- onImageInputChange(input) {
2229
- if (!input.files || !input.files[0]) {
2230
- return
2231
- }
2232
-
2233
- const reader = new FileReader();
2234
-
2235
- reader.onload = (event) => {
2236
- const wrapperDiv = input.parentElement.parentElement;
2237
- const image = wrapperDiv.querySelector('.image');
2238
-
2239
- if (null === image) {
2240
- const img = document.createElement('img');
2241
- img.setAttribute('class', 'ui small bordered image');
2242
- img.setAttribute('src', event.target.result);
2243
-
2244
- const inputLabel = wrapperDiv.querySelector(':scope > label');
2245
- wrapperDiv.insertBefore(img, inputLabel.nextSibling);
2246
- } else {
2247
- image.setAttribute('src', event.target.result);
2248
- }
2249
- };
2250
-
2251
- reader.readAsDataURL(input.files[0]);
2252
- }
2253
- }
2254
-
2255
- class ProductVariantPricingSimulation {
2256
- constructor(selector) {
2257
- this.selector = selector;
2258
- }
2259
-
2260
- init() {
2261
- document.querySelectorAll(this.selector).forEach((element) => {
2262
- const productVariantId = element.getAttribute('data-product-variant-id');
2263
- const channels = JSON.parse(element.getAttribute('data-channels'));
2264
- const searchApiEndpoint = element.getAttribute('data-customer-search-url');
2265
- const pricingApiEndpoint = element.getAttribute('data-pricing-url');
2266
-
2267
- this.initElement(element, productVariantId, channels, searchApiEndpoint, pricingApiEndpoint);
2268
- });
2269
- }
2270
-
2271
- initElement(parentElement, productVariantId, channels, searchApiEndpoint, pricingApiEndpoint) {
2272
- parentElement.innerHTML = '';
2273
-
2274
- const simulationData = {
2275
- productVariantId: productVariantId,
2276
- channelId: null,
2277
- currencyId: null,
2278
- customerId: null,
2279
- };
2280
-
2281
- const submitButton = document.createElement('button');
2282
- const currencySelect = document.createElement('select');
2283
-
2284
- const onChannelSelect = (event) => {
2285
- const selectedChannelId = parseInt(event.target.value);
2286
- simulationData.channelId = selectedChannelId;
2287
- simulationData.currencyId = null;
2288
- submitButton.disabled = this.isSubmitButtonDisabled(simulationData);
2289
-
2290
- const selectedChannel = channels.find((channel) => {
2291
- return channel.id === selectedChannelId
2292
- });
2293
-
2294
- currencySelect.innerHTML = '';
2295
- this.addSelectOptions(currencySelect, selectedChannel.currencies, 'Select currency');
2296
- };
2297
-
2298
- const onCurrencySelect = (event) => {
2299
- simulationData.currencyId = event.target.value;
2300
- submitButton.disabled = this.isSubmitButtonDisabled(simulationData);
2301
- };
2302
-
2303
- const onCustomerSelect = (event) => {
2304
- simulationData.customerId = event.target.value;
2305
- submitButton.disabled = this.isSubmitButtonDisabled(simulationData);
2306
- };
2307
-
2308
- const graphWrapper = this.createGraphWrapper();
2309
-
2310
- const onSubmit = () => {
2311
- const pricingUrl = `${pricingApiEndpoint}?${this.serializeObjectToQuery(simulationData)}`;
2312
-
2313
- axios$1
2314
- .get(pricingUrl)
2315
- .then((response) => {
2316
- const chartData = response.data;
2317
- graphWrapper.setAttribute('data-debug-chart', JSON.stringify(chartData)); // For e2e tests
2318
- this.renderGraph(graphWrapper, chartData);
2319
- })
2320
- .catch((error) => {
2321
- console.error(error);
2322
- graphWrapper.innerHTML = 'Pricing simulation error';
2323
- });
2324
- };
2325
-
2326
- const wrapper = document.createElement('div');
2327
- wrapper.setAttribute('style', 'border: solid 1px #ddd; background-color: #fafafa;');
2328
-
2329
- const filters = this.createFilters(
2330
- channels,
2331
- currencySelect,
2332
- onChannelSelect,
2333
- onCurrencySelect,
2334
- onCustomerSelect,
2335
- onSubmit,
2336
- submitButton,
2337
- searchApiEndpoint
2338
- );
2339
- filters.setAttribute(
2340
- 'style',
2341
- 'display: grid; grid-template-columns: 1fr 1fr 1fr 60px; grid-gap: 10px; ' +
2342
- 'padding: 15px; border-bottom: solid 1px #ddd;'
2343
- );
2344
-
2345
- const graphFiller = this.createGraphFiller();
2346
- graphWrapper.append(graphFiller);
2347
-
2348
- wrapper.append(filters, graphWrapper);
2349
- parentElement.append(wrapper);
2350
- }
2351
-
2352
- createFilters(
2353
- channels,
2354
- currencySelect,
2355
- onChannelSelect,
2356
- onCurrencySelect,
2357
- onCustomerSelect,
2358
- onSubmit,
2359
- submitButton,
2360
- searchApiEndpoint
2361
- ) {
2362
- const filtersWrapper = document.createElement('div');
2363
-
2364
- const channelSelect = document.createElement('select');
2365
- channelSelect.classList.add('dirtyignore');
2366
- this.addSelectOptions(channelSelect, channels, 'Select channel');
2367
- channelSelect.addEventListener('change', onChannelSelect);
2368
-
2369
- currencySelect.classList.add('dirtyignore');
2370
- currencySelect.addEventListener('change', onCurrencySelect);
2371
-
2372
- const customerSelect = document.createElement('select');
2373
- customerSelect.classList.add('dirtyignore');
2374
- customerSelect.addEventListener('change', onCustomerSelect);
2375
-
2376
- // this is delayed to avoid racing conditions
2377
- setTimeout(() => this.hookClientSearchOnSelect(customerSelect, searchApiEndpoint), 600);
2378
-
2379
- submitButton.disabled = true;
2380
- submitButton.setAttribute('class', 'ui icon primary button');
2381
- submitButton.type = 'button';
2382
- submitButton.addEventListener('click', onSubmit);
2383
-
2384
- const playIcon = document.createElement('i');
2385
- playIcon.setAttribute('class', 'icon play');
2386
- submitButton.append(playIcon);
2387
-
2388
- filtersWrapper.append(channelSelect, currencySelect, customerSelect, submitButton);
2389
-
2390
- return filtersWrapper
2391
- }
2392
-
2393
- createGraphWrapper() {
2394
- const wrapper = document.createElement('div');
2395
- wrapper.setAttribute('style', 'padding: 15px;');
2396
-
2397
- return wrapper
2398
- }
2399
-
2400
- createGraphFiller() {
2401
- const filler = document.createElement('div');
2402
- filler.setAttribute(
2403
- 'style',
2404
- 'border-radius: 7px; background-color: #eee; height: 350px; display: flex; ' +
2405
- 'justify-content: space-around; align-items: center; font-size: 4em;'
2406
- );
2407
-
2408
- const chartIcon = document.createElement('i');
2409
- chartIcon.setAttribute('class', 'icon chart line');
2410
- filler.append(chartIcon);
2411
-
2412
- return filler
2413
- }
2414
-
2415
- addSelectOptions(select, choices, placeholder = null) {
2416
- if (placeholder !== null) {
2417
- const placeholderOption = document.createElement('option');
2418
- placeholderOption.innerHTML = placeholder;
2419
- placeholderOption.disabled = true;
2420
- placeholderOption.selected = true;
2421
- select.append(placeholderOption);
2422
- }
2423
-
2424
- for (const property in choices) {
2425
- const choice = choices[property];
2426
-
2427
- const channelOption = document.createElement('option');
2428
- channelOption.innerHTML = choice.name;
2429
- channelOption.setAttribute('value', choice.id);
2430
- select.append(channelOption);
2431
- }
2432
-
2433
- return select
2434
- }
2435
-
2436
- hookClientSearchOnSelect(selectElement, searchApiEndpoint) {
2437
- selectElement.setAttribute('class', `${selectElement.getAttribute('class')} search dropdown selection`);
2438
-
2439
- $(selectElement).dropdown({
2440
- apiSettings: {
2441
- url: `${searchApiEndpoint}/{query}`,
2442
- cache: false,
2443
- },
2444
-
2445
- minCharacters: 2,
2446
- });
2447
- }
2448
-
2449
- isSubmitButtonDisabled(simulationData) {
2450
- return (
2451
- null === simulationData.productVariantId ||
2452
- null === simulationData.channelId ||
2453
- null === simulationData.currencyId ||
2454
- null === simulationData.customerId
2455
- )
2456
- }
2457
-
2458
- serializeObjectToQuery(object) {
2459
- const query = [];
2460
-
2461
- for (const part in object) {
2462
- if (Object.prototype.hasOwnProperty.call(object, part)) {
2463
- query.push(`${encodeURIComponent(part)}=${encodeURIComponent(object[part])}`);
2464
- }
2465
- }
2466
-
2467
- return query.join('&')
2468
- }
2469
-
2470
- renderGraph(graphWrapper, graphData) {
2471
- graphWrapper.innerHTML = '';
2472
-
2473
- const graphCanvas = document.createElement('canvas');
2474
- graphCanvas.width = 600;
2475
- graphCanvas.height = 200;
2476
-
2477
- graphWrapper.append(graphCanvas);
2478
-
2479
- const graphConfig = this.getGraphConfig(graphData);
2480
- console.log('graphConfig', graphConfig);
2481
- new Chart$1(graphCanvas.getContext('2d'), graphConfig);
2482
- }
2483
-
2484
- /** @private */
2485
- getGraphConfig(rawGraphData) {
2486
- return {
2487
- type: 'line',
2488
- data: {
2489
- datasets: rawGraphData.datasets.map((rawDataset) => {
2490
- return {
2491
- label: rawDataset.label,
2492
- data: rawDataset.data,
2493
- borderColor: '#0000ff',
2494
- fill: false,
2495
- steppedLine: true,
2496
- pointRadius: 8,
2497
- pointHoverRadius: 10,
2498
- }
2499
- }),
2500
- },
2501
- options: {
2502
- maintainAspectRatio: true,
2503
- responsive: true,
2504
- scales: {
2505
- xAxes: [
2506
- {
2507
- type: 'linear',
2508
- position: 'bottom',
2509
- scaleLabel: {
2510
- display: true,
2511
- labelString: rawGraphData.xAxisLabel,
2512
- },
2513
- },
2514
- ],
2515
- yAxes: [
2516
- {
2517
- scaleLabel: {
2518
- display: true,
2519
- labelString: rawGraphData.yAxisLabel,
2520
- },
2521
- },
2522
- ],
2523
- },
2524
- },
2525
- }
2526
- }
2527
- }
2528
-
2529
- class DocumentUploadInput {
2530
- /** @param {string} documentUploadInputSelector */
2531
- constructor(documentUploadInputSelector) {
2532
- this.selector = documentUploadInputSelector;
2533
- }
2534
-
2535
- init() {
2536
- const fileInputs = document.querySelectorAll(this.selector);
2537
-
2538
- Array.prototype.forEach.call(fileInputs, (inputElement) => {
2539
- const fileUrl = inputElement.getAttribute('data-file-url');
2540
- const fileTitle = inputElement.getAttribute('data-file-name');
2541
- const downloadText = inputElement.getAttribute('data-download-translation');
2542
-
2543
- const iconElement = document.createElement('i');
2544
- iconElement.classList.add('download', 'icon');
2545
-
2546
- const buttonElement = document.createElement('button');
2547
- buttonElement.classList.add('ui', 'compact', 'labeled', 'icon', 'button');
2548
- buttonElement.setAttribute('type', 'button');
2549
- buttonElement.append(iconElement);
2550
- buttonElement.innerHTML += `${downloadText}: ${fileTitle}`;
2551
-
2552
- const downloadLink = document.createElement('a');
2553
- downloadLink.setAttribute('style', 'display: inline-block; margin: -5px 0 25px 0;');
2554
- downloadLink.setAttribute('target', '_blank');
2555
- downloadLink.setAttribute('href', fileUrl);
2556
- downloadLink.append(buttonElement);
2557
-
2558
- inputElement.parentNode.parentNode.append(downloadLink);
2559
- });
2560
- }
2561
- }
2562
-
2563
- (function ($) {
2564
-
2565
- $.fn.extend({
2566
- blogSlugGenerator: function () {
2567
- let timeout;
2568
-
2569
- $('[name*="nextgen_cms_bundle_blog[translations]"][name*="[name]"]').on('input', function () {
2570
- clearTimeout(timeout);
2571
- let element = $(this);
2572
-
2573
- timeout = setTimeout(function () {
2574
- updateSlug(element);
2575
- }, 1000);
2576
- });
2577
-
2578
- $('.toggle-blog-slug-modification').on('click', function (e) {
2579
- e.preventDefault();
2580
- toggleSlugModification($(this), $(this).siblings('input'));
2581
- });
2582
-
2583
- function updateSlug(element) {
2584
- let slugInput = element.parents('.content').find('[name*="[slug]"]');
2585
- let loadableParent = slugInput.parents('.field.loadable');
2586
-
2587
- if ('readonly' === slugInput.attr('readonly')) {
2588
- return
2589
- }
2590
-
2591
- loadableParent.addClass('loading');
2592
-
2593
- $.ajax({
2594
- type: 'GET',
2595
- url: slugInput.attr('data-url'),
2596
- data: { name: element.val() },
2597
- dataType: 'json',
2598
- accept: 'application/json',
2599
- success: function (data) {
2600
- slugInput.val(data.slug);
2601
- if (slugInput.parents('.field').hasClass('error')) {
2602
- slugInput.parents('.field').removeClass('error');
2603
- slugInput.parents('.field').find('.sylius-validation-error').remove();
2604
- }
2605
- loadableParent.removeClass('loading');
2606
- },
2607
- });
2608
- }
2609
-
2610
- function toggleSlugModification(button, slugInput) {
2611
- if (slugInput.attr('readonly')) {
2612
- slugInput.removeAttr('readonly');
2613
- button.html('<i class="unlock icon"></i>');
2614
- } else {
2615
- slugInput.attr('readonly', 'readonly');
2616
- button.html('<i class="lock icon"></i>');
2617
- }
2618
- }
2619
- },
2620
- });
2621
- })(jQuery)
2622
- ;(function ($) {
2623
- $(document).ready(function () {
2624
- $(this).blogSlugGenerator();
2625
- });
2626
- })(jQuery);
2627
-
2628
- (function ($) {
2629
-
2630
- $.fn.extend({
2631
- articleSlugGenerator: function () {
2632
- let timeout;
2633
-
2634
- $('[name*="nextgen_cms_bundle_article[translations]"][name*="[name]"]').on('input', function () {
2635
- clearTimeout(timeout);
2636
- let element = $(this);
2637
-
2638
- timeout = setTimeout(function () {
2639
- updateSlug(element);
2640
- }, 1000);
2641
- });
2642
-
2643
- $('.toggle-article-slug-modification').on('click', function (e) {
2644
- e.preventDefault();
2645
- toggleSlugModification($(this), $(this).siblings('input'));
2646
- });
2647
-
2648
- function updateSlug(element) {
2649
- let slugInput = element.parents('.content').find('[name*="[slug]"]');
2650
- let loadableParent = slugInput.parents('.field.loadable');
2651
-
2652
- if ('readonly' === slugInput.attr('readonly')) {
2653
- return
2654
- }
2655
-
2656
- loadableParent.addClass('loading');
2657
-
2658
- $.ajax({
2659
- type: 'GET',
2660
- url: slugInput.attr('data-url'),
2661
- data: { name: element.val() },
2662
- dataType: 'json',
2663
- accept: 'application/json',
2664
- success: function (data) {
2665
- slugInput.val(data.slug);
2666
- if (slugInput.parents('.field').hasClass('error')) {
2667
- slugInput.parents('.field').removeClass('error');
2668
- slugInput.parents('.field').find('.sylius-validation-error').remove();
2669
- }
2670
- loadableParent.removeClass('loading');
2671
- },
2672
- });
2673
- }
2674
-
2675
- function toggleSlugModification(button, slugInput) {
2676
- if (slugInput.attr('readonly')) {
2677
- slugInput.removeAttr('readonly');
2678
- button.html('<i class="unlock icon"></i>');
2679
- } else {
2680
- slugInput.attr('readonly', 'readonly');
2681
- button.html('<i class="lock icon"></i>');
2682
- }
2683
- }
2684
- },
2685
- });
2686
- })(jQuery)
2687
- ;(function ($) {
2688
- $(document).ready(function () {
2689
- $(this).articleSlugGenerator();
2690
- });
2691
- })(jQuery);
2692
-
2693
- (function ($) {
2694
-
2695
- $.fn.extend({
2696
- blogCategorySlugGenerator: function () {
2697
- let timeout;
2698
-
2699
- $('[name*="nextgen_cms_bundle_blog_category[translations]"][name*="[name]"]').on('input', function () {
2700
- clearTimeout(timeout);
2701
- let element = $(this);
2702
-
2703
- timeout = setTimeout(function () {
2704
- updateSlug(element);
2705
- }, 1000);
2706
- });
2707
-
2708
- $('.toggle-blog-category-slug-modification').on('click', function (e) {
2709
- e.preventDefault();
2710
- toggleSlugModification($(this), $(this).siblings('input'));
2711
- });
2712
-
2713
- function updateSlug(element) {
2714
- let slugInput = element.parents('.content').find('[name*="[slug]"]');
2715
- let loadableParent = slugInput.parents('.field.loadable');
2716
-
2717
- if ('readonly' === slugInput.attr('readonly')) {
2718
- return
2719
- }
2720
-
2721
- loadableParent.addClass('loading');
2722
-
2723
- let data;
2724
- data = {
2725
- name: element.val(),
2726
- locale: element.closest('[data-locale]').data('locale'),
2727
- };
2728
-
2729
- $.ajax({
2730
- type: 'GET',
2731
- url: slugInput.attr('data-url'),
2732
- data: data,
2733
- dataType: 'json',
2734
- accept: 'application/json',
2735
- success: function (data) {
2736
- slugInput.val(data.slug);
2737
- if (slugInput.parents('.field').hasClass('error')) {
2738
- slugInput.parents('.field').removeClass('error');
2739
- slugInput.parents('.field').find('.sylius-validation-error').remove();
2740
- }
2741
- loadableParent.removeClass('loading');
2742
- },
2743
- });
2744
- }
2745
-
2746
- function toggleSlugModification(button, slugInput) {
2747
- if (slugInput.attr('readonly')) {
2748
- slugInput.removeAttr('readonly');
2749
- button.html('<i class="unlock icon"></i>');
2750
- } else {
2751
- slugInput.attr('readonly', 'readonly');
2752
- button.html('<i class="lock icon"></i>');
2753
- }
2754
- }
2755
- },
2756
- });
2757
- })(jQuery)
2758
- ;(function ($) {
2759
- $(document).ready(function () {
2760
- $(this).blogCategorySlugGenerator();
2761
- });
2762
- })(jQuery);
2763
-
2764
2042
  /**
2765
2043
  * CKEditor config
2766
2044
  */
@@ -2854,35 +2132,6 @@ vendorDescriptionElements.forEach((element) => {
2854
2132
  CKEDITOR.replace(element.name, ckEditorOptions);
2855
2133
  });
2856
2134
 
2857
- /**
2858
- * Blog article
2859
- */
2860
- const articleAnnotationElements = document.querySelectorAll(
2861
- 'form[name="nextgen_cms_bundle_article"] textarea[name$="[annotation]"]'
2862
- );
2863
- articleAnnotationElements.forEach((element) => {
2864
- // eslint-disable-next-line no-undef
2865
- CKEDITOR.replace(element.name, ckEditorOptions);
2866
- });
2867
- const articleContentElements = document.querySelectorAll(
2868
- 'form[name="nextgen_cms_bundle_article"] textarea[name$="[content]"]'
2869
- );
2870
- articleContentElements.forEach((element) => {
2871
- // eslint-disable-next-line no-undef
2872
- CKEDITOR.replace(element.name, ckEditorOptions);
2873
- });
2874
-
2875
- /**
2876
- * Blog category
2877
- */
2878
- const categoryDescriptionElements = document.querySelectorAll(
2879
- 'form[name="nextgen_cms_bundle_blog_category"] textarea[name$="[description]"]'
2880
- );
2881
- categoryDescriptionElements.forEach((element) => {
2882
- // eslint-disable-next-line no-undef
2883
- CKEDITOR.replace(element.name, ckEditorOptions);
2884
- });
2885
-
2886
2135
  (function ($) {
2887
2136
  $(document).ready(function () {
2888
2137
  $('#sylius_payment_method_calculator').handlePrototypes({
@@ -2892,12 +2141,6 @@ categoryDescriptionElements.forEach((element) => {
2892
2141
  });
2893
2142
  })(jQuery);
2894
2143
 
2895
- /*
2896
- This file was created by developers working at BitBag
2897
- Do you need more information about us and what we do? Visit our https://bitbag.io website!
2898
- We are hiring developers from all over the world. Join us and start your new, exciting adventure and become part of us: https://bitbag.io/career
2899
- */
2900
-
2901
2144
  (function ( $ ) {
2902
2145
 
2903
2146
  $.fn.extend({
@@ -2947,12 +2190,6 @@ categoryDescriptionElements.forEach((element) => {
2947
2190
  });
2948
2191
  })(jQuery);
2949
2192
 
2950
- /*
2951
- This file was created by developers working at BitBag
2952
- Do you need more information about us and what we do? Visit our https://bitbag.io website!
2953
- We are hiring developers from all over the world. Join us and start your new, exciting adventure and become part of us: https://bitbag.io/career
2954
- */
2955
-
2956
2193
  (function ( $ ) {
2957
2194
 
2958
2195
  $.fn.extend({
@@ -2964,7 +2201,7 @@ categoryDescriptionElements.forEach((element) => {
2964
2201
  if (callback !== undefined) {
2965
2202
  callback();
2966
2203
  }
2967
-
2204
+
2968
2205
  var actionButton = $(this);
2969
2206
  var form = actionButton.closest('form');
2970
2207
  var url = actionButton.data('url');
@@ -3016,12 +2253,6 @@ categoryDescriptionElements.forEach((element) => {
3016
2253
  });
3017
2254
  })(jQuery);
3018
2255
 
3019
- /*
3020
- This file was created by developers working at BitBag
3021
- Do you need more information about us and what we do? Visit our https://bitbag.io website!
3022
- We are hiring developers from all over the world. Join us and start your new, exciting adventure and become part of us: https://bitbag.io/career
3023
- */
3024
-
3025
2256
  (function ($) {
3026
2257
 
3027
2258
  $.fn.extend({
@@ -3088,12 +2319,6 @@ categoryDescriptionElements.forEach((element) => {
3088
2319
  });
3089
2320
  })(jQuery);
3090
2321
 
3091
- /*
3092
- This file was created by developers working at BitBag
3093
- Do you need more information about us and what we do? Visit our https://bitbag.io website!
3094
- We are hiring developers from all over the world. Join us and start your new, exciting adventure and become part of us: https://bitbag.io/career
3095
- */
3096
-
3097
2322
  (function($) {
3098
2323
  $('.bitbag-cms-import input[type="text"]').click(function() {
3099
2324
  $(this).parent().find('input[type="file"]').click();
@@ -3107,6 +2332,60 @@ categoryDescriptionElements.forEach((element) => {
3107
2332
 
3108
2333
  })( jQuery );
3109
2334
 
2335
+ class CustomerGroupClientAssigner {
2336
+ constructor(selector, searchSelector = '.ng-client-search-select', submitSelector = '.ng-client-assign-submit') {
2337
+ this.selector = selector;
2338
+ this.searchSelector = searchSelector;
2339
+ this.submitSelector = submitSelector;
2340
+ }
2341
+
2342
+ init() {
2343
+ document.querySelectorAll(this.selector).forEach((containerElement) => {
2344
+ const submitApiEndpoint = containerElement.getAttribute('data-assign-customers-url');
2345
+ const redirectAfterUrl = containerElement.getAttribute('data-redirect-after-url');
2346
+
2347
+ const searchElement = containerElement.querySelector(this.searchSelector);
2348
+ const searchApiEndpoint = searchElement.getAttribute('data-customer-search-url');
2349
+
2350
+ $(searchElement).dropdown({
2351
+ apiSettings: {
2352
+ url: `${searchApiEndpoint}/{query}`,
2353
+ cache: false,
2354
+ },
2355
+
2356
+ minCharacters: 2,
2357
+ });
2358
+
2359
+ const submitElement = containerElement.querySelector(this.submitSelector);
2360
+ submitElement.addEventListener('click', () => {
2361
+ const selectedCustomersIds = this.getSelectValues(searchElement);
2362
+ this.submitCustomers(submitElement, submitApiEndpoint, selectedCustomersIds, redirectAfterUrl);
2363
+ });
2364
+ });
2365
+ }
2366
+
2367
+ getSelectValues(selectElement) {
2368
+ const selected = selectElement.querySelectorAll('option:checked');
2369
+ return Array.from(selected).map((optionElement) => optionElement.value)
2370
+ }
2371
+
2372
+ submitCustomers(submitElement, apiEndpoint, selectedIds, redirectTo) {
2373
+ submitElement.disabled = true;
2374
+
2375
+ axios
2376
+ .post(apiEndpoint, { customers: selectedIds })
2377
+ .then(() => {
2378
+ window.location = redirectTo;
2379
+ })
2380
+ .catch((error) => {
2381
+ console.error(error);
2382
+ })
2383
+ .finally(() => {
2384
+ submitElement.disabled = false;
2385
+ });
2386
+ }
2387
+ }
2388
+
3110
2389
  // Scripts
3111
2390
 
3112
2391
  // Components initializations
@@ -3136,21 +2415,7 @@ $(document).ready(() => {
3136
2415
  const adminSidebarScroller = new AdminSidebarScroller(adminSidebarElement, 'a.item');
3137
2416
  adminSidebarScroller.scrollToActiveLink();
3138
2417
 
3139
- const productVariantPricingGraph = new ProductVariantPricingGraph('.ng-product-variant-pricing-graph');
3140
- productVariantPricingGraph.init();
3141
-
3142
- const productVariantPricingSimulation = new ProductVariantPricingSimulation(
3143
- '.ng-product-variant-pricing-simulation'
3144
- );
3145
- productVariantPricingSimulation.init();
3146
-
3147
2418
  // Client search select
3148
2419
  const clientSearchSelect = new CustomerGroupClientAssigner('.ng-customer-group-client-assigner');
3149
2420
  clientSearchSelect.init();
3150
-
3151
- const imageInput = new ImageInput('.ng-image-input');
3152
- imageInput.init();
3153
-
3154
- const documentUploadInput = new DocumentUploadInput('input.ng-document-upload-input');
3155
- documentUploadInput.init();
3156
2421
  });