Nested tree in Content Link

Hi, great job with CockpitCMS.
It could be great if you could make the tree selection in content-link nested, just like when you create them.


Could someone guide me on how to develop this?

Hi, I would need this feature for my new project, so I took a look at it. It’s not that complicated to solve, but my solution is not entirely ideal. Loading values ​​is currently limited, which could be avoided for a tree model, but which means that all values ​​must always be loaded. The loaded values ​​must be sorted by PARENT CHILD before being displayed, which can be a bit slow for large tables, so I don’t recommend using it on large trees.


As I wrote above, it’s not an ideal solution, but it solves my current problem with displaying the tree in dialog.

\cockpit\modules\Content\assets\dialogs\select-content-item.js
template: /html/`

<tbody>
    <tr v-for="item in items" :class="'lv lv-'+ (item._lv+1)">

or (if you don’t want to edit the CSS file due to the large number of nesting)

<tbody>
    <tr v-for="item in items" :style="'position: relative; left:' + (item._lv * 25) + 'px;'">

\cockpit\modules\App\assets\css\app.css

TABLE TR.lv { position: relative; left:0px; }
TABLE TR.lv-2 { left:25px; }
TABLE TR.lv-3 { left:50px; }
TABLE TR.lv-4 { left:75px; }
TABLE TR.lv-5 { left:100px; }
TABLE TR.lv-6 { left:125px; }
TABLE TR.lv-7 { left:150px; }
TABLE TR.lv-8 { left:175px; }
TABLE TR.lv-9 { left:200px; }
TABLE TR.lv-10 { left:225px; }

\cockpit\modules\Content\Controller\Collection.php
public function find($model = null) {

if (!is_null($state)) {
    if (!isset($options['filter'])) $options['filter'] = [];
    $options['filter']['_state'] = intval($state);
}

if($model['type'] == 'tree') {
    $options['sort'] = ['_o' => 1];
    if(isset($options['limit'])) unset($options['limit']);
}

try {
    $items = $this->app->module('content')->items($model['name'], $options, $process);
    $count = $this->app->module('content')->count($model['name'], $options['filter'] ?? []);
    $pages = isset($options['limit']) ? ceil($count / $options['limit']) : 1;
    $page  = 1;

    function buildTree(array &$items, $pid = null, $lv = 0) {
        $r = [];
        foreach($items as $i) {
            if($i['_pid'] == $pid) {
                $i['_lv'] = $lv;
                $r[] = $i;
                $r = array_merge($r, buildTree($items, $i['_id'], $lv+1));
            }
        }
        return $r;
    }

    if($model['type'] == 'tree' && count($items)>1) {
        $items = buildTree($items);
    }

    if ($pages > 1 && isset($options['skip'])) {
        $page = ceil($options['skip'] / $options['limit']) + 1;
    }
} catch (\Exception $e) {
    $items = [];
    $count = 0;
    $pages = 1;
    $page  = 1;
}