diff --git a/app/assets/javascripts/admin/controllers/admin-web-hooks-show-events.js.es6 b/app/assets/javascripts/admin/controllers/admin-web-hooks-show-events.js.es6 index 9b4cc91f5c5..d91469d33df 100644 --- a/app/assets/javascripts/admin/controllers/admin-web-hooks-show-events.js.es6 +++ b/app/assets/javascripts/admin/controllers/admin-web-hooks-show-events.js.es6 @@ -1,14 +1,65 @@ import { ajax } from 'discourse/lib/ajax'; import { popupAjaxError } from 'discourse/lib/ajax-error'; +import computed from 'ember-addons/ember-computed-decorators'; export default Ember.Controller.extend({ + pingDisabled: false, + incomingEventIds: [], + incomingCount: Ember.computed.alias("incomingEventIds.length"), + + @computed('incomingCount') + hasIncoming(incomingCount) { + return incomingCount > 0; + }, + + subscribe() { + this.messageBus.subscribe(`/web_hook_events/${this.get('model.extras.web_hook_id')}`, data => { + if (data.event_type === 'ping') { + this.set('pingDisabled', false); + } + this._addIncoming(data.web_hook_event_id); + }); + }, + + unsubscribe() { + this.messageBus.unsubscribe('/web_hook_events/*'); + }, + + _addIncoming(eventId) { + const incomingEventIds = this.get("incomingEventIds"); + + if (incomingEventIds.indexOf(eventId) === -1) { + incomingEventIds.pushObject(eventId); + } + }, + actions: { loadMore() { this.get('model').loadMore(); }, ping() { - ajax(`/admin/web_hooks/${this.get('model.extras.web_hook_id')}/ping`, {type: 'POST'}).catch(popupAjaxError); + this.set('pingDisabled', true); + + ajax(`/admin/web_hooks/${this.get('model.extras.web_hook_id')}/ping`, { + type: 'POST' + }).catch(error => { + this.set('pingDisabled', false); + popupAjaxError(error); + }); + }, + + showInserted() { + const webHookId = this.get('model.extras.web_hook_id'); + + ajax(`/admin/web_hooks/${webHookId}/events/bulk`, { + type: 'GET', + data: { ids: this.get('incomingEventIds') } + }).then(data => { + const objects = data.map(event => this.store.createRecord('web-hook-event', event)); + this.get("model").unshiftObjects(objects); + this.set("incomingEventIds", []); + }); } } }); diff --git a/app/assets/javascripts/admin/routes/admin-web-hooks-show-events.js.es6 b/app/assets/javascripts/admin/routes/admin-web-hooks-show-events.js.es6 index ea4e33ac630..89841d5a7ba 100644 --- a/app/assets/javascripts/admin/routes/admin-web-hooks-show-events.js.es6 +++ b/app/assets/javascripts/admin/routes/admin-web-hooks-show-events.js.es6 @@ -5,6 +5,11 @@ export default Discourse.Route.extend({ setupController(controller, model) { controller.set('model', model); + controller.subscribe(); + }, + + deactivate() { + this.controllerFor('adminWebHooks.showEvents').unsubscribe(); }, renderTemplate() { diff --git a/app/assets/javascripts/admin/templates/web-hooks-show-events.hbs b/app/assets/javascripts/admin/templates/web-hooks-show-events.hbs index 7cfb1bd794c..9b4f1e80a3f 100644 --- a/app/assets/javascripts/admin/templates/web-hooks-show-events.hbs +++ b/app/assets/javascripts/admin/templates/web-hooks-show-events.hbs @@ -2,7 +2,7 @@ {{#link-to 'adminWebHooks' tagName='button' classNames='btn'}} {{fa-icon 'list'}} {{i18n 'admin.web_hooks.events.go_list'}} {{/link-to}} - {{d-button icon="send" label="admin.web_hooks.events.ping" action="ping"}} + {{d-button icon="send" label="admin.web_hooks.events.ping" action="ping" disabled=pingDisabled}} {{#link-to 'adminWebHooks.show' model.extras.web_hook_id tagName='button' classNames='btn'}} {{fa-icon 'edit'}} {{i18n 'admin.web_hooks.events.go_details'}} {{/link-to}} @@ -10,6 +10,12 @@ <div class='web-hook-events-listing'> {{#if model}} + {{#if hasIncoming}} + <div class='alert alert-info clickable' {{action "showInserted"}}> + {{count-i18n key="admin.web_hooks.events.incoming" count=incomingCount}} + {{i18n 'click_to_show'}} + </div> + {{/if}} {{#load-more selector=".web-hook-events li" action="loadMore"}} <div class='web-hook-events content-list'> <ul> diff --git a/app/assets/stylesheets/common/admin/admin_base.scss b/app/assets/stylesheets/common/admin/admin_base.scss index d8a734cf7d5..5d81c310b84 100644 --- a/app/assets/stylesheets/common/admin/admin_base.scss +++ b/app/assets/stylesheets/common/admin/admin_base.scss @@ -1859,8 +1859,6 @@ table#user-badges { } .web-hook-events { - margin-top: 15px; - li { padding: 2px 0; } @@ -1906,6 +1904,13 @@ table#user-badges { } } +.web-hook-events-listing { + margin-top: 15px; + .alert { + margin: 15px 0 0 0; + } +} + // Mobile specific styles // Mobile view text-inputs need some padding .mobile-view .admin-contents { diff --git a/app/controllers/admin/web_hooks_controller.rb b/app/controllers/admin/web_hooks_controller.rb index d70048c7428..3d7a134c44e 100644 --- a/app/controllers/admin/web_hooks_controller.rb +++ b/app/controllers/admin/web_hooks_controller.rb @@ -1,5 +1,5 @@ class Admin::WebHooksController < Admin::AdminController - before_filter :fetch_web_hook, only: %i(show update destroy list_events ping) + before_filter :fetch_web_hook, only: %i(show update destroy list_events bulk_events ping) def index limit = 50 @@ -72,6 +72,12 @@ class Admin::WebHooksController < Admin::AdminController render json: MultiJson.dump(json), status: 200 end + def bulk_events + params.require(:ids) + web_hook_events = @web_hook.web_hook_events.where(id: params[:ids]) + render_serialized(web_hook_events, AdminWebHookEventSerializer) + end + def redeliver_event web_hook_event = WebHookEvent.find(params[:event_id]) diff --git a/app/jobs/regular/emit_web_hook_event.rb b/app/jobs/regular/emit_web_hook_event.rb index d3315b33fcf..c3bbc3c14ae 100644 --- a/app/jobs/regular/emit_web_hook_event.rb +++ b/app/jobs/regular/emit_web_hook_event.rb @@ -67,6 +67,10 @@ module Jobs response_headers: MultiJson.dump(response.headers), response_body: response.body, duration: ((Time.zone.now - now) * 1000).to_i) + MessageBus.publish("/web_hook_events/#{@web_hook.id}", { + web_hook_event_id: web_hook_event.id, + event_type: @opts[:event_type] + }, user_ids: User.staff.pluck(:id)) end def build_web_hook_body diff --git a/app/serializers/admin_web_hook_event_serializer.rb b/app/serializers/admin_web_hook_event_serializer.rb index 0343d1739d0..14ff7248839 100644 --- a/app/serializers/admin_web_hook_event_serializer.rb +++ b/app/serializers/admin_web_hook_event_serializer.rb @@ -10,7 +10,6 @@ class AdminWebHookEventSerializer < ApplicationSerializer :duration, :created_at - def request_url object.web_hook.payload_url end diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 217f1f09a73..9809cd7df0f 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -2478,6 +2478,9 @@ en: events: none: "There are no related events." redeliver: "Redeliver" + incoming: + one: "There is a new event." + other: "There are {{count}} new events." completion: "Completed in %{seconds} seconds." request: "Request" response: "Response" diff --git a/config/routes.rb b/config/routes.rb index 45cf5a871df..d4a33a08053 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -209,6 +209,7 @@ Discourse::Application.routes.draw do resources :web_hooks, constraints: AdminConstraint.new get 'web_hook_events/:id' => 'web_hooks#list_events', constraints: AdminConstraint.new, as: :web_hook_events get 'web_hooks/:id/events' => 'web_hooks#list_events', constraints: AdminConstraint.new + get 'web_hooks/:id/events/bulk' => 'web_hooks#bulk_events', constraints: AdminConstraint.new post 'web_hooks/:web_hook_id/events/:event_id/redeliver' => 'web_hooks#redeliver_event', constraints: AdminConstraint.new post 'web_hooks/:id/ping' => 'web_hooks#ping', constraints: AdminConstraint.new