tampermonkey/idea/idea-kfz-zd.user.js
2025-12-15 19:42:21 +01:00

584 lines
26 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ==UserScript==
// @name IDEA ERP KFZ
// @namespace http://tampermonkey.net/
// @version 0.16
// @description Przełączanie widoczności produktów z korektą w module KFZ IDEA ERP
// @author Adam
// @match https://emma.ideaerp.pl/*
// @icon https://emma.ideaerp.pl/web/static/src/img/favicon.ico
// @downloadURL https://n8n.emma.net.pl/webhook/kfz-zd
// @updateURL https://n8n.emma.net.pl/webhook/kfz-zd
// @grant none
// @run-at document-end
// ==/UserScript==
try {
console.log('[Tampermonkey KFZ] Skrypt załadowany - wersja 0.16');
} catch(e) {
alert('Błąd w Tampermonkey KFZ: ' + e);
}
/* ========================OPIS==============================
WERSJA 0.16 - Znajdowanie kolumny po indeksie (data-name tylko w th, nie w td)
WYMAGANE PARAMETRY URL:
- action=276 (ID akcji KFZ - Korekty zakupu)
- menu_id=141 (ID menu KFZ)
- view_type=form (tylko widok formularza)
- Skrypt działa TYLKO na stronie faktury korygującej (KFZ)
WYMAGANE ELEMENTY:
- Element .o_notebook ul.nav.nav-tabs (zakładki na stronie)
- Tabela .o_field_x2many[name="invoice_line_ids"] table.o_list_table
- Kolumna data-name="price_subtotal" (wartość korekty)
- Element .o_pager .o_pager_value (zakres paginacji)
- Element .o_pager .o_pager_limit (całkowita liczba produktów)
DZIAŁANIE SKRYPTU:
- Dodaje przycisk w zakładkach strony
- "Pokaż korygowane produkty" → ładuje wszystkie produkty i ukrywa wiersze z wartością = 0
- "Pokaż wszystko" → pokazuje wszystkie wiersze i resetuje do domyślnego widoku
- Filtrowanie po kolumnie price_subtotal (nie używa indeksów kolumn)
- Bezpieczne obsługiwanie dla < 41 produktów (brak paginacji)
FUNKCJE:
- runScriptCheck() - sprawdza czy hash się zmienił i czy to właściwa strona, dodaje przycisk tylko raz
- isCorrectPage() - sprawdza czy to właściwa strona KFZ (action=276, menu_id=141, view_type=form)
- createTestButton() - tworzy przycisk w interfejsie
- parsePolishNumber() - parsuje polskie wartości numeryczne (przecinek, zł, etc.)
- toggleValueRows() - filtruje wiersze według wartości (ukrywa/pokazuje wartość = 0)
- changePaginationRange() - pomocnicza funkcja do zmiany zakresu paginacji
- loadAllProducts() - ładuje wszystkie produkty
- resetToDefault() - resetuje do domyślnego widoku (1-40)
- init() - inicjalizuje skrypt i czeka na poprawne parametry URL w SPA (do 5 sek)
- startElementCheck() - sprawdza elementy DOM po potwierdzeniu poprawności URL
NASTĘPNE KROKI:
- Zapamiętywanie stanu filtra między sesjami
- Dodanie wskaźnika liczby widocznych/ukrytych wierszy
AUTOMATYCZNE AKTUALIZACJE:
- Serwer aktualizacji: https://n8n.emma.net.pl/webhook/kfz-zd
- Tampermonkey automatycznie sprawdza dostępność nowych wersji
CHANGELOG:
v0.16 (2025) - ZNAJDOWANIE KOLUMNY PO INDEKSIE Z NAGŁÓWKA
- Naprawiono problem z brakiem atrybutu data-name w komórkach <td>
- Teraz znajdujemy kolumnę po indeksie z nagłówka <th[data-name="price_subtotal"]>
- Pobieramy indeks kolumny z nagłówka i używamy go do znalezienia komórki w wierszu
- Dodano obsługę wielu wierszy w thead (pomijamy .i7_list_search_wrap)
- Dodano szczegółowe logi pokazujące liczbę znalezionych komórek w wierszu
- Podwyższenie numeru wersji do 0.16
v0.15 (2025) - POPRAWIONO PARSOWANIE WARTOŚCI Z &NBSP; I PRZECINKAMI
- Naprawiono funkcję parsePolishNumber() - zamiana WSZYSTKICH przecinków na kropki
- Dodano obsługę &amp;nbsp; (zakodowany entity) w atrybucie title
- Dodano szczegółowe logi parsowania każdej wartości
- Naprawiono problem z filtrowaniem wierszy z wartościami ujemnymi (np. -10,15)
- Filtrowanie teraz poprawnie rozpoznaje wartości z przecinkami i spacjami
- Podwyższenie numeru wersji do 0.16
v0.14 (2025) - DODANO NASŁUCHIWANIE NA ZMIANY HASH
- Dodano window.addEventListener('hashchange') do nasłuchiwania zmian URL
- Dodano funkcję runScriptCheck() która sprawdza czy dodano przycisk
- Dodano zmienną buttonAdded żeby nie dodawać przycisku wielokrotnie
- Gdy hash się zmienia, resetujemy stan i ponownie sprawdzamy
- Naprawiono problem z brakiem działania przy nawigacji z listingu
- Podwyższenie numeru wersji do 0.16
v0.13 (2025) - ZMIANA @run-at NA document-end
- Zmieniono @run-at z document-start na document-end
- Dodano try-catch blok dla wychwycenia błędów
- document-end jest bardziej kompatybilny z SPA aplikacjami
- Naprawiono problem z brakiem uruchomienia skryptu
- Podwyższenie numeru wersji do 0.16
v0.12 (2025) - ELASTYCZNE SPRAWDZANIE PARAMETRÓW URL
- Funkcja isCorrectPage() teraz rozróżnia brak view_type od błędnego view_type
- Gdy action=276 i menu_id=141 są OK, ale view_type jest null - skrypt czeka
- Dodano specjalny log "⏳ Czekam na view_type=form..." gdy parametry są częściowo poprawne
- To pozwala na dłuższe czekanie aż view_type zostanie ustawiony asynchronicznie
- Podwyższenie numeru wersji do 0.12
v0.11 (2025) - ZWIĘKSZONO CZAS OCZEKIWANIA NA URL
- Zwiększono czas oczekiwania z 5 do 10 sekund (100 prób)
- Dodano logowanie co 10 prób (mniej spam w konsoli)
- Naprawiono problem z brakiem działania przy nawigacji z listingu
- Skrypt teraz czeka dłużej na asynchroniczne ustawienie parametrów URL
- Dodano więcej szczegółowych logów przy timeout
- Podwyższenie numeru wersji do 0.11
v0.10 (2025) - @run-at document-start + natychmiastowy console.log
- Zmieniono @run-at z document-end na document-start dla wcześniejszego uruchomienia
- Dodano natychmiastowy console.log przed IIFE dla debugowania
- Naprawiono problem z brakiem logów w konsoli
- Skrypt uruchamia się teraz na samym początku ładowania strony
- Podwyższenie numeru wersji do 0.10
v0.9 (2025) - OBSŁUGA ASYNCHRONICZNEGO URL W SPA
- Skrypt czeka do 5 sekund na ustawienie prawidłowych parametrów URL
- Naprawiono problem z brakiem przycisku gdy przechodzi się z listingu
- Dodano rozszerzone logi sprawdzające parametry URL
- Funkcja startElementCheck() - osobna funkcja do sprawdzania elementów DOM
- Skrypt działa zarówno przy bezpośrednim linku jak i przy nawigacji z listingu
- URLSearchParams parsuje parametry niezależnie od kolejności
- Podwyższenie numeru wersji do 0.9
v0.8 (2025) - DODANO KONTROLĘ URL
- Dodano funkcję isCorrectPage() sprawdzającą parametry URL
- Skrypt działa tylko na stronie KFZ (action=276, menu_id=141, view_type=form)
- Poprawiono parametry z action=278 na action=276
- Zmieniono menu_id=167 lub 141 na tylko menu_id=141
- Dodano sprawdzanie view_type=form (tylko widok formularza)
- Skrypt nie uruchamia się na niewłaściwych stronach
- Podwyższenie numeru wersji do 0.8
v0.7 (2025) - DODANO FILTROWANIE WIERSZY WEDŁUG WARTOŚCI
- Dodano funkcję toggleValueRows() do ukrywania wierszy z wartością = 0
- Dodano funkcję parsePolishNumber() do parsowania polskich wartości
- Filtrowanie po kolumnie data-name="price_subtotal" (nie używa indeksów)
- "Pokaż korygowane produkty" → ukrywa wiersze z wartością = 0
- "Pokaż wszystko" → pokazuje wszystkie wiersze
- Dodano logi pokazujące wartość każdego wiersza
- Podwyższenie numeru wersji do 0.7
v0.6 (2025) - POPRAWKA SPRAWDZANIA PUSTYCH WARTOŚCI PAGINACJI
- Dodano sprawdzenie czy totalProducts i currentRange nie są puste
- Eliminacja problemu z ustawianiem zakresu "1-" (pusta wartość)
- Teraz poprawnie wykrywa gdy wartości są puste i przerywa działanie
- Podwyższenie numeru wersji do 0.6
v0.5 (2025) - POPRAWKA OBSŁUGI < 41 PRODUKTÓW
- Dodano lepsze zabezpieczenia w loadAllProducts() dla < 41 produktów
- Dodano sprawdzenie w resetToDefault() - nie resetuje gdy brak paginacji
- Eliminacja problemu z pojawianiem się paginacji po pierwszym kliknięciu
- Dodano szczegółowe logi do debugowania
- Podwyższenie numeru wersji do 0.5
v0.4 (2025) - POPRAWKA LOGIKI PAGINACJI I BEZPIECZEŃSTWA
- Dodano funkcję changePaginationRange() - wspólna logika zmiany zakresu
- Dodano funkcję resetToDefault() - reset do domyślnego widoku
- Poprawiono logikę przycisku: "Pokaż korygowane" → wszystkie produkty, "Pokaż wszystko" → 1-40
- Bezpieczne obsługiwanie < 41 produktów (brak paginacji nie powoduje błędów)
- Eliminacja problemu z pokazywaniem tylko ostatniego produktu
- Podwyższenie numeru wersji do 0.4
v0.3 (2025) - POPRAWKA ZAKRESU PAGINACJI
- Poprawiono zakres paginacji z "195" na "1-195" (pełny zakres)
- Teraz pokazuje wszystkie produkty zamiast tylko ostatniego
- Zaktualizowano logi konsoli dla lepszej czytelności
- Podwyższenie numeru wersji do 0.3
v0.2 (2025) - ŁADOWANIE WSZYSTKICH PRODUKTÓW
- Dodano funkcję loadAllProducts() do automatycznego ładowania wszystkich produktów
- Po kliknięciu przycisku zmienia zakres paginacji z "1-40" na "1-{całkowita_liczba}"
- Implementacja poprzez kliknięcie w .o_pager_value, wpisanie wartości i naciśnięcie Enter
- Podwyższenie numeru wersji do 0.2
v0.1 (2025) - TESTOWA WERSJA
- Dodano podstawowy przycisk w zakładkach
- Przycisk zmienia swoją nazwę po kliknięciu
- Brak funkcjonalności filtrowania
- Podwyższenie numeru wersji do 0.1 (testowa wersja)
============================================================ */
(() => {
'use strict';
console.log('[Tampermonkey KFZ] Wersja 0.16 - znajdowanie kolumny po indeksie z nagłówka');
// Zmienne do śledzenia stanu
let lastHash = '';
let buttonAdded = false;
// Funkcja do uruchomienia skryptu
function runScriptCheck() {
console.log('[Tampermonkey KFZ] runScriptCheck wywołane, hash:', window.location.hash);
// Jeśli już dodaliśmy przycisk, nie dodajemy ponownie
if (buttonAdded) {
console.log('[Tampermonkey KFZ] Przycisk już dodany, pomijam');
return;
}
// Jeśli hash się nie zmienił, nie sprawdzamy ponownie
if (lastHash === window.location.hash) {
console.log('[Tampermonkey KFZ] Hash bez zmian, pomijam');
return;
}
lastHash = window.location.hash;
// Sprawdzamy czy to właściwa strona
if (isCorrectPage()) {
console.log('[Tampermonkey KFZ] ✅ Poprawna strona, uruchamiam startElementCheck()');
buttonAdded = true; // Oznaczamy że dodaliśmy przycisk
startElementCheck();
}
}
// Funkcja sprawdzająca czy to właściwa strona (KFZ - korekty zakupu)
function isCorrectPage() {
const hash = window.location.hash;
console.log('[Tampermonkey KFZ] Sprawdzam URL hash:', hash);
console.log('[Tampermonkey KFZ] Pełny URL:', window.location.href);
// Parametry są w hash, np. #action=276&menu_id=141&view_type=form
if (!hash || hash.length <= 1) {
console.log('[Tampermonkey KFZ] Brak parametrów w hash lub hash jest pusty');
return false;
}
if (!hash.includes('action=')) {
console.log('[Tampermonkey KFZ] Hash nie zawiera parametru action');
return false;
}
// Parsujemy parametry z hash
const params = new URLSearchParams(hash.substring(1)); // usuwamy #
const action = params.get('action');
const menuId = params.get('menu_id');
const viewType = params.get('view_type');
console.log('[Tampermonkey KFZ] Parsowanie: action =', action, ', menu_id =', menuId, ', view_type =', viewType);
// Sprawdzamy czy to strona korekty zakupu
// Wymagamy action=276 i menu_id=141
// view_type może być jeszcze nie ustawiony (będzie ustawiony później)
const hasCorrectAction = action === '276';
const hasCorrectMenu = menuId === '141';
const hasFormView = viewType === 'form';
const isWaitingForViewType = hasCorrectAction && hasCorrectMenu && !viewType;
const isCorrect = hasCorrectAction && hasCorrectMenu && hasFormView;
if (isWaitingForViewType) {
console.log('[Tampermonkey KFZ] ⏳ Czekam na view_type=form...');
console.log('[Tampermonkey KFZ] Otrzymano: action=' + action + ', menu_id=' + menuId + ', view_type=' + viewType);
return false; // Jeszcze czekamy
}
if (!isCorrect) {
console.log('[Tampermonkey KFZ] ❌ To nie jest strona KFZ (korekty zakupu na formularzu)');
console.log('[Tampermonkey KFZ] Wymagane: action=276, menu_id=141, view_type=form');
console.log('[Tampermonkey KFZ] Otrzymano: action=' + action + ', menu_id=' + menuId + ', view_type=' + viewType);
} else {
console.log('[Tampermonkey KFZ] ✅ Poprawna strona KFZ wykryta');
}
return isCorrect;
}
// Funkcja pomocnicza do zmiany zakresu paginacji
function changePaginationRange(newRange) {
console.log('[Tampermonkey KFZ] Zmieniam zakres paginacji na:', newRange);
const pager = document.querySelector('.o_field_x2many[name="invoice_line_ids"] .o_pager');
if (!pager) {
console.log('[Tampermonkey KFZ] Nie znaleziono paginacji (mniej niż 41 produktów)');
return false;
}
const pagerValue = pager.querySelector('.o_pager_value');
if (!pagerValue) {
console.log('[Tampermonkey KFZ] Nie znaleziono elementu .o_pager_value');
return false;
}
pagerValue.click();
setTimeout(() => {
const input = pager.querySelector('.o_pager_value input');
if (input) {
input.value = newRange;
const enterEvent = new KeyboardEvent('keydown', {
key: 'Enter',
code: 'Enter',
keyCode: 13,
bubbles: true
});
input.dispatchEvent(enterEvent);
console.log('[Tampermonkey KFZ] Ustawiono zakres na:', newRange);
}
}, 500);
return true;
}
// Funkcja do parsowania polskich wartości numerycznych
function parsePolishNumber(value) {
if (!value) return 0;
console.log('[Tampermonkey KFZ] Parsuję wartość:', value);
// Usuwamy "zł", wszystkie spacje (w tym &nbsp; i &amp;nbsp;), zastępujemy przecinki kropkami
let cleanValue = value
.replace(/zł/gi, '') // Usuń zł
.replace(/\s+/g, '') // Usuń wszystkie białe znaki (w tym zwykłe spacje)
.replace(/&nbsp;/g, '') // Usuń &nbsp;
.replace(/&amp;nbsp;/g, '') // Usuń zakodowane &amp;nbsp;
.replace(/,/g, '.'); // Zamień WSZYSTKIE przecinki na kropki
console.log('[Tampermonkey KFZ] Oczyszczona wartość:', cleanValue);
const result = parseFloat(cleanValue) || 0;
console.log('[Tampermonkey KFZ] Wynik:', result);
return result;
}
// Funkcja do filtrowania wierszy - ukrywanie/pokazywanie wierszy z wartością = 0
function toggleValueRows(showOnlyWithValue) {
console.log('[Tampermonkey KFZ] Filtruję wiersze - pokazuję tylko z wartością ≠ 0:', showOnlyWithValue);
// Szukamy tabeli pozycji faktury
const table = document.querySelector('.o_field_x2many[name="invoice_line_ids"] table.o_list_table');
if (!table) {
console.log('[Tampermonkey KFZ] Nie znaleziono tabeli');
return;
}
// Szukamy nagłówka kolumny "Wartość" po data-name
// W thead może być kilka wierszy, bierzemy pierwszy (nie .i7_list_search_wrap)
const headerRow = table.querySelector('thead tr:not(.i7_list_search_wrap)');
const headers = headerRow.querySelectorAll('th');
let priceSubtotalIndex = -1;
headers.forEach((th, idx) => {
if (th.getAttribute('data-name') === 'price_subtotal') {
priceSubtotalIndex = idx;
console.log('[Tampermonkey KFZ] Znaleziono kolumnę price_subtotal na indeksie', priceSubtotalIndex);
}
});
if (priceSubtotalIndex === -1) {
console.log('[Tampermonkey KFZ] Nie znaleziono kolumny "price_subtotal"');
return;
}
// Pobieramy wszystkie wiersze danych
const rows = table.querySelectorAll('tbody tr.o_data_row');
console.log('[Tampermonkey KFZ] Znaleziono', rows.length, 'wierszy');
let hiddenCount = 0;
let visibleCount = 0;
// Przetwarzamy każdy wiersz
rows.forEach((row, index) => {
// Szukamy wszystkich komórek w wierszu (włączając th i td)
const cells = row.querySelectorAll('th, td');
console.log('[Tampermonkey KFZ] Wiersz', index + 1, '- znaleziono', cells.length, 'komórek');
// Pobieramy komórkę po indeksie kolumny
// UWAGA: W wierszu pierwsza komórka to <th>, więc indeks się zgadza
const valueCell = cells[priceSubtotalIndex];
if (!valueCell) {
console.log('[Tampermonkey KFZ] Wiersz', index + 1, '- brak komórki na indeksie', priceSubtotalIndex);
return;
}
console.log('[Tampermonkey KFZ] Wiersz', index + 1, '- komórka:', valueCell);
// Pobieramy wartość z atrybutu title lub textContent
const valueText = valueCell.getAttribute('title') || valueCell.textContent;
const numericValue = parsePolishNumber(valueText);
console.log('[Tampermonkey KFZ] Wiersz', index + 1, ':', valueText, '->', numericValue);
if (showOnlyWithValue) {
// Pokaż tylko wiersze z wartością ≠ 0
if (numericValue !== 0) {
row.style.display = '';
visibleCount++;
} else {
row.style.display = 'none';
hiddenCount++;
}
} else {
// Pokaż wszystkie wiersze
row.style.display = '';
visibleCount++;
}
});
console.log('[Tampermonkey KFZ] Filtrowanie zakończone - widoczne:', visibleCount, 'ukryte:', hiddenCount);
}
// Funkcja do ładowania wszystkich produktów
function loadAllProducts() {
console.log('[Tampermonkey KFZ] Ładuję wszystkie produkty...');
// Szukamy elementów paginacji - trzeba znaleźć je w kontekście tabeli pozycji faktury
const pager = document.querySelector('.o_field_x2many[name="invoice_line_ids"] .o_pager');
// Jeśli nie ma paginacji, to znaczy że jest mniej niż 41 produktów - wszystkie są już widoczne
if (!pager) {
console.log('[Tampermonkey KFZ] Nie ma paginacji - wszystkie produkty (< 41) są już widoczne');
return;
}
const pagerLimit = pager.querySelector('.o_pager_limit');
const pagerValue = pager.querySelector('.o_pager_value');
if (!pagerLimit || !pagerValue) {
console.log('[Tampermonkey KFZ] Nie znaleziono elementów paginacji');
return;
}
const totalProducts = pagerLimit.textContent.trim();
const currentRange = pagerValue.textContent.trim();
console.log('[Tampermonkey KFZ] Aktualny zakres:', currentRange, 'Całkowita liczba:', totalProducts);
// Jeśli wartości są puste, to znaczy że nie ma prawidłowej paginacji
if (!totalProducts || !currentRange) {
console.log('[Tampermonkey KFZ] Wartości paginacji są puste - wszystkie produkty są już widoczne');
return;
}
// Sprawdzamy, czy już są pokazane wszystkie produkty
if (currentRange.includes(`1-${totalProducts}`)) {
console.log('[Tampermonkey KFZ] Wszystkie produkty są już załadowane');
return;
}
console.log('[Tampermonkey KFZ] Zmieniam zakres z', currentRange, 'na 1-', totalProducts);
changePaginationRange(`1-${totalProducts}`);
}
// Funkcja do resetowania do domyślnego widoku
function resetToDefault() {
console.log('[Tampermonkey KFZ] Resetuję do domyślnego widoku...');
// Sprawdzamy czy w ogóle jest paginacja
const pager = document.querySelector('.o_field_x2many[name="invoice_line_ids"] .o_pager');
if (!pager) {
console.log('[Tampermonkey KFZ] Nie ma paginacji (< 41 produktów) - reset nie jest potrzebny');
return;
}
changePaginationRange('1-40');
}
function createTestButton() {
// Szukamy przycisku w zakładkach
const nav = document.querySelector('.o_notebook ul.nav.nav-tabs');
if (!nav) {
console.log('[Tampermonkey KFZ] Nie znaleziono nav-tabs');
return;
}
console.log('[Tampermonkey KFZ] Znaleziono nav-tabs, tworzę przycisk');
// Tworzymy element li
const li = document.createElement('li');
li.className = 'nav-item';
// Tworzymy link
const a = document.createElement('a');
a.href = '#';
a.className = 'nav-link';
a.textContent = 'Pokaż korygowane produkty';
// Dodajemy event listener
a.addEventListener('click', async (e) => {
e.preventDefault();
// Sprawdzamy aktualną nazwę
if (a.textContent === 'Pokaż korygowane produkty') {
a.textContent = 'Pokaż wszystko';
console.log('[Tampermonkey KFZ] Zmieniono nazwę na: Pokaż wszystko');
// Ładujemy wszystkie produkty
loadAllProducts();
// Po załadowaniu filtrujemy wiersze (ukrywamy wartość = 0)
setTimeout(() => {
toggleValueRows(true);
}, 1000);
} else {
a.textContent = 'Pokaż korygowane produkty';
console.log('[Tampermonkey KFZ] Zmieniono nazwę na: Pokaż korygowane produkty');
// Pokaż wszystkie wiersze
toggleValueRows(false);
// Resetujemy do domyślnego widoku
resetToDefault();
}
});
li.appendChild(a);
nav.appendChild(li);
console.log('[Tampermonkey KFZ] Przycisk dodany pomyślnie');
}
// Funkcja inicjalizująca
function init() {
console.log('[Tampermonkey KFZ] Inicjalizacja...');
// W aplikacji SPA parametry URL mogą być ustawiane asynchronicznie
// Czekamy do 10 sekund na poprawne parametry URL
let attempts = 0;
const maxAttempts = 100; // 100 * 100ms = 10 sekund
console.log('[Tampermonkey KFZ] Rozpoczynam sprawdzanie URL (max 100 prób co 100ms)');
// Nasłuchujemy na zmiany URL (hashchange)
window.addEventListener('hashchange', () => {
console.log('[Tampermonkey KFZ] 🎯 Hash changed!');
buttonAdded = false; // Resetujemy stan - możliwa nowa strona
lastHash = ''; // Resetujemy hash żeby wykryć zmianę
setTimeout(runScriptCheck, 200);
});
const urlCheckInterval = setInterval(() => {
attempts++;
// Log co 10 prób
if (attempts % 10 === 0 || attempts === 1) {
console.log('[Tampermonkey KFZ] Próba', attempts, '/', maxAttempts, 'sprawdzenia URL...');
}
runScriptCheck();
if (attempts >= maxAttempts) {
console.log('[Tampermonkey KFZ] ❌ Timeout po', attempts, 'próbach');
clearInterval(urlCheckInterval);
}
}, 100); // Sprawdzamy co 100ms
}
// Funkcja sprawdzająca elementy strony po potwierdzeniu URL
function startElementCheck() {
// Szukamy elementów strony
const checkInterval = setInterval(() => {
const nav = document.querySelector('.o_notebook ul.nav.nav-tabs');
console.log('[Tampermonkey KFZ] Sprawdzam nav-tabs:', !!nav);
if (nav) {
clearInterval(checkInterval);
createTestButton();
}
}, 500);
// Timeout po 10 sekundach
setTimeout(() => {
clearInterval(checkInterval);
console.log('[Tampermonkey KFZ] Timeout - nie znaleziono nav-tabs');
}, 10000);
}
// Start
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();