diff --git a/Aufgabenmonitor.php b/Aufgabenmonitor.php index cef43ac..0aee1b3 100644 --- a/Aufgabenmonitor.php +++ b/Aufgabenmonitor.php @@ -1,113 +1,250 @@ - - - - - - - - - Aufgabenmonitor + + + + + + Aufgabenmonitor - - - - - - - - - - - - + -
-
-
-

Aufgaben

- - - - - - - - - - - - - -
#BearbeiterAufgabeZieldatumPriorität
- - - - -
- - - - - - - + + + +
+
+
+

Aufgaben

+ +
+ + + + + + + + + + + + + +
#BearbeiterAufgabeZieldatumPriorität
+
+ +
+
+ + + + - - - + function isEnabled() { return !!SCROLL_FLAGS.aufgaben; } + + /* =========================== + Höhe der Scroll-Container + - Voller Viewport ab Oberkante + =========================== */ + function sizeScrollContainers() { + const node = document.querySelector('#aufgaben-scroll'); + if (!node) return; + const rect = node.getBoundingClientRect(); + const bottomMargin = 16; + const minH = 120; + const available = window.innerHeight - rect.top - bottomMargin; + node.style.maxHeight = Math.max(minH, available) + 'px'; + } + + /* =========================== + Scroll-/Interaktionsstatus + =========================== */ + const scrollState = new WeakMap(); // { userActive:boolean, autoTimer:number|null, loopHeight:number } + + function ensureState(el) { + if (!scrollState.get(el)) scrollState.set(el, { userActive: false, autoTimer: null, loopHeight: 0 }); + return scrollState.get(el); + } + + function attachScrollGuards($scroller) { + const el = $scroller.get(0); + if (!el || el.__guardsBound) return; + if (!isEnabled()) return; + const state = ensureState(el); + + const markActive = () => { + state.userActive = true; + clearTimeout(state._quietT); + state._quietT = setTimeout(() => { state.userActive = false; }, 800); + stopAutoScroll($scroller); + }; + + $scroller.on('wheel touchstart touchmove keydown mousedown mouseenter', markActive); + $scroller.on('mouseleave', () => setTimeout(() => maybeStartAutoScroll($scroller), 600)); + el.__guardsBound = true; + } + + /* =========================== + Nahtloser Loop (Clone) + =========================== */ + function buildSeamlessLoop($table, $scroller) { + $table.find('tbody.__loopClone').remove(); + + const scEl = $scroller.get(0); + const st = ensureState(scEl); + st.loopHeight = 0; + + if (!isEnabled()) return; + + const $main = $table.find('tbody').first(); + if ($main.length === 0 || $main.children().length === 0) return; + + const needScroll = $main.get(0).offsetHeight > scEl.clientHeight + 1; + if (!needScroll) return; + + const $clone = $main.clone(false, false).addClass('__loopClone').attr('aria-hidden', 'true'); + $table.append($clone); + st.loopHeight = $main.get(0).offsetHeight; + } + + /* =========================== + Auto-Scroll + =========================== */ + function startAutoScroll($scroller, speedPx = 1, stepMs = 40) { + const el = $scroller.get(0); + if (!isEnabled()) return; + + const st = ensureState(el); + if (st.autoTimer) return; + if (st.loopHeight <= 0) return; + + const tick = () => { + if (st.userActive) { stopAutoScroll($scroller); return; } + el.scrollTop += speedPx; + if (el.scrollTop >= st.loopHeight) el.scrollTop -= st.loopHeight; + }; + + st.autoTimer = setInterval(tick, stepMs); + } + + function stopAutoScroll($scroller) { + const el = $scroller.get(0); + const st = ensureState(el); + if (st.autoTimer) { + clearInterval(st.autoTimer); + st.autoTimer = null; + } + } + + function maybeStartAutoScroll($scroller) { + const el = $scroller.get(0); + if (!isEnabled()) { stopAutoScroll($scroller); return; } + const st = ensureState(el); + if (st.userActive) return; + if (st.loopHeight > 0) startAutoScroll($scroller, 1, 80); + else stopAutoScroll($scroller); + } + + /* =========================== + Smart AJAX Reload + =========================== */ + function smartLoad($scroller, $table, $target, url, intervalMs) { + const scEl = $scroller.get(0); + const st = ensureState(scEl); + + const oldLoop = st.loopHeight > 0 ? st.loopHeight : Math.max(1, scEl.scrollHeight - scEl.clientHeight); + const posInLoop = st.loopHeight > 0 ? (scEl.scrollTop % oldLoop) : scEl.scrollTop; + const posRatio = Math.min(1, posInLoop / oldLoop); + + $target.load(url, function () { + buildSeamlessLoop($table, $scroller); + + if (st.loopHeight > 0 && isEnabled()) { + const newPos = Math.floor(posRatio * st.loopHeight); + if (Math.abs(scEl.scrollTop - newPos) > 1) { + requestAnimationFrame(() => { scEl.scrollTop = newPos; }); + } + stopAutoScroll($scroller); + startAutoScroll($scroller, 1, 80); + } else { + if (scEl.scrollTop !== 0) requestAnimationFrame(() => { scEl.scrollTop = 0; }); + stopAutoScroll($scroller); + } + + setTimeout(() => smartLoad($scroller, $table, $target, url, intervalMs), intervalMs); + }); + } + + /* =========================== + Initialisierung + =========================== */ + $(document).ready(function () { + sizeScrollContainers(); + $(window).on('resize', function () { + sizeScrollContainers(); + const $scroller = $('#aufgaben-scroll'); + const $table = $('#aufgaben-table'); + buildSeamlessLoop($table, $scroller); + maybeStartAutoScroll($scroller); + }); + + // Guards nur aktivieren, wenn Scrolling erlaubt + if (isEnabled()) attachScrollGuards($('#aufgaben-scroll')); + + // Erstladen + (function init() { + const $scroller = $('#aufgaben-scroll'); + const $table = $('#aufgaben-table'); + const $target = $('#AufgabenTableHolder'); + const url = 'sources/getAufgabenTable.php'; + const interval = 30000; + + $target.load(url, function () { + buildSeamlessLoop($table, $scroller); + maybeStartAutoScroll($scroller); + setTimeout(() => smartLoad($scroller, $table, $target, url, interval), interval); + }); + })(); + }); + + - - \ No newline at end of file +?> diff --git a/PackAufgabenMonitor.php b/PackAufgabenMonitor.php index 79663b9..9ac584c 100644 --- a/PackAufgabenMonitor.php +++ b/PackAufgabenMonitor.php @@ -23,15 +23,71 @@ $Epi = new Epirent(); - + + + + + + + +
+
+
+
+
+

