Exemples

Dans ce package, nous avons également fourni quelques exemples de personnalisation (disponibles à l’adresse guides_extension/src) . Vous trouverez ci-dessous une brève description de chacun d’eux.

  1. Menu contextuel : dans cet exemple, nous avons personnalisé le menu contextuel file_options pour supprimer les options Delete et Edit, et remplacer l’option Duplicate par une option Download. Téléchargez l’exemple de code pour ​ Menu contextuel ​.

    code language-typescript
    enum VIEW_STATE {
      APPEND = 'append',
      PREPEND = 'prepend',
      REPLACE = 'replace',
    }
    
    const loadDitaFile = (filePath, uuid) =>{
      return $.ajax({
        type: 'POST',
        url: '/bin/referencelistener',
        data: {
            operation: 'getdita',
            path: filePath,
            type: uuid ? 'UUID' : 'PATH',
            cache: false,
        },
      })
    }
    
    const fileOptions = {
      id: "file_options",
      contextMenuWidget: "repository_panel",
      view: {
        items: [
          {
            component: "div",
            target: {
              key: "displayName", value: "Delete",
              viewState: VIEW_STATE.REPLACE
            }
          },
          {
            component: "div",
            target: {
              key: "displayName", value: "Edit",
              viewState: VIEW_STATE.REPLACE
            }
          },
          {
            "displayName": "Download",
            "data": {
              "eventid": "downloadFile"
            },
            "icon": "downloadFromCloud",
            "class": "menu-separator",
            target: {
              key: "displayName", value: "Duplicate",
              viewState: VIEW_STATE.REPLACE
            }
          },
        ]
      },
    
      controller: {
        downloadFile() {
          const path = this.getValue('selectedItems')[0].path
          loadDitaFile(path, true).then((file) => {
            function download_file(name, contents) {
              const mime_type = "text/plain";
    
              const blob = new Blob([contents], { type: mime_type });
    
              const dlink = document.createElement('a');
              dlink.download = name;
              dlink.href = window.URL.createObjectURL(blob);
              dlink.onclick = function () {
                // revokeObjectURL needs a delay to work properly
                const that = this;
                setTimeout(function () {
                  window.URL.revokeObjectURL(that.href);
                }, 1500);
              };
    
              dlink.click();
              dlink.remove();
            }
            download_file(path, file.xml)
    
          });
        }
      }
    }
    
    export default fileOptions
    
  2. Panneau de gauche : dans cet exemple, nous avons personnalisé le left tab panel pour obtenir un autre tab intitulé « EXTENSION DE TEST », ainsi qu’un tab panel correspondant avec un libellé : Test Tab Panel.
    Téléchargez l’exemple de code pour panneau de gauche.

    code language-typescript
    const tabLeftPanel = {
        "id": "left_panel_container",
        "tabView": {
            "id": "left_panel_container",
            "tabs": [
                {
                    "component": "tab",
                    "id": "new_tab_extension",
                    "extraclass": "collection-panel-tab",
                    "showClass": "@visibleTabs.collection_panel",
                    "on-click": "tabClick",
                    "icon": "collection",
                    "title": "TEST EXTENSION",
                    "label": "TEST EXTENSION",
                    "prevTabID": "condition_panel"
                },
            ],
            "tabPanels":
                [
                    {
                        "component": "tabPanel",
                        "tabId": "new_tab_extension",
                        "showClass": "@visibleTabs.citation_panel",
                        "items": [
                            {
                                "id": "annotation_toolbox"
                            }
                        ],
                    },
                ]
        }
    }
    export default tabLeftPanel
    
  3. Panneau de droite : dans cet exemple, nous avons personnalisé le right tab panel pour obtenir un autre tab appelé « EXTENSION DE TEST », ainsi qu’un tab panel correspondant avec un libellé : New Tab Panel. Téléchargez l’exemple de code pour Panneau de droite.

    code language-typescript
    const rightPanel = {
        "id": "right_panel_container",
        "tabView": {
            "id": "right_panel_container_tab",
            "tabs": [
                {
                    "component": "tab",
                    "id": "new_tab_extension",
                    "on-click": "tabClick",
                    "icon": "collection",
                    "title": "TEST EXTENSION",
                },
            ],
            "tabPanels":
                [
                    {
                        "component": "tabPanel",
                        "tabId": "new_tab_extension",
                        "items": [
                            {
                                "component": "label",
                                "label": "New Tab Label",
                            }
                        ],
                    },
                ]
        }
    }
    export default rightPanel
    
  4. Panneau Référentiel : téléchargez l’exemple de code pour Panneau Référentiel.

    code language-typescript
    export enum VIEW_STATE2 {
      APPEND = 'append',
      PREPEND = 'prepend',
      REPLACE = 'replace',
    }
    
    export default {
      class: "flex bg-red-100 bg-green-200 bg-green-300 mr-4",
      id: 'repository_panel',
      view: {
        className: '',
        items: [
          {
            target: {
              key: "id",
              value: 'respository-'
              ,
            },
            component: 'widget',
            id: 'loading_shimmer',
            viewState: VIEW_STATE2.REPLACE,
            index: 2,
          },
          {
            component: 'button',
            label: 'Close',
            'on-click': 'cancel',
            variant: 'secondary',
            quiet: true,
            index: 20,
          },
          {
            label: "@testLabel",
            component: "label"
          }
        ],
      },
      controller: {
        init: function() {
          console.log('subject: ', this.subject)
          this.subscribe({
            key: 'rename',
            next: () => { console.log('rename using extension') }
          })
          console.log('Logging view config ', this.viewConfig)
          this.next(this.viewConfig.items[1].searchModeChangedEvent, { searchMode: true })
          this.subscribeAppEvent({
            key: 'app.active_document_changed',
            next: () => { console.log('active doc changed subs') }
          })
          this.subscribeAppModel('app.mode',
            () => { console.log('app mode subs') }
          )
          this.subscribeParentEvent({
            key: 'tabChange',
            next: () => { console.log('tab change subs') }
          })
          this.parentEventHandlerNext('tabChange', {
            data: 'map_panel'
          })
          this.appModelNext('app.mode', 'author')
          this.appEventHandlerNext('app.active_document_changed', 'active doc changed')
        },
        cancel: function (args) {
          this.setValue('testLabel', 'testlabel2')
        },
      },
      model: {
        deps: ['testLabel'],
      },
    }
    
  5. Barre d’outils : dans cet exemple, nous avons remplacé les boutons Insert Element, Insert Paragraph, Insert Numbered List et Insert Bulleted List par un seul bouton More Insert Options contenant tous ces éléments. Téléchargez l’exemple de code pour Toolbar.

    code language-typescript
    import { VIEW_STATE } from "./review_app_examples/review_comment"
    
    const topbarExtend = {
        id: "toolbar",
        view: {
            items: [
                {
                    component: "div",
                    target: {
                        key: "title", value: "Insert Element",
                        viewState: VIEW_STATE.REPLACE
                    }
                },
                {
                    component: "div",
                    target: {
                        key: "title", value: "Insert Paragraph",
                        viewState: VIEW_STATE.REPLACE
                    }
                },
                {
                    component: "div",
                    target: {
                        key: "title", value: "Insert Numbered List",
                        viewState: VIEW_STATE.REPLACE
                    }
                },
                {
                    component: "div",
                    target: {
                        key: "title", value: "Insert Bulleted List",
                        viewState: VIEW_STATE.REPLACE
                    }
                },
                {
                    "component": "button",
                    "extraclass": "insert-multimedia",
                    "icon": "more",
                    "variant": "action",
                    "quiet": true,
                    "holdAffordance": true,
                    "title": "More Insert Options",
                    "elementID": "toolbar_insert",
                    "on-click": {
                        "name": "APP_SHOW_OPTIONS_POPOVER",
                        "args": {
                            "target": "toolbar_insert",
                            "extraclass": "new_options_buttons",
                            "items": [
                                {
                                    "component": "button",
                                    "icon": "add",
                                    "variant": "action",
                                    "quiet": true,
                                    "title": "Insert Element",
                                    "on-click": "AUTHOR_SHOW_INSERT_ELEMENT_UI"
                                },
                                {
                                    "component": "button",
                                    "icon": "textParagraph",
                                    "variant": "action",
                                    "quiet": true,
                                    "title": "Insert Paragraph",
                                    "on-click": "INSERT_P"
                                },
                                {
                                    "component": "button",
                                    "icon": "textNumbered",
                                    "variant": "action",
                                    "quiet": true,
                                    "title": "Insert Numbered List",
                                    "on-click": "AUTHOR_INSERT_REMOVE_NUMBERED_LIST"
                                },
                                {
                                    "component": "button",
                                    "icon": "textBulleted",
                                    "variant": "action",
                                    "quiet": true,
                                    "title": "Insert Bulleted List",
                                    "on-click": "AUTHOR_INSERT_REMOVE_BULLETED_LIST"
                                },
                                {
                                    "component": "button",
                                    "icon": "table",
                                    "variant": "action",
                                    "quiet": true,
                                    "title": "Insert Table",
                                    "on-click": "AUTHOR_INSERT_ELEMENT",
                                }
                            ]
                        },
                    },
                    target: {
                        key: "title", value: "Insert Table",
                        viewState: VIEW_STATE.REPLACE
                    }
                },
            ]
        },
        controller: {
            init() {
                console.log(this.proxy.getValue("canUndo"))
                this.proxy.subscribeAppEvent({
                  key: "editor.preview_rendered",
                  next: async function (e) {
                    console.log(this.proxy.getValue("canUndo"))
                  }.bind(this)
                })
            },
            INSERT_P() {
                this.next("AUTHOR_INSERT_ELEMENT", "p")
            }
        }
    }
    
    export default topbarExtend
    
  6. Bouton Gérer dans le panneau Métadonnées : dans cet exemple, nous avons personnalisé le bouton Gérer (situé dans le panneau Métadonnées de la page Rapports) afin qu’il soit désactivé lorsque le ou les fichiers sélectionnés sont en mode lecture seule. Cela permet d’éviter les modifications accidentelles des métadonnées dans les fichiers qui ne sont pas destinés à être modifiés. Téléchargez l’exemple de code pour le bouton ​ Gérer dans le panneau Métadonnées.

    code language-typescript
    const mapConsoleActionBar = {
      id: "map_console_action_bar",
      view: {
        items: [
          {
            "key": "manageTags",
            "component": "button",
            "title": "Manage",
            "on-click": "reports.manage_report",
            "label": "Manage",
            "icon": "s2AppGear",
            "type": "secondary",
            "variant": "action",
            "quiet": true,
            "show": "@showManageTags",
            "disabled": "$$extensionMap.overrideShowManageTags",
            target: {
              key: "title", value: "Manage",
              viewState: 'replace'
            }
          },
          {
    
            "key": "selectAll",
            "component": "button",
            "title": "@selectAllTitle",
            "on-click": "SELECT_ALL",
            "label": "@selectAllTitle",
            "variant": "action",
            "extraclass": "select-all-button",
            "quiet": true,
            "show": "@showSelectAllButton",
            "hide": "$$extensionMap.overrideShowManageTags",
            target: {
              key: "key", value: "selectAll",
              viewState: 'replace'
            }
          },
        ]
      }
    }
    
    function getAutoCheckoutConfigFromAppModel() {
      const config = tcx.model.getValue(tcx.model.KEYS.EDITOR_CHECKOUT_CONFIG)
      return config === true || config === 'true'
    }
    
    const bulkMetadataEditorController = {
      id: "bulkmetadata_report_view",
      controller: {
        rowSelectionChanged() {
          const selectedItems = this.getValue('selectedItems');
          let areReadOnlyFilesSelected = false;
          let autoCheckoutConfig = getAutoCheckoutConfigFromAppModel();
    
          for (let idx = 0; idx < selectedItems.length; idx++) {
            const item = selectedItems[idx].obj;
            const isLocked = Boolean(item.isCheckedOut);
    
            if (autoCheckoutConfig && !isLocked) {
              areReadOnlyFilesSelected = true;
              break;
            }
          }
    
          this.setExtensionAppState('overrideShowManageTags', areReadOnlyFilesSelected);
        }
      }
    }
    
    export {
      mapConsoleActionBar,
      bulkMetadataEditorController
    }
    

Consulter les exemples d’applications

  1. Boîte à outils d’annotation : dans cet exemple, nous avons ajouté un autre bouton à la boîte à outils d’annotation qui ouvre la rubrique de révision actuelle dans AEM. Téléchargez l’exemple de code pour Annotation Toolbox.

    code language-typescript
    import { VIEW_STATE } from './review_comment'
    
    export default {
      id: 'annotation_toolbox',
      view: {
        items: [
          {
            component: 'button',
            icon: 'linkOut',
            title: 'openTopicInAEM',
            'on-click': 'openTopicInAEM',
            target: {
              key: 'value',
              value: 'addcomment',
              viewState: VIEW_STATE.APPEND
            },
          },
        ],
      },
      controller: {
        openTopicInAEM: function (args) {
          const topicIndex = tcx.model.getValue(tcx.model.KEYS.REVIEW_CURR_TOPIC)
          const { allTopics = {} } = tcx.model.getValue(tcx.model.KEYS.REVIEW_DATA) || {}
          tcx.appGet('util').openInAEM(allTopics[topicIndex])
        },
      },
    }
    
  2. Vérifier le commentaire : dans cet exemple, nous avons remplacé le nom d’utilisateur par les informations utilisateur (qui comprennent le nom complet et le titre du commentateur), ajouté un ID de commentaire unique, une icône mailTo et ajouté des champs de saisie pour mentionner la gravité et la raison du commentaire.
    Nous avons également ajouté un bouton accept with modification dans les commentaires du côté de l’éditeur XMLE qui ouvre une boîte de dialogue. Téléchargez l’exemple de code pour Commentaire de révision.

    code language-typescript
    export enum VIEW_STATE {
      APPEND = 'append',
      PREPEND = 'prepend',
      REPLACE = 'replace',
    }
    
    const reviewComment = {
      id: 'review_comment',
      view: {
        items: [
          {
            component: 'label',
            label: '@extraProps.commentUniqId',
            extraclass: 'commentUniqId',
            target: {
              key: 'extraclass',
              value: 'user-image',
              viewState: VIEW_STATE.PREPEND,
            },
          },
          {
            component: 'div',
            extraclass: 'user-info',
            items: [
              {
                component: 'label',
                "label": "@extraProps.userInfo",
                "extraclass": "reviewer-name",
              },
              {
                component: 'button',
                icon: 'email',
                extraclass: 'mailto-icon',
                "on-click": "openMailTo"
              }
            ],
            target: {
              key: 'extraclass',
              value: 'reviewer-name',
              viewState: VIEW_STATE.REPLACE,
            },
          },
          {
            component: 'div',
            extraclass: 'comment-details',
            items:
              [
                {
                  component: 'div',
                  extraclass: 'comment-type-text',
                  items:
                    [
                      {
                        component: 'label',
                        label: 'Comment Type: ',
                        "extraclass": "severity-label",
                      },
                      {
                        component: 'label',
                        label: '@extraProps.severity'
                      }
                    ],
                },
                {
                  component: 'div',
                  extraclass: 'comment-rationale',
                  items:
                    [
                      {
                        component: 'label',
                        label: 'Comment Rationale: ',
                        extraclass: 'comment-rationale-label'
                      },
                      {
                        component: 'label',
                        label: '@extraProps.commentRationale'
                      }
                    ],
                },
              ],
            target: {
              key: 'id',
              value: 'attachment_tiles',
              viewState: VIEW_STATE.PREPEND,
            },
          },
          {
            component: 'div',
            items: [
              {
                component: 'div',
                extraclass: 'edit-comment-type',
                items: [
                  {
                    component: 'label',
                    "label": "Comment Type",
                  },
                  {
                    "component": "comboBox",
                    "data": "@extraProps.labels",
                    "extraclass": "severity-combobox",
                    "multiple": false,
                    "placeholder": "",
                    'value': "@extraProps.severity",
                    "on-change": "changeSeverity",
                    "on-keyup": { "name": "changeSeverity", "eventArgs": { "keys": ["ENTER"] } },
                  },
                ],
              },
              {
                component: "div",
                extraclass: 'edit-comment-rationale',
                items: [
                  {
                    component: 'label',
                    label: 'Comment Rationale'
                  },
                  {
                    component: "textarea",
                    extraclass: "edit-textfield",
                    "id": "edit_comment_rationale",
                    "data": "@extraProps.commentRationale",
                    "on-keyup": {
                      "name": "submitEditComment",
                      "eventArgs": {
                        "keys": [
                          "ENTER"
                        ]
                      }
                    },
                    "stopKeyPropagation": true
                  },
                ],
              },
            ],
            target: {
              key: 'class',
              value: 'comment-block',
              viewState: VIEW_STATE.APPEND,
            },
          },
          {
            component: "button",
            "icon": "MultipleAdd",
            "variant": "action",
            "quiet": true,
            "extraclass": "hover-item",
            "title": "Accept with Modifications",
            "on-click": "acceptWithModification",
            target: {
              key: 'title',
              value: 'Reject comment',
              viewState: VIEW_STATE.APPEND,
            },
          }
        ],
      },
    
      controller: {
        init: function () {
          const reqComment = tcx.commentStore.getComment(this.getValue('commentId'))
          this.setValue('extraProps', reqComment.extraProps)
          this.setValue("labels", ['None', 'CRITICAL', 'MAJOR', 'SUBSTANTATIVE', 'ADMINISTRATIVE'])
        },
    
        sendAcceptWithModificationProps(args) {
          this.next('updateExtraProps', args)
        },
    
        changeSeverity: function (args) {
          this.setValue("severity", args.data)
          this.next('updateExtraProps',
            { 'severity': this.getValue("severity") }
          )
        },
    
        changeCommentRationale: function () {
          this.next('updateExtraProps',
            { 'commentRationale': this.getValue("commentRationale") }
          )
        },
    
        submitEditComment({ domEvent }: { domEvent?: KeyboardEvent } = {}) {
          if (domEvent?.key === 'Enter') {
            this.setValue('commentRationale', _.trim(this.getValue('commentRationale')))
          }
          if (this.getValue("originalCommentRationale") !== this.getValue("commentRationale")) {
            this.setValue("originalCommentRationale", this.getValue("commentRationale"))
            this.next('changeCommentRationale')
          }
        },
    
        openMailTo() {
          const mailToLink = `mailto:${this.getValue("userEmail")}`
          tcx.util.openLink(mailToLink)
        },
    
        acceptWithModification() {
          tcx.eventHandler.next(tcx.eventHandler.KEYS.APP_SHOW_DIALOG,
            {
              id: 'accept_with_modification_dialog',
              args: {
                onSuccess: (extraProps) => this.next('sendAcceptWithModificationProps', extraProps),
              }
            })
        }
      }
    }
    
    export default reviewComment
    
  3. Réponse au commentaire : dans cet exemple, nous avons remplacé le nom d’utilisateur par les informations utilisateur (comprenant le nom complet et le titre du commentateur), puis ajouté une icône mailTo dans l’en-tête du commentaire. Téléchargez l’exemple de code pour Réponse au commentaire.

    code language-typescript
    import { VIEW_STATE } from "./review_comment"
    
    const commentReply = {
      id: 'comment_reply',
      view: {
        items: [
          {
            component: 'div',
            extraclass: 'user-info',
            items: [
              {
                component: 'label',
                label: "@extraProps.userInfo",
                "extraclass": "user-name",
              },
              {
                component: 'button',
                icon: 'email',
                extraclass: 'mailto-icon',
                "on-click": "openMailTo"
              }
            ],
    
            target: {
              key: 'extraclass',
              value: 'user-name',
              viewState: VIEW_STATE.REPLACE,
            },
          },
        ],
      },
      model: {
        deps: [],
      },
      controller: {
        init: function () {
          const reqComment = tcx.commentStore.getComment(this.getValue('commentId'))
          const reqReply = reqComment.findReply(this.getValue('replyId'))
          this.setValue('extraProps', reqReply.extraProps)
        },
    
        openMailTo(){
          const mailToLink = `mailto:${this.getValue("userEmail")}`
          tcx.util.openLink(mailToLink)
        }
      }
    }
    
    export default commentReply
    
  4. Panneau de révision intégré : dans ce fichier, nous calculons et attribuons l’ID de commentaire unique, mentionné dans les exemples Review Comment et Comment Reply.

    • La méthode setCommentId définit l’ID de commentaire unique pour chaque commentaire en fonction du nombre de commentaires.

    • Le setUserInfo définit la valeur de userInfo en utilisant le nom complet et le titre de chaque commentaire.

    • Le onNewCommentEvent garantit que la méthode setUserInfo est appelée pour chaque nouveau commentaire ou réponse.

    • La fonction updatedProcessComments s’exécute pour chaque nouvel événement de commentaire et s’assure que setCommentId est appelé si nous obtenons un nouvel événement de commentaire.

    Téléchargez l’exemple de code pour Panneau de révision intégré.

    code language-typescript
    export const updatedProcessComments = function (data, topicIndex) {
      const newCommentEvents = ["highlight", "strikethrough", "addcomment", "insertext"]
      _.each(data, (event: any) => {
        const identify = _.findIndex(newCommentEvents, eventType => eventType === event.eventType)
        if (identify !== -1) {
          this.next('setCommentId', { event, topicIndex })
        }
      })
    }
    
    const inline_extend = {
      id: 'inline_review_panel',
      model: {
        deps: ['commentCount'],
      },
      controller: {
        init: function () {
          this.setValue("commentCount", {})
          tcx.model.subscribeVal(tcx.model.KEYS.REVIEW_DATA, (reviewData) => {
            for (let topicId of reviewData.topicsinReview) {
              topicId = topicId.toString()
              tcx.commentStore.onProcessEvent(topicId, (events) => updatedProcessComments.call(this, events, topicId))
            }
          })
        },
    
        onNewCommentEvent(args) {
          const events = _.get(args, "events")
          const currTopicIndex = tcx.model.getValue(tcx.model.KEYS.REVIEW_CURR_TOPIC) || this.getValue('currTopicIndex') || "0"
          const event = _.get(_.get(events, currTopicIndex), '0')
          const newComment = _.get(args, 'newComment')
          const newReply = _.get(args, 'newReply')
          if ((newComment || newReply) && event) {
            this.next('setUserInfo', event)
          }
        },
    
        setUserInfo(event) {
          tcx.api?.getUserInfo(event.user).subscribe(userData => {
            const extraProps = {
              "userFirstName": userData?.givenName || '',
              "userLastName": userData?.familyName || '',
              "userTitle": userData?.title || '',
              "userJobTitle": userData?.jobTitle || '',
              'userEmail': userData?.email || '',
            }
            const name = `${extraProps.userFirstName} ${extraProps.userLastName}, ${extraProps.userJobTitle}`
            if (_.trim(name) === ',') {
              extraProps.userInfo = userData.displayName
            }
            else {
              extraProps.userInfo = name
            }
            const data = { ...event, extraProps }
            this.next(
              'sendExtraProps',
              data
            )
          })
        },
    
        setCommentId({ event, topicIndex }) {
          const processingComments = this.getValue('processingComments')
          const modelComment = _.find(processingComments, { commentId: event.commentId })
          const reqComment = tcx.commentStore.getComment(event.commentId)
          const commentCount = this.getValue('commentCount')
          if (_.has(this.getValue('commentCount'), topicIndex)) {
            commentCount[topicIndex] += 1
            this.setValue("commentCount", commentCount)
          }
          else {
            commentCount[topicIndex] = 1
          }
          if (reqComment) {
            this.setValue("commentCount", commentCount)
            const commentUniqId = `${Number(topicIndex) + 1}.${commentCount[topicIndex]}`
            reqComment.extraProps.set("commentUniqId", commentUniqId)
            modelComment?.extraProps?.set("commentUniqId", commentUniqId)
          }
        },
      },
    }
    
    export default inline_extend
    
  5. Panneau de révision de rubrique : ce fichier étend Panneau de révision intégré (comme illustré précédemment) afin que les personnalisations ajoutées fonctionnent également du côté de l’application de révision. Téléchargez l’exemple de code pour Panneau des révisions de rubrique.

    code language-typescript
    import inline_extend from './inline_review_panel';
    import { updatedProcessComments } from './inline_review_panel';
    
    const topic_reviews_extend = {
      id: 'topic_reviews',
      model: {
        deps: [],
      },
      controller: {
        ...inline_extend.controller,
        init: function () {
          this.setValue("commentCount", {})
          tcx.model.subscribeVal(tcx.model.KEYS.REVIEW_DATA, (reviewData) => {
            for (let topicId of reviewData.topicsinReview) {
              topicId = topicId.toString()
              tcx.commentStore.onProcessEvent(topicId, (events) => updatedProcessComments.call(this, events, topicId))
            }
          })
        },
    
      },
    }
    
    export default topic_reviews_extend
    
  6. Boîte de dialogue Accepter avec modification : il s’agit d’un exemple d’ajout de nouveaux widgets à l’application. Nous avons créé ici une boîte de dialogue qui comporte deux champs de texte d’entrée : Revised Text et Adjudicator Comment Rationale. Téléchargez l’exemple de code pour Boîte de dialogue Accepter avec modification.

    code language-typescript
    const acceptWithModification = {
      id: 'accept_with_modification_dialog',
      view: {
        component: "dialog",
        "header": {
          "items": [
            {
              component: 'label',
              extraclass: "header",
              label: 'Accept With Modifications',
            }
          ]
        },
        content: {
          items: [
            {
              component: 'div',
              "extraclass": "revised-text",
              items: [
                {
                  component: 'label',
                  label: 'Revised Text (Required)',
                  extraclass: 'revised-text-label'
                },
                {
                  component: "textarea",
                  "extraclass": "revised-text-textarea",
                  "data": "@extraProps.revisedText",
                  "stopKeyPropagation": true,
                }
              ]
            },
            {
              component: 'div',
              "extraclass": "adjudication-rationale",
              items: [
                {
                  component: 'label',
                  label: 'Adjudicator Comment Rationale (Required)',
                  extraclass: 'adjudication-rationale-label'
                },
                {
                  component: "textarea",
                  extraclass: "adjudication-rationale-textarea",
                  "data": "@extraProps.adjudicationRationale",
                  "on-keyup": {
                    "name": "",
                    "eventArgs": {
                      "keys": [
                        "ENTER"
                      ]
                    }
                  },
                  "stopKeyPropagation": true
                }
              ]
            },
          ],
        },
        footer: {
          "items": [
            {
              "component": "button",
              "label": "Cancel",
              "on-click": "handleClose",
              "variant": "secondary"
            },
            {
              "component": "button",
              "label": "Submit",
              "variant": "cta",
              "on-click": "submitAcceptWithModification"
            }
          ]
        }
      },
      model: {
        deps: [],
      },
      controller: {
        init: function () {
        },
    
        submitAcceptWithModification: function () {
          const extraProps = {
            'revisedText': this.getValue("revisedText"),
            'adjudicationRationale': this.getValue("adjudicationRationale"),
          }
          this.args.onSuccess(extraProps)
          this.next('handleClose')
        },
    
        handleClose() {
          tcx.eventHandler.next(tcx.eventHandler.KEYS.APP_HIDE_DIALOG, { id: 'accept_with_modification_dialog' })
        }
      }
    }
    
    export default acceptWithModification
    
  7. Enregistrer la révision : il s’agit d’un exemple de mise à jour d’une boîte de dialogue existante. Nous ajoutons un bouton pour la publication dans ce . Nous autorisons la modification du contenu de la boîte de dialogue. Reportez-vous à son fichier json ici : save_revision. Téléchargez l’exemple de code pour ​ Enregistrer la révision ​.

    code language-typescript
    enum VIEW_STATE {
        APPEND = 'append',
        PREPEND = 'prepend',
        REPLACE = 'replace',
    }
    
    const saveRevision = {
        id: 'save_revision',
        view: {
            items: [
                {
                    component: "button",
                    label: 'publish',
                    target: {
                        key: 'label',
                        value: 'Save',
                        viewState: VIEW_STATE.APPEND
                    }
                }
            ]
        }
    }
    
    export default saveRevision
    

Boîte De Dialogue Accepter Avec Modification

Voici le panneau de révision avant et après la personnalisation :

Comité d'examen;
Boîte De Dialogue Accepter Avec Modification

recommendation-more-help
experience-manager-guides-help-product-guide