Git Product home page Git Product logo

app_scaffold's Introduction

Use of this software is subject to important terms and conditions as set forth in the License file

App Scaffold

Description

This repo contains a scaffold to help developers build apps for Zendesk products.

Getting Started

Dependencies

Setup

  1. Clone or fork this repo
  2. Change (cd) into the app_scaffold directory
  3. Run yarn install

You can use either yarn or npm as package manager and run the scripts with the corresponding commands.

To run your app locally in Zendesk, you need the latest Zendesk Apps Tools (ZAT).

Running locally

To serve the app to your Zendesk instance with ?zat=true, run

yarn run watch
zat server -p dist

But why?

The App Scaffold includes many features to help you maintain and scale your app. Some of the features provided by the App Scaffold are listed below. However, you don't need prior experience in any of these to be able to use the scaffold successfully.

ECMAScript 6, also known as ECMAScript 2015, is the latest version of the ECMAScript standard. The App Scaffold includes the Babel compiler to transpile your code to ES5. This allows you to use ES6 features, such as classes, arrow functions and template strings even in browsers that haven't fully implemented these features.

Collection of React components for Zendesk products. Youโ€™ll find components built to respond to a range of user input devices, tuned to handle right-to-left layouts, and finessed with just the right touch of subtle animation.

Webpack is a module bundler, we use it to bundle up Javascript modules for use as web applications, also to perform tasks like transforming and transpiling, etc.

PostCSS transforms stylesheets with JS plugins. These plugins can lint your CSS, support variables and mixins, transpile future CSS syntax, inline images, and more.

StandardJS is a Javascript style guide, it helps catching style issues or code errors, and automatically formats code for you.

  • Jest Javascript testing framework

Jest is bundled with JSDom and built on top of Jasmine. It's more than just a ReactJS testing framework. In the Zendesk Apps team, we use it for unit and integration testing of the Official Apps. It also includes a good test coverage toolset out of the box.

Folder structure

The folder and file structure of the App Scaffold is as follows:

Name Description
.github/ The folder to store PULL_REQUEST_TEMPLATE.md, ISSUE_TEMPLATE.md and CONTRIBUTING.md, etc
dist/ The folder in which webpack packages the built version of your app
spec/ The folder in which all of your test files live
src/ The folder in which all of your source JavaScript, CSS, templates and translation files live
webpack/ translations-loader and translations-plugin to support i18n in the application
.babelrc Configuration file for Babel.js
.browserslistrc Configuration file for browserslist
jest.config.js Configuration file for Jest
package.json Configuration file for Project metadata, dependencies and build scripts
postcss.config.js Configuration file for PostCSS
webpack.config.js Configuration file that webpack uses to build your app

dist

The dist directory is created when you run the app building scripts. You will need to package this folder when submitting your app to the Zendesk Apps Marketplace, It is also the folder you will have to serve when using ZAT. It includes your app's manifest.json file, an assets folder with all your compiled JavaScript and CSS as well as HTML and images.

spec

The spec directory is where all your tests and test helpers live. Tests are not required to submit/upload your app to Zendesk and your test files are not included in your app's package, however it is good practice to write tests to document functionality and prevent bugs.

src

The src directory is where your raw source code lives. The App Scaffold includes different directories for JavaScript, stylesheets, templates, images and translations. Most of your additions will be in here (and spec, of course!).

webpack

This directory contains custom tooling to process translations at build time:

  • translations-loader.js is used by Webpack to convert .json translation files to JavaScript objects, for the app itself.
  • translations-plugin.js is used to extract compulsory translation strings from the en.json file that are used to display metadata about your app on the Zendesk Apps Marketplace.

.babelrc

.babelrc is the configuration file for babel compiler.

.browserslistrc

.browserslistrc is a configuration file to specify browsers supported by your application, some develop/build tools read info from this file if it exists in your project root. At present, our scaffolding doesn't reply on this file, default browserslist query is used by Babel and PostCSS

jest.config.js

jest.config.js is the configuration file for Jest

package.json

package.json is the configuration file for Yarn, which is a package manager for JavaScript. This file includes information about your project and its dependencies. For more information on how to configure this file, see Yarn package.json.

postcss.config.js

postcss.config.js is the configuration file for PostCSS

webpack.config.js

webpack.config.js is a configuration file for webpack. Webpack is a JavaScript module bundler. For more information about webpack and how to configure it, see What is webpack.

Helpers

The App Scaffold provides some helper functions in /src/javascripts/lib/helpers.js to help building apps.

I18n

The I18n (internationalization) module in /src/javascripts/lib/i18n.js provides a t method to look up translations based on a key. For more information, see Using the I18n module.

Parameters and Settings

If you need to test your app with a parameters section in dist/manifest.json, foreman might crash with a message like:

Would have prompted for a value interactively, but zat is not listening to keyboard input.

To resolve this problem, set default values for parameters or create a settings.yml file in the root directory of your app scaffold-based project, and populate it with your parameter names and test values. For example, using a parameters section like:

{
  "parameters": [
    {
      "name": "myParameter"
    }
  ]
}

create a settings.yml containing:

myParameter: 'some value!'

Testing

