diff --git a/app/coffee/app.coffee b/app/coffee/app.coffee index f5c58e35..e708957a 100644 --- a/app/coffee/app.coffee +++ b/app/coffee/app.coffee @@ -94,6 +94,8 @@ configure = ($routeProvider, $locationProvider, $httpProvider, $provide, $tgEven {templateUrl: "/partials/admin-memberships.html"}) $routeProvider.when("/project/:pslug/admin/roles", {templateUrl: "/partials/admin-roles.html"}) + $routeProvider.when("/project/:pslug/admin/third-parties/github", + {templateUrl: "/partials/admin-third-parties-github.html"}) # User settings $routeProvider.when("/project/:pslug/user-settings/user-profile", diff --git a/app/coffee/modules/admin/third-parties.coffee b/app/coffee/modules/admin/third-parties.coffee new file mode 100644 index 00000000..80abf881 --- /dev/null +++ b/app/coffee/modules/admin/third-parties.coffee @@ -0,0 +1,87 @@ +### +# 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/memberships.coffee +### + +taiga = @.taiga + +mixOf = @.taiga.mixOf +bindOnce = @.taiga.bindOnce +debounce = @.taiga.debounce + +module = angular.module("taigaAdmin") + + +############################################################################# +## Github Controller +############################################################################# + +class GithubController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.FiltersMixin) + @.$inject = [ + "$scope", + "$tgRepo", + "$tgResources", + "$routeParams", + "$q", + "$tgNavUrls", + "$appTitle" + ] + + constructor: (@scope, @repo, @rs, @params, @q, @navUrls, @appTitle) -> + _.bindAll(@) + + @scope.sectionName = "Github" #i18n + @scope.project = {} + @scope.anyComputableRole = true + + promise = @.loadInitialData() + + promise.then () => + @appTitle.set("Github - " + @scope.project.name) + + promise.then null, @.onInitialDataError.bind(@) + + loadProject: -> + return @rs.projects.get(@scope.projectId).then (project) => + @scope.project = project + @scope.$emit('project:loaded', project) + @scope.anyComputableRole = _.some(_.map(project.roles, (point) -> point.computable)) + + return project + + loadInitialData: -> + promise = @repo.resolve({pslug: @params.pslug}).then (data) => + @scope.projectId = data.project + return data + + return promise.then(=> @.loadProject()) + + +module.controller("GithubController", GithubController) + + +SelectInputText = -> + link = ($scope, $el, $attrs) -> + $el.on "click", ".select-input-content", () -> + $el.find("input").select() + $el.find(".help-copy").addClass("visible") + + return {link:link} + +module.directive("tgSelectInputText", SelectInputText) diff --git a/app/coffee/modules/base.coffee b/app/coffee/modules/base.coffee index 8310d95c..3aeb6e99 100644 --- a/app/coffee/modules/base.coffee +++ b/app/coffee/modules/base.coffee @@ -89,6 +89,7 @@ urls = { "project-admin-project-values-issue-severities": "/project/:project/admin/project-values/issue-severities" "project-admin-memberships": "/project/:project/admin/memberships" "project-admin-roles": "/project/:project/admin/roles" + "project-admin-third-parties-github": "/project/:project/admin/third-parties/github" # User settings "user-settings-user-profile": "/project/:project/user-settings/user-profile" diff --git a/app/images/github-help.png b/app/images/github-help.png new file mode 100644 index 00000000..43c64f77 Binary files /dev/null and b/app/images/github-help.png differ diff --git a/app/partials/admin-third-parties-github.jade b/app/partials/admin-third-parties-github.jade new file mode 100644 index 00000000..f2d255a5 --- /dev/null +++ b/app/partials/admin-third-parties-github.jade @@ -0,0 +1,88 @@ +block head + title Taiga Your agile, free, and open source project management tool + +block content + div.wrapper.roles(ng-controller="GithubController as ctrl", + ng-init="section='admin'") + sidebar.menu-secondary.sidebar(tg-admin-navigation="third-parties") + include views/modules/admin-menu + sidebar.menu-tertiary.sidebar(tg-admin-navigation="third-parties-github") + include views/modules/admin-submenu-third-parties + + section.main.admin-common.admin-third-parties + include views/components/mainTitle + + form + fieldset + label(for="secret-key") Secret key + input(type="text", name="secret-key", placeholder="Secret key", id="secret-key") + + fieldset + .select-input-text(tg-select-input-text) + div + label(for="payload-url") Payload URL + .field-with-option + input(type="text", name="payload-url", readonly="readonly", placeholder="Payload URL", id="payload-url") + .option-wrapper.select-input-content + .icon.icon-copy + .help-copy Copy to clipboard: Ctrl+C + + input(type="submit", class="hidden") + a.button.button-green(href="") Save + + + .help + h2 How to use it + + h3 Configure Taiga + ol + li Fill + span Secret key. + li Copy the + span Payload URL field. + + h3 Configure Github + ol + li Go to your github repository. + li Click on + span Settings + | > + span Webhooks + | > + span Services + | > + span Add webhook + + li On that screen set the payload url with the payload url of this screen. + li Secret must be filled with the same content as the secret field of this screen. + li Content type must be + span application/json. + li You must check + span "Send me everything". + + .img + .alt-image Github Webhooke page + img(src="/images/github-help.png", alt="webhook") + + h3 Commit message + + p The commits message must have this command. + + code + | TG-REF #STATUS + + ul.code-info + li + span REF + | US/Issue/Task reference + li + span STATUS + | Status slug, you can get the status slug in + a(href="", tg-nav="project-admin-project-values-us-status:project=project.slug") US STATUSES. + + h3 Example + + code + | TG-123 #closed + + p In this example, 123 is an issue and with this command, the issue will change its status to closed. diff --git a/app/partials/views/modules/admin-menu.jade b/app/partials/views/modules/admin-menu.jade index 14cfaef4..198667f3 100644 --- a/app/partials/views/modules/admin-menu.jade +++ b/app/partials/views/modules/admin-menu.jade @@ -20,3 +20,7 @@ section.admin-menu a(href="" tg-nav="project-admin-roles:project=project.slug") span.title Roles & Permissions span.icon.icon-arrow-right + li#adminmenu-third-parties + a(href="" tg-nav="project-admin-third-parties-github:project=project.slug") + span.title Third parties + span.icon.icon-arrow-right diff --git a/app/partials/views/modules/admin-submenu-third-parties.jade b/app/partials/views/modules/admin-submenu-third-parties.jade new file mode 100644 index 00000000..95746408 --- /dev/null +++ b/app/partials/views/modules/admin-submenu-third-parties.jade @@ -0,0 +1,10 @@ +section.admin-submenu + header + h1 Third parties + + nav + ul + li#adminmenu-third-parties-github + a(href="", tg-nav="project-admin-third-parties-github:project=project.slug") + span.title Github + span.icon.icon-arrow-right diff --git a/app/styles/modules/admin/third-parties.scss b/app/styles/modules/admin/third-parties.scss new file mode 100644 index 00000000..1baf83ea --- /dev/null +++ b/app/styles/modules/admin/third-parties.scss @@ -0,0 +1,91 @@ +.admin-third-parties { + form { + margin-top: 1rem; + max-width: 700px; + width: 100%; + } + input[type="text"], + textarea { + @extend %title; + } + fieldset { + margin-bottom: 1rem; + } + label { + @extend %title; + display: block; + margin-bottom: .2rem; + } + textarea { + height: 10rem; + } + .button-green { + color: $white; + display: block; + text-align: center; + } + .select-input-text { + .field-with-option { + @include display(flex); + } + .option-wrapper { + @include display(flex); + @include align-items(center); + border: 1px solid $gray-light; + border-left: 0; + border-radius: 0 5px 5px 0; + cursor: pointer; + padding: 0 1rem; + } + .help-copy { + @extend %small; + opacity: 0; + &.visible { + @include transition(opacity .2s linear); + opacity: 1; + } + } + } + .help { + margin-top: 2rem; + h3 { + font-family: opensans-semibold; + margin-bottom: 1rem; + } + ol { + padding: 0 0 0 2rem; + span { + font-family: opensans-semibold; + } + } + .img { + margin-bottom: 1rem; + } + .alt-image { + @extend %small; + font-style: italic; + } + code { + @extend %small; + background: $whitish; + direction: ltr; + display: block; + font-family: 'courier new', 'monospace'; + line-height: 1.4rem; + margin-bottom: 1rem; + padding: .5rem; + unicode-bidi: embed; + white-space: pre; + width: 100%; + } + .code-info { + padding-left: 1rem; + li { + margin-bottom: .5rem; + } + span { + font-family: opensans-semibold; + } + } + } +} diff --git a/main-sass.js b/main-sass.js index b3ebd1da..8571274b 100644 --- a/main-sass.js +++ b/main-sass.js @@ -120,6 +120,7 @@ exports.files = function () { 'modules/admin/admin-project-profile', 'modules/admin/default-values', 'modules/admin/project-values', + 'modules/admin/third-parties', //Modules user Settings 'modules/user-settings/user-profile',