Post

3 followers Follow
0
Avatar

Organization Chart Custom Panel

We use the Org Chart application from the Apps Marketplace and really like it. It makes it easy to find where people fit in the organization.

The app includes a custom panel that we can access from the People Module. Is there any way that we can access the highest level of the org chart directly from the navgation bar? This would make it much easier to access.

Thanks,

 

Leo Lovely

Leo Lovely Answered

Please sign in to leave a comment.

3 comments

0
Avatar

Hi Leo,

 

Yes it is possible,  this is the script for the panel (Hope it will come out ok).

The other component of the page (html, style, etc) should be the same as the panel and you don't need the Json part at all.

google.load("visualization", "1", { packages: ["orgchart"] });

google.setOnLoadCallback(drawChart);

function drawChart() {

API.Utils.beginLoading();

refreshChart();

}

function refreshChart(onlyRefresh) {

var data = API.Context.getData();

queryAllUsers(function (result) {

var selectedUser = API.Context.getCurrentUserId();

if (data && data.user)

selectedUser = data.user.id;

initChart(result, selectedUser, true);

});

}

function queryAllUsers(callback) {

queryMore(0, [], callback);

}

function queryMore(from, allResults, callback) {

API.Objects.query("SELECT Name,JobTitle.Name,ImageUrl,State,Email,DirectManager.State FROM user where state='Active' limit 1000 offset " + from, function (results, nextQuery) {

if (results.length > 0)

allResults = allResults.concat(results);

if (nextQuery && nextQuery.q.paging.hasMore)

queryMore(nextQuery.q.paging.from, allResults, callback);

else

{

fillDeletedDirectManagers(allResults, callback);

}

}, { startFrom: 0 });

}

function fillDeletedDirectManagers(users, callback)

{

var deletedManagers = [];

for (var i = 0; i < users.length; i++)

{

var user = users[i];

if (user.DirectManager && user.DirectManager.State && (user.DirectManager.State.id == '/State/Deleted' || user.DirectManager.State.id == '/State/Disabled'))

{

deletedManagers.push('"'+user.DirectManager.id.split('/')[2]+'"');

}

}

if (deletedManagers.length > 0)

{

getDeletedManagers(0, users, deletedManagers, callback)

}

else

{

callback(users);

}

}

function getDeletedManagers(from, users, deletedManagers, callback)

{

API.Objects.query("SELECT Name,JobTitle.Name,ImageUrl,State,Email,DirectManager.State FROM user where ExternalId in ("+deletedManagers.join()+") limit 1000 offset " + from, function (results, nextQuery) {

if (results.length > 0)

users = users.concat(results);

callback(users);

}, { startFrom: 0 });

}

function initChart(users, currentUserId, allowEdit) {

//Draw the chart

var dataTable = new google.visualization.DataTable();

dataTable.addColumn('string', 'Name');

dataTable.addColumn('string', 'Manager');

dataTable.addColumn('string', 'ToolTip');

var orphans = [];

var managers = {};

var selectedId = null;

for (var i = 0; i < users.length; i++) {

var node = users[i];

var row = dataNodeToRow(node, node.id == currentUserId ? "me" : null);

if (node.id == currentUserId)

selectedId = row[0].v;

var manager = row[1];

if (manager != null || managers[node.id]!=null) {

managers[manager] = 1;

dataTable.addRows([row]);

}

else {

orphans.push(row);

}

}

for (var i = 0; i < orphans.length; i++) {

var orphan = orphans[i];

var orphanId = orphan[0].v;

if (managers[orphanId])

dataTable.addRows([orphan]);

}

var chart = new google.visualization.OrgChart(document.getElementById('chart_div'));

var options = {

allowCollapse: false,

'allowHtml': true,

'nodeClass': 'node',

'selectedNodeClass': 'selected',

size: "medium"

}

chart.draw(dataTable, options);

//if (allowEdit)

{

$(".node").addClass("draggable");

//Setup drag and drop

$(".node").draggable({ opacity: 0.7, helper: "clone", revert: "invalid", scroll: true });

$(".node").droppable({

hoverClass: "dropHover",

drop: function (event, ui) {

var mngrId = $("div[data-id]", this).attr("data-id");

var subordinateId = $("div[data-id]", ui.draggable[0]).attr("data-id");

API.Utils.beginUpdate();

API.Objects.update(subordinateId, { DirectManager: mngrId }, function () {

API.Utils.endUpdate();

refreshChart(true);

});

}

});

}

API.Utils.endLoading();

if (selectedId)

{

var container = $(window);

var content = $("[data-id='"+selectedId+"']").parent();

$("body").animate(

{

scrollLeft:content.offset().left - window.document.documentElement.clientWidth/2.5,

scrollTop:content.offset().top - window.document.documentElement.clientHeight/2.5

}, 1300);

}

}

function dataNodeToRow(node, cls) {

var jt = (node.JobTitle != null ? node.JobTitle.Name : '');

var nameClass = "";

cls = (cls == null) ? "" : 'class="' + cls + '"';

if (node.State && (node.State.id == '/State/Deleted' || node.State.id == '/State/Disabled'))

{

nameClass = "class='strike'";

}

var mngrId = (node.DirectManager == null) ? null : node.DirectManager.id;

if (nameClass == "class='strike'" && (node.DirectManager && node.DirectManager.State && (node.DirectManager.State.id == '/State/Deleted' || node.DirectManager.State.id == '/State/Disabled')))

{

mngrId = null;

}

return [{ v: node.id, f: '<div data-id="' + node.id + '" ' + cls + '><img src="' + node.ImageUrl + '" height="32"/><div ' + nameClass + '><a href="' + API.Utils.getObjectUrl(node.id) + '">' + node.Name + '</a><div class="jobtitle">' + jt + '</div></div></div>' }, mngrId, node.Email];

 

I also packaged this as an app: 

https://app2.clarizen.com/Clarizen/View/Default.aspx?id=efe52cb4-9bd0-4b76-aefb-708db3fa7299&type=Published+Application&ver=v6

 

Please let me know if that worked.

 

Good luck!

Tamir

Tamir Avital 0 votes
Comment actions Permalink