diff --git a/app/assets/javascripts/wizard/components/radio-button.js.es6 b/app/assets/javascripts/wizard/components/radio-button.js.es6
new file mode 100644
index 000000000..ef547d301
--- /dev/null
+++ b/app/assets/javascripts/wizard/components/radio-button.js.es6
@@ -0,0 +1,17 @@
+import { observes, on } from 'ember-addons/ember-computed-decorators';
+
+export default Ember.Component.extend({
+ tagName: 'label',
+
+ click(e) {
+ e.preventDefault();
+ this.sendAction('onChange', this.get('radioValue'));
+ },
+
+ @observes('value')
+ @on('init')
+ updateVal() {
+ const checked = this.get('value') === this.get('radioValue');
+ Ember.run.next(() => this.$('input[type=radio]').prop('checked', checked));
+ }
+});
diff --git a/app/assets/javascripts/wizard/components/wizard-field-radio.js.es6 b/app/assets/javascripts/wizard/components/wizard-field-radio.js.es6
new file mode 100644
index 000000000..24481e15b
--- /dev/null
+++ b/app/assets/javascripts/wizard/components/wizard-field-radio.js.es6
@@ -0,0 +1,7 @@
+export default Ember.Component.extend({
+ actions: {
+ changed(value) {
+ this.set('field.value', value);
+ }
+ }
+});
diff --git a/app/assets/javascripts/wizard/templates/components/radio-button.hbs b/app/assets/javascripts/wizard/templates/components/radio-button.hbs
new file mode 100644
index 000000000..ed8e2c870
--- /dev/null
+++ b/app/assets/javascripts/wizard/templates/components/radio-button.hbs
@@ -0,0 +1,12 @@
+
+
+
+ {{#if icon}}
+ {{fa-icon icon}}
+ {{/if}}
+ {{label}}
+
+
+
+ {{description}}
+
diff --git a/app/assets/javascripts/wizard/templates/components/wizard-field-radio.hbs b/app/assets/javascripts/wizard/templates/components/wizard-field-radio.hbs
new file mode 100644
index 000000000..6461851a7
--- /dev/null
+++ b/app/assets/javascripts/wizard/templates/components/wizard-field-radio.hbs
@@ -0,0 +1,10 @@
+{{#each field.choices as |c|}}
+
+ {{radio-button value=field.value
+ radioValue=c.id
+ label=c.label
+ icon=c.icon
+ description=c.description
+ onChange="changed"}}
+
+{{/each}}
diff --git a/app/assets/javascripts/wizard/test/wizard-pretender.js.es6 b/app/assets/javascripts/wizard/test/wizard-pretender.js.es6
index c85aceb0a..1ede6fdfb 100644
--- a/app/assets/javascripts/wizard/test/wizard-pretender.js.es6
+++ b/app/assets/javascripts/wizard/test/wizard-pretender.js.es6
@@ -51,7 +51,8 @@ export default function() {
index: 1,
fields: [
{ id: 'snack', type: 'dropdown', required: true },
- { id: 'theme-preview', type: 'component' }
+ { id: 'theme-preview', type: 'component' },
+ { id: 'an-image', type: 'image' }
],
previous: 'hello-world'
}]
diff --git a/app/assets/stylesheets/wizard.scss b/app/assets/stylesheets/wizard.scss
index 024899c7a..e7cfaf2d2 100644
--- a/app/assets/stylesheets/wizard.scss
+++ b/app/assets/stylesheets/wizard.scss
@@ -263,3 +263,20 @@ body.wizard {
}
}
+.radio-field-choice {
+ margin-bottom: 1.5em;
+
+ input {
+ outline: 0;
+ }
+
+ .radio-label {
+ font-weight: bold;
+ margin-left: 0.5em;
+ }
+ .radio-description {
+ margin-top: 0.25em;
+ margin-left: 1.75em;
+ color: #777;
+ }
+}
diff --git a/app/serializers/wizard_field_choice_serializer.rb b/app/serializers/wizard_field_choice_serializer.rb
index d364f0bdd..286562ad4 100644
--- a/app/serializers/wizard_field_choice_serializer.rb
+++ b/app/serializers/wizard_field_choice_serializer.rb
@@ -1,17 +1,37 @@
class WizardFieldChoiceSerializer < ApplicationSerializer
- attributes :id, :label, :data
+ attributes :id, :label, :description, :icon, :data
def id
object.id
end
+ def i18nkey
+ field = object.field
+ step = field.step
+ "wizard.step.#{step.id}.fields.#{field.id}.choices.#{id}"
+ end
+
def label
return object.label if object.label.present?
# Try getting one from a translation
- field = object.field
- step = field.step
- I18n.t("wizard.step.#{step.id}.fields.#{field.id}.options.#{id}", default: id)
+ I18n.t("#{i18nkey}.label", default: id)
+ end
+
+ def description
+ I18n.t("#{i18nkey}.description", default: "")
+ end
+
+ def include_description?
+ description.present?
+ end
+
+ def icon
+ object.icon
+ end
+
+ def include_icon?
+ object.icon.present?
end
def data
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index 605177aeb..1396ffc59 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -3236,6 +3236,21 @@ en:
site_description:
label: "Describe your forum in one sentence"
placeholder: "A place for Jane and her friends to discuss cool stuff"
+
+ privacy:
+ title: "Privacy Options"
+ description: "Feel free to set things up privately, then switch to public later!"
+
+ fields:
+ privacy:
+ choices:
+ open:
+ label: "Open Access"
+ description: "Anyone can access and sign up for your forum"
+ restricted:
+ label: "Restricted Access"
+ description: "Access will be restricted to those you've invited"
+
contact:
title: "Don't be a Stranger"
fields:
@@ -3255,9 +3270,11 @@ en:
fields:
theme_id:
label: "Theme"
- options:
- default: "Simple"
- dark: "Dark"
+ choices:
+ default:
+ label: "Simple"
+ dark:
+ label: "Dark"
logos:
title: "Personalize your Forum"
fields:
diff --git a/lib/wizard.rb b/lib/wizard.rb
index a58e7332b..522b9de60 100644
--- a/lib/wizard.rb
+++ b/lib/wizard.rb
@@ -52,6 +52,17 @@ class Wizard
step.add_field(id: 'site_description', type: 'text', required: true, value: SiteSetting.site_description)
end
+ wizard.append_step('privacy') do |step|
+
+ locked = SiteSetting.login_required? && SiteSetting.invite_only?
+ privacy = step.add_field(id: 'privacy',
+ type: 'radio',
+ required: true,
+ value: locked ? 'restricted' : 'open')
+ privacy.add_choice('open', icon: 'unlock')
+ privacy.add_choice('restricted', icon: 'lock')
+ end
+
wizard.append_step('contact') do |step|
step.add_field(id: 'contact_email', type: 'text', required: true, value: SiteSetting.contact_email)
step.add_field(id: 'contact_url', type: 'text', value: SiteSetting.contact_url)
diff --git a/lib/wizard/field.rb b/lib/wizard/field.rb
index 5b8faf8fc..47883161c 100644
--- a/lib/wizard/field.rb
+++ b/lib/wizard/field.rb
@@ -1,13 +1,14 @@
class Wizard
class Choice
- attr_reader :id, :label, :data
+ attr_reader :id, :label, :icon, :data
attr_accessor :field
def initialize(id, opts)
@id = id
@data = opts[:data]
@label = opts[:label]
+ @icon = opts[:icon]
end
end
diff --git a/lib/wizard/step_updater.rb b/lib/wizard/step_updater.rb
index 5e473fe21..e8c3253e6 100644
--- a/lib/wizard/step_updater.rb
+++ b/lib/wizard/step_updater.rb
@@ -15,19 +15,24 @@ class Wizard
def update_locale(fields)
old_locale = SiteSetting.default_locale
- update_setting(:default_locale, fields, :default_locale)
+ update_setting_field(:default_locale, fields, :default_locale)
@refresh_required = true if old_locale != fields[:default_locale]
end
+ def update_privacy(fields)
+ update_setting(:login_required, fields[:privacy] == 'restricted')
+ update_setting(:invite_only, fields[:privacy] == 'restricted')
+ end
+
def update_forum_title(fields)
- update_setting(:title, fields, :title)
- update_setting(:site_description, fields, :site_description)
+ update_setting_field(:title, fields, :title)
+ update_setting_field(:site_description, fields, :site_description)
end
def update_contact(fields)
- update_setting(:contact_email, fields, :contact_email)
- update_setting(:contact_url, fields, :contact_url)
- update_setting(:site_contact_username, fields, :site_contact_username)
+ update_setting_field(:contact_email, fields, :contact_email)
+ update_setting_field(:contact_url, fields, :contact_url)
+ update_setting_field(:site_contact_username, fields, :site_contact_username)
end
def update_colors(fields)
@@ -60,10 +65,10 @@ class Wizard
end
def update_logos(fields)
- update_setting(:logo_url, fields, :logo_url)
- update_setting(:logo_small_url, fields, :logo_small_url)
- update_setting(:favicon_url, fields, :favicon_url)
- update_setting(:apple_touch_icon_url, fields, :apple_touch_icon_url)
+ update_setting_field(:logo_url, fields, :logo_url)
+ update_setting_field(:logo_small_url, fields, :logo_small_url)
+ update_setting_field(:favicon_url, fields, :favicon_url)
+ update_setting_field(:apple_touch_icon_url, fields, :apple_touch_icon_url)
end
def success?
@@ -76,11 +81,13 @@ class Wizard
protected
- def update_setting(id, fields, field_id)
- value = fields[field_id]
+ def update_setting(id, value)
value.strip! if value.is_a?(String)
-
SiteSetting.set_and_log(id, value, @current_user) if SiteSetting.send(id) != value
+ end
+
+ def update_setting_field(id, fields, field_id)
+ update_setting(id, fields[field_id])
rescue Discourse::InvalidParameters => e
errors.add(field_id, e.message)
end
diff --git a/spec/components/step_updater_spec.rb b/spec/components/step_updater_spec.rb
index 4867ddb5a..c53be46de 100644
--- a/spec/components/step_updater_spec.rb
+++ b/spec/components/step_updater_spec.rb
@@ -19,9 +19,6 @@ describe Wizard::StepUpdater do
end
end
- it "updates the locale" do
- end
-
it "updates the forum title step" do
updater = Wizard::StepUpdater.new(user, 'forum_title')
updater.update(title: 'new forum title', site_description: 'neat place')
@@ -31,6 +28,24 @@ describe Wizard::StepUpdater do
expect(SiteSetting.site_description).to eq("neat place")
end
+ context "privacy settings" do
+ let(:updater) { Wizard::StepUpdater.new(user, 'privacy') }
+
+ it "updates to open correctly" do
+ updater.update(privacy: 'open')
+ expect(updater.success?).to eq(true)
+ expect(SiteSetting.login_required?).to eq(false)
+ expect(SiteSetting.invite_only?).to eq(false)
+ end
+
+ it "updates to private correctly" do
+ updater.update(privacy: 'restricted')
+ expect(updater.success?).to eq(true)
+ expect(SiteSetting.login_required?).to eq(true)
+ expect(SiteSetting.invite_only?).to eq(true)
+ end
+ end
+
context "contact step" do
let(:updater) { Wizard::StepUpdater.new(user, 'contact') }