The App Scaffold is currently setup for testing with Jest. To run specs, run

yarn test

Specs live under the spec directory.

Deploying

To check that your app will pass the server-side validation check, run

zat validate --path=dist

If validation is successful, you can upload the app into your Zendesk account by running

zat create --path=dist

To update your app after it has been created in your account, run

zat update --path=dist

Or, to create a zip archive for manual upload, run

zat package --path=dist

taking note of the created filename.

For more information on the Zendesk Apps Tools please see the documentation.

External Dependencies

External dependencies are defined in webpack.config.js. This ensures these dependencies are included in your app's index.html.

Contribute

  • Put up a PR into the master branch.
  • CC and get a +1 from @zendesk/vegemite.

Bugs

Submit Issues via GitHub or email [email protected].

Useful Links

Links to maintaining team, confluence pages, Datadog dashboard, Kibana logs, etc

Copyright and license

Copyright 2018 Zendesk

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.

You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

app_scaffold's People

Contributors

adammw avatar baopham avatar cl8au avatar dadah89 avatar danielbreves avatar dependabot[bot] avatar eddiestacks avatar fbvilela avatar hoangtrvu avatar ocke avatar pmgrove avatar sandlerr avatar sarmadsangi avatar sostopher avatar svizzari avatar token-cjg avatar yu-tian113 avatar z3nmlanius avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

app_scaffold's Issues

Translations are not transferred to the "dist" folder on Windows, so app can't start

Hello! I trying to use app_scaffold on Windows 10 x64 with ruby 2.3.3, node 6.9.2 and npm 3.10.9. When I run "nf start", server starts successfully, but no translation files appearing in dist/translations folder. So I got an error in browser's console when I trying to show app in zendesk's interface with "?zat=true". If i put translation file manually, app run successfully.

Document example of how to handle UI events

It would be nice to have an example in the bare scaffold of not only how to send data to the view, but also how the authors imagine binding UI events in the view and acting on them back in the controller. A simple "You clicked me" would do, I think, and newcomers could set off from there.

translations-loader.js is only copying the "app" key

Using the following file as an example:

{
  "app": {
    "description": "add your app description here",
    "name": "add your app name here"
  },

  "hello": "Hello {{name}}!",

  "save": {
    "button": "Bookmark ticket #{{id}}",
    "success": "Bookmarked ticket #{{id}}",
    "error": "Sorry, something went wrong."
  },

  "learn_more": {
    "message": "To learn more, {{link}}",
    "link_text": "see the Zendesk forums"
  }
}

will produce this in the dist folder:

{
  "_warning": "AUTOMATICALLY GENERATED FROM src/translations/en.json - DO NOT MODIFY THIS FILE DIRECTLY",
  "app": {
    "name": "add your app name here",
    "description": "add your app description here"
  }
}

If I remove the "app" key, I get this when "webpack --watch" runs:

WARNING in ./src/translations/en.json
Module build failed: TypeError: Cannot use 'in' operator to search for 'name' in undefined
ย  ย  at /Users/Me/Zendesk Apps/app_scaffold-master/lib/loaders/translations-loader.js:38:28
ย  ย  at Array.forEach (native)
ย  ย  at extractMarketplaceTranslation (/Users/Me/Zendesk Apps/app_scaffold-master/lib/loaders/translations-loader.js:37:17)
ย  ย  at Object.TranslationsLoader (/Users/Me/Zendesk Apps/app_scaffold-master/lib/loaders/translations-loader.js:58:33)
@ ./src/translations ^./.*.json$

Am I doing something wrong?

ZAF v1 shims path

In the documentation snippet

import BaseApp from './base_app'; // ZAF v1 shims

var App = {
  events: {
    'app.created': function() {
      this.switchTo('main');
    }
  }
};

export default BaseApp.extend(App);

base_app.js is in ./lib/javascripts/base_app.js but webpack expects it in ./src/javascripts.

Error:

ERROR in ./src/javascripts/legacy_app.js
Module not found: Error: Cannot resolve 'file' or 'directory' ./base_app in /Users/mrosendin/Code/app_scaffold/src/javascripts
 @ ./src/javascripts/legacy_app.js 7:16-37

Error creating modal, Iframe location?

Trying to load a test modal and I'm getting the following error.

[App "Xtool V2"] Error: Tried to show an iframe with a location that is neither absolute nor an asset: TestModal.html#parent_guid=488714c8-f663-4142-b07b-c3186c92f812
2018-02-05 18_17_49

for the modal I'm using example code from: https://github.com/zendesk/demo_apps/blob/master/v2/support/modal_sample_app/assets/iframe.html

The legacy app is only:

import BaseApp from "base_app";
import ZAFClient from 'zendesk_app_framework_sdk';

