Fix speed and error
This commit is contained in:
@@ -7,6 +7,11 @@ require_once __DIR__ . '/auth.php';
|
||||
$currentUser = $currentUser ?? require_auth();
|
||||
$currentPage = basename($_SERVER['PHP_SELF']);
|
||||
$currentUserTheme = !empty($currentUser['id']) ? get_user_theme((int)$currentUser['id']) : 'dark';
|
||||
|
||||
// Geef direct het PHP sessieslot vrij voor getoonde pagina's zodat parallelle requests en navigatie nooit blokkeren
|
||||
if (session_status() === PHP_SESSION_ACTIVE && ($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'GET') {
|
||||
session_write_close();
|
||||
}
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="nl" class="dark">
|
||||
|
||||
@@ -401,7 +401,9 @@ function jira_fetch_project_statuses(string $domain, string $email, string $apiT
|
||||
return strcasecmp($a['name'], $b['name']);
|
||||
});
|
||||
|
||||
fociz_cache_set($cacheKey, $statuses, 3600);
|
||||
fociz_cache_set($cacheKey, $statuses, 86400); // 24 uur cache
|
||||
} else {
|
||||
fociz_cache_set($cacheKey, [], 1800); // 30 min negatieve cache
|
||||
}
|
||||
|
||||
return $statuses;
|
||||
@@ -1195,7 +1197,7 @@ function jira_get_dashboard_data(int $userId, bool $forceRefresh = false): array
|
||||
return array_merge($cachedData, ['from_cache' => true]);
|
||||
}
|
||||
if (session_status() === PHP_SESSION_ACTIVE && !empty($_SESSION[$cacheKey]['data'])) {
|
||||
if (($_SESSION[$cacheKey]['timestamp'] ?? 0) > (time() - 60)) {
|
||||
if (($_SESSION[$cacheKey]['timestamp'] ?? 0) > (time() - 180)) {
|
||||
return array_merge($_SESSION[$cacheKey]['data'], ['from_cache' => true]);
|
||||
}
|
||||
}
|
||||
@@ -1230,8 +1232,8 @@ function jira_get_dashboard_data(int $userId, bool $forceRefresh = false): array
|
||||
$targetProjKeys = array_fill_keys(['SD', 'IN', 'AAN', 'GEN'], true);
|
||||
}
|
||||
|
||||
// Ophalen van teamtaken binnen de relevante projecten (met paginatie tot max 500)
|
||||
$teamRes = jira_fetch_team_issues($domain, $email, $apiToken, array_keys($targetProjKeys), 500);
|
||||
// Ophalen van teamtaken binnen de relevante projecten (met paginatie tot max 200)
|
||||
$teamRes = jira_fetch_team_issues($domain, $email, $apiToken, array_keys($targetProjKeys), 200);
|
||||
// Ophalen van Jira statussen
|
||||
$availableStatuses = jira_fetch_statuses($domain, $email, $apiToken);
|
||||
|
||||
@@ -1281,7 +1283,7 @@ function jira_get_dashboard_data(int $userId, bool $forceRefresh = false): array
|
||||
'project_statuses' => $projectStatusesMap,
|
||||
];
|
||||
|
||||
fociz_cache_set($cacheKey, $data, 60);
|
||||
fociz_cache_set($cacheKey, $data, 180); // 3 minuten cache
|
||||
|
||||
if (session_status() === PHP_SESSION_ACTIVE) {
|
||||
$_SESSION[$cacheKey] = [
|
||||
|
||||
@@ -1187,7 +1187,7 @@ function microsoft_fetch_mail_folders(int $userId, bool $forceRefresh = false):
|
||||
$cacheKey = "ms_folders_{$userId}";
|
||||
if (!$forceRefresh) {
|
||||
$cached = fociz_cache_get($cacheKey);
|
||||
if ($cached !== null && is_array($cached)) {
|
||||
if ($cached !== null && is_array($cached) && !empty($cached['success'])) {
|
||||
return $cached;
|
||||
}
|
||||
}
|
||||
@@ -1206,6 +1206,8 @@ function microsoft_fetch_mail_folders(int $userId, bool $forceRefresh = false):
|
||||
'unread_count' => 2,
|
||||
'total_count' => 5,
|
||||
'is_inbox' => true,
|
||||
'parent_id' => null,
|
||||
'is_child' => false,
|
||||
],
|
||||
[
|
||||
'id' => 'demo-folder-dx',
|
||||
@@ -1213,6 +1215,8 @@ function microsoft_fetch_mail_folders(int $userId, bool $forceRefresh = false):
|
||||
'unread_count' => 1,
|
||||
'total_count' => 3,
|
||||
'is_inbox' => false,
|
||||
'parent_id' => null,
|
||||
'is_child' => false,
|
||||
],
|
||||
[
|
||||
'id' => 'demo-folder-klanten',
|
||||
@@ -1220,6 +1224,8 @@ function microsoft_fetch_mail_folders(int $userId, bool $forceRefresh = false):
|
||||
'unread_count' => 0,
|
||||
'total_count' => 2,
|
||||
'is_inbox' => false,
|
||||
'parent_id' => null,
|
||||
'is_child' => false,
|
||||
],
|
||||
[
|
||||
'id' => 'demo-folder-fin',
|
||||
@@ -1227,6 +1233,8 @@ function microsoft_fetch_mail_folders(int $userId, bool $forceRefresh = false):
|
||||
'unread_count' => 1,
|
||||
'total_count' => 2,
|
||||
'is_inbox' => false,
|
||||
'parent_id' => null,
|
||||
'is_child' => false,
|
||||
],
|
||||
];
|
||||
$totalUnread = array_sum(array_column($demoFolders, 'unread_count'));
|
||||
@@ -1243,12 +1251,23 @@ function microsoft_fetch_mail_folders(int $userId, bool $forceRefresh = false):
|
||||
return [
|
||||
'success' => false,
|
||||
'error' => 'Geen geldig Microsoft 365 token beschikbaar.',
|
||||
'folders' => [],
|
||||
'folders' => [
|
||||
[
|
||||
'id' => 'inbox',
|
||||
'name' => 'Postvak IN',
|
||||
'unread_count' => 0,
|
||||
'total_count' => 0,
|
||||
'is_inbox' => true,
|
||||
'parent_id' => null,
|
||||
'is_child' => false,
|
||||
]
|
||||
],
|
||||
'total_unread' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
$url = MS_GRAPH_BASE_URL . '/me/mailFolders?$top=100&$select=id,displayName,parentFolderId,childFolderCount,unreadItemCount,totalItemCount,wellKnownName';
|
||||
// 1. Haal de hoofdmappen op ZONDER restrictief $select (voorkomt 400 Bad Request op wellKnownName)
|
||||
$url = MS_GRAPH_BASE_URL . '/me/mailFolders?$top=100';
|
||||
$res = fociz_http_request($url, [
|
||||
'method' => 'GET',
|
||||
'headers' => [
|
||||
@@ -1271,73 +1290,117 @@ function microsoft_fetch_mail_folders(int $userId, bool $forceRefresh = false):
|
||||
'unread_count' => 0,
|
||||
'total_count' => 0,
|
||||
'is_inbox' => true,
|
||||
'parent_id' => null,
|
||||
'is_child' => false,
|
||||
]
|
||||
],
|
||||
'total_unread' => 0,
|
||||
];
|
||||
}
|
||||
|
||||
$rawFolders = $res['json']['value'];
|
||||
$rawFolders = is_array($res['json']['value']) ? $res['json']['value'] : [];
|
||||
|
||||
// Haal eventuele submappen op voor mappen met childFolderCount > 0
|
||||
foreach ($res['json']['value'] as $f) {
|
||||
if (!empty($f['childFolderCount']) && (int)$f['childFolderCount'] > 0 && !empty($f['id'])) {
|
||||
$childUrl = MS_GRAPH_BASE_URL . '/me/mailFolders/' . urlencode($f['id']) . '/childFolders?$top=50&$select=id,displayName,parentFolderId,childFolderCount,unreadItemCount,totalItemCount,wellKnownName';
|
||||
$cRes = fociz_http_request($childUrl, [
|
||||
// 2. Haal ALTIJD expliciet de submappen van Postvak IN op
|
||||
// (In Outlook bevinden 95% van de door gebruikers aangemaakte mappen zich direct onder Inbox)
|
||||
$inboxChildUrl = MS_GRAPH_BASE_URL . '/me/mailFolders/inbox/childFolders?$top=100';
|
||||
$inboxChildRes = fociz_http_request($inboxChildUrl, [
|
||||
'method' => 'GET',
|
||||
'headers' => [
|
||||
'Authorization' => "Bearer {$token}",
|
||||
'Accept' => 'application/json',
|
||||
],
|
||||
'timeout' => 10,
|
||||
'timeout' => 8,
|
||||
]);
|
||||
if ($cRes['status'] === 200 && !empty($cRes['json']['value'])) {
|
||||
foreach ($cRes['json']['value'] as $child) {
|
||||
if ($inboxChildRes['status'] === 200 && !empty($inboxChildRes['json']['value']) && is_array($inboxChildRes['json']['value'])) {
|
||||
foreach ($inboxChildRes['json']['value'] as $child) {
|
||||
$rawFolders[] = $child;
|
||||
// Als een eigen submap onder Inbox zelf ook weer submappen heeft: haal die ook op
|
||||
$cfc = (int)($child['childFolderCount'] ?? 0);
|
||||
$cId = $child['id'] ?? '';
|
||||
if ($cfc > 0 && !empty($cId)) {
|
||||
$subRes = fociz_http_request(MS_GRAPH_BASE_URL . '/me/mailFolders/' . rawurlencode($cId) . '/childFolders?$top=100', [
|
||||
'method' => 'GET',
|
||||
'headers' => [
|
||||
'Authorization' => "Bearer {$token}",
|
||||
'Accept' => 'application/json',
|
||||
],
|
||||
'timeout' => 6,
|
||||
]);
|
||||
if ($subRes['status'] === 200 && !empty($subRes['json']['value']) && is_array($subRes['json']['value'])) {
|
||||
foreach ($subRes['json']['value'] as $subChild) {
|
||||
$rawFolders[] = $subChild;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Uitsluitingen conform gebruikerswens: SPAM / Ongewenst, Prullenbak / Deleted, Outbox en Drafts
|
||||
$excludedWellKnown = ['junkemail', 'deleteditems', 'outbox', 'drafts', 'conflicts', 'localfailures', 'serverfailures', 'syncissues'];
|
||||
$excludedTerms = ['junk', 'spam', 'ongewenst', 'ongewenste e-mail', 'ongewenste email', 'deleted items', 'verwijderde items', 'prullenbak', 'trash', 'verwijderd', 'outbox', 'postvak uit', 'drafts', 'concepten'];
|
||||
// 4. Uitsluitingen conform gebruikerswens:
|
||||
// "de SPAM , Ongewenste email en Prullenbak hoeven er niet in."
|
||||
// Ook Outbox, Drafts en technische sync logs uitsluiten
|
||||
$excludedWellKnown = [
|
||||
'junkemail', 'deleteditems', 'outbox', 'drafts',
|
||||
'conflicts', 'localfailures', 'serverfailures', 'syncissues', 'conversationhistory',
|
||||
'clutter', 'recoverableitemsdeletions'
|
||||
];
|
||||
|
||||
$excludedExactNames = [
|
||||
// Nederlands
|
||||
'ongewenste e-mail', 'ongewenste email', 'ongewenst', 'spam', 'junk',
|
||||
'verwijderde items', 'prullenbak', 'trash', 'verwijderd',
|
||||
'postvak uit', 'outbox',
|
||||
'concepten', 'drafts',
|
||||
'gespreksgeschiedenis', 'conversation history',
|
||||
'problemen met synchronisatie', 'synchronisatieproblemen', 'conflicten',
|
||||
// Engels
|
||||
'junk email', 'deleted items', 'sync issues', 'conflicts', 'local failures', 'server failures'
|
||||
];
|
||||
|
||||
$folders = [];
|
||||
$seenIds = [];
|
||||
|
||||
foreach ($rawFolders as $rf) {
|
||||
$fId = $rf['id'] ?? '';
|
||||
if (empty($fId) || isset($seenIds[$fId])) continue;
|
||||
$seenIds[$fId] = true;
|
||||
$fId = trim($rf['id'] ?? '');
|
||||
if (empty($fId) || isset($seenIds[$fId])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Sla verborgen mappen over
|
||||
if (!empty($rf['isHidden'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$wk = strtolower(trim($rf['wellKnownName'] ?? ''));
|
||||
if (in_array($wk, $excludedWellKnown, true)) continue;
|
||||
if (in_array($wk, $excludedWellKnown, true)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$dName = trim($rf['displayName'] ?? '');
|
||||
$dNameLower = strtolower($dName);
|
||||
|
||||
$skip = false;
|
||||
foreach ($excludedTerms as $term) {
|
||||
if ($dNameLower === $term || strpos($dNameLower, $term) !== false) {
|
||||
$skip = true;
|
||||
break;
|
||||
if (in_array($dNameLower, $excludedExactNames, true)) {
|
||||
continue;
|
||||
}
|
||||
if (strpos($dNameLower, 'problemen met synchronisatie') === 0 || strpos($dNameLower, 'sync issues') === 0) {
|
||||
continue;
|
||||
}
|
||||
if ($skip) continue;
|
||||
|
||||
$isInbox = ($wk === 'inbox' || $dNameLower === 'inbox' || $dNameLower === 'postvak in');
|
||||
|
||||
$seenIds[$fId] = true;
|
||||
|
||||
$folders[] = [
|
||||
'id' => $isInbox ? 'inbox' : $fId,
|
||||
'name' => $dName ?: 'Map',
|
||||
'name' => $dName ?: ($isInbox ? 'Postvak IN' : 'Map'),
|
||||
'unread_count' => (int)($rf['unreadItemCount'] ?? 0),
|
||||
'total_count' => (int)($rf['totalItemCount'] ?? 0),
|
||||
'is_inbox' => $isInbox,
|
||||
'parent_id' => $rf['parentFolderId'] ?? null,
|
||||
'is_child' => !empty($rf['parentFolderId']) && !$isInbox,
|
||||
];
|
||||
}
|
||||
|
||||
// Zorg dat Inbox altijd vooraan staat
|
||||
// Garandeer dat Inbox altijd aanwezig is
|
||||
$hasInbox = false;
|
||||
foreach ($folders as $f) {
|
||||
if (!empty($f['is_inbox'])) {
|
||||
@@ -1352,9 +1415,12 @@ function microsoft_fetch_mail_folders(int $userId, bool $forceRefresh = false):
|
||||
'unread_count' => 0,
|
||||
'total_count' => 0,
|
||||
'is_inbox' => true,
|
||||
'parent_id' => null,
|
||||
'is_child' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
// Sorteer: Inbox altijd bovenaan, daarna alfabetisch
|
||||
usort($folders, function($a, $b) {
|
||||
if (!empty($a['is_inbox'])) return -1;
|
||||
if (!empty($b['is_inbox'])) return 1;
|
||||
@@ -1369,7 +1435,9 @@ function microsoft_fetch_mail_folders(int $userId, bool $forceRefresh = false):
|
||||
'folders' => $folders,
|
||||
'total_unread' => $totalUnread,
|
||||
];
|
||||
fociz_cache_set($cacheKey, $result, 60); // 60 seconden cache
|
||||
|
||||
fociz_cache_set($cacheKey, $result, 300); // 5 minuten cache
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
@@ -1428,7 +1496,7 @@ function microsoft_fetch_folder_messages(int $userId, string $folderId = 'inbox'
|
||||
$queryParams['$filter'] = 'isRead eq false';
|
||||
}
|
||||
|
||||
$folderEndpoint = ($cleanFolderId === 'inbox') ? 'inbox' : urlencode($cleanFolderId);
|
||||
$folderEndpoint = ($cleanFolderId === 'inbox') ? 'inbox' : rawurlencode($cleanFolderId);
|
||||
$url = MS_GRAPH_BASE_URL . '/me/mailFolders/' . $folderEndpoint . '/messages?' . http_build_query($queryParams);
|
||||
$res = fociz_http_request($url, [
|
||||
'method' => 'GET',
|
||||
|
||||
@@ -13,6 +13,11 @@ $userId = (int)($currentUser['id'] ?? 0);
|
||||
$isAdmin = (($currentUser['role'] ?? '') === 'ADMIN');
|
||||
$forceRefresh = isset($_GET['refresh']) && $_GET['refresh'] === '1';
|
||||
|
||||
// Geef direct het PHP sessieslot vrij zodat achtergrondverzoeken en paginanavigatie nooit blokkeren
|
||||
if (session_status() === PHP_SESSION_ACTIVE) {
|
||||
session_write_close();
|
||||
}
|
||||
|
||||
// Haal Jira data op
|
||||
$jiraData = jira_get_dashboard_data($userId, $forceRefresh);
|
||||
$isDemo = !empty($jiraData['is_demo']);
|
||||
@@ -72,6 +77,12 @@ $defaultQueueFilter = $jiraData['default_queue_filter'] ?? jira_get_user_queue_p
|
||||
$userQueueFilters = $jiraData['user_queue_filters'] ?? jira_get_user_queue_preferences($userId);
|
||||
$userQueueFilters = array_values(array_filter(array_map('strtoupper', array_map('trim', $userQueueFilters ?? []))));
|
||||
$jiraData['user_queue_filters'] = $userQueueFilters;
|
||||
$hasUserAssignments = !empty($userQueueFilters);
|
||||
|
||||
$isCodeVisible = function(string $code) use ($hasUserAssignments, $userQueueFilters): bool {
|
||||
if (!$hasUserAssignments) return true;
|
||||
return in_array(strtoupper(trim($code)), $userQueueFilters, true);
|
||||
};
|
||||
|
||||
// Hulpfunctie om te controleren of een ticket behoort tot een wachtrij / project
|
||||
$issueMatchesQueue = function(array $iss, string $code) use ($queueFilters): bool {
|
||||
@@ -597,14 +608,6 @@ $currentUserEmailJson = json_encode($currentUserEmail, JSON_HEX_TAG | JSON_HEX_A
|
||||
<!-- Project Knoppen met direct ingebouwde dropdowns voor statusinstellingen & uitvoerder -->
|
||||
<div class="flex flex-wrap items-center gap-2 relative z-50" id="projectPillsContainer">
|
||||
|
||||
<?php
|
||||
$hasUserAssignments = !empty($userQueueFilters);
|
||||
$isCodeVisible = function(string $code) use ($hasUserAssignments, $userQueueFilters): bool {
|
||||
if (!$hasUserAssignments) return true;
|
||||
return in_array(strtoupper(trim($code)), $userQueueFilters, true);
|
||||
};
|
||||
?>
|
||||
|
||||
<!-- Alle Projecten -->
|
||||
<div class="relative inline-flex items-stretch rounded-xl shadow-xs group flex-shrink-0 project-pill-container" data-project="" id="projGroup_all">
|
||||
<button type="button" onclick="selectProject('')" data-project="" class="project-pill-btn flex items-center space-x-1.5 pl-2.5 sm:pl-3 pr-2 py-1.5 rounded-l-xl text-xs font-bold transition cursor-pointer bg-slate-900 dark:bg-white text-white dark:text-slate-900">
|
||||
|
||||
@@ -14,6 +14,11 @@ $isAdmin = (($currentUser['role'] ?? '') === 'ADMIN');
|
||||
$db = get_db_connection();
|
||||
$userBoards = fociz_get_user_boards_with_lanes($db, $userId, $isAdmin);
|
||||
|
||||
// Geef direct het PHP sessieslot vrij zodat achtergrondverzoeken en paginanavigatie nooit blokkeren
|
||||
if (session_status() === PHP_SESSION_ACTIVE) {
|
||||
session_write_close();
|
||||
}
|
||||
|
||||
// Haal alle beschikbare mailmappen op (exclusief SPAM/Junk, Prullenbak/Deleted, Outbox, Drafts)
|
||||
$forceRefresh = !empty($_GET['refresh']) && $_GET['refresh'] === '1';
|
||||
$foldersData = microsoft_fetch_mail_folders($userId, $forceRefresh);
|
||||
@@ -24,7 +29,7 @@ $totalUnreadCount = (int)($foldersData['total_unread'] ?? 0);
|
||||
$inboxData = microsoft_fetch_inbox_messages($userId, 30, false, $forceRefresh);
|
||||
$messages = $inboxData['messages'] ?? [];
|
||||
$isDemo = !empty($inboxData['is_demo']) || !empty($foldersData['is_demo']);
|
||||
$warning = $inboxData['warning'] ?? ($foldersData['warning'] ?? '');
|
||||
$warning = $inboxData['warning'] ?? ($foldersData['warning'] ?? ($foldersData['error'] ?? ''));
|
||||
$needsReconsent = !empty($inboxData['needs_reconsent']);
|
||||
|
||||
// Bereken actuele ongelezen aantal: neem het hoogste van total_unread over mappen en inbox unread_count
|
||||
@@ -55,6 +60,18 @@ $jsonFolders = json_encode($mailFolders, JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if (!empty($warning)): ?>
|
||||
<div class="p-4 rounded-2xl bg-amber-50 dark:bg-amber-950/40 border border-amber-200 dark:border-amber-800/60 flex flex-col sm:flex-row sm:items-center justify-between gap-3 text-xs text-amber-800 dark:text-amber-200 shadow-2xs">
|
||||
<div class="flex items-center space-x-2.5">
|
||||
<i data-lucide="alert-triangle" class="w-4 h-4 text-amber-600 dark:text-amber-400 flex-shrink-0"></i>
|
||||
<span><?= htmlspecialchars($warning) ?></span>
|
||||
</div>
|
||||
<?php if (!empty($needsReconsent)): ?>
|
||||
<a href="/auth/oauth_microsoft.php?reconsent=1&return_to=/mail.php" class="px-3 py-1.5 rounded-xl bg-amber-600 hover:bg-amber-500 text-white font-bold text-xs shadow-xs transition whitespace-nowrap flex-shrink-0 text-center">Machtigingen Bijwerken</a>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<!-- Top Banner: Status & Snelle Acties -->
|
||||
<div class="fociz-card p-6 sm:p-7 relative overflow-hidden">
|
||||
<div class="flex flex-col lg:flex-row lg:items-center justify-between gap-4">
|
||||
@@ -681,9 +698,9 @@ function renderFolders() {
|
||||
<div class="rounded-2xl border border-slate-200/80 dark:border-slate-800/80 bg-white/70 dark:bg-slate-900/40 overflow-hidden shadow-2xs">
|
||||
<!-- Folder Header Accordion Knop -->
|
||||
<button type="button" onclick="toggleFolder('${folder.id}')" class="w-full flex items-center justify-between p-3 select-none transition cursor-pointer ${isInbox ? 'bg-slate-100/90 dark:bg-slate-800/80' : 'bg-slate-50/80 dark:bg-slate-800/40 hover:bg-slate-100 dark:hover:bg-slate-800/70'}">
|
||||
<div class="flex items-center space-x-2.5 min-w-0">
|
||||
<div class="w-7 h-7 rounded-xl ${isInbox ? 'bg-sky-600 text-white shadow-xs' : 'bg-slate-200 dark:bg-slate-700 text-slate-700 dark:text-slate-300'} flex items-center justify-center flex-shrink-0">
|
||||
<i data-lucide="${isInbox ? 'inbox' : 'folder'}" class="w-3.5 h-3.5"></i>
|
||||
<div class="flex items-center space-x-2.5 min-w-0 ${folder.is_child ? 'pl-3' : ''}">
|
||||
<div class="w-7 h-7 rounded-xl ${isInbox ? 'bg-sky-600 text-white shadow-xs' : (folder.is_child ? 'bg-slate-100 dark:bg-slate-800 text-slate-500' : 'bg-slate-200 dark:bg-slate-700 text-slate-700 dark:text-slate-300')} flex items-center justify-center flex-shrink-0">
|
||||
<i data-lucide="${isInbox ? 'inbox' : (folder.is_child ? 'corner-down-right' : 'folder')}" class="w-3.5 h-3.5"></i>
|
||||
</div>
|
||||
<div class="flex items-center space-x-1.5 truncate">
|
||||
<span class="text-xs font-bold text-slate-900 dark:text-white truncate">${escapeHtml(folder.name)}</span>
|
||||
|
||||
Reference in New Issue
Block a user