mirror of
https://github.com/Sylius/Sylius.git
synced 2026-07-03 03:37:12 +00:00
Lint project files
This commit is contained in:
parent
1b9d3adaf8
commit
23fcad77c8
24 changed files with 638 additions and 644 deletions
|
|
@ -2,20 +2,20 @@ import js from '@eslint/js';
|
|||
import globals from 'globals';
|
||||
|
||||
export default [
|
||||
js.configs.recommended,
|
||||
{
|
||||
ignores: ['vendor/', 'node_modules/', 'public/'],
|
||||
},
|
||||
{
|
||||
languageOptions: {
|
||||
globals: {
|
||||
...globals.browser,
|
||||
...globals.node,
|
||||
}
|
||||
js.configs.recommended,
|
||||
{
|
||||
ignores: ['vendor/', 'node_modules/', 'public/'],
|
||||
},
|
||||
rules: {
|
||||
indent: ['error', 4],
|
||||
semi: ['error', 'always'],
|
||||
{
|
||||
languageOptions: {
|
||||
globals: {
|
||||
...globals.browser,
|
||||
...globals.node,
|
||||
}
|
||||
},
|
||||
rules: {
|
||||
indent: ['error', 4],
|
||||
semi: ['error', 'always'],
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
|
|
|
|||
|
|
@ -22,9 +22,9 @@ import TabsErrorsController from './controllers/TabsErrorsController';
|
|||
|
||||
// Registers Stimulus controllers from controllers.json and in the controllers/ directory
|
||||
export const app = startStimulusApp(require.context(
|
||||
'@symfony/stimulus-bridge/lazy-controller-loader!./controllers',
|
||||
true,
|
||||
/\.[jt]sx?$/
|
||||
'@symfony/stimulus-bridge/lazy-controller-loader!./controllers',
|
||||
true,
|
||||
/\.[jt]sx?$/
|
||||
));
|
||||
|
||||
app.register('live', LiveController);
|
||||
|
|
|
|||
|
|
@ -11,22 +11,22 @@ import { Controller } from '@hotwired/stimulus';
|
|||
import { Modal } from 'bootstrap';
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = ['modal', 'parent', 'csrfToken'];
|
||||
static targets = ['modal', 'parent', 'csrfToken'];
|
||||
|
||||
connect() {
|
||||
this.element.addEventListener('sylius_admin:taxon:open_delete_modal', (event) => {
|
||||
this.csrfTokenTarget.value = event.detail.csrfToken;
|
||||
this.modalElement = this.modalTarget;
|
||||
connect() {
|
||||
this.element.addEventListener('sylius_admin:taxon:open_delete_modal', (event) => {
|
||||
this.csrfTokenTarget.value = event.detail.csrfToken;
|
||||
this.modalElement = this.modalTarget;
|
||||
|
||||
this.modalElement.closest(".dropdown").appendChild(this.modalElement);
|
||||
this.modal = new Modal(this.modalElement);
|
||||
this.modal.show();
|
||||
this.modalElement.closest(".dropdown").appendChild(this.modalElement);
|
||||
this.modal = new Modal(this.modalElement);
|
||||
this.modal.show();
|
||||
|
||||
this.modalElement.addEventListener(
|
||||
'hidden.bs.modal',
|
||||
() => {this.parentTarget.appendChild(this.modalElement);},
|
||||
{once: true}
|
||||
);
|
||||
});
|
||||
}
|
||||
this.modalElement.addEventListener(
|
||||
'hidden.bs.modal',
|
||||
() => {this.parentTarget.appendChild(this.modalElement);},
|
||||
{once: true}
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,48 +10,48 @@
|
|||
import AutocompleteController from '@symfony/ux-autocomplete';
|
||||
|
||||
export default class extends AutocompleteController {
|
||||
observer;
|
||||
connected = false;
|
||||
observer;
|
||||
connected = false;
|
||||
|
||||
initialize() {
|
||||
super.initialize();
|
||||
initialize() {
|
||||
super.initialize();
|
||||
|
||||
this.element.addEventListener('change', () => {
|
||||
this.tomSelect.sync();
|
||||
});
|
||||
this.observer = new MutationObserver((mutations) => {
|
||||
mutations.forEach((mutation) => {
|
||||
this.tomSelect.sync();
|
||||
});
|
||||
});
|
||||
window.addEventListener('sylius_admin.product_attribute_autocomplete.clear_requested', () => {
|
||||
this.tomSelect.clear();
|
||||
});
|
||||
}
|
||||
|
||||
connect() {
|
||||
super.connect();
|
||||
|
||||
this.observer.observe(this.element, { attributes: true });
|
||||
|
||||
this.connected = true;
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
super.disconnect();
|
||||
|
||||
this.observer.disconnect();
|
||||
|
||||
this.connected = false;
|
||||
}
|
||||
|
||||
urlValueChanged() {
|
||||
if (!this.connected) {
|
||||
return;
|
||||
this.element.addEventListener('change', () => {
|
||||
this.tomSelect.sync();
|
||||
});
|
||||
this.observer = new MutationObserver((mutations) => {
|
||||
mutations.forEach(() => {
|
||||
this.tomSelect.sync();
|
||||
});
|
||||
});
|
||||
window.addEventListener('sylius_admin.product_attribute_autocomplete.clear_requested', () => {
|
||||
this.tomSelect.clear();
|
||||
});
|
||||
}
|
||||
|
||||
this.disconnect();
|
||||
this.connect();
|
||||
this.tomSelect.refreshItems();
|
||||
}
|
||||
connect() {
|
||||
super.connect();
|
||||
|
||||
this.observer.observe(this.element, { attributes: true });
|
||||
|
||||
this.connected = true;
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
super.disconnect();
|
||||
|
||||
this.observer.disconnect();
|
||||
|
||||
this.connected = false;
|
||||
}
|
||||
|
||||
urlValueChanged() {
|
||||
if (!this.connected) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.disconnect();
|
||||
this.connect();
|
||||
this.tomSelect.refreshItems();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,52 +11,52 @@ import { Controller } from '@hotwired/stimulus';
|
|||
import InfiniteTree from "infinite-tree";
|
||||
|
||||
export default class extends Controller {
|
||||
static values = {
|
||||
treeData: Array,
|
||||
autoOpen: Boolean,
|
||||
};
|
||||
static targets = ['tree', 'filter', 'productTaxons'];
|
||||
static values = {
|
||||
treeData: Array,
|
||||
autoOpen: Boolean,
|
||||
};
|
||||
static targets = ['tree', 'filter', 'productTaxons'];
|
||||
|
||||
connect() {
|
||||
this.tree = this.createInfiniteTree();
|
||||
connect() {
|
||||
this.tree = this.createInfiniteTree();
|
||||
|
||||
this.tree.on('contentDidUpdate', () => this.updateIndeterminateState());
|
||||
this.tree.on('clusterDidChange', () => this.updateIndeterminateState());
|
||||
this.tree.on('checkNode', (node) => this.updateProductTaxons(node));
|
||||
this.tree.on('contentDidUpdate', () => this.updateIndeterminateState());
|
||||
this.tree.on('clusterDidChange', () => this.updateIndeterminateState());
|
||||
this.tree.on('checkNode', (node) => this.updateProductTaxons(node));
|
||||
|
||||
this.checkInitialNodes();
|
||||
}
|
||||
|
||||
createInfiniteTree() {
|
||||
return new InfiniteTree({
|
||||
el: this.treeTarget,
|
||||
data: this.treeDataValue,
|
||||
autoOpen: this.autoOpenValue,
|
||||
selectable: false,
|
||||
rowRenderer: this.rowRenderer,
|
||||
});
|
||||
}
|
||||
|
||||
rowRenderer(node, treeOptions) {
|
||||
const { id, name, children, state } = node;
|
||||
const { depth, open, path, total, filtered, checked, indeterminate } = state;
|
||||
const more = node.hasChildren();
|
||||
const nodeMargin = 20;
|
||||
|
||||
if (filtered === false) {
|
||||
return '';
|
||||
this.checkInitialNodes();
|
||||
}
|
||||
|
||||
let togglerClass = '';
|
||||
if (more) {
|
||||
togglerClass = open ? 'infinite-tree-open' : 'infinite-tree-closed';
|
||||
createInfiniteTree() {
|
||||
return new InfiniteTree({
|
||||
el: this.treeTarget,
|
||||
data: this.treeDataValue,
|
||||
autoOpen: this.autoOpenValue,
|
||||
selectable: false,
|
||||
rowRenderer: this.rowRenderer,
|
||||
});
|
||||
}
|
||||
|
||||
const toggler = `<span class="${treeOptions.togglerClass} ${togglerClass}" style="width: ${nodeMargin}px"></span>`;
|
||||
const checkbox = `<span class="infinite-tree-check" style="width: ${nodeMargin}px;"><input class="form-check-input" type="checkbox" data-action="product-taxon-tree#clickNode" ${indeterminate && !checked ? 'data-indeterminate' : ''} ${checked ? 'checked' : ''}></span>`;
|
||||
const treeNode = `<div class="infinite-tree-node" style="margin-left: ${(depth * nodeMargin)}px">${toggler}${checkbox}<span class="infinite-tree-title">${name}</span></div>`;
|
||||
rowRenderer(node, treeOptions) {
|
||||
const { id, name, children, state } = node;
|
||||
const { depth, open, path, total, filtered, checked, indeterminate } = state;
|
||||
const more = node.hasChildren();
|
||||
const nodeMargin = 20;
|
||||
|
||||
return `<div
|
||||
if (filtered === false) {
|
||||
return '';
|
||||
}
|
||||
|
||||
let togglerClass = '';
|
||||
if (more) {
|
||||
togglerClass = open ? 'infinite-tree-open' : 'infinite-tree-closed';
|
||||
}
|
||||
|
||||
const toggler = `<span class="${treeOptions.togglerClass} ${togglerClass}" style="width: ${nodeMargin}px"></span>`;
|
||||
const checkbox = `<span class="infinite-tree-check" style="width: ${nodeMargin}px;"><input class="form-check-input" type="checkbox" data-action="product-taxon-tree#clickNode" ${indeterminate && !checked ? 'data-indeterminate' : ''} ${checked ? 'checked' : ''}></span>`;
|
||||
const treeNode = `<div class="infinite-tree-node" style="margin-left: ${(depth * nodeMargin)}px">${toggler}${checkbox}<span class="infinite-tree-title">${name}</span></div>`;
|
||||
|
||||
return `<div
|
||||
data-id="${id}"
|
||||
data-expanded="${more && open}"
|
||||
data-depth="${depth}"
|
||||
|
|
@ -67,106 +67,106 @@ export default class extends Controller {
|
|||
>
|
||||
${treeNode}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
clickNode(event) {
|
||||
const id = event.target.closest('.infinite-tree-item').dataset.id;
|
||||
this.checkNode(this.tree.getNodeById(id));
|
||||
}
|
||||
|
||||
checkNode(node, checked) {
|
||||
if (true === checked) {
|
||||
node.state.checked = true;
|
||||
} else if (false === checked) {
|
||||
node.state.checked = false;
|
||||
} else {
|
||||
node.state.checked = node.state.checked === undefined ? true : !node.state.checked;
|
||||
}
|
||||
|
||||
const topParentNode = this.updateParentNodes(node);
|
||||
this.tree.updateNode(topParentNode);
|
||||
this.tree.emit('checkNode', node);
|
||||
}
|
||||
clickNode(event) {
|
||||
const id = event.target.closest('.infinite-tree-item').dataset.id;
|
||||
this.checkNode(this.tree.getNodeById(id));
|
||||
}
|
||||
|
||||
updateParentNodes(childNode) {
|
||||
let parentNode = childNode;
|
||||
|
||||
while (parentNode.parent && parentNode.parent.state.depth >= 0) {
|
||||
parentNode = parentNode.parent;
|
||||
let checkedCount = 0;
|
||||
let indeterminate = false;
|
||||
|
||||
parentNode.children.forEach((childNode) => {
|
||||
indeterminate = indeterminate || !!childNode.state.indeterminate;
|
||||
if (childNode.state.checked) {
|
||||
checkedCount++;
|
||||
checkNode(node, checked) {
|
||||
if (true === checked) {
|
||||
node.state.checked = true;
|
||||
} else if (false === checked) {
|
||||
node.state.checked = false;
|
||||
} else {
|
||||
node.state.checked = node.state.checked === undefined ? true : !node.state.checked;
|
||||
}
|
||||
});
|
||||
|
||||
if (checkedCount > 0 || indeterminate) {
|
||||
parentNode.state.indeterminate = true;
|
||||
} else if (checkedCount === 0) {
|
||||
parentNode.state.indeterminate = false;
|
||||
}
|
||||
const topParentNode = this.updateParentNodes(node);
|
||||
this.tree.updateNode(topParentNode);
|
||||
this.tree.emit('checkNode', node);
|
||||
}
|
||||
|
||||
return parentNode;
|
||||
}
|
||||
updateParentNodes(childNode) {
|
||||
let parentNode = childNode;
|
||||
|
||||
updateIndeterminateState() {
|
||||
const checkboxes = this.tree.contentElement.querySelectorAll('input[type="checkbox"]');
|
||||
for (const checkbox of checkboxes) {
|
||||
checkbox.indeterminate = checkbox.hasAttribute('data-indeterminate');
|
||||
}
|
||||
}
|
||||
while (parentNode.parent && parentNode.parent.state.depth >= 0) {
|
||||
parentNode = parentNode.parent;
|
||||
let checkedCount = 0;
|
||||
let indeterminate = false;
|
||||
|
||||
updateProductTaxons(node) {
|
||||
let values = this.productTaxonsTarget.value.split(',').filter(Boolean);
|
||||
parentNode.children.forEach((childNode) => {
|
||||
indeterminate = indeterminate || !!childNode.state.indeterminate;
|
||||
if (childNode.state.checked) {
|
||||
checkedCount++;
|
||||
}
|
||||
});
|
||||
|
||||
if (false === node.state.checked) {
|
||||
values.splice(values.indexOf(node.id), 1);
|
||||
} else if (!values.includes(node.id)) {
|
||||
values.push(node.id);
|
||||
if (checkedCount > 0 || indeterminate) {
|
||||
parentNode.state.indeterminate = true;
|
||||
} else if (checkedCount === 0) {
|
||||
parentNode.state.indeterminate = false;
|
||||
}
|
||||
}
|
||||
|
||||
return parentNode;
|
||||
}
|
||||
|
||||
this.productTaxonsTarget.value = values.join();
|
||||
}
|
||||
updateIndeterminateState() {
|
||||
const checkboxes = this.tree.contentElement.querySelectorAll('input[type="checkbox"]');
|
||||
for (const checkbox of checkboxes) {
|
||||
checkbox.indeterminate = checkbox.hasAttribute('data-indeterminate');
|
||||
}
|
||||
}
|
||||
|
||||
checkInitialNodes() {
|
||||
this.productTaxonsTarget.value.split(',').filter(Boolean).forEach((productTaxonCode) => {
|
||||
this.checkNode(this.tree.getNodeById(productTaxonCode));
|
||||
});
|
||||
}
|
||||
updateProductTaxons(node) {
|
||||
let values = this.productTaxonsTarget.value.split(',').filter(Boolean);
|
||||
|
||||
filter(event) {
|
||||
this.tree.filter(event.target.value, {
|
||||
caseSensitive: false,
|
||||
exactMatch: false,
|
||||
includeAncestors: true,
|
||||
includeDescendants: true,
|
||||
});
|
||||
}
|
||||
if (false === node.state.checked) {
|
||||
values.splice(values.indexOf(node.id), 1);
|
||||
} else if (!values.includes(node.id)) {
|
||||
values.push(node.id);
|
||||
}
|
||||
|
||||
clearFilter() {
|
||||
this.filterTarget.value = '';
|
||||
this.tree.unfilter();
|
||||
}
|
||||
this.productTaxonsTarget.value = values.join();
|
||||
}
|
||||
|
||||
checkAll(event) {
|
||||
event.preventDefault();
|
||||
this.toggleAllNodes(true);
|
||||
}
|
||||
checkInitialNodes() {
|
||||
this.productTaxonsTarget.value.split(',').filter(Boolean).forEach((productTaxonCode) => {
|
||||
this.checkNode(this.tree.getNodeById(productTaxonCode));
|
||||
});
|
||||
}
|
||||
|
||||
uncheckAll(event) {
|
||||
event.preventDefault();
|
||||
this.toggleAllNodes(false);
|
||||
}
|
||||
filter(event) {
|
||||
this.tree.filter(event.target.value, {
|
||||
caseSensitive: false,
|
||||
exactMatch: false,
|
||||
includeAncestors: true,
|
||||
includeDescendants: true,
|
||||
});
|
||||
}
|
||||
|
||||
toggleAllNodes(isChecked) {
|
||||
this.tree.nodes.forEach((node) => {
|
||||
if (!this.tree.filtered || node.state.filtered) {
|
||||
this.checkNode(node, isChecked);
|
||||
}
|
||||
});
|
||||
}
|
||||
clearFilter() {
|
||||
this.filterTarget.value = '';
|
||||
this.tree.unfilter();
|
||||
}
|
||||
|
||||
checkAll(event) {
|
||||
event.preventDefault();
|
||||
this.toggleAllNodes(true);
|
||||
}
|
||||
|
||||
uncheckAll(event) {
|
||||
event.preventDefault();
|
||||
this.toggleAllNodes(false);
|
||||
}
|
||||
|
||||
toggleAllNodes(isChecked) {
|
||||
this.tree.nodes.forEach((node) => {
|
||||
if (!this.tree.filtered || node.state.filtered) {
|
||||
this.checkNode(node, isChecked);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,47 +10,47 @@
|
|||
import { Controller } from '@hotwired/stimulus';
|
||||
|
||||
export default class extends Controller {
|
||||
static values = {
|
||||
url: String,
|
||||
csrfToken: String,
|
||||
inputSelector: String,
|
||||
dataKey: String
|
||||
};
|
||||
changedPositions = [];
|
||||
|
||||
connect() {
|
||||
document.querySelectorAll(this.inputSelectorValue).forEach(input => {
|
||||
input.addEventListener('change', (event) => this.handlePositionChange(event));
|
||||
});
|
||||
}
|
||||
|
||||
handlePositionChange(event) {
|
||||
const input = event.target;
|
||||
const elementId = input.getAttribute('data-id');
|
||||
const changedPosition = this.changedPositions.find(({ id }) => id === elementId);
|
||||
|
||||
if (!changedPosition) {
|
||||
this.changedPositions.push({ id: elementId, position: input.value });
|
||||
} else {
|
||||
changedPosition.position = input.value;
|
||||
}
|
||||
}
|
||||
|
||||
submit() {
|
||||
const requestOptions = {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ [this.dataKeyValue]: this.changedPositions, _csrf_token: this.csrfTokenValue}),
|
||||
static values = {
|
||||
url: String,
|
||||
csrfToken: String,
|
||||
inputSelector: String,
|
||||
dataKey: String
|
||||
};
|
||||
changedPositions = [];
|
||||
|
||||
fetch(this.urlValue, requestOptions)
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to move positions.');
|
||||
connect() {
|
||||
document.querySelectorAll(this.inputSelectorValue).forEach(input => {
|
||||
input.addEventListener('change', (event) => this.handlePositionChange(event));
|
||||
});
|
||||
}
|
||||
|
||||
handlePositionChange(event) {
|
||||
const input = event.target;
|
||||
const elementId = input.getAttribute('data-id');
|
||||
const changedPosition = this.changedPositions.find(({ id }) => id === elementId);
|
||||
|
||||
if (!changedPosition) {
|
||||
this.changedPositions.push({ id: elementId, position: input.value });
|
||||
} else {
|
||||
changedPosition.position = input.value;
|
||||
}
|
||||
}
|
||||
|
||||
window.location.reload();
|
||||
})
|
||||
.catch(error => console.error(error.message));
|
||||
}
|
||||
submit() {
|
||||
const requestOptions = {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ [this.dataKeyValue]: this.changedPositions, _csrf_token: this.csrfTokenValue}),
|
||||
};
|
||||
|
||||
fetch(this.urlValue, requestOptions)
|
||||
.then(response => {
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to move positions.');
|
||||
}
|
||||
|
||||
window.location.reload();
|
||||
})
|
||||
.catch(error => console.error(error.message));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,21 +7,21 @@
|
|||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
import {ApplicationController, useDebounce} from 'stimulus-use'
|
||||
import {ApplicationController, useDebounce} from 'stimulus-use';
|
||||
import slugify from 'slugify';
|
||||
|
||||
export default class extends ApplicationController {
|
||||
static debounces = ['generateSlug']
|
||||
static targets = [ 'sluggable', 'slug' ]
|
||||
static values = { locale: String }
|
||||
static debounces = ['generateSlug'];
|
||||
static targets = [ 'sluggable', 'slug' ];
|
||||
static values = { locale: String };
|
||||
|
||||
connect() {
|
||||
useDebounce(this);
|
||||
}
|
||||
connect() {
|
||||
useDebounce(this);
|
||||
}
|
||||
|
||||
generateSlug() {
|
||||
this.element.setAttribute('busy', '');
|
||||
this.slugTarget.value = slugify(this.sluggableTarget.value, { locale: this.localeValue, lower: true });
|
||||
this.element.removeAttribute('busy');
|
||||
}
|
||||
generateSlug() {
|
||||
this.element.setAttribute('busy', '');
|
||||
this.slugTarget.value = slugify(this.sluggableTarget.value, { locale: this.localeValue, lower: true });
|
||||
this.element.removeAttribute('busy');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,58 +10,58 @@
|
|||
import { Controller } from '@hotwired/stimulus';
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = ['tab'];
|
||||
observer;
|
||||
static targets = ['tab'];
|
||||
observer;
|
||||
|
||||
initialize() {
|
||||
this.observer = new MutationObserver(() => {
|
||||
this.findErrors();
|
||||
});
|
||||
}
|
||||
|
||||
connect() {
|
||||
this.findErrors();
|
||||
this.observe();
|
||||
}
|
||||
|
||||
findErrors() {
|
||||
this.tabTargets.forEach((tab) => {
|
||||
const tabContentId = tab.attributes['data-bs-target'].value;
|
||||
const errorsCount = this.countTabErrors(this.element.querySelector(tabContentId));
|
||||
|
||||
if (errorsCount > 0) {
|
||||
this.appendIndicator(tab, errorsCount)
|
||||
} else {
|
||||
this.removeIndicator(tab)
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
countTabErrors(target) {
|
||||
return target.querySelectorAll('.is-invalid').length;
|
||||
}
|
||||
|
||||
appendIndicator(target, errorsCount) {
|
||||
const errorElement = document.createElement('div');
|
||||
const errorContainer = target.querySelector('.tab-icons');
|
||||
|
||||
errorElement.classList.add('tab-error');
|
||||
errorElement.innerText = errorsCount;
|
||||
|
||||
if (!errorContainer.querySelector('.tab-error')) {
|
||||
errorContainer.insertBefore(errorElement, errorContainer.firstChild);
|
||||
initialize() {
|
||||
this.observer = new MutationObserver(() => {
|
||||
this.findErrors();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
removeIndicator(tab) {
|
||||
const errorBadge = tab.querySelector('.tab-error');
|
||||
|
||||
if (errorBadge) {
|
||||
errorBadge.remove();
|
||||
connect() {
|
||||
this.findErrors();
|
||||
this.observe();
|
||||
}
|
||||
}
|
||||
|
||||
observe() {
|
||||
this.observer.observe(this.element.querySelector('#product_attribute_tabs'), { attributes: false, childList: true, subtree: false });
|
||||
}
|
||||
findErrors() {
|
||||
this.tabTargets.forEach((tab) => {
|
||||
const tabContentId = tab.attributes['data-bs-target'].value;
|
||||
const errorsCount = this.countTabErrors(this.element.querySelector(tabContentId));
|
||||
|
||||
if (errorsCount > 0) {
|
||||
this.appendIndicator(tab, errorsCount);
|
||||
} else {
|
||||
this.removeIndicator(tab);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
countTabErrors(target) {
|
||||
return target.querySelectorAll('.is-invalid').length;
|
||||
}
|
||||
|
||||
appendIndicator(target, errorsCount) {
|
||||
const errorElement = document.createElement('div');
|
||||
const errorContainer = target.querySelector('.tab-icons');
|
||||
|
||||
errorElement.classList.add('tab-error');
|
||||
errorElement.innerText = errorsCount;
|
||||
|
||||
if (!errorContainer.querySelector('.tab-error')) {
|
||||
errorContainer.insertBefore(errorElement, errorContainer.firstChild);
|
||||
}
|
||||
}
|
||||
|
||||
removeIndicator(tab) {
|
||||
const errorBadge = tab.querySelector('.tab-error');
|
||||
|
||||
if (errorBadge) {
|
||||
errorBadge.remove();
|
||||
}
|
||||
}
|
||||
|
||||
observe() {
|
||||
this.observer.observe(this.element.querySelector('#product_attribute_tabs'), { attributes: false, childList: true, subtree: false });
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,30 +10,30 @@
|
|||
import {default as SlugController} from './SlugController';
|
||||
|
||||
export default class extends SlugController {
|
||||
static debounces = [ 'generateSlug' ]
|
||||
static targets = [ 'sluggable', 'slug' ]
|
||||
static values = { url: String, locale: String, parentTaxonCode: String }
|
||||
parent = document.querySelector('[data-input-id="sylius_taxon_parent"]');
|
||||
static debounces = [ 'generateSlug' ];
|
||||
static targets = [ 'sluggable', 'slug' ];
|
||||
static values = { url: String, locale: String, parentTaxonCode: String };
|
||||
parent = document.querySelector('[data-input-id="sylius_taxon_parent"]');
|
||||
|
||||
connect() {
|
||||
parent.addEventListener('change', this.onParentTaxonChange.bind(this));
|
||||
}
|
||||
connect() {
|
||||
parent.addEventListener('change', this.onParentTaxonChange.bind(this));
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
parent.removeEventListener('change', this.onParentTaxonChange.bind(this));
|
||||
}
|
||||
disconnect() {
|
||||
parent.removeEventListener('change', this.onParentTaxonChange.bind(this));
|
||||
}
|
||||
|
||||
onParentTaxonChange(event) {
|
||||
this.parentTaxonCodeValue = event.detail.value;
|
||||
this.generateSlug();
|
||||
}
|
||||
onParentTaxonChange(event) {
|
||||
this.parentTaxonCodeValue = event.detail.value;
|
||||
this.generateSlug();
|
||||
}
|
||||
|
||||
generateSlug() {
|
||||
let url = this.urlValue + '?' + new URLSearchParams({locale: this.localeValue, name: this.sluggableTarget.value, parentCode: this.parentTaxonCodeValue})
|
||||
generateSlug() {
|
||||
let url = this.urlValue + '?' + new URLSearchParams({locale: this.localeValue, name: this.sluggableTarget.value, parentCode: this.parentTaxonCodeValue});
|
||||
|
||||
fetch(url)
|
||||
.then(response => response.json())
|
||||
.then(data => { this.slugTarget.value = data.slug; })
|
||||
;
|
||||
}
|
||||
fetch(url)
|
||||
.then(response => response.json())
|
||||
.then(data => { this.slugTarget.value = data.slug; })
|
||||
;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,55 +12,55 @@ import { getComponent } from '@symfony/ux-live-component';
|
|||
import InfiniteTree from "infinite-tree";
|
||||
|
||||
export default class extends Controller {
|
||||
static values = {
|
||||
treeData: Array,
|
||||
autoOpen: Boolean,
|
||||
};
|
||||
static targets = ['tree', 'itemPrototyp'];
|
||||
static values = {
|
||||
treeData: Array,
|
||||
autoOpen: Boolean,
|
||||
};
|
||||
static targets = ['tree', 'itemPrototyp'];
|
||||
|
||||
async initialize() {
|
||||
this.component = await getComponent(this.element);
|
||||
this.tree = this.createInfiniteTree();
|
||||
async initialize() {
|
||||
this.component = await getComponent(this.element);
|
||||
this.tree = this.createInfiniteTree();
|
||||
|
||||
this.component.on('render:finished', () => {
|
||||
this.tree.loadData(this.treeDataValue);
|
||||
});
|
||||
}
|
||||
|
||||
createInfiniteTree() {
|
||||
return new InfiniteTree({
|
||||
el: this.treeTarget,
|
||||
data: this.treeDataValue,
|
||||
autoOpen: this.autoOpenValue,
|
||||
selectable: false,
|
||||
rowRenderer: (node, treeOptions) => this.rowRenderer(node, treeOptions),
|
||||
});
|
||||
}
|
||||
|
||||
rowRenderer(node, treeOptions) {
|
||||
const { id, name, children, state } = node;
|
||||
const { depth, open, path, total } = state;
|
||||
const more = node.hasChildren();
|
||||
const nodeMargin = 20;
|
||||
|
||||
let itemPrototyp = this.itemPrototypTarget.firstElementChild.cloneNode(true);
|
||||
let togglerPrototyp = itemPrototyp.querySelector('[data-infinite-tree-toggler]');
|
||||
|
||||
itemPrototyp.style.marginLeft = `${(depth * nodeMargin)}px`;
|
||||
itemPrototyp.setAttribute('data-id', id);
|
||||
itemPrototyp.setAttribute('data-expanded', more && open);
|
||||
itemPrototyp.setAttribute('data-depth', depth);
|
||||
itemPrototyp.setAttribute('data-path', path);
|
||||
itemPrototyp.setAttribute('data-children', children.length);
|
||||
itemPrototyp.setAttribute('data-total', total);
|
||||
|
||||
togglerPrototyp.style.width = `${nodeMargin}px`;
|
||||
if (more) {
|
||||
togglerPrototyp.classList.add(open ? 'infinite-tree-open' : 'infinite-tree-closed');
|
||||
} else {
|
||||
togglerPrototyp.classList.add('infinite-tree-leaf');
|
||||
this.component.on('render:finished', () => {
|
||||
this.tree.loadData(this.treeDataValue);
|
||||
});
|
||||
}
|
||||
|
||||
return itemPrototyp.outerHTML.replaceAll(`__TAXON_ID__`, id).replaceAll(`__TAXON_NAME__`, name);
|
||||
}
|
||||
createInfiniteTree() {
|
||||
return new InfiniteTree({
|
||||
el: this.treeTarget,
|
||||
data: this.treeDataValue,
|
||||
autoOpen: this.autoOpenValue,
|
||||
selectable: false,
|
||||
rowRenderer: (node, treeOptions) => this.rowRenderer(node, treeOptions),
|
||||
});
|
||||
}
|
||||
|
||||
rowRenderer(node) {
|
||||
const { id, name, children, state } = node;
|
||||
const { depth, open, path, total } = state;
|
||||
const more = node.hasChildren();
|
||||
const nodeMargin = 20;
|
||||
|
||||
let itemPrototyp = this.itemPrototypTarget.firstElementChild.cloneNode(true);
|
||||
let togglerPrototyp = itemPrototyp.querySelector('[data-infinite-tree-toggler]');
|
||||
|
||||
itemPrototyp.style.marginLeft = `${(depth * nodeMargin)}px`;
|
||||
itemPrototyp.setAttribute('data-id', id);
|
||||
itemPrototyp.setAttribute('data-expanded', more && open);
|
||||
itemPrototyp.setAttribute('data-depth', depth);
|
||||
itemPrototyp.setAttribute('data-path', path);
|
||||
itemPrototyp.setAttribute('data-children', children.length);
|
||||
itemPrototyp.setAttribute('data-total', total);
|
||||
|
||||
togglerPrototyp.style.width = `${nodeMargin}px`;
|
||||
if (more) {
|
||||
togglerPrototyp.classList.add(open ? 'infinite-tree-open' : 'infinite-tree-closed');
|
||||
} else {
|
||||
togglerPrototyp.classList.add('infinite-tree-leaf');
|
||||
}
|
||||
|
||||
return itemPrototyp.outerHTML.replaceAll(`__TAXON_ID__`, id).replaceAll(`__TAXON_NAME__`, name);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,23 +3,23 @@ import * as bootstrap from 'bootstrap';
|
|||
|
||||
// Fix dropdowns
|
||||
(() => {
|
||||
document.querySelectorAll('.dropdown-static').forEach((dropdownToggleEl) => {
|
||||
const parent = dropdownToggleEl.closest('[data-bs-toggle="dropdown"]');
|
||||
if (parent) {
|
||||
let dropdown = new bootstrap.Dropdown(parent, {
|
||||
popperConfig(defaultBsPopperConfig) {
|
||||
return { ...defaultBsPopperConfig, strategy: 'fixed' };
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
document.querySelectorAll('.dropdown-static').forEach((dropdownToggleEl) => {
|
||||
const parent = dropdownToggleEl.closest('[data-bs-toggle="dropdown"]');
|
||||
if (parent) {
|
||||
new bootstrap.Dropdown(parent, {
|
||||
popperConfig(defaultBsPopperConfig) {
|
||||
return { ...defaultBsPopperConfig, strategy: 'fixed' };
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
// Initialize tooltips
|
||||
(() => {
|
||||
document.querySelectorAll('[data-bs-toggle="tooltip"]').forEach((tooltipTriggerEl) => {
|
||||
let tooltip = new bootstrap.Tooltip(tooltipTriggerEl);
|
||||
});
|
||||
document.querySelectorAll('[data-bs-toggle="tooltip"]').forEach((tooltipTriggerEl) => {
|
||||
new bootstrap.Tooltip(tooltipTriggerEl);
|
||||
});
|
||||
})();
|
||||
|
||||
window.bootstrap = bootstrap;
|
||||
|
|
|
|||
|
|
@ -7,8 +7,6 @@
|
|||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/* global document */
|
||||
|
||||
function syliusBulkDelete(form) {
|
||||
const groupName = form.getAttribute('data-bulk-delete');
|
||||
const groupItems = Array.from(document.querySelectorAll(`input[data-check-all-group="${groupName}"]`));
|
||||
|
|
|
|||
|
|
@ -7,8 +7,6 @@
|
|||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/* global document */
|
||||
|
||||
function syliusCheckAll(trigger) {
|
||||
const groupName = trigger.getAttribute('data-check-all');
|
||||
const groupItems = Array.from(document.querySelectorAll(`[data-check-all-group="${groupName}"]`));
|
||||
|
|
@ -24,18 +22,18 @@ function syliusCheckAll(trigger) {
|
|||
groupItems.forEach((item) => {
|
||||
item.addEventListener('change', () => {
|
||||
switch (groupItems.filter((filteredItem) => filteredItem.checked).length) {
|
||||
case groupItems.length:
|
||||
trigger.indeterminate = false;
|
||||
trigger.checked = true;
|
||||
break;
|
||||
case 0:
|
||||
trigger.indeterminate = false;
|
||||
trigger.checked = false;
|
||||
break;
|
||||
default:
|
||||
trigger.indeterminate = true;
|
||||
trigger.checked = false;
|
||||
break;
|
||||
case groupItems.length:
|
||||
trigger.indeterminate = false;
|
||||
trigger.checked = true;
|
||||
break;
|
||||
case 0:
|
||||
trigger.indeterminate = false;
|
||||
trigger.checked = false;
|
||||
break;
|
||||
default:
|
||||
trigger.indeterminate = true;
|
||||
trigger.checked = false;
|
||||
break;
|
||||
}
|
||||
actionButtonsRefresh();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -7,64 +7,62 @@
|
|||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
/* global document */
|
||||
|
||||
(function() {
|
||||
const menuSearchInput = document.querySelector('[data-menu-search]');
|
||||
const menuClearButton = document.querySelector('[data-menu-search-clear]');
|
||||
const menuSearchInput = document.querySelector('[data-menu-search]');
|
||||
const menuClearButton = document.querySelector('[data-menu-search-clear]');
|
||||
|
||||
const clearInput = () => {
|
||||
menuSearchInput.value = '';
|
||||
menuSearchInput.dispatchEvent(new Event('input'));
|
||||
};
|
||||
const clearInput = () => {
|
||||
menuSearchInput.value = '';
|
||||
menuSearchInput.dispatchEvent(new Event('input'));
|
||||
};
|
||||
|
||||
if (menuSearchInput) {
|
||||
menuSearchInput.addEventListener('input', function(e) {
|
||||
const query = e.target.value.toLowerCase();
|
||||
const navItems = document.querySelectorAll('.sidebar .nav-item');
|
||||
if (menuSearchInput) {
|
||||
menuSearchInput.addEventListener('input', function(e) {
|
||||
const query = e.target.value.toLowerCase();
|
||||
const navItems = document.querySelectorAll('.sidebar .nav-item');
|
||||
|
||||
navItems.forEach(navItem => {
|
||||
const navLink = navItem.querySelector('.nav-link');
|
||||
const dropdownMenu = navItem.querySelector('.dropdown-menu');
|
||||
const dropdownItems = navItem.querySelectorAll('.dropdown-item');
|
||||
let matchFound = false;
|
||||
navItems.forEach(navItem => {
|
||||
const navLink = navItem.querySelector('.nav-link');
|
||||
const dropdownMenu = navItem.querySelector('.dropdown-menu');
|
||||
const dropdownItems = navItem.querySelectorAll('.dropdown-item');
|
||||
let matchFound = false;
|
||||
|
||||
dropdownItems.forEach(item => {
|
||||
const text = item.textContent.toLowerCase();
|
||||
if (query === '' || text.includes(query)) {
|
||||
item.style.display = '';
|
||||
matchFound = true;
|
||||
} else {
|
||||
item.style.display = 'none';
|
||||
}
|
||||
dropdownItems.forEach(item => {
|
||||
const text = item.textContent.toLowerCase();
|
||||
if (query === '' || text.includes(query)) {
|
||||
item.style.display = '';
|
||||
matchFound = true;
|
||||
} else {
|
||||
item.style.display = 'none';
|
||||
}
|
||||
});
|
||||
|
||||
if (matchFound || query === '') {
|
||||
navItem.style.display = '';
|
||||
} else {
|
||||
navItem.style.display = 'none';
|
||||
}
|
||||
|
||||
if (query !== '') {
|
||||
if (navLink) navLink.classList.add('d-flex');
|
||||
if (dropdownMenu) dropdownMenu.classList.add('d-flex');
|
||||
} else {
|
||||
if (navLink) navLink.classList.remove('d-flex');
|
||||
if (dropdownMenu) dropdownMenu.classList.remove('d-flex');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if (matchFound || query === '') {
|
||||
navItem.style.display = '';
|
||||
} else {
|
||||
navItem.style.display = 'none';
|
||||
}
|
||||
menuSearchInput.addEventListener('keydown', function(event) {
|
||||
if (event.key === 'Escape') {
|
||||
clearInput();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (query !== '') {
|
||||
if (navLink) navLink.classList.add('d-flex');
|
||||
if (dropdownMenu) dropdownMenu.classList.add('d-flex');
|
||||
} else {
|
||||
if (navLink) navLink.classList.remove('d-flex');
|
||||
if (dropdownMenu) dropdownMenu.classList.remove('d-flex');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
menuSearchInput.addEventListener('keydown', function(event) {
|
||||
if (event.key === 'Escape') {
|
||||
clearInput();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (menuClearButton) {
|
||||
menuClearButton.addEventListener('click', function() {
|
||||
clearInput();
|
||||
});
|
||||
}
|
||||
if (menuClearButton) {
|
||||
menuClearButton.addEventListener('click', function() {
|
||||
clearInput();
|
||||
});
|
||||
}
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@
|
|||
*/
|
||||
|
||||
window.addEventListener('sylius_admin:product:form:attributed_deleted', () => {
|
||||
let tabs = document.getElementById('product_attribute_tabs');
|
||||
let firstTab = tabs.querySelector('.list-group-item');
|
||||
let tabs = document.getElementById('product_attribute_tabs');
|
||||
let firstTab = tabs.querySelector('.list-group-item');
|
||||
|
||||
window.bootstrap.Tab.getOrCreateInstance(firstTab).show();
|
||||
window.bootstrap.Tab.getOrCreateInstance(firstTab).show();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -11,102 +11,102 @@ import ApexCharts from 'apexcharts';
|
|||
|
||||
let chart = null;
|
||||
function renderChart() {
|
||||
// eslint-disable-next-line no-undef
|
||||
const statisticsChart = document.querySelector('#statistics-chart');
|
||||
// eslint-disable-next-line no-undef
|
||||
const statisticsChart = document.querySelector('#statistics-chart');
|
||||
|
||||
if (!statisticsChart) {
|
||||
return;
|
||||
}
|
||||
if (!statisticsChart) {
|
||||
return;
|
||||
}
|
||||
|
||||
const options = {
|
||||
colors: ['#32be9f'],
|
||||
fill: {
|
||||
colors: ['#32be9f'],
|
||||
},
|
||||
series: [{
|
||||
name: 'Sales',
|
||||
data: JSON.parse(statisticsChart.dataset.sales),
|
||||
}],
|
||||
chart: {
|
||||
toolbar: {
|
||||
show: false,
|
||||
},
|
||||
height: 350,
|
||||
type: 'bar',
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
borderRadius: 4,
|
||||
dataLabels: {
|
||||
position: 'top', // top, center, bottom
|
||||
},
|
||||
},
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: true,
|
||||
formatter(val) {
|
||||
const { currency } = statisticsChart.dataset;
|
||||
return `${currency}${val}`;
|
||||
},
|
||||
offsetY: -20,
|
||||
style: {
|
||||
fontSize: '12px',
|
||||
colors: ['#304758'],
|
||||
},
|
||||
},
|
||||
xaxis: {
|
||||
categories: JSON.parse(statisticsChart.dataset.intervals),
|
||||
position: 'top',
|
||||
axisBorder: {
|
||||
show: false,
|
||||
},
|
||||
axisTicks: {
|
||||
show: false,
|
||||
},
|
||||
crosshairs: {
|
||||
const options = {
|
||||
colors: ['#32be9f'],
|
||||
fill: {
|
||||
type: 'gradient',
|
||||
gradient: {
|
||||
colorFrom: '#32be9f',
|
||||
colorTo: '#2a9f83',
|
||||
stops: [0, 100],
|
||||
opacityFrom: 0.4,
|
||||
opacityTo: 0.5,
|
||||
},
|
||||
colors: ['#32be9f'],
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
yaxis: {
|
||||
axisBorder: {
|
||||
show: false,
|
||||
},
|
||||
axisTicks: {
|
||||
show: false,
|
||||
},
|
||||
labels: {
|
||||
show: false,
|
||||
formatter(val) {
|
||||
const { currency } = statisticsChart.dataset;
|
||||
return `${currency}${val}`;
|
||||
series: [{
|
||||
name: 'Sales',
|
||||
data: JSON.parse(statisticsChart.dataset.sales),
|
||||
}],
|
||||
chart: {
|
||||
toolbar: {
|
||||
show: false,
|
||||
},
|
||||
height: 350,
|
||||
type: 'bar',
|
||||
},
|
||||
},
|
||||
plotOptions: {
|
||||
bar: {
|
||||
borderRadius: 4,
|
||||
dataLabels: {
|
||||
position: 'top', // top, center, bottom
|
||||
},
|
||||
},
|
||||
},
|
||||
dataLabels: {
|
||||
enabled: true,
|
||||
formatter(val) {
|
||||
const { currency } = statisticsChart.dataset;
|
||||
return `${currency}${val}`;
|
||||
},
|
||||
offsetY: -20,
|
||||
style: {
|
||||
fontSize: '12px',
|
||||
colors: ['#304758'],
|
||||
},
|
||||
},
|
||||
xaxis: {
|
||||
categories: JSON.parse(statisticsChart.dataset.intervals),
|
||||
position: 'top',
|
||||
axisBorder: {
|
||||
show: false,
|
||||
},
|
||||
axisTicks: {
|
||||
show: false,
|
||||
},
|
||||
crosshairs: {
|
||||
fill: {
|
||||
type: 'gradient',
|
||||
gradient: {
|
||||
colorFrom: '#32be9f',
|
||||
colorTo: '#2a9f83',
|
||||
stops: [0, 100],
|
||||
opacityFrom: 0.4,
|
||||
opacityTo: 0.5,
|
||||
},
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
yaxis: {
|
||||
axisBorder: {
|
||||
show: false,
|
||||
},
|
||||
axisTicks: {
|
||||
show: false,
|
||||
},
|
||||
labels: {
|
||||
show: false,
|
||||
formatter(val) {
|
||||
const { currency } = statisticsChart.dataset;
|
||||
return `${currency}${val}`;
|
||||
},
|
||||
},
|
||||
|
||||
},
|
||||
title: {
|
||||
floating: true,
|
||||
offsetY: 330,
|
||||
align: 'center',
|
||||
style: {
|
||||
color: '#444',
|
||||
},
|
||||
},
|
||||
};
|
||||
},
|
||||
title: {
|
||||
floating: true,
|
||||
offsetY: 330,
|
||||
align: 'center',
|
||||
style: {
|
||||
color: '#444',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
chart = new ApexCharts(statisticsChart, options);
|
||||
chart.render();
|
||||
chart = new ApexCharts(statisticsChart, options);
|
||||
chart.render();
|
||||
}
|
||||
|
||||
renderChart();
|
||||
|
|
@ -114,16 +114,16 @@ renderChart();
|
|||
const element = document.querySelector('#statistics-chart');
|
||||
|
||||
if (element) {
|
||||
const observer = new MutationObserver(function(mutations) {
|
||||
mutations.forEach(function(mutation) {
|
||||
if (mutation.attributeName === 'data-sales' || mutation.attributeName === 'data-intervals') {
|
||||
chart.destroy();
|
||||
renderChart();
|
||||
}
|
||||
const observer = new MutationObserver(function(mutations) {
|
||||
mutations.forEach(function(mutation) {
|
||||
if (mutation.attributeName === 'data-sales' || mutation.attributeName === 'data-intervals') {
|
||||
chart.destroy();
|
||||
renderChart();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
observer.observe(element, {
|
||||
attributes: true,
|
||||
});
|
||||
observer.observe(element, {
|
||||
attributes: true,
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
(function() {
|
||||
const el = document.querySelector('[data-sticky-header]');
|
||||
const el = document.querySelector('[data-sticky-header]');
|
||||
|
||||
const observer = new IntersectionObserver(
|
||||
([e]) => e.target.classList.toggle('is-sticky', e.intersectionRatio < 1),
|
||||
{ threshold: [1] }
|
||||
);
|
||||
const observer = new IntersectionObserver(
|
||||
([e]) => e.target.classList.toggle('is-sticky', e.intersectionRatio < 1),
|
||||
{ threshold: [1] }
|
||||
);
|
||||
|
||||
if (el) {
|
||||
observer.observe(el)
|
||||
}
|
||||
if (el) {
|
||||
observer.observe(el);
|
||||
}
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -11,31 +11,31 @@ const path = require('path');
|
|||
const Encore = require('@symfony/webpack-encore');
|
||||
|
||||
class SyliusAdmin {
|
||||
static getWebpackConfig(rootDir) {
|
||||
Encore
|
||||
.setOutputPath('public/build/admin/')
|
||||
.setPublicPath('/build/admin')
|
||||
.addEntry('admin-entry', path.resolve(__dirname, 'Resources/assets/entrypoint.js'))
|
||||
.addEntry('admin-product-entry', path.resolve(__dirname, 'Resources/assets/product-entrypoint.js'))
|
||||
.disableSingleRuntimeChunk()
|
||||
.cleanupOutputBeforeBuild()
|
||||
.enableSourceMaps(!Encore.isProduction())
|
||||
.enableVersioning(Encore.isProduction())
|
||||
.enableSassLoader((options) => {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
options.additionalData = `$rootDir: '${rootDir}';`;
|
||||
})
|
||||
.enableStimulusBridge(path.resolve(__dirname, 'Resources/assets/controllers.json'));
|
||||
static getWebpackConfig(rootDir) {
|
||||
Encore
|
||||
.setOutputPath('public/build/admin/')
|
||||
.setPublicPath('/build/admin')
|
||||
.addEntry('admin-entry', path.resolve(__dirname, 'Resources/assets/entrypoint.js'))
|
||||
.addEntry('admin-product-entry', path.resolve(__dirname, 'Resources/assets/product-entrypoint.js'))
|
||||
.disableSingleRuntimeChunk()
|
||||
.cleanupOutputBeforeBuild()
|
||||
.enableSourceMaps(!Encore.isProduction())
|
||||
.enableVersioning(Encore.isProduction())
|
||||
.enableSassLoader((options) => {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
options.additionalData = `$rootDir: '${rootDir}';`;
|
||||
})
|
||||
.enableStimulusBridge(path.resolve(__dirname, 'Resources/assets/controllers.json'));
|
||||
|
||||
const adminConfig = Encore.getWebpackConfig();
|
||||
const adminConfig = Encore.getWebpackConfig();
|
||||
|
||||
adminConfig.externals = { ...adminConfig.externals, window: 'window', document: 'document' };
|
||||
adminConfig.name = 'admin';
|
||||
adminConfig.externals = { ...adminConfig.externals, window: 'window', document: 'document' };
|
||||
adminConfig.name = 'admin';
|
||||
|
||||
Encore.reset();
|
||||
Encore.reset();
|
||||
|
||||
return adminConfig;
|
||||
}
|
||||
return adminConfig;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = SyliusAdmin;
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@ import ApiLoginController from './controllers/ApiLoginController';
|
|||
|
||||
// Registers Stimulus controllers from controllers.json and in the controllers/ directory
|
||||
export const app = startStimulusApp(require.context(
|
||||
'@symfony/stimulus-bridge/lazy-controller-loader!./controllers',
|
||||
true,
|
||||
/\.[jt]sx?$/
|
||||
'@symfony/stimulus-bridge/lazy-controller-loader!./controllers',
|
||||
true,
|
||||
/\.[jt]sx?$/
|
||||
));
|
||||
|
||||
app.register('live', LiveController);
|
||||
|
|
|
|||
|
|
@ -10,34 +10,34 @@
|
|||
import { Controller } from '@hotwired/stimulus';
|
||||
|
||||
export default class extends Controller {
|
||||
static values = { url: String };
|
||||
static targets = ['email', 'password', 'csrfToken', 'error', 'errorPrototype'];
|
||||
static values = { url: String };
|
||||
static targets = ['email', 'password', 'csrfToken', 'error', 'errorPrototype'];
|
||||
|
||||
login() {
|
||||
const requestOptions = {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
_username: this.emailTarget.value,
|
||||
_password: this.passwordTarget.value,
|
||||
[this.csrfTokenTarget.name]: this.csrfTokenTarget.value,
|
||||
}),
|
||||
};
|
||||
login() {
|
||||
const requestOptions = {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-Requested-With': 'XMLHttpRequest',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
_username: this.emailTarget.value,
|
||||
_password: this.passwordTarget.value,
|
||||
[this.csrfTokenTarget.name]: this.csrfTokenTarget.value,
|
||||
}),
|
||||
};
|
||||
|
||||
fetch(this.urlValue, requestOptions)
|
||||
.then(response => response.json())
|
||||
.then(response => {
|
||||
if (response.success) {
|
||||
window.location.reload();
|
||||
} else {
|
||||
const errorElement = this.errorPrototypeTarget.cloneNode(true);
|
||||
errorElement.innerHTML = response.message;
|
||||
this.errorTarget.innerHTML = errorElement.outerHTML;
|
||||
}
|
||||
})
|
||||
;
|
||||
}
|
||||
fetch(this.urlValue, requestOptions)
|
||||
.then(response => response.json())
|
||||
.then(response => {
|
||||
if (response.success) {
|
||||
window.location.reload();
|
||||
} else {
|
||||
const errorElement = this.errorPrototypeTarget.cloneNode(true);
|
||||
errorElement.innerHTML = response.message;
|
||||
this.errorTarget.innerHTML = errorElement.outerHTML;
|
||||
}
|
||||
})
|
||||
;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,4 +7,5 @@
|
|||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
import * as bootstrap from 'bootstrap';
|
||||
|
|
|
|||
|
|
@ -11,30 +11,30 @@ const path = require('path');
|
|||
const Encore = require('@symfony/webpack-encore');
|
||||
|
||||
class SyliusShop {
|
||||
static getWebpackConfig(rootDir) {
|
||||
Encore
|
||||
.setOutputPath('public/build/shop/')
|
||||
.setPublicPath('/build/shop')
|
||||
.addEntry('shop-entry', path.resolve(__dirname, 'Resources/assets/entrypoint.js'))
|
||||
.disableSingleRuntimeChunk()
|
||||
.cleanupOutputBeforeBuild()
|
||||
.enableSourceMaps(!Encore.isProduction())
|
||||
.enableVersioning(Encore.isProduction())
|
||||
.enableSassLoader((options) => {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
options.additionalData = `$rootDir: '${rootDir}';`;
|
||||
})
|
||||
.enableStimulusBridge(path.resolve(__dirname, 'Resources/assets/controllers.json'));
|
||||
static getWebpackConfig(rootDir) {
|
||||
Encore
|
||||
.setOutputPath('public/build/shop/')
|
||||
.setPublicPath('/build/shop')
|
||||
.addEntry('shop-entry', path.resolve(__dirname, 'Resources/assets/entrypoint.js'))
|
||||
.disableSingleRuntimeChunk()
|
||||
.cleanupOutputBeforeBuild()
|
||||
.enableSourceMaps(!Encore.isProduction())
|
||||
.enableVersioning(Encore.isProduction())
|
||||
.enableSassLoader((options) => {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
options.additionalData = `$rootDir: '${rootDir}';`;
|
||||
})
|
||||
.enableStimulusBridge(path.resolve(__dirname, 'Resources/assets/controllers.json'));
|
||||
|
||||
const shopConfig = Encore.getWebpackConfig();
|
||||
const shopConfig = Encore.getWebpackConfig();
|
||||
|
||||
shopConfig.externals = { ...shopConfig.externals, window: 'window', document: 'document' };
|
||||
shopConfig.name = 'shop';
|
||||
shopConfig.externals = { ...shopConfig.externals, window: 'window', document: 'document' };
|
||||
shopConfig.name = 'shop';
|
||||
|
||||
Encore.reset();
|
||||
Encore.reset();
|
||||
|
||||
return shopConfig;
|
||||
}
|
||||
return shopConfig;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = SyliusShop;
|
||||
|
|
|
|||
|
|
@ -1,20 +1,20 @@
|
|||
module.exports = {
|
||||
extends: 'airbnb-base',
|
||||
env: {
|
||||
browser: true,
|
||||
},
|
||||
rules: {
|
||||
'object-shorthand': ['error', 'always', {
|
||||
avoidQuotes: true,
|
||||
avoidExplicitReturnArrows: true,
|
||||
}],
|
||||
'function-paren-newline': ['error', 'consistent'],
|
||||
'max-len': ['warn', 120, 2, {
|
||||
ignoreUrls: true,
|
||||
ignoreComments: false,
|
||||
ignoreRegExpLiterals: true,
|
||||
ignoreStrings: true,
|
||||
ignoreTemplateLiterals: true,
|
||||
}],
|
||||
},
|
||||
extends: 'airbnb-base',
|
||||
env: {
|
||||
browser: true,
|
||||
},
|
||||
rules: {
|
||||
'object-shorthand': ['error', 'always', {
|
||||
avoidQuotes: true,
|
||||
avoidExplicitReturnArrows: true,
|
||||
}],
|
||||
'function-paren-newline': ['error', 'consistent'],
|
||||
'max-len': ['warn', 120, 2, {
|
||||
ignoreUrls: true,
|
||||
ignoreComments: false,
|
||||
ignoreRegExpLiterals: true,
|
||||
ignoreStrings: true,
|
||||
ignoreTemplateLiterals: true,
|
||||
}],
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
const path = require('path');
|
||||
const Encore = require('@symfony/webpack-encore');
|
||||
|
||||
const SyliusAdmin = require('@sylius-ui/admin');
|
||||
const SyliusShop = require('@sylius-ui/shop');
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue