new project menu

stable
Juanfran 2015-05-20 14:36:48 +02:00
parent 931120f88d
commit 78f6164c0b
49 changed files with 720 additions and 137 deletions

View File

@ -81,81 +81,200 @@ configure = ($routeProvider, $locationProvider, $httpProvider, $provide, $tgEven
) )
$routeProvider.when("/project/:pslug/search", $routeProvider.when("/project/:pslug/search",
{templateUrl: "search/search.html", reloadOnSearch: false}) {
templateUrl: "search/search.html",
reloadOnSearch: false,
section: "search"
}
)
$routeProvider.when("/project/:pslug/backlog", $routeProvider.when("/project/:pslug/backlog",
{templateUrl: "backlog/backlog.html", resolve: {loader: tgLoaderProvider.add()}}) {
templateUrl: "backlog/backlog.html",
resolve: {loader: tgLoaderProvider.add()},
section: "backlog"
}
)
$routeProvider.when("/project/:pslug/kanban", $routeProvider.when("/project/:pslug/kanban",
{templateUrl: "kanban/kanban.html", resolve: {loader: tgLoaderProvider.add()}}) {
templateUrl: "kanban/kanban.html",
resolve: {loader: tgLoaderProvider.add()},
section: "kanban"
}
)
# Milestone # Milestone
$routeProvider.when("/project/:pslug/taskboard/:sslug", $routeProvider.when("/project/:pslug/taskboard/:sslug",
{templateUrl: "taskboard/taskboard.html", resolve: {loader: tgLoaderProvider.add()}}) {
templateUrl: "taskboard/taskboard.html",
resolve: {loader: tgLoaderProvider.add()},
section: "backlog"
}
)
# User stories # User stories
$routeProvider.when("/project/:pslug/us/:usref", $routeProvider.when("/project/:pslug/us/:usref",
{templateUrl: "us/us-detail.html", resolve: {loader: tgLoaderProvider.add()}}) {
templateUrl: "us/us-detail.html",
resolve: {loader: tgLoaderProvider.add()},
section: "backlog-kanban"
}
)
# Tasks # Tasks
$routeProvider.when("/project/:pslug/task/:taskref", $routeProvider.when("/project/:pslug/task/:taskref",
{templateUrl: "task/task-detail.html", resolve: {loader: tgLoaderProvider.add()}}) {
templateUrl: "task/task-detail.html",
resolve: {loader: tgLoaderProvider.add()},
section: "backlog-kanban"
}
)
# Wiki # Wiki
$routeProvider.when("/project/:pslug/wiki", $routeProvider.when("/project/:pslug/wiki",
{redirectTo: (params) -> "/project/#{params.pslug}/wiki/home"}, ) {redirectTo: (params) -> "/project/#{params.pslug}/wiki/home"}, )
$routeProvider.when("/project/:pslug/wiki/:slug", $routeProvider.when("/project/:pslug/wiki/:slug",
{templateUrl: "wiki/wiki.html", resolve: {loader: tgLoaderProvider.add()}}) {
templateUrl: "wiki/wiki.html",
resolve: {loader: tgLoaderProvider.add()},
section: "wiki"
}
)
# Team # Team
$routeProvider.when("/project/:pslug/team", $routeProvider.when("/project/:pslug/team",
{templateUrl: "team/team.html", resolve: {loader: tgLoaderProvider.add()}}) {
templateUrl: "team/team.html",
resolve: {loader: tgLoaderProvider.add()},
section: "team"
}
)
# Issues # Issues
$routeProvider.when("/project/:pslug/issues", $routeProvider.when("/project/:pslug/issues",
{templateUrl: "issue/issues.html", resolve: {loader: tgLoaderProvider.add()}}) {
templateUrl: "issue/issues.html",
resolve: {loader: tgLoaderProvider.add()},
section: "issues"
}
)
$routeProvider.when("/project/:pslug/issue/:issueref", $routeProvider.when("/project/:pslug/issue/:issueref",
{templateUrl: "issue/issues-detail.html", resolve: {loader: tgLoaderProvider.add()}}) {
templateUrl: "issue/issues-detail.html",
resolve: {loader: tgLoaderProvider.add()},
section: "issues"
}
)
# Admin - Project Profile # Admin - Project Profile
$routeProvider.when("/project/:pslug/admin/project-profile/details", $routeProvider.when("/project/:pslug/admin/project-profile/details",
{templateUrl: "admin/admin-project-profile.html"}) {
templateUrl: "admin/admin-project-profile.html",
section: "admin"
}
)
$routeProvider.when("/project/:pslug/admin/project-profile/default-values", $routeProvider.when("/project/:pslug/admin/project-profile/default-values",
{templateUrl: "admin/admin-project-default-values.html"}) {
templateUrl: "admin/admin-project-default-values.html",
section: "admin"
}
)
$routeProvider.when("/project/:pslug/admin/project-profile/modules", $routeProvider.when("/project/:pslug/admin/project-profile/modules",
{templateUrl: "admin/admin-project-modules.html"}) {
templateUrl: "admin/admin-project-modules.html",
section: "admin"
}
)
$routeProvider.when("/project/:pslug/admin/project-profile/export", $routeProvider.when("/project/:pslug/admin/project-profile/export",
{templateUrl: "admin/admin-project-export.html"}) {
templateUrl: "admin/admin-project-export.html",
section: "admin"
}
)
$routeProvider.when("/project/:pslug/admin/project-profile/reports", $routeProvider.when("/project/:pslug/admin/project-profile/reports",
{templateUrl: "admin/admin-project-reports.html"}) {
templateUrl: "admin/admin-project-reports.html",
section: "admin"
}
)
$routeProvider.when("/project/:pslug/admin/project-values/status", $routeProvider.when("/project/:pslug/admin/project-values/status",
{templateUrl: "admin/admin-project-values-status.html"}) {
templateUrl: "admin/admin-project-values-status.html",
section: "admin"
}
)
$routeProvider.when("/project/:pslug/admin/project-values/points", $routeProvider.when("/project/:pslug/admin/project-values/points",
{templateUrl: "admin/admin-project-values-points.html"}) {
templateUrl: "admin/admin-project-values-points.html",
section: "admin"
}
)
$routeProvider.when("/project/:pslug/admin/project-values/priorities", $routeProvider.when("/project/:pslug/admin/project-values/priorities",
{templateUrl: "admin/admin-project-values-priorities.html"}) {
templateUrl: "admin/admin-project-values-priorities.html",
section: "admin"
}
)
$routeProvider.when("/project/:pslug/admin/project-values/severities", $routeProvider.when("/project/:pslug/admin/project-values/severities",
{templateUrl: "admin/admin-project-values-severities.html"}) {
templateUrl: "admin/admin-project-values-severities.html",
section: "admin"
}
)
$routeProvider.when("/project/:pslug/admin/project-values/types", $routeProvider.when("/project/:pslug/admin/project-values/types",
{templateUrl: "admin/admin-project-values-types.html"}) {
templateUrl: "admin/admin-project-values-types.html",
section: "admin"
}
)
$routeProvider.when("/project/:pslug/admin/project-values/custom-fields", $routeProvider.when("/project/:pslug/admin/project-values/custom-fields",
{templateUrl: "admin/admin-project-values-custom-fields.html"}) {
templateUrl: "admin/admin-project-values-custom-fields.html",
section: "admin"
}
)
$routeProvider.when("/project/:pslug/admin/memberships", $routeProvider.when("/project/:pslug/admin/memberships",
{templateUrl: "admin/admin-memberships.html"}) {
templateUrl: "admin/admin-memberships.html",
section: "admin"
}
)
# Admin - Roles # Admin - Roles
$routeProvider.when("/project/:pslug/admin/roles", $routeProvider.when("/project/:pslug/admin/roles",
{templateUrl: "admin/admin-roles.html"}) {
templateUrl: "admin/admin-roles.html",
section: "backlog-kanban"
}
)
# Admin - Third Parties # Admin - Third Parties
$routeProvider.when("/project/:pslug/admin/third-parties/webhooks", $routeProvider.when("/project/:pslug/admin/third-parties/webhooks",
{templateUrl: "admin/admin-third-parties-webhooks.html"}) {
templateUrl: "admin/admin-third-parties-webhooks.html",
section: "admin"
}
)
$routeProvider.when("/project/:pslug/admin/third-parties/github", $routeProvider.when("/project/:pslug/admin/third-parties/github",
{templateUrl: "admin/admin-third-parties-github.html"}) {
templateUrl: "admin/admin-third-parties-github.html",
section: "admin"
}
)
$routeProvider.when("/project/:pslug/admin/third-parties/gitlab", $routeProvider.when("/project/:pslug/admin/third-parties/gitlab",
{templateUrl: "admin/admin-third-parties-gitlab.html"}) {
templateUrl: "admin/admin-third-parties-gitlab.html",
section: "admin"
}
)
$routeProvider.when("/project/:pslug/admin/third-parties/bitbucket", $routeProvider.when("/project/:pslug/admin/third-parties/bitbucket",
{templateUrl: "admin/admin-third-parties-bitbucket.html"}) {
templateUrl: "admin/admin-third-parties-bitbucket.html",
section: "admin"
}
)
# Admin - Contrib Plugins # Admin - Contrib Plugins
$routeProvider.when("/project/:pslug/admin/contrib/:plugin", $routeProvider.when("/project/:pslug/admin/contrib/:plugin",
{templateUrl: "contrib/main.html"}) {templateUrl: "contrib/main.html"})
@ -364,7 +483,7 @@ i18nInit = (lang, $translate) ->
checksley.updateMessages('default', messages) checksley.updateMessages('default', messages)
init = ($log, $rootscope, $auth, $events, $analytics, $translate, $location, $navUrls, $appTitle) -> init = ($log, $rootscope, $auth, $events, $analytics, $translate, $location, $navUrls, $appTitle, projectService) ->
$log.debug("Initialize application") $log.debug("Initialize application")
# Taiga Plugins # Taiga Plugins
@ -392,6 +511,12 @@ init = ($log, $rootscope, $auth, $events, $analytics, $translate, $location, $na
if !$auth.isAuthenticated() if !$auth.isAuthenticated()
$location.path($navUrls.resolve("login")) $location.path($navUrls.resolve("login"))
if next.section
projectService.setSection(next.section)
if next.params.pslug
projectService.setProject(next.params.pslug)
if next.title if next.title
$translate(next.title).then (text) => $appTitle.set(text) $translate(next.title).then (text) => $appTitle.set(text)
@ -419,7 +544,6 @@ modules = [
"taigaWiki", "taigaWiki",
"taigaSearch", "taigaSearch",
"taigaAdmin", "taigaAdmin",
"taigaNavMenu",
"taigaProject", "taigaProject",
"taigaUserSettings", "taigaUserSettings",
"taigaFeedback", "taigaFeedback",
@ -467,5 +591,6 @@ module.run([
"$tgLocation", "$tgLocation",
"$tgNavUrls", "$tgNavUrls",
"$appTitle", "$appTitle",
"tgProjectService",
init init
]) ])

