0
0
Fork 1
Spiegel von https://github.com/paviliondev/discourse-custom-wizard.git synchronisiert 2024-11-22 09:20:29 +01:00

Merge pull request #147 from paviliondev/pro-release-api

Pro release api
Dieser Commit ist enthalten in:
Angus McLeod 2021-11-17 20:18:54 +08:00 committet von GitHub
Commit bbd1253891
Es konnte kein GPG-Schlüssel zu dieser Signatur gefunden werden
GPG-Schlüssel-ID: 4AEE18F83AFDEB23
48 geänderte Dateien mit 427 neuen und 165 gelöschten Zeilen

Datei anzeigen

@ -1,27 +1,27 @@
import Component from "@ember/component"; import Component from "@ember/component";
import discourseComputed, { observes } from "discourse-common/utils/decorators"; import discourseComputed, { observes } from "discourse-common/utils/decorators";
import { alias, equal, or } from "@ember/object/computed"; import { alias, equal, or } from "@ember/object/computed";
import { computed } from "@ember/object";
import I18n from "I18n"; import I18n from "I18n";
const klasses = ["topic", "post", "group", "category"]; import wizardSchema, {
const types = ["string", "boolean", "integer", "json"]; requiringAdditionalSubscription,
const subscriptionTypes = { subscriptionLevel,
klass: ["group", "category"], } from "discourse/plugins/discourse-custom-wizard/discourse/lib/wizard-schema";
type: ["json"],
};
const generateContent = function (array, type, subscribed = false) { const generateContent = function (kategory, subscription) {
return array.reduce((result, key) => { let unsubscribedCustomFields = requiringAdditionalSubscription(
let subArr = subscriptionTypes[type]; subscription,
let subscription = subArr && subArr.includes(key); "custom_fields",
if (!subscription || subscribed) { kategory
result.push({ );
id: key, return wizardSchema.custom_field[kategory].reduce((result, item) => {
name: I18n.t(`admin.wizard.custom_field.${type}.${key}`), let disabled = unsubscribedCustomFields.includes(item);
subscription, result.push({
}); id: item,
} name: I18n.t(`admin.wizard.custom_field.${kategory}.${item}`),
subscription: subscriptionLevel(item, "custom_fields", kategory),
disabled,
});
return result; return result;
}, []); }, []);
}; };
@ -32,12 +32,6 @@ export default Component.extend({
postSerializers: ["post"], postSerializers: ["post"],
groupSerializers: ["basic_group"], groupSerializers: ["basic_group"],
categorySerializers: ["basic_category"], categorySerializers: ["basic_category"],
klassContent: computed("subscribed", function () {
return generateContent(klasses, "klass", this.subscribed);
}),
typeContent: computed("subscribed", function () {
return generateContent(types, "type", this.subscribed);
}),
showInputs: or("field.new", "field.edit"), showInputs: or("field.new", "field.edit"),
classNames: ["custom-field-input"], classNames: ["custom-field-input"],
loading: or("saving", "destroying"), loading: or("saving", "destroying"),
@ -54,12 +48,26 @@ export default Component.extend({
const serializers = this.get(`${klass}Serializers`); const serializers = this.get(`${klass}Serializers`);
if (serializers) { if (serializers) {
return generateContent(serializers, "serializers", this.subscribed); return serializers.reduce((result, key) => {
} else { result.push({
return []; id: key,
name: I18n.t(`admin.wizard.custom_field.serializers.${key}`),
});
return result;
}, []);
} }
}, },
@discourseComputed("subscription")
customFieldTypes(subscription) {
return generateContent("type", subscription);
},
@discourseComputed("subscription")
customFieldKlasses(subscription) {
return generateContent("klass", subscription);
},
@observes("field.klass") @observes("field.klass")
clearSerializersWhenClassChanges() { clearSerializersWhenClassChanges() {
this.set("field.serializers", null); this.set("field.serializers", null);

Datei anzeigen

@ -4,18 +4,22 @@ import discourseComputed from "discourse-common/utils/decorators";
export default Component.extend({ export default Component.extend({
classNameBindings: [":subscription-container", "subscribed"], classNameBindings: [":subscription-container", "subscribed"],
@discourseComputed('subscribed') @discourseComputed("subscribed")
subscribedIcon(subscribed) { subscribedIcon(subscribed) {
return subscribed ? 'check' : 'dash'; return subscribed ? "check" : "dash";
}, },
@discourseComputed('subscribed') @discourseComputed("subscribed")
subscribedLabel(subscribed) { subscribedLabel(subscribed) {
return `admin.wizard.subscription_container.${subscribed ? 'subscribed' : 'not_subscribed'}.label`; return `admin.wizard.subscription_container.${
subscribed ? "subscribed" : "not_subscribed"
}.label`;
}, },
@discourseComputed('subscribed') @discourseComputed("subscribed")
subscribedTitle(subscribed) { subscribedTitle(subscribed) {
return `admin.wizard.subscription_container.${subscribed ? 'subscribed' : 'not_subscribed'}.title`; return `admin.wizard.subscription_container.${
} subscribed ? "subscribed" : "not_subscribed"
}); }.title`;
},
});

Datei anzeigen

@ -1,5 +1,8 @@
import { default as discourseComputed } from "discourse-common/utils/decorators"; import { default as discourseComputed } from "discourse-common/utils/decorators";
import wizardSchema from "discourse/plugins/discourse-custom-wizard/discourse/lib/wizard-schema"; import wizardSchema, {
requiringAdditionalSubscription,
subscriptionLevel,
} from "discourse/plugins/discourse-custom-wizard/discourse/lib/wizard-schema";
import { empty, equal, or } from "@ember/object/computed"; import { empty, equal, or } from "@ember/object/computed";
import { notificationLevels, selectKitContent } from "../lib/wizard"; import { notificationLevels, selectKitContent } from "../lib/wizard";
import { computed } from "@ember/object"; import { computed } from "@ember/object";
@ -94,17 +97,21 @@ export default Component.extend(UndoChanges, {
return apis.find((a) => a.name === api).endpoints; return apis.find((a) => a.name === api).endpoints;
}, },
@discourseComputed("subscribed") @discourseComputed("subscription")
actionTypes(subscribed) { actionTypes(subscription) {
let unsubscribedActions = requiringAdditionalSubscription(
subscription,
"actions",
""
);
return Object.keys(wizardSchema.action.types).reduce((result, type) => { return Object.keys(wizardSchema.action.types).reduce((result, type) => {
let subscription = wizardSchema.action.subscriptionTypes.includes(type); let disabled = unsubscribedActions.includes(type);
if (subscribed || !subscription) { result.push({
result.push({ id: type,
id: type, name: I18n.t(`admin.wizard.action.${type}.label`),
name: I18n.t(`admin.wizard.action.${type}.label`), subscription: subscriptionLevel(type, "actions", ""),
subscription, disabled,
}); });
}
return result; return result;
}, []); }, []);
}, },

Datei anzeigen

@ -4,33 +4,39 @@ import { not, notEmpty } from "@ember/object/computed";
import I18n from "I18n"; import I18n from "I18n";
export default Component.extend({ export default Component.extend({
classNameBindings: [':wizard-notice', 'notice.type', 'dismissed', 'expired', 'resolved'], classNameBindings: [
":wizard-notice",
"notice.type",
"dismissed",
"expired",
"resolved",
],
showFull: false, showFull: false,
resolved: notEmpty('notice.expired_at'), resolved: notEmpty("notice.expired_at"),
dismissed: notEmpty('notice.dismissed_at'), dismissed: notEmpty("notice.dismissed_at"),
canDismiss: not('dismissed'), canDismiss: not("dismissed"),
@discourseComputed('notice.type') @discourseComputed("notice.type")
title(type) { title(type) {
return I18n.t(`admin.wizard.notice.title.${type}`); return I18n.t(`admin.wizard.notice.title.${type}`);
}, },
@discourseComputed('notice.type') @discourseComputed("notice.type")
icon(type) { icon(type) {
return { return {
plugin_status_warning: 'exclamation-circle', plugin_status_warning: "exclamation-circle",
plugin_status_connection_error: 'bolt', plugin_status_connection_error: "bolt",
subscription_messages_connection_error: 'bolt', subscription_messages_connection_error: "bolt",
info: 'info-circle' info: "info-circle",
}[type]; }[type];
}, },
actions: { actions: {
dismiss() { dismiss() {
this.set('dismissing', true); this.set("dismissing", true);
this.notice.dismiss().then(() => { this.notice.dismiss().then(() => {
this.set('dismissing', false); this.set("dismissing", false);
}); });
} },
} },
}); });

Datei anzeigen

@ -7,7 +7,8 @@ export default SingleSelectComponent.extend({
autoFilterable: false, autoFilterable: false,
filterable: false, filterable: false,
showFullTitle: true, showFullTitle: true,
headerComponent: "wizard-subscription-selector/wizard-subscription-selector-header", headerComponent:
"wizard-subscription-selector/wizard-subscription-selector-header",
caretUpIcon: "caret-up", caretUpIcon: "caret-up",
caretDownIcon: "caret-down", caretDownIcon: "caret-down",
}, },

Datei anzeigen

@ -1,3 +1,20 @@
import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row"; import SelectKitRowComponent from "select-kit/components/select-kit/select-kit-row";
import { default as discourseComputed } from "discourse-common/utils/decorators";
export default SelectKitRowComponent.extend(); export default SelectKitRowComponent.extend({
classNameBindings: ["isDisabled:disabled"],
@discourseComputed("item")
isDisabled() {
return this.item.disabled;
},
click(event) {
event.preventDefault();
event.stopPropagation();
if (!this.item.disabled) {
this.selectKit.select(this.rowValue, this.item);
}
return false;
},
});

Datei anzeigen

@ -25,7 +25,9 @@ export default Component.extend({
@discourseComputed("stateClass") @discourseComputed("stateClass")
stateLabel(stateClass) { stateLabel(stateClass) {
return I18n.t(`admin.wizard.subscription.subscription.status.${stateClass}`); return I18n.t(
`admin.wizard.subscription.subscription.status.${stateClass}`
);
}, },
actions: { actions: {

Datei anzeigen

@ -6,11 +6,11 @@ export default {
}, },
setupComponent() { setupComponent() {
const controller = getOwner(this).lookup('controller:admin-dashboard'); const controller = getOwner(this).lookup("controller:admin-dashboard");
const importantNotice = controller.get('customWizardImportantNotice'); const importantNotice = controller.get("customWizardImportantNotice");
if (importantNotice) { if (importantNotice) {
this.set('importantNotice', importantNotice); this.set("importantNotice", importantNotice);
} }
} },
}; };

Datei anzeigen

@ -11,7 +11,7 @@ export default Controller.extend({
queryParams: ["refresh_list"], queryParams: ["refresh_list"],
loadingSubscriptions: false, loadingSubscriptions: false,
notAuthorized: not("api.authorized"), notAuthorized: not("api.authorized"),
endpointMethods: selectKitContent(["GET", "PUT", "POST", "PATCH", "DELETE"]), endpointMethods: selectKitContent(["PUT", "POST", "PATCH", "DELETE"]),
showRemove: not("isNew"), showRemove: not("isNew"),
showRedirectUri: and("threeLeggedOauth", "api.name"), showRedirectUri: and("threeLeggedOauth", "api.name"),
responseIcon: null, responseIcon: null,

Datei anzeigen

@ -8,13 +8,13 @@ export default Controller.extend({
ajax(`/admin/wizards/notice/${this.id}`, { ajax(`/admin/wizards/notice/${this.id}`, {
type: "DELETE", type: "DELETE",
}) })
.then(result => { .then((result) => {
if (result.success) { if (result.success) {
const notices = this.notices; const notices = this.notices;
notices.removeObject(notices.findBy('id', noticeId)); notices.removeObject(notices.findBy("id", noticeId));
} }
}) })
.catch(popupAjaxError); .catch(popupAjaxError);
} },
} },
}); });

Datei anzeigen

@ -21,27 +21,37 @@ export default {
}; };
withPluginApi("0.8.36", (api) => { withPluginApi("0.8.36", (api) => {
api.modifyClass('route:admin-dashboard', { api.modifyClass("route:admin-dashboard", {
afterModel() { afterModel() {
return CustomWizardNotice.list().then(result => { return CustomWizardNotice.list().then((result) => {
if (result && result.length) { if (result && result.length) {
this.set('notices', A(result.map(n => CustomWizardNotice.create(n)))); this.set(
"notices",
A(result.map((n) => CustomWizardNotice.create(n)))
);
} }
}); });
}, },
setupController(controller) { setupController(controller) {
if (this.notices) { if (this.notices) {
let pluginStatusConnectionError = this.notices.filter(n => n.type === 'plugin_status_connection_error')[0]; let pluginStatusConnectionError = this.notices.filter(
let pluginStatusWarning = this.notices.filter(n => n.type === 'plugin_status_warning')[0]; (n) => n.type === "plugin_status_connection_error"
)[0];
let pluginStatusWarning = this.notices.filter(
(n) => n.type === "plugin_status_warning"
)[0];
if (pluginStatusConnectionError || pluginStatusWarning) { if (pluginStatusConnectionError || pluginStatusWarning) {
controller.set('customWizardImportantNotice', pluginStatusConnectionError || pluginStatusWarning); controller.set(
"customWizardImportantNotice",
pluginStatusConnectionError || pluginStatusWarning
);
} }
} }
this._super(...arguments); this._super(...arguments);
} },
}); });
}); });
}, },

Datei anzeigen

@ -193,32 +193,110 @@ const action = {
"members_visibility_level", "members_visibility_level",
], ],
required: ["id", "type"], required: ["id", "type"],
subscriptionTypes: [
"send_message",
"add_to_group",
"create_category",
"create_group",
"send_to_api",
],
required: ["id", "type"],
proTypes: [
"send_message",
"add_to_group",
"create_category",
"create_group",
"send_to_api",
],
dependent: {}, dependent: {},
objectArrays: {}, objectArrays: {},
}; };
const custom_field = {
klass: ["topic", "post", "group", "category"],
type: ["string", "boolean", "integer", "json"],
};
const subscription_levels = {
standard: {
actions: ["send_message", "add_to_group", "watch_categories"],
custom_fields: {
klass: [],
type: ["json"],
},
},
business: {
actions: ["create_category", "create_group", "send_to_api"],
custom_fields: {
klass: ["group", "category"],
type: [],
},
},
};
const wizardSchema = { const wizardSchema = {
wizard, wizard,
step, step,
field, field,
custom_field,
action, action,
subscription_levels,
}; };
export function requiringAdditionalSubscription(
currentSubscription,
category,
subCategory
) {
switch (category) {
case "actions":
switch (currentSubscription) {
case "business":
return [];
case "standard":
return subscription_levels["business"][category];
default:
return subscription_levels["standard"][category].concat(
subscription_levels["business"][category]
);
}
case "custom_fields":
switch (currentSubscription) {
case "business":
return [];
case "standard":
return subscription_levels["business"][category][subCategory];
default:
return subscription_levels["standard"][category][subCategory].concat(
subscription_levels["business"][category][subCategory]
);
}
default:
return [];
}
}
export function subscriptionLevel(type, category, subCategory) {
switch (category) {
case "actions":
if (subscription_levels["business"].actions.includes(type)) {
return "business";
} else {
if (subscription_levels["standard"].actions.includes(type)) {
return "standard";
} else {
return "";
}
}
case "custom_fields":
if (
subscription_levels["business"].custom_fields[subCategory].includes(
type
)
) {
return "business";
} else {
if (
subscription_levels["standard"].custom_fields[subCategory].includes(
type
)
) {
return "standard";
} else {
return "";
}
}
default:
return "";
}
}
export function buildFieldTypes(types) { export function buildFieldTypes(types) {
wizardSchema.field.types = types; wizardSchema.field.types = types;
} }

