├── README.md ├── client ├── .gitignore ├── Readme.md ├── app.js ├── app.json ├── app │ ├── Application.js │ ├── Application.scss │ ├── Readme.md │ ├── model │ │ ├── Person.js │ │ └── Readme.md │ ├── profile │ │ ├── Phone.js │ │ └── Tablet.js │ ├── store │ │ ├── Personnel.js │ │ └── Readme.md │ └── view │ │ ├── main │ │ ├── List.js │ │ ├── List.scss │ │ ├── Main.js │ │ ├── MainController.js │ │ └── MainModel.js │ │ └── person │ │ ├── Details.js │ │ ├── Header.js │ │ ├── Person.js │ │ ├── Person.scss │ │ ├── PersonController.js │ │ └── PersonModel.js ├── build.xml ├── index.html ├── overrides │ ├── XTemplate.js │ └── util │ │ ├── Format.js │ │ └── XTemplateCompiler.js ├── package.json ├── resources │ ├── icon-large.png │ ├── icon-medium.png │ ├── icon-small.png │ ├── manifest.json │ └── splash.png └── workspace.json ├── notes.txt └── server ├── .gitignore ├── api ├── personnel.json └── portraits │ ├── men │ ├── 0.jpg │ ├── 1.jpg │ ├── 10.jpg │ ├── 11.jpg │ ├── 12.jpg │ ├── 13.jpg │ ├── 14.jpg │ ├── 15.jpg │ ├── 16.jpg │ ├── 17.jpg │ ├── 18.jpg │ ├── 19.jpg │ ├── 2.jpg │ ├── 20.jpg │ ├── 21.jpg │ ├── 22.jpg │ ├── 23.jpg │ ├── 24.jpg │ ├── 25.jpg │ ├── 26.jpg │ ├── 27.jpg │ ├── 28.jpg │ ├── 29.jpg │ ├── 3.jpg │ ├── 30.jpg │ ├── 31.jpg │ ├── 32.jpg │ ├── 33.jpg │ ├── 34.jpg │ ├── 35.jpg │ ├── 36.jpg │ ├── 37.jpg │ ├── 38.jpg │ ├── 39.jpg │ ├── 4.jpg │ ├── 40.jpg │ ├── 41.jpg │ ├── 42.jpg │ ├── 43.jpg │ ├── 44.jpg │ ├── 45.jpg │ ├── 46.jpg │ ├── 47.jpg │ ├── 48.jpg │ ├── 49.jpg │ ├── 5.jpg │ ├── 50.jpg │ ├── 51.jpg │ ├── 52.jpg │ ├── 53.jpg │ ├── 54.jpg │ ├── 55.jpg │ ├── 56.jpg │ ├── 57.jpg │ ├── 58.jpg │ ├── 59.jpg │ ├── 6.jpg │ ├── 60.jpg │ ├── 61.jpg │ ├── 62.jpg │ ├── 63.jpg │ ├── 64.jpg │ ├── 65.jpg │ ├── 66.jpg │ ├── 67.jpg │ ├── 68.jpg │ ├── 69.jpg │ ├── 7.jpg │ ├── 70.jpg │ ├── 71.jpg │ ├── 72.jpg │ ├── 73.jpg │ ├── 74.jpg │ ├── 75.jpg │ ├── 76.jpg │ ├── 77.jpg │ ├── 78.jpg │ ├── 79.jpg │ ├── 8.jpg │ ├── 80.jpg │ ├── 81.jpg │ ├── 82.jpg │ ├── 83.jpg │ ├── 84.jpg │ ├── 85.jpg │ ├── 86.jpg │ ├── 87.jpg │ ├── 88.jpg │ ├── 89.jpg │ ├── 9.jpg │ ├── 90.jpg │ ├── 91.jpg │ ├── 92.jpg │ ├── 93.jpg │ ├── 94.jpg │ ├── 95.jpg │ ├── 96.jpg │ ├── 97.jpg │ ├── 98.jpg │ └── 99.jpg │ └── women │ ├── 0.jpg │ ├── 1.jpg │ ├── 10.jpg │ ├── 11.jpg │ ├── 12.jpg │ ├── 13.jpg │ ├── 14.jpg │ ├── 15.jpg │ ├── 16.jpg │ ├── 17.jpg │ ├── 18.jpg │ ├── 19.jpg │ ├── 2.jpg │ ├── 20.jpg │ ├── 21.jpg │ ├── 22.jpg │ ├── 23.jpg │ ├── 24.jpg │ ├── 25.jpg │ ├── 26.jpg │ ├── 27.jpg │ ├── 28.jpg │ ├── 29.jpg │ ├── 3.jpg │ ├── 30.jpg │ ├── 31.jpg │ ├── 32.jpg │ ├── 33.jpg │ ├── 34.jpg │ ├── 35.jpg │ ├── 36.jpg │ ├── 37.jpg │ ├── 38.jpg │ ├── 39.jpg │ ├── 4.jpg │ ├── 40.jpg │ ├── 41.jpg │ ├── 42.jpg │ ├── 43.jpg │ ├── 44.jpg │ ├── 45.jpg │ ├── 46.jpg │ ├── 47.jpg │ ├── 48.jpg │ ├── 49.jpg │ ├── 5.jpg │ ├── 50.jpg │ ├── 51.jpg │ ├── 52.jpg │ ├── 53.jpg │ ├── 54.jpg │ ├── 55.jpg │ ├── 56.jpg │ ├── 57.jpg │ ├── 58.jpg │ ├── 59.jpg │ ├── 6.jpg │ ├── 60.jpg │ ├── 61.jpg │ ├── 62.jpg │ ├── 63.jpg │ ├── 64.jpg │ ├── 65.jpg │ ├── 66.jpg │ ├── 67.jpg │ ├── 68.jpg │ ├── 69.jpg │ ├── 7.jpg │ ├── 70.jpg │ ├── 71.jpg │ ├── 72.jpg │ ├── 73.jpg │ ├── 74.jpg │ ├── 75.jpg │ ├── 76.jpg │ ├── 77.jpg │ ├── 78.jpg │ ├── 79.jpg │ ├── 8.jpg │ ├── 80.jpg │ ├── 81.jpg │ ├── 82.jpg │ ├── 83.jpg │ ├── 84.jpg │ ├── 85.jpg │ ├── 86.jpg │ ├── 87.jpg │ ├── 88.jpg │ ├── 89.jpg │ ├── 9.jpg │ ├── 90.jpg │ ├── 91.jpg │ ├── 92.jpg │ ├── 93.jpg │ ├── 94.jpg │ ├── 95.jpg │ ├── 96.jpg │ ├── 97.jpg │ ├── 98.jpg │ └── 99.jpg ├── certs └── .gitkeep ├── index.js └── package.json /README.md: -------------------------------------------------------------------------------- 1 | # PWA 2 | 3 | A demo of the Progressive Web App support in Ext JS 6.5 and Sencha Cmd 6.5. 4 | 5 | ## To run 6 | 7 | You will need to download [Sencha Ext JS](https://www.sencha.com/products/extjs). We 8 | recommend extracting Ext JS into a `"sencha-sdks"` folder in your home directory. 9 | 10 | Once Ext JS is extracted, run these commands: 11 | 12 | cd client 13 | sencha app install ~/sencha-sdks 14 | sencha app build --dev 15 | cd ../server 16 | npm install 17 | npm start 18 | 19 | On Windows the "~" part of the path will be replaced by something like "C:\Users\Me\". 20 | 21 | You should now be able to point your browser to [http://localhost:8082/](http://localhost:8082/). 22 | 23 | ## Run Production Build 24 | 25 | To run a production build, run these commands: 26 | 27 | cd client 28 | sencha app build 29 | cd ../server 30 | NODE_ENV=production npm start 31 | 32 | This will run a production build and start the server with a path to the production build. 33 | You should now be able to point your browser to [http://localhost:8082/](http://localhost:8082/). 34 | 35 | ## HTTPS 36 | 37 | When the node server is started, it will check if there are any SSL certificates in the `certs` 38 | directory. If not, a non-secure only server will be started. If there is, it will start both 39 | a non-secure and a secure server. You can generate self-signed localhost certificates by running: 40 | 41 | cd server 42 | npm run ssl 43 | 44 | This will prompt you a few questions, you can accept the defaults except for the **Common Name** 45 | prompt. For this prompt, enter `localhost`. Once completed, there will be a `server.crt` and 46 | `server.key` in the `certs` directory. Now when you run `npm start`, it will detect these and 47 | start both servers. You can then point your browser to the [non-secure](http://localhost:8082/) 48 | or [secure server](https://localhost:8082/). 49 | 50 | **Note:** *Self signed certificates are not trusted and should not be used in production. The 51 | browser will warn you of this and you must opt into allowing the self signed certificate.* 52 | -------------------------------------------------------------------------------- /client/.gitignore: -------------------------------------------------------------------------------- 1 | /bootstrap.* 2 | /build 3 | /ext 4 | -------------------------------------------------------------------------------- /client/Readme.md: -------------------------------------------------------------------------------- 1 | # PWA 2 | 3 | This folder is the container for the top-level pieces of front-end application. 4 | 5 | The following files are all needed to build and load the application. 6 | 7 | - `"app.json"` - The application descriptor which controls how the application is 8 | built and loaded. 9 | - `"app.js"` - The file that launches the application. This is primarily used to 10 | launch an instance of the `MyApp.Application` class. 11 | - `"index.html"` - The default web page for this application. This can be customized 12 | in `"app.json"`. 13 | - `"build.xml"` - The entry point for Sencha Cmd to access the generated build 14 | script. This file is a place where you can hook into these processes and tune 15 | them. See the comments in that file for more information. 16 | 17 | These files can be ignored from source control as they are regenerated by the build 18 | process. 19 | 20 | - `"build"` - This folder contain the output of the build. The generated CSS file, 21 | consolidated resources and concatenated JavaScript file are all stored in this 22 | folder. 23 | - `"bootstrap.*"` - These files are generated by the build and watch commands to 24 | enable the application to load in "development mode". 25 | 26 | # Other Folders 27 | 28 | ## Basic Application Structure 29 | 30 | Applications that target a single toolkit will have the following structure. 31 | 32 | app/ # Contains JavaScript code 33 | model/ # Data model classes 34 | view/ # Views as well as ViewModels and ViewControllers 35 | store/ # Data stores 36 | controller/ # Global / application-level controllers 37 | 38 | overrides/ # JavaScript code that is automatically required 39 | 40 | resources/ # Assets such as images, fonts, etc. 41 | 42 | ## Overrides 43 | 44 | The contents of "overrides" folders are automatically required and included in 45 | builds. These should not be explicitly mentioned in "requires" or "uses" in code. 46 | This area is intended for overrides like these: 47 | 48 | Ext.define('PWA.overrides.foo.Bar', { 49 | override: 'Ext.foo.Bar', 50 | ... 51 | }); 52 | 53 | Such overrides, while automatically required, will only be included if their target 54 | class ("Ext.foo.Bar" in this case) is also required. This simplifies applying 55 | patches or extensions to other classes. 56 | -------------------------------------------------------------------------------- /client/app.js: -------------------------------------------------------------------------------- 1 | /* 2 | * This file launches the application by asking Ext JS to create 3 | * and launch() the Application class. 4 | */ 5 | Ext.application({ 6 | name: 'PWA', 7 | 8 | extend: 'PWA.Application', 9 | 10 | requires: [ 11 | 'PWA.*' 12 | ], 13 | 14 | // The name of the initial view to create. The main view will 15 | // be added to the Ext.Viewport. 16 | // 17 | mainView: 'PWA.view.main.Main' 18 | }); 19 | -------------------------------------------------------------------------------- /client/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "PWA", 3 | "version": "1.0.0.0", 4 | "framework": "ext", 5 | "toolkit": "modern", 6 | "theme": "theme-material", 7 | 8 | "indexHtmlPath": "index.html", 9 | 10 | /** 11 | * Comma-separated string with the paths of directories or files to search. Any classes 12 | * declared in these locations will be available in your class "requires" or in calls 13 | * to "Ext.require". The "app.dir" variable below is expanded to the path where the 14 | * application resides (the same folder in which this file is located). 15 | */ 16 | "classpath": [ 17 | "app" 18 | ], 19 | 20 | /** 21 | * Comma-separated string with the paths of directories or files to search. Any classes 22 | * declared in these locations will be automatically required and included in the build. 23 | * If any file defines an Ext JS override (using Ext.define with an "override" property), 24 | * that override will in fact only be included in the build if the target class specified 25 | * in the "override" property is also included. 26 | */ 27 | "overrides": [ 28 | "overrides" 29 | ], 30 | 31 | /** 32 | * The list of required packages (with optional versions; default is "latest"). 33 | * 34 | * For example, 35 | * 36 | * "requires": [ 37 | * "charts" 38 | * ] 39 | */ 40 | "requires": [ 41 | "font-awesome" 42 | ], 43 | 44 | /** 45 | * Fashion build configuration properties. 46 | */ 47 | "fashion": { 48 | "inliner": { 49 | /** 50 | * Disable resource inliner. Production builds enable this by default. 51 | */ 52 | "enable": false 53 | } 54 | }, 55 | 56 | /** 57 | * Sass configuration properties. 58 | */ 59 | "sass": { 60 | "namespace": "PWA", 61 | 62 | /** 63 | * Generated sass source settings 64 | * 65 | * "generated": { 66 | * // The file used to save sass variables edited via Sencha Inspector and Sencha Themer. 67 | * // This file will automatically be applied to the end of the scss build. 68 | * "var": "sass/save.scss", 69 | * 70 | * // The directory used to save generated sass sources. 71 | * // This directory will automatically be applied to the end of the scss build. 72 | * "src": "sass/save" 73 | * } 74 | * 75 | */ 76 | "generated": { 77 | "var": "sass/save.scss", 78 | "src": "sass/save" 79 | } 80 | }, 81 | 82 | /** 83 | * List of all JavaScript assets in the right execution order. 84 | * 85 | * Each item is an object with the following format: 86 | * 87 | * { 88 | * // Path to file. If the file is local this must be a relative path from 89 | * // this app.json file. 90 | * // 91 | * "path": "path/to/script.js", // REQUIRED 92 | * 93 | * // Set to true on one file to indicate that it should become the container 94 | * // for the concatenated classes. 95 | * // 96 | * "bundle": false, // OPTIONAL 97 | * 98 | * // Set to true to include this file in the concatenated classes. 99 | * // 100 | * "includeInBundle": false, // OPTIONAL 101 | * 102 | * // Specify as true if this file is remote and should not be copied into the 103 | * // build folder. Defaults to false for a local file which will be copied. 104 | * // 105 | * "remote": false, // OPTIONAL 106 | * 107 | * // If not specified, this file will only be loaded once, and cached inside 108 | * // localStorage until this value is changed. You can specify: 109 | * // 110 | * // - "delta" to enable over-the-air delta update for this file 111 | * // - "full" means full update will be made when this file changes 112 | * // 113 | * "update": "", // OPTIONAL 114 | * 115 | * // A value of true indicates that is a development mode only dependency. 116 | * // These files will not be copied into the build directory or referenced 117 | * // in the generate app.json manifest for the micro loader. 118 | * // 119 | * "bootstrap": false // OPTIONAL 120 | * } 121 | * 122 | */ 123 | "js": [ 124 | { "path": "${framework.dir}/build/ext-modern-all-debug.js" }, 125 | { 126 | "path": "app.js", 127 | "bundle": true 128 | } 129 | ], 130 | 131 | /** 132 | * List of all CSS assets in the right inclusion order. 133 | * 134 | * Each item is an object with the following format: 135 | * 136 | * { 137 | * // Path to file. If the file is local this must be a relative path from 138 | * // this app.json file. 139 | * // 140 | * "path": "path/to/stylesheet.css", // REQUIRED 141 | * 142 | * // Specify as true if this file is remote and should not be copied into the 143 | * // build folder. Defaults to false for a local file which will be copied. 144 | * // 145 | * "remote": false, // OPTIONAL 146 | * 147 | * // If not specified, this file will only be loaded once, and cached inside 148 | * // localStorage until this value is changed. You can specify: 149 | * // 150 | * // - "delta" to enable over-the-air delta update for this file 151 | * // - "full" means full update will be made when this file changes 152 | * // 153 | * "update": "" // OPTIONAL 154 | * } 155 | */ 156 | "css": [ 157 | { 158 | // this entry uses an ant variable that is the calculated 159 | // value of the generated output css file for the app, 160 | // defined in .sencha/app/defaults.properties 161 | "path": "${build.out.css.path}", 162 | "bundle": true, 163 | "exclude": ["fashion"] 164 | } 165 | ], 166 | 167 | /** 168 | * This option is used to configure the dynamic loader. At present these options 169 | * are supported. 170 | * 171 | */ 172 | "loader": { 173 | // This property controls how the loader manages caching for requests: 174 | // 175 | // - true: allows requests to receive cached responses 176 | // - false: disable cached responses by adding a random "cache buster" 177 | // - other: a string (such as the build.timestamp shown here) to allow 178 | // requests to be cached for this build. 179 | // 180 | "cache": false, 181 | 182 | // When "cache" is not true, this value is the request parameter used 183 | // to control caching. 184 | // 185 | "cacheParam": "_dc" 186 | }, 187 | 188 | /** 189 | * Settings specific to production builds. 190 | */ 191 | "production": { 192 | "output": { 193 | "appCache": { 194 | "enable": true, 195 | "path": "cache.appcache" 196 | } 197 | }, 198 | "loader": { 199 | "cache": "${build.timestamp}" 200 | }, 201 | "cache": { 202 | "enable": true 203 | }, 204 | "compressor": { 205 | "type": "yui" 206 | } 207 | }, 208 | 209 | /** 210 | * Settings specific to testing builds. 211 | */ 212 | "testing": { 213 | }, 214 | 215 | /** 216 | * Settings specific to development builds. 217 | */ 218 | "development": { 219 | "watch": { 220 | "delay": 250 221 | } 222 | }, 223 | 224 | /** 225 | * Controls the output structure of development-mode (bootstrap) artifacts. May 226 | * be specified by a string: 227 | * 228 | * "bootstrap": "${app.dir}" 229 | * 230 | * This will adjust the base path for all bootstrap objects, or expanded into object 231 | * form: 232 | * 233 | * "bootstrap": { 234 | * "base": "${app.dir}, 235 | * "manifest": "bootstrap.json", 236 | * "microloader": "bootstrap.js", 237 | * "css": "bootstrap.css" 238 | * } 239 | * 240 | * You can optionally exclude entries from the manifest. For example, to exclude 241 | * the "loadOrder" (to help development load approximate a build) you can add: 242 | * 243 | * "bootstrap": { 244 | * "manifest": { 245 | * "path": "bootstrap.json", 246 | * "exclude": "loadOrder" 247 | * } 248 | * } 249 | * 250 | */ 251 | "bootstrap": { 252 | "base": "${app.dir}", 253 | 254 | "microloader": "bootstrap.js", 255 | "css": "bootstrap.css" 256 | }, 257 | 258 | /** 259 | * Controls the output directory for build resources. May be set with 260 | * either a string: 261 | * 262 | * "${workspace.build.dir}/${build.environment}/${app.name}" 263 | * 264 | * or an object containing values for various types of build artifacts: 265 | * 266 | * { 267 | * "base": "${workspace.build.dir}/${build.environment}/${app.name}", 268 | * "page": { 269 | * "path": "../index.html", 270 | * "enable": false 271 | * }, 272 | * "css": "${app.output.resources}/${app.name}-all.css", 273 | * "js": "app.js", 274 | * "microloader": { 275 | * "path": "microloader.js", 276 | * "embed": true, 277 | * "enable": true 278 | * }, 279 | * "manifest": { 280 | * "path": "app.json", 281 | * "embed": false, 282 | * "enable": "${app.output.microloader.enable}" 283 | * }, 284 | * "resources": "resources", 285 | * "slicer": { 286 | * "path": "${app.output.resources}/images", 287 | * "enable": false 288 | * }, 289 | * // Setting the "enable" property of this object to a Truthy value will cause a Application Cache 290 | * // manifest file to be generated based on this files appCache object. This file will then be injected 291 | * // into the index.html file of the built application 292 | * "appCache":{ 293 | * "enable": false" 294 | * } 295 | * } 296 | * 297 | */ 298 | "output": { 299 | "base": "${workspace.build.dir}/${build.environment}/${app.name}", 300 | "appCache": { 301 | "enable": false 302 | } 303 | }, 304 | 305 | /** 306 | * Controls for localStorage caching 307 | * "cache": { 308 | * // This property controls whether localStorage caching of this manifest file is on or off. 309 | * // if disabled no deltas will be generated during a build and full updates will be disabled 310 | * "enable": false, 311 | * 312 | * // This property allows for global toggle of deltas. 313 | * // If set to a string the value will be used as the path to where deltas will be generated relative to you build. 314 | * // If set to a Truthy Value the default path ok "deltas" will be used 315 | * // If set to a Falsey value or if this property is not present deltas will be disabled and not generated. 316 | * 317 | * "deltas": "deltas" 318 | * } 319 | */ 320 | "cache": { 321 | "enable": false, 322 | "deltas": true 323 | }, 324 | 325 | /** 326 | * Used to automatically generate cache.manifest (HTML 5 application cache manifest) 327 | * file when you build. 328 | */ 329 | "appCache": { 330 | /** 331 | * List of items in the CACHE MANIFEST section 332 | */ 333 | "cache": [ 334 | "index.html" 335 | ], 336 | /** 337 | * List of items in the NETWORK section 338 | */ 339 | "network": [ 340 | "*" 341 | ], 342 | /** 343 | * List of items in the FALLBACK section 344 | */ 345 | "fallback": [] 346 | }, 347 | 348 | /** 349 | * Extra resources to be copied into the resource folder as specified in the "resources" 350 | * property of the "output" object. Folders specified in this list will be deeply copied. 351 | */ 352 | "resources": [ 353 | { 354 | "path": "resources", 355 | "output": "shared" 356 | } 357 | ], 358 | 359 | /** 360 | * Directory path to store all previous production builds. Note that the content 361 | * generated inside this directory must be kept intact for proper generation of 362 | * deltas between updates. 363 | */ 364 | "archivePath": "archive", 365 | 366 | "slicer": null, 367 | 368 | /** 369 | * File / directory name patttern to ignore when copying to the builds. Must be a 370 | * valid regular expression. 371 | */ 372 | "ignore": [ 373 | "(^|/)CVS(/?$|/.*?$)" 374 | ], 375 | 376 | /** 377 | * Uniquely generated id for this application, used as prefix for localStorage keys. 378 | * Normally you should never change this value. 379 | */ 380 | "id": "cd7eba1e-e099-4eab-aeef-b0f2e538b8a6", 381 | 382 | "progressive": { 383 | "manifest": { 384 | "name": "Sencha", 385 | "short_name": "Sencha Employee Directory", 386 | "icons": [{ 387 | "src": "resources/icon-small.png", 388 | "sizes": "96x96" 389 | }, { 390 | "src": "resources/icon-medium.png", 391 | "sizes": "192x192" 392 | }, { 393 | "src": "resources/icon-large.png", 394 | "sizes": "256x256" 395 | }], 396 | "theme_color": "#054059", 397 | "background_color": "#054059", 398 | "display": "standalone", 399 | "orientation": "portrait", 400 | "start_url": "/index.html" 401 | } 402 | } 403 | } 404 | -------------------------------------------------------------------------------- /client/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('PWA.Application', { 7 | extend: 'Ext.app.Application', 8 | name: 'PWA', 9 | 10 | defaultToken: 'home', 11 | 12 | router: { 13 | hashbang: true 14 | }, 15 | 16 | profiles: [ 17 | 'Phone', 18 | 'Tablet' 19 | ], 20 | 21 | onAppUpdate: function () { 22 | Ext.Msg.confirm('Application Update', 'This application has an update, reload?', 23 | function (choice) { 24 | if (choice === 'yes') { 25 | window.location.reload(); 26 | } 27 | } 28 | ); 29 | } 30 | }); 31 | -------------------------------------------------------------------------------- /client/app/Application.scss: -------------------------------------------------------------------------------- 1 | $panel-header-color: $panel-body-color; 2 | //$panel-header-background-color: contrast-color($panel-body-background-color, -5%); 3 | $panel-header-border-width: 0; 4 | $panel-header-font-weight: 400; 5 | 6 | // Application specific variables 7 | $picture-border-radius: dynamic(50%); 8 | $blocks-max-width: dynamic(1024px); 9 | $blocks-spacing: dynamic(1em); 10 | 11 | body.launching { 12 | background-color: white; 13 | } 14 | 15 | body.launching #appLoadingIndicator { 16 | display: block; 17 | } 18 | 19 | #appLoadingIndicator { 20 | display: none; 21 | position : absolute; 22 | top : 50%; 23 | text-align : center; 24 | width : 98%; 25 | height : 30px; 26 | } 27 | 28 | #appLoadingIndicator > * { 29 | background-color : #1565C0; 30 | display : inline-block; 31 | height : 24px; 32 | margin : 8px; 33 | width : 24px; 34 | 35 | -webkit-animation-name : bounce; 36 | -webkit-animation-duration : 0.6s; 37 | -webkit-animation-iteration-count : infinite; 38 | -webkit-animation-direction : normal; 39 | -webkit-border-radius : 16px; 40 | 41 | border-radius : 16px; 42 | } 43 | 44 | #appLoadingIndicator > div:first-child { 45 | -webkit-animation-delay : 0.1s; 46 | } 47 | 48 | #appLoadingIndicator > div:nth-child(2) { 49 | -webkit-animation-delay : 0.2s; 50 | } 51 | 52 | #appLoadingIndicator > div:last-child { 53 | -webkit-animation-delay : 0.3s; 54 | } 55 | 56 | @-webkit-keyframes bounce { 57 | 0% { 58 | } 59 | 60 | 50% { 61 | background-color : #fff; 62 | } 63 | 64 | 100% { 65 | } 66 | } 67 | 68 | @mixin action-ui($ui, $background-color, $color) { 69 | $ui-suffix: ui-suffix($ui); 70 | 71 | .action#{$ui-suffix} { 72 | background-color: $background-color; 73 | color: $color; 74 | } 75 | 76 | .action#{$ui-suffix}-flat { 77 | color: $background-color; 78 | } 79 | 80 | @include button-ui( 81 | $ui: action#{$ui-suffix}, 82 | $background-color: $background-color, 83 | $color: $color, 84 | $border-radius: 25em, 85 | $icon-size: 1.25em, 86 | $icon-size-big: 1.5em, 87 | $icon-font-size: 1.35em, 88 | $icon-font-size-big: 1.5em, 89 | $padding: 0.75em, 90 | $padding-big: 0.8em 91 | ); 92 | } 93 | 94 | @include action-ui($ui: 'phone', $color: white, $background-color: #20C659); 95 | @include action-ui($ui: 'skype', $color: white, $background-color: #00AFF0); 96 | @include action-ui($ui: 'linkedin', $color: white, $background-color: #0077B5); 97 | @include action-ui($ui: 'email', $color: white, $background-color: #428C8A); 98 | @include action-ui($ui: 'profile', $color: white, $background-color: #89C8AE); 99 | @include action-ui($ui: 'remove', $color: white, $background-color: #FF1540); 100 | @include action-ui($ui: 'edit', $color: black, $background-color: #FFCC33); 101 | 102 | .picture { 103 | @include border-radius(50%); 104 | @include background-size(cover); 105 | background-color: $neutral-color; 106 | background-repeat: no-repeat; 107 | background-position: center; 108 | } 109 | 110 | .picture { 111 | height: 38px; 112 | width: 38px; 113 | 114 | &.large { 115 | height: 48px; 116 | width: 48px; 117 | } 118 | } 119 | 120 | .blocks { 121 | margin: 0 auto; 122 | max-width: $blocks-max-width; 123 | position: relative; 124 | 125 | .tablet-profile & { 126 | padding: $blocks-spacing/2; 127 | 128 | .x-panel-block { 129 | margin: $blocks-spacing/2; 130 | } 131 | 132 | > .x-inner { 133 | display: flex; 134 | flex-direction: row; 135 | 136 | > .blocks-column:nth-child(1) { 137 | flex: 1 1 0; 138 | } 139 | 140 | > .blocks-column:nth-child(2) { 141 | width: 35%; 142 | 143 | @media screen and (max-width: 800px) { 144 | width: 45%; 145 | } 146 | @media screen and (max-width: 600px) { 147 | width: 100% 148 | } 149 | } 150 | 151 | @media screen and (max-width: 600px) { 152 | flex-direction: column; 153 | } 154 | } 155 | } 156 | 157 | .phone-profile & { 158 | padding: $blocks-spacing/2; 159 | 160 | .x-panel-block { 161 | margin: $blocks-spacing/2; 162 | } 163 | } 164 | } 165 | 166 | .block-section { 167 | display: inline-block; 168 | vertical-align: top; 169 | line-height: 1.5em; 170 | padding: 0.5em; 171 | 172 | .item { 173 | padding: 0.5em; 174 | 175 | .value, 176 | .extra { 177 | display: inline-block; 178 | } 179 | 180 | .label { 181 | color: lighten($color, 20%); 182 | font-weight: 100; 183 | font-size: 0.9em; 184 | text-transform: uppercase; 185 | } 186 | 187 | .extra { 188 | font-weight: bold; 189 | margin-left: 0.5em; 190 | } 191 | } 192 | 193 | .phone-profile & { 194 | font-size: 0.9em; 195 | } 196 | } 197 | 198 | @include panel-ui( 199 | $ui: 'block', 200 | $body-background-color: $neutral-light-color, 201 | $header-background-color: $neutral-light-color, 202 | $header-color: $color, 203 | $header-font-weight: 100, 204 | $header-icon-size: 2em, 205 | $header-icon-size-big: 2em, 206 | $header-icon-font-size: 1em, 207 | $header-icon-font-size-big: 1.35em, 208 | $header-font-size: 1.4em, 209 | $header-font-size-big: 1.25em, 210 | $header-line-height: 1em, 211 | $header-line-height-big: 1em 212 | ); 213 | 214 | @include panel-ui( 215 | $ui: 'dark-header', 216 | $header-background-color: #444444, 217 | $header-color: $neutral-light-color 218 | ); 219 | -------------------------------------------------------------------------------- /client/app/Readme.md: -------------------------------------------------------------------------------- 1 | # ./controller 2 | 3 | This folder contains the application's global controllers. ViewControllers are located 4 | alongside their respective view class in `"./view"`. These controllers are used for routing 5 | and other activities that span all views. 6 | 7 | # ./model 8 | 9 | This folder contains the application's (data) Model classes. 10 | 11 | # ./view 12 | 13 | This folder contains the views as well as ViewModels and ViewControllers depending on the 14 | application's architecture. Pure MVC applications may not have ViewModels, for example. 15 | The following organization is recommended: 16 | 17 | ./view/ 18 | foo/ # Some meaningful grouping of one or more views 19 | Foo.js # The view class 20 | Foo.scss # The styling for view class 21 | FooController.js # The controller for Foo (a ViewController) 22 | FooModel.js # The ViewModel for Foo 23 | 24 | This structure helps keep these closely related classes together and easily identifiable in 25 | most tabbed IDE's or text editors. 26 | 27 | # ./store 28 | 29 | This folder contains any number of store instances or types that can then be reused in the 30 | application. 31 | -------------------------------------------------------------------------------- /client/app/model/Person.js: -------------------------------------------------------------------------------- 1 | Ext.define('PWA.model.Person', { 2 | extend: 'Ext.data.Model', 3 | 4 | fields: [ 5 | { name: 'id', type: 'string' }, 6 | { name: 'username', type: 'string' }, 7 | { name: 'firstname', type: 'string' }, 8 | { name: 'lastname', type: 'string' }, 9 | { name: 'email', type: 'string' }, 10 | { name: 'skype', type: 'string' }, 11 | { name: 'linkedin', type: 'string' }, 12 | { name: 'phone', type: 'string' }, 13 | { name: 'extension', type: 'string' }, 14 | { name: 'birthday', type: 'date', dateFormat: 'Y-m-d' }, 15 | { name: 'title', type: 'string' }, 16 | 17 | { name: 'picture', type: 'string' }, 18 | { name: 'started', type: 'date', dateFormat: 'Y-m-d' }, 19 | { name: 'ended', type: 'date', dateFormat: 'Y-m-d' }, 20 | { name: 'office_id', reference: 'Office' }, 21 | { name: 'organization_id', reference: 'Organization' }, 22 | 23 | // Calculated fields 24 | { 25 | name: 'fullname', 26 | calculate: function (data) { 27 | return data.firstname + ' ' + data.lastname; 28 | } 29 | } 30 | ] 31 | }); 32 | -------------------------------------------------------------------------------- /client/app/model/Readme.md: -------------------------------------------------------------------------------- 1 | This folder contains the Models for this application. 2 | -------------------------------------------------------------------------------- /client/app/profile/Phone.js: -------------------------------------------------------------------------------- 1 | Ext.define('PWA.profile.Phone', { 2 | extend: 'Ext.app.Profile', 3 | 4 | isActive: function () { 5 | return Ext.platformTags.phone; 6 | }, 7 | 8 | launch: function () { 9 | // Add a class to the body el to identify the phone profile so we can 10 | // override CSS styles easily. The framework adds x-phone so we could 11 | // use it but this way the app controls a class that is always present 12 | // when this profile isActive, regardless of the actual device type. 13 | Ext.getBody().addCls('phone-profile'); 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /client/app/profile/Tablet.js: -------------------------------------------------------------------------------- 1 | Ext.define('PWA.profile.Tablet', { 2 | extend: 'Ext.app.Profile', 3 | 4 | isActive: function () { 5 | return !Ext.platformTags.phone; 6 | }, 7 | 8 | launch: function () { 9 | // Add a class to the body el to identify the phone profile so we can 10 | // override CSS styles easily. The framework adds x-phone so we could 11 | // use it but this way the app controls a class that is always present 12 | // when this profile isActive, regardless of the actual device type. 13 | Ext.getBody().addCls('tablet-profile'); 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /client/app/store/Personnel.js: -------------------------------------------------------------------------------- 1 | Ext.define('PWA.store.Personnel', { 2 | extend: 'Ext.data.Store', 3 | alias: 'store.personnel', 4 | 5 | model: 'PWA.model.Person', 6 | 7 | proxy: { 8 | type: 'ajax', 9 | 10 | // @sw-cache { urlPattern: "\\/portraits\\/.*", handler: "networkFirst", options: { cache: { name: "images", maxEntries: 100 } } } 11 | // @sw-cache { handler: "networkFirst", options: { cache: { name: "api" } } } 12 | url: '/personnel.json', 13 | 14 | reader: { 15 | type: 'json' 16 | } 17 | }, 18 | 19 | grouper: { 20 | groupFn: function(record) { 21 | return record.get('lastname')[0]; 22 | } 23 | }, 24 | 25 | sorters: [{ 26 | property: 'lastname' 27 | }, { 28 | property: 'firstname' 29 | }] 30 | }); 31 | -------------------------------------------------------------------------------- /client/app/store/Readme.md: -------------------------------------------------------------------------------- 1 | This folder contains store instances (identified by storeId) and store types 2 | (with "store.foo" aliases). 3 | -------------------------------------------------------------------------------- /client/app/view/main/List.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This view is an example list of people. 3 | */ 4 | Ext.define('PWA.view.main.List', { 5 | extend: 'Ext.dataview.List', 6 | xtype: 'mainlist', 7 | 8 | requires: [ 9 | 'Ext.plugin.PullRefresh' 10 | ], 11 | 12 | bind: '{personnel}', 13 | cls: 'home-events', 14 | grouped: true, 15 | infinite: true, 16 | loadingText: '', 17 | 18 | indexBar: { 19 | platformConfigs: { 20 | desktop: { 21 | autoHide: true 22 | }, 23 | '!desktop': { 24 | autoHide: false 25 | } 26 | } 27 | }, 28 | 29 | plugins: { 30 | pullrefresh: { 31 | pullText: 'Pull down to refresh' 32 | } 33 | }, 34 | 35 | itemConfig: { 36 | ui: 'cards', 37 | header: { 38 | ui: 'cards' 39 | } 40 | }, 41 | 42 | listeners: { 43 | itemtap: 'onItemSelected' 44 | }, 45 | 46 | itemTpl: '
' + 47 | '
' + 48 | '
' + 49 | '
' + 50 | '
{firstname} {lastname}
' + 51 | '
{title}
' + 52 | '
' + 53 | '
' + 54 | '
' 55 | }); 56 | -------------------------------------------------------------------------------- /client/app/view/main/List.scss: -------------------------------------------------------------------------------- 1 | @include itemheader-ui( 2 | $ui: 'cards', 3 | $background-color: transparent, 4 | $font-size: 1.4em, 5 | $font-size-big: 1.4em 6 | ); 7 | 8 | @include listitem-ui( 9 | $ui: 'cards', 10 | $border-style: none, 11 | $background-color: transparent, 12 | $hovered-background-color: transparent, 13 | $pressed-background-color: transparent, 14 | $selected-background-color: transparent, 15 | $padding: 0, 16 | $padding-big: 0 17 | ); 18 | 19 | .home-events { 20 | .x-listitem-cards { 21 | padding: 0.5em; 22 | 23 | > .x-listitem-body-el { 24 | background-color: $neutral-light-color; 25 | } 26 | 27 | .tablet-profile & { 28 | @media screen and (max-width: 800px) { 29 | width: 100% 30 | } 31 | } 32 | 33 | .phone-profile.x-portrait & { 34 | width: 100%; 35 | } 36 | 37 | .badge { 38 | @include border-radius(4em); 39 | background-color: $neutral-highlight-color; 40 | color: $neutral-dark-color; 41 | display: inline-block; 42 | font-size: 0.9em; 43 | margin: 1em 0 0 1em; 44 | padding: 0.45em 1.2em; 45 | 46 | .date, .title { 47 | display: inline-block; 48 | } 49 | 50 | .date { 51 | font-weight: bold; 52 | } 53 | 54 | .title { 55 | &:before { 56 | content: '|'; 57 | margin: 0 0.5em 58 | } 59 | } 60 | 61 | &.event-birthday { 62 | background-color: $base-light-color; 63 | color: $base-dark-color; 64 | } 65 | 66 | &.event-ended { 67 | background-color: $neutral-light-color; 68 | border: 1px solid $neutral-color; 69 | color: $neutral-dark-color; 70 | } 71 | } 72 | 73 | .content { 74 | display: flex; 75 | align-items: stretch; 76 | flex-direction: row; 77 | padding: 1.15em; 78 | } 79 | 80 | .picture { 81 | margin-right: 1em; 82 | } 83 | 84 | .event-title { 85 | color: $base-color; 86 | } 87 | 88 | .person-name, 89 | .person-title { 90 | @include ellipsis; 91 | } 92 | 93 | .person-name { 94 | font-size: 1.1em; 95 | font-weight: bold; 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /client/app/view/main/Main.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This class is the main view for the application. It is specified in app.js as the 3 | * "mainView" property. 4 | */ 5 | Ext.define('PWA.view.main.Main', { 6 | extend: 'Ext.Panel', 7 | xtype: 'app-main', 8 | 9 | requires: [ 10 | 'Ext.MessageBox', 11 | 'Ext.field.Text', 12 | 'PWA.view.main.List', 13 | 'PWA.view.main.MainController', 14 | 'PWA.view.main.MainModel' 15 | ], 16 | 17 | controller: 'main', 18 | viewModel: 'main', 19 | 20 | layout: { 21 | type: 'card', 22 | animation: { 23 | type: 'slide' 24 | } 25 | }, 26 | 27 | header: { 28 | ui: 'dark-header', 29 | title: { 30 | bind: { 31 | margin: '{title === "Profile" ? "0 0 0 5" : "0 0 0 20"}' 32 | } 33 | }, 34 | items: [{ 35 | xtype: 'button', 36 | ui: 'dark flat large', 37 | docked: 'left', 38 | iconCls: 'x-fa fa-chevron-left', 39 | handler: 'onBackTap', 40 | hidden: true, 41 | bind: { 42 | hidden: '{title !== "Profile"}' 43 | } 44 | }] 45 | }, 46 | 47 | bind: { 48 | title: '{title}' 49 | }, 50 | 51 | items: [{ 52 | docked: 'top', 53 | style: 'padding: 10px; background-color: red; color: white', 54 | xtype: 'component', 55 | html: 'OFFLINE MODE', 56 | hidden: true, 57 | bind: { 58 | hidden: '{online}' 59 | } 60 | }, { 61 | xtype: 'mainlist', 62 | reference: 'list' 63 | }, { 64 | xtype: 'person', 65 | reference: 'person' 66 | }] 67 | }); 68 | -------------------------------------------------------------------------------- /client/app/view/main/MainController.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This class is the controller for the main view for the application. It is specified as 3 | * the "controller" of the Main view class. 4 | */ 5 | Ext.define('PWA.view.main.MainController', { 6 | extend: 'Ext.app.ViewController', 7 | 8 | alias: 'controller.main', 9 | 10 | requires: [ 11 | 'Ext.data.Store', 12 | 'Ext.data.proxy.Ajax', 13 | 'PWA.view.person.Person', 14 | 'PWA.model.Person' 15 | ], 16 | 17 | listen: { 18 | controller: { 19 | '*': { 20 | 'home': 'showList' 21 | } 22 | } 23 | }, 24 | 25 | routes: { 26 | 'home': 'showList', 27 | 'person/:id': { 28 | before: 'waitForStore', 29 | action: 'showPerson' 30 | } 31 | }, 32 | 33 | initViewModel: function() { 34 | Ext.getWin().on({ 35 | scope: this, 36 | offline: 'onOffline', 37 | online: 'onOnline' 38 | }); 39 | }, 40 | 41 | onOffline: function () { 42 | var vm = this.getViewModel(); 43 | 44 | vm.set('online', false); 45 | }, 46 | 47 | onOnline: function () { 48 | var vm = this.getViewModel(); 49 | 50 | vm.set('online', true); 51 | 52 | vm.get('personnel').reload(); 53 | }, 54 | 55 | onItemSelected: function (sender, index, target, record) { 56 | this.redirectTo('person/' + record.getId()); 57 | }, 58 | 59 | waitForStore: function () { 60 | var view = this.getView(), 61 | vm = view.getViewModel(), 62 | store = vm.get('personnel'); 63 | 64 | return new Ext.Promise(function (resolve, reject) { 65 | if (store.isLoaded()) { 66 | resolve(); 67 | } else { 68 | store.on('load', resolve, this, { single: true }); 69 | } 70 | }); 71 | }, 72 | 73 | showPerson: function(id) { 74 | var view = this.getView(), 75 | list = this.lookup('person'), 76 | viewVm = view.getViewModel(), 77 | personVm = list.getViewModel(), 78 | store = viewVm.get('personnel'), 79 | record = store.getById(id); 80 | 81 | viewVm.set({ 82 | title: 'Profile' 83 | }); 84 | 85 | personVm.set({ 86 | record: Ext.create('PWA.model.Person', record.data) 87 | }); 88 | 89 | view.setActiveItem(list); 90 | }, 91 | 92 | showList: function() { 93 | var view = this.getView(), 94 | vm = view.getViewModel(); 95 | 96 | vm.set({ 97 | title: 'Employee Directory' 98 | }); 99 | 100 | view.setActiveItem(0); 101 | }, 102 | 103 | onBackTap: function() { 104 | this.redirectTo(-1); 105 | }, 106 | }); 107 | -------------------------------------------------------------------------------- /client/app/view/main/MainModel.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This class is the view model for the Main view of the application. 3 | */ 4 | Ext.define('PWA.view.main.MainModel', { 5 | extend: 'Ext.app.ViewModel', 6 | 7 | alias: 'viewmodel.main', 8 | 9 | requires: [ 10 | 'PWA.store.Personnel' 11 | ], 12 | 13 | data: { 14 | name: 'PWA', 15 | online: navigator.onLine, 16 | loremIpsum: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.', 17 | title: 'Employee Directory' 18 | }, 19 | 20 | stores: { 21 | personnel: { 22 | type: 'personnel', 23 | autoLoad: true 24 | } 25 | } 26 | }); 27 | -------------------------------------------------------------------------------- /client/app/view/person/Details.js: -------------------------------------------------------------------------------- 1 | Ext.define('PWA.view.person.Details', { 2 | xtype: 'person-details', 3 | extend: 'Ext.Panel', 4 | cls: 'person-details', 5 | title: 'Details', 6 | 7 | tpl: [ 8 | '
', 9 | '
', 10 | '
Username
', 11 | '
{username}
', 12 | '
', 13 | '', 14 | '
', 15 | '
Phone
', 16 | '
{phone}
', 17 | '
', 18 | '
', 19 | '', 20 | '
', 21 | '
Extension
', 22 | '
{extension}
', 23 | '
', 24 | '
', 25 | '
', 26 | '
', 27 | '
', 28 | '
Email
', 29 | '
{email}
', 30 | '
', 31 | '', 32 | '
', 33 | '
Skype
', 34 | '
{skype}
', 35 | '
', 36 | '
', 37 | '', 38 | '
', 39 | '
LinkedIn
', 40 | '
{linkedin}
', 41 | '
', 42 | '
', 43 | '
', 44 | '
', 45 | '
', 46 | '
Birthday
', 47 | '
{birthday:date("F jS, Y")}
', 48 | '
({birthday:dateDiff(new Date())})
', 49 | '
', 50 | '
', 51 | '
Entry Date
', 52 | '
{started:date("F jS, Y")}
', 53 | '', 54 | '
({started:dateDiff(new Date())})
', 55 | '
', 56 | '
', 57 | '', 58 | '
', 59 | '
Exit Date
', 60 | '
{ended:date("F jS, Y")}
', 61 | '
({started:dateDiff(values.ended)})
', 62 | '
', 63 | '
', 64 | '
' 65 | ] 66 | }); 67 | -------------------------------------------------------------------------------- /client/app/view/person/Header.js: -------------------------------------------------------------------------------- 1 | Ext.define('PWA.view.person.Header', { 2 | extend: 'Ext.Container', 3 | xtype: 'person-header', 4 | 5 | requires: [ 6 | 'Ext.Image' 7 | ], 8 | 9 | cls: 'person-header', 10 | 11 | items: [{ 12 | xtype: 'image', 13 | userCls: 'picture', 14 | bind: { 15 | src: '{record.picture}' 16 | } 17 | }, { 18 | xtype: 'component', 19 | userCls: 'person-info', 20 | tpl: [ 21 | '
{firstname} {lastname}
', 22 | '
{title}
' 23 | ], 24 | bind: { 25 | record: '{record}' 26 | } 27 | }, { 28 | xtype: 'container', 29 | userCls: 'person-tools', 30 | defaultType: 'button', 31 | layout: 'hbox', 32 | items: [{ 33 | iconCls: 'x-fa fa-phone', 34 | handler: 'onCallTap', 35 | ui: 'action-phone', 36 | bind: { 37 | tooltip: 'Call {record.phone}' 38 | } 39 | },{ 40 | iconCls: 'x-fa fa-skype', 41 | handler: 'onSkypeTap', 42 | ui: 'action-skype', 43 | bind: { 44 | tooltip: 'Skype with {record.skype}' 45 | } 46 | },{ 47 | iconCls: 'x-fa fa-envelope', 48 | handler: 'onEmailTap', 49 | ui: 'action-email', 50 | bind: { 51 | tooltip: 'Send email to {record.email}' 52 | } 53 | },{ 54 | iconCls: 'x-fa fa-linkedin', 55 | handler: 'onLinkedInTap', 56 | ui: 'action-linkedin', 57 | bind: { 58 | tooltip: 'See {record.linkedin} LinkedIn profile' 59 | } 60 | }] 61 | }, { 62 | xtype: 'component', 63 | userCls: 'person-extra', 64 | flex: 1, 65 | tpl: [ 66 | '
{office.city}
', 67 | '
11:00 pm
' //< TODO time 68 | ], 69 | bind: { 70 | record: '{record}' 71 | } 72 | }] 73 | }); 74 | -------------------------------------------------------------------------------- /client/app/view/person/Person.js: -------------------------------------------------------------------------------- 1 | Ext.define('PWA.view.person.Person', { 2 | extend: 'Ext.Container', 3 | xtype: 'person', 4 | 5 | requires: [ 6 | 'PWA.view.person.*' 7 | ], 8 | 9 | controller: 'person', 10 | 11 | viewModel: { 12 | type: 'person' 13 | }, 14 | 15 | cls: 'person', 16 | scrollable: true, 17 | 18 | items: [{ 19 | xtype: 'person-header' 20 | }, { 21 | xtype: 'person-details', 22 | ui: 'block', 23 | bind: { 24 | record: '{record}' 25 | } 26 | }], 27 | 28 | updateRecord: function(record) { 29 | this.getViewModel().set('record', record); 30 | } 31 | }); 32 | -------------------------------------------------------------------------------- /client/app/view/person/Person.scss: -------------------------------------------------------------------------------- 1 | $person-header-padding: 1em; 2 | $person-header-spacing: 1em; 3 | $person-header-picture-size: dynamic(150px); 4 | 5 | .person-header { 6 | overflow: auto; 7 | padding: $person-header-padding; 8 | position: relative; 9 | z-index: 1; 10 | 11 | > .x-inner { 12 | margin: auto; 13 | max-width: $blocks-max-width; 14 | padding: 0 $blocks-spacing; 15 | } 16 | 17 | .picture { 18 | @include single-box-shadow($hoff: 0, $voff: 4px, $spread: -2px); 19 | margin: 0 $person-header-spacing $person-header-spacing 0; 20 | border: 8px solid $panel-header-background-color; 21 | height: $person-header-picture-size; 22 | width: $person-header-picture-size; 23 | 24 | // decoration 25 | &:before { 26 | @include single-box-shadow; 27 | background: $panel-header-background-color; 28 | height: calc(#{$person-header-picture-size}*0.6 + #{$person-header-padding}); 29 | position: absolute; 30 | display: block; 31 | content: ''; 32 | left: 0; 33 | right: 0; 34 | top: 0; 35 | z-index: -1; 36 | } 37 | } 38 | 39 | .person-name, 40 | .person-title { 41 | @include ellipsis(); 42 | } 43 | 44 | .person-name { 45 | font-size: 1.4em; 46 | } 47 | 48 | .person-title { 49 | @include opacity(0.7); 50 | } 51 | 52 | .person-tools { 53 | display: inline-block; 54 | margin: 1em 0; 55 | 56 | .x-button { 57 | margin-right: 0.4em; 58 | } 59 | } 60 | 61 | .person-extra { 62 | @include border-radius; 63 | //background-color: contrasted($background-color, 4%); 64 | padding: 0.3em 0.6em; 65 | } 66 | 67 | .person-time, 68 | .person-city { 69 | @include opacity(0.7); 70 | display: inline-block; 71 | font-size: 0.85em; 72 | } 73 | 74 | .person-time::before { 75 | content: '|'; 76 | margin: 0 0.25em; 77 | } 78 | 79 | .person-city { 80 | font-weight: bold; 81 | } 82 | 83 | .tablet-profile & { 84 | font-size: 1.2em; 85 | 86 | .picture { 87 | float: left; 88 | } 89 | 90 | .person-info { 91 | display: table-cell; 92 | height: $person-header-picture-size*0.6; 93 | padding-bottom: $person-header-spacing; 94 | vertical-align: bottom; 95 | } 96 | 97 | .person-tools { 98 | float: left; 99 | } 100 | 101 | .person-extra { 102 | margin-top: $person-header-spacing; 103 | float: right; 104 | } 105 | } 106 | 107 | .phone-profile & { 108 | text-align: center; 109 | 110 | .picture { 111 | margin-left: auto; 112 | margin-right: auto; 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /client/app/view/person/PersonController.js: -------------------------------------------------------------------------------- 1 | Ext.define('PWA.view.person.PersonController', { 2 | extend: 'Ext.app.ViewController', 3 | alias: 'controller.person', 4 | 5 | onCallTap: function() { 6 | var vm = this.getViewModel(), 7 | record = vm.get('record'); 8 | 9 | location = 'tel:' + record.get('email'); 10 | }, 11 | 12 | onEmailTap: function() { 13 | var vm = this.getViewModel(), 14 | record = vm.get('record'); 15 | 16 | location = 'mailto:' + record.get('email'); 17 | }, 18 | 19 | onLinkedInTap: function() { 20 | var vm = this.getViewModel(), 21 | record = vm.get('record'); 22 | 23 | window.open('https://www.linkedin.com/in/' + record.get('linkedin'), '_blank'); 24 | }, 25 | 26 | onSkypeTap: function() { 27 | var vm = this.getViewModel(), 28 | record = vm.get('record'); 29 | 30 | location = 'skype:' + record.get('skype') + '?call'; 31 | } 32 | }) 33 | -------------------------------------------------------------------------------- /client/app/view/person/PersonModel.js: -------------------------------------------------------------------------------- 1 | Ext.define('PWA.view.person.PersonModel', { 2 | extend: 'Ext.app.ViewModel', 3 | alias: 'viewmodel.person', 4 | 5 | data: { 6 | record: null 7 | } 8 | }); 9 | -------------------------------------------------------------------------------- /client/build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 68 | 69 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /client/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | PWA 9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 |
17 |
18 |
19 |
20 | 21 | 22 | -------------------------------------------------------------------------------- /client/overrides/XTemplate.js: -------------------------------------------------------------------------------- 1 | Ext.define('App.overrides.XTemplate', { 2 | override: 'Ext.XTemplate', 3 | 4 | /** 5 | * [FIX] Don't convert the result to string if only one value, allowing, for 6 | * instance, to build ObjectTemplate with number properties and still be able 7 | * to use formatters (e.g. {value:round}). 8 | */ 9 | apply: function(values, parent, xindex, xcount) { 10 | var buffer = this.applyOut(values, [], parent, xindex, xcount); 11 | 12 | return buffer.length === 1 ? buffer[0] : buffer.join(''); 13 | } 14 | }); 15 | -------------------------------------------------------------------------------- /client/overrides/util/Format.js: -------------------------------------------------------------------------------- 1 | Ext.define('App.overrides.util.Format', { 2 | override: 'Ext.util.Format', 3 | 4 | dateDiff: function(v0, v1, unit) { 5 | var seconds, name, diff; 6 | 7 | if (!unit || unit == 'auto') { 8 | seconds = Math.floor((+v1 - v0)/1000); 9 | unit = 10 | seconds < 1 ? 'ms' : // 1 second 11 | seconds < 60 ? 's' : // 1 minute 12 | seconds < 3600 ? 'mi' : // 60 minutes 13 | seconds < 86400 ? 'h' : // 24 hours 14 | seconds < 604800 ? 'd' : // 7 days 15 | seconds < 2419200 ? 'w' : // 4 weeks 16 | seconds < 31622400 ? 'mo' : // 366 days 17 | 'y'; 18 | } 19 | 20 | switch (unit) { 21 | case 'ms': name = 'millisecond'; break; 22 | case 's': name = 'second'; break; 23 | case 'mi': name = 'minute'; break; 24 | case 'h': name = 'hour'; break; 25 | case 'd': name = 'day'; break; 26 | case 'w': name = 'week'; break; 27 | case 'mo': name = 'month'; break; 28 | case 'y': name = 'year'; break; 29 | default: 30 | } 31 | 32 | diff = Ext.Date.diff(v0, v1, unit); 33 | return Ext.util.Format.plural(diff, name); 34 | }, 35 | 36 | actionIconCls: function(type) { 37 | switch (type) { 38 | case 'profile': type = 'user'; break; 39 | case 'email': type = 'envelope'; break; 40 | default: 41 | } 42 | 43 | return 'fa fa-' + type; 44 | } 45 | }); 46 | -------------------------------------------------------------------------------- /client/overrides/util/XTemplateCompiler.js: -------------------------------------------------------------------------------- 1 | Ext.define('App.overrides.util.XTemplateCompiler', { 2 | override: 'Ext.util.XTemplateCompiler', 3 | 4 | /** 5 | * [OPTIM/FIX] XTemplate::apply calls join('') which already coerce values to string, 6 | * but also preserve the input type when working on only one token. 7 | */ 8 | doExpr: function (expr) { 9 | var out = this.body; 10 | 11 | out.push('if ((v=' + expr + ') != null) out'); 12 | 13 | if (this.useIndex) { 14 | out.push('[out.length]=v\n'); 15 | } else { 16 | out.push('.push(v)\n'); 17 | } 18 | } 19 | }); 20 | -------------------------------------------------------------------------------- /client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pwa", 3 | "version": "1.0.0", 4 | "description": "This folder is primarily a container for the top-level pieces of the application. While you can remove some files and folders that this application does not use, be sure to read below before deciding what can be deleted and what needs to be kept in source control.", 5 | "main": "app.js", 6 | "scripts": { 7 | "start": "webpack-dev-server --content-base build/production/PWA --host 0.0.0.0 & sencha app build", 8 | "precache": "pushd build/production/PWA; sw-precache --verbose --config=../../../sw-precache-config.json; popd;", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "author": "", 12 | "license": "ISC", 13 | "devDependencies": { 14 | "gulp": "^3.9.1", 15 | "webpack": "^1.13.2", 16 | "webpack-dev-server": "^1.16.2" 17 | }, 18 | "dependencies": { 19 | "escape-string-regexp": "^1.0.5", 20 | "express": "^4.14.0", 21 | "minimist": "^1.2.0", 22 | "sw-precache": "^4.1.0" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /client/resources/icon-large.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/client/resources/icon-large.png -------------------------------------------------------------------------------- /client/resources/icon-medium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/client/resources/icon-medium.png -------------------------------------------------------------------------------- /client/resources/icon-small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/client/resources/icon-small.png -------------------------------------------------------------------------------- /client/resources/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "lang": "en", 3 | "name": "PWA", 4 | "short_name": "PWA", 5 | "description": "Ext JS PWA Test", 6 | "icons": [{ 7 | "src": "icon-small.png", 8 | "sizes": "96x96" 9 | }, { 10 | "src": "icon-normal.png", 11 | "sizes": "192x192" 12 | }, { 13 | "src": "icon-medium.png", 14 | "sizes": "256x256" 15 | }], 16 | "splash_screens": [{ 17 | "src": "splash.png", 18 | "sizes": "600x800" 19 | }], 20 | "theme_color": "#2ebd59", 21 | "background_color": "#000", 22 | "display": "fullscreen", 23 | "orientation": "portrait", 24 | "start_url": "../index.html" 25 | } -------------------------------------------------------------------------------- /client/resources/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/client/resources/splash.png -------------------------------------------------------------------------------- /client/workspace.json: -------------------------------------------------------------------------------- 1 | { 2 | /** 3 | * An object containing key value pair framework descriptors. 4 | * 5 | * The value can be a string or an object containing at least one of "dir" or "pkg", 6 | * where "dir" can be a filesystem path to the framework sources and "pkg" can be a 7 | * package name. For example: 8 | * 9 | * "frameworks": { 10 | * 11 | * "ext-x": "/absolute/path/to/ext", 12 | * "ext-y": { 13 | * "source": "../relative/path/to/ext", 14 | * "path": "ext" 15 | * }, 16 | * "ext-z": { 17 | * "package": "ext@n.n.n", 18 | * "path": "ext-n.n.n" 19 | * }, 20 | * "touch": "touch" 21 | * } 22 | * 23 | */ 24 | "frameworks": { 25 | "ext": { 26 | "path":"ext", 27 | "version":"7.0.0" 28 | } 29 | 30 | 31 | }, 32 | 33 | /** 34 | * This is the folder for build outputs in the workspace. 35 | */ 36 | "build": { 37 | "dir": "${workspace.dir}/build" 38 | }, 39 | 40 | /** 41 | * These configs determine where packages are generated and extracted to (when downloaded). 42 | */ 43 | "packages": { 44 | /** 45 | * This folder contains all local packages. 46 | * If a comma-separated string is used as value the first path will be used as the path to generate new packages. 47 | */ 48 | "dir": "${workspace.dir}/packages/local,${workspace.dir}/packages", 49 | 50 | /** 51 | * This folder contains all extracted (remote) packages. 52 | */ 53 | "extract": "${workspace.dir}/packages/remote" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /notes.txt: -------------------------------------------------------------------------------- 1 | "progressive": { 2 | "manifest": { 3 | "name": "Sencha", 4 | "short_name": "Sencha Employee Directory", 5 | "icons": [{ 6 | "src": "resources/icon-small.png", 7 | "sizes": "96x96" 8 | }, { 9 | "src": "resources/icon-medium.png", 10 | "sizes": "192x192" 11 | }, { 12 | "src": "resources/icon-large.png", 13 | "sizes": "256x256" 14 | }], 15 | "theme_color": "#054059", 16 | "background_color": "#054059", 17 | "display": "standalone", 18 | "orientation": "portrait", 19 | "start_url": "/index.html" 20 | } 21 | }, 22 | 23 | // @sw-precache { urlPattern: "\\/portraits\\/.*", handler: "networkFirst", options: { cache: { name: "images", maxEntries: 100 } } } 24 | // @sw-precache { handler: "networkFirst", options: { cache: { name: "api" } } } 25 | -------------------------------------------------------------------------------- /server/.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | 3 | /certs/server* 4 | -------------------------------------------------------------------------------- /server/api/portraits/men/0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/0.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/1.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/10.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/11.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/12.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/13.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/14.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/15.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/16.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/17.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/18.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/19.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/2.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/20.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/21.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/22.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/23.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/24.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/25.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/25.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/26.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/26.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/27.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/27.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/28.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/28.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/29.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/29.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/3.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/30.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/30.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/31.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/31.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/32.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/32.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/33.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/33.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/34.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/34.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/35.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/35.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/36.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/36.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/37.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/37.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/38.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/38.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/39.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/39.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/4.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/40.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/40.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/41.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/41.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/42.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/42.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/43.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/43.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/44.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/44.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/45.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/45.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/46.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/46.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/47.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/47.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/48.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/48.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/49.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/49.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/5.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/50.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/50.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/51.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/51.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/52.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/52.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/53.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/53.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/54.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/54.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/55.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/55.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/56.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/56.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/57.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/57.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/58.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/58.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/59.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/59.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/6.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/60.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/60.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/61.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/61.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/62.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/62.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/63.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/63.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/64.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/64.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/65.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/65.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/66.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/66.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/67.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/67.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/68.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/68.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/69.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/69.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/7.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/70.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/70.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/71.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/71.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/72.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/72.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/73.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/73.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/74.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/74.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/75.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/75.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/76.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/76.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/77.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/77.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/78.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/78.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/79.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/79.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/8.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/80.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/80.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/81.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/81.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/82.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/82.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/83.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/83.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/84.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/84.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/85.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/85.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/86.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/86.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/87.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/87.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/88.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/88.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/89.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/89.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/9.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/90.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/90.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/91.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/91.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/92.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/92.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/93.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/93.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/94.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/94.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/95.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/95.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/96.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/96.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/97.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/97.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/98.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/98.jpg -------------------------------------------------------------------------------- /server/api/portraits/men/99.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/men/99.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/0.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/1.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/10.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/11.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/12.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/13.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/14.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/15.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/16.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/17.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/18.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/19.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/2.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/20.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/21.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/22.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/23.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/24.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/25.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/25.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/26.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/26.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/27.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/27.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/28.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/28.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/29.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/29.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/3.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/30.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/30.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/31.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/31.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/32.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/32.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/33.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/33.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/34.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/34.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/35.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/35.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/36.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/36.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/37.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/37.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/38.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/38.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/39.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/39.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/4.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/40.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/40.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/41.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/41.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/42.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/42.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/43.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/43.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/44.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/44.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/45.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/45.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/46.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/46.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/47.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/47.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/48.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/48.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/49.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/49.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/5.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/50.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/50.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/51.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/51.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/52.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/52.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/53.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/53.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/54.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/54.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/55.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/55.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/56.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/56.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/57.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/57.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/58.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/58.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/59.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/59.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/6.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/60.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/60.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/61.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/61.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/62.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/62.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/63.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/63.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/64.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/64.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/65.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/65.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/66.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/66.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/67.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/67.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/68.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/68.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/69.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/69.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/7.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/70.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/70.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/71.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/71.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/72.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/72.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/73.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/73.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/74.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/74.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/75.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/75.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/76.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/76.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/77.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/77.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/78.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/78.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/79.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/79.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/8.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/80.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/80.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/81.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/81.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/82.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/82.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/83.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/83.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/84.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/84.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/85.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/85.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/86.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/86.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/87.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/87.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/88.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/88.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/89.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/89.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/9.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/90.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/90.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/91.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/91.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/92.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/92.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/93.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/93.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/94.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/94.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/95.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/95.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/96.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/96.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/97.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/97.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/98.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/98.jpg -------------------------------------------------------------------------------- /server/api/portraits/women/99.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/api/portraits/women/99.jpg -------------------------------------------------------------------------------- /server/certs/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sencha-extjs-examples/PWA/2eb08a0cd55889f6824ce8bc1e1d381248f38b39/server/certs/.gitkeep -------------------------------------------------------------------------------- /server/index.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const path = require('path'); 3 | const fs = require('fs'); 4 | const https = require('https'); 5 | const certPath = path.join(__dirname, 'certs'); 6 | const ENV = process.env.ENV; 7 | const app = express(); 8 | const ports = { 9 | http: 8082, 10 | https: 8083 11 | }; 12 | 13 | let server; 14 | 15 | try { 16 | const crt = fs.readFileSync(path.join(certPath, 'server.crt')); 17 | const key = fs.readFileSync(path.join(certPath, 'server.key')); 18 | 19 | server = https.createServer({ 20 | cert: crt, 21 | key: key 22 | }, app); 23 | } catch (e) {} 24 | 25 | let clientPath = path.join(__dirname, '../client'); 26 | 27 | if (/^prod/i.test(ENV)) { 28 | clientPath = path.join(clientPath, '/build/production/PWA'); 29 | } else if (/^test/i.test(ENV)) { 30 | clientPath = path.join(clientPath, '/build/testing/PWA'); 31 | } 32 | 33 | app.use(express.static(path.join(__dirname, 'api'))); 34 | app.use(express.static(clientPath)); 35 | 36 | console.log(`Client app will be loaded from ${clientPath}`); 37 | 38 | app.listen(ports.http, () => { 39 | console.log(`Non-Secure Server listening on port ${ports.http}`); 40 | }); 41 | 42 | if (server) { 43 | server.listen(ports.https, () => { 44 | console.log(`Secure Server listening on port ${ports.https}`); 45 | }); 46 | } 47 | -------------------------------------------------------------------------------- /server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "sencha-pwa-server", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "ssl": "openssl req -nodes -x509 -newkey rsa:2048 -keyout certs/server.key -out certs/server.crt -days 365", 8 | "start": "node .", 9 | "test": "echo \"Error: no test specified\" && exit 1" 10 | }, 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "express": "^4.15.2" 15 | } 16 | } 17 | --------------------------------------------------------------------------------