View File

@ -106,7 +106,7 @@ module.controller("ProjectProfileController", ProjectProfileController)
## Project Profile Directive ## Project Profile Directive
############################################################################# #############################################################################
ProjectProfileDirective = ($repo, $confirm, $loading, $navurls, $location, projectsService) -> ProjectProfileDirective = ($repo, $confirm, $loading, $navurls, $location, projectService) ->
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
form = $el.find("form").checksley({"onlyOneErrorElement": true}) form = $el.find("form").checksley({"onlyOneErrorElement": true})
submit = debounce 2000, (event) => submit = debounce 2000, (event) =>
@ -115,7 +115,6 @@ ProjectProfileDirective = ($repo, $confirm, $loading, $navurls, $location, proje
return if not form.validate() return if not form.validate()
$loading.start(submitButton) $loading.start(submitButton)
promise = $repo.save($scope.project) promise = $repo.save($scope.project)
promise.then -> promise.then ->
$loading.finish(submitButton) $loading.finish(submitButton)
@ -123,7 +122,8 @@ ProjectProfileDirective = ($repo, $confirm, $loading, $navurls, $location, proje
newUrl = $navurls.resolve("project-admin-project-profile-details", {project: $scope.project.slug}) newUrl = $navurls.resolve("project-admin-project-profile-details", {project: $scope.project.slug})
$location.path(newUrl) $location.path(newUrl)
$scope.$emit("project:loaded", $scope.project) $scope.$emit("project:loaded", $scope.project)
projectsService.fetchProjects()
projectService.fetchProject()
promise.then null, (data) -> promise.then null, (data) ->
$loading.finish(submitButton) $loading.finish(submitButton)
@ -137,7 +137,7 @@ ProjectProfileDirective = ($repo, $confirm, $loading, $navurls, $location, proje
return {link:link} return {link:link}
module.directive("tgProjectProfile", ["$tgRepo", "$tgConfirm", "$tgLoading", "$tgNavUrls", "$tgLocation", "tgProjectsService", ProjectProfileDirective]) module.directive("tgProjectProfile", ["$tgRepo", "$tgConfirm", "$tgLoading", "$tgNavUrls", "$tgLocation", "tgProjectService", ProjectProfileDirective])
############################################################################# #############################################################################
## Project Default Values Directive ## Project Default Values Directive
@ -180,7 +180,7 @@ module.directive("tgProjectDefaultValues", ["$tgRepo", "$tgConfirm", "$tgLoading
## Project Modules Directive ## Project Modules Directive
############################################################################# #############################################################################
ProjectModulesDirective = ($repo, $confirm, $loading) -> ProjectModulesDirective = ($repo, $confirm, $loading, projectService) ->
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
form = $el.find("form").checksley() form = $el.find("form").checksley()
submit = => submit = =>
@ -194,6 +194,8 @@ ProjectModulesDirective = ($repo, $confirm, $loading) ->
$confirm.notify("success") $confirm.notify("success")
$scope.$emit("project:loaded", $scope.project) $scope.$emit("project:loaded", $scope.project)
projectService.fetchProject()
promise.then null, (data) -> promise.then null, (data) ->
$loading.finish(target) $loading.finish(target)
$confirm.notify("error", data._error_message) $confirm.notify("error", data._error_message)
@ -222,7 +224,7 @@ ProjectModulesDirective = ($repo, $confirm, $loading) ->
return {link:link} return {link:link}
module.directive("tgProjectModules", ["$tgRepo", "$tgConfirm", "$tgLoading", ProjectModulesDirective]) module.directive("tgProjectModules", ["$tgRepo", "$tgConfirm", "$tgLoading", "tgProjectService", ProjectModulesDirective])
############################################################################# #############################################################################

View File

@ -86,7 +86,7 @@ NavigationUrlsDirective = ($navurls, $auth, $q, $location) ->
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
if $el.is("a") if $el.is("a")
$el.attr("href", "#") $el.attr("href", "")
$el.on "mouseenter", (event) -> $el.on "mouseenter", (event) ->
target = $(event.currentTarget) target = $(event.currentTarget)

View File

@ -107,7 +107,7 @@ module.controller("SearchController", SearchController)
## Search box directive ## Search box directive
############################################################################# #############################################################################
SearchBoxDirective = ($lightboxService, $navurls, $location, $route)-> SearchBoxDirective = (projectService, $lightboxService, $navurls, $location, $route)->
link = ($scope, $el, $attrs) -> link = ($scope, $el, $attrs) ->
project = null project = null
@ -120,7 +120,7 @@ SearchBoxDirective = ($lightboxService, $navurls, $location, $route)->
text = $el.find("#search-text").val() text = $el.find("#search-text").val()
url = $navurls.resolve("project-search", {project: project.slug}) url = $navurls.resolve("project-search", {project: project.get("slug")})
$lightboxService.close($el) $lightboxService.close($el)
$scope.$apply -> $scope.$apply ->
@ -128,16 +128,29 @@ SearchBoxDirective = ($lightboxService, $navurls, $location, $route)->
$location.search("text", text).path(url) $location.search("text", text).path(url)
$route.reload() $route.reload()
$scope.$on "search-box:show", (ctx, newProject)-> openLightbox = () ->
project = newProject project = projectService.project
$lightboxService.open($el) $lightboxService.open($el)
$el.find("#search-text").val("")
$el.on "submit", "form", submit $el.on "submit", "form", submit
return {link:link} openLightbox()
module.directive("tgSearchBox", ["lightboxService", "$tgNavUrls", "$tgLocation", "$route", SearchBoxDirective]) return {
templateUrl: "search/lightbox-search.html",
link:link
}
SearchBoxDirective.$inject = [
"tgProjectService",
"lightboxService",
"$tgNavUrls",
"$tgLocation",
"$route"
]
module.directive("tgSearchBox", SearchBoxDirective)
############################################################################# #############################################################################

View File

@ -109,7 +109,8 @@ class WikiDetailController extends mixOf(taiga.Controller, taiga.PageMixin)
promise = @.loadProject() promise = @.loadProject()
return promise.then (project) => return promise.then (project) =>
@.fillUsersAndRoles(project.users, project.roles) @.fillUsersAndRoles(project.users, project.roles)
@q.all([@.loadWikiLinks(), @.loadWiki()]) @q.all([@.loadWikiLinks(), @.loadWiki()]).then () =>
delete: -> delete: ->
title = @translate.instant("WIKI.DELETE_LIGHTBOX_TITLE") title = @translate.instant("WIKI.DELETE_LIGHTBOX_TITLE")

View File

@ -28,8 +28,6 @@ html(lang="en")
include partials/includes/modules/lightbox-generic-error include partials/includes/modules/lightbox-generic-error
div.lightbox.lightbox-generic-loading div.lightbox.lightbox-generic-loading
include partials/includes/modules/lightbox-generic-loading include partials/includes/modules/lightbox-generic-loading
div.lightbox.lightbox-search(tg-search-box)
include partials/includes/modules/lightbox-search
include partials/includes/modules/loader include partials/includes/modules/loader

View File

@ -0,0 +1,92 @@
class ProjectMenuController
@.$inject = [
"tgProjectService",
"tgLightboxFactory"
]
constructor: (@projectService, @lightboxFactory) ->
@.project = null
@.menu = Immutable.Map()
show: () ->
@.project = @projectService.project
@.active = @._getActiveSection()
@._setVideoConference()
@._setMenuPermissions()
hide: () ->
@.project = null
@.menu = {}
search: () ->
@lightboxFactory.create("tg-search-box", {
"class": "lightbox lightbox-search"
})
_setVideoConference: () ->
videoconferenceUrl = @._videoConferenceUrl()
if videoconferenceUrl
@.project = @.project.set("videoconferenceUrl", videoconferenceUrl)
_setMenuPermissions: () ->
@.menu = Immutable.Map({
backlog: false,
kanban: false,
issues: false,
wiki: false
})
if @.project.get("is_backlog_activated") && @.project.get("my_permissions").indexOf("view_us") != -1
@.menu = @.menu.set("backlog", true)
if @.project.get("is_kanban_activated") && @.project.get("my_permissions").indexOf("view_us") != -1
@.menu = @.menu.set("kanban", true)
if @.project.get("is_issues_activated") && @.project.get("my_permissions").indexOf("view_issues") != -1
@.menu = @.menu.set("issues", true)
if @.project.get("is_wiki_activated") && @.project.get("my_permissions").indexOf("view_wiki_pages") != -1
@.menu = @.menu.set("wiki", true)
_getActiveSection: () ->
sectionName = @projectService.section
sectionsBreadcrumb = @projectService.sectionsBreadcrumb
indexBacklog = sectionsBreadcrumb.lastIndexOf("backlog")
indexKanban = sectionsBreadcrumb.lastIndexOf("kanban")
if indexBacklog != -1 || indexKanban != -1
if indexBacklog > indexKanban
oldSectionName = "backlog"
else
oldSectionName = "kanban"
if sectionName == "backlog-kanban"
if oldSectionName in ["backlog", "kanban"]
sectionName = oldSectionName
else if @.project.get("is_backlog_activated") && !@.project.get("is_kanban_activated")
sectionName = "backlog"
else if !@.project.get("is_backlog_activated") && @.project.get("is_kanban_activated")
sectionName = "kanban"
return sectionName
_videoConferenceUrl: () ->
if @.project.get("videoconferences") == "appear-in"
baseUrl = "https://appear.in/"
else if @.project.get("videoconferences") == "talky"
baseUrl = "https://talky.io/"
else
return ""
if @.project.get("videoconferences_salt")
url = @.project.get("slug") + "-" + @.project.get("videoconferences_salt")
else
url = @.project.get("slug")
return baseUrl + url
angular.module("taigaComponents").controller("ProjectMenu", ProjectMenuController)

View File

@ -0,0 +1,234 @@
describe "ProjectMenu", ->
$provide = null
$controller = null
mocks = {}
_mockProjectService = ->
mocks.projectService = {}
$provide.value("tgProjectService", mocks.projectService)
_mockLightboxFactory = ->
mocks.lightboxFactory = {
create: sinon.spy()
}
$provide.value("tgLightboxFactory", mocks.lightboxFactory)
_mocks = ->
module (_$provide_) ->
$provide = _$provide_
_mockProjectService()
_mockLightboxFactory()
return null
_inject = ->
inject (_$controller_) ->
$controller = _$controller_
_setup = ->
_mocks()
_inject()
beforeEach ->
module "taigaComponents"
_setup()
it "open search lightbox", () ->
ctrl = $controller("ProjectMenu")
ctrl.search()
expectation = mocks.lightboxFactory.create.calledWithExactly("tg-search-box", {
"class": "lightbox lightbox-search"
})
expect(expectation).to.be.true
describe "show menu", ->
it "project filled", () ->
project = Immutable.fromJS({})
mocks.projectService.project = project
mocks.projectService.sectionsBreadcrumb = Immutable.List()
ctrl = $controller("ProjectMenu")
ctrl.show()
expect(ctrl.project).to.be.equal(project)
it "videoconference url", () ->
project = Immutable.fromJS({
"videoconferences": "appear-in",
"videoconferences_salt": "123",
"slug": "project-slug"
})
mocks.projectService.project = project
mocks.projectService.sectionsBreadcrumb = Immutable.List()
ctrl = $controller("ProjectMenu")
ctrl.show()
url = "https://appear.in/project-slug-123"
expect(ctrl.project.get("videoconferenceUrl")).to.be.equal(url)
describe "menu permissions", () ->
it "all options disable", () ->
project = Immutable.fromJS({})
mocks.projectService.project = project
mocks.projectService.sectionsBreadcrumb = Immutable.List()
ctrl = $controller("ProjectMenu")
ctrl.show()
menu = ctrl.menu.toJS()
expect(menu).to.be.eql({
backlog: false,
kanban: false,
issues: false,
wiki: false
})
it "all options enabled", () ->
project = Immutable.fromJS({
is_backlog_activated: true,
is_kanban_activated: true,
is_issues_activated: true,
is_wiki_activated: true,
my_permissions: ["view_us", "view_issues", "view_wiki_pages"]
})
mocks.projectService.project = project
mocks.projectService.sectionsBreadcrumb = Immutable.List()
ctrl = $controller("ProjectMenu")
ctrl.show()
menu = ctrl.menu.toJS()
expect(menu).to.be.eql({
backlog: true,
kanban: true,
issues: true,
wiki: true
})
it "all options disabled because the user doesn't have permissions", () ->
project = Immutable.fromJS({
is_backlog_activated: true,
is_kanban_activated: true,
is_issues_activated: true,
is_wiki_activated: true,
my_permissions: []
})
mocks.projectService.project = project
mocks.projectService.sectionsBreadcrumb = Immutable.List()
ctrl = $controller("ProjectMenu")
ctrl.show()
menu = ctrl.menu.toJS()
expect(menu).to.be.eql({
backlog: false,
kanban: false,
issues: false,
wiki: false
})
describe "menu active", () ->
it "backlog", () ->
project = Immutable.fromJS({})
mocks.projectService.project = project
mocks.projectService.section = "backlog"
mocks.projectService.sectionsBreadcrumb = Immutable.List()
ctrl = $controller("ProjectMenu")
ctrl.show()
expect(ctrl.active).to.be.equal("backlog")
it "backlog-kanban without parent", () ->
project = Immutable.fromJS({})
mocks.projectService.project = project
mocks.projectService.section = "backlog-kanban"
mocks.projectService.sectionsBreadcrumb = Immutable.List()
ctrl = $controller("ProjectMenu")
ctrl.show()
expect(ctrl.active).to.be.equal("backlog-kanban")
it "backlog-kanban when only kanban is enabled", () ->
project = Immutable.fromJS({
is_kanban_activated: true,
my_permissions: []
})
mocks.projectService.project = project
mocks.projectService.section = "backlog-kanban"
mocks.projectService.sectionsBreadcrumb = Immutable.List()
ctrl = $controller("ProjectMenu")
ctrl.show()
expect(ctrl.active).to.be.equal("kanban")
it "backlog-kanban when only backlog is enabled", () ->
project = Immutable.fromJS({
is_backlog_activated: true,
my_permissions: []
})
mocks.projectService.project = project
mocks.projectService.section = "backlog-kanban"
mocks.projectService.sectionsBreadcrumb = Immutable.List()
ctrl = $controller("ProjectMenu")
ctrl.show()
expect(ctrl.active).to.be.equal("backlog")
it "backlog-kanban when is child of kanban", () ->
project = Immutable.fromJS({})
mocks.projectService.project = project
mocks.projectService.section = "backlog-kanban"
mocks.projectService.sectionsBreadcrumb = Immutable.List.of("kanban", "backlog", "oo")
ctrl = $controller("ProjectMenu")
ctrl.show()
expect(ctrl.active).to.be.equal("kanban")
it "backlog-kanban when is child of backlog", () ->
project = Immutable.fromJS({})
mocks.projectService.project = project
mocks.projectService.section = "backlog-kanban"
mocks.projectService.sectionsBreadcrumb = Immutable.List.of("backlog", "kanban", "oo")
ctrl = $controller("ProjectMenu")
ctrl.show()
expect(ctrl.active).to.be.equal("backlog")

View File

@ -0,0 +1,28 @@
taiga = @.taiga
ProjectMenuDirective = (projectService, lightboxFactory) ->
link = (scope, el, attrs, ctrl) ->
projectChange = () ->
if projectService.project
ctrl.show()
else
ctrl.hide()
scope.$watch ( () ->
return projectService.project
), projectChange
return {
controller: "ProjectMenu",
templateUrl: "components/project-menu/project-menu.html",
link: link,
controllerAs: "vm",
replace: true
}
ProjectMenuDirective.$inject = [
"tgProjectService",
"tgLightboxFactory"
]
angular.module("taigaComponents").directive("tgProjectMenu", ProjectMenuDirective)

View File

@ -0,0 +1,42 @@
nav.menu(ng-if="vm.project")
div(class="menu-container")
ul(class="main-nav")
li(id="nav-search")
a(href="", ng-class="{active: vm.active == 'search'}", title="{{'PROJECT.SECTION.SEARCH' | translate}}", tabindex="1", ng-click="vm.search()")
span(class="icon icon-search")
span.helper(translate="PROJECT.SECTION.SEARCH")
li(id="nav-backlog", ng-if="vm.menu.get('backlog')")
a(ng-class="{active: vm.active == 'backlog'}", title="{{'PROJECT.SECTION.BACKLOG' | translate}}", tg-nav="project-backlog:project=vm.project.get('slug')", tabindex="2")
span(class="icon icon-backlog")
span.helper(translate="PROJECT.SECTION.BACKLOG")
li(id="nav-kanban", ng-if="vm.menu.get('kanban')")
a(ng-class="{active: vm.active == 'kanban'}", title="{{'PROJECT.SECTION.KANBAN' | translate}}", tg-nav="project-kanban:project=vm.project.get('slug')", tabindex="3")
span(class="icon icon-kanban")
span.helper(translate="PROJECT.SECTION.KANBAN")
li(id="nav-issues", ng-if="vm.menu.get('issues')")
a(ng-class="{active: vm.active == 'issues'}", title="{{'PROJECT.SECTION.ISSUES' | translate}}", tg-nav="project-issues:project=vm.project.get('slug')", tabindex="4")
span(class="icon icon-issues")
span.helper(translate="PROJECT.SECTION.ISSUES")
li(id="nav-wiki", ng-if="vm.menu.get('wiki')")
a(ng-class="{active: vm.active == 'wiki'}", title="{{'PROJECT.SECTION.WIKI' | translate}}", tg-nav="project-wiki:project=vm.project.get('slug')", tabindex="5")
span(class="icon icon-wiki")
span.helper(translate="PROJECT.SECTION.WIKI")
li(id="nav-team")
a(ng-class="{active: vm.active == 'team'}", title="{{'PROJECT.SECTION.TEAM' | translate}}", tg-nav="project-team:project=vm.project.get('slug')", tabindex="6")
span(class="icon icon-team")
span.helper(translate="PROJECT.SECTION.TEAM")
li(id="nav-video", ng-if="vm.project.get('videoconferenceUrl')")
a(ng-href="{{vm.project.get('videoconferenceUrl')}}", target="_blank", title="{{'PROJECT.SECTION.MEETUP' | translate}}", tabindex="7")
span(class="icon icon-video")
span.helper(translate="PROJECT.SECTION.MEETUP")
li(id="nav-admin", ng-if="vm.project.get('i_am_owner')")
a(ng-class="{active: vm.active == 'admin'}", tg-nav="project-admin-home:project=vm.project.get('slug')", title="{{'PROJECT.SECTION.ADMIN' | translate}}", tabindex="8")
span(class="icon icon-settings")
span.helper(translate="PROJECT.SECTION.ADMIN")

View File

@ -1,4 +1,5 @@
div.wrapper div.wrapper
div(tg-project-menu)
div.main.centered.single-project div.main.centered.single-project
section.single-project-intro section.single-project-intro
h1 h1

View File

@ -0,0 +1,30 @@
taiga = @.taiga
class ProjectService
@.$inject = [
"tgProjectsService"
]
constructor: (@projectsService) ->
@._project = null
@._section = null
@._sectionsBreadcrumb = Immutable.List()
taiga.defineImmutableProperty @, "project", () => return @._project
taiga.defineImmutableProperty @, "section", () => return @._section
taiga.defineImmutableProperty @, "sectionsBreadcrumb", () => return @._sectionsBreadcrumb
setSection: (section) ->
@._section = section
@._sectionsBreadcrumb = @._sectionsBreadcrumb.unshift(@._section)
setProject: (pslug) ->
if @._pslug != pslug
@._pslug = pslug
@.fetchProject()
fetchProject: () ->
return @projectsService.getProjectBySlug(@._pslug).then (project) =>
@._project = project
angular.module("taigaCommon").service("tgProjectService", ProjectService)

View File

@ -0,0 +1,76 @@
describe "tgProjectService", ->
$provide = null
mocks = {}
projectService = null
_mockProjectsService = () ->
mocks.projectsService = {
getProjectBySlug: sinon.stub().promise()
}
$provide.value "tgProjectsService", mocks.projectsService
_mocks = () ->
module (_$provide_) ->
$provide = _$provide_
_mockProjectsService()
return null
_setup = () ->
_mocks()
_inject = () ->
inject (_tgProjectService_) ->
projectService = _tgProjectService_
beforeEach ->
module "taigaCommon"
_setup()
_inject()
it "update section and add it at the begginning of section breadcrumb", () ->
section = "fakeSection"
breadcrumb = ["fakeSection"]
projectService.setSection(section)
expect(projectService.section).to.be.equal(section)
expect(projectService.sectionsBreadcrumb.toJS()).to.be.eql(breadcrumb)
section = "fakeSection222"
breadcrumb = ["fakeSection222","fakeSection"]
projectService.setSection(section)
expect(projectService.sectionsBreadcrumb.toJS()).to.be.eql(breadcrumb)
it "set project if the project slug has changed", () ->
projectService.fetchProject = sinon.spy()
pslug = "slug-1"
projectService.setProject(pslug)
expect(projectService.fetchProject).to.be.calledOnce
projectService.setProject(pslug)
expect(projectService.fetchProject).to.be.calledOnce
projectService.setProject("slug-2")
expect(projectService.fetchProject).to.be.calledTwice
it "fetch project", (done) ->
project = Immutable.Map({id: 1})
pslug = "slug-1"
projectService._pslug = pslug
mocks.projectsService.getProjectBySlug.withArgs(pslug).resolve(project)
projectService.fetchProject().then () ->
expect(projectService.project).to.be.equal(project)
done()

View File

@ -2,7 +2,7 @@ doctype html
div.wrapper.memberships(ng-controller="MembershipsController as ctrl", div.wrapper.memberships(ng-controller="MembershipsController as ctrl",
ng-init="section='admin'; sectionName='ADMIN.MEMBERSHIPS.TITLE'", tg-memberships) ng-init="section='admin'; sectionName='ADMIN.MEMBERSHIPS.TITLE'", tg-memberships)
nav.menu.hidden(tg-project-menu) div(tg-project-menu)
sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="memberships") sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="memberships")
include ../includes/modules/admin-menu include ../includes/modules/admin-menu

View File

@ -2,7 +2,7 @@ doctype html
div.wrapper(tg-project-default-values, ng-controller="ProjectProfileController as ctrl", div.wrapper(tg-project-default-values, ng-controller="ProjectProfileController as ctrl",
ng-init="section='admin'; sectionName='ADMIN.PROJECT_DEFAULT_VALUES.TITLE'") ng-init="section='admin'; sectionName='ADMIN.PROJECT_DEFAULT_VALUES.TITLE'")
nav.menu.hidden(tg-project-menu) div(tg-project-menu)
sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="project-profile") sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="project-profile")
include ../includes/modules/admin-menu include ../includes/modules/admin-menu

View File

@ -2,7 +2,7 @@ doctype html
div.wrapper(ng-controller="ProjectProfileController as ctrl", div.wrapper(ng-controller="ProjectProfileController as ctrl",
ng-init="section='admin'; sectionName='ADMIN.PROJECT_EXPORT.TITLE'") ng-init="section='admin'; sectionName='ADMIN.PROJECT_EXPORT.TITLE'")
nav.menu.hidden(tg-project-menu) div(tg-project-menu)
sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="project-profile") sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="project-profile")
include ../includes/modules/admin-menu include ../includes/modules/admin-menu