Datei anzeigen

@ -6,18 +6,20 @@ const CustomWizardNotice = EmberObject.extend();
CustomWizardNotice.reopen({ CustomWizardNotice.reopen({
dismiss() { dismiss() {
return ajax(`/admin/wizards/notice/${this.id}`, { type: 'PUT' }).then(result => { return ajax(`/admin/wizards/notice/${this.id}`, { type: "PUT" })
if (result.success) { .then((result) => {
this.set('dismissed_at', result.dismissed_at); if (result.success) {
} this.set("dismissed_at", result.dismissed_at);
}).catch(popupAjaxError); }
} })
.catch(popupAjaxError);
},
}); });
CustomWizardNotice.reopenClass({ CustomWizardNotice.reopenClass({
list() { list() {
return ajax('/admin/wizards/notice').catch(popupAjaxError); return ajax("/admin/wizards/notice").catch(popupAjaxError);
} },
}); });
export default CustomWizardNotice; export default CustomWizardNotice;

Datei anzeigen

@ -10,10 +10,12 @@ export default DiscourseRoute.extend({
setupController(controller, model) { setupController(controller, model) {
const customFields = A(model.custom_fields || []); const customFields = A(model.custom_fields || []);
const subscribed = model.subscribed; const subscribed = model.subscribed;
const subscription = model.subscription;
controller.setProperties({ controller.setProperties({
customFields, customFields,
subscribed, subscribed,
subscription,
}); });
}, },
}); });

