[Résolu][Alfresco Share]WebScripts et Actions Personnalisées

cancel
Showing results for 
Search instead for 
Did you mean: 
lamba
Active Member

[Résolu][Alfresco Share]WebScripts et Actions Personnalisées

Bonjour,

Dans le cadre d'un projet d'intégration de Alfresco avec l'une de nos solutions, j'ai besoin de:
- Créer et Déployer de nouveaux WSs sous Alfresco Share
- Associer une action personnalisée aux documents dans le Document Library de Alfresco Share.

Je sais comment créer et déployer un WS sous Alfresco Explorer, aussi comment ajouter une action personnalisée sous Alfresco Explorer mais j'ai pas encore arrivé à comprendre le mécanisme pour Alfresco Share.

Je m'adresse à ceux qui ont déjà tenter d'étendre Alfresco Share, veuillez me partager de la doc si vous l'avez ou m'expliquer le mécanisme.

NB: J'utilise Alfresco alfresco-community-tomcat-3.2r2

Merci d'avance.
11 Replies
bertrandf
Active Member

Re: [Résolu][Alfresco Share]WebScripts et Actions Personnalisées

Si j'ai bien compris votre demande, ce lien devrait vous intéresser : http://wiki.alfresco.com/wiki/Custom_Document_Library_Action

Cordialement.
lamba
Active Member

Re: [Résolu][Alfresco Share]WebScripts et Actions Personnalisées

C'est un lien très utile. Merci Bertrand.

Mais, l'actions que j'essaie d'exécuter:
- doit passer par une fenêtre de dialogue pour spécifier quelques params et
- après, lancer l'action en appuyant sur le bouton valider.

Jusqu'à maintenant, voilà ce que j'ai fait et veuillez me compléter car j'arrive encore pas à afficher la fenêtre de dialogue:
- Sous le répertoire 'share\WEB-INF\classes\alfresco\site-webscripts\org\alfresco\components\documentlibrary'
— Déclarer l'action dans les fichiers: documentlist.get.config.xml, documentlist.get.properties et documentlist.get.head.ftl.

- Sous le répertoire 'share\components\documentlibrary'
— Ajouter l'image sous le répertoire 'images'
— Créer les fichiers 'xxx-action.css' et 'xxx-action.js'.
Voilà le contenu du fichier 'xxx-action.js'

(function()
{   
   Alfresco.doclib.Actions.prototype.onActionXxx = function DL_onActionXxx(assets)
      {
         if (!this.modules.xxx)
         {
            this.modules.xxx= new Alfresco.module.DoclibXxx(this.id + "-xxx");
         }

         this.modules.xxx.setOptions(
         {
            siteId: this.options.siteId,
            containerId: this.options.containerId,
            path: this.currentPath,
            files: assets
         }).showDialog();
      };
   })();

- Sous le répertoire 'share\WEB-INF\classes\alfresco\site-webscripts\org\alfresco\modules\documentlibrary'
— Ajouter les fichiers: xxx.get.desc.xml, xxx.get.html.ftl et xxx.get.properties de la fenêtre de dialogue.

- Sous le répertoire 'alfresco\WEB-INF\classes\alfresco\templates\webscripts\org\alfresco\slingshot\documentlibrary\action'
— Ajouter les fichiers : xxx.post.desc.xml, xxx.post.json.ftl et xxx.post.json.js définissant l'action.

Selon les recherches que j'ai effectué, je pense qu'il faut ajouter d'autres sources (.js et .css) au répertoire 'share\modules\documentlibrary'. Mais que doivent contenir ces derniers ?

Si vous avez un exemple illustrant ceci ou des explications, veuillez me les partager.


Merci.
lamba
Active Member

Re: [Résolu][Alfresco Share]WebScripts et Actions Personnalisées

Bonjour,

Pour ceux qui ont déjà étendu Alfresco Share, comment faire pour ajouter une action comme Addaspect ou Assign Workflow ?

En fait, j'ai réussi à ajouter l'icône (comme il est décrit dans l'exemple que m'a envoyé Bertrand). J'ai créé aussi le WS pour la fenêtre de dialogue (à déployer sous le répertoire 'share\WEB-INF\classes\alfresco\site-webscripts\org\alfresco\modules\documentlibrary\' ). Mais pour la liaison entre la fenêtre de dialogue et l'icône de l'action, j'ai pas encore arrivé à le faire! Smiley Sad


Sinon, connaissez vous un livre pour développeur comme celui de JeffPotts 'Alfresco Developer Guide' mais cette fois-ci pour des travaux d'extension sur Share.