View File

@ -2,7 +2,7 @@ doctype html
div.wrapper(tg-project-modules, ng-controller="ProjectProfileController as ctrl", div.wrapper(tg-project-modules, ng-controller="ProjectProfileController as ctrl",
ng-init="section='admin'; sectionName='ADMIN.MODULES.TITLE'") ng-init="section='admin'; sectionName='ADMIN.MODULES.TITLE'")
nav.menu.hidden(tg-project-menu) div(tg-project-menu)
sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="project-profile") sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="project-profile")
include ../includes/modules/admin-menu include ../includes/modules/admin-menu

View File

@ -2,7 +2,7 @@ doctype html
div.wrapper(tg-project-profile, ng-controller="ProjectProfileController as ctrl", div.wrapper(tg-project-profile, ng-controller="ProjectProfileController as ctrl",
ng-init="section='admin'; sectionName='ADMIN.PROJECT_PROFILE.PROJECT_DETAILS'") ng-init="section='admin'; sectionName='ADMIN.PROJECT_PROFILE.PROJECT_DETAILS'")
nav.menu.hidden(tg-project-menu) div(tg-project-menu)
sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="project-profile") sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="project-profile")
include ../includes/modules/admin-menu include ../includes/modules/admin-menu

View File

@ -2,7 +2,7 @@ doctype html
div.wrapper(ng-controller="ProjectProfileController as ctrl", div.wrapper(ng-controller="ProjectProfileController as ctrl",
ng-init="section='admin'; sectionName='ADMIN.REPORTS.TITLE'") ng-init="section='admin'; sectionName='ADMIN.REPORTS.TITLE'")
nav.menu.hidden(tg-project-menu) div(tg-project-menu)
sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="project-profile") sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="project-profile")
include ../includes/modules/admin-menu include ../includes/modules/admin-menu

