├── src ├── assets │ ├── .gitkeep │ ├── images │ │ ├── logo.png │ │ ├── board │ │ │ ├── desk.png │ │ │ ├── sofa.png │ │ │ ├── carpet.png │ │ │ ├── chair.png │ │ │ ├── clock.png │ │ │ ├── couch.png │ │ │ ├── table.png │ │ │ ├── tvUnit.png │ │ │ ├── batteries.png │ │ │ ├── coffeeMug.png │ │ │ ├── deskPad.png │ │ │ ├── floorLamp.png │ │ │ ├── ovenDish.png │ │ │ ├── trashCan.png │ │ │ ├── nightstand.png │ │ │ ├── pencilCase.png │ │ │ ├── tapeMeasure.png │ │ │ ├── towelHanger.png │ │ │ ├── laptopSupport.png │ │ │ ├── magneticBoard.png │ │ │ ├── showerCurtain.png │ │ │ ├── soapDispenser.png │ │ │ └── tarpaulinRope.png │ │ └── onboarding │ │ │ ├── shadow_bg.png │ │ │ ├── slide3_lamp.png │ │ │ ├── slide4_cup.png │ │ │ ├── slide1_circle.png │ │ │ ├── slide1_pluses.png │ │ │ ├── slide1_roger.png │ │ │ ├── slide2_circle.png │ │ │ ├── slide2_pluses.png │ │ │ ├── slide3_circle.png │ │ │ ├── slide3_pluses.png │ │ │ ├── slide4_circle.png │ │ │ ├── slide4_pluses.png │ │ │ ├── onboarding_dots1.png │ │ │ ├── onboarding_dots2.png │ │ │ ├── onboarding_dots3.png │ │ │ ├── onboarding_dots4.png │ │ │ └── slide2_big_plus.png │ └── i18n │ │ ├── en.json │ │ └── jp.json ├── app │ ├── app.component.css │ ├── app.component.html │ ├── messages-service │ │ ├── messageTarget.ts │ │ ├── message.ts │ │ ├── messages.service.spec.ts │ │ └── messages.service.ts │ ├── app.component.ts │ ├── addorder │ │ ├── addorder.component.css │ │ ├── addorder.component.spec.ts │ │ ├── addorder.component.html │ │ └── addorder.component.ts │ ├── order │ │ ├── order.component.css │ │ ├── order.component.spec.ts │ │ ├── order.component.html │ │ └── order.component.ts │ ├── orders-service │ │ ├── orderStatus.ts │ │ ├── orders.service.spec.ts │ │ ├── order.ts │ │ ├── orders.service.ts │ │ └── orders-mock.ts │ ├── board │ │ ├── board.component.spec.ts │ │ ├── board.component.css │ │ ├── board.component.html │ │ └── board.component.ts │ ├── onboarding │ │ ├── onboarding.component.spec.ts │ │ ├── onboarding.component.css │ │ ├── onboarding.component.html │ │ └── onboarding.component.ts │ ├── app.component.spec.ts │ └── app.module.ts ├── favicon.ico ├── environments │ ├── environment.prod.ts │ └── environment.ts ├── typings.d.ts ├── styles.css ├── tsconfig.app.json ├── tsconfig.spec.json ├── main.ts ├── index.html ├── test.ts └── polyfills.ts ├── e2e ├── app.po.ts ├── tsconfig.e2e.json └── app.e2e-spec.ts ├── .editorconfig ├── tsconfig.json ├── .gitignore ├── protractor.conf.js ├── karma.conf.js ├── README.md ├── package.json ├── tslint.json └── angular.json /src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/app.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /src/app/messages-service/messageTarget.ts: -------------------------------------------------------------------------------- 1 | export enum MessageTarget { 2 | Board = 0, 3 | } -------------------------------------------------------------------------------- /src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/favicon.ico -------------------------------------------------------------------------------- /src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /src/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/logo.png -------------------------------------------------------------------------------- /src/assets/images/board/desk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/board/desk.png -------------------------------------------------------------------------------- /src/assets/images/board/sofa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/board/sofa.png -------------------------------------------------------------------------------- /src/assets/images/board/carpet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/board/carpet.png -------------------------------------------------------------------------------- /src/assets/images/board/chair.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/board/chair.png -------------------------------------------------------------------------------- /src/assets/images/board/clock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/board/clock.png -------------------------------------------------------------------------------- /src/assets/images/board/couch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/board/couch.png -------------------------------------------------------------------------------- /src/assets/images/board/table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/board/table.png -------------------------------------------------------------------------------- /src/assets/images/board/tvUnit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/board/tvUnit.png -------------------------------------------------------------------------------- /src/assets/images/board/batteries.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/board/batteries.png -------------------------------------------------------------------------------- /src/assets/images/board/coffeeMug.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/board/coffeeMug.png -------------------------------------------------------------------------------- /src/assets/images/board/deskPad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/board/deskPad.png -------------------------------------------------------------------------------- /src/assets/images/board/floorLamp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/board/floorLamp.png -------------------------------------------------------------------------------- /src/assets/images/board/ovenDish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/board/ovenDish.png -------------------------------------------------------------------------------- /src/assets/images/board/trashCan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/board/trashCan.png -------------------------------------------------------------------------------- /src/assets/images/board/nightstand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/board/nightstand.png -------------------------------------------------------------------------------- /src/assets/images/board/pencilCase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/board/pencilCase.png -------------------------------------------------------------------------------- /src/assets/images/board/tapeMeasure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/board/tapeMeasure.png -------------------------------------------------------------------------------- /src/assets/images/board/towelHanger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/board/towelHanger.png -------------------------------------------------------------------------------- /src/typings.d.ts: -------------------------------------------------------------------------------- 1 | /* SystemJS module definition */ 2 | declare var module: NodeModule; 3 | interface NodeModule { 4 | id: string; 5 | } 6 | -------------------------------------------------------------------------------- /src/assets/images/board/laptopSupport.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/board/laptopSupport.png -------------------------------------------------------------------------------- /src/assets/images/board/magneticBoard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/board/magneticBoard.png -------------------------------------------------------------------------------- /src/assets/images/board/showerCurtain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/board/showerCurtain.png -------------------------------------------------------------------------------- /src/assets/images/board/soapDispenser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/board/soapDispenser.png -------------------------------------------------------------------------------- /src/assets/images/board/tarpaulinRope.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/board/tarpaulinRope.png -------------------------------------------------------------------------------- /src/assets/images/onboarding/shadow_bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/onboarding/shadow_bg.png -------------------------------------------------------------------------------- /src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | 3 | body { 4 | overflow: hidden; 5 | } 6 | -------------------------------------------------------------------------------- /src/assets/images/onboarding/slide3_lamp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/onboarding/slide3_lamp.png -------------------------------------------------------------------------------- /src/assets/images/onboarding/slide4_cup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/onboarding/slide4_cup.png -------------------------------------------------------------------------------- /src/assets/images/onboarding/slide1_circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/onboarding/slide1_circle.png -------------------------------------------------------------------------------- /src/assets/images/onboarding/slide1_pluses.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/onboarding/slide1_pluses.png -------------------------------------------------------------------------------- /src/assets/images/onboarding/slide1_roger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/onboarding/slide1_roger.png -------------------------------------------------------------------------------- /src/assets/images/onboarding/slide2_circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/onboarding/slide2_circle.png -------------------------------------------------------------------------------- /src/assets/images/onboarding/slide2_pluses.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/onboarding/slide2_pluses.png -------------------------------------------------------------------------------- /src/assets/images/onboarding/slide3_circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/onboarding/slide3_circle.png -------------------------------------------------------------------------------- /src/assets/images/onboarding/slide3_pluses.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/onboarding/slide3_pluses.png -------------------------------------------------------------------------------- /src/assets/images/onboarding/slide4_circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/onboarding/slide4_circle.png -------------------------------------------------------------------------------- /src/assets/images/onboarding/slide4_pluses.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/onboarding/slide4_pluses.png -------------------------------------------------------------------------------- /src/assets/images/onboarding/onboarding_dots1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/onboarding/onboarding_dots1.png -------------------------------------------------------------------------------- /src/assets/images/onboarding/onboarding_dots2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/onboarding/onboarding_dots2.png -------------------------------------------------------------------------------- /src/assets/images/onboarding/onboarding_dots3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/onboarding/onboarding_dots3.png -------------------------------------------------------------------------------- /src/assets/images/onboarding/onboarding_dots4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/onboarding/onboarding_dots4.png -------------------------------------------------------------------------------- /src/assets/images/onboarding/slide2_big_plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IgniteUI/warehouse-js-blocks/HEAD/src/assets/images/onboarding/slide2_big_plus.png -------------------------------------------------------------------------------- /src/app/messages-service/message.ts: -------------------------------------------------------------------------------- 1 | import { MessageTarget } from "./messageTarget"; 2 | 3 | export class Message { 4 | messageTarget: MessageTarget; 5 | message: string; 6 | } -------------------------------------------------------------------------------- /e2e/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo() { 5 | return browser.get('/'); 6 | } 7 | 8 | getParagraphText() { 9 | return element(by.css('app-root h1')).getText(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from "@angular/core"; 2 | 3 | @Component({ 4 | selector: "app-root", 5 | templateUrl: "./app.component.html", 6 | styleUrls: ["./app.component.css"] 7 | }) 8 | export class AppComponent { 9 | title = "app"; 10 | } 11 | -------------------------------------------------------------------------------- /src/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/app", 5 | "baseUrl": "./", 6 | "module": "es2015", 7 | "types": [] 8 | }, 9 | "exclude": [ 10 | "test.ts", 11 | "**/*.spec.ts" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = off 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /e2e/tsconfig.e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/e2e", 5 | "baseUrl": "./", 6 | "module": "commonjs", 7 | "target": "es5", 8 | "types": [ 9 | "jasmine", 10 | "jasminewd2", 11 | "node" 12 | ] 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/app/addorder/addorder.component.css: -------------------------------------------------------------------------------- 1 | 2 | .pageImages { 3 | text-align: center; 4 | margin-top: 20px; 5 | margin-bottom: 20px; 6 | } 7 | 8 | .pageContent { 9 | text-align: center; 10 | margin-top: 20px; 11 | margin-bottom: 20px; 12 | padding-top: 280px; 13 | } 14 | 15 | .actionButtons { 16 | text-align: center; 17 | } 18 | -------------------------------------------------------------------------------- /e2e/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | 3 | describe('warehouse App', () => { 4 | let page: AppPage; 5 | 6 | beforeEach(() => { 7 | page = new AppPage(); 8 | }); 9 | 10 | it('should display welcome message', () => { 11 | page.navigateTo(); 12 | expect(page.getParagraphText()).toEqual('Welcome to app!'); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /src/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../out-tsc/spec", 5 | "baseUrl": "./", 6 | "module": "commonjs", 7 | "types": [ 8 | "jasmine", 9 | "node" 10 | ] 11 | }, 12 | "files": [ 13 | "test.ts", 14 | "polyfills.ts" 15 | ], 16 | "include": [ 17 | "**/*.spec.ts", 18 | "**/*.d.ts" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /src/app/order/order.component.css: -------------------------------------------------------------------------------- 1 | .orderInfo { 2 | color: black; 3 | margin: 10px; 4 | } 5 | 6 | .orderItems { 7 | color: black; 8 | } 9 | 10 | .aisleBin { 11 | background-color: #1276BC; 12 | color: white; 13 | } 14 | 15 | .orderActionButtons { 16 | text-align: center; 17 | } 18 | 19 | .actionButton { 20 | margin-top: 10px; 21 | margin-bottom: 10px; 22 | width: 230px; 23 | } 24 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import { enableProdMode } from '@angular/core'; 2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 3 | 4 | import { AppModule } from './app/app.module'; 5 | import { environment } from './environments/environment'; 6 | 7 | if (environment.production) { 8 | enableProdMode(); 9 | } 10 | 11 | platformBrowserDynamic().bootstrapModule(AppModule) 12 | .catch(err => console.log(err)); 13 | -------------------------------------------------------------------------------- /src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // The file contents for the current environment will overwrite these during build. 2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do 3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead. 4 | // The list of which env maps to which file can be found in `.angular-cli.json`. 5 | 6 | export const environment = { 7 | production: false 8 | }; 9 | -------------------------------------------------------------------------------- /src/app/orders-service/orderStatus.ts: -------------------------------------------------------------------------------- 1 | export enum OrderStatus { 2 | Active = 0, // these orders are in progress and are shown in the 'ACTIVE' list 3 | Incomplete = 1, // these orders are currently on hold and are shown in the 'ARCHIVE' list 4 | Complete = 2, // these orders are completed and are shown in the 'ARCHIVE' list 5 | Available = 3 // these orders are waiting for assignment can be added in the 'ACTIVE' list using the 'PLUS' button 6 | } 7 | -------------------------------------------------------------------------------- /src/app/orders-service/orders.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, inject } from "@angular/core/testing"; 2 | 3 | import { OrdersService } from "./orders.service"; 4 | 5 | describe("OrdersService", () => { 6 | beforeEach(() => { 7 | TestBed.configureTestingModule({ 8 | providers: [OrdersService] 9 | }); 10 | }); 11 | 12 | it("should be created", inject([OrdersService], (service: OrdersService) => { 13 | expect(service).toBeTruthy(); 14 | })); 15 | }); 16 | -------------------------------------------------------------------------------- /src/app/messages-service/messages.service.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, inject } from '@angular/core/testing'; 2 | 3 | import { MessagesService } from './messages.service'; 4 | 5 | describe('MessagesService', () => { 6 | beforeEach(() => { 7 | TestBed.configureTestingModule({ 8 | providers: [MessagesService] 9 | }); 10 | }); 11 | 12 | it('should be created', inject([MessagesService], (service: MessagesService) => { 13 | expect(service).toBeTruthy(); 14 | })); 15 | }); 16 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "outDir": "./dist/out-tsc", 5 | "sourceMap": true, 6 | "declaration": false, 7 | "moduleResolution": "node", 8 | "emitDecoratorMetadata": true, 9 | "experimentalDecorators": true, 10 | "target": "es5", 11 | "typeRoots": [ 12 | "node_modules/@types", 13 | "hammerjs" 14 | ], 15 | "lib": [ 16 | "es2017", 17 | "dom" 18 | ], 19 | "module": "es2015", 20 | "baseUrl": "./" 21 | } 22 | } -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Warehouse 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /dist-server 6 | /tmp 7 | /out-tsc 8 | 9 | # dependencies 10 | /node_modules 11 | 12 | # IDEs and editors 13 | /.idea 14 | .project 15 | .classpath 16 | .c9/ 17 | *.launch 18 | .settings/ 19 | *.sublime-workspace 20 | 21 | # IDE - VSCode 22 | .vscode/* 23 | !.vscode/settings.json 24 | !.vscode/tasks.json 25 | !.vscode/launch.json 26 | !.vscode/extensions.json 27 | 28 | # misc 29 | /.sass-cache 30 | /connect.lock 31 | /coverage 32 | /libpeerconnection.log 33 | npm-debug.log 34 | testem.log 35 | /typings 36 | 37 | # e2e 38 | /e2e/*.js 39 | /e2e/*.map 40 | 41 | # System Files 42 | .DS_Store 43 | Thumbs.db 44 | -------------------------------------------------------------------------------- /src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'zone.js/dist/zone-testing'; 4 | import { getTestBed } from '@angular/core/testing'; 5 | import { 6 | BrowserDynamicTestingModule, 7 | platformBrowserDynamicTesting 8 | } from '@angular/platform-browser-dynamic/testing'; 9 | 10 | declare const require: any; 11 | 12 | // First, initialize the Angular testing environment. 13 | getTestBed().initTestEnvironment( 14 | BrowserDynamicTestingModule, 15 | platformBrowserDynamicTesting() 16 | ); 17 | // Then we find all the tests. 18 | const context = require.context('./', true, /\.spec\.ts$/); 19 | // And load the modules. 20 | context.keys().map(context); 21 | -------------------------------------------------------------------------------- /src/app/board/board.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from "@angular/core/testing"; 2 | 3 | import { BoardComponent } from "./board.component"; 4 | 5 | describe("BoardComponent", () => { 6 | let component: BoardComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ BoardComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(BoardComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it("should create", () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/order/order.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { OrderComponent } from './order.component'; 4 | 5 | describe('OrderComponent', () => { 6 | let component: OrderComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ OrderComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(OrderComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/addorder/addorder.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from "@angular/core/testing"; 2 | 3 | import { AddOrderComponent } from "./addorder.component"; 4 | 5 | describe("BoardComponent", () => { 6 | let component: AddOrderComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ AddOrderComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(AddOrderComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it("should create", () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /src/app/onboarding/onboarding.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from "@angular/core/testing"; 2 | 3 | import { OnboardingComponent } from "./onboarding.component"; 4 | 5 | describe("OnboardingComponent", () => { 6 | let component: OnboardingComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ OnboardingComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(OnboardingComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it("should create", () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /protractor.conf.js: -------------------------------------------------------------------------------- 1 | // Protractor configuration file, see link for more information 2 | // https://github.com/angular/protractor/blob/master/lib/config.ts 3 | 4 | const { SpecReporter } = require('jasmine-spec-reporter'); 5 | 6 | exports.config = { 7 | allScriptsTimeout: 11000, 8 | specs: [ 9 | './e2e/**/*.e2e-spec.ts' 10 | ], 11 | capabilities: { 12 | 'browserName': 'chrome' 13 | }, 14 | directConnect: true, 15 | baseUrl: 'http://localhost:4200/', 16 | framework: 'jasmine', 17 | jasmineNodeOpts: { 18 | showColors: true, 19 | defaultTimeoutInterval: 30000, 20 | print: function() {} 21 | }, 22 | onPrepare() { 23 | require('ts-node').register({ 24 | project: 'e2e/tsconfig.e2e.json' 25 | }); 26 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /src/app/onboarding/onboarding.component.css: -------------------------------------------------------------------------------- 1 | 2 | body, div { 3 | -webkit-user-select: none; 4 | -khtml-user-select: none; 5 | -moz-user-select: none; 6 | -o-user-select: none; 7 | user-select: none; 8 | } 9 | 10 | .mainDivContent { 11 | text-align: center; 12 | overflow: hidden; 13 | } 14 | 15 | .obNavigation { 16 | background-color: white; 17 | height: 120px; 18 | width: 100%; 19 | text-align: center; 20 | position: fixed; 21 | bottom: 0px; 22 | } 23 | 24 | .customSkipButton { 25 | font-family: Verdana; 26 | cursor:pointer; 27 | color: #8A8A8A; 28 | position: absolute; 29 | margin-top: 20px; 30 | left: 25px; 31 | } 32 | 33 | .customNextButton { 34 | font-family: Verdana; 35 | cursor:pointer; 36 | color: #0375BE; 37 | position: absolute; 38 | margin-top: 20px; 39 | right: 25px; 40 | } 41 | 42 | .shadow { 43 | background-image: url(../../assets/images/onboarding/shadow_bg.png); 44 | background-repeat: repeat-x; 45 | height: 60px; 46 | } 47 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/1.0/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', '@angular-devkit/build-angular'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-jasmine-html-reporter'), 12 | require('karma-coverage-istanbul-reporter'), 13 | require('@angular-devkit/build-angular/plugins/karma') 14 | ], 15 | client:{ 16 | clearContext: false // leave Jasmine Spec Runner output visible in browser 17 | }, 18 | coverageIstanbulReporter: { 19 | dir: require('path').join(__dirname, 'coverage'), reports: [ 'html', 'lcovonly' ], 20 | fixWebpackSourcePaths: true 21 | }, 22 | 23 | reporters: ['progress', 'kjhtml'], 24 | port: 9876, 25 | colors: true, 26 | logLevel: config.LOG_INFO, 27 | autoWatch: true, 28 | browsers: ['Chrome'], 29 | singleRun: false 30 | }); 31 | }; 32 | -------------------------------------------------------------------------------- /src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, async } from "@angular/core/testing"; 2 | import { AppComponent } from "./app.component"; 3 | describe("AppComponent", () => { 4 | beforeEach(async(() => { 5 | TestBed.configureTestingModule({ 6 | declarations: [ 7 | AppComponent 8 | ], 9 | }).compileComponents(); 10 | })); 11 | it("should create the app", async(() => { 12 | const fixture = TestBed.createComponent(AppComponent); 13 | const app = fixture.debugElement.componentInstance; 14 | expect(app).toBeTruthy(); 15 | })); 16 | it("should have as title 'app'", async(() => { 17 | const fixture = TestBed.createComponent(AppComponent); 18 | const app = fixture.debugElement.componentInstance; 19 | expect(app.title).toEqual("app"); 20 | })); 21 | it("should render title in a h1 tag", async(() => { 22 | const fixture = TestBed.createComponent(AppComponent); 23 | fixture.detectChanges(); 24 | const compiled = fixture.debugElement.nativeElement; 25 | expect(compiled.querySelector("h1").textContent).toContain("Welcome to app!"); 26 | })); 27 | }); 28 | -------------------------------------------------------------------------------- /src/app/messages-service/messages.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | import { Message } from "./message"; 4 | import { MessageTarget } from "./messageTarget"; 5 | 6 | @Injectable() 7 | export class MessagesService { 8 | 9 | private messages: Message[] = new Array(); 10 | 11 | // this service is used to pass messages between the components 12 | constructor() { 13 | } 14 | 15 | // add new messages for a specific target 16 | addMessage(target: MessageTarget, message: string) { 17 | let newMessage:Message = new Message(); 18 | newMessage.messageTarget = target; 19 | newMessage.message = message; 20 | this.messages.push(newMessage); 21 | } 22 | 23 | // obtain the messages for a specific target 24 | // the returned messages will be removed fomr the messages list 25 | obtainMessages(target: MessageTarget): string[] { 26 | let result: string[] = new Array(); 27 | for (let i = this.messages.length - 1; i >= 0 ; i--) { 28 | if (this.messages[i].messageTarget == target) { 29 | result.unshift(this.messages[i].message); 30 | this.messages.splice(i, 1); 31 | } 32 | } 33 | return result; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/app/addorder/addorder.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |
7 | 8 | 9 | 10 |
11 | 12 |
13 | 14 | 15 | 16 | {{ order.id }} 17 | 18 | 19 |
20 | 21 |
22 | 26 |
27 | -------------------------------------------------------------------------------- /src/app/orders-service/order.ts: -------------------------------------------------------------------------------- 1 | import { OrderStatus } from "./orderStatus"; 2 | 3 | export class Order { 4 | id: string; 5 | date: string; 6 | status: OrderStatus; 7 | items: object[]; 8 | 9 | private progressValid: boolean = false; 10 | private progress: number; 11 | 12 | public getProgress(): number { 13 | if (!this.progressValid) { 14 | let found: number = 0; 15 | this.progress = 0; 16 | if (this.items && this.items.length > 0) { 17 | for (let i = 0; i < this.items.length; i++) { 18 | if (this.items[i]["Found"] === true) { 19 | found++; 20 | } 21 | } 22 | this.progress = Math.round(found * 100 / this.items.length); 23 | } 24 | this.progressValid = true; 25 | } 26 | return this.progress; 27 | } 28 | 29 | public invalidateProgress() { 30 | this.progressValid = false; 31 | } 32 | 33 | public clone(): Order { 34 | const result = new Order(); 35 | result.id = this.id; 36 | result.date = this.date; 37 | result.status = this.status; 38 | result.items = []; 39 | 40 | for (const item of this.items) { 41 | result.items.push( 42 | { ID: item["ID"], Name: item["Name"], Description: item["Description"], Price: item["Price"], Quantity: item["Quantity"], 43 | Image: item["Image"], Found: item["Found"], Aisle: item["Aisle"], Bin: item["Bin"]} 44 | ); 45 | } 46 | 47 | result.progressValid = this.progressValid; 48 | result.progress = this.progress; 49 | return result; 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Warehouse Picklist App 2 | 3 | A showcase application built using [Ignite UI for Angular](https://github.com/IgniteUI/ignite-ui). 4 | 5 | **List of components used:** 6 | 7 | | Component/Directive | | Used in (*screen*) | 8 | | :-: | :-: | :-: | 9 | | igx-bottom-nav | | Active Orders, Archived Orders | 10 | | igx-checkbox | | Order | 11 | | igx-circular-bar | | Active Orders | 12 | | igx-drop-down | | Add Order | 13 | | igx-icon | | Active Orders, Orders | 14 | | igx-list | | Active Orders, Archived Orders, Order | 15 | | igx-navbar | | Active Orders, Add Order, Order | 16 | | igx-snackbar | | Active Orders | 17 | | igx-toast | | Active Orders, Add Order | 18 | | igxButton | | Active Orders, Add Order, Order | 19 | | igxInput | | Active Orders | 20 | | igxRipple | | Order | 21 | 22 | ## Install 23 | To get started follow the respective package manager installation: 24 | 25 | #### npm 26 | ```shell 27 | npm install 28 | ``` 29 | 30 | ## Start 31 | 32 | #### ng 33 | ```shell 34 | ng serve 35 | ``` 36 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "warehouse", 3 | "version": "0.0.0", 4 | "license": "MIT", 5 | "scripts": { 6 | "ng": "ng", 7 | "start": "ng serve", 8 | "build": "ng build --prod", 9 | "test": "ng test", 10 | "lint": "ng lint", 11 | "e2e": "ng e2e" 12 | }, 13 | "private": true, 14 | "dependencies": { 15 | "@angular/animations": "^7.0.3", 16 | "@angular/common": "^7.0.3", 17 | "@angular/compiler": "^7.0.3", 18 | "@angular/core": "^7.0.3", 19 | "@angular/forms": "^7.0.3", 20 | "@angular/http": "^7.0.3", 21 | "@angular/platform-browser": "^7.0.3", 22 | "@angular/platform-browser-dynamic": "^7.0.3", 23 | "@angular/router": "^7.0.3", 24 | "@ngx-translate/core": "^9.1.1", 25 | "@ngx-translate/http-loader": "^2.0.1", 26 | "@types/hammerjs": "^2.0.35", 27 | "core-js": "^2.5.7", 28 | "hammerjs": "^2.0.8", 29 | "igniteui-angular": "^7.1.0", 30 | "jszip": "^3.1.5", 31 | "npm": "^6.4.1", 32 | "rxjs": "^6.2.1", 33 | "rxjs-compat": "^6.2.1", 34 | "web-animations-js": "^2.3.1", 35 | "zone.js": "^0.8.26" 36 | }, 37 | "devDependencies": { 38 | "@angular-devkit/build-angular": "~0.10.0", 39 | "@angular/cli": "^7.0.3", 40 | "@angular/compiler-cli": "^7.0.3", 41 | "@angular/language-service": "^7.0.3", 42 | "@types/jasmine": "^2.8.8", 43 | "@types/jasminewd2": "~2.0.3", 44 | "@types/node": "^6.0.113", 45 | "codelyzer": "^4.4.2", 46 | "jasmine-core": "~2.8.0", 47 | "jasmine-spec-reporter": "~4.2.1", 48 | "karma": "^2.0.4", 49 | "karma-chrome-launcher": "~2.2.0", 50 | "karma-coverage-istanbul-reporter": "^1.4.3", 51 | "karma-jasmine": "^1.1.2", 52 | "karma-jasmine-html-reporter": "^0.2.2", 53 | "protractor": "~5.1.2", 54 | "ts-node": "~4.1.0", 55 | "tsickle": ">=0.25.5", 56 | "tslint": "~5.9.1", 57 | "typescript": "^3.1.3" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/app/board/board.component.css: -------------------------------------------------------------------------------- 1 | .logoContainer { 2 | text-align: center; 3 | margin-top: 10px; 4 | margin-bottom: 10px; 5 | } 6 | 7 | .searchBoxContainer { 8 | margin-left: 10px; 9 | margin-right: 10px; 10 | margin-top: 5px; 11 | margin-bottom: 5px; 12 | } 13 | 14 | .igx-list { 15 | overflow-x: hidden; 16 | overflow-y: auto; 17 | } 18 | 19 | .emptyListContainer { 20 | text-align: center; 21 | margin-top: 50px; 22 | vertical-align: middle; 23 | } 24 | 25 | .emptyListHeader { 26 | width: 282px; 27 | height: 36px; 28 | /* font-family: TitilliumWeb; */ 29 | font-size: 28px; 30 | font-weight: bold; 31 | font-style: normal; 32 | font-stretch: normal; 33 | line-height: 1.29; 34 | letter-spacing: normal; 35 | text-align: center; 36 | color: #0375be; 37 | /* color: var(--cerulean); */ 38 | } 39 | 40 | .emptyListDescription { 41 | width: 261px; 42 | height: 36px; 43 | /* font-family: TitilliumWeb; */ 44 | font-size: 14px; 45 | font-weight: normal; 46 | font-style: normal; 47 | font-stretch: normal; 48 | line-height: 1.29; 49 | letter-spacing: normal; 50 | text-align: center; 51 | color: rgba(0, 0, 0, 0.54); 52 | } 53 | 54 | .igx-list__header { 55 | color: #0375be; 56 | font-size: 18px; 57 | } 58 | 59 | .archivePageHeader { 60 | background-color: #1276BC; 61 | color: black; 62 | height: 60px; 63 | padding-top: 18px; 64 | padding-left: 20px; 65 | } 66 | 67 | .addOrderButton { 68 | z-index: 3; 69 | position: absolute; 70 | right: 70px; 71 | bottom: 150px; 72 | } 73 | 74 | .listItemLeftPanningStyle { 75 | display: flex; 76 | flex-direction: row-reverse; 77 | background-color:limegreen; 78 | color: white; 79 | width: 100%; 80 | padding-right: 10px; 81 | align-items: center; 82 | } 83 | 84 | .listItemRightPanningStyle { 85 | display: flex; 86 | flex-direction: row; 87 | background-color:red; 88 | color: white; 89 | width: 100%; 90 | padding-left: 10px; 91 | align-items: center; 92 | } 93 | -------------------------------------------------------------------------------- /src/polyfills.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This file includes polyfills needed by Angular and is loaded before the app. 3 | * You can add your own extra polyfills to this file. 4 | * 5 | * This file is divided into 2 sections: 6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers. 7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main 8 | * file. 9 | * 10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that 11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera), 12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile. 13 | * 14 | * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html 15 | */ 16 | 17 | /*************************************************************************************************** 18 | * BROWSER POLYFILLS 19 | */ 20 | 21 | /** IE9, IE10 and IE11 requires all of the following polyfills. **/ 22 | // import 'core-js/es6/symbol'; 23 | // import 'core-js/es6/object'; 24 | // import 'core-js/es6/function'; 25 | // import 'core-js/es6/parse-int'; 26 | // import 'core-js/es6/parse-float'; 27 | // import 'core-js/es6/number'; 28 | // import 'core-js/es6/math'; 29 | // import 'core-js/es6/string'; 30 | // import 'core-js/es6/date'; 31 | // import 'core-js/es6/array'; 32 | // import 'core-js/es6/regexp'; 33 | // import 'core-js/es6/map'; 34 | // import 'core-js/es6/weak-map'; 35 | // import 'core-js/es6/set'; 36 | 37 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */ 38 | // import 'classlist.js'; // Run `npm install --save classlist.js`. 39 | 40 | /** IE10 and IE11 requires the following for the Reflect API. */ 41 | // import 'core-js/es6/reflect'; 42 | 43 | 44 | /** Evergreen browsers require these. **/ 45 | // Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove. 46 | import 'core-js/es7/reflect'; 47 | 48 | 49 | /** 50 | * Required to support Web Animations `@angular/platform-browser/animations`. 51 | * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation 52 | **/ 53 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 54 | 55 | 56 | 57 | /*************************************************************************************************** 58 | * Zone JS is required by default for Angular itself. 59 | */ 60 | import 'zone.js/dist/zone'; // Included with Angular CLI. 61 | 62 | 63 | 64 | /*************************************************************************************************** 65 | * APPLICATION IMPORTS 66 | */ 67 | -------------------------------------------------------------------------------- /src/assets/i18n/en.json: -------------------------------------------------------------------------------- 1 | { 2 | "btnSkip": "SKIP", 3 | "btnNext": "NEXT", 4 | "btnGotIt": "GOT IT", 5 | 6 | "slide1Title": "Meet Roger", 7 | "slide1Text": "Welcome to the warehouse demo app.
Step in the shoes of Roger
from the Furniture store warehouse.", 8 | 9 | "slide2Title": "Orders", 10 | "slide2Text": "Roger and his teammates assign
themselves the incoming customer
orders from the online store. It's done
either by entering the number of the
order manually or by scanning a barcode.", 11 | 12 | "slide3Title": "Search mode", 13 | "slide3Text": "Roger then starts looking for the items to
fulfill his assigned orders. He's able to
see the location of each item in the
warehouse, or tap to expand and see
further details.", 14 | 15 | "slide4Title": "Completion", 16 | "slide4Text": "When Roger finds an item, he marks it as
found. When he retrieves all items, he's
allowed to finalize the order. If he can't find
items, he's able to raise a flag by marking
an order as 'incomplete'.", 17 | 18 | "btnActive": "ACTIVE", 19 | "btnArchive": "ARCHIVE", 20 | "lblSearchBoxDefaultText": "Search active orders", 21 | "lblCompleted": "Completed", 22 | "lblIncompleted": "Incompleted", 23 | "lblQuickComplete": "Quick Complete", 24 | "lblCannotComplete": "Cannot Complete", 25 | "lblMovedToCompleted": "Order moved to completed", 26 | "lblMovedToIncompleted": "Order moved to incompleted", 27 | "btnUndo": "UNDO", 28 | 29 | "lblActive": "Active Order", 30 | "lblArchiveOrders": "Archive orders", 31 | "lblCompleteOrder": "Complete Order", 32 | "lblIncompleteOrder": "Incomplete Order", 33 | "lblCreatedOn": "Created on ", 34 | "lblCompletedOn": "Completed on ", 35 | 36 | "emptyListTemplateHeader": "No active orders found.", 37 | "emptyListTemplateDescription": "Could the order you're looking for be in the Archive already?", 38 | 39 | "btnSentToActive": "SEND TO ACTIVE", 40 | "btnPermanentlyDelete": "PERMANENTLY DELETE", 41 | "btnCompleteOrder": "COMPLETE ORDER", 42 | 43 | "lblMissingItems": "If there are missing items from the list, you can", 44 | "lblMarkTheOrderAsIncomplete": "mark the order as incomplete", 45 | 46 | "lblOrderToActive": "Order sent to active!", 47 | "lblOrderToDeleted": "Order successfully deleted.", 48 | "lblOrderToCompleted": "Order successfully completed.", 49 | "lblOrderToIncomplete": "Order marked as incomplete.", 50 | 51 | "lblAddOrder": "Add Order", 52 | "lblNoOrders": "There are no orders", 53 | "lblSelectOrder": "Select an order", 54 | "lblOrderSuccessful": "Order successfully added." 55 | 56 | } -------------------------------------------------------------------------------- /src/app/order/order.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | Order Number
6 | {{order.id}}
7 | Date
8 | {{order.date}} 9 |
10 | 11 |
12 | 13 | 14 | 15 | 16 |
17 |
18 |
19 | 20 |
21 | {{item.Quantity}}x 22 | {{item.ID}} 23 | {{item.Aisle}}  24 | {{item.Bin}} 25 |
26 | 29 |
30 |
31 |
32 | 33 | {{item.Name}}
34 | {{item.Description}}
35 | {{item.Price}} 36 |
37 |
38 | 39 |
40 |
41 | 42 |
43 | 44 |
45 | 46 |
50 | 51 |
55 | 56 |
60 | 61 | 62 | {{ "lblMissingItems" | translate }} 63 |
64 | 65 | 66 | {{ "lblMarkTheOrderAsIncomplete" | translate }} 67 | 68 | 69 |
70 | -------------------------------------------------------------------------------- /src/assets/i18n/jp.json: -------------------------------------------------------------------------------- 1 | { 2 | "btnSkip": "[jp] SKIP", 3 | "btnNext": "[jp] NEXT", 4 | "btnGotIt": "[jp] GOT IT", 5 | 6 | "slide1Title": "[jp] Meet Roger", 7 | "slide1Text": "[jp] Welcome to the warehouse demo app.
Step in the shoes of Roger
from the Furniture store warehouse.", 8 | 9 | "slide2Title": "[jp] Orders", 10 | "slide2Text": "[jp] Roger and his teammates assign
themselves the incoming customer
orders from the online store. It's done
either by entering the number of the
order manually or by scanning a barcode.", 11 | 12 | "slide3Title": "[jp] Search mode", 13 | "slide3Text": "[jp] Roger then starts looking for the items to
fulfill his assigned orders. He's able to
see the location of each item in the
warehouse, or tap to expand and see
further details.", 14 | 15 | "slide4Title": "[jp] Completion", 16 | "slide4Text": "[jp] When Roger finds an item, he marks it as
found. When he retrieves all items, he's
allowed to finalize the order. If he can't find
items, he's able to raise a flag by marking
an order as 'incomplete'.", 17 | 18 | "btnActive": "[jp] ACTIVE", 19 | "btnArchive": "[jp] ARCHIVE", 20 | "lblSearchBoxDefaultText": "[jp] Search active orders", 21 | "lblCompleted": "[jp] Completed", 22 | "lblIncompleted": "[jp] Incompleted", 23 | "lblQuickComplete": "[jp] Quick Complete", 24 | "lblCannotComplete": "[jp] Cannot Complete", 25 | "lblMovedToCompleted": "[jp] Order moved to completed", 26 | "lblMovedToIncompleted": "[jp] Order moved to incompleted", 27 | "btnUndo": "[jp] UNDO", 28 | 29 | "lblActive": "[jp] Active Order", 30 | "lblArchiveOrders": "[jp] Archive orders", 31 | "lblCompleteOrder": "[jp] Complete Order", 32 | "lblIncompleteOrder": "[jp] Incomplete Order", 33 | "lblCreatedOn": "[jp] Created on ", 34 | "lblCompletedOn": "[jp] Completed on ", 35 | 36 | "emptyListTemplateHeader": "[jp] No active orders found.", 37 | "emptyListTemplateDescription": "[jp] Could the order you're looking for be in the Archive already?", 38 | 39 | "btnSentToActive": "[jp] SEND TO ACTIVE", 40 | "btnPermanentlyDelete": "[jp] PERMANENTLY DELETE", 41 | "btnCompleteOrder": "[jp] COMPLETE ORDER", 42 | 43 | "lblMissingItems": "[jp] If there are missing items from the list, you can", 44 | "lblMarkTheOrderAsIncomplete": "[jp] mark the order as incomplete", 45 | 46 | "lblOrderToActive": "[jp] Order sent to active!", 47 | "lblOrderToDeleted": "[jp] Order successfully deleted.", 48 | "lblOrderToCompleted": "[jp] Order successfully completed.", 49 | "lblOrderToIncomplete": "[jp] Order marked as incomplete.", 50 | 51 | "lblAddOrder": "[jp] Add Order", 52 | "lblNoOrders": "[jp] There are no orders", 53 | "lblSelectOrder": "[jp] Select an order", 54 | "lblOrderSuccessful": "[jp] Order successfully added." 55 | 56 | } -------------------------------------------------------------------------------- /src/app/onboarding/onboarding.component.html: -------------------------------------------------------------------------------- 1 |
5 |  
6 | 7 | 9 | 10 | 15 | 16 | 21 | 22 | 27 | 28 | 33 |

{{currentSlideInfo.slideTitle}}

34 |
35 | 36 | 41 | 42 | 43 |
44 | 45 |
46 |
 
47 |
48 | {{leftButtonText}} 49 |
50 |
51 | {{rightButtonText}} 52 |
53 | 54 |
-------------------------------------------------------------------------------- /src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; 2 | import { BrowserModule } from "@angular/platform-browser"; 3 | import { FormsModule } from "@angular/forms"; 4 | import { NgModule } from "@angular/core"; 5 | import { RouterModule, Routes } from "@angular/router"; 6 | import { HttpClientModule, HttpClient } from "@angular/common/http"; 7 | 8 | import { TranslateModule, TranslateLoader } from "@ngx-translate/core"; 9 | import { TranslateHttpLoader } from "@ngx-translate/http-loader"; 10 | 11 | import { IgxButtonModule } from "igniteui-angular"; 12 | import { IgxBottomNavModule } from "igniteui-angular"; 13 | import { IgxCheckboxModule } from "igniteui-angular"; 14 | import { IgxDropDownModule } from "igniteui-angular"; 15 | import { IgxIconModule } from "igniteui-angular"; 16 | import { IgxInputGroupModule } from "igniteui-angular"; 17 | import { IgxListModule } from "igniteui-angular"; 18 | import { IgxNavbarModule } from "igniteui-angular"; 19 | import { IgxProgressBarModule } from "igniteui-angular"; 20 | import { IgxSnackbarModule } from "igniteui-angular"; 21 | import { IgxToastModule } from "igniteui-angular"; 22 | 23 | import { AddOrderComponent } from "./addorder/addorder.component"; 24 | import { AppComponent } from "./app.component"; 25 | import { BoardComponent } from "./board/board.component"; 26 | import { OnboardingComponent } from "./onboarding/onboarding.component"; 27 | import { OrderComponent } from "./order/order.component"; 28 | 29 | import { MessagesService } from "./messages-service/messages.service"; 30 | import { OrdersService } from "./orders-service/orders.service"; 31 | 32 | import "hammerjs"; 33 | 34 | const appRoutes: Routes = [ 35 | { path: "addorder", component: AddOrderComponent}, 36 | { path: "board", component: BoardComponent }, 37 | { path: "onboarding", component: OnboardingComponent }, 38 | { path: "order/:orderId", component: OrderComponent }, 39 | { path: "", redirectTo: "/onboarding", pathMatch: "full" }, 40 | ]; 41 | 42 | export function HttpLoaderFactory(http: HttpClient) { 43 | return new TranslateHttpLoader(http, "./assets/i18n/", ".json"); 44 | } 45 | 46 | @NgModule({ 47 | declarations: [ 48 | AddOrderComponent, 49 | AppComponent, 50 | BoardComponent, 51 | OnboardingComponent, 52 | OrderComponent, 53 | ], 54 | imports: [ 55 | BrowserModule, 56 | BrowserAnimationsModule, 57 | FormsModule, 58 | IgxButtonModule, 59 | IgxBottomNavModule, 60 | IgxCheckboxModule, 61 | IgxDropDownModule, 62 | IgxIconModule, 63 | IgxInputGroupModule, 64 | IgxListModule, 65 | IgxNavbarModule, 66 | IgxProgressBarModule, 67 | IgxSnackbarModule, 68 | IgxToastModule, 69 | RouterModule.forRoot(appRoutes, {enableTracing: false}), 70 | HttpClientModule, 71 | TranslateModule.forRoot({ 72 | loader: { 73 | provide: TranslateLoader, 74 | useFactory: HttpLoaderFactory, 75 | deps: [HttpClient] 76 | } 77 | }) 78 | ], 79 | providers: [ 80 | MessagesService, 81 | OrdersService 82 | ], 83 | bootstrap: [AppComponent] 84 | }) 85 | export class AppModule { } 86 | -------------------------------------------------------------------------------- /src/app/orders-service/orders.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from "@angular/core"; 2 | 3 | import { ORDERS_MOCK_DATA } from "./orders-mock" 4 | import { Order } from "./order"; 5 | import { OrderStatus } from "./orderStatus"; 6 | 7 | @Injectable() 8 | export class OrdersService { 9 | 10 | allOrders: Order[]; 11 | 12 | constructor() { 13 | this.allOrders = new Array(); 14 | for (let i = 0; i < ORDERS_MOCK_DATA.length; i++) { 15 | const order = new Order(); 16 | order.id = ORDERS_MOCK_DATA[i].ID; 17 | order.date = ORDERS_MOCK_DATA[i].CreationDate; 18 | order.status = ORDERS_MOCK_DATA[i].Status; 19 | order.items = ORDERS_MOCK_DATA[i].Items; 20 | this.allOrders.push(order); 21 | } 22 | } 23 | 24 | getOrdersActive(): Order[] { 25 | const result = []; 26 | for (let i = 0; i < this.allOrders.length; i++) { 27 | if (this.allOrders[i].status === OrderStatus.Active) { 28 | result.push(this.allOrders[i]); 29 | } 30 | } 31 | return result; 32 | } 33 | 34 | getOrdersActiveById(idPattern: string): Order[] { 35 | const result = []; 36 | for (let i = 0; i < this.allOrders.length; i++) { 37 | if (this.allOrders[i].status === OrderStatus.Active && this.allOrders[i].id.indexOf(idPattern) >= 0) { 38 | result.push(this.allOrders[i]); 39 | } 40 | } 41 | return result; 42 | } 43 | 44 | getOrdersCompleted(): Order[] { 45 | const result = []; 46 | for (let i = 0; i < this.allOrders.length; i++) { 47 | if (this.allOrders[i].status === OrderStatus.Complete) { 48 | result.push(this.allOrders[i]); 49 | } 50 | } 51 | return result; 52 | } 53 | 54 | getOrdersIncompleted(): Order[] { 55 | const result = []; 56 | for (let i = 0; i < this.allOrders.length; i++) { 57 | if (this.allOrders[i].status === OrderStatus.Incomplete) { 58 | result.push(this.allOrders[i]); 59 | } 60 | } 61 | return result; 62 | } 63 | 64 | getOrdersAvailable(): Order[] { 65 | const result = []; 66 | for (let i = 0; i < this.allOrders.length; i++) { 67 | if (this.allOrders[i].status === OrderStatus.Available) { 68 | result.push(this.allOrders[i]); 69 | } 70 | } 71 | return result; 72 | } 73 | 74 | getOrder(searchOrderId: string): Order { 75 | for (let i = 0; i < this.allOrders.length; i++) { 76 | if (this.allOrders[i].id === searchOrderId) { 77 | return this.allOrders[i]; 78 | } 79 | } 80 | return null; 81 | } 82 | 83 | deleteOrder(orderId: string) { 84 | for (let i = 0; i < this.allOrders.length; i++) { 85 | if (this.allOrders[i].id === orderId) { 86 | this.allOrders.splice(i, 1); 87 | break; 88 | } 89 | } 90 | } 91 | 92 | updateOrderStatus(orderId: string, newStatus: OrderStatus) { 93 | for (let i = 0; i < this.allOrders.length; i++) { 94 | if (this.allOrders[i].id === orderId) { 95 | this.allOrders[i].status = newStatus; 96 | break; 97 | } 98 | } 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /src/app/addorder/addorder.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewChild } from "@angular/core"; 2 | import { Location } from '@angular/common'; 3 | 4 | import { TranslateService } from "@ngx-translate/core"; 5 | 6 | import { ConnectedPositioningStrategy, CloseScrollStrategy, HorizontalAlignment, VerticalAlignment } from "igniteui-angular"; 7 | import { IgxDropDownComponent, IgxToastComponent } from "igniteui-angular"; 8 | 9 | import { OrdersService } from "../orders-service/orders.service"; 10 | import { OrderStatus } from "../orders-service/orderStatus"; 11 | 12 | @Component({ 13 | selector: "app-addorder", 14 | templateUrl: "./addorder.component.html", 15 | styleUrls: ["./addorder.component.css"] 16 | }) 17 | export class AddOrderComponent implements OnInit { 18 | 19 | @ViewChild("toastComp") 20 | private toastComp: IgxToastComponent; 21 | 22 | @ViewChild(IgxDropDownComponent) 23 | private igxDropDown: IgxDropDownComponent; 24 | 25 | public toastMessage: string; 26 | public ordersAvailable = []; 27 | public selectedOrderId = null; 28 | 29 | private _positionSettings = { 30 | horizontalStartPoint: HorizontalAlignment.Left, 31 | verticalStartPoint: VerticalAlignment.Bottom 32 | }; 33 | 34 | private _overlaySettings = { 35 | closeOnOutsideClick: true, 36 | modal: false, 37 | positionStrategy: new ConnectedPositioningStrategy(this._positionSettings), 38 | scrollStrategy: new CloseScrollStrategy() 39 | }; 40 | 41 | constructor(private ordersService: OrdersService, 42 | private translate: TranslateService, 43 | private location: Location) { 44 | 45 | // internationalization 46 | translate.addLangs(["en", "jp"]); 47 | translate.setDefaultLang("en"); 48 | const browserLang = translate.getBrowserLang(); 49 | translate.use(browserLang.match(/en|jp/) ? browserLang : "en"); 50 | //translate.use("jp"); 51 | } 52 | 53 | ngOnInit() { 54 | this.ordersAvailable = this.ordersService.getOrdersAvailable(); 55 | } 56 | 57 | backButtonClicked() { 58 | this.location.back(); 59 | } 60 | 61 | public toggleDropDown(eventArgs) { 62 | this._overlaySettings.positionStrategy.settings.target = eventArgs.target; 63 | this.igxDropDown.toggle(this._overlaySettings); 64 | } 65 | 66 | get selectOrderButtonCaption(): string { 67 | if (this.ordersAvailable == null || this.ordersAvailable.length === 0) { 68 | return this.translate.instant("lblNoOrders"); 69 | } else { 70 | if (this.selectedOrderId == null) { 71 | return this.translate.instant("lblSelectOrder"); 72 | } else { 73 | return this.selectedOrderId; 74 | } 75 | } 76 | } 77 | 78 | public onSelectionHandler(eventArgs) { 79 | this.selectedOrderId = eventArgs.newSelection.element.nativeElement.innerText.trim(); 80 | } 81 | 82 | public btnAddOrderHandler() { 83 | this.ordersService.updateOrderStatus(this.selectedOrderId, OrderStatus.Active); 84 | this.selectedOrderId = null; 85 | this.ordersAvailable = this.ordersService.getOrdersAvailable(); 86 | this.toastMessage = this.translate.instant("lblOrderSuccessful"); 87 | this.toastComp.show(); 88 | } 89 | 90 | } 91 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rulesDirectory": [ 3 | "node_modules/codelyzer" 4 | ], 5 | "rules": { 6 | "arrow-return-shorthand": true, 7 | "callable-types": true, 8 | "class-name": true, 9 | "comment-format": [ 10 | true, 11 | "check-space" 12 | ], 13 | "curly": true, 14 | "deprecation": { 15 | "severity": "warn" 16 | }, 17 | "eofline": true, 18 | "forin": true, 19 | "import-blacklist": [ 20 | true, 21 | "rxjs", 22 | "rxjs/Rx" 23 | ], 24 | "import-spacing": true, 25 | "indent": [ 26 | true, 27 | "spaces" 28 | ], 29 | "interface-over-type-literal": true, 30 | "label-position": true, 31 | "max-line-length": [ 32 | true, 33 | 140 34 | ], 35 | "member-access": false, 36 | "member-ordering": [ 37 | true, 38 | { 39 | "order": [ 40 | "static-field", 41 | "instance-field", 42 | "static-method", 43 | "instance-method" 44 | ] 45 | } 46 | ], 47 | "no-arg": true, 48 | "no-bitwise": true, 49 | "no-console": [ 50 | true, 51 | "debug", 52 | "info", 53 | "time", 54 | "timeEnd", 55 | "trace" 56 | ], 57 | "no-construct": true, 58 | "no-debugger": true, 59 | "no-duplicate-super": true, 60 | "no-empty": false, 61 | "no-empty-interface": true, 62 | "no-eval": true, 63 | "no-inferrable-types": [ 64 | true, 65 | "ignore-params" 66 | ], 67 | "no-misused-new": true, 68 | "no-non-null-assertion": true, 69 | "no-shadowed-variable": true, 70 | "no-string-literal": false, 71 | "no-string-throw": true, 72 | "no-switch-case-fall-through": true, 73 | "no-trailing-whitespace": true, 74 | "no-unnecessary-initializer": true, 75 | "no-unused-expression": true, 76 | "no-use-before-declare": true, 77 | "no-var-keyword": true, 78 | "object-literal-sort-keys": false, 79 | "one-line": [ 80 | true, 81 | "check-open-brace", 82 | "check-catch", 83 | "check-else", 84 | "check-whitespace" 85 | ], 86 | "prefer-const": true, 87 | "quotemark": [ 88 | true, 89 | "single" 90 | ], 91 | "radix": true, 92 | "semicolon": [ 93 | true, 94 | "always" 95 | ], 96 | "triple-equals": [ 97 | true, 98 | "allow-null-check" 99 | ], 100 | "typedef-whitespace": [ 101 | true, 102 | { 103 | "call-signature": "nospace", 104 | "index-signature": "nospace", 105 | "parameter": "nospace", 106 | "property-declaration": "nospace", 107 | "variable-declaration": "nospace" 108 | } 109 | ], 110 | "unified-signatures": true, 111 | "variable-name": false, 112 | "whitespace": [ 113 | true, 114 | "check-branch", 115 | "check-decl", 116 | "check-operator", 117 | "check-separator", 118 | "check-type" 119 | ], 120 | "directive-selector": [ 121 | true, 122 | "attribute", 123 | "app", 124 | "camelCase" 125 | ], 126 | "component-selector": [ 127 | true, 128 | "element", 129 | "app", 130 | "kebab-case" 131 | ], 132 | "no-output-on-prefix": true, 133 | "use-input-property-decorator": true, 134 | "use-output-property-decorator": true, 135 | "use-host-property-decorator": true, 136 | "no-input-rename": true, 137 | "no-output-rename": true, 138 | "use-life-cycle-interface": true, 139 | "use-pipe-transform-interface": true, 140 | "component-class-suffix": true, 141 | "directive-class-suffix": true 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /src/app/board/board.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 |
10 | 11 |
12 | 13 | 16 | 17 | search 18 | 19 | 20 | clear 21 | 22 | 23 |
24 | 25 | 26 | 29 | 30 |
{{ "lblQuickComplete" | translate }}
31 |
32 | 33 |
{{ "lblCannotComplete" | translate }}
34 |
35 | 36 |
37 | {{ "emptyListTemplateHeader" | translate }} 38 |
39 | {{ "emptyListTemplateDescription" | translate }} 40 |
41 |
42 | 43 | 44 | 45 |
46 | {{ order.id }} 47 |
{{ "lblCreatedOn" | translate }} {{ order.date }} 48 |
49 |
50 | {{ snackBarActionMessage }} 51 |
52 | 53 | 56 | 57 |
58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | {{ "lblCompleted" | translate }} 68 | 69 |
70 | {{ order.id }} 71 |
{{ "lblCompletedOn" | translate }} {{ order.date }} 72 |
73 |
74 | 75 | {{ "lblIncompleted" | translate }} 76 | 77 |
78 | {{ order.id }} 79 |
{{ "lblCreatedOn" | translate }} {{ order.date }} 80 |
81 |
82 | 83 |
84 |
85 | 86 |
87 | -------------------------------------------------------------------------------- /angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "warehouse": { 7 | "root": "", 8 | "sourceRoot": "src", 9 | "projectType": "application", 10 | "architect": { 11 | "build": { 12 | "builder": "@angular-devkit/build-angular:browser", 13 | "options": { 14 | "outputPath": "dist", 15 | "index": "src/index.html", 16 | "main": "src/main.ts", 17 | "tsConfig": "src/tsconfig.app.json", 18 | "polyfills": "src/polyfills.ts", 19 | "assets": [ 20 | "src/assets", 21 | "src/favicon.ico" 22 | ], 23 | "styles": [ 24 | "src/styles.css", 25 | "node_modules/igniteui-angular/styles/igniteui-angular.css" 26 | ], 27 | "scripts": [] 28 | }, 29 | "configurations": { 30 | "production": { 31 | "optimization": true, 32 | "outputHashing": "all", 33 | "sourceMap": false, 34 | "extractCss": true, 35 | "namedChunks": false, 36 | "aot": true, 37 | "extractLicenses": true, 38 | "vendorChunk": false, 39 | "buildOptimizer": true, 40 | "fileReplacements": [ 41 | { 42 | "replace": "src/environments/environment.ts", 43 | "with": "src/environments/environment.prod.ts" 44 | } 45 | ] 46 | } 47 | } 48 | }, 49 | "serve": { 50 | "builder": "@angular-devkit/build-angular:dev-server", 51 | "options": { 52 | "browserTarget": "warehouse:build" 53 | }, 54 | "configurations": { 55 | "production": { 56 | "browserTarget": "warehouse:build:production" 57 | } 58 | } 59 | }, 60 | "extract-i18n": { 61 | "builder": "@angular-devkit/build-angular:extract-i18n", 62 | "options": { 63 | "browserTarget": "warehouse:build" 64 | } 65 | }, 66 | "test": { 67 | "builder": "@angular-devkit/build-angular:karma", 68 | "options": { 69 | "main": "src/test.ts", 70 | "karmaConfig": "./karma.conf.js", 71 | "polyfills": "src/polyfills.ts", 72 | "tsConfig": "src/tsconfig.spec.json", 73 | "scripts": [], 74 | "styles": [ 75 | "src/styles.css", 76 | "node_modules/igniteui-angular/styles/igniteui-angular.css" 77 | ], 78 | "assets": [ 79 | "src/assets", 80 | "src/favicon.ico" 81 | ] 82 | } 83 | }, 84 | "lint": { 85 | "builder": "@angular-devkit/build-angular:tslint", 86 | "options": { 87 | "tsConfig": [ 88 | "src/tsconfig.app.json", 89 | "src/tsconfig.spec.json" 90 | ], 91 | "exclude": [ 92 | "**/node_modules/**" 93 | ] 94 | } 95 | } 96 | } 97 | }, 98 | "warehouse-e2e": { 99 | "root": "e2e", 100 | "sourceRoot": "e2e", 101 | "projectType": "application", 102 | "architect": { 103 | "e2e": { 104 | "builder": "@angular-devkit/build-angular:protractor", 105 | "options": { 106 | "protractorConfig": "./protractor.conf.js", 107 | "devServerTarget": "warehouse:serve" 108 | } 109 | }, 110 | "lint": { 111 | "builder": "@angular-devkit/build-angular:tslint", 112 | "options": { 113 | "tsConfig": [ 114 | "e2e/tsconfig.e2e.json" 115 | ], 116 | "exclude": [ 117 | "**/node_modules/**" 118 | ] 119 | } 120 | } 121 | } 122 | } 123 | }, 124 | "defaultProject": "warehouse", 125 | "schematics": { 126 | "@schematics/angular:component": { 127 | "prefix": "app", 128 | "styleext": "css" 129 | }, 130 | "@schematics/angular:directive": { 131 | "prefix": "app" 132 | } 133 | } 134 | } -------------------------------------------------------------------------------- /src/app/order/order.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnDestroy, OnInit } from "@angular/core"; 2 | import { Location } from '@angular/common'; 3 | import { Router, ActivatedRoute, ParamMap } from '@angular/router'; 4 | 5 | import { MessagesService } from "../messages-service/messages.service"; 6 | import { MessageTarget } from "../messages-service/messageTarget"; 7 | import { Order } from "../orders-service/order"; 8 | import { OrderStatus } from "../orders-service/orderStatus"; 9 | import { OrdersService } from "../orders-service/orders.service"; 10 | 11 | import { TranslateService, LangChangeEvent } from "@ngx-translate/core"; 12 | 13 | @Component({ 14 | selector: "app-order", 15 | templateUrl: "./order.component.html", 16 | styleUrls: ["./order.component.css"] 17 | }) 18 | export class OrderComponent implements OnInit, OnDestroy { 19 | 20 | orderId: string; 21 | order: Order; 22 | private subscription: any; 23 | 24 | constructor(private ordersService: OrdersService, 25 | private translate: TranslateService, 26 | private route: ActivatedRoute, 27 | private router: Router, 28 | private location: Location, 29 | private messagesService: MessagesService) { 30 | 31 | // internationalization 32 | translate.addLangs(["en", "jp"]); 33 | translate.setDefaultLang("en"); 34 | const browserLang = translate.getBrowserLang(); 35 | translate.use(browserLang.match(/en|jp/) ? browserLang : "en"); 36 | //translate.use("jp"); 37 | } 38 | 39 | get itemsDisabled(): boolean { 40 | return (!this.order || (this.order.status === OrderStatus.Complete || this.order.status === OrderStatus.Incomplete)); 41 | } 42 | 43 | get orderCompletionDisabled(): boolean { 44 | for (let i = 0; i < this.order.items.length; i++) { 45 | if (!this.order.items[i]["Found"]) { 46 | return true; 47 | } 48 | } 49 | return false; 50 | } 51 | 52 | get pageTitle(): string { 53 | if (this.order) { 54 | switch (this.order.status) { 55 | case OrderStatus.Active: return this.translate.instant("lblActive"); 56 | case OrderStatus.Complete: return this.translate.instant("lblCompleteOrder"); 57 | case OrderStatus.Incomplete: return this.translate.instant("lblIncompleteOrder"); 58 | } 59 | } 60 | return "Unknown Order"; 61 | } 62 | 63 | ngOnInit() { 64 | this.subscription = this.route.params.subscribe( 65 | params => { 66 | this.orderId = params["orderId"]; 67 | this.order = this.ordersService.getOrder(this.orderId); 68 | if (this.order) { 69 | this.order.invalidateProgress(); 70 | } 71 | } 72 | ); 73 | } 74 | 75 | ngOnDestroy() { 76 | this.subscription.unsubscribe(); 77 | } 78 | 79 | backButtonClicked() { 80 | if (this.order) { 81 | if (this.order.status === OrderStatus.Complete || this.order.status === OrderStatus.Incomplete) { 82 | this.messagesService.addMessage(MessageTarget.Board, "switchTab:Archive"); 83 | this.router.navigate(['/board']); 84 | return; 85 | } 86 | } 87 | this.location.back(); 88 | } 89 | 90 | toggleListItem(itemId) { 91 | for (let i = 0; i < this.order.items.length; i++) { 92 | if (this.order.items[i]["ID"] === itemId) { 93 | if (this.order.items[i]["Expanded"] === undefined) { 94 | this.order.items[i]["Expanded"] = true; 95 | } else { 96 | this.order.items[i]["Expanded"] = !this.order.items[i]["Expanded"]; 97 | } 98 | break; 99 | } 100 | } 101 | } 102 | 103 | convertExpandedStateToIcon(itemId) { 104 | for (let i = 0; i < this.order.items.length; i++) { 105 | if (this.order.items[i]["ID"] === itemId) { 106 | return this.order.items[i]["Expanded"] === true ? 'keyboard_arrow_up' : 'keyboard_arrow_down'; 107 | } 108 | } 109 | } 110 | 111 | convertBooleanToDisplay(inputValue) { 112 | return inputValue === true ? 'block' : 'none'; 113 | } 114 | 115 | btnSentToActiveHandler() { 116 | if (this.order) { 117 | this.order.status = OrderStatus.Active; 118 | this.messagesService.addMessage(MessageTarget.Board, "showToast:" + this.translate.instant("lblOrderToActive")); 119 | this.router.navigate(['/board']); 120 | } 121 | } 122 | 123 | btnDeleteHandler() { 124 | if (this.order) { 125 | this.ordersService.deleteOrder(this.order.id); 126 | this.messagesService.addMessage(MessageTarget.Board, "showToast:" + this.translate.instant("lblOrderToDeleted")); 127 | this.router.navigate(['/board']); 128 | } 129 | } 130 | 131 | 132 | btnCompleteHandler() { 133 | if (this.order) { 134 | this.order.status = OrderStatus.Complete; 135 | this.messagesService.addMessage(MessageTarget.Board, "switchTab:Archive"); 136 | this.messagesService.addMessage(MessageTarget.Board, "showToast:" + this.translate.instant("lblOrderToCompleted")); 137 | this.router.navigate(['/board']); 138 | } 139 | } 140 | 141 | btnMarkAsIncompleteHandler() { 142 | if (this.order) { 143 | this.order.status = OrderStatus.Incomplete; 144 | this.messagesService.addMessage(MessageTarget.Board, "showToast:" + this.translate.instant("lblOrderToIncomplete")); 145 | this.router.navigate(['/board']); 146 | } 147 | return false; 148 | } 149 | 150 | } 151 | -------------------------------------------------------------------------------- /src/app/board/board.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, HostListener, ViewChild, AfterViewInit, ChangeDetectorRef } from "@angular/core"; 2 | import { Router, ActivatedRoute, ParamMap } from "@angular/router"; 3 | 4 | import { MessagesService } from "../messages-service/messages.service"; 5 | import { MessageTarget } from "../messages-service/messageTarget"; 6 | import { OrdersService } from "../orders-service/orders.service"; 7 | import { OrderStatus } from "../orders-service/orderStatus"; 8 | 9 | import { TranslateService, LangChangeEvent } from "@ngx-translate/core"; 10 | import { IgxBottomNavComponent, IgxListPanState, IgxSnackbarComponent, IgxToastComponent } from "igniteui-angular"; 11 | import { Order } from "../orders-service/order"; 12 | 13 | @Component({ 14 | selector: "app-board", 15 | templateUrl: "./board.component.html", 16 | styleUrls: ["./board.component.css"] 17 | }) 18 | export class BoardComponent implements OnInit, AfterViewInit { 19 | 20 | @ViewChild("toastComp") 21 | toastComp: IgxToastComponent; 22 | 23 | @ViewChild("mainTabBar") 24 | mainTabBar: IgxBottomNavComponent; 25 | 26 | @ViewChild("snackbar1") 27 | snackbar1: IgxSnackbarComponent; 28 | 29 | searchCriteriaValue = ""; 30 | ordersActive = []; 31 | ordersCompleted = []; 32 | ordersIncompleted = []; 33 | componentMessages: string[]; 34 | toastMessage = ""; 35 | snackBarActionMessage = ""; 36 | activeIgxListHeight = 0; 37 | archiveIgxListHeight = 0; 38 | 39 | // for undo operation 40 | undoOrder: Order = null; 41 | undoOrderIndex: number; 42 | 43 | constructor(private ordersService: OrdersService, 44 | private translate: TranslateService, 45 | private route: ActivatedRoute, 46 | private router: Router, 47 | private messagesService: MessagesService, 48 | private cdr: ChangeDetectorRef) { 49 | 50 | // internationalization 51 | translate.addLangs(["en", "jp"]); 52 | translate.setDefaultLang("en"); 53 | const browserLang = translate.getBrowserLang(); 54 | translate.use(browserLang.match(/en|jp/) ? browserLang : "en"); 55 | // translate.use("jp"); 56 | } 57 | 58 | ngOnInit() { 59 | // load orders 60 | this.ordersActive = this.ordersService.getOrdersActive(); 61 | this.ordersCompleted = this.ordersService.getOrdersCompleted(); 62 | this.ordersIncompleted = this.ordersService.getOrdersIncompleted(); 63 | 64 | // initial resize of the IgxLists 65 | this.onResize(null); 66 | 67 | // obtain messages for this component 68 | this.componentMessages = this.messagesService.obtainMessages(MessageTarget.Board); 69 | 70 | // show a toast message if there is such request 71 | for (let i = 0; i < this.componentMessages.length; i++) { 72 | if (this.componentMessages[i].startsWith("showToast:")) { 73 | const msgStr = this.componentMessages[i].substr(10); 74 | this.toastMessage = msgStr; 75 | this.toastComp.show(); 76 | this.componentMessages.splice(i, 1); 77 | } 78 | } 79 | } 80 | 81 | ngAfterViewInit() { 82 | // switch selected tab if there is such request 83 | for (let i = 0; i < this.componentMessages.length; i++) { 84 | if (this.componentMessages[i].startsWith("switchTab:")) { 85 | const requestedTabStr = this.componentMessages[i].substr(10); 86 | if (requestedTabStr === "Active") { 87 | const aTab = this.mainTabBar.tabs.toArray()[0]; 88 | aTab.select(); 89 | } else 90 | if (requestedTabStr === "Archive") { 91 | const aTab = this.mainTabBar.tabs.toArray()[1]; 92 | aTab.select(); 93 | } 94 | this.cdr.detectChanges(); 95 | this.componentMessages.splice(i, 1); 96 | } 97 | } 98 | } 99 | 100 | clearSearchInputClicked() { 101 | this.searchCriteriaValue = ""; 102 | this.searchBoxKeyDown(null); 103 | } 104 | 105 | activeListItemClicked(evt) { 106 | if (evt.item && evt.direction === IgxListPanState.NONE) { 107 | const orderId = this.ordersActive[evt.item.index].id; 108 | this.router.navigate(['/order', orderId]); 109 | } 110 | } 111 | 112 | archiveListItemClicked(evt) { 113 | if (evt.item) { 114 | let orderId = ""; 115 | let idx = evt.item.index; 116 | if (idx <= this.ordersCompleted.length) { 117 | orderId = this.ordersCompleted[idx - 1].id; // excluding 1 header (complete) 118 | } else { 119 | idx = idx - this.ordersCompleted.length; 120 | orderId = this.ordersIncompleted[idx - 2].id; // excluding 2 headers (complete and incomplete) 121 | } 122 | this.router.navigate(['/order', orderId]); 123 | } 124 | } 125 | 126 | searchBoxKeyDown(event) { 127 | if (!this.searchCriteriaValue) { 128 | this.ordersActive = this.ordersService.getOrdersActive(); 129 | } else { 130 | this.ordersActive = this.ordersService.getOrdersActiveById(this.searchCriteriaValue.toUpperCase()); 131 | } 132 | } 133 | 134 | // used to resize the IgxLists when resizing the browser window 135 | @HostListener("window:resize", ["$event"]) 136 | onResize(evt) { 137 | this.activeIgxListHeight = window.innerHeight - 226; 138 | this.archiveIgxListHeight = window.innerHeight - 139; 139 | } 140 | 141 | addOrderClicked() { 142 | this.router.navigateByUrl("/addorder"); 143 | } 144 | 145 | public onLeftPanHandler(args) { 146 | args.keepItem = true; 147 | 148 | // cloning order befor it is changed 149 | this.undoOrder = this.ordersActive[args.item.index].clone(); 150 | this.undoOrderIndex = args.item.index; 151 | 152 | // remove from active list 153 | const extractedOrder = this.ordersActive.splice(args.item.index, 1)[0]; 154 | 155 | // update the order by setting all order's items as found 156 | for (const orderItem of extractedOrder.items) { 157 | if (!orderItem.Found) { 158 | orderItem.Found = true; 159 | } 160 | } 161 | 162 | // set order's state to complete 163 | extractedOrder.status = OrderStatus.Complete; 164 | 165 | // add order to completed list 166 | this.ordersCompleted.push(extractedOrder); 167 | 168 | // update order status in the data source service 169 | this.ordersService.updateOrderStatus(extractedOrder.id, OrderStatus.Complete); 170 | 171 | // show an information snackbar with UNDO option 172 | this.snackBarActionMessage = this.translate.instant("lblMovedToCompleted"); 173 | this.snackbar1.show(); 174 | } 175 | 176 | public onRightPanHandler(args) { 177 | args.keepItem = true; 178 | 179 | // cloning order befor it is changed 180 | this.undoOrder = this.ordersActive[args.item.index].clone(); 181 | this.undoOrderIndex = args.item.index; 182 | 183 | // remove from active list 184 | const extractedOrder = this.ordersActive.splice(args.item.index, 1)[0]; 185 | 186 | // set order's state to complete 187 | extractedOrder.status = OrderStatus.Incomplete; 188 | 189 | // add order to incompleted list 190 | this.ordersIncompleted.push(extractedOrder); 191 | 192 | // update order status in the data source service 193 | this.ordersService.updateOrderStatus(extractedOrder.id, OrderStatus.Incomplete); 194 | 195 | // show an information snackbar with UNDO option 196 | this.snackBarActionMessage = this.translate.instant("lblMovedToIncompleted"); 197 | this.snackbar1.show(); 198 | } 199 | 200 | public performUndo() { 201 | this.snackbar1.hide(); 202 | if (this.undoOrder != null) { 203 | // search for order with this id in both local completed list and local incompleted list and remove it 204 | if (this.ordersCompleted[this.ordersCompleted.length - 1].id === this.undoOrder.id) { 205 | this.ordersCompleted.pop(); 206 | } else if (this.ordersIncompleted[this.ordersIncompleted.length - 1].id === this.undoOrder.id) { 207 | this.ordersIncompleted.pop(); 208 | } 209 | 210 | // insert back the removed order in the active list 211 | this.ordersActive.splice(this.undoOrderIndex, 0, this.undoOrder); 212 | 213 | // update order status in the data source service 214 | this.ordersService.updateOrderStatus(this.undoOrder.id, OrderStatus.Active); 215 | 216 | this.undoOrder = null; 217 | this.undoOrderIndex = 0; 218 | } 219 | } 220 | 221 | } 222 | -------------------------------------------------------------------------------- /src/app/onboarding/onboarding.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from "@angular/core"; 2 | import { trigger, state, style, animate, transition } from "@angular/animations"; 3 | import { Router } from "@angular/router"; 4 | 5 | import { TranslateService, LangChangeEvent } from "@ngx-translate/core"; 6 | 7 | // this parameter (in percents) defines how much the mouse should be dragged 8 | // compared to the current browser width in order for a slide to be switched 9 | const slideSwitchTreshold: number = 30; // default - 30% 10 | 11 | @Component({ 12 | selector: "app-onboarding", 13 | templateUrl: "./onboarding.component.html", 14 | styleUrls: ["./onboarding.component.css"], 15 | animations: [ 16 | trigger("swipeLeftRightAnimation", [ 17 | state("left", style( { left: "-20%", opacity: "0" } )), // 0 - positioned left (outside of the screen) 18 | state("center", style( { left: "50%", opacity: "1" } ) ), // 1 - positioned center (inside the screen) 19 | state("right", style( { left: "120%", opacity: "0" } ) ), // 2 - positioned right (outside of the screen) 20 | state("move", style( {} ) ), // 3 - this state is when partially dragged with the mouse 21 | 22 | transition("left => center", animate("{{speed}} ease-out")), 23 | transition("right => center", animate("{{speed}} ease-out")), 24 | transition("center => left", animate("{{speed}} ease-out")), 25 | transition("center => right", animate("{{speed}} ease-out")), 26 | 27 | transition("move => center", animate("{{speed}} ease-out")), 28 | transition("move => left", animate("{{speed}} ease")), 29 | transition("move => right", animate("{{speed}} ease")), 30 | transition("left <=> right", animate("5ms ease")), 31 | ]), 32 | ] 33 | }) 34 | export class OnboardingComponent implements OnInit { 35 | 36 | isUserDown: boolean = false; 37 | inSlideSwitchingAnimation: boolean = false; 38 | animationCounter: number = 0; 39 | 40 | userDownInitialX: number; 41 | userDownInitialY: number; 42 | mouseDeltaX: number; 43 | 44 | // 0 - moved to the left (outside the of screen), 1 - center (on screen), 2 - moved to the right (outside of the screen) 45 | currentSlideState: number = 1; 46 | currentSlideIndex: number = 0; 47 | currentSlideInfo: VisibleSlideInfo = new VisibleSlideInfo(); 48 | 49 | slides: Array = new Array(); 50 | leftButtonText: string; 51 | rightButtonText: string; 52 | 53 | constructor(private router: Router, private translate: TranslateService) { 54 | // internationalization 55 | translate.addLangs(["en", "jp"]); 56 | translate.setDefaultLang("en"); 57 | const browserLang = translate.getBrowserLang(); 58 | translate.use(browserLang.match(/en|jp/) ? browserLang : "en"); 59 | //translate.use("jp"); 60 | translate.onLangChange.subscribe((event: LangChangeEvent) => { 61 | this.generateSlidesData(); 62 | this.setCurrentSlide(this.slides[this.currentSlideIndex]); 63 | }); 64 | } 65 | 66 | ngOnInit() { 67 | } 68 | 69 | get getCurrentSlideState() { 70 | switch (this.currentSlideState) { 71 | case 0: return "left"; 72 | case 1: return "center"; 73 | case 2: return "right"; 74 | case 3: return "move"; 75 | } 76 | console.log("!!! Unknow slide state !!!"); 77 | } 78 | 79 | 80 | 81 | // handling the mouse down and touch start events 82 | 83 | mouseDownHandler(args) { 84 | this.userDownHandler(args.clientX, args.clientY); 85 | } 86 | 87 | touchStartHandler(args) { 88 | this.userDownHandler(args.touches[0].clientX, args.touches[0].clientY); 89 | } 90 | 91 | userDownHandler(x: number, y: number) { 92 | this.isUserDown = true; 93 | this.userDownInitialX = x; 94 | this.userDownInitialY = y; 95 | } 96 | 97 | 98 | 99 | // handling the mouse move and touch move events 100 | 101 | mouseMoveHandler(args) { 102 | this.userMoveHandler(args.clientX, args.clientY); 103 | } 104 | 105 | touchMoveHandler(args) { 106 | this.userMoveHandler(args.touches[0].clientX, args.touches[0].clientY); 107 | } 108 | 109 | userMoveHandler(x: number, y: number) { 110 | if (!this.isUserDown) { 111 | return; 112 | } 113 | if (this.currentSlideState !== 3) { 114 | this.currentSlideState = 3; 115 | } 116 | 117 | // calculate mouse movement since mouse down 118 | this.mouseDeltaX = x - this.userDownInitialX; 119 | 120 | // calculate how much the mouse has moved compared to the screen width in percents 121 | let percentageMoved: number = Math.abs(this.mouseDeltaX) * 100 / this.getBrowserRenderWidth(); 122 | 123 | if (this.mouseDeltaX < 0) { 124 | percentageMoved = -percentageMoved; 125 | } 126 | 127 | // calculate left value (in percent) for each layer depending on 128 | // how far the mouse has been moved and each layer's individual accelaration 129 | this.currentSlideInfo.image1Left = Math.round(50 + percentageMoved * this.currentSlideInfo.image1Acceleration) + "%"; 130 | this.currentSlideInfo.image2Left = Math.round(50 + percentageMoved * this.currentSlideInfo.image2Acceleration) + "%"; 131 | this.currentSlideInfo.image3Left = Math.round(50 + percentageMoved * this.currentSlideInfo.image3Acceleration) + "%"; 132 | this.currentSlideInfo.slideTitleLeft = Math.round(50 + percentageMoved * this.currentSlideInfo.slideTitleAcceleration) + "%"; 133 | this.currentSlideInfo.slideTextLeft = Math.round(50 + percentageMoved * this.currentSlideInfo.slideTextAcceleration) + "%"; 134 | 135 | // calculate the opacity for all layers based on how far the mouse has been moved 136 | const opacityValue = (1 - Math.abs(percentageMoved) / 100).toString(); 137 | this.currentSlideInfo.image1Opacity = opacityValue; 138 | this.currentSlideInfo.image2Opacity = opacityValue; 139 | this.currentSlideInfo.image3Opacity = opacityValue; 140 | this.currentSlideInfo.slideTitleOpacity = opacityValue; 141 | this.currentSlideInfo.slideTextOpacity = opacityValue; 142 | 143 | } 144 | 145 | 146 | 147 | // handling the mouse up and touch end events 148 | mouseUpHandler(args) { 149 | this.userUpHandler(); 150 | } 151 | 152 | touchEndHandler(args) { 153 | this.userUpHandler(); 154 | } 155 | 156 | userUpHandler() { 157 | this.isUserDown = false; 158 | 159 | const percentageMoved = Math.abs(this.mouseDeltaX) * 100 / this.getBrowserRenderWidth(); 160 | 161 | // checking if the slide switch treshold has been reached 162 | if (percentageMoved > slideSwitchTreshold) { 163 | // slide switch treshold reached - check pan/swipe direction 164 | if (this.mouseDeltaX < 0) { 165 | // left - next slide 166 | if (this.currentSlideIndex < 3) { 167 | this.animationCounter = 0; 168 | this.inSlideSwitchingAnimation = true; 169 | this.currentSlideState = 0; // animate content to left and switch to next slide 170 | } else { 171 | this.currentSlideState = 1; // last slide reached - get back current slide 172 | } 173 | } else { 174 | // right - previous slide 175 | if (this.currentSlideIndex > 0) { 176 | this.animationCounter = 0; 177 | this.inSlideSwitchingAnimation = true; 178 | this.currentSlideState = 2; // animate content to right and switch to previous slide 179 | } else { 180 | this.currentSlideState = 1; // first slide reached - get back to current slide 181 | } 182 | } 183 | } else { 184 | // slide switch treshold not reached - switching the current slide back to state 1 (center) from 3 (move) 185 | this.currentSlideState = 1; 186 | } 187 | } 188 | 189 | 190 | 191 | // handling the mouse out event 192 | mouseOutHandler(args) { 193 | if (this.isUserDown === true) { 194 | this.userUpHandler(); 195 | } 196 | } 197 | 198 | 199 | 200 | // used to switch to previous slide programmatically 201 | invokePrev() { 202 | if (this.inSlideSwitchingAnimation) return; 203 | if (this.currentSlideIndex > 0) { 204 | // animate content to right and switch to previous slide 205 | this.inSlideSwitchingAnimation = true; 206 | this.animationCounter = 0; 207 | this.currentSlideState = 2; // animate content to right 208 | } 209 | } 210 | 211 | // used to switch to next slide programmatically 212 | invokeNext() { 213 | if (this.inSlideSwitchingAnimation) return; 214 | if (this.currentSlideIndex < 3) { 215 | // animate content to left and switch to next slide 216 | this.inSlideSwitchingAnimation = true; 217 | this.animationCounter = 0; 218 | this.currentSlideState = 0; // animate content to left 219 | } 220 | } 221 | 222 | invokeLeftButton() { 223 | this.router.navigateByUrl("/board"); 224 | } 225 | 226 | invokeRightButton() { 227 | if (this.currentSlideIndex < 3) { 228 | this.invokeNext(); 229 | } else { 230 | this.router.navigateByUrl("/board"); 231 | } 232 | } 233 | 234 | 235 | 236 | // used to trigger several animation one after another 237 | swipeAnimationFinished(ev) { 238 | this.animationCounter++; 239 | if (this.animationCounter == 5) { 240 | if (this.currentSlideState == 0) { 241 | // if the animation has just moved all components to the left 242 | // move them instantly to the right 243 | this.currentSlideState = 2; 244 | } else 245 | if (this.currentSlideState == 2) { 246 | // if the animation has just moved all components to the right 247 | // move them instantly to the left 248 | this.currentSlideState = 0; 249 | } else { 250 | this.animationCounter = 0; 251 | } 252 | } 253 | 254 | if (this.animationCounter == 10) { 255 | if (this.currentSlideState == 0) { 256 | // move to previous slide 257 | this.currentSlideIndex--; 258 | // add the content of the new slide in the visual elements 259 | this.setCurrentSlide(this.slides[this.currentSlideIndex]); 260 | // animate the new content to the center of the screen; 261 | this.currentSlideState = 1; 262 | } else 263 | if (this.currentSlideState == 2) { 264 | // move to next slide 265 | this.currentSlideIndex++; 266 | // add the content of the new slide in the visual elements 267 | this.setCurrentSlide(this.slides[this.currentSlideIndex]); 268 | // animate the new content to the center of the screen; 269 | this.currentSlideState = 1; 270 | } 271 | } 272 | 273 | if (this.animationCounter == 15) { 274 | this.inSlideSwitchingAnimation = false; 275 | } 276 | } 277 | 278 | 279 | 280 | getBrowserRenderWidth() { 281 | return Math.max( 282 | window.innerWidth, 283 | document.body.scrollWidth, 284 | document.documentElement.scrollWidth, 285 | document.body.offsetWidth, 286 | document.documentElement.offsetWidth, 287 | document.documentElement.clientWidth 288 | ); 289 | } 290 | 291 | 292 | 293 | // set the "currentSlideInfo" with the values from the "newSlide" argument 294 | setCurrentSlide(newSlide: SlideInfo) { 295 | this.currentSlideInfo.image1Path = newSlide.image1Path; 296 | this.currentSlideInfo.image1Opacity = ""; 297 | this.currentSlideInfo.image1Acceleration = newSlide.image1Acceleration; 298 | 299 | this.currentSlideInfo.image2Path = newSlide.image2Path; 300 | this.currentSlideInfo.image2Opacity = ""; 301 | this.currentSlideInfo.image2Acceleration = newSlide.image2Acceleration; 302 | 303 | this.currentSlideInfo.image3Path = newSlide.image3Path; 304 | this.currentSlideInfo.image3Opacity = ""; 305 | this.currentSlideInfo.image3Acceleration = newSlide.image3Acceleration; 306 | 307 | this.currentSlideInfo.slideTitle = newSlide.slideTitle; 308 | this.currentSlideInfo.slideTitleOpacity = ""; 309 | this.currentSlideInfo.slideTitleAcceleration = newSlide.slideTitleAcceleration; 310 | 311 | this.currentSlideInfo.slideText = newSlide.slideText; 312 | this.currentSlideInfo.slideTextOpacity = ""; 313 | this.currentSlideInfo.slideTextAcceleration = newSlide.slideTextAcceleration; 314 | 315 | this.currentSlideInfo.slideDotsImagePath = newSlide.slideDotsImagePath; 316 | 317 | switch (this.currentSlideIndex) { 318 | case 0: 319 | this.translate.get("btnSkip").subscribe((res: string) => { this.leftButtonText = res; }); 320 | this.translate.get("btnNext").subscribe((res: string) => { this.rightButtonText = res; }); 321 | break; 322 | case 1: 323 | this.translate.get("btnSkip").subscribe((res: string) => { this.leftButtonText = res; }); 324 | this.translate.get("btnNext").subscribe((res: string) => { this.rightButtonText = res; }); 325 | break; 326 | case 2: 327 | this.translate.get("btnSkip").subscribe((res: string) => { this.leftButtonText = res; }); 328 | this.translate.get("btnNext").subscribe((res: string) => { this.rightButtonText = res; }); 329 | break; 330 | case 3: 331 | this.leftButtonText = ""; 332 | this.translate.get("btnGotIt").subscribe((res: string) => { this.rightButtonText = res; }); 333 | break; 334 | } 335 | } 336 | 337 | 338 | 339 | // generates the slides' data 340 | generateSlidesData() { 341 | const slide1 = new SlideInfo(); 342 | slide1.image1Path = "../../assets/images/onboarding/slide1_circle.png"; 343 | slide1.image1Acceleration = 0.6; 344 | slide1.image2Path = "../../assets/images/onboarding/slide1_pluses.png"; 345 | slide1.image2Acceleration = 0.8; 346 | slide1.image3Path = "../../assets/images/onboarding/slide1_roger.png"; 347 | slide1.image3Acceleration = 1.0; 348 | slide1.slideTitle = this.translate.instant("slide1Title"); 349 | slide1.slideTitleAcceleration = 0.8; 350 | slide1.slideText = this.translate.instant("slide1Text"); 351 | slide1.slideTextAcceleration = 0.6; 352 | slide1.slideDotsImagePath = "../../assets/images/onboarding/onboarding_dots1.png"; 353 | this.slides.push(slide1); 354 | 355 | const slide2 = new SlideInfo(); 356 | slide2.image1Path = "../../assets/images/onboarding/slide2_circle.png"; 357 | slide2.image1Acceleration = 0.6; 358 | slide2.image2Path = "../../assets/images/onboarding/slide2_pluses.png"; 359 | slide2.image2Acceleration = 0.8; 360 | slide2.image3Path = "../../assets/images/onboarding/slide2_big_plus.png"; 361 | slide2.image3Acceleration = 1.0; 362 | slide2.slideTitle = this.translate.instant("slide2Title"); 363 | slide2.slideTitleAcceleration = 0.8; 364 | slide2.slideText = this.translate.instant("slide2Text"); 365 | slide2.slideTextAcceleration = 0.6; 366 | slide2.slideDotsImagePath = "../../assets/images/onboarding/onboarding_dots2.png"; 367 | this.slides.push(slide2); 368 | 369 | const slide3 = new SlideInfo(); 370 | slide3.image1Path = "../../assets/images/onboarding/slide3_circle.png"; 371 | slide3.image1Acceleration = 0.6; 372 | slide3.image2Path = "../../assets/images/onboarding/slide3_pluses.png"; 373 | slide3.image2Acceleration = 0.8; 374 | slide3.image3Path = "../../assets/images/onboarding/slide3_lamp.png"; 375 | slide3.image3Acceleration = 1.0; 376 | slide3.slideTitle = this.translate.instant("slide3Title"); 377 | slide3.slideTitleAcceleration = 0.8; 378 | slide3.slideText = this.translate.instant("slide3Text"); 379 | slide3.slideTextAcceleration = 0.6; 380 | slide3.slideDotsImagePath = "../../assets/images/onboarding/onboarding_dots3.png"; 381 | this.slides.push(slide3); 382 | 383 | const slide4 = new SlideInfo(); 384 | slide4.image1Path = "../../assets/images/onboarding/slide4_circle.png"; 385 | slide4.image1Acceleration = 0.6; 386 | slide4.image2Path = "../../assets/images/onboarding/slide4_pluses.png"; 387 | slide4.image2Acceleration = 0.8; 388 | slide4.image3Path = "../../assets/images/onboarding/slide4_cup.png"; 389 | slide4.image3Acceleration = 1.0; 390 | slide4.slideTitle = this.translate.instant("slide4Title"); 391 | slide4.slideTitleAcceleration = 0.8; 392 | slide4.slideText = this.translate.instant("slide4Text"); 393 | slide4.slideTextAcceleration = 0.6; 394 | slide4.slideDotsImagePath = "../../assets/images/onboarding/onboarding_dots4.png"; 395 | this.slides.push(slide4); 396 | } 397 | 398 | } 399 | 400 | 401 | 402 | // This class holds the static information for a "slide" from the onboarding slides pack. 403 | // There will be an instance of this class for each slide 404 | export class SlideInfo { 405 | image1Path: string; 406 | image1Acceleration: number; 407 | image2Path: string; 408 | image2Acceleration: number; 409 | image3Path: string; 410 | image3Acceleration: number; 411 | slideTitle: string; 412 | slideTitleAcceleration: number; 413 | slideText: string; 414 | slideTextAcceleration: number; 415 | slideDotsImagePath: string; 416 | } 417 | 418 | 419 | 420 | // This class holds the dynamic information of the visible slide. 421 | // In addition to the "SlideInfo" class this class also has the current opacity level and the left positioning. 422 | // With the current implementation there will be one single instance of this class. 423 | export class VisibleSlideInfo { 424 | image1Path: string; 425 | image1Left: string; 426 | image1Opacity: string; 427 | image1Acceleration: number; 428 | 429 | image2Path: string; 430 | image2Left: string; 431 | image2Opacity: string; 432 | image2Acceleration: number; 433 | 434 | image3Path: string; 435 | image3Left: string; 436 | image3Opacity: string; 437 | image3Acceleration: number; 438 | 439 | slideTitle: string; 440 | slideTitleLeft: string; 441 | slideTitleOpacity: string; 442 | slideTitleAcceleration: number; 443 | 444 | slideText: string; 445 | slideTextLeft: string; 446 | slideTextOpacity: string; 447 | slideTextAcceleration: number; 448 | 449 | slideDotsImagePath: string; 450 | } 451 | -------------------------------------------------------------------------------- /src/app/orders-service/orders-mock.ts: -------------------------------------------------------------------------------- 1 | export const ORDERS_MOCK_DATA = [ 2 | { 3 | ID: "R-156649-GT", 4 | CreationDate: "06/24/2017", 5 | Progress: 35, 6 | Status: 0, 7 | Items: [ 8 | { 9 | ID: 8657, 10 | Name: "Table", 11 | Description: "Oak veneer brown stained", 12 | Price: 1050, 13 | Quantity: 2, 14 | Image: "../../assets/images/board/table.png", 15 | Found: false, 16 | Aisle: 76, 17 | Bin: 49 18 | }, 19 | { 20 | ID: 4645, 21 | Name: "Chair", 22 | Description: "Light-gray", 23 | Price: 250, 24 | Quantity: 8, 25 | Image: "../../assets/images/board/chair.png", 26 | Found: true, 27 | Aisle: 80, 28 | Bin: 27 29 | }, 30 | { 31 | ID: 2288, 32 | Name: "Desk", 33 | Description: "White", 34 | Price: 499, 35 | Quantity: 6, 36 | Image: "../../assets/images/board/desk.png", 37 | Found: true, 38 | Aisle: 37, 39 | Bin: 6 40 | }, 41 | { 42 | ID: 4947, 43 | Name: "Magnetic board", 44 | Description: "Can use magnets on the board and write with chalk", 45 | Price: 29, 46 | Quantity: 5, 47 | Image: "../../assets/images/board/magneticBoard.png", 48 | Found: true, 49 | Aisle: 6, 50 | Bin: 45 51 | }, 52 | { 53 | ID: 9041, 54 | Name: "Carpet", 55 | Description: "Low pile, brown", 56 | Price: 101, 57 | Quantity: 5, 58 | Image: "../../assets/images/board/carpet.png", 59 | Found: true, 60 | Aisle: 73, 61 | Bin: 35 62 | } 63 | ] 64 | }, 65 | { 66 | ID: "H-506468-FO", 67 | CreationDate: "06/09/2018", 68 | Progress: 19, 69 | Status: 0, 70 | Items: [ 71 | { 72 | ID: 4589, 73 | Name: "Couch", 74 | Description: "3-seat, dark gray", 75 | Price: 1414, 76 | Quantity: 3, 77 | Image: "../../assets/images/board/couch.png", 78 | Found: true, 79 | Aisle: 60, 80 | Bin: 82 81 | }, 82 | { 83 | ID: 5490, 84 | Name: "Desk", 85 | Description: "Dark-gray", 86 | Price: 1619, 87 | Quantity: 7, 88 | Image: "../../assets/images/board/desk.png", 89 | Found: false, 90 | Aisle: 87, 91 | Bin: 92 92 | }, 93 | { 94 | ID: 5873, 95 | Name: "Oven dish", 96 | Description: "Rectangular, black", 97 | Price: 55, 98 | Quantity: 1, 99 | Image: "../../assets/images/board/ovenDish.png", 100 | Found: false, 101 | Aisle: 11, 102 | Bin: 44 103 | } 104 | ] 105 | }, 106 | { 107 | ID: "W-281286-GT", 108 | CreationDate: "12/20/2018", 109 | Progress: 47, 110 | Status: 1, 111 | Items: [ 112 | { 113 | ID: 5513, 114 | Name: "Couch", 115 | Description: "4-seat, brown", 116 | Price: 4500, 117 | Quantity: 3, 118 | Image: "../../assets/images/board/couch.png", 119 | Found: true, 120 | Aisle: 100, 121 | Bin: 77 122 | }, 123 | { 124 | ID: 9873, 125 | Name: "Carpet", 126 | Description: "High pile, black", 127 | Price: 380, 128 | Quantity: 7, 129 | Image: "../../assets/images/board/carpet.png", 130 | Found: false, 131 | Aisle: 94, 132 | Bin: 5 133 | } 134 | ] 135 | }, 136 | { 137 | ID: "L-739165-QI", 138 | CreationDate: "02/04/2019", 139 | Progress: 45, 140 | Status: 1, 141 | Items: [ 142 | { 143 | ID: 6678, 144 | Name: "TV unit", 145 | Description: "Black-brown", 146 | Price: 5000, 147 | Quantity: 8, 148 | Image: "../../assets/images/board/tvUnit.png", 149 | Found: false, 150 | Aisle: 71, 151 | Bin: 78 152 | }, 153 | { 154 | ID: 9909, 155 | Name: "Desk", 156 | Description: "White, adjustable height", 157 | Price: 812, 158 | Quantity: 7, 159 | Image: "../../assets/images/board/desk.png", 160 | Found: false, 161 | Aisle: 9, 162 | Bin: 98 163 | }, 164 | { 165 | ID: 1968, 166 | Name: "Laptop support", 167 | Description: "Gray", 168 | Price: 45, 169 | Quantity: 10, 170 | Image: "../../assets/images/board/laptopSupport.png", 171 | Found: true, 172 | Aisle: 18, 173 | Bin: 83 174 | } 175 | ] 176 | }, 177 | { 178 | ID: "U-679097-EL", 179 | CreationDate: "05/25/2018", 180 | Progress: 70, 181 | Status: 2, 182 | Items: [ 183 | { 184 | ID: 8541, 185 | Name: "Chair", 186 | Description: "Green armchair, outdoor", 187 | Price: 70, 188 | Quantity: 4, 189 | Image: "../../assets/images/board/chair.png", 190 | Found: true, 191 | Aisle: 83, 192 | Bin: 58 193 | } 194 | ] 195 | }, 196 | { 197 | ID: "P-313076-XH", 198 | CreationDate: "07/31/2018", 199 | Progress: 65, 200 | Status: 0, 201 | Items: [ 202 | { 203 | ID: 1875, 204 | Name: "Coffee mug", 205 | Description: "Black", 206 | Price: 15, 207 | Quantity: 3, 208 | Image: "../../assets/images/board/coffeeMug.png", 209 | Found: false, 210 | Aisle: 50, 211 | Bin: 8 212 | }, 213 | { 214 | ID: 5006, 215 | Name: "Desk", 216 | Description: "Black-brown", 217 | Price: 220, 218 | Quantity: 10, 219 | Image: "../../assets/images/board/desk.png", 220 | Found: false, 221 | Aisle: 70, 222 | Bin: 33 223 | } 224 | ] 225 | }, 226 | { 227 | ID: "W-312357-MO", 228 | CreationDate: "05/06/2018", 229 | Progress: 67, 230 | Status: 2, 231 | Items: [ 232 | { 233 | ID: 3507, 234 | Name: "Nightstand", 235 | Description: "White", 236 | Price: 200, 237 | Quantity: 3, 238 | Image: "../../assets/images/board/nightstand.png", 239 | Found: true, 240 | Aisle: 49, 241 | Bin: 46 242 | }, 243 | { 244 | ID: 4953, 245 | Name: "Table", 246 | Description: "Extendable table, dark brown", 247 | Price: 2449, 248 | Quantity: 7, 249 | Image: "../../assets/images/board/table.png", 250 | Found: true, 251 | Aisle: 49, 252 | Bin: 10 253 | }, 254 | { 255 | ID: 4658, 256 | Name: "Desk pad", 257 | Description: "Black", 258 | Price: 35, 259 | Quantity: 7, 260 | Image: "../../assets/images/board/deskPad.png", 261 | Found: true, 262 | Aisle: 28, 263 | Bin: 16 264 | } 265 | ] 266 | }, 267 | { 268 | ID: "I-526137-FM", 269 | CreationDate: "09/12/2017", 270 | Progress: 47, 271 | Status: 2, 272 | Items: [ 273 | { 274 | ID: 8947, 275 | Name: "Batteries", 276 | Description: "Type AAA", 277 | Price: 5, 278 | Quantity: 3, 279 | Image: "../../assets/images/board/batteries.png", 280 | Found: true, 281 | Aisle: 2, 282 | Bin: 48 283 | } 284 | ] 285 | }, 286 | { 287 | ID: "V-016633-FI", 288 | CreationDate: "03/27/2017", 289 | Progress: 19, 290 | Status: 0, 291 | Items: [ 292 | { 293 | ID: 6613, 294 | Name: "Desk", 295 | Description: "Black-brown, pull-out panel", 296 | Price: 1260, 297 | Quantity: 1, 298 | Image: "../../assets/images/board/desk.png", 299 | Found: true, 300 | Aisle: 14, 301 | Bin: 32 302 | }, 303 | { 304 | ID: 2616, 305 | Name: "Trash can", 306 | Description: "White, plastic", 307 | Price: 20, 308 | Quantity: 7, 309 | Image: "../../assets/images/board/trashCan.png", 310 | Found: false, 311 | Aisle: 96, 312 | Bin: 51 313 | } 314 | ] 315 | }, 316 | { 317 | ID: "Q-911277-MP", 318 | CreationDate: "11/24/2017", 319 | Progress: 83, 320 | Status: 0, 321 | Items: [ 322 | { 323 | ID: 2583, 324 | Name: "Carpet", 325 | Description: "High pile, blue", 326 | Price: 190, 327 | Quantity: 4, 328 | Image: "../../assets/images/board/carpet.png", 329 | Found: true, 330 | Aisle: 47, 331 | Bin: 61 332 | }, 333 | { 334 | ID: 8200, 335 | Name: "Sofa", 336 | Description: "Sleeper sofa, 4-seat, gray", 337 | Price: 7587, 338 | Quantity: 1, 339 | Image: "../../assets/images/board/sofa.png", 340 | Found: false, 341 | Aisle: 47, 342 | Bin: 17 343 | }, 344 | { 345 | ID: 3756, 346 | Name: "Tape measure", 347 | Description: "5m", 348 | Price: 4, 349 | Quantity: 2, 350 | Image: "../../assets/images/board/tapeMeasure.png", 351 | Found: false, 352 | Aisle: 78, 353 | Bin: 48 354 | }, 355 | { 356 | ID: 7328, 357 | Name: "Table", 358 | Description: "Extendable table, black", 359 | Price: 530, 360 | Quantity: 5, 361 | Image: "../../assets/images/board/table.png", 362 | Found: false, 363 | Aisle: 63, 364 | Bin: 22 365 | } 366 | ] 367 | }, 368 | { 369 | ID: "F-488574-ZP", 370 | CreationDate: "10/25/2018", 371 | Progress: 71, 372 | Status: 1, 373 | Items: [ 374 | { 375 | ID: 4417, 376 | Name: "Chair", 377 | Description: "Chrome plated, white", 378 | Price: 1510, 379 | Quantity: 7, 380 | Image: "../../assets/images/board/chair.png", 381 | Found: false, 382 | Aisle: 34, 383 | Bin: 79 384 | } 385 | ] 386 | }, 387 | { 388 | ID: "J-183938-AS", 389 | CreationDate: "03/29/2017", 390 | Progress: 12, 391 | Status: 1, 392 | Items: [ 393 | { 394 | ID: 2388, 395 | Name: "Coffee table", 396 | Description: "Walnut veneer", 397 | Price: 399, 398 | Quantity: 1, 399 | Image: "../../assets/images/board/table.png", 400 | Found: false, 401 | Aisle: 59, 402 | Bin: 65 403 | } 404 | ] 405 | }, 406 | { 407 | ID: "L-572038-RW", 408 | CreationDate: "05/23/2018", 409 | Progress: 47, 410 | Status: 0, 411 | Items: [ 412 | { 413 | ID: 3998, 414 | Name: "Coffee mug", 415 | Description: "White", 416 | Price: 15, 417 | Quantity: 1, 418 | Image: "../../assets/images/board/coffeeMug.png", 419 | Found: true, 420 | Aisle: 99, 421 | Bin: 68 422 | }, 423 | { 424 | ID: 2737, 425 | Name: "Oven dish", 426 | Description: "Rectangular, white", 427 | Price: 70, 428 | Quantity: 1, 429 | Image: "../../assets/images/board/ovenDish.png", 430 | Found: false, 431 | Aisle: 7, 432 | Bin: 72 433 | } 434 | ] 435 | }, 436 | { 437 | ID: "V-802147-KK", 438 | CreationDate: "06/06/2018", 439 | Progress: 26, 440 | Status: 0, 441 | Items: [ 442 | { 443 | ID: 9763, 444 | Name: "Floor lamp", 445 | Description: "White, single-bulb", 446 | Price: 619, 447 | Quantity: 3, 448 | Image: "../../assets/images/board/floorLamp.png", 449 | Found: false, 450 | Aisle: 23, 451 | Bin: 51 452 | }, 453 | { 454 | ID: 6894, 455 | Name: "Tarpaulin rope", 456 | Description: "20m", 457 | Price: 60, 458 | Quantity: 5, 459 | Image: "../../assets/images/board/tarpaulinRope.png", 460 | Found: false, 461 | Aisle: 29, 462 | Bin: 72 463 | }, 464 | { 465 | ID: 7029, 466 | Name: "Table", 467 | Description: "Solid pine, black", 468 | Price: 2049, 469 | Quantity: 2, 470 | Image: "../../assets/images/board/table.png", 471 | Found: true, 472 | Aisle: 19, 473 | Bin: 12 474 | } 475 | ] 476 | }, 477 | { 478 | ID: "N-234981-OY", 479 | CreationDate: "02/04/2019", 480 | Progress: 91, 481 | Status: 0, 482 | Items: [ 483 | { 484 | ID: 7487, 485 | Name: "Shower curtain", 486 | Description: "Brown", 487 | Price: 20, 488 | Quantity: 3, 489 | Image: "../../assets/images/board/showerCurtain.png", 490 | Found: false, 491 | Aisle: 38, 492 | Bin: 77 493 | } 494 | ] 495 | }, 496 | { 497 | ID: "L-996879-YY", 498 | CreationDate: "04/15/2017", 499 | Progress: 27, 500 | Status: 0, 501 | Items: [ 502 | { 503 | ID: 7797, 504 | Name: "Trash can", 505 | Description: "Black, plastic", 506 | Price: 20, 507 | Quantity: 3, 508 | Image: "../../assets/images/board/trashCan.png", 509 | Found: false, 510 | Aisle: 26, 511 | Bin: 76 512 | }, 513 | { 514 | ID: 1145, 515 | Name: "Floor lamp", 516 | Description: "Black, three-bulbs", 517 | Price: 819, 518 | Quantity: 3, 519 | Image: "../../assets/images/board/floorLamp.png", 520 | Found: true, 521 | Aisle: 36, 522 | Bin: 28 523 | } 524 | ] 525 | }, 526 | { 527 | ID: "C-244975-BD", 528 | CreationDate: "04/29/2017", 529 | Progress: 64, 530 | Status: 2, 531 | Items: [ 532 | { 533 | ID: 1699, 534 | Name: "Pencil cup", 535 | Description: "Silver", 536 | Price: 10, 537 | Quantity: 1, 538 | Image: "../../assets/images/board/pencilCase.png", 539 | Found: true, 540 | Aisle: 28, 541 | Bin: 4 542 | } 543 | ] 544 | }, 545 | { 546 | ID: "H-049454-GQ", 547 | CreationDate: "09/28/2018", 548 | Progress: 27, 549 | Status: 0, 550 | Items: [ 551 | { 552 | ID: 3506, 553 | Name: "Towel hanger", 554 | Description: "Silver", 555 | Price: 12, 556 | Quantity: 4, 557 | Image: "../../assets/images/board/towelHanger.png", 558 | Found: false, 559 | Aisle: 43, 560 | Bin: 73 561 | }, 562 | { 563 | ID: 3303, 564 | Name: "Coffee table", 565 | Description: "High-gloss white", 566 | Price: 399, 567 | Quantity: 4, 568 | Image: "../../assets/images/board/table.png", 569 | Found: false, 570 | Aisle: 82, 571 | Bin: 91 572 | }, 573 | { 574 | ID: 9559, 575 | Name: "Table", 576 | Description: "Plastic table, three-legged, white", 577 | Price: 55, 578 | Quantity: 3, 579 | Image: "../../assets/images/board/table.png", 580 | Found: false, 581 | Aisle: 38, 582 | Bin: 80 583 | } 584 | ] 585 | }, 586 | { 587 | ID: "W-614749-GC", 588 | CreationDate: "09/05/2018", 589 | Progress: 15, 590 | Status: 2, 591 | Items: [ 592 | { 593 | ID: 7234, 594 | Name: "Clock", 595 | Description: "Wall clock, white", 596 | Price: 25, 597 | Quantity: 1, 598 | Image: "../../assets/images/board/clock.png", 599 | Found: true, 600 | Aisle: 48, 601 | Bin: 75 602 | } 603 | ] 604 | }, 605 | { 606 | ID: "E-637209-ST", 607 | CreationDate: "01/07/2018", 608 | Progress: 99, 609 | Status: 0, 610 | Items: [ 611 | { 612 | ID: 5759, 613 | Name: "Soap dispenser", 614 | Description: "White", 615 | Price: 7, 616 | Quantity: 2, 617 | Image: "../../assets/images/board/soapDispenser.png", 618 | Found: false, 619 | Aisle: 7, 620 | Bin: 59 621 | }, 622 | { 623 | ID: 7504, 624 | Name: "Shower curtain", 625 | Description: "White", 626 | Price: 20, 627 | Quantity: 3, 628 | Image: "../../assets/images/board/showerCurtain.png", 629 | Found: true, 630 | Aisle: 17, 631 | Bin: 27 632 | } 633 | ] 634 | }, 635 | { 636 | ID: "I-382031-GD", 637 | CreationDate: "04/17/2018", 638 | Status: 3, 639 | Items: [ 640 | { 641 | ID: 5759, 642 | Name: "Soap dispenser", 643 | Description: "White", 644 | Price: 7, 645 | Quantity: 2, 646 | Image: "../../assets/images/board/soapDispenser.png", 647 | Found: false, 648 | Aisle: 7, 649 | Bin: 59 650 | }, 651 | { 652 | ID: 7504, 653 | Name: "Shower curtain", 654 | Description: "White", 655 | Price: 20, 656 | Quantity: 3, 657 | Image: "../../assets/images/board/showerCurtain.png", 658 | Found: false, 659 | Aisle: 17, 660 | Bin: 27 661 | } 662 | ] 663 | }, 664 | { 665 | ID: "E-703619-KD", 666 | CreationDate: "09/28/2018", 667 | Status: 3, 668 | Items: [ 669 | { 670 | ID: 3506, 671 | Name: "Towel hanger", 672 | Description: "Silver", 673 | Price: 12, 674 | Quantity: 4, 675 | Image: "../../assets/images/board/towelHanger.png", 676 | Found: false, 677 | Aisle: 43, 678 | Bin: 73 679 | }, 680 | { 681 | ID: 3303, 682 | Name: "Coffee table", 683 | Description: "High-gloss white", 684 | Price: 399, 685 | Quantity: 4, 686 | Image: "../../assets/images/board/table.png", 687 | Found: false, 688 | Aisle: 82, 689 | Bin: 91 690 | }, 691 | { 692 | ID: 9559, 693 | Name: "Table", 694 | Description: "Plastic table, three-legged, white", 695 | Price: 55, 696 | Quantity: 3, 697 | Image: "../../assets/images/board/table.png", 698 | Found: false, 699 | Aisle: 38, 700 | Bin: 80 701 | } 702 | ] 703 | }, 704 | { 705 | ID: "N-473091-WN", 706 | CreationDate: "06/06/2018", 707 | Status: 3, 708 | Items: [ 709 | { 710 | ID: 9763, 711 | Name: "Floor lamp", 712 | Description: "White, single-bulb", 713 | Price: 619, 714 | Quantity: 3, 715 | Image: "../../assets/images/board/floorLamp.png", 716 | Found: false, 717 | Aisle: 23, 718 | Bin: 51 719 | }, 720 | { 721 | ID: 6894, 722 | Name: "Tarpaulin rope", 723 | Description: "20m", 724 | Price: 60, 725 | Quantity: 5, 726 | Image: "../../assets/images/board/tarpaulinRope.png", 727 | Found: false, 728 | Aisle: 29, 729 | Bin: 72 730 | }, 731 | { 732 | ID: 7029, 733 | Name: "Table", 734 | Description: "Solid pine, black", 735 | Price: 2049, 736 | Quantity: 2, 737 | Image: "../../assets/images/board/table.png", 738 | Found: false, 739 | Aisle: 19, 740 | Bin: 12 741 | } 742 | ] 743 | }, 744 | ]; 745 | --------------------------------------------------------------------------------