diff --git a/assets/javascripts/discourse/components/query-result.js.es6 b/assets/javascripts/discourse/components/query-result.js.es6 index 6409c8c..3dbcb73 100644 --- a/assets/javascripts/discourse/components/query-result.js.es6 +++ b/assets/javascripts/discourse/components/query-result.js.es6 @@ -96,6 +96,10 @@ const QueryResultComponent = Ember.Component.extend({ return transformedRelTable(this.get('content.relations.topic')); }.property('content.relations.topic'), + transformedGroupTable: function() { + return transformedRelTable(this.get('site.groups')); + }.property('site.groups'), + lookupUser(id) { return this.get('transformedUserTable')[id]; }, @@ -108,6 +112,9 @@ const QueryResultComponent = Ember.Component.extend({ lookupTopic(id) { return this.get('transformedTopicTable')[id]; }, + lookupGroup(id) { + return this.get('transformedGroupTable')[id]; + }, lookupCategory(id) { return this.site.get('categoriesById')[id]; diff --git a/assets/javascripts/discourse/components/query-row-content.js.es6 b/assets/javascripts/discourse/components/query-row-content.js.es6 index bd144e2..b720a75 100644 --- a/assets/javascripts/discourse/components/query-row-content.js.es6 +++ b/assets/javascripts/discourse/components/query-row-content.js.es6 @@ -1,4 +1,8 @@ + +import { categoryLinkHTML } from 'discourse/helpers/category-link'; +import { autoUpdatingRelativeAge } from 'discourse/lib/formatter'; + function icon_or_image_replacement(str, ctx) { str = Ember.get(ctx.contexts[0], str); if (Ember.isEmpty(str)) { return ""; } @@ -10,12 +14,16 @@ function icon_or_image_replacement(str, ctx) { } } -function shorthandTinyAvatar(avatar_template, ctx) { - return new Handlebars.SafeString(Discourse.Utilities.avatarImg({ - size: "tiny", - extraClasses: '', - avatarTemplate: avatar_template - })); +function category_badge_replacement(str, ctx) { + const category = Ember.get(ctx.contexts[0], str); + return categoryLinkHTML(category, { + allowUncategorized: true, + }); +} + +function bound_date_replacement(str, ctx) { + const value = Ember.get(ctx.contexts[0], str); + return new Handlebars.SafeString(autoUpdatingRelativeAge(new Date(value), {title: true })); } const esc = Handlebars.Utils.escapeExpression; @@ -28,28 +36,42 @@ const QueryRowContentComponent = Ember.Component.extend({ const row = this.get('row'); const parent = self.get('parent'); const fallback = parent.get('fallbackTemplate'); + const helpers = { + "icon-or-image": icon_or_image_replacement, + "category-link": category_badge_replacement, + "reltime": bound_date_replacement, + }; const parts = this.get('columnTemplates').map(function(t, idx) { - const ctx = {}; - const params = {} - if (t.name === "text") { + const value = row[idx], + id = parseInt(value); + + const ctx = {value, id, baseuri: Discourse.BaseUri === '/' ? '' : Discourse.BaseUri }; + const params = {}; + + if (row[idx] === null) { + return "NULL"; + } else if (t.name === "text") { return esc(row[idx]); - } else if (t.name === "user") { - ctx.user = parent.lookupUser(parseInt(row[idx])); - if (!ctx.user) { - return esc(row[idx]); - } - } else if (t.name === "badge") { - ctx.badge = parent.lookupBadge(parseInt(row[idx])); - params.helpers = {"icon-or-image": icon_or_image_replacement}; - } else if (t.name === "post") { - ctx.post = parent.lookupPost(parseInt(row[idx])); - params.helpers = {avatar: shorthandTinyAvatar}; - } else { - ctx.value = row[idx]; } - return new Handlebars.SafeString((t.template || fallback)(ctx, params)); + const lookupFunc = parent[`lookup${t.name.capitalize()}`]; + if (lookupFunc) { + ctx[t.name] = parent[`lookup${t.name.capitalize()}`](id); + } + + if (t.name === "category" || t.name === "badge" || t.name === "reltime") { + // only replace helpers if needed + params.helpers = helpers; + } + + try { + return new Handlebars.SafeString((t.template || fallback)(ctx, params)); + } catch (e) { + console.error(e); + debugger; + return "error"; + } }); buffer.push("" + parts.join("") + ""); diff --git a/assets/javascripts/discourse/templates/explorer/badge.raw.hbs b/assets/javascripts/discourse/templates/explorer/badge.raw.hbs index e0d5243..63cc9d7 100644 --- a/assets/javascripts/discourse/templates/explorer/badge.raw.hbs +++ b/assets/javascripts/discourse/templates/explorer/badge.raw.hbs @@ -1,2 +1,6 @@ {{! source: badge-button component }} -{{icon-or-image badge.icon}} {{badge.displayName}} +{{icon-or-image badge.icon}} +{{badge.displayName}} diff --git a/assets/javascripts/discourse/templates/explorer/category.raw.hbs b/assets/javascripts/discourse/templates/explorer/category.raw.hbs new file mode 100644 index 0000000..6649880 --- /dev/null +++ b/assets/javascripts/discourse/templates/explorer/category.raw.hbs @@ -0,0 +1,5 @@ +{{#if category}} + {{category-link category}} +{{else}} + {{id}} +{{/if}} diff --git a/assets/javascripts/discourse/templates/explorer/group.raw.hbs b/assets/javascripts/discourse/templates/explorer/group.raw.hbs new file mode 100644 index 0000000..9089690 --- /dev/null +++ b/assets/javascripts/discourse/templates/explorer/group.raw.hbs @@ -0,0 +1,5 @@ +{{#if group}} + {{group.name}} +{{else}} + {{id}} +{{/if}} diff --git a/assets/javascripts/discourse/templates/explorer/post.raw.hbs b/assets/javascripts/discourse/templates/explorer/post.raw.hbs index 6698277..5d71d48 100644 --- a/assets/javascripts/discourse/templates/explorer/post.raw.hbs +++ b/assets/javascripts/discourse/templates/explorer/post.raw.hbs @@ -1,4 +1,15 @@ - +{{~#if post}} + +{{~else}} + {{id}} +{{~/if}} diff --git a/assets/javascripts/discourse/templates/explorer/reltime.raw.hbs b/assets/javascripts/discourse/templates/explorer/reltime.raw.hbs new file mode 100644 index 0000000..901f251 --- /dev/null +++ b/assets/javascripts/discourse/templates/explorer/reltime.raw.hbs @@ -0,0 +1 @@ +{{reltime value}} diff --git a/assets/javascripts/discourse/templates/explorer/text.raw.hbs b/assets/javascripts/discourse/templates/explorer/text.raw.hbs index f07ceec..672f203 100644 --- a/assets/javascripts/discourse/templates/explorer/text.raw.hbs +++ b/assets/javascripts/discourse/templates/explorer/text.raw.hbs @@ -1,2 +1 @@ {{value}} -{{! note - this template isn't actually used, it gets short-circuited in query-row-content.js.es6}} diff --git a/assets/javascripts/discourse/templates/explorer/topic.raw.hbs b/assets/javascripts/discourse/templates/explorer/topic.raw.hbs new file mode 100644 index 0000000..2a58449 --- /dev/null +++ b/assets/javascripts/discourse/templates/explorer/topic.raw.hbs @@ -0,0 +1,6 @@ +{{#if topic}} + {{{topic.fancy_title}}} ({{topic.posts_count}}) +{{else}} + {{id}} +{{/if}} diff --git a/assets/javascripts/discourse/templates/explorer/user.raw.hbs b/assets/javascripts/discourse/templates/explorer/user.raw.hbs index 1b24eea..2a7e1bf 100644 --- a/assets/javascripts/discourse/templates/explorer/user.raw.hbs +++ b/assets/javascripts/discourse/templates/explorer/user.raw.hbs @@ -1 +1,6 @@ -{{avatar user imageSize="tiny"}} {{user.username}} +{{#if user}} + {{avatar user imageSize="tiny"}} {{user.username}} +{{else}} + {{id}} +{{/if}} diff --git a/plugin.rb b/plugin.rb index e9b08ad..a44808e 100644 --- a/plugin.rb +++ b/plugin.rb @@ -50,7 +50,7 @@ after_initialize do Post.excerpt(object.cooked, 70) end def username; object.user.username; end - def uploaded_avatar_id; object.user.avatar_template; end + def avatar_template; object.user.avatar_template; end end # Run a data explorer query on the currently connected database. @@ -141,6 +141,7 @@ SQL badge: {class: Badge, fields: [:id, :name, :badge_type_id, :description, :icon], include: [:badge_type], serializer: SmallBadgeSerializer}, post: {class: Post, fields: [:id, :topic_id, :post_number, :cooked, :user_id], include: [:user], serializer: SmallPostWithExcerptSerializer}, topic: {class: Topic, fields: [:id, :title, :slug, :posts_count], serializer: BasicTopicSerializer}, + group: {class: Group, ignore: true}, category: {class: Category, ignore: true}, reltime: {ignore: true}, html: {ignore: true}, @@ -196,8 +197,13 @@ SQL ids.map! &:to_i object_class = support_info[:class] - all_objs = object_class.select(support_info[:fields]). - where(id: ids.to_a.sort).includes(support_info[:include]).order(:id) + all_objs = object_class + all_objs = all_objs.with_deleted if all_objs.respond_to? :with_deleted + all_objs = all_objs + .select(support_info[:fields]) + .where(id: ids.to_a.sort) + .includes(support_info[:include]) + .order(:id) ret[cls] = ActiveModel::ArraySerializer.new(all_objs, each_serializer: support_info[:serializer]) end diff --git a/test/test_query.sql b/test/test_query.sql new file mode 100644 index 0000000..9298db0 --- /dev/null +++ b/test/test_query.sql @@ -0,0 +1,11 @@ +SELECT + (SELECT id FROM badges LIMIT 1) as badge_id, + (SELECT id FROM categories LIMIT 1) as category_id, + (SELECT id FROM groups LIMIT 1) as group_id, + '

hello

' as html$html, + (SELECT id FROM posts LIMIT 1) as post_id, + 'hello' as text$text, + (SELECT id FROM topics LIMIT 1) as topic_id, + (SELECT id FROM users LIMIT 1) as user_id, + TIMESTAMP 'yesterday' as reltime$time, + 1 as end