View File

@ -3,7 +3,7 @@ doctype html
div.wrapper(ng-controller="ProjectValuesSectionController", div.wrapper(ng-controller="ProjectValuesSectionController",
ng-init="sectionName='ADMIN.CUSTOM_FIELDS.TITLE'") ng-init="sectionName='ADMIN.CUSTOM_FIELDS.TITLE'")
nav.menu.hidden(tg-project-menu) div(tg-project-menu)
sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="project-values") sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="project-values")
include ../includes/modules/admin-menu include ../includes/modules/admin-menu

View File

@ -2,7 +2,7 @@ doctype html
div.wrapper(ng-controller="ProjectValuesSectionController") div.wrapper(ng-controller="ProjectValuesSectionController")
nav.menu.hidden(tg-project-menu) div(tg-project-menu)
sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="project-values") sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="project-values")
include ../includes/modules/admin-menu include ../includes/modules/admin-menu

View File

@ -1,7 +1,7 @@
doctype html doctype html
div.wrapper(ng-controller="ProjectValuesSectionController") div.wrapper(ng-controller="ProjectValuesSectionController")
nav.menu.hidden(tg-project-menu) div(tg-project-menu)
sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="project-values") sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="project-values")
include ../includes/modules/admin-menu include ../includes/modules/admin-menu

