Dokumentit: kokousmuistiot, kansiorakenne, sub-tabit, asiakaslinkkaus

- Uusi dokumenttityyppi "kokousmuistio" jolla inline tekstieditori (ei tiedostopohjainen)
- document_versions.content -sarake kokousmuistioiden tekstin tallennukseen
- Sub-tabit Dokumentit-välilehdelle (Kaikki / Kokoukset) Tekniikka-mallin mukaan
- Kansiorakenne: document_folders-taulu, kansionavigaatio breadcrumbsilla
- Uudet API-endpointit: document_folders, document_folder_save/delete, document_content_save, document_move
- Asiakasprofiilin Dokumentit-osio: näyttää linkitetyt dokumentit + pikanapit luontiin
- Asiakasprofiilista voi avata dokumentin suoraan tai luoda uuden linkitettynä asiakkaaseen

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-11 23:19:05 +02:00
parent 150c774bb3
commit f40b387383
5 changed files with 549 additions and 38 deletions

84
api.php
View File

@@ -4310,6 +4310,90 @@ switch ($action) {
}
break;
// ==================== DOKUMENTTIKANSIOT ====================
case 'document_folders':
requireAuth();
$companyId = requireCompany();
echo json_encode(dbLoadFolders($companyId));
break;
case 'document_folder_save':
requireAuth();
$companyId = requireCompany();
if ($method !== 'POST') break;
$input = json_decode(file_get_contents('php://input'), true);
if (empty($input['name'])) {
http_response_code(400);
echo json_encode(['error' => 'Kansion nimi puuttuu']);
break;
}
$input['created_by'] = currentUser();
$id = dbSaveFolder($companyId, $input);
echo json_encode(['id' => $id, 'name' => $input['name']]);
break;
case 'document_folder_delete':
requireAdmin();
$companyId = requireCompany();
if ($method !== 'POST') break;
$input = json_decode(file_get_contents('php://input'), true);
$result = dbDeleteFolder($companyId, $input['id'] ?? '');
echo json_encode(['ok' => $result]);
break;
case 'document_content_save':
requireAuth();
$companyId = requireCompany();
if ($method !== 'POST') break;
try {
$input = json_decode(file_get_contents('php://input'), true);
$docId = $input['document_id'] ?? '';
$doc = dbLoadDocument($docId);
if (!$doc || $doc['company_id'] !== $companyId) {
http_response_code(404);
echo json_encode(['error' => 'Dokumenttia ei löytynyt']);
break;
}
dbAddDocumentVersion($docId, [
'content' => $input['content'] ?? '',
'change_notes' => $input['change_notes'] ?? '',
'created_by' => currentUser(),
'filename' => '',
'original_name' => '',
'file_size' => strlen($input['content'] ?? ''),
'mime_type' => 'text/plain'
]);
$updated = dbLoadDocument($docId);
echo json_encode($updated);
} catch (Exception $e) {
http_response_code(500);
echo json_encode(['error' => 'Tallennus epäonnistui: ' . $e->getMessage()]);
}
break;
case 'document_move':
requireAuth();
$companyId = requireCompany();
if ($method !== 'POST') break;
try {
$input = json_decode(file_get_contents('php://input'), true);
$docId = $input['document_id'] ?? '';
$folderId = $input['folder_id'] ?? null;
$doc = dbLoadDocument($docId);
if (!$doc || $doc['company_id'] !== $companyId) {
http_response_code(404);
echo json_encode(['error' => 'Dokumenttia ei löytynyt']);
break;
}
_dbExecute("UPDATE documents SET folder_id = ? WHERE id = ?", [$folderId ?: null, $docId]);
echo json_encode(['ok' => true]);
} catch (Exception $e) {
http_response_code(500);
echo json_encode(['error' => 'Siirto epäonnistui: ' . $e->getMessage()]);
}
break;
// ==================== NETADMIN ====================
case 'netadmin_connections':