Pages de calendrier

  • Rversion finale: Zurich
  • Mis à jour 31 juil. 2025
  • 8 minutes de lecture
  • Une page de calendrier est un enregistrement qui contient une collection de scripts permettant la génération personnalisée d’un affichage de calendrier ou de chronologie.

    La création de pages de calendrier de chronologie nécessite une compréhension du flux de page/d’événement et la capacité à écrire du JavaScript côté client et côté serveur.

    Formulaire Pages de calendrier

    Pour accéder aux pages de calendrier, accédez à Planificateur système > Calendriers > Pages de calendrier.

    Le formulaire fournit les champs suivants, selon le type de vue sélectionné :
    Tableau 1. Formulaire Pages de calendrier
    Champ Type de champ Description
    Nom Chaîne Nom général utilisé pour identifier la page de calendrier actuelle.
    Type de calendrier Chaîne Le type de calendrier est une chaîne utilisée pour identifier de façon unique la page de calendrier via le paramètre d’URI « sysparm_page_schedule_type ». Par exemple, une page de planification peut être consultée comme suit :

    /show_schedule_page.do ?sysparm_type=gantt_chart&sysparm_timeline_task_id=d530bf907f0000015ce594fd929cf6a4

    Vous pouvez également accéder à la page de planification en définissant le paramètre URI «sysparm_page_sys_id » sur celui de l’identificateur système hexadécimal unique de 32 caractères de la page de planification.

    Type de vue Choix Chaque type de vue affiche différentes combinaisons de champs. Deux options sont disponibles :
    • Calendriers
    • Chronologies
    Description Chaîne Description générale qui fournit des informations supplémentaires sur la page de calendrier actuelle. Ce champ n’est pas nécessaire.
    Nom de la fonction Init Chaîne
    Remarque :
    Cette fonctionnalité n’est utilisée que par les pages de calendrier de type Calendrier .
    Le nom de la fonction init spécifie le nom de la fonction JavaScript à appeler à l’intérieur de la fonction de script client pour les pages de calendrier de type calendrier.
    HTML Chaîne
    Remarque :
    Cette fonctionnalité n’est utilisée que par les pages de calendrier de type Calendrier .
    Le champ HTML est une section pouvant contenir des scripts qui est analysée par Jelly et injectée dans la page d’affichage avant le reste du calendrier. Il peut être utilisé pour transmettre des variables du serveur et définir des champs supplémentaires nécessaires.
    Script client Chaîne Le script client est une section pouvant contenir des scripts qui permet de configurer les options d’affichage de la page de calendrier. L’API est différente selon le type de vue de page de calendrier et est abordée ci-dessous.
    Processeur de serveur AJAX Chaîne
    Remarque :
    Cette fonctionnalité n’est utilisée que par les pages de calendrier de type Calendrier .
    Le processeur AJAX du serveur est spécifique aux pages de calendrier qui sont utilisées pour renvoyer un ensemble d’éléments de calendrier et de parcours à afficher.

    Pages de calendrier de chronologie

    Une page de calendrier de chronologie est un enregistrement spécifique qui contient des informations de configuration pour afficher des points et des périodes basés sur le temps à la manière d’une « chronologie ».

    La page de calendrier de chronologie fait référence à un include de script qui s’étend à partir de AbstractTimelineSchedulePage pour apporter une modification dynamique à la chronologie en fonction de différents événements et conditions. La page de calendrier et l’include de script pour la génération de chronologie permettent une personnalisation extrême et leur interface de programmation d’application (API) correspondante est documentée ci-dessous.

    Le diagramme suivant montre la série d’événements qui se produit lors de l’accès à une page de planification de chronologie. Une fois la chronologie chargée, tous les événements suivants, tels que les événements résultant d’une interaction de chronologie (par exemple, le déplacement d’un parcours de chronologie), suivent le même flux logique affiché dans la zone d’événement gris.
    Figure 1. Flux de chronologie

    Applications qui utilisent des pages de calendrier pour générer des chronologies

    • Gestion des projets
    • Calendriers de maintenance
    • Rotation d’astreinte de groupe
    • Gestion des services sur site

    Exemple de page de calendrier de chronologie

    L’exemple suivant montre comment créer une page de calendrier de chronologie avec l’include de script correspondant à l’aide de la majorité de l’API décrite ci-dessus.

    Pour cet exemple, nous allons créer une chronologie récapitulative des incidents pour qu’un gestionnaire de support de projet visualise tous les nouveaux incidents. Tous les nouveaux incidents doivent être affichés sous la forme de points uniques où la priorité de l’incident est distinguée par une icône de point différente. En outre, tous les incidents fermés doivent être affichés sur la chronologie dans un groupe distinct qui indique la durée de l’incident avant sa fermeture. Étant donné que le chef de projet souhaite pouvoir fermer facilement les nouveaux éléments qui sont résolus sans utiliser de liste de formulaires, nous gérerons l’événement de déplacement vertical permettant aux nouveaux incidents d’être glissés vers le groupe d’incidents fermés ou les éléments à l’intérieur.

    Page de calendrier

    Créez une page de calendrier avec les propriétés suivantes :
    • Nom : Incidents matériels
    • Type de calendrier : incident_timeline
    • Type d’affichage : Chronologie
    • Script client :
    // Set our page configuration
    glideTimeline.setReadOnly(false);
    glideTimeline.showLeftPane(true);
    glideTimeline.showLeftPaneAsTree(true);
    glideTimeline.showTimelineText(true);
    glideTimeline.showDependencyLines(false);
    glideTimeline.groupByParent(true);
    glideTimeline.setDefaultPointIconClass('milestone');
     
    // We will define what items to display and provide a custom event handler for moving new items to the closed state
    glideTimeline.registerEvent('getItems', 'IncidentTimelineScriptInclude');
    glideTimeline.registerEvent('elementMoveY', 'IncidentTimelineScriptInclude');

    Script Include

    Maintenant que la page de calendrier a été créée, nous devons générer un include de script correspondant pour les événements qui ont été enregistrés. Créez un include de script avec les propriétés suivantes :
    • Nom : IncidentTimelineScriptInclude
    • Actif : vérifié
    • Glide AJAX activé : vérifié
    • Script :
    // Class Imports
     
    var IncidentTimelineScriptInclude = Class.create();
    IncidentTimelineScriptInclude.prototype = Object.extendsObject(AbstractTimelineSchedulePage, {
     
      /////////////////////// // GET_ITEMS ///////////////////////////////////////
      getItems:function() { 
        // Specify the page title 
        this.setPageTitle('My Custom Incident Summary Timeline');
     
        var groupNew = new GlideTimelineItem('new');
        groupNew.setLeftLabelText('New Incidents');
        groupNew.setImage('../images/icons/all.gifx');
        groupNew.setTextBold(true);
        this.add(groupNew);
     
        var groupClosed = new GlideTimelineItem('closed');
        groupClosed.setLeftLabelText('Closed Incidents');
        groupClosed.setImage('../images/icons/all.gifx');
        groupClosed.setTextBold(true);
        groupClosed.setIsDroppable(true);
     
        // This allows us to drag an open incident onto the closed group row. 
        this.add(groupClosed);
     
        // Get all the incidents and let's add only the new/closed ones appropriately 
        var now_GR = new GlideRecord('incident');
        gr.query(); 
        while(gr.next()) { 
           // Only loop through new/closed incidents 
           if(gr.incident_state != '1' && gr.incident_state != '7') continue;
     
           // Ok, we have a new/closed incident. Create the item and the span first. 
           var item = new GlideTimelineItem(gr.getTableName(), gr.sys_id); 
           var span = item.createTimelineSpan(gr.getTableName(), gr.sys_id);
     
           // Specific properties for a new incident 
           if(gr.incident_state == '1') { // New 
             item.setParent(groupNew.getSysId()); 
             item.setImage('../images/icons/open.gifx');
             span.setTimeSpan(gr.getElement('opened_at').getGlideObject().getNumericValue(),
                              gr.getElement('opened_at').getGlideObject().getNumericValue());
     
             // We will show different colors based upon the priorities only for new incidents 
             switch(gr.getElement('priority').toString()) {
               case '1': span.setPointIconClass('red_circle'); break; 
               case '2': span.setPointIconClass('red_square'); break; 
               case '3': span.setPointIconClass('blue_circle'); break; 
               case '4': span.setPointIconClass('blue_square'); break; 
               case '5': span.setPointIconClass('sepia_circle'); break; 
               default: // Otherwise, the default point icon class will be used (Milestone)
              }
             }
            // Specific properties for a closed incident 
            else if(gr.incident_state == '7') { 
              item.setParent(groupClosed.getSysId()); 
              item.setImage('../images/icons/closed.gifx');
              span.setTimeSpan(gr.getElement('opened_at').getGlideObject().getNumericValue(),
                               gr.getElement('closed_at').getGlideObject().getNumericValue()); }
     
            // Common item properties 
            item.setLeftLabelText(gr.short_description);
     
            // Common span properties
            span.setSpanText(gr.short_description);
            span.setTooltip('<strong>' + GlideStringUtil.escapeHTML(gr.short_description) + '</strong><br>' + gr.number);
            span.setAllowXMove(false);
            span.setAllowYMove(gr.canWrite() ? true:false);
            span.setAllowYMovePredecessor(false);
            span.setAllowXDragLeft(false);
            span.setAllowXDragRight(false);
     
            // Now we add the actual item 
            this.add(item); 
            } } ,
     
     
       //////////////////////// // ELEMENT_MOVE_Y /////////////////////////////////////////////////////////////
     
       /**
       * This is one of the AbstractTimelineSchedulePage event handler methods that corresponds to a vertical
       * move. The arguments for this function are defined in the API section of the event handler methods.
       */
      elementMoveY: function(spanId, itemId, newItemId) {
     
        // Get information about the current incident 
        var now_GR = new GlideRecord('incident');
        gr.addQuery('sys_id', spanId);
        gr.query(); 
        if(!gr.next()) 
          return this.setStatusError('Error', 'Unable to lookup the current incident.');
     
        // Only allow the new incidents to have their state adjusted. 
        if(gr.incident_state != '1') 
          return this.setStatusError('Error','Only new incidents can have their state adjusted.');
     
        // Get information about the dropped GlideTimelineItem. If it was dropped in an item on the "New Incidents" 
        // group let's do nothing. If it was dropped in the "Closed Incidents" then let's adjust the state automatically. 
        var grDropped = new GlideRecord('incident');
        grDropped.addQuery('sys_id', newItemId );
        grDropped.query(); 
        if(!grDropped.next() || grDropped.incident_state == '7') { 
           // This means the dropped item was either the 'Closed Incidents' group (which has no record or sys_id) or an 
           // existing incident that is closed. The 'New Incidents' also has no sys_id; however, the default behavior for 
           // items without a sysId is to be non-droppable. This is why we explicitly denoted the 'Closed Incidents' to  
           // be marked as "droppable".
     
           // Return a dialog prompt 
           this.setStatusPrompt('Confirm', 'Are you sure you want to close: ' + 
                  '<div style="margin:10px 0 10px 14px;padding:4px;background-color:#EBEBEB;"><strong>' +
                   GlideStringUtil.escapeHTML(gr.short_description) + 
                   '</strong><br/><div class="font_smaller">' + now_GR. number + '</div></div>', 
                   'this._elementMoveYHandler_DoClose', // This function is for when the OK button is clicked. 
                   'this._elementMoveYHandler_DoNothing', // This function is for when the Cancel button is clicked. 
                   'this._elementMoveYHandler_DoNothing'); // This function is for when the Close button is clicked.
           } } ,
     
      _elementMoveYHandler_DoClose: function(spanId, itemId, newItemId) { 
        // Notice that this function takes the same function arguments as the original function for which it  
        // is a custom event handler for.
     
        // Update the database record from 'New' to 'Closed'. 
        var now_GR = new GlideRecord('incident');
        gr.addQuery('sys_id', spanId);
        gr.query();
        gr.next();
        gr.setValue('incident_state', '7');
        gr.update();
     
        // This will re-render the timeline showing the updated item in the closed group. 
        this.setDoReRenderTimeline(true);
     
        // Let's show a success message 
        this.setStatusSuccess('Success', '<strong>' + gr.short_description + '</strong> was successfully closed.'); } ,
     
      // Since the user clicked cancel or close we simply do nothing.
      _elementMoveYHandler_DoNothing: function(spanId, itemId, newItemId) { }
     
     });

    Captures d’écran/Résultats

    1. Accédez à :

      http://[VOTREINSTANCE] :8080/show_schedule_page.do ?sysparm_page_schedule_type=incident_timeline

      Notez que le texte en gras est la valeur du champ de type de calendrier de la page de calendrier.

    2. La page affiche une chronologie spécifiée par la page de calendrier et l’include de script créé. Un lien vers cette page peut être créé et placé en tant que module ou action d’interface utilisateur si nécessaire.
      Figure 2. Exemple de chronologie Aperçu de l’incident
    3. Tenter de déplacer un incident fermé n’importe où affiche le message d’erreur attendu.
      Figure 3. Exemple de chronologie Erreur lors du déplacement
    4. Déplacer l’incident : J’ai besoin de plus de mémoire affiche la boîte de confirmation suivante.
      Figure 4. Exemple de chronologie Confirmer la fermeture
    5. Cliquez sur le bouton Annuler pour fermer la superposition. Cliquer sur le bouton OK met à jour les incident_state de l’enregistrement, puis affiche la case de réussite suivante.
      Figure 5. Exemple de chronologie Fermer la réussite
    6. Après avoir cliqué sur OK, il est clair que l’incident est maintenant répertorié dans le groupe Incidents fermés .
      Figure 6. Exemple de chronologie Incident mis à jour
      Chronologie d’un exemple d’incident