Commits vergleichen
16 Commits
main
...
workflow-f
Autor | SHA1 | Datum | |
---|---|---|---|
|
9e76acbd66 | ||
|
c6ec744b13 | ||
|
ec78229ba0 | ||
|
5360cef214 | ||
|
86ff55c33a | ||
|
52fe6e2baa | ||
|
ecd1fdc5c7 | ||
|
d696ccd982 | ||
|
8770266d3e | ||
|
f537d8504b | ||
|
72778884fa | ||
|
f13b017b83 | ||
|
76c2fd511c | ||
|
95b0758647 | ||
|
21cf81b7a5 | ||
|
de2faf893f |
16 geänderte Dateien mit 153 neuen und 8 gelöschten Zeilen
12
.github/workflows/plugin-tests.yml
gevendort
12
.github/workflows/plugin-tests.yml
gevendort
|
@ -31,7 +31,7 @@ jobs:
|
||||||
build_type: ["backend", "frontend"]
|
build_type: ["backend", "frontend"]
|
||||||
ruby: ["2.7"]
|
ruby: ["2.7"]
|
||||||
postgres: ["12"]
|
postgres: ["12"]
|
||||||
redis: ["4.x"]
|
redis: ["6.x"]
|
||||||
|
|
||||||
services:
|
services:
|
||||||
postgres:
|
postgres:
|
||||||
|
@ -49,10 +49,17 @@ jobs:
|
||||||
--health-retries 5
|
--health-retries 5
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
- uses: haya14busa/action-cond@v1
|
||||||
|
id: discourse_branch
|
||||||
|
with:
|
||||||
|
cond: ${{ github.base_ref == 'stable' }}
|
||||||
|
if_true: "stable"
|
||||||
|
if_false: "tests-passed"
|
||||||
|
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
repository: discourse/discourse
|
repository: discourse/discourse
|
||||||
ref: "${{ (github.base_ref || github.ref) }}"
|
ref: ${{ steps.discourse_branch.outputs.value }}
|
||||||
fetch-depth: 1
|
fetch-depth: 1
|
||||||
|
|
||||||
- name: Fetch Repo Name
|
- name: Fetch Repo Name
|
||||||
|
@ -63,6 +70,7 @@ jobs:
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
path: plugins/${{ steps.repo-name.outputs.value }}
|
path: plugins/${{ steps.repo-name.outputs.value }}
|
||||||
|
ref: "${{ github.base_ref }}"
|
||||||
fetch-depth: 1
|
fetch-depth: 1
|
||||||
|
|
||||||
- name: Check spec existence
|
- name: Check spec existence
|
||||||
|
|
|
@ -208,6 +208,20 @@
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/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}}
|
{{#if showAdvanced}}
|
||||||
{{wizard-advanced-toggle showAdvanced=field.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);
|
||||||
|
},
|
||||||
|
});
|
|
@ -40,6 +40,12 @@ CustomWizard.reopenClass({
|
||||||
.catch(popupAjaxError);
|
.catch(popupAjaxError);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
restart(wizardId) {
|
||||||
|
ajax({ url: `/w/${wizardId}/skip`, type: "PUT" }).then(() => {
|
||||||
|
window.location.href = `/w/${wizardId}`;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
finished(result) {
|
finished(result) {
|
||||||
let url = "/";
|
let url = "/";
|
||||||
if (result.redirect_on_complete) {
|
if (result.redirect_on_complete) {
|
||||||
|
|
|
@ -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"
|
property: "Property"
|
||||||
prefill: "Prefill"
|
prefill: "Prefill"
|
||||||
content: "Content"
|
content: "Content"
|
||||||
|
tag_groups: "Tag Groups"
|
||||||
date_time_format:
|
date_time_format:
|
||||||
label: "Format"
|
label: "Format"
|
||||||
instructions: "<a href='https://momentjs.com/docs/#/displaying/format/' target='_blank'>Moment.js format</a>"
|
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,
|
condition: mapped_params,
|
||||||
index: mapped_params,
|
index: mapped_params,
|
||||||
validations: {},
|
validations: {},
|
||||||
|
tag_groups: [],
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
actions: [
|
actions: [
|
||||||
|
|
18
extensions/discourse_tagging.rb
Normale Datei
18
extensions/discourse_tagging.rb
Normale Datei
|
@ -0,0 +1,18 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
require 'request_store'
|
||||||
|
|
||||||
|
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
|
9
extensions/tags_controller.rb
Normale Datei
9
extensions/tags_controller.rb
Normale Datei
|
@ -0,0 +1,9 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
require 'request_store'
|
||||||
|
|
||||||
|
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']
|
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]
|
params[key.to_sym] = field_template[key] if field_template[key]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ class CustomWizard::Field
|
||||||
:limit,
|
:limit,
|
||||||
:property,
|
:property,
|
||||||
:content,
|
:content,
|
||||||
|
:tag_groups,
|
||||||
:preview_template,
|
:preview_template,
|
||||||
:placeholder
|
:placeholder
|
||||||
|
|
||||||
|
@ -46,6 +47,7 @@ class CustomWizard::Field
|
||||||
@limit = attrs[:limit]
|
@limit = attrs[:limit]
|
||||||
@property = attrs[:property]
|
@property = attrs[:property]
|
||||||
@content = attrs[:content]
|
@content = attrs[:content]
|
||||||
|
@tag_groups = attrs[:tag_groups]
|
||||||
@preview_template = attrs[:preview_template]
|
@preview_template = attrs[:preview_template]
|
||||||
@placeholder = attrs[:placeholder]
|
@placeholder = attrs[:placeholder]
|
||||||
end
|
end
|
||||||
|
@ -111,7 +113,8 @@ class CustomWizard::Field
|
||||||
tag: {
|
tag: {
|
||||||
limit: nil,
|
limit: nil,
|
||||||
prefill: nil,
|
prefill: nil,
|
||||||
content: nil
|
content: nil,
|
||||||
|
tag_groups: nil
|
||||||
},
|
},
|
||||||
category: {
|
category: {
|
||||||
limit: 1,
|
limit: 1,
|
||||||
|
|
10
plugin.rb
10
plugin.rb
|
@ -1,12 +1,13 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
# name: discourse-custom-wizard
|
# name: discourse-custom-wizard
|
||||||
# about: Create custom wizards
|
# about: Create custom wizards
|
||||||
# version: 1.17.2
|
# version: 1.18.2.stable
|
||||||
# authors: Angus McLeod
|
# authors: Angus McLeod
|
||||||
# url: https://github.com/paviliondev/discourse-custom-wizard
|
# url: https://github.com/paviliondev/discourse-custom-wizard
|
||||||
# contact emails: angus@thepavilion.io
|
# contact emails: angus@thepavilion.io
|
||||||
|
|
||||||
gem 'liquid', '5.0.1', require: true
|
gem 'liquid', '5.0.1', require: true
|
||||||
|
|
||||||
register_asset 'stylesheets/common/wizard-admin.scss'
|
register_asset 'stylesheets/common/wizard-admin.scss'
|
||||||
register_asset 'stylesheets/common/wizard-mapper.scss'
|
register_asset 'stylesheets/common/wizard-mapper.scss'
|
||||||
|
|
||||||
|
@ -110,9 +111,11 @@ after_initialize do
|
||||||
../extensions/invites_controller.rb
|
../extensions/invites_controller.rb
|
||||||
../extensions/guardian.rb
|
../extensions/guardian.rb
|
||||||
../extensions/users_controller.rb
|
../extensions/users_controller.rb
|
||||||
|
../extensions/tags_controller.rb
|
||||||
../extensions/custom_field/preloader.rb
|
../extensions/custom_field/preloader.rb
|
||||||
../extensions/custom_field/serializer.rb
|
../extensions/custom_field/serializer.rb
|
||||||
../extensions/custom_field/extension.rb
|
../extensions/custom_field/extension.rb
|
||||||
|
../extensions/discourse_tagging.rb
|
||||||
].each do |path|
|
].each do |path|
|
||||||
load File.expand_path(path, __FILE__)
|
load File.expand_path(path, __FILE__)
|
||||||
end
|
end
|
||||||
|
@ -249,5 +252,10 @@ after_initialize do
|
||||||
"#{serializer_klass}_serializer".classify.constantize.prepend CustomWizardCustomFieldSerializer
|
"#{serializer_klass}_serializer".classify.constantize.prepend CustomWizardCustomFieldSerializer
|
||||||
end
|
end
|
||||||
|
|
||||||
|
reloadable_patch do |plugin|
|
||||||
|
::TagsController.prepend CustomWizardTagsController
|
||||||
|
::DiscourseTagging.singleton_class.prepend CustomWizardDiscourseTagging
|
||||||
|
end
|
||||||
|
|
||||||
DiscourseEvent.trigger(:custom_wizard_ready)
|
DiscourseEvent.trigger(:custom_wizard_ready)
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,6 +16,7 @@ class CustomWizard::FieldSerializer < ::ApplicationSerializer
|
||||||
:limit,
|
:limit,
|
||||||
:property,
|
:property,
|
||||||
:content,
|
:content,
|
||||||
|
:tag_groups,
|
||||||
:validations,
|
:validations,
|
||||||
:max_length,
|
:max_length,
|
||||||
:char_counter,
|
:char_counter,
|
||||||
|
@ -100,6 +101,10 @@ class CustomWizard::FieldSerializer < ::ApplicationSerializer
|
||||||
object.content
|
object.content
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def content
|
||||||
|
object.tag_groups
|
||||||
|
end
|
||||||
|
|
||||||
def validations
|
def validations
|
||||||
validations = {}
|
validations = {}
|
||||||
object.validations&.each do |type, props|
|
object.validations&.each do |type, props|
|
||||||
|
|
|
@ -64,6 +64,12 @@ class CustomWizard::WizardSerializer < CustomWizard::BasicWizardSerializer
|
||||||
end
|
end
|
||||||
|
|
||||||
def categories
|
def categories
|
||||||
object.categories.map { |c| c.to_h }
|
object.categories.map do |category|
|
||||||
|
if category.respond_to?(:to_h)
|
||||||
|
category.to_h
|
||||||
|
else
|
||||||
|
::BasicCategorySerializer.new(category).as_json
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -199,7 +199,7 @@ describe CustomWizard::Wizard do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "lists the site categories" do
|
it "lists the site categories" do
|
||||||
Site.clear_cache
|
Site.clear_cache if Site.respond_to?(:clear_cache)
|
||||||
expect(@wizard.categories.length).to eq(1)
|
expect(@wizard.categories.length).to eq(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
48
spec/extensions/tags_controller_spec.rb
Normale Datei
48
spec/extensions/tags_controller_spec.rb
Normale Datei
|
@ -0,0 +1,48 @@
|
||||||
|
# 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]) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
::RequestStore.store[:tag_groups] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#search" do
|
||||||
|
context "tag group param present" do
|
||||||
|
it "returns tags 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