From c0d185bb6d7ca3e4615444ea9391dcb3a5c1c68f Mon Sep 17 00:00:00 2001 From: Bachir Soussi Chiadmi Date: Sun, 11 Mar 2018 18:44:32 +0100 Subject: [PATCH] Chutier link from audio player cartel is working git add . --- .../edlp_studio/assets/js/edlp_studio.js | 60 ++++++- .../edlp_studio/edlp_studio.libraries.yml | 5 +- .../figli/edlp_studio/edlp_studio.module | 57 +++++-- .../figli/edlp_studio/edlp_studio.routing.yml | 9 +- .../edlp_studio/src/ChutierListBuilder.php | 9 + .../src/Controller/ChutierController.php | 161 ++++++++++++++++-- .../figli/edlp_studio/src/Entity/Chutier.php | 52 ++++++ .../src/Entity/ChutierInterface.php | 29 ++++ .../edlptheme/assets/dist/img/favori-off.svg | 1 + .../edlptheme/assets/dist/img/favori-on.svg | 1 + .../edlptheme/assets/dist/scripts/main.min.js | 1 + .../edlptheme/assets/dist/styles/app.min.css | 84 +++++---- .../edlptheme/assets/img/favori-off.svg | 39 +++++ .../custom/edlptheme/assets/img/favori-on.svg | 69 ++++++++ .../custom/edlptheme/assets/scripts/main.js | 1 + .../custom/edlptheme/assets/styles/app.scss | 110 ++++++++---- .../__node--enregistrement--index.html.twig | 78 --------- ...e--enregistrement--player-cartel.html.twig | 55 +++--- ...play.node.enregistrement.player_cartel.yml | 5 + ...ystem.action.user_add_role_action.user.yml | 14 ++ ...em.action.user_remove_role_action.user.yml | 14 ++ .../config/sync/user.role.authenticated.yml | 1 + sites/default/config/sync/user.role.user.yml | 9 + 23 files changed, 667 insertions(+), 197 deletions(-) create mode 100644 sites/all/themes/custom/edlptheme/assets/dist/img/favori-off.svg create mode 100644 sites/all/themes/custom/edlptheme/assets/dist/img/favori-on.svg create mode 100644 sites/all/themes/custom/edlptheme/assets/img/favori-off.svg create mode 100644 sites/all/themes/custom/edlptheme/assets/img/favori-on.svg delete mode 100644 sites/all/themes/custom/edlptheme/templates/content/__node--enregistrement--index.html.twig create mode 100644 sites/default/config/sync/system.action.user_add_role_action.user.yml create mode 100644 sites/default/config/sync/system.action.user_remove_role_action.user.yml create mode 100644 sites/default/config/sync/user.role.user.yml diff --git a/sites/all/modules/figli/edlp_studio/assets/js/edlp_studio.js b/sites/all/modules/figli/edlp_studio/assets/js/edlp_studio.js index 136e84934..59305d35d 100644 --- a/sites/all/modules/figli/edlp_studio/assets/js/edlp_studio.js +++ b/sites/all/modules/figli/edlp_studio/assets/js/edlp_studio.js @@ -1,5 +1,63 @@ (function ($, Drupal) { - + function init(){ + console.log('Studio Init'); + initEvents(); + initAjax(); + }; + function initEvents(){ + $('body').on('new-audio-cartel-loaded', initAjax); + }; + + function initAjax(){ + console.log('studio initAjax chutier'); + $('.chutier-ajax-link:not(.ajax-enabled)') + .addClass('ajax-enabled') + .on('click', onClickAjaxLink); + }; + + function onClickAjaxLink(e){ + console.log('studio onClickAjaxLink chutier'); + e.preventDefault(); + // var $this = $(this); + addRemoveToChutier($(this)); + // switch($this.attr('action')){ + // case 'add': + // // TODO: get target chutier + // addToChutier($this); + // break; + // case 'remove': + // // TODO: if we use more than one chutoer per user get target chutier + // removeFromChutier($this); + // break; + // } + return false; + }; + + function addRemoveToChutier($link){ + // var ajax_path = 'edlp_studio/ajax/chutier/add/'+id; // + '/' +cid; + var ajax_path = $link.attr('data-drupal-link-system-path'); + var path = window.location.origin + drupalSettings.path.baseUrl + ajax_path; + $link.addClass('ajax-loading'); + $.getJSON(path, {}) + .done(function(data){ + onActionToChutierDone($link, data); + }) + .fail(function(jqxhr, textStatus, error){ + onErrorActionToChutier(jqxhr, textStatus, error, $link); + }); + }; + + function onActionToChutierDone($link, data){ + console.log('onActionToChutierDone',data); + $link.replaceWith(data.new_link); + initAjax(); + }; + + function onErrorActionToChutier(jqxhr, textStatus, error, $link){ + console.warn('add to chuttier load failed : '+error, jqxhr.responseText); + }; + + init(); })(jQuery, Drupal); diff --git a/sites/all/modules/figli/edlp_studio/edlp_studio.libraries.yml b/sites/all/modules/figli/edlp_studio/edlp_studio.libraries.yml index d598a6f45..61a3935d5 100644 --- a/sites/all/modules/figli/edlp_studio/edlp_studio.libraries.yml +++ b/sites/all/modules/figli/edlp_studio/edlp_studio.libraries.yml @@ -1,3 +1,6 @@ edlp_studio-library: js: - js/edlp_studio.js: {} + assets/js/edlp_studio.js: { scope: footer } + dependencies: + - core/drupalSettings + - core/jquery diff --git a/sites/all/modules/figli/edlp_studio/edlp_studio.module b/sites/all/modules/figli/edlp_studio/edlp_studio.module index a7ea7303d..26e93f09d 100644 --- a/sites/all/modules/figli/edlp_studio/edlp_studio.module +++ b/sites/all/modules/figli/edlp_studio/edlp_studio.module @@ -6,7 +6,8 @@ */ use Drupal\Core\Routing\RouteMatchInterface; - +use Drupal\Core\Url; +use Drupal\edlp_studio\Entity\Chutier; /** * Implements hook_help(). */ @@ -23,6 +24,15 @@ function edlp_studio_help($route_name, RouteMatchInterface $route_match) { } } +/** + * Implements hook_page_attachments(). + * @param array $attachments + */ +function edlp_studio_page_attachments(array &$attachments) { + $attachments['#attached']['library'][] = 'edlp_studio/edlp_studio-library'; +} + + /** * hook_entity_extra_field_info() * @@ -30,8 +40,8 @@ function edlp_studio_help($route_name, RouteMatchInterface $route_match) { function edlp_studio_entity_extra_field_info(){ $extra = []; // TODO: get node content type by settings @see readme - $extra['node']['enregistrement']['display']['add_to_chutier'] = [ - 'label' => t('Add to chutier link'), + $extra['node']['enregistrement']['display']['chutier_actions'] = [ + 'label' => t('Chutier actions'), 'description' => 'Display a link to add the content to chutier', 'weight' => 99, 'visible' => FALSE, @@ -45,18 +55,41 @@ function edlp_studio_entity_extra_field_info(){ * @see https://www.amazeelabs.com/en/render-menu-tree-custom-code-drupal-8 */ function edlp_studio_node_view(array &$build, \Drupal\Core\Entity\EntityInterface $entity, \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display, $view_mode) { - $display_settings = $display->getComponent('add_to_chutier'); + $display_settings = $display->getComponent('chutier_actions'); if (!empty($display_settings)) { // dpm($entity); // dpm($entity->id()); - $url = Url::fromRoute('edlp_studio.chutier_controller_add_content', ['id'=>$entity->id()], array( - 'attributes' => array( - 'class' => ['add-to-chutier-link', 'ajax-link'], - 'target_id' => $entity->id(), - ) - )); - $build['add_to_chutier'] = array( - '#title' => t("Add this content to chutier."), + $user = \Drupal::currentUser(); + // dpm($user); + if($user->id() == 0){ + // // TODO: check if user loged in ? yes -> links : no : popup message + // $action = 'add'; + } + // else{ + // // TODO: check if node already in chutier ? no -> add link : yes -> remove link + // // use getUserChutiersContents() from \Drupal\edlp_studio\ChutierInterface + // $contents = Chutier::getUserChutiersContents($user->id()); + // dpm($contents); + // if(array_search($entity->id(), $contents) === false){ + // $action = 'add'; + // }else{ + // $action = 'remove'; + // } + // } + // $args = array( + // 'action'=>$action, + // 'id'=>$entity->id() + // ); + // $url = Url::fromRoute('edlp_studio.chutier_controller_ajax_add_content', $args, array( + // 'attributes' => array( + // 'class' => ['chutier-link','chutier-ajax-link'], + // 'action' => $action, + // 'target_id' => $entity->id(), + // ) + // )); + $url = Chutier::getActionsUrl($entity->id(), $user->id()); + $build['chutier_actions'] = array( + '#title' => t("Chutier."), '#type' => 'link', '#url' => $url, '#options'=>array( diff --git a/sites/all/modules/figli/edlp_studio/edlp_studio.routing.yml b/sites/all/modules/figli/edlp_studio/edlp_studio.routing.yml index 18b6167f5..e09de976e 100644 --- a/sites/all/modules/figli/edlp_studio/edlp_studio.routing.yml +++ b/sites/all/modules/figli/edlp_studio/edlp_studio.routing.yml @@ -6,10 +6,11 @@ edlp_studio.studio: requirements: _permission: 'administer studio' -edlp_studio.chutier_controller_add_content: - path: '/studio/chutier/add/{id}' +edlp_studio.chutier_controller_ajax_add_content: + path: '/edlp_studio/ajax/chutier/{action}/{id}/{cid}' defaults: - _controller: '\Drupal\edlp_studio\Controller\ChutierController::addContent' - _title: 'Add content to chutier' + _controller: '\Drupal\edlp_studio\Controller\ChutierController::AddRemoveContent' + _title: 'Add/remove content to/from chutier' + cid: null requirements: _permission: 'use chutier' diff --git a/sites/all/modules/figli/edlp_studio/src/ChutierListBuilder.php b/sites/all/modules/figli/edlp_studio/src/ChutierListBuilder.php index c1082379e..3bd258f17 100644 --- a/sites/all/modules/figli/edlp_studio/src/ChutierListBuilder.php +++ b/sites/all/modules/figli/edlp_studio/src/ChutierListBuilder.php @@ -20,6 +20,8 @@ class ChutierListBuilder extends EntityListBuilder { public function buildHeader() { $header['id'] = $this->t('Chutier ID'); $header['name'] = $this->t('Name'); + $header['user'] = $this->t('User'); + // $header['default'] = $this->t('User id'); return $header + parent::buildHeader(); } @@ -34,6 +36,13 @@ class ChutierListBuilder extends EntityListBuilder { 'entity.chutier.edit_form', ['chutier' => $entity->id()] ); + $row['user'] = Link::createFromRoute( + $entity->getOwner()->getUserName(), + 'entity.user.canonical', + ['user' => $entity->getOwnerId()] + ); + + // $row['uid'] = $entity->getOwnerId(); return $row + parent::buildRow($entity); } diff --git a/sites/all/modules/figli/edlp_studio/src/Controller/ChutierController.php b/sites/all/modules/figli/edlp_studio/src/Controller/ChutierController.php index 9d225876f..b5eb9f907 100644 --- a/sites/all/modules/figli/edlp_studio/src/Controller/ChutierController.php +++ b/sites/all/modules/figli/edlp_studio/src/Controller/ChutierController.php @@ -3,38 +3,173 @@ namespace Drupal\edlp_studio\Controller; use Drupal\Core\Controller\ControllerBase; +use Drupal\Core\Session\AccountInterface; +use Drupal\User\UserDataInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\JsonResponse; +use Drupal\edlp_studio\Entity\Chutier; /** * Class ChutierController. */ class ChutierController extends ControllerBase { + protected $user; + protected $userdata; + /** - * Hello. + * Class constructor. + */ + public function __construct(AccountInterface $account, UserDataInterface $userdata) { + $this->user = $account; + $this->userdata = $userdata; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + // Instantiates this form class. + return new static( + // Load the service required to construct this class. + $container->get('current_user'), + $container->get('user.data') + ); + } + + + /** + * AdddContent. * * @return json - * Return Hello string. + * Return status. */ - public function AddContent($id) { - // TODO: get current user - // TODO: check if default chutier exists ? yes use it : no create and use it. - // TODO: add $id to documents field - // TODO: return status + public function AddRemoveContent($action, $id, $cid) { + $this->error_message = null; + $status = 'ok'; + // get current user : + // done by DependencyInjection of AccountInterface - $response = new JsonResponse(); + // TODO: use the send chutier instead of default + // check if default chutier exists ? yes use it : no create and use it. + $this->checkChutier(); + // dpm($this->chutier); - $data = array( - 'test' => 'Hello chutier', + // check if $id exists, is a document, and does not already exist in chutier + switch($action){ + case 'add': + $this->validateNewDoc($id); + if(!$this->error_message){ + // add $id to documents field + $this->addNewDoc($id); + $message = t('Node @id added to chutier.', array('@id'=>$id)); + }else{ + $status = "error"; + } + break; + case 'remove': + $this->removeDoc($id); + $message = t('Node @id removed to chutier.', array('@id'=>$id)); + break; + } + + $url = Chutier::getActionsUrl($id, $this->user->id()); + $new_link_build = array( + '#title' => t("Chutier."), + '#type' => 'link', + '#url' => $url, + '#options'=>array( + 'attributes' => array( + 'data-drupal-link-system-path' => $url->getInternalPath() + ) + ) ); + $new_link = render($new_link_build); + if($status == 'error'){ + $message = $this->error_message; + } + + // JSON + $response = new JsonResponse(); + $data = array( + 'status' => $status, + 'message' => $message, + 'new_link' => $new_link, + ); $response->setData($data); - return $response; + + // classic html // return array( - // '#markup'=>'Hello Chutier' - // ); } + // '#markup'=>'Status : ' . $status . ' | Message : ' . $message, + // ); + } + + private function addNewDoc($id){ + $this->chutier->documents->appendItem($id); + $this->chutier->save(); + } + + private function removeDoc($id){ + $values = array_column($this->chutier->documents->getValue(), 'target_id'); + $index = array_search($id,$values); + $this->chutier->documents->removeItem($index); + $this->chutier->save(); + } + + private function validateNewDoc($id){ + $node = entity_load('node', $id); + if($node){ + // TODO: get node bundle by settings (@see readme) + if($node->getType() == 'enregistrement'){ + $docs = array_column($this->chutier->documents->getValue(), 'target_id'); + if( in_array($id, $docs) ){ + $this->error_message = t("Node '@title'(@id) already exists in chutier '@name'(@cid)", array( + '@title'=>$node->getTitle(), + '@id'=>$id, + '@name' => $this->chutier->getName(), + '@cid' => $this->chutier->id()) + ); + } + }else{ + $this->error_message = t("Node @title (@id) is not an Enregistrement (@type)", array( + '@title'=>$node->getTitle(), + '@id'=>$id, + '@type' => $node->getType()) + ); + } + }else{ + $this->error_message = t("Node @id does not exists", array('@id'=>$id)); + } + } + + private function checkChutier(){ + $default_chutier_id = $this->userdata->get('edlp_studio', $this->user->id(), 'default_chutier'); + // dpm($this->default_chutier_id); + $this->chutier = entity_load('chutier', $default_chutier_id); + // if default chutier does not exists, create, save and record it + if(!$this->chutier){ + $this->createDefaultChutier(); + } + } + + private function createDefaultChutier(){ + // dpm('createDefaultChutier'); + $this->createChutier(); + $this->userdata->set('edlp_studio', $this->user->id(), 'default_chutier', $this->chutier->id()); + } + + public function createChutier(){ + $chutier = array( + 'id' => NULL, + 'uid' => $this->user->id(), + 'status' => TRUE, + 'name' => t('Default'), + ); + $this->chutier = entity_create('chutier', $chutier); + $this->chutier->save(); } } diff --git a/sites/all/modules/figli/edlp_studio/src/Entity/Chutier.php b/sites/all/modules/figli/edlp_studio/src/Entity/Chutier.php index e9e063f8f..315a24612 100644 --- a/sites/all/modules/figli/edlp_studio/src/Entity/Chutier.php +++ b/sites/all/modules/figli/edlp_studio/src/Entity/Chutier.php @@ -8,6 +8,7 @@ use Drupal\Core\Entity\ContentEntityBase; use Drupal\Core\Entity\EntityChangedTrait; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\user\UserInterface; +use Drupal\Core\Url; /** * Defines the Chutier entity. @@ -240,4 +241,55 @@ class Chutier extends ContentEntityBase implements ChutierInterface { return $fields; } + /** + * {@inheritdoc} + */ + public static function getUserChutiersContents($uid){ + // TODO: use query if we use more than one chutier + // $query = \Drupal::entityQuery('chutier') + // ->condition('user_id', $uid); + // + // $chutiers_nids = $query->execute(); + // $chutiers = entity_load_multiple('chutier', $chutiers_nids); + // + // $contents = array(); + // foreach ($chutiers as $id => $chutier) { + // $contents[$id] = array_column($chutier->documents->getValue(), 'target_id'); + // } + + /** @var UserDataInterface $userData */ + $userData = \Drupal::service('user.data'); + $default_chutier_id = $userData->get('edlp_studio', $uid, 'default_chutier'); + if($chutier = entity_load('chutier', $default_chutier_id)){ + return array_column($chutier->documents->getValue(), 'target_id'); + }else{ + return array(); + } + } + + /** + * {@inheritdoc} + */ + public static function getActionsUrl($id, $uid){ + $contents = self::getUserChutiersContents($uid); + // dpm($contents); + if(array_search($id, $contents) === false){ + $action = 'add'; + }else{ + $action = 'remove'; + } + $args = array( + 'action'=>$action, + 'id'=>$id + ); + $url = Url::fromRoute('edlp_studio.chutier_controller_ajax_add_content', $args, array( + 'attributes' => array( + 'class' => ['chutier-link','chutier-ajax-link'], + 'action' => $action, + 'target_id' => $id, + ) + )); + return $url; + } + } diff --git a/sites/all/modules/figli/edlp_studio/src/Entity/ChutierInterface.php b/sites/all/modules/figli/edlp_studio/src/Entity/ChutierInterface.php index d67dbac92..0a65d006b 100644 --- a/sites/all/modules/figli/edlp_studio/src/Entity/ChutierInterface.php +++ b/sites/all/modules/figli/edlp_studio/src/Entity/ChutierInterface.php @@ -74,4 +74,33 @@ interface ChutierInterface extends ContentEntityInterface, EntityChangedInterfac */ public function setPublished($published); + /** + * get the contents in user's chutiers + * + * @param int $uid + * user id + * + * @return array + * associative array of contents by chutiers + * + */ + public static function getUserChutiersContents($uid); + + + /** + * get the contents in user's chutiers + * + * @param int $id + * content id + * + * @param int $uid + * user id + * + * @return Drupal\Core\Url + * depending on action is add or remove + * + */ + public static function getActionsURL($id, $uid); + + } diff --git a/sites/all/themes/custom/edlptheme/assets/dist/img/favori-off.svg b/sites/all/themes/custom/edlptheme/assets/dist/img/favori-off.svg new file mode 100644 index 000000000..dcf534ac1 --- /dev/null +++ b/sites/all/themes/custom/edlptheme/assets/dist/img/favori-off.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/sites/all/themes/custom/edlptheme/assets/dist/img/favori-on.svg b/sites/all/themes/custom/edlptheme/assets/dist/img/favori-on.svg new file mode 100644 index 000000000..dd00a7cf0 --- /dev/null +++ b/sites/all/themes/custom/edlptheme/assets/dist/img/favori-on.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/sites/all/themes/custom/edlptheme/assets/dist/scripts/main.min.js b/sites/all/themes/custom/edlptheme/assets/dist/scripts/main.min.js index fe549e620..d15c3964d 100644 --- a/sites/all/themes/custom/edlptheme/assets/dist/scripts/main.min.js +++ b/sites/all/themes/custom/edlptheme/assets/dist/scripts/main.min.js @@ -131,6 +131,7 @@ edlp_vars = { console.log('AudioPlayer node loaded', data); this.$cartel.html(data.rendered); this.$cartel.removeClass('loading'); + _$body.trigger({'type':'new-audio-cartel-loaded'}); initAjaxLinks(); }, onNodeLoadFail(jqxhr, textStatus, error){ diff --git a/sites/all/themes/custom/edlptheme/assets/dist/styles/app.min.css b/sites/all/themes/custom/edlptheme/assets/dist/styles/app.min.css index 9a630ebf7..ed6be48e7 100644 --- a/sites/all/themes/custom/edlptheme/assets/dist/styles/app.min.css +++ b/sites/all/themes/custom/edlptheme/assets/dist/styles/app.min.css @@ -1365,67 +1365,75 @@ body.ajax-loading main[role="main"]:before { height: 100%; } #audio-player .cartel { position: relative; - max-width: 400px; + max-width: 350px; margin-left: 1em; background-color: white; opacity: 1; -webkit-transition: opacity 0.5s ease-in-out; - transition: opacity 0.5s ease-in-out; } + transition: opacity 0.5s ease-in-out; + white-space: nowrap; } #audio-player .cartel.loading { opacity: 0; } - #audio-player .cartel .first-cartel .entrees { + #audio-player .cartel .actions, #audio-player .cartel .cartels { + display: inline-block; + vertical-align: top; + white-space: normal; + position: relative; } + #audio-player .cartel .actions { + width: 1.5em; } + #audio-player .cartel .cartels .first-cartel .entrees { line-height: 0; } - #audio-player .cartel .first-cartel .entrees span { + #audio-player .cartel .cartels .first-cartel .entrees span { display: inline-block; width: 8px; height: 8px; background-color: black; margin-right: 3px; } - #audio-player .cartel .first-cartel .entrees span[tid='134'] { + #audio-player .cartel .cartels .first-cartel .entrees span[tid='134'] { background-color: #2b8f2f; } - #audio-player .cartel .first-cartel .entrees span[tid='121'] { + #audio-player .cartel .cartels .first-cartel .entrees span[tid='121'] { background-color: #3a33b6; } - #audio-player .cartel .first-cartel .entrees span[tid='125'] { + #audio-player .cartel .cartels .first-cartel .entrees span[tid='125'] { background-color: #2c9f57; } - #audio-player .cartel .first-cartel .entrees span[tid='119'] { + #audio-player .cartel .cartels .first-cartel .entrees span[tid='119'] { background-color: #c48978; } - #audio-player .cartel .first-cartel .entrees span[tid='132'] { + #audio-player .cartel .cartels .first-cartel .entrees span[tid='132'] { background-color: #5270bb; } - #audio-player .cartel .first-cartel .entrees span[tid='122'] { + #audio-player .cartel .cartels .first-cartel .entrees span[tid='122'] { background-color: #fb54d3; } - #audio-player .cartel .first-cartel .entrees span[tid='129'] { + #audio-player .cartel .cartels .first-cartel .entrees span[tid='129'] { background-color: #e07483; } - #audio-player .cartel .first-cartel .entrees span[tid='120'] { + #audio-player .cartel .cartels .first-cartel .entrees span[tid='120'] { background-color: #655845; } - #audio-player .cartel .first-cartel .entrees span[tid='130'] { + #audio-player .cartel .cartels .first-cartel .entrees span[tid='130'] { background-color: #7e0868; } - #audio-player .cartel .first-cartel .entrees span[tid='118'] { + #audio-player .cartel .cartels .first-cartel .entrees span[tid='118'] { background-color: #0e7121; } - #audio-player .cartel .first-cartel .entrees span[tid='127'] { + #audio-player .cartel .cartels .first-cartel .entrees span[tid='127'] { background-color: #dabd42; } - #audio-player .cartel .first-cartel .entrees span[tid='133'] { + #audio-player .cartel .cartels .first-cartel .entrees span[tid='133'] { background-color: #0399bb; } - #audio-player .cartel .first-cartel .entrees span[tid='128'] { + #audio-player .cartel .cartels .first-cartel .entrees span[tid='128'] { background-color: #399a1c; } - #audio-player .cartel .first-cartel .entrees span[tid='124'] { + #audio-player .cartel .cartels .first-cartel .entrees span[tid='124'] { background-color: #708540; } - #audio-player .cartel .first-cartel .entrees span[tid='116'] { + #audio-player .cartel .cartels .first-cartel .entrees span[tid='116'] { background-color: #191bff; } - #audio-player .cartel .first-cartel .entrees span[tid='117'] { + #audio-player .cartel .cartels .first-cartel .entrees span[tid='117'] { background-color: #279d84; } - #audio-player .cartel .first-cartel .entrees span[tid='131'] { + #audio-player .cartel .cartels .first-cartel .entrees span[tid='131'] { background-color: #5219ab; } - #audio-player .cartel .first-cartel .entrees span[tid='126'] { + #audio-player .cartel .cartels .first-cartel .entrees span[tid='126'] { background-color: #d49cb6; } - #audio-player .cartel .first-cartel .entrees span[tid='123'] { + #audio-player .cartel .cartels .first-cartel .entrees span[tid='123'] { background-color: #497715; } - #audio-player .cartel .first-cartel h2.node-title { + #audio-player .cartel .cartels .first-cartel h2.node-title { margin: 0.2em 0 0; font-size: 1em; } - #audio-player .cartel .first-cartel p { + #audio-player .cartel .cartels .first-cartel p { margin: 0; font-size: 0.75em; } - #audio-player .cartel .second-cartel { + #audio-player .cartel .cartels .second-cartel { position: absolute; top: 0; left: 0; @@ -1435,20 +1443,37 @@ body.ajax-loading main[role="main"]:before { opacity: 0; -webkit-transition: opacity 0.2s ease-in-out; transition: opacity 0.2s ease-in-out; } - #audio-player .cartel .second-cartel > * { + #audio-player .cartel .cartels .second-cartel > * { display: inline-block; vertical-align: top; } - #audio-player .cartel .second-cartel .col-left a { + #audio-player .cartel .cartels .second-cartel .col-left a { display: block; font-size: 0.90em; font-weight: 600; } - #audio-player .cartel .second-cartel .col-right { + #audio-player .cartel .cartels .second-cartel .col-right { font-size: 0.75em; } #audio-player .cartel:hover .second-cartel { opacity: 1; } #audio-player.is-playing .btns .play-pause { background-image: url(../img/audio-player-pause.svg); } +a.chutier-link { + display: block; + width: 1em; + height: 1em; + overflow: hidden; + text-indent: 50em; + background-position: center; + background-repeat: no-repeat; + background-size: contain; + background-image: url(../img/favori-off.svg); + -webkit-transition: opacity 0.2s ease-in-out; + transition: opacity 0.2s ease-in-out; } + a.chutier-link[action="remove"] { + background-image: url(../img/favori-on.svg); } + a.chutier-link.ajax-loading { + opacity: 0.2; } + body.path-agenda main .col > .wrapper { height: 100%; } @@ -1767,6 +1792,7 @@ footer { width: 350px; opacity: 1; } footer #block-userlogin { + pointer-events: all; position: relative; width: 20px; height: 20px; } diff --git a/sites/all/themes/custom/edlptheme/assets/img/favori-off.svg b/sites/all/themes/custom/edlptheme/assets/img/favori-off.svg new file mode 100644 index 000000000..8ce33fbd6 --- /dev/null +++ b/sites/all/themes/custom/edlptheme/assets/img/favori-off.svg @@ -0,0 +1,39 @@ + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/sites/all/themes/custom/edlptheme/assets/img/favori-on.svg b/sites/all/themes/custom/edlptheme/assets/img/favori-on.svg new file mode 100644 index 000000000..51258472c --- /dev/null +++ b/sites/all/themes/custom/edlptheme/assets/img/favori-on.svg @@ -0,0 +1,69 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/sites/all/themes/custom/edlptheme/assets/scripts/main.js b/sites/all/themes/custom/edlptheme/assets/scripts/main.js index 340e7ecb5..7eca5fce0 100644 --- a/sites/all/themes/custom/edlptheme/assets/scripts/main.js +++ b/sites/all/themes/custom/edlptheme/assets/scripts/main.js @@ -108,6 +108,7 @@ console.log('AudioPlayer node loaded', data); this.$cartel.html(data.rendered); this.$cartel.removeClass('loading'); + _$body.trigger({'type':'new-audio-cartel-loaded'}); initAjaxLinks(); }, onNodeLoadFail(jqxhr, textStatus, error){ diff --git a/sites/all/themes/custom/edlptheme/assets/styles/app.scss b/sites/all/themes/custom/edlptheme/assets/styles/app.scss index 0d8ead48c..b27e57174 100644 --- a/sites/all/themes/custom/edlptheme/assets/styles/app.scss +++ b/sites/all/themes/custom/edlptheme/assets/styles/app.scss @@ -248,6 +248,7 @@ main[role="main"]{ &>*{ display: inline-block; vertical-align: middle; + // word-break:keep-all; padding:0; max-height: 100%; // outline: 1px solid green; @@ -312,49 +313,61 @@ main[role="main"]{ .cartel{ // TODO: set max-width regarding responsive position: relative; - max-width: 400px; + max-width: 350px; margin-left: 1em; background-color: white; opacity: 1; transition: opacity 0.5s ease-in-out; &.loading{opacity: 0;} - .first-cartel{ - - .entrees{ - line-height: 0; - span{ - @include entrie-micro-square; - } - } - h2.node-title{ - margin:0.2em 0 0; - font-size: 1em; - } - p{ - margin:0; - font-size: 0.75em; - } + white-space: nowrap; + .actions, .cartels{ + display: inline-block; + vertical-align: top; + white-space: normal; + position: relative; } - .second-cartel{ - position: absolute; - top: 0; left:0; - background-color: white; - height:100%; min-width: 100%; - opacity: 0; - transition: opacity 0.2s ease-in-out; - &>*{ - display: inline-block; - vertical-align: top; - } - .col-left{ - a{ - display: block; - font-size: 0.90em; - font-weight: 600; + .actions{ + width:1.5em; + } + .cartels{ + .first-cartel{ + + .entrees{ + line-height: 0; + span{ + @include entrie-micro-square; + } + } + h2.node-title{ + margin:0.2em 0 0; + font-size: 1em; + } + p{ + margin:0; + font-size: 0.75em; } } - .col-right{ - font-size: 0.75em; + .second-cartel{ + position: absolute; + top: 0; left:0; + background-color: white; + height:100%; min-width: 100%; + opacity: 0; + transition: opacity 0.2s ease-in-out; + &>*{ + display: inline-block; + vertical-align: top; + } + .col-left{ + a{ + display: block; + font-size: 0.90em; + font-weight: 600; + } + } + .col-right{ + font-size: 0.75em; + } } } &:hover{ @@ -368,6 +381,32 @@ main[role="main"]{ } } + + // ___ _ _ _ + // / __| |_ _ _ __| (_)___ + // \__ \ _| || / _` | / _ \ + // |___/\__|\_,_\__,_|_\___/ + +a.chutier-link{ + display: block; + width:1em;height:1em; + overflow: hidden; + text-indent: 50em; + // background-color: red; + background-position: center; + background-repeat: no-repeat; + background-size: contain; + background-image: url(../img/favori-off.svg); + &[action="remove"]{ + background-image: url(../img/favori-on.svg); + } + transition: opacity 0.2s ease-in-out; + &.ajax-loading{ + opacity: 0.2; + } +} + + // _ _ _ _ _ // /_\ (_)__ ___ __ | \| |___ __| |___ // / _ \ | / _` \ \ / | .` / _ \/ _` / -_) @@ -772,6 +811,7 @@ footer{ } #block-userlogin{ + pointer-events: all; // outline: 1px solid blue; $wh:20px; position: relative; diff --git a/sites/all/themes/custom/edlptheme/templates/content/__node--enregistrement--index.html.twig b/sites/all/themes/custom/edlptheme/templates/content/__node--enregistrement--index.html.twig deleted file mode 100644 index 059df2593..000000000 --- a/sites/all/themes/custom/edlptheme/templates/content/__node--enregistrement--index.html.twig +++ /dev/null @@ -1,78 +0,0 @@ -{# -/** - * @file - * Theme override to display a node. - * - * Available variables: - * - node: The node entity with limited access to object properties and methods. - * Only method names starting with "get", "has", or "is" and a few common - * methods such as "id", "label", and "bundle" are available. For example: - * - node.getCreatedTime() will return the node creation timestamp. - * - node.hasField('field_example') returns TRUE if the node bundle includes - * field_example. (This does not indicate the presence of a value in this - * field.) - * - node.isPublished() will return whether the node is published or not. - * Calling other methods, such as node.delete(), will result in an exception. - * See \Drupal\node\Entity\Node for a full list of public properties and - * methods for the node object. - * - label: The title of the node. - * - content: All node items. Use {{ content }} to print them all, - * or print a subset such as {{ content.field_example }}. Use - * {{ content|without('field_example') }} to temporarily suppress the printing - * of a given child element. - * - author_picture: The node author user entity, rendered using the "compact" - * view mode. - * - metadata: Metadata for this node. - * - date: Themed creation date field. - * - author_name: Themed author name field. - * - url: Direct URL of the current node. - * - display_submitted: Whether submission information should be displayed. - * - attributes: HTML attributes for the containing element. - * The attributes.class element may contain one or more of the following - * classes: - * - node: The current template type (also known as a "theming hook"). - * - node--type-[type]: The current node type. For example, if the node is an - * "Article" it would result in "node--type-article". Note that the machine - * name will often be in a short form of the human readable label. - * - node--view-mode-[view_mode]: The View Mode of the node; for example, a - * teaser would result in: "node--view-mode-teaser", and - * full: "node--view-mode-full". - * The following are controlled through the node publishing options. - * - node--promoted: Appears on nodes promoted to the front page. - * - node--sticky: Appears on nodes ordered above other non-sticky nodes in - * teaser listings. - * - node--unpublished: Appears on unpublished nodes visible only to site - * admins. - * - title_attributes: Same as attributes, except applied to the main title - * tag that appears in the template. - * - content_attributes: Same as attributes, except applied to the main - * content tag that appears in the template. - * - author_attributes: Same as attributes, except applied to the author of - * the node tag that appears in the template. - * - title_prefix: Additional output populated by modules, intended to be - * displayed in front of the main title tag that appears in the template. - * - title_suffix: Additional output populated by modules, intended to be - * displayed after the main title tag that appears in the template. - * - view_mode: View mode; for example, "teaser" or "full". - * - teaser: Flag for the teaser state. Will be true if view_mode is 'teaser'. - * - page: Flag for the full page state. Will be true if view_mode is 'full'. - * - readmore: Flag for more state. Will be true if the teaser content of the - * node cannot hold the main body content. - * - logged_in: Flag for authenticated user status. Will be true when the - * current user is a logged-in member. - * - is_admin: Flag for admin user status. Will be true when the current user - * is an administrator. - * - * @see template_preprocess_node() - * - * @todo Remove the id attribute (or make it a class), because if that gets - * rendered twice on a page this is invalid CSS for example: two lists - * in different view modes. - */ -#} - - {{ label }} - - - {{ content }} - diff --git a/sites/all/themes/custom/edlptheme/templates/content/node--enregistrement--player-cartel.html.twig b/sites/all/themes/custom/edlptheme/templates/content/node--enregistrement--player-cartel.html.twig index 725786739..fac235029 100644 --- a/sites/all/themes/custom/edlptheme/templates/content/node--enregistrement--player-cartel.html.twig +++ b/sites/all/themes/custom/edlptheme/templates/content/node--enregistrement--player-cartel.html.twig @@ -82,32 +82,39 @@ %} {{ attach_library('classy/node') }} -
-
- {# THIS IS REALLY DIRTY !! #} - {% for key, child in content.field_entrees if key|first != '#' %} - {% set tid = child['#cache']['tags'][0]|replace({'taxonomy_term:':''}) %} - - {% endfor %} -
- - {{ label }} - -
- {{ content.field_description }} -
+
+ {{ content.chutier_actions }}
-
- {% if col_left %} -
- {{ link_transcript }} - {{ link_article }} +
+ +
+
+ {# THIS IS REALLY DIRTY !! #} + {% for key, child in content.field_entrees if key|first != '#' %} + {% set tid = child['#cache']['tags'][0]|replace({'taxonomy_term:':''}) %} + + {% endfor %}
- {% endif %} - {% if col_right %} -
- right colume + + {{ label }} + +
+ {{ content.field_description }}
- {% endif %} +
+
+ {% if col_left %} +
+ {{ link_transcript }} + {{ link_article }} +
+ {% endif %} + {% if col_right %} +
+ right colume +
+ {% endif %} +
+
diff --git a/sites/default/config/sync/core.entity_view_display.node.enregistrement.player_cartel.yml b/sites/default/config/sync/core.entity_view_display.node.enregistrement.player_cartel.yml index 49ce4a50a..a7ca96b42 100644 --- a/sites/default/config/sync/core.entity_view_display.node.enregistrement.player_cartel.yml +++ b/sites/default/config/sync/core.entity_view_display.node.enregistrement.player_cartel.yml @@ -29,6 +29,11 @@ content: region: content settings: { } third_party_settings: { } + chutier_actions: + weight: 1 + region: content + settings: { } + third_party_settings: { } content_moderation_control: weight: -20 region: content diff --git a/sites/default/config/sync/system.action.user_add_role_action.user.yml b/sites/default/config/sync/system.action.user_add_role_action.user.yml new file mode 100644 index 000000000..42c84dc67 --- /dev/null +++ b/sites/default/config/sync/system.action.user_add_role_action.user.yml @@ -0,0 +1,14 @@ +uuid: edce0062-97e8-4dba-848f-0d1ada71a23e +langcode: fr +status: true +dependencies: + config: + - user.role.user + module: + - user +id: user_add_role_action.user +label: 'Add the User role to the selected user(s)' +type: user +plugin: user_add_role_action +configuration: + rid: user diff --git a/sites/default/config/sync/system.action.user_remove_role_action.user.yml b/sites/default/config/sync/system.action.user_remove_role_action.user.yml new file mode 100644 index 000000000..e3003893e --- /dev/null +++ b/sites/default/config/sync/system.action.user_remove_role_action.user.yml @@ -0,0 +1,14 @@ +uuid: c4a61f84-8f75-4d58-a319-0deb762aba56 +langcode: fr +status: true +dependencies: + config: + - user.role.user + module: + - user +id: user_remove_role_action.user +label: 'Remove the User role from the selected user(s)' +type: user +plugin: user_remove_role_action +configuration: + rid: user diff --git a/sites/default/config/sync/user.role.authenticated.yml b/sites/default/config/sync/user.role.authenticated.yml index 8076f3bab..a7ef75126 100644 --- a/sites/default/config/sync/user.role.authenticated.yml +++ b/sites/default/config/sync/user.role.authenticated.yml @@ -20,6 +20,7 @@ permissions: - 'delete own fil entities' - 'edit own chutier entities' - 'edit own fil entities' + - 'use chutier' - 'use text format wysiwyg' - 'view own unpublished chutier entities' - 'view own unpublished fil entities' diff --git a/sites/default/config/sync/user.role.user.yml b/sites/default/config/sync/user.role.user.yml new file mode 100644 index 000000000..2d6edc254 --- /dev/null +++ b/sites/default/config/sync/user.role.user.yml @@ -0,0 +1,9 @@ +uuid: 05cb1550-ab78-4bf9-a7d0-39a33e3fa03b +langcode: fr +status: true +dependencies: { } +id: user +label: User +weight: -4 +is_admin: null +permissions: { }