const client = ZAFClient.init();
// get current instance context so we can pass to modals as needed.
var appContext;
client.context().then(function(data) {
    appContext = data;
    console.log("CONTEXT:");
    console.log(appContext);
});
var App = {
    defaultState: "loading",
    requests: {
        getMe: {
            url: "/api/v2/users/me.json"
        },        
    },
    events: {
        "app.created": "CreateModal",
        "app.willDestroy": "logClosedApp",        
    },
    CreateModal() {
        console.log("Creating Modal!");
        client.invoke('instances.create', {
            location: 'modal',
            url: 'TestModal.html#parent_guid=' + appContext.instanceGuid
        }).then(function(modalContext) {
            console.log("The modal is on the screen now!");
            var modalClient = client.instance(modalContext['instances.create'][0].instanceGuid);
            modalClient.on('modal.close', function() {
                 console.log("The modal has been closed!");
            });
        });
    },
    logClosedApp() {
        this.xtlLog("Xtool: About to close the app.");
    },
};
export default BaseApp.extend(App);

resize function in breaking

For top bar app, when we do switchTo any template , internally it called resize() from base_app.js, but percentage values are not supported when resizing top nav apps, so its breaking.

/code

let view = new View({
afterRender: () => {
// Automatically resize the iframe based on document height, if it's not in the "nav_bar" location
if (this._context.location !== "nav_bar") {
let newHeight = Math.min($("html").height(), MAX_HEIGHT);
this.zafClient.invoke("resize", { height: newHeight, width: "100%" });
}
}
});

ERR_CONNECTION_REFUSED (local)

I'm running npm run watch. It successfully builds the dist/ folder, but when trying to load the app in Zendesk using ?zat=true, it returns this error in the console:
http://prntscr.com/ozuaxt

Error log:

VM3051:1 GET http://localhost:4567/app.js?locale=en-US&subdomain=imgix1 net::ERR_CONNECTION_REFUSED
(anonymous) @ VM3051:1
(anonymous) @ vendor-e12530a4bec8d74148e99dcc853395ad.js:34
reload @ reloader.js?8db2:24
(anonymous) @ app_runtime.js?1ac3:263
Promise.then (async)
reloadAllApps @ app_runtime.js?1ac3:262
(anonymous) @ app_framework-36df7c805a36f06989dcc3c058418073.js:2
onAppRuntimeReady @ app_framework-36df7c805a36f06989dcc3c058418073.js:2
reloadApps @ app_framework-36df7c805a36f06989dcc3c058418073.js:2
w @ vendor-e12530a4bec8d74148e99dcc853395ad.js:9
h @ vendor-e12530a4bec8d74148e99dcc853395ad.js:8
trigger @ vendor-e12530a4bec8d74148e99dcc853395ad.js:12
reloadAllApps @ application-5d2b08145d954378126feb1abdec56b9.js:3
reloadApps @ app_framework-36df7c805a36f06989dcc3c058418073.js:6
send @ vendor-e12530a4bec8d74148e99dcc853395ad.js:12
(anonymous) @ vendor-e12530a4bec8d74148e99dcc853395ad.js:9
run @ vendor-e12530a4bec8d74148e99dcc853395ad.js:5
u @ vendor-e12530a4bec8d74148e99dcc853395ad.js:9
handler @ vendor-e12530a4bec8d74148e99dcc853395ad.js:9
(anonymous) @ vendor-e12530a4bec8d74148e99dcc853395ad.js:14
dispatch @ vendor-e12530a4bec8d74148e99dcc853395ad.js:2
v.handle @ vendor-e12530a4bec8d74148e99dcc853395ad.js:2
23199?zat=true:1 

Not sure what I'm doing wrong there.

Sinatra doesnโ€™t know this ditty.

Installed everything as per the README locally on my Mac. nf start. No errors.

When pointing my browser to http://localhost:4567 I get

Sinatra doesnโ€™t know this ditty.

Try this:
# in Library/Ruby/Gems/2.0.0/gems/zendesk_apps_tools-1.34.1/lib/zendesk_apps_tools/server.rb
class ZendeskAppsTools::Server
  get '/' do
    "Hello World"
  end
end

Console:

6:10:41 PM server.1 |  localhost - - [18/Aug/2016:18:10:41 CEST] "GET / HTTP/1.1" 404 636
6:10:41 PM server.1 |  - -> /

What am I doing wrong?

from-scratch branch does not include moment in the external js assets

The current webpack.config.js is as follows:

var externalAssets = {
  css: [
    'https://assets.zendesk.com/apps/sdk-assets/css/0/zendesk_garden.css'
  ],
  js: [
    'https://cdn.jsdelivr.net/g/[email protected],[email protected],[email protected]',
    'https://assets.zendesk.com/apps/sdk/2.0/zaf_sdk.js'
  ]
}

It should be:

var externalAssets = {
  css: [
    'https://assets.zendesk.com/apps/sdk-assets/css/0/zendesk_garden.css'
  ],
  js: [
    'https://cdn.jsdelivr.net/g/[email protected],[email protected],[email protected],[email protected]',
    'https://assets.zendesk.com/apps/sdk/2.0/zaf_sdk.js'
  ]
}

App V1 modals created from side_bar: how to migrate?

I am migrating a V1 app to V2 and I have some modals that are created from side_bar, which is where my app is hosted. This is the snippet typically used in V1

...
var $modal = this.$('.newWorkItemModal').modal();
$modal.find('.modal-body').html(this.renderTemplate('loading'));
...

This code runs in V1 perfectly well, since the modal and the app itself are using the same DOM and context of the main support app, right?

