New admin interface for improved channel definitions
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
import buildPluginAdapter from 'admin/adapters/build-plugin';
|
||||
import Rule from 'discourse/plugins/discourse-chat-integration/admin/models/rule'
|
||||
|
||||
export default buildPluginAdapter('chat').extend({
|
||||
|
||||
|
||||
});
|
||||
@@ -0,0 +1,36 @@
|
||||
import { popupAjaxError } from 'discourse/lib/ajax-error';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
classNames: ['channel-details'],
|
||||
actions: {
|
||||
refresh: function(){
|
||||
this.sendAction('refresh');
|
||||
},
|
||||
|
||||
delete(channel){
|
||||
bootbox.confirm(I18n.t("chat_integration.channel_delete_confirm"), I18n.t("no_value"), I18n.t("yes_value"), result => {
|
||||
if (result) {
|
||||
channel.destroyRecord().then(() => {
|
||||
this.send('refresh');
|
||||
}).catch(popupAjaxError)
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
edit(channel){
|
||||
this.sendAction('edit', channel)
|
||||
},
|
||||
|
||||
test(channel){
|
||||
this.sendAction('test', channel)
|
||||
},
|
||||
|
||||
createRule(channel){
|
||||
var newRule = this.get('store').createRecord('rule',{channel_id: channel.id});
|
||||
channel.rules.pushObject(newRule)
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,38 @@
|
||||
import { popupAjaxError } from 'discourse/lib/ajax-error';
|
||||
|
||||
export default Ember.Component.extend({
|
||||
tagName: 'tr',
|
||||
editing: false,
|
||||
|
||||
autoEdit: function(){
|
||||
if(!this.get('rule').id){
|
||||
this.set('editing', true);
|
||||
}
|
||||
}.on('init'),
|
||||
|
||||
actions: {
|
||||
edit: function(){
|
||||
this.set('editing', true);
|
||||
},
|
||||
|
||||
cancel: function(){
|
||||
this.send('refresh');
|
||||
},
|
||||
|
||||
save: function(){
|
||||
this.get('rule').save().then(result => {
|
||||
this.send('refresh');
|
||||
}).catch(popupAjaxError);
|
||||
},
|
||||
|
||||
delete(rule){
|
||||
rule.destroyRecord().then(() => {
|
||||
this.send('refresh');
|
||||
}).catch(popupAjaxError)
|
||||
},
|
||||
|
||||
refresh: function(){
|
||||
this.sendAction('refresh');
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -7,42 +7,38 @@ import { popupAjaxError } from 'discourse/lib/ajax-error';
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
modalShowing: false,
|
||||
|
||||
|
||||
anyErrors: function(){
|
||||
var anyErrors = false;
|
||||
this.get('model.rules').forEach(function(rule){
|
||||
if(rule.error_key){
|
||||
this.get('model.channels').forEach(function(channel){
|
||||
if(channel.error_key){
|
||||
anyErrors = true;
|
||||
}
|
||||
});
|
||||
return anyErrors;
|
||||
}.property('model.rules'),
|
||||
}.property('model.channels'),
|
||||
|
||||
actions:{
|
||||
create(){
|
||||
createChannel(){
|
||||
this.set('modalShowing', true);
|
||||
var model = {rule: this.store.createRecord('rule',{provider: this.get('model.provider').id}), provider:this.get('model.provider')};
|
||||
showModal('admin-plugins-chat-edit-rule', { model: model, admin: true });
|
||||
var model = {channel: this.store.createRecord('channel',{provider: this.get('model.provider').id, data:{}},), provider:this.get('model.provider')};
|
||||
showModal('admin-plugins-chat-edit-channel', { model: model, admin: true });
|
||||
},
|
||||
edit(rule){
|
||||
editChannel(channel){
|
||||
this.set('modalShowing', true);
|
||||
var model = {rule: rule, provider:this.get('model.provider')};
|
||||
showModal('admin-plugins-chat-edit-rule', { model: model, admin: true });
|
||||
},
|
||||
delete(rule){
|
||||
const self = this;
|
||||
rule.destroyRecord().then(function() {
|
||||
self.send('refresh');
|
||||
}).catch(popupAjaxError)
|
||||
var model = {channel: channel, provider: this.get('model.provider')};
|
||||
showModal('admin-plugins-chat-edit-channel', { model: model, admin: true });
|
||||
},
|
||||
testChannel(channel){
|
||||
this.set('modalShowing', true);
|
||||
var model = {channel:channel}
|
||||
showModal('admin-plugins-chat-test', { model: model, admin: true });
|
||||
},
|
||||
showError(error_key){
|
||||
bootbox.alert(I18n.t(error_key));
|
||||
},
|
||||
test(){
|
||||
this.set('modalShowing', true);
|
||||
var model = {provider:this.get('model.provider'), channel:''}
|
||||
showModal('admin-plugins-chat-test', { model: model, admin: true });
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
import Rule from 'discourse/plugins/discourse-chat-integration/admin/models/rule'
|
||||
import ModalFunctionality from 'discourse/mixins/modal-functionality';
|
||||
import { ajax } from 'discourse/lib/ajax';
|
||||
import { extractError } from 'discourse/lib/ajax-error';
|
||||
import InputValidation from 'discourse/models/input-validation';
|
||||
|
||||
export default Ember.Controller.extend(ModalFunctionality, {
|
||||
|
||||
initThing: function(){
|
||||
console.log("Initialising controller");
|
||||
console.log(this.get('model.data'));
|
||||
}.on('init'),
|
||||
|
||||
// The validation property must be defined at runtime since the possible parameters vary by provider
|
||||
setupValidations: function(){
|
||||
if(this.get('model.provider')){
|
||||
var theKeys = this.get('model.provider.channel_parameters').map( ( param ) => param['key'] );
|
||||
Ember.defineProperty(this,'paramValidation',Ember.computed('model.channel.data.{' + theKeys.join(',') + '}',this._paramValidation));
|
||||
}
|
||||
}.observes('model'),
|
||||
|
||||
validate(parameter){
|
||||
var regString = parameter.regex;
|
||||
var regex = new RegExp(regString);
|
||||
var val = this.get('model.channel.data.'+parameter.key);
|
||||
|
||||
if(val == ""){ // Fail silently if field blank
|
||||
return InputValidation.create({
|
||||
failed: true,
|
||||
});
|
||||
}else if(!regString){ // Pass silently if no regex available for provider
|
||||
return InputValidation.create({
|
||||
ok: true,
|
||||
});
|
||||
}else if(regex.test(val)){ // Test against regex
|
||||
return InputValidation.create({
|
||||
ok: true,
|
||||
reason: I18n.t('chat_integration.edit_channel_modal.channel_validation.ok')
|
||||
});
|
||||
}else{ // Failed regex
|
||||
return InputValidation.create({
|
||||
failed: true,
|
||||
reason: I18n.t('chat_integration.edit_channel_modal.channel_validation.fail')
|
||||
});
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
_paramValidation: function(){
|
||||
var response = {}
|
||||
var parameters = this.get('model.provider.channel_parameters');
|
||||
parameters.forEach(parameter => {
|
||||
response[parameter.key] = this.validate(parameter);
|
||||
});
|
||||
return response;
|
||||
},
|
||||
|
||||
saveDisabled: function(){
|
||||
var validations = this.get('paramValidation');
|
||||
|
||||
if(!validations){ return true }
|
||||
|
||||
var invalid = false;
|
||||
|
||||
Object.keys(validations).forEach(key =>{
|
||||
if(!validations[key]){
|
||||
invalid = true;
|
||||
}
|
||||
if(!validations[key]['ok']){
|
||||
invalid = true;
|
||||
}
|
||||
});
|
||||
|
||||
return invalid;
|
||||
}.property('paramValidation'),
|
||||
|
||||
actions: {
|
||||
cancel: function(){
|
||||
this.send('closeModal');
|
||||
},
|
||||
|
||||
save: function(){
|
||||
|
||||
const self = this;
|
||||
|
||||
this.get('model.channel').save().then(function(result) {
|
||||
self.send('closeModal');
|
||||
}).catch(function(error) {
|
||||
self.flash(extractError(error), 'error');
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1,61 +0,0 @@
|
||||
import Rule from 'discourse/plugins/discourse-chat-integration/admin/models/rule'
|
||||
import ModalFunctionality from 'discourse/mixins/modal-functionality';
|
||||
import { ajax } from 'discourse/lib/ajax';
|
||||
import { extractError } from 'discourse/lib/ajax-error';
|
||||
import InputValidation from 'discourse/models/input-validation';
|
||||
|
||||
export default Ember.Controller.extend(ModalFunctionality, {
|
||||
|
||||
model: Rule.create({}),
|
||||
|
||||
channelValidation: function(){
|
||||
|
||||
var regString = this.get('model.provider.channel_regex');
|
||||
var regex = new RegExp(regString);
|
||||
var val = this.get('model.rule.channel');
|
||||
|
||||
if(val == ""){ // Fail silently if field blank
|
||||
return InputValidation.create({
|
||||
failed: true,
|
||||
});
|
||||
}else if(!regString){ // Pass silently if no regex available for provider
|
||||
return InputValidation.create({
|
||||
ok: true,
|
||||
});
|
||||
}else if(regex.test(val)){ // Test against regex
|
||||
return InputValidation.create({
|
||||
ok: true,
|
||||
reason: I18n.t('chat_integration.edit_rule_modal.channel_validation.ok')
|
||||
});
|
||||
}else{ // Failed regex
|
||||
return InputValidation.create({
|
||||
failed: true,
|
||||
reason: I18n.t('chat_integration.edit_rule_modal.channel_validation.fail')
|
||||
});
|
||||
}
|
||||
}.property('model.rule.channel'),
|
||||
|
||||
saveDisabled: function(){
|
||||
if(this.get('channelValidation.failed')){ return true }
|
||||
|
||||
return false;
|
||||
}.property('channelValidation.failed'),
|
||||
|
||||
actions: {
|
||||
cancel: function(){
|
||||
this.send('closeModal');
|
||||
},
|
||||
|
||||
save: function(){
|
||||
|
||||
const self = this;
|
||||
|
||||
this.get('model.rule').update().then(function(result) {
|
||||
self.send('closeModal');
|
||||
}).catch(function(error) {
|
||||
self.flash(extractError(error), 'error');
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -3,11 +3,11 @@ import { ajax } from 'discourse/lib/ajax';
|
||||
|
||||
export default Ember.Controller.extend(ModalFunctionality, {
|
||||
sendDisabled: function(){
|
||||
if(this.get('model').topic_id && this.get('model').channel){
|
||||
if(this.get('model').topic_id){
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}.property('model.topic_id', 'model.channel'),
|
||||
}.property('model.topic_id'),
|
||||
|
||||
actions: {
|
||||
|
||||
@@ -15,8 +15,7 @@ export default Ember.Controller.extend(ModalFunctionality, {
|
||||
self = this;
|
||||
this.set('loading', true);
|
||||
ajax("/admin/plugins/chat/test", {
|
||||
data: { provider: this.get('model.provider.name'),
|
||||
channel: this.get('model.channel'),
|
||||
data: { channel_id: this.get('model.channel.id'),
|
||||
topic_id: this.get('model.topic_id')
|
||||
},
|
||||
type: 'POST'
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import RestModel from 'discourse/models/rest';
|
||||
|
||||
export default RestModel.extend({
|
||||
|
||||
updateProperties() {
|
||||
var prop_names = ['data'];
|
||||
return this.getProperties(prop_names);
|
||||
},
|
||||
|
||||
createProperties() {
|
||||
var prop_names = ['provider','data'];
|
||||
return this.getProperties(prop_names);
|
||||
}
|
||||
});
|
||||
@@ -11,9 +11,8 @@ export default RestModel.extend({
|
||||
|
||||
category_id: null,
|
||||
tags: null,
|
||||
provider: '',
|
||||
channel: '',
|
||||
filter: null,
|
||||
channel_id: null,
|
||||
filter: 'watch',
|
||||
error_key: null,
|
||||
|
||||
@computed('category_id')
|
||||
@@ -31,12 +30,13 @@ export default RestModel.extend({
|
||||
},
|
||||
|
||||
updateProperties() {
|
||||
var prop_names = ['category_id','provider','channel', 'tags','filter'];
|
||||
var prop_names = ['category_id','tags','filter'];
|
||||
return this.getProperties(prop_names);
|
||||
},
|
||||
|
||||
createProperties() {
|
||||
return this.updateProperties();
|
||||
var prop_names = ['channel_id', 'category_id','tags','filter'];
|
||||
return this.getProperties(prop_names);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
@@ -1,12 +1,20 @@
|
||||
import Rule from 'discourse/plugins/discourse-chat-integration/admin/models/rule'
|
||||
import { ajax } from 'discourse/lib/ajax';
|
||||
|
||||
export default Discourse.Route.extend({
|
||||
|
||||
model(params, transition) {
|
||||
return Ember.RSVP.hash({
|
||||
rules: this.store.find('rule', {provider: params.provider}),
|
||||
channels: this.store.findAll('channel', {provider: params.provider}),
|
||||
provider: this.modelFor("admin-plugins-chat").findBy('id',params.provider)
|
||||
}).then(value => {
|
||||
value.channels.forEach(channel => {
|
||||
channel.set('rules', channel.rules.map(rule => {
|
||||
rule = this.store.createRecord('rule', rule);
|
||||
rule.channel = channel;
|
||||
return rule;
|
||||
}));
|
||||
});
|
||||
return value;
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
{{#d-modal-body id="chat_integration_edit_channel_modal" title="chat_integration.edit_channel_modal.title"}}
|
||||
<div>
|
||||
<form>
|
||||
<table>
|
||||
|
||||
<tr class="input">
|
||||
<td class="label"><label for='provider'>{{i18n "chat_integration.edit_channel_modal.provider"}}</label></td>
|
||||
<td>
|
||||
{{i18n (concat 'chat_integration.provider.' model.channel.provider '.title')}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="instructions">
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
{{# each model.provider.channel_parameters as |param|}}
|
||||
<tr class="input">
|
||||
<td class="label"><label for='param-{{param.key}}'>{{i18n (concat 'chat_integration.provider.' model.channel.provider '.param.' param.key '.title')}}</label></td>
|
||||
<td>
|
||||
{{text-field
|
||||
name=(concat 'param-' param.key)
|
||||
value=(mut (get model.channel.data param.key))
|
||||
}}
|
||||
|
||||
|
||||
{{#if (get model.channel.data param.key)}}
|
||||
{{input-tip validation=(get paramValidation param.key)}}
|
||||
{{/if}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="instructions">
|
||||
<td></td>
|
||||
<td><label>{{i18n (concat 'chat_integration.provider.' model.channel.provider '.param.' param.key '.help')}}</label></td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</table>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
{{/d-modal-body}}
|
||||
|
||||
<div class="modal-footer">
|
||||
|
||||
{{d-button id="save_rule" class='btn-primary btn-large' action="save" title="chat_integration.edit_channel_modal.save" label="chat_integration.edit_channel_modal.save" disabled=saveDisabled}}
|
||||
|
||||
{{d-button class="btn-large" action="cancel" title="chat_integration.edit_channel_modal.cancel" label="chat_integration.edit_channel_modal.cancel"}}
|
||||
|
||||
</div>
|
||||
@@ -1,87 +0,0 @@
|
||||
{{#d-modal-body id="chat_integration_edit_rule_modal" title="chat_integration.edit_rule_modal.title"}}
|
||||
<div>
|
||||
<form>
|
||||
<table>
|
||||
|
||||
<tr class="input">
|
||||
<td class="label"><label for='provider'>{{i18n "chat_integration.edit_rule_modal.provider"}}</label></td>
|
||||
<td>
|
||||
{{i18n (concat 'chat_integration.provider.' model.rule.provider '.title')}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="instructions">
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr class="input">
|
||||
<td class="label"><label for='channel'>{{i18n "chat_integration.edit_rule_modal.channel"}}</label></td>
|
||||
<td>
|
||||
{{text-field
|
||||
name="channel"
|
||||
value=model.rule.channel
|
||||
autofocus="autofocus"
|
||||
id="channel-field"}}
|
||||
|
||||
{{input-tip validation=channelValidation}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="instructions">
|
||||
<td></td>
|
||||
<td><label>{{i18n (concat 'chat_integration.provider.' model.rule.provider '.channel_instructions')}}</label></td>
|
||||
</tr>
|
||||
|
||||
<tr class="input">
|
||||
<td class="label"><label for='filter'>{{i18n "chat_integration.edit_rule_modal.filter"}}</label></td>
|
||||
<td>
|
||||
{{combo-box name="filter" content=model.rule.available_filters value=model.rule.filter}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="instructions">
|
||||
<td></td>
|
||||
<td><label>{{i18n 'chat_integration.edit_rule_modal.instructions.filter'}}</label></td>
|
||||
</tr>
|
||||
|
||||
<tr class="input">
|
||||
<td class="label"><label for='category'>{{i18n "chat_integration.edit_rule_modal.category"}}</label></td>
|
||||
<td>
|
||||
{{category-chooser
|
||||
name="category"
|
||||
value=model.rule.category_id
|
||||
rootNoneLabel="chat_integration.all_categories"
|
||||
rootNone=true
|
||||
overrideWidths=false
|
||||
}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="instructions">
|
||||
<td></td>
|
||||
<td><label>{{i18n 'chat_integration.edit_rule_modal.instructions.category'}}</label></td>
|
||||
</tr>
|
||||
|
||||
{{#if siteSettings.tagging_enabled}}
|
||||
<tr class="input">
|
||||
<td class="label"><label for='tags'>{{i18n "chat_integration.edit_rule_modal.tags"}}</label></td>
|
||||
<td>
|
||||
{{tag-chooser placeholderKey="chat_integration.all_tags" name="tags" tags=model.rule.tags}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="instructions">
|
||||
<td></td>
|
||||
<td><label>{{i18n 'chat_integration.edit_rule_modal.instructions.tags'}}</label></td>
|
||||
</tr>
|
||||
{{/if}}
|
||||
|
||||
</table>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
{{/d-modal-body}}
|
||||
|
||||
<div class="modal-footer">
|
||||
|
||||
{{d-button id="save_rule" class='btn-primary btn-large' action="save" title="chat_integration.edit_rule_modal.save" label="chat_integration.edit_rule_modal.save" disabled=saveDisabled}}
|
||||
|
||||
{{d-button class="btn-large" action="cancel" title="chat_integration.edit_rule_modal.cancel" label="chat_integration.edit_rule_modal.cancel"}}
|
||||
|
||||
</div>
|
||||
@@ -3,34 +3,7 @@
|
||||
<form>
|
||||
<table>
|
||||
|
||||
<tr class="input">
|
||||
<td class="label"><label for='provider'>{{i18n "chat_integration.test_modal.provider"}}</label></td>
|
||||
<td>
|
||||
{{i18n (concat 'chat_integration.provider.' model.provider.id '.title')}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="instructions">
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
|
||||
<tr class="input">
|
||||
<td class="label"><label for='channel'>{{i18n "chat_integration.test_modal.channel"}}</label></td>
|
||||
<td>
|
||||
{{text-field
|
||||
name="channel"
|
||||
value=model.channel
|
||||
autofocus="autofocus"
|
||||
id="channel-field"}}
|
||||
|
||||
{{!-- {{input-tip validation=channelValidation}} --}}
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="instructions">
|
||||
<td></td>
|
||||
<td><label>{{i18n (concat 'chat_integration.provider.' model.provider.id '.channel_instructions')}}</label></td>
|
||||
</tr>
|
||||
|
||||
|
||||
<tr class="input">
|
||||
<td class="label"><label for='channel'>{{i18n "chat_integration.test_modal.topic"}}</label></td>
|
||||
<td>
|
||||
|
||||
Reference in New Issue
Block a user