diff --git a/web/app/controllers/Application.java b/web/app/controllers/Application.java index 4a6eadda6f..cfd8b54529 100644 --- a/web/app/controllers/Application.java +++ b/web/app/controllers/Application.java @@ -25,6 +25,7 @@ import views.html.index; import views.html.login; import views.html.lineage; import views.html.schemaHistory; +import views.html.idpc; import static play.data.Form.form; import org.apache.commons.lang3.StringUtils; import security.AuthenticationManager; @@ -107,6 +108,17 @@ public class Application extends Controller return ok(schemaHistory.render(username)); } + @Security.Authenticated(Secured.class) + public static Result idpc() + { + String username = session("user"); + if (username == null) + { + username = ""; + } + return ok(idpc.render(username)); + } + public static Result login() { //You cann generate the Csrf token such as String csrfToken = SecurityPlugin.getInstance().getCsrfToken(); diff --git a/web/app/controllers/api/v1/Jira.java b/web/app/controllers/api/v1/Jira.java new file mode 100644 index 0000000000..686031645a --- /dev/null +++ b/web/app/controllers/api/v1/Jira.java @@ -0,0 +1,79 @@ +/** + * Copyright 2015 LinkedIn Corp. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + */ +package controllers.api.v1; + +import com.fasterxml.jackson.databind.node.ObjectNode; +import dao.JiraDAO; +import dao.UserDAO; +import models.JiraTicket; +import org.apache.commons.lang3.StringUtils; +import play.libs.Json; +import play.mvc.Controller; +import play.mvc.Result; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class Jira extends Controller +{ + public static String HEADLESS_COMPONENT = "Auto Purge Program - Headless"; + + public static Result getLdapInfo() + { + ObjectNode result = Json.newObject(); + + result.put("status", "ok"); + result.set("ldapinfo", Json.toJson(JiraDAO.getLdapInfo())); + return ok(result); + } + + public static Result getFirstLevelLdapInfo(String managerId) + { + ObjectNode result = Json.newObject(); + + result.put("status", "ok"); + result.set("currentUser", Json.toJson(JiraDAO.getCurrentUserLdapInfo(managerId))); + result.set("members", Json.toJson(JiraDAO.getFirstLevelLdapInfo(managerId))); + return ok(result); + } + + public static Result getJiraTickets(String managerId) + { + ObjectNode result = Json.newObject(); + + List headlessTickets = new ArrayList(); + List userTickets = new ArrayList(); + List tickets = JiraDAO.getUserTicketsByManagerId(managerId); + if ( tickets != null && tickets.size() > 0) + { + for( JiraTicket ticket : tickets) + { + if (ticket.ticketComponent.equalsIgnoreCase(HEADLESS_COMPONENT)) + { + headlessTickets.add(ticket); + } + else + { + userTickets.add(ticket); + } + } + } + result.put("status", "ok"); + result.set("headlessTickets", Json.toJson(headlessTickets)); + result.set("userTickets", Json.toJson(userTickets)); + return ok(result); + } + +} diff --git a/web/app/dao/AbstractMySQLDAO.java b/web/app/dao/AbstractMySQLDAO.java new file mode 100644 index 0000000000..4653435e7c --- /dev/null +++ b/web/app/dao/AbstractMySQLDAO.java @@ -0,0 +1,34 @@ +/** + * Copyright 2015 LinkedIn Corp. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + */ +package dao; + +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate; + +public class AbstractMySQLDAO +{ + private static JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSource.getDataSource("wherehows_mysql")); + private static NamedParameterJdbcTemplate nPJdbcTemplate = + new NamedParameterJdbcTemplate(DataSource.getDataSource("wherehows_mysql")); + + protected static JdbcTemplate getJdbcTemplate() + { + return jdbcTemplate; + } + + protected static NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() + { + return nPJdbcTemplate; + } +} diff --git a/web/app/dao/JiraDAO.java b/web/app/dao/JiraDAO.java new file mode 100644 index 0000000000..cb0e763df2 --- /dev/null +++ b/web/app/dao/JiraDAO.java @@ -0,0 +1,64 @@ +/** + * Copyright 2015 LinkedIn Corp. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + */ +package dao; + +import java.util.*; + +import models.*; + +public class JiraDAO extends AbstractMySQLOpenSourceDAO +{ + private final static String GET_LDAP_INFO = "SELECT full_name, display_name, email, " + + "department_id, department_name, manager_user_id, org_hierarchy, user_id " + + "FROM dir_external_user_info"; + + private final static String GET_CURRENT_USER_INFO = "SELECT full_name, display_name, email, " + + "department_id, department_name, manager_user_id, org_hierarchy, user_id " + + "FROM dir_external_user_info WHERE user_id = ?"; + + private final static String GET_FIRST_LEVEL_LDAP_INFO = "SELECT full_name, display_name, email, " + + "department_id, department_name, manager_user_id, org_hierarchy, user_id " + + "FROM dir_external_user_info WHERE manager_user_id = ?"; + + private final static String GET_TICKETS_BY_MANAGER_ID = "SELECT u.user_id, u.full_name, " + + "u.display_name, u.title, u.manager_user_id, u.email, u.org_hierarchy, l.hdfs_name, l.directory_path, " + + "l.total_size_mb, l.num_of_files, l.jira_key, l.jira_status, l.jira_component " + + "FROM dir_external_user_info u JOIN log_jira__hdfs_directory_to_owner_map l " + + "on u.user_id = l.current_assignee_id WHERE u.org_hierarchy like ?"; + + public static List getLdapInfo() + { + return getJdbcTemplate().query(GET_LDAP_INFO, new LdapInfoRowMapper()); + } + + public static List getCurrentUserLdapInfo(String userId) + { + return getJdbcTemplate().query(GET_CURRENT_USER_INFO, new LdapInfoRowMapper(), userId); + } + + public static List getFirstLevelLdapInfo(String managerId) + { + return getJdbcTemplate().query(GET_FIRST_LEVEL_LDAP_INFO, new LdapInfoRowMapper(), managerId); + } + + public static List getFirstLevelLdapInfo() + { + return getJdbcTemplate().query(GET_LDAP_INFO, new LdapInfoRowMapper()); + } + + public static List getUserTicketsByManagerId(String managerId) + { + return getJdbcTemplate().query(GET_TICKETS_BY_MANAGER_ID, new JiraTicketRowMapper(), "/%" + managerId + "%"); + } +} diff --git a/web/app/dao/JiraTicketRowMapper.java b/web/app/dao/JiraTicketRowMapper.java new file mode 100644 index 0000000000..c04d4e5d5e --- /dev/null +++ b/web/app/dao/JiraTicketRowMapper.java @@ -0,0 +1,78 @@ +/** + * Copyright 2015 LinkedIn Corp. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + */ +package dao; + +import controllers.api.v1.Jira; +import models.DatasetComment; +import models.JiraTicket; +import models.LdapInfo; +import org.apache.commons.lang3.StringUtils; +import org.springframework.jdbc.core.RowMapper; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class JiraTicketRowMapper implements RowMapper +{ + public static String USER_ID_COLUMN = "user_id"; + public static String FULL_NAME_COLUMN = "full_name"; + public static String DISPLAY_NAME_COLUMN = "display_name"; + public static String EMAIL_COLUMN = "email"; + public static String ORG_HIERARCHY_COLUMN = "org_hierarchy"; + public static String TITLE_COLUMN = "title"; + public static String MANAGER_USER_ID_COLUMN = "manager_user_id"; + public static String HDFS_NAME_COLUMN = "hdfs_name"; + public static String DIRECTORY_PATH_COLUMN = "directory_path"; + public static String TOTAL_SIZE_COLUMN = "total_size_mb"; + public static String NUM_OF_FILES_COLUMN = "num_of_files"; + public static String JIRA_KEY_COLUMN = "jira_key"; + public static String JIRA_STATUS_COLUMN = "jira_status"; + public static String JIRA_COMPONENT_COLUMN = "jira_component"; + + @Override + public JiraTicket mapRow(ResultSet rs, int rowNum) throws SQLException { + + String userId = rs.getString(USER_ID_COLUMN); + String fullName = rs.getString(FULL_NAME_COLUMN); + String displayName = rs.getString(DISPLAY_NAME_COLUMN); + String title = rs.getString(TITLE_COLUMN); + String managerId = rs.getString(MANAGER_USER_ID_COLUMN); + String email = rs.getString(EMAIL_COLUMN); + String orgHierarchy = rs.getString(ORG_HIERARCHY_COLUMN); + String hdfsName = rs.getString(HDFS_NAME_COLUMN); + String directoryPath = rs.getString(DIRECTORY_PATH_COLUMN); + Long totalSize = rs.getLong(TOTAL_SIZE_COLUMN); + Long numOfFiles = rs.getLong(NUM_OF_FILES_COLUMN); + String jiraKey = rs.getString(JIRA_KEY_COLUMN); + String jiraStatus = rs.getString(JIRA_STATUS_COLUMN); + String jiraComponent = rs.getString(JIRA_COMPONENT_COLUMN); + JiraTicket ticket = new JiraTicket(); + ticket.currentAssignee = userId; + ticket.assigneeDisplayName = displayName; + ticket.assigneeFullName = fullName; + ticket.assigneeTitle = title; + ticket.assigneeEmail = email; + ticket.currentAssigneeOrgHierarchy = orgHierarchy; + ticket.assigneeManagerId = managerId; + ticket.ticketHdfsName = hdfsName; + ticket.ticketDirectoryPath = directoryPath; + ticket.ticketTotalSize = totalSize; + ticket.ticketNumOfFiles = numOfFiles; + ticket.ticketKey = jiraKey; + ticket.ticketStatus = jiraStatus; + ticket.ticketComponent = jiraComponent; + + return ticket; + } +} diff --git a/web/app/dao/LdapInfoRowMapper.java b/web/app/dao/LdapInfoRowMapper.java new file mode 100644 index 0000000000..2be6b62eb6 --- /dev/null +++ b/web/app/dao/LdapInfoRowMapper.java @@ -0,0 +1,61 @@ +/** + * Copyright 2015 LinkedIn Corp. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + */ +package dao; + +import models.DatasetComment; +import models.LdapInfo; +import org.apache.commons.lang3.StringUtils; +import org.springframework.jdbc.core.RowMapper; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class LdapInfoRowMapper implements RowMapper +{ + public static String USER_ID_COLUMN = "user_id"; + public static String FULL_NAME_COLUMN = "full_name"; + public static String DISPLAY_NAME_COLUMN = "display_name"; + public static String EMAIL_COLUMN = "email"; + public static String DEPARTMENT_ID_COLUMN = "department_id"; + public static String DEPARTMENT_NAME_COLUMN = "department_name"; + public static String MANAGER_USER_ID_COLUMN = "manager_user_id"; + public static String ORG_HIERARCHY_COLUMN = "org_hierarchy"; + public static String ICON_URL_PREFIX = "https://cinco.corp.linkedin.com/api/profile/"; + public static String ICON_URL_SUBFIX = "/picture?access_token=2rzmbzEMGlHsszQktFY-B1TxUic"; + + @Override + public LdapInfo mapRow(ResultSet rs, int rowNum) throws SQLException { + + String userId = rs.getString(USER_ID_COLUMN); + String fullName = rs.getString(FULL_NAME_COLUMN); + String displayName = rs.getString(DISPLAY_NAME_COLUMN); + String email = rs.getString(EMAIL_COLUMN); + Integer departmentId = rs.getInt(DEPARTMENT_ID_COLUMN); + String departmentName = rs.getString(DEPARTMENT_NAME_COLUMN); + String managerUserId = rs.getString(MANAGER_USER_ID_COLUMN); + String orgHierarchy = rs.getString(ORG_HIERARCHY_COLUMN); + LdapInfo ldapInfo = new LdapInfo(); + ldapInfo.userName = userId; + ldapInfo.displayName = displayName; + ldapInfo.fullName = fullName; + ldapInfo.email = email; + ldapInfo.departmentId = departmentId; + ldapInfo.departmentName = departmentName; + ldapInfo.managerUserId = managerUserId; + ldapInfo.orgHierarchy = orgHierarchy; + ldapInfo.iconUrl = ICON_URL_PREFIX + userId + ICON_URL_SUBFIX; + + return ldapInfo; + } +} diff --git a/web/app/dao/MySQLDataSource.java b/web/app/dao/MySQLDataSource.java index 09f82fcade..b964c813c2 100644 --- a/web/app/dao/MySQLDataSource.java +++ b/web/app/dao/MySQLDataSource.java @@ -23,6 +23,10 @@ public class MySQLDataSource extends DataSource public static String DATABASE_WHEREHOWS_OPENSOURCE_USER_NAME_KEY = "database.opensource.username"; public static String DATABASE_WHEREHOWS_OPENSOURCE_USER_PASSWORD_KEY = "database.opensource.password"; public static String DATABASE_WHEREHOWS_OPENSOURCE_URL_KEY = "database.opensource.url"; + public static String DATABASE_WHEREHOWS_DB = "wherehows_mysql"; + public static String DATABASE_WHEREHOWS_DB_USER_NAME_KEY = "database.wherehows.username"; + public static String DATABASE_WHEREHOWS_DB_USER_PASSWORD_KEY = "database.wherehows.password"; + public static String DATABASE_WHEREHOWS_DB_URL_KEY = "database.wherehows.url"; @Override public String getType() @@ -39,6 +43,13 @@ public class MySQLDataSource extends DataSource setPassword(Play.application().configuration().getString(DATABASE_WHEREHOWS_OPENSOURCE_USER_PASSWORD_KEY)); setJdbcUrl(Play.application().configuration().getString(DATABASE_WHEREHOWS_OPENSOURCE_URL_KEY)); } + else if (StringUtils.isNotBlank(identifier) && identifier.equalsIgnoreCase(DATABASE_WHEREHOWS_DB)) + { + setUsername(Play.application().configuration().getString(DATABASE_WHEREHOWS_DB_USER_NAME_KEY)); + setPassword(Play.application().configuration().getString(DATABASE_WHEREHOWS_DB_USER_PASSWORD_KEY)); + setJdbcUrl(Play.application().configuration().getString(DATABASE_WHEREHOWS_DB_URL_KEY)); + } + setIdleConnectionTestPeriodInMinutes(1); setIdleMaxAgeInMinutes(1); setMaxConnectionsPerPartition(10); diff --git a/web/app/models/IdpcInfo.java b/web/app/models/IdpcInfo.java new file mode 100644 index 0000000000..264d75c0d1 --- /dev/null +++ b/web/app/models/IdpcInfo.java @@ -0,0 +1,27 @@ +/** + * Copyright 2015 LinkedIn Corp. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + */ +package models; + +public class IdpcInfo { + + public String userName; + public String fullName; + public String displayName; + public int departmentId; + public String departmentName; + public String email; + public String managerUserId; + public String orgHierarchy; + public String iconUrl; +} diff --git a/web/app/models/JiraTicket.java b/web/app/models/JiraTicket.java new file mode 100644 index 0000000000..9f16291b9c --- /dev/null +++ b/web/app/models/JiraTicket.java @@ -0,0 +1,32 @@ +/** + * Copyright 2015 LinkedIn Corp. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + */ +package models; + +public class JiraTicket { + + public String currentAssignee; + public String currentAssigneeOrgHierarchy; + public String assigneeDisplayName; + public String assigneeFullName; + public String assigneeTitle; + public String assigneeManagerId; + public String assigneeEmail; + public String ticketHdfsName; + public String ticketDirectoryPath; + public Long ticketTotalSize; + public Long ticketNumOfFiles; + public String ticketKey; + public String ticketStatus; + public String ticketComponent; +} diff --git a/web/app/models/LdapInfo.java b/web/app/models/LdapInfo.java new file mode 100644 index 0000000000..11bf339cd0 --- /dev/null +++ b/web/app/models/LdapInfo.java @@ -0,0 +1,27 @@ +/** + * Copyright 2015 LinkedIn Corp. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + */ +package models; + +public class LdapInfo { + + public String userName; + public String fullName; + public String displayName; + public int departmentId; + public String departmentName; + public String email; + public String managerUserId; + public String orgHierarchy; + public String iconUrl; +} diff --git a/web/app/views/idpc.scala.html b/web/app/views/idpc.scala.html new file mode 100644 index 0000000000..5c98af501f --- /dev/null +++ b/web/app/views/idpc.scala.html @@ -0,0 +1,387 @@ +@(user: String) + @main(user, "") { +
+ +
+ + + + + } diff --git a/web/app/views/main.scala.html b/web/app/views/main.scala.html index b726e2209b..6032ed794e 100644 --- a/web/app/views/main.scala.html +++ b/web/app/views/main.scala.html @@ -89,6 +89,13 @@ +
  • + + + IDPC + + +
  • diff --git a/web/conf/routes b/web/conf/routes index e5a4b1ed73..45639ebe58 100644 --- a/web/conf/routes +++ b/web/conf/routes @@ -35,6 +35,8 @@ GET /schemaHistory controllers.Application.sche GET /api/v1/owner/types controllers.api.v1.Dataset.getDatasetOwnerTypes() +GET /idpc controllers.Application.idpc() + GET /api/v1/party/entities controllers.api.v1.User.getAllUserEntities() GET /api/v1/party/employees controllers.api.v1.User.getAllCompanyUsers() @@ -185,8 +187,14 @@ GET /api/v1/lineage/flow/:application/:project/:flowId controllers.api.v1. GET /api/v1/schemaHistory/datasets controllers.api.v1.SchemaHistory.getPagedDatasets() +GET /api/v1/jira/ldapinfo controllers.api.v1.Jira.getLdapInfo() + +GET /api/v1/jira/members/:managerId controllers.api.v1.Jira.getFirstLevelLdapInfo(managerId :String) + GET /api/v1/schemaHistory/historyData/:id controllers.api.v1.SchemaHistory.getSchemaHistory(id: Int) +GET /api/v1/jira/tickets/:managerId controllers.api.v1.Jira.getJiraTickets(managerId :String) + POST /api/v1/tracking controllers.api.v1.Tracking.addTrackingEvent() # Map static resources from the /public folder to the /assets URL path diff --git a/web/public/javascripts/idpc.js b/web/public/javascripts/idpc.js new file mode 100644 index 0000000000..4d1d6da609 --- /dev/null +++ b/web/public/javascripts/idpc.js @@ -0,0 +1,211 @@ +(function ($) { + $(document).ready(function() { + + App = Ember.Application.create({rootElement: "#content"}); + + App.Router.map(function() { + this.resource('jira', function(){ + this.resource('user', {path: '/:user'}); + }); + }); + + App.IndexRoute = Ember.Route.extend({ + redirect: function() { + this.transitionTo('user', "jweiner"); + } + }); + + var genBreadcrumbs = function(urn) { + var breadcrumbs = [] + var b = urn.split('/') + b.shift() + for(var i = 0; i < b.length; i++) { + if(i === 0) + { + breadcrumbs.push({title: b[i], urn: b[i]}) + } + else + { + var urn = genUrn(b.slice(0, (i+1))) + breadcrumbs.push({title: b[i], urn: urn}) + } + } + return breadcrumbs + } + + var setActiveTab = function(){ + $('#jiratabs a:first').tab("show"); + } + + var getMemberHeadlessTickets = function(members, tickets) + { + if (!members) + { + return members; + } + var memberTotal = 0; + var memberOpened = 0; + var memberRollupTotal = 0; + var memberRollupOpened = 0; + + for(var i = 0; i < members.length; i++) + { + memberTotal = 0; + memberOpened = 0; + if (tickets) + { + for(var j = 0; j < tickets.length; j++) + { + if (tickets[j].currentAssigneeOrgHierarchy && + (tickets[j].currentAssigneeOrgHierarchy.indexOf(members[i].userName) != -1)) + { + memberTotal += 1; + if (tickets[j].ticketStatus.toLowerCase() === 'open') + { + memberOpened += 1; + } + } + } + } + + members[i].totalHeadlessTickets = memberTotal; + members[i].openedHeadlessTickets = memberOpened; + members[i].closedHeadlessTickets = memberTotal - memberOpened; + if (members[i].totalHeadlessTickets > 0) + { + members[i].headlessTicketsCompletion = + Math.round( ( (memberTotal - memberOpened) / memberTotal ) * 100 ); + } + else + { + members[i].headlessTicketsCompletion = 100; + } + members[i].url = "/idpc#/jira/" + members[i].userName; + memberRollupOpened += memberOpened; + memberRollupTotal += memberTotal; + } + if (jiraController) + { + var currentUser = jiraController.get('selectedUser'); + var totalHeadlessTickets = memberRollupTotal; + var openedHeadlessTickets = memberRollupOpened; + var headlessTicketsCompletion; + var closedHeadlessTickets = + totalHeadlessTickets - openedHeadlessTickets; + if (totalHeadlessTickets > 0) + { + headlessTicketsCompletion = + Math.round( ( ( + totalHeadlessTickets - openedHeadlessTickets) / totalHeadlessTickets ) * 100 ); + } + else + { + headlessTicketsCompletion = 100; + } + Ember.set(currentUser, 'totalHeadlessTickets', totalHeadlessTickets); + Ember.set(currentUser, 'openedHeadlessTickets', openedHeadlessTickets); + Ember.set(currentUser, 'closedHeadlessTickets', closedHeadlessTickets); + Ember.set(currentUser, 'headlessTicketsCompletion', headlessTicketsCompletion); + } + return members; + } + var jiraController = null; + var hierarchy = '/jweiner'; + var breadcrumbs; + var sortOptions = ['Assignee First', 'Jira Status First', 'Directory Path First']; + var selectedUser = { + 'userId': 'jweiner', + 'displayName': 'jweiner', + 'headlessTicketsCompletion': 0, + 'totalHeadlessTickets': 0, + 'openedHeadlessTickets': 0, + 'closedHeadlessTickets': 0, + 'userCompletion': 0, + 'userTotalTickets': 0, + 'userOpenTickets': 0, + 'userClosedTickets': 0}; + setTimeout(setActiveTab, 500); + + App.JiraRoute = Ember.Route.extend({ + setupController: function(controller) { + jiraController = controller; + breadcrumbs = genBreadcrumbs(hierarchy); + jiraController.set('breadcrumbs', breadcrumbs); + jiraController.set('selectedUser', selectedUser); + jiraController.set('sortOptions', sortOptions); + } + }); + + App.UserRoute = Ember.Route.extend({ + setupController: function(controller, params) { + if (params && params.user) + { + jiraController.set('ticketsInProgress', true); + var ticketsUrl = 'api/v1/jira/tickets/' + params.user; + var headlessTickets; + var userTickets; + $.get(ticketsUrl, function(data) { + jiraController.set('ticketsInProgress', false); + if (data && data.status == "ok") { + jiraController.set('headlessTickets', data.headlessTickets); + if (data.headlessTickets && data.headlessTickets.length > 0) + { + jiraController.set('headlessNoTickets', false); + headlessTickets = data.headlessTickets; + jiraController.set('headlessTickets', data.headlessTickets); + } + else + { + jiraController.set('headlessNoTickets', true); + } + jiraController.set('usersTickets', data.userTickets); + if (data.userTickets && data.userTickets.length > 0) + { + jiraController.set('userNoTickets', false); + userTickets = data.userTickets; + jiraController.set('userTickets', data.userTickets); + } + else + { + jiraController.set('userNoTickets', true); + } + jiraController.set('membersInProgress', true); + var membersUrl = 'api/v1/jira/members/' + params.user; + $.get(membersUrl, function(data) { + jiraController.set('membersInProgress', false); + if (data && data.status == "ok") { + var currentUser = jiraController.get('selectedUser'); + Ember.set(currentUser, 'displayName', data.currentUser[0].displayName); + + if (data.members && data.members.length > 0) + { + jiraController.set('userNoMembers', false); + var members = getMemberHeadlessTickets(data.members, headlessTickets); + jiraController.set('members', members); + } + else + { + jiraController.set('userNoMembers', true); + } + } + }); + } + }); + } + } + }); + + App.JiraController = Ember.Controller.extend({ + actions: { + onSelect: function(dataset, data) { + highlightRow(dataset, data, false); + if (dataset && (dataset.id != 0)) + { + updateTimeLine(dataset.id, false); + } + } + } + }); + }); + +})(jQuery)