Files
Sheep-Service/web/lib/pages/territory/script.js

280 lines
12 KiB
JavaScript

const Territory = {
init: async () => {
let html = await fetch('/lib/pages/territory/index.html').then((response) => response.text());
app.innerHTML = html;
let selectStatus = document.getElementById('list-controls-filter-status');
let filterStatus = localStorage.getItem("filterStatus") ? Number(localStorage.getItem("filterStatus")) : 0;
selectStatus.value = filterStatus;
if (USER.mode == 2) {
document.getElementById("buttons-list").style.display = "flex";
document.getElementById("historyButton").style.display = "";
}
if (USER.possibilities.can_add_territory) {
document.getElementById("buttons-list").style.display = "flex";
document.getElementById("constructorButton").style.display = "";
}
// Застосовуємо режим сортування
Territory.sort(localStorage.getItem('territory_sort_mode'));
if (localStorage.getItem('territory_entrances') == 'true') {
document.getElementById('territory_entrances_true').setAttribute('data-state', '')
document.getElementById('territory_entrances_false').setAttribute('data-state', 'active')
} else {
document.getElementById('territory_entrances_true').setAttribute('data-state', 'active')
document.getElementById('territory_entrances_false').setAttribute('data-state', '')
}
},
// Сортування
sort(mode) {
const idx = Math.max(1, Math.min(4, Number(mode) || 1));
['sort_1', 'sort_2', 'sort_3', 'sort_4'].forEach((id, i) => {
document.getElementById(id)?.setAttribute('data-state', i + 1 === idx ? 'active' : '');
});
localStorage.setItem('territory_sort_mode', idx);
Territory.house.setHTML();
Territory.homestead.setHTML();
},
house: {
list: [],
loadAPI: async function (url) {
const uuid = localStorage.getItem("uuid");
const response = await fetch(url, {
method: 'GET',
headers: {
"Content-Type": "application/json",
"Authorization": uuid
}
});
Territory.house.list = await response.json();
return Territory.house.list;
},
setHTML: async function () {
const block_house = document.getElementById('list-house');
const territory_entrances = localStorage.getItem('territory_entrances') === 'true';
const sort_mode = localStorage.getItem('territory_sort_mode') ?? "1";
const filterStatus = Number(localStorage.getItem("filterStatus") ?? 0);
const url = `${CONFIG.api}houses/list${territory_entrances ? '/entrances' : ''}`;
let list = this.list.length > 0 ? this.list : await this.loadAPI(url);
const compare = {
"1": (a, b) => this.compareAB(a, b, territory_entrances, 'asc'),
"2": (a, b) => this.compareAB(a, b, territory_entrances, 'desc'),
"3": (a, b) => a.history?.date?.start - b.history?.date?.start,
"4": (a, b) => b.history?.date?.start - a.history?.date?.start,
}[sort_mode] ?? ((a, b) => a.id - b.id);
list.sort(compare);
let html = "";
for (const element of list) {
const qty = element.entrance?.quantity ?? 0;
const work = element.entrance?.working ?? 0;
const statusMatch =
filterStatus === 0 ||
(filterStatus === 1 && qty === work && !territory_entrances) ||
(filterStatus === 1 && element.working === true) ||
(filterStatus === 2 && qty !== work && !territory_entrances) ||
(filterStatus === 2 && element.working === false);
if (statusMatch) {
html += this.renderCard({ element, territory_entrances });
}
}
block_house.innerHTML = html;
},
compareAB: (a, b, entrances, order = 'asc') => {
const dir = order === 'asc' ? 1 : -1;
const ah = entrances ? a.house : a;
const bh = entrances ? b.house : b;
const tA = ah.title?.toLowerCase() ?? '';
const tB = bh.title?.toLowerCase() ?? '';
if (tA < tB) return -1 * dir;
if (tA > tB) return 1 * dir;
const nA = ah.number?.toLowerCase() ?? '';
const nB = bh.number?.toLowerCase() ?? '';
if (nA < nB) return -1 * dir;
if (nA > nB) return 1 * dir;
return 0;
},
renderCard: ({ element, territory_entrances }) => {
if (territory_entrances) {
const working = element.working;
const bg = working ? `background: ${colorGroup(element.history.group_id)} color: #fff;` : "";
const person = working
? `<span>Територію опрацьовує:</span> <p>${element.history.name === 'Групова' ? 'Група ' + element.history.group_id : element.history.name}</p>`
: `<span>Територія не опрацьовується</span>`;
return `
<div class="card">
<i style="background-image: url(https://sheep-service.com/cards/house/T${element.house.id}.webp);"></i>
<div class="contents">
<div class="info">
<div>
<p>${element.house.title} ${element.house.number} (${element.title})</p>
</div>
</div>
<div class="sheep" style="${bg}">
${person}
</div>
</div>
<a href="/territory/manager/house/${element.house.id}" data-route></a>
</div>
`;
} else {
const qty = element.entrance.quantity;
const work = element.entrance.working;
const progress = ((work / qty) * 100).toFixed(1);
return `
<div class="card">
<i style="background-image: url(https://sheep-service.com/cards/house/T${element.id}.webp);"></i>
<div class="contents">
<div class="info">
<div>
<p>${element.title} ${element.number}</p>
</div>
</div>
<div class="info">
<div>
<div class="progress" style="width: ${progress}%"></div>
<span>Вільні під'їзди:</span>
<p>${qty - work} / ${qty}</p>
</div>
</div>
</div>
<a href="/territory/manager/house/${element.id}" data-route></a>
</div>
`;
}
},
territoryType: (type) => {
localStorage.setItem('territory_entrances', type);
document.getElementById('territory_entrances_true').setAttribute('data-state', type === 'false' ? 'active' : '');
document.getElementById('territory_entrances_false').setAttribute('data-state', type === 'true' ? 'active' : '');
Territory.house.list = [];
Territory.house.setHTML();
}
},
homestead: {
list: [],
loadAPI: async function () {
const uuid = localStorage.getItem("uuid");
const URL = `${CONFIG.api}homestead/list`;
const response = await fetch(URL, {
method: 'GET',
headers: {
"Content-Type": "application/json",
"Authorization": uuid
}
});
this.list = await response.json();
return this.list;
},
setHTML: async function () {
const block = document.getElementById('list-homestead');
const sortMode = localStorage.getItem('territory_sort_mode') ?? "1";
const filterStatus = Number(localStorage.getItem("filterStatus") ?? 0);
let list = this.list.length > 0 ? this.list : await this.loadAPI();
const compare = {
"1": (a, b) => a.id - b.id,
"2": (a, b) => b.id - a.id,
"3": (a, b) => (a.history?.date?.start ?? 0) - (b.history?.date?.start ?? 0),
"4": (a, b) => (b.history?.date?.start ?? 0) - (a.history?.date?.start ?? 0),
}[sortMode] ?? ((a, b) => a.id - b.id);
list.sort(compare);
let html = "";
for (const element of list) {
const statusMatch =
filterStatus === 0 ||
(filterStatus === 1 && element.working) ||
(filterStatus === 2 && !element.working);
if (statusMatch) {
html += this.renderCard(element);
}
}
block.innerHTML = html;
},
renderCard: (element) => {
const working = element.working;
const bg = working ? `background: ${colorGroup(element.history.group_id)} color: #fff;` : "";
const person = working
? `<span>Територію опрацьовує:</span> <p>${element.history.name === 'Групова' ? 'Група ' + element.history.group_id : element.history.name}</p>`
: `<span>Територія не опрацьовується</span>`;
return `
<div class="card">
<i style="background-image: url(https://sheep-service.com/cards/homestead/H${element.id}.webp);"></i>
<div class="contents">
<div class="info">
<div>
<p>${element.title} ${element.number}</p>
</div>
</div>
<div class="sheep" style="${bg}">
${person}
</div>
</div>
<a href="/territory/manager/homestead/${element.id}" data-route></a>
</div>
`;
}
},
filter: () => {
let selectStatus = document.getElementById('list-controls-filter-status').value;
localStorage.setItem("filterStatus", selectStatus);
Territory.house.setHTML();
Territory.homestead.setHTML();
},
report: async () => {
const uuid = localStorage.getItem("uuid");
const url = `${CONFIG.api}generator/report/territories`;
await fetch(url, {
method: 'GET',
headers: {
"Content-Type": "application/json",
"Authorization": uuid
}
}).then(response => {
if (!response.ok) throw new Error('Network response was not ok');
return response.blob();
})
.then(blob => {
const link = document.createElement('a');
const url = window.URL.createObjectURL(blob);
link.href = url;
link.download = 'report.xlsx';
document.body.appendChild(link);
link.click();
link.remove();
window.URL.revokeObjectURL(url);
})
.catch(err => {
console.error('Fetch error:', err);
});
}
}