├── .gitignore ├── README.md ├── app.js ├── app.json ├── app ├── Application.js ├── store │ └── Employees.js └── view │ └── main │ ├── ListViewController.js │ ├── Main.js │ ├── PopupForm.js │ └── PopupFormController.js ├── build.xml ├── data └── data.json ├── index.html └── workspace.json /.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /ext 3 | /.sencha 4 | /bootstrap.* 5 | /sass 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Taking QuickStart to Production 2 | 3 | Let's walk through the steps of creating the app we've been working on above in 4 | a real world environment. 5 | 6 | ## Download the Ext JS Framework 7 | 8 | If you have not already done so, download and unpack the Ext JS framework from 9 | either the Products section of the main Sencha website 10 | ([www.sencha.com](http://www.sencha.com)) or from the downloads section of the 11 | Sencha Support portal. 12 | 13 | ## Download the Sample Application 14 | 15 | You can download from Github by clicking the green "Clone or Download" button. Then 16 | just click "Download Zip" and save the file to your machine. 17 | 18 | Once downloaded, move the folder to wherever you'd like your application to live. 19 | 20 | ## Add Sencha Cmd to your App 21 | 22 | Once you have your application where you want it, "cd" into its directory in your 23 | Command Line Interface (CLI). Then, issue the following command: 24 | 25 | sencha app install --framework=/path/to/extjs/ 26 | 27 | This command will update your folder with Sencha Cmd's application scaffold that 28 | allows your application to benefit from Sencha Cmd's many features. 29 | 30 | **Note:** "/path/to/extjs/" should be replaced with the path to wherever you 31 | unzipped the Ext JS framework on your machine. 32 | 33 | ## Build Your Application 34 | 35 | Finally, run the following command to build the application: 36 | 37 | sencha app build 38 | 39 | You can now visit your application at its local address on your web server. 40 | 41 | Alternatively, you can run this command so that Sencha Cmd will provide a web 42 | server for you: 43 | 44 | sencha app watch 45 | 46 | You can now visit the resulting address displayed in your console. It will 47 | usually be found here: 48 | 49 | http://localhost:1841/ 50 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | Ext.application({ 2 | name: 'QuickStart', 3 | 4 | extend: 'QuickStart.Application', 5 | 6 | requires: [ 7 | 'QuickStart.*' 8 | ], 9 | 10 | // The name of the initial view to create. With the classic toolkit this class 11 | // will gain a "viewport" plugin if it does not extend Ext.Viewport. With the 12 | // modern toolkit, the main view will be added to the Viewport. 13 | // 14 | mainView: 'QuickStart.view.main.Main' 15 | }); 16 | -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | /** 3 | * The application's namespace. 4 | */ 5 | "name": "QuickStart", 6 | 7 | /** 8 | * The version of the application. 9 | */ 10 | "version": "1.0.0.0", 11 | 12 | /** 13 | * The relative path to the application's markup file (html, jsp, asp, etc.). 14 | */ 15 | "indexHtmlPath": "index.html", 16 | 17 | /** 18 | * Comma-separated string with the paths of directories or files to search. Any classes 19 | * declared in these locations will be available in your class "requires" or in calls 20 | * to "Ext.require". The "app.dir" variable below is expanded to the path where the 21 | * application resides (the same folder in which this file is located). 22 | */ 23 | "classpath": [ 24 | "app" 25 | ], 26 | 27 | /** 28 | * Comma-separated string with the paths of directories or files to search. Any classes 29 | * declared in these locations will be automatically required and included in the build. 30 | * If any file defines an Ext JS override (using Ext.define with an "override" property), 31 | * that override will in fact only be included in the build if the target class specified 32 | * in the "override" property is also included. 33 | */ 34 | "overrides": [ 35 | "overrides" 36 | ], 37 | 38 | /** 39 | * The Sencha Framework for this application: "ext" or "touch". 40 | */ 41 | "framework": "ext", 42 | 43 | /** 44 | * The toolkit to use. Select either "classic" or "modern". 45 | */ 46 | "toolkit": "modern", 47 | 48 | /** 49 | * The name of the theme for this application. 50 | */ 51 | "theme": "theme-material", 52 | 53 | /** 54 | * The list of required packages (with optional versions; default is "latest"). 55 | * 56 | * For example, 57 | * 58 | * "requires": [ 59 | * "charts" 60 | * ] 61 | */ 62 | "requires": [ 63 | "font-awesome" 64 | ], 65 | 66 | /** 67 | * Fashion build configuration properties. 68 | */ 69 | "fashion": { 70 | "inliner": { 71 | /** 72 | * Disable resource inliner. Production builds enable this by default. 73 | */ 74 | "enable": false 75 | } 76 | }, 77 | 78 | /** 79 | * Sass configuration properties. 80 | */ 81 | "sass": { 82 | /** 83 | * The root namespace to use when mapping *.scss files to classes in the 84 | * sass/src and sass/var directories. For example, "QuickStart.view.Foo" would 85 | * map to "sass/src/view/Foo.scss". If we changed this to "QuickStart.view" then 86 | * it would map to "sass/src/Foo.scss". To style classes outside the app's 87 | * root namespace, change this to "". Doing so would change the mapping of 88 | * "QuickStart.view.Foo" to "sass/src/QuickStart/view/Foo.scss". 89 | */ 90 | "namespace": "QuickStart", 91 | 92 | /** 93 | * Comma-separated list of files or folders containing extra Sass. These 94 | * files are automatically included in the Sass compilation. By default this 95 | * is just "etc/all.scss" to allow import directives to control the order 96 | * other files are included. 97 | * 98 | * All "etc" files are included at the top of the Sass compilation in their 99 | * dependency order: 100 | * 101 | * +-------+---------+ 102 | * | | base | 103 | * | theme +---------+ 104 | * | | derived | 105 | * +-------+---------+ 106 | * | packages | (in package dependency order) 107 | * +-----------------+ 108 | * | application | 109 | * +-----------------+ 110 | */ 111 | "etc": [ 112 | "sass/etc/all.scss" 113 | ], 114 | 115 | /** 116 | * Comma-separated list of folders containing Sass variable definitions 117 | * files. These file can also define Sass mixins for use by components. 118 | * 119 | * All "var" files are included after "etc" files in the Sass compilation in 120 | * dependency order: 121 | * 122 | * +-------+---------+ 123 | * | | base | 124 | * | theme +---------+ 125 | * | | derived | 126 | * +-------+---------+ 127 | * | packages | (in package dependency order) 128 | * +-----------------+ 129 | * | application | 130 | * +-----------------+ 131 | * 132 | * The "sass/var/all.scss" file is always included at the start of the var 133 | * block before any files associated with JavaScript classes. 134 | */ 135 | "var": [ 136 | "sass/var/all.scss", 137 | "sass/var" 138 | ], 139 | 140 | /** 141 | * Comma-separated list of folders containing Sass rule files. 142 | * 143 | * All "src" files are included after "var" files in the Sass compilation in 144 | * dependency order (the same order as "etc"): 145 | * 146 | * +-------+---------+ 147 | * | | base | 148 | * | theme +---------+ 149 | * | | derived | 150 | * +-------+---------+ 151 | * | packages | (in package dependency order) 152 | * +-----------------+ 153 | * | application | 154 | * +-----------------+ 155 | */ 156 | "src": [ 157 | "sass/src" 158 | ] 159 | }, 160 | 161 | /** 162 | * List of all JavaScript assets in the right execution order. 163 | * 164 | * Each item is an object with the following format: 165 | * 166 | * { 167 | * // Path to file. If the file is local this must be a relative path from 168 | * // this app.json file. 169 | * // 170 | * "path": "path/to/script.js", // REQUIRED 171 | * 172 | * // Set to true on one file to indicate that it should become the container 173 | * // for the concatenated classes. 174 | * // 175 | * "bundle": false, // OPTIONAL 176 | * 177 | * // Set to true to include this file in the concatenated classes. 178 | * // 179 | * "includeInBundle": false, // OPTIONAL 180 | * 181 | * // Specify as true if this file is remote and should not be copied into the 182 | * // build folder. Defaults to false for a local file which will be copied. 183 | * // 184 | * "remote": false, // OPTIONAL 185 | * 186 | * // If not specified, this file will only be loaded once, and cached inside 187 | * // localStorage until this value is changed. You can specify: 188 | * // 189 | * // - "delta" to enable over-the-air delta update for this file 190 | * // - "full" means full update will be made when this file changes 191 | * // 192 | * "update": "", // OPTIONAL 193 | * 194 | * // A value of true indicates that is a development mode only dependency. 195 | * // These files will not be copied into the build directory or referenced 196 | * // in the generate app.json manifest for the micro loader. 197 | * // 198 | * "bootstrap": false // OPTIONAL 199 | * } 200 | * 201 | */ 202 | "js": [ 203 | { 204 | "path": "${framework.dir}/build/ext-modern-all-debug.js" 205 | }, 206 | { 207 | "path": "app.js", 208 | "bundle": true 209 | } 210 | ], 211 | 212 | /** 213 | * List of all CSS assets in the right inclusion order. 214 | * 215 | * Each item is an object with the following format: 216 | * 217 | * { 218 | * // Path to file. If the file is local this must be a relative path from 219 | * // this app.json file. 220 | * // 221 | * "path": "path/to/stylesheet.css", // REQUIRED 222 | * 223 | * // Specify as true if this file is remote and should not be copied into the 224 | * // build folder. Defaults to false for a local file which will be copied. 225 | * // 226 | * "remote": false, // OPTIONAL 227 | * 228 | * // If not specified, this file will only be loaded once, and cached inside 229 | * // localStorage until this value is changed. You can specify: 230 | * // 231 | * // - "delta" to enable over-the-air delta update for this file 232 | * // - "full" means full update will be made when this file changes 233 | * // 234 | * "update": "" // OPTIONAL 235 | * } 236 | */ 237 | "css": [ 238 | { 239 | // this entry uses an ant variable that is the calculated 240 | // value of the generated output css file for the app, 241 | // defined in .sencha/app/defaults.properties 242 | "path": "${build.out.css.path}", 243 | "bundle": true, 244 | "exclude": ["fashion"] 245 | } 246 | ], 247 | 248 | /** 249 | * This option is used to configure the dynamic loader. At present these options 250 | * are supported. 251 | * 252 | */ 253 | "loader": { 254 | // This property controls how the loader manages caching for requests: 255 | // 256 | // - true: allows requests to receive cached responses 257 | // - false: disable cached responses by adding a random "cache buster" 258 | // - other: a string (such as the build.timestamp shown here) to allow 259 | // requests to be cached for this build. 260 | // 261 | "cache": false, 262 | 263 | // When "cache" is not true, this value is the request parameter used 264 | // to control caching. 265 | // 266 | "cacheParam": "_dc" 267 | }, 268 | 269 | /** 270 | * Settings specific to production builds. 271 | */ 272 | "production": { 273 | "output": { 274 | "appCache": { 275 | "enable": true, 276 | "path": "cache.appcache" 277 | } 278 | }, 279 | "loader": { 280 | "cache": "${build.timestamp}" 281 | }, 282 | "cache": { 283 | "enable": true 284 | }, 285 | "compressor": { 286 | "type": "yui" 287 | } 288 | }, 289 | 290 | /** 291 | * Settings specific to testing builds. 292 | */ 293 | "testing": { 294 | }, 295 | 296 | /** 297 | * Settings specific to development builds. 298 | */ 299 | "development": { 300 | "tags": [] 301 | }, 302 | 303 | /** 304 | * Controls the output structure of development-mode (bootstrap) artifacts. May 305 | * be specified by a string: 306 | * 307 | * "bootstrap": "${app.dir}" 308 | * 309 | * This will adjust the base path for all bootstrap objects, or expanded into object 310 | * form: 311 | * 312 | * "bootstrap": { 313 | * "base": "${app.dir}, 314 | * "manifest": "bootstrap.json", 315 | * "microloader": "bootstrap.js", 316 | * "css": "bootstrap.css" 317 | * } 318 | * 319 | * You can optionally exclude entries from the manifest. For example, to exclude 320 | * the "loadOrder" (to help development load approximate a build) you can add: 321 | * 322 | * "bootstrap": { 323 | * "manifest": { 324 | * "path": "bootstrap.json", 325 | * "exclude": "loadOrder" 326 | * } 327 | * } 328 | * 329 | */ 330 | "bootstrap": { 331 | "base": "${app.dir}", 332 | "microloader": "bootstrap.js", 333 | "css": "bootstrap.css" 334 | }, 335 | 336 | /** 337 | * Controls the output directory for build resources. May be set with 338 | * either a string: 339 | * 340 | * "${workspace.build.dir}/${build.environment}/${app.name}" 341 | * 342 | * or an object containing values for various types of build artifacts: 343 | * 344 | * { 345 | * "base": "${workspace.build.dir}/${build.environment}/${app.name}", 346 | * "page": { 347 | * "path": "../index.html", 348 | * "enable": false 349 | * }, 350 | * "css": "${app.output.resources}/${app.name}-all.css", 351 | * "js": "app.js", 352 | * "microloader": { 353 | * "path": "microloader.js", 354 | * "embed": true, 355 | * "enable": true 356 | * }, 357 | * "manifest": { 358 | * "path": "app.json", 359 | * "embed": false, 360 | * "enable": "${app.output.microloader.enable}" 361 | * }, 362 | * "resources": "resources", 363 | * // Setting the "enable" property of this object to a Truthy value will cause a Application Cache 364 | * // manifest file to be generated based on this files appCache object. This file will then be injected 365 | * // into the index.html file of the built application 366 | * "appCache":{ 367 | * "enable": false" 368 | * } 369 | * } 370 | * 371 | */ 372 | "output": { 373 | "base": "${workspace.build.dir}/${build.environment}/${app.name}", 374 | "appCache": { 375 | "enable": false 376 | } 377 | }, 378 | 379 | /** 380 | * Controls for localStorage caching 381 | * "cache": { 382 | * // This property controls whether localStorage caching of this manifest file is on or off. 383 | * // if disabled no deltas will be generated during a build and full updates will be disabled 384 | * "enable": false, 385 | * 386 | * // This property allows for global toggle of deltas. 387 | * // If set to a string the value will be used as the path to where deltas will be generated relative to you build. 388 | * // If set to a Truthy Value the default path ok "deltas" will be used 389 | * // If set to a Falsey value or if this property is not present deltas will be disabled and not generated. 390 | * 391 | * "deltas": "deltas" 392 | * } 393 | */ 394 | "cache": { 395 | "enable": false, 396 | "deltas": true 397 | }, 398 | 399 | /** 400 | * Used to automatically generate cache.manifest (HTML 5 application cache manifest) 401 | * file when you build. 402 | */ 403 | "appCache": { 404 | /** 405 | * List of items in the CACHE MANIFEST section 406 | */ 407 | "cache": [ 408 | "index.html" 409 | ], 410 | /** 411 | * List of items in the NETWORK section 412 | */ 413 | "network": [ 414 | "*" 415 | ], 416 | /** 417 | * List of items in the FALLBACK section 418 | */ 419 | "fallback": [] 420 | }, 421 | 422 | /** 423 | * Extra resources to be copied into the resource folder as specified in the "resources" 424 | * property of the "output" object. Folders specified in this list will be deeply copied. 425 | */ 426 | "resources": [ 427 | { 428 | "path": "resources", 429 | "output": "shared" 430 | } 431 | ], 432 | 433 | /** 434 | * File / directory name patttern to ignore when copying to the builds. Must be a 435 | * valid regular expression. 436 | */ 437 | "ignore": [ 438 | "(^|/)CVS(/?$|/.*?$)" 439 | ], 440 | 441 | /** 442 | * Directory path to store all previous production builds. Note that the content 443 | * generated inside this directory must be kept intact for proper generation of 444 | * deltas between updates. 445 | */ 446 | "archivePath": "archive", 447 | 448 | /** 449 | * Uniquely generated id for this application, used as prefix for localStorage keys. 450 | * Normally you should never change this value. 451 | */ 452 | "id": "9b26bc93-57e1-4173-910f-d75951525cfc" 453 | } 454 | -------------------------------------------------------------------------------- /app/Application.js: -------------------------------------------------------------------------------- 1 | /** 2 | * The main application class. An instance of this class is created by app.js when it 3 | * calls Ext.application(). This is the ideal place to handle application launch and 4 | * initialization details. 5 | */ 6 | Ext.define('QuickStart.Application', { 7 | extend: 'Ext.app.Application', 8 | 9 | name: 'QuickStart', 10 | 11 | // The application is launched using the mainView config in app.js 12 | // 13 | // launch: function () { 14 | // Implement this method to do a custom launch. 15 | // }, 16 | 17 | onAppUpdate: function () { 18 | Ext.Msg.confirm('Application Update', 'This application has an update, reload?', 19 | function (choice) { 20 | if (choice === 'yes') { 21 | window.location.reload(); 22 | } 23 | } 24 | ); 25 | } 26 | }); 27 | -------------------------------------------------------------------------------- /app/store/Employees.js: -------------------------------------------------------------------------------- 1 | Ext.define('QuickStart.store.Employees', { 2 | extend: 'Ext.data.Store', 3 | alias: 'store.employees', 4 | 5 | proxy: { 6 | type: 'ajax', 7 | url: 'data/data.json' 8 | }, 9 | 10 | listeners: { 11 | 12 | update: function(store, record , operation , modifiedFieldNames) { 13 | if (!modifiedFieldNames) { 14 | return; 15 | } 16 | 17 | // Ensure that select field is being set to a value, not the entire record 18 | var modField = modifiedFieldNames.toString(), 19 | mod = record.get(modField); 20 | 21 | if (mod && mod.isModel) { 22 | record.set(modField, mod.get('text')); 23 | } 24 | } 25 | } 26 | }); 27 | -------------------------------------------------------------------------------- /app/view/main/ListViewController.js: -------------------------------------------------------------------------------- 1 | Ext.define('QuickStart.view.main.ListViewController', { 2 | extend: 'Ext.app.ViewController', 3 | alias: 'controller.listview', 4 | 5 | onPopupForm: function (view, index, item, record) { 6 | var popupWindow = new QuickStart.view.main.PopupForm({ 7 | id: 'rec_update', 8 | width: 400, 9 | height: 400, 10 | centered: true, 11 | modal: true, 12 | record: record, 13 | viewModel : { 14 | data: { 15 | employee: record 16 | } 17 | } 18 | }); 19 | Ext.Viewport.add(popupWindow); 20 | popupWindow.show(); 21 | } 22 | }); 23 | -------------------------------------------------------------------------------- /app/view/main/Main.js: -------------------------------------------------------------------------------- 1 | Ext.define('QuickStart.view.main.Main', { 2 | extend: 'Ext.tab.Panel', 3 | controller: 'listview', 4 | 5 | items: [{ 6 | title: 'Employee Directory', 7 | xtype: 'grid', 8 | iconCls: 'x-fa fa-users', 9 | grouped: true, 10 | listeners: { 11 | itemtap: 'onPopupForm' 12 | }, 13 | store: { 14 | type: 'employees', 15 | autoLoad: true, 16 | sorters: ['firstName', 'lastName', 'officeLocation'], 17 | grouper: 'officeLocation' 18 | }, 19 | columns: [{ 20 | text: 'First Name', 21 | dataIndex: 'firstName', 22 | flex: 1 23 | }, { 24 | text: 'Last Name', 25 | dataIndex: 'lastName', 26 | flex: 1 27 | }, { 28 | text: 'Phone Number', 29 | dataIndex: 'phoneNumber', 30 | flex: 1 31 | }] 32 | },{ 33 | title: 'About Sencha', 34 | padding: 20, 35 | iconCls: 'x-fa fa-info-circle', 36 | html: '