Merci d'avance.
bertrandf
Active Member

Re: [Résolu][Alfresco Share]WebScripts et Actions Personnalisées

Bonjour,

Il faut en effet comme vous le disiez dans votre message précédent ajouter d'autres sources (.js et .css) dans le répertoire 'share\modules\documentlibrary'.
C'est dans votre fichier js que vous ferez le lien avec votre webscript que vous avez créé dans 'share\WEB-INF\classes\alfresco\site-webscripts\org\alfresco\modules\documentlibrary'

Pour créer votre classe javascript, la seule piste que je peux vous donner et de repartir d'un des fichiers existants dans le dossier 'share\modules\documentlibrary'.
Avec votre éditeur préféré faites des "rechercher/remplacer" du nom de la classe par la votre.
Essayez de comprendre la classe et enlever tout ce qui est superflu.

Pour voir à quel moment l'appel à votre webscript (la fenêtre de dialogue) est fait, recherchez "modules/documentlibrary" dans le fichier.

Je sais, ce n'est pas génial comme explications, mais la personnalisation de Share n'est pas chose facile …

Si j'ai le temps, j'essayerai de vous donner une réponse plus complète demain.
lamba
Active Member

Re: [Résolu][Alfresco Share]WebScripts et Actions Personnalisées

OK, en attendant je vais continuer sur la piste que vous m'avez indiqué.
En fait je l'ai déjà commencé mais j'ai pas encore arrivé à qc qui fonctionne!

Merci Bertrand.
lamba
Active Member

Re: [Résolu][Alfresco Share]WebScripts et Actions Personnalisées

Salut tout le monde,

En fait, je suis bloquée à ce niveau là  :cry:

Je me suis inspirée des actions "assign WF" et "add aspects" pour rédiger mon fichier .js mais ça n'a pas marché, l'appel est ignoré !

Bertrand, je pense que vous n'avez pas trouvé de temps pour me détaillé le truc, donc si qq'un a un exemple d'action personnalisée avec interaction d'utilisateur, qu'il me le partage!


Merci.
bertrandf
Active Member

Re: [Résolu][Alfresco Share]WebScripts et Actions Personnalisées

Bonjour,

Pourriez-vous donner plus de détails sur ce que vous désirez mettre dans votre fenêtre de dialogue ?
Pourriez vous poster le contenu du webscript chargé d'afficher la fenêtre de dialogue svp (xxx.get.html.ftl) ?

Cordialement.
lamba
Active Member

Re: [Résolu][Alfresco Share]WebScripts et Actions Personnalisées

Bonjour Bertrand,

Voilà le contenu de mon fichier form-xxx.get.html.ftl


<div id="${args.htmlid}-dialog" class="xxx">
   <div id="${args.htmlid}-title" class="hd"></div>
   <div class="bd">
      <form id="${args.htmlid}-form" action="" method="post" accept-charset="utf-8">
              
       <div class="yui-g">
            <h2>${msg("header.type")}</h2>
         </div>
         <div class="field">
            <select id="${args.htmlid}-type" name="type" tabindex="2">
               <option value="typearch:gen" selected="selected">generic</option>
               <option value="typearch:alfrep">alfresco reports</option>
            <option value="typearch:alfsec">alfresco screens</option>
            <option value="typearch:pcrep">pcdoc reports</option>
            <option value="typearch:pcsec">pcdoc screens</option>
            </select>
         </div>
        
         <div class="bdft">
            <input type="button" id="${args.htmlid}-ok" value="${msg("button.assign")}" tabindex="4" />
            <input type="button" id="${args.htmlid}-cancel" value="${msg("button.cancel")}" tabindex="5" />
         </div>
      </form>
   </div>
</div>

Pour plus de détails, voilà la méthode d'appel que j'ai ajouté au fichier actions.js

/**
       * action xxx.
       *
       * @method onActionXxx
       * @param assets {object} Object literal representing one or more file(s) or folder(s) to be actioned
       */
    
     onActionXxx: function dlA_onActionXxx(assets)
      {
         if (!this.modules.xxx)
         {
            this.modules.xxx= new Alfresco.module.DoclibXxx(this.id + "-xxx");
         }

         this.modules.xxx.setOptions(
         {
            siteId: this.options.siteId,
            containerId: this.options.containerId,
            path: this.currentPath,
            file: assets
         }).showDialog();
      }

et la classe Alfresco.module.DoclibXxx définie dans un fichier xxx-action.js

