flat-tree-builder
Advanced tools
Comparing version 1.5.23 to 1.5.24
{ | ||
"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 @@ }, |
957
src/main.js
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
20
173090
3
4449
+ Addedprettier@^3.2.5
+ Addedprettier@3.4.2(transitive)