From dc7df750342829274d7080cfda42c3f4e649ad8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Caruso?= Date: Fri, 24 Nov 2017 12:46:31 +0100 Subject: [PATCH 01/16] =?UTF-8?q?Add=20module=20=E2=80=9CUser=20Notificati?= =?UTF-8?q?ons=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- drupal-org.make | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drupal-org.make b/drupal-org.make index a03b4089..04e35c14 100644 --- a/drupal-org.make +++ b/drupal-org.make @@ -484,6 +484,9 @@ projects[title][version] = 1.0-alpha9 projects[token][version] = 1.7 +projects[user_notifications][version] = 2.x-dev +projects[user_notifications][patch][] = https://www.drupal.org/files/issues/user_notifications-2926012-1.patch + projects[userone][version] = 1.0-beta1 projects[uuid][version] = 1.0 From 5bedec1c7797ce1ad7e27f0fe27049f57571bbca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Caruso?= Date: Fri, 24 Nov 2017 15:33:30 +0100 Subject: [PATCH 02/16] Enable module "User Notifications" --- modules/roomify/roomify_system/roomify_system.install | 7 +++++++ roomify.info | 1 + 2 files changed, 8 insertions(+) diff --git a/modules/roomify/roomify_system/roomify_system.install b/modules/roomify/roomify_system/roomify_system.install index d2173e5b..ad203087 100644 --- a/modules/roomify/roomify_system/roomify_system.install +++ b/modules/roomify/roomify_system/roomify_system.install @@ -989,3 +989,10 @@ function roomify_system_update_7061() { function roomify_system_update_7062() { module_enable(array('video')); } + +/** + * Enable module "User Notifications". + */ +function roomify_system_update_7063() { + module_enable(array('user_notifications')); +} diff --git a/roomify.info b/roomify.info index a9537410..43092375 100644 --- a/roomify.info +++ b/roomify.info @@ -138,6 +138,7 @@ dependencies[] = hreflang dependencies[] = select2 dependencies[] = yoast_seo dependencies[] = video +dependencies[] = user_notifications ; Users dependencies[] = profile2 From 093d517e6f327f40c1e7c7df41fccda646c9c55e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Caruso?= Date: Fri, 24 Nov 2017 15:45:48 +0100 Subject: [PATCH 03/16] Create notification types --- .../roomify_system/roomify_system.install | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/modules/roomify/roomify_system/roomify_system.install b/modules/roomify/roomify_system/roomify_system.install index ad203087..17408124 100644 --- a/modules/roomify/roomify_system/roomify_system.install +++ b/modules/roomify/roomify_system/roomify_system.install @@ -23,6 +23,77 @@ function roomify_system_install() { roomify_system_add_user_fields(); roomify_system_setup_advagg(); + + roomify_system_create_notification_types(); +} + +/** + * Create notification types. + */ +function roomify_system_create_notification_types() { + $user_notifications_types = array( + array( + 'name' => 'channel_manager_conflict', + 'label' => 'Channel manager conflict', + 'locked' => 1, + ), + array( + 'name' => 'new_booking', + 'label' => 'New Booking', + 'locked' => 1, + ), + array( + 'name' => 'new_conversation', + 'label' => 'New Conversation', + 'locked' => 1, + ), + array( + 'name' => 'new_conversation_message', + 'label' => 'New Conversation Message', + 'locked' => 1, + ), + ); + + foreach ($user_notifications_types as $info) { + if (empty(entity_load_multiple_by_name('user_notifications_type', array($info['name'])))) { + $user_notifications_type = entity_get_controller('user_notifications_type')->create($info); + $user_notifications_type->save(); + + $instance = array( + 'bundle' => $info['name'], + 'default_value' => NULL, + 'deleted' => 0, + 'description' => 'Enter a message that will be displayed to a user as a notification.', + 'display' => array( + 'default' => array( + 'label' => 'above', + 'module' => 'text', + 'settings' => array(), + 'type' => 'text_default', + 'weight' => 2, + ), + ), + 'entity_type' => 'user_notifications', + 'field_name' => 'user_notifications_message', + 'label' => 'New Message', + 'required' => 1, + 'settings' => array( + 'text_processing' => 0, + 'user_register_form' => FALSE, + ), + 'widget' => array( + 'active' => 1, + 'module' => 'text', + 'settings' => array( + 'rows' => 5, + ), + 'type' => 'text_textarea', + 'weight' => 3, + ), + ); + field_create_instance($instance); + } + } } /** @@ -996,3 +1067,10 @@ function roomify_system_update_7062() { function roomify_system_update_7063() { module_enable(array('user_notifications')); } + +/** + * Create notification types. + */ +function roomify_system_update_7064() { + roomify_system_create_notification_types(); +} From 21214f97a4c1701a3c9d092b699914f3c39841a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Caruso?= Date: Fri, 24 Nov 2017 16:13:03 +0100 Subject: [PATCH 04/16] =?UTF-8?q?Add=20view=20=E2=80=9CDashboard=20notific?= =?UTF-8?q?ations=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../roomify_dashboard/roomify_dashboard.info | 1 + .../roomify_dashboard.panels_default.inc | 20 +++++ .../roomify_dashboard.views_default.inc | 86 +++++++++++++++++++ 3 files changed, 107 insertions(+) diff --git a/modules/roomify/roomify_dashboard/roomify_dashboard.info b/modules/roomify/roomify_dashboard/roomify_dashboard.info index af966164..5c44b930 100644 --- a/modules/roomify/roomify_dashboard/roomify_dashboard.info +++ b/modules/roomify/roomify_dashboard/roomify_dashboard.info @@ -28,6 +28,7 @@ features[panels_mini][] = dashboard_welcome features[views_view][] = availability_calendar features[views_view][] = dashboard_bookings features[views_view][] = dashboard_guest_stays +features[views_view][] = dashboard_notifications features[views_view][] = email_templates features[views_view][] = favorite_properties features[views_view][] = form_submissions diff --git a/modules/roomify/roomify_dashboard/roomify_dashboard.panels_default.inc b/modules/roomify/roomify_dashboard/roomify_dashboard.panels_default.inc index 3f22c62a..3d283e97 100644 --- a/modules/roomify/roomify_dashboard/roomify_dashboard.panels_default.inc +++ b/modules/roomify/roomify_dashboard/roomify_dashboard.panels_default.inc @@ -1597,6 +1597,7 @@ function roomify_dashboard_default_panels_mini() { ), 'middle' => NULL, 'bottom' => NULL, + 'middle-second' => NULL, ), 'top' => array( 'style' => 'tabs', @@ -1826,6 +1827,25 @@ function roomify_dashboard_default_panels_mini() { $pane->uuid = 'c58443f0-5efd-440c-916a-c5b8bcbdc63d'; $display->content['new-c58443f0-5efd-440c-916a-c5b8bcbdc63d'] = $pane; $display->panels['top'][6] = 'new-c58443f0-5efd-440c-916a-c5b8bcbdc63d'; + $pane = new stdClass(); + $pane->pid = 'new-9c03ae9f-5f7e-43fc-8af3-9bee26ba71d7'; + $pane->panel = 'top'; + $pane->type = 'views_panes'; + $pane->subtype = 'dashboard_notifications-panel_pane_1'; + $pane->shown = TRUE; + $pane->access = array(); + $pane->configuration = array(); + $pane->cache = array(); + $pane->style = array( + 'settings' => NULL, + ); + $pane->css = array(); + $pane->extras = array(); + $pane->position = 7; + $pane->locks = array(); + $pane->uuid = '9c03ae9f-5f7e-43fc-8af3-9bee26ba71d7'; + $display->content['new-9c03ae9f-5f7e-43fc-8af3-9bee26ba71d7'] = $pane; + $display->panels['top'][7] = 'new-9c03ae9f-5f7e-43fc-8af3-9bee26ba71d7'; $display->hide_title = PANELS_TITLE_FIXED; $display->title_pane = '0'; $mini->display = $display; diff --git a/modules/roomify/roomify_dashboard/roomify_dashboard.views_default.inc b/modules/roomify/roomify_dashboard/roomify_dashboard.views_default.inc index 870b1b78..8cef16eb 100644 --- a/modules/roomify/roomify_dashboard/roomify_dashboard.views_default.inc +++ b/modules/roomify/roomify_dashboard/roomify_dashboard.views_default.inc @@ -4423,5 +4423,91 @@ function roomify_dashboard_views_default_views() { ); $export['roomify_user_orders'] = $view; + $view = new view(); + $view->name = 'dashboard_notifications'; + $view->description = ''; + $view->tag = 'default'; + $view->base_table = 'user_notifications'; + $view->human_name = 'Dashboard notifications'; + $view->core = 7; + $view->api_version = '3.0'; + $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ + + /* Display: Master */ + $handler = $view->new_display('default', 'Master', 'default'); + $handler->display->display_options['title'] = 'Notifications'; + $handler->display->display_options['use_ajax'] = TRUE; + $handler->display->display_options['use_more_always'] = FALSE; + $handler->display->display_options['access']['type'] = 'none'; + $handler->display->display_options['cache']['type'] = 'none'; + $handler->display->display_options['query']['type'] = 'views_query'; + $handler->display->display_options['exposed_form']['type'] = 'basic'; + $handler->display->display_options['pager']['type'] = 'mini'; + $handler->display->display_options['pager']['options']['items_per_page'] = '10'; + $handler->display->display_options['pager']['options']['offset'] = '0'; + $handler->display->display_options['pager']['options']['id'] = '0'; + $handler->display->display_options['style_plugin'] = 'default'; + $handler->display->display_options['row_plugin'] = 'fields'; + /* No results behavior: Global: Text area */ + $handler->display->display_options['empty']['area']['id'] = 'area'; + $handler->display->display_options['empty']['area']['table'] = 'views'; + $handler->display->display_options['empty']['area']['field'] = 'area'; + $handler->display->display_options['empty']['area']['empty'] = TRUE; + $handler->display->display_options['empty']['area']['content'] = 'No notifications to read.'; + $handler->display->display_options['empty']['area']['format'] = 'filtered_text'; + /* Field: User notification: User Notification type */ + $handler->display->display_options['fields']['type']['id'] = 'type'; + $handler->display->display_options['fields']['type']['table'] = 'user_notifications'; + $handler->display->display_options['fields']['type']['field'] = 'type'; + $handler->display->display_options['fields']['type']['label'] = ''; + $handler->display->display_options['fields']['type']['element_label_colon'] = FALSE; + /* Field: User notification: New Message */ + $handler->display->display_options['fields']['user_notifications_message']['id'] = 'user_notifications_message'; + $handler->display->display_options['fields']['user_notifications_message']['table'] = 'field_data_user_notifications_message'; + $handler->display->display_options['fields']['user_notifications_message']['field'] = 'user_notifications_message'; + $handler->display->display_options['fields']['user_notifications_message']['label'] = ''; + $handler->display->display_options['fields']['user_notifications_message']['element_label_colon'] = FALSE; + $handler->display->display_options['fields']['user_notifications_message']['settings'] = array( + 'conditions' => array( + 0 => array( + 'condition' => '', + ), + ), + ); + /* Contextual filter: User notification: Notification Recipient (user_notifications_recipient_uid) */ + $handler->display->display_options['arguments']['user_notifications_recipient_uid_target_id']['id'] = 'user_notifications_recipient_uid_target_id'; + $handler->display->display_options['arguments']['user_notifications_recipient_uid_target_id']['table'] = 'field_data_user_notifications_recipient_uid'; + $handler->display->display_options['arguments']['user_notifications_recipient_uid_target_id']['field'] = 'user_notifications_recipient_uid_target_id'; + $handler->display->display_options['arguments']['user_notifications_recipient_uid_target_id']['default_action'] = 'default'; + $handler->display->display_options['arguments']['user_notifications_recipient_uid_target_id']['default_argument_type'] = 'current_user'; + $handler->display->display_options['arguments']['user_notifications_recipient_uid_target_id']['summary']['number_of_records'] = '0'; + $handler->display->display_options['arguments']['user_notifications_recipient_uid_target_id']['summary']['format'] = 'default_summary'; + $handler->display->display_options['arguments']['user_notifications_recipient_uid_target_id']['summary_options']['items_per_page'] = '25'; + + /* Display: Content pane */ + $handler = $view->new_display('panel_pane', 'Content pane', 'panel_pane_1'); + $translatables['dashboard_notifications'] = array( + t('Master'), + t('Notifications'), + t('more'), + t('Apply'), + t('Reset'), + t('Sort by'), + t('Asc'), + t('Desc'), + t('Items per page'), + t('- All -'), + t('Offset'), + t('« first'), + t('‹ previous'), + t('next ›'), + t('last »'), + t('No notifications to read.'), + t('All'), + t('Content pane'), + t('View panes'), + ); + $export['dashboard_notifications'] = $view; + return $export; } From b9ed85f82f1283f52c0ca52acbe53097f41db571 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Caruso?= Date: Fri, 24 Nov 2017 17:25:31 +0100 Subject: [PATCH 05/16] Add module "Views Refresh" --- drupal-org.make | 2 ++ modules/roomify/roomify_system/roomify_system.install | 7 +++++++ roomify.info | 1 + 3 files changed, 10 insertions(+) diff --git a/drupal-org.make b/drupal-org.make index 04e35c14..231195ba 100644 --- a/drupal-org.make +++ b/drupal-org.make @@ -530,6 +530,8 @@ projects[views_megarow][version] = 1.7 projects[views_php][version] = 1.0-alpha3 +projects[views_refresh][version] = 1.2 + projects[votingapi][version] = 2.12 projects[votingapi][patch][] = https://www.drupal.org/files/issues/updating_voting_api_default_views-2679585-3.patch diff --git a/modules/roomify/roomify_system/roomify_system.install b/modules/roomify/roomify_system/roomify_system.install index 17408124..2b436647 100644 --- a/modules/roomify/roomify_system/roomify_system.install +++ b/modules/roomify/roomify_system/roomify_system.install @@ -1074,3 +1074,10 @@ function roomify_system_update_7063() { function roomify_system_update_7064() { roomify_system_create_notification_types(); } + +/** + * Enable module "Views Refresh". + */ +function roomify_system_update_7065() { + module_enable(array('views_refresh')); +} diff --git a/roomify.info b/roomify.info index 43092375..9e8cf544 100644 --- a/roomify.info +++ b/roomify.info @@ -53,6 +53,7 @@ dependencies[] = i18n_panels dependencies[] = views_content dependencies[] = views dependencies[] = views_data_export +dependencies[] = views_refresh ; Rules dependencies[] = rules From c59cba451511caaa591c17a7fc34ee5d327b4d48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Caruso?= Date: Fri, 24 Nov 2017 17:25:57 +0100 Subject: [PATCH 06/16] Hide user notifications --- .../roomify_dashboard/roomify_dashboard.info | 1 + .../roomify_dashboard.module | 46 +++++++++++++++ .../roomify_dashboard.panels_default.inc | 5 +- .../roomify_dashboard.views_default.inc | 13 +++++ ...fy_dashboard_handler_bat_booking_price.inc | 1 - ...fy_dashboard_handler_hide_notification.inc | 32 +++++++++++ .../css/roomify_adminimal_theme.css | 57 +++++++------------ .../less/components/dashboard.less | 22 +++++++ 8 files changed, 139 insertions(+), 38 deletions(-) create mode 100644 modules/roomify/roomify_dashboard/views/roomify_dashboard_handler_hide_notification.inc diff --git a/modules/roomify/roomify_dashboard/roomify_dashboard.info b/modules/roomify/roomify_dashboard/roomify_dashboard.info index 5c44b930..ef2da885 100644 --- a/modules/roomify/roomify_dashboard/roomify_dashboard.info +++ b/modules/roomify/roomify_dashboard/roomify_dashboard.info @@ -39,3 +39,4 @@ files[] = views/roomify_dashboard_filters_handler_filter_language_select.inc files[] = views/roomify_dashboard_handler_localized_edit_link.inc files[] = views/roomify_dashboard_handler_properties_types_edit_link.inc files[] = views/roomify_dashboard_handler_bat_booking_price.inc +files[] = views/roomify_dashboard_handler_hide_notification.inc diff --git a/modules/roomify/roomify_dashboard/roomify_dashboard.module b/modules/roomify/roomify_dashboard/roomify_dashboard.module index 4704c301..deea34fc 100644 --- a/modules/roomify/roomify_dashboard/roomify_dashboard.module +++ b/modules/roomify/roomify_dashboard/roomify_dashboard.module @@ -20,6 +20,15 @@ function roomify_dashboard_menu() { 'access arguments' => array('administer theme colors'), ); + $items['user-notifications/%user_notifications/hide'] = array( + 'delivery callback' => 'ajax_deliver', + 'page callback' => 'roomify_dashboard_hide_user_notification', + 'page arguments' => array(1), + 'access callback' => 'roomify_dashboard_hide_user_notification_access', + 'access arguments' => array(1), + 'type' => MENU_CALLBACK, + ); + return $items; } @@ -361,6 +370,14 @@ function roomify_dashboard_views_data_alter(&$data) { 'handler' => 'roomify_dashboard_handler_properties_types_edit_link', ), ); + + $data['user_notifications']['hide'] = array( + 'field' => array( + 'title' => t('Hide notification'), + 'help' => t('Hide notification'), + 'handler' => 'roomify_dashboard_handler_hide_notification', + ), + ); } /** @@ -558,3 +575,32 @@ function roomify_dashboard_views_query_alter(&$view, &$query) { } } } + +/** + * Hide user notification access callback. + */ +function roomify_dashboard_hide_user_notification_access($user_notification) { + global $user; + + if ($user_notification->wrapper->user_notifications_recipient_uid->uid->value() == $user->uid) { + return TRUE; + } + + return FALSE; +} + +/** + * Hide user notification. + */ +function roomify_dashboard_hide_user_notification($user_notification) { + $user_notification->update_state('seen'); + + $commands = array(); + + $commands[] = views_refresh_ajax_command_refresh('.view-dashboard-notifications'); + + return array( + '#type' => 'ajax', + '#commands' => $commands, + ); +} diff --git a/modules/roomify/roomify_dashboard/roomify_dashboard.panels_default.inc b/modules/roomify/roomify_dashboard/roomify_dashboard.panels_default.inc index 3d283e97..f1f93f25 100644 --- a/modules/roomify/roomify_dashboard/roomify_dashboard.panels_default.inc +++ b/modules/roomify/roomify_dashboard/roomify_dashboard.panels_default.inc @@ -1839,7 +1839,10 @@ function roomify_dashboard_default_panels_mini() { $pane->style = array( 'settings' => NULL, ); - $pane->css = array(); + $pane->css = array( + 'css_id' => '', + 'css_class' => 'col-xs-12', + ); $pane->extras = array(); $pane->position = 7; $pane->locks = array(); diff --git a/modules/roomify/roomify_dashboard/roomify_dashboard.views_default.inc b/modules/roomify/roomify_dashboard/roomify_dashboard.views_default.inc index 8cef16eb..0ab6de02 100644 --- a/modules/roomify/roomify_dashboard/roomify_dashboard.views_default.inc +++ b/modules/roomify/roomify_dashboard/roomify_dashboard.views_default.inc @@ -4455,6 +4455,12 @@ function roomify_dashboard_views_default_views() { $handler->display->display_options['empty']['area']['empty'] = TRUE; $handler->display->display_options['empty']['area']['content'] = 'No notifications to read.'; $handler->display->display_options['empty']['area']['format'] = 'filtered_text'; + /* Field: User notification: Hide notification */ + $handler->display->display_options['fields']['hide']['id'] = 'hide'; + $handler->display->display_options['fields']['hide']['table'] = 'user_notifications'; + $handler->display->display_options['fields']['hide']['field'] = 'hide'; + $handler->display->display_options['fields']['hide']['label'] = ''; + $handler->display->display_options['fields']['hide']['element_label_colon'] = FALSE; /* Field: User notification: User Notification type */ $handler->display->display_options['fields']['type']['id'] = 'type'; $handler->display->display_options['fields']['type']['table'] = 'user_notifications'; @@ -4483,6 +4489,13 @@ function roomify_dashboard_views_default_views() { $handler->display->display_options['arguments']['user_notifications_recipient_uid_target_id']['summary']['number_of_records'] = '0'; $handler->display->display_options['arguments']['user_notifications_recipient_uid_target_id']['summary']['format'] = 'default_summary'; $handler->display->display_options['arguments']['user_notifications_recipient_uid_target_id']['summary_options']['items_per_page'] = '25'; + /* Filter criterion: User notification: State entity */ + $handler->display->display_options['filters']['state']['id'] = 'state'; + $handler->display->display_options['filters']['state']['table'] = 'user_notifications'; + $handler->display->display_options['filters']['state']['field'] = 'state'; + $handler->display->display_options['filters']['state']['value'] = array( + 'unseen' => 'unseen', + ); /* Display: Content pane */ $handler = $view->new_display('panel_pane', 'Content pane', 'panel_pane_1'); diff --git a/modules/roomify/roomify_dashboard/views/roomify_dashboard_handler_bat_booking_price.inc b/modules/roomify/roomify_dashboard/views/roomify_dashboard_handler_bat_booking_price.inc index 351df2cc..ba8869d6 100644 --- a/modules/roomify/roomify_dashboard/views/roomify_dashboard_handler_bat_booking_price.inc +++ b/modules/roomify/roomify_dashboard/views/roomify_dashboard_handler_bat_booking_price.inc @@ -28,7 +28,6 @@ class roomify_dashboard_handler_bat_booking_price extends views_handler_field { * {@inheritdoc} */ public function render($values) { - // Standard Booking. if (isset($values->field_booking_price) && (!empty($values->field_booking_price[0]['rendered']['#markup']))) { return $values->field_booking_price[0]['rendered']['#markup']; diff --git a/modules/roomify/roomify_dashboard/views/roomify_dashboard_handler_hide_notification.inc b/modules/roomify/roomify_dashboard/views/roomify_dashboard_handler_hide_notification.inc new file mode 100644 index 00000000..064c643d --- /dev/null +++ b/modules/roomify/roomify_dashboard/views/roomify_dashboard_handler_hide_notification.inc @@ -0,0 +1,32 @@ +ensure_my_table(); + } + + /** + * {@inheritdoc} + */ + public function render($values) { + $user_notification = $this->get_value($values); + + return l('Hide', 'user-notifications/' . $user_notification->user_notifications_id . '/hide', array('attributes' => array('class' => 'use-ajax'))); + } + +} diff --git a/themes/roomify/roomify_adminimal_theme/css/roomify_adminimal_theme.css b/themes/roomify/roomify_adminimal_theme/css/roomify_adminimal_theme.css index 2fc1755a..185bbec7 100644 --- a/themes/roomify/roomify_adminimal_theme/css/roomify_adminimal_theme.css +++ b/themes/roomify/roomify_adminimal_theme/css/roomify_adminimal_theme.css @@ -1,3 +1,5 @@ +@import url(https://fonts.googleapis.com/css?family=Lato:400,300,700); +@import url(https://fonts.googleapis.com/css?family=Open+Sans:400,800,700); .btn-circle { width: 30px; height: 30px; @@ -2717,6 +2719,25 @@ body.adminimal-skin-material table.views-table tbody tr td { top: 15px; } } +.view-dashboard-notifications .views-row { + color: white; + margin-bottom: 15px; +} +.view-dashboard-notifications .views-row .views-field-type { + padding: 5px 12px; + background: #405467; +} +.view-dashboard-notifications .views-row .views-field-user-notifications-message { + padding: 7px 12px; + background: #687c90; +} +.view-dashboard-notifications .views-row .views-field-hide { + float: right; + margin: 5px 12px; +} +.view-dashboard-notifications .views-row .views-field-hide a { + color: white; +} .page-admin-bat-config-booking-add-roomify-accommodation-booking #bat-booking-edit-form .field-name-booking-end-date, #bat-booking-edit-roomify-accommodation-booking-form .field-name-booking-end-date, .page-admin-bat-config-booking-add-roomify-accommodation-booking #bat-booking-edit-form .field-name-booking-start-date, @@ -3455,42 +3476,6 @@ body.adminimal-skin-material .vertical-tabs-panes fieldset.vertical-tabs-pane { line-height: 33px; } /* Custom font */ -@font-face { - font-family: 'Lato'; - font-style: normal; - font-weight: 300; - src: local('Lato Light'), local('Lato-Light'), url(https://fonts.gstatic.com/s/lato/v14/nj47mAZe0mYUIySgfn0wpQ.ttf) format('truetype'); -} -@font-face { - font-family: 'Lato'; - font-style: normal; - font-weight: 400; - src: local('Lato Regular'), local('Lato-Regular'), url(https://fonts.gstatic.com/s/lato/v14/v0SdcGFAl2aezM9Vq_aFTQ.ttf) format('truetype'); -} -@font-face { - font-family: 'Lato'; - font-style: normal; - font-weight: 700; - src: local('Lato Bold'), local('Lato-Bold'), url(https://fonts.gstatic.com/s/lato/v14/DvlFBScY1r-FMtZSYIYoYw.ttf) format('truetype'); -} -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 400; - src: local('Open Sans Regular'), local('OpenSans-Regular'), url(https://fonts.gstatic.com/s/opensans/v15/cJZKeOuBrn4kERxqtaUH3aCWcynf_cDxXwCLxiixG1c.ttf) format('truetype'); -} -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 700; - src: local('Open Sans Bold'), local('OpenSans-Bold'), url(https://fonts.gstatic.com/s/opensans/v15/k3k702ZOKiLJc3WVjuplzInF5uFdDttMLvmWuJdhhgs.ttf) format('truetype'); -} -@font-face { - font-family: 'Open Sans'; - font-style: normal; - font-weight: 800; - src: local('Open Sans ExtraBold'), local('OpenSans-ExtraBold'), url(https://fonts.gstatic.com/s/opensans/v15/EInbV5DfGHOiMmvb1Xr-honF5uFdDttMLvmWuJdhhgs.ttf) format('truetype'); -} #references-dialog-page { background: white; } diff --git a/themes/roomify/roomify_adminimal_theme/less/components/dashboard.less b/themes/roomify/roomify_adminimal_theme/less/components/dashboard.less index 943f3879..974a76c0 100644 --- a/themes/roomify/roomify_adminimal_theme/less/components/dashboard.less +++ b/themes/roomify/roomify_adminimal_theme/less/components/dashboard.less @@ -416,3 +416,25 @@ } } } + +.view-dashboard-notifications { + .views-row { + color: white; + margin-bottom: 15px; + .views-field-type { + padding: 5px 12px; + background: #405467; + } + .views-field-user-notifications-message { + padding: 7px 12px; + background: #687c90; + } + .views-field-hide { + float: right; + margin: 5px 12px; + a { + color: white; + } + } + } +} From 0918204c284b846cc0467251f9d2af3cd84d2f1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Caruso?= Date: Fri, 24 Nov 2017 17:39:37 +0100 Subject: [PATCH 07/16] Hide all notifications --- .../roomify_dashboard.module | 34 +++++++++++++++++++ .../roomify_dashboard.views_default.inc | 7 ++++ .../css/roomify_adminimal_theme.css | 8 +++++ .../less/components/dashboard.less | 8 +++++ 4 files changed, 57 insertions(+) diff --git a/modules/roomify/roomify_dashboard/roomify_dashboard.module b/modules/roomify/roomify_dashboard/roomify_dashboard.module index deea34fc..a24503fc 100644 --- a/modules/roomify/roomify_dashboard/roomify_dashboard.module +++ b/modules/roomify/roomify_dashboard/roomify_dashboard.module @@ -29,6 +29,14 @@ function roomify_dashboard_menu() { 'type' => MENU_CALLBACK, ); + $items['user-notifications/hide-all'] = array( + 'delivery callback' => 'ajax_deliver', + 'page callback' => 'roomify_dashboard_hide_all_user_notification', + 'page arguments' => array(1), + 'access callback' => TRUE, + 'type' => MENU_CALLBACK, + ); + return $items; } @@ -604,3 +612,29 @@ function roomify_dashboard_hide_user_notification($user_notification) { '#commands' => $commands, ); } + +function roomify_dashboard_hide_all_user_notification() { + global $user; + + $query = new EntityFieldQuery(); + $query->entityCondition('entity_type', 'user_notifications'); + $query->propertyCondition('state', 'unseen'); + $query->fieldCondition('user_notifications_recipient_uid', 'target_id', $user->uid); + + $results = $query->execute(); + if (isset($results['user_notifications'])) { + foreach ($results['user_notifications'] as $result) { + $user_notification = user_notifications_load($result->user_notifications_id); + $user_notification->update_state('seen'); + } + } + + $commands = array(); + + $commands[] = views_refresh_ajax_command_refresh('.view-dashboard-notifications'); + + return array( + '#type' => 'ajax', + '#commands' => $commands, + ); +} diff --git a/modules/roomify/roomify_dashboard/roomify_dashboard.views_default.inc b/modules/roomify/roomify_dashboard/roomify_dashboard.views_default.inc index 0ab6de02..740fecc6 100644 --- a/modules/roomify/roomify_dashboard/roomify_dashboard.views_default.inc +++ b/modules/roomify/roomify_dashboard/roomify_dashboard.views_default.inc @@ -4448,6 +4448,12 @@ function roomify_dashboard_views_default_views() { $handler->display->display_options['pager']['options']['id'] = '0'; $handler->display->display_options['style_plugin'] = 'default'; $handler->display->display_options['row_plugin'] = 'fields'; + /* Header: Global: Text area */ + $handler->display->display_options['header']['area']['id'] = 'area'; + $handler->display->display_options['header']['area']['table'] = 'views'; + $handler->display->display_options['header']['area']['field'] = 'area'; + $handler->display->display_options['header']['area']['content'] = 'Hide all'; + $handler->display->display_options['header']['area']['format'] = 'filtered_text'; /* No results behavior: Global: Text area */ $handler->display->display_options['empty']['area']['id'] = 'area'; $handler->display->display_options['empty']['area']['table'] = 'views'; @@ -4515,6 +4521,7 @@ function roomify_dashboard_views_default_views() { t('‹ previous'), t('next ›'), t('last »'), + t('Hide all'), t('No notifications to read.'), t('All'), t('Content pane'), diff --git a/themes/roomify/roomify_adminimal_theme/css/roomify_adminimal_theme.css b/themes/roomify/roomify_adminimal_theme/css/roomify_adminimal_theme.css index 185bbec7..6146ffd2 100644 --- a/themes/roomify/roomify_adminimal_theme/css/roomify_adminimal_theme.css +++ b/themes/roomify/roomify_adminimal_theme/css/roomify_adminimal_theme.css @@ -2719,6 +2719,14 @@ body.adminimal-skin-material table.views-table tbody tr td { top: 15px; } } +.view-dashboard-notifications .view-header { + margin-bottom: 15px; + width: 100%; + display: inline-block; +} +.view-dashboard-notifications .view-header a { + float: right; +} .view-dashboard-notifications .views-row { color: white; margin-bottom: 15px; diff --git a/themes/roomify/roomify_adminimal_theme/less/components/dashboard.less b/themes/roomify/roomify_adminimal_theme/less/components/dashboard.less index 974a76c0..cd51a811 100644 --- a/themes/roomify/roomify_adminimal_theme/less/components/dashboard.less +++ b/themes/roomify/roomify_adminimal_theme/less/components/dashboard.less @@ -418,6 +418,14 @@ } .view-dashboard-notifications { + .view-header { + margin-bottom: 15px; + width: 100%; + display: inline-block; + a { + float: right; + } + } .views-row { color: white; margin-bottom: 15px; From 76f5bc0992d1b43822f9ab5d3bf3fad8f7064504 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Caruso?= Date: Fri, 24 Nov 2017 18:01:53 +0100 Subject: [PATCH 08/16] =?UTF-8?q?Add=20dependency=20of=20=E2=80=9Cuser=5Fn?= =?UTF-8?q?otifications=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/roomify/roomify_system/roomify_system.info | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/roomify/roomify_system/roomify_system.info b/modules/roomify/roomify_system/roomify_system.info index e41378db..46e1bd81 100644 --- a/modules/roomify/roomify_system/roomify_system.info +++ b/modules/roomify/roomify_system/roomify_system.info @@ -10,6 +10,7 @@ dependencies[] = file_entity dependencies[] = panels dependencies[] = panels_mini dependencies[] = logintoboggan +dependencies[] = user_notifications dependencies[] = variable_realm files[] = views/roomify_system_handler_edit_link_field.inc From 9796d6758cf49a3701de57c90ba4779c26073ff2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Caruso?= Date: Fri, 24 Nov 2017 18:21:00 +0100 Subject: [PATCH 09/16] =?UTF-8?q?FadeOut=20effect=20on=20=E2=80=9CHide?= =?UTF-8?q?=E2=80=9D=20a=20notification?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../roomify_dashboard.views_default.inc | 4 +- .../css/roomify_adminimal_theme.css | 17 ++++--- .../js/roomify_adminimal_theme.js | 8 +++ .../less/components/dashboard.less | 51 ++++++++++--------- 4 files changed, 48 insertions(+), 32 deletions(-) diff --git a/modules/roomify/roomify_dashboard/roomify_dashboard.views_default.inc b/modules/roomify/roomify_dashboard/roomify_dashboard.views_default.inc index 740fecc6..a0087373 100644 --- a/modules/roomify/roomify_dashboard/roomify_dashboard.views_default.inc +++ b/modules/roomify/roomify_dashboard/roomify_dashboard.views_default.inc @@ -4452,7 +4452,7 @@ function roomify_dashboard_views_default_views() { $handler->display->display_options['header']['area']['id'] = 'area'; $handler->display->display_options['header']['area']['table'] = 'views'; $handler->display->display_options['header']['area']['field'] = 'area'; - $handler->display->display_options['header']['area']['content'] = 'Hide all'; + $handler->display->display_options['header']['area']['content'] = 'Hide all'; $handler->display->display_options['header']['area']['format'] = 'filtered_text'; /* No results behavior: Global: Text area */ $handler->display->display_options['empty']['area']['id'] = 'area'; @@ -4521,7 +4521,7 @@ function roomify_dashboard_views_default_views() { t('‹ previous'), t('next ›'), t('last »'), - t('Hide all'), + t('Hide all'), t('No notifications to read.'), t('All'), t('Content pane'), diff --git a/themes/roomify/roomify_adminimal_theme/css/roomify_adminimal_theme.css b/themes/roomify/roomify_adminimal_theme/css/roomify_adminimal_theme.css index 6146ffd2..fdc48456 100644 --- a/themes/roomify/roomify_adminimal_theme/css/roomify_adminimal_theme.css +++ b/themes/roomify/roomify_adminimal_theme/css/roomify_adminimal_theme.css @@ -2719,31 +2719,34 @@ body.adminimal-skin-material table.views-table tbody tr td { top: 15px; } } -.view-dashboard-notifications .view-header { +.pane-dashboard-notifications-panel-pane-1 .ajax-progress { + display: none; +} +.pane-dashboard-notifications-panel-pane-1 .view-dashboard-notifications .view-header { margin-bottom: 15px; width: 100%; display: inline-block; } -.view-dashboard-notifications .view-header a { +.pane-dashboard-notifications-panel-pane-1 .view-dashboard-notifications .view-header a { float: right; } -.view-dashboard-notifications .views-row { +.pane-dashboard-notifications-panel-pane-1 .view-dashboard-notifications .views-row { color: white; margin-bottom: 15px; } -.view-dashboard-notifications .views-row .views-field-type { +.pane-dashboard-notifications-panel-pane-1 .view-dashboard-notifications .views-row .views-field-type { padding: 5px 12px; background: #405467; } -.view-dashboard-notifications .views-row .views-field-user-notifications-message { +.pane-dashboard-notifications-panel-pane-1 .view-dashboard-notifications .views-row .views-field-user-notifications-message { padding: 7px 12px; background: #687c90; } -.view-dashboard-notifications .views-row .views-field-hide { +.pane-dashboard-notifications-panel-pane-1 .view-dashboard-notifications .views-row .views-field-hide { float: right; margin: 5px 12px; } -.view-dashboard-notifications .views-row .views-field-hide a { +.pane-dashboard-notifications-panel-pane-1 .view-dashboard-notifications .views-row .views-field-hide a { color: white; } .page-admin-bat-config-booking-add-roomify-accommodation-booking #bat-booking-edit-form .field-name-booking-end-date, diff --git a/themes/roomify/roomify_adminimal_theme/js/roomify_adminimal_theme.js b/themes/roomify/roomify_adminimal_theme/js/roomify_adminimal_theme.js index 39f36cbc..5c5b2dfc 100644 --- a/themes/roomify/roomify_adminimal_theme/js/roomify_adminimal_theme.js +++ b/themes/roomify/roomify_adminimal_theme/js/roomify_adminimal_theme.js @@ -37,6 +37,14 @@ Drupal.behaviors.roomify_admin_js = { if (('table tbody td a.references-dialog-activate.waves-effect').length > 0) { $('table tbody td a.references-dialog-activate.waves-effect').removeClass('waves-effect'); } + + $('.view-dashboard-notifications .views-field-hide a').once().click(function() { + $(this).closest('.views-row').fadeOut('slow'); + }); + $('.view-dashboard-notifications .hide-all').once().click(function() { + $(this).closest('.view').find('.view-content').fadeOut('slow'); + $(this).closest('.view').find('ul.pager').fadeOut('slow'); + }); } }; diff --git a/themes/roomify/roomify_adminimal_theme/less/components/dashboard.less b/themes/roomify/roomify_adminimal_theme/less/components/dashboard.less index cd51a811..dc523d6e 100644 --- a/themes/roomify/roomify_adminimal_theme/less/components/dashboard.less +++ b/themes/roomify/roomify_adminimal_theme/less/components/dashboard.less @@ -417,31 +417,36 @@ } } -.view-dashboard-notifications { - .view-header { - margin-bottom: 15px; - width: 100%; - display: inline-block; - a { - float: right; - } +.pane-dashboard-notifications-panel-pane-1 { + .ajax-progress { + display: none; } - .views-row { - color: white; - margin-bottom: 15px; - .views-field-type { - padding: 5px 12px; - background: #405467; - } - .views-field-user-notifications-message { - padding: 7px 12px; - background: #687c90; - } - .views-field-hide { - float: right; - margin: 5px 12px; + .view-dashboard-notifications { + .view-header { + margin-bottom: 15px; + width: 100%; + display: inline-block; a { - color: white; + float: right; + } + } + .views-row { + color: white; + margin-bottom: 15px; + .views-field-type { + padding: 5px 12px; + background: #405467; + } + .views-field-user-notifications-message { + padding: 7px 12px; + background: #687c90; + } + .views-field-hide { + float: right; + margin: 5px 12px; + a { + color: white; + } } } } From a2f2ddc687060323ec4ad1589b7a440f96c76895 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Caruso?= Date: Fri, 1 Dec 2017 17:09:53 +0100 Subject: [PATCH 10/16] =?UTF-8?q?Dashboard=20=E2=80=9CNotification?= =?UTF-8?q?=E2=80=9D=20icon?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../roomify_dashboard.views_default.inc | 2 +- .../css/roomify_adminimal_theme.css | 17 +++++++++++++++++ .../images/dashboard/notification.png | Bin 0 -> 50704 bytes .../images/dashboard/notification.svg | 1 + .../less/components/dashboard.less | 15 +++++++++++++++ 5 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 themes/roomify/roomify_adminimal_theme/images/dashboard/notification.png create mode 100644 themes/roomify/roomify_adminimal_theme/images/dashboard/notification.svg diff --git a/modules/roomify/roomify_dashboard/roomify_dashboard.views_default.inc b/modules/roomify/roomify_dashboard/roomify_dashboard.views_default.inc index a0087373..670b6e5e 100644 --- a/modules/roomify/roomify_dashboard/roomify_dashboard.views_default.inc +++ b/modules/roomify/roomify_dashboard/roomify_dashboard.views_default.inc @@ -4435,7 +4435,7 @@ function roomify_dashboard_views_default_views() { /* Display: Master */ $handler = $view->new_display('default', 'Master', 'default'); - $handler->display->display_options['title'] = 'Notifications'; + $handler->display->display_options['title'] = 'Notifications'; $handler->display->display_options['use_ajax'] = TRUE; $handler->display->display_options['use_more_always'] = FALSE; $handler->display->display_options['access']['type'] = 'none'; diff --git a/themes/roomify/roomify_adminimal_theme/css/roomify_adminimal_theme.css b/themes/roomify/roomify_adminimal_theme/css/roomify_adminimal_theme.css index fdc48456..6c6adcb1 100644 --- a/themes/roomify/roomify_adminimal_theme/css/roomify_adminimal_theme.css +++ b/themes/roomify/roomify_adminimal_theme/css/roomify_adminimal_theme.css @@ -2685,6 +2685,23 @@ body.adminimal-skin-material table.views-table tbody tr td { top: 15px; } } +.roomify-dashboard #notifications-tab { + background: url("../images/dashboard/notification.png") center center no-repeat; + background: url("../images/dashboard/notification.svg") center center no-repeat, linear-gradient(transparent, transparent); + display: inline-block; + width: 18px; + height: 18px; + position: relative; + top: 4px; + right: 6px; +} +@media (max-width: 991px) { + .roomify-dashboard #notifications-tab { + position: absolute; + left: 20px; + top: 15px; + } +} .roomify-dashboard #dashboard-stays-tab { background: url("../images/dashboard/reservation.png") center center no-repeat; background: url("../images/dashboard/reservation.svg") center center no-repeat, linear-gradient(transparent, transparent); diff --git a/themes/roomify/roomify_adminimal_theme/images/dashboard/notification.png b/themes/roomify/roomify_adminimal_theme/images/dashboard/notification.png new file mode 100644 index 0000000000000000000000000000000000000000..e623fdaf25a36a057ee3f9e97ff302b1495132ae GIT binary patch literal 50704 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 edZN1ub$5clepr|GbyGg@cksaB{jaRNZ~g}#6u \ No newline at end of file diff --git a/themes/roomify/roomify_adminimal_theme/less/components/dashboard.less b/themes/roomify/roomify_adminimal_theme/less/components/dashboard.less index dc523d6e..fb70999b 100644 --- a/themes/roomify/roomify_adminimal_theme/less/components/dashboard.less +++ b/themes/roomify/roomify_adminimal_theme/less/components/dashboard.less @@ -385,6 +385,21 @@ top: 15px; } } + #notifications-tab { + background: url("../images/dashboard/notification.png") center center no-repeat; + background: url("../images/dashboard/notification.svg") center center no-repeat, linear-gradient(transparent, transparent); + display: inline-block; + width: 18px; + height: 18px; + position: relative; + top: 4px; + right: 6px; + @media (max-width: @screen-sm-max) { + position: absolute; + left: 20px; + top: 15px; + } + } #dashboard-stays-tab { background: url("../images/dashboard/reservation.png") center center no-repeat; background: url("../images/dashboard/reservation.svg") center center no-repeat, linear-gradient(transparent, transparent); From 41b1bd3dc24c04646218a073d96760d4aca04d86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Caruso?= Date: Fri, 1 Dec 2017 17:17:01 +0100 Subject: [PATCH 11/16] =?UTF-8?q?=E2=80=9CUser=20notification=20type?= =?UTF-8?q?=E2=80=9D=20views=20field?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...eld--dashboard-notifications--type.tpl.php | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 themes/roomify/roomify_adminimal_theme/templates/views-view-field--dashboard-notifications--type.tpl.php diff --git a/themes/roomify/roomify_adminimal_theme/templates/views-view-field--dashboard-notifications--type.tpl.php b/themes/roomify/roomify_adminimal_theme/templates/views-view-field--dashboard-notifications--type.tpl.php new file mode 100644 index 00000000..e7641625 --- /dev/null +++ b/themes/roomify/roomify_adminimal_theme/templates/views-view-field--dashboard-notifications--type.tpl.php @@ -0,0 +1,28 @@ +{$field->field_alias} + * + * The above will guarantee that you'll always get the correct data, + * regardless of any changes in the aliasing that might happen if + * the view is modified. + */ +?> +label; +?> From 65427b080db7b623ea1319d0bb7b85c43ea06e3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Caruso?= Date: Fri, 1 Dec 2017 18:02:35 +0100 Subject: [PATCH 12/16] Show a red dot for unseen notifications --- .../roomify_dashboard.module | 22 +++++++++++++++++++ .../css/roomify_adminimal_theme.css | 9 ++++++++ .../less/components/dashboard.less | 9 ++++++++ 3 files changed, 40 insertions(+) diff --git a/modules/roomify/roomify_dashboard/roomify_dashboard.module b/modules/roomify/roomify_dashboard/roomify_dashboard.module index a24503fc..49762645 100644 --- a/modules/roomify/roomify_dashboard/roomify_dashboard.module +++ b/modules/roomify/roomify_dashboard/roomify_dashboard.module @@ -170,6 +170,28 @@ function roomify_dashboard_views_pre_render(&$view) { $view->exposed_widgets = FALSE; } } + + if ($view->name == 'dashboard_notifications') { + global $user; + + $last_user_notifications_id = db_select('user_notifications', 'u') + ->fields('u', array('user_notifications_id')) + ->condition('author_uid', $user->uid) + ->condition('state', 'unseen') + ->orderBy('created', 'DESC') + ->range(0, 1) + ->execute() + ->fetchField(); + + if ($last_user_notifications_id !== FALSE) { + if (!isset($user->data['last_user_notifications_id']) || $user->data['last_user_notifications_id'] < $last_user_notifications_id) { + $view->set_title($view->get_title() . '
'); + + $user->data['last_user_notifications_id'] = $last_user_notifications_id; + user_save($user); + } + } + } } /** diff --git a/themes/roomify/roomify_adminimal_theme/css/roomify_adminimal_theme.css b/themes/roomify/roomify_adminimal_theme/css/roomify_adminimal_theme.css index 6c6adcb1..5c6b3daa 100644 --- a/themes/roomify/roomify_adminimal_theme/css/roomify_adminimal_theme.css +++ b/themes/roomify/roomify_adminimal_theme/css/roomify_adminimal_theme.css @@ -2702,6 +2702,15 @@ body.adminimal-skin-material table.views-table tbody tr td { top: 15px; } } +.roomify-dashboard #notifications-to-read { + background: red; + width: 10px; + height: 10px; + border-radius: 5px; + position: absolute; + top: 4px; + right: 4px; +} .roomify-dashboard #dashboard-stays-tab { background: url("../images/dashboard/reservation.png") center center no-repeat; background: url("../images/dashboard/reservation.svg") center center no-repeat, linear-gradient(transparent, transparent); diff --git a/themes/roomify/roomify_adminimal_theme/less/components/dashboard.less b/themes/roomify/roomify_adminimal_theme/less/components/dashboard.less index fb70999b..0674cc84 100644 --- a/themes/roomify/roomify_adminimal_theme/less/components/dashboard.less +++ b/themes/roomify/roomify_adminimal_theme/less/components/dashboard.less @@ -400,6 +400,15 @@ top: 15px; } } + #notifications-to-read { + background: red; + width: 10px; + height: 10px; + border-radius: 5px; + position: absolute; + top: 4px; + right: 4px; + } #dashboard-stays-tab { background: url("../images/dashboard/reservation.png") center center no-repeat; background: url("../images/dashboard/reservation.svg") center center no-repeat, linear-gradient(transparent, transparent); From 1089d476fd9ff7ceb837b14c01133e05bb3499f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Caruso?= Date: Mon, 4 Dec 2017 16:06:33 +0100 Subject: [PATCH 13/16] Code style --- modules/roomify/roomify_system/roomify_system.install | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/roomify/roomify_system/roomify_system.install b/modules/roomify/roomify_system/roomify_system.install index 71eee0f0..9a7afa53 100644 --- a/modules/roomify/roomify_system/roomify_system.install +++ b/modules/roomify/roomify_system/roomify_system.install @@ -1087,5 +1087,4 @@ function roomify_system_update_7065() { */ function roomify_system_update_7066() { module_enable(array('views_refresh')); - } - \ No newline at end of file +} From 285bbcac74c97dab57378964be4d3d30643333a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Caruso?= Date: Tue, 5 Dec 2017 12:30:53 +0100 Subject: [PATCH 14/16] Improve query for last user notification --- .../roomify_dashboard.module | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/modules/roomify/roomify_dashboard/roomify_dashboard.module b/modules/roomify/roomify_dashboard/roomify_dashboard.module index 49762645..8a1f7afa 100644 --- a/modules/roomify/roomify_dashboard/roomify_dashboard.module +++ b/modules/roomify/roomify_dashboard/roomify_dashboard.module @@ -174,16 +174,19 @@ function roomify_dashboard_views_pre_render(&$view) { if ($view->name == 'dashboard_notifications') { global $user; - $last_user_notifications_id = db_select('user_notifications', 'u') - ->fields('u', array('user_notifications_id')) - ->condition('author_uid', $user->uid) - ->condition('state', 'unseen') - ->orderBy('created', 'DESC') - ->range(0, 1) - ->execute() - ->fetchField(); - - if ($last_user_notifications_id !== FALSE) { + $query = new EntityFieldQuery(); + + $query->entityCondition('entity_type', 'user_notifications') + ->propertyCondition('state', 'unseen') + ->fieldCondition('user_notifications_recipient_uid', 'target_id', $user->uid) + ->propertyOrderBy('created', 'DESC') + ->range(0, 1); + + $last_user_notification = $query->execute(); + + if (!empty($last_user_notification)) { + $last_user_notifications_id = key($last_user_notification['user_notifications']); + if (!isset($user->data['last_user_notifications_id']) || $user->data['last_user_notifications_id'] < $last_user_notifications_id) { $view->set_title($view->get_title() . '
'); From d03116d946116bfc84f18da61ac76757a1c87855 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Caruso?= Date: Tue, 5 Dec 2017 12:50:27 +0100 Subject: [PATCH 15/16] =?UTF-8?q?Replace=20=E2=80=9CHide=E2=80=9D=20with?= =?UTF-8?q?=20a=20close=20icon?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../css/roomify_adminimal_theme.css | 8 ++++++-- .../less/components/dashboard.less | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/themes/roomify/roomify_adminimal_theme/css/roomify_adminimal_theme.css b/themes/roomify/roomify_adminimal_theme/css/roomify_adminimal_theme.css index 5c6b3daa..d982eb4c 100644 --- a/themes/roomify/roomify_adminimal_theme/css/roomify_adminimal_theme.css +++ b/themes/roomify/roomify_adminimal_theme/css/roomify_adminimal_theme.css @@ -2770,10 +2770,14 @@ body.adminimal-skin-material table.views-table tbody tr td { } .pane-dashboard-notifications-panel-pane-1 .view-dashboard-notifications .views-row .views-field-hide { float: right; - margin: 5px 12px; + margin: 5px 8px; } .pane-dashboard-notifications-panel-pane-1 .view-dashboard-notifications .views-row .views-field-hide a { - color: white; + display: block; + text-indent: -999999px; + width: 24px; + background: url('../images/close.png') center center no-repeat; + background-size: 10px; } .page-admin-bat-config-booking-add-roomify-accommodation-booking #bat-booking-edit-form .field-name-booking-end-date, #bat-booking-edit-roomify-accommodation-booking-form .field-name-booking-end-date, diff --git a/themes/roomify/roomify_adminimal_theme/less/components/dashboard.less b/themes/roomify/roomify_adminimal_theme/less/components/dashboard.less index 0674cc84..6b30a9f9 100644 --- a/themes/roomify/roomify_adminimal_theme/less/components/dashboard.less +++ b/themes/roomify/roomify_adminimal_theme/less/components/dashboard.less @@ -467,9 +467,13 @@ } .views-field-hide { float: right; - margin: 5px 12px; + margin: 5px 8px; a { - color: white; + display: block; + text-indent: -999999px; + width: 24px; + background: url('../images/close.png') center center no-repeat; + background-size: 10px; } } } From 9d4c21f531f2c558d31aa8bf1ea51107b0cc35b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Caruso?= Date: Tue, 5 Dec 2017 15:02:43 +0100 Subject: [PATCH 16/16] Code style --- .../views/roomify_dashboard_handler_hide_notification.inc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/roomify/roomify_dashboard/views/roomify_dashboard_handler_hide_notification.inc b/modules/roomify/roomify_dashboard/views/roomify_dashboard_handler_hide_notification.inc index 064c643d..b4775f38 100644 --- a/modules/roomify/roomify_dashboard/views/roomify_dashboard_handler_hide_notification.inc +++ b/modules/roomify/roomify_dashboard/views/roomify_dashboard_handler_hide_notification.inc @@ -4,6 +4,9 @@ * @file */ +/** + * + */ class roomify_dashboard_handler_hide_notification extends views_handler_field_entity { /** @@ -26,7 +29,7 @@ class roomify_dashboard_handler_hide_notification extends views_handler_field_en public function render($values) { $user_notification = $this->get_value($values); - return l('Hide', 'user-notifications/' . $user_notification->user_notifications_id . '/hide', array('attributes' => array('class' => 'use-ajax'))); + return l(t('Hide'), 'user-notifications/' . $user_notification->user_notifications_id . '/hide', array('attributes' => array('class' => 'use-ajax'))); } }