mirror of
https://codeberg.org/PostERG/xamxam.git
synced 2026-06-25 16:19:19 +02:00
Add language-search component for Autre Langue input + active search in lists
Mirrors the mots-clé tag-search system: dropdown suggestions from existing languages via HTMX, pill display with bin-icon remove buttons, 'Créer' option for new languages. Replaces the plain text input. - New partial: templates/partials/form/language-search.php - New fragment: public/partage/language-search-fragment.php - Admin wrapper: public/admin/language-search-fragment.php - Updated language-autre-fragment to return just the required asterisk indicator - Updated both controllers to handle language_autre as array (pill-based) with backward-compatible string path - Updated edit form to compute selectedOtherLanguages from DB - Registered new route in partage/index.php - Fix CSV importer: split comma-separated language column into individual entries - Add htmx active search to admin index, title line-clamp, predefined languages only in checkboxes - Admin index: filter form now uses htmx triggers (input delay:300ms on search, change on selects) to actively search without page reload - Sort links include hx-push-url for back-button support - Added loading indicator bar (.admin-search-indicator) - Title column: line-clamp at 2 lines with overflow hidden, native title attr tooltip for full text - Language checkboxes now show only 3 predefined languages (Français, Anglais, Néerlandais); all others go via the Autre langue search component - Added Database::getPredefinedLanguages() and excluded predefined from language-search-fragment suggestions - Included hidden sort/dir inputs in table-wrap so sort state preserved across filter changes - Fix language-search: block 'Créer' for predefined languages in dropdown The 'Créer' option in the language-search dropdown now also checks against the predefined set (français, anglais, néerlandais) to avoid offering creation of languages that already exist as checkboxes.
This commit is contained in:
@@ -16,20 +16,14 @@ if (!isset($_POST['csrf_token'], $_SESSION['csrf_token'])
|
||||
exit;
|
||||
}
|
||||
|
||||
$isBulk = !empty($_POST['bulk']);
|
||||
$isDeleteAll = !empty($_POST['delete_all']);
|
||||
$isBulk = !empty($_POST['bulk']);
|
||||
|
||||
try {
|
||||
$db = new Database();
|
||||
|
||||
$logger = AdminLogger::make();
|
||||
|
||||
if ($isDeleteAll) {
|
||||
$count = $db->deleteAllTheses();
|
||||
$logger->logDeleteAllTheses($count);
|
||||
App::flash('success', "$count TFE(s) supprimé(s) avec succès.");
|
||||
|
||||
} elseif ($isBulk) {
|
||||
if ($isBulk) {
|
||||
$ids = array_filter(array_map('intval', $_POST['selected_theses'] ?? []), fn($id) => $id > 0);
|
||||
|
||||
if (empty($ids)) {
|
||||
|
||||
@@ -18,6 +18,7 @@ try {
|
||||
$pages = array_values(array_filter($allPages, fn($p) => in_array($p['slug'], $allowedPageSlugs, true)));
|
||||
$aproposKeys = $db->getAllAproposContents();
|
||||
$formHelpBlocks = $db->getAllFormHelpBlocks();
|
||||
$siteSettings = $db->getAllSettings();
|
||||
} catch (Exception $e) {
|
||||
error_log("Error loading contenus: " . $e->getMessage());
|
||||
die("Erreur lors du chargement des contenus.");
|
||||
|
||||
@@ -349,18 +349,21 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_FILES['csv_file'])) {
|
||||
}
|
||||
}
|
||||
if (!empty($languageRaw)) {
|
||||
$langName = strtolower(trim($languageRaw));
|
||||
// Lookup case-insensitively; insert if missing (stored lowercase).
|
||||
$s = $importPdo->prepare("SELECT id FROM languages WHERE LOWER(name) = LOWER(?)");
|
||||
$s->execute([$langName]);
|
||||
$r = $s->fetch();
|
||||
$langId = $r ? (int)$r['id'] : null;
|
||||
if ($langId === null) {
|
||||
$importPdo->prepare("INSERT INTO languages (name) VALUES (?)")->execute([$langName]);
|
||||
$langId = (int)$importPdo->lastInsertId();
|
||||
foreach (array_map('trim', explode(',', $languageRaw)) as $langName) {
|
||||
$langName = strtolower($langName);
|
||||
if ($langName === '') continue;
|
||||
// Lookup case-insensitively; insert if missing (stored lowercase).
|
||||
$s = $importPdo->prepare("SELECT id FROM languages WHERE LOWER(name) = LOWER(?)");
|
||||
$s->execute([$langName]);
|
||||
$r = $s->fetch();
|
||||
$langId = $r ? (int)$r['id'] : null;
|
||||
if ($langId === null) {
|
||||
$importPdo->prepare("INSERT INTO languages (name) VALUES (?)")->execute([$langName]);
|
||||
$langId = (int)$importPdo->lastInsertId();
|
||||
}
|
||||
$s2 = $importPdo->prepare("INSERT INTO thesis_languages (thesis_id, language_id) VALUES (?,?)");
|
||||
$s2->execute([$thesisId, $langId]);
|
||||
}
|
||||
$s2 = $importPdo->prepare("INSERT INTO thesis_languages (thesis_id, language_id) VALUES (?,?)");
|
||||
$s2->execute([$thesisId, $langId]);
|
||||
}
|
||||
if (!empty($formatsRaw)) {
|
||||
foreach (array_map('trim', explode(',', $formatsRaw)) as $fmt) {
|
||||
|
||||
13
app/public/admin/language-search-fragment.php
Normal file
13
app/public/admin/language-search-fragment.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
/**
|
||||
* language-search-fragment.php (admin)
|
||||
*
|
||||
* HTMX fragment: returns matching language suggestions for the
|
||||
* "Autre(s) langue(s)" interactive search input. Admin-auth gated wrapper.
|
||||
*/
|
||||
require_once __DIR__ . '/../../bootstrap.php';
|
||||
require_once __DIR__ . '/../../src/AdminAuth.php';
|
||||
|
||||
AdminAuth::requireLogin();
|
||||
|
||||
require_once APP_ROOT . '/public/partage/language-search-fragment.php';
|
||||
@@ -16,7 +16,6 @@ $siteSettings = $db->getAllSettings();
|
||||
$peerTubeSettings = PeerTubeService::getSettings($db);
|
||||
$peerTubeEnabled = PeerTubeService::isEnabled($db);
|
||||
$peerTubeConfigured = PeerTubeService::isConfigured($db);
|
||||
$stats = $db->getThesesStats();
|
||||
$smtpSettings = SmtpRelay::getSettings($db);
|
||||
$smtpConfigured = SmtpRelay::isConfigured($db);
|
||||
$smtpErrorField = $_SESSION['_flash_smtp_field'] ?? null;
|
||||
|
||||
Reference in New Issue
Block a user