JS API

Enrichisser l'interface avec vos propres sripts

    L’interface graphique FlowerDocs peut être personnalisée à l’aide de scripts écrits en JavaScript. Ces scripts permettent l’utilisation de la JS API afin d’enrichir et d’interagir avec l’interface.

    Pour être exécutés, au sein du navigateur, ces scripts doivent être chargés à partir d’une URL accessible à partir du poste utilisateur.


    Documents de classe Script

    Les documents stockés dans la GED avec la classe Scriptsont chargés côté client. Les utilisateurs devant charger ces documents doivent avoir la permission READ et READ_CONTENT pour pouvoir y accéder.

    Ces fichiers Javascript sont mis en cache côté client et sont renouvellés à chaque mise à jour.


    Scripts externes

    Des scripts externes peuvent être chargés côté client en incluant des ressources WEB dont les URLs sont concaténées dans la propriété js.api.scripts (séparées par des ,). Les URLs définies doivent être accessibles depuis les postes clients.

    Si ces scripts sont amenés à changer, les URLs doivent être suffixées (par exemple avec ?version) afin de forcer le navigateur à les renouveller.

    En fonction du type de composant à créer, différents constructeurs sont mis à disposition :

    var newDocument = new Document();
    var newTask = new Task();
    var newFolder = new Folder();
    var newVFolder = new VirtualFolder();
    

    Fonctions communes

    Fonctions Description
    getId() Récupération de l’identifiant du composant
    setId(String id) Définition de l’identifiant du composant
    getName() Récupération du nom du composant
    setName(String name) Définition du nom du composant
    setClassId(String name) Définition de la classe du composant
    String getCategory() Récupération de la catégorie
    getACL() Récupération de l’ACL référencée par le composant
    setACL(String aclId) Définition de l’ACL à appliquer
    getStatus() Récupération du statut du composant
    setStatus(String status) Définition du statut du composant (cf. Javadoc)
    getVersion() Récupération de la version du composant
    setVersion(long version) Définition de la version du composant
    getCreationDate() Récupération de la date de création du composant
    getLastUpdateDate() Récupération de la date de mise à jour du composant
    getOwner() Récupération du propriétaire du composant
    addTag(String name, String value, boolean readonly) Ajout d’un tag sur le composant
    addTag(String name, String[] values, boolean readonly) Ajout d’un tag sur le composant contenant plusieurs valeurs
    getTagValue(String name) Récupération de la valeur d’un tag
    getTagValues(String name) Récupération des valeurs d’un tag
    getTags() Récupération de la liste des noms de tags du composant

    Les fonctions disponibles sur l’objet Document sont :

    Fonctions Description
    getVersionSeriesId() Récupération de l’identifiant de VersionSeries
    getVersionLabel() Récupération du label de version
    isCurrentVersion() Détermine si le document est la version courante
    getFiles() Récupération des identifiants de fichiers du documents
    getDocumentFiles() Récupérération des fichiers d’un document
    addFile(String fileId) Ajout d’un fichier temporaire comme contenu
    setFiles(String[] fileIds) Définition de fichiers temporaire comme contenus

    Les fonctions disponibles sur l’objet DocumentFile sont :

    Fonctions Description
    getId() Récupération de l’identifiant du fichier
    setId(String id) Définition de l’identifiant du fichier
    getName() Récupération du nom du fichier
    setName(String name) Définition du nom du fichier
    getFormatCode() Récupération du format du fichier
    setFormatCode(String formatCode) Définition du format du fichier
    getCreationDate() Récupération de la date de création du fichier

    Fonctions spécifiques aux tâches

    Fonctions Description
    getAssignee() Déterminer la valeur du champ assignee
    setAssignee(String assignee) Définir à qui est assignée la tâche
    getWorkflow() Determiner l’identifiant du traitement de la tâche
    setWorkflow(String workflow) Définir l’identifiant du traitement de la tâche
    getParticipants() Déterminer les identités ayant participées au traitement
    addParticipant(String participant) Ajout d’un participant à une tâche
    addAttachment(String attachmentId, String componentId, String category) Ajout d’un composant en tant que pièce jointe
    addAttachments(String attachmentId, String[] componentIds, String category) Ajout de composants en tant que pièce jointe multivaluée
    getFiles() Récupération des identifiants de fichiers de la tâche
    addFile(String fileId) Ajout d’un fichier temporaire comme contenu
    setFiles(String[] fileIds) Ajout de fichiers temporaire comme contenus


    Récupérer les informations des classes de composant depuis des scripts JS.


    Pour plus d’informations concernant le modèle des classes de composants, une partie y est dédiée ici.

    Les fonctions suivantes sont disponibles sur les classes de composant récupérées depuis les services en JS.


    Fonctions communes

    Fonctions Description
    getId() Récupération de l’identifiant de la classe de composant
    getLocalizedDisplayName() Récupération du nom de la classe internationalisé en fonction de la langue de l’utilisateur courant
    getLocalizedDescription() Récupération de la description de la classe internationalisé en fonction de la langue de l’utilisateur courant
    getTagReferences() Récupération des références de tag portées par la classe de composant

    Références de tags

    Fonctions Description
    getTagName() Récupération du nom de la référence de tag
    getLocalizedDescription() Récupération de la description de la référence internationalisé en fonction de la langue de l’utilisateur courant
    getPattern() Récupération du pattern de la référence de tag
    getDefaultValue() Récupération de la valeur par défaut de la référence de tag
    getOrder() Récupération de la position de la référence de tag
    isMandatory() Détermine si le tag est obligatoire
    isMultivalued() Détermine si le tag est multivalué
    isReadonly() Détermine si le tag est en lecture seule
    isTechnical() Détermine si le tag est technique

    Fonctions spécifiques aux classes de tâches

    Fonctions Description
    getIcon() Récupération de l’icône de la classe
    getAnswers() Récupération des réponses

    Réponses

    Fonctions Description
    getId() Récupération de l’identifiant de la réponse
    setId(String id) Définition de l’identifiant de la réponse
    getLocalizedDisplayName() Récupération du nom de la réponse internationalisé en fonction de la langue de l’utilisateur courant
    getLocalizedConfirmationMessage() Récupération du message de confirmation de la réponse internationalisé en fonction de la langue de l’utilisateur courant
    hasReason() Détermine si la réponse à un motif


    Cette section décrit comment consommer les services exposés par FlowerDocs directement depuis l’API JS.

    Composants

    Tout comme la couche de service, un service par catégorie de composant est mis à dispotion :

    • Document : JSAPI.get().document()
    • Dossier : JSAPI.get().folder()
    • Dossier virtuel : JSAPI.get().virtualFolder()
    • Tâche : JSAPI.get().task()

    CRUD & Recherche

    Fonctions Description
    create(Component[] components, successCallback, errorCallback) Création de nouveaux composants d’une même catégorie
    get(String[] ids, successCallback, errorCallback) Récupération des composants à partir de leurs identifiants
    update(Component[] components, successCallback, errorCallback) Mise à jour des composants
    doDelete(String[] ids, successCallback, errorCallback) Suppression des composants à partir de leurs identifiants
    search(SearchRequest request, successCallback, errorCallback) Recherche de composants basée sur une requête

    Nota : Les paramètres successCallback et errorCallback sont décrit dans la partie Gestion des réponses et erreurs L’exemple ci-dessous permet de créer un document et le sauvegarder dans Flower:

    var bill = new Document();
    bill.setName("FC140023 ");
    bill.setClassId("ProviderBill");
    
    var documentAPI = JSAPI.get().document();
    documentAPI.create(new Array(bill), function(documents)
    {
       JSAPI.get().getNotificationAPI().sendInformation(documents.length + " documents were created");
    });
    

    Les dossiers & leurs contenus

    Fonctions Description
    addChildren(String folderId, ComponentReference[] children, boolean replace) Ajout d’enfants à un dossier
    deleteChildren(String folderId, ComponentReference[] children) Suppression d’enfants d’un dossier

    L’exemple ci-dessous permet d’ajouter un document dans un dossier:

    var child = new ComponentReference("documentId", "DOCUMENT");
    var folderAPI = JSAPI.get().folder();
    folderAPI.addChildren("folderId", new Array(child), false, function()
    {
    	JSAPI.get().getNotificationAPI().sendInformation("The document has been added as child");
    });
    

    Le contenu d’un dossier est déterminé à partir de références de composant qui peuvent être instanciées tel que :

    var reference = new ComponentReference();
    reference.setId("componentId");
    reference.setCategory("componentCategory");
    

    Les tâches

    Fonctions Description
    answer(String[] ids, Answer answer) Application d’une réponse à plusieurs tâches
    assign(String[] ids, String userId) Assignation de tâche à un utilisateur

    L’exemple ci-dessous permet d’appliquer une réponse à une tâche:

    var taskAPI = JSAPI.get().task();
    taskAPI.answer(new Array("taskId"), new Answer("Validate"), function()
    {
        JSAPI.get().getNotificationAPI().sendInformation("Answer was applied");
    });
    

    Gestion des réponses et erreurs

    Toutes les fonctions possèdent deux types de callback :

    • Un callback exécuté en cas de succès success
    • Un callback, optionnel, exécuté en cas d’erreur error

    L’exemple ci-dessous permet de mettre à jour un document :

    var documentAPI = JSAPI.get().document();
    documentAPI.get(new Array("unknown"), 
    	function(documents){
    		console.info("Success!");
    	},
    	function(error){
    		console.error("Documents could not be get: " + error);
    	}
    );
    

    Classe de composants

    Tout comme la couche de service, un service par catégorie de composant est mis à dispotion :

    • Classe de document : JSAPI.get().documentClass()
    • Classe de dossier : JSAPI.get().folderClass()
    • Classe de dossier virtuel : JSAPI.get().virtualFolderClass()
    • Classe de tâche : JSAPI.get().taskClass()

    Pour chacun de ces services, la fonction `get permettant de récupérer la classe de composant est disponible. Comme les services de composants, toutes les fonctions possèdent deux callback, un de succès et un d’erreur (cf Gestion des réponses et erreurs).

    var documentClassAPI = JSAPI.get().documentClass();
    documentClassAPI.get(new Array("unknown"), 
    	function(documentClasses){
    		console.info("Success !");
    	},
    	function(error){
    		console.error("Document classes could not be get: " + error);
    	}
    );
    

    Plusiers types d’actions sont mis à disposition :

    • Bouton : texte présenté sous la forme d’un bouton
    • Icône : basé sur les différentes polices d’icônes supportés par Flower
    • DOM : élément HTML

    Conteneur d’actions

    Les actions sont regroupées dans des conteneurs d’actions à partir desquels il est possible d’accéder aux actions. Pour accéder à une action, il est donc nécessaire d’identifier quel conteneur est concerné.


    Pour lister les actions présentes dans un conteneur container, il faut utiliser la fonction suivante :

        console.log("Container actions : " + container.getIds());
    


    Tous les conteneurs d’actions de FlowerDocs sont accessibles via la JSAPI. Ceci permet de les manipuler, par exemple, il est possible d’ajouter, supprimer, désactiver, cacher ou bien modifier des actions de ce conteneur.

    Dans un formulaire

    L’objet componentFormAPI.getActions() permet d’intéragir avec les actions d’un formulaire présentant un document, dossier…

    Pour cela plusieurs fonctions sont exposées :

    Fonctions Description
    getHeaderActions() Récupère le conteneur d’action dans l’en-tête
    getTaskActions() Récupère le conteneur d’action permettant la création de tâches
    getFooterActions() Récupère le conteneur d’action de pied de page (validation, annulation…)

    Accéder à une action

    A partir d’un conteneur d’action container, plusieurs moyens permettent d’accéder à une action.

    • De manière synchrone (ce qui nécessite que l’action soit, lors de l’exécution, déjà ajoutée au conteneur) :

      var action = container.get(actionId);
      
    • De manière asynchrone :

      container.registerForAdd(function(action){});
      

    Les actions

    Fonctions disponibles

    Une fois qu’une action a été récupérée, il est possible d’intéragir avec en utilisant les fonctions mises à disposition :

    Fonctions Description
    setEnabled(enabled) Activer ou désactiver l’action
    isEnabled() Détermine si l’action est activée ou non
    setTemporaryDisabled(disabled) Désactive de manière temporaire une action (seulement pour les boutons)
    getId() Récupère l’identifiant d’une action
    execute() Exécute l’action de manière programmatique

    Exemple : Désactiver l’action Annuler d’un composant

    var actions = componentFormAPI.getActions();
    var cancelAction = actions.getFooterActions().get("cancel");
    cancelAction.setEnabled(false);
    

    Interactions avec les actions de composant

    Au sein d’un formulaire d’indexation d’un composant, il est possible de réagir à l’exécution d’une action.

    Pour cela, il suffit d’utiliser la fonction registerForActionConfirmation(container, name, function(value, executor){}) :

    • container : le container de l’action soit header, footer ou task
    • name le nom de l’action
    • function(value, executor) la fonction à exécuter lorsque l’utilisateur intéragit avec l’action

    Exemple : Pour appeler une fonction à chaque fois qu’un utilisateur clique sur le bouton Annuler d’une page d’indexation

    JSAPI.get().registerForComponentChange(function(api, results, phase) {
    	api.getActions().registerForActionConfirmation("footer", "cancel", function(value) {
    		//do some stuff
    	})
    });
    

    Pour avoir un contrôle encore plus fin sur les actions, l’objet executor fourni en paramètre à la closure permet de :

    • Bloquer l’exécution de l’action :

      executor.hold();
      
    • Reprendre l’exécution de l’action :

      executor.resume();
      
    • Déterminer si l’exécution de l’action est bloquée ou non :

      executor.isHeld();
      

    Nota : si l’exécution d’une action n’est pas bloquée, elle reprend une fois la closure exécutée.


    Exemples : Bloquer l’exécution d’une action jusqu’à l’obtention du retour d’un appel asynchrone

    var actions = formAPI.getActions() 
    actions.registerForActionConfirmation("footer", "Valider", function(value, executor) {
        executor.hold();
        setTimeout(function(){ 
            executor.resume(); 
        }, 3000);
    });
    
    var actions = formAPI.getActions() 
    actions.registerForActionConfirmation("footer", "Refuser", function(value, executor) {
        executor.hold();
        setTimeout(function(){  
            JSAPI.get().getNotificationAPI().sendError("La tâche ne peut pas être refusée."); 
        }, 3000);
    });
    

    Construire une actions

    Grâce à l’API ActionFactoryAPI, il est possible de créer des actions personnalisées.

    Action de type bouton

    Deux sortes d’action de type bouton peuvent être créées :

    • les textuelles ou principales :

      JSAPI.get().getActionFactoryAPI().buildTextual(id, displayName, function(a){});
      
    • les mineures

      JSAPI.get().getActionFactoryAPI().buildMinor(id, displayName, function(a){});
      

    Exemple : Ajout d’une action de type bouton sur le tableau présentant le contenu d’un dossier

    JSAPI.get().registerForFolderChildrenLoaded(function(api, component, phase) {
    	var action = JSAPI.get().getActionFactoryAPI().buildTextual("action", "Mon action","fa fa-plus" function(a)
    	{
    		console.log("execute action: " + a.getId());
    	});
    	api.getDocumentChildren().getActions().add(action);
    });
    

    Action de type icône

    Ce type d’action se base sur la police de caractère FontAwesome proposant un choix important d’icône à travers des styles CSS.

    Exemple : Ajout d’une action icône sur les pièces jointes d’une tâche

    var cardAPI = JSAPI.get().getCardAPI();
    cardAPI.registerForAttachment(function(card, task, definition, component){
    	var actionAPI = JSAPI.get().getActionFactoryAPI();
    	var action = actionAPI.buildIcon("myAction","Mon action", "fa fa-user", function(actionPresenter){
    		console.info("on click");
    		actionPresenter.setEnabled(false);
        });
        card.getActions().add(action);
    });
    

    Action de type menu

    Ce type d’action se base sur la police de caractère FontAwesome proposant un choix important d’icône à travers des styles CSS et un label.

    Exemple : Ajout d’une action icône sur les pièces jointes d’une tâche

    var actionSet = JSAPI.get().getLastComponentFormAPI().getActions().getHeaderActions();
    var actionAPI = JSAPI.get().getActionFactoryAPI();
    var action = actionAPI.buildMenu("myAction", "Mon menu", "fa fa-user", function(actionPresenter){
    		console.info("on click");
    });
    actionSet.add(action)
    

    Action DOM

    Ce troisième type d’action possède également les propriétés name et label. La dernière propriété est un élement DOM element. Il est possible d’intéragir avec cet élément DOM en utilisant les évenements classiques de DOM comme onclick, onmouseover, …

    Exemple :

    	var actionAPI = JSAPI.get().getActionFactoryAPI();
    	
    	var element = document.createElement('button'); 
    	element.innerHTML = "Custom button title";
    	var action = actionAPI.buildDOM("className", "hover label", element);
    
    	element.onclick= function(){ 
    		console.log("Click on DOM button");
    	}
    


    Cette section a pour but de décrire comment surcharger les libellés provenant du produit.


    Afin d’effectuer cette surcharge, l’API suivante est à disposition :

    JSAPI.get().getLabelsAPI();
    


    Cette fonctionnalité est également disponible en surchargeant une partie des libellés via des fichiers de propriétés. La documentation concernant cette partie est disponible ici.


    Afin de modifier ou récupérer des libellés existants, les fonctions suivantes sont à disposition :

    Fonction Description
    getLabel(String labelName) Récupère la valeur d’un libellé
    getLabelWithParams(String labelName, Object… params) Récupère la valeur d’un libellé ayant des paramètres en entrée
    getLabelWithPlural(String labelName, int pluralCount, Object… params) Récupère la valeur d’un libellé ayant des paramètres en entrée en prenant l’application du pluriel ou non avec la valeur du paramètre pluralCount
    setLabel(String labelName, String value) Surcharge la valeur d’un libellé
    getLabelsNames() Récupére tous les identifiants de libellés

    Exemple : Surcharger le libellé de recherche sauvegardée

    	var api = JSAPI.get().getLabelsAPI();
    	//Initial value : My saved searches
    	api.setLabel("searchSaved", "Favorite searches");
    


    FlowerDocs s’appuie sur un mécanisme de place permettant de définir dans l’URL l’activité (ou écran) sur laquelle se trouve l’utilisateur. Le fait que cette place soit portée par l’URL permet aux utilisateurs de pouvoir :

    • rafraîchir leur navigateur tout en restant dans le même contexte
    • de naviguer à travers l’historique du navigateur (boutons Précédent et Suivant)

Pour piloter ces fonctionnalités à travers l’API JavaScript, une API de navigation est mise à disposition :

JSAPI.get().getNavigationAPI();
Fonctions Description
reload() Permet de recharger la place courante sans confirmation
goBack() Permet de revenir à la place précédente (équivalent au bouton précédent)
getWhereId() Permet d’obtenir l’identifiant de la place courante
getWhere() Permet d’obtenir le type de la place courante
goToComponentPlace(category, identifiant, confirmation) Permet de rediriger l’utilisateur vers l’écran de modification d’un composant en fournissant :
-category : DOCUMENT, FOLDER, TASK, VIRTUAL_FOLDER
-identifiant : identifiant du composant à ouvrir
-confirmation : booléen permettant de désactiver la confirmation au changement de place
goTo(place, confirmation) Permet de rediriger l’utilisateur vers une place avec possibilité ou non de désactivation de confirmation de changement de place

L’API de navigation permet également de surcharger la place défaut (définie au niveau du profile). Pour cela, il est possible de s’abonner à son ouverture via la fonction registerForPlaceChange(callback)

Exemple : Surcharger la place par défaut par le formulaire de recherche pliSearch

var api = JSAPI.get().getNavigationAPI();
api.registerForPlaceChange(function(placeToken, callback){
   callback.go(flower.docs.PlaceBuilder.build("search(pliSearch)"));
});

Une API JavaScript permet d’obtenir des informations concernant les utilisateurs :

JSAPI.get().getUserAPI();

Obtenir un objet utilisateur

Pour obtenir un objet utilisateur deux méthodes sont mise à disposition :

  • Utilisateur courant :

    JSAPI.get().getUserAPI().getCurrentUser();
    
  • Autre utilisateur :

    JSAPI.get().getUserAPI().getUser("kta", function(user){ 
    	console.log("user: "+ user.getId())
    });
    
Fonctions Description
getScope() Récupération du scope auquel l’utilisateur est connecté
getCurrentUser() Récupération de l’utilisateur courant
getUser(id, closure) Récupération d’un utilisateur par son identifiant
addAttribute(name,values) Ajout d’un attribut pour l’utilisateur connecté
removeAttribute(name) Suppression des valeurs d’un attribut de l’utilisateur connecté

Informations d’un utilisateur

Les fonctions listées ci-dessous peuvent être appelées sur un objet utilisateur.

Fonctions Description
getId() Récupération de l’utilisateur
getDisplayName() Récupération du libellé de l’utilisateur
getFirstName() Récupération du prénom de l’utilisateur
getLastName() Récupération du nom de famille de l’utilisateur
getProfiles() Récupération des équipes auxquelles appartient l’utilisateur
getGroups() Récupération des groupes auxquels appartient l’utilisateur
getMail() Récupération de l’adresse email de l’utilisateur
getAttributeValue(name) Récupération de la valeur d’un attribut de l’utilisateur
getAttributeValues(name) Récupération des valeurs d’un attribut de l’utilisateur

Assignee Provider

Un Assignee Provider permet de fournir à la GUI un callback exécuté lorsqu’un utilisateur recherche un utilisateur auquel assigner une tâche. Par défaut, l’ensemble des utilisateurs sont remontés.

Dans certaines situations métiers, il peut être nécessaire de filtrer ces utilisateurs. Pour cela, l’API Utilisateur met à disposition la fonction :

var userAPI = JSAPI.get().getUserAPI();
userAPI.registerAssigneeProvider(function(tasks, key, callback){
});


Paramètres de la fonction :

Paramètre Description
tasks Liste des tâches sur lesquelles l’assignation est effectuée
key Saisie de l’utilisateur
callback fonction de callback exécutée

2 méthodes sont disponibles pour appeler le callback :

  • callback.provide(users) - doit être appelé avec un tableau d’objet User.
  • callback.na() - ne pas filtrer les utilisateurs.



Dans le cas d’une assignation effectuée à partir d’une recherche, le paramètre tasks est construit à partir des résultats de recherche. Ils ne comportent pas les tags qui ne sont pas présents dans l’objet SearchResult associé et sont donc dépendants du formulaire de recherche.

Un type de filtre est fourni par défaut à travers le web service REST ./plugins/rest/profiles/<profiles>/users/. Ce web service permet de rechercher des utilisateurs faisant partie d’une ou plusieurs équipes.

Exemple : sélection d’utilisateurs faisant partie des équipes JURIDIQUE et GESTIONNAIRE :

var userAPI = JSAPI.get().getUserAPI();
userAPI.registerAssigneeProvider(function(tasks, key, callback){
	var profile = "JURIDIQUE,GESTIONNAIRE";
	$.get("./plugins/rest/profiles/"+profile+"/users/"+key,function(data){
		var users = new Array();
		$.each(data, function(k,v) {
			users.push(User.fromJSON(JSON.stringify(v)));
		});
		callback.provide(users);
	});
});

Afin de faciliter l’accès à certaines actions, plusieurs conteneurs de raccourcis peuvent être manipulés à travers l’API JS :

  • ContextualMenuAPI : menu contextuel de composant (présent sur les tableaux de résultats de recherche)
  • MenuShortcutsAPI : bouton + accessible depuis la barre de menu
  • FloatingShortcutsAPI : bouton flottant + accessible depuis la page d’accueil


Afin d’accéder à ces APIs, deux moyens sont fournis :

  • get() : accéder à n’importe quel moment au conteneur de raccouris chargé
  • registerForLoad(function(api){}); : s’abonner au chargement d’un conteneur de raccourci

Général

Les fonctions suivantes sont mises à disposition sur les conteneurs de raccourcis.

Fonctions Description
addCircled(String id, String icon, String color, String name, String description, Callback callback) Ajoute un raccourci avec une icône de type cercle comportant une description au survol
addIconized(String id, String icon, String color, String name, Callback callback) Ajoute un raccourci avec une icône (FontAwesome)
add(String id, Element element, String name, Callback callback) Ajoute un raccourci avec un élement DOM comme icône
remove(String id) Supprime un raccourci à partir de son identifiant
getIds() Récupère les identifiants des raccourcis présents

Exemples

Afin de s’abonner au chargement de ces menus de raccourcis, les fonctions suivantes vont être utilisées :

Créer un dossier depuis la barre de menu

MenuShortcutsAPI.get().registerForLoad(function(api){ 
	api.addCircled("createFolder", "fas fa-folder-open", "flat-red" , "Dossier","Créer un dossier", function(){
	    var newFolder = new Folder();
	    newFolder.setClassId("Folder");
	    var popup = JSAPI.get().getPopupAPI().buildComponentCreation(newFolder);
	    popup.show();
	});  
});

Créer un document depuis le bouton flottant

FloatingShortcutsAPI.get().registerForLoad(function(api){ 
	var circle = new Circle();
	circle.setSize(1);
	circle.setContent("fa fa-user");
	circle.setColor("flat-green");
	api.add("createCourrier", circle.asElement() , "Courrier", function(){
		var newDocument = new Document();
		newDocument.setClassId("CourrierEntrant");
		var popup = JSAPI.get().getPopupAPI().buildComponentCreation(newDocument);
		popup.show();
	});  
});

Menu contextuel

Des fonctions supplémentaires sont fournies pour manipuler un menu contextuel :

Fonctions Description
add(String groupId, String id, String icon, String label, Callback callback) Ajoute un raccourci avec une icône dans le menu contextuel et dans un groupe de l’en-tête du tableau
getSelected() Récupère les composants sélectionnés
getCategory() Récupère la catégorie des composants sélectionnés

En utilisation la fonction add, il est possible de regrouper des actions en fonction du besoin en utilisant le même identifiant de groupe.

Création d’une tâche à partir de deux documents.

ContextualMenuAPI.get().registerForLoad(function(api){
	if(api.getSelected().length != 2 || api.getCategory() != "DOCUMENT"){
		return;
	}

	api.add("customActions", "createTask", "fa fa-user" , "Tâche", function(){
		var newTask = new Task();
		newTask.setClassId("GEC_Step0_Creation");
		TagOracle.predict(api.getSelected(), newTask);			
		newTask.addAttachments("Courrier", Ids.from(api.getSelected()), "DOCUMENT");			
		var popup = JSAPI.get().getPopupAPI().buildComponentCreation(newTask);
		popup.show();
	});  
});

Réponses à une tâche

Si l’utilisateur sélectionne des tâches d’une même classe et que celle-ci a des réponses, ces réponses seront affichées comme des actions dans le menu contextuel.

Cette fonctionnalité peut être désactivée en ajoutant le script JS suivant :

function registerToAddAnswersInTaskContextualMenu(){}

Objets disponibles

Carte

Les fonctions disponibles sur les cartes sont les suivantes :

Fonctions Description
setTitle(title) Modifie le titre de la carte
setHeading(heading) Modifie la description de la carte
getActions() Récupère le conteneur d’action de la carte
getStyle(style) Récupère la classe CSS de la carte
addStyle(style) Ajoute la classe CSS à la carte
setStyle(style) Remplace les classes CSS de la carte par celle fournie
asElement() Récupère la carte comme un element DOM

Cartes conteneur

Les cartes conteneur, sont de grandes cartes dans lesquels il est possible d’ajouter du contenu. Les fonctions disponibles sont les suivantes :

Fonctions Description
setTitle(title) Modifie le titre de la carte
setCaption(caption) Modifie la description de la carte
setIcon(icon) Modifie l’icône de la carte
addCard(card) Permet d’ajouter une carte à celle-ci
setContent(content) Permet d’ajouter un element DOM à la carte
setVisible(isVisible) Permet de cacher ou rendre visible la carte
setReduced(isReduced) Permet de réduire la carte (uniquement le titre est visible)
getStyle(style) Récupère la classe CSS de la carte
addStyle(style) Ajoute la classe CSS à la carte
setStyle(style) Remplace les classes CSS de la carte par celle fournie

Enregistrement

Afin d’accéder aux cartes, il faut s’enregistrer à leur ajout. Il existe deux types de cartes pour lesquelles l’API JS peut s’enregistrer, les cartes de pièces jointes et celles de résultats de recherches.

Résultat de recherche

L’abonnement à l’ajout d’une carte de résultat de recherche est effectué à l’aide de l’objet cardAPI :

var cardAPI = JSAPI.get().getCardAPI();
cardAPI.registerForComponent(function(card, component){
	...
}

Les paramètres de la fonction sont :

  • card : la carte ajoutée
  • component : le composant créé à partir du résultat de recherche

Exemple :

var cardAPI = JSAPI.get().getCardAPI();
cardAPI.registerForComponent(function(card, component){
	var actionAPI = JSAPI.get().getActionFactoryAPI();
	var myElement = document.createElement('button'); 
	myElement.innerHTML = "Custom button title";
	var action = actionAPI.buildDOM("className", "My action description", myElement);

	card.getActions().add(action);
	card.setTitle("Title");
	card.setHeading("Heading");

	myElement.onclick= function(){ 
		console.log(card);
		console.log(component.getClassId());
    }
});

Pièce jointe

Chargement

Pour chaque définition de pièces jointes, il est possible de s’abonner au chargement de la carte correspondante par un mécanisme d’abonnement à l’aide de l’objet cardAPI :

var cardAPI = JSAPI.get().getCardAPI();
cardAPI.registerForAttachment(function(card, task, attDefinition, component){
	...
}

Les paramètres de la fonction sont :

  • card : la carte ajoutée
  • task : la tâche sur laquelle est attachée la pièce jointe
  • attDefinition : la définition de la pièce jointe
  • attComponent : le composant attaché à la tâche

Exemples :

var cardAPI = JSAPI.get().getCardAPI();

cardAPI.registerForAttachment(function(card, task, definition, component){
	var actionAPI = JSAPI.get().getActionFactoryAPI();
	var myElement = document.createElement('button'); 
	myElement.innerHTML = "Custom button title";
	var action = actionAPI.buildDOM("className", "My action description", myElement);
	
	card.getActions().add(action);
	card.setTitle("Title");
	card.setHeading("Heading");

	myElement.onclick= function(){ 
		console.log(card);
		console.log(task.getClassId());
		console.log(definition.getClassId());
		console.log(component);
    }
});

Pour ajouter, de manière programmatique, une pièce jointe sur une tâche il est possible de déclencher un événement tel que :

var doc = new Document();
doc.setName("Document attaché");
doc.setClassId("Claim");
var event = new AddTaskAttachmentEvent("Attachment2", doc);
JSAPI.get().getLastComponentFormAPI().fireEvent(event);

Changements

Afin de réagir aux modifications effectuées par les utilisateurs sur les pièces jointes, il est possible de s’abonner aux changement sur l’objet card :

card.registerForChange(function(attachment){
	console.info("Detected attachment change : " + attachment);		
});

Actions

Les cartes présentant les pièces jointes de type DOCUMENT disposent d’un ensemble d’actions natives.

Ces actions peuvent être gérées de manière programmatique à partir de leur identifiant :

  • upload-version : upload d’une nouvelle version d’un document
  • delete-version : supprimer la version uploadée
  • upload-attached : upload d’un document à créer
  • delete-attached : supprimer le document existant ajouté

Un lookup consiste en la récupération de données issues d’un référentiel tiers. Il permet ainsi d’enrichir les données stockées ou restituées à travers Flower. L’API JavaScript Lookup permet de faire appel à des lookups, au sein d’une extension JavaScript de FlowerDocs, de manière dynamique.

Cette fonctionalité s’appuie sur une notion de plugin permettant d’exécuter différents types d’appel/requêtes (base de données, web services…).

Lookup plugins

Plugin Javascript

Un lookup plugin peut être défini en Javascript à l’aide de l’API mise à disposition. Pour cela, il est nécessaire d’instancier un objet LookupPlugin comme indiqué dans l’exemple ci-dessous. Un plugin de ce type dispose d’un LookupHandler appelé lorsque le lookup est exécuté afin de fournir à Flower une liste de résultats correspondants.

var lookupPlugin = new LookupPlugin();
lookupPlugin.setLookupHandler(function(fieldName, fieldValue, callback){
	var results = new Array();
	callback.onSuccess(results);
});

Chaque plugin doit ensuite être mis à disposition de l’application. Le snipet ci-dessous indique comment enregistrer le plugin où lookupId correspond au nom du lookup.

var lookupAPI = JSAPI.get().getLookupAPI();
lookupAPI.register("lookupId", lookupPlugin);

Plugin serveur

Pour rendre un LookupPlugin disponible depuis l’interface graphique, il faut :

  • Définir le plugin dans le contexte Spring :

    <bean id="BusinessReferenceLookup" class="com.flower.docs.gui.server.lookup.sql.DBLookupPlugin">
    <property name="dataSource" ref="lookupDataSource" />
    <property name="requests">
    	<list>
    	  <bean class="com.flower.docs.gui.server.lookup.sql.FieldLookupRequest">
    		<property name="request" value="Select DISPLAY_NAME from BUSINESS_REFERENCES WHERE REF LIKE '%{value}%'" />
    		<property name="column" value="DISPLAY_NAME" />
    	  </bean>
    	</list>
    </property>
    </bean>
    
  • Référencer le plugin au sein du catalogue LookupPluginCatalog :

    <entry key="<id du plugin>" value-ref="<id du bean Spring>" />
    

Exemple complet :

<util:map id="LookupPluginCatalog" map-class="java.util.HashMap">
	<entry key="BusinessReferenceLookup" value-ref="BusinessReferenceLookup" />
</util:map>
<bean id="BusinessReferenceLookup" class="com.flower.docs.gui.server.lookup.sql.DBLookupPlugin">
	<property name="dataSource" ref="lookupDataSource" />
	<property name="requests">
		<list>
			<bean class="com.flower.docs.gui.server.lookup.sql.FieldLookupRequest">
				<property name="request" value="Select DISPLAY_NAME from BUSINESS_REFERENCES WHERE REF LIKE '%{value}%'" />
				<property name="column" value="DISPLAY_NAME" />
			</bean>
		</list>
	</property>
</bean>
<bean id="lookupDataSource" class="oracle.jdbc.pool.OracleDataSource" destroy-method="close">
	<property name="connectionCachingEnabled" value="true" />
	<property name="URL" value="${jdbc.url:jdbc:oracle:thin:@//localhost:1521/orcl}" />
	<property name="user" value="${jdbc.username:hr}" />
	<property name="password" value="${jdbc.password:oracle}" />
	<property name="connectionCacheProperties">
		<props merge="default">
			<prop key="MinLimit">${jdbc.minLimit:1}</prop>
			<prop key="MaxLimit">${jdbc.maxLimit:20}</prop>
			<prop key="InitialLimit">${jdbc.initialLimit:1}</prop>
			<prop key="ConnectionWaitTimeout">${jdbc.connectionWaitTimeout:120}</prop>
			<prop key="InactivityTimeout">${jdbc.inactivityTimeout:180}</prop>
			<prop key="ValidateConnection">${jdbc.validateConnection:true}</prop>
		</props>
	</property>
</bean>

Utilisation d’un lookup

Les lookups enregistrés au sein de l’application peuvent être consommés de différentes manières en fonction des besoins.

Utilisation adhoc

L’exemple ci-dessous décrit l’exécution de manière adhoc d’un LookupPlugin. Cette exécution peut tout aussi bien être utilisée au sein d’un abonnement aux modifications d’un tag afin de remplir un autre tag.

Exemple : exécution d’un lookup BusinessReferenceLookup

JSAPI.get().getLookupAPI().lookup("BusinessReferenceLookup" ,"BusinessReference", "ref123", function(results) {
	// Utilisation des résultats du lookup
});

L’objet results est un tableau d’objets LookupResult qui sont utilisables tel que :

Fonctions Description
getKey() Permet de récupérer la clé d’un résultat (i.e nom symbolique )
getValue() Permet de récupérer la valeur ou le libellé d’un résultat

Dans cet exemple, on execute le LookupPlugin dont l’identifiant Spring Beans est BusinessReferenceLookup avec en paramètre le nom du tag concerné et sa valeur.

Exemple : Suggestion de valeur pour un tag

formAPI.registerForFieldChange("Montant", function(fieldName, fieldValue) {			
	JSAPI.get().getLookupAPI().lookup("DBLookup","Montant", fieldValue, function(results) {
		formAPI.suggest("Montant", results);
	});
});

Dans cet exemple, le lookup DBLookup est utilisé pour suggérer des valeurs au tag Montant

Exemple : Définition des valeurs autorisées dans une liste

formAPI.registerForFieldChange("Montant", function(fieldName, fieldValue) {			
	JSAPI.get().getLookupAPI().lookup("DBLookup","Montant", fieldValue, function(results) {
		var restrictedAllowedValues = new Array();
		for ( var i in results) {
			result = results[i];
			var allowedValue = buildAllowedValue(result.getName(), result.getValue());
			restrictedAllowedValues[i] = allowedValue;
		}
		formAPI.setAllowedValues("EDS", restrictedAllowedValues);
	});
});

function buildAllowedValue(symbolicName, label) {
	var language = new Language("EN");

	var allowedValue = new AllowedValueDefinition();
	allowedValue.setSymbolicName(symbolicName);

	var displayNames = new I18NLabel()
	displayNames.setLabel(language, label);
	allowedValue.setDisplayNames(displayNames);
	return allowedValue;
}

Binding

Cette API JavaScript fournit également la possibilité de remplir automatiquement un champ lorsqu’il est modifié à partir du retour d’un LookupPlugin. Pour cela, il est possible d’utiliser la fonction bindFieldOnLookup(String tagName, String lookupId) où :

  • tagName est l’identifiant du tag concerné
  • lookupId est l’identifiant du LookupPlugin à utiliser.

Exemple : Binding d’un tag sur le lookup userLookup

var formAPI = JSAPI.get().getLastComponentFormAPI();
formAPI.bindFieldOnLookup("DestinatairePourInfo", "userLookup");


En indexation, un dossier est composé d’un formulaire et du contenu du dossier correspondant aux tableaux de recherches de ses sous-dossiers et de ses documents.

Afin de manipuler le contenu du dossier, il faut s’abonner à son ajout :

JSAPI.get().registerForFolderChildrenLoaded(function(folderChildrenAPI, component, phase) {
	//Do some stuff
}

Une fois abonné au chargement du contenu du dossier, les fonctions suivantes sont disponibles sur l’API FolderChildrenAPI:

Fonctions Description
getFolder() Récupération du dossier dont le contenu a été chargé
getDocumentChildren() Récupération du tableau de documents du dossier
getFolderChildren() Récupération du tableau de sous-dossier du dossier

Manipulation des tableaux

Pour les tableaux de documents et sous-dossiers, les fonctions suivantes sont disponibles :

Fonctions Description
getActions() Récupération du conteneur d’actions présent au dessus du tableau
setVisible(isVisible) Affiche ou cache le tableau
addStyleName() Ajout d’un style sur le tableau


L’historique permet d’afficher les modifications qui ont été effectuées sur un composant depuis sa création. Afin de modifier l’historique d’un composant, il faut s’abonner à l’ouverture de l’historique :

    var factAPI = JSAPI.get().getHelperFactory().getFactAPI();  
    factAPI.register(component.getId(), function(facts, callback){
		//Manipulate facts of component

   });

L’historique est composé de faits qui comprennent un ensemble d’attributs. Ces faits peuvent être personnalisés grâce aux fonctions suivantes :

Fonctions Description
Fact(component) Création d’un fait à partir d’un composant
getUser() Récupération de l’utilisateur du fait
setUser(user) Modification de l’utilisateur du fait
getAction() Récupération du conteneur d’action du fait
setAction(action) Modification de l’action du fait
getDescription() Récupération de la description du fait
setDescription(description) Modification de la description du fait
getCreationDate() Récupération de la date de création du fait
setCreationDate(date) Modification de la date de création du fait
getUpdatedFields() Récupération des champs du faits
setUpdatedFields(updatedFields) Modification des champs du fait
addUpdatedField(updatedField) Ajout d’un champ dans le fait
addUpdatedFields(resultFields) Ajout de plusieurs champs dans le fait

Les types d’action supportés pour les faits sont :

  • CREATE : Création d’un composant
  • UPDATE : Mise à jour d’un composant
  • VERSION : Création d’une version de composant
  • ASSIGN : Assignation d’une tâche à un utilisateur
  • ADD_CONTENT : Ajout d’une pièce jointe pour les tâches, ajout ou mise à jour de contenu pour les documents et ajout de composants dans un dossier
  • DELETE_CONTENT : Suppression d’une pièce jointe pour les tâches, suppression de contenu pour les documents et suppression de composants dans un dossier


Exemple : ajout de deux faits à l’historique d’un composant

JSAPI.get().registerForComponentChange(function(componentFormAPI, component, phase) {        
	var factAPI = JSAPI.get().getHelperFactory().getFactAPI();
	factAPI.register(component.getId(), function(facts, callback){
		var fact1 = new Fact(component);
		var date1 = new Date("January 15, 2017 11:13:00");
		fact1.setUser(JSAPI.get().getUserAPI().getUserId());
		fact1.setCreationDate(date1.getTime());
		fact1.setAction("UPDATE");
		var field1 = new ResultField();
		field1.setName("RefClient");
		field1.setValue("2018-01-01 12:01:07.006 +0100");
		fact1.addUpdatedField(field1);

		var fact2 = new Fact(component);
		var date2 = new Date("January 16, 2017 11:13:00");
		fact2.setCreationDate(date2.getTime());
		fact2.setDescription("Description for fact2");

		facts.push(fact1);		
		facts.push(fact2);
		callback.onProcessed(facts);
	});
});


Configurer les champs à historiser avec un document de classe FactFieldsConfiguration.

Autre

Popups

Recherche

Formulaires