Add (currently read-only) UI to the admin panel, displaying all existing rules. Dynamic routes created for each registered provider.

This commit is contained in:
David Taylor 2017-06-28 15:12:37 +01:00
parent 02692cf100
commit d8e5494d4c
13 changed files with 201 additions and 40 deletions

View File

@ -0,0 +1,10 @@
export default {
resource: 'admin.adminPlugins',
path: '/plugins',
map() {
this.route('chat', function(){
this.route('index', { 'path': '/' });
this.route('provider', {path: '/:provider'});
});
}
};

View File

@ -0,0 +1,14 @@
import FilterRule from 'discourse/plugins/discourse-chat/admin/models/filter-rule'
import { ajax } from 'discourse/lib/ajax';
import computed from "ember-addons/ember-computed-decorators";
export default Ember.Controller.extend({
filters: [
{ id: 'watch', name: I18n.t('chat.filter.watch'), icon: 'exclamation-circle' },
{ id: 'follow', name: I18n.t('chat.filter.follow'), icon: 'circle'},
{ id: 'mute', name: I18n.t('chat.filter.mute'), icon: 'times-circle' }
],
editing: FilterRule.create({}),
});

View File

@ -0,0 +1,24 @@
import RestModel from 'discourse/models/rest';
import Category from 'discourse/models/category';
import computed from "ember-addons/ember-computed-decorators";
export default RestModel.extend({
category_id: null,
provider: '',
channel: '',
filter: null,
@computed('category_id')
categoryName(categoryId) {
if (categoryId)
return Category.findById(categoryId).get('name');
else {
return I18n.t('slack.choose.all_categories');
}
},
@computed('filter')
filterName(filter) {
return I18n.t(`slack.present.${filter}`);
}
});

View File

@ -0,0 +1,7 @@
import AdminPluginsChatProvider from 'discourse/plugins/discourse-chat/admin/routes/admin-plugins-chat-provider'
export default AdminPluginsChatProvider.extend({
afterModel(model, transition) {
this.transitionTo('adminPlugins.chat.provider', model);
}
});

View File

@ -0,0 +1,24 @@
import FilterRule from 'discourse/plugins/discourse-chat/admin/models/filter-rule'
import { ajax } from 'discourse/lib/ajax';
export default Discourse.Route.extend({
model(params, transition) {
var url = '/admin/plugins/chat'
if(params.provider !== undefined){
url += `/${params.provider}`
}
url += '.json'
return ajax(url).then(result => {
var rules = result.rules.map(v => FilterRule.create(v))
var providers = result.providers
return {provider: result.provider, rules: rules, providers: providers};
});
},
serialize: function(model, params) {
return { provider: model['provider']};
}
});

View File

@ -1,7 +0,0 @@
export default {
resource: 'admin.adminPlugins',
path: '/plugins',
map() {
this.route('chat');
}
};

View File

@ -1,3 +0,0 @@
export default Ember.Controller.extend({
});

View File

@ -1,9 +0,0 @@
import { ajax } from 'discourse/lib/ajax';
export default Discourse.Route.extend({
model() {
return ajax("/chat/list-providers.json").then(result => {
return result.chat;
});
}
});

View File