(function()
{
   /**
   * YUI Library aliases
   */
   var Dom = YAHOO.util.Dom,
      Event = YAHOO.util.Event,
      //Element = YAHOO.util.Element;

   /**
    * Alfresco Slingshot aliases
    */
   var $html = Alfresco.util.encodeHTML;


   Alfresco.module.DoclibXxx = function(htmlId)
   {
      // Mandatory properties
      this.name = "Alfresco.module.DoclibXxx";
      this.id = htmlId;

      // Initialise prototype properties
      this.widgets = {};
      this.modules = {};
     
      // Register this component
      Alfresco.util.ComponentManager.register(this);

      // Load YUI Components
      Alfresco.util.YUILoaderHelper.require(["button", "container"], this.onComponentsLoaded, this);

      return this;
   };
  
   Alfresco.module.DoclibXxx.prototype =
   {
      /**
       * Object container for initialization options
       */
      options:
      {
         /**
          * Current siteId.
          *
          * @property siteId
          * @type string
          */
         siteId: "",

         /**
          * ContainerId representing root container
          *
          * @property containerId
          * @type string
          * @default "documentLibrary"
          */
         containerId: "documentLibrary",

         /**
          * Files to be included in Xxx
          *
          * @property: files
          * @type: object
          * @default: null
          */
         file: null,

         /**
          * Width for the dialog
          *
          * @property: width
          * @type: integer
          * @default: 50em
          */
         width: "50em"
      },
     
      /**
       * Object container for storing YUI widget instances.
       *
       * @property widgets
       * @type object
       */
      widgets: null,

      /**
       * Object container for storing module instances.
       *
       * @property modules
       * @type object
       */
      modules: null,

      /**
       * Container element for template in DOM.
       *
       * @property containerDiv
       * @type DOMElement
       */
      containerDiv: null,

      /**
       * Set multiple initialization options at once.
       *
       * @method setOptions
       * @param obj {object} Object literal specifying a set of options
       * @return {Alfresco.module.DoclibXxx} returns 'this' for method chaining
       */
      setOptions: function DLW_setOptions(obj)
      {
         this.options = YAHOO.lang.merge(this.options, obj);
         return this;
      },

      /**
       * Set messages for this component.
       *
       * @method setMessages
       * @param obj {object} Object literal specifying a set of messages
       * @return {Alfresco.module.DoclibXxx} returns 'this' for method chaining
       */
      setMessages: function DLW_setMessages(obj)
      {
         Alfresco.util.addMessages(obj, this.name);
         return this;
      },

      /**
       * Fired by YUILoaderHelper when required component script files have
       * been loaded into the browser.
       * @method onComponentsLoaded
       */
      onComponentsLoaded: function DLW_onComponentsLoaded()
      {
      },

      /**
       * Main entry point
       * @method showDialog
       */
      showDialog: function DLW_showDialog()
      {
         if (!this.containerDiv)
         {
            // Load the UI template from the server
            Alfresco.util.Ajax.request(
            {
               url: Alfresco.constants.URL_SERVICECONTEXT + "modules/documentlibrary/xxx",
               dataObj:
               {
                  htmlid: this.id
               },
               successCallback:
               {
                  fn: this.onTemplateLoaded,
                  scope: this
               },
               failureMessage: "Could not load Document Library Xxx template",
               execScripts: true
            });
         }
         else
         {
            // Show the dialog
            this._showDialog();
         }
      },

      /**
       * Event callback when dialog template has been loaded
       *
       * @method onTemplateLoaded
       * @param response {object} Server response from load template XHR request
       */
      onTemplateLoaded: function DLW_onTemplateLoaded(response)
      {
         // Inject the template from the XHR request into a new DIV element
         this.containerDiv = document.createElement("div");
         this.containerDiv.setAttribute("style", "display:none");
         this.containerDiv.innerHTML = response.serverResponse.responseText;

         // The panel is created from the HTML returned in the XHR request, not the container
         var dialogDiv = Dom.getFirstChild(this.containerDiv);
         while (dialogDiv && dialogDiv.tagName.toLowerCase() != "div")
         {
            dialogDiv = Dom.getNextSibling(dialogDiv);
         }
        
         // Create and render the YUI dialog
         this.widgets.dialog = Alfresco.util.createYUIPanel(dialogDiv,
         {
            width: this.options.width
         },
         {
            type: YAHOO.widget.Dialog
         });

         this.widgets.dialog.cancelEvent.subscribe(this.onCancel, null, this);

         );
      },
     
      /**
       * Xxx form submit success handler
       *
       * @method onSuccess
       * @param p_data {object} Server response object
       */
      onSuccess: function DLW_onSuccess(p_data)
      {
         //var result;
         this._hideDialog();
      
       // Did the operation succeed?
         if (!p_data.json.overallSuccess)
         {
            Alfresco.util.PopupManager.displayMessage(
            {
               text: this._msg("message.xxx.failure")
            });
            return;
         }
      
       Alfresco.util.PopupManager.displayMessage(
         {
            text: this._msg("message.xxx.success")
         });
      },

      /**
       * xxx form submit failure handler
       *
       * @method onFailure
       * @param p_data {object} Server response object
       */
      onFailure: function DLW_onFailure(p_data)
      {
         //this.widgets.feedbackMessage.destroy();
         this.widgets.okButton.set("disabled", false);
         this.widgets.cancelButton.set("disabled", false);
         this.widgets.dialog.show();
         Alfresco.util.PopupManager.displayPrompt(
         {
            text: this._msg("message.xxx.failure")
         });
      },

      /**
       * Dialog Cancel button event handler
       *
       * @method onCancel
       * @param e {object} DomEvent
       * @param p_obj {object} Object passed back from addListener method
       */
      onCancel: function DLW_onCancel(e, p_obj)
      {
         this._hideDialog();
      },

      /**
       * PRIVATE FUNCTIONS
       */

      /**
       * Internal show dialog function
       * @method _showDialog
       */
      _showDialog: function DLW__showDialog()
      {
         // Grab the form element
         var formElement = Dom.get(this.id + "-form");

         // Submission Url
         formElement.attributes.action.nodeValue = Alfresco.constants.PROXY_URI + "/slingshot/doclib/action/xxx";
        
         // Dialog title
         var fileSpan = '<span class="light">' + $html(this.options.file.displayName) + '</span>';
         Dom.get(this.id + "-title").innerHTML = this.msg("title", fileSpan);
        
         // Enable buttons
         this.widgets.okButton.set("disabled", false);
         this.widgets.cancelButton.set("disabled", false);

         // Initialise the Forms Runtime
         this.modules.form.init();

         // Show the dialog
         this.widgets.dialog.show();

         // Fix Firefox caret issue
         Alfresco.util.caretFix(this.id + "-form");

         // We're in a popup, so need the tabbing fix
         this.modules.form.applyTabFix();
        
         // Register the ESC key to close the dialog
         var escapeListener = new YAHOO.util.KeyListener(document,
         {
            keys: YAHOO.util.KeyListener.KEY.ESCAPE
         },
         {
            fn: function(id, keyEvent)
            {
               this.onCancel();
            },
            scope: this,
            correctScope: true
         });
         escapeListener.enable();

         // Set focus to xxx type input
         //Dom.get(this.id + "-type").focus();
      },

      /**
       * Hide the dialog, removing the caret-fix patch
       *
       * @method _hideDialog
       * @private
       */
      _hideDialog: function DLW__hideDialog()
      {
         // Grab the form element
         var formElement = Dom.get(this.id + "-form");
        
         // Ensure pop-up calendar is hidden
         //this.widgets.calendarOverlay.hide();

         // Undo Firefox caret issue
         Alfresco.util.undoCaretFix(formElement);
         this.widgets.dialog.hide();
      },

      /**
       * Gets a custom message
       *
       * @method _msg
       * @param messageId {string} The messageId to retrieve
       * @return {string} The custom message
       * @private
       */
       _msg: function DLW__msg(messageId)
       {
          return Alfresco.util.message.call(this, messageId, this.name, Array.prototype.slice.call(arguments).slice(1));
       }
   };
})();

/* Dummy instance to load optional YUI components early */
new Alfresco.module.DoclibXxx(null);
bertrandf
Active Member

Re: [Résolu][Alfresco Share]WebScripts et Actions Personnalisées

Je n'ai pas testé votre fichier xxx-action.js, mais voici une version très simplifiée, qui se contente d'afficher votre template.
Je pense que vous pouvez partir de cette base (il n'y a pas de code derrière le bouton 'assign', seulement derrière le bouton 'cancel' pour masquer la fenêtre).

Code de la classe :
/**
* Document Library "Details" module for Document Library.
*
* @namespace Alfresco.module
* @class Alfresco.module.DoclibXxx
*/
(function()
{
   /** YUI Library aliases **/
   var Dom = YAHOO.util.Dom, Event = YAHOO.util.Event, KeyListener = YAHOO.util.KeyListener;

   /** Alfresco Slingshot aliases **/
   var $html = Alfresco.util.encodeHTML;

   Alfresco.module.DoclibXxx = function(htmlId) {
      return Alfresco.module.DoclibXxx.superclass.constructor.call(this, "Alfresco.module.DoclibXxx", htmlId, ["button", "container", "connection", "json", "calendar", "datatable"]);
   };
  
   YAHOO.extend(Alfresco.module.DoclibXxx, Alfresco.component.Base, {
      /**
       * Object container for initialization options
       */
      options: {
         /** Current siteId. **/
         siteId: "",

         /** ContainerId representing root container **/
         containerId: "documentLibrary",

         /** Files to be included in workflow **/
         files: null,

         /** Width for the dialog **/
         width: "50em"
      },
     
      /** Container element for template in DOM. **/
      containerDiv: null,

      /**
       * Main entry point
       * @method showDialog
       */
      showDialog: function MyDL_showDialog() {
         if (!this.containerDiv)
         {
            // Load the UI template from the server
            Alfresco.util.Ajax.request(
            {
              //FIXME: mettre l'adresse vers votre template
               url: Alfresco.constants.URL_SERVICECONTEXT + "modules/documentlibrary/xxx",
               dataObj: {
                  htmlid: this.id
               },
               successCallback: {
                  fn: this.onTemplateLoaded,
                  scope: this
               },
               failureMessage: "Could not load template",
               execScripts: true
            });
         }
         else
         {
            // Show the dialog
            this._showDialog();
         }
      },

      /**
       * Event callback when dialog template has been loaded
       *
       * @method onTemplateLoaded
       * @param response {object} Server response from load template XHR request
       */
      onTemplateLoaded: function MyDL_onTemplateLoaded(response)
      {
         // Inject the template from the XHR request into a new DIV element
         this.containerDiv = document.createElement("div");
         this.containerDiv.setAttribute("style", "display:none");
         this.containerDiv.innerHTML = response.serverResponse.responseText;

         // The panel is created from the HTML returned in the XHR request, not the container
         var dialogDiv = Dom.getFirstChild(this.containerDiv);
         while (dialogDiv && dialogDiv.tagName.toLowerCase() != "div")  {
            dialogDiv = Dom.getNextSibling(dialogDiv);
         }
        
         // Create and render the YUI dialog
         this.widgets.dialog = Alfresco.util.createYUIPanel(dialogDiv, {
            width: this.options.width
         },
         {
            type: YAHOO.widget.Dialog
         });

         // Cancel button
         this.widgets.cancelButton = Alfresco.util.createYUIButton(this, "cancel", this.onCancel);
        
         this.widgets.dialog.cancelEvent.subscribe(this.onCancel, null, this);

         // Show the dialog
         this._showDialog();
      },

      /**
       * Dialog Cancel button event handler
       *
       * @method onCancel
       * @param e {object} DomEvent
       * @param p_obj {object} Object passed back from addListener method
       */
      onCancel: function MyDL_onCancel(e, p_obj) {
         this._hideDialog();
      },


      /**
       * PRIVATE FUNCTIONS
       */

      /**
       * Internal show dialog function
       * @method _showDialog
       */
      _showDialog: function MyDL__showDialog() {
         // Dialog title
         var titleDiv = Dom.get(this.id + "-title");
         if (YAHOO.lang.isArray(this.options.files)) {
            titleDiv.innerHTML = this.msg("title.multi", this.options.files.length);
         }
         else {
            titleDiv.innerHTML = this.msg("title.single", '<span class="light">' + $html(this.options.files.displayName) + '</span>');
         }

         // Show the dialog
         this.widgets.dialog.show();

         // Register the ESC key to close the dialog
         var escapeListener = new KeyListener(document,
         {
            keys: KeyListener.KEY.ESCAPE
         },
         {
            fn: function(id, keyEvent)
            {
               this.onCancel();
            },
            scope: this,
            correctScope: true
         });
         escapeListener.enable();
      },

      /**
       * Hide the dialog, removing the caret-fix patch
       *
       * @method _hideDialog
       * @private
       */
      _hideDialog: function MyDL__hideDialog()  {
        //TODO

         this.widgets.dialog.hide();
      }
   });

   /* Dummy instance to load optional YUI components early */
   var dummyInstance = new Alfresco.module.DoclibXxx("null");
})();

Chose très importante, n'oubliez pas d'inclure ce fichier !!
J'ai testé rapidement en incluant la classe JS dans le fichier : actions-common.get.head.ftl. Ajoutez cette ligne avant le "<#if DEBUG>"
<script type="text/javascript" src="${page.url.context}/modules/documentlibrary/xxx-action.js"></script>

Après cela, pensez à rafraichir les webscripts Share.


En espérant que ca vous aide.
Cordialement.