Part 3: Creating the configuration user interface

In this tutorial, you’ll continue to build your Zendesk app by adding user interface components for configuration. You'll also learn how to store the configuration data in ZIS and use that data in workflows.

By the end of the tutorial, the app should allow you to configure a ticket notifications workflow based on the customized ticket priority as a filter and Slack channel as the destination.

Add Zendesk Garden UI components

Garden is a design system by Zendesk. For simplicity, you’ll use Garden's CSS components in this tutorial to style the UI. However, Garden's React components are recommended for building real-world applications. You can read more about our design guidelines in Designing an integration.

In the first tutorial in the series, the Garden CSS was already included in the assets/index.html file. It provides all the styling you need.

<link href="https://cdn.jsdelivr.net/combine/npm/@zendeskgarden/css-bedrock,npm/@zendeskgarden/css-grid,npm/@zendeskgarden/css-buttons,npm/@zendeskgarden/css-forms,npm/@zendeskgarden/css-utilities" rel="stylesheet">

To add Garden components

  1. In assets/index.html, paste the following code to add a dropdown option, text field, and Submit button to the app interface:

    ...        <button id="btnConnect" class="c-btn c-btn--primary">Zendesk Authorization</button>      </div>      <div class="row">        <div class="col-6">          <div class="c-txt u-mb-small">            <label class="c-txt__label" for="txt-priority">Ticket priority</label>            <select class="c-txt__input c-txt__input--select" id="select-priority">              <option value="low">Low</option>              <option value="normal">Normal</option>              <option value="high">High</option>              <option value="urgent">Urgent</option>            </select>          </div>        </div>        <div class="col-6">          <div class="c-txt u-mb-small">            <label class="c-txt__label" for="txt-channel">Slack channel</label>            <input class="c-txt__input" id="txt-channel" placeholder="e.g. #general or C1234567890" type="text">          </div>        </div>      </div>      <div class="row u-mt">        <div class="col-12">          <button id="submit" class="c-btn c-btn--primary" style="float: right">Save</button>        </div>      </div>      ...
  2. In your command line tool, navigate to the app directory that contains manifest.json, and run zcli apps:server to start a local HTTP server.

  3. In your Zendesk instance, append ?zcli_apps=true to the URL and reload the app. See Testing your app locally in a browser.

The app should look as follows:

Store configuration data

ZIS provides flexible but straightforward key-value storage for saving your application's configuration data. The workflow engine can use the configuration to drive different behavior. You’ll add some JavaScript code for saving and fetching configuration data entered by the UI.

To store configuration data

  1. In assets/config.js, paste the following code and save the file:

    // configScope is a custom-defined key for referencing the configuration datalet configScope = 'slackNotification'
    // scopeExists is a boolean flag to indicate if the config data exists// for a given scopelet scopeExists = false
    // fetchConfig defines the function to fetch config datafunction fetchConfig(integrationKey) {  // Fetch config request  let request = {    type: 'GET',    url:      '/api/services/zis/integrations/' +      integrationKey +      '/configs?filter[scope]=' +      configScope  }
      client.request(request).then(    function (response) {      console.log(        'Config fetched successfully: ',        response.configs[0].config      )      scopeExists = true      updateComponents(response.configs[0].config)    },    function (response) {      console.log('Config fetching failed: ', response)      if (response.status == 404) {        scopeExists = false      }    }  )}
    // submitConfig maps the data from DOM and submit it through ZIS Configs APIfunction submitConfig(integrationKey) {  // Prepare the config payload  let data = JSON.stringify({    scope: configScope,    config: {      priority: $('#select-priority').val(),      channel: $('#txt-channel').val()    }  })
      // The request is to create or update config data  let request
      if (scopeExists) {    // request for update config    request = {      type: 'PUT',      url:        '/api/services/zis/integrations/' +        integrationKey +        '/configs/' +        configScope,      contentType: 'application/json',      data: data    }  } else {    // request for create config    request = {      type: 'POST',      url: '/api/services/zis/integrations/' + integrationKey + '/configs',      contentType: 'application/json',      data: data    }  }
      client.request(request).then(    function (response) {      console.log('Config submitted successfully: ', response)      client.invoke('notify', 'Submitted successfully')    },    function (response) {      console.log('Config submission failed: ', response)    }  )}
    // updateComponents updates the UI components with the newly fetched config datafunction updateComponents(config) {  console.log('Updating components with config: ', config)  $('#select-priority').val(config.priority)  $('#txt-channel').val(config.channel)}
  2. In assets/index.html, insert the follow code to load the file:

    ...   <script type="text/javascript" src="connect.js"></script>
       <!-- configs management -->   <script type="text/javascript" src="config.js"></script></head>...
  3. In assets/bootstrap.js, add the following code to submit and load the existing configuration:

    ...}).then(function() {    // Bind button to start OAuth flow    $("#btnConnect").click(function() { startOAuth(integrationKey, subdomain) });
        // Bind button to submit config    $("#submit").click(function() { submitConfig(integrationKey) });
        // Fetch configuration data and render on UI    fetchConfig(integrationKey);});...
  4. Reload the app. You should be able to save the configured ticket priority and the Slack channel. If the change doesn't appear, try force-refreshing the browser to clear the cache.

Next: Part 4: Connecting to Slack and installing the integration