@ -0,0 +1,63 @@
<div id="admin-plugin-slack">
<div class="admin-controls">
<div class="span15">
<ul class="nav nav-pills">
{{#each model.providers as |provider|}}
{{nav-item route='adminPlugins.chat.provider' routeParam=provider label=(concat 'chat.integration.' provider '.title')}}
{{/each}}
</ul>
</div>
</div>
<table>
<tr>
<th>{{i18n "chat.channel"}}</th>
<th>{{i18n "chat.filter"}}</th>
<th>{{i18n "chat.category"}}</th>
{{#if siteSettings.tagging_enabled}}
<th>{{i18n "chat.tags"}}</th>
{{/if}}
<th></th>
</tr>
{{#each model.rules as |rule|}}
<tr class="">
<td>{{rule.channel}}</td>
<td>{{rule.filterName}}</td>
<td>{{rule.categoryName}}</td>
{{#if siteSettings.tagging_enabled}}
<td>{{rule.tags}}</td>
{{/if}}
<td>
{{d-button action="edit" actionParam=rule icon="pencil" class="edit" title="chat.edit"}}
{{d-button action="delete" actionParam=rule icon="trash-o" class="delete btn-danger" title="chat.delete"}}
</td>
</tr>
{{/each}}
</table>
<hr/>
{{d-button action="testNotification"
icon="rocket"
disabled=testingNotification
title="chat.test_notification"
label="chat.test_notification"}}
{{#d-button
action="resetSettings"
icon="trash"
title="chat.reset_settings"
label="chat.reset_settings"}}
{{/d-button}}
</div>

View File

@ -1,12 +0,0 @@
<div class='admin-chat'>
<div class="admin-controls">
<div class="span15">
<ul class="nav nav-pills">
{{#each model as |provider|}}
{{nav-item label=(concat 'chat.integration.' provider '.title')}}
{{/each}}
</ul>
</div>
</div>
</div>

View File

@ -2,7 +2,14 @@ en:
js: js:
chat: chat:
menu_title: "Chat Integrations" menu_title: "Chat Integrations"
channel: "Channel"
filter: "Filter"
category: "Category"
tags: "Tags"
edit: "Edit"
delete: "Delete"
test_notification: "Test Notification"
reset_settings: "Reset Settings"
integration: integration:
telegram: telegram:
title: "Telegram" title: "Telegram"

View File

@ -10,6 +10,36 @@ module DiscourseChat
"#{KEY_PREFIX}#{cat_id.present? ? cat_id : '*'}" "#{KEY_PREFIX}#{cat_id.present? ? cat_id : '*'}"
end end
def self.get_all_rules
rules = []
PluginStoreRow.where(plugin_name: DiscourseChat::PLUGIN_NAME)
.where("key ~* :pattern", pattern: "^#{DiscourseChat::Manager::KEY_PREFIX}.*")
.each do |row|
PluginStore.cast_value(row.type_name, row.value).each do |rule|
category_id =
if row.key == DiscourseChat::Manager.get_store_key
nil
else
row.key.gsub!(DiscourseChat::Manager::KEY_PREFIX, '')
row.key
end
rules << {
provider: rule[:provider],
channel: rule[:channel],
filter: rule[:filter],
category_id: category_id,
tags: rule[:tags]
}
end
end
return rules
end
def self.get_rules_for_provider(provider)
get_all_rules.select { |rule| rule[:provider] == provider }
end
def self.get_rules_for_category(cat_id = nil) def self.get_rules_for_category(cat_id = nil)
PluginStore.get(DiscourseChat::PLUGIN_NAME, get_store_key(cat_id)) || [] PluginStore.get(DiscourseChat::PLUGIN_NAME, get_store_key(cat_id)) || []
end end

View File

@ -28,8 +28,24 @@ after_initialize do
class ::DiscourseChat::ChatController < ::ApplicationController class ::DiscourseChat::ChatController < ::ApplicationController
requires_plugin DiscourseChat::PLUGIN_NAME requires_plugin DiscourseChat::PLUGIN_NAME
def list_providers def list
render json: ::DiscourseChat::Provider.providers.map {|x| x::PROVIDER_NAME} requested_provider = params[:provider]
providers = ::DiscourseChat::Provider.providers.map {|x| x::PROVIDER_NAME}
if requested_provider.nil?
requested_provider = providers[0]
end
if not providers.include? requested_provider
raise Discourse::NotFound
end
rules = DiscourseChat::Manager.get_rules_for_provider(requested_provider)
out = {provider: requested_provider, providers: providers, rules: rules}
render json: out
end end
end end
@ -40,15 +56,12 @@ after_initialize do
add_admin_route 'chat.menu_title', 'chat' add_admin_route 'chat.menu_title', 'chat'
DiscourseChat::Engine.routes.draw do DiscourseChat::Engine.routes.draw do
get "/list-providers" => "chat#list_providers", constraints: AdminConstraint.new get "(.:format)" => "chat#list" # TODO: Fix this hack
end get "/:provider" => "chat#list"
Discourse::Application.routes.prepend do
mount ::DiscourseChat::Engine, at: "/chat"
end end
Discourse::Application.routes.append do Discourse::Application.routes.append do
get '/admin/plugins/chat' => 'admin/plugins#index', constraints: StaffConstraint.new mount ::DiscourseChat::Engine, at: '/admin/plugins/chat', constraints: AdminConstraint.new
end end
end end