Added working treeviews and buttons.

This commit is contained in:
Jan Böhmer 2019-03-25 12:44:44 +01:00
parent 82761a3454
commit afd45d464c
17 changed files with 547 additions and 74 deletions

304
assets/ts_src/ajax_ui.js Normal file
View file

@ -0,0 +1,304 @@
"use strict";
/*
*
* part-db version 0.1
* Copyright (C) 2005 Christoph Lechner
* http://www.cl-projects.de/
*
* part-db version 0.2+
* Copyright (C) 2009 K. Jacobs and others (see authors.php)
* http://code.google.com/p/part-db/
*
* Part-DB Version 0.4+
* Copyright (C) 2016 - 2019 Jan Böhmer
* https://github.com/jbtronics
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*
*/
Object.defineProperty(exports, "__esModule", { value: true });
var Cookies = require("js-cookie");
/**
* Extract the title (The name between the <title> tags) of a HTML snippet.
* @param {string} html The HTML code which should be searched.
* @returns {string} The title extracted from the html.
*/
function extractTitle(html) {
var title = "";
var regex = /<title>(.*?)<\/title>/gi;
if (regex.test(html)) {
var matches = html.match(regex);
for (var match in matches) {
title = $(matches[match]).text();
}
}
return title;
}
var AjaxUI = /** @class */ (function () {
function AjaxUI() {
this.BASE = "/";
this.trees_filled = false;
this.statePopped = false;
//Make back in the browser go back in history
window.onpopstate = this.onPopState;
$(document).ajaxError(this.onAjaxError.bind(this));
//$(document).ajaxComplete(this.onAjaxComplete.bind(this));
}
/**
* Starts the ajax ui und execute handlers registered in addStartAction().
* Should be called in a document.ready, after handlers are set.
*/
AjaxUI.prototype.start = function () {
console.info("AjaxUI started!");
this.BASE = $("body").data("base-url") + "/";
console.info("Base path is " + this.BASE);
this.registerLinks();
this.registerForm();
this.fillTrees();
};
/**
* Fill the trees with the given data.
*/
AjaxUI.prototype.fillTrees = function () {
var categories = Cookies.get("tree_datasource_tree-categories");
var devices = Cookies.get("tree_datasource_tree-devices");
var tools = Cookies.get("tree_datasource_tree-tools");
if (typeof categories == "undefined") {
categories = "categories";
}
if (typeof devices == "undefined") {
devices = "devices";
}
if (typeof tools == "undefined") {
tools = "tools";
}
this.treeLoadDataSource("tree-categories", categories);
this.treeLoadDataSource("tree-devices", devices);
this.treeLoadDataSource("tree-tools", tools);
this.trees_filled = true;
//Register tree btns to expand all, or to switch datasource.
$(".tree-btns").click(function (event) {
event.preventDefault();
$(this).parents("div.dropdown").removeClass('show');
//$(this).closest(".dropdown-menu").removeClass('show');
$(".dropdown-menu.show").removeClass("show");
var mode = $(this).data("mode");
var target = $(this).data("target");
var text = $(this).text() + " \n<span class='caret'></span>"; //Add caret or it will be removed, when written into title
if (mode === "collapse") {
// @ts-ignore
$('#' + target).treeview('collapseAll', { silent: true });
}
else if (mode === "expand") {
// @ts-ignore
$('#' + target).treeview('expandAll', { silent: true });
}
else {
Cookies.set("tree_datasource_" + target, mode);
exports.ajaxUI.treeLoadDataSource(target, mode);
}
return false;
});
};
/**
* Load the given url into the tree with the given id.
* @param target_id
* @param datasource
*/
AjaxUI.prototype.treeLoadDataSource = function (target_id, datasource) {
var text = $(".tree-btns[data-mode='" + datasource + "']").html();
text = text + " \n<span class='caret'></span>"; //Add caret or it will be removed, when written into title
switch (datasource) {
case "categories":
exports.ajaxUI.initTree("#" + target_id, 'tree/categories/');
break;
case "locations":
exports.ajaxUI.initTree("#" + target_id, 'tree/locations');
break;
case "footprints":
exports.ajaxUI.initTree("#" + target_id, 'tree/footprints');
break;
case "manufacturers":
exports.ajaxUI.initTree("#" + target_id, 'tree/manufacturers');
break;
case "suppliers":
exports.ajaxUI.initTree("#" + target_id, 'tree/suppliers');
break;
case "tools":
exports.ajaxUI.initTree("#" + target_id, 'tree/tools/');
break;
case "devices":
exports.ajaxUI.initTree("#" + target_id, 'tree/devices');
break;
}
$("#" + target_id + "-title").html(text);
};
/**
* Fill a treeview with data from the given url.
* @param tree The Jquery selector for the tree (e.g. "#tree-tools")
* @param url The url from where the data should be loaded
*/
AjaxUI.prototype.initTree = function (tree, url) {
//let contextmenu_handler = this.onNodeContextmenu;
$.getJSON(exports.ajaxUI.BASE + url, function (data) {
// @ts-ignore
$(tree).treeview({
data: data,
enableLinks: false,
showIcon: false,
showBorder: true,
onNodeSelected: function (event, data) {
if (data.href) {
exports.ajaxUI.navigateTo(data.href);
}
},
//onNodeContextmenu: contextmenu_handler,
expandIcon: "fas fa-plus fa-fw fa-treeview", collapseIcon: "fas fa-minus fa-fw fa-treeview"
}).treeview('collapseAll', { silent: true });
});
};
/**
* Register all links, for loading via ajax.
*/
AjaxUI.prototype.registerLinks = function () {
$('a').not(".link-external, [data-no-ajax]").click(function (event) {
var a = $(this);
var href = $.trim(a.attr("href"));
//Ignore links without href attr and nav links ('they only have a #)
if (href != null && href != "" && href.charAt(0) !== '#') {
event.preventDefault();
exports.ajaxUI.navigateTo(href);
}
});
console.debug('Links registered!');
};
/**
* Register all forms for loading via ajax.
*/
AjaxUI.prototype.registerForm = function () {
var options = {
success: this.onAjaxComplete,
beforeSubmit: function (arr, $form, options) {
//When data-with-progbar is specified, then show progressbar.
if ($form.data("with-progbar") != undefined) {
exports.ajaxUI.showProgressBar();
}
return true;
}
};
$('form').not('[data-no-ajax]').ajaxForm(options);
console.debug('Forms registered!');
};
AjaxUI.prototype.showProgressBar = function () {
//Blur content background
$('#content').addClass('loading-content');
// @ts-ignore
$('#progressModal').modal({
keyboard: false,
backdrop: false,
show: true
});
};
AjaxUI.prototype.hideProgressBar = function () {
// @ts-ignore
$('#progressModal').modal('hide');
//Remove the remaining things of the modal
$('.modal-backdrop').remove();
$('body').removeClass('modal-open');
$('body, .navbar').css('padding-right', "");
};
/**
* Navigates to the given URL
* @param url The url which should be opened.
* @param show_loading Show the loading bar during loading.
*/
AjaxUI.prototype.navigateTo = function (url, show_loading) {
if (show_loading === void 0) { show_loading = true; }
if (show_loading) {
this.showProgressBar();
}
$.ajax(url, {
success: this.onAjaxComplete
});
//$.ajax(url).promise().done(this.onAjaxComplete);
};
/**
* Called when an error occurs on loading ajax. Outputs the message to the console.
*/
AjaxUI.prototype.onAjaxError = function (event, request, settings) {
'use strict';
//Ignore aborted requests.
if (request.statusText == 'abort') {
return;
}
console.error("Error getting the ajax data from server!");
console.log(event);
console.log(request);
console.log(settings);
//If it was a server error and response is not empty, show it to user.
if (request.status == 500 && request.responseText !== "") {
console.log("Response:" + request.responseText);
}
};
/**
* This function gets called every time, the "back" button in the browser is pressed.
* We use it to load the content from history stack via ajax and to rewrite url, so we only have
* to load #content-data
* @param event
*/
AjaxUI.prototype.onPopState = function (event) {
var page = location.href;
exports.ajaxUI.statePopped = true;
exports.ajaxUI.navigateTo(page);
};
/**
* This function takes the response of an ajax requests, and does the things we need to do for our AjaxUI.
* This includes inserting the content and pushing history.
* @param responseText
* @param textStatus
* @param jqXHR
*/
AjaxUI.prototype.onAjaxComplete = function (responseText, textStatus, jqXHR) {
console.debug("Ajax load completed!");
exports.ajaxUI.hideProgressBar();
//Parse response to DOM structure
var dom = $.parseHTML(responseText);
//And replace the content container
$("#content").replaceWith($("#content", dom));
//Replace login menu too (so everything is up to date)
$("#login-content").replaceWith($('#login-content', dom));
//Replace flash messages and show them
$("#message-container").replaceWith($('#message-container', dom));
$(".toast").toast('show');
//Set new title
var title = extractTitle(responseText);
document.title = title;
//Push to history, if we currently arent poping an old value.
if (!exports.ajaxUI.statePopped) {
// @ts-ignore
history.pushState(null, title, this.url);
}
else {
//Clear pop state
exports.ajaxUI.statePopped;
}
//Do things on the new dom
exports.ajaxUI.registerLinks();
exports.ajaxUI.registerForm();
};
return AjaxUI;
}());
exports.ajaxUI = new AjaxUI();
//# sourceMappingURL=ajax_ui.js.map

