From a662909246e94e32e4b774c17f59cde2a07f9be6 Mon Sep 17 00:00:00 2001 From: Aaron Christian Date: Fri, 9 Jun 2017 16:00:18 -0700 Subject: [PATCH] Created the wizard modules shell. --- .../modules/wizard/commerce_wizard.info.yml | 14 +++ .../modules/wizard/commerce_wizard.libraries.yml | 16 +++ .../modules/wizard/commerce_wizard.links.menu.yml | 6 + .../commerce/modules/wizard/commerce_wizard.module | 70 +++++++++++ .../modules/wizard/commerce_wizard.routing.yml | 15 +++ .../wizard/css/commerce_wizard.component.css | 69 +++++++++++ .../modules/wizard/css/commerce_wizard.layout.css | 10 ++ .../commerce/modules/wizard/js/commerce_wizard.js | 129 ++++++++++++++++++++ .../wizard/src/Controller/WizardController.php | 23 ++++ .../modules/wizard/src/Element/Stepper.php | 81 +++++++++++++ .../modules/wizard/src/Form/WizardForm.php | 131 +++++++++++++++++++++ .../wizard/templates/commerce-wizard.html.twig | 52 ++++++++ .../modules/wizard/templates/stepper.html.twig | 51 ++++++++ 13 files changed, 667 insertions(+) create mode 100644 modules/contrib/commerce/modules/wizard/commerce_wizard.info.yml create mode 100644 modules/contrib/commerce/modules/wizard/commerce_wizard.libraries.yml create mode 100644 modules/contrib/commerce/modules/wizard/commerce_wizard.links.menu.yml create mode 100644 modules/contrib/commerce/modules/wizard/commerce_wizard.module create mode 100644 modules/contrib/commerce/modules/wizard/commerce_wizard.routing.yml create mode 100644 modules/contrib/commerce/modules/wizard/css/commerce_wizard.component.css create mode 100644 modules/contrib/commerce/modules/wizard/css/commerce_wizard.layout.css create mode 100644 modules/contrib/commerce/modules/wizard/js/commerce_wizard.js create mode 100644 modules/contrib/commerce/modules/wizard/src/Controller/WizardController.php create mode 100644 modules/contrib/commerce/modules/wizard/src/Element/Stepper.php create mode 100644 modules/contrib/commerce/modules/wizard/src/Form/WizardForm.php create mode 100644 modules/contrib/commerce/modules/wizard/templates/commerce-wizard.html.twig create mode 100644 modules/contrib/commerce/modules/wizard/templates/stepper.html.twig diff --git a/modules/contrib/commerce/modules/wizard/commerce_wizard.info.yml b/modules/contrib/commerce/modules/wizard/commerce_wizard.info.yml new file mode 100644 index 0000000..01f118d --- /dev/null +++ b/modules/contrib/commerce/modules/wizard/commerce_wizard.info.yml @@ -0,0 +1,14 @@ +name: Commerce Wizard +type: module +description: 'Provides a quick installation method for drupal commerce.' +package: Commerce +dependencies: + - commerce +core: 8.x +project: 'commerce' + + + + + + diff --git a/modules/contrib/commerce/modules/wizard/commerce_wizard.libraries.yml b/modules/contrib/commerce/modules/wizard/commerce_wizard.libraries.yml new file mode 100644 index 0000000..bdabdbb --- /dev/null +++ b/modules/contrib/commerce/modules/wizard/commerce_wizard.libraries.yml @@ -0,0 +1,16 @@ +wizard_intro: + version: VERSION + css: + layout: + css/commerce_wizard.layout.css: {} + +wizard_form: + version: VERSION + css: + component: + css/commerce_wizard.component.css: {} + js: + js/commerce_wizard.js: {} + dependencies: + - core/jquery + - core/drupal diff --git a/modules/contrib/commerce/modules/wizard/commerce_wizard.links.menu.yml b/modules/contrib/commerce/modules/wizard/commerce_wizard.links.menu.yml new file mode 100644 index 0000000..c70e7d6 --- /dev/null +++ b/modules/contrib/commerce/modules/wizard/commerce_wizard.links.menu.yml @@ -0,0 +1,6 @@ +commerce.commerce_wizard: + title: 'Wizard Setup' + description: 'Quick Installation Method.' + parent: 'commerce.admin_commerce' + route_name: 'commerce.commerce_wizard' + weight: 100 \ No newline at end of file diff --git a/modules/contrib/commerce/modules/wizard/commerce_wizard.module b/modules/contrib/commerce/modules/wizard/commerce_wizard.module new file mode 100644 index 0000000..cd33386 --- /dev/null +++ b/modules/contrib/commerce/modules/wizard/commerce_wizard.module @@ -0,0 +1,70 @@ + array ( + 'variables' => [ + 'intro_title' => NULL, + 'intro_text' => NULL, + ], + ), + 'stepper' => array ( + 'render element' => 'element', + 'template' => 'stepper', + 'variables' => [ + 'title' => NULL, + 'attributes' => NULL, + 'children' => NULL, + 'value' => NULL, + 'required' => NULL, + 'errors' => NULL, + 'open' => FALSE, + 'change_link' => TRUE, + 'button_text' => NULL, + 'skip_text' => NULL, + ], + ), + ); + + return $variables; + +} + +/** + * Prepares variables for details element templates. + * + * Default template: details.html.twig. + * + * @param array $variables + * An associative array containing: + * - element: An associative array containing the properties of the element. + * Properties used: #attributes, #children, #open, + * #id, #title, #value, #optional. + */ +function commerce_wizard_stepper(&$variables) { + $element = $variables['element']; + $variables['attributes'] = $element['#attributes']; + + $variables['title'] = (!empty($element['#title'])) ? $element['#title'] : ''; + $variables['children'] = (isset($element['#children'])) ? $element['#children'] : ''; + $variables['value'] = (isset($element['#value'])) ? $element['#value'] : ''; + $variables['required'] = !empty($element['#required']) ? $element['#required'] : NULL; + + $variables['change_link'] = (isset($element['#change_link'])) ? $element['#change_link'] : ''; + $variables['button_text'] = (isset($element['#button_text'])) ? $element['#button_text'] : ''; + $variables['skip_text'] = (isset($element['#skip_text'])) ? $element['#skip_text'] : ''; + + // Suppress error messages. + $variables['errors'] = NULL; +} \ No newline at end of file diff --git a/modules/contrib/commerce/modules/wizard/commerce_wizard.routing.yml b/modules/contrib/commerce/modules/wizard/commerce_wizard.routing.yml new file mode 100644 index 0000000..8be66dc --- /dev/null +++ b/modules/contrib/commerce/modules/wizard/commerce_wizard.routing.yml @@ -0,0 +1,15 @@ +commerce.commerce_wizard: + path: '/admin/commerce/wizard' + defaults: + _controller: 'Drupal\commerce_wizard\Controller\WizardController::content' + _title: 'Wizard' + requirements: + _permission: 'access commerce administration pages' + +commerce.commerce_wizard.install: + path: '/admin/commerce/wizard/install' + defaults: + _form: '\Drupal\commerce_wizard\Form\WizardForm' + _title: 'Wizard: Install' + requirements: + _permission: 'access content' \ No newline at end of file diff --git a/modules/contrib/commerce/modules/wizard/css/commerce_wizard.component.css b/modules/contrib/commerce/modules/wizard/css/commerce_wizard.component.css new file mode 100644 index 0000000..2a5cbd0 --- /dev/null +++ b/modules/contrib/commerce/modules/wizard/css/commerce_wizard.component.css @@ -0,0 +1,69 @@ +.stepper { + padding: 1em 0; + border-bottom: 1px solid #ccc; +} +.stepper--last { + margin-bottom: 2.5em; +} + +.stepper__header { + padding: .25em 0; + font-size: 1.35em; + display: table; + width: 100%; +} +.stepper__header--title { + color: #666; + width: 75%; + display: table-cell; + vertical-align: top; +} +.stepper__header--skipped { + font-size: .75em; + text-align: right; + width: 25%; + display: table-cell; + vertical-align: top; +} +.stepper__header--button { + font-size: .75em; + display: none; +} + +.stepper__content { + height: 0; + overflow: hidden; + display: none; +} + +/* active state */ +.stepper--active .stepper__content { + padding: 0; + display: block; + height: auto; +} +.stepper--active .stepper__actions { + margin-top: 1.5em; +} +.stepper--active .stepper__header--title { + color: #333; +} + +/* completed state */ +.stepper--complete .stepper__header--title { + color: #325e1c; +} +.stepper--complete .stepper__header--button, +.stepper--complete .stepper__icon { + display: inline-block; +} + +/* icons */ +.stepper__icon { + display: none; + margin: 0 10px 0 5px; + width: 15px; + height: 15px; + background: url(../../../../../../core/themes/stable/images/core/icons/73b355/check.svg) no-repeat; + background-size: 15px 15px; +} \ No newline at end of file diff --git a/modules/contrib/commerce/modules/wizard/css/commerce_wizard.layout.css b/modules/contrib/commerce/modules/wizard/css/commerce_wizard.layout.css new file mode 100644 index 0000000..1c5258a --- /dev/null +++ b/modules/contrib/commerce/modules/wizard/css/commerce_wizard.layout.css @@ -0,0 +1,10 @@ +.commerce__wizard--intro ol { + margin-top: 2em; + margin-bottom: 2em; + margin-left: 1em; + font-size: 1.125em; + line-height: 1.75em; +} +.commerce__wizard--intro ol li { + margin-bottom: 1.25em; +} \ No newline at end of file diff --git a/modules/contrib/commerce/modules/wizard/js/commerce_wizard.js b/modules/contrib/commerce/modules/wizard/js/commerce_wizard.js new file mode 100644 index 0000000..9ac48ae --- /dev/null +++ b/modules/contrib/commerce/modules/wizard/js/commerce_wizard.js @@ -0,0 +1,129 @@ +/** + * @file + * Defines functionality for the wizard's stepping system. + */ +(function ($, Drupal, drupalSettings) { + 'use strict'; + + var Steps = []; + + var Stepper = { + + // init constructor + init: function (step) { + this.step = step; + this.id = step.attr('id'); + this.next_step = step.next(); + this.next_steps = step.nextAll('.stepper'); + this.submit_button = step.find('.stepper__actions .button--primary'); + }, + + // helper function to open up the step to the active state + open: function () { + + var form_submit_button = $('.form-actions .form-submit'); + + // set the proper classes for showing the active state and remove any old classes + this.step.addClass('stepper--active').removeClass('stepper--complete'); + + // hide the skipped button if this step is active + this.step.find('.stepper__header--skipped').addClass('visually-hidden'); + + // make sure all steps below are set to inactive + this.next_steps.each(function() { + var _this = $(this); + _this = $('#' + _this.attr('id')); + _this.removeClass('stepper--active stepper--complete'); + }); + + // enable/disabled the main form submit + // depending on if were on the last step or not + if(this.step.hasClass('stepper--last')){ + form_submit_button.removeClass('is-disabled').removeAttr('disabled'); + } else { + form_submit_button.addClass('is-disabled').attr('disabled', 'disabled'); + } + + }, + + // Helper function to complete a step. + // Should mainly be used in the submit function + complete: function () { + var next_step_id = this.next_step.attr('id'); + + // close the current step and set it to complete state + this.step.addClass('stepper--complete').removeClass('stepper--active'); + + // open the next step, and perform the ajax submit in the step we're closing + window.Steps[next_step_id].open(); + this.submit_button.mousedown(); + }, + + submit: function() { + // @todo: setup some js validation in here + this.complete(); + }, + + }; + + // document ready + $(document).ready(function() { + + var step = $('.stepper'); + var first_step = step.first(); + var last_step = step.last(); + + //get all the steps so we can create their objects + step.each(function () { + var _this = $(this); + var id = $(this).attr('id'); + + // add the step object for later use. + Steps[id] = Object.create(Stepper); + Steps[id].init(_this); + }); + window.Steps = Steps; + + // open the first step + // add a class to the last step + window.Steps[first_step.attr('id')].open(); + last_step.addClass('stepper--last'); + + // edit buttons + $('.stepper__header--button').click(function (e) { + e.preventDefault(); + var step_id = $(this).parents('.stepper').attr('id'); + window.Steps[step_id].open(); + }); + + // steps primary button + $('.stepper__actions .button--primary').click(function (e) { + e.preventDefault(); + var _this = $(this); + var step_id = _this.parents('.stepper').attr('id'); + + if (!_this.hasClass('is-disabled')) { + window.Steps[step_id].submit(); + } + }); + + // steps primary button + $('.stepper__actions .button--danger').click(function (e) { + e.preventDefault(); + var _this = $(this); + var step_id = _this.parents('.stepper').attr('id'); + + // show the skipped text + $('#' + step_id).find('.stepper__header--skipped').removeClass('visually-hidden'); + + if (!_this.hasClass('is-disabled')) { + window.Steps[step_id].submit(); + } + }); + + + + }); + + +})(jQuery, Drupal, drupalSettings); diff --git a/modules/contrib/commerce/modules/wizard/src/Controller/WizardController.php b/modules/contrib/commerce/modules/wizard/src/Controller/WizardController.php new file mode 100644 index 0000000..b9a34db --- /dev/null +++ b/modules/contrib/commerce/modules/wizard/src/Controller/WizardController.php @@ -0,0 +1,23 @@ + 'commerce_wizard', + '#title' => $this->t('Commerce: Quick Install'), + '#intro_title' => $this->t('Hey! It looks like this is your first time using drupal commerce.'), + '#intro_text' => $this->t('Lets take a few minutes to get your store setup and configured, or skip the setup wizard if you plan to configure your store manually.', array('@handbook-url' => 'https://www.drupal.org/node/2474731')), + '#attached' => array( + 'library' => array( + 'commerce_wizard/wizard_intro', + ), + ), + ]; + } + +} \ No newline at end of file diff --git a/modules/contrib/commerce/modules/wizard/src/Element/Stepper.php b/modules/contrib/commerce/modules/wizard/src/Element/Stepper.php new file mode 100644 index 0000000..97bc24d --- /dev/null +++ b/modules/contrib/commerce/modules/wizard/src/Element/Stepper.php @@ -0,0 +1,81 @@ + FALSE, + '#value' => NULL, + '#process' => [ + [$class, 'processGroup'], + [$class, 'processAjaxForm'], + ], + '#pre_render' => [ + [$class, 'preRenderStepper'], + [$class, 'preRenderGroup'], + ], + '#theme_wrappers' => ['stepper'], + '#attached' => array( + 'library' => array( + 'commerce_wizard/wizard_form', + ), + ), + ]; + } + + + + /** + * Adds form element theming to details. + * + * @param $element + * An associative array containing the properties and children of the + * details. + * + * @return + * The modified element. + */ + public static function preRenderStepper($element) { + Element::setAttributes($element, ['id']); + + // The .js-form-wrapper class is required for #states to treat details like + // containers. + static::setAttributes($element, ['js-form-wrapper', 'form-wrapper']); + $element['#attributes']['class'] = 'stepper'; + + // Collapsible details. + $element['#attached']['library'][] = 'core/drupal.collapse'; + + // Open the detail if specified or if a child has an error. + if (!empty($element['#open']) || !empty($element['#children_errors'])) { + $element['#attributes']['class'] .= ' stepper--active'; + } + + // Do not render optional details elements if there are no children. + if (isset($element['#parents'])) { + $group = implode('][', $element['#parents']); + if (!empty($element['#optional']) && !Element::getVisibleChildren($element['#groups'][$group])) { + $element['#printed'] = TRUE; + } + } + + return $element; + } + +} \ No newline at end of file diff --git a/modules/contrib/commerce/modules/wizard/src/Form/WizardForm.php b/modules/contrib/commerce/modules/wizard/src/Form/WizardForm.php new file mode 100644 index 0000000..d5ec219 --- /dev/null +++ b/modules/contrib/commerce/modules/wizard/src/Form/WizardForm.php @@ -0,0 +1,131 @@ + 'stepper', + '#title' => t('1. Add Store Details'), +// '#open' => TRUE, + '#button_text' => t('Next, location'), + ); + + + /* + * 2. Store Location + */ + $form['commerce_location'] = array( + '#type' => 'stepper', + '#title' => t('2. Enter the stores location'), + '#button_text' => t('Next, currency'), + ); + + /* + * 3. Currency + */ + $form['commerce_currency'] = array( + '#type' => 'stepper', + '#title' => t('3. Confirm the stores primary currency'), + '#markup' => t('

We\'ve determined that based on your stores location, the following currency: Canadian Dollar (CAD) will be imported.

'), + '#button_text' => t('Confirm'), + '#skip_text' => t('I\'ll set it up later'), + ); + + /* + * 4. Tax + */ + $form['commerce_tax'] = array( + '#type' => 'stepper', + '#title' => t('4. Confirm the stores primary tax rate(s)'), + '#markup' => t('

We\'ve determined that based on your stores location, the following tax rates; GST & PST will be imported.

'), + '#button_text' => t('Confirm'), + '#skip_text' => t('I\'ll set it up later'), + ); + + /* + * 5. Cart Block + */ + $form['commerce_cart_block'] = array( + '#type' => 'stepper', + '#title' => t('5. Place your cart block in a region'), + '#markup' => t('

As a default, the cart block consists of; the number of items added to the users cart, their total, and a link to proceed to their cart for review & checkout.

+

Select a region on your site where you’d like customers to view this block.

'), + '#button_text' => t('Place block'), + '#skip_text' => t('I\'ll set it up later'), + ); + + /* + * 6. Payment + */ + $form['commerce_payment'] = array( + '#type' => 'stepper', + '#title' => t('6. Add a payment processor'), + '#markup' => t('

Start accepting payments by choosing from 30+ supported payment processors.

'), + '#change_link' => FALSE, + ); + + /* + * Form Actions + */ + $form['actions'] = array('#type' => 'actions'); + $form['actions']['submit'] = array( + '#type' => 'submit', + '#value' => t('Create Store'), + '#attributes' => array( + 'class' => array('button', 'button--primary'), + ), + '#disabled' => TRUE, + ); + + $form['actions']['cancel'] = array( + '#type' => 'link', + '#title' => $this->t('Exit wizard'), + '#url' => Url::fromRoute('commerce.commerce_wizard'), + '#attributes' => array( + 'class' => array('button', 'button--danger'), + ), + ); + + return $form; + } + + /** + * {@inheritdoc} + */ + public function validateForm(array &$form, FormStateInterface $form_state) { + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, FormStateInterface $form_state) { + } + +} \ No newline at end of file diff --git a/modules/contrib/commerce/modules/wizard/templates/commerce-wizard.html.twig b/modules/contrib/commerce/modules/wizard/templates/commerce-wizard.html.twig new file mode 100644 index 0000000..92dac55 --- /dev/null +++ b/modules/contrib/commerce/modules/wizard/templates/commerce-wizard.html.twig @@ -0,0 +1,52 @@ +{# +/** + * @file + * + * Default template for the wizard form. + * + * Available variables: + * - attributes: HTML attributes for the wrapper. + * @ingroup themeable + */ +#} +
+ +

{{ intro_title }}

+

{{ intro_text }}

+ + {% trans %} +
    +
  1. + Add store details
    + Enter a name for your store, and an email to receive notifications from it. +
  2. +
  3. + Enter the stores location
    + Add the store physical address, or choose one closest to its' location. +
  4. +
  5. + Confirm the stores primary currency
    + We’ll try to determine your stores currency based on the location you've entered. +
  6. +
  7. + Confirm the stores primary tax rate(s)
    + We’ll try to determine your stores tax rate(s) based on the location you’ve entered. +
  8. +
  9. + Place your cart block in a region
    + Next, choose where your customers will see the number of items they've added to their cart on your site. +
  10. +
  11. + Add a payment processor
    + Start accepting payments by choosing from over 30 supported payment processors. +
  12. +
+ + + + {% endtrans %} + +
\ No newline at end of file diff --git a/modules/contrib/commerce/modules/wizard/templates/stepper.html.twig b/modules/contrib/commerce/modules/wizard/templates/stepper.html.twig new file mode 100644 index 0000000..41efe9e --- /dev/null +++ b/modules/contrib/commerce/modules/wizard/templates/stepper.html.twig @@ -0,0 +1,51 @@ +{# +/** + * @file + * Theme override for a details element. + * + * Available variables + * - attributes: A list of HTML attributes for the details element. + * - errors: (optional) Any errors for this details element, may not be set. + * - title: (optional) The title of the element, may not be set. + * - description: (optional) The description of the element, may not be set. + * - children: (optional) The children of the element, may not be set. + * - value: (optional) The value of the element, may not be set. + * + * @see template_preprocess_details() + */ +#} + + {%- if title -%} +
+
{{ title }} + + ({{ 'Edit'|trans }}) +
+ +
+ {%- endif -%} + +
+ + {% if errors %} +
+ {{ errors }} +
+ {% endif %} + {%- if children -%} + {{ children }} + {%- endif -%} + {%- if value -%} + {{ value }} + {%- endif -%} + + {%- if (button_text or skip_text) -%} +
+ {%- if button_text -%}{{ button_text }}{%- endif -%} + {%- if skip_text -%}{{ skip_text }}{%- endif -%} +
+ {%- endif -%} + +
+ + -- 2.7.4.windows.1