@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/style.css CHANGED
@@ -212,80 +212,6 @@ input[type="color"]::-moz-color-swatch {
212
212
  border-radius: 99px;
213
213
  border: 0; }
214
214
 
215
- .attributes-group {
216
- border: 1px solid rgba(34, 36, 38, 0.1); }
217
- .attributes-group:not(:last-child) {
218
- border-bottom: 0; }
219
- .attributes-group:first-child {
220
- border-top-left-radius: 4px;
221
- border-top-right-radius: 4px; }
222
- .attributes-group:last-child {
223
- border-bottom-left-radius: 4px;
224
- border-bottom-right-radius: 4px; }
225
-
226
- .attributes-header {
227
- display: flex;
228
- align-items: center;
229
- justify-content: space-between;
230
- background: rgba(0, 0, 0, 0.03);
231
- padding: 0.5em 1.8em;
232
- border-bottom: 1px solid rgba(34, 36, 38, 0.1); }
233
- .attributes-header .ui.basic.red.button {
234
- box-shadow: none !important; }
235
- .attributes-header .ui.basic.red.button:hover {
236
- background: rgba(255, 0, 0, 0.1) !important; }
237
-
238
- .attributes-list {
239
- padding: 1.4em 1.8em; }
240
-
241
- .attribute-row {
242
- flex-wrap: wrap;
243
- margin: 10px 0; }
244
- @media (min-width: 1152px) {
245
- .attribute-row {
246
- display: flex; } }
247
-
248
- .attribute-label {
249
- align-self: center;
250
- width: 200px;
251
- margin-right: 20px;
252
- padding-top: 5px;
253
- padding-bottom: 5px;
254
- white-space: nowrap;
255
- text-overflow: ellipsis;
256
- overflow: hidden; }
257
- .attribute-label i {
258
- width: 20px;
259
- text-align: left; }
260
-
261
- .attribute-input {
262
- flex-grow: 1; }
263
-
264
- .attribute-input, .attribute-input div:not(.checkbox) {
265
- display: flex;
266
- flex-grow: 1;
267
- align-items: center; }
268
-
269
- .attribute-input *:not(:last-child) {
270
- margin-right: 5px; }
271
-
272
- .attribute-input *:not(:first-child) {
273
- margin-left: 5px; }
274
-
275
- .attribute-input textarea {
276
- height: 6em !important;
277
- min-height: 6em !important; }
278
-
279
- .attribute-action > * {
280
- margin: 4px 0 !important; }
281
- @media (min-width: 1152px) {
282
- .attribute-action > * {
283
- margin: 0 0 0 10px !important; } }
284
-
285
- .attribute-error {
286
- width: 100%;
287
- text-align: center; }
288
-
289
215
  .sylius-tree.hidden {
290
216
  display: none; }
291
217
 
@@ -489,10 +415,6 @@ a {
489
415
  background: inherit;
490
416
  color: #1abb9c; }
491
417
 
492
- .sylius-grid-image {
493
- max-height: 50px;
494
- max-width: 50px; }
495
-
496
418
  .ui.toggle.checkbox input:checked ~ .box:before, .ui.toggle.checkbox input:checked ~ label:before,
497
419
  .ui.toggle.checkbox input:focus:checked ~ .box:before, .ui.toggle.checkbox input:focus:checked ~ label:before {
498
420
  background-color: #1abb9c !important; }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oxyshop/admin",
3
- "version": "1.3.48",
3
+ "version": "1.3.49",
4
4
  "author": "oXy Online s.r.o. <info@oxyshop.cz>",
5
5
  "main": "lib/index.js",
6
6
  "sass": "scss/main.scss",
@@ -13,13 +13,7 @@ export default class FeedCategorySelect {
13
13
  cache: false,
14
14
  },
15
15
  minCharacters: 2,
16
- clearable: true,
17
16
  })
18
-
19
- // Workaround for dropdown clear button not showing after loading initial value from the API
20
- setTimeout(() => {
21
- $(selectElement).dropdown('restore defaults')
22
- }, 0)
23
17
  })
24
18
  }
25
19
  }
package/src/index.js CHANGED
@@ -7,17 +7,9 @@ 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'
12
10
  import TooltipHelpers from './components/tooltipHelpers'
13
11
  import AdminSidebarScroller from './components/adminSidebarScroller'
