From c79dee3d1653da818f1835c2e361ac95f5bcbdb8 Mon Sep 17 00:00:00 2001 From: Angus McLeod Date: Fri, 23 Sep 2022 15:52:05 +0200 Subject: [PATCH] Add community subscription as an explicit type --- .rubocop.yml | 6 ++ .../wizard-subscription-badge.js.es6 | 2 +- .../wizard-subscription-container.js.es6 | 4 +- .../components/wizard-subscription-cta.js.es6 | 34 +++++++++++ .../wizard-subscription-selector.js.es6 | 47 +++++++-------- .../controllers/admin-wizards.js.es6 | 4 +- .../discourse/lib/wizard-subscription.js.es6 | 22 ------- .../discourse/mixins/subscription.js.es6 | 18 +++++- .../admin-wizards-submissions-show.js.es6 | 1 - .../discourse/templates/admin-wizards.hbs | 10 ++-- .../wizard-subscription-container.hbs | 2 +- .../components/wizard-subscription-cta.hbs | 1 + .../wizard-subscription-selector-header.hbs | 6 +- .../wizard-subscription-selector-row.hbs | 6 +- assets/stylesheets/common/admin.scss | 8 ++- .../stylesheets/common/admin/variables.scss | 2 + config/locales/client.en.yml | 18 ++++-- lib/custom_wizard/subscription.rb | 57 +++++++++++++------ .../custom_wizard/submission_spec.rb | 2 +- .../custom_wizard/subscription_spec.rb | 16 +++++- 20 files changed, 176 insertions(+), 90 deletions(-) create mode 100644 assets/javascripts/discourse/components/wizard-subscription-cta.js.es6 delete mode 100644 assets/javascripts/discourse/lib/wizard-subscription.js.es6 create mode 100644 assets/javascripts/discourse/templates/components/wizard-subscription-cta.hbs diff --git a/.rubocop.yml b/.rubocop.yml index d46296cf..69fcfc56 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,2 +1,8 @@ inherit_gem: rubocop-discourse: default.yml + +RSpec/ContextWording: + Enabled: false + +RSpec/DescribeClass: + Enabled: false diff --git a/assets/javascripts/discourse/components/wizard-subscription-badge.js.es6 b/assets/javascripts/discourse/components/wizard-subscription-badge.js.es6 index 87c985a4..301c618e 100644 --- a/assets/javascripts/discourse/components/wizard-subscription-badge.js.es6 +++ b/assets/javascripts/discourse/components/wizard-subscription-badge.js.es6 @@ -11,7 +11,7 @@ export default Component.extend(Subscription, { @discourseComputed("subscriptionType") i18nKey(type) { - return `admin.wizard.subscription_container.type.${type ? type : "none"}`; + return `admin.wizard.subscription.type.${type ? type : "none"}`; }, @discourseComputed("i18nKey") diff --git a/assets/javascripts/discourse/components/wizard-subscription-container.js.es6 b/assets/javascripts/discourse/components/wizard-subscription-container.js.es6 index ccaf2f48..5cc6b17c 100644 --- a/assets/javascripts/discourse/components/wizard-subscription-container.js.es6 +++ b/assets/javascripts/discourse/components/wizard-subscription-container.js.es6 @@ -12,14 +12,14 @@ export default Component.extend(Subscription, { @discourseComputed("subscribed") subscribedLabel(subscribed) { - return `admin.wizard.subscription_container.${ + return `admin.wizard.subscription.${ subscribed ? "subscribed" : "not_subscribed" }.label`; }, @discourseComputed("subscribed") subscribedTitle(subscribed) { - return `admin.wizard.subscription_container.${ + return `admin.wizard.subscription.${ subscribed ? "subscribed" : "not_subscribed" }.title`; }, diff --git a/assets/javascripts/discourse/components/wizard-subscription-cta.js.es6 b/assets/javascripts/discourse/components/wizard-subscription-cta.js.es6 new file mode 100644 index 00000000..4fb3002b --- /dev/null +++ b/assets/javascripts/discourse/components/wizard-subscription-cta.js.es6 @@ -0,0 +1,34 @@ +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 8ef6896a..06f705b3 100644 --- a/assets/javascripts/discourse/components/wizard-subscription-selector.js.es6 +++ b/assets/javascripts/discourse/components/wizard-subscription-selector.js.es6 @@ -1,10 +1,6 @@ import SingleSelectComponent from "select-kit/components/single-select"; import Subscription from "../mixins/subscription"; import wizardSchema from "discourse/plugins/discourse-custom-wizard/discourse/lib/wizard-schema"; -import { - subscriptionTypeSufficient, - subscriptionTypes, -} from "discourse/plugins/discourse-custom-wizard/discourse/lib/wizard-subscription"; import discourseComputed from "discourse-common/utils/decorators"; import I18n from "I18n"; @@ -29,45 +25,50 @@ export default SingleSelectComponent.extend(Subscription, { caretDownIcon: "caret-down", }, - requiredSubscriptionType(feature, attribute, value) { + allowedSubscriptionTypes(feature, attribute, value) { let attributes = this.subscriptionAttributes[feature]; if (!attributes || !attributes[attribute]) { - return null; + return ['none']; } - - let requiredType = null; - Object.keys(attributes[attribute]).some((subscriptionType) => { + let allowedTypes = []; + Object.keys(attributes[attribute]).forEach((subscriptionType) => { let values = attributes[attribute][subscriptionType]; if (values[0] === "*" || values.includes(value)) { - if (subscriptionTypes.includes(subscriptionType)) { - requiredType = subscriptionType; - } - return true; + allowedTypes.push(subscriptionType); } - return false; }); - - return requiredType; + return allowedTypes; }, @discourseComputed("feature", "attribute") content(feature, attribute) { return wizardSchema[feature][attribute] .map((value) => { - let requiredSubscriptionType = this.requiredSubscriptionType( + let allowedSubscriptionTypes = this.allowedSubscriptionTypes( feature, attribute, value ); - return { + + let subscriptionRequired = allowedSubscriptionTypes.length && + !allowedSubscriptionTypes.includes('none'); + + let attrs = { id: value, name: I18n.t(nameKey(feature, attribute, value)), - subscriptionType: requiredSubscriptionType, - disabled: !subscriptionTypeSufficient( - this.subscriptionType, - requiredSubscriptionType - ), + subscriptionRequired }; + + if (subscriptionRequired) { + let subscribed = allowedSubscriptionTypes.includes(this.subscriptionType); + let selectorKey = subscribed ? "subscribed" : "not_subscribed"; + let selectorLabel = `admin.wizard.subscription.${selectorKey}.selector`; + + attrs.disabled = !subscribed; + attrs.selectorLabel = selectorLabel; + } + + return attrs; }) .sort(function (a, b) { if (a.subscriptionType && !b.subscriptionType) { diff --git a/assets/javascripts/discourse/controllers/admin-wizards.js.es6 b/assets/javascripts/discourse/controllers/admin-wizards.js.es6 index f99c06cc..15c6ea85 100644 --- a/assets/javascripts/discourse/controllers/admin-wizards.js.es6 +++ b/assets/javascripts/discourse/controllers/admin-wizards.js.es6 @@ -1,7 +1,9 @@ import Controller from "@ember/controller"; -import { equal } from "@ember/object/computed"; +import { equal, or } from "@ember/object/computed"; export default Controller.extend({ businessSubscription: equal("subscriptionType", "business"), + communitySubscription: equal("subscriptionType", "community"), standardSubscription: equal("subscriptionType", "standard"), + showApi: or('businessSubscription', 'communitySubscription') }); diff --git a/assets/javascripts/discourse/lib/wizard-subscription.js.es6 b/assets/javascripts/discourse/lib/wizard-subscription.js.es6 deleted file mode 100644 index adecf063..00000000 --- a/assets/javascripts/discourse/lib/wizard-subscription.js.es6 +++ /dev/null @@ -1,22 +0,0 @@ -const subscriptionTypes = ["standard", "business"]; - -function subscriptionTypeSufficient(subscriptionType, requiredType) { - if (requiredType && !subscriptionType) { - return false; - } - if (requiredType === "none" || requiredType === null) { - return true; - } - if ( - requiredType === "standard" && - subscriptionTypes.includes(subscriptionType) - ) { - return true; - } - if (requiredType === "business" && subscriptionType === "business") { - return true; - } - return false; -} - -export { subscriptionTypeSufficient, subscriptionTypes }; diff --git a/assets/javascripts/discourse/mixins/subscription.js.es6 b/assets/javascripts/discourse/mixins/subscription.js.es6 index 574f8585..072b57e9 100644 --- a/assets/javascripts/discourse/mixins/subscription.js.es6 +++ b/assets/javascripts/discourse/mixins/subscription.js.es6 @@ -3,8 +3,12 @@ import { getOwner } from "discourse-common/lib/get-owner"; import { readOnly } from "@ember/object/computed"; import discourseComputed from "discourse-common/utils/decorators"; +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 Mixin.create({ - subscriptionLandingUrl: "https://custom-wizard.pavilion.tech", + subscriptionLandingUrl: PRODUCT_PAGE, subscriptionClientUrl: "/admin/plugins/subscription-client", @discourseComputed @@ -15,6 +19,7 @@ export default Mixin.create({ subscribed: readOnly("adminWizards.subscribed"), subscriptionType: readOnly("adminWizards.subscriptionType"), businessSubscription: readOnly("adminWizards.businessSubscription"), + communitySubscription: readOnly("adminWizards.communitySubscription"), standardSubscription: readOnly("adminWizards.standardSubscription"), subscriptionAttributes: readOnly("adminWizards.subscriptionAttributes"), subscriptionClientInstalled: readOnly( @@ -27,4 +32,15 @@ export default Mixin.create({ ? this.subscriptionClientUrl : this.subscriptionLandingUrl; }, + + @discourseComputed("subscriptionType") + subscriptionCtaLink(subscriptionType) { + switch (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/routes/admin-wizards-submissions-show.js.es6 b/assets/javascripts/discourse/routes/admin-wizards-submissions-show.js.es6 index 17b03e78..5a9d6046 100644 --- a/assets/javascripts/discourse/routes/admin-wizards-submissions-show.js.es6 +++ b/assets/javascripts/discourse/routes/admin-wizards-submissions-show.js.es6 @@ -2,7 +2,6 @@ import { A } from "@ember/array"; import EmberObject from "@ember/object"; import CustomWizardAdmin from "../models/custom-wizard-admin"; import DiscourseRoute from "discourse/routes/discourse"; -import CustomWizard from "../models/custom-wizard"; export default DiscourseRoute.extend({ model(params) { diff --git a/assets/javascripts/discourse/templates/admin-wizards.hbs b/assets/javascripts/discourse/templates/admin-wizards.hbs index 236444cd..cea77942 100644 --- a/assets/javascripts/discourse/templates/admin-wizards.hbs +++ b/assets/javascripts/discourse/templates/admin-wizards.hbs @@ -2,17 +2,15 @@ {{nav-item route="adminWizardsWizard" label="admin.wizard.nav_label"}} {{nav-item route="adminWizardsCustomFields" label="admin.wizard.custom_field.nav_label"}} {{nav-item route="adminWizardsSubmissions" label="admin.wizard.submissions.nav_label"}} - {{#if businessSubscription}} + {{#if showApi}} {{nav-item route="adminWizardsApi" label="admin.wizard.api.nav_label"}} {{/if}} {{nav-item route="adminWizardsLogs" label="admin.wizard.log.nav_label"}} {{nav-item route="adminWizardsManager" label="admin.wizard.manager.nav_label"}} -
- - - Custom Wizard Subscriptions Are Coming! - +
+ {{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 index 78be031f..01d436f5 100644 --- a/assets/javascripts/discourse/templates/components/wizard-subscription-container.hbs +++ b/assets/javascripts/discourse/templates/components/wizard-subscription-container.hbs @@ -1,5 +1,5 @@
-

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

+

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

{{d-icon subscribedIcon}} diff --git a/assets/javascripts/discourse/templates/components/wizard-subscription-cta.hbs b/assets/javascripts/discourse/templates/components/wizard-subscription-cta.hbs new file mode 100644 index 00000000..00569756 --- /dev/null +++ b/assets/javascripts/discourse/templates/components/wizard-subscription-cta.hbs @@ -0,0 +1 @@ +{{d-icon icon}}{{label}} diff --git a/assets/javascripts/discourse/templates/components/wizard-subscription-selector/wizard-subscription-selector-header.hbs b/assets/javascripts/discourse/templates/components/wizard-subscription-selector/wizard-subscription-selector-header.hbs index 708b0887..d91e90f1 100644 --- a/assets/javascripts/discourse/templates/components/wizard-subscription-selector/wizard-subscription-selector-header.hbs +++ b/assets/javascripts/discourse/templates/components/wizard-subscription-selector/wizard-subscription-selector-header.hbs @@ -7,10 +7,8 @@ shouldDisplayClearableButton=shouldDisplayClearableButton }} - {{#if selectedContent.subscriptionType}} - - {{selectedContent.subscriptionType}} - + {{#if subscriptionRequired}} + {{i18n selectorLabel}} {{/if}} {{d-icon caretIcon class="caret-icon"}} diff --git a/assets/javascripts/discourse/templates/components/wizard-subscription-selector/wizard-subscription-selector-row.hbs b/assets/javascripts/discourse/templates/components/wizard-subscription-selector/wizard-subscription-selector-row.hbs index 1db906e6..de24fd75 100644 --- a/assets/javascripts/discourse/templates/components/wizard-subscription-selector/wizard-subscription-selector-row.hbs +++ b/assets/javascripts/discourse/templates/components/wizard-subscription-selector/wizard-subscription-selector-row.hbs @@ -9,9 +9,7 @@
{{html-safe label}} - {{#if item.subscriptionType}} - - {{item.subscriptionType}} - + {{#if item.subscriptionRequired}} + {{i18n item.selectorLabel}} {{/if}}
diff --git a/assets/stylesheets/common/admin.scss b/assets/stylesheets/common/admin.scss index 43fe9b5c..9c23d498 100644 --- a/assets/stylesheets/common/admin.scss +++ b/assets/stylesheets/common/admin.scss @@ -841,7 +841,7 @@ $error: #ef1700; vertical-align: middle; } -.btn[href].btn-pavilion-support { +.btn.btn-pavilion-support { background: var(--pavilion-primary); color: var(--pavilion-secondary); @@ -920,6 +920,12 @@ $error: #ef1700; color: $secondary; } + &.community { + background-color: $subscription_community; + border: 1.5px solid $pavilion_primary; + color: $pavilion_primary; + } + .d-icon { margin-right: 0.75em; } diff --git a/assets/stylesheets/common/admin/variables.scss b/assets/stylesheets/common/admin/variables.scss index 9bb93798..33a67c2d 100644 --- a/assets/stylesheets/common/admin/variables.scss +++ b/assets/stylesheets/common/admin/variables.scss @@ -4,6 +4,7 @@ $pavilion_warning: rgb(243, 163, 61); $subscription_standard: $pavilion_primary; $subscription_business: #333; +$subscription_community: #fff; :root { --pavilion-primary: #{$pavilion_primary}; @@ -11,4 +12,5 @@ $subscription_business: #333; --pavilion-warning: #{$pavilion_warning}; --subscription-standard: #{$subscription_standard}; --subscription-business: #{$subscription_business}; + --subscription-community: #{$subscription_community}; } diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index 82f7da70..9b6efeae 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -129,9 +129,6 @@ en: edit_columns: "Edit Columns" expand_text: "Read More" collapse_text: "Show Less" - support_button: - title: "Request Support" - label: "Support" category_settings: custom_wizard: title: "Custom Wizard" @@ -535,14 +532,16 @@ en: destroy: Destroy destroyed: destroyed - subscription_container: + subscription: title: Subscriber Features subscribed: label: Subscribed title: You're subscribed and can use these features + selector: subscribed not_subscribed: label: Not Subscribed title: Subscribe to use these features + selector: not subscribed type: none: label: Not Subscribed @@ -553,6 +552,17 @@ en: standard: label: Standard title: There is a Custom Wizard Standard subscription active on this forum. + community: + label: Community + title: There is a Custom Wizard Community subscription active on this forum. + cta: + none: + label: Get a Subscription + title: Get a subscription for this forum. + subscribed: + label: Support + title: Get support for your subscription. + wizard_js: group: diff --git a/lib/custom_wizard/subscription.rb b/lib/custom_wizard/subscription.rb index 114f6743..06e8bd76 100644 --- a/lib/custom_wizard/subscription.rb +++ b/lib/custom_wizard/subscription.rb @@ -1,7 +1,8 @@ # frozen_string_literal: true class CustomWizard::Subscription - STANDARD_PRODUCT_ID = 'prod_LNAGVAaIqDsHmB' - BUSINESS_PRODUCT_ID = 'prod_LNABQ50maBQ1pY' + STANDARD_PRODUCT_ID = 'prod_MH11woVoZU5AWb' + BUSINESS_PRODUCT_ID = 'prod_MH0wT627okh3Ef' + COMMUNITY_PRODUCT_ID = 'prod_MU7l9EjxhaukZ7' def self.attributes { @@ -9,75 +10,88 @@ class CustomWizard::Subscription required: { none: [], standard: ['*'], - business: ['*'] + business: ['*'], + community: ['*'] }, permitted: { none: [], standard: ['*'], - business: ['*'] + business: ['*'], + community: ['*'] } }, step: { condition: { none: [], standard: ['*'], - business: ['*'] + business: ['*'], + community: ['*'] }, index: { none: [], standard: ['*'], - business: ['*'] + business: ['*'], + community: ['*'] }, required_data: { none: [], standard: ['*'], - business: ['*'] + business: ['*'], + community: ['*'] }, permitted_params: { none: [], standard: ['*'], - business: ['*'] + business: ['*'], + community: ['*'] } }, field: { condition: { none: [], standard: ['*'], - business: ['*'] + business: ['*'], + community: ['*'] }, index: { none: [], standard: ['*'], - business: ['*'] + business: ['*'], + community: ['*'] }, type: { none: ['text', 'textarea', 'text_only', 'date', 'time', 'date_time', 'number', 'checkbox', 'dropdown', 'upload'], standard: ['*'], - business: ['*'] + business: ['*'], + community: ['*'] }, realtime_validations: { none: [], standard: ['*'], - business: ['*'] + business: ['*'], + community: ['*'] } }, action: { type: { none: ['create_topic', 'update_profile', 'open_composer', 'route_to'], standard: ['create_topic', 'update_profile', 'open_composer', 'route_to', 'send_message', 'watch_categories', 'add_to_group'], - business: ['*'] + business: ['*'], + community: ['*'] } }, custom_field: { klass: { none: ['topic', 'post'], standard: ['topic', 'post'], - business: ['*'] + business: ['*'], + community: ['*'] }, type: { none: ['string', 'boolean', 'integer'], standard: ['string', 'boolean', 'integer'], - business: ['*'] + business: ['*'], + community: ['*'] } } } @@ -109,10 +123,11 @@ class CustomWizard::Subscription return :none unless subscribed? return :standard if standard? return :business if business? + return :community if community? end def subscribed? - standard? || business? + standard? || business? || community? end def standard? @@ -123,6 +138,10 @@ class CustomWizard::Subscription @subscription.product_id === BUSINESS_PRODUCT_ID end + def community? + @subscription.product_id === COMMUNITY_PRODUCT_ID + end + def client_installed? defined?(SubscriptionClient) == 'constant' && SubscriptionClient.class == Module end @@ -132,7 +151,7 @@ class CustomWizard::Subscription if client_installed? subscription = SubscriptionClientSubscription.active - .where(product_id: [STANDARD_PRODUCT_ID, BUSINESS_PRODUCT_ID]) + .where(product_id: [STANDARD_PRODUCT_ID, BUSINESS_PRODUCT_ID, COMMUNITY_PRODUCT_ID]) .order("product_id = '#{BUSINESS_PRODUCT_ID}' DESC") .first end @@ -152,6 +171,10 @@ class CustomWizard::Subscription new.business? end + def self.community? + new.community? + end + def self.standard? new.standard? end diff --git a/spec/components/custom_wizard/submission_spec.rb b/spec/components/custom_wizard/submission_spec.rb index 97732c7a..48459a08 100644 --- a/spec/components/custom_wizard/submission_spec.rb +++ b/spec/components/custom_wizard/submission_spec.rb @@ -17,7 +17,7 @@ describe CustomWizard::Submission do ).to eq("I am user submission") end - context "#list" do + describe "#list" do before do template_json_2 = template_json.dup template_json_2["id"] = "super_mega_fun_wizard_2" diff --git a/spec/components/custom_wizard/subscription_spec.rb b/spec/components/custom_wizard/subscription_spec.rb index 984eff9f..5f06397b 100644 --- a/spec/components/custom_wizard/subscription_spec.rb +++ b/spec/components/custom_wizard/subscription_spec.rb @@ -96,7 +96,21 @@ describe CustomWizard::Subscription do expect(described_class.type).to eq(:business) end - it "business are included" do + it "business features are included" do + expect(described_class.includes?(:action, :type, 'create_category')).to eq(true) + end + end + + context "with community subscription" do + before do + SubscriptionClientSubscription.stubs(:product_id).returns(CustomWizard::Subscription::COMMUNITY_PRODUCT_ID) + end + + it "detects community type" do + expect(described_class.type).to eq(:community) + end + + it "community features are included" do expect(described_class.includes?(:action, :type, 'create_category')).to eq(true) end end