diff --git a/app/controllers/custom_wizard/admin/admin.rb b/app/controllers/custom_wizard/admin/admin.rb index aa8862b6..2b950b23 100644 --- a/app/controllers/custom_wizard/admin/admin.rb +++ b/app/controllers/custom_wizard/admin/admin.rb @@ -2,16 +2,6 @@ class CustomWizard::AdminController < ::Admin::AdminController before_action :ensure_admin - def index - subcription = CustomWizard::Subscription.new - render_json_dump( - subscribed: subcription.subscribed?, - subscription_type: subcription.type, - subscription_attributes: CustomWizard::Subscription.attributes, - subscription_client_installed: CustomWizard::Subscription.client_installed? - ) - end - private def find_wizard diff --git a/app/controllers/custom_wizard/admin/subscription.rb b/app/controllers/custom_wizard/admin/subscription.rb new file mode 100644 index 00000000..7b596ec6 --- /dev/null +++ b/app/controllers/custom_wizard/admin/subscription.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true +class CustomWizard::SubscriptionController < ::Admin::AdminController + before_action :ensure_admin + + def index + if params[:update_from_remote] + subscription = CustomWizard::Subscription.new(true) + else + subscription = CustomWizard::Subscription.new + end + + render_json_dump( + subscribed: subscription.subscribed?, + subscription_type: subscription.type, + subscription_attributes: CustomWizard::Subscription.attributes, + ) + end +end diff --git a/assets/javascripts/discourse/components/modal/admin-wizards-columns.js b/assets/javascripts/discourse/components/modal/admin-wizards-columns.js index d4da771e..8204f6c3 100644 --- a/assets/javascripts/discourse/components/modal/admin-wizards-columns.js +++ b/assets/javascripts/discourse/components/modal/admin-wizards-columns.js @@ -5,11 +5,13 @@ import I18n from "I18n"; export default class AdminWizardsColumnComponent extends Component { title = I18n.t("admin.wizard.edit_columns"); - @action save() { + @action + save() { this.args.closeModal(); } - @action resetToDefault() { + @action + resetToDefault() { this.args.model.reset(); } } diff --git a/assets/javascripts/discourse/components/modal/next-session-scheduled.js b/assets/javascripts/discourse/components/modal/next-session-scheduled.js index 446237f0..e5b719f8 100644 --- a/assets/javascripts/discourse/components/modal/next-session-scheduled.js +++ b/assets/javascripts/discourse/components/modal/next-session-scheduled.js @@ -18,13 +18,15 @@ export default class NextSessionScheduledComponent extends Component { return moment().isAfter(this.bufferedDateTime); } - @action submit() { + @action + submit() { const dateTime = this.bufferedDateTime; this.args.model.update(moment(dateTime).utc().toISOString()); this.args.closeModal(); } - @action dateTimeChanged(dateTime) { + @action + dateTimeChanged(dateTime) { this.bufferedDateTime = dateTime; } } diff --git a/assets/javascripts/discourse/components/wizard-mapper-selector.js.es6 b/assets/javascripts/discourse/components/wizard-mapper-selector.js.es6 index d7cf846b..eb9e735a 100644 --- a/assets/javascripts/discourse/components/wizard-mapper-selector.js.es6 +++ b/assets/javascripts/discourse/components/wizard-mapper-selector.js.es6 @@ -15,7 +15,7 @@ import { import Component from "@ember/component"; import { bind, later } from "@ember/runloop"; import I18n from "I18n"; -import Subscription from "../mixins/subscription"; +import { inject as service } from "@ember/service"; const customFieldActionMap = { topic: ["create_topic", "send_message"], @@ -27,8 +27,9 @@ const customFieldActionMap = { const values = ["present", "true", "false"]; -export default Component.extend(Subscription, { +export default Component.extend({ classNameBindings: [":mapper-selector", "activeType"], + subscription: service(), showText: computed("activeType", function () { return this.showInput("text"); @@ -130,7 +131,11 @@ export default Component.extend(Subscription, { return this.connector === "is"; }), - @discourseComputed("site.groups", "guestGroup", "subscriptionType") + @discourseComputed( + "site.groups", + "guestGroup", + "subscription.subscriptionType" + ) groups(groups, guestGroup, subscriptionType) { let result = groups; if (!guestGroup) { diff --git a/assets/javascripts/discourse/components/wizard-subscription-badge.hbs b/assets/javascripts/discourse/components/wizard-subscription-badge.hbs new file mode 100644 index 00000000..dee4724f --- /dev/null +++ b/assets/javascripts/discourse/components/wizard-subscription-badge.hbs @@ -0,0 +1,19 @@ + + {{d-icon "pavilion-logo"}} + {{this.label}} + + + {{#if this.updating}} + {{loading-spinner size="small"}} + {{/if}} + \ No newline at end of file diff --git a/assets/javascripts/discourse/components/wizard-subscription-badge.js b/assets/javascripts/discourse/components/wizard-subscription-badge.js new file mode 100644 index 00000000..e103c95b --- /dev/null +++ b/assets/javascripts/discourse/components/wizard-subscription-badge.js @@ -0,0 +1,47 @@ +import { inject as service } from "@ember/service"; +import { action, computed } from "@ember/object"; +import Component from "@glimmer/component"; +import { tracked } from "@glimmer/tracking"; +import DiscourseURL from "discourse/lib/url"; +import I18n from "I18n"; + +export default class WizardSubscriptionBadge extends Component { + @service subscription; + @tracked updating = false; + @tracked updateIcon = "sync"; + basePath = "/admin/plugins/subscription-client"; + + @computed("subscription.subscriptionType") + get i18nKey() { + return `admin.wizard.subscription.type.${ + this.subscription.subscriptionType + ? this.subscription.subscriptionType + : "none" + }`; + } + + @computed("i18nKey") + get title() { + return `${this.i18nKey}.title`; + } + + @computed("i18nKey") + get label() { + return I18n.t(`${this.i18nKey}.label`); + } + + @action + click() { + DiscourseURL.routeTo(this.subscription.subscriptionLink); + } + + @action + update() { + this.updating = true; + this.updateIcon = null; + this.subscription.updateSubscriptionStatus().finally(() => { + this.updateIcon = "sync"; + this.updating = false; + }); + } +} diff --git a/assets/javascripts/discourse/components/wizard-subscription-badge.js.es6 b/assets/javascripts/discourse/components/wizard-subscription-badge.js.es6 deleted file mode 100644 index 301c618e..00000000 --- a/assets/javascripts/discourse/components/wizard-subscription-badge.js.es6 +++ /dev/null @@ -1,30 +0,0 @@ -import Component from "@ember/component"; -import discourseComputed from "discourse-common/utils/decorators"; -import Subscription from "../mixins/subscription"; -import DiscourseURL from "discourse/lib/url"; -import I18n from "I18n"; - -export default Component.extend(Subscription, { - tagName: "a", - classNameBindings: [":wizard-subscription-badge", "subscriptionType"], - attributeBindings: ["title"], - - @discourseComputed("subscriptionType") - i18nKey(type) { - return `admin.wizard.subscription.type.${type ? type : "none"}`; - }, - - @discourseComputed("i18nKey") - title(i18nKey) { - return I18n.t(`${i18nKey}.title`); - }, - - @discourseComputed("i18nKey") - label(i18nKey) { - return I18n.t(`${i18nKey}.label`); - }, - - click() { - DiscourseURL.routeTo(this.subscriptionLink); - }, -}); diff --git a/assets/javascripts/discourse/components/wizard-subscription-container.hbs b/assets/javascripts/discourse/components/wizard-subscription-container.hbs new file mode 100644 index 00000000..a59263ed --- /dev/null +++ b/assets/javascripts/discourse/components/wizard-subscription-container.hbs @@ -0,0 +1,17 @@ +
+
+

{{i18n "admin.wizard.subscription.title"}}

+ + + {{d-icon subscribedIcon}} + {{i18n subscribedLabel}} + +
+ +
+ {{yield}} +
+
\ No newline at end of file diff --git a/assets/javascripts/discourse/components/wizard-subscription-container.js b/assets/javascripts/discourse/components/wizard-subscription-container.js new file mode 100644 index 00000000..060d7af6 --- /dev/null +++ b/assets/javascripts/discourse/components/wizard-subscription-container.js @@ -0,0 +1,26 @@ +import Component from "@glimmer/component"; +import { computed } from "@ember/object"; +import { inject as service } from "@ember/service"; + +export default class WizardSubscriptionContainer extends Component { + @service subscription; + + @computed("subscription.subscribed") + get subscribedIcon() { + return this.subscription.subscribed ? "check" : "times"; + } + + @computed("subscription.subscribed") + get subscribedLabel() { + return `admin.wizard.subscription.${ + this.subscription.subscribed ? "subscribed" : "not_subscribed" + }.label`; + } + + @computed("subscription.subscribed") + get subscribedTitle() { + return `admin.wizard.subscription.${ + this.subscription.subscribed ? "subscribed" : "not_subscribed" + }.title`; + } +} diff --git a/assets/javascripts/discourse/components/wizard-subscription-container.js.es6 b/assets/javascripts/discourse/components/wizard-subscription-container.js.es6 deleted file mode 100644 index 3a1eac9c..00000000 --- a/assets/javascripts/discourse/components/wizard-subscription-container.js.es6 +++ /dev/null @@ -1,26 +0,0 @@ -import Component from "@ember/component"; -import discourseComputed from "discourse-common/utils/decorators"; -import Subscription from "../mixins/subscription"; - -export default Component.extend(Subscription, { - classNameBindings: [":wizard-subscription-container", "subscribed"], - - @discourseComputed("subscribed") - subscribedIcon(subscribed) { - return subscribed ? "check" : "times"; - }, - - @discourseComputed("subscribed") - subscribedLabel(subscribed) { - return `admin.wizard.subscription.${ - subscribed ? "subscribed" : "not_subscribed" - }.label`; - }, - - @discourseComputed("subscribed") - subscribedTitle(subscribed) { - return `admin.wizard.subscription.${ - subscribed ? "subscribed" : "not_subscribed" - }.title`; - }, -}); diff --git a/assets/javascripts/discourse/components/wizard-subscription-cta.hbs b/assets/javascripts/discourse/components/wizard-subscription-cta.hbs new file mode 100644 index 00000000..945eb90c --- /dev/null +++ b/assets/javascripts/discourse/components/wizard-subscription-cta.hbs @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/assets/javascripts/discourse/components/wizard-subscription-cta.js b/assets/javascripts/discourse/components/wizard-subscription-cta.js new file mode 100644 index 00000000..47b2f382 --- /dev/null +++ b/assets/javascripts/discourse/components/wizard-subscription-cta.js @@ -0,0 +1,34 @@ +import { inject as service } from "@ember/service"; +import { action, computed } from "@ember/object"; +import Component from "@glimmer/component"; + +export default class WizardSubscriptionCta extends Component { + @service subscription; + + @computed("subscription.subscribed") + get i18nKey() { + return `admin.wizard.subscription.cta.${ + this.subscription.subscribed ? "subscribed" : "none" + }`; + } + + @computed("subscription.subscribed") + get icon() { + return this.subscription.subscribed ? "far-life-ring" : "external-link-alt"; + } + + @computed("i18nKey") + get title() { + return `${this.i18nKey}.title`; + } + + @computed("i18nKey") + get label() { + return `${this.i18nKey}.label`; + } + + @action + click() { + window.open(this.subscription.subscriptionCtaLink, "_blank").focus(); + } +} diff --git a/assets/javascripts/discourse/components/wizard-subscription-cta.js.es6 b/assets/javascripts/discourse/components/wizard-subscription-cta.js.es6 deleted file mode 100644 index f483fbe8..00000000 --- a/assets/javascripts/discourse/components/wizard-subscription-cta.js.es6 +++ /dev/null @@ -1,36 +0,0 @@ -import Component from "@ember/component"; -import discourseComputed from "discourse-common/utils/decorators"; -import Subscription from "../mixins/subscription"; -import I18n from "I18n"; - -export default Component.extend(Subscription, { - tagName: "a", - classNameBindings: [":btn", ":btn-pavilion-support", "subscriptionType"], - attributeBindings: ["title"], - - @discourseComputed("subscribed") - i18nKey(subscribed) { - return `admin.wizard.subscription.cta.${ - subscribed ? "subscribed" : "none" - }`; - }, - - @discourseComputed("subscribed") - icon(subscribed) { - return subscribed ? "far-life-ring" : "external-link-alt"; - }, - - @discourseComputed("i18nKey") - title(i18nKey) { - return I18n.t(`${i18nKey}.title`); - }, - - @discourseComputed("i18nKey") - label(i18nKey) { - return I18n.t(`${i18nKey}.label`); - }, - - click() { - window.open(this.subscriptionCtaLink, "_blank").focus(); - }, -}); diff --git a/assets/javascripts/discourse/components/wizard-subscription-selector.js.es6 b/assets/javascripts/discourse/components/wizard-subscription-selector.js.es6 index 351b5782..b7203c30 100644 --- a/assets/javascripts/discourse/components/wizard-subscription-selector.js.es6 +++ b/assets/javascripts/discourse/components/wizard-subscription-selector.js.es6 @@ -1,5 +1,5 @@ import SingleSelectComponent from "select-kit/components/single-select"; -import Subscription from "../mixins/subscription"; +import { inject as service } from "@ember/service"; import { filterValues } from "discourse/plugins/discourse-custom-wizard/discourse/lib/wizard-schema"; import discourseComputed from "discourse-common/utils/decorators"; import I18n from "I18n"; @@ -12,8 +12,9 @@ const nameKey = function (feature, attribute, value) { } }; -export default SingleSelectComponent.extend(Subscription, { +export default SingleSelectComponent.extend({ classNames: ["combo-box", "wizard-subscription-selector"], + subscription: service(), selectKitOptions: { autoFilterable: false, @@ -26,7 +27,7 @@ export default SingleSelectComponent.extend(Subscription, { }, allowedSubscriptionTypes(feature, attribute, value) { - let attributes = this.subscriptionAttributes[feature]; + let attributes = this.subscription.subscriptionAttributes[feature]; if (!attributes || !attributes[attribute]) { return ["none"]; } @@ -59,10 +60,9 @@ export default SingleSelectComponent.extend(Subscription, { name: I18n.t(nameKey(feature, attribute, value)), subscriptionRequired, }; - if (subscriptionRequired) { let subscribed = allowedSubscriptionTypes.includes( - this.subscriptionType + this.subscription.subscriptionType ); let selectorKey = subscribed ? "subscribed" : "not_subscribed"; let selectorLabel = `admin.wizard.subscription.${selectorKey}.selector`; diff --git a/assets/javascripts/discourse/components/wizard-subscription-status.hbs b/assets/javascripts/discourse/components/wizard-subscription-status.hbs new file mode 100644 index 00000000..a5c69a1b --- /dev/null +++ b/assets/javascripts/discourse/components/wizard-subscription-status.hbs @@ -0,0 +1,23 @@ +
+ {{#if authorized}} + {{conditional-loading-spinner size="small" condition=unauthorizing}} + + {{i18n "admin.wizard.subscription.deauthorize.label"}} + + {{else}} + + {{/if}} + + +
\ No newline at end of file diff --git a/assets/javascripts/discourse/components/wizard-subscription-status.js b/assets/javascripts/discourse/components/wizard-subscription-status.js new file mode 100644 index 00000000..e8efc49c --- /dev/null +++ b/assets/javascripts/discourse/components/wizard-subscription-status.js @@ -0,0 +1,53 @@ +import { action } from "@ember/object"; +import { inject as service } from "@ember/service"; +import Component from "@glimmer/component"; +import { tracked } from "@glimmer/tracking"; +import { ajax } from "discourse/lib/ajax"; +import { popupAjaxError } from "discourse/lib/ajax-error"; + +export default class WizardSubscriptionStatus extends Component { + @service siteSettings; + @service subscription; + @tracked supplierId = null; + @tracked authorized = false; + @tracked unauthorizing = false; + basePath = "/admin/plugins/subscription-client/suppliers"; + + constructor() { + super(...arguments); + ajax(`${this.basePath}`) + .then((result) => { + this.supplierId = result.suppliers[0].id; + this.authorized = result.suppliers[0].authorized; + }) + .finally(() => { + this.subscription.retrieveSubscriptionStatus(); + }); + } + + @action + authorize() { + window.location.href = `${this.basePath}/authorize?supplier_id=${this.supplierId}&final_landing_path=/admin/wizards/wizard`; + } + + @action + deauthorize() { + this.unauthorizing = true; + + ajax(`${this.basePath}/authorize`, { + type: "DELETE", + data: { + supplier_id: this.supplierId, + }, + }) + .then((result) => { + this.supplierId = result.supplier.id; + this.authorized = !(result.supplier.authorized_at === null); + }) + .finally(() => { + this.unauthorizing = false; + this.subscription.retrieveSubscriptionStatus(); + }) + .catch(popupAjaxError); + } +} diff --git a/assets/javascripts/discourse/controllers/admin-wizards.js.es6 b/assets/javascripts/discourse/controllers/admin-wizards.js.es6 index 518893b6..ded14b91 100644 --- a/assets/javascripts/discourse/controllers/admin-wizards.js.es6 +++ b/assets/javascripts/discourse/controllers/admin-wizards.js.es6 @@ -1,9 +1,12 @@ import Controller from "@ember/controller"; -import { equal, or } from "@ember/object/computed"; +import { or } from "@ember/object/computed"; +import { inject as service } from "@ember/service"; export default Controller.extend({ - businessSubscription: equal("subscriptionType", "business"), - communitySubscription: equal("subscriptionType", "community"), - standardSubscription: equal("subscriptionType", "standard"), - showApi: or("businessSubscription", "communitySubscription"), + subscription: service(), + + showApi: or( + "subscription.businessSubscription", + "subscription.communitySubscription" + ), }); diff --git a/assets/javascripts/discourse/helpers/wizard-char-counter.js b/assets/javascripts/discourse/helpers/wizard-char-counter.js new file mode 100644 index 00000000..97f7e98b --- /dev/null +++ b/assets/javascripts/discourse/helpers/wizard-char-counter.js @@ -0,0 +1,21 @@ +import I18n from "I18n"; +import Handlebars from "handlebars"; + +export default function wizardCharCounter(body, maxLength) { + let bodyLength = body ? body.length : 0; + let finalString; + + if (maxLength) { + let isOverMax = bodyLength > maxLength ? "true" : "false"; + finalString = `
${bodyLength} / ${I18n.t( + "wizard.x_characters", + { count: parseInt(maxLength, 10) } + )}
`; + } else { + finalString = `
${I18n.t("wizard.x_characters", { + count: parseInt(bodyLength, 10), + })}
`; + } + + return new Handlebars.SafeString(finalString); +} diff --git a/assets/javascripts/discourse/helpers/wizard-char-counter.js.es6 b/assets/javascripts/discourse/helpers/wizard-char-counter.js.es6 deleted file mode 100644 index 1e194314..00000000 --- a/assets/javascripts/discourse/helpers/wizard-char-counter.js.es6 +++ /dev/null @@ -1,25 +0,0 @@ -import { registerUnbound } from "discourse-common/lib/helpers"; -import I18n from "I18n"; -import Handlebars from "handlebars"; - -export default registerUnbound( - "wizard-char-counter", - function (body, maxLength) { - let bodyLength = body ? body.length : 0; - let finalString; - - if (maxLength) { - let isOverMax = bodyLength > maxLength ? "true" : "false"; - finalString = `
${bodyLength} / ${I18n.t( - "wizard.x_characters", - { count: parseInt(maxLength, 10) } - )}
`; - } else { - finalString = `
${I18n.t("wizard.x_characters", { - count: parseInt(bodyLength, 10), - })}
`; - } - - return new Handlebars.SafeString(finalString); - } -); diff --git a/assets/javascripts/discourse/routes/admin-wizards.js.es6 b/assets/javascripts/discourse/routes/admin-wizards.js.es6 index ff8a949a..a16df9ae 100644 --- a/assets/javascripts/discourse/routes/admin-wizards.js.es6 +++ b/assets/javascripts/discourse/routes/admin-wizards.js.es6 @@ -1,23 +1,9 @@ import DiscourseRoute from "discourse/routes/discourse"; -import { ajax } from "discourse/lib/ajax"; import { inject as service } from "@ember/service"; export default DiscourseRoute.extend({ router: service(), - model() { - return ajax("/admin/wizards"); - }, - - setupController(controller, model) { - controller.setProperties({ - subscribed: model.subscribed, - subscriptionType: model.subscription_type, - subscriptionAttributes: model.subscription_attributes, - subscriptionClientInstalled: model.subscription_client_installed, - }); - }, - afterModel(model, transition) { if (transition.targetName === "adminWizards.index") { this.router.transitionTo("adminWizardsWizard"); diff --git a/assets/javascripts/discourse/services/subscription.js b/assets/javascripts/discourse/services/subscription.js new file mode 100644 index 00000000..08ea5278 --- /dev/null +++ b/assets/javascripts/discourse/services/subscription.js @@ -0,0 +1,70 @@ +import Service from "@ember/service"; +import { tracked } from "@glimmer/tracking"; +import { ajax } from "discourse/lib/ajax"; +import { popupAjaxError } from "discourse/lib/ajax-error"; + +const PRODUCT_PAGE = "https://custom-wizard.pavilion.tech"; +const SUPPORT_MESSAGE = + "https://coop.pavilion.tech/new-message?username=support&title=Custom%20Wizard%20Support"; +const MANAGER_CATEGORY = + "https://discourse.pluginmanager.org/c/discourse-custom-wizard"; + +export default class SubscriptionService extends Service { + @tracked subscribed = false; + @tracked subscriptionType = ""; + @tracked businessSubscription = false; + @tracked communitySubscription = false; + @tracked standardSubscription = false; + @tracked subscriptionAttributes = {}; + subscriptionLandingUrl = PRODUCT_PAGE; + + async init() { + super.init(...arguments); + await this.retrieveSubscriptionStatus(); + } + + async retrieveSubscriptionStatus() { + let result = await ajax("/admin/wizards/subscription").catch( + popupAjaxError + ); + + this.subscribed = result.subscribed; + this.subscriptionType = result.subscription_type; + this.subscriptionAttributes = result.subscription_attributes; + this.businessSubscription = this.subscriptionType === "business"; + this.communitySubscription = this.subscriptionType === "community"; + this.standardSubscription = this.subscriptionType === "standard"; + } + + async updateSubscriptionStatus() { + let result = await ajax( + "/admin/wizards/subscription?update_from_remote=true" + ).catch(popupAjaxError); + + this.subscribed = result.subscribed; + this.subscriptionType = result.subscription_type; + this.subscriptionAttributes = result.subscription_attributes; + this.businessSubscription = this.subscriptionType === "business"; + this.communitySubscription = this.subscriptionType === "community"; + this.standardSubscription = this.subscriptionType === "standard"; + } + + get subscriptionLink() { + return this.subscriptionLandingUrl; + } + + get subscriptionCtaLink() { + switch (this.subscriptionType) { + case "none": + return PRODUCT_PAGE; + case "standard": + return SUPPORT_MESSAGE; + case "business": + return SUPPORT_MESSAGE; + case "community": + return MANAGER_CATEGORY; + default: + return PRODUCT_PAGE; + } + } +} diff --git a/assets/javascripts/discourse/templates/admin-wizards.hbs b/assets/javascripts/discourse/templates/admin-wizards.hbs index 452193b1..d650986d 100644 --- a/assets/javascripts/discourse/templates/admin-wizards.hbs +++ b/assets/javascripts/discourse/templates/admin-wizards.hbs @@ -18,8 +18,7 @@ }}
- {{wizard-subscription-badge}} - {{wizard-subscription-cta}} +
{{/admin-nav}} diff --git a/assets/javascripts/discourse/templates/components/wizard-subscription-container.hbs b/assets/javascripts/discourse/templates/components/wizard-subscription-container.hbs deleted file mode 100644 index b8031bfe..00000000 --- a/assets/javascripts/discourse/templates/components/wizard-subscription-container.hbs +++ /dev/null @@ -1,12 +0,0 @@ -
-

{{i18n "admin.wizard.subscription.title"}}

- - - {{d-icon subscribedIcon}} - {{i18n subscribedLabel}} - -
- -
- {{yield}} -
\ No newline at end of file diff --git a/assets/javascripts/discourse/templates/components/wizard-subscription-cta.hbs b/assets/javascripts/discourse/templates/components/wizard-subscription-cta.hbs deleted file mode 100644 index cb20df2b..00000000 --- a/assets/javascripts/discourse/templates/components/wizard-subscription-cta.hbs +++ /dev/null @@ -1 +0,0 @@ -{{d-icon icon}}{{label}} \ No newline at end of file diff --git a/assets/stylesheets/common/admin.scss b/assets/stylesheets/common/admin.scss index 6a1601d9..f8722c2d 100644 --- a/assets/stylesheets/common/admin.scss +++ b/assets/stylesheets/common/admin.scss @@ -43,14 +43,6 @@ $error: #ef1700; } } -.admin-wizards .admin-actions { - display: flex; - - .btn-pavilion-support { - margin-left: 10px; - } -} - .wizard-message { background-color: var(--primary-low); width: 100%; @@ -940,3 +932,52 @@ $error: #ef1700; font-size: 0.75em; } } + +.admin-wizards .admin-actions { + .supplier-authorize { + display: inline-flex; + + button.update { + width: 40px; + height: 34px; + } + + .btn-pavilion-support { + &:hover { + color: var(--pavilion-secondary); + } + } + + .wizard-subscription-badge { + margin-right: 5px; + svg { + margin-right: 0.45em; + } + &.none { + svg { + color: #919191; + } + } + &.community, + &.standard, + &.business { + svg { + color: #fff; + } + } + } + + .loading-container { + svg, + div { + vertical-align: -moz-middle-with-baseline; + vertical-align: -webkit-baseline-middle; + margin-right: 3px; + } + } + + .btn-primary { + margin-right: 5px; + } + } +} diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index b4b9ba68..0a088855 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -545,6 +545,14 @@ en: subscription: title: Subscriber Features + authorize: + label: Authorize + title: Authorize your subscription on this site + deauthorize: + label: deauthorize + title: Deauthorize your subscription on this site + update: + title: "Update subscription status" subscribed: label: Subscribed title: You're subscribed and can use these features diff --git a/config/routes.rb b/config/routes.rb index 607a87ac..b611916e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -14,6 +14,7 @@ Discourse::Application.routes.append do scope module: 'custom_wizard', constraints: AdminConstraint.new do get 'admin/wizards' => 'admin#index' + get 'admin/wizards/subscription' => 'subscription#index' get 'admin/wizards/wizard' => 'admin_wizard#index' get 'admin/wizards/wizard/create' => 'admin#index' diff --git a/lib/custom_wizard/subscription.rb b/lib/custom_wizard/subscription.rb index 23de1808..96efe92c 100644 --- a/lib/custom_wizard/subscription.rb +++ b/lib/custom_wizard/subscription.rb @@ -1,4 +1,6 @@ # frozen_string_literal: true +require "discourse_subscription_client" + class CustomWizard::Subscription PRODUCT_HIERARCHY = %w[ community @@ -104,25 +106,27 @@ class CustomWizard::Subscription attr_accessor :product_id, :product_slug - def initialize - if CustomWizard::Subscription.client_installed? - result = DiscourseSubscriptionClient.find_subscriptions("discourse-custom-wizard") + def initialize(update = false) + if update + ::DiscourseSubscriptionClient::Subscriptions.update + end - if result&.any? - ids_and_slugs = result.subscriptions.map do |subscription| - { - id: subscription.product_id, - slug: result.products[subscription.product_id] - } - end + result = ::DiscourseSubscriptionClient.find_subscriptions("discourse-custom-wizard") - id_and_slug = ids_and_slugs.sort do |a, b| - PRODUCT_HIERARCHY.index(b[:slug]) - PRODUCT_HIERARCHY.index(a[:slug]) - end.first - - @product_id = id_and_slug[:id] - @product_slug = id_and_slug[:slug] + if result&.any? + ids_and_slugs = result.subscriptions.map do |subscription| + { + id: subscription.product_id, + slug: result.products[subscription.product_id] + } end + + id_and_slug = ids_and_slugs.sort do |a, b| + PRODUCT_HIERARCHY.index(b[:slug]) - PRODUCT_HIERARCHY.index(a[:slug]) + end.first + + @product_id = id_and_slug[:id] + @product_slug = id_and_slug[:slug] end @product_slug ||= ENV["CUSTOM_WIZARD_PRODUCT_SLUG"] @@ -176,6 +180,7 @@ class CustomWizard::Subscription product_slug === "community" end + # TODO candidate for removal once code that depends on it externally is no longer used. def self.client_installed? defined?(DiscourseSubscriptionClient) == 'constant' && DiscourseSubscriptionClient.class == Module end diff --git a/plugin.rb b/plugin.rb index 3f199471..99789ebc 100644 --- a/plugin.rb +++ b/plugin.rb @@ -1,16 +1,18 @@ # frozen_string_literal: true # name: discourse-custom-wizard # about: Forms for Discourse. Better onboarding, structured posting, data enrichment, automated actions and much more. -# version: 2.5.0 +# version: 2.5.1 # authors: Angus McLeod, Faizaan Gagan, Robert Barrow, Keegan George, Kaitlin Maddever, Juan Marcos Gutierrez Ramos # url: https://github.com/paviliondev/discourse-custom-wizard # contact_emails: development@pavilion.tech # subscription_url: https://coop.pavilion.tech gem 'liquid', '5.0.1', require: true +gem "discourse_subscription_client", "0.1.0.pre15", require_name: "discourse_subscription_client" gem 'discourse_plugin_statistics', '0.1.0.pre7', require: true register_asset 'stylesheets/common/admin.scss' register_asset 'stylesheets/common/wizard.scss' +register_svg_icon 'pavilion-logo' enabled_site_setting :custom_wizard_enabled @@ -36,6 +38,7 @@ after_initialize do ../lib/custom_wizard/engine.rb ../config/routes.rb ../app/controllers/custom_wizard/admin/admin.rb + ../app/controllers/custom_wizard/admin/subscription.rb ../app/controllers/custom_wizard/admin/wizard.rb ../app/controllers/custom_wizard/admin/submissions.rb ../app/controllers/custom_wizard/admin/api.rb diff --git a/spec/components/custom_wizard/action_spec.rb b/spec/components/custom_wizard/action_spec.rb index 57fe7f56..b867cced 100644 --- a/spec/components/custom_wizard/action_spec.rb +++ b/spec/components/custom_wizard/action_spec.rb @@ -42,6 +42,7 @@ describe CustomWizard::Action do } before do + stub_out_subscription_classes Group.refresh_automatic_group!(:trust_level_2) update_template(wizard_template) end diff --git a/spec/components/custom_wizard/builder_spec.rb b/spec/components/custom_wizard/builder_spec.rb index 1e55b203..23db81e5 100644 --- a/spec/components/custom_wizard/builder_spec.rb +++ b/spec/components/custom_wizard/builder_spec.rb @@ -29,6 +29,7 @@ describe CustomWizard::Builder do } before do + stub_out_subscription_classes Group.refresh_automatic_group!(:trust_level_3) CustomWizard::Template.save(wizard_template, skip_jobs: true) @template = CustomWizard::Template.find('super_mega_fun_wizard') diff --git a/spec/components/custom_wizard/custom_field_spec.rb b/spec/components/custom_wizard/custom_field_spec.rb index 4b8d43e2..e25294a0 100644 --- a/spec/components/custom_wizard/custom_field_spec.rb +++ b/spec/components/custom_wizard/custom_field_spec.rb @@ -5,6 +5,7 @@ describe CustomWizard::CustomField do let(:custom_field_subscription_json) { get_wizard_fixture("custom_field/subscription_custom_fields") } before do + stub_out_subscription_classes CustomWizard::CustomField.invalidate_cache end diff --git a/spec/components/custom_wizard/submission_spec.rb b/spec/components/custom_wizard/submission_spec.rb index d0e0c986..54249380 100644 --- a/spec/components/custom_wizard/submission_spec.rb +++ b/spec/components/custom_wizard/submission_spec.rb @@ -7,6 +7,7 @@ describe CustomWizard::Submission do let(:guest_id) { CustomWizard::Wizard.generate_guest_id } before do + stub_out_subscription_classes CustomWizard::Template.save(template_json, skip_jobs: true) @wizard = CustomWizard::Wizard.create(template_json["id"], user) described_class.new(@wizard, step_1_field_1: "I am user submission").save diff --git a/spec/components/custom_wizard/subscription_spec.rb b/spec/components/custom_wizard/subscription_spec.rb index 239233ef..7272ecf3 100644 --- a/spec/components/custom_wizard/subscription_spec.rb +++ b/spec/components/custom_wizard/subscription_spec.rb @@ -13,41 +13,9 @@ describe CustomWizard::Subscription do } } - after do - undefine_client_classes - end - - it "detects the subscription client" do - undefine_client_classes - expect(described_class.client_installed?).to eq(false) - end - - context "without a subscription client" do - it "is not subscribed" do - expect(described_class.subscribed?).to eq(false) - end - - it "has none type" do - subscription = described_class.new - expect(subscription.type).to eq(:none) - end - - it "non subscriber features are included" do - expect(described_class.includes?(:wizard, :after_signup, true)).to eq(true) - end - - it "subscriber features are not included" do - expect(described_class.includes?(:wizard, :permitted, {})).to eq(false) - end - end - - context "with subscription client" do + context "with subscription client gem mocked out" do before do - define_client_classes - end - - it "detects the subscription client" do - expect(described_class.client_installed?).to eq(true) + stub_out_subscription_classes end context "without a subscription" do @@ -69,11 +37,12 @@ describe CustomWizard::Subscription do end context "with subscriptions" do + def get_subscription_result(product_ids) result = DiscourseSubscriptionClient::Subscriptions::Result.new result.supplier = SubscriptionClientSupplier.new(product_slugs) result.resource = SubscriptionClientResource.new - result.subscriptions = product_ids.map { |product_id| SubscriptionClientSubscription.new(product_id) } + result.subscriptions = product_ids.map { |product_id| ::SubscriptionClientSubscription.new(product_id) } result.products = product_slugs result end diff --git a/spec/components/custom_wizard/template_spec.rb b/spec/components/custom_wizard/template_spec.rb index 76b229dc..5c16f3fa 100644 --- a/spec/components/custom_wizard/template_spec.rb +++ b/spec/components/custom_wizard/template_spec.rb @@ -7,6 +7,7 @@ describe CustomWizard::Template do fab!(:upload) { Fabricate(:upload) } before do + stub_out_subscription_classes CustomWizard::Template.save(template_json, skip_jobs: true) end diff --git a/spec/components/custom_wizard/template_validator_spec.rb b/spec/components/custom_wizard/template_validator_spec.rb index fe61be91..83170c34 100644 --- a/spec/components/custom_wizard/template_validator_spec.rb +++ b/spec/components/custom_wizard/template_validator_spec.rb @@ -39,6 +39,10 @@ describe CustomWizard::TemplateValidator do expect(validator.errors.first.message).to eq("Liquid syntax error in #{object_id}: #{message}") end + before do + stub_out_subscription_classes + end + it "validates valid templates" do expect( CustomWizard::TemplateValidator.new(template).perform diff --git a/spec/components/custom_wizard/update_validator_spec.rb b/spec/components/custom_wizard/update_validator_spec.rb index 7caa1784..0cfc7e44 100644 --- a/spec/components/custom_wizard/update_validator_spec.rb +++ b/spec/components/custom_wizard/update_validator_spec.rb @@ -6,6 +6,7 @@ describe CustomWizard::UpdateValidator do let(:url_field) { get_wizard_fixture("field/url") } before do + stub_out_subscription_classes CustomWizard::Template.save(template, skip_jobs: true) @template = CustomWizard::Template.find('super_mega_fun_wizard') end diff --git a/spec/components/custom_wizard/wizard_spec.rb b/spec/components/custom_wizard/wizard_spec.rb index 3483d211..91eb7424 100644 --- a/spec/components/custom_wizard/wizard_spec.rb +++ b/spec/components/custom_wizard/wizard_spec.rb @@ -10,6 +10,7 @@ describe CustomWizard::Wizard do let(:step_json) { get_wizard_fixture("step/step") } before do + stub_out_subscription_classes Group.refresh_automatic_group!(:trust_level_3) @permitted_template = template_json.dup @permitted_template["permitted"] = permitted_json["permitted"] diff --git a/spec/extensions/custom_field_extensions_spec.rb b/spec/extensions/custom_field_extensions_spec.rb index b0088972..e73099ca 100644 --- a/spec/extensions/custom_field_extensions_spec.rb +++ b/spec/extensions/custom_field_extensions_spec.rb @@ -11,6 +11,7 @@ describe "custom field extensions" do let(:subscription_custom_field_json) { get_wizard_fixture("custom_field/subscription_custom_fields") } before do + stub_out_subscription_classes custom_field_json['custom_fields'].each do |field_json| custom_field = CustomWizard::CustomField.new(nil, field_json) custom_field.save diff --git a/spec/extensions/extra_locales_controller_spec.rb b/spec/extensions/extra_locales_controller_spec.rb index 1be62f36..0590f274 100644 --- a/spec/extensions/extra_locales_controller_spec.rb +++ b/spec/extensions/extra_locales_controller_spec.rb @@ -7,6 +7,7 @@ describe ExtraLocalesControllerCustomWizard, type: :request do let(:permitted) { get_wizard_fixture("wizard/permitted") } before do + stub_out_subscription_classes CustomWizard::Template.save(template, skip_jobs: true) end diff --git a/spec/extensions/guardian_extension_spec.rb b/spec/extensions/guardian_extension_spec.rb index ddfeb9ef..c35bd04c 100644 --- a/spec/extensions/guardian_extension_spec.rb +++ b/spec/extensions/guardian_extension_spec.rb @@ -33,6 +33,7 @@ describe ::Guardian do end before do + stub_out_subscription_classes CustomWizard::Template.save(wizard_template, skip_jobs: true) @template = CustomWizard::Template.find('super_mega_fun_wizard') end diff --git a/spec/extensions/invites_controller_spec.rb b/spec/extensions/invites_controller_spec.rb index 99c3b402..ff57ae7d 100644 --- a/spec/extensions/invites_controller_spec.rb +++ b/spec/extensions/invites_controller_spec.rb @@ -6,6 +6,7 @@ describe InvitesControllerCustomWizard, type: :request do let(:template) { get_wizard_fixture("wizard") } before do + stub_out_subscription_classes @controller = InvitesController.new end diff --git a/spec/extensions/users_controller_spec.rb b/spec/extensions/users_controller_spec.rb index a28dc08e..6f9185af 100644 --- a/spec/extensions/users_controller_spec.rb +++ b/spec/extensions/users_controller_spec.rb @@ -4,6 +4,7 @@ describe CustomWizardUsersController, type: :request do let(:template) { get_wizard_fixture("wizard") } before do + stub_out_subscription_classes @controller = UsersController.new end diff --git a/spec/fixtures/subscription_client.rb b/spec/fixtures/subscription_client.rb index acadbe8f..03b88101 100644 --- a/spec/fixtures/subscription_client.rb +++ b/spec/fixtures/subscription_client.rb @@ -5,7 +5,7 @@ module DiscourseSubscriptionClient end end -class SubscriptionClientSupplier +SubscriptionClientSupplier = Class.new Object do attr_reader :product_slugs def initialize(product_slugs) @@ -13,10 +13,10 @@ class SubscriptionClientSupplier end end -class SubscriptionClientResource +SubscriptionClientResource = Class.new Object do end -class SubscriptionClientSubscription +SubscriptionClientSubscription = Class.new Object do attr_reader :product_id def initialize(product_id) diff --git a/spec/plugin_helper.rb b/spec/plugin_helper.rb index 53b7173c..436fefcd 100644 --- a/spec/plugin_helper.rb +++ b/spec/plugin_helper.rb @@ -9,11 +9,13 @@ def get_wizard_fixture(path) end def enable_subscription(type) + stub_out_subscription_classes CustomWizard::Subscription.stubs("#{type}?".to_sym).returns(true) CustomWizard::Subscription.any_instance.stubs("#{type}?".to_sym).returns(true) end def disable_subscriptions + stub_out_subscription_classes %w[ standard business @@ -24,11 +26,11 @@ def disable_subscriptions end end -def undefine_client_classes +def unstub_out_subscription_classes Object.send(:remove_const, :DiscourseSubscriptionClient) if Object.constants.include?(:DiscourseSubscriptionClient) Object.send(:remove_const, :SubscriptionClientSubscription) if Object.constants.include?(:SubscriptionClientSubscription) end -def define_client_classes +def stub_out_subscription_classes load File.expand_path("#{Rails.root}/plugins/discourse-custom-wizard/spec/fixtures/subscription_client.rb", __FILE__) end diff --git a/spec/requests/custom_wizard/admin/api_controller_spec.rb b/spec/requests/custom_wizard/admin/api_controller_spec.rb index f95681f8..a6e5df7e 100644 --- a/spec/requests/custom_wizard/admin/api_controller_spec.rb +++ b/spec/requests/custom_wizard/admin/api_controller_spec.rb @@ -5,6 +5,7 @@ describe CustomWizard::AdminApiController do let(:api_json) { get_wizard_fixture("api/api") } before do + stub_out_subscription_classes sign_in(admin_user) end diff --git a/spec/requests/custom_wizard/admin/custom_fields_controller_spec.rb b/spec/requests/custom_wizard/admin/custom_fields_controller_spec.rb index 7aef791c..dc6de785 100644 --- a/spec/requests/custom_wizard/admin/custom_fields_controller_spec.rb +++ b/spec/requests/custom_wizard/admin/custom_fields_controller_spec.rb @@ -5,6 +5,7 @@ describe CustomWizard::AdminCustomFieldsController do let(:custom_field_json) { get_wizard_fixture("custom_field/custom_fields") } before do + stub_out_subscription_classes custom_field_json['custom_fields'].each do |field_json| CustomWizard::CustomField.new(nil, field_json).save end diff --git a/spec/requests/custom_wizard/admin/logs_controller_spec.rb b/spec/requests/custom_wizard/admin/logs_controller_spec.rb index b67907a4..91846d7f 100644 --- a/spec/requests/custom_wizard/admin/logs_controller_spec.rb +++ b/spec/requests/custom_wizard/admin/logs_controller_spec.rb @@ -5,6 +5,7 @@ describe CustomWizard::AdminLogsController do let(:template) { get_wizard_fixture("wizard") } before do + stub_out_subscription_classes ["first", "second", "third"].each_with_index do |key, index| temp = template.dup temp["id"] = "#{key}_test_wizard" diff --git a/spec/requests/custom_wizard/admin/manager_controller_spec.rb b/spec/requests/custom_wizard/admin/manager_controller_spec.rb index c5282db6..bbbfafb9 100644 --- a/spec/requests/custom_wizard/admin/manager_controller_spec.rb +++ b/spec/requests/custom_wizard/admin/manager_controller_spec.rb @@ -5,6 +5,7 @@ describe CustomWizard::AdminManagerController do let(:template) { get_wizard_fixture("wizard") } before do + stub_out_subscription_classes sign_in(admin_user) template_2 = template.dup diff --git a/spec/requests/custom_wizard/admin/admin_controller_spec.rb b/spec/requests/custom_wizard/admin/subscription_controller_spec.rb similarity index 73% rename from spec/requests/custom_wizard/admin/admin_controller_spec.rb rename to spec/requests/custom_wizard/admin/subscription_controller_spec.rb index 877f4262..7be33f32 100644 --- a/spec/requests/custom_wizard/admin/admin_controller_spec.rb +++ b/spec/requests/custom_wizard/admin/subscription_controller_spec.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -describe CustomWizard::AdminController do +describe CustomWizard::SubscriptionController do fab!(:admin_user) { Fabricate(:user, admin: true) } it "requires an admin" do @@ -16,28 +16,26 @@ describe CustomWizard::AdminController do context "without a subscription" do before do disable_subscriptions - define_client_classes + stub_out_subscription_classes end it "returns the right subscription details" do - get "/admin/wizards.json" + get "/admin/wizards/subscription.json" expect(response.parsed_body["subscribed"]).to eq(false) expect(response.parsed_body["subscription_attributes"]).to eq(CustomWizard::Subscription.attributes.as_json) - expect(response.parsed_body["subscription_client_installed"]).to eq(true) end end context "with a subscription" do before do enable_subscription("standard") - define_client_classes + stub_out_subscription_classes end it "returns the right subscription details" do - get "/admin/wizards.json" + get "/admin/wizards/subscription.json" expect(response.parsed_body["subscribed"]).to eq(true) expect(response.parsed_body["subscription_type"]).to eq("standard") - expect(response.parsed_body["subscription_client_installed"]).to eq(true) end end end diff --git a/spec/requests/custom_wizard/admin/wizard_controller_spec.rb b/spec/requests/custom_wizard/admin/wizard_controller_spec.rb index c94007e2..9690fbc7 100644 --- a/spec/requests/custom_wizard/admin/wizard_controller_spec.rb +++ b/spec/requests/custom_wizard/admin/wizard_controller_spec.rb @@ -8,9 +8,8 @@ describe CustomWizard::AdminWizardController do let(:category) { Fabricate(:category, custom_fields: { create_topic_wizard: template['name'].parameterize(separator: "_") }) } before do - CustomWizard::Template.save(template, skip_jobs: true) enable_subscription("standard") - + CustomWizard::Template.save(template, skip_jobs: true) template_2 = template.dup template_2["id"] = 'super_mega_fun_wizard_2' template_2["permitted"] = template_2['permitted'] diff --git a/spec/requests/custom_wizard/application_controller_spec.rb b/spec/requests/custom_wizard/application_controller_spec.rb index 1eb1b857..1df3442b 100644 --- a/spec/requests/custom_wizard/application_controller_spec.rb +++ b/spec/requests/custom_wizard/application_controller_spec.rb @@ -5,6 +5,7 @@ describe ApplicationController do let(:wizard_template) { get_wizard_fixture("wizard") } before do + stub_out_subscription_classes CustomWizard::Template.save(wizard_template, skip_jobs: true) @template = CustomWizard::Template.find('super_mega_fun_wizard') end diff --git a/spec/requests/custom_wizard/custom_field_extensions_spec.rb b/spec/requests/custom_wizard/custom_field_extensions_spec.rb index 44556ef1..6b8afedb 100644 --- a/spec/requests/custom_wizard/custom_field_extensions_spec.rb +++ b/spec/requests/custom_wizard/custom_field_extensions_spec.rb @@ -10,6 +10,7 @@ describe "custom field extensions" do let(:subscription_custom_field_json) { get_wizard_fixture("custom_field/subscription_custom_fields") } before do + stub_out_subscription_classes custom_field_json['custom_fields'].each do |field_json| custom_field = CustomWizard::CustomField.new(nil, field_json) custom_field.save diff --git a/spec/requests/custom_wizard/steps_controller_spec.rb b/spec/requests/custom_wizard/steps_controller_spec.rb index 4d8b96eb..953f1149 100644 --- a/spec/requests/custom_wizard/steps_controller_spec.rb +++ b/spec/requests/custom_wizard/steps_controller_spec.rb @@ -11,6 +11,7 @@ describe CustomWizard::StepsController do let(:guests_permitted) { get_wizard_fixture("wizard/guests_permitted") } before do + stub_out_subscription_classes CustomWizard::Template.save(wizard_template, skip_jobs: true) end diff --git a/spec/requests/custom_wizard/wizard_controller_spec.rb b/spec/requests/custom_wizard/wizard_controller_spec.rb index 93ec196b..5a073e7d 100644 --- a/spec/requests/custom_wizard/wizard_controller_spec.rb +++ b/spec/requests/custom_wizard/wizard_controller_spec.rb @@ -6,6 +6,7 @@ describe CustomWizard::WizardController do let(:permitted_json) { get_wizard_fixture("wizard/permitted") } before do + stub_out_subscription_classes CustomWizard::Template.save(wizard_template, skip_jobs: true) @template = CustomWizard::Template.find("super_mega_fun_wizard") end diff --git a/spec/serializers/custom_wizard/basic_wizard_serializer_spec.rb b/spec/serializers/custom_wizard/basic_wizard_serializer_spec.rb index 4a2f353a..ea4e4568 100644 --- a/spec/serializers/custom_wizard/basic_wizard_serializer_spec.rb +++ b/spec/serializers/custom_wizard/basic_wizard_serializer_spec.rb @@ -4,6 +4,10 @@ describe CustomWizard::BasicWizardSerializer do fab!(:user) { Fabricate(:user) } let(:template) { get_wizard_fixture("wizard") } + before do + stub_out_subscription_classes + end + it 'should return basic wizard attributes' do CustomWizard::Template.save(template, skip_jobs: true) json = CustomWizard::BasicWizardSerializer.new( diff --git a/spec/serializers/custom_wizard/custom_field_serializer_spec.rb b/spec/serializers/custom_wizard/custom_field_serializer_spec.rb index 1da62245..490b4775 100644 --- a/spec/serializers/custom_wizard/custom_field_serializer_spec.rb +++ b/spec/serializers/custom_wizard/custom_field_serializer_spec.rb @@ -4,6 +4,10 @@ describe CustomWizard::CustomFieldSerializer do fab!(:user) { Fabricate(:user) } let(:custom_field_json) { get_wizard_fixture("custom_field/custom_fields") } + before do + stub_out_subscription_classes + end + it 'should return custom field attributes' do custom_field_json['custom_fields'].each do |field_json| CustomWizard::CustomField.new(nil, field_json).save diff --git a/spec/serializers/custom_wizard/submission_serializer_spec.rb b/spec/serializers/custom_wizard/submission_serializer_spec.rb index fc2c46a2..0548f381 100644 --- a/spec/serializers/custom_wizard/submission_serializer_spec.rb +++ b/spec/serializers/custom_wizard/submission_serializer_spec.rb @@ -13,6 +13,7 @@ describe CustomWizard::SubmissionSerializer do } before do + stub_out_subscription_classes CustomWizard::Template.save(template_json, skip_jobs: true) wizard = CustomWizard::Wizard.create(template_json["id"], user1) diff --git a/spec/serializers/custom_wizard/wizard_field_serializer_spec.rb b/spec/serializers/custom_wizard/wizard_field_serializer_spec.rb index 0568f898..be883e6b 100644 --- a/spec/serializers/custom_wizard/wizard_field_serializer_spec.rb +++ b/spec/serializers/custom_wizard/wizard_field_serializer_spec.rb @@ -5,6 +5,7 @@ describe CustomWizard::FieldSerializer do let(:template) { get_wizard_fixture("wizard") } before do + stub_out_subscription_classes CustomWizard::Template.save(template, skip_jobs: true) @wizard = CustomWizard::Builder.new("super_mega_fun_wizard", user).build end diff --git a/spec/serializers/custom_wizard/wizard_serializer_spec.rb b/spec/serializers/custom_wizard/wizard_serializer_spec.rb index aa1d82f2..3a39827c 100644 --- a/spec/serializers/custom_wizard/wizard_serializer_spec.rb +++ b/spec/serializers/custom_wizard/wizard_serializer_spec.rb @@ -8,6 +8,7 @@ describe CustomWizard::WizardSerializer do let(:advanced_fields) { get_wizard_fixture("field/advanced_types") } before do + stub_out_subscription_classes CustomWizard::Template.save(template, skip_jobs: true) @template = CustomWizard::Template.find('super_mega_fun_wizard') end diff --git a/spec/serializers/custom_wizard/wizard_step_serializer_spec.rb b/spec/serializers/custom_wizard/wizard_step_serializer_spec.rb index 2c28479c..4bcc6718 100644 --- a/spec/serializers/custom_wizard/wizard_step_serializer_spec.rb +++ b/spec/serializers/custom_wizard/wizard_step_serializer_spec.rb @@ -6,6 +6,7 @@ describe CustomWizard::StepSerializer do let(:required_data_json) { get_wizard_fixture("step/required_data") } before do + stub_out_subscription_classes CustomWizard::Template.save(wizard_template, skip_jobs: true) @wizard = CustomWizard::Builder.new("super_mega_fun_wizard", user).build end diff --git a/assets/javascripts/discourse/templates/components/wizard-subscription-badge.hbs b/svg-icons/plugin-icons.svg similarity index 57% rename from assets/javascripts/discourse/templates/components/wizard-subscription-badge.hbs rename to svg-icons/plugin-icons.svg index baba957c..f456dbca 100644 --- a/assets/javascripts/discourse/templates/components/wizard-subscription-badge.hbs +++ b/svg-icons/plugin-icons.svg @@ -1,24 +1,18 @@ + - - -{{label}} \ No newline at end of file + + \ No newline at end of file diff --git a/test/javascripts/acceptance/admin-custom-fields-unsubscribed-test.js b/test/javascripts/acceptance/admin-custom-fields-unsubscribed-test.js index fbfa2314..80e80773 100644 --- a/test/javascripts/acceptance/admin-custom-fields-unsubscribed-test.js +++ b/test/javascripts/acceptance/admin-custom-fields-unsubscribed-test.js @@ -8,6 +8,7 @@ import { click, fillIn, findAll, visit, waitUntil } from "@ember/test-helpers"; import selectKit from "discourse/tests/helpers/select-kit-helper"; import { getCustomFields, + getSuppliers, getUnsubscribedAdminWizards, getWizard, } from "../helpers/admin-wizard"; @@ -24,7 +25,7 @@ acceptance("Admin | Custom Fields Unsubscribed", function (needs) { server.get("/admin/wizards/wizard", () => { return helper.response(getWizard); }); - server.get("/admin/wizards", () => { + server.get("/admin/wizards/subscription", () => { return helper.response(getUnsubscribedAdminWizards); }); server.get("/admin/wizards/custom-fields", () => { @@ -36,6 +37,9 @@ acceptance("Admin | Custom Fields Unsubscribed", function (needs) { server.delete("/admin/wizards/custom-fields/topic_custom_field", () => { return helper.response({ success: "OK" }); }); + server.get("/admin/plugins/subscription-client/suppliers", () => { + return helper.response(getSuppliers); + }); }); async function selectTypeAndSerializerAndFillInName( diff --git a/test/javascripts/acceptance/admin-logs-test.js b/test/javascripts/acceptance/admin-logs-test.js index c888a55a..0b82e93a 100644 --- a/test/javascripts/acceptance/admin-logs-test.js +++ b/test/javascripts/acceptance/admin-logs-test.js @@ -3,6 +3,7 @@ import { test } from "qunit"; import { click, findAll, visit } from "@ember/test-helpers"; import selectKit from "discourse/tests/helpers/select-kit-helper"; import { + getSuppliers, getUnsubscribedAdminWizards, getWizard, getWizardTestingLog, @@ -23,12 +24,15 @@ acceptance("Admin | Logs", function (needs) { server.get("/admin/wizards/logs/this_is_testing_wizard", () => { return helper.response(getWizardTestingLog); }); - server.get("/admin/wizards", () => { + server.get("/admin/wizards/subscription", () => { return helper.response(getUnsubscribedAdminWizards); }); server.get("/admin/wizards/wizard", () => { return helper.response(getWizard); }); + server.get("/admin/plugins/subscription-client/suppliers", () => { + return helper.response(getSuppliers); + }); }); test("viewing logs fields tab", async (assert) => { await visit("/admin/wizards/logs"); diff --git a/test/javascripts/acceptance/admin-manager-test.js b/test/javascripts/acceptance/admin-manager-test.js index 4ce1c0bf..a50c9820 100644 --- a/test/javascripts/acceptance/admin-manager-test.js +++ b/test/javascripts/acceptance/admin-manager-test.js @@ -2,6 +2,7 @@ import { acceptance, query } from "discourse/tests/helpers/qunit-helpers"; import { test } from "qunit"; import { click, find, findAll, visit, waitUntil } from "@ember/test-helpers"; import { + getSuppliers, getUnsubscribedAdminWizards, getWizard, getWizardTestingLog, @@ -18,7 +19,7 @@ acceptance("Admin | Manager", function (needs) { server.get("/admin/wizards/manager/this_is_testing_wizard", () => { return helper.response(getWizardTestingLog); }); - server.get("/admin/wizards", () => { + server.get("/admin/wizards/subscription", () => { return helper.response(getUnsubscribedAdminWizards); }); server.get("/admin/wizards/wizard", () => { @@ -33,6 +34,9 @@ acceptance("Admin | Manager", function (needs) { failures: [], }); }); + server.get("/admin/plugins/subscription-client/suppliers", () => { + return helper.response(getSuppliers); + }); }); async function waitForDestructionAndResetMessage() { await waitUntil( diff --git a/test/javascripts/acceptance/admin-submissions-test.js b/test/javascripts/acceptance/admin-submissions-test.js index 50635a37..828decb7 100644 --- a/test/javascripts/acceptance/admin-submissions-test.js +++ b/test/javascripts/acceptance/admin-submissions-test.js @@ -4,6 +4,7 @@ import { click, findAll, visit } from "@ember/test-helpers"; import selectKit from "discourse/tests/helpers/select-kit-helper"; import { getAnotherWizardSubmission, + getSuppliers, getUnsubscribedAdminWizards, getWizard, getWizardSubmissions, @@ -28,12 +29,15 @@ acceptance("Admin | Submissions", function (needs) { server.get("/admin/wizards/submissions/another_wizard", () => { return helper.response(getAnotherWizardSubmission); }); - server.get("/admin/wizards", () => { + server.get("/admin/wizards/subscription", () => { return helper.response(getUnsubscribedAdminWizards); }); server.get("/admin/wizards/wizard", () => { return helper.response(getWizard); }); + server.get("/admin/plugins/subscription-client/suppliers", () => { + return helper.response(getSuppliers); + }); }); test("View submissions fields tab and content", async (assert) => { await visit("/admin/wizards/submissions"); diff --git a/test/javascripts/acceptance/admin-wizards-api-test.js b/test/javascripts/acceptance/admin-wizards-api-test.js index 80fb1014..d3afc1f8 100644 --- a/test/javascripts/acceptance/admin-wizards-api-test.js +++ b/test/javascripts/acceptance/admin-wizards-api-test.js @@ -6,6 +6,7 @@ import { getBusinessAdminWizard, getCustomFields, getNewApi, + getSuppliers, getWizard, putNewApi, } from "../helpers/admin-wizard"; @@ -21,7 +22,7 @@ acceptance("Admin | API tab", function (needs) { server.get("/admin/wizards/wizard", () => { return helper.response(getWizard); }); - server.get("/admin/wizards", () => { + server.get("/admin/wizards/subscription", () => { return helper.response(getBusinessAdminWizard); }); server.get("/admin/wizards/custom-fields", () => { @@ -45,6 +46,9 @@ acceptance("Admin | API tab", function (needs) { server.get("/admin/wizards/api/new_api", () => { return helper.response(getNewApi); }); + server.get("/admin/plugins/subscription-client/suppliers", () => { + return helper.response(getSuppliers); + }); }); test("Visit API tab and fill data", async function (assert) { diff --git a/test/javascripts/acceptance/admin-wizards-business-subscription-test.js b/test/javascripts/acceptance/admin-wizards-business-subscription-test.js index a3edc9bc..ea8cbac2 100644 --- a/test/javascripts/acceptance/admin-wizards-business-subscription-test.js +++ b/test/javascripts/acceptance/admin-wizards-business-subscription-test.js @@ -1,5 +1,6 @@ import { acceptance, + exists, query, visible, } from "discourse/tests/helpers/qunit-helpers"; @@ -11,6 +12,7 @@ import { getBusinessAdminWizard, getCreatedWizard, getCustomFields, + getSuppliersAuthorized, getWizard, } from "../helpers/admin-wizard"; @@ -28,7 +30,7 @@ acceptance("Admin | Custom Wizard Business Subscription", function (needs) { server.get("/admin/wizards/custom-fields", () => { return helper.response(getCustomFields); }); - server.get("/admin/wizards", () => { + server.get("/admin/wizards/subscription", () => { return helper.response(getBusinessAdminWizard); }); server.get("/admin/wizards/api", () => { @@ -49,6 +51,9 @@ acceptance("Admin | Custom Wizard Business Subscription", function (needs) { server.get("/admin/wizards/wizard/new_wizard_for_testing", () => { return helper.response(getCreatedWizard); }); + server.get("/admin/plugins/subscription-client/suppliers", () => { + return helper.response(getSuppliersAuthorized); + }); }); test("Displaying all tabs including API", async (assert) => { @@ -58,6 +63,22 @@ acceptance("Admin | Custom Wizard Business Subscription", function (needs) { assert.equal(count, 6, "There should be 6 admin tabs"); }); + test("shows authorized and subscribed", async (assert) => { + await visit("/admin/wizards"); + assert.notOk( + exists(".supplier-authorize .btn-primary:not(.update)"), + "the authorize button is shown." + ); + assert.strictEqual( + query("button.wizard-subscription-badge span").innerText.trim(), + "Business" + ); + assert.strictEqual( + query("button.btn-pavilion-support span").innerText.trim(), + "Support" + ); + }); + test("creating a new wizard", async (assert) => { await visit("/admin/wizards/wizard"); await click(".admin-wizard-controls button"); diff --git a/test/javascripts/acceptance/admin-wizards-standard-subscription-test.js b/test/javascripts/acceptance/admin-wizards-standard-subscription-test.js index 364ee26f..0670e703 100644 --- a/test/javascripts/acceptance/admin-wizards-standard-subscription-test.js +++ b/test/javascripts/acceptance/admin-wizards-standard-subscription-test.js @@ -1,5 +1,6 @@ import { acceptance, + exists, query, visible, } from "discourse/tests/helpers/qunit-helpers"; @@ -11,6 +12,7 @@ import { getCreatedWizard, getCustomFields, getStandardAdminWizard, + getSuppliersAuthorized, getWizard, } from "../helpers/admin-wizard"; @@ -28,7 +30,7 @@ acceptance("Admin | Custom Wizard Standard Subscription", function (needs) { server.get("/admin/wizards/custom-fields", () => { return helper.response(getCustomFields); }); - server.get("/admin/wizards", () => { + server.get("/admin/wizards/subscription", () => { return helper.response(getStandardAdminWizard); }); server.get("/admin/wizards/api", () => { @@ -49,6 +51,9 @@ acceptance("Admin | Custom Wizard Standard Subscription", function (needs) { server.get("/admin/wizards/wizard/new_wizard_for_testing", () => { return helper.response(getCreatedWizard); }); + server.get("/admin/plugins/subscription-client/suppliers", () => { + return helper.response(getSuppliersAuthorized); + }); }); test("Displaying all tabs except API", async (assert) => { @@ -58,6 +63,22 @@ acceptance("Admin | Custom Wizard Standard Subscription", function (needs) { assert.equal(count, 5, "There should be 5 admin tabs"); }); + test("shows authorized and subscribed", async (assert) => { + await visit("/admin/wizards"); + assert.notOk( + exists(".supplier-authorize .btn-primary:not(.update)"), + "the authorize button not shown." + ); + assert.strictEqual( + query("button.wizard-subscription-badge span").innerText.trim(), + "Standard" + ); + assert.strictEqual( + query("button.btn-pavilion-support span").innerText.trim(), + "Support" + ); + }); + test("creating a new wizard", async (assert) => { await visit("/admin/wizards/wizard"); await click(".admin-wizard-controls button"); diff --git a/test/javascripts/acceptance/admin-wizards-unsuscribed-test.js b/test/javascripts/acceptance/admin-wizards-unsubscribed-test.js similarity index 93% rename from test/javascripts/acceptance/admin-wizards-unsuscribed-test.js rename to test/javascripts/acceptance/admin-wizards-unsubscribed-test.js index 52d70e69..52038d5e 100644 --- a/test/javascripts/acceptance/admin-wizards-unsuscribed-test.js +++ b/test/javascripts/acceptance/admin-wizards-unsubscribed-test.js @@ -11,6 +11,7 @@ import { getAdminTestingWizard, getCreatedWizard, getCustomFields, + getSuppliers, getUniqueWizard, getUnsubscribedAdminWizards, getWizard, @@ -30,7 +31,7 @@ acceptance("Admin | Custom Wizard Unsubscribed", function (needs) { server.get("/admin/wizards/custom-fields", () => { return helper.response(getCustomFields); }); - server.get("/admin/wizards", () => { + server.get("/admin/wizards/subscription", () => { return helper.response(getUnsubscribedAdminWizards); }); server.get("/admin/wizards/api", () => { @@ -54,6 +55,9 @@ acceptance("Admin | Custom Wizard Unsubscribed", function (needs) { server.get("/admin/wizards/wizard/unique_wizard", () => { return helper.response(getUniqueWizard); }); + server.get("/admin/plugins/subscription-client/suppliers", () => { + return helper.response(getSuppliers); + }); }); async function appendText(selector, text) { @@ -72,6 +76,22 @@ acceptance("Admin | Custom Wizard Unsubscribed", function (needs) { assert.equal(count, 5, "There should be 5 admin tabs"); }); + test("shows unauthorized and unsubscribed", async (assert) => { + await visit("/admin/wizards"); + assert.ok( + exists(".supplier-authorize .btn-primary"), + "the authorize button is shown." + ); + assert.strictEqual( + query("button.wizard-subscription-badge span").innerText.trim(), + "Not Subscribed" + ); + assert.strictEqual( + query("button.btn-pavilion-support span").innerText.trim(), + "Get a Subscription" + ); + }); + test("creating a new wizard", async (assert) => { await visit("/admin/wizards/wizard"); await click(".admin-wizard-controls button"); @@ -240,11 +260,14 @@ acceptance("Admin | Custom Wizard Unsubscribed", function (needs) { await click( ".wizard-custom-step .wizard-text-editor .d-editor button.link" ); - assert.ok(exists(".insert-link.modal-body"), "hyperlink modal visible"); + assert.ok( + exists(".d-modal.insert-hyperlink-modal"), + "hyperlink modal visible" + ); - await fillIn(".modal-body .link-url", "google.com"); - await fillIn(".modal-body .link-text", "Google"); - await click(".modal-footer button.btn-primary"); + await fillIn(".d-modal__body.insert-link .inputs .link-url", "google.com"); + await fillIn(".d-modal__body.insert-link .inputs .link-text", "Google"); + await click(".d-modal__footer button.btn-primary"); let urlText = await query( ".wizard-custom-step .wizard-text-editor .d-editor-preview-wrapper a" ).innerHTML.trim(); @@ -256,24 +279,26 @@ acceptance("Admin | Custom Wizard Unsubscribed", function (needs) { await click( ".wizard-custom-step .wizard-text-editor .d-editor button.local-dates" ); + assert.ok( - exists(".discourse-local-dates-create-modal .modal-body"), + exists(".d-modal.discourse-local-dates-create-modal"), "Insert date-time modal visible" ); + assert.ok( !exists( - ".discourse-local-dates-create-modal.modal-body .advanced-options" + ".discourse-local-dates-create-modal .d-modal__body .advanced-options" ), "Advanced mode not visible" ); - await click(".modal-footer button.advanced-mode-btn"); + await click(".d-modal__footer button.advanced-mode-btn"); assert.ok( exists( - ".discourse-local-dates-create-modal .modal-body .advanced-options" + ".discourse-local-dates-create-modal .d-modal__body .advanced-options" ), "Advanced mode is visible" ); - await click(".modal-footer button.btn-primary"); + await click(".d-modal__footer button.btn-primary"); assert.ok( exists( ".wizard-custom-step .wizard-text-editor .d-editor-preview-wrapper span.discourse-local-date" diff --git a/test/javascripts/acceptance/field-test.js b/test/javascripts/acceptance/field-test.js index f1d97130..67ef8c38 100644 --- a/test/javascripts/acceptance/field-test.js +++ b/test/javascripts/acceptance/field-test.js @@ -68,17 +68,20 @@ acceptance("Field | Fields", function (needs) { "This is a link to " ); assert.ok( - !exists(".insert-link.modal-body"), + !exists(".d-modal.insert-hyperlink-modal"), "no hyperlink modal by default" ); await click( ".wizard-field.composer-field .wizard-field-composer .d-editor button.link" ); - assert.ok(exists(".insert-link.modal-body"), "hyperlink modal visible"); + assert.ok( + exists(".d-modal.insert-hyperlink-modal"), + "hyperlink modal visible" + ); - await fillIn(".modal-body .link-url", "google.com"); - await fillIn(".modal-body .link-text", "Google"); - await click(".modal-footer button.btn-primary"); + await fillIn(".d-modal__body.insert-link .inputs .link-url", "google.com"); + await fillIn(".d-modal__body.insert-link .inputs .link-text", "Google"); + await click(".d-modal__footer button.btn-primary"); assert.strictEqual( query(".wizard-field.composer-field .wizard-field-composer textarea") @@ -102,9 +105,9 @@ acceptance("Field | Fields", function (needs) { await click( ".wizard-field.composer-field .wizard-field-composer .d-editor button.link" ); - await fillIn(".modal-body .link-url", "google.com"); - await fillIn(".modal-body .link-text", "Google"); - await click(".modal-footer button.btn-danger"); + await fillIn(".d-modal__body.insert-link .inputs .link-url", "google.com"); + await fillIn(".d-modal__body.insert-link .inputs .link-text", "Google"); + await click(".d-modal__footer button.btn-danger"); assert.strictEqual( query(".wizard-field.composer-field .wizard-field-composer textarea") diff --git a/test/javascripts/helpers/admin-wizard.js b/test/javascripts/helpers/admin-wizard.js index 6c5dd84c..79eba3b7 100644 --- a/test/javascripts/helpers/admin-wizard.js +++ b/test/javascripts/helpers/admin-wizard.js @@ -224,7 +224,6 @@ const getUnsubscribedAdminWizards = { all: { none: [], standard: [], business: ["*"], community: ["*"] }, }, }, - subscription_client_installed: false, }; const getCustomFields = { custom_fields: [ @@ -478,7 +477,6 @@ const getBusinessAdminWizard = { all: { none: [], standard: [], business: ["*"], community: ["*"] }, }, }, - subscription_client_installed: false, }; const getStandardAdminWizard = { subscribed: true, @@ -589,7 +587,6 @@ const getStandardAdminWizard = { all: { none: [], standard: [], business: ["*"], community: ["*"] }, }, }, - subscription_client_installed: false, }; const getAdminTestingWizard = { id: "this_is_testing_wizard", @@ -917,6 +914,31 @@ const putNewApi = { log: [], }, }; + +const getSuppliers = { + suppliers: [ + { + id: 1, + name: "Pavilion", + authorized: false, + authorized_at: null, + user: null, + }, + ], +}; + +const getSuppliersAuthorized = { + suppliers: [ + { + id: 1, + name: "Pavilion", + authorized: true, + authorized_at: null, + user: null, + }, + ], +}; + export { getWizard, getUnsubscribedAdminWizards, @@ -931,4 +953,6 @@ export { putNewApi, getAnotherWizardSubmission, getUniqueWizard, + getSuppliers, + getSuppliersAuthorized, };