14
12
  import CustomerGroupingRuleConfiguration from './components/customerGroupingRuleConfiguration'
15
- import ImageInput from './components/imageInput'
16
- import ProductVariantPricingSimulation from './components/productVariantPricingSimulation'
17
- import DocumentUploadInput from './components/documentUploadInput'
18
- import './components/blog-slug.js'
19
- import './components/article-slug.js'
20
- import './components/blog-category-slug.js'
21
13
 
22
14
  // Scripts - plugin
23
15
  import './plugins/ckeditor/index'
@@ -37,6 +29,8 @@ import '@oxyshop/admin/lib/style.css'
37
29
  // Images
38
30
  import '@oxyshop/admin/images/logo.png'
39
31
  import '@oxyshop/admin/images/admin-logo.svg'
32
+ import '@oxyshop/admin/images/50x50.png'
33
+ import CustomerGroupClientAssigner from './components/customerGroupClientAssigner'
40
34
 
41
35
  // Components initializations
42
36
  $(document).ready(() => {
@@ -65,21 +59,7 @@ $(document).ready(() => {
65
59
  const adminSidebarScroller = new AdminSidebarScroller(adminSidebarElement, 'a.item')
66
60
  adminSidebarScroller.scrollToActiveLink()
67
61
 
68
- const productVariantPricingGraph = new ProductVariantPricingGraph('.ng-product-variant-pricing-graph')
69
- productVariantPricingGraph.init()
70
-
71
- const productVariantPricingSimulation = new ProductVariantPricingSimulation(
72
- '.ng-product-variant-pricing-simulation'
73
- )
74
- productVariantPricingSimulation.init()
75
-
76
62
  // Client search select
77
63
  const clientSearchSelect = new CustomerGroupClientAssigner('.ng-customer-group-client-assigner')
78
64
  clientSearchSelect.init()
79
-
80
- const imageInput = new ImageInput('.ng-image-input')
81
- imageInput.init()
82
-
83
- const documentUploadInput = new DocumentUploadInput('input.ng-document-upload-input')
84
- documentUploadInput.init()
85
65
  })
@@ -90,32 +90,3 @@ vendorDescriptionElements.forEach((element) => {
90
90
  // eslint-disable-next-line no-undef
91
91
  CKEDITOR.replace(element.name, ckEditorOptions)
92
92
  })
93
-
94
- /**
95
- * Blog article
96
- */
97
- const articleAnnotationElements = document.querySelectorAll(
98
- 'form[name="nextgen_cms_bundle_article"] textarea[name$="[annotation]"]'
99
- )
100
- articleAnnotationElements.forEach((element) => {
101
- // eslint-disable-next-line no-undef
102
- CKEDITOR.replace(element.name, ckEditorOptions)
103
- })
104
- const articleContentElements = document.querySelectorAll(
105
- 'form[name="nextgen_cms_bundle_article"] textarea[name$="[content]"]'
106
- )
107
- articleContentElements.forEach((element) => {
108
- // eslint-disable-next-line no-undef
109
- CKEDITOR.replace(element.name, ckEditorOptions)
110
- })
111
-
112
- /**
113
- * Blog category
114
- */
115
- const categoryDescriptionElements = document.querySelectorAll(
116
- 'form[name="nextgen_cms_bundle_blog_category"] textarea[name$="[description]"]'
117
- )
118
- categoryDescriptionElements.forEach((element) => {
119
- // eslint-disable-next-line no-undef
120
- CKEDITOR.replace(element.name, ckEditorOptions)
121
- })
@@ -1,65 +0,0 @@
1
- ;(function ($) {
2
- 'use strict'
3
-
4
- $.fn.extend({
5
- articleSlugGenerator: function () {
6
- let timeout
7
-
8
- $('[name*="nextgen_cms_bundle_article[translations]"][name*="[name]"]').on('input', function () {
9
- clearTimeout(timeout)
10
- let element = $(this)
11
-
12
- timeout = setTimeout(function () {
13
- updateSlug(element)
14
- }, 1000)
15
- })
16
-
17
- $('.toggle-article-slug-modification').on('click', function (e) {
18
- e.preventDefault()
19
- toggleSlugModification($(this), $(this).siblings('input'))
20
- })
21
-
22
- function updateSlug(element) {
23
- let slugInput = element.parents('.content').find('[name*="[slug]"]')
24
- let loadableParent = slugInput.parents('.field.loadable')
25
-
26
- if ('readonly' === slugInput.attr('readonly')) {
27
- return
28
- }
29
-
30
- loadableParent.addClass('loading')
31
-
32
- $.ajax({
33
- type: 'GET',
34
- url: slugInput.attr('data-url'),
35
- data: { name: element.val() },
36
- dataType: 'json',
37
- accept: 'application/json',
38
- success: function (data) {
39
- slugInput.val(data.slug)
40
- if (slugInput.parents('.field').hasClass('error')) {
41
- slugInput.parents('.field').removeClass('error')
42
- slugInput.parents('.field').find('.sylius-validation-error').remove()
43
- }
44
- loadableParent.removeClass('loading')
45
- },
46
- })
47
- }
48
-
49
- function toggleSlugModification(button, slugInput) {
50
- if (slugInput.attr('readonly')) {
51
- slugInput.removeAttr('readonly')
52
- button.html('<i class="unlock icon"></i>')
53
- } else {
54
- slugInput.attr('readonly', 'readonly')
55
- button.html('<i class="lock icon"></i>')
56
- }
57
- }
58
- },
59
- })
60
- })(jQuery)
61
- ;(function ($) {
62
- $(document).ready(function () {
63
- $(this).articleSlugGenerator()
64
- })
65
- })(jQuery)
@@ -1,71 +0,0 @@
1
- ;(function ($) {
2
- 'use strict'
3
-
4
- $.fn.extend({
5
- blogCategorySlugGenerator: function () {
6
- let timeout
7
-
8
- $('[name*="nextgen_cms_bundle_blog_category[translations]"][name*="[name]"]').on('input', function () {
9
- clearTimeout(timeout)
10
- let element = $(this)
11
-
12
- timeout = setTimeout(function () {
13
- updateSlug(element)
14
- }, 1000)
15
- })
16
-
17
- $('.toggle-blog-category-slug-modification').on('click', function (e) {
18
- e.preventDefault()
19
- toggleSlugModification($(this), $(this).siblings('input'))
20
- })
21
-
22
- function updateSlug(element) {
23
- let slugInput = element.parents('.content').find('[name*="[slug]"]')
24
- let loadableParent = slugInput.parents('.field.loadable')
25
-
26
- if ('readonly' === slugInput.attr('readonly')) {
27
- return
28
- }
29
-
30
- loadableParent.addClass('loading')
31
-
32
- let data
33
- data = {
34
- name: element.val(),
35
- locale: element.closest('[data-locale]').data('locale'),
36
- }
37
-
38
- $.ajax({
39
- type: 'GET',
40
- url: slugInput.attr('data-url'),
41
- data: data,
42
- dataType: 'json',
43
- accept: 'application/json',
44
- success: function (data) {
45
- slugInput.val(data.slug)
46
- if (slugInput.parents('.field').hasClass('error')) {
47
- slugInput.parents('.field').removeClass('error')
48
- slugInput.parents('.field').find('.sylius-validation-error').remove()
49
- }
50
- loadableParent.removeClass('loading')
51
- },
52
- })
53
- }
54
-
55
- function toggleSlugModification(button, slugInput) {
56
- if (slugInput.attr('readonly')) {
57
- slugInput.removeAttr('readonly')
58
- button.html('<i class="unlock icon"></i>')
59
- } else {
60
- slugInput.attr('readonly', 'readonly')
61
- button.html('<i class="lock icon"></i>')
62
- }
63
- }
64
- },
65
- })
66
- })(jQuery)
67
- ;(function ($) {
68
- $(document).ready(function () {
69
- $(this).blogCategorySlugGenerator()
70
- })
71
- })(jQuery)
@@ -1,65 +0,0 @@
1
- ;(function ($) {
2
- 'use strict'
3
-
4
- $.fn.extend({
5
- blogSlugGenerator: function () {
6
- let timeout
7
-
8
- $('[name*="nextgen_cms_bundle_blog[translations]"][name*="[name]"]').on('input', function () {
9
- clearTimeout(timeout)
10
- let element = $(this)
11
-
12
- timeout = setTimeout(function () {
13
- updateSlug(element)
14
- }, 1000)
15
- })
16
-
17
- $('.toggle-blog-slug-modification').on('click', function (e) {
18
- e.preventDefault()
19
- toggleSlugModification($(this), $(this).siblings('input'))
20
- })
21
-
22
- function updateSlug(element) {
23
- let slugInput = element.parents('.content').find('[name*="[slug]"]')
24
- let loadableParent = slugInput.parents('.field.loadable')
25
-
26
- if ('readonly' === slugInput.attr('readonly')) {
27
- return
28
- }
29
-
30
- loadableParent.addClass('loading')
31
-
32
- $.ajax({
33
- type: 'GET',
34
- url: slugInput.attr('data-url'),
35
- data: { name: element.val() },
36
- dataType: 'json',
37
- accept: 'application/json',
38
- success: function (data) {
39
- slugInput.val(data.slug)
40
- if (slugInput.parents('.field').hasClass('error')) {
41
- slugInput.parents('.field').removeClass('error')
42
- slugInput.parents('.field').find('.sylius-validation-error').remove()
43
- }
44
- loadableParent.removeClass('loading')
45
- },
46
- })
47
- }
48
-
49
- function toggleSlugModification(button, slugInput) {
50
- if (slugInput.attr('readonly')) {
51
- slugInput.removeAttr('readonly')
52
- button.html('<i class="unlock icon"></i>')
53
- } else {
54
- slugInput.attr('readonly', 'readonly')
55
- button.html('<i class="lock icon"></i>')
56
- }
57
- }
58
- },
59
- })
60
- })(jQuery)
61
- ;(function ($) {
62
- $(document).ready(function () {
63
- $(this).blogSlugGenerator()
64
- })
65
- })(jQuery)
@@ -1,33 +0,0 @@
1
- export default class DocumentUploadInput {
2
- /** @param {string} documentUploadInputSelector */
3
- constructor(documentUploadInputSelector) {
4
- this.selector = documentUploadInputSelector
5
- }
6
-
7
- init() {
8
- const fileInputs = document.querySelectorAll(this.selector)
9
-
10
- Array.prototype.forEach.call(fileInputs, (inputElement) => {
11
- const fileUrl = inputElement.getAttribute('data-file-url')
12
- const fileTitle = inputElement.getAttribute('data-file-name')
13
- const downloadText = inputElement.getAttribute('data-download-translation')
14
-
15
- const iconElement = document.createElement('i')
16
- iconElement.classList.add('download', 'icon')
17
-
18
- const buttonElement = document.createElement('button')
19
- buttonElement.classList.add('ui', 'compact', 'labeled', 'icon', 'button')
20
- buttonElement.setAttribute('type', 'button')
21
- buttonElement.append(iconElement)
22
- buttonElement.innerHTML += `${downloadText}: ${fileTitle}`
23
-
24
- const downloadLink = document.createElement('a')
25
- downloadLink.setAttribute('style', 'display: inline-block; margin: -5px 0 25px 0;')
26
- downloadLink.setAttribute('target', '_blank')
27
- downloadLink.setAttribute('href', fileUrl)
28
- downloadLink.append(buttonElement)
29
-
30
- inputElement.parentNode.parentNode.append(downloadLink)
31
- })
32
- }
33
- }
@@ -1,41 +0,0 @@
1
- export default class ImageInput {
2
- constructor(selector) {
3
- this.selector = selector
4
- }
5
-
6
- init() {
7
- document.querySelectorAll(this.selector).forEach((element) => {
8
- element.querySelectorAll('input[type="file"]').forEach((input) => {
9
- input.addEventListener('change', () => {
10
- this.onImageInputChange(input)
11
- })
12
- })
13
- })
14
- }
15
-
16
- onImageInputChange(input) {
17
- if (!input.files || !input.files[0]) {
18
- return
19
- }
20
-
21
- const reader = new FileReader()
22
-
23
- reader.onload = (event) => {
24
- const wrapperDiv = input.parentElement.parentElement
25
- const image = wrapperDiv.querySelector('.image')
26
-
27
- if (null === image) {
28
- const img = document.createElement('img')
29
- img.setAttribute('class', 'ui small bordered image')
30
- img.setAttribute('src', event.target.result)
31
-
32
- const inputLabel = wrapperDiv.querySelector(':scope > label')
33
- wrapperDiv.insertBefore(img, inputLabel.nextSibling)
34
- } else {
35
- image.setAttribute('src', event.target.result)
36
- }
37
- }
38
-
39
- reader.readAsDataURL(input.files[0])
40
- }
41
- }
@@ -1,86 +0,0 @@
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
- }