Explorar el Código

now diplaying composition list + new compo link which is working ajaxly

Bachir Soussi Chiadmi hace 6 años
padre
commit
4b8d6d0a65

+ 84 - 10
sites/all/modules/figli/edlp_studio/assets/js/edlp_studio.js

@@ -5,23 +5,26 @@
   function init(){
     console.log('Studio Init');
     initEvents();
-    initAjaxChutier();
+    initAjaxLinks();
   };
 
   function initEvents(){
     $('body')
-      .on('new-audio-cartel-loaded', initAjaxChutier)
-      .on('new-content-ajax-loaded', initAjaxChutier);
+      .on('new-audio-cartel-loaded', initAjaxChutierLinks)
+      .on('new-content-ajax-loaded', initAjaxLinks);
   };
 
-
+  function initAjaxLinks(){
+    initAjaxChutierLinks();
+    initAjaxCompoLinks();
+  }
   //   ___ _        _   _           _  _         _       _    _      _
   //  / __| |_ _  _| |_(_)___ _ _  | \| |___  __| |___  | |  (_)_ _ | |__ ___
   // | (__| ' \ || |  _| / -_) '_| | .` / _ \/ _` / -_) | |__| | ' \| / /(_-<
   //  \___|_||_\_,_|\__|_\___|_|   |_|\_\___/\__,_\___| |____|_|_||_|_\_\/__/
 
-  function initAjaxChutier(){
-    console.log('studio initAjax chutier');
+  function initAjaxChutierLinks(){
+    console.log('studio initAjaxChutierLinks');
     $('.chutier-ajax-link:not(.ajax-enabled)')
       .addClass('ajax-enabled')
       .on('click', onClickChutierAjaxLink);
@@ -57,13 +60,84 @@
       'target_id':$link.attr('target_id'),
     });
     $link.replaceWith(data.new_link);
-    initAjaxChutier();
+    initAjaxChutierLinks();
+    // reload Studio chutier_ui's documents list
     updateStudioChutier();
-    // TODO: reload Studio chutier_ui's documents list
   };
 
   function onErrorActionToChutier(jqxhr, textStatus, error, $link){
-    console.warn('add to chuttier load failed : '+error, jqxhr.responseText);
+    console.warn('action to chuttier load failed : '+error, jqxhr.responseText);
+  };
+
+  //   ___                        _ _   _
+  //  / __|___ _ __  _ __  ___ __(_) |_(_)___ _ _  ___
+  // | (__/ _ \ '  \| '_ \/ _ (_-< |  _| / _ \ ' \(_-<
+  //  \___\___/_|_|_| .__/\___/__/_|\__|_\___/_||_/__/
+  //                |_|
+  function initAjaxCompoLinks(){
+    console.log('studio initAjaxCompoLinks');
+    $('.new-composition-link:not(.ajax-enabled)')
+      .addClass('ajax-enabled')
+      .on('click', onClickCompoLink);
+  };
+
+  function onClickCompoLink(e){
+    e.preventDefault();
+    setInputForNewCompoName($(this));
+    return false;
+  };
+
+  function setInputForNewCompoName($link){
+    var $form = $('<form>').addClass('new-compo-form')
+      .append($('<input>').attr('type', 'text').attr('placeholder', 'new name'))
+      .append($('<button>').attr('type', 'submit').html('+'))
+      .submit(function(e){
+        onNewCompoFormSubmit(e, $link, $(this));
+      });
+
+    $link
+      .after($form)
+      .addClass('folded');
+    $form.children('input[type="text"]').focus();
+  };
+
+  function onNewCompoFormSubmit(e, $link, $form){
+    var name = $('input[type="text"]',$form).val();
+    console.log('onNewCompoFormSubmit', name);
+    if(name != ''){
+      $form.addClass('ajax-loading').children('*').attr('disabled', 'disabled');
+      createNewCompo(name, $link, $form);
+    }
+    e.preventDefault();
+  };
+
+  function createNewCompo(name,$link, $form){
+    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, {
+        'new_name':name
+      })
+      .done(function(data){
+        onActionToCompoDone(data, $link, $form);
+      })
+      .fail(function(jqxhr, textStatus, error){
+        onErrorActionToCompo(jqxhr, textStatus, error, $link);
+      });
+  };
+
+  function onActionToCompoDone(data, $link, $form){
+    console.log('onActionToCompoDone',data);
+    $link
+      .removeClass('folded')
+      .parents('li')
+        .before($('<li>').append(data.new_link));
+    $form.remove();
+    // TODO: open new composition to composer
+  };
+
+  function onErrorActionToCompo(jqxhr, textStatus, error, $link){
+    console.warn('action to compo load failed : '+error, jqxhr.responseText);
   };
 
 