View File

@ -1,7 +1,7 @@
doctype html doctype html
div.wrapper(ng-controller="ProjectValuesSectionController") div.wrapper(ng-controller="ProjectValuesSectionController")
nav.menu.hidden(tg-project-menu) div(tg-project-menu)
sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="project-values") sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="project-values")
include ../includes/modules/admin-menu include ../includes/modules/admin-menu

View File

@ -2,7 +2,7 @@ doctype html
div.wrapper(ng-controller="ProjectValuesSectionController", div.wrapper(ng-controller="ProjectValuesSectionController",
ng-init="section='admin'; sectionName='ADMIN.PROJECT_VALUES_STATUS.TITLE'") ng-init="section='admin'; sectionName='ADMIN.PROJECT_VALUES_STATUS.TITLE'")
nav.menu.hidden(tg-project-menu) div(tg-project-menu)
sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="project-values") sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="project-values")
include ../includes/modules/admin-menu include ../includes/modules/admin-menu

View File

@ -2,7 +2,7 @@ doctype html
div.wrapper(ng-controller="ProjectValuesSectionController" div.wrapper(ng-controller="ProjectValuesSectionController"
ng-init="sectionName='ADMIN.PROJECT_VALUES_TYPES.TITLE'") ng-init="sectionName='ADMIN.PROJECT_VALUES_TYPES.TITLE'")
nav.menu.hidden(tg-project-menu) div(tg-project-menu)
sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="project-values") sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="project-values")
include ../includes/modules/admin-menu include ../includes/modules/admin-menu

View File

@ -2,7 +2,7 @@ doctype html
div.wrapper.roles(ng-controller="RolesController as ctrl", div.wrapper.roles(ng-controller="RolesController as ctrl",
ng-init="section='admin'", tg-roles) ng-init="section='admin'", tg-roles)
nav.menu.hidden(tg-project-menu) div(tg-project-menu)
sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="roles") sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="roles")
include ../includes/modules/admin-menu include ../includes/modules/admin-menu

View File

@ -2,7 +2,7 @@ doctype html
div.wrapper.roles(tg-bitbucket-webhooks, ng-controller="BitbucketController as ctrl", div.wrapper.roles(tg-bitbucket-webhooks, ng-controller="BitbucketController as ctrl",
ng-init="section='admin'") ng-init="section='admin'")
nav.menu.hidden(tg-project-menu) div(tg-project-menu)
sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="third-parties") sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="third-parties")
include ../includes/modules/admin-menu include ../includes/modules/admin-menu
sidebar.menu-tertiary.sidebar(tg-admin-navigation="third-parties-bitbucket") sidebar.menu-tertiary.sidebar(tg-admin-navigation="third-parties-bitbucket")

View File

@ -2,7 +2,7 @@ doctype html
div.wrapper.roles(tg-github-webhooks, ng-controller="GithubController as ctrl", div.wrapper.roles(tg-github-webhooks, ng-controller="GithubController as ctrl",
ng-init="section='admin'") ng-init="section='admin'")
nav.menu.hidden(tg-project-menu) div(tg-project-menu)
sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="third-parties") sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="third-parties")
include ../includes/modules/admin-menu include ../includes/modules/admin-menu
sidebar.menu-tertiary.sidebar(tg-admin-navigation="third-parties-github") sidebar.menu-tertiary.sidebar(tg-admin-navigation="third-parties-github")

View File

@ -2,7 +2,7 @@ doctype html
div.wrapper.roles(tg-gitlab-webhooks, ng-controller="GitlabController as ctrl", div.wrapper.roles(tg-gitlab-webhooks, ng-controller="GitlabController as ctrl",
ng-init="section='admin'") ng-init="section='admin'")
nav.menu.hidden(tg-project-menu) div(tg-project-menu)
sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="third-parties") sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="third-parties")
include ../includes/modules/admin-menu include ../includes/modules/admin-menu
sidebar.menu-tertiary.sidebar(tg-admin-navigation="third-parties-gitlab") sidebar.menu-tertiary.sidebar(tg-admin-navigation="third-parties-gitlab")

View File

@ -2,7 +2,7 @@ doctype html
div.wrapper.roles(ng-controller="WebhooksController as ctrl", div.wrapper.roles(ng-controller="WebhooksController as ctrl",
ng-init="section='admin'") ng-init="section='admin'")
nav.menu.hidden(tg-project-menu) div(tg-project-menu)
sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="third-parties") sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="third-parties")
include ../includes/modules/admin-menu include ../includes/modules/admin-menu
sidebar.menu-tertiary.sidebar(tg-admin-navigation="third-parties-webhooks") sidebar.menu-tertiary.sidebar(tg-admin-navigation="third-parties-webhooks")

View File

@ -2,7 +2,7 @@ doctype html
div.wrapper(tg-backlog, ng-controller="BacklogController as ctrl", div.wrapper(tg-backlog, ng-controller="BacklogController as ctrl",
ng-init="section='backlog'") ng-init="section='backlog'")
nav.menu.hidden(tg-project-menu) div(tg-project-menu)
sidebar.menu-secondary.extrabar.filters-bar(tg-backlog-filters) sidebar.menu-secondary.extrabar.filters-bar(tg-backlog-filters)
include ../includes/modules/backlog-filters include ../includes/modules/backlog-filters
section.main.backlog section.main.backlog

View File

@ -1,7 +1,7 @@
doctype html doctype html
div.wrapper.roles(ng-init="section='admin'", ng-controller="ContribController as ctrl") div.wrapper.roles(ng-init="section='admin'", ng-controller="ContribController as ctrl")
nav.menu.hidden(tg-project-menu) div(tg-project-menu)
sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="contrib") sidebar.menu-secondary.sidebar.settings-nav(tg-admin-navigation="contrib")
include ../includes/modules/admin-menu include ../includes/modules/admin-menu

View File

@ -2,7 +2,7 @@ doctype html
div.wrapper(ng-controller="IssueDetailController as ctrl", div.wrapper(ng-controller="IssueDetailController as ctrl",
ng-init="section='issues'") ng-init="section='issues'")
nav.menu.hidden(tg-project-menu) div(tg-project-menu)
div.main.us-detail div.main.us-detail
div.us-detail-header.header-with-actions div.us-detail-header.header-with-actions
include ../includes/components/mainTitle include ../includes/components/mainTitle

View File

@ -1,7 +1,7 @@
doctype html doctype html
div.wrapper.issues(tg-issues, ng-controller="IssuesController as ctrl", ng-init="section='issues'") div.wrapper.issues(tg-issues, ng-controller="IssuesController as ctrl", ng-init="section='issues'")
nav.menu.hidden(tg-project-menu) div(tg-project-menu)
sidebar.menu-secondary.extrabar.filters-bar(tg-issues-filters) sidebar.menu-secondary.extrabar.filters-bar(tg-issues-filters)
include ../includes/modules/issues-filters include ../includes/modules/issues-filters

View File

@ -2,7 +2,7 @@ doctype html
div.wrapper(tg-kanban, ng-controller="KanbanController as ctrl" div.wrapper(tg-kanban, ng-controller="KanbanController as ctrl"
ng-init="section='kanban'") ng-init="section='kanban'")
nav.menu.hidden(tg-project-menu) div(tg-project-menu)
section.main.kanban section.main.kanban
include ../includes/components/mainTitle include ../includes/components/mainTitle
include ../includes/modules/kanban-table include ../includes/modules/kanban-table

View File

@ -1,7 +0,0 @@
div(tg-projects-pagination)
ul.projects-list
<% _.each(projects, function(project) { %>
li
a.button(href!='<%- project.url %>')
<%- project.name %>
<% }) %>

View File

@ -1,46 +0,0 @@
div(class="menu-container")
ul(class="main-nav")
li(id="nav-search")
a(href="", title="{{'PROJECT.SECTION.SEARCH' | translate}}", tabindex="1")
span(class="icon icon-search")
span.helper(translate="PROJECT.SECTION.SEARCH")
<% if (project.is_backlog_activated && project.my_permissions.indexOf("view_us") != -1) { %>
li(id="nav-backlog")
a(href="" title="{{'PROJECT.SECTION.BACKLOG' | translate}}" tg-nav="project-backlog:project=project.slug", tabindex="1")
span(class="icon icon-backlog")
span.helper(translate="PROJECT.SECTION.BACKLOG")
<% } %>
<% if (project.is_kanban_activated && project.my_permissions.indexOf("view_us") != -1) { %>
li(id="nav-kanban")
a(href="" title="{{'PROJECT.SECTION.KANBAN' | translate}}" tg-nav="project-kanban:project=project.slug", tabindex="1")
span(class="icon icon-kanban")
span.helper(translate="PROJECT.SECTION.KANBAN")
<% } %>
<% if (project.is_issues_activated && project.my_permissions.indexOf("view_issues") != -1) { %>
li(id="nav-issues")
a(href="" title="{{'PROJECT.SECTION.ISSUES' | translate}}" tg-nav="project-issues:project=project.slug", tabindex="1")
span(class="icon icon-issues")
span.helper(translate="PROJECT.SECTION.ISSUES")
<% } %>
<% if (project.is_wiki_activated && project.my_permissions.indexOf("view_wiki_pages") != -1) { %>
li(id="nav-wiki")
a(href="" title="{{'PROJECT.SECTION.WIKI' | translate}}" tg-nav="project-wiki:project=project.slug", tabindex="1")
span(class="icon icon-wiki")
span.helper(translate="PROJECT.SECTION.WIKI")
<% } %>
li(id="nav-team")
a(href="" title="{{'PROJECT.SECTION.TEAM' | translate}}" tg-nav="project-team:project=project.slug", tabindex="1")
span(class="icon icon-team")
span.helper(translate="PROJECT.SECTION.TEAM")
<% if (project.videoconferences) { %>
li(id="nav-video")
a(href!="<%- project.videoconferenceUrl %>" target="_blank" title="{{'PROJECT.SECTION.MEETUP' | translate}}", tabindex="1")
span(class="icon icon-video")
span.helper(translate="PROJECT.SECTION.MEETUP")
<% } %>
<% if (project.i_am_owner) { %>
li(id="nav-admin")
a(href="" tg-nav="project-admin-home:project=project.slug" title="{{'PROJECT.SECTION.ADMIN' | translate}}", tabindex="1")
span(class="icon icon-settings")
span.helper(translate="PROJECT.SECTION.ADMIN")
<% } %>

View File

@ -1,6 +0,0 @@
<% _.each(projects, function(project) { %>
li
a(href!="<%- project.url %>")
span(class="project-name") <%- project.name %>
span(class="icon icon-arrow-right")
<% }) %>

View File

@ -2,7 +2,7 @@ doctype html
div.wrapper(tg-search, ng-controller="SearchController as ctrl", div.wrapper(tg-search, ng-controller="SearchController as ctrl",
ng-init="section='search'") ng-init="section='search'")
nav.menu.hidden(tg-project-menu) div(tg-project-menu)
sidebar.menu-secondary.sidebar sidebar.menu-secondary.sidebar
include ../includes/modules/search-in include ../includes/modules/search-in

View File

@ -2,7 +2,7 @@ doctype html
div.wrapper(ng-controller="TaskDetailController as ctrl", div.wrapper(ng-controller="TaskDetailController as ctrl",
ng-init="section='backlog-kanban'") ng-init="section='backlog-kanban'")
nav.menu.hidden(tg-project-menu) div(tg-project-menu)
div.main.us-detail div.main.us-detail
div.us-detail-header.header-with-actions div.us-detail-header.header-with-actions
include ../includes/components/mainTitle include ../includes/components/mainTitle

View File

@ -2,7 +2,7 @@ doctype html
div.wrapper(tg-taskboard, ng-controller="TaskboardController as ctrl", div.wrapper(tg-taskboard, ng-controller="TaskboardController as ctrl",
ng-init="section='backlog'") ng-init="section='backlog'")
nav.menu.hidden(tg-project-menu) div(tg-project-menu)
section.main.taskboard section.main.taskboard
.taskboard-inner .taskboard-inner
h1 h1

View File

@ -1,7 +1,7 @@
doctype html doctype html
div.wrapper(ng-controller="TeamController as ctrl", ng-init="section='team'") div.wrapper(ng-controller="TeamController as ctrl", ng-init="section='team'")
nav.menu.hidden(tg-project-menu) div(tg-project-menu)
sidebar.menu-secondary sidebar.menu-secondary
include ../includes/modules/team/team-filters include ../includes/modules/team/team-filters
section.main.team section.main.team

View File

@ -2,7 +2,7 @@ doctype html
div.wrapper(ng-controller="UserStoryDetailController as ctrl", div.wrapper(ng-controller="UserStoryDetailController as ctrl",
ng-init="section='backlog-kanban'") ng-init="section='backlog-kanban'")
nav.menu.hidden(tg-project-menu) div(tg-project-menu)
div.main.us-detail div.main.us-detail
div.us-detail-header.header-with-actions div.us-detail-header.header-with-actions
include ../includes/components/mainTitle include ../includes/components/mainTitle

View File

@ -2,7 +2,7 @@ doctype html
div.wrapper(tg-user-notifications, ng-controller="UserNotificationsController as ctrl", div.wrapper(tg-user-notifications, ng-controller="UserNotificationsController as ctrl",
ng-init="section='mail-notifications'") ng-init="section='mail-notifications'")
nav.menu.hidden(tg-project-menu) div(tg-project-menu)
sidebar.menu-secondary.sidebar.settings-nav(tg-user-settings-navigation="mail-notifications") sidebar.menu-secondary.sidebar.settings-nav(tg-user-settings-navigation="mail-notifications")
include ../includes/modules/user-settings-menu include ../includes/modules/user-settings-menu

View File

@ -2,7 +2,7 @@ doctype html
div.wrapper(tg-user-change-password, ng-controller="UserChangePasswordController as ctrl", div.wrapper(tg-user-change-password, ng-controller="UserChangePasswordController as ctrl",
ng-init="section='user-settings'") ng-init="section='user-settings'")
nav.menu.hidden(tg-project-menu) div(tg-project-menu)
sidebar.menu-secondary.sidebar.settings-nav(tg-user-settings-navigation="change-password") sidebar.menu-secondary.sidebar.settings-nav(tg-user-settings-navigation="change-password")
include ../includes/modules/user-settings-menu include ../includes/modules/user-settings-menu

View File

@ -2,7 +2,7 @@ doctype html
div.wrapper(tg-user-profile, ng-controller="UserSettingsController as ctrl", div.wrapper(tg-user-profile, ng-controller="UserSettingsController as ctrl",
ng-init="section='user-settings'") ng-init="section='user-settings'")
nav.menu.hidden(tg-project-menu) div(tg-project-menu)
sidebar.menu-secondary.sidebar.settings-nav(tg-user-settings-navigation="user-profile") sidebar.menu-secondary.sidebar.settings-nav(tg-user-settings-navigation="user-profile")
include ../includes/modules/user-settings-menu include ../includes/modules/user-settings-menu

View File

@ -2,7 +2,7 @@ doctype html
div.wrapper(ng-controller="WikiDetailController as ctrl", div.wrapper(ng-controller="WikiDetailController as ctrl",
ng-init="section='wiki'") ng-init="section='wiki'")
nav.menu.hidden(tg-project-menu) div(tg-project-menu)
sidebar.menu-secondary.extrabar(tg-check-permission="view_wiki_links") sidebar.menu-secondary.extrabar(tg-check-permission="view_wiki_links")
section.wiki-nav(tg-wiki-nav, ng-model="wikiLinks") section.wiki-nav(tg-wiki-nav, ng-model="wikiLinks")
section.main.wiki section.main.wiki

View File

@ -21,8 +21,8 @@ $label-arrow-wh: 12px;
position: relative; position: relative;
} }
a:hover { a:hover {
//color: $fresh-taiga;
background: rgba($black, .2); background: rgba($black, .2);
color: $fresh-taiga;
transition: color .3s linear; transition: color .3s linear;
.helper { .helper {
@extend %small; @extend %small;