From 06866ff577ad735e376ed734a8fa51ec5ac33bb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20Barrag=C3=A1n=20Merino?= Date: Tue, 22 Jul 2014 14:20:22 +0200 Subject: [PATCH 1/3] List memberships --- app/coffee/app.coffee | 2 + app/coffee/modules/admin/memberships.coffee | 157 ++++++++++++++++++ app/coffee/modules/base.coffee | 11 +- app/coffee/modules/resources.coffee | 1 + .../modules/resources/memberships.coffee | 41 +++++ ...membership.jade => admin-memberships.jade} | 12 +- app/partials/views/modules/admin-menu.jade | 10 +- .../modules/admin/admin-membership-table.jade | 39 +---- 8 files changed, 225 insertions(+), 48 deletions(-) create mode 100644 app/coffee/modules/admin/memberships.coffee create mode 100644 app/coffee/modules/resources/memberships.coffee rename app/partials/{membership.jade => admin-memberships.jade} (56%) diff --git a/app/coffee/app.coffee b/app/coffee/app.coffee index 934c85b6..9805f9bd 100644 --- a/app/coffee/app.coffee +++ b/app/coffee/app.coffee @@ -63,6 +63,8 @@ configure = ($routeProvider, $locationProvider, $httpProvider, $provide) -> $routeProvider.when("/project/:pslug/admin/project-values/us-status", {templateUrl: "/partials/admin-project-values-us-status.html"}) + $routeProvider.when("/project/:pslug/admin/memberships", + {templateUrl: "/partials/admin-memberships.html"}) # Auth $routeProvider.when("/login", {templateUrl: "/partials/login.html"}) $routeProvider.when("/register", {templateUrl: "/partials/register.html"}) diff --git a/app/coffee/modules/admin/memberships.coffee b/app/coffee/modules/admin/memberships.coffee new file mode 100644 index 00000000..f2234e0b --- /dev/null +++ b/app/coffee/modules/admin/memberships.coffee @@ -0,0 +1,157 @@ +### +# Copyright (C) 2014 Andrey Antukh +# Copyright (C) 2014 Jesús Espino Garcia +# Copyright (C) 2014 David Barragán Merino +# +# 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 . +# +# File: modules/admin/project-profile.coffee +### + +taiga = @.taiga + +mixOf = @.taiga.mixOf + +module = angular.module("taigaAdmin") + + +############################################################################# +## Project Memberships Controller +############################################################################# + +class MembershipsController extends mixOf(taiga.Controller, taiga.PageMixin) + @.$inject = [ + "$scope", + "$rootScope", + "$tgRepo", + "$tgConfirm", + "$tgResources", + "$routeParams", + "$q", + "$location" + ] + + constructor: (@scope, @rootscope, @repo, @confirm, @rs, @params, @q, @location) -> + _.bindAll(@) + + @scope.sectionName = "Memberships" + + promise = @.loadInitialData() + promise.then null, -> + console.log "FAIL" #TODO + + loadProject: -> + return @rs.projects.get(@scope.projectId).then (project) => + @scope.project = project + return project + + loadMembers: -> + return @rs.memberships.list(@scope.projectId).then (data) => + @scope.memberships = data.models + return data + + loadInitialData: -> + promise = @repo.resolve({pslug: @params.pslug}).then (data) => + @scope.projectId = data.project + return data + + return promise.then(=> @.loadProject()) + .then(=> @.loadMembers()) + + +module.controller("MembershipsController", MembershipsController) + + +############################################################################# +## Member Avatar Directive +############################################################################# + +MembershipsMemberAvatarDirective = ($log) -> + template = _.template(""" +
+ <%- full_name %> +
+ <%- full_name %> + +
+
+ """) + + render = (member) -> + ctx = { + full_name: if member.full_name then member.full_name else "------" + email: member.email + imgurl: if member.photo then member.photo else "http://thecodeplayer.com/u/uifaces/12.jpg" + } + + return template(ctx) + + link = ($scope, $el, $attrs) -> + if not $attrs.tgMembershipsMemberAvatar? + return $log.error "MembershipsMemberAvatarDirective: the directive need a member" + + member = $scope.$eval($attrs.tgMembershipsMemberAvatar) + html = render(member) + $el.html(html) + + return { + link: link + } + + +module.directive("tgMembershipsMemberAvatar", ["$log", MembershipsMemberAvatarDirective]) + + +############################################################################# +## Member Actions Directive +############################################################################# + +MembershipsMemberActionsDirective = ($log) -> + activedTemplate = _.template(""" +
+ Active +
+ + + + """) + pendingTemplate = _.template(""" + + Pending + + + + + + """) + + render = (member) -> + if member.user + return activedTemplate() + return pendingTemplate() + + link = ($scope, $el, $attrs) -> + if not $attrs.tgMembershipsMemberActions? + return $log.error "MembershipsMemberActionsDirective: the directive need a member" + + member = $scope.$eval($attrs.tgMembershipsMemberActions) + html = render(member) + $el.html(html) + + return { + link: link + } + + +module.directive("tgMembershipsMemberActions", ["$log", MembershipsMemberActionsDirective]) diff --git a/app/coffee/modules/base.coffee b/app/coffee/modules/base.coffee index d6cc4440..e30c4a2d 100644 --- a/app/coffee/modules/base.coffee +++ b/app/coffee/modules/base.coffee @@ -51,14 +51,13 @@ urls = { "invitation": "/invitation/:token", "profile": "/:user", + "project": "/project/:project", "project-backlog": "/project/:project/backlog", "project-taskboard": "/project/:project/taskboard/:sprint", "project-kanban": "/project/:project/kanban", "project-issues": "/project/:project/issues", "project-search": "/project/:project/search", - "project-issues-detail": "/project/:project/issues/:ref", - "project-issues-detail-edit": "/project/:project/issues/:ref/edit", "project-userstories-detail": "/project/:project/us/:ref", "project-userstories-detail-edit": "/project/:project/us/:ref/edit", @@ -66,12 +65,16 @@ urls = { "project-tasks-detail": "/project/:project/tasks/:ref", "project-tasks-detail-edit": "/project/:project/tasks/:ref/edit", + "project-issues-detail": "/project/:project/issues/:ref", + "project-issues-detail-edit": "/project/:project/issues/:ref/edit", + # Admin "project-admin-home": "/project/:project/admin/project-profile/details", "project-admin-project-profile-details": "/project/:project/admin/project-profile/details", "project-admin-project-profile-default-values": "/project/:project/admin/project-profile/default-values", - "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-profile-features": "/project/:project/admin/project-profile/features", + "project-admin-project-values-us-status": "/project/:project/admin/project-values/us-status", + "project-admin-memberships": "/project/:project/admin/memberships" } init = ($log, $navurls) -> diff --git a/app/coffee/modules/resources.coffee b/app/coffee/modules/resources.coffee index 40ee8859..716ebe5a 100644 --- a/app/coffee/modules/resources.coffee +++ b/app/coffee/modules/resources.coffee @@ -106,6 +106,7 @@ module.run([ "$log", "$tgResources", "$tgProjectsResourcesProvider", + "$tgMembershipsResourcesProvider", "$tgSprintsResourcesProvider", "$tgUserstoriesResourcesProvider", "$tgTasksResourcesProvider", diff --git a/app/coffee/modules/resources/memberships.coffee b/app/coffee/modules/resources/memberships.coffee new file mode 100644 index 00000000..f9ab2b75 --- /dev/null +++ b/app/coffee/modules/resources/memberships.coffee @@ -0,0 +1,41 @@ +### +# Copyright (C) 2014 Andrey Antukh +# Copyright (C) 2014 Jesús Espino Garcia +# Copyright (C) 2014 David Barragán Merino +# +# 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 . +# +# File: modules/resources/memberships.coffee +### + + +taiga = @.taiga + +resourceProvider = ($repo) -> + service = {} + + service.get = (id) -> + return $repo.queryOne("memberships", id) + + service.list = (projectId, filters) -> + params = {project: projectId} + params = _.extend({}, params, filters or {}) + return $repo.queryPaginated("memberships", params) + + return (instance) -> + instance.memberships = service + + +module = angular.module("taigaResources") +module.factory("$tgMembershipsResourcesProvider", ["$tgRepo", resourceProvider]) diff --git a/app/partials/membership.jade b/app/partials/admin-memberships.jade similarity index 56% rename from app/partials/membership.jade rename to app/partials/admin-memberships.jade index 9c5aa7fb..d3665e1e 100644 --- a/app/partials/membership.jade +++ b/app/partials/admin-memberships.jade @@ -1,18 +1,20 @@ -extends layout +extends dummy-layout block head title Taiga Project management web application with scrum in mind! block content - div.wrapper - sidebar.menu-secondary.sidebar + div.wrapper(ng-controller="MembershipsController as ctrl", + ng-init="section='admin'") + sidebar.menu-secondary.sidebar(tg-admin-navigation="memberships") include views/modules/admin-menu section.main.admin-membership header include views/components/mainTitle - a.button.button-green(title="Add New US" href="") - span.text + New role + + a.button.button-green(title="Add new member" href="") + span.text + New member include views/modules/admin/admin-membership-table diff --git a/app/partials/views/modules/admin-menu.jade b/app/partials/views/modules/admin-menu.jade index e8e35106..eb6353e8 100644 --- a/app/partials/views/modules/admin-menu.jade +++ b/app/partials/views/modules/admin-menu.jade @@ -8,15 +8,15 @@ section.admin-menu a(href="", tg-nav="project-admin-project-profile-details:project=project.slug") span.title Project profile span.icon.icon-arrow-right + li#adminmenu-project-values + a(href="", tg-nav="project-admin-project-values-us-status:project=project.slug") + span.title Project values + span.icon.icon-arrow-right li#adminmenu-memberships - a(href="") + a(href="" tg-nav="project-admin-memberships:project=project.slug") span.title Memberships span.icon.icon-arrow-right li#adminmenu-roles a(href="") span.title Roles span.icon.icon-arrow-right - li#adminmenu-project-values - a(href="", tg-nav="project-admin-project-values-us-status:project=project.slug") - span.title Project values - span.icon.icon-arrow-right diff --git a/app/partials/views/modules/admin/admin-membership-table.jade b/app/partials/views/modules/admin/admin-membership-table.jade index 885f16ed..0a53b2fe 100644 --- a/app/partials/views/modules/admin/admin-membership-table.jade +++ b/app/partials/views/modules/admin/admin-membership-table.jade @@ -4,44 +4,15 @@ section.admin-membership-table.basic-table div.header-admin Admin div.header-role Role div.header-status Status - div.row - div.row-member - figure.avatar - img(alt="username" src="http://thecodeplayer.com/u/uifaces/12.jpg") - figcaption - span.name Pilar - span.email pilar.estaban@secuoyas.com - div.row-admin - input(type="checkbox", id="is-admin") - label(for="is-admin") Is admin? - div.row-role - select - option UX - option Front - option Back - div.row-status - div.active Active - a(href="#").delete - span.icon.icon-delete - div.row - div.row-member - figure.avatar - img(alt="username" src="http://thecodeplayer.com/u/uifaces/12.jpg") - figcaption - span.name Pilar - span.email pilar.estaban@secuoyas.com + div.row(ng-repeat="member in memberships") + div.row-member(tg-memberships-member-avatar="member") div.row-admin - input(type="checkbox", id="is-admin") + input(type="checkbox", id="is-admin" ng-model="member.is_admin") label(for="is-admin") Is admin? div.row-role - select + select(ng-model="member.role") option UX option Front option Back - div.row-status - a(href="#").pending - | Pending - span.icon.icon-reload - a(href="#").delete - span.icon.icon-delete + div.row-status(tg-memberships-member-actions="member") From edcc03cc65b75249cc06c6efd36c8e040ace4c1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xavier=20Juli=C3=A1n?= Date: Tue, 22 Jul 2014 14:29:06 +0200 Subject: [PATCH 2/3] Select color popover predefined colors --- .../views/components/select-color.jade | 24 +++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/app/partials/views/components/select-color.jade b/app/partials/views/components/select-color.jade index 9fc3db61..92f86e6f 100644 --- a/app/partials/views/components/select-color.jade +++ b/app/partials/views/components/select-color.jade @@ -1,6 +1,26 @@ div.popover.select-color ul - - for (var z = 0; z < 21; z++) - li.color + li.color(style="background: #fce94f") + li.color(style="background: #edd400") + li.color(style="background: #c4a000") + li.color(style="background: #8ae234") + li.color(style="background: #73d216") + li.color(style="background: #4e9a06") + li.color(style="background: #d3d7cf") + li.color(style="background: #fcaf3e") + li.color(style="background: #f57900") + li.color(style="background: #ce5c00") + li.color(style="background: #729fcf") + li.color(style="background: #3465a4") + li.color(style="background: #204a87") + li.color(style="background: #888a85") + li.color(style="background: #ad7fa8") + li.color(style="background: #75507b") + li.color(style="background: #5c3566") + li.color(style="background: #ef2929") + li.color(style="background: #cc0000") + li.color(style="background: #a40000") + li.color(style="background: #2e3436") + input(type="text", placeholder="personalized colors") div.selected-color(style="background-color: red") From d4186c4180d2fcc503f512c122e8ae8dda197c0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Xavier=20Juli=C3=A1n?= Date: Tue, 22 Jul 2014 14:52:12 +0200 Subject: [PATCH 3/3] User notifications by mail template --- app/partials/mail-notifications.jade | 18 +++++++ .../mail-notifications-table.jade | 27 ++++++++++ app/styles/layout/mail-notifications.scss | 0 app/styles/main.scss | 3 ++ .../mail-notifications-table.scss | 49 +++++++++++++++++++ 5 files changed, 97 insertions(+) create mode 100644 app/partials/mail-notifications.jade create mode 100644 app/partials/views/modules/user-settings/mail-notifications-table.jade create mode 100644 app/styles/layout/mail-notifications.scss create mode 100644 app/styles/modules/user-settings/mail-notifications-table.scss diff --git a/app/partials/mail-notifications.jade b/app/partials/mail-notifications.jade new file mode 100644 index 00000000..b53ed1ba --- /dev/null +++ b/app/partials/mail-notifications.jade @@ -0,0 +1,18 @@ +extends layout + +block head + title Taiga Project management web application with scrum in mind! + +block content + div.wrapper(tg-project-us-status, ng-controller="ProjectValuesController as ctrl", + ng-init="section='admin'") + sidebar.menu-secondary.sidebar(tg-admin-navigation="project-values") + include views/modules/admin-menu + + section.main.admin-roles + header + include views/components/mainTitle + + p.total Notifications By Mail + + include views/modules/user-settings/mail-notifications-table diff --git a/app/partials/views/modules/user-settings/mail-notifications-table.jade b/app/partials/views/modules/user-settings/mail-notifications-table.jade new file mode 100644 index 00000000..aa16a5e1 --- /dev/null +++ b/app/partials/views/modules/user-settings/mail-notifications-table.jade @@ -0,0 +1,27 @@ +section.mail-notifications-table + div.mail-notifications-table-header + div.mail-notifications-table-row + div.mail-notifications-table-project + span Project + div.mail-notifications-table-all + span Receive All + div.mail-notifications-table-involved + span Only Involved + div.mail-notifications-table-none + span No notifications + div.mail-notifications-table-body + div.mail-notifications-table-row + div.mail-notifications-table-project + span Decathlon + div.mail-notifications-table-all + fieldset + input(type="radio", name="mail-notifications", id="notifications-all") + label(for="notifications-all") All + div.mail-notifications-table-involved + fieldset + input(type="radio", name="mail-notifications", id="notifications-involved") + label(for="notifications-involved") Involved + div.mail-notifications-table-none + fieldset + input(type="radio", name="mail-notifications", id="notifications-none") + label(for="notifications-none") None diff --git a/app/styles/layout/mail-notifications.scss b/app/styles/layout/mail-notifications.scss new file mode 100644 index 00000000..e69de29b diff --git a/app/styles/main.scss b/app/styles/main.scss index 5b049527..76db945e 100755 --- a/app/styles/main.scss +++ b/app/styles/main.scss @@ -74,6 +74,9 @@ $prefix-for-spec: true; @import 'modules/admin/default-values'; @import 'modules/admin/project-values'; +//Modules user Settings +@import 'modules/user-settings/mail-notifications-table'; + //Layout @import 'layout/base'; @import 'layout/login'; diff --git a/app/styles/modules/user-settings/mail-notifications-table.scss b/app/styles/modules/user-settings/mail-notifications-table.scss new file mode 100644 index 00000000..aff935ad --- /dev/null +++ b/app/styles/modules/user-settings/mail-notifications-table.scss @@ -0,0 +1,49 @@ +.mail-notifications-table { + .mail-notifications-table-row { + @include table-flex(stretch, center, flex, row, wrap, center); + border-bottom: 1px solid $whitish; + } + + .mail-notifications-table-header { + @extend %bold; + border-bottom: 2px solid $gray-light; + } + + .mail-notifications-table-project , + .mail-notifications-table-all, + .mail-notifications-table-involved, + .mail-notifications-table-none { + padding: 1rem; + } + + .mail-notifications-table-project { + @include table-flex-child(3, 0, 0); + } + + .mail-notifications-table-all, + .mail-notifications-table-involved, + .mail-notifications-table-none { + @include table-flex-child(1, 0, 0); + } + input { + display: none; + &:checked { + +label { + @include transition(background .3s linear); + background: $green-taiga; + } + } + } + label { + background: $gray-light; + border-radius: 5px; + color: $white; + display: block; + padding: .5rem; + &:hover { + @include transition(background .3s linear); + background: $fresh-taiga; + cursor: pointer; + } + } +}