Start work on JS side
This commit is contained in:
-3
@@ -1,3 +0,0 @@
|
||||
{{#if canEditTags}}
|
||||
{{tag-chooser tags=model.tags tabIndex="4"}}
|
||||
{{/if}}
|
||||
@@ -1,3 +0,0 @@
|
||||
{{#if canEditTags}}
|
||||
{{tag-chooser tags=buffered.tags}}
|
||||
{{/if}}
|
||||
-13
@@ -1,13 +0,0 @@
|
||||
{{#if tags_changes}}
|
||||
<div class='row'>
|
||||
{{i18n "tagging.changed"}}
|
||||
{{#each t in previousTagChanges}}
|
||||
{{discourse-tag tagId=t}}
|
||||
{{/each}}
|
||||
→
|
||||
|
||||
{{#each t in currentTagChanges}}
|
||||
{{discourse-tag tagId=t}}
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/if}}
|
||||
-3
@@ -1,3 +0,0 @@
|
||||
<li>
|
||||
{{#link-to 'tags'}}{{i18n "tagging.tags"}}{{/link-to}}
|
||||
</li>
|
||||
@@ -1,3 +0,0 @@
|
||||
{{#each t in topic.tags}}
|
||||
{{discourse-tag tagId=t}}
|
||||
{{/each}}
|
||||
@@ -0,0 +1,3 @@
|
||||
import buildPluginAdapter from 'discourse/adapters/build-plugin';
|
||||
|
||||
export default buildPluginAdapter('explorer');
|
||||
@@ -1,7 +0,0 @@
|
||||
import RESTAdapter from 'discourse/adapters/rest';
|
||||
|
||||
export default RESTAdapter.extend({
|
||||
pathFor(type, id) {
|
||||
return "/tags/" + id + "/notifications";
|
||||
}
|
||||
});
|
||||
@@ -1,33 +0,0 @@
|
||||
export default Ember.Component.extend({
|
||||
tagName: 'a',
|
||||
classNameBindings: [':discourse-tag'],
|
||||
attributeBindings: ['href', 'style'],
|
||||
|
||||
href: function() {
|
||||
return "/tags/" + this.get('tagId');
|
||||
}.property('tagId'),
|
||||
|
||||
style: function() {
|
||||
const count = parseFloat(this.get('count')),
|
||||
minCount = parseFloat(this.get('minCount')),
|
||||
maxCount = parseFloat(this.get('maxCount'));
|
||||
|
||||
if (count && maxCount && minCount) {
|
||||
let ratio = (count - minCount) / maxCount;
|
||||
if (ratio) {
|
||||
ratio = ratio + 1.0;
|
||||
return "font-size: " + ratio + "em";
|
||||
}
|
||||
}
|
||||
}.property('count', 'scaleTo'),
|
||||
|
||||
render(buffer) {
|
||||
buffer.push(Handlebars.Utils.escapeExpression(this.get('tagId')));
|
||||
},
|
||||
|
||||
click(e) {
|
||||
e.preventDefault();
|
||||
Discourse.URL.routeTo(this.get('href'));
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@@ -1,88 +0,0 @@
|
||||
function formatTag(t) {
|
||||
const ret = "<a href class='discourse-tag'>" + Handlebars.Utils.escapeExpression(t.id) + "</a>";
|
||||
return (t.count) ? ret + " <span class='discourse-tag-count'>x" + t.count + "</span>" : ret;
|
||||
}
|
||||
|
||||
export default Ember.TextField.extend({
|
||||
classNameBindings: [':tag-chooser'],
|
||||
attributeBindings: ['tabIndex'],
|
||||
|
||||
_setupTags: function() {
|
||||
const tags = this.get('tags') || [];
|
||||
this.set('value', tags.join(", "));
|
||||
}.on('init'),
|
||||
|
||||
_valueChanged: function() {
|
||||
const tags = this.get('value').split(',').map(v => v.trim()).reject(v => v.length === 0).uniq();
|
||||
this.set('tags', tags);
|
||||
}.observes('value'),
|
||||
|
||||
_initializeTags: function() {
|
||||
const site = this.site,
|
||||
filterRegexp = new RegExp(this.site.tags_filter_regexp, "g");
|
||||
|
||||
this.$().select2({
|
||||
tags: true,
|
||||
placeholder: I18n.t('tagging.choose_for_topic'),
|
||||
maximumInputLength: this.siteSettings.max_tag_length,
|
||||
maximumSelectionSize: this.siteSettings.max_tags_per_topic,
|
||||
initSelection(element, callback) {
|
||||
const data = [];
|
||||
|
||||
function splitVal(string, separator) {
|
||||
var val, i, l;
|
||||
if (string === null || string.length < 1) return [];
|
||||
val = string.split(separator);
|
||||
for (i = 0, l = val.length; i < l; i = i + 1) val[i] = $.trim(val[i]);
|
||||
return val;
|
||||
}
|
||||
|
||||
$(splitVal(element.val(), ",")).each(function () {
|
||||
data.push({
|
||||
id: this,
|
||||
text: this
|
||||
});
|
||||
});
|
||||
|
||||
callback(data);
|
||||
},
|
||||
createSearchChoice: function(term, data) {
|
||||
term = term.replace(filterRegexp, '').trim();
|
||||
|
||||
// No empty terms, make sure the user has permission to create the tag
|
||||
if (!term.length || !site.get('can_create_tag')) { return; }
|
||||
|
||||
if ($(data).filter(function() {
|
||||
return this.text.localeCompare(term) === 0;
|
||||
}).length === 0) {
|
||||
return { id: term, text: term };
|
||||
}
|
||||
},
|
||||
createSearchChoicePosition: function(list, item) {
|
||||
// Search term goes on the bottom
|
||||
list.push(item);
|
||||
},
|
||||
formatSelectionCssClass: function () { return "discourse-tag"; },
|
||||
formatResult: formatTag,
|
||||
// formatSelection: formatTag,
|
||||
multiple: true,
|
||||
ajax: {
|
||||
quietMillis: 200,
|
||||
cache: true,
|
||||
url: "/tags/filter/search",
|
||||
dataType: 'json',
|
||||
data: function (term) {
|
||||
return { q: term };
|
||||
},
|
||||
results: function (data) {
|
||||
return data;
|
||||
}
|
||||
},
|
||||
});
|
||||
}.on('didInsertElement'),
|
||||
|
||||
_destroyTags: function() {
|
||||
this.$().select2('destroy');
|
||||
}.on('willDestroyElement')
|
||||
|
||||
});
|
||||
@@ -1,11 +0,0 @@
|
||||
import NotificationsButton from 'discourse/components/notifications-button';
|
||||
|
||||
export default NotificationsButton.extend({
|
||||
classNames: ['notification-options', 'tag-notification-menu'],
|
||||
buttonIncludesText: false,
|
||||
i18nPrefix: 'tagging.notifications',
|
||||
|
||||
clicked(id) {
|
||||
this.sendAction('action', id);
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
|
||||
export default Ember.ArrayController.extend({
|
||||
|
||||
});
|
||||
@@ -0,0 +1,46 @@
|
||||
import ModalFunctionality from 'discourse/mixins/modal-functionality';
|
||||
|
||||
export default Ember.Controller.extend(ModalFunctionality, {
|
||||
notReady: Em.computed.not('ready'),
|
||||
|
||||
needs: ['admin-plugins-explorer'],
|
||||
|
||||
ready: function() {
|
||||
let parsed;
|
||||
try {
|
||||
parsed = JSON.parse(this.get('queryFile'));
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !!parsed["query"];
|
||||
}.property('queryFile'),
|
||||
|
||||
actions: {
|
||||
doImport: function() {
|
||||
const self = this;
|
||||
const object = JSON.parse(this.get('queryFile')).query;
|
||||
|
||||
// Slight fixup before creating object
|
||||
delete object.id;
|
||||
|
||||
this.set('loading', true);
|
||||
this.store.createRecord('query', object).save().then(function(query) {
|
||||
self.send('closeModal');
|
||||
self.set('loading', false);
|
||||
|
||||
const parentController = self.get('controllers.admin-plugins-explorer');
|
||||
parentController.pushObject(query);
|
||||
parentController.set('selectedItem', query);
|
||||
}).catch(function(xhr) {
|
||||
self.set('loading', false);
|
||||
if (xhr.responseJSON) {
|
||||
bootbox.alert(xhr.responseJSON.errors.join("<br>"));
|
||||
} else {
|
||||
bootbox.alert(I18n.t('generic_error'));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
@@ -1,15 +0,0 @@
|
||||
export default Ember.Controller.extend({
|
||||
tag: null,
|
||||
list: null,
|
||||
|
||||
loadMoreTopics() {
|
||||
return this.get('list').loadMore();
|
||||
},
|
||||
|
||||
actions: {
|
||||
changeTagNotification(id) {
|
||||
const tagNotification = this.get('tagNotification');
|
||||
tagNotification.update({ notification_level: id });
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,8 @@
|
||||
export default {
|
||||
resource: 'admin.adminPlugins',
|
||||
path: '/plugins',
|
||||
map() {
|
||||
this.route('explorer');
|
||||
this.route('explorer-show', {path: 'explorer/:id'});
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,7 @@
|
||||
|
||||
export default {
|
||||
name: 'add-query-pluralization',
|
||||
initialize(container) {
|
||||
container.lookup('store:main').addPluralization('query', 'queries');
|
||||
}
|
||||
};
|
||||
@@ -1,44 +0,0 @@
|
||||
import ComposerController from 'discourse/controllers/composer';
|
||||
import HistoryController from 'discourse/controllers/history';
|
||||
import TopicController from 'discourse/controllers/topic';
|
||||
import { needsSecondRowIf } from 'discourse/components/header-extra-info';
|
||||
|
||||
// Work around a quirk of custom fields -- an array of one element
|
||||
// is returned as just that element. We should fix this properly
|
||||
// in custom fields and remove this.
|
||||
function customTagArray(fieldName) {
|
||||
return function() {
|
||||
var val = this.get(fieldName);
|
||||
if (!val) { return val; }
|
||||
if (!Array.isArray(val)) { val = [val]; }
|
||||
return val;
|
||||
}.property(fieldName);
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'extend-for-tagging',
|
||||
initialize() {
|
||||
Discourse.Composer.serializeOnCreate('tags');
|
||||
Discourse.Composer.serializeToTopic('tags', 'topic.tags');
|
||||
|
||||
TopicController.reopen({
|
||||
canEditTags: Ember.computed.not('isPrivateMessage')
|
||||
});
|
||||
|
||||
HistoryController.reopen({
|
||||
previousTagChanges: customTagArray('tags_changes.previous'),
|
||||
currentTagChanges: customTagArray('tags_changes.current')
|
||||
});
|
||||
|
||||
ComposerController.reopen({
|
||||
canEditTags: function() {
|
||||
return !this.site.mobileView &&
|
||||
this.get('model.canEditTitle') &&
|
||||
!this.get('model.creatingPrivateMessage');
|
||||
}.property('model.canEditTitle', 'model.creatingPrivateMessage')
|
||||
});
|
||||
|
||||
// Show a second row in the header if there are any tags on the topic
|
||||
needsSecondRowIf('topic.tags.length', tagsLength => parseInt(tagsLength) > 0);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
export default Discourse.Route.extend({
|
||||
model(params) {
|
||||
return this.store.find('query', params.get('id'));
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,22 @@
|
||||
import showModal from 'discourse/lib/show-modal';
|
||||
|
||||
export default Discourse.Route.extend({
|
||||
controllerName: 'admin-plugins-explorer',
|
||||
|
||||
model() {
|
||||
return this.store.findAll('query');
|
||||
},
|
||||
|
||||
setupController(controller, model) {
|
||||
|
||||
},
|
||||
|
||||
actions: {
|
||||
create() {
|
||||
|
||||
},
|
||||
importQuery() {
|
||||
showModal('import-query');
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1,5 +0,0 @@
|
||||
export default Discourse.Route.extend({
|
||||
model() {
|
||||
return Discourse.ajax("/tags/filter/cloud.json");
|
||||
}
|
||||
});
|
||||
@@ -1,32 +0,0 @@
|
||||
export default Discourse.Route.extend({
|
||||
|
||||
model(tag) {
|
||||
tag.tag_id = Handlebars.Utils.escapeExpression(tag.tag_id);
|
||||
|
||||
if (this.get('currentUser')) {
|
||||
// If logged in, we should get the tag's user settings
|
||||
const self = this;
|
||||
return this.store.find('tagNotification', tag.tag_id).then(function(tn) {
|
||||
self.set('tagNotification', tn);
|
||||
return tag;
|
||||
});
|
||||
}
|
||||
|
||||
return tag;
|
||||
},
|
||||
|
||||
afterModel(tag) {
|
||||
const self = this;
|
||||
return Discourse.TopicList.list('tags/' + tag.tag_id).then(function(list) {
|
||||
self.set('list', list);
|
||||
});
|
||||
},
|
||||
|
||||
setupController(controller, model) {
|
||||
controller.setProperties({
|
||||
tag: model,
|
||||
list: this.get('list'),
|
||||
tagNotification: this.get('tagNotification')
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -1,5 +0,0 @@
|
||||
export default function() {
|
||||
this.resource('tags', function() {
|
||||
this.route('show', {path: ':tag_id'});
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
{{d-button action="create" label="explorer.create" icon="plus"}}
|
||||
{{d-button action="importQuery" label="explorer.import.label" icon="upload"}}
|
||||
|
||||
{{#each query in model}}
|
||||
<div class="row">
|
||||
{{query.name}}
|
||||
</div>
|
||||
{{/each}}
|
||||
@@ -0,0 +1,8 @@
|
||||
<form {{action "dummy" on="submit"}}>
|
||||
<div class='modal-body'>
|
||||
{{json-file-uploader value=queryFile extension=".dcquery.json"}}
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
{{d-button class='btn-primary' action='doImport' type='submit' disabled=notReady icon="plus" label='explorer.import.label'}}
|
||||
</div>
|
||||
</form>
|
||||
@@ -1,9 +0,0 @@
|
||||
<div class="container list-container">
|
||||
<div class="row">
|
||||
<div class="full-width">
|
||||
<div id='list-area'>
|
||||
{{outlet}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,10 +0,0 @@
|
||||
<h2>{{i18n "tagging.all_tags"}}</h2>
|
||||
|
||||
<div class='tag-cloud'>
|
||||
{{#each tag in cloud}}
|
||||
{{discourse-tag tagId=tag.id
|
||||
count=tag.count
|
||||
maxCount=model.max_count
|
||||
minCount=model.min_count}}
|
||||
{{/each}}
|
||||
</div>
|
||||
@@ -1,9 +0,0 @@
|
||||
{{#if tagNotification}}
|
||||
{{tag-notifications-button tag=tag.tag_id
|
||||
action="changeTagNotification"
|
||||
notificationLevel=tagNotification.notification_level}}
|
||||
{{/if}}
|
||||
|
||||
<h2>{{{i18n "tagging.topics_tagged" tag=tag.tag_id}}}</h2>
|
||||
|
||||
{{topic-list topics=list.topics}}
|
||||
@@ -0,0 +1,6 @@
|
||||
import ModalBodyView from "discourse/views/modal-body";
|
||||
|
||||
export default ModalBodyView.extend({
|
||||
templateName: 'modal/import-query',
|
||||
title: I18n.t('explorer.import.modal')
|
||||
});
|
||||
@@ -1,3 +0,0 @@
|
||||
import DiscoveryTopicsView from "discourse/views/discovery-topics";
|
||||
|
||||
export default DiscoveryTopicsView;
|
||||
Reference in New Issue
Block a user