Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

flat-tree-builder

Package Overview
Dependencies
Maintainers
1
Versions
62
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

flat-tree-builder - npm Package Compare versions

Comparing version 1.5.23 to 1.5.24

.idea/codeStyles/codeStyleConfig.xml

3

package.json
{
"name": "flat-tree-builder",
"version": "1.5.23",
"version": "1.5.24",
"description": "A package for building tree structures from postgres ltree data",

@@ -12,2 +12,3 @@ "main": "classifier.mjs",

"bootstrap": "^5.3.2",
"prettier": "^3.2.5",
"sortablejs": "^1.15.0"

@@ -14,0 +15,0 @@ },

import Sortable from "sortablejs";
import {isRootPath} from "./utils/funcitons.js";
import {mainMarkup, mockResponse, modalMarkup, searchMarkup} from "./utils/static.js";
import {create, del, edit, sort} from "./utils/api.js";
import {createDeleteBtn, createSortElements} from "./utils/UI.js";
import {settingsIcon, toggleIcon} from "./utils/icons.js";
import { isRootPath } from "./utils/funcitons.js";
import { mainMarkup, mockResponse, modalMarkup, searchMarkup } from "./utils/static.js";
import { create, del, edit, sort } from "./utils/api.js";
import { createDeleteBtn, createSortElements } from "./utils/UI.js";
import { settingsIcon, toggleIcon } from "./utils/icons.js";
export default class Classifier {
#deleteBlock = {}
#deleteBlock = {};
constructor(
targetElId,
{
getUrl,
postClassifierUrl,
postOrderUrl,
delUrl,
paramsName = "classifier",
selectedIds = [],
search = false,
test = false,
draggable = false,
isRootSelectable = true,
}
) {
this.targetInput = document.querySelector(targetElId);
if (!this.targetInput) {
console.log(`Failed to find the element: ${targetElId}`);
return null;
}
this.hideElem(this.targetInput);
const div = document.createElement("div");
this.targetInput.insertAdjacentElement("afterend", div);
this.targetEl = div;
constructor(
targetElId,
{
getUrl,
postClassifierUrl,
postOrderUrl,
delUrl,
paramsName = "classifier",
selectedIds = [],
search = false,
test = false,
draggable = false,
isRootSelectable = true,
},
) {
this.targetInput = document.querySelector(targetElId);
if (!this.targetInput) {
console.log(`Failed to find the element: ${targetElId}`);
return null;
}
this.hideElem(this.targetInput);
const div = document.createElement("div");
this.targetInput.insertAdjacentElement("afterend", div);
this.targetEl = div;
if (selectedIds?.length && selectedIds instanceof Array)
this.selectedIds = new Set(selectedIds.map(parseFloat));
else this.selectedIds = new Set();
if (selectedIds?.length && selectedIds instanceof Array)
this.selectedIds = new Set(selectedIds.map(parseFloat));
else this.selectedIds = new Set();
const storageSortedIds = JSON.parse(localStorage.getItem('classifierSortedIds'))
const storageSortedIds = JSON.parse(localStorage.getItem("classifierSortedIds"));
if (storageSortedIds) this.sortedIds = new Set(storageSortedIds);
else this.sortedIds = new Set();
if (storageSortedIds) this.sortedIds = new Set(storageSortedIds);
else this.sortedIds = new Set();
this.getUrl = getUrl;
this.postOrderUrl = postOrderUrl;
this.delUrl = delUrl || postClassifierUrl;
this.postClassifierUrl = postClassifierUrl;
this.paramsName = paramsName;
this.isRootSelectable = isRootSelectable;
this.getUrl = getUrl;
this.postOrderUrl = postOrderUrl;
this.delUrl = delUrl || postClassifierUrl;
this.postClassifierUrl = postClassifierUrl;
this.paramsName = paramsName;
this.isRootSelectable = isRootSelectable;
this.needBtn = false;
this.canSelect = false;
this.order = false;
this.withSearch = search;
this.test = test;
this.draggable = draggable;
this.needBtn = false;
this.canSelect = false;
this.order = false;
this.withSearch = search;
this.test = test;
this.draggable = draggable;
if (this.withSearch) {
this.defaultShow = true;
this.canSelect = true;
this.createMarkupForSearch();
this.getElems();
this.addSearchClass();
this.addListeners();
} else {
this.editableItems = true;
this.draggable = true;
this.needBtn = true;
this.order = true;
this.defaultShow = false;
this.createMarkupForMain();
this.getElems();
this.addListeners();
}
if (this.withSearch) {
this.defaultShow = true;
this.canSelect = true;
this.createMarkupForSearch();
this.getElems();
this.addSearchClass();
this.addListeners();
} else {
this.editableItems = true;
this.draggable = true;
this.needBtn = true;
this.order = true;
this.defaultShow = false;
this.createMarkupForMain();
this.getElems();
this.addListeners();
}
this.getData();
this.getData();
this.targetInput.classifier = this;
this.targetInput.classifier = this;
this.revertSettings = {
innerHTML: this.targetInput.innerHTML,
};
}
sortableOptions = {
ghostClass: "classifier__sort-item",
filter: ".non-draggable, .custom-checkbox, .classifier__button",
forceFallback: true,
onUpdate: async ({newIndex, item}) => {
await sort.call(this, item.dataset.classifierId, newIndex);
},
onMove: function (e) {
return e.related.className.indexOf("non-draggable") === -1;
},
this.revertSettings = {
innerHTML: this.targetInput.innerHTML,
};
data = [];
showIds = new Set();
nodes = [];
dataItem = {};
}
destroy() {
this.targetInput.innerHTML = this.revertSettings.innerHTML;
this.targetEl.remove();
sortableOptions = {
ghostClass: "classifier__sort-item",
filter: ".non-draggable, .custom-checkbox, .classifier__button",
forceFallback: true,
onUpdate: async ({ newIndex, item }) => {
await sort.call(this, item.dataset.classifierId, newIndex);
},
onMove: function(e) {
return e.related.className.indexOf("non-draggable") === -1;
},
};
data = [];
showIds = new Set();
nodes = [];
dataItem = {};
delete this.targetInput.classifier;
}
destroy() {
this.targetInput.innerHTML = this.revertSettings.innerHTML;
this.targetEl.remove();
createMarkupForSearch() {
this.targetEl.innerHTML = searchMarkup;
}
delete this.targetInput.classifier;
}
createMarkupForMain() {
this.targetEl.innerHTML = `${mainMarkup}${modalMarkup}`;
}
createMarkupForSearch() {
this.targetEl.innerHTML = searchMarkup;
}
getElems() {
if (this.withSearch) {
this.selectedList = this.targetEl.querySelector(
".classifier__select-list"
);
} else {
this.modal = this.targetEl.querySelector(".classifier__modal");
this.modalEditBlock = this.modal.querySelector(".edit")
this.modalForm = this.modal.querySelector(".form");
this.modalInput = this.modal.querySelector("input");
this.modalButton = this.modal.querySelector(".classifier__modal-btn");
this.modalTitle = this.modal.querySelector("h5");
this.modalFeedback = this.modal.querySelector(".feedback");
createMarkupForMain() {
this.targetEl.innerHTML = `${mainMarkup}${modalMarkup}`;
}
this.#deleteBlock.container = this.modal.querySelector('.delete')
this.#deleteBlock.name = this.modal.querySelector('.delete__name')
this.#deleteBlock.paragraph = this.modal.querySelector('.delete__p')
this.#deleteBlock.cancelBtn = this.modal.querySelector('.delete__cancel')
this.#deleteBlock.agreeBtn = this.modal.querySelector('.delete__agree')
}
getElems() {
if (this.withSearch) {
this.selectedList = this.targetEl.querySelector(
".classifier__select-list",
);
} else {
this.modal = this.targetEl.querySelector(".classifier__modal");
this.modalEditBlock = this.modal.querySelector(".edit");
this.modalForm = this.modal.querySelector(".form");
this.modalInput = this.modal.querySelector("input");
this.modalButton = this.modal.querySelector(".classifier__modal-btn");
this.modalTitle = this.modal.querySelector("h5");
this.modalFeedback = this.modal.querySelector(".feedback");
this.mainUl = this.targetEl.querySelector(".classifier__main-list");
if (this.draggable)
this.sortable = Sortable.create(this.mainUl, this.sortableOptions);
this.#deleteBlock.container = this.modal.querySelector(".delete");
this.#deleteBlock.name = this.modal.querySelector(".delete__name");
this.#deleteBlock.paragraph = this.modal.querySelector(".delete__p");
this.#deleteBlock.cancelBtn = this.modal.querySelector(".delete__cancel");
this.#deleteBlock.agreeBtn = this.modal.querySelector(".delete__agree");
}
addListeners() {
if (!this.withSearch) {
this.modal.addEventListener("click", (e) => {
if (e.target === this.modal ||
e.target.classList.contains("btn-close") ||
e.target.classList.contains("delete__cancel"))
this.hideModal();
});
this.modalForm.addEventListener("submit", (e) => e.preventDefault());
document.addEventListener("keydown", (e) => {
if (e.code === "Escape") this.hideModal();
});
}
}
this.mainUl = this.targetEl.querySelector(".classifier__main-list");
if (this.draggable)
this.sortable = Sortable.create(this.mainUl, this.sortableOptions);
}
hideElem(elem) {
elem.classList.add("d-none");
addListeners() {
if (!this.withSearch) {
this.modal.addEventListener("click", (e) => {
if (e.target === this.modal ||
e.target.classList.contains("btn-close") ||
e.target.classList.contains("delete__cancel"))
this.hideModal();
});
this.modalForm.addEventListener("submit", (e) => e.preventDefault());
document.addEventListener("keydown", (e) => {
if (e.code === "Escape") this.hideModal();
});
}
}
showElem(elem) {
elem.classList.remove("d-none");
}
hideElem(elem) {
elem.classList.add("d-none");
}
showModal(state = 'edit') {
this.modal.classList.remove("d-none");
showElem(elem) {
elem.classList.remove("d-none");
}
switch (state) {
case "edit":
this.showElem(this.modalEditBlock)
this.hideElem(this.#deleteBlock.container)
this.modalInput?.focus();
break;
case "delete":
this.showElem(this.#deleteBlock.container)
this.hideElem(this.modalEditBlock)
break;
}
}
showModal(state = "edit") {
this.modal.classList.remove("d-none");
hideModal() {
this.modal.classList.add("d-none");
switch (state) {
case "edit":
this.showElem(this.modalEditBlock);
this.hideElem(this.#deleteBlock.container);
this.modalInput?.focus();
break;
case "delete":
this.showElem(this.#deleteBlock.container);
this.hideElem(this.modalEditBlock);
break;
}
}
addSearchClass() {
this.mainUl.classList.add("--search");
}
hideModal() {
this.modal.classList.add("d-none");
}
openCreateModal(parentItem) {
this.dataItem = parentItem;
this.modalInput.value = "";
this.setModalFeedback();
this.modalButton.textContent = "Создать";
this.modalButton.onclick = create.bind(this);
this.showModal();
}
addSearchClass() {
this.mainUl.classList.add("--search");
}
openEditModal(item) {
this.dataItem = item;
this.modalInput.value = this.getName(item.tree_path);
this.setModalFeedback();
this.modalButton.textContent = "Сохранить";
this.modalButton.onclick = edit.bind(this);
this.showModal();
}
openCreateModal(parentItem) {
this.dataItem = parentItem;
this.modalInput.value = "";
this.setModalFeedback();
this.modalButton.textContent = "Создать";
this.modalButton.onclick = create.bind(this);
this.showModal();
}
openDeleteModal(item) {
this.dataItem = item;
this.#deleteBlock.name.textContent = this.getName(item.tree_path);
this.#deleteBlock.agreeBtn.onclick = this.del.bind(this);
this.showElem(this.#deleteBlock.agreeBtn)
this.showElem(this.#deleteBlock.paragraph)
this.#deleteBlock.cancelBtn.textContent = 'Нет'
this.setModalFeedback();
this.showModal('delete');
}
openEditModal(item) {
this.dataItem = item;
this.modalInput.value = this.getName(item.tree_path);
this.setModalFeedback();
this.modalButton.textContent = "Сохранить";
this.modalButton.onclick = edit.bind(this);
this.showModal();
}
buildNodes(data, parentNode = {tree_path: ''}) {
let nodes = data
.filter((node) => node.tree_path.split(".").slice(0, -1).join(".") === parentNode.tree_path)
openDeleteModal(item) {
this.dataItem = item;
this.#deleteBlock.name.textContent = this.getName(item.tree_path);
this.#deleteBlock.agreeBtn.onclick = this.del.bind(this);
this.showElem(this.#deleteBlock.agreeBtn);
this.showElem(this.#deleteBlock.paragraph);
this.#deleteBlock.cancelBtn.textContent = "Нет";
this.setModalFeedback();
this.showModal("delete");
}
if (this.sortedIds.has(parentNode.id)) nodes.sort()
else nodes.sort((node1, node2) => node1.row_order - node2.row_order);
buildNodes(data, parentNode = { tree_path: "" }) {
let nodes = data
.filter((node) => node.tree_path.split(".").slice(0, -1).join(".") === parentNode.tree_path);
nodes.forEach((node) => {
node.children = this.buildNodes(data, node);
if (this.sortedIds.has(parentNode.id)) nodes.sort();
else nodes.sort((node1, node2) => node1.row_order - node2.row_order);
if (isRootPath(node.tree_path)) this.showIds.add(node.id); //root
nodes.forEach((node) => {
node.children = this.buildNodes(data, node);
node.name = `${this.getName(node.tree_path)}${
node.children.length ? ` (${node.children.length})` : ""
}`;
});
if (isRootPath(node.tree_path)) this.showIds.add(node.id); //root
return nodes;
}
node.name = `${this.getName(node.tree_path)}${
node.children.length ? ` (${node.children.length})` : ""
}`;
});
renderTree(data, parentUl) {
data.forEach((item) => {
const li = document.createElement("li");
const liContainer = document.createElement("div");
liContainer.classList.add("classifier__li-container");
li.dataset.classifierId = item.id;
return nodes;
}
const showCheckbox = document.createElement("input");
showCheckbox.type = "checkbox";
// showCheckbox.setAttribute("data-show", "");
showCheckbox.dataset.show = "";
showCheckbox.checked = this.showIds.has(item.id);
showCheckbox.classList.add('classifier__show-checkbox')
showCheckbox.addEventListener("change", () => this.toggle(item.id));
const showLabel = document.createElement("label");
showLabel.innerHTML = toggleIcon
// const showSpan = document.createElement("span");
showLabel.classList.add("custom-checkbox", 'classifier__show-label');
showLabel.append(showCheckbox);
// showLabel.append(showSpan);
renderTree(data, parentUl) {
data.forEach((item) => {
const li = document.createElement("li");
const liContainer = document.createElement("div");
liContainer.classList.add("classifier__li-container");
li.dataset.classifierId = item.id;
const ul = document.createElement("ul");
ul.classList.add("classifier__secondary-list");
if (this.draggable && !this.sortedIds.has(item.id)) Sortable.create(ul, this.sortableOptions);
if (this.showIds.has(item.id)) this.showElem(ul);
else this.hideElem(ul);
const showCheckbox = document.createElement("input");
showCheckbox.type = "checkbox";
// showCheckbox.setAttribute("data-show", "");
showCheckbox.dataset.show = "";
showCheckbox.checked = this.showIds.has(item.id);
showCheckbox.classList.add("classifier__show-checkbox");
showCheckbox.addEventListener("change", () => this.toggle(item.id));
const showLabel = document.createElement("label");
showLabel.innerHTML = toggleIcon;
// const showSpan = document.createElement("span");
showLabel.classList.add("custom-checkbox", "classifier__show-label", "cursor-pointer");
showLabel.append(showCheckbox);
// showLabel.append(showSpan);
let addLi;
if (this.needBtn) addLi = this.createAddLi(item, "Создать раздел");
const ul = document.createElement("ul");
ul.classList.add("classifier__secondary-list");
if (this.draggable && !this.sortedIds.has(item.id)) Sortable.create(ul, this.sortableOptions);
if (this.showIds.has(item.id)) this.showElem(ul);
else this.hideElem(ul);
const selectLabel = document.createElement("label");
const selectSpan = document.createElement("span");
selectLabel.classList.add("classifier__name");
selectSpan.textContent = `${item.name}`;
if (this.canSelect &&
!(isRootPath(item.tree_path) && !this.isRootSelectable)
) {
const selectCheckbox = document.createElement("input");
selectCheckbox.type = "checkbox";
selectCheckbox.dataset.select = "";
selectCheckbox.checked = this.selectedIds.has(item.id);
selectCheckbox.classList.add("visually-hidden");
selectCheckbox.addEventListener("change", () => this.select(item.id));
let addLi;
if (this.needBtn) addLi = this.createAddLi(item, "Создать раздел");
selectLabel.classList.add("classifier__name--tick");
selectLabel.classList.add("cursor-pointer");
selectLabel.classList.add("classifier__name--hover");
selectLabel.append(selectCheckbox);
selectLabel.append(selectSpan);
}
selectLabel.append(selectSpan);
liContainer.append(selectLabel);
const selectLabel = document.createElement("label");
const selectSpan = document.createElement("span");
selectLabel.classList.add("classifier__name");
selectSpan.textContent = `${item.name}`;
if (this.canSelect &&
!(isRootPath(item.tree_path) && !this.isRootSelectable)
) {
const selectCheckbox = document.createElement("input");
selectCheckbox.type = "checkbox";
selectCheckbox.dataset.select = "";
selectCheckbox.checked = this.selectedIds.has(item.id);
selectCheckbox.classList.add("visually-hidden");
selectCheckbox.addEventListener("change", () => this.select(item.id));
if (item.children.length || this.needBtn) liContainer.append(showLabel);
selectLabel.classList.add("classifier__name--tick", "cursor-pointer", "classifier__name--hover");
selectLabel.append(selectCheckbox);
selectLabel.append(selectSpan);
}
selectLabel.append(selectSpan);
liContainer.append(selectLabel);
let editBtn;
if (this.editableItems) {
editBtn = document.createElement("button");
editBtn.classList.add("classifier__button");
editBtn.innerHTML = settingsIcon;
editBtn.addEventListener("click", () => this.openEditModal(item));
liContainer.append(editBtn);
if (item.children.length || this.needBtn) liContainer.append(showLabel);
const deleteBtn = createDeleteBtn()
liContainer.append(deleteBtn)
deleteBtn.addEventListener('click', () => this.openDeleteModal(item))
}
let editBtn;
if (this.editableItems) {
editBtn = document.createElement("button");
editBtn.classList.add("classifier__button");
editBtn.innerHTML = settingsIcon;
editBtn.addEventListener("click", () => this.openEditModal(item));
liContainer.append(editBtn);
// sort
if (item.children.length >= 2) {
const {label: sortLabel, input: sortCheckbox} = createSortElements()
sortCheckbox.addEventListener('change', () => this.handleSort(item.id))
sortCheckbox.checked = this.sortedIds.has(item.id)
// liContainer.append(sortLabel)
}
const deleteBtn = createDeleteBtn();
liContainer.append(deleteBtn);
deleteBtn.addEventListener("click", () => this.openDeleteModal(item));
}
li.append(liContainer);
li.append(ul);
parentUl.append(li);
// sort
if (item.children.length >= 2) {
const { label: sortLabel, input: sortCheckbox } = createSortElements();
sortCheckbox.addEventListener("change", () => this.handleSort(item.id));
sortCheckbox.checked = this.sortedIds.has(item.id);
// liContainer.append(sortLabel)
}
if (item.children.length > 0) this.renderTree(item.children, ul);
if (this.needBtn) ul.append(addLi);
});
}
li.append(liContainer);
li.append(ul);
parentUl.append(li);
createAddLi(parentItem, text) {
const addBtn = document.createElement("button");
addBtn.classList.add("btn");
addBtn.classList.add("btn-link");
addBtn.classList.add("text-black");
addBtn.classList.add("p-0");
addBtn.textContent = text;
addBtn.addEventListener("click", () => this.openCreateModal(parentItem));
if (item.children.length > 0) this.renderTree(item.children, ul);
if (this.needBtn) ul.append(addLi);
});
}
const addLi = document.createElement("li");
addLi.classList.add("non-draggable");
addLi.append(addBtn);
createAddLi(parentItem, text) {
const addBtn = document.createElement("button");
addBtn.classList.add("classifier__create-btn");
addBtn.textContent = text;
addBtn.addEventListener("click", () => this.openCreateModal(parentItem));
return addLi;
}
const addLi = document.createElement("li");
addLi.classList.add("non-draggable");
addLi.append(addBtn);
getListItemById(id) {
return this.targetEl.querySelector(`[data-classifier-id="${id}"]`);
}
return addLi;
}
toggle(id) {
const li = this.getListItemById(id);
const checkbox = li.querySelector(`[data-show=""]`);
const ul = li.querySelector("ul");
getListItemById(id) {
return this.targetEl.querySelector(`[data-classifier-id="${id}"]`);
}
if (this.showIds.has(id)) {
checkbox.checked = false
this.hideElem(ul);
this.showIds.delete(id);
} else {
checkbox.checked = true
this.showElem(ul);
this.showIds.add(id);
}
toggle(id) {
const li = this.getListItemById(id);
const checkbox = li.querySelector(`[data-show=""]`);
const ul = li.querySelector("ul");
if (this.showIds.has(id)) {
checkbox.checked = false;
this.hideElem(ul);
this.showIds.delete(id);
} else {
checkbox.checked = true;
this.showElem(ul);
this.showIds.add(id);
}
}
select(id) {
const li = this.getListItemById(id);
const checkbox = li.querySelector(`[data-select=""]`);
select(id) {
if (!this.isRootSelectable && this.nodes.find(node => node.id === id)) throw new Error("impossible to select a root classifier");
if (this.selectedIds.has(id)) {
checkbox.checked = false
this.selectedIds.delete(id);
} else {
checkbox.checked = true
this.selectedIds.add(id);
}
const li = this.getListItemById(id);
const checkbox = li.querySelector(`[data-select=""]`);
this.renderSelected();
if (this.selectedIds.has(id)) {
checkbox.checked = false;
this.selectedIds.delete(id);
} else {
checkbox.checked = true;
this.selectedIds.add(id);
}
handleSort(id) {
const li = this.getListItemById(id)
const checkbox = li.querySelector('.classifier__sort-checkbox')
this.renderSelected();
}
if (this.sortedIds.has(id)) this.sortedIds.delete(id)
else this.sortedIds.add(id)
localStorage.setItem('classifierSortedIds', JSON.stringify([...this.sortedIds]))
handleSort(id) {
const li = this.getListItemById(id);
const checkbox = li.querySelector(".classifier__sort-checkbox");
this.nodes = this.buildNodes(this.data);
this.render();
}
if (this.sortedIds.has(id)) this.sortedIds.delete(id);
else this.sortedIds.add(id);
localStorage.setItem("classifierSortedIds", JSON.stringify([...this.sortedIds]));
changeTargetInput() {
this.targetInput.innerHTML = "";
this.selectedIds.forEach((id) => {
if (this.data.find((x) => x.id === id)) {
const option = document.createElement("option");
option.value = id;
option.selected = true;
this.targetInput.append(option);
}
});
}
this.nodes = this.buildNodes(this.data);
this.render();
}
renderSelected() {
this.selectedList.textContent = "";
const arrIds = Array.from(this.selectedIds);
arrIds.forEach((id) => {
const item = this.data.find((x) => x.id === id);
if (item) {
const btn = document.createElement("button");
btn.classList.add("classifier__button", "classifier__button--rotated-icon");
btn.type = "button";
btn.addEventListener("click", () => this.deselect(item));
changeTargetInput() {
this.targetInput.innerHTML = "";
this.selectedIds.forEach((id) => {
if (this.data.find((x) => x.id === id)) {
const option = document.createElement("option");
option.value = id;
option.selected = true;
this.targetInput.append(option);
}
});
}
btn.innerHTML = toggleIcon;
renderSelected() {
this.selectedList.textContent = "";
const arrIds = Array.from(this.selectedIds);
arrIds.forEach((id) => {
const item = this.data.find((x) => x.id === id);
if (item) {
const btn = document.createElement("button");
btn.classList.add("classifier__button", "classifier__button--rotated-icon");
btn.type = "button";
btn.addEventListener("click", () => this.deselect(item));
const span = document.createElement("span");
span.textContent = this.getName(item.tree_path);
span.textContent = item.tree_path;
btn.innerHTML = toggleIcon;
const li = document.createElement("li");
li.classList.add("select-list__item");
li.classList.add("bg-secondary-subtle");
li.classList.add("rounded-1");
li.classList.add("p-1");
li.append(span);
li.append(btn);
const span = document.createElement("span");
span.textContent = this.getName(item.tree_path);
span.textContent = item.tree_path;
this.selectedList.append(li);
}
});
this.changeTargetInput();
}
const li = document.createElement("li");
li.classList.add("select-list__item");
li.classList.add("bg-secondary-subtle");
li.classList.add("rounded-1");
li.classList.add("p-1");
li.append(span);
li.append(btn);
deselect(item) {
this.selectedIds.delete(item.id);
this.render();
this.renderSelected();
}
this.selectedList.append(li);
}
});
this.changeTargetInput();
}
getName(path) {
return path.split(".").at(-1);
}
deselect(item) {
this.selectedIds.delete(item.id);
this.render();
this.renderSelected();
}
render() {
this.mainUl.innerHTML = "";
const addLi = this.createAddLi(this.data, "Создать классификатор");
this.renderTree(this.nodes, this.mainUl);
if (this.needBtn) this.mainUl.append(addLi);
}
getName(path) {
return path.split(".").at(-1);
}
addValue(val) {
if (val instanceof Array) {
val.forEach((id) => {
this.selectedIds.add(id);
});
} else {
this.selectedIds.add(val);
}
render() {
this.mainUl.innerHTML = "";
const addLi = this.createAddLi(this.data, "Создать классификатор");
this.renderTree(this.nodes, this.mainUl);
if (this.needBtn) this.mainUl.append(addLi);
}
this.render();
this.renderSelected();
addValue(val) {
try {
if (val instanceof Array) {
val.forEach((id) => {
if (!this.selectedIds.has(id)) this.select(id);
});
} else {
if (!this.selectedIds.has(val)) this.select(val);
}
return true;
} catch (e) {
throw e;
}
}
clear(val) {
if (val instanceof Array) {
val.forEach((id) => {
this.selectedIds.delete(id);
});
} else if (val) {
this.selectedIds.delete(val);
} else {
this.selectedIds.clear();
}
this.render();
this.renderSelected();
clear(val) {
try {
if (val instanceof Array) {
val.forEach((id) => {
if (this.selectedIds.has(id)) this.select(id);
});
} else {
if (this.selectedIds.has(val)) this.select(val);
}
return true;
} catch (e) {
throw e;
}
}
getCsrfToken() {
this.csrfToken = document.querySelector('meta[name="csrf-token"]')?.content;
}
getCsrfToken() {
this.csrfToken = document.querySelector("meta[name=\"csrf-token\"]")?.content;
}
setModalFeedback(errors) {
this.modalFeedback.textContent = "";
setModalFeedback(errors) {
this.modalFeedback.textContent = "";
if (!errors) {
return;
}
errors.forEach((error) => {
const li = document.createElement("li");
li.textContent = error;
this.modalFeedback.append(li);
});
if (!errors) {
return;
}
async del() {
try {
this.#deleteBlock.agreeBtn.disabled = true
this.getCsrfToken();
const response = await fetch(`${this.delUrl}/${this.dataItem.id}`, {
headers: {
"Content-Type": "application/json",
"X-CSRF-Token": this.csrfToken,
},
method: "DELETE"
});
if (response.ok) {
await this.getData();
this.hideModal();
} else {
this.delError()
const json = await response.json();
this.setModalFeedback([json.error]);
}
} catch (error) {
this.delError()
this.setModalFeedback(["Error"]);
console.error(error);
} finally {
this.#deleteBlock.agreeBtn.disabled = false
}
}
errors.forEach((error) => {
const li = document.createElement("li");
li.textContent = error;
this.modalFeedback.append(li);
});
}
delError() {
this.hideElem(this.#deleteBlock.agreeBtn)
this.hideElem(this.#deleteBlock.paragraph)
this.#deleteBlock.cancelBtn.textContent = 'Закрыть'
async del() {
try {
this.#deleteBlock.agreeBtn.disabled = true;
this.getCsrfToken();
const response = await fetch(`${this.delUrl}/${this.dataItem.id}`, {
headers: {
"Content-Type": "application/json",
"X-CSRF-Token": this.csrfToken,
},
method: "DELETE",
});
if (response.ok) {
await this.getData();
this.hideModal();
} else {
this.delError();
const json = await response.json();
this.setModalFeedback([json.error]);
}
} catch (error) {
this.delError();
this.setModalFeedback(["Error"]);
console.error(error);
} finally {
this.#deleteBlock.agreeBtn.disabled = false;
}
}
async getData() {
if (this.test) {
this.data = mockResponse.data;
} else {
try {
this.getCsrfToken();
const response = await fetch(this.getUrl, {
headers: {
"Content-Type": "application/json",
"X-CSRF-Token": this.csrfToken,
Accept: "application/json",
},
});
if (response.ok) {
let json = await response.json();
this.data = json;
}
} catch (error) {
console.error(error);
}
delError() {
this.hideElem(this.#deleteBlock.agreeBtn);
this.hideElem(this.#deleteBlock.paragraph);
this.#deleteBlock.cancelBtn.textContent = "Закрыть";
}
async getData() {
if (this.test) {
this.data = mockResponse.data;
} else {
try {
this.getCsrfToken();
const response = await fetch(this.getUrl, {
headers: {
"Content-Type": "application/json",
"X-CSRF-Token": this.csrfToken,
Accept: "application/json",
},
});
if (response.ok) {
let json = await response.json();
this.data = json;
}
this.nodes = this.buildNodes(this.data);
this.render();
if (this.withSearch) this.renderSelected();
} catch (error) {
console.error(error);
}
}
this.nodes = this.buildNodes(this.data);
this.render();
if (this.withSearch) this.renderSelected();
}
toggleManual(id) {
const li = this.getListItemById(id);
const checkbox = li.querySelector(`[data-show=""]`);
checkbox.checked = !checkbox.checked;
this.toggle(id);
}
toggleManual(id) {
const li = this.getListItemById(id);
const checkbox = li.querySelector(`[data-show=""]`);
checkbox.checked = !checkbox.checked;
this.toggle(id);
}
fillModalForm(text) {
this.modalInput.value = text;
}
fillModalForm(text) {
this.modalInput.value = text;
}
clickModalBtn() {
this.modalButton.click();
}
clickModalBtn() {
this.modalButton.click();
}
getModalFormValue() {
return this.modalInput.value;
}
getModalFormValue() {
return this.modalInput.value;
}
findById(id) {
return this.getListItemById(id);
}
findById(id) {
return this.getListItemById(id);
}
}

@@ -17,3 +17,3 @@ export const searchMarkup = `

</div>
`
`;

@@ -24,3 +24,3 @@ export const mainMarkup = `

</div>
`
`;

@@ -64,179 +64,179 @@ export const modalMarkup = `

export const mockResponse = {
data: [
{
id: 1,
tree_path: "Основной_классификатор",
created_at: "2023-11-17T14:47:25.105+03:00",
updated_at: "2023-11-17T20:51:51.094+03:00",
project_id: 1,
row_order: 2120220672,
},
{
id: 3,
tree_path: "Основной_классификатор.Science",
created_at: "2023-11-17T14:47:25.127+03:00",
updated_at: "2023-11-17T14:47:25.127+03:00",
project_id: 1,
row_order: 0,
},
{
id: 4,
tree_path: "Основной_классификатор.Science.Отдел_1",
created_at: "2023-11-17T14:47:25.137+03:00",
updated_at: "2023-11-17T14:47:25.137+03:00",
project_id: 1,
row_order: 0,
},
{
id: 33,
tree_path: "Первый",
created_at: "2023-11-17T17:41:37.682+03:00",
updated_at: "2023-11-17T20:52:09.607+03:00",
project_id: 1,
row_order: 2025848832,
},
{
id: 3345265652346,
tree_path: "Первый.а",
created_at: "2023-11-17T17:41:37.682+03:00",
updated_at: "2023-11-17T20:52:09.607+03:00",
project_id: 1,
row_order: 1,
},
{
id: 12312333,
tree_path: "Первый.б",
created_at: "2023-11-17T17:41:37.682+03:00",
updated_at: "2023-11-17T20:52:09.607+03:00",
project_id: 1,
row_order: 0,
},
// {
// id: 72,
// tree_path: "Первый.123123",
// created_at: "2023-11-17T20:52:13.871+03:00",
// updated_at: "2023-11-17T20:52:13.871+03:00",
// project_id: 1,
// row_order: 0,
// },
// {
// id: 73,
// tree_path: "Первый.12312321",
// created_at: "2023-11-17T20:52:17.380+03:00",
// updated_at: "2023-11-17T20:52:20.324+03:00",
// project_id: 1,
// row_order: 1073741824,
// },
data: [
{
id: 1,
tree_path: "Основной_классификатор",
created_at: "2023-11-17T14:47:25.105+03:00",
updated_at: "2023-11-17T20:51:51.094+03:00",
project_id: 1,
row_order: 2120220672,
},
{
id: 3,
tree_path: "Основной_классификатор.Science",
created_at: "2023-11-17T14:47:25.127+03:00",
updated_at: "2023-11-17T14:47:25.127+03:00",
project_id: 1,
row_order: 0,
},
{
id: 4,
tree_path: "Основной_классификатор.Science.Отдел_1",
created_at: "2023-11-17T14:47:25.137+03:00",
updated_at: "2023-11-17T14:47:25.137+03:00",
project_id: 1,
row_order: 0,
},
{
id: 33,
tree_path: "Первый",
created_at: "2023-11-17T17:41:37.682+03:00",
updated_at: "2023-11-17T20:52:09.607+03:00",
project_id: 1,
row_order: 2025848832,
},
{
id: 3345265652346,
tree_path: "Первый.а",
created_at: "2023-11-17T17:41:37.682+03:00",
updated_at: "2023-11-17T20:52:09.607+03:00",
project_id: 1,
row_order: 1,
},
{
id: 12312333,
tree_path: "Первый.б",
created_at: "2023-11-17T17:41:37.682+03:00",
updated_at: "2023-11-17T20:52:09.607+03:00",
project_id: 1,
row_order: 0,
},
// {
// id: 72,
// tree_path: "Первый.123123",
// created_at: "2023-11-17T20:52:13.871+03:00",
// updated_at: "2023-11-17T20:52:13.871+03:00",
// project_id: 1,
// row_order: 0,
// },
// {
// id: 73,
// tree_path: "Первый.12312321",
// created_at: "2023-11-17T20:52:17.380+03:00",
// updated_at: "2023-11-17T20:52:20.324+03:00",
// project_id: 1,
// row_order: 1073741824,
// },
{
id: 5,
tree_path: "Основной_классификатор.Science.Отдел_1.Astrophysics",
created_at: "2023-11-17T14:47:25.147+03:00",
updated_at: "2023-11-17T14:47:25.147+03:00",
project_id: 1,
row_order: 0,
},
{
id: 6,
tree_path: "Основной_классификатор.Science.Отдел_1.Cosmology",
created_at: "2023-11-17T14:47:25.157+03:00",
updated_at: "2023-11-17T14:47:25.157+03:00",
project_id: 1,
row_order: 1073741824,
},
{
id: 7,
tree_path: "Основной_классификатор.Hobbies",
created_at: "2023-11-17T14:47:25.167+03:00",
updated_at: "2023-11-17T14:47:25.167+03:00",
project_id: 1,
row_order: 1073741824,
},
{
id: 8,
tree_path: "Основной_классификатор.Hobbies.Amateurs_Astronomy",
created_at: "2023-11-17T14:47:25.178+03:00",
updated_at: "2023-11-17T14:47:25.178+03:00",
project_id: 1,
row_order: 0,
},
{
id: 9,
tree_path: "Основной_классификатор.Подразделение_2",
created_at: "2023-11-17T14:47:25.190+03:00",
updated_at: "2023-11-17T14:47:25.190+03:00",
project_id: 1,
// row_order: 1610612736,
row_order: -100,
},
{
id: 10,
tree_path: "Основной_классификатор.Подразделение_2.Отдел_2",
created_at: "2023-11-17T14:47:25.200+03:00",
updated_at: "2023-11-17T14:47:25.200+03:00",
project_id: 1,
row_order: 0,
},
{
id: 11,
tree_path: "Основной_классификатор.Подразделение_2.Отдел_2.Отдел_1",
created_at: "2023-11-17T14:47:25.211+03:00",
updated_at: "2023-11-17T14:47:25.211+03:00",
project_id: 1,
row_order: 0,
},
{
id: 12,
tree_path:
"Основной_классификатор.Подразделение_2.Отдел_2.Отдел_1.Stars",
created_at: "2023-11-17T14:47:25.221+03:00",
updated_at: "2023-11-17T14:47:25.221+03:00",
project_id: 1,
row_order: 0,
},
{
id: 13,
tree_path:
"Основной_классификатор.Подразделение_2.Отдел_2.Отдел_1.Galaxies",
created_at: "2023-11-17T14:47:25.233+03:00",
updated_at: "2023-11-17T14:47:25.233+03:00",
project_id: 1,
row_order: 1073741824,
},
{
id: 5,
tree_path: "Основной_классификатор.Science.Отдел_1.Astrophysics",
created_at: "2023-11-17T14:47:25.147+03:00",
updated_at: "2023-11-17T14:47:25.147+03:00",
project_id: 1,
row_order: 0,
},
{
id: 6,
tree_path: "Основной_классификатор.Science.Отдел_1.Cosmology",
created_at: "2023-11-17T14:47:25.157+03:00",
updated_at: "2023-11-17T14:47:25.157+03:00",
project_id: 1,
row_order: 1073741824,
},
{
id: 7,
tree_path: "Основной_классификатор.Hobbies",
created_at: "2023-11-17T14:47:25.167+03:00",
updated_at: "2023-11-17T14:47:25.167+03:00",
project_id: 1,
row_order: 1073741824,
},
{
id: 8,
tree_path: "Основной_классификатор.Hobbies.Amateurs_Astronomy",
created_at: "2023-11-17T14:47:25.178+03:00",
updated_at: "2023-11-17T14:47:25.178+03:00",
project_id: 1,
row_order: 0,
},
{
id: 9,
tree_path: "Основной_классификатор.Подразделение_2",
created_at: "2023-11-17T14:47:25.190+03:00",
updated_at: "2023-11-17T14:47:25.190+03:00",
project_id: 1,
// row_order: 1610612736,
row_order: -100,
},
{
id: 10,
tree_path: "Основной_классификатор.Подразделение_2.Отдел_2",
created_at: "2023-11-17T14:47:25.200+03:00",
updated_at: "2023-11-17T14:47:25.200+03:00",
project_id: 1,
row_order: 0,
},
{
id: 11,
tree_path: "Основной_классификатор.Подразделение_2.Отдел_2.Отдел_1",
created_at: "2023-11-17T14:47:25.211+03:00",
updated_at: "2023-11-17T14:47:25.211+03:00",
project_id: 1,
row_order: 0,
},
{
id: 12,
tree_path:
"Основной_классификатор.Подразделение_2.Отдел_2.Отдел_1.Stars",
created_at: "2023-11-17T14:47:25.221+03:00",
updated_at: "2023-11-17T14:47:25.221+03:00",
project_id: 1,
row_order: 0,
},
{
id: 13,
tree_path:
"Основной_классификатор.Подразделение_2.Отдел_2.Отдел_1.Galaxies",
created_at: "2023-11-17T14:47:25.233+03:00",
updated_at: "2023-11-17T14:47:25.233+03:00",
project_id: 1,
row_order: 1073741824,
},
{
id: 14,
tree_path:
"Основной_классификатор.Подразделение_2.Отдел_2.Отдел_1.Astronauts",
created_at: "2023-11-17T14:47:25.244+03:00",
updated_at: "2023-11-17T14:47:25.244+03:00",
project_id: 1,
row_order: 1610612736,
},
{
id: 15,
tree_path: "Основной_классификатор.Подразделение_2.Отдел_3",
created_at: "2023-11-17T14:47:25.255+03:00",
updated_at: "2023-11-17T14:47:25.255+03:00",
project_id: 1,
row_order: 1073741824,
},
{
id: 16,
tree_path:
"Основной_классификатор.Подразделение_2.Отдел_3.Vacation",
created_at: "2023-11-17T14:47:25.265+03:00",
updated_at: "2023-11-17T14:47:25.265+03:00",
project_id: 1,
row_order: 0,
},
{
id: 17,
tree_path: "Основной_классификатор.Подразделение_2.Отдел_3.NewYear",
created_at: "2023-11-17T14:47:25.275+03:00",
updated_at: "2023-11-17T14:47:25.275+03:00",
project_id: 1,
row_order: 1073741824,
},
],
}
{
id: 14,
tree_path:
"Основной_классификатор.Подразделение_2.Отдел_2.Отдел_1.Astronauts",
created_at: "2023-11-17T14:47:25.244+03:00",
updated_at: "2023-11-17T14:47:25.244+03:00",
project_id: 1,
row_order: 1610612736,
},
{
id: 15,
tree_path: "Основной_классификатор.Подразделение_2.Отдел_3",
created_at: "2023-11-17T14:47:25.255+03:00",
updated_at: "2023-11-17T14:47:25.255+03:00",
project_id: 1,
row_order: 1073741824,
},
{
id: 16,
tree_path:
"Основной_классификатор.Подразделение_2.Отдел_3.Vacation",
created_at: "2023-11-17T14:47:25.265+03:00",
updated_at: "2023-11-17T14:47:25.265+03:00",
project_id: 1,
row_order: 0,
},
{
id: 17,
tree_path: "Основной_классификатор.Подразделение_2.Отдел_3.NewYear",
created_at: "2023-11-17T14:47:25.275+03:00",
updated_at: "2023-11-17T14:47:25.275+03:00",
project_id: 1,
row_order: 1073741824,
},
],
};

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc