Skip to content

Commit 93ed26d

Browse files
committed
Fixes, added tree view for keys
1 parent ecfe233 commit 93ed26d

File tree

15 files changed

+430
-44
lines changed

15 files changed

+430
-44
lines changed

assets/css/styles.css

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
/*! tailwindcss v4.0.5 | MIT License | https://tailwindcss.com */
1+
/*! tailwindcss v4.0.6 | MIT License | https://tailwindcss.com */
22
@layer theme, base, components, utilities;
33
@layer theme {
44
:root, :host {
5+
--color-primary-50: #f8fafc;
6+
--color-primary-100: #f1f5f9;
57
--color-primary-200: #e2e8f0;
68
--color-primary-300: #cbd5e1;
79
--color-primary-400: #94a3b8;
@@ -10,6 +12,7 @@
1012
--color-primary-700: #334155;
1113
--color-primary-800: #1e293b;
1214
--color-primary-900: #0f172a;
15+
--color-primary-950: #020617;
1316
--link-bg: #64748b;
1417
--link-bg-hover: #334155;
1518
--link-active: #cbd5e1;
@@ -194,6 +197,9 @@
194197
.-mt-1\.5 {
195198
margin-top: calc(0.25rem * -1.5);
196199
}
200+
.mt-0 {
201+
margin-top: calc(0.25rem * 0);
202+
}
197203
.mr-3 {
198204
margin-right: calc(0.25rem * 3);
199205
}
@@ -276,6 +282,9 @@
276282
.table-auto {
277283
table-layout: auto;
278284
}
285+
.-rotate-90 {
286+
rotate: calc(90deg * -1);
287+
}
279288
.rotate-180 {
280289
rotate: 180deg;
281290
}
@@ -442,6 +451,9 @@
442451
.p-4 {
443452
padding: calc(0.25rem * 4);
444453
}
454+
.px-2 {
455+
padding-inline: calc(0.25rem * 2);
456+
}
445457
.px-3 {
446458
padding-inline: calc(0.25rem * 3);
447459
}
@@ -469,6 +481,9 @@
469481
.py-\[0\.54rem\] {
470482
padding-block: 0.54rem;
471483
}
484+
.pb-2 {
485+
padding-bottom: calc(0.25rem * 2);
486+
}
472487
.pl-6 {
473488
padding-left: calc(0.25rem * 6);
474489
}
@@ -645,6 +660,13 @@
645660
}
646661
}
647662
}
663+
.hover\:bg-gray-300 {
664+
&:hover {
665+
@media (hover: hover) {
666+
background-color: oklch(0.872 0.01 258.338);
667+
}
668+
}
669+
}
648670
.hover\:bg-green-600 {
649671
&:hover {
650672
@media (hover: hover) {
@@ -1360,6 +1382,32 @@
13601382
.dark #phpinfo .v i {
13611383
color: #c2c2c2;
13621384
}
1385+
@keyframes spin {
1386+
to {
1387+
transform: rotate(360deg);
1388+
}
1389+
}
1390+
@keyframes ping {
1391+
75%, 100% {
1392+
transform: scale(2);
1393+
opacity: 0;
1394+
}
1395+
}
1396+
@keyframes pulse {
1397+
50% {
1398+
opacity: 0.5;
1399+
}
1400+
}
1401+
@keyframes bounce {
1402+
0%, 100% {
1403+
transform: translateY(-25%);
1404+
animation-timing-function: cubic-bezier(0.8, 0, 1, 1);
1405+
}
1406+
50% {
1407+
transform: none;
1408+
animation-timing-function: cubic-bezier(0, 0, 0.2, 1);
1409+
}
1410+
}
13631411
@property --tw-space-x-reverse {
13641412
syntax: "*";
13651413
inherits: false;

assets/icons/tableview.svg

Lines changed: 3 additions & 0 deletions
Loading

assets/icons/treeview.svg

Lines changed: 3 additions & 0 deletions
Loading

assets/js/scripts.js

Lines changed: 112 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,14 @@ if (delete_selected) {
6060
document.querySelectorAll('.check-key:checked').forEach(checkbox => {
6161
let parent = checkbox.parentElement.parentElement;
6262
selected_keys.push(parent.dataset.key);
63-
parent.remove();
63+
64+
const treeview = document.querySelector('.treeview');
65+
if (treeview) {
66+
parent.closest('.keywrapper').remove();
67+
update_folder_counts();
68+
} else {
69+
parent.remove();
70+
}
6471
});
6572

6673
ajax('delete', function (request) {
@@ -92,7 +99,14 @@ keys.forEach(key => {
9299
ajax('delete', function (request) {
93100
if (this.status >= 200 && this.status < 400) {
94101
document.getElementById('alerts').innerHTML = request.currentTarget.response;
95-
key.remove();
102+
103+
const treeview = document.querySelector('.treeview');
104+
if (treeview) {
105+
key.closest('.keywrapper').remove();
106+
update_folder_counts();
107+
} else {
108+
key.remove();
109+
}
96110
}
97111
}, key.dataset.key);
98112
});
@@ -111,7 +125,13 @@ if (delete_all) {
111125
document.getElementById('alerts').innerHTML = request.currentTarget.response;
112126

113127
keys.forEach(key => {
114-
key.remove();
128+
const treeview = document.querySelector('.treeview');
129+
if (treeview) {
130+
key.closest('.keywrapper').remove();
131+
update_folder_counts();
132+
} else {
133+
key.remove();
134+
}
115135
});
116136

117137
document.getElementById('table-no-keys').classList.remove('hidden');
@@ -221,6 +241,95 @@ document.querySelectorAll('[data-sortcol]').forEach(element => {
221241
});
222242
});
223243

244+
/**
245+
* Tree view
246+
*/
247+
const treeview = document.querySelector('.treeview');
248+
if (treeview) {
249+
let is_expanded = false;
250+
const expand_toggle = treeview.querySelector('.expand-toggle');
251+
252+
expand_toggle.addEventListener('click', function () {
253+
is_expanded = !is_expanded;
254+
expand_toggle.textContent = is_expanded ? 'Collapse all' : 'Expand all';
255+
256+
const folders = treeview.querySelectorAll('.tree-toggle');
257+
folders.forEach(button => toggle_folder(button, is_expanded));
258+
259+
const paths = [...folders].map(f => f.dataset.path).filter(Boolean);
260+
localStorage.setItem('open_folders', is_expanded ? JSON.stringify(paths) : '[]');
261+
});
262+
263+
function toggle_folder(button, show = null) {
264+
// Find the next sibling that contains the children
265+
const children = button.closest('div').parentElement.querySelector('.tree-children');
266+
if (!children) return false;
267+
268+
const chevron = button.querySelector('svg');
269+
const will_show = show !== null ? show : children.classList.contains('hidden');
270+
271+
children.classList.toggle('hidden', !will_show);
272+
chevron.style.transform = will_show ? 'rotate(90deg)' : '';
273+
274+
return will_show;
275+
}
276+
277+
// Handle folder toggling
278+
treeview.addEventListener('click', function (e) {
279+
const toggle_btn = e.target.closest('.tree-toggle');
280+
if (toggle_btn) {
281+
e.preventDefault();
282+
e.stopPropagation();
283+
284+
const is_open = toggle_folder(toggle_btn);
285+
const path = toggle_btn.dataset.path;
286+
287+
if (path) {
288+
const open_folders = JSON.parse(localStorage.getItem('open_folders') || '[]');
289+
290+
if (is_open) {
291+
if (!open_folders.includes(path)) open_folders.push(path);
292+
} else {
293+
const index = open_folders.indexOf(path);
294+
if (index > -1) open_folders.splice(index, 1);
295+
}
296+
297+
localStorage.setItem('open_folders', JSON.stringify(open_folders));
298+
}
299+
}
300+
});
301+
302+
function init_expand_state() {
303+
const open_folders = JSON.parse(localStorage.getItem('open_folders') || '[]');
304+
if (open_folders.length > 0) {
305+
is_expanded = true;
306+
expand_toggle.textContent = 'Collapse all';
307+
}
308+
309+
open_folders.forEach(path => {
310+
const button = treeview.querySelector(`.tree-toggle[data-path="${path}"]`);
311+
if (button) toggle_folder(button, true);
312+
});
313+
}
314+
315+
init_expand_state();
316+
}
317+
318+
function update_folder_counts() {
319+
const folders = document.querySelectorAll('.tree-toggle[data-path]');
320+
321+
folders.forEach(folder => {
322+
const path = folder.getAttribute('data-path');
323+
const tree_children = document.querySelector(`.tree-children[data-path="${path}"]`);
324+
const children_count = tree_children ? tree_children.querySelectorAll('.keywrapper').length : 0;
325+
const items_count = folder.parentElement.querySelector('.items-count');
326+
327+
if (items_count) {
328+
items_count.textContent = `(${children_count})`;
329+
}
330+
});
331+
}
332+
224333
/**
225334
* Light / Dark mode
226335
*/

src/Dashboards/APCu/APCuTrait.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ private function getAllKeys(): array {
195195
$keys[] = [
196196
'key' => $key,
197197
'base64' => true,
198-
'items' => [
198+
'info' => [
199199
'link_title' => $key,
200200
'bytes_size' => $key_data['mem_size'],
201201
'number_hits' => $key_data['num_hits'],

src/Dashboards/Memcached/MemcachedTrait.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,8 +218,8 @@ private function getAllKeys(): array {
218218
$ttl = $key_data['exp'] ?? null;
219219

220220
$keys[] = [
221-
'key' => $key,
222-
'items' => [
221+
'key' => $key,
222+
'info' => [
223223
'link_title' => urldecode($key),
224224
'bytes_size' => $key_data['size'],
225225
'timediff_last_access' => $key_data['la'],

src/Dashboards/OPCache/OPCacheTrait.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,8 @@ private function getCachedScripts(): array {
135135

136136
if (stripos($script['full_path'], $search) !== false) {
137137
$cached_scripts[] = [
138-
'key' => $script['full_path'],
139-
'items' => [
138+
'key' => $script['full_path'],
139+
'info' => [
140140
'title' => $full_path,
141141
'number_hits' => $script['hits'],
142142
'bytes_memory' => $script['memory_consumption'],

src/Dashboards/Realpath/RealpathTrait.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ private function getAllKeys(): array {
5050
foreach ($this->all_keys as $key_name => $key_data) {
5151
if (stripos($key_name, $search) !== false) {
5252
$keys[] = [
53-
'key' => $key_name,
54-
'items' => [
53+
'key' => $key_name,
54+
'info' => [
5555
'title' => $key_name,
5656
'realpath' => $key_data['realpath'],
5757
'is_dir' => $key_data['is_dir'] ? 'true' : 'false',

0 commit comments

Comments
 (0)