diff --git a/modules/custom/openy_group_schedules/js/openy_group_schedules.js b/modules/custom/openy_group_schedules/js/openy_group_schedules.js index b0b4ec442e..a63732edf6 100644 --- a/modules/custom/openy_group_schedules/js/openy_group_schedules.js +++ b/modules/custom/openy_group_schedules/js/openy_group_schedules.js @@ -9,14 +9,11 @@ */ Drupal.openy_group_schedules.update_filter_date = function(parameters) { if (typeof(parameters.filter_date) !== 'undefined') { - var date = parameters.filter_date.replace('0',''); - if (date.charAt(0) === '0') { - date = date.slice(1); - } - var exists = 0 !== $('select[name="date_select"] option[value="' + date + '"]').length; - if (exists) { - $('select[name="date_select"]').val(date); - } + var split_date = parameters.filter_date.split('/'); + var day = split_date[0].length == 1 ? '0' + split_date[0] : split_date[0]; + var year = parseInt(split_date[2]) + 2000; + var date = year + '-' + day + '-' + split_date[1]; + $('input[name="date_select"]').val(date); } }; @@ -26,10 +23,6 @@ * @param parameters */ Drupal.openy_group_schedules.update_class_select = function(parameters) { - if (typeof(parameters.view_mode) !== 'undefined' && parameters.view_mode == 'class') { - $('#date-select-wrapper, #location-wrapper').addClass('hidden'); - $('#class-select-wrapper, #location-select-wrapper').removeClass('hidden'); - } if (typeof(parameters.class) !== 'undefined') { var exists = 0 !== $('#class-select-wrapper select option[value="' + parameters.class + '"]').length; if (exists) { @@ -38,6 +31,20 @@ } }; + /** + * Update "Instructor" select value to be equal with "instructor" query param. + * + * @param parameters + */ + Drupal.openy_group_schedules.update_instructor_select = function(parameters) { + if (typeof(parameters.instructor) !== 'undefined') { + var exists = 0 !== $('#instructor-select-wrapper select option[value="' + parameters.instructor + '"]').length; + if (exists) { + $('#instructor-select-wrapper select').val(parameters.instructor); + } + } + }; + /** * Update "Location" select value to be equal with "location" query param. * @@ -74,18 +81,19 @@ history.pushState(null, null, window.location.pathname + '?' + params.join('&')); if (typeof(parameters.instructor) !== 'undefined') { - $('#date-select-wrapper, #location-wrapper, #class-select-wrapper').addClass('hidden'); + $('#location-wrapper').addClass('hidden'); } else if (typeof(parameters.view_mode) !== 'undefined' && parameters.view_mode == 'class') { - $('#location-select-wrapper, #class-select-wrapper').removeClass('hidden'); - $('#date-select-wrapper, #location-wrapper').addClass('hidden'); + $('#location-select-wrapper, #class-select-wrapper, #instructor-select-wrapper').removeClass('hidden'); + $('#location-wrapper').addClass('hidden'); } else { - $('#location-select-wrapper, #date-select-wrapper').removeClass('hidden'); - $('#class-select-wrapper, #location-wrapper').addClass('hidden'); + $('#location-select-wrapper, #date-select-wrapper, #class-select-wrapper, #instructor-select-wrapper').removeClass('hidden'); + $('#location-wrapper').addClass('hidden'); } Drupal.openy_group_schedules.update_class_select(parameters); + Drupal.openy_group_schedules.update_instructor_select(parameters); Drupal.openy_group_schedules.update_filter_date(parameters); Drupal.openy_group_schedules.update_location_select(parameters); }; diff --git a/modules/custom/openy_group_schedules/modules/groupex_form_cache/README.md b/modules/custom/openy_group_schedules/modules/groupex_form_cache/README.md index 334a060812..e5e2bb3944 100644 --- a/modules/custom/openy_group_schedules/modules/groupex_form_cache/README.md +++ b/modules/custom/openy_group_schedules/modules/groupex_form_cache/README.md @@ -5,11 +5,19 @@ ## How to run the warmer -``\Drupal::service("groupex_form_cache.warmer")->warm();`` +``groupex_form_cache_warm();`` ## How to clear the cache -``\Drupal::service("groupex_form_cache.manager")->resetCache(10);`` +``\Drupal::service("groupex_form_cache.manager")->resetCache(100);`` + +or + +``groupex_form_cache_reset_all();`` + +## How to clear the cache (using truncate) + +``groupex_form_cache_reset_all_quick();`` ## How to clear the only stale cache diff --git a/modules/custom/openy_group_schedules/modules/groupex_form_cache/groupex_form_cache.module b/modules/custom/openy_group_schedules/modules/groupex_form_cache/groupex_form_cache.module new file mode 100644 index 0000000000..3ca4823224 --- /dev/null +++ b/modules/custom/openy_group_schedules/modules/groupex_form_cache/groupex_form_cache.module @@ -0,0 +1,46 @@ +acquire($lock_name, $lock_lifetime)) { + \Drupal::service('groupex_form_cache.warmer')->warm(); + $lock->release($lock_name); + } + else { + $msg = 'Lock "%name" is still working. Exit.'; + Drupal::logger('groupex_form_cache')->info( + $msg, + [ + '%name' => $lock_name, + ] + ); + } +} + +/** + * Reset all GroupEx form cache. + */ +function groupex_form_cache_reset_all() { + \Drupal::service("groupex_form_cache.manager")->resetCache(100); +} + +/** + * Quick Groupex cache reset (using TRUNCATE). + */ +function groupex_form_cache_reset_all_quick() { + \Drupal::service("groupex_form_cache.manager")->quickResetCache(); +} diff --git a/modules/custom/openy_group_schedules/modules/groupex_form_cache/src/GroupexFormCacheManager.php b/modules/custom/openy_group_schedules/modules/groupex_form_cache/src/GroupexFormCacheManager.php index dcbc589bfa..94229c831d 100644 --- a/modules/custom/openy_group_schedules/modules/groupex_form_cache/src/GroupexFormCacheManager.php +++ b/modules/custom/openy_group_schedules/modules/groupex_form_cache/src/GroupexFormCacheManager.php @@ -214,4 +214,21 @@ public function runCronServices() { $this->resetStaleCache(10, 172800); } + /** + * Quick reset of Groupex Form Cache. + */ + public function quickResetCache() { + $tables = [ + 'groupex_form_cache', + 'groupex_form_cache__field_gfc_created', + 'groupex_form_cache__field_gfc_options', + 'groupex_form_cache__field_gfc_response', + ]; + + foreach ($tables as $table) { + db_truncate($table)->execute(); + } + $this->logger->info('Groupex Form Cache has been quickly erased using "TRUNCATE".'); + } + } diff --git a/modules/custom/openy_group_schedules/modules/groupex_form_cache/src/GroupexFormCacheWarmer.php b/modules/custom/openy_group_schedules/modules/groupex_form_cache/src/GroupexFormCacheWarmer.php index 926e38e652..3187cd7809 100644 --- a/modules/custom/openy_group_schedules/modules/groupex_form_cache/src/GroupexFormCacheWarmer.php +++ b/modules/custom/openy_group_schedules/modules/groupex_form_cache/src/GroupexFormCacheWarmer.php @@ -7,7 +7,6 @@ use Drupal\Core\Entity\Query\QueryFactory; use Drupal\groupex_form_cache\Entity\GroupexFormCache; use Drupal\Core\Logger\LoggerChannelFactory; -use Drupal\Core\Logger\LoggerChannel; use Drupal\openy_socrates\OpenyCronServiceInterface; use Drupal\openy_group_schedules\GroupexRequestTrait; @@ -72,8 +71,27 @@ public function warm() { * Warm up simple elements. */ private function simpleWarmUp() { - $this->request(['locations' => TRUE]); - $this->request(['classes' => TRUE]); + // Warm up frequent requests. + $this->request(['query' => ['classes' => TRUE]]); + $locations = $this->request(['query' => ['locations' => TRUE]]); + + // Warm up cache for current day for all locations. + $timezone = new \DateTimeZone($this->configFactory->get('system.date')->get('timezone')['default']); + $datetime = new \DateTime('today midnight', $timezone); + $start = $datetime->getTimestamp(); + $end = $datetime->add(new \DateInterval('P1D'))->getTimestamp(); + foreach ($locations as $location) { + $options = [ + 'query' => [ + 'schedule' => TRUE, + 'desc' => "true", + 'location' => [(string) $location->id], + 'start' => $start, + 'end' => $end, + ] + ]; + $this->request($options); + } } /** @@ -85,7 +103,12 @@ private function traverse() { } // Loop over each cache entity. + $this->logger->info('Starting warming up %count cache entities.', ['%count' => count($result)]); + krsort($result); foreach ($result as $item) { + // Let's protect GroupEx servers. + sleep(1); + if (!$entity = GroupexFormCache::load($item)) { continue; } diff --git a/modules/custom/openy_group_schedules/openy_group_schedules.module b/modules/custom/openy_group_schedules/openy_group_schedules.module index e98daba736..ad1962f870 100644 --- a/modules/custom/openy_group_schedules/openy_group_schedules.module +++ b/modules/custom/openy_group_schedules/openy_group_schedules.module @@ -6,6 +6,7 @@ */ use Drupal\openy_group_schedules\GroupexScheduleFetcher; +use Drupal\Component\Utility\Xss; /** * Implements hook_theme(). @@ -241,10 +242,13 @@ function openy_group_schedules_schedule_table_layout(array $schedule) { $class_item = reset($day['classes']); if ($class_item) { $class = $class_item['#class']; + // Allow iframe tag in description to embed video. + $allowed_tags = array_merge(Xss::getAdminTagList(), ['iframe']); $prefix = [ [ '#type' => 'container', '#markup' => $class['description'], + '#allowed_tags' => $allowed_tags, '#attributes' => [ 'class' => ['class-description'], ], @@ -260,6 +264,19 @@ function openy_group_schedules_schedule_table_layout(array $schedule) { } } + // Show help text in case of there is no prefix and there are results. + if (empty($prefix)) { + $prefix = [ + [ + '#type' => 'container', + '#markup' => '

Please note, you may search by class or instructor by clicking on the links in class cards.

', + '#attributes' => [ + 'class' => ['class-description'], + ], + ], + ]; + } + // Output schedule by type. switch ($schedule['type']) { case 'day': diff --git a/modules/custom/openy_group_schedules/src/Form/GroupexFormFull.php b/modules/custom/openy_group_schedules/src/Form/GroupexFormFull.php index 257f1ba4e8..85773838bd 100644 --- a/modules/custom/openy_group_schedules/src/Form/GroupexFormFull.php +++ b/modules/custom/openy_group_schedules/src/Form/GroupexFormFull.php @@ -87,21 +87,13 @@ public function __construct(QueryFactory $entity_query, EntityTypeManagerInterfa parent::__construct($config_factory); $this->groupexHelper = $groupex_helper; $this->scheduleFetcher = $scheduleFetcher; - - $this->locationOptions = $this->getOptions($this->request(['query' => ['locations' => TRUE]]), 'id', 'name'); - $raw_classes_data = $this->getOptions($this->request(['query' => ['classes' => TRUE]]), 'id', 'title'); - $processed_classes_data['any'] = $this->t('-All-'); - foreach ($raw_classes_data as $key => $class) { - $id = str_replace('DESC--[', '', $key); - $processed_classes_data[$id] = $class; - } - $this->classesOptions = $processed_classes_data; $this->entityQuery = $entity_query; $this->entityTypeManager = $entity_type_manager; $this->logger = $logger_factory->get('ymca_mindbody'); $query = $this->getRequest()->query->all(); $request = $this->getRequest()->request->all(); + $state = [ 'location' => isset($query['location']) && is_numeric($query['location']) ? $query['location'] : NULL, 'class' => isset($query['class']) ? $query['class'] : NULL, @@ -158,12 +150,15 @@ public function getFormId() { */ public function buildForm(array $form, FormStateInterface $form_state, $locations = []) { $values = $form_state->getValues(); + $user_input = $form_state->getUserInput(); $state = $this->state; $formatted_results = NULL; $conf = $this->configFactory->get('openy_group_schedules.settings'); - $days_range = is_numeric($conf->get('days_range')) ? $conf->get('days_range') : 14; $max_age = is_numeric($conf->get('cache_max_age')) ? $conf->get('cache_max_age') : 3600; + // Get location options. + $this->locationOptions = $this->getOptions($this->request(['query' => ['locations' => TRUE]]), 'id', 'name'); + // Set location if value passed through form builder. if (is_numeric($locations)) { $state['location'] = $locations; @@ -204,6 +199,10 @@ public function buildForm(array $form, FormStateInterface $form_state, $location if (isset($state['filter_date'])) { $values['date_select'] = $state['filter_date']; } + if (!empty($user_input['class_select'])) { + $state['class'] = $user_input['class_select']; + $this->state = $state; + } $form['#prefix'] = '
'; $form['#suffix'] = '
'; @@ -211,22 +210,17 @@ public function buildForm(array $form, FormStateInterface $form_state, $location $class_select_classes = $location_select_classes = $classes = 'hidden'; $location_classes = 'show'; if (isset($groupex_id) && empty($state['class'])) { - $classes = 'show'; + $classes = $class_select_classes = 'show'; } if (isset($state['location']) && is_numeric($state['location'])) { - $location_select_classes = $classes = 'show'; + $location_select_classes = $classes = $class_select_classes = 'show'; $location_classes = 'hidden'; } if (isset($site_section)) { $location_select_classes = 'hidden'; } if (!empty($state['class']) && is_numeric($state['class'])) { - $classes = 'hidden'; - $location_select_classes = $class_select_classes = 'show'; - } - if (isset($state['instructor'])) { - $classes = $class_select_classes = 'hidden'; - $location_select_classes = 'show'; + $location_select_classes = $class_select_classes = $classes = 'show'; } $form['location'] = [ @@ -269,20 +263,30 @@ public function buildForm(array $form, FormStateInterface $form_state, $location '#weight' => -3, ]; - $date_options = []; - for ($i = 0; $i < $days_range; $i++) { - $time = REQUEST_TIME + $i * 86400; - $dateKey = date('n/d/y', $time); - $dateTitle = date('D, m/d', $time); - $date_options[$dateKey] = $dateTitle; + $tz = new \DateTimeZone(\Drupal::config('system.date')->get('timezone.default')); + $default_date = NULL; + + if (!empty($state['date_select'])) { + $dt = new \DateTime($state['date_select'], $tz); + $default_date = $dt->format('Y-m-d'); + } + elseif (!empty($values['date_select'])) { + $dt = new \DateTime($values['date_select'], $tz); + $default_date = $dt->format('Y-m-d'); } + else { + $dt = new \DateTime(); + $dt->setTimezone($tz); + $dt->setTimestamp(REQUEST_TIME); + $default_date = $dt->format('Y-m-d'); + } + $form['date_select'] = [ - '#type' => 'select', - '#options' => $date_options, + '#type' => 'date', '#title' => $this->t('Date'), '#prefix' => '
', '#suffix' => '
', - '#default_value' => !empty($values['date_select']) ? $values['date_select'] : reset($date_options), + '#default_value' => $default_date, '#ajax' => [ 'callback' => [$this, 'rebuildAjaxCallback'], 'wrapper' => 'groupex-full-form-wrapper', @@ -293,16 +297,24 @@ public function buildForm(array $form, FormStateInterface $form_state, $location 'type' => 'throbber', ], ], - '#cache' => [ - 'max-age' => $max_age, - ], '#weight' => -2, ]; + // Get classes options. + $raw_classes_data = $this->getOptions($this->request(['query' => ['classes' => TRUE]]), 'id', 'title'); + $this->classesOptions = ['any' => $this->t('-All-')]; + $processed_classes_data = []; + foreach ($raw_classes_data as $key => $class) { + // Remove excess key text & cleanup markup being sent back. + $id = str_replace('DESC--[', '', $key); + $processed_classes_data[$id] = t($class); + } + $this->classesOptions = $this->classesOptions + $processed_classes_data; + $form['class_select'] = [ '#type' => 'select', '#options' => $this->classesOptions, - '#default_value' => !empty($state['class']) ? $state['class'] : 'all', + '#default_value' => !empty($state['class']) ? $state['class'] : 'any', '#title' => $this->t('Class:'), '#prefix' => '
', '#suffix' => '
', @@ -319,12 +331,71 @@ public function buildForm(array $form, FormStateInterface $form_state, $location ], ]; + // Get instructor options. + $instructors_location = isset($values['location_select']) ? $values['location_select'] : $values['location']; + $instructors_query = !empty($instructors_location) && $instructors_location != 'any' ? ['schedule' => TRUE, 'location' => $instructors_location] : ['schedule' => TRUE]; + $this->instructorOptions = ['any' => (string) $this->t('-All-')]; + $raw_schedule_data = $this->request(['query' => $instructors_query]); + $instructors = $this->getOptions($raw_schedule_data, 'instructor', 'instructor'); + // Cleanup markup being sent back. + foreach($instructors as $key => $value) { + // Here we need to remove redundant HTML if exists. + $pos = strpos($key, 'instructorOptions = $this->instructorOptions + $instructors_options; + + $form['instructor_select'] = [ + '#type' => 'select', + '#options' => $this->instructorOptions, + '#default_value' => !empty($state['instructor']) ? $state['instructor'] : 'any', + '#title' => $this->t('Instructor:'), + '#prefix' => '
', + '#suffix' => '
', + '#ajax' => [ + 'callback' => [$this, 'rebuildAjaxCallback'], + 'wrapper' => 'groupex-full-form-wrapper', + 'event' => 'change', + 'method' => 'replace', + 'effect' => 'fade', + 'progress' => [ + 'type' => 'throbber', + ], + '#weight' => 0, + ], + ]; + + $form['submit'] = [ + '#type' => 'submit', + '#value' => $this->t('Submit'), + '#prefix' => '
', + '#suffix' => '
', + '#ajax' => [ + 'callback' => [$this, 'rebuildAjaxCallback'], + ] + ]; + $form['groupex_pdf_link'] = [ '#prefix' => '', ]; if (!empty($values['location'])) { + $form['groupex_pdf_link'] = [ + '#type' => 'container', + '#attributes' => [ + 'class' => [ + 'groupex-pdf-link-container', + 'clearfix', + ], + ], + '#weight' => 1, + ]; + $url = $this->groupexHelper->getPdfLink($values['location']); $form['groupex_pdf_link']['link'] = [ '#title' => $this->t('Download PDF'), @@ -359,6 +430,13 @@ public function buildForm(array $form, FormStateInterface $form_state, $location $form['#cache'] = [ 'max-age' => 0, + 'contexts' => [ + 'url.query_args:location', + 'url.query_args:filter_date', + 'url.query_args:class', + 'url.query_args:filter_length', + 'url.query_args:groupex_class', + ], ]; return $form; @@ -372,6 +450,10 @@ public function rebuildAjaxCallback(array &$form, FormStateInterface $form_state $state = $this->state; $location = !empty($values['location_select']) ? $values['location_select'] : $values['location']; $filter_date = !empty($values['date_select']) ? $values['date_select'] : $values['date']; + $tz = \Drupal::config('system.date')->get('timezone.default'); + $date = new \DateTime($filter_date, new \DateTimeZone($tz)); + $filter_date = $date->format('n/d/y'); + $parameters = [ 'location' => $location, 'filter_date' => $filter_date, @@ -395,6 +477,16 @@ public function rebuildAjaxCallback(array &$form, FormStateInterface $form_state $parameters['groupex_class'] = 'groupex_table_class_individual'; $parameters['view_mode'] = 'class'; } + if (isset($triggering_element['#name']) && $triggering_element['#name'] == 'instructor_select') { + $parameters['class'] = $state['class']; + $parameters['filter_length'] = 'week'; + $parameters['category'] = 'any'; + $parameters['groupex_class'] = 'groupex_table_instructor_individual'; + if ($triggering_element['#value'] != 'any') { + $parameters['instructor'] = $triggering_element['#value']; + } + } + $formatted_results = self::buildResults($form, $form_state); $response = new AjaxResponse(); $response->addCommand(new HtmlCommand('#groupex-full-form-wrapper .groupex-results', $formatted_results)); @@ -440,7 +532,7 @@ public function buildResults(array &$form, FormStateInterface $form_state) { $filter_date == $user_input; } $class = !empty($values['class_select']) ? $values['class_select'] : 'any'; - if ($class == 'any' && is_numeric($query['class'])) { + if ($class == 'any' && empty($user_input['class_select']) && is_numeric($query['class'])) { $class = $query['class']; } @@ -478,7 +570,10 @@ public function buildResults(array &$form, FormStateInterface $form_state) { 'groupex_class' => $groupex_class, ]; // Add optional parameters. - if (!empty($query['instructor'])) { + if (!empty($user_input['instructor_select'])) { + $parameters['instructor'] = $user_input['instructor_select']; + } + elseif (!empty($query['instructor'])) { $parameters['instructor'] = $query['instructor']; } if (isset($view_mode)) { @@ -489,6 +584,11 @@ public function buildResults(array &$form, FormStateInterface $form_state) { unset($parameters['view_mode']); } + // Remove instructor parameter in case of no instructor selected. + if ($parameters['instructor'] == 'any') { + unset($parameters['instructor']); + } + $this->scheduleFetcher->__construct($this->groupexHelper, $this->configFactory, $parameters); // Get classes schedules. diff --git a/modules/custom/openy_group_schedules/src/GroupexHelper.php b/modules/custom/openy_group_schedules/src/GroupexHelper.php index 21bbfa2fe3..469c4d6f94 100644 --- a/modules/custom/openy_group_schedules/src/GroupexHelper.php +++ b/modules/custom/openy_group_schedules/src/GroupexHelper.php @@ -53,7 +53,7 @@ public function getPdfLink($location, $timestamp = FALSE, $category = FALSE) { $account = $this->configFactory->get('openy_group_schedules.settings')->get('account_id'); $query = [ 'font' => 'larger', - 'a' => $account, + 'account' => $account, 'l' => $location, ]; diff --git a/modules/custom/openy_group_schedules/src/GroupexRequestTrait.php b/modules/custom/openy_group_schedules/src/GroupexRequestTrait.php index 17e445f27e..467f4e097a 100644 --- a/modules/custom/openy_group_schedules/src/GroupexRequestTrait.php +++ b/modules/custom/openy_group_schedules/src/GroupexRequestTrait.php @@ -70,6 +70,10 @@ trait GroupexRequestTrait { * Data, NULL on failure. */ protected function request(array $options, $defaults = TRUE) { + $st = & drupal_static(md5(json_encode(array_merge($options, (array)$defaults)))); + if ($st) { + return $st; + } $status = \Drupal::config('groupex_form_cache.settings')->get('status'); $all_options = $options; @@ -80,7 +84,10 @@ protected function request(array $options, $defaults = TRUE) { // Try to use cached data. if ($status == TRUE) { $manager = \Drupal::service('groupex_form_cache.manager'); - if ($data = $manager->getCache($all_options)) { + $data = $manager->getCache($all_options); + // Empty array should be a valid cache, but FALSE no. + if (FALSE !== $data) { + $st = $data; return $data; } } @@ -90,10 +97,10 @@ protected function request(array $options, $defaults = TRUE) { $body = $response->getBody(); $data = json_decode($body->getContents()); - if ($status == TRUE && !empty($manager) && !empty($data)) { - $manager->setCache($all_options, $data); + if ($status == TRUE) { + $manager->setCache($all_options, (array) $data); } - + $st = $data; return $data; } catch (\Exception $e) { diff --git a/modules/custom/openy_group_schedules/src/GroupexScheduleFetcher.php b/modules/custom/openy_group_schedules/src/GroupexScheduleFetcher.php index 9ef0beb7af..5bb0dbc59f 100644 --- a/modules/custom/openy_group_schedules/src/GroupexScheduleFetcher.php +++ b/modules/custom/openy_group_schedules/src/GroupexScheduleFetcher.php @@ -653,7 +653,7 @@ public function isEmpty() { public function getPdfLink($location, $timestamp = FALSE, $category = FALSE) { $query = [ 'font' => 'larger', - 'a' => GroupexRequestTrait::$account, + 'account' => GroupexRequestTrait::$account, 'l' => $location, ]; diff --git a/tests/features/bootstrap/FeatureContext.php b/tests/features/bootstrap/FeatureContext.php index bac0d9130b..4529a3abc6 100644 --- a/tests/features/bootstrap/FeatureContext.php +++ b/tests/features/bootstrap/FeatureContext.php @@ -364,12 +364,12 @@ protected function getNodeIdByTitle($title) { /** * @Given /^I select this "([^"]*)" from "([^"]*)"$/ */ - public function iSelectThisFrom($time, $select) { - $option = date('n/d/y', strtotime($time)); - // Mimic \Behat\MinkExtension\Context\MinkContext::selectOption. - $select = $this->fixStepArgument($select); - $option = $this->fixStepArgument($option); - $this->getSession()->getPage()->selectFieldOption($select, $option); + public function iSelectThisFrom($time, $field) { + $value = date('n/d/Y', strtotime($time)); + // Mimic \Behat\MinkExtension\Context\MinkContext::fillField. + $field = $this->fixStepArgument($field); + $value = $this->fixStepArgument($value); + $this->getSession()->getPage()->fillField($field, $value); } /** diff --git a/tests/features/paragraphs/groupex_pro_paragraphs.feature b/tests/features/paragraphs/groupex_pro_paragraphs.feature index fb8455312f..3c12f540a8 100644 --- a/tests/features/paragraphs/groupex_pro_paragraphs.feature +++ b/tests/features/paragraphs/groupex_pro_paragraphs.feature @@ -31,11 +31,13 @@ Feature: GroupEx Pro paragraphs And Element "#edit-location--wrapper .fieldset-legend" has text "Locations" And I should see an "#edit-location" element And I should see an "#edit-location .form-item-location" element - When I select "202" from "location" + When I select "203" from "location" Then I wait for AJAX to finish And I select this "next monday" from "date_select" + When I select "202" from "location_select" Then I wait for AJAX to finish And I should see an ".groupex-pdf-link-container a:contains('Download PDF')" element +# And I wait 45 seconds And I should see text matching "8:30am 60 min" And I should see text matching "Chisel Studio 1" And I should see text matching "Jennifer K." diff --git a/themes/openy_themes/openy_rose/css/styles.css b/themes/openy_themes/openy_rose/css/styles.css index 258a69ee17..c5b43aa2fa 100644 --- a/themes/openy_themes/openy_rose/css/styles.css +++ b/themes/openy_themes/openy_rose/css/styles.css @@ -5219,7 +5219,8 @@ html.js .branch__updates_queue__button { overflow: hidden; padding: 20px; } -.groupex-form-full .top-form-wrapper .js-form-type-select { +.groupex-form-full .top-form-wrapper .js-form-type-select, +.groupex-form-full .top-form-wrapper .js-form-type-date { margin: 0; } .groupex-form-full .top-form-wrapper select { @@ -5259,6 +5260,10 @@ html.js .branch__updates_queue__button { float: left; margin-right: 30px; } + .groupex-form-full #submit-wrapper { + float: left; + margin: 2em 30px 0 0; + } } .groupex-form-full .groupex-pdf-link-container { margin-top: 10px; diff --git a/themes/openy_themes/openy_rose/scss/modules/_schedules.scss b/themes/openy_themes/openy_rose/scss/modules/_schedules.scss index 67237fc29f..2b6c004a3e 100644 --- a/themes/openy_themes/openy_rose/scss/modules/_schedules.scss +++ b/themes/openy_themes/openy_rose/scss/modules/_schedules.scss @@ -636,7 +636,8 @@ background-color: $lighter-grey; overflow: hidden; padding: 20px; - .js-form-type-select { + .js-form-type-select, + .js-form-type-date { margin: 0; } select { @@ -677,6 +678,10 @@ float: left; margin-right: 30px; } + #submit-wrapper { + float: left; + margin: 2em 30px 0 0; + } } .groupex-pdf-link-container { margin-top: 10px;