Datei anzeigen

@ -40,6 +40,7 @@ export default DiscourseRoute.extend({
currentAction: wizard.actions[0], currentAction: wizard.actions[0],
creating: model.create, creating: model.create,
subscribed: parentModel.subscribed, subscribed: parentModel.subscribed,
subscription: parentModel.subscription,
}; };
controller.setProperties(props); controller.setProperties(props);

Datei anzeigen

@ -4,16 +4,17 @@ import { A } from "@ember/array";
export default DiscourseRoute.extend({ export default DiscourseRoute.extend({
model() { model() {
return ajax('/admin/wizards'); return ajax("/admin/wizards");
}, },
setupController(controller, model) { setupController(controller, model) {
controller.set('notices', A(model.notices)); controller.set("notices", A(model.notices));
controller.set("api_section", model.api_section);
}, },
afterModel(model, transition) { afterModel(model, transition) {
if (transition.targetName === "adminWizards.index") { if (transition.targetName === "adminWizards.index") {
this.transitionTo("adminWizardsWizard"); this.transitionTo("adminWizardsWizard");
} }
} },
}); });

Datei anzeigen

@ -33,7 +33,8 @@
field=field field=field
removeField=(action "removeField") removeField=(action "removeField")
saveField=(action "saveField") saveField=(action "saveField")
subscribed=subscribed}} subscribed=subscribed
subscription=subscription}}
{{/each}} {{/each}}
</tbody> </tbody>
</table> </table>

