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-picker value=date containerId="date-container"}}
-
-
-
-
-
-
-
-
+ {{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 %>