Now, If I try to run this code in V2, the modal content is loaded inside the side_bar which is now hosted in an iframe.

The V2 docs mention that the modal feature is implemented using the instances api. In this case a new iframe will be created to host the modal content, which isn't the behavior that I want in my case, otherwise the migration becomes complex due the communication between modals and side_bar.

Any thoughts?

Thanks in advance

ReferenceError: ZAFClient is not defined at eval (ticket_sidebar.js:10)

Default scaffold - running commands in root folder npm run watch and npm start

Is causing either can't have multiple babel-polyfill, if I turn off babel-polyfill in webpack, I get ReferenceError: ZAFClient is not defined at eval (ticket_sidebar.js:10)

I am using zat=true in browser window (chrome). I have disable cache enabled in dev tools.

What would be causing this issue? its driving me insane and no help from google. I cant get a basic app to run in sidebar, the one project it did load in the side bar but the iframe does not exist. Is the zat broken?

Uncaught TypeError: Cannot assign to read only property 'exports' of object '#<Object>'

When running the default app_scaffold app I get the following error in the Chrome's developer console and the app does not load.

Uncaught TypeError: Cannot assign to read only property 'exports' of object '#<Object>'
    at Object.eval (i18n.js:58)
    at eval (i18n.js:59)
    at Object.<anonymous> (main.js:1)
    at n (main.js:1)
    at eval (index.js:4)
    at Object.<anonymous> (main.js:1)
    at n (main.js:1)
    at eval (app.scss:2)
    at Object.<anonymous> (main.js:1)
    at n (main.js:1)
(anonymous) @ i18n.js:58
(anonymous) @ i18n.js:59
(anonymous) @ main.js:1
n @ main.js:1
(anonymous) @ index.js:4
(anonymous) @ main.js:1
n @ main.js:1
(anonymous) @ app.scss:2
(anonymous) @ main.js:1
n @ main.js:1
(anonymous) @ main.js:1
(anonymous) @ main.js:1

It seems to be due to mixing import and modules.exports with webpack
webpack/webpack#4039

Webpack not generating dist/assets files

Steps I took

  • Installed global dependencies
  • Checkout branch from-scratch
  • Installed local dependencies npm install
  • Run nf start

Results
The server runs but the app did not generate files in dist/assets folder. So the iFrame in Zendesk Support shows the message "Sinatra did not know this ditty".

Attempting to run only webpack --watch spits out the following error:

Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
 - configuration has an unknown property 'externalAssets'. These properties are valid:
   object { mode?, amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, externals?, loader?, module?, name?, node?, output?, optimization?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, serve?, stats?, target?, watch?, watchOptions? }
   For typos: please correct them.
   For loader options: webpack >= v2.0.0 no longer allows custom properties in configuration.
     Loaders should be updated to allow passing options via loader options in module.rules.
     Until loaders are updated one can use the LoaderOptionsPlugin to pass these options to the loader:
     plugins: [
       new webpack.LoaderOptionsPlugin({
         // test: /\.xxx$/, // may apply this only for some modules
         options: {
           externalAssets: โ€ฆ
         }
       })
     ]
 - configuration.module has an unknown property 'loaders'. These properties are valid:
   object { exprContextCritical?, exprContextRecursive?, exprContextRegExp?, exprContextRequest?, noParse?, rules?, defaultRules?, unknownContextCritical?, unknownContextRecursive?, unknownContextRegExp?, unknownContextRequest?, unsafeCache?, wrappedContextCritical?, wrappedContextRecursive?, wrappedContextRegExp?, strictExportPresence?, strictThisContextOnImports? }
   -> Options affecting the normal modules (`NormalModuleFactory`).
 - configuration.output.path: The provided value "./dist/assets" is not an absolute path!
   -> The output directory as **absolute path** (required).
 - configuration.resolve.extensions[0] should not be empty.
   -> A non-empty string
 - configuration.resolveLoader has an unknown property 'modulesDirectories'. These properties are valid:
   object { alias?, aliasFields?, cachePredicate?, cacheWithContext?, descriptionFiles?, enforceExtension?, enforceModuleExtension?, extensions?, fileSystem?, mainFields?, mainFiles?, moduleExtensions?, modules?, plugins?, resolver?, symlinks?, concord?, unsafeCache?, useSyncFileSystemCalls? }
   -> Options for the resolver when resolving loaders

I am running
node v8.9.4
npm 5.6.0
ruby 2.4.4

App Framework V2 Services: services.notify()

I am migrating an app to V2 and it seems that there is no services module that I can import to have the services object of V1, for example to use the notify method.

Am I missing something? Is there a new way in V2 to show notifications to the user?

Upgrading to webpack 5 + babel 7, watch mode not working

Hi,

I'm yesterday I tried to upgrade app_scaffold to webpack 5 + babel 7 but found out watch mode doesn't work correctly (using ?zat=true) as whenever I reload the app I got error so I need to terminate watch and reissue the command.

Error

Sinatra doesnโ€™t know this ditty.

class ZendeskAppsTools::Server
  get '/iframe.html' do
    "Hello World"
  end
end

Terminal