@@ -90,7 +164,7 @@
 
   function onLoadedChutier($studioChutier, data){
     $studioChutier.replaceWith(data.rendered);
-    initAjaxChutier();
+    initAjaxChutierLinks();
     $('body').trigger({
       'type':'on-studio-chutier-updated'
     });

+ 9 - 1
sites/all/modules/figli/edlp_studio/edlp_studio.module

@@ -53,7 +53,15 @@ function edlp_studio_theme($existing, $type, $theme, $path) {
       'file' => 'includes/edlp_composition_ui.inc',
       'variables' => array(
         'title' => t('Compositon'),
-        'compositions' => array(),
+        'compositions' => null,
+        'composer' => null,
+      ),
+    ),
+    'edlp_compositions_list' => array(
+      'file' => 'includes/edlp_compositions_list.inc',
+      'variables' => array(
+        'composition_entities' => array(),
+        'new_composition_url' => Null,
       ),
     ),
     'edlp_studio_ui' => array(

+ 9 - 0
sites/all/modules/figli/edlp_studio/edlp_studio.routing.yml

@@ -15,6 +15,15 @@ edlp_studio.chutier_controller_ajax_add_content:
   requirements:
     _permission: 'use chutier'
 
+edlp_studio.composition_controller_action_ajax:
+  path: '/edlp_studio/ajax/composition/{action}/{cid}'
+  defaults:
+    _controller: '\Drupal\edlp_studio\Controller\CompositionController::CompositionActionJson'
+    _title: 'Create, Delete or Rename composition'
+    cid: null
+  requirements:
+    _permission: 'use chutier'
+
 edlp_studio.studio_ui:
   path: '/edlp/studio-ui'
   defaults:

+ 42 - 0
sites/all/modules/figli/edlp_studio/includes/edlp_compositions_list.inc

@@ -0,0 +1,42 @@
+<?php
+
+use \Drupal\Core\Url;
+use \Drupal\Component\Utility\Unicode;
+
+function template_preprocess_edlp_compositions_list(&$vars){
+
+  $vars['compositions'] = array (
+    '#theme' => 'item_list',
+    '#items' => [],
+  );
+  foreach($vars['composition_entities'] as $entity){
+    // get the url
+    $url = Url::fromRoute('entity.composition.canonical', ['composition' => $entity->id()], ['absolute' => TRUE]);
+    $title = $entity->getName();
+    $vars['compositions']['#items'][] = array(
+      '#title' => $title,
+      '#type' => 'link',
+      '#url' => $url,
+      '#options'=>array(
+        'attributes' => array(
+          'data-drupal-link-system-path' => $url->getInternalPath(),
+          'nid' => $entity->id(),
+          'class' => ['composition-link'],
+          'title'=>$title,
+        ),
+      ),
+    );
+  }
+
+  $vars['compositions']['#items'][] = array(
+    '#title' => t('New composition'),
+    '#type' => 'link',
+    '#url' => $vars['new_composition_url'],
+    '#options'=>array(
+      'attributes' => array(
+        'data-drupal-link-system-path' => $vars['new_composition_url']->getInternalPath(),
+        'class' => ['new-composition-link']
+      ),
+    ),
+  );
+}

+ 127 - 0
sites/all/modules/figli/edlp_studio/src/Controller/CompositionController.php

@@ -0,0 +1,127 @@
+<?php
+
+namespace Drupal\edlp_studio\Controller;
+
+use Drupal\Core\Controller\ControllerBase;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\User\UserDataInterface;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\JsonResponse;
+use Drupal\Core\Url;
+
+use Drupal\edlp_studio\Entity\Compositon;
+
+/**
+ * Class CompositionController.
+ */
+class CompositionController extends ControllerBase {
+
+  protected $user;
+  protected $userdata;
+
+  /**
+   * 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 status.
+   */
+  public function CompositionActionJson($action, $cid, Request $request) {
+    $this->error_message = null;
+    $status = 'ok';
+    $message = 'Hello';
+
+    switch($action){
+      case 'create':
+        $name = $request->query->get('new_name');
+        if($name){
+          $this->createComposition($name);
+        }else{
+          $this->error_message = t("Composition creation needs a name as query paramater!");
+        }
+        break;
+      // case 'delete':
+      //
+      //   break;
+      // case 'rename':
+      //
+      //   break;
+    }
+
+    if($this->error_message){
+      $status = 'error';
+    }
+
+    if($status == 'error'){
+      $message = $this->error_message;
+    }else{
+      $url = Url::fromRoute('entity.composition.canonical', ['composition' => $this->compo->id()], ['absolute' => TRUE]);
+      $title = $this->compo->getName();
+      $new_link_build = array(
+        '#title' => $title,
+        '#type' => 'link',
+        '#url' => $url,
+        '#options'=>array(
+          'attributes' => array(
+            'data-drupal-link-system-path' => $url->getInternalPath(),
+            'nid' => $this->compo->id(),
+            'class' => ['composition-link'],
+            'title'=>$title,
+          ),
+        ),
+      );
+      $new_link = render($new_link_build);
+    }
+
+
+    // JSON
+    $response = new JsonResponse();
+    $data = array(
+      'action' => $action,
+      'status' => $status,
+      'message' => $this->error_message,
+      'new_name' => $request->query->get('new_name'),
+      'new_link' => $new_link,
+    );
+    $response->setData($data);
+    return $response;
+
+    // classic html
+    // return array(
+    //   '#markup'=>'Status : ' . $status . ' | Message : ' . $message,
+    // );
+  }
+
+  private function createComposition($name){
+    $compo = array(
+      'id' => NULL,
+      'uid' => $this->user->id(),
+      'status' => TRUE,
+      'name' => $name,
+    );
+    $this->compo = entity_create('composition', $compo);
+    $this->compo->save();
+  }
+
+}

+ 28 - 6
sites/all/modules/figli/edlp_studio/src/Controller/StudioUIController.php

@@ -6,6 +6,7 @@ use Drupal\Core\Controller\ControllerBase;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\User\UserDataInterface;
+use Drupal\Core\Url;
 use Symfony\Component\HttpFoundation\JsonResponse;
 
 use Drupal\edlp_studio\Entity\Chutier;
@@ -46,7 +47,7 @@ class StudioUIController extends ControllerBase {
    *   Return renderable array.
    */
   public function StudioUI() {
-    return $this->buildUI();
+    return $this->buildStudioUI();
   }
 
   /**
@@ -107,15 +108,36 @@ class StudioUIController extends ControllerBase {
   }
 
   private function buildCompostionUI(){
-    // TODO: get compositions
-    // TODO: add compositions theme, preprocess, twig template to studio module
-    // TODO: build content renderable array
+
+    // build content renderable array
     $composition_ui = array(
-      "#theme"=>'edlp_compostion_ui',
+      "#theme"=>'edlp_composition_ui',
       "#title" => t('Composition'),
-      "#compositions" => array('#markup'=>'TODO : compositions UI'),
+      "#compositions" => $this->buildCompostionsList(),
+      "#composer" => $this->buildComposer(),
     );
 
     return $composition_ui;
   }
+
+  private function buildCompostionsList(){
+    // get compositions
+    $query = \Drupal::entityQuery('composition')
+      ->condition('user_id', $this->user->id());
+
+    $compos_nids = $query->execute();
+    $compos = entity_load_multiple('composition', $compos_nids);
+
+    $createurl = Url::fromRoute('edlp_studio.composition_controller_action_ajax', ['action' => 'create'], ['absolute' => TRUE]);
+
+    return array(
+      '#theme' => 'edlp_compositions_list',
+      '#composition_entities' => $compos,
+      '#new_composition_url' => $createurl,
+    );
+  }
+
+  private function buildComposer(){
+    return array('#markup'=>'TODO : composer UI');
+  }
 }

+ 4 - 4
sites/all/modules/figli/edlp_studio/src/Entity/Composition.php

@@ -44,10 +44,10 @@ use Drupal\user\UserInterface;
  *     "status" = "status",
  *   },
  *   links = {
- *     "canonical" = "/admin/structure/studio/composition/{composition}",
- *     "add-form" = "/admin/structure/studio/composition/add",
- *     "edit-form" = "/admin/structure/studio/composition/{composition}/edit",
- *     "delete-form" = "/admin/structure/studio/composition/{composition}/delete",
+ *     "canonical" = "/composition/{composition}",
+ *     "add-form" = "/composition/add",
+ *     "edit-form" = "/composition/{composition}/edit",
+ *     "delete-form" = "/composition/{composition}/delete",
  *     "collection" = "/admin/structure/studio/composition",
  *   },
  *   field_ui_base_route = "composition.settings"

+ 8 - 3
sites/all/modules/figli/edlp_studio/templates/edlp-composition-ui.html.twig

@@ -1,6 +1,11 @@
 <div class="composition_ui">
  <h2>{{ title }}</h2>
- <section class="composition">
-   {{ compostions }}
- </section>
+ <div class="wrapper">
+  <section class='compositions-list'>
+    {{ compositions }}
+  </section>
+  <section class="composer">
+    {{ composer }}
+  </section>
+ </div>
 </div>

+ 1 - 0
sites/all/modules/figli/edlp_studio/templates/edlp-compositions-list.html.twig

@@ -0,0 +1 @@
+{{ compositions }}

+ 64 - 0
sites/all/themes/custom/edlptheme/assets/dist/styles/app.min.css

@@ -1587,6 +1587,70 @@ body.ajax-loading main[role="main"]:before {
           opacity: 0.8; }
   #studio-ui .composition_ui {
     height: 50%; }
+    #studio-ui .composition_ui > h2 {
+      z-index: 10;
+      position: absolute;
+      width: calc(100% - 20px);
+      margin: 0;
+      padding: 0.5em 0;
+      font-size: 1em;
+      font-weight: 500;
+      text-transform: uppercase;
+      background-color: white; }
+    #studio-ui .composition_ui > .wrapper {
+      padding-top: 35px;
+      height: calc(100% - 35px);
+      overflow: hidden;
+      white-space: nowrap; }
+      #studio-ui .composition_ui > .wrapper section.compositions-list, #studio-ui .composition_ui > .wrapper section.composer {
+        display: inline-block;
+        vertical-align: top;
+        height: 100%; }
+      #studio-ui .composition_ui > .wrapper .compositions-list {
+        width: 30%;
+        height: 100%;
+        overflow-y: auto; }
+        #studio-ui .composition_ui > .wrapper .compositions-list a {
+          font-size: 0.756em; }
+          #studio-ui .composition_ui > .wrapper .compositions-list a.new-composition-link {
+            display: inline-block;
+            vertical-align: top;
+            overflow: hidden;
+            height: 1em;
+            -webkit-transition: height 0.2s ease-in-out;
+            transition: height 0.2s ease-in-out; }
+            #studio-ui .composition_ui > .wrapper .compositions-list a.new-composition-link:before {
+              content: "+";
+              font-weight: bold;
+              margin-right: 0.2em; }
+            #studio-ui .composition_ui > .wrapper .compositions-list a.new-composition-link.folded {
+              height: 0; }
+        #studio-ui .composition_ui > .wrapper .compositions-list .new-compo-form {
+          opacity: 1;
+          -webkit-transition: opacity 0.2s ease-in-out;
+          transition: opacity 0.2s ease-in-out; }
+          #studio-ui .composition_ui > .wrapper .compositions-list .new-compo-form input[type="text"] {
+            font-size: 0.756em;
+            padding: 0 0.5em;
+            width: calc(100% - 50px);
+            height: 1.7em;
+            border: none;
+            border-top: 1px dotted red;
+            border-bottom: 1px dotted red; }
+          #studio-ui .composition_ui > .wrapper .compositions-list .new-compo-form button {
+            background: none;
+            border: none;
+            font-size: 1em;
+            line-height: 1;
+            font-weight: bold; }
+          #studio-ui .composition_ui > .wrapper .compositions-list .new-compo-form.ajax-loading {
+            opacity: 0.4; }
+      #studio-ui .composition_ui > .wrapper .composer {
+        -webkit-box-sizing: content-box;
+        box-sizing: content-box;
+        width: 69%;
+        padding-left: 1em;
+        border-left: 1px solid #aaa; }
 
 body.path-agenda main .col > .wrapper {
   height: 100%; }

+ 74 - 0
sites/all/themes/custom/edlptheme/assets/styles/app.scss

@@ -484,6 +484,80 @@ main[role="main"]{
   }
   .composition_ui{
     height:50%;
+    &>h2{
+      z-index: 10;
+      position: absolute;
+      width: calc(100% - 20px);
+      margin: 0;
+      padding:0.5em 0;
+      font-size: 1em;
+      font-weight: 500;
+      text-transform: uppercase;
+      // outline: 1px solid orange;
+      background-color: white;
+    }
+    >.wrapper{
+      padding-top: 35px;
+      height:calc(100% - 35px);
+      overflow: hidden;
+      white-space: nowrap;
+      section.compositions-list, section.composer{
+        display: inline-block; vertical-align: top;
+        height: 100%;
+      }
+      .compositions-list{
+        width:30%; height:100%;
+        overflow-y: auto;
+        a{
+          font-size: 0.756em;
+          &.new-composition-link{
+            // padding-left: 1em;
+            &:before{
+              content:"+";
+              font-weight: bold;
+              margin-right: 0.2em;
+            }
+            display: inline-block;
+            vertical-align: top;
+            overflow: hidden;
+            height:1em;
+            transition: height 0.2s ease-in-out;
+            &.folded{
+              height:0;
+            }
+          }
+        }
+        .new-compo-form{
+          input[type="text"]{
+            font-size: 0.756em;
+            padding:0 0.5em;
+            width:calc(100% - 50px);
+            height:1.7em;
+            border: none;
+            border-top:1px dotted red;
+            border-bottom:1px dotted red;
+          }
+          button{
+            background: none;
+            border: none;
+            font-size: 1em;
+            line-height: 1;
+            font-weight: bold;
+          }
+          opacity: 1;
+          transition: opacity 0.2s ease-in-out;
+          &.ajax-loading{
+            opacity: 0.4;
+          }
+        }
+      }
+      .composer{
+        box-sizing: content-box;
+        width:69%;
+        padding-left: 1em;
+        border-left: 1px solid #aaa;
+      }
+    }
   }
 }
 

+ 5 - 2
sites/default/config/sync/user.role.authenticated.yml

@@ -12,16 +12,19 @@ permissions:
   - 'access content'
   - 'access devel information'
   - 'access kint'
-  - 'add chutier entities'
+  - 'add composition entities'
   - 'add fil entities'
   - 'create corpus_documents workflow_transition'
   - 'create generique workflow_transition'
-  - 'delete own chutier entities'
+  - 'delete own composition entities'
   - 'delete own fil entities'
   - 'edit own chutier entities'
+  - 'edit own composition entities'
   - 'edit own fil entities'
   - 'use chutier'
   - 'use text format wysiwyg'
   - 'view own unpublished chutier entities'
+  - 'view own unpublished composition entities'
   - 'view own unpublished fil entities'
+  - 'view published composition entities'
   - 'view published fil entities'

+ 5 - 0
sites/default/config/sync/user.role.root.yml

@@ -35,6 +35,7 @@ permissions:
   - 'administer chutier entities'
   - 'administer chutier fields'
   - 'administer chutier form display'
+  - 'administer composition entities'
   - 'administer content translation'
   - 'administer content types'
   - 'administer contexts'
@@ -110,6 +111,7 @@ permissions:
   - 'delete all revisions'
   - 'delete any autre_son content'
   - 'delete any chutier entities'
+  - 'delete any composition entities'
   - 'delete any enregistrement content'
   - 'delete any evenement content'
   - 'delete any fil content'
@@ -127,6 +129,7 @@ permissions:
   - 'delete fil revisions'
   - 'delete maillog'
   - 'delete own autre_son content'
+  - 'delete own chutier entities'
   - 'delete own enregistrement content'
   - 'delete own evenement content'
   - 'delete own fil content'
@@ -142,6 +145,7 @@ permissions:
   - 'delete terms in page_type'
   - 'edit any autre_son content'
   - 'edit any chutier entities'
+  - 'edit any composition entities'
   - 'edit any enregistrement content'
   - 'edit any evenement content'
   - 'edit any fil content'
@@ -193,6 +197,7 @@ permissions:
   - 'view all fil revisions'
   - 'view all revisions'
   - 'view any unpublished chutier entities'
+  - 'view any unpublished composition entities'
   - 'view any unpublished fil entities'
   - 'view assigned domains'
   - 'view autre_son revisions'