Datei anzeigen

@ -178,7 +178,8 @@
apis=apis apis=apis
removeAction="removeAction" removeAction="removeAction"
wizardFields=wizardFields wizardFields=wizardFields
subscribed=subscribed}} subscribed=subscribed
subscription=subscription}}
{{/each}} {{/each}}
<div class="admin-wizard-buttons"> <div class="admin-wizard-buttons">

Datei anzeigen

@ -2,7 +2,7 @@
{{nav-item route="adminWizardsWizard" label="admin.wizard.nav_label"}} {{nav-item route="adminWizardsWizard" label="admin.wizard.nav_label"}}
{{nav-item route="adminWizardsCustomFields" label="admin.wizard.custom_field.nav_label"}} {{nav-item route="adminWizardsCustomFields" label="admin.wizard.custom_field.nav_label"}}
{{nav-item route="adminWizardsSubmissions" label="admin.wizard.submissions.nav_label"}} {{nav-item route="adminWizardsSubmissions" label="admin.wizard.submissions.nav_label"}}
{{#if siteSettings.wizard_apis_enabled}} {{#if api_section}}
{{nav-item route="adminWizardsApi" label="admin.wizard.api.nav_label"}} {{nav-item route="adminWizardsApi" label="admin.wizard.api.nav_label"}}
{{/if}} {{/if}}
{{nav-item route="adminWizardsLogs" label="admin.wizard.log.nav_label"}} {{nav-item route="adminWizardsLogs" label="admin.wizard.log.nav_label"}}

Datei anzeigen

@ -2,14 +2,14 @@
<td> <td>
{{wizard-subscription-selector {{wizard-subscription-selector
value=field.klass value=field.klass
content=klassContent content=customFieldKlasses
none="admin.wizard.custom_field.klass.select" none="admin.wizard.custom_field.klass.select"
onChange=(action (mut field.klass))}} onChange=(action (mut field.klass))}}
</td> </td>
<td> <td>
{{wizard-subscription-selector {{wizard-subscription-selector
value=field.type value=field.type
content=typeContent content=customFieldTypes
none="admin.wizard.custom_field.type.select" none="admin.wizard.custom_field.type.select"
onChange=(action (mut field.type))}} onChange=(action (mut field.type))}}
</td> </td>

Datei anzeigen

@ -33,7 +33,7 @@
</div> </div>
<div class="notice-message"> <div class="notice-message">
{{{notice.message}}} {{html-safe notice.message}}
</div> </div>
{{#if importantOnDashboard}} {{#if importantOnDashboard}}

Datei anzeigen

@ -10,6 +10,8 @@
<div class="texts"> <div class="texts">
<span class="name">{{html-safe label}}</span> <span class="name">{{html-safe label}}</span>
{{#if item.subscription}} {{#if item.subscription}}
<span class="subscription-label">{{i18n "admin.wizard.subscription.label"}}</span> <span class="subscription-label">
{{item.subscription}}
</span>
{{/if}} {{/if}}
</div> </div>

Datei anzeigen

@ -7,7 +7,7 @@ import { getOwner } from "discourse-common/lib/get-owner";
export function cook(text, options) { export function cook(text, options) {
if (!options) { if (!options) {
options = buildOptions({ options = buildOptions({
getURL: getURL, getURL,
siteSettings: getOwner(this).lookup("site-settings:main"), siteSettings: getOwner(this).lookup("site-settings:main"),
}); });
} }

Datei anzeigen

@ -27,12 +27,12 @@ function performSearch(
// need to be able to cancel this // need to be able to cancel this
oldSearch = $.ajax(getUrl("/u/search/users"), { oldSearch = $.ajax(getUrl("/u/search/users"), {
data: { data: {
term: term, term,
topic_id: topicId, topic_id: topicId,
include_groups: includeGroups, include_groups: includeGroups,
include_mentionable_groups: includeMentionableGroups, include_mentionable_groups: includeMentionableGroups,
include_messageable_groups: includeMessageableGroups, include_messageable_groups: includeMessageableGroups,
group: group, group,
topic_allowed_users: allowedUsers, topic_allowed_users: allowedUsers,
}, },
}); });

Datei anzeigen

@ -788,11 +788,6 @@
vertical-align: middle; vertical-align: middle;
} }
.subscription-label {
color: var(--tertiary);
font-size: 0.75em;
}
.admin-wizards-subscription { .admin-wizards-subscription {
.admin-wizard-controls { .admin-wizard-controls {
h3, h3,
@ -853,14 +848,21 @@
} }
.wizard-subscription-selector.select-kit.single-select { .wizard-subscription-selector.select-kit.single-select {
.select-kit-row .texts { .select-kit-row {
display: flex; .texts {
align-items: center; display: flex;
align-items: center;
}
&.disabled {
background: var(--primary-low);
}
} }
.subscription-label { .subscription-label {
margin-left: 0.75em; margin-left: 0.75em;
padding-top: 0.25em; padding-top: 0.25em;
color: var(--tertiary);
font-size: 0.75em;
} }
} }
@ -924,7 +926,7 @@
} }
.d-icon { .d-icon {
margin-right: .4em; margin-right: 0.4em;
} }
.notice-header { .notice-header {
@ -935,9 +937,9 @@
border: 1px solid var(--primary); border: 1px solid var(--primary);
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
padding: 0 .5em; padding: 0 0.5em;
margin-right: 1em; margin-right: 1em;
font-size: .9em; font-size: 0.9em;
line-height: 25px; line-height: 25px;
min-height: 25px; min-height: 25px;
box-sizing: border-box; box-sizing: border-box;
@ -963,12 +965,12 @@
.notice-issued, .notice-issued,
.notice-resolved { .notice-resolved {
margin-right: .3em; margin-right: 0.3em;
} }
.notice-message { .notice-message {
p { p {
margin: .5em 0; margin: 0.5em 0;
} }
p:last-of-type { p:last-of-type {

Datei anzeigen

@ -466,7 +466,8 @@ en:
subscription: subscription:
nav_label: Subscription nav_label: Subscription
label: Subscription label: In subscription
additional_label: "Add subscription"
title: Custom Wizard Subscription title: Custom Wizard Subscription
authorize: Authorize authorize: Authorize
authorized: Authorized authorized: Authorized
@ -474,7 +475,7 @@ en:
not_subscribed: You're not currently subscribed not_subscribed: You're not currently subscribed
subscription: subscription:
title: title:
community: Community Subscription standard: Standard Subscription
business: Business Subscription business: Business Subscription
status: status:
active: Active active: Active

Datei anzeigen

@ -15,9 +15,6 @@ plugins:
refresh: true refresh: true
type: list type: list
list_type: compact list_type: compact
wizard_apis_enabled:
client: true
default: false
wizard_important_notices_on_dashboard: wizard_important_notices_on_dashboard:
client: true client: true
default: true default: true

Datei anzeigen

@ -4,6 +4,8 @@ class CustomWizard::AdminController < ::Admin::AdminController
def index def index
render_json_dump( render_json_dump(
#TODO replace with appropriate static?
api_section: ["business"].include?(CustomWizard::Subscription.type),
notices: ActiveModel::ArraySerializer.new( notices: ActiveModel::ArraySerializer.new(
CustomWizard::Notice.list, CustomWizard::Notice.list,
each_serializer: CustomWizard::NoticeSerializer each_serializer: CustomWizard::NoticeSerializer

Datei anzeigen

@ -3,7 +3,8 @@ class CustomWizard::AdminCustomFieldsController < CustomWizard::AdminController
def index def index
render_json_dump( render_json_dump(
custom_fields: custom_field_list, custom_fields: custom_field_list,
subscribed: CustomWizard::Subscription.subscribed? subscribed: CustomWizard::Subscription.subscribed?,
subscription: CustomWizard::Subscription.type
) )
end end

Datei anzeigen

@ -11,7 +11,8 @@ class CustomWizard::AdminWizardController < CustomWizard::AdminController
field_types: CustomWizard::Field.types, field_types: CustomWizard::Field.types,
realtime_validations: CustomWizard::RealtimeValidation.types, realtime_validations: CustomWizard::RealtimeValidation.types,
custom_fields: custom_field_list, custom_fields: custom_field_list,
subscribed: CustomWizard::Subscription.subscribed? subscribed: CustomWizard::Subscription.subscribed?,
subscription: CustomWizard::Subscription.type
) )
end end

Datei anzeigen

@ -74,7 +74,7 @@ class CustomWizard::Api::Endpoint
headers["Authorization"] = auth_string if auth_string headers["Authorization"] = auth_string if auth_string
headers["Content-Type"] = content_type if content_type headers["Content-Type"] = content_type if content_type
connection = Excon.new(UrlHelper.encode_and_parse(endpoint.url), headers: headers) connection = Excon.new(endpoint.url, headers: headers)
params = { method: endpoint.method } params = { method: endpoint.method }

Datei anzeigen

@ -17,9 +17,8 @@ class ::CustomWizard::CustomField
category: ["basic_category"], category: ["basic_category"],
post: ["post"] post: ["post"]
} }
SUBSCRIPTION_CLASSES ||= ['category', 'group']
TYPES ||= ["string", "boolean", "integer", "json"] TYPES ||= ["string", "boolean", "integer", "json"]
SUBSCRIPTION_TYPES ||= ["json"]
LIST_CACHE_KEY ||= 'custom_field_list' LIST_CACHE_KEY ||= 'custom_field_list'
def self.serializers def self.serializers
@ -85,7 +84,7 @@ class ::CustomWizard::CustomField
next next
end end
if attr == 'klass' && SUBSCRIPTION_CLASSES.include?(value) && !@subscription.subscribed? if attr == 'klass' && @subscription.requires_additional_subscription("custom_fields", "klass").include?(value)
add_error(I18n.t("wizard.custom_field.error.subscription_type", type: value)) add_error(I18n.t("wizard.custom_field.error.subscription_type", type: value))
end end
@ -100,7 +99,7 @@ class ::CustomWizard::CustomField
add_error(I18n.t("#{i18n_key}.unsupported_type", type: value)) add_error(I18n.t("#{i18n_key}.unsupported_type", type: value))
end end
if attr == 'type' && SUBSCRIPTION_TYPES.include?(value) && !@subscription.subscribed? if attr == 'type' && @subscription.requires_additional_subscription("custom_fields", "type").include?(value)
add_error(I18n.t("wizard.custom_field.error.subscription_type", type: value)) add_error(I18n.t("wizard.custom_field.error.subscription_type", type: value))
end end

Datei anzeigen

@ -6,6 +6,23 @@ class CustomWizard::Subscription
attr_accessor :authentication, attr_accessor :authentication,
:subscription :subscription
SUBSCRIPTION_LEVELS = {
standard: {
actions: ["send_message", "add_to_group", "watch_categories"],
custom_fields: {
klass: [],
type: ["json"],
},
},
business: {
actions: ["create_category", "create_group", "send_to_api"],
custom_fields: {
klass: ["group", "category"],
type: [],
},
},
}
def initialize def initialize
@authentication = CustomWizard::Subscription::Authentication.new(get_authentication) @authentication = CustomWizard::Subscription::Authentication.new(get_authentication)
@subscription = CustomWizard::Subscription::Subscription.new(get_subscription) @subscription = CustomWizard::Subscription::Subscription.new(get_subscription)
@ -27,6 +44,10 @@ class CustomWizard::Subscription
"stripe" "stripe"
end end
def type
@subscription.type
end
def client_name def client_name
"custom-wizard" "custom-wizard"
end end
@ -35,6 +56,31 @@ class CustomWizard::Subscription
"discourse-subscription-server:user_subscription" "discourse-subscription-server:user_subscription"
end end
def requires_additional_subscription(kategory, sub_kategory)
case kategory
when "actions"
case self.type
when "business"
[]
when "standard"
SUBSCRIPTION_LEVELS[:business][kategory.to_sym]
else
SUBSCRIPTION_LEVELS[:standard][kategory.to_sym] + SUBSCRIPTION_LEVELS[:business][kategory.to_sym]
end
when "custom_fields"
case self.type
when "business"
[]
when "standard"
SUBSCRIPTION_LEVELS[:business][kategory.to_sym][sub_kategory.to_sym]
else
SUBSCRIPTION_LEVELS[:standard][kategory.to_sym][sub_kategory.to_sym] + SUBSCRIPTION_LEVELS[:business][kategory.to_sym][sub_kategory.to_sym]
end
else
[]
end
end
def update def update
if @authentication.active? if @authentication.active?
response = Excon.get( response = Excon.get(
@ -119,6 +165,14 @@ class CustomWizard::Subscription
self.new.subscribed? self.new.subscribed?
end end
def self.type
self.new.type
end
def self.requires_additional_subscription(kategory, sub_kategory)
self.new.requires_additional_subscription(kategory, sub_kategory)
end
def self.authorized? def self.authorized?
self.new.authorized? self.new.authorized?
end end

Datei anzeigen

@ -13,7 +13,7 @@ class CustomWizard::Subscription::Subscription
end end
def types def types
%w(community business) %w(none standard business)
end end
def active? def active?

Datei anzeigen

@ -13,6 +13,9 @@ describe CustomWizard::Action do
let(:add_to_group) { get_wizard_fixture("actions/add_to_group") } let(:add_to_group) { get_wizard_fixture("actions/add_to_group") }
let(:send_message) { get_wizard_fixture("actions/send_message") } let(:send_message) { get_wizard_fixture("actions/send_message") }
let(:send_message_multi) { get_wizard_fixture("actions/send_message_multi") } let(:send_message_multi) { get_wizard_fixture("actions/send_message_multi") }
let(:api_test_endpoint) { get_wizard_fixture("endpoints/test_endpoint") }
let(:api_test_endpoint_body) { get_wizard_fixture("endpoints/test_endpoint_body") }
let(:api_test_no_authorization) { get_wizard_fixture("api/no_authorization") }
def update_template(template) def update_template(template)
CustomWizard::Template.save(template, skip_jobs: true) CustomWizard::Template.save(template, skip_jobs: true)
@ -176,7 +179,7 @@ describe CustomWizard::Action do
context "subscription actions" do context "subscription actions" do
before do before do
enable_subscription enable_subscription("standard")
end end
it '#send_message' do it '#send_message' do
@ -265,5 +268,51 @@ describe CustomWizard::Action do
expect(group.users.first.username).to eq('angus') expect(group.users.first.username).to eq('angus')
end end
it '#send_to_api successful' do
stub_request(:put, "https://myexternalapi.com/update").
with(
body: "some_body",
headers: {
'Host' => 'myexternalapi.com'
}).
to_return(status: 200, body: "success", headers: {})
new_api = CustomWizard::Api.new("my_api")
CustomWizard::Api.set("my_api", title: "Mocked external api")
CustomWizard::Api::Authorization.set("my_api", api_test_no_authorization)
CustomWizard::Api::Endpoint.new("my_api")
CustomWizard::Api::Endpoint.set("my_api", api_test_endpoint)
endpoint_id = CustomWizard::Api::Endpoint.list("my_api").first.id
result = CustomWizard::Api::Endpoint.request("my_api", endpoint_id, "some_body")
log_entry = CustomWizard::Api::LogEntry.list("my_api").first
expect(result).to eq('success')
expect(log_entry.status).to eq('SUCCESS')
end
it '#send_to_api failure' do
stub_request(:put, "https://myexternalapi.com/update").
with(
body: "some_body",
headers: {
'Host' => 'myexternalapi.com'
}).
to_return(status: 500, body: "failure", headers: {})
new_api = CustomWizard::Api.new("my_api")
CustomWizard::Api.set("my_api", title: "Mocked external api")
CustomWizard::Api::Authorization.set("my_api", api_test_no_authorization)
CustomWizard::Api::Endpoint.new("my_api")
CustomWizard::Api::Endpoint.set("my_api", api_test_endpoint)
endpoint_id = CustomWizard::Api::Endpoint.list("my_api").first.id
result = CustomWizard::Api::Endpoint.request("my_api", endpoint_id, "some_body")
log_entry = CustomWizard::Api::LogEntry.list("my_api").first
expect(result).to eq({ error: "API request failed" })
expect(log_entry.status).to eq('FAIL')
end
end end
end end

Datei anzeigen

@ -176,7 +176,7 @@ describe CustomWizard::Builder do
context "restart is enabled" do context "restart is enabled" do
before do before do
enable_subscription enable_subscription("standard")
@template[:restart_on_revisit] = true @template[:restart_on_revisit] = true
CustomWizard::Template.save(@template.as_json) CustomWizard::Template.save(@template.as_json)
end end
@ -205,7 +205,7 @@ describe CustomWizard::Builder do
context 'with required data' do context 'with required data' do
before do before do
enable_subscription enable_subscription("standard")
@template[:steps][0][:required_data] = required_data_json['required_data'] @template[:steps][0][:required_data] = required_data_json['required_data']
@template[:steps][0][:required_data_message] = required_data_json['required_data_message'] @template[:steps][0][:required_data_message] = required_data_json['required_data_message']
CustomWizard::Template.save(@template.as_json) CustomWizard::Template.save(@template.as_json)
@ -241,7 +241,7 @@ describe CustomWizard::Builder do
context "with permitted params" do context "with permitted params" do
before do before do
enable_subscription enable_subscription("standard")
@template[:steps][0][:permitted_params] = permitted_param_json['permitted_params'] @template[:steps][0][:permitted_params] = permitted_param_json['permitted_params']
CustomWizard::Template.save(@template.as_json) CustomWizard::Template.save(@template.as_json)
end end
@ -256,7 +256,7 @@ describe CustomWizard::Builder do
context "with condition" do context "with condition" do
before do before do
enable_subscription enable_subscription("standard")
@template[:steps][0][:condition] = user_condition_json['condition'] @template[:steps][0][:condition] = user_condition_json['condition']
CustomWizard::Template.save(@template.as_json) CustomWizard::Template.save(@template.as_json)
end end
@ -295,7 +295,7 @@ describe CustomWizard::Builder do
context "with condition" do context "with condition" do
before do before do
enable_subscription enable_subscription("standard")
@template[:steps][0][:fields][0][:condition] = user_condition_json['condition'] @template[:steps][0][:fields][0][:condition] = user_condition_json['condition']
CustomWizard::Template.save(@template.as_json) CustomWizard::Template.save(@template.as_json)
end end
@ -327,7 +327,7 @@ describe CustomWizard::Builder do
context 'save submissions disabled' do context 'save submissions disabled' do
before do before do
enable_subscription enable_subscription("standard")
@template[:save_submissions] = false @template[:save_submissions] = false
CustomWizard::Template.save(@template.as_json) CustomWizard::Template.save(@template.as_json)
@wizard = CustomWizard::Builder.new(@template[:id], user).build @wizard = CustomWizard::Builder.new(@template[:id], user).build

Datei anzeigen

@ -217,7 +217,7 @@ describe CustomWizard::CustomField do
context "with a subscription" do context "with a subscription" do
before do before do
enable_subscription enable_subscription("business")
end end
it "saves subscription field types" do it "saves subscription field types" do

Datei anzeigen

@ -359,7 +359,7 @@ describe CustomWizard::Mapper do
context "with a subscription" do context "with a subscription" do
before do before do
enable_subscription enable_subscription("standard")
end end
it "treats replaced values as string literals" do it "treats replaced values as string literals" do

Datei anzeigen

@ -75,7 +75,7 @@ describe CustomWizard::TemplateValidator do
context "with subscription" do context "with subscription" do
before do before do
enable_subscription enable_subscription("standard")
end end
it "validates wizard attributes" do it "validates wizard attributes" do

Datei anzeigen

@ -74,7 +74,7 @@ describe "custom field extensions" do
context "subscription custom fields" do context "subscription custom fields" do
before do before do
enable_subscription enable_subscription("business")
subscription_custom_field_json['custom_fields'].each do |field_json| subscription_custom_field_json['custom_fields'].each do |field_json|
custom_field = CustomWizard::CustomField.new(nil, field_json) custom_field = CustomWizard::CustomField.new(nil, field_json)

3
spec/fixtures/api/no_authorization.json gevendort Normale Datei
Datei anzeigen

@ -0,0 +1,3 @@
{
"auth_type": "none"
}

5
spec/fixtures/endpoints/test_endpoint.json gevendort Normale Datei
Datei anzeigen

@ -0,0 +1,5 @@
{
"method": "PUT",
"url": "https://myexternalapi.com/update",
"success_codes": [200]
}

Datei anzeigen

@ -0,0 +1,3 @@
{
"data": "some_data"
}

Datei anzeigen

@ -15,6 +15,7 @@ require 'oj'
Oj.default_options = Oj.default_options.merge(cache_str: -1) Oj.default_options = Oj.default_options.merge(cache_str: -1)
require 'rails_helper' require 'rails_helper'
require 'webmock/rspec'
def get_wizard_fixture(path) def get_wizard_fixture(path)
JSON.parse( JSON.parse(
@ -28,8 +29,10 @@ def authenticate_subscription
CustomWizard::Subscription::Authentication.any_instance.stubs(:active?).returns(true) CustomWizard::Subscription::Authentication.any_instance.stubs(:active?).returns(true)
end end
def enable_subscription def enable_subscription(type)
# CustomWizard::Subscription.new
CustomWizard::Subscription.any_instance.stubs(:subscribed?).returns(true) CustomWizard::Subscription.any_instance.stubs(:subscribed?).returns(true)
CustomWizard::Subscription.any_instance.stubs(:type).returns(type)
end end
def disable_subscription def disable_subscription

Datei anzeigen

@ -40,8 +40,7 @@ describe "custom field extensions" do
context "with a subscription" do context "with a subscription" do
before do before do
enable_subscription enable_subscription("business")
subscription_custom_field_json['custom_fields'].each do |field_json| subscription_custom_field_json['custom_fields'].each do |field_json|
custom_field = CustomWizard::CustomField.new(nil, field_json) custom_field = CustomWizard::CustomField.new(nil, field_json)
custom_field.save custom_field.save

Datei anzeigen

@ -121,7 +121,7 @@ describe CustomWizard::StepsController do
context "subscription" do context "subscription" do
before do before do
enable_subscription enable_subscription("standard")
end end
it "raises an error when user cant see the step due to conditions" do it "raises an error when user cant see the step due to conditions" do

Datei anzeigen

@ -4,11 +4,11 @@ require_relative '../../../plugin_helper'
describe CustomWizard::Subscription::SubscriptionSerializer do describe CustomWizard::Subscription::SubscriptionSerializer do
it 'should return subscription attributes' do it 'should return subscription attributes' do
sub = CustomWizard::Subscription::Subscription.new(OpenStruct.new(type: 'community', updated_at: Time.now)) sub = CustomWizard::Subscription::Subscription.new(OpenStruct.new(type: 'standard', updated_at: Time.now))
serialized = described_class.new(sub, root: false).as_json serialized = described_class.new(sub, root: false).as_json
expect(serialized[:active]).to eq(true) expect(serialized[:active]).to eq(true)
expect(serialized[:type]).to eq('community') expect(serialized[:type]).to eq('standard')
expect(serialized[:updated_at]).to eq(sub.updated_at) expect(serialized[:updated_at]).to eq(sub.updated_at)
end end
end end

Datei anzeigen

@ -34,7 +34,7 @@ describe CustomWizard::StepSerializer do
context 'with required data' do context 'with required data' do
before do before do
enable_subscription enable_subscription("standard")
wizard_template['steps'][0]['required_data'] = required_data_json['required_data'] wizard_template['steps'][0]['required_data'] = required_data_json['required_data']
wizard_template['steps'][0]['required_data_message'] = required_data_json['required_data_message'] wizard_template['steps'][0]['required_data_message'] = required_data_json['required_data_message']
CustomWizard::Template.save(wizard_template) CustomWizard::Template.save(wizard_template)