::1 - - [03/Dec/2020:16:55:22 +0700] "GET /app.js?locale=en&subdomain=fabelio HTTP/1.1" 200 1075 0.0083
::1 - - [03/Dec/2020:16:55:22 +0700] "GET /iframe.html?origin=https%3A%2F%2Ffabelio.zendesk.com&app_guid=b0b3c092-ed92-4f4c-b19c-895103d3928e HTTP/1.1" 404 705 0.0006

Here my package.json

"devDependencies": {
    "@babel/core": "^7.12.9",
    "@babel/plugin-proposal-object-rest-spread": "^7.12.1",
    "@babel/polyfill": "^7.12.1",
    "@babel/preset-env": "^7.12.7",
    "@babel/runtime-corejs3": "^7.12.5",
    "@commitlint/cli": "^11.0.0",
    "@commitlint/config-conventional": "^11.0.0",
    "@zendeskgarden/css-arrows": "^3.1.4",
    "@zendeskgarden/css-avatars": "^6.0.10",
    "@zendeskgarden/css-bedrock": "^8.0.1",
    "@zendeskgarden/css-buttons": "^8.0.0",
    "@zendeskgarden/css-callouts": "^3.3.17",
    "@zendeskgarden/css-forms": "^7.0.20",
    "@zendeskgarden/css-grid": "^0.1.38",
    "@zendeskgarden/css-menus": "^9.0.20",
    "@zendeskgarden/css-modals": "^6.4.21",
    "@zendeskgarden/css-pagination": "^4.0.19",
    "@zendeskgarden/css-tables": "^4.0.19",
    "@zendeskgarden/css-tabs": "^6.0.19",
    "@zendeskgarden/css-tags": "^5.1.15",
    "@zendeskgarden/css-tooltips": "^4.1.27",
    "@zendeskgarden/css-utilities": "^4.5.5",
    "babel-core": "^7.0.0-bridge.0",
    "babel-jest": "^26.6.3",
    "babel-loader": "^8.2.2",
    "clean-webpack-plugin": "^3.0.0",
    "copy-webpack-plugin": "6.3.2",
    "core-js": "^3.8.0",
    "css-loader": "^5.0.1",
    "html-webpack-plugin": "^4.5.0",
    "jest": "^26.6.3",
    "mini-css-extract-plugin": "^1.3.1",
    "postcss": "^8.1.10",
    "postcss-import": "^13.0.0",
    "postcss-loader": "^4.1.0",
    "postcss-preset-env": "^6.7.0",
    "precss": "^4.0.0",
    "standard": "^16.0.3",
    "webpack": "^5.8.0",
    "webpack-cli": "^4.2.0"
  },

and webpack.config.js

const path = require('path')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const CopyPlugin = require('copy-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const TranslationsPlugin = require('./webpack/translations-plugin')
const devDependencies = require('./package.json').devDependencies

// this function reads Zendesk Garden npm dependencies from package.json and
// creates a jsDelivr url
const zendeskGardenJsDelivrUrl = (function () {
  const pkg = Object.keys(devDependencies).filter(item => item.includes('@zendeskgarden/css'))
  const getPkgName = (url, pkg) => {
    const version = devDependencies[pkg]
      .replace(/^[\^~]/g, '')
      .replace(/\.\d$/, '')
    url = `${url}npm/${pkg}@${version},`
    return url
  }
  return pkg.length && pkg.reduce(
    getPkgName,
    'https://cdn.jsdelivr.net/combine/'
  ).slice(0, -1)
}())

const externalAssets = {
  css: [
    zendeskGardenJsDelivrUrl
  ],
  js: [
    'https://assets.zendesk.com/apps/sdk/2.0/zaf_sdk.js'
  ]
}

module.exports = {
  entry: {
    app: [
      './src/javascripts/locations/ticket_sidebar.js',
      './src/index.css'
    ]
  },
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'dist/assets')
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        use: { loader: 'babel-loader' }
      },
      {
        type: 'javascript/auto',
        test: /\.json$/,
        include: path.resolve(__dirname, './src/translations'),
        use: './webpack/translations-loader'
      },
      {
        test: /\.(sa|sc|c)ss$/,
        use: [
          MiniCssExtractPlugin.loader,
          { loader: 'css-loader', options: { url: false } },
          'postcss-loader'
        ]
      }
    ]
  },
  devtool: 'source-map',
  plugins: [
    // Empties the dist folder
    new CleanWebpackPlugin({
      cleanOnceBeforeBuildPatterns: ['dist/*']
    }),

    // Copy over static assets
    new CopyPlugin({
      patterns: [
        { from: 'src/manifest.json', to: '../', flatten: true },
        { from: 'src/images/*', to: '.', flatten: true }
      ]
    }),

    new MiniCssExtractPlugin({
      filename: '[name].css'
    }),

    new TranslationsPlugin({
      path: path.resolve(__dirname, './src/translations')
    }),

    new HtmlWebpackPlugin({
      warning: 'AUTOMATICALLY GENERATED FROM ./src/templates/iframe.html - DO NOT MODIFY THIS FILE DIRECTLY',
      vendorCss: externalAssets.css.filter(path => !!path),
      vendorJs: externalAssets.js,
      template: './src/templates/iframe.html',
      filename: 'iframe.html'
    })
  ]
}

