Додані повідомлення та перепрацьована структура застосунку та api
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
const appTerritoryCardStyles = new CSSStyleSheet();
|
||||
appTerritoryCardStyles.replaceSync(`
|
||||
// Заміна вмісту таблиці стилів на надані CSS-правила.
|
||||
const CARD_STYLES_CSS = `
|
||||
:host {
|
||||
display: inline-block;
|
||||
box-sizing: border-box;
|
||||
@@ -54,14 +54,15 @@ appTerritoryCardStyles.replaceSync(`
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
filter: blur(3px);
|
||||
border-radius: calc(var(--border-radius, 15px) - 5px);
|
||||
}
|
||||
.contents {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
filter: blur(3px);
|
||||
}
|
||||
.contents {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
background: rgb(64 64 64 / 0.7);
|
||||
width: 100%;
|
||||
@@ -89,7 +90,7 @@ appTerritoryCardStyles.replaceSync(`
|
||||
|
||||
|
||||
|
||||
/* Стили для режима 'sheep' */
|
||||
/* Стилі для режиму 'sheep' */
|
||||
.sheep {
|
||||
margin: 10px;
|
||||
max-height: 50px;
|
||||
@@ -116,7 +117,7 @@ appTerritoryCardStyles.replaceSync(`
|
||||
}
|
||||
|
||||
|
||||
/* Стили для режима 'info' (прогресс) */
|
||||
/* Стилі для режиму 'info' (прогресс) */
|
||||
.info {
|
||||
margin: 10px;
|
||||
}
|
||||
@@ -133,7 +134,7 @@ appTerritoryCardStyles.replaceSync(`
|
||||
}
|
||||
.info span {
|
||||
z-index: 2;
|
||||
font-size: var(--FontSize1, 12px);
|
||||
font-size: var(--FontSize3, 14px);
|
||||
color: var(--ColorThemes3, #f3f3f3);
|
||||
}
|
||||
.info p {
|
||||
@@ -158,24 +159,45 @@ appTerritoryCardStyles.replaceSync(`
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 10;
|
||||
border-radius: calc(var(--border-radius, 15px) - 5px);
|
||||
}
|
||||
`);
|
||||
`;
|
||||
|
||||
// Створення об'єкта CSSStyleSheet (якщо підтримується)
|
||||
let appTerritoryCardStyles = null;
|
||||
if (typeof CSSStyleSheet !== 'undefined' && CSSStyleSheet.prototype.replaceSync) {
|
||||
appTerritoryCardStyles = new CSSStyleSheet(); // (2) Визначення об'єкта тут
|
||||
appTerritoryCardStyles.replaceSync(CARD_STYLES_CSS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Веб-компонент AppTerritoryCard.
|
||||
* Відображає картку території з фоновим зображенням та різними режимами відображення.
|
||||
*/
|
||||
class AppTerritoryCard extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
this.attachShadow({ mode: 'open' });
|
||||
|
||||
// Додаємо стилі в конструкторі, якщо це adoptable
|
||||
if (this.shadowRoot.adoptedStyleSheets) {
|
||||
this.shadowRoot.adoptedStyleSheets = [appTerritoryCardStyles];
|
||||
} else {
|
||||
// FALLBACK для старих браузерів (наприклад, iOS < 16.4)
|
||||
const style = document.createElement('style');
|
||||
style.textContent = CARD_STYLES_CSS;
|
||||
this.shadowRoot.appendChild(style);
|
||||
}
|
||||
}
|
||||
|
||||
// Определяем, какие атрибуты будем отслеживать
|
||||
// Вказуємо, які атрибути ми хочемо відстежувати
|
||||
static get observedAttributes() {
|
||||
return ['image', 'address', 'sheep', 'link', 'atWork', 'quantity'];
|
||||
return ['image', 'address', 'sheep', 'link', 'atWork', 'quantity', 'overdue'];
|
||||
}
|
||||
|
||||
// Геттери та Сеттери для атрибутів
|
||||
// Вони спрощують роботу з атрибутами як з властивостями DOM-елемента
|
||||
|
||||
get image() {
|
||||
return this.getAttribute('image');
|
||||
}
|
||||
@@ -198,6 +220,11 @@ class AppTerritoryCard extends HTMLElement {
|
||||
}
|
||||
}
|
||||
|
||||
/** * Атрибут 'sheep' може приймати три стани:
|
||||
* 1. null / відсутній: відключення блоку sheep та info
|
||||
* 2. порожній рядок ('') / присутній без значення: Режим "Територія не опрацьовується"
|
||||
* 3. рядок зі значенням: Режим "Територію опрацьовує: [значення]"
|
||||
*/
|
||||
get sheep() {
|
||||
return this.getAttribute('sheep');
|
||||
}
|
||||
@@ -228,6 +255,7 @@ class AppTerritoryCard extends HTMLElement {
|
||||
if (newValue === null) {
|
||||
this.removeAttribute('atWork');
|
||||
} else {
|
||||
// Приводимо до рядка, оскільки атрибути завжди є рядками
|
||||
this.setAttribute('atWork', String(newValue));
|
||||
}
|
||||
}
|
||||
@@ -239,41 +267,74 @@ class AppTerritoryCard extends HTMLElement {
|
||||
if (newValue === null) {
|
||||
this.removeAttribute('quantity');
|
||||
} else {
|
||||
// Приводимо до рядка
|
||||
this.setAttribute('quantity', String(newValue));
|
||||
}
|
||||
}
|
||||
|
||||
// Вызывается при добавлении элемента в DOM
|
||||
get overdue() {
|
||||
return this.getAttribute('address');
|
||||
}
|
||||
set overdue(newValue) {
|
||||
if (newValue === null) {
|
||||
this.removeAttribute('overdue');
|
||||
} else {
|
||||
this.setAttribute('overdue', newValue);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* connectedCallback викликається, коли елемент додається в DOM.
|
||||
* Тут ми викликаємо початкове рендеринг.
|
||||
*/
|
||||
connectedCallback() {
|
||||
this.render();
|
||||
}
|
||||
|
||||
// Вызывается при изменении одного из отслеживаемых атрибутов
|
||||
/**
|
||||
* attributeChangedCallback викликається при зміні одного зі спостережуваних атрибутів.
|
||||
*/
|
||||
attributeChangedCallback(name, oldValue, newValue) {
|
||||
if (oldValue !== newValue) {
|
||||
this.render();
|
||||
this.render(); // Перерендеринг при зміні атрибута
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Логіка рендерингу (відображення) вмісту компонента.
|
||||
*/
|
||||
render() {
|
||||
const image = this.getAttribute('image') || '';
|
||||
const address = this.getAttribute('address') || '';
|
||||
const sheep = this.getAttribute('sheep'); // Может быть null или ""
|
||||
const sheep = this.getAttribute('sheep');
|
||||
const link = this.getAttribute('link') || '#';
|
||||
const atWork = this.getAttribute('atWork'); // Может быть null
|
||||
const quantity = this.getAttribute('quantity'); // Может быть null
|
||||
const atWork = this.getAttribute('atWork');
|
||||
const quantity = this.getAttribute('quantity');
|
||||
const overdue = this.getAttribute('overdue') == 'true' ? true : false;
|
||||
|
||||
this.shadowRoot.innerHTML = ``;
|
||||
|
||||
// Додаємо стилі для старих браузерів
|
||||
if (!this.shadowRoot.adoptedStyleSheets) {
|
||||
const style = document.createElement('style');
|
||||
style.textContent = CARD_STYLES_CSS;
|
||||
this.shadowRoot.appendChild(style);
|
||||
}
|
||||
|
||||
|
||||
// --- Логика определения контента ---
|
||||
let contentHTML = '';
|
||||
|
||||
// Перевіряємо, чи має бути увімкнений режим прогресу ('info'):
|
||||
// обидва атрибути 'atWork' та 'quantity' присутні і є коректними числами.
|
||||
const isProgressMode = atWork !== null && quantity !== null && !isNaN(parseInt(atWork)) && !isNaN(parseInt(quantity));
|
||||
const hasSheep = sheep !== null && sheep !== '';
|
||||
|
||||
if (isProgressMode) {
|
||||
// Режим прогресса (свободные подъезды)
|
||||
// Режим прогресу (вільні під'їзди)
|
||||
const atWorkNum = parseInt(atWork);
|
||||
const quantityNum = parseInt(quantity);
|
||||
|
||||
const free = quantityNum - atWorkNum;
|
||||
// Обчислення відсотка прогресу. Уникнення ділення на нуль.
|
||||
const progressPercent = quantityNum > 0 ? (atWorkNum / quantityNum) * 100 : 100;
|
||||
|
||||
contentHTML = `
|
||||
@@ -286,15 +347,15 @@ class AppTerritoryCard extends HTMLElement {
|
||||
</div>
|
||||
`;
|
||||
} else if (sheep !== null && sheep !== '') {
|
||||
// Режим ответственного
|
||||
// Режим опрацювання (значення атрибута 'sheep' є ім'ям опрацювача)
|
||||
contentHTML = `
|
||||
<div class="sheep">
|
||||
<div class="sheep" ${overdue ? `style="background: #bb4444;"` : ``}>
|
||||
<span>Територію опрацьовує:</span>
|
||||
<p>${sheep}</p>
|
||||
</div>
|
||||
`;
|
||||
} else if (sheep !== null) {
|
||||
// Режим "не опрацьовується"
|
||||
} else if (sheep !== null && sheep === '') {
|
||||
// Режим "не опрацьовується" (атрибут 'sheep' присутній, але порожній)
|
||||
contentHTML = `
|
||||
<div class="sheep">
|
||||
<span>Територія не опрацьовується</span>
|
||||
@@ -302,9 +363,9 @@ class AppTerritoryCard extends HTMLElement {
|
||||
`;
|
||||
}
|
||||
|
||||
// --- Сборка всего шаблона ---
|
||||
this.shadowRoot.innerHTML = `
|
||||
<div class="card">
|
||||
// --- Складання всього шаблону ---
|
||||
this.shadowRoot.innerHTML += `
|
||||
<div class="card" ${overdue ? `title="Термін опрацювання минув!"` : ``}>
|
||||
<img src="${image}" alt="${address}" />
|
||||
<div class="contents">
|
||||
<h1 class="address">${address}</h1>
|
||||
@@ -316,8 +377,42 @@ class AppTerritoryCard extends HTMLElement {
|
||||
}
|
||||
}
|
||||
|
||||
// Регистрируем веб-компонент
|
||||
// Реєструємо веб-компонент у браузері
|
||||
customElements.define('app-territory-card', AppTerritoryCard);
|
||||
|
||||
// document.getElementById('app-territory-card-1').setAttribute('sheep', 'test')
|
||||
|
||||
/*
|
||||
============================
|
||||
ПРИКЛАД ВИКОРИСТАННЯ
|
||||
============================
|
||||
*/
|
||||
|
||||
/*
|
||||
<app-territory-card
|
||||
address="Вул. Прикладна, 15А"
|
||||
image="https://example.com/images/territory-1.jpg"
|
||||
link="/territory/15a"
|
||||
atWork="12"
|
||||
quantity="20"
|
||||
></app-territory-card>
|
||||
|
||||
<app-territory-card
|
||||
address="Просп. Науковий, 5"
|
||||
image="https://example.com/images/territory-2.jpg"
|
||||
link="/territory/naukovyi-5"
|
||||
sheep="Іван Петренко"
|
||||
></app-territory-card>
|
||||
|
||||
<app-territory-card
|
||||
address="Майдан Свободи, 1"
|
||||
image="https://example.com/images/territory-3.jpg"
|
||||
link="/territory/svobody-1"
|
||||
sheep=""
|
||||
></app-territory-card>
|
||||
|
||||
<app-territory-card
|
||||
address="Вул. Безіменна, 99"
|
||||
image="https://example.com/images/territory-4.jpg"
|
||||
link="/territory/bezymenna-99"
|
||||
></app-territory-card>
|
||||
*/
|
||||
Reference in New Issue
Block a user