Adding admin roles page
parent
0369a35228
commit
62f31aeab3
|
@ -97,6 +97,9 @@ configure = ($routeProvider, $locationProvider, $httpProvider, $provide) ->
|
||||||
$routeProvider.when("/project/:pslug/admin/memberships",
|
$routeProvider.when("/project/:pslug/admin/memberships",
|
||||||
{templateUrl: "/partials/admin-memberships.html"})
|
{templateUrl: "/partials/admin-memberships.html"})
|
||||||
|
|
||||||
|
$routeProvider.when("/project/:pslug/admin/roles",
|
||||||
|
{templateUrl: "/partials/admin-roles.html"})
|
||||||
|
|
||||||
# User settings
|
# User settings
|
||||||
$routeProvider.when("/project/:pslug/user-settings/user-profile",
|
$routeProvider.when("/project/:pslug/user-settings/user-profile",
|
||||||
{templateUrl: "/partials/user-profile.html"})
|
{templateUrl: "/partials/user-profile.html"})
|
||||||
|
|
|
@ -0,0 +1,329 @@
|
||||||
|
###
|
||||||
|
# Copyright (C) 2014 Andrey Antukh <niwi@niwi.be>
|
||||||
|
# Copyright (C) 2014 Jesús Espino Garcia <jespinog@gmail.com>
|
||||||
|
# Copyright (C) 2014 David Barragán Merino <bameda@dbarragan.com>
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as
|
||||||
|
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# File: modules/admin/memberships.coffee
|
||||||
|
###
|
||||||
|
|
||||||
|
taiga = @.taiga
|
||||||
|
|
||||||
|
mixOf = @.taiga.mixOf
|
||||||
|
bindOnce = @.taiga.bindOnce
|
||||||
|
|
||||||
|
module = angular.module("taigaAdmin")
|
||||||
|
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
## Project Roles Controller
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
class RolesController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.FiltersMixin)
|
||||||
|
@.$inject = [
|
||||||
|
"$scope",
|
||||||
|
"$rootScope",
|
||||||
|
"$tgRepo",
|
||||||
|
"$tgConfirm",
|
||||||
|
"$tgResources",
|
||||||
|
"$routeParams",
|
||||||
|
"$q",
|
||||||
|
"$tgLocation"
|
||||||
|
]
|
||||||
|
|
||||||
|
constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location) ->
|
||||||
|
_.bindAll(@)
|
||||||
|
|
||||||
|
@scope.sectionName = "Roles" #i18n
|
||||||
|
@scope.project = {}
|
||||||
|
|
||||||
|
promise = @.loadInitialData()
|
||||||
|
promise.then null, ->
|
||||||
|
console.log "FAIL" #TODO
|
||||||
|
|
||||||
|
loadProject: ->
|
||||||
|
return @rs.projects.get(@scope.projectId).then (project) =>
|
||||||
|
@scope.project = project
|
||||||
|
return project
|
||||||
|
|
||||||
|
loadRoles: ->
|
||||||
|
return @rs.roles.list(@scope.projectId).then (data) =>
|
||||||
|
@scope.roles = data
|
||||||
|
@scope.role = @scope.roles[0]
|
||||||
|
return data
|
||||||
|
|
||||||
|
loadInitialData: ->
|
||||||
|
promise = @repo.resolve({pslug: @params.pslug}).then (data) =>
|
||||||
|
@scope.projectId = data.project
|
||||||
|
return data
|
||||||
|
|
||||||
|
return promise.then(=> @.loadProject())
|
||||||
|
.then(=> @.loadUsersAndRoles())
|
||||||
|
.then(=> @.loadRoles())
|
||||||
|
|
||||||
|
setRole: (role) ->
|
||||||
|
@scope.role = role
|
||||||
|
@scope.$broadcast("role:changed", @scope.role)
|
||||||
|
|
||||||
|
delete: ->
|
||||||
|
# TODO: i18n
|
||||||
|
title = "Delete Role"
|
||||||
|
subtitle = @scope.role.name
|
||||||
|
|
||||||
|
@confirm.ask(title, subtitle).then =>
|
||||||
|
promise = @repo.remove(@scope.role)
|
||||||
|
promise.then =>
|
||||||
|
@confirm.notify('success')
|
||||||
|
@.loadRoles()
|
||||||
|
promise.then null, =>
|
||||||
|
@confirm.notify('error')
|
||||||
|
|
||||||
|
setComputable: ->
|
||||||
|
onSuccess = (role) =>
|
||||||
|
@confirm.notify('success')
|
||||||
|
|
||||||
|
onError = =>
|
||||||
|
@confirm.notify("error")
|
||||||
|
@scope.role.computable = !@scope.role.computable
|
||||||
|
|
||||||
|
@repo.save(@scope.role).then onSuccess, onError
|
||||||
|
|
||||||
|
|
||||||
|
module.controller("RolesController", RolesController)
|
||||||
|
|
||||||
|
|
||||||
|
RolesDirective = ->
|
||||||
|
link = ($scope, $el, $attrs) ->
|
||||||
|
$ctrl = $el.controller()
|
||||||
|
|
||||||
|
$scope.$on "$destroy", ->
|
||||||
|
$el.off()
|
||||||
|
|
||||||
|
return {link:link}
|
||||||
|
|
||||||
|
module.directive("tgRoles", RolesDirective)
|
||||||
|
|
||||||
|
NewRoleDirective = ($tgrepo) ->
|
||||||
|
DEFAULT_PERMISSIONS = ["view_project", "view_milestones", "view_us", "view_tasks", "view_issues"]
|
||||||
|
|
||||||
|
link = ($scope, $el, $attrs) ->
|
||||||
|
$ctrl = $el.controller()
|
||||||
|
|
||||||
|
$scope.$on "$destroy", ->
|
||||||
|
$el.off()
|
||||||
|
|
||||||
|
$el.on "click", "a.add-button", (event) ->
|
||||||
|
event.preventDefault()
|
||||||
|
$el.find(".new").removeClass("hidden")
|
||||||
|
$el.find(".new").focus()
|
||||||
|
$el.find(".add-button").hide()
|
||||||
|
|
||||||
|
$el.on "keyup", ".new", (event) ->
|
||||||
|
event.preventDefault()
|
||||||
|
if event.keyCode == 13 # Enter key
|
||||||
|
target = angular.element(event.currentTarget)
|
||||||
|
newRole = {
|
||||||
|
project: $scope.projectId
|
||||||
|
name: target.val()
|
||||||
|
permissions: DEFAULT_PERMISSIONS
|
||||||
|
order: _.max($scope.roles, (r) -> r.order).order + 1
|
||||||
|
computable: false
|
||||||
|
}
|
||||||
|
|
||||||
|
$el.find(".new").addClass("hidden")
|
||||||
|
$el.find(".new").val('')
|
||||||
|
|
||||||
|
$tgrepo.create("roles", newRole).then (role) ->
|
||||||
|
$scope.roles.push(role)
|
||||||
|
$ctrl.setRole(role)
|
||||||
|
$el.find(".add-button").show()
|
||||||
|
|
||||||
|
else if event.keyCode == 27 # ESC key
|
||||||
|
target = angular.element(event.currentTarget)
|
||||||
|
$el.find(".new").addClass("hidden")
|
||||||
|
$el.find(".new").val('')
|
||||||
|
$el.find(".add-button").show()
|
||||||
|
|
||||||
|
return {link:link}
|
||||||
|
|
||||||
|
module.directive("tgNewRole", ["$tgRepo", NewRoleDirective])
|
||||||
|
|
||||||
|
|
||||||
|
# Use category-config.scss styles
|
||||||
|
RolePermissionsDirective = ($repo, $confirm) ->
|
||||||
|
resumeTemplate = _.template("""
|
||||||
|
<div class="resume-title"><%- category.name %></div>
|
||||||
|
<div class="count"><%- category.activePermissions %>/<%- category.permissions.length %></div>
|
||||||
|
<div class="summary-role">
|
||||||
|
<% _.each(category.permissions, function(permission) { %>
|
||||||
|
<div class="role-summary-single <% if(permission.active) { %>active<% } %>" title="<%- permission.description %>"></div>
|
||||||
|
<% }) %>
|
||||||
|
</div>
|
||||||
|
<div class="icon icon-arrow-bottom"></div>
|
||||||
|
""")
|
||||||
|
|
||||||
|
categoryTemplate = _.template("""
|
||||||
|
<div class="category-config" data-id="<%- index %>">
|
||||||
|
<div class="resume">
|
||||||
|
</div>
|
||||||
|
<div class="category-items">
|
||||||
|
<div class="items-container">
|
||||||
|
<% _.each(category.permissions, function(permission) { %>
|
||||||
|
<div class="category-item" data-id="<%- permission.key %>"> <%- permission.description %>
|
||||||
|
<div class="check">
|
||||||
|
<input type="checkbox" <% if(permission.active) { %>checked="checked"<% } %>/>
|
||||||
|
<div></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% }) %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
""")
|
||||||
|
|
||||||
|
baseTemplate = _.template("""
|
||||||
|
<div class="category-config-list">
|
||||||
|
</div>
|
||||||
|
""")
|
||||||
|
|
||||||
|
link = ($scope, $el, $attrs) ->
|
||||||
|
$ctrl = $el.controller()
|
||||||
|
|
||||||
|
generateCategoriesFromRole = (role) ->
|
||||||
|
setActivePermissions = (permissions) ->
|
||||||
|
return _.map(permissions, (x) -> _.extend({}, x, {active: x["key"] in role.permissions}))
|
||||||
|
|
||||||
|
setActivePermissionsPerCategory = (category) ->
|
||||||
|
return _.map(category, (x) ->
|
||||||
|
_.extend({}, x, {
|
||||||
|
activePermissions: _.filter(x["permissions"], "active").length
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
categories = []
|
||||||
|
|
||||||
|
projectPermissions = [
|
||||||
|
{ key: "view_project", description: "View project" }
|
||||||
|
]
|
||||||
|
categories.push({ name: "Project", permissions: setActivePermissions(projectPermissions) })
|
||||||
|
|
||||||
|
milestonePermissions = [
|
||||||
|
{ key: "view_milestones", description: "View milestones" }
|
||||||
|
{ key: "add_milestone", description: "Add milestone" }
|
||||||
|
{ key: "modify_milestone", description: "Modify milestone" }
|
||||||
|
{ key: "delete_last_milestone", description: "Delete last milestone" }
|
||||||
|
{ key: "delete_milestone", description: "Delete milestone" }
|
||||||
|
{ key: "add_us_to_milestone", description: "Add use to milestone" }
|
||||||
|
{ key: "remove_us_from_milestone", description: "Remove us from milestone" }
|
||||||
|
{ key: "reorder_us_on_milestone", description: "Reorder us on milestone" }
|
||||||
|
]
|
||||||
|
categories.push({ name: "Milestones", permissions: setActivePermissions(milestonePermissions) })
|
||||||
|
|
||||||
|
userStoryPermissions = [
|
||||||
|
{ key: "view_us", description: "View user story" }
|
||||||
|
{ key: "add_us", description: "Add user story" }
|
||||||
|
{ key: "modify_us", description: "Modify user story" }
|
||||||
|
{ key: "delete_us", description: "Delete user story" }
|
||||||
|
]
|
||||||
|
categories.push({ name: "User Stories", permissions: setActivePermissions(userStoryPermissions) })
|
||||||
|
|
||||||
|
taskPermissions = [
|
||||||
|
{ key: "view_tasks", description: "View tasks" }
|
||||||
|
{ key: "add_task", description: "Add task" }
|
||||||
|
{ key: "modify_task", description: "Modify task" }
|
||||||
|
{ key: "delete_task", description: "Delete task" }
|
||||||
|
]
|
||||||
|
categories.push({ name: "Tasks", permissions: setActivePermissions(taskPermissions) })
|
||||||
|
|
||||||
|
issuePermissions = [
|
||||||
|
{ key: "view_issues", description: "View issues" }
|
||||||
|
{ key: "add_issue", description: "Add issue" }
|
||||||
|
{ key: "modify_issue", description: "Modify issue" }
|
||||||
|
{ key: "delete_issue", description: "Delete issue" }
|
||||||
|
{ key: "vote_issues", description: "Vote issues" }
|
||||||
|
]
|
||||||
|
categories.push({ name: "Issues", permissions: setActivePermissions(issuePermissions) })
|
||||||
|
|
||||||
|
wikiPermissions = [
|
||||||
|
{ key: "view_wiki_pages", description: "View wiki pages" }
|
||||||
|
{ key: "add_wiki_page", description: "Add wiki page" }
|
||||||
|
{ key: "modify_wiki_page", description: "Modify wiki page" }
|
||||||
|
{ key: "delete_wiki_page", description: "Delete wiki page" }
|
||||||
|
{ key: "view_wiki_links", description: "View wiki links" }
|
||||||
|
{ key: "add_wiki_link", description: "Add wiki link" }
|
||||||
|
{ key: "modify_wiki_link", description: "Modify wiki link" }
|
||||||
|
{ key: "delete_wiki_link", description: "Delete wiki link" }
|
||||||
|
]
|
||||||
|
categories.push({ name: "Wiki", permissions: setActivePermissions(wikiPermissions) })
|
||||||
|
|
||||||
|
return setActivePermissionsPerCategory(categories)
|
||||||
|
|
||||||
|
renderResume = (element, category) ->
|
||||||
|
element.find(".resume").html(resumeTemplate({category: category}))
|
||||||
|
|
||||||
|
renderCategory = (category, index) ->
|
||||||
|
html = categoryTemplate({category: category, index: index})
|
||||||
|
html = angular.element(html)
|
||||||
|
renderResume(html, category)
|
||||||
|
return html
|
||||||
|
|
||||||
|
renderPermissions = () ->
|
||||||
|
$el.off()
|
||||||
|
html = baseTemplate()
|
||||||
|
_.each generateCategoriesFromRole($scope.role), (category, index) ->
|
||||||
|
html = angular.element(html).append(renderCategory(category, index))
|
||||||
|
|
||||||
|
$el.html(html)
|
||||||
|
$el.on "click", ".resume", (event) ->
|
||||||
|
event.preventDefault()
|
||||||
|
target = angular.element(event.currentTarget)
|
||||||
|
target.next().toggleClass("open")
|
||||||
|
|
||||||
|
$el.on "change", ".category-item input", (event) ->
|
||||||
|
getActivePermissions = ->
|
||||||
|
activePermissions = _.filter($el.find(".category-item input"), (t) -> angular.element(t).is(":checked"))
|
||||||
|
activePermissions = _.sortBy(_.map(activePermissions, (t) ->
|
||||||
|
permission = angular.element(t).parents(".category-item").data("id")
|
||||||
|
))
|
||||||
|
return activePermissions
|
||||||
|
|
||||||
|
target = angular.element(event.currentTarget)
|
||||||
|
$scope.role.permissions = getActivePermissions()
|
||||||
|
|
||||||
|
onSuccess = (role) ->
|
||||||
|
$confirm.notify('success')
|
||||||
|
categories = generateCategoriesFromRole(role)
|
||||||
|
categoryId = target.parents(".category-config").data("id")
|
||||||
|
renderResume(target.parents(".category-config"), categories[categoryId])
|
||||||
|
|
||||||
|
onError = ->
|
||||||
|
$confirm.notify("error")
|
||||||
|
target.prop "checked", !target.prop("checked")
|
||||||
|
$scope.role.permissions = getActivePermissions()
|
||||||
|
|
||||||
|
$repo.save($scope.role).then onSuccess, onError
|
||||||
|
|
||||||
|
|
||||||
|
$scope.$on "$destroy", ->
|
||||||
|
$el.off()
|
||||||
|
|
||||||
|
$scope.$on "role:changed", ->
|
||||||
|
renderPermissions()
|
||||||
|
|
||||||
|
bindOnce($scope, $attrs.ngModel, renderPermissions)
|
||||||
|
|
||||||
|
return {link:link}
|
||||||
|
|
||||||
|
module.directive("tgRolePermissions", ['$tgRepo', '$tgConfirm', RolePermissionsDirective])
|
|
@ -85,6 +85,7 @@ urls = {
|
||||||
"project-admin-project-values-issue-priorities": "/project/:project/admin/project-values/issue-priorities"
|
"project-admin-project-values-issue-priorities": "/project/:project/admin/project-values/issue-priorities"
|
||||||
"project-admin-project-values-issue-severities": "/project/:project/admin/project-values/issue-severities"
|
"project-admin-project-values-issue-severities": "/project/:project/admin/project-values/issue-severities"
|
||||||
"project-admin-memberships": "/project/:project/admin/memberships"
|
"project-admin-memberships": "/project/:project/admin/memberships"
|
||||||
|
"project-admin-roles": "/project/:project/admin/roles"
|
||||||
"project-admin-project-profile-features": "/project/:project/admin/project-profile/features"
|
"project-admin-project-profile-features": "/project/:project/admin/project-profile/features"
|
||||||
"project-admin-project-values-us-status": "/project/:project/admin/project-values/us-status"
|
"project-admin-project-values-us-status": "/project/:project/admin/project-values/us-status"
|
||||||
|
|
||||||
|
|
|
@ -116,6 +116,7 @@ module.run([
|
||||||
"$tgProjectsResourcesProvider",
|
"$tgProjectsResourcesProvider",
|
||||||
"$tgMembershipsResourcesProvider",
|
"$tgMembershipsResourcesProvider",
|
||||||
"$tgInvitationsResourcesProvider",
|
"$tgInvitationsResourcesProvider",
|
||||||
|
"$tgRolesResourcesProvider",
|
||||||
"$tgSprintsResourcesProvider",
|
"$tgSprintsResourcesProvider",
|
||||||
"$tgUserstoriesResourcesProvider",
|
"$tgUserstoriesResourcesProvider",
|
||||||
"$tgTasksResourcesProvider",
|
"$tgTasksResourcesProvider",
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
###
|
||||||
|
# Copyright (C) 2014 Andrey Antukh <niwi@niwi.be>
|
||||||
|
# Copyright (C) 2014 Jesús Espino Garcia <jespinog@gmail.com>
|
||||||
|
# Copyright (C) 2014 David Barragán Merino <bameda@dbarragan.com>
|
||||||
|
#
|
||||||
|
# This program is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Affero General Public License as
|
||||||
|
# published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# File: modules/resources/memberships.coffee
|
||||||
|
###
|
||||||
|
|
||||||
|
|
||||||
|
taiga = @.taiga
|
||||||
|
|
||||||
|
resourceProvider = ($repo, $http, $urls) ->
|
||||||
|
service = {}
|
||||||
|
|
||||||
|
service.get = (id) ->
|
||||||
|
return $repo.queryOne("roles", id)
|
||||||
|
|
||||||
|
service.list = (projectId) ->
|
||||||
|
return $repo.queryMany("roles", {project: projectId})
|
||||||
|
|
||||||
|
return (instance) ->
|
||||||
|
instance.roles = service
|
||||||
|
|
||||||
|
|
||||||
|
module = angular.module("taigaResources")
|
||||||
|
module.factory("$tgRolesResourcesProvider", ["$tgRepo", "$tgHttp", "$tgUrls", resourceProvider])
|
|
@ -1,48 +1,30 @@
|
||||||
extends layout
|
extends dummy-layout
|
||||||
|
|
||||||
block head
|
block head
|
||||||
title Taiga Project management web application with scrum in mind!
|
title Taiga Project management web application with scrum in mind!
|
||||||
|
|
||||||
block content
|
block content
|
||||||
div.wrapper
|
div.wrapper.roles(ng-controller="RolesController as ctrl",
|
||||||
sidebar.menu-secondary.sidebar
|
ng-init="section='admin'", tg-roles)
|
||||||
|
sidebar.menu-secondary.sidebar(tg-admin-navigation="roles")
|
||||||
include views/modules/admin-menu
|
include views/modules/admin-menu
|
||||||
sidebar.menu-tertiary.sidebar
|
sidebar.menu-tertiary.sidebar
|
||||||
include views/modules/admin-submenu
|
include views/modules/admin-submenu-roles
|
||||||
|
|
||||||
section.main.admin-roles
|
section.main.admin-roles
|
||||||
header
|
header
|
||||||
include views/components/mainTitle
|
include views/components/mainTitle
|
||||||
|
|
||||||
|
a.button.button-red.delete-role(href="", title="Delete", ng-click="ctrl.delete()") Delete
|
||||||
|
|
||||||
p.total
|
p.total
|
||||||
| UX
|
| {{ role.name }}
|
||||||
span (6 members with this role)
|
span ({{ role.members_count }} members with this role)
|
||||||
|
|
||||||
include views/modules/category-config
|
div.general-category
|
||||||
|
| Can do estimations?
|
||||||
|
div.check
|
||||||
|
input(type="checkbox", ng-model="role.computable", ng-change="ctrl.setComputable()")
|
||||||
|
div
|
||||||
|
|
||||||
script(type='text/javascript').
|
div(tg-role-permissions, ng-model="role")
|
||||||
function randomIntFromInterval(min,max) {
|
|
||||||
return Math.floor(Math.random()*(max-min+1)+min);
|
|
||||||
}
|
|
||||||
(function() {
|
|
||||||
if(randomIntFromInterval(0, 4) !== 4) return true;
|
|
||||||
|
|
||||||
var inputs = document.querySelectorAll('input');
|
|
||||||
|
|
||||||
function change(input) {
|
|
||||||
var num = randomIntFromInterval(100, 600);
|
|
||||||
|
|
||||||
setTimeout(function() {
|
|
||||||
if(input.hasAttribute('checked')) {
|
|
||||||
input.removeAttribute('checked');
|
|
||||||
} else {
|
|
||||||
input.setAttribute('checked', 'checked');
|
|
||||||
}
|
|
||||||
}, num);
|
|
||||||
}
|
|
||||||
setInterval(function() {
|
|
||||||
for(var i = 0; i < inputs.length; i++) {
|
|
||||||
change(inputs[i]);
|
|
||||||
}
|
|
||||||
}, 500);
|
|
||||||
})()
|
|
||||||
|
|
|
@ -17,6 +17,6 @@ section.admin-menu
|
||||||
span.title Memberships
|
span.title Memberships
|
||||||
span.icon.icon-arrow-right
|
span.icon.icon-arrow-right
|
||||||
li#adminmenu-roles
|
li#adminmenu-roles
|
||||||
a(href="")
|
a(href="" tg-nav="project-admin-roles:project=project.slug")
|
||||||
span.title Roles
|
span.title Roles
|
||||||
span.icon.icon-arrow-right
|
span.icon.icon-arrow-right
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
section.admin-submenu-roles
|
||||||
|
header
|
||||||
|
h1 Roles
|
||||||
|
|
||||||
|
nav
|
||||||
|
ul
|
||||||
|
li(ng-repeat="item in roles")
|
||||||
|
a(href="" ng-click="ctrl.setRole(item)", ng-class="{active: role.id == item.id}") {{ item.name }}
|
||||||
|
span.icon.icon-arrow-right
|
||||||
|
|
||||||
|
div(tg-new-role)
|
||||||
|
a.button.button-gray.add-button(href="", title="Add New Role")
|
||||||
|
span.text + New role
|
||||||
|
input(type="text", class="hidden new")
|
|
@ -1,3 +1,7 @@
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Included in the admin-roles.jade and in the RolePermissionsDirective //
|
||||||
|
// in the modules/admin/roles.coffee file. //
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
div.general-category
|
div.general-category
|
||||||
| Can do estimations?
|
| Can do estimations?
|
||||||
div.check
|
div.check
|
||||||
|
|
|
@ -96,6 +96,7 @@ $prefix-for-spec: true;
|
||||||
//modules admin
|
//modules admin
|
||||||
@import 'modules/admin/admin-menu';
|
@import 'modules/admin/admin-menu';
|
||||||
@import 'modules/admin/admin-submenu';
|
@import 'modules/admin/admin-submenu';
|
||||||
|
@import 'modules/admin/admin-submenu-roles';
|
||||||
@import 'modules/admin/admin-roles';
|
@import 'modules/admin/admin-roles';
|
||||||
@import 'modules/admin/admin-functionalities';
|
@import 'modules/admin/admin-functionalities';
|
||||||
@import 'modules/admin/admin-membership-table';
|
@import 'modules/admin/admin-membership-table';
|
||||||
|
|
|
@ -50,4 +50,9 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.delete-role {
|
||||||
|
position: absolute;
|
||||||
|
right: 2rem;
|
||||||
|
top: 2rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
.admin-submenu-roles {
|
||||||
|
h1 {
|
||||||
|
@extend %xlarge;
|
||||||
|
color: $white;
|
||||||
|
}
|
||||||
|
li {
|
||||||
|
@extend %larger;
|
||||||
|
@extend %title;
|
||||||
|
border-bottom: 1px solid #a6b2a7;
|
||||||
|
text-transform: uppercase;
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color: $white;
|
||||||
|
display: block;
|
||||||
|
padding: 1rem 0 1rem 1rem;
|
||||||
|
&.active,
|
||||||
|
&:hover {
|
||||||
|
color: $blackish;
|
||||||
|
.icon {
|
||||||
|
@include transition (opacity .3s linear);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.icon {
|
||||||
|
color: $white;
|
||||||
|
float: right;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
.button-gray {
|
||||||
|
padding: .5rem 0;
|
||||||
|
text-align: center;
|
||||||
|
&:hover {
|
||||||
|
background-color: darken($button-gray-hover, 15%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -38,9 +38,12 @@
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
.category-items {
|
.category-items {
|
||||||
|
@include slide(400px, overflow-y);
|
||||||
background-color: $whitish;
|
background-color: $whitish;
|
||||||
padding: 2rem 1rem;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
.items-container {
|
||||||
|
padding: 2rem 1rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.category-item {
|
.category-item {
|
||||||
border-bottom: 1px dotted $gray;
|
border-bottom: 1px dotted $gray;
|
||||||
|
|
Loading…
Reference in New Issue