Konfiguration

+ + + +
+ + +
+ + +
+
+ + Einstellungen + ( Source: ) +
+
+
+ + + + '.h($item['title']).''; + continue; + } + if ($item['kind'] === 'hr') { + echo '
'; + continue; + } + if ($item['kind'] === 'note') { + echo '

'.h($item['text']).'

'; + continue; + } + if ($item['kind'] !== 'define') { + continue; + } + + $key = $item['name']; + // Nur Keys rendern, die in example vorkommen + if (!isset($example['defines'][$key])) continue; + + [$type, $val, $tooltip] = valueForForm($example, $current, $key); + ?> + +
+ + + +
+ /> + +
+ + + + + +
+ + + + +
+
Veraltete Parameter (nur in , nicht mehr in )
+ + +
+ + +
Dieser Parameter ist in der aktuellen Version nicht mehr vorgesehen.
+
+ + + +
+ + Speichert nach +
+
+
+
+ +
+
+
+
+
+ + + + + + diff --git a/example.config.php b/example.config.php index 93ffa5d..8126c5b 100644 --- a/example.config.php +++ b/example.config.php @@ -1,58 +1,59 @@ date_start (Dispo Start) - * 2 = $VorbereitungsTimeDetail->date_start (Vorbereitung Start) - * 3 = $PackingNoteDetail->date_packing (Packen Zeit) - * 4 = $PackingNoteDetail->date_delivery (Delivery Zeit) - */ +define('Nachbereitung_Zeitvariable', 'Rückpacken'); //Name des zu verwendenden Zeitabschnitts aus dem Auftrag, der die Nachbereitung angibt +define('Rückpacken_Zeitvariable', 'Rückpacken'); //Name des zu verwendenden Zeitabschnitts aus dem Auftrag, der das Rückpacken angibt. +define('UseDeliveredForCheckOutCompleted', true); //Nutzt statt dem erfolgreichen abschließen eines Packscheins durch ausbuchen das erfolgreiche Liefern (Geliefert != 00.00.00) +define('EnableScrollingCheckOut', true); //Aktiviert das automatische Scrollen der CheckOut Liste +define('EnableScrollingCheckIn', true); //Aktiviert das automatische Scrollen der CheckIn Liste +define('EnableScrollingAufgaben', true); //Aktiviert das automatische Scrollen der Aufgabenliste +// @note: -------------------- CheckOutRowMarkSource: Konfig Zusände -------------------- +// @note: 1 = $packingjob->date_start (Dispo Start) +// @note: 2 = $VorbereitungsTimeDetail->date_start (Vorbereitung Start) +// @note: 3 = $PackingNoteDetail->date_packing (Packen Zeit) +// @note: 4 = $PackingNoteDetail->date_delivery (Delivery Zeit) define('CheckOutRowMarkSource', 4); -/** -------------------- Row-Marking: Konfig Zusände -------------------- - * 1 = $packingjob->date_end (Dispo Ende) - * 2 = $NachbereitungssTimeDetail->date_start (Nachbereitung Start) - * 3 = $RePackagingTimeDetail->date_start (Rückpacken Zeit AUS AUFTRAG) - * 4 = $PackingNoteDetail->date_redelivery (ReDelivery Zeit) - */ +// @note: -------------------- CheckInRowMarkSource: Konfig Zusände -------------------- +// @note: 1 = $packingjob->date_end (Dispo Ende) +// @note: 2 = $NachbereitungssTimeDetail->date_start (Nachbereitung Start) +// @note: 3 = $RePackagingTimeDetail->date_start (Rückpacken Zeit AUS AUFTRAG) +// @note: 4 = $PackingNoteDetail->date_redelivery (ReDelivery Zeit) define('CheckInRowMarkSource', 4); define('CheckIn_UseDispoEndForRowMarking', false); //else: Use Same Variable as "Rueckpacken Zeitvariable" | Konfiguration, welche Zeit für die Zeilenmarkierung beim Check In Verwendet werden soll -define('ShowCheckoutTimeOnCheckout', true); -define('ShowVorbereitungTimeOnCheckout', true); -define('ShowPackagingTimeOnCheckout', true); -define('ShowDeliveryTimeOnCheckout', true); -define('ShowTimesOnCheckout', true); - -define('ShowCheckInTimeOnCheckin', true); -define('ShowNachbereitungTimeOnCheckin', true); -define('ShowRePackagingTimeOnCheckin', true); -define('ShowReDeliveryTimeOnCheckin', true); -define('ShowTimesOnCheckin', true); +define('ShowCheckoutTimeOnCheckout', true); //Zeigt die Checkout Zeit im Checkout +define('ShowVorbereitungTimeOnCheckout', true); //Zeigt die Vorbereitungs Zeitvariable im Checkout +define('ShowPackagingTimeOnCheckout', true); //Zeigt die Packenzeit im Checkout +define('ShowDeliveryTimeOnCheckout', true); //Zeigt die Lieferzeit im Checkout +define('ShowTimesOnCheckout', true); //Aktiviert das anzeigen der Uhrzeit im Checkout +// @hr +define('ShowCheckInTimeOnCheckin', true); //Zeigt die CheckIn Zeit im CheckIn +define('ShowNachbereitungTimeOnCheckin', true); //Zeigt die Nachbereitungs Zeitvariable im CheckIn +define('ShowRePackagingTimeOnCheckin', true); //Zeigt die Rückpackzeit im Checkin
Achtung: Zeit nur Im Auftrag festlegbar +define('ShowReDeliveryTimeOnCheckin', true); //Zeigt die geplante Rücklieferung im Checkin +define('ShowTimesOnCheckin', true); //Aktiviert das anzeigen der Uhrzeit im CheckIn +// @section: Epirent-Spezifische Einstellungen - Shipping define('ShowShippingIcons', true); //Zeigt Lieferung / Rücklieferungs Icons an define('KurierContainsText', 'Kurier'); //Text, der in der Versandart enthalten sein muss (enthält), damit diese als KURIER erkannt wird. define('SpeditionContainsText', 'Spedition'); //Text, der in der Versandart enthalten sein muss (enthält), damit diese als SPEDITION erkannt wird. @@ -66,8 +67,7 @@ define('ShippingOutOrganizedStatus', 'Hinversand OK'); //Packschein Status (Epir define('ShippingInOrganizedStatus', 'Rückversand OK'); //Packschein Status (EpirentDropdown) der Gematcht werden muss, dass der Rückversand Organisiert / Bestellt wurde define('ShippingOrganizedStatus', 'Versand OK'); //Packschein Status (EpirentDropdown) der Gematcht werden muss, dass der komplette Versand Organisiert / Bestellt wurde -define('UseDeliveredForCheckOutCompleted', true); //Nutzt statt dem erfolgreichen abschließen eines Packscheins durch ausbuchen das erfolgreiche Liefern (Geliefert != 00.00.00) - +// @section: Epirent-Spezifische Einstellungen - Anzeigesortierung define('CheckOut_FutureDays', -1); // Konfiguration, wie viele Tage in der Zukunft der CheckOut angezeigt werden soll. '-1' zeigt alle an. Abhängig von der Variablen CheckOut_UseDispoStartForRowMarking define('CheckIn_FutureDays', -1); // Konfiguration, wie viele Tage in der Zukunft der CheckIn angezeigt werden soll. '-1' zeigt alle an. Abhängig von der Variablen CheckIn_UseDispoEndForRowMarking define('SortCheckOut', 2); // Konfiguration, welcher Datensatz für die Sortierung Verwendet werden soll. Möglichkeiten '1': Packscheinnummer / '2': Dispostart diff --git a/sources/getSidenav.php b/sources/getSidenav.php index a53d418..d682b21 100644 --- a/sources/getSidenav.php +++ b/sources/getSidenav.php @@ -25,6 +25,11 @@ Pack- & Aufgabenmonitor +
Config
+ + + Config +