FEATURE: allow tags from tag field to be confined to a tag group (#175)
* FEATURE: allow tag field to be confined to a tag group * fixed linting * bump minor version * moved monkeypatch to a separate module * use snake case for variable names * added specs
Dieser Commit ist enthalten in:
Ursprung
676d538da2
Commit
f0580d2bba
12 geänderte Dateien mit 123 neuen und 4 gelöschten Zeilen
|
@ -208,6 +208,20 @@
|
|||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if isTag}}
|
||||
<div class="setting full field-mapper-setting">
|
||||
<div class="setting-label">
|
||||
<label>{{i18n "admin.wizard.field.tag_groups"}}</label>
|
||||
</div>
|
||||
|
||||
<div class="setting-value">
|
||||
{{tag-group-chooser
|
||||
tagGroups=field.tag_groups
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if showAdvanced}}
|
||||
{{wizard-advanced-toggle showAdvanced=field.showAdvanced}}
|
||||
|
||||
|
|
12
assets/javascripts/wizard/components/wizard-tag-chooser.js.es6
Normale Datei
12
assets/javascripts/wizard/components/wizard-tag-chooser.js.es6
Normale Datei
|
@ -0,0 +1,12 @@
|
|||
import TagChooser from "select-kit/components/tag-chooser";
|
||||
|
||||
export default TagChooser.extend({
|
||||
searchTags(url, data, callback) {
|
||||
if (this.tagGroups) {
|
||||
let tagGroupsString = this.tagGroups.join(",");
|
||||
data.tag_groups = tagGroupsString;
|
||||
}
|
||||
|
||||
return this._super(url, data, callback);
|
||||
},
|
||||
});
|
|
@ -1 +1,7 @@
|
|||
{{tag-chooser tags=field.value maximum=field.limit tabindex=field.tabindex everyTag=true}}
|
||||
{{wizard-tag-chooser
|
||||
tags=field.value
|
||||
maximum=field.limit
|
||||
tabindex=field.tabindex
|
||||
tagGroups=field.tag_groups
|
||||
everyTag=true
|
||||
}}
|
||||
|
|
|
@ -188,6 +188,7 @@ en:
|
|||
property: "Property"
|
||||
prefill: "Prefill"
|
||||
content: "Content"
|
||||
tag_groups: "Tag Groups"
|
||||
date_time_format:
|
||||
label: "Format"
|
||||
instructions: "<a href='https://momentjs.com/docs/#/displaying/format/' target='_blank'>Moment.js format</a>"
|
||||
|
|
|
@ -117,6 +117,7 @@ class CustomWizard::AdminWizardController < CustomWizard::AdminController
|
|||
condition: mapped_params,
|
||||
index: mapped_params,
|
||||
validations: {},
|
||||
tag_groups: [],
|
||||
]
|
||||
],
|
||||
actions: [
|
||||
|
|
17
extensions/discourse_tagging.rb
Normale Datei
17
extensions/discourse_tagging.rb
Normale Datei
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module CustomWizardDiscourseTagging
|
||||
def filter_allowed_tags(guardian, opts = {})
|
||||
if tag_groups = RequestStore.store[:tag_groups]
|
||||
tag_group_array = tag_groups.split(",")
|
||||
filtered_tags = TagGroup.includes(:tags).where(name: tag_group_array).map do |tag_group|
|
||||
tag_group.tags.pluck(:name)
|
||||
end.flatten
|
||||
|
||||
opts[:only_tag_names] ||= []
|
||||
opts[:only_tag_names].push(*filtered_tags)
|
||||
end
|
||||
|
||||
super
|
||||
end
|
||||
end
|
8
extensions/tags_controller.rb
Normale Datei
8
extensions/tags_controller.rb
Normale Datei
|
@ -0,0 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module CustomWizardTagsController
|
||||
def search
|
||||
RequestStore.store[:tag_groups] = params[:tag_groups] if params[:tag_groups].present?
|
||||
super
|
||||
end
|
||||
end
|
|
@ -86,7 +86,7 @@ class CustomWizard::Builder
|
|||
required: field_template['required']
|
||||
}
|
||||
|
||||
%w(label description image key validations min_length max_length char_counter).each do |key|
|
||||
%w(label description image key validations min_length max_length char_counter tag_groups).each do |key|
|
||||
params[key.to_sym] = field_template[key] if field_template[key]
|
||||
end
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ class CustomWizard::Field
|
|||
:limit,
|
||||
:property,
|
||||
:content,
|
||||
:tag_groups,
|
||||
:preview_template,
|
||||
:placeholder
|
||||
|
||||
|
@ -46,6 +47,7 @@ class CustomWizard::Field
|
|||
@limit = attrs[:limit]
|
||||
@property = attrs[:property]
|
||||
@content = attrs[:content]
|
||||
@tag_groups = attrs[:tag_groups]
|
||||
@preview_template = attrs[:preview_template]
|
||||
@placeholder = attrs[:placeholder]
|
||||
end
|
||||
|
@ -111,7 +113,8 @@ class CustomWizard::Field
|
|||
tag: {
|
||||
limit: nil,
|
||||
prefill: nil,
|
||||
content: nil
|
||||
content: nil,
|
||||
tag_groups: nil
|
||||
},
|
||||
category: {
|
||||
limit: 1,
|
||||
|
|
11
plugin.rb
11
plugin.rb
|
@ -1,12 +1,14 @@
|
|||
# frozen_string_literal: true
|
||||
# name: discourse-custom-wizard
|
||||
# about: Create custom wizards
|
||||
# version: 1.17.3
|
||||
# version: 1.18.0
|
||||
# authors: Angus McLeod
|
||||
# url: https://github.com/paviliondev/discourse-custom-wizard
|
||||
# contact emails: angus@thepavilion.io
|
||||
|
||||
gem 'liquid', '5.0.1', require: true
|
||||
## ensure compatibility with category lockdown plugin
|
||||
gem 'request_store', '1.5.0', require: true
|
||||
register_asset 'stylesheets/common/wizard-admin.scss'
|
||||
register_asset 'stylesheets/common/wizard-mapper.scss'
|
||||
|
||||
|
@ -110,9 +112,11 @@ after_initialize do
|
|||
../extensions/invites_controller.rb
|
||||
../extensions/guardian.rb
|
||||
../extensions/users_controller.rb
|
||||
../extensions/tags_controller.rb
|
||||
../extensions/custom_field/preloader.rb
|
||||
../extensions/custom_field/serializer.rb
|
||||
../extensions/custom_field/extension.rb
|
||||
../extensions/discourse_tagging.rb
|
||||
].each do |path|
|
||||
load File.expand_path(path, __FILE__)
|
||||
end
|
||||
|
@ -249,5 +253,10 @@ after_initialize do
|
|||
"#{serializer_klass}_serializer".classify.constantize.prepend CustomWizardCustomFieldSerializer
|
||||
end
|
||||
|
||||
reloadable_patch do |plugin|
|
||||
::TagsController.prepend CustomWizardTagsController
|
||||
::DiscourseTagging.singleton_class.prepend CustomWizardDiscourseTagging
|
||||
end
|
||||
|
||||
DiscourseEvent.trigger(:custom_wizard_ready)
|
||||
end
|
||||
|
|
|
@ -16,6 +16,7 @@ class CustomWizard::FieldSerializer < ::ApplicationSerializer
|
|||
:limit,
|
||||
:property,
|
||||
:content,
|
||||
:tag_groups,
|
||||
:validations,
|
||||
:max_length,
|
||||
:char_counter,
|
||||
|
@ -100,6 +101,10 @@ class CustomWizard::FieldSerializer < ::ApplicationSerializer
|
|||
object.content
|
||||
end
|
||||
|
||||
def content
|
||||
object.tag_groups
|
||||
end
|
||||
|
||||
def validations
|
||||
validations = {}
|
||||
object.validations&.each do |type, props|
|
||||
|
|
43
spec/extensions/tags_controller_spec.rb
Normale Datei
43
spec/extensions/tags_controller_spec.rb
Normale Datei
|
@ -0,0 +1,43 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require_relative '../plugin_helper'
|
||||
|
||||
describe ::TagsController, type: :request do
|
||||
fab!(:tag_1) { Fabricate(:tag, name: "Angus") }
|
||||
fab!(:tag_2) { Fabricate(:tag, name: "Faizaan") }
|
||||
fab!(:tag_3) { Fabricate(:tag, name: "Robert") }
|
||||
fab!(:tag_4) { Fabricate(:tag, name: "Eli") }
|
||||
fab!(:tag_5) { Fabricate(:tag, name: "Jeff") }
|
||||
|
||||
fab!(:tag_group_1) { Fabricate(:tag_group, tags: [tag_1, tag_2]) }
|
||||
fab!(:tag_group_2) { Fabricate(:tag_group, tags: [tag_3, tag_4]) }
|
||||
|
||||
describe "#search" do
|
||||
context "tag group param present" do
|
||||
it "returns tags only only in the tag group" do
|
||||
get "/tags/filter/search.json", params: { q: '', tag_groups: [tag_group_1.name, tag_group_2.name] }
|
||||
expect(response.status).to eq(200)
|
||||
results = response.parsed_body['results']
|
||||
names = results.map { |result| result['name'] }
|
||||
|
||||
expected_tag_names = TagGroup
|
||||
.includes(:tags)
|
||||
.where(id: [tag_group_1.id, tag_group_2.id])
|
||||
.map { |tag_group| tag_group.tags.pluck(:name) }.flatten
|
||||
expect(names).to contain_exactly(*expected_tag_names)
|
||||
end
|
||||
end
|
||||
|
||||
context "tag group param not present" do
|
||||
it "returns all tags" do
|
||||
get "/tags/filter/search.json", params: { q: '' }
|
||||
expect(response.status).to eq(200)
|
||||
results = response.parsed_body['results']
|
||||
names = results.map { |result| result['name'] }
|
||||
|
||||
all_tag_names = Tag.all.pluck(:name)
|
||||
expect(names).to contain_exactly(*all_tag_names)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Laden …
In neuem Issue referenzieren