File diff suppressed because one or more lines are too long

View file

@ -50,15 +50,12 @@ function extractTitle(html : string) : string {
class AjaxUI { class AjaxUI {
protected BASE = "/";
private trees_filled : boolean = false; private trees_filled : boolean = false;
private statePopped : boolean = false; private statePopped : boolean = false;
public test()
{
alert("Test");
}
public constructor() public constructor()
{ {
//Make back in the browser go back in history //Make back in the browser go back in history
@ -74,14 +71,132 @@ class AjaxUI {
public start() public start()
{ {
console.info("AjaxUI started!"); console.info("AjaxUI started!");
this.BASE = $("body").data("base-url") + "/";
console.info("Base path is " + this.BASE);
this.registerLinks(); this.registerLinks();
this.registerForm(); this.registerForm();
this.fillTrees();
} }
/**
* Fill the trees with the given data.
*/
public fillTrees()
{
let categories = Cookies.get("tree_datasource_tree-categories");
let devices = Cookies.get("tree_datasource_tree-devices");
let tools = Cookies.get("tree_datasource_tree-tools");
if(typeof categories == "undefined") {
categories = "categories";
}
if(typeof devices == "undefined") {
devices = "devices";
}
if(typeof tools == "undefined") {
tools = "tools";
}
this.treeLoadDataSource("tree-categories", categories);
this.treeLoadDataSource("tree-devices", devices);
this.treeLoadDataSource("tree-tools", tools);
this.trees_filled = true;
//Register tree btns to expand all, or to switch datasource.
$(".tree-btns").click(function (event) {
event.preventDefault();
$(this).parents("div.dropdown").removeClass('show');
//$(this).closest(".dropdown-menu").removeClass('show');
$(".dropdown-menu.show").removeClass("show");
let mode = $(this).data("mode");
let target = $(this).data("target");
let text = $(this).text() + " \n<span class='caret'></span>"; //Add caret or it will be removed, when written into title
if (mode==="collapse") {
// @ts-ignore
$('#' + target).treeview('collapseAll', { silent: true });
}
else if(mode==="expand") {
// @ts-ignore
$('#' + target).treeview('expandAll', { silent: true });
} else {
Cookies.set("tree_datasource_" + target, mode);
ajaxUI.treeLoadDataSource(target, mode);
}
return false;
});
}
/**
* Load the given url into the tree with the given id.
* @param target_id
* @param datasource
*/
protected treeLoadDataSource(target_id, datasource) {
let text : string = $(".tree-btns[data-mode='" + datasource + "']").html();
text = text + " \n<span class='caret'></span>"; //Add caret or it will be removed, when written into title
switch(datasource) {
case "categories":
ajaxUI.initTree("#" + target_id, 'tree/categories/');
break;
case "locations":
ajaxUI.initTree("#" + target_id, 'tree/locations');
break;
case "footprints":
ajaxUI.initTree("#" + target_id, 'tree/footprints');
break;
case "manufacturers":
ajaxUI.initTree("#" + target_id, 'tree/manufacturers');
break;
case "suppliers":
ajaxUI.initTree("#" + target_id, 'tree/suppliers');
break;
case "tools":
ajaxUI.initTree("#" + target_id, 'tree/tools/');
break;
case "devices":
ajaxUI.initTree("#" + target_id, 'tree/devices');
break;
}
$( "#" + target_id + "-title").html(text);
}
/**
* Fill a treeview with data from the given url.
* @param tree The Jquery selector for the tree (e.g. "#tree-tools")
* @param url The url from where the data should be loaded
*/
public initTree(tree, url) {
//let contextmenu_handler = this.onNodeContextmenu;
$.getJSON(ajaxUI.BASE + url, function (data) {
// @ts-ignore
$(tree).treeview({
data: data,
enableLinks: false,
showIcon: false,
showBorder: true,
onNodeSelected: function(event, data) {
if(data.href) {
ajaxUI.navigateTo(data.href);
}
},
//onNodeContextmenu: contextmenu_handler,
expandIcon: "fas fa-plus fa-fw fa-treeview", collapseIcon: "fas fa-minus fa-fw fa-treeview"}).treeview('collapseAll', { silent: true });
});
}
/** /**
* Register all links, for loading via ajax. * Register all links, for loading via ajax.
*/ */
protected registerLinks() public registerLinks()
{ {
$('a').not(".link-external, [data-no-ajax]").click(function (event) { $('a').not(".link-external, [data-no-ajax]").click(function (event) {
let a = $(this); let a = $(this);
@ -92,14 +207,14 @@ class AjaxUI {
ajaxUI.navigateTo(href); ajaxUI.navigateTo(href);
} }
} }
) );
console.debug('Links registered!'); console.debug('Links registered!');
} }
/** /**
* Register all forms for loading via ajax. * Register all forms for loading via ajax.
*/ */
protected registerForm() public registerForm()
{ {
let options : JQueryFormOptions = { let options : JQueryFormOptions = {
success: this.onAjaxComplete, success: this.onAjaxComplete,
@ -110,7 +225,7 @@ class AjaxUI {
} }
return true; return true;
} }
} };
$('form').not('[data-no-ajax]').ajaxForm(options); $('form').not('[data-no-ajax]').ajaxForm(options);
console.debug('Forms registered!'); console.debug('Forms registered!');
@ -168,7 +283,10 @@ class AjaxUI {
return; return;
} }
console.error("Error getting the ajax data from server!");
console.log(event); console.log(event);
console.log(request);
console.log(settings);
//If it was a server error and response is not empty, show it to user. //If it was a server error and response is not empty, show it to user.
if(request.status == 500 && request.responseText !== "") if(request.status == 500 && request.responseText !== "")
{ {

View file

@ -4,7 +4,7 @@
"target": "es5", "target": "es5",
"sourceMap": true, "sourceMap": true,
"typeRoots": ["../node_modules"], "typeRoots": ["../node_modules"],
"types": ["jquery", "js-cookie", "bootstrap", "jquery.form"] "types": ["jquery", "js-cookie", "bootstrap", "jquery.form", "bootstrap-treeview"]
}, },
"exclude": [ "exclude": [
"node_modules" "node_modules"

View file

@ -18,6 +18,7 @@
"dependencies": { "dependencies": {
"@ckeditor/ckeditor5-build-classic": "^12.0.0", "@ckeditor/ckeditor5-build-classic": "^12.0.0",
"@types/bootstrap": "^4.3.0", "@types/bootstrap": "^4.3.0",
"@types/bootstrap-treeview": "^1.20.0",
"@types/jquery": "^3.3.29", "@types/jquery": "^3.3.29",
"@types/jquery.form": "^3.26.30", "@types/jquery.form": "^3.26.30",
"@types/js-cookie": "^2.2.1", "@types/js-cookie": "^2.2.1",

View file

@ -30,9 +30,16 @@
namespace App\Controller; namespace App\Controller;
use App\Entity\Category; use App\Entity\Category;
use App\Entity\Device;
use App\Entity\Footprint;
use App\Entity\Manufacturer;
use App\Entity\Storelocation;
use App\Entity\Supplier;
use App\Helpers\TreeViewNode; use App\Helpers\TreeViewNode;
use App\Services\ToolsTreeBuilder; use App\Services\ToolsTreeBuilder;
use App\Services\TreeBuilder;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Form\Extension\Core\Type\LocaleType;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
/** /**
@ -55,10 +62,11 @@ class TreeController extends AbstractController
/** /**
* @Route("/tree/category/{id}", name="tree_category") * @Route("/tree/category/{id}", name="tree_category")
* @Route("/tree/categories")
*/ */
public function categoryTree(TreeBuilder $builder, Category $category = null) public function categoryTree(TreeBuilder $builder, Category $category = null)
{ {
if($category != null) { if ($category != null) {
$tree[] = $builder->elementToTreeNode($category); $tree[] = $builder->elementToTreeNode($category);
} else { } else {
$tree = $builder->typeToTree(Category::class); $tree = $builder->typeToTree(Category::class);
@ -68,7 +76,85 @@ class TreeController extends AbstractController
return $this->json($tree, 200, [], ['skip_null_values' => true]); return $this->json($tree, 200, [], ['skip_null_values' => true]);
} }
/**
* @Route("/tree/footprint/{id}", name="tree_footprint")
* @Route("/tree/footprints")
*/
public function footprintTree(TreeBuilder $builder, Footprint $footprint = null)
{
if ($footprint != null) {
$tree[] = $builder->elementToTreeNode($footprint);
} else {
$tree = $builder->typeToTree(Footprint::class, null);
}
return $this->json($tree, 200, [], ['skip_null_values' => true]);
}
/**
* @Route("/tree/location/{id}", name="tree_location")
* @Route("/tree/locations")
*/
public function locationTree(TreeBuilder $builder, Storelocation $location = null)
{
if ($location != null) {
$tree[] = $builder->elementToTreeNode($location);
} else {
$tree = $builder->typeToTree(Storelocation::class, null);
}
return $this->json($tree, 200, [], ['skip_null_values' => true]);
}
/**
* @Route("/tree/manufacturer/{id}", name="tree_manufacturer")
* @Route("/tree/manufacturers")
*/
public function manufacturerTree(TreeBuilder $builder, Manufacturer $manufacturer = null)
{
if ($manufacturer != null) {
$tree[] = $builder->elementToTreeNode($manufacturer);
} else {
$tree = $builder->typeToTree(Manufacturer::class, null);
}
return $this->json($tree, 200, [], ['skip_null_values' => true]);
}
/**
* @Route("/tree/supplier/{id}", name="tree_supplier")
* @Route("/tree/suppliers")
*/
public function supplierTree(TreeBuilder $builder, Supplier $supplier = null)
{
if ($supplier != null) {
$tree[] = $builder->elementToTreeNode($supplier);
} else {
$tree = $builder->typeToTree(Supplier::class, null);
}
return $this->json($tree, 200, [], ['skip_null_values' => true]);
}
/**
* @Route("/tree/device/{id}", name="tree_device")
* @Route("/tree/devices")
*/
public function deviceTree(TreeBuilder $builder, Device $device = null)
{
if ($device != null) {
$tree[] = $builder->elementToTreeNode($device);
} else {
$tree = $builder->typeToTree(Device::class, null);
}
return $this->json($tree, 200, [], ['skip_null_values' => true]);
}
} }

View file

@ -29,7 +29,7 @@ use Doctrine\ORM\Mapping as ORM;
/** /**
* Class AttachmentType. * Class AttachmentType.
* *
* @ORM\Entity() * @ORM\Entity(repositoryClass="App\Repository\StructuralDBElementRepository")
* @ORM\Table(name="attachement_types") * @ORM\Table(name="attachement_types")
*/ */
class AttachmentType extends StructuralDBElement class AttachmentType extends StructuralDBElement

View file

@ -28,7 +28,7 @@ use Doctrine\ORM\Mapping as ORM;
/** /**
* Class AttachmentType. * Class AttachmentType.
* *
* @ORM\Entity * @ORM\Entity(repositoryClass="App\Repository\StructuralDBElementRepository")
* @ORM\Table(name="categories") * @ORM\Table(name="categories")
*/ */
class Category extends PartsContainingDBElement class Category extends PartsContainingDBElement

View file

@ -37,7 +37,7 @@ use Doctrine\ORM\Mapping as ORM;
/** /**
* Class AttachmentType. * Class AttachmentType.
* *
* @ORM\Entity() * @ORM\Entity(repositoryClass="App\Repository\StructuralDBElementRepository")
* @ORM\Table(name="devices") * @ORM\Table(name="devices")
*/ */
class Device extends PartsContainingDBElement class Device extends PartsContainingDBElement

View file

@ -37,7 +37,7 @@ use Doctrine\ORM\Mapping as ORM;
/** /**
* Class Footprint. * Class Footprint.
* *
* @ORM\Entity() * @ORM\Entity(repositoryClass="App\Repository\StructuralDBElementRepository")
* @ORM\Table("footprints") * @ORM\Table("footprints")
*/ */
class Footprint extends PartsContainingDBElement class Footprint extends PartsContainingDBElement

View file

@ -37,7 +37,7 @@ use Doctrine\ORM\Mapping as ORM;
/** /**
* Class Manufacturer. * Class Manufacturer.
* *
* @ORM\Entity() * @ORM\Entity(repositoryClass="App\Repository\StructuralDBElementRepository")
* @ORM\Table("manufacturers") * @ORM\Table("manufacturers")
*/ */
class Manufacturer extends Company class Manufacturer extends Company

View file

@ -37,7 +37,7 @@ use Doctrine\ORM\Mapping as ORM;
/** /**
* Class Storelocation. * Class Storelocation.
* *
* @ORM\Entity() * @ORM\Entity(repositoryClass="App\Repository\StructuralDBElementRepository")
* @ORM\Table("storelocations") * @ORM\Table("storelocations")
*/ */
class Storelocation extends PartsContainingDBElement class Storelocation extends PartsContainingDBElement

View file

@ -36,8 +36,7 @@ use Doctrine\ORM\PersistentCollection;
* It's allowed to have instances of root elements, but if you try to change * It's allowed to have instances of root elements, but if you try to change
* an attribute of a root element, you will get an exception! * an attribute of a root element, you will get an exception!
* *
* @ORM\MappedSuperclass() * @ORM\MappedSuperclass(repositoryClass="App\Repository\StructuralDBElementRepository")
* //@ORM\Entity(repositoryClass="App\Repository\StructuralDBElementRepository")
*/ */
abstract class StructuralDBElement extends AttachmentContainingDBElement abstract class StructuralDBElement extends AttachmentContainingDBElement
{ {
@ -310,50 +309,6 @@ abstract class StructuralDBElement extends AttachmentContainingDBElement
return implode("\n", $html); return implode("\n", $html);
} }
public function buildBootstrapTree(
$page,
$parameter,
$recursive = false,
$show_root = false,
$use_db_root_name = true,
$root_name = '$$'
): array {
if ('$$' == $root_name) {
$root_name = _('Oberste Ebene');
}
$subelements = $this->getSubelements(false);
$nodes = array();
foreach ($subelements as $element) {
$nodes[] = $element->buildBootstrapTree($page, $parameter);
}
// if we are on root level?
if (-1 == $this->getParentID()) {
if ($show_root) {
$tree = array(
array('text' => $use_db_root_name ? htmlspecialchars($this->getName()) : $root_name,
'href' => $page.'?'.$parameter.'='.$this->getID(),
'nodes' => $nodes, ),
);
} else { //Dont show root node
$tree = $nodes;
}
} elseif (!empty($nodes)) {
$tree = array('text' => htmlspecialchars($this->getName()),
'href' => $page.'?'.$parameter.'='.$this->getID(),
'nodes' => $nodes,
);
} else {
$tree = array('text' => htmlspecialchars($this->getName()),
'href' => $page.'?'.$parameter.'='.$this->getID(),
);
}
return $tree;
}
/** /**
* Creates a template loop for a Breadcrumb bar, representing the structural DB element. * Creates a template loop for a Breadcrumb bar, representing the structural DB element.
* *

View file

@ -37,7 +37,7 @@ use Doctrine\ORM\Mapping as ORM;
/** /**
* Class Supplier. * Class Supplier.
* *
* @ORM\Entity() * @ORM\Entity(repositoryClass="App\Repository\StructuralDBElementRepository")
* @ORM\Table("suppliers") * @ORM\Table("suppliers")
*/ */
class Supplier extends Company class Supplier extends Company

View file

@ -1,8 +1,9 @@
<?php <?php
/** /**
*
* part-db version 0.1 * part-db version 0.1
* Copyright (C) 2005 Christoph Lechner * Copyright (C) 2005 Christoph Lechner
* http://www.cl-projects.de/. * http://www.cl-projects.de/
* *
* part-db version 0.2+ * part-db version 0.2+
* Copyright (C) 2009 K. Jacobs and others (see authors.php) * Copyright (C) 2009 K. Jacobs and others (see authors.php)
@ -25,15 +26,14 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*
*/ */
namespace App\Controller; namespace App\Services;
use App\Entity\StructuralDBElement; use App\Entity\StructuralDBElement;
use App\Helpers\TreeViewNode; use App\Helpers\TreeViewNode;
use App\Repository\StructuralDBElementRepository; use App\Repository\StructuralDBElementRepository;
use App\Services\EntityURLGenerator;
use App\Services\ToolsTreeBuilder;
use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\EntityManagerInterface;
/** /**
@ -59,13 +59,13 @@ class TreeBuilder
* See EntityURLGenerator::getURL for possible types. * See EntityURLGenerator::getURL for possible types.
* @return TreeViewNode The Node for the given Element. * @return TreeViewNode The Node for the given Element.
*/ */
public function elementToTreeNode(StructuralDBElement $element, string $href_type = 'list_parts') : TreeViewNode public function elementToTreeNode(StructuralDBElement $element, ?string $href_type = 'list_parts') : TreeViewNode
{ {
$children = $element->getSubelements(); $children = $element->getSubelements();
$children_nodes = null; $children_nodes = null;
foreach ($children as $child) { foreach ($children as $child) {
$children_nodes[] = $this->elementToTreeNode($child); $children_nodes[] = $this->elementToTreeNode($child, $href_type);
} }
//Check if we need to generate a href type //Check if we need to generate a href type
@ -86,7 +86,7 @@ class TreeBuilder
* See EntityURLGenerator::getURL for possible types. * See EntityURLGenerator::getURL for possible types.
* @return TreeViewNode[] Returns an array, containing all nodes. It is empty if the given class has no elements. * @return TreeViewNode[] Returns an array, containing all nodes. It is empty if the given class has no elements.
*/ */
public function typeToTree(StructuralDBElement $class_name, string $href_type = 'list_parts') : array public function typeToTree(string $class_name, ?string $href_type = 'list_parts') : array
{ {
/** /**
* @var $repo StructuralDBElementRepository * @var $repo StructuralDBElementRepository
@ -96,7 +96,7 @@ class TreeBuilder
$array = array(); $array = array();
foreach ($root_nodes as $node) { foreach ($root_nodes as $node) {
$array = $this->elementToTreeNode($node, $href_type); $array[] = $this->elementToTreeNode($node, $href_type);
} }
return $array; return $array;

View file

@ -13,13 +13,12 @@
<meta name="msapplication-config" content="{{ asset('icons/browserconfig.xml') }}"> <meta name="msapplication-config" content="{{ asset('icons/browserconfig.xml') }}">
<meta name="theme-color" content="#ffffff"> <meta name="theme-color" content="#ffffff">
<title>{% filter trim %}{% block title %}{{ partdb_title}}{% endblock %}{% endfilter %}</title> <title>{% filter trim %}{% block title %}{{ partdb_title}}{% endblock %}{% endfilter %}</title>
{% block stylesheets %} {% block stylesheets %}
{{ encore_entry_link_tags('app') }} {{ encore_entry_link_tags('app') }}
{% endblock %} {% endblock %}
</head> </head>
<body> <body data-base-url="{{ app.request.schemeAndHttpHost }}">
{% block body %} {% block body %}
<header> <header>
@ -279,6 +278,7 @@
<script> <script>
{#
$.getJSON("{{ path("tree_tools") }}",null, function (data) { $.getJSON("{{ path("tree_tools") }}",null, function (data) {
$('#tree-tools').treeview({ $('#tree-tools').treeview({
data: data, data: data,
@ -293,6 +293,7 @@
enableLinks: true enableLinks: true
}); });
}); });
#}
</script> </script>
{% block scripts %} {% block scripts %}

View file

@ -650,6 +650,13 @@
resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a"
integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA== integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==
"@types/bootstrap-treeview@^1.20.0":
version "1.20.0"
resolved "https://registry.yarnpkg.com/@types/bootstrap-treeview/-/bootstrap-treeview-1.20.0.tgz#08157e2f26b5b278dfd70e2054bbf8aa7d6f0b2d"
integrity sha512-o1FFKSNd68ohmyvrHna11q5cLd9aiVUp/Itr7B33OmFY37GFufQvVOH9Iv/+2xcE9tVc7pHfmxucBnQkjZzHCQ==
dependencies:
"@types/jquery" "*"
"@types/bootstrap@^4.3.0": "@types/bootstrap@^4.3.0":
version "4.3.0" version "4.3.0"
resolved "https://registry.yarnpkg.com/@types/bootstrap/-/bootstrap-4.3.0.tgz#4cac01617f56239a5146945a98bde64274838c35" resolved "https://registry.yarnpkg.com/@types/bootstrap/-/bootstrap-4.3.0.tgz#4cac01617f56239a5146945a98bde64274838c35"