diff --git a/assets/javascripts/discourse/components/wizard-custom-action.js.es6 b/assets/javascripts/discourse/components/wizard-custom-action.js.es6 index 95ac4dd7..196bf328 100644 --- a/assets/javascripts/discourse/components/wizard-custom-action.js.es6 +++ b/assets/javascripts/discourse/components/wizard-custom-action.js.es6 @@ -5,6 +5,8 @@ import { computed } from "@ember/object"; import wizardSchema from '../lib/wizard-schema'; import UndoChanges from '../mixins/undo-changes'; import Component from "@ember/component"; +import { notificationLevels } from '../lib/wizard'; +import I18n from "I18n"; export default Component.extend(UndoChanges, { componentType: 'action', @@ -12,6 +14,7 @@ export default Component.extend(UndoChanges, { visible: computed('currentActionId', function() { return this.action.id === this.currentActionId }), createTopic: equal('action.type', 'create_topic'), updateProfile: equal('action.type', 'update_profile'), + watchCategories: equal('action.type', 'watch_categories'), sendMessage: equal('action.type', 'send_message'), openComposer: equal('action.type', 'open_composer'), sendToApi: equal('action.type', 'send_to_api'), @@ -31,6 +34,12 @@ export default Component.extend(UndoChanges, { name: I18n.t(`admin.wizard.action.${type}.label`) }; }), + availableNotificationLevels: notificationLevels.map((type, index) => { + return { + id: type, + name: I18n.t(`admin.wizard.action.watch_categories.notification_level.${type}`) + }; + }), messageUrl: 'https://thepavilion.io/t/2810', diff --git a/assets/javascripts/discourse/components/wizard-custom-field.js.es6 b/assets/javascripts/discourse/components/wizard-custom-field.js.es6 index d7d53e00..9251f433 100644 --- a/assets/javascripts/discourse/components/wizard-custom-field.js.es6 +++ b/assets/javascripts/discourse/components/wizard-custom-field.js.es6 @@ -63,7 +63,8 @@ export default Component.extend(UndoChanges, { if (this.isDropdown) { options.wizardFieldSelection = 'key,value'; options.userFieldOptionsSelection = 'output'; - options.inputTypes = 'association,assignment'; + options.textSelection = 'key,value,output'; + options.inputTypes = 'conditional,association,assignment'; options.pairConnector = 'association'; options.keyPlaceholder = 'admin.wizard.key'; options.valuePlaceholder = 'admin.wizard.value'; diff --git a/assets/javascripts/discourse/components/wizard-export.js.es6 b/assets/javascripts/discourse/components/wizard-export.js.es6 index 2537511d..c75b745e 100644 --- a/assets/javascripts/discourse/components/wizard-export.js.es6 +++ b/assets/javascripts/discourse/components/wizard-export.js.es6 @@ -1,5 +1,6 @@ import Component from "@ember/component"; import { A } from "@ember/array"; +import I18n from "I18n"; export default Component.extend({ classNames: ['container', 'export'], diff --git a/assets/javascripts/discourse/components/wizard-import.js.es6 b/assets/javascripts/discourse/components/wizard-import.js.es6 index d844d5a6..446d2b00 100644 --- a/assets/javascripts/discourse/components/wizard-import.js.es6 +++ b/assets/javascripts/discourse/components/wizard-import.js.es6 @@ -2,6 +2,7 @@ import { ajax } from 'discourse/lib/ajax'; import { default as discourseComputed } from 'discourse-common/utils/decorators'; import { notEmpty } from "@ember/object/computed"; import Component from "@ember/component"; +import I18n from "I18n"; export default Component.extend({ classNames: ['container', 'import'], diff --git a/assets/javascripts/discourse/components/wizard-mapper-connector.js.es6 b/assets/javascripts/discourse/components/wizard-mapper-connector.js.es6 index d2903005..58203e51 100644 --- a/assets/javascripts/discourse/components/wizard-mapper-connector.js.es6 +++ b/assets/javascripts/discourse/components/wizard-mapper-connector.js.es6 @@ -4,6 +4,7 @@ import { computed } from "@ember/object"; import { defaultConnector } from '../lib/wizard-mapper'; import { later } from "@ember/runloop"; import { observes } from "discourse-common/utils/decorators"; +import I18n from "I18n"; export default Component.extend({ classNameBindings: [':mapper-connector', ':mapper-block', 'hasMultiple::single'], diff --git a/assets/javascripts/discourse/components/wizard-mapper-selector.js.es6 b/assets/javascripts/discourse/components/wizard-mapper-selector.js.es6 index b92ab4de..91af570b 100644 --- a/assets/javascripts/discourse/components/wizard-mapper-selector.js.es6 +++ b/assets/javascripts/discourse/components/wizard-mapper-selector.js.es6 @@ -6,6 +6,7 @@ import { defaultSelectionType, selectionTypes } from '../lib/wizard-mapper'; import { snakeCase, generateName, userProperties } from '../lib/wizard'; import Component from "@ember/component"; import { bind, later } from "@ember/runloop"; +import I18n from "I18n"; export default Component.extend({ classNameBindings: [':mapper-selector', 'activeType'], diff --git a/assets/javascripts/discourse/components/wizard-message.js.es6 b/assets/javascripts/discourse/components/wizard-message.js.es6 index 1f1c56ef..0592e9ca 100644 --- a/assets/javascripts/discourse/components/wizard-message.js.es6 +++ b/assets/javascripts/discourse/components/wizard-message.js.es6 @@ -1,5 +1,6 @@ import { default as discourseComputed } from 'discourse-common/utils/decorators'; import Component from "@ember/component"; +import I18n from "I18n"; export default Component.extend({ classNames: 'wizard-message', diff --git a/assets/javascripts/discourse/components/wizard-text-editor.js.es6 b/assets/javascripts/discourse/components/wizard-text-editor.js.es6 index 2b54b56c..25cf05e8 100644 --- a/assets/javascripts/discourse/components/wizard-text-editor.js.es6 +++ b/assets/javascripts/discourse/components/wizard-text-editor.js.es6 @@ -3,6 +3,7 @@ import { notEmpty } from "@ember/object/computed"; import { userProperties } from '../lib/wizard'; import { scheduleOnce } from "@ember/runloop"; import Component from "@ember/component"; +import I18n from "I18n"; export default Component.extend({ classNames: 'wizard-text-editor', diff --git a/assets/javascripts/discourse/controllers/admin-wizards-api-show.js.es6 b/assets/javascripts/discourse/controllers/admin-wizards-api-show.js.es6 index f449e19a..da6822a3 100644 --- a/assets/javascripts/discourse/controllers/admin-wizards-api-show.js.es6 +++ b/assets/javascripts/discourse/controllers/admin-wizards-api-show.js.es6 @@ -5,6 +5,7 @@ import { default as discourseComputed } from 'discourse-common/utils/decorators' import { not, and, equal } from "@ember/object/computed"; import { selectKitContent } from '../lib/wizard'; import Controller from "@ember/controller"; +import I18n from "I18n"; export default Controller.extend({ queryParams: ['refresh_list'], diff --git a/assets/javascripts/discourse/controllers/admin-wizards-logs.js.es6 b/assets/javascripts/discourse/controllers/admin-wizards-logs.js.es6 index 26e2d622..71ced3a5 100644 --- a/assets/javascripts/discourse/controllers/admin-wizards-logs.js.es6 +++ b/assets/javascripts/discourse/controllers/admin-wizards-logs.js.es6 @@ -3,8 +3,9 @@ import { popupAjaxError } from 'discourse/lib/ajax-error'; import { ajax } from 'discourse/lib/ajax'; import { notEmpty } from "@ember/object/computed"; import CustomWizardLogs from '../models/custom-wizard-logs'; +import Controller from "@ember/controller"; -export default Ember.Controller.extend({ +export default Controller.extend({ refreshing: false, hasLogs: notEmpty("logs"), page: 0, diff --git a/assets/javascripts/discourse/controllers/admin-wizards-wizard-show.js.es6 b/assets/javascripts/discourse/controllers/admin-wizards-wizard-show.js.es6 index 5f10283e..fd01f605 100644 --- a/assets/javascripts/discourse/controllers/admin-wizards-wizard-show.js.es6 +++ b/assets/javascripts/discourse/controllers/admin-wizards-wizard-show.js.es6 @@ -9,6 +9,7 @@ import { scheduleOnce, later } from "@ember/runloop"; import Controller from "@ember/controller"; import copyText from "discourse/lib/copy-text"; import CustomWizard from '../models/custom-wizard'; +import I18n from "I18n"; export default Controller.extend({ hasName: notEmpty('wizard.name'), diff --git a/assets/javascripts/discourse/controllers/next-session-scheduled.js.es6 b/assets/javascripts/discourse/controllers/next-session-scheduled.js.es6 index cb7650e7..4cfd4883 100644 --- a/assets/javascripts/discourse/controllers/next-session-scheduled.js.es6 +++ b/assets/javascripts/discourse/controllers/next-session-scheduled.js.es6 @@ -1,58 +1,27 @@ import { default as discourseComputed } from 'discourse-common/utils/decorators'; -import { scheduleOnce } from "@ember/runloop"; import Controller from "@ember/controller"; export default Controller.extend({ title: 'admin.wizard.after_time_modal.title', setup() { - const dateTime = this.get('model.dateTime'); - const ROUNDING = 30 * 60 * 1000; - const nextInterval = moment(Math.ceil((+moment()) / ROUNDING) * ROUNDING); - const mDateTime = dateTime ? moment(dateTime) : nextInterval; - const mDateTimeLocal = mDateTime.local(); - const date = mDateTimeLocal.format('YYYY-MM-DD'); - const time = mDateTimeLocal.format('HH:mm'); - - this.setProperties({ date, time }); - - scheduleOnce('afterRender', this, () => { - const $timePicker = $("#time-picker"); - $timePicker.timepicker({ timeFormat: 'H:i' }); - $timePicker.timepicker('setTime', time); - $timePicker.change(() => this.set('time', $timePicker.val())); - }); + this.set('bufferedDateTime', moment(this.model.dateTime)); }, - @discourseComputed('date', 'time') - dateTime: function(date, time) { - return moment(date + 'T' + time).format(); - }, - - @discourseComputed('dateTime') + @discourseComputed('bufferedDateTime') submitDisabled(dateTime) { return moment().isAfter(dateTime); }, - resetProperties() { - this.setProperties({ - date: null, - time: null - }); - }, - actions: { - clear() { - this.resetProperties(); - this.get('model.update')(null); - }, - submit() { - const dateTime = this.get('dateTime'); - const formatted = moment(dateTime).utc().toISOString(); - this.get('model.update')(formatted); - this.resetProperties(); + const dateTime = this.get('bufferedDateTime'); + this.get('model.update')(moment(dateTime).utc().toISOString()); this.send("closeModal"); + }, + + dateTimeChanged(dateTime) { + this.set('bufferedDateTime', dateTime); } } }); diff --git a/assets/javascripts/discourse/lib/wizard-mapper.js.es6 b/assets/javascripts/discourse/lib/wizard-mapper.js.es6 index 1b54572c..6d179ef6 100644 --- a/assets/javascripts/discourse/lib/wizard-mapper.js.es6 +++ b/assets/javascripts/discourse/lib/wizard-mapper.js.es6 @@ -1,5 +1,6 @@ import EmberObject from "@ember/object"; import { A } from "@ember/array"; +import I18n from "I18n"; // Inputs diff --git a/assets/javascripts/discourse/lib/wizard-schema.js.es6 b/assets/javascripts/discourse/lib/wizard-schema.js.es6 index bd99ba7b..1b480471 100644 --- a/assets/javascripts/discourse/lib/wizard-schema.js.es6 +++ b/assets/javascripts/discourse/lib/wizard-schema.js.es6 @@ -141,6 +141,16 @@ const action = { profile_updates: null, custom_fields: null }, + watch_categories: { + categories: null, + notification_level: null, + mute_remainder: null + }, + send_to_api: { + api: null, + api_endpoint: null, + api_body: null + }, add_to_group: { group: null }, @@ -158,7 +168,9 @@ const action = { 'recipient', 'profile_updates', 'group', - 'url' + 'url', + 'categories', + 'mute_remainder' ], advanced: [ 'code', diff --git a/assets/javascripts/discourse/lib/wizard.js.es6 b/assets/javascripts/discourse/lib/wizard.js.es6 index 668ebe6a..852e4fa6 100644 --- a/assets/javascripts/discourse/lib/wizard.js.es6 +++ b/assets/javascripts/discourse/lib/wizard.js.es6 @@ -46,7 +46,16 @@ const userProperties = [ 'location', 'website', 'bio_raw', - 'trust_level' + 'trust_level', + 'email_level' +]; + +const notificationLevels = [ + 'regular', + 'watching', + 'tracking', + 'watching_first_post', + 'muted' ]; function listProperties(type, opts={}) { @@ -106,5 +115,6 @@ export { snakeCase, userProperties, listProperties, + notificationLevels, wizardFieldList }; \ No newline at end of file diff --git a/assets/javascripts/discourse/routes/admin-wizards-logs.js.es6 b/assets/javascripts/discourse/routes/admin-wizards-logs.js.es6 index 1c1de391..a7e62ad6 100644 --- a/assets/javascripts/discourse/routes/admin-wizards-logs.js.es6 +++ b/assets/javascripts/discourse/routes/admin-wizards-logs.js.es6 @@ -1,11 +1,12 @@ import CustomWizardLogs from '../models/custom-wizard-logs'; +import DiscourseRoute from "discourse/routes/discourse"; -export default Discourse.Route.extend({ +export default DiscourseRoute.extend({ model() { return CustomWizardLogs.list(); }, - + setupController(controller, model) { controller.set('logs', model); } -}) \ No newline at end of file +}) diff --git a/assets/javascripts/discourse/routes/admin-wizards-wizard-show.js.es6 b/assets/javascripts/discourse/routes/admin-wizards-wizard-show.js.es6 index 5530ec33..f8dd8479 100644 --- a/assets/javascripts/discourse/routes/admin-wizards-wizard-show.js.es6 +++ b/assets/javascripts/discourse/routes/admin-wizards-wizard-show.js.es6 @@ -1,6 +1,7 @@ import CustomWizard from '../models/custom-wizard'; import { ajax } from 'discourse/lib/ajax'; import DiscourseRoute from "discourse/routes/discourse"; +import I18n from "I18n"; export default DiscourseRoute.extend({ model(params) { diff --git a/assets/javascripts/discourse/templates/components/wizard-custom-action.hbs b/assets/javascripts/discourse/templates/components/wizard-custom-action.hbs index c27e56cd..c52f6cd1 100644 --- a/assets/javascripts/discourse/templates/components/wizard-custom-action.hbs +++ b/assets/javascripts/discourse/templates/components/wizard-custom-action.hbs @@ -283,6 +283,63 @@ {{/if}} +{{#if watchCategories}} +
+
+ +
+ +
+ {{wizard-mapper + inputs=action.categories + property='categories' + onUpdate=(action 'mappedFieldUpdated') + options=(hash + textSelection='key,value' + wizardFieldSelection=true + userFieldSelection='key,value' + categorySelection='output' + context='action' + )}} +
+
+ +
+
+ +
+ +
+ {{wizard-mapper + inputs=action.mute_remainder + property='mute_remainder' + onUpdate=(action 'mappedFieldUpdated') + options=(hash + context='action' + wizardFieldSelection=true + userFieldSelection='key,value' + )}} +
+
+ +
+
+ +
+ +
+ {{combo-box + value=action.notification_level + content=availableNotificationLevels + onChange=(action (mut action.notification_level)) + options=(hash + isDisabled=action.custom_title_enabled + none='admin.wizard.action.watch_categories.select_a_notification_level' + )}} +
+
+{{/if}} + {{#if showAdvanced}} {{wizard-advanced-toggle showAdvanced=action.showAdvanced}} diff --git a/assets/javascripts/discourse/templates/modal/next-session-scheduled.hbs b/assets/javascripts/discourse/templates/modal/next-session-scheduled.hbs index 36c08a3f..1b138360 100644 --- a/assets/javascripts/discourse/templates/modal/next-session-scheduled.hbs +++ b/assets/javascripts/discourse/templates/modal/next-session-scheduled.hbs @@ -1,24 +1,16 @@ {{#d-modal-body class="next-session-time-modal" title=title}} -
- -
-
+ {{date-time-input + date=bufferedDateTime + onChange=(action "dateTimeChanged") + showTime=true + clearable=true + }} {{/d-modal-body}} diff --git a/assets/javascripts/wizard-custom.js b/assets/javascripts/wizard-custom.js index 70bc4c8d..cef27152 100644 --- a/assets/javascripts/wizard-custom.js +++ b/assets/javascripts/wizard-custom.js @@ -91,10 +91,12 @@ //= require discourse/app/components/input-tip //= require discourse/app/components/date-picker //= require discourse/app/components/text-field +//= require discourse/app/components/d-textarea //= require discourse/app/templates/components/conditional-loading-spinner //= require discourse/app/templates/components/d-button //= require discourse/app/templates/components/d-editor +//= require discourse/app/templates/components/date-picker //= require discourse/app/templates/components/emoji-picker //= require discourse/app/templates/components/popup-input-tip //= require discourse/app/templates/category-tag-autocomplete diff --git a/assets/javascripts/wizard/components/custom-user-selector.js.es6 b/assets/javascripts/wizard/components/custom-user-selector.js.es6 index 143b340c..dfc45604 100644 --- a/assets/javascripts/wizard/components/custom-user-selector.js.es6 +++ b/assets/javascripts/wizard/components/custom-user-selector.js.es6 @@ -1,6 +1,7 @@ import { default as computed, observes } from 'discourse-common/utils/decorators'; import { renderAvatar } from 'discourse/helpers/user-avatar'; import userSearch from '../lib/user-search'; +import I18n from "I18n"; const template = function(params) { const options = params.options; diff --git a/assets/javascripts/wizard/components/wizard-composer-editor.js.es6 b/assets/javascripts/wizard/components/wizard-composer-editor.js.es6 index f7a89464..50061883 100644 --- a/assets/javascripts/wizard/components/wizard-composer-editor.js.es6 +++ b/assets/javascripts/wizard/components/wizard-composer-editor.js.es6 @@ -1,6 +1,6 @@ import ComposerEditor from 'discourse/components/composer-editor'; import { default as computed, on } from 'discourse-common/utils/decorators'; -import { findRawTemplate } from "discourse/lib/raw-templates"; +import { findRawTemplate } from "discourse-common/lib/raw-templates"; import { throttle } from "@ember/runloop"; import { scheduleOnce } from "@ember/runloop"; import { safariHacksDisabled } from "discourse/lib/utilities"; diff --git a/assets/javascripts/wizard/components/wizard-field-upload.js.es6 b/assets/javascripts/wizard/components/wizard-field-upload.js.es6 index 58faff14..2241c940 100644 --- a/assets/javascripts/wizard/components/wizard-field-upload.js.es6 +++ b/assets/javascripts/wizard/components/wizard-field-upload.js.es6 @@ -1,5 +1,6 @@ import getUrl from "discourse-common/lib/get-url"; import { getToken } from "wizard/lib/ajax"; +import I18n from "I18n"; export default Ember.Component.extend({ classNames: ["wizard-field-upload"], diff --git a/assets/javascripts/wizard/components/wizard-text-field.js.es6 b/assets/javascripts/wizard/components/wizard-text-field.js.es6 index 5c62abc8..8e4570a7 100644 --- a/assets/javascripts/wizard/components/wizard-text-field.js.es6 +++ b/assets/javascripts/wizard/components/wizard-text-field.js.es6 @@ -2,6 +2,7 @@ import computed from "discourse-common/utils/decorators"; import { siteDir, isRTL, isLTR } from "discourse/lib/text-direction"; +import I18n from "I18n"; export default Ember.TextField.extend({ attributeBindings: ['autocorrect', 'autocapitalize', 'autofocus', 'maxLength', 'dir'], diff --git a/assets/javascripts/wizard/initializers/custom.js.es6 b/assets/javascripts/wizard/initializers/custom.js.es6 index 628548ce..ae4c9d19 100644 --- a/assets/javascripts/wizard/initializers/custom.js.es6 +++ b/assets/javascripts/wizard/initializers/custom.js.es6 @@ -23,7 +23,7 @@ export default { const Store = requirejs("discourse/models/store").default; const registerRawHelpers = requirejs("discourse-common/lib/raw-handlebars-helpers").registerRawHelpers; const RawHandlebars = requirejs("discourse-common/lib/raw-handlebars").default; - const Site = requirejs("discourse/models/site").default; + const Site = requirejs("discourse/plugins/discourse-custom-wizard/wizard/models/site").default; const RestAdapter = requirejs("discourse/adapters/rest").default; Discourse.Model = EmberObject.extend(); diff --git a/assets/javascripts/wizard/models/site.js.es6 b/assets/javascripts/wizard/models/site.js.es6 new file mode 100644 index 00000000..f3a7d1e5 --- /dev/null +++ b/assets/javascripts/wizard/models/site.js.es6 @@ -0,0 +1,10 @@ +import Site from "discourse/models/site"; + +export default Site.reopenClass({ + // There is no site data actually loaded by the CW yet. This placeholder is + // needed by imported classes + createCurrent() { + const store = Discourse.__container__.lookup("service:store"); + return store.createRecord("site", {}); + }, +}) \ No newline at end of file diff --git a/assets/javascripts/wizard/routes/custom-step.js.es6 b/assets/javascripts/wizard/routes/custom-step.js.es6 index bba4b49f..72dd5263 100644 --- a/assets/javascripts/wizard/routes/custom-step.js.es6 +++ b/assets/javascripts/wizard/routes/custom-step.js.es6 @@ -1,3 +1,5 @@ +import I18n from "I18n"; + export default Ember.Route.extend({ model(params) { const appModel = this.modelFor('custom'); diff --git a/assets/javascripts/wizard/templates/components/wizard-field-date.hbs b/assets/javascripts/wizard/templates/components/wizard-field-date.hbs new file mode 100644 index 00000000..b2ac15d8 --- /dev/null +++ b/assets/javascripts/wizard/templates/components/wizard-field-date.hbs @@ -0,0 +1,4 @@ +{{date-picker + value=field.value + id=field.id +}} \ No newline at end of file diff --git a/assets/stylesheets/common/wizard-admin.scss b/assets/stylesheets/common/wizard-admin.scss index fba44a3e..5eacc613 100644 --- a/assets/stylesheets/common/wizard-admin.scss +++ b/assets/stylesheets/common/wizard-admin.scss @@ -481,54 +481,12 @@ min-height: 150px; } -.next-session-time-modal { - text-align: center; - - .date-time-card { - width: 270px; - padding: 10px 20px; - text-align: left; - } - - .modal-date-time-set{ - padding-top: 3px; - padding-bottom: 4px; - display: flex; - flex-direction: row; - - .modal-date-area{ - order: 1; - } - - .modal-time-area{ - order: 2; - margin-left: 10px; - - .modal-time{ - width: 127px; - } - } - } - - .ui-timepicker-input { - width: 119px; - text-align: center; - } - - .date-picker{ - width: 121px; - } - - .pika-single { - position: relative !important; - - .pika-lendar { - border: 1px solid #eee; - padding: 14px; - margin: 0; - float: none; - width: auto; - } +.modal .modal-body.next-session-time-modal { + overflow: visible; + + .picker-container { + position: absolute; + top: 30px; } } diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 0a79915d..5d58200f 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -163,6 +163,7 @@ en: category: Category group: Group user_selector: User Selector + date: Date connector: and: "and" @@ -208,6 +209,18 @@ en: label: "Update Profile" setting: "Fields" key: "field" + watch_categories: + label: "Watch Categories" + categories: "Categories" + mute_remainder: "Mute Remainder" + notification_level: + label: "Notification Level" + regular: "Normal" + watching: "Watching" + tracking: "Tracking" + watching_first_post: "Watching First Post" + muted: "Muted" + select_a_notification_level: "Select level" post_builder: checkbox: "Post Builder" label: "Builder" diff --git a/controllers/custom_wizard/admin/wizard.rb b/controllers/custom_wizard/admin/wizard.rb index d7f87f9a..dcf6fa00 100644 --- a/controllers/custom_wizard/admin/wizard.rb +++ b/controllers/custom_wizard/admin/wizard.rb @@ -116,12 +116,18 @@ class CustomWizard::AdminWizardController < CustomWizard::AdminController :post, :post_builder, :post_template, + :notification_level, + :api, + :api_endpoint, + :api_body, title: mapped_params, category: mapped_params, tags: mapped_params, custom_fields: mapped_params, required: mapped_params, recipient: mapped_params, + categories: mapped_params, + mute_remainder: mapped_params, profile_updates: mapped_params, group: mapped_params, url: mapped_params diff --git a/jobs/set_after_time_wizard.rb b/jobs/set_after_time_wizard.rb index 7aa528ba..80f8f5e5 100644 --- a/jobs/set_after_time_wizard.rb +++ b/jobs/set_after_time_wizard.rb @@ -2,7 +2,7 @@ module Jobs class SetAfterTimeWizard < ::Jobs::Base def execute(args) if SiteSetting.custom_wizard_enabled - wizard = CustomWizard::Wizard.find(args[:wizard_id]) + wizard = CustomWizard::Wizard.create(args[:wizard_id]) if wizard && wizard.after_time user_ids = [] diff --git a/lib/custom_wizard/action.rb b/lib/custom_wizard/action.rb index d85067bb..a33a244f 100644 --- a/lib/custom_wizard/action.rb +++ b/lib/custom_wizard/action.rb @@ -97,19 +97,20 @@ class CustomWizard::Action end def update_profile - return unless (profile_updates = action['profile_updates']).length params = {} - profile_updates.first[:pairs].each do |pair| - if allowed_profile_field?(pair['key']) - key = cast_profile_key(pair['key']) - value = cast_profile_value(mapper.map_field(pair['value'], pair['value_type']), pair['key']) - - if user_field?(pair['key']) - params[:custom_fields] ||= {} - params[:custom_fields][key] = value - else - params[key.to_sym] = value + if (profile_updates = action['profile_updates']) + profile_updates.first[:pairs].each do |pair| + if allowed_profile_field?(pair['key']) + key = cast_profile_key(pair['key']) + value = cast_profile_value(mapper.map_field(pair['value'], pair['value_type']), pair['key']) + + if user_field?(pair['key']) + params[:custom_fields] ||= {} + params[:custom_fields][key] = value + else + params[key.to_sym] = value + end end end end @@ -133,6 +134,36 @@ class CustomWizard::Action end end + def watch_categories + + watched_categories = CustomWizard::Mapper.new( + inputs: action['categories'], + data: data, + user: user + ).perform + + notification_level = action['notification_level'] + + if notification_level.blank? + log_error("Notifcation Level was not set! Exiting wizard action") + return + end + + mute_remainder = CustomWizard::Mapper.new( + inputs: action['mute_remainder'], + data: data, + user: user + ).perform + + Category.all.each do |category| + if watched_categories.present? && watched_categories.include?(category.id.to_s) + CategoryUser.set_notification_level_for_category(user, CategoryUser.notification_levels[notification_level.to_sym], category.id) + elsif mute_remainder + CategoryUser.set_notification_level_for_category(user, CategoryUser.notification_levels[:muted], category.id) + end + end + end + def send_to_api api_body = nil diff --git a/lib/custom_wizard/builder.rb b/lib/custom_wizard/builder.rb index c04f11b1..ebe24a4a 100644 --- a/lib/custom_wizard/builder.rb +++ b/lib/custom_wizard/builder.rb @@ -258,7 +258,9 @@ class CustomWizard::Builder } ).perform - if content.present? + if content.present? && + content[:result].present? + if content[:type] == 'association' content[:result] = content[:result].map do |item| { @@ -324,6 +326,10 @@ class CustomWizard::Builder if type === 'upload' && value.present? && !validate_file_type(value, file_types) updater.errors.add(id, I18n.t('wizard.field.invalid_file', label: label, types: file_types)) end + + if type === 'date' && value.present? && !validate_date(value) + updater.errors.add(id, I18n.t('wizard.field.invalid_date')) + end CustomWizard::Builder.field_validators.each do |validator| if type === validator[:type] @@ -337,6 +343,15 @@ class CustomWizard::Builder .map { |t| t.gsub('.', '') } .include?(File.extname(value['original_filename'])[1..-1]) end + + def validate_date(value) + begin + Date.parse(value) + true + rescue ArgumentError + false + end + end def is_text_type(field) ['text', 'textarea'].include? field['type'] diff --git a/lib/custom_wizard/field.rb b/lib/custom_wizard/field.rb index 77838cd0..dff610ce 100644 --- a/lib/custom_wizard/field.rb +++ b/lib/custom_wizard/field.rb @@ -11,6 +11,7 @@ class CustomWizard::Field min_length: nil }, text_only: {}, + date: {}, number: {}, checkbox: {}, url: { diff --git a/lib/custom_wizard/mapper.rb b/lib/custom_wizard/mapper.rb index 19b40e6b..b1fe585d 100644 --- a/lib/custom_wizard/mapper.rb +++ b/lib/custom_wizard/mapper.rb @@ -1,7 +1,7 @@ class CustomWizard::Mapper attr_accessor :inputs, :data, :user - USER_FIELDS = ['name', 'username', 'email', 'date_of_birth', 'title', 'locale', 'trust_level'] + USER_FIELDS = ['name', 'username', 'email', 'date_of_birth', 'title', 'locale', 'trust_level', 'email_level'] PROFILE_FIELDS = ['location', 'website', 'bio_raw'] def self.user_fields @@ -188,7 +188,7 @@ class CustomWizard::Mapper def map_user_field_options(value) if value.include?(User::USER_FIELD_PREFIX) - if field = UserField.find(value.split('_').last) + if field = UserField.find_by(id: value.split('_').last) field.user_field_options.map(&:value) end end diff --git a/plugin.rb b/plugin.rb index d4c04a99..6e26bcee 100644 --- a/plugin.rb +++ b/plugin.rb @@ -18,6 +18,7 @@ config.assets.paths << "#{plugin_asset_path}/stylesheets/wizard" if Rails.env.production? config.assets.precompile += %w{ + wizard-preload.js wizard-custom-guest.js wizard-custom-lib.js wizard-custom.js diff --git a/views/layouts/wizard.html.erb b/views/layouts/wizard.html.erb index 47d54309..0deb4c71 100644 --- a/views/layouts/wizard.html.erb +++ b/views/layouts/wizard.html.erb @@ -11,7 +11,8 @@ <%- if theme_ids.present? %> <%= discourse_stylesheet_link_tag (mobile_view? ? :mobile_theme : :desktop_theme) %> <%- end %> - + + <%= preload_script "locales/#{I18n.locale}" %> <%= preload_script "ember_jquery" %> <%= preload_script "wizard-vendor" %> <%= preload_script "wizard-application" %> @@ -19,7 +20,6 @@ <%= preload_script "wizard-custom" %> <%= preload_script "wizard-plugin" %> <%= preload_script "pretty-text-bundle" %> - <%= preload_script "locales/#{I18n.locale}" %> <%= csrf_meta_tags %>