Kanban mit FileMaker und PHP

Die Verwaltung von Aufgaben kann schnell unübersichtlich werden, wenn viele Prozesse gleichzeitig laufen und verschiedene Mitarbeiter involviert sind. Eine klassische Methode zur Visualisierung solcher Abläufe ist die Kanban-Tafel, die durch ihre intuitive Struktur einen schnellen Überblick über den Status der einzelnen Aufgaben bietet. Doch während viele Tools auf dem Markt existieren, soll in diesem Artikel eine maßgeschneiderte Lösung direkt in FileMaker realisiert werden – mit Hilfe von PHP und JavaScript in einem Webviewer. Es gibt natürlich eine FileMaker-Eigene Implementierung über die Add-ons. Mir persönlich ist diese Möglichkeit aber zu eingeschränkt. So sind die Tafeln nicht Dynamisch, ich kann z.B. keine Symbole oder Bilder mit integrieren und die Steuerung der Abläufe ist nicht richtig konsistent.
Deshalb die Idee, ich setze das einfach mit PHP, Java-Script über den WebViewer von FileMaker um. Das Ziel ist es, eine interaktive Kanban-Tafel direkt in FileMaker zu integrieren, die alle relevanten Aufgaben übersichtlich darstellt und es ermöglicht, diese per Drag & Drop zwischen den verschiedenen Status-Spalten zu verschieben. Diese Statusänderungen sollen dann automatisch an FileMaker zurückgemeldet werden, sodass keine doppelte Pflege von Daten notwendig ist. Die Techniken dahinter: -PHP als Schnittstelle zur Verarbeitung und Bereitstellung der Daten. -JavaScript mit jQuery UI für die interaktive Drag & Drop-Funktionalität. -FileMaker-Skripte, um die Änderungen zurück in die FileMaker-Datenbank zu schreiben.
Als erstes müssen wir uns klar werden wie die Daten an das PHP-Script übergeben werden. Ich persönlich nutze gern die Möglichkeit Einträge mit einem Pipe getrennt zu übertragen. Das lässt sich in FileMaker wunderbar über eine Schleife realisieren. In meinem Beispiel werden verschiedene ID,s übertragen.
Damit die Kanban-Ansicht ihre Inhalte aus FileMaker beziehen kann, müssen die relevanten Daten über eine URL in PHP übergeben werden. Dazu werden die folgenden Parameter als GET-Request an eine PHP-Datei gesendet:
projects: Enthält die Auftragsnummern. staff: Enthält die zugeordneten Mitarbeiter. anlage: Enthält die Referenz zur Anlage. status: Gibt den aktuellen Status der Aufgabe an (z. B. “In Planung” oder “Erledigt”). task: Enthält die eindeutige Task-ID (Aufgaben ID) zur Identifikation. image: Gibt den Namen des Symbols an, das in der Kanban-Karte angezeigt werden soll.
Meine fertige URL schaut ungefähr so aus: https://maeine_url_.de/cap/kanban.php?projects=24944|24945|24946&staff=STA020|STA023|STA025&anlage=B14C380C-4329-E54B-ACA1-B2054C5D4B3A|B14C380C-4329-E54B-ACA1-B2054C5D4B3A&status=Erledigt|In Planung|Material bestellt&task=TSK004729|TSK004730|TSK004731&image=Blau|Gelb|Rot
Der Weg diese zu generieren sollte klar sein. Per Schleife durch die Aufgaben, entweder gefiltert nach Datum oder Zeitraum etc. Nun wird dieser Wert in eine Globale Variable geschrieben z.B. $$URL. Dann der FileMaker Befehl, aus URL einfügen. Dabei generieren wir eine Variable z.B. $$URL_WEBVIEWER. Diese kommt dann als Inhalt in unseren Webviewer den wir uns innerhalb eines FileMaker-Layouts platzieren.
Unser Script:
<?php
// Header für UTF-8 Encoding
header("Content-Type: text/html; charset=UTF-8");
// Daten aus der URL holen
$projects = isset($_GET['projects']) ? explode('|', $_GET['projects']) : [];
$staff = isset($_GET['staff']) ? explode('|', $_GET['staff']) : [];
$anlage = isset($_GET['anlage']) ? explode('|', $_GET['anlage']) : [];
$status = isset($_GET['status']) ? explode('|', $_GET['status']) : [];
$task = isset($_GET['task']) ? explode('|', $_GET['task']) : [];
$images = isset($_GET['image']) ? explode('|', $_GET['image']) : [];
// Basis-URL für die Icons
$imageBaseUrl = "http://Deine_URL.de/GoogleMarkers/";
// Status und Farben definieren
$status_colors = [
"Material bestellt" => "#FFD700", // Gelb
"In Planung" => "#FFA500", // Orange
"Verplant" => "#FF4500", // Dunkelorange
"Ausgeführt" => "#008000", // Grün
"Angebot folgt" => "#FF0000", // Rot
"Erledigt" => "#808080" // Grau
];
// Spalten für das Kanban-Board
$columns = ["Material bestellt", "In Planung", "Verplant", "Ausgeführt", "Angebot folgt", "Erledigt"];
// Aufgaben nach Status sortieren
$tasks_by_status = [];
foreach ($status as $index => $task_status) {
$tasks_by_status[$task_status][] = [
"id" => $task[$index] ?? "TSK-Unbekannt",
"project" => $projects[$index] ?? "Unbekannt",
"staff" => $staff[$index] ?? "Kein Mitarbeiter",
"anlage" => $anlage[$index] ?? "Keine Anlage",
"image" => isset($images[$index]) && !empty($images[$index]) ? $imageBaseUrl . $images[$index] . ".png" : "",
"status" => $task_status
];
}
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Aufgaben Board</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
}
.kanban-board {
display: flex;
justify-content: space-between;
padding: 20px;
gap: 10px;
}
.kanban-column {
width: 16%;
min-height: 400px;
background: #ddd;
padding: 10px;
border-radius: 5px;
display: flex;
flex-direction: column;
align-items: center;
}
.kanban-card {
background: white;
padding: 10px;
margin-bottom: 10px;
border-radius: 5px;
box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.1);
cursor: grab;
width: 90%;
text-align: center;
transition: background-color 0.3s;
position: relative;
}
.kanban-card img {
position: absolute;
top: 5px;
left: 5px;
width: 20px;
height: 20px;
}
.sortable {
width: 100%;
min-height: 50px;
}
.sortable-placeholder {
background: #ccc;
height: 50px;
border-radius: 5px;
margin-bottom: 10px;
width: 90%;
}
</style>
</head>
<body>
<h2 style="text-align: center;">Aufgaben Board</h2>
<div class="kanban-board">
<?php foreach ($columns as $column): ?>
<div class="kanban-column" id="<?= htmlspecialchars($column) ?>">
<h3><?= htmlspecialchars($column) ?></h3>
<div class="sortable" id="sortable-<?= htmlspecialchars($column) ?>">
<?php if (!empty($tasks_by_status[$column])): ?>
<?php foreach ($tasks_by_status[$column] as $task): ?>
<div class="kanban-card"
id="<?= htmlspecialchars($task['id']) ?>"
data-task-id="<?= htmlspecialchars($task['id']) ?>"
data-status="<?= htmlspecialchars($task['status']) ?>"
style="background-color: <?= $status_colors[$column] ?? '#ffffff' ?>;">
<?php if (!empty($task['image'])): ?>
<img src="<?= $task['image'] ?>" alt="Symbol">
<?php endif; ?>
<strong>Auftrag:</strong> <?= htmlspecialchars($task["project"]) ?><br>
<strong>Anlage:</strong> <?= htmlspecialchars($task["anlage"]) ?><br>
<strong>Mitarbeiter:</strong> <?= htmlspecialchars($task["staff"]) ?>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
</div>
<?php endforeach; ?>
</div>
<script>
// Status und zugehörige Farben
var statusColors = {
"Material bestellt": "#FFD700", // Gelb
"In Planung": "#FFA500", // Orange
"Verplant": "#FF4500", // Dunkelorange
"Ausgeführt": "#008000", // Grün
"Angebot folgt": "#FF0000", // Rot
"Erledigt": "#808080" // Grau
};
$(document).ready(function() {
console.log(" jQuery und jQuery-UI wurden geladen.");
$(".sortable").sortable({
connectWith: ".sortable",
placeholder: "sortable-placeholder",
revert: true,
start: function(event, ui) {
console.log("Drag gestartet für:", ui.item.attr("id"));
},
stop: function(event, ui) {
var newStatus = ui.item.closest(".kanban-column").attr("id");
var taskId = ui.item.attr("id");
console.log("Aufgabe verschoben:", taskId, "Neuer Status:", newStatus);
// Neue Farbe setzen
if (statusColors[newStatus]) {
ui.item.css("background-color", statusColors[newStatus]);
}
// FileMaker-Skript über fmp:// URL aufrufen
var fileMakerScriptURL = "fmp://$/Deine_Datei?script=UpdateTaskStatus¶m=" + encodeURIComponent(taskId + "|" + newStatus);
console.log(" FileMaker-Skript aufrufen:", fileMakerScriptURL);
// WebViewer öffnet FileMaker-Skript
window.location = fileMakerScriptURL;
}
}).disableSelection();
});
</script>
</body>
</html>
Die Updates der Änderungen werden über ein kleines weiteres PHP Script abgefangen.
<?php
// POST-Daten empfangen
$taskId = $_POST['id'] ?? null;
$newStatus = $_POST['status'] ?? null;
if ($taskId && $newStatus) {
// Hier würdest du die Daten in FileMaker oder einer Datenbank speichern
file_put_contents("kanban_log.txt", "ID: $taskId -> $newStatus\n", FILE_APPEND);
echo "OK";
} else {
echo "Fehler: Ungültige Daten";
}
?>
Führe ich nun eine Änderung durch, wird das FileMaker-Script -UpdateTaskStatus- aufgerufen, es übergibt als Parameter die Task-ID und den neuen Status. Damit habe ich natürlich die Möglichkeit im Hintergrund sofort die Änderungen zu verarbeiten. Also, neues Fenster, 1x1 px, bei -30000px. Dort suche ich die Task-ID und ändere den Status. Fenster schließen und der Vorgang ist abgeschlossen.