[QUESTION] ReactJS

Hello, I want to use ReactJS with scaffold, but I don't know how to integrate it. Could you please give me some steps to use it? Or an idea on how do I have to do it?

Thanks

"TypeError - can't dup NilClass" in `from-scratch` branch

Environment:

  • Windows 7
  • Opera 53.0
  • ruby 2.2.6p396 (2016-11-15 revision 56800) [x64-mingw32]
  • npm 6.1.0
  • zat 2.8.4
  • node v9.3.0

Steps to reproduce (note that ZAT is already installed):

  • open windows command prompt (cmd)
  • npm install --global webpack foreman karma-cli
  • git clone https://github.com/zendesk/app_scaffold
  • cd app_scaffold
  • git checkout from-scratch
  • npm install
  • nf start
  • Navigate to https:<subdomain>.zendesk.com/agent/dashboard?zat=true

EXPECTED:

  • No errors in console
  • Scaffold loads in Zendesk interface

ACTUAL:

  • No evidence of scaffold in Zendesk interface
  • The following warning in console:
[WARN] No ENV file found
11:56:20 reload.1   |  One CLI for webpack must be installed. These are recommended choices, delivered as separate packages:
11:56:20 reload.1   |   - webpack-cli (https://github.com/webpack/webpack-cli)
11:56:20 reload.1   |     The original webpack full-featured CLI.
11:56:20 reload.1   |   - webpack-command (https://github.com/webpack-contrib/webpack-command)
11:56:20 reload.1   |     A lightweight, opinionated webpack CLI.
11:56:20 reload.1   |  We will use "yarn" to install the CLI via "yarn add -D".
11:56:20 reload.1   |  Which one do you like to install (webpack-cli/webpack-command):
11:56:22 server.1   |  == Sinatra (v1.4.8) has taken the stage on 4567 for development with backup from Thin
  • The following stacktrace in console:
11:50:01 server.1   |  2018-06-19 11:50:01 - TypeError - can't dup NilClass:
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/zendesk_apps_support-4.7.0/lib/zendesk_apps_support/package.rb:256
:in `dup'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/zendesk_apps_support-4.7.0/lib/zendesk_apps_support/package.rb:256
:in `runtime_translations'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/zendesk_apps_support-4.7.0/lib/zendesk_apps_support/package.rb:132
:in `compile'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/zendesk_apps_tools-2.8.4/lib/zendesk_apps_tools/server.rb:39:in `s
erve_installed_js'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/zendesk_apps_tools-2.8.4/lib/zendesk_apps_tools/server.rb:14:in `b
lock in <class:Server>'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1611:in `call'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1611:in `block in compile!'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:975:in `[]'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:975:in `block (3 levels) in rout
e!'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:994:in `route_eval'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:975:in `block (2 levels) in rout
e!'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1015:in `block in process_route'

11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1013:in `catch'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1013:in `process_route'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:973:in `block in route!'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:972:in `each'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:972:in `route!'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1085:in `block in dispatch!'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1067:in `block in invoke'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1067:in `catch'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1067:in `invoke'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1082:in `dispatch!'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:907:in `block in call!'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1067:in `block in invoke'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1067:in `catch'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1067:in `invoke'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:907:in `call!'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:895:in `call'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.5/lib/rack/protection/xss_header.rb:18:in `cal
l'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.5/lib/rack/protection/path_traversal.rb:16:in
`call'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.5/lib/rack/protection/json_csrf.rb:18:in `call
'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.5/lib/rack/protection/base.rb:49:in `call'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/rack-protection-1.5.5/lib/rack/protection/base.rb:49:in `call'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/rack-1.6.9/lib/rack/logger.rb:15:in `call'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/rack-1.6.9/lib/rack/commonlogger.rb:33:in `call'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:219:in `call'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:212:in `call'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/rack-1.6.9/lib/rack/head.rb:13:in `call'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/sinatra-1.4.8/lib/sinatra/show_exceptions.rb:25:in `call'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:182:in `call'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:2013:in `call'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1487:in `block in call'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1787:in `synchronize'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/sinatra-1.4.8/lib/sinatra/base.rb:1487:in `call'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/thin-1.7.2/lib/thin/connection.rb:86:in `block in pre_process'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/thin-1.7.2/lib/thin/connection.rb:84:in `catch'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/thin-1.7.2/lib/thin/connection.rb:84:in `pre_process'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/thin-1.7.2/lib/thin/connection.rb:50:in `block in process'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/eventmachine-1.2.5-x64-mingw32/lib/eventmachine.rb:1076:in `call'
11:50:01 server.1   |   d:/Ruby22-x64/lib/ruby/gems/2.2.0/gems/eventmachine-1.2.5-x64-mingw32/lib/eventmachine.rb:1076:in `block
in spawn_threadpool'

Word wraps in stack trace are presumably due to Windows console ๐Ÿ™„

NOTES

  • Error does not occur if git checkout from-scratch step is omitted.
  • I attempted to resolve the warning about the webpack-cli by separately installing either one of the CLIs, but neither could be installed by webpack. No idea if that's related, but it doesn't halt the dev server from starting, which implies that it's not strictly necessary to fix.

Getting error when trying to run `nf start`

[WARN] No ENV file found
11:38:55 AM reload.1 | The CLI moved into a separate package: webpack-cli.
11:38:55 AM reload.1 | Please install 'webpack-cli' in addition to webpack itself to use the CLI.
11:38:55 AM reload.1 | -> When using npm: npm install webpack-cli -D
11:38:55 AM reload.1 | -> When using yarn: yarn add webpack-cli -D
[DONE] Killing all processes with signal null
11:38:55 AM reload.1 Exited with exit code 1
11:38:55 AM server.1 | /Users/ratneshnavlakhe/.rbenv/libexec/rbenv-which: line 54: echo: write error: Broken pipe
11:38:55 AM server.1 Exited with exit code null

make this package

Unable to get my app to package ... and this one works neither ... weird issues and too-many-open-files ... plz add whatever is needed to make zat package work

@svizzari

webpack -p error

When trying to run the zat migrate command I get the following error:

npm ERR! Darwin 15.6.0
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "run" "build"
npm ERR! node v5.9.0
npm ERR! npm v3.7.3
npm ERR! code ELIFECYCLE
npm ERR! [email protected] build: webpack -p
npm ERR! Exit status 2
npm ERR!
npm ERR! Failed at the [email protected] build script 'webpack -p'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the app_scaffold package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR! webpack -p
npm ERR! You can get information on how to open an issue for this project with:
npm ERR! npm bugs app_scaffold
npm ERR! Or if that isn't available, you can get their info via:
npm ERR! npm owner ls app_scaffold
npm ERR! There is likely additional logging output above.

Attaching the log file:
npm-debug.log

ZAFClient.init() returns false result on app reload

I am using an iFrame app inside Zendesk. When the app loads for the first time (or on a browser refresh), everything works as expected.
However, if I reload the iFrame app only (which internally re-initializes all the components) ZAFClient.init() returns false - resulting in breaking all the functionalities in the app.

Load an unsafe script (Chrome) does not appears

I followed the steps in the tutorial, but when I open my subdomain with ?zat=true in Chrome, the "load an unsafe script" message does not appears, neither the security shield icon.
Is there any step that I can do in most recent Chrome version that I'm missing?
The requests are send to my local server, because I can see the log messages in terminal, like:

::1 - - [29/Nov/2018:23:54:53 -0200] "GET /app.js?locale=pt-br&subdomain=mydemoapp HTTP/1.1" 200 943 0.2076 

Google Chrome: Version 70.0.3538.77 (Official Build) (64-bit)
Ubuntu: 18.10
ruby: 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux-gnu]
nodejs: v8.12.0

Karma Coverage not work

Hi people, i try insert karma-coverage in the karma config but i didn't make it work.
I install karma-coverage:

npm install --save-dev karma-coverage

And my karma.conf.js =>

const webpackConfig = require('./webpack.config')
const externalAssets = require('./lib/javascripts/external_assets')

module.exports = function (config) {
  config.set({
    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['jasmine'],

    // list of files / patterns to load in the browser
    files: externalAssets.js.concat([
      'spec/helpers/**/*.js',
      'spec/**/*_spec.js',
      'node_modules/babel-polyfill/dist/polyfill.js'
    ]),
    // list of files to exclude
    exclude: [],

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
      'src/**/*.js': ['webpack', 'coverage'],
      'spec/helpers/**/*.js': ['webpack'],
      'spec/**/*_spec.js': ['webpack']
    },
    // optionally, configure the reporter
    coverageReporter: {
      type: 'html',
      dir: 'coverage/',
      includeAllSources: true
    },
    webpack: {
      // karma watches the test entry points
      // (you don't need to specify the entry option)
      // webpack watches dependencies

      // webpack configuration
      module: webpackConfig.module,
      resolveLoader: webpackConfig.resolveLoader,
      resolve: webpackConfig.resolve,
      externals: webpackConfig.externals
    },
    webpackServer: {
      noInfo: true // Suppress all webpack messages, except errors
    },

    webpackMiddleware: {
      // webpack-dev-middleware configuration
      // i. e.
      stats: 'errors-only'
    },

    plugins: [
      require('karma-webpack'),
      require('karma-jasmine'),
      require('karma-phantomjs-launcher'),
      require('karma-chrome-launcher'),
      require('karma-coverage')
    ],

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['progress', 'coverage'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['PhantomJS'],

    customLaunchers: {
      // CRUFT: needed to load zaf_sdk with crossorigin=anonymous
      Chrome_without_security: {
        base: 'Chrome',
        flags: ['--disable-web-security']
      }
    },

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false,

    // Concurrency level
    // how many browser should be started simultaneous
    concurrency: Infinity
  })
}

When i execute karma start, my coverage don't show anything.

screenshot from 2018-04-26 11-50-53

assets in scss file

I tried migrating an app from v1 and v2 and am basically done, this repo helped a lot.
However, I noticed that all images that are references via css do not work as soon as the app is properly installed.

I am not skilled with webpack but it is the problem here. I have to write image paths like url("/image.png") or else it can't resolve images within the dist folder. However, I get absolute urls in my app which won't work as soon as I upload them to zendesk (Which has the assets in a folder like 106609/assets/1483613068-fa78dc30432094d311a5bd1c056d5cba/.

Could you give me a hint how to reference images within my stylesheet? Maybe adjust this scaffold so it works out of the box?

Documentation for packaging

The README covers everything from installation to running locally and testing. The area that is missing, is packaging and deployment.

I assume the following is still relevant for this repo:

cd dist
zat validate
zat package

And, then manually uploading the .zip file from the /tmp to your Zendesk instance.

Testing by adding ?zat=true to the URL.

Cannot see any console log messages

Hello, I'm looking for some advice on how to access the console log messages. I'm guessing they get eaten up because the app is running in an iframe. Do you know of any ways around this to see the console logs while the app runs?

Can not package

When trying to package the app, i receive the following error message

validate  Javascripts, stylesheets, and templates are not allowed when an iframe URI or noTemplate is specified

The app does not get packaged.

Any hints on why this issue is being shown and potential solution?

Thanks

Error ZAFClient not defined

Found the following error when running from-scratch branch app after packing and uploading:

Mixed Content: The page at '*' was loaded over HTTPS, but requested an insecure script 'http://assets.zendesk.com/apps/sdk/2.0/zaf_sdk.js'. This request has been blocked; the content must be served over HTTPS.

The nf start command doesn't work

nf start command does not work, when I run then does not make index.html file and another files.

I did install all dependencies {yarn, webpack and karma ...} in windows.

Location Folder and registered event.

I don't understand how this new structure works, I created an additional file under /Locations named new_ticket_sidebar.js, my manifest only has one location, ticket_sidebar, but it still executes both scripts on /Location . Moreover, it registers the app 2 times, independent of the location.

Here I'm just console logging the appData object after the app.registered event fires:

image

client.on('app.registered', function (appData) { client.invoke('app.hide'); console.log(appData); return new App(client, appData); });

Event always fire twice for both scripts, even though I don't have new_ticket_sidebar as a location on my manifest.

dist translation files not generated from src

I have updated the translations in src/translations/en.json, but when I run webpack --watch, these changes do not appear to be reflected in dist/translations/en.json. Do I need to do something besides run webpack?

There are no errors in my webpack output:

โžœ ticket_history git:(master!?) webpack --watch
Hash: 4d2fe7b36193bf7c6652
Version: webpack 1.15.0
Time: 2672ms
                  Asset       Size  Chunks             Chunk Names
../translations/de.json  409 bytes          [emitted]
../translations/en.json  392 bytes          [emitted]
../translations/fr.json  438 bytes          [emitted]
                main.js    48.7 kB       0  [emitted]  app
               main.css  892 bytes       0  [emitted]  app
             index.html     1.1 kB          [emitted]
   [0] multi app 40 bytes {0} [built]
   [6] ./src/translations ^\.\/.*\.json$ 202 bytes {0} [optional] [built]
   [7] ./src/translations/de.json 4.93 kB {0} [optional] [built]
   [8] ./src/translations/en.json 4.81 kB {0} [optional] [built]
   [9] ./src/translations/fr.json 4.96 kB {0} [optional] [built]
  [10] ./src/javascripts ^\.\/.*\.js$ 214 bytes {0} [built]
  [15] ./src/templates ^\.\/.*\.hdbs$ 238 bytes {0} [built]
    + 19 hidden modules
Child html-webpack-plugin for "index.html":
        + 20 hidden modules
Child extract-text-webpack-plugin:
        + 2 hidden modules

My source translations look like this:

{
  "app": {
    "description": "Displays recent tickets in the ticket sidebar.",
    "name": "Ticket History",
    "installation_instructions": "Installation is simple. Simply search for the Ticket History app in the Zendesk Apps Marketplace and click Install.",
    "long_description": "Displays a user's recent tickets in the ticket sidebar, along with the status, creation date, and currently assigned user. Clicking on a particular ticket will open up a preview of the requester's original comment, and also allows the user to switch directly to that ticket in the agent interface.",
    "parameters": {
      "list_length": {
        "label": "List Length",
        "helpText": "How many items should show up in the recent tickets list?"
      }
    }
  },

  "ticket_preview": "Ticket Preview (#{{id}})",

  "go_to_ticket": "Go to ticket",

  "new": "new",

  "open": "open",

  "hold": "hold",

  "pending": "pending",

  "solved": "solved",

  "closed": "closed",

  "unassigned": "unassigned",

  "tickets_from": "{{count}} ticket(s) from {{{requester_name}}}",

  "show_all": "Show all"
}

And the dist file looks like this:

{
  "_warning": "AUTOMATICALLY GENERATED FROM src/translations/en.json - DO NOT MODIFY THIS FILE DIRECTLY",
  "app": {
    "name": "Ticket History",
    "description": "Displays recent tickets in the ticket sidebar.",
    "parameters": {
      "list_length": {
        "label": "List Length",
        "helpText": "How many items should show up in the recent tickets list?"
      }
    }
  }
}

Thank you!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.