';
print '
';
+ if ($permissiontoadd) {
+ $pinClass = $file->is_pinned ? ' kundenkarte-file-btn-pinned' : '';
+ $pinTitle = $file->is_pinned ? $langs->trans('Unpin') : $langs->trans('Pin');
+ print '
';
+ }
if ($permissiontodelete) {
print '
';
}
@@ -865,6 +971,19 @@ if (empty($customerSystems)) {
$typeSelect.prop("disabled", true);
$("#row_type").hide();
}
+
+ // Select2 für übergeordnetes Element mit Icons
+ var $parentSelect = $("select[name=\'fk_parent\']");
+ if ($parentSelect.length) {
+ $parentSelect.select2({
+ templateResult: formatTypeOption,
+ templateSelection: formatTypeOption,
+ placeholder: "'.dol_escape_js($langs->trans('SelectParent')).'",
+ allowClear: true,
+ width: "300px",
+ dropdownAutoWidth: true
+ });
+ }
});
';
}
@@ -949,7 +1068,8 @@ function printTree($nodes, $socid, $systemId, $canEdit, $canDelete, $langs, $lev
);
// Collect fields for tooltip (show_in_hover) and tree label (show_in_tree)
- $treeInfo = array();
+ $treeInfoBadges = array(); // Fields to display as badges (right side)
+ $treeInfoParentheses = array(); // Fields to display in parentheses (after label)
if (!empty($typeFieldsMap[$node->fk_anlage_type])) {
foreach ($typeFieldsMap[$node->fk_anlage_type] as $fieldDef) {
@@ -984,10 +1104,24 @@ function printTree($nodes, $socid, $systemId, $canEdit, $canDelete, $langs, $lev
// Add to tree label info if show_in_tree
if ($fieldDef->show_in_tree && $value !== '') {
// Format date for tree info too
+ $displayVal = $value;
if ($fieldDef->field_type === 'date' && $value) {
- $treeInfo[] = dol_print_date(strtotime($value), 'day');
+ $displayVal = dol_print_date(strtotime($value), 'day');
+ }
+ // Store as array with field info
+ $fieldInfo = array(
+ 'label' => $fieldDef->field_label,
+ 'value' => $displayVal,
+ 'code' => $fieldDef->field_code,
+ 'type' => $fieldDef->field_type,
+ 'color' => $fieldDef->badge_color ?? ''
+ );
+ // Sort into badge or parentheses based on field setting
+ $displayMode = $fieldDef->tree_display_mode ?? 'badge';
+ if ($displayMode === 'parentheses') {
+ $treeInfoParentheses[] = $fieldInfo;
} else {
- $treeInfo[] = $value;
+ $treeInfoBadges[] = $fieldInfo;
}
}
}
@@ -1045,34 +1179,47 @@ function printTree($nodes, $socid, $systemId, $canEdit, $canDelete, $langs, $lev
$picto = $node->type_picto ? $node->type_picto : 'fa-cube';
print '
'.kundenkarte_render_icon($picto).'';
- // Label with tree info in parentheses + file indicators
+ // Label with parentheses info (directly after label, only values)
$viewUrl = $_SERVER['PHP_SELF'].'?id='.$socid.'&system='.$systemId.'&action=view&anlage_id='.$node->id;
print '
'.dol_escape_htmltag($node->label);
- if (!empty($treeInfo)) {
- print ' ('.dol_escape_htmltag(implode(', ', $treeInfo)).')';
- }
- // File indicators - directly after parentheses
- if ($node->image_count > 0 || $node->doc_count > 0) {
- print ' ';
- if ($node->image_count > 0) {
- print '';
- print '';
- if ($node->image_count > 1) {
- print ' '.$node->image_count;
- }
- print '';
+
+ // Parentheses info directly after label (only values, no field names)
+ if (!empty($treeInfoParentheses)) {
+ $infoValues = array();
+ foreach ($treeInfoParentheses as $info) {
+ $infoValues[] = dol_escape_htmltag($info['value']);
}
- if ($node->doc_count > 0) {
- print '';
- print '';
- if ($node->doc_count > 1) {
- print ' '.$node->doc_count;
- }
- print '';
+ print ' ('.implode(', ', $infoValues).')';
+ }
+ print '';
+
+ // Spacer to push badges to the right
+ print '';
+
+ // Badges (far right, before actions)
+ $defaultBadgeColor = getDolGlobalString('KUNDENKARTE_TREE_BADGE_COLOR', '#2a4a5e');
+ if (!empty($treeInfoBadges)) {
+ print '';
+ foreach ($treeInfoBadges as $info) {
+ $badgeIcon = kundenkarte_get_field_icon($info['code'], $info['type']);
+ // Use field-specific color if set, otherwise global default
+ $fieldBadgeColor = !empty($info['color']) ? $info['color'] : $defaultBadgeColor;
+ print '';
+ print ' '.dol_escape_htmltag($info['value']);
+ print '';
}
print '';
}
- print '';
+
+ // File indicators
+ if ($node->image_count > 0 || $node->doc_count > 0) {
+ $totalFiles = $node->image_count + $node->doc_count;
+ print '
';
+ print '';
+ print ' '.$totalFiles;
+ print '';
+ print '';
+ }
// Type badge
if ($node->type_short || $node->type_label) {
@@ -1156,7 +1303,8 @@ function printTreeWithCableLines($nodes, $socid, $systemId, $canEdit, $canDelete
'fields' => array()
);
- $treeInfo = array();
+ $treeInfoBadges = array();
+ $treeInfoParentheses = array();
if (!empty($typeFieldsMap[$node->fk_anlage_type])) {
foreach ($typeFieldsMap[$node->fk_anlage_type] as $fieldDef) {
if ($fieldDef->field_type === 'header') continue;
@@ -1173,7 +1321,20 @@ function printTreeWithCableLines($nodes, $socid, $systemId, $canEdit, $canDelete
);
}
if ($fieldDef->show_in_tree && $value !== '') {
- $treeInfo[] = ($fieldDef->field_type === 'date' && $value) ? dol_print_date(strtotime($value), 'day') : $value;
+ $displayVal = ($fieldDef->field_type === 'date' && $value) ? dol_print_date(strtotime($value), 'day') : $value;
+ $fieldInfo = array(
+ 'label' => $fieldDef->field_label,
+ 'value' => $displayVal,
+ 'code' => $fieldDef->field_code,
+ 'type' => $fieldDef->field_type,
+ 'color' => $fieldDef->badge_color ?? ''
+ );
+ $displayMode = $fieldDef->tree_display_mode ?? 'badge';
+ if ($displayMode === 'parentheses') {
+ $treeInfoParentheses[] = $fieldInfo;
+ } else {
+ $treeInfoBadges[] = $fieldInfo;
+ }
}
}
}
@@ -1279,27 +1440,43 @@ function printTreeWithCableLines($nodes, $socid, $systemId, $canEdit, $canDelete
print '
'.kundenkarte_render_icon($picto).'';
$viewUrl = $_SERVER['PHP_SELF'].'?id='.$socid.'&system='.$systemId.'&action=view&anlage_id='.$node->id;
+ // Label with parentheses info (only values, no field names)
print '
'.dol_escape_htmltag($node->label);
- if (!empty($treeInfo)) {
- print ' ('.dol_escape_htmltag(implode(', ', $treeInfo)).')';
- }
- if ($node->image_count > 0 || $node->doc_count > 0) {
- print ' ';
- if ($node->image_count > 0) {
- print '';
- print '';
- if ($node->image_count > 1) print ' '.$node->image_count;
- print '';
+ if (!empty($treeInfoParentheses)) {
+ $infoValues = array();
+ foreach ($treeInfoParentheses as $info) {
+ $infoValues[] = dol_escape_htmltag($info['value']);
}
- if ($node->doc_count > 0) {
- print '';
- print '';
- if ($node->doc_count > 1) print ' '.$node->doc_count;
- print '';
+ print ' ('.implode(', ', $infoValues).')';
+ }
+ print '';
+
+ // Spacer to push badges to the right
+ print '';
+
+ // Badges (far right)
+ if (!empty($treeInfoBadges)) {
+ $defaultBadgeColor = getDolGlobalString('KUNDENKARTE_TREE_BADGE_COLOR', '#2a4a5e');
+ print '';
+ foreach ($treeInfoBadges as $info) {
+ $badgeIcon = kundenkarte_get_field_icon($info['code'], $info['type']);
+ $fieldBadgeColor = !empty($info['color']) ? $info['color'] : $defaultBadgeColor;
+ print '';
+ print ' '.dol_escape_htmltag($info['value']);
+ print '';
}
print '';
}
- print '';
+
+ // File indicators
+ if ($node->image_count > 0 || $node->doc_count > 0) {
+ $totalFiles = $node->image_count + $node->doc_count;
+ print '
';
+ print '';
+ print ' '.$totalFiles;
+ print '';
+ print '';
+ }
if ($node->type_short || $node->type_label) {
$typeDisplay = $node->type_short ? $node->type_short : $node->type_label;
@@ -1405,16 +1582,18 @@ function printTreeNode($node, $socid, $systemId, $canEdit, $canDelete, $langs, $
/**
* Print tree options for select
*/
-function printTreeOptions($nodes, $selected = 0, $excludeId = 0, $prefix = '')
+function printTreeOptions($nodes, $selected = 0, $excludeId = 0, $prefix = '', $level = 0)
{
foreach ($nodes as $node) {
if ($node->id == $excludeId) continue;
$sel = ($node->id == $selected) ? ' selected' : '';
- print '
';
+ $icon = !empty($node->type_picto) ? $node->type_picto : 'fa-cube';
+ $color = !empty($node->type_color) ? $node->type_color : '#888';
+ print '
';
if (!empty($node->children)) {
- printTreeOptions($node->children, $selected, $excludeId, $prefix.' ');
+ printTreeOptions($node->children, $selected, $excludeId, $prefix.'── ', $level + 1);
}
}
}
diff --git a/tabs/contact_anlagen.php b/tabs/contact_anlagen.php
index 8f825f1..64b93d7 100755
--- a/tabs/contact_anlagen.php
+++ b/tabs/contact_anlagen.php
@@ -32,7 +32,11 @@ dol_include_once('/kundenkarte/lib/kundenkarte.lib.php');
$langs->loadLangs(array('companies', 'kundenkarte@kundenkarte'));
// Get parameters
+// Support both 'id' and 'contactid' for compatibility with Dolibarr's contact navigation arrows
$id = GETPOSTINT('id');
+if ($id <= 0) {
+ $id = GETPOSTINT('contactid');
+}
$action = GETPOST('action', 'aZ09');
$confirm = GETPOST('confirm', 'alpha');
$systemId = GETPOSTINT('system');
@@ -50,13 +54,28 @@ $form = new Form($db);
$anlage = new Anlage($db);
$anlageType = new AnlageType($db);
-// Load contact
-if ($id > 0) {
- $result = $object->fetch($id);
- if ($result <= 0) {
- dol_print_error($db, $object->error);
- exit;
+// Load contact - id is required
+if ($id <= 0) {
+ // If no id, try to get it from anlage_id
+ if ($anlageId > 0) {
+ $tmpAnlage = new Anlage($db);
+ if ($tmpAnlage->fetch($anlageId) > 0) {
+ $id = $tmpAnlage->fk_contact;
+ if ($id > 0) {
+ // Redirect to include id in URL for proper navigation
+ header('Location: '.$_SERVER['PHP_SELF'].'?id='.$id.'&system='.$systemId.'&action='.$action.'&anlage_id='.$anlageId);
+ exit;
+ }
+ }
}
+ // Still no id - show error
+ accessforbidden($langs->trans('ErrorRecordNotFound'));
+}
+
+$result = $object->fetch($id);
+if ($result <= 0) {
+ dol_print_error($db, $object->error);
+ exit;
}
$permissiontoread = $user->hasRight('kundenkarte', 'read');
@@ -623,7 +642,9 @@ if (empty($customerSystems)) {
print '
';
foreach ($types as $t) {
$selected = (($isEdit || $isCopy) && $anlage->fk_anlage_type == $t->id) ? ' selected' : '';
- print '
';
+ $icon = !empty($t->picto) ? $t->picto : 'fa-cube';
+ $color = !empty($t->color) ? $t->color : '#888';
+ print '
';
}
print '';
if (empty($types)) {
@@ -657,6 +678,49 @@ if (empty($customerSystems)) {
print '
';
print '';
+
+ // JavaScript: Select2 mit Icons für Type und Parent
+ print '';
}
print '