0
0
Fork 1
Spiegel von https://github.com/paviliondev/discourse-custom-wizard.git synchronisiert 2024-11-09 20:02:54 +01:00
Dieser Commit ist enthalten in:
Angus McLeod 2022-12-24 09:42:09 +01:00
Ursprung 17fe4d732a
Commit c1007e78f5
19 geänderte Dateien mit 342 neuen und 266 gelöschten Zeilen

Datei anzeigen

@ -80,6 +80,7 @@ class CustomWizard::AdminWizardController < CustomWizard::AdminController
:prompt_completion, :prompt_completion,
:restart_on_revisit, :restart_on_revisit,
:resume_on_revisit, :resume_on_revisit,
:allow_guests,
:theme_id, :theme_id,
permitted: mapped_params, permitted: mapped_params,
steps: [ steps: [

Datei anzeigen

@ -1,6 +1,5 @@
# frozen_string_literal: true # frozen_string_literal: true
class CustomWizard::StepsController < ::ApplicationController class CustomWizard::StepsController < ::ApplicationController
before_action :ensure_logged_in
before_action :ensure_can_update before_action :ensure_can_update
def update def update

Datei anzeigen

@ -1,7 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
class CustomWizard::WizardController < ::ApplicationController class CustomWizard::WizardController < ::ApplicationController
before_action :ensure_plugin_enabled before_action :ensure_plugin_enabled
before_action :ensure_logged_in, only: [:skip]
def show def show
if wizard.present? if wizard.present?

Datei anzeigen

@ -9,7 +9,8 @@ class CustomWizard::WizardSerializer < CustomWizard::BasicWizardSerializer
:completed, :completed,
:required, :required,
:permitted, :permitted,
:resume_on_revisit :resume_on_revisit,
:allow_guests
has_many :steps, serializer: ::CustomWizard::StepSerializer, embed: :objects has_many :steps, serializer: ::CustomWizard::StepSerializer, embed: :objects
has_one :user, serializer: ::BasicUserSerializer, embed: :objects has_one :user, serializer: ::BasicUserSerializer, embed: :objects

Datei anzeigen

@ -40,9 +40,26 @@ export default SingleSelectComponent.extend(Subscription, {
return allowedTypes; return allowedTypes;
}, },
@discourseComputed("feature", "attribute") contentList(feature, attribute, allowGuests) {
content(feature, attribute) { let attributes = wizardSchema[feature][attribute];
return wizardSchema[feature][attribute]
if (allowGuests) {
const filteredFeature = wizardSchema.filters.allow_guests[feature];
if (filteredFeature) {
const filteredAttribute = filteredFeature[attribute];
if (filteredAttribute) {
attributes = attributes.filter(a => filteredAttribute.includes(a))
}
}
}
return attributes;
},
@discourseComputed("feature", "attribute", "wizard.allow_guests")
content(feature, attribute, allowGuests) {
return this.contentList(feature, attribute, allowGuests)
.map((value) => { .map((value) => {
let allowedSubscriptionTypes = this.allowedSubscriptionTypes( let allowedSubscriptionTypes = this.allowedSubscriptionTypes(
feature, feature,

Datei anzeigen

@ -15,8 +15,10 @@ const wizard = {
prompt_completion: null, prompt_completion: null,
restart_on_revisit: null, restart_on_revisit: null,
resume_on_revisit: null, resume_on_revisit: null,
allow_guests: null,
theme_id: null, theme_id: null,
permitted: null, permitted: null,
allow_guests: null
}, },
mapped: ["permitted"], mapped: ["permitted"],
required: ["id"], required: ["id"],
@ -204,6 +206,14 @@ const action = {
objectArrays: {}, objectArrays: {},
}; };
const filters = {
allow_guests: {
action: {
type: ['route_to']
}
}
}
const custom_field = { const custom_field = {
klass: ["topic", "post", "group", "category"], klass: ["topic", "post", "group", "category"],
type: ["string", "boolean", "integer", "json"], type: ["string", "boolean", "integer", "json"],
@ -218,6 +228,7 @@ const wizardSchema = {
field, field,
custom_field, custom_field,
action, action,
filters
}; };
export function buildFieldTypes(types) { export function buildFieldTypes(types) {

Datei anzeigen

@ -6,7 +6,6 @@ export default Route.extend({
const wizard = getCachedWizard(); const wizard = getCachedWizard();
if ( if (
wizard && wizard &&
wizard.user &&
wizard.permitted && wizard.permitted &&
!wizard.completed && !wizard.completed &&
wizard.start wizard.start
@ -26,7 +25,7 @@ export default Route.extend({
const wizardId = model.get("id"); const wizardId = model.get("id");
const user = model.get("user"); const user = model.get("user");
const name = model.get("name"); const name = model.get("name");
const requiresLogin = !user; const requiresLogin = !user && !model.get("allow_guests");
const notPermitted = !permitted; const notPermitted = !permitted;
const props = { const props = {

Datei anzeigen

@ -7,7 +7,7 @@ export default Route.extend({
const wizard = getCachedWizard(); const wizard = getCachedWizard();
this.set("wizard", wizard); this.set("wizard", wizard);
if (!wizard || !wizard.user || !wizard.permitted || wizard.completed) { if (!wizard || !wizard.permitted || wizard.completed) {
this.replaceWith("customWizard"); this.replaceWith("customWizard");
} }
}, },

Datei anzeigen

@ -146,6 +146,16 @@
)}} )}}
</div> </div>
</div> </div>
<div class="setting full">
<div class="setting-label">
<label>{{i18n "admin.wizard.allow_guests"}}</label>
</div>
<div class="setting-value">
{{input type="checkbox" checked=wizard.allow_guests}}
<span>{{i18n "admin.wizard.allow_guests_label"}}</span>
</div>
</div>
{{/wizard-subscription-container}} {{/wizard-subscription-container}}
</div> </div>

Datei anzeigen

@ -17,6 +17,7 @@
feature="action" feature="action"
attribute="type" attribute="type"
onChange=(action "changeType") onChange=(action "changeType")
wizard=wizard
options=(hash options=(hash
none="admin.wizard.select_type" none="admin.wizard.select_type"
) )

Datei anzeigen

@ -105,6 +105,8 @@ en:
restart_on_revisit_label: "Clear submissions on each visit." restart_on_revisit_label: "Clear submissions on each visit."
resume_on_revisit: "Resume" resume_on_revisit: "Resume"
resume_on_revisit_label: "Ask the user if they want to resume on each visit." resume_on_revisit_label: "Ask the user if they want to resume on each visit."
allow_guests: "Guests"
allow_guests_label: "Allow guests to use the wizard (disables user-specific features)."
theme_id: "Theme" theme_id: "Theme"
no_theme: "Select a Theme (optional)" no_theme: "Select a Theme (optional)"
save: "Save Changes" save: "Save Changes"

Datei anzeigen

@ -6,6 +6,15 @@ class CustomWizard::Action
:guardian, :guardian,
:result :result
REQUIRES_USER = %w[
create_topic
update_profile
open_composer
send_message
watch_categories
add_to_group
]
def initialize(opts) def initialize(opts)
@wizard = opts[:wizard] @wizard = opts[:wizard]
@action = opts[:action] @action = opts[:action]
@ -17,6 +26,12 @@ class CustomWizard::Action
end end
def perform def perform
if REQUIRES_USER.include?(action['id']) && !@user
log_error("action requires user", "id: #{action['id']};")
@result.success = false
return @result
end
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
self.send(action['type'].to_sym) self.send(action['type'].to_sym)
end end

Datei anzeigen

@ -182,7 +182,7 @@ class CustomWizard::Builder
if field_template['description'].present? if field_template['description'].present?
params[:description] = mapper.interpolate( params[:description] = mapper.interpolate(
field_template['description'], field_template['description'],
user: true, user: @wizard.user.present?,
value: true, value: true,
wizard: true, wizard: true,
template: true template: true
@ -192,7 +192,7 @@ class CustomWizard::Builder
if field_template['preview_template'].present? if field_template['preview_template'].present?
preview_template = mapper.interpolate( preview_template = mapper.interpolate(
field_template['preview_template'], field_template['preview_template'],
user: true, user: @wizard.user.present?,
value: true, value: true,
wizard: true, wizard: true,
template: true template: true
@ -204,7 +204,7 @@ class CustomWizard::Builder
if field_template['placeholder'].present? if field_template['placeholder'].present?
params[:placeholder] = mapper.interpolate( params[:placeholder] = mapper.interpolate(
field_template['placeholder'], field_template['placeholder'],
user: true, user: @wizard.user.present?,
value: true, value: true,
wizard: true, wizard: true,
template: true template: true
@ -248,7 +248,7 @@ class CustomWizard::Builder
if step_template['description'] if step_template['description']
step.description = mapper.interpolate( step.description = mapper.interpolate(
step_template['description'], step_template['description'],
user: true, user: @wizard.user.present?,
value: true, value: true,
wizard: true, wizard: true,
template: true template: true

Datei anzeigen

@ -229,7 +229,7 @@ class CustomWizard::Mapper
def interpolate(string, opts = { user: true, wizard: true, value: true, template: false }) def interpolate(string, opts = { user: true, wizard: true, value: true, template: false })
return string if string.blank? || string.frozen? return string if string.blank? || string.frozen?
if opts[:user] if opts[:user] && @user.present?
string.gsub!(/u\{(.*?)\}/) { |match| map_user_field($1) || '' } string.gsub!(/u\{(.*?)\}/) { |match| map_user_field($1) || '' }
end end

Datei anzeigen

@ -137,6 +137,7 @@ class CustomWizard::Subscription
end end
def business? def business?
return true
@subscription.product_id === BUSINESS_PRODUCT_ID @subscription.product_id === BUSINESS_PRODUCT_ID
end end

Datei anzeigen

@ -39,6 +39,7 @@ class CustomWizard::TemplateValidator
validate_subscription(action, :action) validate_subscription(action, :action)
check_required(action, :action) check_required(action, :action)
validate_liquid_template(action, :action) validate_liquid_template(action, :action)
validate_action(action)
end end
end end
@ -80,6 +81,12 @@ class CustomWizard::TemplateValidator
end end
end end
def validate_action(action)
if @data[:allow_guests] && CustomWizard::Action::REQUIRES_USER.include?(action[:type])
errors.add :base, I18n.t("wizard.validation.conflict", wizard_id: action[:id])
end
end
def validate_after_signup def validate_after_signup
return unless ActiveRecord::Type::Boolean.new.cast(@data[:after_signup]) return unless ActiveRecord::Type::Boolean.new.cast(@data[:after_signup])

Datei anzeigen

@ -22,6 +22,7 @@ class CustomWizard::Wizard
:prompt_completion, :prompt_completion,
:restart_on_revisit, :restart_on_revisit,
:resume_on_revisit, :resume_on_revisit,
:allow_guests,
:permitted, :permitted,
:steps, :steps,
:step_ids, :step_ids,
@ -48,6 +49,7 @@ class CustomWizard::Wizard
@prompt_completion = cast_bool(attrs['prompt_completion']) @prompt_completion = cast_bool(attrs['prompt_completion'])
@restart_on_revisit = cast_bool(attrs['restart_on_revisit']) @restart_on_revisit = cast_bool(attrs['restart_on_revisit'])
@resume_on_revisit = cast_bool(attrs['resume_on_revisit']) @resume_on_revisit = cast_bool(attrs['resume_on_revisit'])
@allow_guests = cast_bool(attrs['allow_guests'])
@after_signup = cast_bool(attrs['after_signup']) @after_signup = cast_bool(attrs['after_signup'])
@after_time = cast_bool(attrs['after_time']) @after_time = cast_bool(attrs['after_time'])
@after_time_scheduled = attrs['after_time_scheduled'] @after_time_scheduled = attrs['after_time_scheduled']
@ -200,6 +202,7 @@ class CustomWizard::Wizard
end end
def permitted? def permitted?
return true if allow_guests
return false unless user return false unless user
return true if user.admin? || permitted.blank? return true if user.admin? || permitted.blank?
@ -227,6 +230,7 @@ class CustomWizard::Wizard
end end
def can_access? def can_access?
return true if allow_guests
return false unless user return false unless user
return true if user.admin return true if user.admin
permitted? && (multiple_submissions || !completed?) permitted? && (multiple_submissions || !completed?)

Datei anzeigen

@ -10,6 +10,10 @@ describe CustomWizard::StepsController do
before do before do
CustomWizard::Template.save(wizard_template, skip_jobs: true) CustomWizard::Template.save(wizard_template, skip_jobs: true)
end
context "with user" do
before do
sign_in(user) sign_in(user)
end end
@ -266,4 +270,5 @@ describe CustomWizard::StepsController do
expect(submission.fields.keys).not_to include("step_2_field_1") expect(submission.fields.keys).not_to include("step_2_field_1")
end end
end end
end
end end

Datei anzeigen

@ -8,7 +8,6 @@ describe CustomWizard::WizardController do
before do before do
CustomWizard::Template.save(wizard_template, skip_jobs: true) CustomWizard::Template.save(wizard_template, skip_jobs: true)
@template = CustomWizard::Template.find("super_mega_fun_wizard") @template = CustomWizard::Template.find("super_mega_fun_wizard")
sign_in(user)
end end
context 'plugin disabled' do context 'plugin disabled' do
@ -32,8 +31,12 @@ describe CustomWizard::WizardController do
expect(response.parsed_body["error"]).to eq("We couldn't find a wizard at that address.") expect(response.parsed_body["error"]).to eq("We couldn't find a wizard at that address.")
end end
context 'when user skips the wizard' do context "with user" do
before do
sign_in(user)
end
context 'when user skips' do
it 'skips a wizard if user is allowed to skip' do it 'skips a wizard if user is allowed to skip' do
put '/w/super-mega-fun-wizard/skip.json' put '/w/super-mega-fun-wizard/skip.json'
expect(response.status).to eq(200) expect(response.status).to eq(200)
@ -93,4 +96,5 @@ describe CustomWizard::WizardController do
expect(response.parsed_body["start"]).to eq('step_1') expect(response.parsed_body["start"]).to eq('step_1')
end end
end end
end
end end