Webhook responses
parent
cdca5a2553
commit
7585ad3450
|
@ -3,6 +3,8 @@
|
||||||
## 1.5.0 Betula Pendula - FOSDEM 2015 (unreleased)
|
## 1.5.0 Betula Pendula - FOSDEM 2015 (unreleased)
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
- Taiga webhooks
|
||||||
|
+ Created admin panel with webhook settings.
|
||||||
- Not showing closed milestones by default in backlog view.
|
- Not showing closed milestones by default in backlog view.
|
||||||
- In kanban view an archived user story status doesn't show his content by default.
|
- In kanban view an archived user story status doesn't show his content by default.
|
||||||
- Now you can export and import projects between Taiga instances.
|
- Now you can export and import projects between Taiga instances.
|
||||||
|
|
|
@ -24,9 +24,239 @@ taiga = @.taiga
|
||||||
mixOf = @.taiga.mixOf
|
mixOf = @.taiga.mixOf
|
||||||
bindMethods = @.taiga.bindMethods
|
bindMethods = @.taiga.bindMethods
|
||||||
debounce = @.taiga.debounce
|
debounce = @.taiga.debounce
|
||||||
|
timeout = @.taiga.timeout
|
||||||
|
|
||||||
module = angular.module("taigaAdmin")
|
module = angular.module("taigaAdmin")
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
## Webhooks
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
class WebhooksController extends mixOf(taiga.Controller, taiga.PageMixin, taiga.FiltersMixin)
|
||||||
|
@.$inject = [
|
||||||
|
"$scope",
|
||||||
|
"$tgRepo",
|
||||||
|
"$tgResources",
|
||||||
|
"$routeParams",
|
||||||
|
"$appTitle"
|
||||||
|
]
|
||||||
|
|
||||||
|
constructor: (@scope, @repo, @rs, @params, @appTitle) ->
|
||||||
|
bindMethods(@)
|
||||||
|
|
||||||
|
@scope.sectionName = "Webhooks" #i18n
|
||||||
|
@scope.project = {}
|
||||||
|
|
||||||
|
promise = @.loadInitialData()
|
||||||
|
|
||||||
|
promise.then () =>
|
||||||
|
@appTitle.set("Webhooks - " + @scope.project.name)
|
||||||
|
|
||||||
|
promise.then null, @.onInitialDataError.bind(@)
|
||||||
|
|
||||||
|
@scope.$on "webhooks:reload", @.loadWebhooks
|
||||||
|
|
||||||
|
loadWebhooks: ->
|
||||||
|
return @rs.webhooks.list(@scope.projectId).then (webhooks) =>
|
||||||
|
@scope.webhooks = webhooks
|
||||||
|
|
||||||
|
loadProject: ->
|
||||||
|
return @rs.projects.get(@scope.projectId).then (project) =>
|
||||||
|
@scope.project = project
|
||||||
|
@scope.$emit('project:loaded', project)
|
||||||
|
return project
|
||||||
|
|
||||||
|
loadInitialData: ->
|
||||||
|
promise = @repo.resolve({pslug: @params.pslug}).then (data) =>
|
||||||
|
@scope.projectId = data.project
|
||||||
|
return data
|
||||||
|
|
||||||
|
return promise.then(=> @.loadProject())
|
||||||
|
.then(=> @.loadWebhooks())
|
||||||
|
|
||||||
|
module.controller("WebhooksController", WebhooksController)
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
## Webhook Directive
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
WebhookDirective = ($rs, $repo, $confirm, $loading) ->
|
||||||
|
link = ($scope, $el, $attrs) ->
|
||||||
|
webhook = $scope.$eval($attrs.tgWebhook)
|
||||||
|
|
||||||
|
updateLogs = () ->
|
||||||
|
$rs.webhooklogs.list(webhook.id).then (webhooklogs) =>
|
||||||
|
webhooklogs = webhooklogs.reverse()
|
||||||
|
for log in webhooklogs
|
||||||
|
statusText = String(log.status)
|
||||||
|
log.validStatus = statusText.length==3 and statusText[0]="2"
|
||||||
|
log.prettySentData = JSON.stringify(log.request_data.data, undefined, 2)
|
||||||
|
log.prettySentHeaders = JSON.stringify(log.request_headers, undefined, 2)
|
||||||
|
log.prettyDate = moment(log.created).format("DD MMM YYYY [at] hh:mm:ss")
|
||||||
|
|
||||||
|
webhook.logs = webhooklogs
|
||||||
|
updateShowHideHistoryText()
|
||||||
|
|
||||||
|
updateShowHideHistoryText = () ->
|
||||||
|
textElement = $el.find(".toggle-history")
|
||||||
|
historyElement = textElement.parents(".single-webhook-wrapper").find(".webhooks-history")
|
||||||
|
if historyElement.hasClass("open")
|
||||||
|
textElement.text("(Hide history)")
|
||||||
|
else
|
||||||
|
textElement.text("(Show history)")
|
||||||
|
|
||||||
|
showVisualizationMode = () ->
|
||||||
|
$el.find(".edition-mode").addClass("hidden")
|
||||||
|
$el.find(".visualization-mode").removeClass("hidden")
|
||||||
|
|
||||||
|
showEditMode = () ->
|
||||||
|
$el.find(".visualization-mode").addClass("hidden")
|
||||||
|
$el.find(".edition-mode").removeClass("hidden")
|
||||||
|
|
||||||
|
cancel = () ->
|
||||||
|
showVisualizationMode()
|
||||||
|
$scope.$apply ->
|
||||||
|
webhook.revert()
|
||||||
|
|
||||||
|
save = debounce 2000, (target) ->
|
||||||
|
form = target.parents("form").checksley()
|
||||||
|
return if not form.validate()
|
||||||
|
|
||||||
|
value = target.scope().value
|
||||||
|
promise = $repo.save(webhook)
|
||||||
|
promise.then =>
|
||||||
|
showVisualizationMode()
|
||||||
|
|
||||||
|
promise.then null, (data) ->
|
||||||
|
$confirm.notify("error")
|
||||||
|
form.setErrors(data)
|
||||||
|
|
||||||
|
$el.on "click", ".test-webhook", () ->
|
||||||
|
$rs.webhooks.test(webhook.id).then =>
|
||||||
|
updateLogs()
|
||||||
|
$el.find(".webhooks-history").addClass("open")
|
||||||
|
updateShowHideHistoryText()
|
||||||
|
|
||||||
|
$el.on "click", ".edit-webhook", () ->
|
||||||
|
showEditMode()
|
||||||
|
|
||||||
|
$el.on "click", ".cancel-existing", () ->
|
||||||
|
cancel()
|
||||||
|
|
||||||
|
$el.on "click", ".edit-existing", (event) ->
|
||||||
|
event.preventDefault()
|
||||||
|
target = angular.element(event.currentTarget)
|
||||||
|
save(target)
|
||||||
|
|
||||||
|
$el.on "keyup", ".edition-mode input", (event) ->
|
||||||
|
if event.keyCode == 13
|
||||||
|
target = angular.element(event.currentTarget)
|
||||||
|
saveWebhook(target)
|
||||||
|
else if event.keyCode == 27
|
||||||
|
target = angular.element(event.currentTarget)
|
||||||
|
cancel(target)
|
||||||
|
|
||||||
|
$el.on "click", ".delete-webhook", () ->
|
||||||
|
title = "Delete webhook" #TODO: i18in
|
||||||
|
message = "Webhook '#{webhook.name}'" #TODO: i18in
|
||||||
|
|
||||||
|
$confirm.askOnDelete(title, message).then (finish) =>
|
||||||
|
onSucces = ->
|
||||||
|
finish()
|
||||||
|
$scope.$emit("webhooks:reload")
|
||||||
|
|
||||||
|
onError = ->
|
||||||
|
finish(false)
|
||||||
|
$confirm.notify("error")
|
||||||
|
|
||||||
|
$repo.remove(webhook).then(onSucces, onError)
|
||||||
|
|
||||||
|
$el.on "click", ".toggle-history", (event) ->
|
||||||
|
target = angular.element(event.currentTarget)
|
||||||
|
if not webhook.logs? or webhook.logs.length == 0
|
||||||
|
updateLogs().then ->
|
||||||
|
#Waiting for ng-repeat to finish
|
||||||
|
timeout 0, ->
|
||||||
|
$el.find(".webhooks-history").toggleClass("open")
|
||||||
|
updateShowHideHistoryText()
|
||||||
|
|
||||||
|
else
|
||||||
|
$el.find(".webhooks-history").toggleClass("open")
|
||||||
|
$scope.$apply () ->
|
||||||
|
updateShowHideHistoryText()
|
||||||
|
|
||||||
|
|
||||||
|
$el.on "click", ".history-single", (event) ->
|
||||||
|
target = angular.element(event.currentTarget)
|
||||||
|
target.toggleClass("history-single-open")
|
||||||
|
target.siblings(".history-single-response").toggleClass("open")
|
||||||
|
|
||||||
|
$el.on "click", ".resend-request", (event) ->
|
||||||
|
target = angular.element(event.currentTarget)
|
||||||
|
log = target.data("log")
|
||||||
|
$rs.webhooklogs.resend(log).then () =>
|
||||||
|
updateLogs()
|
||||||
|
|
||||||
|
return {link:link}
|
||||||
|
|
||||||
|
module.directive("tgWebhook", ["$tgResources", "$tgRepo", "$tgConfirm", "$tgLoading", WebhookDirective])
|
||||||
|
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
## New webhook Directive
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
NewWebhookDirective = ($rs, $repo, $confirm, $loading) ->
|
||||||
|
link = ($scope, $el, $attrs) ->
|
||||||
|
webhook = $scope.$eval($attrs.tgWebhook)
|
||||||
|
formDOMNode = $el.find(".new-webhook-form")
|
||||||
|
addWebhookDOMNode = $el.find(".add-webhook")
|
||||||
|
initializeNewValue = ->
|
||||||
|
$scope.newValue = {
|
||||||
|
"name": ""
|
||||||
|
"url": ""
|
||||||
|
"key": ""
|
||||||
|
}
|
||||||
|
|
||||||
|
initializeNewValue()
|
||||||
|
|
||||||
|
$scope.$watch "webhooks", (webhooks) ->
|
||||||
|
if webhooks?
|
||||||
|
if webhooks.length == 0
|
||||||
|
formDOMNode.removeClass("hidden")
|
||||||
|
addWebhookDOMNode.addClass("hidden")
|
||||||
|
formDOMNode.find("input")[0].focus()
|
||||||
|
else
|
||||||
|
formDOMNode.addClass("hidden")
|
||||||
|
addWebhookDOMNode.removeClass("hidden")
|
||||||
|
|
||||||
|
formDOMNode.on "click", ".add-new", debounce 2000, (event) ->
|
||||||
|
event.preventDefault()
|
||||||
|
form = formDOMNode.checksley()
|
||||||
|
return if not form.validate()
|
||||||
|
|
||||||
|
$scope.newValue.project = $scope.project.id
|
||||||
|
promise = $repo.create("webhooks", $scope.newValue)
|
||||||
|
promise.then =>
|
||||||
|
$scope.$emit("webhooks:reload")
|
||||||
|
initializeNewValue()
|
||||||
|
|
||||||
|
promise.then null, (data) ->
|
||||||
|
$confirm.notify("error")
|
||||||
|
form.setErrors(data)
|
||||||
|
|
||||||
|
formDOMNode.on "click", ".cancel-new", (event) ->
|
||||||
|
$scope.$apply ->
|
||||||
|
initializeNewValue()
|
||||||
|
|
||||||
|
addWebhookDOMNode.on "click", (event) ->
|
||||||
|
formDOMNode.removeClass("hidden")
|
||||||
|
formDOMNode.find("input")[0].focus()
|
||||||
|
|
||||||
|
return {link:link}
|
||||||
|
|
||||||
|
module.directive("tgNewWebhook", ["$tgResources", "$tgRepo", "$tgConfirm", "$tgLoading", NewWebhookDirective])
|
||||||
|
|
||||||
|
|
||||||
#############################################################################
|
#############################################################################
|
||||||
## Github Controller
|
## Github Controller
|
||||||
|
|
|
@ -85,6 +85,10 @@ urls = {
|
||||||
"priorities": "/priorities"
|
"priorities": "/priorities"
|
||||||
"severities": "/severities"
|
"severities": "/severities"
|
||||||
"project-modules": "/projects/%s/modules"
|
"project-modules": "/projects/%s/modules"
|
||||||
|
"webhooks": "/webhooks"
|
||||||
|
"webhooks-test": "/webhooks/%s/test"
|
||||||
|
"webhooklogs": "/webhooklogs"
|
||||||
|
"webhooklogs-resend": "/webhooklogs/%s/resend"
|
||||||
|
|
||||||
# History
|
# History
|
||||||
"history/us": "/history/userstory"
|
"history/us": "/history/userstory"
|
||||||
|
@ -145,5 +149,7 @@ module.run([
|
||||||
"$tgHistoryResourcesProvider",
|
"$tgHistoryResourcesProvider",
|
||||||
"$tgKanbanResourcesProvider",
|
"$tgKanbanResourcesProvider",
|
||||||
"$tgModulesResourcesProvider",
|
"$tgModulesResourcesProvider",
|
||||||
|
"$tgWebhooksResourcesProvider",
|
||||||
|
"$tgWebhookLogsResourcesProvider",
|
||||||
initResources
|
initResources
|
||||||
])
|
])
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
resourceProvider = ($repo, $urls, $http) ->
|
||||||
|
service = {}
|
||||||
|
|
||||||
|
service.list = (webhookId) ->
|
||||||
|
params = {webhook: webhookId}
|
||||||
|
return $repo.queryMany("webhooklogs", params)
|
||||||
|
|
||||||
|
service.resend = (webhooklogId) ->
|
||||||
|
url = $urls.resolve("webhooklogs-resend", webhooklogId)
|
||||||
|
return $http.post(url)
|
||||||
|
|
||||||
|
return (instance) ->
|
||||||
|
instance.webhooklogs = service
|
||||||
|
|
||||||
|
|
||||||
|
module = angular.module("taigaResources")
|
||||||
|
module.factory("$tgWebhookLogsResourcesProvider", ["$tgRepo", "$tgUrls", "$tgHttp", resourceProvider])
|
|
@ -0,0 +1,17 @@
|
||||||
|
resourceProvider = ($repo, $urls, $http) ->
|
||||||
|
service = {}
|
||||||
|
|
||||||
|
service.list = (projectId) ->
|
||||||
|
params = {project: projectId}
|
||||||
|
return $repo.queryMany("webhooks", params)
|
||||||
|
|
||||||
|
service.test = (webhookId) ->
|
||||||
|
url = $urls.resolve("webhooks-test", webhookId)
|
||||||
|
return $http.post(url)
|
||||||
|
|
||||||
|
return (instance) ->
|
||||||
|
instance.webhooks = service
|
||||||
|
|
||||||
|
|
||||||
|
module = angular.module("taigaResources")
|
||||||
|
module.factory("$tgWebhooksResourcesProvider", ["$tgRepo", "$tgUrls", "$tgHttp", resourceProvider])
|
|
@ -2,19 +2,19 @@ block head
|
||||||
title Taiga Your agile, free, and open source project management tool
|
title Taiga Your agile, free, and open source project management tool
|
||||||
|
|
||||||
block content
|
block content
|
||||||
div.wrapper.roles(tg-github-webhooks, ng-controller="GithubController as ctrl",
|
div.wrapper.roles(ng-controller="WebhooksController as ctrl",
|
||||||
ng-init="section='admin'")
|
ng-init="section='admin'")
|
||||||
sidebar.menu-secondary.sidebar(tg-admin-navigation="Webhooks")
|
sidebar.menu-secondary.sidebar(tg-admin-navigation="Webhooks")
|
||||||
include ../admin-menu
|
include ../admin-menu
|
||||||
sidebar.menu-tertiary.sidebar(tg-admin-navigation="third-parties-webhooks")
|
sidebar.menu-tertiary.sidebar(tg-admin-navigation="third-parties-webhooks")
|
||||||
include ../admin-submenu-third-parties
|
include ../admin-submenu-third-parties
|
||||||
|
|
||||||
section.main.admin-common.admin-webhooks
|
section.main.admin-common.admin-webhooks(tg-new-webhook)
|
||||||
include ../../components/mainTitle
|
include ../../components/mainTitle
|
||||||
|
|
||||||
p.admin-subtitle Webhooks notify external services about events in Taiga, like comments, user stories....
|
p.admin-subtitle Webhooks notify external services about events in Taiga, like comments, user stories....
|
||||||
div.webhooks-options
|
div.webhooks-options
|
||||||
a.button.button-green.add-webhook(href="",title="Add a New Webhook") Add Webhook
|
a.button.button-green.hidden.add-webhook(href="",title="Add a New Webhook") Add Webhook
|
||||||
|
|
||||||
section.webhooks-table.basic-table
|
section.webhooks-table.basic-table
|
||||||
div.table-header
|
div.table-header
|
||||||
|
@ -23,72 +23,77 @@ block content
|
||||||
div.webhook-url URL
|
div.webhook-url URL
|
||||||
div.webhook-options
|
div.webhook-options
|
||||||
div.table-body
|
div.table-body
|
||||||
form.row
|
div.single-webhook-wrapper(tg-webhook="webhook", ng-repeat="webhook in webhooks")
|
||||||
div.webhook-service
|
div.edition-mode.hidden
|
||||||
input(type="text", name="service-name", placeholder="Type the service name")
|
form.row
|
||||||
|
fieldset.webhook-service
|
||||||
|
input(type="text", name="name", placeholder="Type the service name", data-required="true", ng-model="webhook.name")
|
||||||
|
div.webhook-url
|
||||||
|
div.webhook-url-inputs
|
||||||
|
fieldset
|
||||||
|
input(type="text", name="url", data-type="url", placeholder="Type the service payload url", data-required="true", ng-model="webhook.url")
|
||||||
|
fieldset
|
||||||
|
input(type="text", name="key", placeholder="Type the service secret key", data-required="true", ng-model="webhook.key")
|
||||||
|
div.webhook-options
|
||||||
|
a.edit-existing.icon.icon-floppy(href="", title="Save Webhook")
|
||||||
|
a.cancel-existing.icon.icon-delete(href="", title="Cancel Webhook")
|
||||||
|
|
||||||
|
div.visualization-mode
|
||||||
|
div.row
|
||||||
|
div.webhook-service
|
||||||
|
span(ng-bind="webhook.name")
|
||||||
|
div.webhook-url
|
||||||
|
span(ng-bind="webhook.url")
|
||||||
|
a.show-history.toggle-history(href="", title="Toggle history", ng-show="webhook.logs_counter ") (Show history)
|
||||||
|
|
||||||
|
div.webhook-options
|
||||||
|
div.webhook-options-wrapper
|
||||||
|
a.test-webhook.icon.icon-check-square(href="", title="Test Webhook")
|
||||||
|
a.edit-webhook.icon.icon-edit(href="", title="Edit Webhook")
|
||||||
|
a.delete-webhook.icon.icon-delete(href="", title="Delete Webhook")
|
||||||
|
|
||||||
|
div.webhooks-history(ng-show="webhook.logs")
|
||||||
|
div.history-single-wrapper(ng-repeat="log in webhook.logs")
|
||||||
|
div.history-single
|
||||||
|
div
|
||||||
|
span.history-response-icon(ng-class="validStatus ? 'history-success' : 'history-error'")
|
||||||
|
span.history-date(ng-bind="log.prettyDate")
|
||||||
|
span.toggle-log.icon.icon-arrow-bottom
|
||||||
|
|
||||||
|
div.history-single-response
|
||||||
|
div.history-single-request-header
|
||||||
|
span Request
|
||||||
|
a.resend-request(href="", title="Resend request", data-log="{{log.id}}")
|
||||||
|
span.icon.icon-reload
|
||||||
|
span Resend request
|
||||||
|
div.history-single-request-body
|
||||||
|
div.response-container
|
||||||
|
span.response-title Headers
|
||||||
|
textarea(name="headers", ng-bind="log.prettySentHeaders")
|
||||||
|
|
||||||
|
div.response-container
|
||||||
|
span.response-title Payload
|
||||||
|
textarea(name="payload", ng-bind="log.prettySentData")
|
||||||
|
|
||||||
|
div.history-single-response-header
|
||||||
|
span Response
|
||||||
|
div.history-single-response-body
|
||||||
|
div.response-container
|
||||||
|
textarea(name="response-data", ng-bind="log.response_data")
|
||||||
|
|
||||||
|
form.new-webhook-form.row.hidden
|
||||||
|
fieldset.webhook-service
|
||||||
|
input(type="text", name="name", placeholder="Type the service name", data-required="true", ng-model="newValue.name")
|
||||||
div.webhook-url
|
div.webhook-url
|
||||||
div.webhook-url-inputs
|
div.webhook-url-inputs
|
||||||
input(type="text", name="service-sexret-key", placeholder="Type the service secret key")
|
fieldset
|
||||||
input(type="text", name="service-payload-url", placeholder="Type the service payload url")
|
input(type="text", name="url", data-type="url", placeholder="Type the service payload url", data-required="true", ng-model="newValue.url")
|
||||||
|
fieldset
|
||||||
|
input(type="text", name="key", placeholder="Type the service secret key", data-required="true", ng-model="newValue.key")
|
||||||
div.webhook-options
|
div.webhook-options
|
||||||
a.icon.icon-floppy(href="", title="Save Webhook")
|
a.add-new.icon.icon-floppy(href="", title="Save Webhook")
|
||||||
a.icon.icon-delete(href="", title="Cancel Webhook")
|
a.cancel-new.icon.icon-delete(href="", title="Cancel Webhook")
|
||||||
div.single-webhook-wrapper
|
|
||||||
div.row
|
|
||||||
div.webhook-service
|
|
||||||
span Github
|
|
||||||
div.webhook-url
|
|
||||||
span http://github.kjrw3543m/nwdlkw4m535/ffm
|
|
||||||
a(href="", title="Test history") (See test history)
|
|
||||||
div.webhook-options
|
|
||||||
div.webhook-options-wrapper
|
|
||||||
a.icon.icon-floppy(href="", title="Save Webhook")
|
|
||||||
a.icon.icon-edit(href="", title="Edit Webhook")
|
|
||||||
a.icon.icon-delete(href="", title="Delete Webhook")
|
|
||||||
div.single-webhook-wrapper
|
|
||||||
div.row
|
|
||||||
div.webhook-service
|
|
||||||
span Slack
|
|
||||||
div.webhook-url
|
|
||||||
span http://slack.kjrw3543m/nwdlkw4m535/ffm
|
|
||||||
a(href="", title="Test history") (See test history)
|
|
||||||
div.webhook-options
|
|
||||||
div.webhook-options-wrapper
|
|
||||||
a.icon.icon-floppy(href="", title="Save Webhook")
|
|
||||||
a.icon.icon-edit(href="", title="Edit Webhook")
|
|
||||||
a.icon.icon-delete(href="", title="Delete Webhook")
|
|
||||||
div.webhooks-history
|
|
||||||
div.history-single
|
|
||||||
div
|
|
||||||
span.history-response.history-success
|
|
||||||
span.history-date Just now
|
|
||||||
span.icon.icon-arrow-bottom
|
|
||||||
div.history-single
|
|
||||||
div
|
|
||||||
span.history-response.history-error
|
|
||||||
span.history-date Just now
|
|
||||||
span.icon.icon-arrow-bottom
|
|
||||||
|
|
||||||
//
|
a.help-button(href="https://taiga.io/support/webhooks/", target="_blank")
|
||||||
form
|
|
||||||
fieldset
|
|
||||||
label(for="secret-key") Secret key
|
|
||||||
input(type="text", name="secret-key", ng-model="github.secret", 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", ng-model="github.webhooks_url", 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
|
|
||||||
|
|
||||||
button(type="submit", class="hidden")
|
|
||||||
a.button.button-green.submit-button(href="", title="Save") Save
|
|
||||||
|
|
||||||
|
|
||||||
a.help-button(href="https://taiga.io/support/github-integration/", target="_blank")
|
|
||||||
span.icon.icon-help
|
span.icon.icon-help
|
||||||
span Do you need help? Check out our support page!
|
span Do you need help? Check out our support page!
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
%text {font-family: 'opensans-regular', Arial, Helvetica, sans-serif; line-height: 1.3rem;}
|
%text {font-family: 'opensans-regular', Arial, Helvetica, sans-serif; line-height: 1.3rem;}
|
||||||
%bold {font-family: 'opensans-semibold', Arial, Helvetica, sans-serif;}
|
%bold {font-family: 'opensans-semibold', Arial, Helvetica, sans-serif;}
|
||||||
%taiga {font-family: 'taiga';}
|
%taiga {font-family: 'taiga';}
|
||||||
|
%mono {font-family: 'courier new', 'monospace';}
|
||||||
|
|
||||||
%lightbox {
|
%lightbox {
|
||||||
background: rgba($white, .95);
|
background: rgba($white, .95);
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
@mixin slide($max, $overflow, $min: 0) {
|
@mixin slide($max, $overflow, $min: 0) {
|
||||||
max-height: $min;
|
max-height: $min;
|
||||||
transition: max-height .5s ease-in;
|
transition: max-height .5s ease-in;
|
||||||
#{$overflow}: hidden;
|
overflow: #{$overflow};
|
||||||
&.open {
|
&.open {
|
||||||
transition: max-height .5s ease-in;
|
transition: max-height .5s ease-in;
|
||||||
max-height: $max;
|
max-height: $max;
|
||||||
|
|
|
@ -78,32 +78,53 @@
|
||||||
.webhook-url-inputs {
|
.webhook-url-inputs {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
input {
|
flex-wrap: nowrap;
|
||||||
flex-basis: 1;
|
justify-content: center;
|
||||||
|
fieldset {
|
||||||
|
flex-grow: 1;
|
||||||
margin-right: .3rem;
|
margin-right: .3rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.webhooks-history{
|
||||||
|
@include slide(1000px, hidden, $min: 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.history-single-wrapper {
|
||||||
|
border-bottom: 1px solid $whitish;
|
||||||
|
margin-left: 22%;
|
||||||
|
}
|
||||||
.history-single {
|
.history-single {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
border-bottom: 1px solid $whitish;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
margin-left: 22%;
|
|
||||||
padding: .5rem;
|
padding: .5rem;
|
||||||
transition: background .2s linear;
|
transition: background .2s linear;
|
||||||
&:hover {
|
&:hover {
|
||||||
background: rgba($fresh-taiga, .1);
|
background: rgba($fresh-taiga, .1);
|
||||||
transition: background .2s linear;
|
transition: background .2s linear;
|
||||||
}
|
}
|
||||||
|
&.history-single-open {
|
||||||
|
&:hover {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
.icon-arrow-bottom {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
transition: transform .3s linear;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.icon-arrow-bottom {
|
||||||
|
transform: rotate(0);
|
||||||
|
transition: transform .3s linear;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.history-response {
|
.history-response-icon {
|
||||||
background: $gray;
|
background: $gray;
|
||||||
border-radius: 25%;
|
border-radius: 25%;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
height: .8rem;
|
height: .8rem;
|
||||||
margin-right: .5rem;
|
margin-right: .5rem;
|
||||||
vertical-align: middle;
|
|
||||||
width: .8rem;
|
width: .8rem;
|
||||||
&.history-success {
|
&.history-success {
|
||||||
background: $fresh-taiga;
|
background: $fresh-taiga;
|
||||||
|
@ -112,4 +133,64 @@
|
||||||
background: $red;
|
background: $red;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.history-single-response {
|
||||||
|
@include slide(1000px, hidden, $min: 0);
|
||||||
|
&.open {
|
||||||
|
margin-top: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.history-single-request-header,
|
||||||
|
.history-single-response-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: .5rem 0;
|
||||||
|
span:first-child {
|
||||||
|
@extend %bold;
|
||||||
|
color: $gray-light;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
@extend %small;
|
||||||
|
color: $gray-light;
|
||||||
|
&:hover {
|
||||||
|
color: $fresh-taiga;
|
||||||
|
transition: color .2s linear;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.icon {
|
||||||
|
margin-right: .3rem;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.history-single-request-body,
|
||||||
|
.history-single-response-body {
|
||||||
|
.response-container {
|
||||||
|
@extend %mono;
|
||||||
|
align-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background: $whitish;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-around;
|
||||||
|
margin-bottom: .5rem;
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
@extend %small;
|
||||||
|
color: $gray-light;
|
||||||
|
flex-basis: 20%;
|
||||||
|
flex-grow: 1;
|
||||||
|
flex-shrink: 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
textarea {
|
||||||
|
@extend %mono;
|
||||||
|
border: 0;
|
||||||
|
flex-grow: 2;
|
||||||
|
min-height: 7.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.history-single-response-body {
|
||||||
|
textarea {
|
||||||
|
min-height: 10rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue