├── projects ├── go-tester │ ├── src │ │ ├── assets │ │ │ └── .gitkeep │ │ ├── app │ │ │ ├── app.component.scss │ │ │ ├── components │ │ │ │ ├── search-test │ │ │ │ │ ├── search-test.component.html │ │ │ │ │ └── search-test.component.ts │ │ │ │ ├── test-page-1 │ │ │ │ │ ├── test-page-1.component.html │ │ │ │ │ └── test-page-1.component.ts │ │ │ │ └── test-page-2 │ │ │ │ │ ├── test-page-2.component.ts │ │ │ │ │ └── test-page-2.component.html │ │ │ ├── app.guard.ts │ │ │ ├── app-routing.module.ts │ │ │ ├── app.component.spec.ts │ │ │ ├── app.component.ts │ │ │ ├── app.service.ts │ │ │ ├── app.module.ts │ │ │ └── app.component.html │ │ ├── environments │ │ │ ├── environment.prod.ts │ │ │ └── environment.ts │ │ ├── favicon.ico │ │ ├── index.html │ │ ├── main.ts │ │ ├── test.ts │ │ ├── styles.scss │ │ └── polyfills.ts │ ├── tsconfig.app.json │ ├── tsconfig.spec.json │ ├── tslint.json │ ├── browserslist │ └── karma.conf.js ├── go-lib │ ├── src │ │ ├── lib │ │ │ ├── animations │ │ │ │ ├── _configs.ts │ │ │ │ ├── off-canvas.animation.ts │ │ │ │ ├── toasts.ts │ │ │ │ ├── fade.animation.ts │ │ │ │ ├── route.animation.ts │ │ │ │ └── search.animation.ts │ │ │ ├── components │ │ │ │ ├── go-icon │ │ │ │ │ ├── go-icon.component.html │ │ │ │ │ ├── go-icon.module.ts │ │ │ │ │ ├── go-icon.component.ts │ │ │ │ │ └── go-icon.component.spec.ts │ │ │ │ ├── go-accordion │ │ │ │ │ ├── go-accordion.component.html │ │ │ │ │ ├── go-accordion.component.scss │ │ │ │ │ ├── go-accordion.module.ts │ │ │ │ │ ├── go-accordion-panel.component.ts │ │ │ │ │ ├── go-accordion.component.spec.ts │ │ │ │ │ ├── go-accordion-panel.component.spec.ts │ │ │ │ │ ├── go-accordion-panel.component.html │ │ │ │ │ ├── go-accordion.component.ts │ │ │ │ │ └── go-accordion-panel.component.scss │ │ │ │ ├── go-toaster │ │ │ │ │ ├── go-toaster.model.ts │ │ │ │ │ ├── go-toaster.component.html │ │ │ │ │ ├── go-toaster.component.scss │ │ │ │ │ ├── go-toaster.component.ts │ │ │ │ │ ├── go-toaster.module.ts │ │ │ │ │ └── go-toaster.service.ts │ │ │ │ ├── go-side-nav │ │ │ │ │ ├── nav-item.model.ts │ │ │ │ │ ├── nav-group.model.ts │ │ │ │ │ ├── go-side-nav │ │ │ │ │ │ ├── go-side-nav.component.html │ │ │ │ │ │ ├── go-side-nav.service.ts │ │ │ │ │ │ ├── go-side-nav.component.scss │ │ │ │ │ │ └── go-side-nav.component.ts │ │ │ │ │ ├── go-nav-item │ │ │ │ │ │ ├── go-nav-item.component.ts │ │ │ │ │ │ ├── go-nav-item.component.html │ │ │ │ │ │ └── go-nav-item.component.scss │ │ │ │ │ ├── go-side-nav.module.ts │ │ │ │ │ └── go-nav-group │ │ │ │ │ │ ├── go-nav-group.component.ts │ │ │ │ │ │ ├── go-nav-group.component.scss │ │ │ │ │ │ └── go-nav-group.component.html │ │ │ │ ├── go-modal │ │ │ │ │ ├── go-modal.item.ts │ │ │ │ │ ├── go-modal.directive.ts │ │ │ │ │ ├── go-modal.component.html │ │ │ │ │ ├── go-modal.module.ts │ │ │ │ │ ├── go-modal.service.ts │ │ │ │ │ ├── go-modal.component.spec.ts │ │ │ │ │ ├── go-modal.component.scss │ │ │ │ │ └── go-modal.component.ts │ │ │ │ ├── go-off-canvas │ │ │ │ │ ├── go-off-canvas.interface.ts │ │ │ │ │ ├── go-off-canvas.directive.ts │ │ │ │ │ ├── go-off-canvas.component.html │ │ │ │ │ ├── go-off-canvas.module.ts │ │ │ │ │ ├── go-off-canvas.service.ts │ │ │ │ │ ├── go-off-canvas.component.scss │ │ │ │ │ └── go-off-canvas.component.ts │ │ │ │ ├── go-card │ │ │ │ │ ├── go-card.component.html │ │ │ │ │ ├── go-card.module.ts │ │ │ │ │ ├── go-card.component.ts │ │ │ │ │ ├── go-card.component.scss │ │ │ │ │ └── go-card.component.spec.ts │ │ │ │ ├── go-table │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── go-table-paging.model.ts │ │ │ │ │ ├── go-table-sort.model.ts │ │ │ │ │ ├── go-table-column.component.ts │ │ │ │ │ ├── go-table-utils.ts │ │ │ │ │ ├── go-table.module.ts │ │ │ │ │ ├── go-table-config.model.ts │ │ │ │ │ ├── go-table.component.spec.ts │ │ │ │ │ ├── go-table.component.scss │ │ │ │ │ ├── go-table.component.html │ │ │ │ │ └── go-table.component.ts │ │ │ │ ├── go-icon-button │ │ │ │ │ ├── go-icon-button.component.html │ │ │ │ │ ├── go-icon-button.module.ts │ │ │ │ │ ├── go-icon-button.component.scss │ │ │ │ │ └── go-icon-button.component.ts │ │ │ │ ├── go-button │ │ │ │ │ ├── go-button.component.html │ │ │ │ │ ├── go-button.module.ts │ │ │ │ │ ├── go-button.component.ts │ │ │ │ │ └── go-button.component.spec.ts │ │ │ │ ├── go-toast │ │ │ │ │ ├── go-toast.module.ts │ │ │ │ │ ├── go-toast.component.html │ │ │ │ │ ├── go-toast.component.ts │ │ │ │ │ ├── go-toast.component.scss │ │ │ │ │ └── go-toast.component.spec.ts │ │ │ │ ├── go-action-sheet │ │ │ │ │ ├── go-action-sheet.component.html │ │ │ │ │ ├── go-action-sheet.module.ts │ │ │ │ │ ├── go-panel │ │ │ │ │ │ ├── go-panel.component.spec.ts │ │ │ │ │ │ ├── go-panel.component.html │ │ │ │ │ │ ├── go-panel.component.ts │ │ │ │ │ │ └── go-panel.component.scss │ │ │ │ │ ├── go-action-sheet.component.spec.ts │ │ │ │ │ ├── go-action-sheet.component.ts │ │ │ │ │ └── go-action-sheet.component.scss │ │ │ │ ├── go-loader │ │ │ │ │ ├── go-loader.module.ts │ │ │ │ │ ├── go-loader.component.html │ │ │ │ │ ├── go-loader.component.ts │ │ │ │ │ ├── go-loader.component.scss │ │ │ │ │ └── go-loader.component.spec.ts │ │ │ │ ├── go-header │ │ │ │ │ ├── go-header.module.ts │ │ │ │ │ ├── go-header.component.spec.ts │ │ │ │ │ ├── go-header.component.html │ │ │ │ │ ├── go-header.component.ts │ │ │ │ │ └── go-header.component.scss │ │ │ │ ├── go-layout │ │ │ │ │ ├── go-layout.component.html │ │ │ │ │ ├── go-layout.component.scss │ │ │ │ │ ├── go-layout.component.ts │ │ │ │ │ ├── go-layout.module.ts │ │ │ │ │ └── go-layout.component.spec.ts │ │ │ │ └── go-search │ │ │ │ │ ├── go-search.module.ts │ │ │ │ │ ├── go-search.component.spec.ts │ │ │ │ │ ├── go-search.component.html │ │ │ │ │ ├── go-search.service.ts │ │ │ │ │ ├── go-search.component.ts │ │ │ │ │ └── go-search.component.scss │ │ │ └── go-shared.module.ts │ │ ├── styles │ │ │ ├── _mixins.scss │ │ │ └── _variables.scss │ │ ├── test.ts │ │ └── public_api.ts │ ├── ng-package.json │ ├── tslint.json │ ├── tsconfig.spec.json │ ├── package.json │ ├── karma.conf.js │ └── tsconfig.lib.json └── go-tester-e2e │ ├── src │ ├── app.po.ts │ └── app.e2e-spec.ts │ ├── tsconfig.e2e.json │ └── protractor.conf.js ├── sass-port.sh ├── .travis.yml ├── local_install.js ├── .editorconfig ├── .github └── ISSUE_TEMPLATE │ ├── --feature-request.md │ └── --bug-report.md ├── .gitignore ├── tsconfig.json ├── tslint.json ├── LICENSE ├── package.json ├── README.md ├── CODE_OF_CONDUCT.md └── angular.json /projects/go-tester/src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /projects/go-tester/src/app/app.component.scss: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /projects/go-tester/src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true 3 | }; 4 | -------------------------------------------------------------------------------- /projects/go-tester/src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eligolding/goponents/master/projects/go-tester/src/favicon.ico -------------------------------------------------------------------------------- /projects/go-lib/src/lib/animations/_configs.ts: -------------------------------------------------------------------------------- 1 | export const timing = '.5s '; 2 | export const easing = 'cubic-bezier(.25, .8, .25, 1)'; 3 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-icon/go-icon.component.html: -------------------------------------------------------------------------------- 1 | 5 | {{ icon }} 6 | 7 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-accordion/go-accordion.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | -------------------------------------------------------------------------------- /sass-port.sh: -------------------------------------------------------------------------------- 1 | declare stylePath=`dirname $0`/projects/go-lib/src/styles 2 | declare buildStylePath=`dirname $0`/dist/go-lib/styles 3 | cp -R $stylePath $buildStylePath -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-toaster/go-toaster.model.ts: -------------------------------------------------------------------------------- 1 | export interface ToastInterface { 2 | header?: string; 3 | message?: string; 4 | type?: string; 5 | } 6 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-side-nav/nav-item.model.ts: -------------------------------------------------------------------------------- 1 | export interface NavItem { 2 | description?: string; 3 | route: string; 4 | routeIcon?: string; 5 | routeTitle: string; 6 | } 7 | -------------------------------------------------------------------------------- /projects/go-lib/ng-package.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "../../node_modules/ng-packagr/ng-package.schema.json", 3 | "dest": "../../dist/go-lib", 4 | "lib": { 5 | "entryFile": "src/public_api.ts" 6 | } 7 | } -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-modal/go-modal.item.ts: -------------------------------------------------------------------------------- 1 | import { Type } from '@angular/core'; 2 | 3 | export class GoModalItem { 4 | constructor(public component: Type, public bindings: {}) {} 5 | } 6 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-off-canvas/go-off-canvas.interface.ts: -------------------------------------------------------------------------------- 1 | import { Type } from "@angular/core"; 2 | 3 | export interface GoOffCanvasItem { 4 | component: Type<{}>; 5 | bindings: {}; 6 | } 7 | -------------------------------------------------------------------------------- /projects/go-tester-e2e/src/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, by, element } from 'protractor'; 2 | 3 | export class AppPage { 4 | navigateTo() { 5 | return browser.get('/'); 6 | } 7 | 8 | getTitleText() { 9 | return element(by.css('app-root h1')).getText(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "8.11.4" 4 | addons: 5 | chrome: stable 6 | before_install: 7 | - npm i -g npm@latest 8 | - npm install -g @angular/cli@7.3.9 9 | cache: 10 | npm: false 11 | script: 12 | - ng test go-lib --watch=false --browsers=ChromeHeadless 13 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-modal/go-modal.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, ViewContainerRef } from '@angular/core'; 2 | 3 | @Directive({ 4 | selector: '[go-modal-host]', 5 | }) 6 | export class GoModalDirective { 7 | constructor(public viewContainerRef: ViewContainerRef) { } 8 | } 9 | -------------------------------------------------------------------------------- /local_install.js: -------------------------------------------------------------------------------- 1 | const npm = require('npm'); 2 | 3 | var filePath = './dist/go-lib/tangoe-goponents-' + require('./projects/go-lib/package.json').version + '.tgz' 4 | npm.load(function(err) { 5 | 6 | npm.commands.install([filePath], function(er, data) { 7 | console.log(er); 8 | }); 9 | 10 | }); -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-side-nav/nav-group.model.ts: -------------------------------------------------------------------------------- 1 | import { NavItem } from './nav-item.model'; 2 | 3 | export interface NavGroup { 4 | description?: string; 5 | expanded?: boolean; 6 | routeIcon?: string; 7 | routeTitle: string; 8 | subRoutes: Array; 9 | } 10 | -------------------------------------------------------------------------------- /projects/go-tester-e2e/tsconfig.e2e.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../out-tsc/app", 5 | "module": "commonjs", 6 | "target": "es5", 7 | "types": [ 8 | "jasmine", 9 | "jasminewd2", 10 | "node" 11 | ] 12 | } 13 | } -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-card/go-card.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 |
6 | 7 |
8 |
9 | -------------------------------------------------------------------------------- /projects/go-tester/tsconfig.app.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../out-tsc/app", 5 | "resolveJsonModule": true, 6 | "esModuleInterop": true, 7 | "types": [] 8 | }, 9 | "exclude": [ 10 | "test.ts", 11 | "**/*.spec.ts" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-off-canvas/go-off-canvas.directive.ts: -------------------------------------------------------------------------------- 1 | import { Directive, ViewContainerRef } from "@angular/core"; 2 | 3 | @Directive({ 4 | selector: '[go-off-canvas-host]' 5 | }) 6 | export class GoOffCanvasDirective { 7 | constructor( 8 | public viewContainerRef: ViewContainerRef 9 | ) { } 10 | } 11 | -------------------------------------------------------------------------------- /projects/go-lib/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tslint.json", 3 | "rules": { 4 | "directive-selector": [ 5 | true, 6 | "attribute", 7 | "go", 8 | "camelCase" 9 | ], 10 | "component-selector": [ 11 | true, 12 | "element", 13 | "go", 14 | "kebab-case" 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /projects/go-lib/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts" 12 | ], 13 | "include": [ 14 | "**/*.spec.ts", 15 | "**/*.d.ts" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /projects/go-tester/src/app/components/search-test/search-test.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
{{ item.id }}{{ item.name.first }}{{ item.name.last }}{{ item.email }}{{ item.gender }}{{ item.ip_address }}
-------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-table/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Use this file for a single import point 3 | * to expose all table-based classes or interfaces 4 | */ 5 | 6 | export { GoTableConfig, GoTableDataSource } from './go-table-config.model'; 7 | export { GoTablePageConfig } from './go-table-paging.model'; 8 | export { GoTableSortConfig, SortDirection } from './go-table-sort.model'; 9 | -------------------------------------------------------------------------------- /projects/go-tester/tsconfig.spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../out-tsc/spec", 5 | "types": [ 6 | "jasmine", 7 | "node" 8 | ] 9 | }, 10 | "files": [ 11 | "src/test.ts", 12 | "src/polyfills.ts" 13 | ], 14 | "include": [ 15 | "**/*.spec.ts", 16 | "**/*.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-icon-button/go-icon-button.component.html: -------------------------------------------------------------------------------- 1 | 14 | -------------------------------------------------------------------------------- /projects/go-tester/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | GoTester 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-table/go-table-paging.model.ts: -------------------------------------------------------------------------------- 1 | export class GoTablePageConfig { 2 | offset: number = 0; 3 | pageSizes: number[] = [10, 25, 50]; 4 | perPage: number = 10; 5 | 6 | constructor(fields?: { 7 | offset?: number, 8 | pageSizes: number[], 9 | perPage?: number 10 | }) { 11 | if (fields) Object.assign(this, fields); 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-side-nav/go-side-nav/go-side-nav.component.html: -------------------------------------------------------------------------------- 1 |
3 | 6 | 7 |
8 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-modal/go-modal.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 |
6 | 7 | 8 |
9 |
-------------------------------------------------------------------------------- /projects/go-tester-e2e/src/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { AppPage } from './app.po'; 2 | 3 | describe('workspace-project 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.getTitleText()).toEqual('Welcome to go-tester!'); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-card/go-card.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | import { GoCardComponent } from './go-card.component'; 5 | 6 | @NgModule({ 7 | declarations: [GoCardComponent], 8 | imports: [ 9 | CommonModule 10 | ], 11 | exports: [GoCardComponent] 12 | }) 13 | 14 | export class GoCardModule { } 15 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-icon/go-icon.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | import { GoIconComponent } from './go-icon.component'; 5 | 6 | @NgModule({ 7 | declarations: [GoIconComponent], 8 | imports: [ 9 | CommonModule 10 | ], 11 | exports: [GoIconComponent] 12 | }) 13 | 14 | export class GoIconModule { } 15 | -------------------------------------------------------------------------------- /projects/go-tester/tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tslint.json", 3 | "rules": { 4 | "directive-selector": [ 5 | true, 6 | "attribute", 7 | "app", 8 | "camelCase" 9 | ], 10 | "component-selector": [ 11 | true, 12 | "element", 13 | "app", 14 | "kebab-case" 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-accordion/go-accordion.component.scss: -------------------------------------------------------------------------------- 1 | @import '~@tangoe/gosheets/base/_variables'; 2 | 3 | .go-accordion { 4 | border-radius: $global-radius; 5 | display: flex; 6 | flex-direction: column; 7 | min-width: 200px; 8 | } 9 | 10 | .go-accordion--theme-light { 11 | background: $theme-light-bg; 12 | border: 1px solid $theme-light-border; 13 | color: $theme-light-color; 14 | } 15 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-card/go-card.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, ViewEncapsulation } from '@angular/core'; 2 | 3 | @Component({ 4 | encapsulation: ViewEncapsulation.None, 5 | selector: 'go-card', 6 | styleUrls: ['./go-card.component.scss'], 7 | templateUrl: './go-card.component.html' 8 | }) 9 | 10 | export class GoCardComponent { 11 | 12 | @Input() showHeader: boolean = true; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-side-nav/go-side-nav/go-side-nav.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Observable, of as observableOf, BehaviorSubject } from 'rxjs'; 3 | 4 | @Injectable({ 5 | providedIn: 'root' 6 | }) 7 | 8 | export class GoSideNavService { 9 | public navOpen = true; 10 | 11 | constructor() { } 12 | 13 | toggleNav() { 14 | this.navOpen = !this.navOpen; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-table/go-table-sort.model.ts: -------------------------------------------------------------------------------- 1 | export class GoTableSortConfig { 2 | column: string; 3 | direction: SortDirection = SortDirection.ascending; 4 | 5 | constructor(fields?: { 6 | column: string, 7 | direction?: SortDirection 8 | }) { 9 | if (fields) Object.assign(this, fields); 10 | } 11 | } 12 | 13 | export enum SortDirection { 14 | ascending = 1, 15 | descending = 0 16 | } 17 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-toaster/go-toaster.component.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
6 | 9 |
10 |
-------------------------------------------------------------------------------- /projects/go-tester/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.error(err)); 13 | -------------------------------------------------------------------------------- /projects/go-tester/browserslist: -------------------------------------------------------------------------------- 1 | # This file is currently used by autoprefixer to adjust CSS to support the below specified browsers 2 | # For additional information regarding the format and rule options, please see: 3 | # https://github.com/browserslist/browserslist#queries 4 | # 5 | # For IE 9-11 support, please remove 'not' from the last line of the file and adjust as needed 6 | 7 | > 0.5% 8 | last 2 versions 9 | Firefox ESR 10 | not dead 11 | IE 9-11 -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-button/go-button.component.html: -------------------------------------------------------------------------------- 1 | 16 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/--feature-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F4A1Feature request" 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-button/go-button.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | import { GoButtonComponent } from './go-button.component'; 5 | import { GoIconModule } from '../go-icon/go-icon.module'; 6 | 7 | @NgModule({ 8 | declarations: [GoButtonComponent], 9 | imports: [ 10 | CommonModule, 11 | GoIconModule 12 | ], 13 | exports: [GoButtonComponent] 14 | }) 15 | 16 | export class GoButtonModule { } 17 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-toaster/go-toaster.component.scss: -------------------------------------------------------------------------------- 1 | @import '~@tangoe/gosheets/base/_variables'; 2 | @import '../../../styles/mixins'; 3 | 4 | .go-toaster { 5 | bottom: 0; 6 | overflow: hidden; 7 | padding: 1rem; 8 | position: fixed; 9 | right: 0; 10 | width: 400px; 11 | z-index: z-index(toaster); 12 | 13 | @media(max-width: $breakpoint-mobile) { 14 | left: 0; 15 | max-width: 100vw; 16 | width: auto; 17 | } 18 | } 19 | 20 | .go-toaster__item { 21 | padding-top: 1rem; 22 | } 23 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-toast/go-toast.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | import { GoIconModule } from '../go-icon/go-icon.module'; 5 | 6 | import { GoToastComponent } from './go-toast.component'; 7 | 8 | @NgModule({ 9 | declarations: [ 10 | GoToastComponent 11 | ], 12 | imports: [ 13 | CommonModule, 14 | GoIconModule 15 | ], 16 | exports: [ 17 | GoToastComponent 18 | ] 19 | }) 20 | 21 | export class GoToastModule { } 22 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-toaster/go-toaster.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | import { GoToasterService } from './go-toaster.service'; 4 | import { toastAnimation } from '../../animations/toasts'; 5 | 6 | @Component({ 7 | animations: [toastAnimation], 8 | selector: 'go-toaster', 9 | templateUrl: './go-toaster.component.html', 10 | styleUrls: ['./go-toaster.component.scss'] 11 | }) 12 | export class GoToasterComponent { 13 | constructor(public goToasterService: GoToasterService) { } 14 | } 15 | -------------------------------------------------------------------------------- /projects/go-lib/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@tangoe/goponents", 3 | "version": "1.1.1", 4 | "repository": { 5 | "type": "git", 6 | "url": "git+https://github.com/mobi/goponents.git" 7 | }, 8 | "author": "Tangoe Mobile", 9 | "description": "A library of UI components for Angular v7+.", 10 | "license": "MIT", 11 | "peerDependencies": { 12 | "@tangoe/gosheets": "^1.0.0" 13 | }, 14 | "devDependencies": { 15 | "@angular/common": "^7.0.0", 16 | "@angular/core": "^7.0.0", 17 | "@tangoe/gosheets": "^1.0.0" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-side-nav/go-nav-item/go-nav-item.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input } from '@angular/core'; 2 | import { NavItem } from '../nav-item.model'; 3 | import { GoSideNavService } from '../go-side-nav/go-side-nav.service'; 4 | 5 | @Component({ 6 | selector: 'go-nav-item', 7 | templateUrl: './go-nav-item.component.html', 8 | styleUrls: ['./go-nav-item.component.scss'] 9 | }) 10 | export class GoNavItemComponent { 11 | @Input() navItem: NavItem; 12 | 13 | constructor (public navService: GoSideNavService) { } 14 | } 15 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-icon-button/go-icon-button.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | import { GoIconModule } from '../go-icon/go-icon.module'; 5 | 6 | import { GoIconButtonComponent } from './go-icon-button.component'; 7 | 8 | @NgModule({ 9 | declarations: [ 10 | GoIconButtonComponent 11 | ], 12 | imports: [ 13 | CommonModule, 14 | GoIconModule 15 | ], 16 | exports: [ 17 | GoIconButtonComponent 18 | ] 19 | }) 20 | export class GoIconButtonModule { } 21 | -------------------------------------------------------------------------------- /projects/go-lib/src/styles/_mixins.scss: -------------------------------------------------------------------------------- 1 | @mixin transition($prop){ 2 | -webkit-transition: $prop .25s cubic-bezier(.25,.8,.25,1); 3 | -moz-transition: $prop .25s cubic-bezier(.25,.8,.25,1); 4 | -ms-transition: $prop .25s cubic-bezier(.25,.8,.25,1); 5 | -o-transition: $prop .25s cubic-bezier(.25,.8,.25,1); 6 | transition: $prop .25s cubic-bezier(.25,.8,.25,1); 7 | } 8 | 9 | $z-index: ( 10 | navigation: 100, 11 | search: 200, 12 | off-canvas: 300, 13 | modal: 400, 14 | toaster: 500, 15 | ); 16 | 17 | @function z-index($key) { 18 | @return map-get($z-index, $key); 19 | } 20 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/animations/off-canvas.animation.ts: -------------------------------------------------------------------------------- 1 | import { 2 | animate, 3 | state, 4 | style, 5 | transition, 6 | trigger 7 | } from '@angular/animations'; 8 | 9 | import { easing, timing } from './_configs'; 10 | 11 | export const offCanvasAnimation = trigger('offCanvas', [ 12 | state('slideIn', style({ 13 | transform: 'translateX(-300px)' 14 | })), 15 | state('slideOut', style({ 16 | transform: 'translateX(0)', 17 | visibility: 'hidden' 18 | })), 19 | transition('slideIn <=> slideOut', [ 20 | animate(timing + easing) 21 | ]) 22 | ]); 23 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-icon-button/go-icon-button.component.scss: -------------------------------------------------------------------------------- 1 | @import '~@tangoe/gosheets/base/variables'; 2 | @import '~@tangoe/gosheets/base/mixins'; 3 | 4 | .go-icon-button { 5 | @include transition(background-color); 6 | 7 | background: $theme-light-bg; 8 | border: 0; 9 | border-radius: $global-radius--round; 10 | cursor: pointer; 11 | display: inline-flex; 12 | outline: none; 13 | padding: .5rem; 14 | 15 | .go-icon-button__icon { 16 | display: flex; 17 | } 18 | 19 | &:hover, &:active, &:focus { 20 | background: $theme-light-bg-hover; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-icon-button/go-icon-button.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, EventEmitter, Input, Output } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'go-icon-button', 5 | templateUrl: './go-icon-button.component.html', 6 | styleUrls: ['./go-icon-button.component.scss'] 7 | }) 8 | export class GoIconButtonComponent { 9 | @Input() buttonDisabled: boolean; 10 | @Input() buttonIcon: string; 11 | @Input() buttonTitle: string; 12 | 13 | @Output() handleClick = new EventEmitter(); 14 | 15 | public clicked(): void { 16 | this.handleClick.emit(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-modal/go-modal.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | import { GoModalComponent } from './go-modal.component'; 5 | import { GoModalDirective } from './go-modal.directive'; 6 | 7 | import { GoIconModule } from '../go-icon/go-icon.module'; 8 | 9 | @NgModule({ 10 | declarations: [ 11 | GoModalComponent, 12 | GoModalDirective 13 | ], 14 | imports: [ 15 | CommonModule, 16 | GoIconModule 17 | ], 18 | exports: [GoModalComponent] 19 | }) 20 | 21 | export class GoModalModule { } 22 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/--bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: "\U0001F41EBug report" 3 | about: Create a report to help us improve 4 | title: "[BUG]" 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-accordion/go-accordion.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | import { GoAccordionComponent } from './go-accordion.component'; 5 | import { GoAccordionPanelComponent } from './go-accordion-panel.component'; 6 | 7 | @NgModule({ 8 | declarations: [ 9 | GoAccordionComponent, 10 | GoAccordionPanelComponent 11 | ], 12 | imports: [ 13 | CommonModule 14 | ], 15 | exports: [ 16 | GoAccordionComponent, 17 | GoAccordionPanelComponent 18 | ] 19 | }) 20 | 21 | export class GoAccordionModule { } 22 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-action-sheet/go-action-sheet.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 | 6 |
9 |
10 |
11 | 12 |
13 |
14 |
15 |
16 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/animations/toasts.ts: -------------------------------------------------------------------------------- 1 | import { 2 | animate, 3 | style, 4 | transition, 5 | trigger 6 | } from '@angular/animations'; 7 | 8 | import { easing, timing } from './_configs'; 9 | 10 | export const toastAnimation = trigger('toastAnimation', [ 11 | transition(':enter', [ 12 | style({ 13 | height: 0, 14 | opacity: 0 15 | }), 16 | animate(timing + easing, style({ 17 | height: '*', 18 | opacity: 1 19 | })) 20 | ]), 21 | transition(':leave', [ 22 | animate(timing + easing, style({ 23 | paddingTop: 0, 24 | opacity: 0, 25 | height: 0 26 | })) 27 | ]) 28 | ]); 29 | -------------------------------------------------------------------------------- /projects/go-tester/src/app/app.guard.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { 3 | ActivatedRouteSnapshot, 4 | CanActivate, 5 | Router, 6 | RouterStateSnapshot 7 | } from '@angular/router'; 8 | 9 | import { Observable } from 'rxjs'; 10 | 11 | @Injectable() 12 | export class AppGuard implements CanActivate { 13 | 14 | constructor(private router: Router) { } 15 | 16 | canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable { 17 | return new Observable(observer => { 18 | setTimeout(() => { 19 | observer.next(true); 20 | }, 1000); 21 | }); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-loader/go-loader.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | import { GoIconModule } from '../go-icon/go-icon.module'; 5 | import { GoLoaderComponent } from './go-loader.component'; 6 | 7 | import { NgModule } from '@angular/core'; 8 | 9 | @NgModule({ 10 | declarations: [ 11 | GoLoaderComponent 12 | ], 13 | imports: [ 14 | BrowserAnimationsModule, 15 | CommonModule, 16 | GoIconModule 17 | ], 18 | exports: [ 19 | GoLoaderComponent 20 | ] 21 | }) 22 | 23 | export class GoLoaderModule { } 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | /out-tsc 7 | 8 | # dependencies 9 | /node_modules 10 | 11 | # IDEs and editors 12 | /.idea 13 | .project 14 | .classpath 15 | .c9/ 16 | *.launch 17 | .settings/ 18 | *.sublime-workspace 19 | 20 | # IDE - VSCode 21 | .vscode/* 22 | !.vscode/settings.json 23 | !.vscode/tasks.json 24 | !.vscode/launch.json 25 | !.vscode/extensions.json 26 | 27 | # misc 28 | /.sass-cache 29 | /connect.lock 30 | /coverage 31 | /libpeerconnection.log 32 | npm-debug.log 33 | yarn-error.log 34 | testem.log 35 | /typings 36 | 37 | # System Files 38 | .DS_Store 39 | Thumbs.db 40 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-off-canvas/go-off-canvas.component.html: -------------------------------------------------------------------------------- 1 |
7 |
8 | 26 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-table/go-table-column.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, ContentChild, Input, TemplateRef } from '@angular/core'; 2 | import { extractFieldData } from './go-table-utils'; 3 | 4 | @Component({ 5 | selector: 'go-table-column', 6 | template: '' 7 | }) 8 | export class GoTableColumnComponent { 9 | @Input() field: string; 10 | @Input() title: string; 11 | @Input() width: number; 12 | 13 | @ContentChild('goTableCell') goTableCell: TemplateRef; 14 | @ContentChild('goTableHead') goTableHead: TemplateRef; 15 | 16 | constructor() { } 17 | 18 | getFieldData(item: any) { 19 | return extractFieldData(this.field, item); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "baseUrl": "./", 5 | "importHelpers": true, 6 | "outDir": "./dist/out-tsc", 7 | "sourceMap": true, 8 | "declaration": false, 9 | "module": "es2015", 10 | "moduleResolution": "node", 11 | "emitDecoratorMetadata": true, 12 | "experimentalDecorators": true, 13 | "target": "es5", 14 | "typeRoots": [ 15 | "node_modules/@types" 16 | ], 17 | "lib": [ 18 | "es2018", 19 | "dom" 20 | ], 21 | "paths": { 22 | "go-lib": [ 23 | "dist/go-lib" 24 | ], 25 | "go-lib/*": [ 26 | "dist/go-lib/*" 27 | ] 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-action-sheet/go-action-sheet.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | import { GoIconModule } from '../go-icon/go-icon.module'; 5 | import { GoActionSheetComponent } from './go-action-sheet.component'; 6 | import { GoPanelComponent } from '../go-action-sheet/go-panel/go-panel.component'; 7 | @NgModule({ 8 | declarations: [ 9 | GoActionSheetComponent, 10 | GoPanelComponent 11 | ], 12 | imports: [ 13 | CommonModule, 14 | GoIconModule 15 | ], 16 | exports: [ 17 | GoActionSheetComponent, 18 | GoPanelComponent 19 | ] 20 | }) 21 | 22 | export class GoActionSheetModule { } 23 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-icon/go-icon.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'go-icon', 5 | templateUrl: 'go-icon.component.html' 6 | }) 7 | export class GoIconComponent { 8 | @Input() icon: string; 9 | @Input() iconModifier: string; 10 | @Input() iconClass: string; 11 | 12 | public classObject(): object { 13 | let classes: object = {}; // tslint:disable-line:prefer-const 14 | 15 | if (this.iconModifier) { 16 | classes[`go-icon--${this.iconModifier}`] = true; 17 | } 18 | 19 | if (this.iconClass) { 20 | classes[this.iconClass] = true; 21 | } 22 | 23 | return classes; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "tslint-angular" 4 | ], 5 | "rules": { 6 | "no-inferrable-types": false, 7 | "ordered-imports": [ 8 | true, 9 | { 10 | "import-sources-order": "case-insensitive", 11 | "named-imports-order": "case-insensitive", 12 | "module-source-path": "any" 13 | } 14 | ], 15 | "typedef": [ 16 | true, 17 | "call-signature", 18 | "arrow-call-signature", 19 | "parameter", 20 | "arrow-parameter", 21 | "property-declaration", 22 | "variable-declaration", 23 | "member-variable-declaration", 24 | "object-destructuring", 25 | "array-destructuring" 26 | ] 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-side-nav/go-nav-item/go-nav-item.component.html: -------------------------------------------------------------------------------- 1 | 18 | -------------------------------------------------------------------------------- /projects/go-tester/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 | -------------------------------------------------------------------------------- /projects/go-tester/src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // This file can be replaced during build by using the `fileReplacements` array. 2 | // `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. 3 | // The list of file replacements can be found in `angular.json`. 4 | 5 | export const environment = { 6 | production: false 7 | }; 8 | 9 | /* 10 | * For easier debugging in development mode, you can import the following file 11 | * to ignore zone related error stack frames such as `zone.run`, `zoneDelegate.invokeTask`. 12 | * 13 | * This import should be commented out in production mode because it will have a negative impact 14 | * on performance if an error is thrown. 15 | */ 16 | // import 'zone.js/dist/zone-error'; // Included with Angular CLI. 17 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-off-canvas/go-off-canvas.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from "@angular/core"; 2 | import { CommonModule } from "@angular/common"; 3 | import { BrowserModule } from '@angular/platform-browser'; 4 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; 5 | 6 | import { GoOffCanvasComponent } from "./go-off-canvas.component"; 7 | import { GoOffCanvasDirective } from "./go-off-canvas.directive"; 8 | 9 | @NgModule({ 10 | declarations: [ 11 | GoOffCanvasComponent, 12 | GoOffCanvasDirective 13 | ], 14 | imports: [ 15 | BrowserAnimationsModule, 16 | BrowserModule, 17 | CommonModule 18 | ], 19 | exports: [ 20 | GoOffCanvasComponent 21 | ] 22 | }) 23 | export class GoOffCanvasModule {} 24 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-accordion/go-accordion-panel.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, Input, Output, EventEmitter, ViewEncapsulation } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'go-accordion-panel', 5 | templateUrl: './go-accordion-panel.component.html', 6 | styleUrls: ['./go-accordion-panel.component.scss'], 7 | encapsulation: ViewEncapsulation.None 8 | }) 9 | export class GoAccordionPanelComponent implements OnInit { 10 | 11 | @Input() expanded: boolean = false; 12 | @Input() icon: string = null; 13 | @Input() title: string; 14 | 15 | @Output() toggle: EventEmitter = new EventEmitter(); 16 | 17 | constructor() { } 18 | 19 | ngOnInit() { 20 | this.expanded = this.expanded || false; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /projects/go-lib/src/styles/_variables.scss: -------------------------------------------------------------------------------- 1 | // Colors 2 | $base-primary: #65B360; 3 | 4 | // Branding 5 | $brand-color: $base-primary; 6 | $brand-color-active: darken($base-primary, 7%); 7 | $brand-color-hover: darken($base-primary, 10%); 8 | $brand-color-dark: darken($base-primary, 15%); 9 | $brand-color-darker: darken($base-primary, 20%); 10 | $brand-color-gradient: linear-gradient(to right, $base-primary, $brand-color-hover); 11 | 12 | // Structure 13 | $side-nav-width: 15.5rem; 14 | $side-nav-width--collapsed: 3.2rem; 15 | 16 | // SideNav 17 | $inner-side-nav-font-size: 0.875rem; 18 | $inner-side-nav-padding: $column-gutter--half $column-gutter--three-quarters $column-gutter--half 3.2rem; 19 | $outer-side-nav-padding: 1rem 1rem 1rem 0; 20 | $side-nav-letter-spacing: .02rem; 21 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-loader/go-loader.component.html: -------------------------------------------------------------------------------- 1 | 7 | loading animation 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-side-nav/go-side-nav/go-side-nav.component.scss: -------------------------------------------------------------------------------- 1 | @import '~@tangoe/gosheets/base/_variables'; 2 | @import '../../../../styles/variables'; 3 | @import '../../../../styles/mixins'; 4 | 5 | .go-side-nav { 6 | background: $theme-dark-bg; 7 | color: $theme-dark-color; 8 | display: flex; 9 | flex-direction: column; 10 | flex-grow: 1; 11 | height: 100%; 12 | overflow-y: auto; 13 | padding: 2rem 0; 14 | width: $side-nav-width; 15 | z-index: z-index(navigation); 16 | 17 | @media(max-width: $breakpoint-mobile) { 18 | display: none; 19 | 20 | &.go-side-nav--show-mobile { 21 | display: flex; 22 | width: 100vw; 23 | } 24 | } 25 | 26 | &.go-side-nav--collapsed { 27 | width: $side-nav-width--collapsed; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-toast/go-toast.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 |
6 |
7 |
{{ header }}
8 |

{{ message }}

9 |
10 |
11 | 14 |
15 |
16 | -------------------------------------------------------------------------------- /projects/go-lib/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('@angular-devkit/build-angular/plugins/karma') 12 | ], 13 | client: { 14 | clearContext: false // leave Jasmine Spec Runner output visible in browser 15 | }, 16 | reporters: ['dots'], 17 | port: 9876, 18 | colors: true, 19 | logLevel: config.LOG_INFO, 20 | autoWatch: true, 21 | browsers: ['Chrome'], 22 | singleRun: false 23 | }); 24 | }; 25 | -------------------------------------------------------------------------------- /projects/go-lib/src/test.ts: -------------------------------------------------------------------------------- 1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files 2 | 3 | import 'core-js/es7/reflect'; 4 | import 'zone.js/dist/zone'; 5 | import 'zone.js/dist/zone-testing'; 6 | import { getTestBed } from '@angular/core/testing'; 7 | import { 8 | BrowserDynamicTestingModule, 9 | platformBrowserDynamicTesting 10 | } from '@angular/platform-browser-dynamic/testing'; 11 | 12 | declare const require: any; 13 | 14 | // First, initialize the Angular testing environment. 15 | getTestBed().initTestEnvironment( 16 | BrowserDynamicTestingModule, 17 | platformBrowserDynamicTesting() 18 | ); 19 | // Then we find all the tests. 20 | const context = require.context('./', true, /\.spec\.ts$/); 21 | // And load the modules. 22 | context.keys().map(context); 23 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-header/go-header.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | 4 | import { GoIconButtonModule} from '../go-icon-button/go-icon-button.module'; 5 | import { GoSideNavModule } from '../go-side-nav/go-side-nav.module'; 6 | 7 | import { GoSideNavService } from '../go-side-nav/go-side-nav/go-side-nav.service'; 8 | 9 | import { GoHeaderComponent } from './go-header.component'; 10 | 11 | @NgModule({ 12 | declarations: [ 13 | GoHeaderComponent 14 | ], 15 | imports: [ 16 | CommonModule, 17 | GoIconButtonModule, 18 | GoSideNavModule 19 | ], 20 | exports: [ 21 | GoHeaderComponent 22 | ], 23 | providers: [ 24 | GoSideNavService 25 | ] 26 | }) 27 | 28 | export class GoHeaderModule { } 29 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-action-sheet/go-panel/go-panel.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { GoPanelComponent } from './go-panel.component'; 4 | 5 | describe('GoPanelComponent', () => { 6 | let component: GoPanelComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ GoPanelComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(GoPanelComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-action-sheet/go-panel/go-panel.component.html: -------------------------------------------------------------------------------- 1 | 5 | 6 | {{icon}} 7 | 8 | 9 | 10 | 11 | 12 | 20 | 21 | -------------------------------------------------------------------------------- /projects/go-tester/src/app/app-routing.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { RouterModule, Routes } from '@angular/router'; 3 | 4 | import { TestPage1Component } from './components/test-page-1/test-page-1.component'; 5 | import { TestPage2Component } from './components/test-page-2/test-page-2.component'; 6 | import { AppGuard } from './app.guard'; 7 | 8 | const routes: Routes = [ 9 | { path: '', redirectTo: 'test-page-1', pathMatch: 'full' }, 10 | { path: 'test-page-1', component: TestPage1Component, canActivate: [AppGuard] }, 11 | { path: 'test-page-2', component: TestPage2Component, canActivate: [AppGuard]} 12 | ]; 13 | 14 | @NgModule({ 15 | imports: [ 16 | RouterModule.forRoot(routes) 17 | ], 18 | exports: [ 19 | RouterModule 20 | ] 21 | }) 22 | export class AppRoutesModule { } 23 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-accordion/go-accordion.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { GoAccordionComponent } from './go-accordion.component'; 4 | 5 | describe('AccordionComponent', () => { 6 | let component: GoAccordionComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ GoAccordionComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(GoAccordionComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-layout/go-layout.component.html: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 | 7 |
9 | 11 |
14 | 15 |
16 |
17 |
18 |
19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-table/go-table-utils.ts: -------------------------------------------------------------------------------- 1 | export function extractFieldData(key: string, obj: object) { 2 | if (key) { 3 | return key.split('.').reduce((p, c) => p && p[c], obj); 4 | } 5 | return ''; 6 | } 7 | 8 | export function sortBy(key: string, reverse: boolean) { 9 | return (a: any, b: any) => { 10 | let aFieldData = extractFieldData(key, a); 11 | let bFieldData = extractFieldData(key, b); 12 | aFieldData = typeof aFieldData === 'string' ? aFieldData.toLowerCase() : aFieldData; 13 | bFieldData = typeof bFieldData === 'string' ? bFieldData.toLowerCase() : bFieldData; 14 | 15 | if (aFieldData < bFieldData) { 16 | return reverse ? -1 : 1; 17 | } 18 | 19 | if (aFieldData > bFieldData) { 20 | return reverse ? 1 : -1; 21 | } 22 | 23 | return 0; 24 | }; 25 | } 26 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-card/go-card.component.scss: -------------------------------------------------------------------------------- 1 | @import '~@tangoe/gosheets/base/_variables'; 2 | @import '../../../styles/variables'; 3 | @import "../../../styles/mixins"; 4 | 5 | .card { 6 | background: $theme-light-bg; 7 | border-radius: $global-radius; 8 | box-shadow: $global-box-shadow; 9 | display: flex; 10 | flex-direction: column; 11 | padding: 1rem; 12 | } 13 | 14 | .card__header { 15 | display: flex; 16 | justify-content: space-between; 17 | padding-bottom: 1rem; 18 | } 19 | 20 | .card__action-list { 21 | display: flex; 22 | 23 | li { 24 | cursor: pointer; 25 | padding: 0 0.4rem; 26 | user-select: none; 27 | @include transition(all); 28 | 29 | &:last-child { 30 | padding-right: 0; 31 | } 32 | 33 | &:hover { 34 | color: $brand-color; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-action-sheet/go-action-sheet.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { GoActionSheetComponent } from './go-action-sheet.component'; 4 | 5 | describe('GoActionSheetComponent', () => { 6 | let component: GoActionSheetComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ GoActionSheetComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(GoActionSheetComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-action-sheet/go-panel/go-panel.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, Output, EventEmitter } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'go-panel', 5 | templateUrl: './go-panel.component.html', 6 | styleUrls: ['./go-panel.component.scss'] 7 | }) 8 | export class GoPanelComponent { 9 | 10 | @Input() danger: boolean; 11 | @Input() showHeader: boolean; 12 | @Input() icon: string; 13 | @Input() externalLink: string; 14 | @Input() panelContent: string; 15 | 16 | @Output() action: EventEmitter = new EventEmitter(); 17 | 18 | constructor() { } 19 | 20 | panelClasses(): object { 21 | return { 22 | 'go-panel--danger': this.danger, 23 | 'go-panel--header': this.showHeader 24 | } 25 | } 26 | 27 | handleAction(): void { 28 | this.action.emit(); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-toaster/go-toaster.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { BrowserModule } from '@angular/platform-browser'; 3 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; 4 | import { CommonModule } from '@angular/common'; 5 | 6 | import { GoToasterService } from './go-toaster.service'; 7 | import { GoToasterComponent } from './go-toaster.component'; 8 | import { GoToastModule } from '../go-toast/go-toast.module'; 9 | 10 | @NgModule({ 11 | declarations: [ 12 | GoToasterComponent 13 | ], 14 | imports: [ 15 | BrowserAnimationsModule, 16 | BrowserModule, 17 | CommonModule, 18 | GoToastModule 19 | ], 20 | providers: [ 21 | GoToasterService 22 | ], 23 | exports: [ 24 | GoToasterComponent 25 | ] 26 | }) 27 | 28 | export class GoToasterModule { } 29 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-accordion/go-accordion-panel.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { GoAccordionPanelComponent } from './go-accordion-panel.component'; 4 | 5 | describe('GoAccordionPanelComponent', () => { 6 | let component: GoAccordionPanelComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ GoAccordionPanelComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(GoAccordionPanelComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-modal/go-modal.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | import { GoModalItem } from './go-modal.item'; 4 | import { Subject } from 'rxjs/internal/Subject'; 5 | 6 | @Injectable() 7 | export class GoModalService { 8 | activeModalComponent: Subject = new Subject(); 9 | modalOpen: Subject = new Subject(); 10 | 11 | constructor() { 12 | this.modalOpen.next(false); 13 | } 14 | 15 | openModal(component: any, bindings: {}) : void { 16 | this.setComponent(component, bindings); 17 | this.toggleModal(true); 18 | } 19 | 20 | setComponent(component: any, bindings: {}) : void { 21 | this.activeModalComponent.next(new GoModalItem(component, bindings)); 22 | } 23 | 24 | toggleModal(open: boolean = true) : void { 25 | this.modalOpen.next(open); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-search/go-search.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { ReactiveFormsModule } from '@angular/forms'; 4 | import { BrowserModule } from '@angular/platform-browser'; 5 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; 6 | 7 | import { GoIconModule } from '../go-icon/go-icon.module'; 8 | import { GoLoaderModule } from '../go-loader/go-loader.module'; 9 | 10 | import { GoSearchComponent } from './go-search.component'; 11 | 12 | @NgModule({ 13 | declarations: [GoSearchComponent], 14 | imports: [ 15 | BrowserAnimationsModule, 16 | BrowserModule, 17 | CommonModule, 18 | GoIconModule, 19 | GoLoaderModule, 20 | ReactiveFormsModule 21 | ], 22 | exports: [GoSearchComponent] 23 | }) 24 | 25 | export class GoSearchModule { } 26 | -------------------------------------------------------------------------------- /projects/go-lib/tsconfig.lib.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "../../out-tsc/lib", 5 | "target": "es2015", 6 | "module": "es2015", 7 | "moduleResolution": "node", 8 | "declaration": true, 9 | "sourceMap": true, 10 | "inlineSources": true, 11 | "emitDecoratorMetadata": true, 12 | "experimentalDecorators": true, 13 | "importHelpers": true, 14 | "types": [], 15 | "lib": [ 16 | "dom", 17 | "es2018" 18 | ] 19 | }, 20 | "angularCompilerOptions": { 21 | "annotateForClosureCompiler": true, 22 | "skipTemplateCodegen": true, 23 | "strictMetadataEmit": true, 24 | "fullTemplateTypeCheck": true, 25 | "strictInjectionParameters": true, 26 | "enableResourceInlining": true 27 | }, 28 | "exclude": [ 29 | "src/test.ts", 30 | "**/*.spec.ts" 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/animations/fade.animation.ts: -------------------------------------------------------------------------------- 1 | import { 2 | animate, 3 | state, 4 | style, 5 | transition, 6 | trigger 7 | } from '@angular/animations'; 8 | 9 | import { easing, timing } from './_configs'; 10 | 11 | export const fadeAnimation = trigger('fade', [ 12 | state('in', style({ 13 | opacity: 1, 14 | visibility: 'visible' 15 | })), 16 | state('out', style({ 17 | opacity: 0, 18 | visibility: 'hidden' 19 | })), 20 | transition('in <=> out', [ 21 | animate(timing + easing) 22 | ]) 23 | ]); 24 | 25 | export const fadeTemplateAnimation = trigger('fadeTemplate', [ 26 | transition(':enter', [ 27 | style({ 28 | opacity: 0 29 | }), 30 | animate(timing + easing, style({ 31 | opacity: 1 32 | })) 33 | ]), 34 | transition(':leave', [ 35 | animate(timing + easing, style({ 36 | opacity: 0 37 | })) 38 | ]) 39 | ]); 40 | -------------------------------------------------------------------------------- /projects/go-tester-e2e/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 | './src/**/*.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: require('path').join(__dirname, './tsconfig.e2e.json') 25 | }); 26 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); 27 | } 28 | }; -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-accordion/go-accordion-panel.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | {{ icon }} 5 | 6 | 7 | 8 | expand_more 9 | 10 |
11 |
12 |
13 | 14 |
15 |
16 |
-------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-side-nav/go-side-nav.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { RouterModule } from '@angular/router'; 4 | 5 | import { GoIconModule } from '../go-icon/go-icon.module'; 6 | 7 | import { GoSideNavComponent } from './go-side-nav/go-side-nav.component'; 8 | import { GoNavGroupComponent } from './go-nav-group/go-nav-group.component'; 9 | import { GoNavItemComponent } from './go-nav-item/go-nav-item.component'; 10 | 11 | @NgModule({ 12 | declarations: [ 13 | GoSideNavComponent, 14 | GoNavGroupComponent, 15 | GoNavItemComponent 16 | ], 17 | imports: [ 18 | CommonModule, 19 | GoIconModule, 20 | RouterModule 21 | ], 22 | exports: [ 23 | GoSideNavComponent, 24 | GoNavGroupComponent, 25 | GoNavItemComponent 26 | ] 27 | }) 28 | 29 | export class GoSideNavModule { } 30 | -------------------------------------------------------------------------------- /projects/go-tester/src/app/components/test-page-1/test-page-1.component.html: -------------------------------------------------------------------------------- 1 | 7 | 8 | Thing 1 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-off-canvas/go-off-canvas.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from "@angular/core"; 2 | import { Subject } from 'rxjs/internal/Subject'; 3 | import { GoOffCanvasItem } from "./go-off-canvas.interface"; 4 | 5 | @Injectable({ 6 | providedIn: 'root' 7 | }) 8 | export class GoOffCanvasService { 9 | activeOffCanvasComponent: Subject = new Subject(); 10 | offCanvasOpen: Subject = new Subject(); 11 | 12 | constructor() { 13 | this.setOffCanvasStatus(false); 14 | } 15 | 16 | public openOffCanvas(offCanvasItem: GoOffCanvasItem): void { 17 | this.activeOffCanvasComponent.next(offCanvasItem); 18 | this.setOffCanvasStatus(true); 19 | } 20 | 21 | public closeOffCanvas(): void { 22 | this.setOffCanvasStatus(false); 23 | } 24 | 25 | private setOffCanvasStatus(isOpen: boolean = true): void { 26 | this.offCanvasOpen.next(isOpen); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-header/go-header.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { GoHeaderComponent } from './go-header.component'; 4 | import { GoIconButtonModule } from '../go-icon-button/go-icon-button.module'; 5 | 6 | describe('GoHeaderComponent', () => { 7 | let component: GoHeaderComponent; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(async(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [ GoHeaderComponent ], 13 | imports: [ 14 | GoIconButtonModule 15 | ] 16 | }) 17 | .compileComponents(); 18 | })); 19 | 20 | beforeEach(() => { 21 | fixture = TestBed.createComponent(GoHeaderComponent); 22 | component = fixture.componentInstance; 23 | fixture.detectChanges(); 24 | }); 25 | 26 | it('should create', () => { 27 | expect(component).toBeTruthy(); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-table/go-table.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { CommonModule } from '@angular/common'; 3 | import { BrowserModule } from '@angular/platform-browser'; 4 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; 5 | 6 | import { GoIconModule } from '../go-icon/go-icon.module'; 7 | import { GoLoaderModule } from '../go-loader/go-loader.module'; 8 | 9 | import { GoTableColumnComponent } from './go-table-column.component'; 10 | import { GoTableComponent } from './go-table.component'; 11 | 12 | @NgModule({ 13 | declarations: [ 14 | GoTableColumnComponent, 15 | GoTableComponent 16 | ], 17 | imports: [ 18 | BrowserAnimationsModule, 19 | BrowserModule, 20 | CommonModule, 21 | GoIconModule, 22 | GoLoaderModule 23 | ], 24 | exports: [ 25 | GoTableColumnComponent, 26 | GoTableComponent 27 | ] 28 | }) 29 | 30 | export class GoTableModule { } 31 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/animations/route.animation.ts: -------------------------------------------------------------------------------- 1 | import { 2 | animate, 3 | query, 4 | style, 5 | transition, 6 | trigger 7 | } from '@angular/animations'; 8 | 9 | import { easing, timing } from './_configs'; 10 | 11 | export const routerAnimation = 12 | trigger('routerAnimation', [ 13 | transition('* <=> *', [ 14 | query(':enter', 15 | [ 16 | style({ opacity: 0 }) 17 | ], 18 | { optional: true } 19 | ), 20 | 21 | query(':leave', 22 | [ 23 | style({ opacity: 1 }), 24 | animate(timing + easing, style({ opacity: 0, transform: 'scale(0.95)' })) 25 | ], 26 | { optional: true } 27 | ), 28 | 29 | query(':enter', 30 | [ 31 | style({ opacity: 0, transform: 'scale(0.95)' }), 32 | animate(timing + easing, style({ opacity: 1, transform: 'scale(1)' })) 33 | ], 34 | { optional: true } 35 | ) 36 | ]) 37 | ]); 38 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-table/go-table-config.model.ts: -------------------------------------------------------------------------------- 1 | import { GoTablePageConfig } from './go-table-paging.model'; 2 | import { GoTableSortConfig } from './go-table-sort.model'; 3 | 4 | export class GoTableConfig { 5 | dataMode: GoTableDataSource = GoTableDataSource.client; 6 | noDataText: string = 'No Data'; 7 | pageable: boolean = true; 8 | pageConfig: GoTablePageConfig = new GoTablePageConfig(); 9 | sortConfig?: GoTableSortConfig; 10 | sortable: boolean = true; 11 | tableData: any[]; 12 | totalCount: number = null; 13 | 14 | constructor(fields?: { 15 | dataMode?: GoTableDataSource, 16 | noDataText?: string, 17 | pageable?: boolean, 18 | pageConfig?: GoTablePageConfig, 19 | sortConfig?: GoTableSortConfig, 20 | sortable?: boolean, 21 | tableData: any[], 22 | totalCount?: number 23 | }) { 24 | if (fields) Object.assign(this, fields); 25 | } 26 | } 27 | 28 | export enum GoTableDataSource { 29 | client, 30 | server 31 | } 32 | -------------------------------------------------------------------------------- /projects/go-tester/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('@angular-devkit/build-angular/plugins/karma') 12 | ], 13 | client: { 14 | clearContext: false // leave Jasmine Spec Runner output visible in browser 15 | }, 16 | coverageIstanbulReporter: { 17 | dir: require('path').join(__dirname, '../../coverage'), 18 | reports: ['html', 'lcovonly'], 19 | fixWebpackSourcePaths: true 20 | }, 21 | reporters: ['progress'], 22 | port: 9876, 23 | colors: true, 24 | logLevel: config.LOG_INFO, 25 | autoWatch: true, 26 | browsers: ['Chrome'], 27 | singleRun: false 28 | }); 29 | }; 30 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-modal/go-modal.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { GoModalComponent } from './go-modal.component'; 4 | import { GoIconModule } from '../go-icon/go-icon.module'; 5 | import { GoModalService } from './go-modal.service'; 6 | 7 | describe('GoModalComponent', () => { 8 | let component: GoModalComponent; 9 | let fixture: ComponentFixture; 10 | 11 | beforeEach(async(() => { 12 | TestBed.configureTestingModule({ 13 | declarations: [ 14 | GoModalComponent 15 | ], 16 | imports: [ GoIconModule ], 17 | providers: [ GoModalService ] 18 | }) 19 | .compileComponents(); 20 | })); 21 | 22 | beforeEach(() => { 23 | fixture = TestBed.createComponent(GoModalComponent); 24 | component = fixture.componentInstance; 25 | fixture.detectChanges(); 26 | }); 27 | 28 | it('should create', () => { 29 | expect(component).toBeTruthy(); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-header/go-header.component.html: -------------------------------------------------------------------------------- 1 |
2 |
4 | 8 | 9 |
11 | 14 |
15 |
16 |
19 | 20 |
21 |
22 | 23 |
24 |
25 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-layout/go-layout.component.scss: -------------------------------------------------------------------------------- 1 | @import '~@tangoe/gosheets/base/_variables'; 2 | 3 | body { 4 | margin: 0; 5 | } 6 | 7 | .go-layout { 8 | background: $theme-light-app-bg; 9 | display: flex; 10 | flex-direction: column; 11 | height: 100vh; 12 | overflow: hidden; 13 | } 14 | 15 | .go-layout__nav { 16 | max-height: 100%; 17 | overflow-y: auto; 18 | } 19 | 20 | .go-layout__content { 21 | display: flex; 22 | flex-grow: 1; 23 | } 24 | 25 | .go-layout__route-container { 26 | display: flex; 27 | flex-grow: 1; 28 | position: relative; 29 | } 30 | 31 | .go-layout__route-container-outlet ~ * { 32 | height: 100%; 33 | overflow-x: hidden; 34 | overflow-y: auto; 35 | padding: 2rem; 36 | position: absolute; 37 | width: 100%; 38 | } 39 | 40 | .go-route-loader { 41 | align-items: center; 42 | background: transparentize($theme-light-app-bg, 0.25%); 43 | display: flex; 44 | height: 100%; 45 | justify-content: center; 46 | overflow: hidden; 47 | position: absolute; 48 | width: 100%; 49 | } 50 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Tangoe 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-loader/go-loader.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, HostBinding, Input } from '@angular/core'; 2 | import { fadeTemplateAnimation } from '../../animations/fade.animation'; 3 | 4 | @Component({ 5 | selector: 'go-loader', 6 | templateUrl: './go-loader.component.html', 7 | styleUrls: ['./go-loader.component.scss'], 8 | animations: [ 9 | fadeTemplateAnimation 10 | ] 11 | }) 12 | export class GoLoaderComponent { 13 | @Input() loaderSize: string = 'medium'; 14 | @Input() loaderType: string = 'neutral'; 15 | 16 | @HostBinding('@fadeTemplate') 17 | public fadeTemplate: boolean = true; 18 | 19 | //#region Public Methods 20 | 21 | loaderClasses(): object { 22 | return { 23 | 'go-loader--small': this.loaderSize === 'small', 24 | 'go-loader--medium': this.loaderSize === 'medium', 25 | 'go-loader--large': this.loaderSize === 'large', 26 | 'go-loader--negative': this.loaderType === 'negative', 27 | 'go-loader--neutral': this.loaderType === 'neutral', 28 | 'go-loader--positive': this.loaderType === 'positive' 29 | }; 30 | } 31 | 32 | //#endregion 33 | } 34 | -------------------------------------------------------------------------------- /projects/go-tester/src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { TestBed, async } from '@angular/core/testing'; 2 | import { AppComponent } from './app.component'; 3 | 4 | describe('AppComponent', () => { 5 | beforeEach(async(() => { 6 | TestBed.configureTestingModule({ 7 | declarations: [ 8 | AppComponent 9 | ], 10 | }).compileComponents(); 11 | })); 12 | 13 | it('should create the app', () => { 14 | const fixture = TestBed.createComponent(AppComponent); 15 | const app = fixture.debugElement.componentInstance; 16 | expect(app).toBeTruthy(); 17 | }); 18 | 19 | it(`should have as title 'go-tester'`, () => { 20 | const fixture = TestBed.createComponent(AppComponent); 21 | const app = fixture.debugElement.componentInstance; 22 | expect(app.title).toEqual('go-tester'); 23 | }); 24 | 25 | it('should render title in a h1 tag', () => { 26 | const fixture = TestBed.createComponent(AppComponent); 27 | fixture.detectChanges(); 28 | const compiled = fixture.debugElement.nativeElement; 29 | expect(compiled.querySelector('h1').textContent).toContain('Welcome to go-tester!'); 30 | }); 31 | }); 32 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-action-sheet/go-action-sheet.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, Input, HostListener, ElementRef } from '@angular/core'; 2 | @Component({ 3 | selector: 'go-action-sheet', 4 | templateUrl: './go-action-sheet.component.html', 5 | styleUrls: ['./go-action-sheet.component.scss'] 6 | }) 7 | export class GoActionSheetComponent { 8 | @Input() shiftLeft: boolean = false; 9 | 10 | 11 | @HostListener('document:click', ['$event.target']) 12 | onDocumentClick(target: HTMLElement) { 13 | this.closeActionSheetEvent(target); 14 | } 15 | 16 | showContent = false; 17 | 18 | constructor( 19 | private elementRef: ElementRef, 20 | ) { } 21 | 22 | triggerAS() { 23 | this.showContent = !this.showContent; 24 | } 25 | 26 | containerClass() { 27 | return { 28 | 'go-action-sheet__content-container--active': this.showContent, 29 | 'go-action-sheet__content-container--shift-left': this.shiftLeft 30 | } 31 | } 32 | 33 | private closeActionSheetEvent(target: HTMLElement): void { 34 | if (!this.elementRef.nativeElement.contains(target)) { 35 | this.showContent = false; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-search/go-search.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | import { ReactiveFormsModule } from '@angular/forms'; 3 | import { CommonModule } from '@angular/common'; 4 | 5 | import { GoSearchComponent } from './go-search.component'; 6 | 7 | import { GoIconModule } from '../go-icon/go-icon.module'; 8 | import { GoLoaderModule } from '../go-loader/go-loader.module'; 9 | 10 | describe('GoSearchComponent', () => { 11 | let component: GoSearchComponent; 12 | let fixture: ComponentFixture; 13 | 14 | beforeEach(async(() => { 15 | TestBed.configureTestingModule({ 16 | declarations: [ GoSearchComponent ], 17 | imports: [ 18 | CommonModule, 19 | GoIconModule, 20 | GoLoaderModule, 21 | ReactiveFormsModule 22 | ] 23 | }) 24 | .compileComponents(); 25 | })); 26 | 27 | beforeEach(() => { 28 | fixture = TestBed.createComponent(GoSearchComponent); 29 | component = fixture.componentInstance; 30 | fixture.detectChanges(); 31 | }); 32 | 33 | it('should create', () => { 34 | expect(component).toBeTruthy(); 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /projects/go-tester/src/app/components/search-test/search-test.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | import { GoSearchService } from '../../../../../go-lib/src/public_api'; 4 | 5 | import { AppService } from '../../app.service'; 6 | 7 | @Component({ 8 | selector: 'app-search-test', 9 | templateUrl: './search-test.component.html' 10 | }) 11 | export class SearchTestComponent implements OnInit { 12 | 13 | results: any[]; 14 | 15 | constructor( 16 | private searchService: GoSearchService, 17 | private appService: AppService 18 | ) { } 19 | 20 | ngOnInit() { 21 | this.searchService.searchTerm.subscribe(searchTerm => { 22 | 23 | // this section is dependent upon what the data looks like 24 | this.appService 25 | .getMockSearch(searchTerm) 26 | .subscribe(results => { 27 | setTimeout(() => { 28 | if (results.length === 0) { 29 | this.results = null; 30 | this.searchService.notFoundResponse(); 31 | } else { 32 | this.results = results; 33 | this.searchService.successResponse(); 34 | } 35 | }, 1000); 36 | }); 37 | }); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-modal/go-modal.component.scss: -------------------------------------------------------------------------------- 1 | @import '~@tangoe/gosheets/base/_variables'; 2 | @import '../../../styles/mixins'; 3 | 4 | .go-modal { 5 | align-items: center; 6 | background: transparentize($color: $base-dark, $amount: 0.1); 7 | display: flex; 8 | height: 100%; 9 | justify-content: center; 10 | left: 0; 11 | opacity: 0; 12 | position: absolute; 13 | top: 0; 14 | visibility: hidden; 15 | width: 100%; 16 | z-index: z-index(modal); 17 | @include transition(all); 18 | } 19 | 20 | .go-modal__container { 21 | background: $theme-light-bg; 22 | border-radius: $global-radius; 23 | box-shadow: $global-box-shadow; 24 | color: $theme-light-color; 25 | max-height: 80%; 26 | max-width: 32.5rem; 27 | padding: 2rem 1rem 1rem; 28 | position: relative; 29 | overflow-x: hidden; 30 | overflow-y: auto; 31 | transform: scale(1.1); 32 | @include transition(all); 33 | } 34 | 35 | .go-modal.go-modal--visible { 36 | opacity: 1; 37 | visibility: visible; 38 | 39 | .go-modal__container { 40 | transform: scale(1); 41 | } 42 | } 43 | 44 | .go-modal__close { 45 | color: $theme-light-color; 46 | cursor: pointer; 47 | padding: 0.5rem; 48 | position: absolute; 49 | right: 0; 50 | top: 0; 51 | } 52 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-loader/go-loader.component.scss: -------------------------------------------------------------------------------- 1 | @import '~@tangoe/gosheets/base/variables'; 2 | @import '~@tangoe/gosheets/base/mixins'; 3 | 4 | $loader-sizes: (small: 50px, medium: 100px, large: 150px); 5 | $loader-speeds: (outer: 1.25s, middle: 1s, inner: .75s); 6 | $loader-colors: ( 7 | negative: $ui-color-negative, 8 | neutral: $ui-color-neutral, 9 | positive: $ui-color-positive 10 | ); 11 | 12 | .go-loader { 13 | display: inline-block; 14 | height: map-get($loader-sizes, medium); 15 | position: relative; 16 | width: map-get($loader-sizes, medium); 17 | 18 | path { 19 | @include transition(fill, .5s); 20 | 21 | fill: $ui-color-neutral; 22 | } 23 | } 24 | 25 | @each $name, $size in $loader-sizes { 26 | .go-loader--#{$name} { 27 | height: $size; 28 | width: $size; 29 | } 30 | } 31 | 32 | @each $name, $color in $loader-colors { 33 | .go-loader--#{$name} path { 34 | fill: $color; 35 | } 36 | } 37 | 38 | @each $name, $speed in $loader-speeds { 39 | .go-loader__#{$name} { 40 | animation: rotate $speed linear infinite; 41 | transform-origin: center center; 42 | } 43 | } 44 | 45 | @keyframes rotate { 46 | from { 47 | transform: rotate(0deg); 48 | } 49 | 50 | to { 51 | transform: rotate(360deg); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-side-nav/go-nav-group/go-nav-group.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, EventEmitter, Input, OnInit, Output, ViewEncapsulation } from '@angular/core'; 2 | import { NavGroup } from '../nav-group.model'; 3 | import { NavItem } from '../nav-item.model'; 4 | import { GoSideNavService } from '../go-side-nav/go-side-nav.service'; 5 | 6 | @Component({ 7 | selector: 'go-nav-group', 8 | templateUrl: './go-nav-group.component.html', 9 | styleUrls: ['./go-nav-group.component.scss'], 10 | encapsulation: ViewEncapsulation.None 11 | }) 12 | export class GoNavGroupComponent implements OnInit { 13 | @Input() navItem: NavGroup | NavItem; 14 | @Input() class: string; 15 | @Output() closeNavs = new EventEmitter(); 16 | 17 | group: NavGroup; 18 | 19 | constructor (public navService: GoSideNavService) { } 20 | 21 | ngOnInit(): void { 22 | // Using this to do type checking between NavGroup and NavItem in the html 23 | this.group = this.navItem as NavGroup; 24 | } 25 | 26 | expand(navGroup: NavGroup): void { 27 | navGroup.expanded = !navGroup.expanded; 28 | 29 | if (!this.navService.navOpen) { 30 | this.navService.toggleNav(); 31 | } 32 | 33 | if (navGroup.expanded) { 34 | this.closeNavs.emit(navGroup); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-off-canvas/go-off-canvas.component.scss: -------------------------------------------------------------------------------- 1 | @import '~@tangoe/gosheets/base/variables'; 2 | @import '../../../styles/mixins'; 3 | 4 | .go-off-canvas-backdrop { 5 | background: rgba($base-dark, .5); 6 | height: 100vh; 7 | left: 0; 8 | position: fixed; 9 | top: 0; 10 | transition: opacity .5s cubic-bezier(.25, .8, .25, 1); 11 | width: 100vw; 12 | z-index: z-index(off-canvas); 13 | } 14 | 15 | .go-off-canvas { 16 | background-color: $base-dark; 17 | border-left: 2px solid $base-dark-secondary; 18 | bottom: 0; 19 | color: $base-light; 20 | display: flex; 21 | flex-direction: column; 22 | left: 100%; 23 | position: fixed; 24 | top: 0; 25 | width: 300px; 26 | z-index: z-index(off-canvas); 27 | } 28 | 29 | .go-off-canvas__header { 30 | align-self: flex-start; 31 | flex: 0 0 auto; 32 | width: 100%; 33 | } 34 | 35 | .go-off-canvas__button { 36 | background: $base-dark-secondary; 37 | border: 0; 38 | color: $base-light; 39 | cursor: pointer; 40 | display: block; 41 | font-family: $heading-font-stack; 42 | font-size: .8rem; 43 | line-height: 1rem; 44 | outline-offset: -2px; 45 | padding: $column-gutter--half $column-gutter; 46 | text-transform: uppercase; 47 | width: 100%; 48 | } 49 | 50 | .go-off-canvas__content { 51 | flex: 1; 52 | overflow-y: auto; 53 | } 54 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/animations/search.animation.ts: -------------------------------------------------------------------------------- 1 | import { 2 | animate, 3 | style, 4 | transition, 5 | trigger 6 | } from '@angular/animations'; 7 | 8 | import { easing, timing } from './_configs'; 9 | 10 | export const searchLoaderAnim = trigger('searchLoaderAnim', [ 11 | transition(':enter', [ 12 | style({ 13 | height: 0, 14 | opacity: 0, 15 | padding: 0 16 | }), 17 | animate(timing + ' ' + easing, style({ 18 | height: '*', 19 | opacity: 1, 20 | padding: '2rem' 21 | })) 22 | ]), 23 | transition(':leave', [ 24 | style({ 25 | padding: '2rem' 26 | }), 27 | animate(timing + ' ' + easing, style({ 28 | height: 0, 29 | opacity: 0, 30 | padding: 0 31 | })) 32 | ]) 33 | ]); 34 | 35 | export const searchResultsAnim = trigger('searchResultsAnim', [ 36 | transition(':enter', [ 37 | style({ 38 | height: 0, 39 | margin: 0, 40 | opacity: 0 41 | }), 42 | animate(timing + ' .25s ' + easing, style({ 43 | height: '*', 44 | margin: '1rem 0 0.5rem 0', 45 | opacity: 1 46 | })) 47 | ]), 48 | transition(':leave', [ 49 | style({ 50 | overflowY: 'hidden', 51 | margin: '1rem 0 0.5rem 0' 52 | }), 53 | animate(timing + ' ' + easing, style({ 54 | height: 0, 55 | margin: 0, 56 | opacity: 0 57 | })) 58 | ]) 59 | ]); 60 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-table/go-table.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { GoTableComponent } from './go-table.component'; 4 | import { GoIconModule } from '../go-icon/go-icon.module'; 5 | import { GoLoaderModule } from '../go-loader/go-loader.module'; 6 | import { GoTableDataSource } from './go-table-config.model'; 7 | import { GoTablePageConfig } from './go-table-paging.model'; 8 | 9 | describe('GoTableComponent', () => { 10 | let component: GoTableComponent; 11 | let fixture: ComponentFixture; 12 | 13 | beforeEach(async(() => { 14 | TestBed.configureTestingModule({ 15 | declarations: [ GoTableComponent ], 16 | imports: [ 17 | GoIconModule, 18 | GoLoaderModule 19 | ] 20 | }) 21 | .compileComponents(); 22 | })); 23 | 24 | beforeEach(() => { 25 | fixture = TestBed.createComponent(GoTableComponent); 26 | component = fixture.componentInstance; 27 | component.tableConfig = { 28 | dataMode: GoTableDataSource.client, 29 | pageConfig: new GoTablePageConfig(), 30 | pageable: true, 31 | totalCount: 10, 32 | noDataText: '', 33 | sortable: true, 34 | tableData: [] 35 | }; 36 | fixture.detectChanges(); 37 | }); 38 | 39 | it('should create', () => { 40 | expect(component).toBeTruthy(); 41 | }); 42 | }); 43 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-button/go-button.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, EventEmitter, Input, Output } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'go-button', 5 | templateUrl: './go-button.component.html' 6 | }) 7 | export class GoButtonComponent { 8 | @Input() buttonDisabled: boolean; 9 | @Input() buttonIcon: string; 10 | @Input() buttonType: string = 'button'; 11 | @Input() buttonVariant: string; 12 | @Input() useLoader: boolean = false; 13 | @Input() useDarkTheme: boolean = false; 14 | 15 | @Output() handleClick = new EventEmitter(); 16 | 17 | isProcessing: boolean = false; 18 | 19 | public clicked(): void { 20 | this.isProcessing = this.useLoader; 21 | this.handleClick.emit(this.isProcessing); 22 | } 23 | 24 | public reset(): void { 25 | this.isProcessing = false; 26 | } 27 | 28 | public classObject(): object { 29 | // 'alert' as a variant is depreciated and 30 | // will be removed in a later version 31 | const isNegative: boolean = [ 32 | 'alert', 33 | 'negative' 34 | ].includes(this.buttonVariant); 35 | 36 | return { 37 | 'go-button--dark': this.useDarkTheme, 38 | 'go-button--loading': this.isProcessing, 39 | 'go-button--negative': isNegative, 40 | 'go-button--neutral': (this.buttonVariant === 'neutral'), 41 | 'go-button--positive': (this.buttonVariant === 'positive') 42 | }; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-layout/go-layout.component.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Component, 3 | OnInit, 4 | ViewEncapsulation 5 | } from '@angular/core'; 6 | 7 | import { 8 | ActivatedRoute, 9 | NavigationCancel, 10 | NavigationEnd, 11 | NavigationError, 12 | NavigationStart, 13 | Router, 14 | RouterOutlet 15 | } from '@angular/router'; 16 | 17 | import { routerAnimation } from '../../animations/route.animation'; 18 | import { fadeTemplateAnimation } from '../../animations/fade.animation'; 19 | 20 | @Component({ 21 | selector: 'go-layout', 22 | templateUrl: './go-layout.component.html', 23 | styleUrls: ['./go-layout.component.scss'], 24 | animations: [routerAnimation, fadeTemplateAnimation], 25 | encapsulation: ViewEncapsulation.None 26 | }) 27 | export class GoLayoutComponent implements OnInit { 28 | 29 | routeLoader: boolean = false; 30 | 31 | constructor(private router: Router) { } 32 | 33 | ngOnInit(): void { 34 | this.router.events.subscribe(event => { 35 | if (event instanceof NavigationStart) { 36 | this.routeLoader = true; 37 | } else if ((event instanceof NavigationEnd) || (event instanceof NavigationCancel) || (event instanceof NavigationError)) { 38 | this.routeLoader = false; 39 | } 40 | }); 41 | } 42 | 43 | routeAnimation(outlet: RouterOutlet): ActivatedRoute | string { 44 | return outlet.isActivated ? outlet.activatedRoute : ''; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /projects/go-tester/src/app/components/test-page-1/test-page-1.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { GoTableConfig, GoTableDataSource } from '../../../../../go-lib/src/public_api'; 3 | 4 | import { AppService } from '../../app.service'; 5 | 6 | 7 | @Component({ 8 | selector: 'app-test-page-1', 9 | templateUrl: './test-page-1.component.html' 10 | }) 11 | export class TestPage1Component implements OnInit { 12 | 13 | tableConfig: GoTableConfig; 14 | tableLoading: boolean = true; 15 | 16 | constructor(private appService: AppService) { } 17 | 18 | ngOnInit() { 19 | this.appService.getMockData(new GoTableConfig()).subscribe(data => { 20 | this.tableConfig = new GoTableConfig({ 21 | dataMode: GoTableDataSource.server, 22 | tableData: data.results, 23 | totalCount: data.totalCount 24 | }); 25 | this.tableLoading = false; 26 | }); 27 | } 28 | 29 | handleTableChange(currentTableConfig: GoTableConfig) : void { 30 | if (this.tableConfig.dataMode === GoTableDataSource.server) { 31 | this.appService.getMockData(currentTableConfig).subscribe(data => { 32 | setTimeout(() => { 33 | currentTableConfig.tableData = data.results; 34 | currentTableConfig.totalCount = data.totalCount; 35 | 36 | this.tableConfig = currentTableConfig; 37 | this.tableLoading = false; 38 | }, 2000); 39 | }); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-side-nav/go-nav-group/go-nav-group.component.scss: -------------------------------------------------------------------------------- 1 | @import '~@tangoe/gosheets/base/variables'; 2 | @import '~@tangoe/gosheets/base/mixins'; 3 | @import '../../../../styles/variables'; 4 | 5 | .go-nav-group__dropdown { 6 | align-items: center; 7 | display: flex; 8 | padding-right: .5rem; 9 | user-select: none; 10 | @include transition(all); 11 | 12 | &:hover { 13 | background: $theme-dark-bg-hover; 14 | } 15 | } 16 | 17 | .go-nav-group__link { 18 | display: flex; 19 | flex-grow: 1; 20 | } 21 | 22 | .go-nav-group__title { 23 | align-items: center; 24 | display: flex; 25 | font-weight: $weight-light; 26 | letter-spacing: $side-nav-letter-spacing; 27 | padding: $outer-side-nav-padding; 28 | } 29 | 30 | .go-nav-group__icon { 31 | font-size: 1.2rem; 32 | padding: 1rem; 33 | } 34 | 35 | .go-nav-group__expand-icon { 36 | border-radius: 50%; 37 | color: $theme-dark-color; 38 | cursor: pointer; 39 | font-size: 1.5rem; 40 | height: 2.5rem; 41 | padding: 0.5rem; 42 | width: 2.5rem; 43 | 44 | &:hover { 45 | background: $theme-dark-bg; 46 | } 47 | } 48 | 49 | .go-nav-group__expand-icon--expanded { 50 | transform: rotate(180deg); 51 | } 52 | 53 | .go-nav-group__inner-group { 54 | .go-nav-group__title { 55 | font-size: $inner-side-nav-font-size; 56 | padding: $inner-side-nav-padding; 57 | } 58 | } 59 | 60 | .go-nav-group--expanded { 61 | background: $theme-dark-bg-active; 62 | } 63 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-card/go-card.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { GoCardComponent } from './go-card.component'; 4 | 5 | describe('GoCardComponent', () => { 6 | let component: GoCardComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ GoCardComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(GoCardComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | 26 | describe('the template', () => { 27 | it('renders the header by default', () => { 28 | const goCardTemplate: HTMLElement = fixture.nativeElement; 29 | const headerElement: HTMLElement = goCardTemplate.querySelector('header'); 30 | 31 | expect(headerElement).not.toBeNull(); 32 | }); 33 | 34 | it('hides the header if showHeader is false', () => { 35 | component.showHeader = false; 36 | fixture.detectChanges(); 37 | 38 | const goCardTemplate: HTMLElement = fixture.nativeElement; 39 | const headerElement: HTMLElement = goCardTemplate.querySelector('header'); 40 | 41 | expect(headerElement).toBeNull(); 42 | }); 43 | }); 44 | }); 45 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-toast/go-toast.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'go-toast', 5 | templateUrl: './go-toast.component.html', 6 | styleUrls: ['./go-toast.component.scss'] 7 | }) 8 | export class GoToastComponent implements OnInit { 9 | statusClass: string = 'go-toast-status--neutral'; 10 | icon: string = 'notifications_none'; 11 | 12 | @Input() dismissable: boolean = false; 13 | @Input() header: string; 14 | @Input() message: string; 15 | @Input() type: string; 16 | 17 | @Output() handleDismiss = new EventEmitter(); 18 | 19 | ngOnInit(): void { 20 | this.statusClass = this.getStatus(); 21 | this.icon = this.getIcon(); 22 | } 23 | 24 | public dismiss(): void { 25 | this.handleDismiss.emit(); 26 | } 27 | 28 | //#region Private Methods 29 | 30 | private getStatus(): string { 31 | switch (this.type) { 32 | case 'positive': 33 | return 'go-toast-status--positive'; 34 | case 'negative': 35 | return 'go-toast-status--negative'; 36 | default: 37 | return 'go-toast-status--neutral'; 38 | } 39 | } 40 | 41 | private getIcon(): string { 42 | switch (this.type) { 43 | case 'positive': 44 | return 'done'; 45 | case 'negative': 46 | return 'priority_high'; 47 | default: 48 | return 'notifications_none'; 49 | } 50 | } 51 | 52 | //#endregion 53 | } 54 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-side-nav/go-nav-group/go-nav-group.component.html: -------------------------------------------------------------------------------- 1 |
4 |
7 | 16 | 20 | 21 |
22 |
23 |
24 | 27 | 28 | 29 | 30 | 31 |
32 |
33 |
34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /projects/go-tester/src/app/components/test-page-2/test-page-2.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewChild } from '@angular/core'; 2 | import { 3 | GoButtonComponent, 4 | GoLoaderComponent, 5 | GoToasterService 6 | } from '../../../../../go-lib/src/public_api'; 7 | 8 | @Component({ 9 | selector: 'app-test-page-2', 10 | templateUrl: './test-page-2.component.html' 11 | }) 12 | export class TestPage2Component implements OnInit { 13 | 14 | @ViewChild('heyButton') heyButton: GoButtonComponent; 15 | @ViewChild('loader') loader: GoLoaderComponent; 16 | 17 | title: string = 'Test 2'; 18 | loaderType: string = 'neutral'; 19 | loading: boolean = true; 20 | 21 | constructor(private goToasterService: GoToasterService) { } 22 | 23 | ngOnInit() { 24 | setTimeout(() => { 25 | this.goToasterService.toastInfo({ message: 'Check this out'}); 26 | this.goToasterService.toastSuccess({message: 'Check this out' }); 27 | this.goToasterService.toastError({ message: 'Check this out' }); 28 | }, 1500); 29 | } 30 | 31 | stopLoaderAnimation() { 32 | const loaderTypes: string[] = [ 33 | 'neutral', 34 | 'negative', 35 | 'positive' 36 | ]; 37 | 38 | this.loaderType = loaderTypes[Math.floor(Math.random() * loaderTypes.length)]; 39 | this.loading = !this.loading; 40 | } 41 | 42 | clickHey(): void { 43 | setTimeout(() => { 44 | this.heyButton.reset(); 45 | }, 4000); 46 | } 47 | 48 | openToast() { 49 | this.goToasterService.toastInfo({ message: 'From the action sheet'}); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-layout/go-layout.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; 3 | import { BrowserModule } from '@angular/platform-browser'; 4 | import { CommonModule } from '@angular/common'; 5 | import { RouterModule } from '@angular/router'; 6 | 7 | import { GoHeaderModule } from '../go-header/go-header.module'; 8 | import { GoLoaderModule } from '../go-loader/go-loader.module'; 9 | import { GoModalModule } from '../go-modal/go-modal.module'; 10 | import { GoOffCanvasModule } from '../go-off-canvas/go-off-canvas.module'; 11 | import { GoToasterModule } from '../go-toaster/go-toaster.module'; 12 | 13 | import { GoModalService } from '../go-modal/go-modal.service'; 14 | import { GoOffCanvasService } from '../go-off-canvas/go-off-canvas.service'; 15 | import { GoToasterService } from '../go-toaster/go-toaster.service'; 16 | 17 | import { GoLayoutComponent } from './go-layout.component'; 18 | 19 | @NgModule({ 20 | declarations: [ 21 | GoLayoutComponent 22 | ], 23 | imports: [ 24 | // Angular 25 | BrowserAnimationsModule, 26 | BrowserModule, 27 | CommonModule, 28 | RouterModule, 29 | // Goponents 30 | GoHeaderModule, 31 | GoLoaderModule, 32 | GoModalModule, 33 | GoOffCanvasModule, 34 | GoToasterModule 35 | ], 36 | exports: [ 37 | GoLayoutComponent 38 | ], 39 | providers: [ 40 | GoModalService, 41 | GoOffCanvasService, 42 | GoToasterService 43 | ] 44 | }) 45 | 46 | export class GoLayoutModule { } 47 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-side-nav/go-nav-item/go-nav-item.component.scss: -------------------------------------------------------------------------------- 1 | @import '~@tangoe/gosheets/base/variables'; 2 | @import '~@tangoe/gosheets/base/mixins'; 3 | @import '../../../../styles/variables'; 4 | 5 | .go-nav-item { 6 | align-items: center; 7 | display: flex; 8 | padding-right: .5rem; 9 | @include transition(all); 10 | 11 | &:hover { 12 | background: $theme-dark-bg-hover; 13 | } 14 | } 15 | 16 | .go-nav-item__link::before { 17 | background: $base-primary; 18 | border-radius: 0 $global-radius $global-radius 0; 19 | content: " "; 20 | height: 100%; 21 | left: 0; 22 | opacity: 0; 23 | position: absolute; 24 | top: 0; 25 | width: 4px; 26 | @include transition(all); 27 | } 28 | 29 | .go-nav-item__link--active { 30 | .go-nav-item__title { 31 | font-weight: $weight-regular; 32 | } 33 | } 34 | 35 | .go-nav-item__link--active::before { 36 | opacity: 1; 37 | } 38 | 39 | .go-nav-item__link, 40 | .go-nav-item__link:visited, 41 | .go-nav-item__link:focus, 42 | .go-nav-item__link:active { 43 | color: $theme-dark-color; 44 | } 45 | 46 | .go-nav-item__link { 47 | align-items: center; 48 | border: none; 49 | display: flex; 50 | flex-grow: 1; 51 | position: relative; 52 | text-decoration: none; 53 | } 54 | 55 | .go-nav-item__title { 56 | font-size: $inner-side-nav-font-size; 57 | font-weight: $weight-light; 58 | letter-spacing: $side-nav-letter-spacing; 59 | padding: $inner-side-nav-padding; 60 | } 61 | 62 | .go-nav-item__title--with-icon { 63 | font-size: 1rem; 64 | padding: $outer-side-nav-padding; 65 | } 66 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-action-sheet/go-action-sheet.component.scss: -------------------------------------------------------------------------------- 1 | @import '~@tangoe/gosheets/base/_variables'; 2 | @import '~@tangoe/gosheets/base/_mixins'; 3 | 4 | .go-action-sheet { 5 | position: relative; 6 | } 7 | 8 | go-action-sheet-button { 9 | display: flex; 10 | } 11 | 12 | .go-action-sheet__scroll-container { 13 | max-height: 375px; 14 | overflow: auto; 15 | } 16 | 17 | .go-action-sheet__content { 18 | border-radius: $global-radius; 19 | overflow: hidden; 20 | } 21 | 22 | .go-action-sheet__content-container { 23 | @include transition; 24 | 25 | background: $theme-light-bg; 26 | border: 1px solid $theme-light-border; 27 | border-radius: $global-radius; 28 | box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.2); 29 | left: 50%; 30 | opacity: 0; 31 | position: absolute; 32 | top: calc(100% + 50px); 33 | transform: translateX(-50%); 34 | visibility: hidden; 35 | z-index: 300; 36 | 37 | &::before { 38 | @include transition; 39 | 40 | background: $theme-light-bg; 41 | border: 1px solid $theme-light-border; 42 | box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.2); 43 | content: " "; 44 | height: 15px; 45 | left: calc(50% - 7.5px); 46 | pointer-events: none; 47 | position: absolute; 48 | top: -7.5px; 49 | transform: rotate(45deg); 50 | width: 15px; 51 | } 52 | 53 | &.go-action-sheet__content-container--active { 54 | opacity: 1; 55 | top: calc(100% + 1rem); 56 | visibility: visible; 57 | } 58 | } 59 | 60 | .go-action-sheet__content-container--shift-left { 61 | transform: translateX(-90%); 62 | 63 | &::before { 64 | left: calc(90% - 7.5px); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-search/go-search.component.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-header/go-header.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, ElementRef, Input, ViewChild } from '@angular/core'; 2 | import { GoSideNavService } from '../go-side-nav/go-side-nav/go-side-nav.service'; 3 | import { fromEvent, Observable, Subscription } from 'rxjs'; 4 | import { debounceTime } from 'rxjs/operators'; 5 | 6 | @Component({ 7 | selector: 'go-header', 8 | templateUrl: './go-header.component.html', 9 | styleUrls: ['./go-header.component.scss'] 10 | }) 11 | export class GoHeaderComponent { 12 | 13 | @Input() altText: string = ''; 14 | @Input() logo: string = ''; 15 | 16 | @ViewChild('middleSection') middleSection: ElementRef; 17 | 18 | private minWidthBreakpoint: number = 768; 19 | private resizeObservable: Observable = fromEvent(window, 'resize'); 20 | private resizeSubsciption: Subscription; 21 | 22 | constructor(public sideNavService: GoSideNavService) { 23 | this.setMobileNav(); 24 | this.setupResizeSubscription(); 25 | } 26 | 27 | isNavCollapsed(): boolean { 28 | return window.innerWidth <= this.minWidthBreakpoint ? true : !this.sideNavService.navOpen; 29 | } 30 | 31 | toggleSideMenu(): void { 32 | this.sideNavService.toggleNav(); 33 | } 34 | 35 | middleContentExists(): boolean { 36 | return this.middleSection.nativeElement.childElementCount > 0; 37 | } 38 | 39 | private setupResizeSubscription(): void { 40 | this.resizeSubsciption = this.resizeObservable 41 | .pipe(debounceTime(250)) 42 | .subscribe(event => { 43 | this.setMobileNav(); 44 | }); 45 | } 46 | 47 | private setMobileNav(): void { 48 | if (window.innerWidth <= this.minWidthBreakpoint) { 49 | this.sideNavService.navOpen = false; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-layout/go-layout.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | import { RouterTestingModule } from '@angular/router/testing'; 3 | 4 | import { GoLayoutComponent } from './go-layout.component'; 5 | import { RouterModule } from '@angular/router'; 6 | import { GoLoaderModule } from '../go-loader/go-loader.module'; 7 | import { GoModalModule } from '../go-modal/go-modal.module'; 8 | import { GoModalService } from '../go-modal/go-modal.service'; 9 | import { GoOffCanvasModule } from '../go-off-canvas/go-off-canvas.module'; 10 | import { GoOffCanvasService } from '../go-off-canvas/go-off-canvas.service'; 11 | import { GoToasterModule } from '../go-toaster/go-toaster.module'; 12 | import { GoToasterService } from '../go-toaster/go-toaster.service'; 13 | 14 | describe('GoLayoutComponent', () => { 15 | let component: GoLayoutComponent; 16 | let fixture: ComponentFixture; 17 | 18 | beforeEach(async(() => { 19 | TestBed.configureTestingModule({ 20 | declarations: [ GoLayoutComponent ], 21 | imports: [ 22 | GoLoaderModule, 23 | GoModalModule, 24 | GoOffCanvasModule, 25 | GoToasterModule, 26 | RouterModule, 27 | RouterTestingModule 28 | ], 29 | providers: [ 30 | GoModalService, 31 | GoOffCanvasService, 32 | GoToasterService 33 | ] 34 | }) 35 | .compileComponents(); 36 | })); 37 | 38 | beforeEach(() => { 39 | fixture = TestBed.createComponent(GoLayoutComponent); 40 | component = fixture.componentInstance; 41 | fixture.detectChanges(); 42 | }); 43 | 44 | it('should create', () => { 45 | expect(component).toBeTruthy(); 46 | }); 47 | }); 48 | -------------------------------------------------------------------------------- /projects/go-tester/src/styles.scss: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | @import url('https://fonts.googleapis.com/css?family=Roboto:300,400,700'); 3 | @import url('https://fonts.googleapis.com/icon?family=Material+Icons'); 4 | 5 | /* http://meyerweb.com/eric/tools/css/reset/ 6 | v2.0 | 20110126 7 | License: none (public domain) 8 | */ 9 | 10 | html, body, div, span, applet, object, iframe, 11 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 12 | a, abbr, acronym, address, big, cite, code, 13 | del, dfn, em, img, ins, kbd, q, s, samp, 14 | small, strike, strong, sub, sup, tt, var, 15 | b, u, i, center, 16 | dl, dt, dd, ol, ul, li, 17 | fieldset, form, label, legend, 18 | table, caption, tbody, tfoot, thead, tr, th, td, 19 | article, aside, canvas, details, embed, 20 | figure, figcaption, footer, header, hgroup, 21 | menu, nav, output, ruby, section, summary, 22 | time, mark, audio, video { 23 | margin: 0; 24 | padding: 0; 25 | border: 0; 26 | font-size: 100%; 27 | font: inherit; 28 | vertical-align: baseline; 29 | } 30 | /* HTML5 display-role reset for older browsers */ 31 | article, aside, details, figcaption, figure, 32 | footer, header, hgroup, menu, nav, section { 33 | display: block; 34 | } 35 | body { 36 | line-height: 1; 37 | } 38 | ol, ul { 39 | list-style: none; 40 | } 41 | blockquote, q { 42 | quotes: none; 43 | } 44 | blockquote:before, blockquote:after, 45 | q:before, q:after { 46 | content: ''; 47 | content: none; 48 | } 49 | table { 50 | border-collapse: collapse; 51 | border-spacing: 0; 52 | } 53 | * { 54 | box-sizing: border-box; 55 | } 56 | 57 | 58 | @import "~@tangoe/gosheets/gosheets"; 59 | 60 | body { 61 | background: $theme-light-app-bg; 62 | font-family: 'Roboto'; 63 | margin: 0px; 64 | } 65 | -------------------------------------------------------------------------------- /projects/go-tester/src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | import { 4 | GoIconComponent, 5 | GoModalService, 6 | GoOffCanvasService, 7 | GoSideNavService, 8 | NavGroup, 9 | NavItem, 10 | GoToasterService 11 | } from '../../../go-lib/src/public_api'; 12 | 13 | @Component({ 14 | selector: 'app-root', 15 | templateUrl: './app.component.html', 16 | styleUrls: ['./app.component.scss'] 17 | }) 18 | export class AppComponent implements OnInit { 19 | 20 | logo: string = 'https://mobi.thefutureis.mobi/images/assets/theme_logo/000/000/000/178/header.png?1556627290'; 21 | title: string = 'go-tester'; 22 | 23 | menuItems: Array = [ 24 | { routeIcon: 'dashboard', routeTitle: 'Tests', description: 'Test Routes', subRoutes: [ 25 | { route: 'test-page-1', routeTitle: 'Test 1', description: 'Test Route 1' }, 26 | { route: 'test-page-2', routeTitle: 'Test 2' } 27 | ]} 28 | ]; 29 | 30 | constructor( 31 | private goToasterService: GoToasterService, 32 | private goOffCanvasService: GoOffCanvasService, 33 | private goSideNavService: GoSideNavService, 34 | private goModalService: GoModalService 35 | ) { } 36 | 37 | ngOnInit() { 38 | } 39 | 40 | openOffCanvas(): void { 41 | this.goOffCanvasService.openOffCanvas({ 42 | component: GoIconComponent, 43 | bindings: { 44 | icon: 'alarm' 45 | } 46 | }); 47 | } 48 | 49 | toggleSideMenu(): void { 50 | this.goSideNavService.toggleNav(); 51 | } 52 | 53 | openModal(): void { 54 | this.goModalService.openModal( 55 | GoIconComponent, 56 | { 57 | icon: 'alarm' 58 | } 59 | ); 60 | } 61 | 62 | openToast() { 63 | this.goToasterService.toastInfo({ message: 'From the action sheet'}); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-table/go-table.component.scss: -------------------------------------------------------------------------------- 1 | @import '~@tangoe/gosheets/base/variables'; 2 | @import '~@tangoe/gosheets/base/mixins'; 3 | 4 | .go-table-container { 5 | background: $theme-light-bg; 6 | border-radius: $global-radius; 7 | box-shadow: $global-box-shadow; 8 | position: relative; 9 | } 10 | 11 | .go-table-header { 12 | align-items: center; 13 | display: flex; 14 | 15 | h5 { 16 | padding: .875rem 0 .875rem 1.25rem; 17 | } 18 | 19 | @media (max-width: $breakpoint-mobile) { 20 | align-items: initial; 21 | flex-direction: column; 22 | justify-content: center; 23 | 24 | .go-table-header__actions { 25 | justify-content: initial; 26 | } 27 | } 28 | } 29 | 30 | .go-table-header__actions { 31 | align-items: center; 32 | display: flex; 33 | flex: 1; 34 | justify-content: flex-end; 35 | padding: .875rem 1.25rem; 36 | } 37 | 38 | .go-table-header--stacked { 39 | align-items: initial; 40 | flex-direction: column; 41 | justify-content: center; 42 | 43 | .go-table-header__actions { 44 | justify-content: initial; 45 | } 46 | } 47 | 48 | // Loader 49 | //================ 50 | .go-table-loader { 51 | @include transition(opacity); 52 | 53 | align-items: center; 54 | background: transparentize($theme-light-bg-hover, .3); 55 | border-radius: $global-radius; 56 | display: flex; 57 | height: 100%; 58 | justify-content: center; 59 | left: 0; 60 | position: absolute; 61 | top: 0; 62 | width: 100%; 63 | } 64 | 65 | // Placeholder Table 66 | //===================== 67 | .go-table-placeholder { 68 | border-spacing: 0; 69 | width: 100%; 70 | 71 | td { 72 | border-top: 1px solid $theme-light-app-bg; 73 | color: $theme-light-color; 74 | font-size: .875rem; 75 | padding: .875rem 1.25rem; 76 | text-align: center; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-search/go-search.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | 3 | import { Subject } from 'rxjs'; 4 | 5 | @Injectable({ 6 | providedIn: 'root' 7 | }) 8 | export class GoSearchService { 9 | 10 | /** 11 | * Whether or not the service making requests returned results 12 | */ 13 | hasResults: boolean = false; 14 | 15 | /** 16 | * The message to be shown when no results are returned from the server that match the search term 17 | */ 18 | noResultsMessage: string = 'No Results Found'; 19 | 20 | /** 21 | * Whether or not to show the noResultsMessage 22 | */ 23 | showNoResultsMessage: boolean = false; 24 | 25 | /** 26 | * Whether or not to show the loader in the search bar 27 | */ 28 | showLoader: boolean = false; 29 | 30 | /** 31 | * The term entered by the user to search 32 | */ 33 | searchTerm: Subject = new Subject(); 34 | 35 | /** 36 | * Minimum number of characters to trigger a search 37 | */ 38 | termLength: number = 3; 39 | 40 | /** 41 | * Use this method to update the search term 42 | * @param term {string} The search term entered by the user 43 | */ 44 | updateSearchTerm(term: string): void { 45 | this.searchTerm.next(term); 46 | } 47 | 48 | /** 49 | * Use this method when you get a response from 50 | * the server that was successful, **with results** 51 | */ 52 | successResponse(): void { 53 | this.hasResults = true; 54 | this.showLoader = false; 55 | this.showNoResultsMessage = false; 56 | } 57 | 58 | /** 59 | * Use this method when you get a response from 60 | * the server that was successful, but **with no results** 61 | */ 62 | notFoundResponse(): void { 63 | this.hasResults = false; 64 | this.showLoader = false; 65 | this.showNoResultsMessage = true; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /projects/go-tester/src/app/app.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { HttpClient } from '@angular/common/http'; 3 | import { map } from 'rxjs/operators'; 4 | import { GoTableConfig, GoTablePageConfig, GoTableSortConfig } from '../../../go-lib/src/public_api'; 5 | 6 | // Only using this to emulate sorting for server side 7 | import { sortBy } from '../../../go-lib/src/lib/components/go-table/go-table-utils'; 8 | 9 | @Injectable({ 10 | providedIn: 'root' 11 | }) 12 | 13 | export class AppService { 14 | 15 | constructor (private http: HttpClient) { } 16 | 17 | getMockData(params?: GoTableConfig) { 18 | return this.http.get("../assets/MOCK_DATA_1000.json").pipe(map(data => { 19 | let formattedData = { totalCount: 0, results: [] }; 20 | 21 | formattedData.totalCount = data.length; 22 | 23 | if (params) { 24 | formattedData.results = params.sortConfig ? this.sortData(params.sortConfig, data) : formattedData.results; 25 | formattedData.results = params.pageConfig ? this.paginateData(params.pageConfig, data) : formattedData.results; 26 | } else { 27 | formattedData.results = data; 28 | } 29 | 30 | return formattedData; 31 | })); 32 | } 33 | 34 | getMockSearch(term: string) { 35 | return this.http.get("../assets/MOCK_DATA_1000.json").pipe(map(data => { 36 | return data.filter(item => { 37 | return item.id.toString().includes(term) || item.name.first.includes(term) || item.name.last.includes(term) || item.email.includes(term); 38 | }) 39 | })) 40 | } 41 | 42 | /***** Private Methods *****/ 43 | private paginateData(paging: GoTablePageConfig, results: any[]) : any[] { 44 | return results.slice(paging.offset, paging.offset + paging.perPage); 45 | } 46 | 47 | private sortData(sort: GoTableSortConfig, results: any[]) : any[] { 48 | return results.sort(sortBy(sort.column, Boolean(sort.direction))); 49 | } 50 | 51 | 52 | } 53 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-modal/go-modal.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ComponentFactoryResolver, OnChanges, ViewChild } from '@angular/core'; 2 | 3 | import { GoModalDirective } from './go-modal.directive'; 4 | import { GoModalService } from './go-modal.service'; 5 | 6 | @Component({ 7 | selector: 'go-modal', 8 | templateUrl: './go-modal.component.html', 9 | styleUrls: ['./go-modal.component.scss'] 10 | }) 11 | export class GoModalComponent implements OnInit { 12 | currentComponent: any; 13 | opened: boolean = false; 14 | 15 | @ViewChild(GoModalDirective) goModalHost: GoModalDirective; 16 | @ViewChild('goModalContainer') goModalContainer: any; 17 | 18 | constructor( 19 | private componentFactoryResolver: ComponentFactoryResolver, 20 | private goModalService: GoModalService 21 | ) { 22 | } 23 | 24 | ngOnInit() { 25 | this.goModalService.activeModalComponent.subscribe((value) => { 26 | this.currentComponent = value; 27 | this.loadComponent(); 28 | }); 29 | 30 | this.goModalService.modalOpen.subscribe((value) => { 31 | this.opened = value; 32 | }); 33 | } 34 | 35 | loadComponent() { 36 | const componentFactory = this.componentFactoryResolver.resolveComponentFactory(this.currentComponent.component); 37 | const viewContainerRef = this.goModalHost.viewContainerRef; 38 | viewContainerRef.clear(); 39 | 40 | let componentRef = viewContainerRef.createComponent(componentFactory); 41 | 42 | Object.keys(this.currentComponent.bindings).forEach(key => { 43 | componentRef.instance[key] = this.currentComponent.bindings[key]; 44 | }); 45 | } 46 | 47 | closeModalContainer(event) { 48 | if (!this.goModalContainer.nativeElement.contains(event.target)) { 49 | this.closeModal(); 50 | } 51 | } 52 | 53 | closeModal() { 54 | this.goModalService.toggleModal(false); 55 | } 56 | 57 | goModalClasses() { 58 | return { 'go-modal--visible': this.opened } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /projects/go-tester/src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { BrowserModule } from '@angular/platform-browser'; 3 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; 4 | import { HttpClientModule } from '@angular/common/http'; 5 | 6 | import { 7 | GoButtonComponent, 8 | GoButtonModule, 9 | GoHeaderModule, 10 | GoIconButtonModule, 11 | GoIconComponent, 12 | GoIconModule, 13 | GoLayoutModule, 14 | GoLoaderModule, 15 | GoOffCanvasModule, 16 | GoSearchModule, 17 | GoSideNavModule, 18 | GoTableModule, 19 | GoToastModule, 20 | GoToasterModule, 21 | GoActionSheetModule, 22 | GoAccordionModule 23 | } from '../../../go-lib/src/public_api'; 24 | 25 | import { AppRoutesModule } from './app-routing.module'; 26 | 27 | import { AppComponent } from './app.component'; 28 | import { AppService } from './app.service'; 29 | import { SearchTestComponent } from './components/search-test/search-test.component'; 30 | import { TestPage1Component } from './components/test-page-1/test-page-1.component'; 31 | import { TestPage2Component } from './components/test-page-2/test-page-2.component'; 32 | import { AppGuard } from './app.guard'; 33 | 34 | 35 | @NgModule({ 36 | declarations: [ 37 | AppComponent, 38 | SearchTestComponent, 39 | TestPage1Component, 40 | TestPage2Component 41 | ], 42 | imports: [ 43 | AppRoutesModule, 44 | BrowserModule, 45 | BrowserAnimationsModule, 46 | HttpClientModule, 47 | GoAccordionModule, 48 | GoActionSheetModule, 49 | GoButtonModule, 50 | GoHeaderModule, 51 | GoIconModule, 52 | GoIconButtonModule, 53 | GoLayoutModule, 54 | GoLoaderModule, 55 | GoOffCanvasModule, 56 | GoSearchModule, 57 | GoSideNavModule, 58 | GoTableModule, 59 | GoToastModule, 60 | GoToasterModule 61 | ], 62 | providers: [ 63 | AppService, 64 | AppGuard 65 | ], 66 | entryComponents: [ 67 | GoButtonComponent, 68 | GoIconComponent 69 | ], 70 | bootstrap: [AppComponent] 71 | }) 72 | export class AppModule { } 73 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/go-shared.module.ts: -------------------------------------------------------------------------------- 1 | import { NgModule } from '@angular/core'; 2 | import { GoAccordionModule } from './components/go-accordion/go-accordion.module'; 3 | import { GoButtonModule } from './components/go-button/go-button.module'; 4 | import { GoCardModule } from './components/go-card/go-card.module'; 5 | import { GoHeaderModule } from './components/go-header/go-header.module'; 6 | import { GoIconModule } from './components/go-icon/go-icon.module'; 7 | import { GoLayoutModule } from './components/go-layout/go-layout.module'; 8 | import { GoLoaderModule } from './components/go-loader/go-loader.module'; 9 | import { GoModalModule } from './components/go-modal/go-modal.module'; 10 | import { GoSearchModule } from './components/go-search/go-search.module'; 11 | import { GoSideNavModule } from './components/go-side-nav/go-side-nav.module'; 12 | import { GoTableModule } from './components/go-table/go-table.module'; 13 | import { GoToastModule } from './components/go-toast/go-toast.module'; 14 | import { GoIconButtonModule } from './components/go-icon-button/go-icon-button.module'; 15 | import { GoToasterModule } from './components/go-toaster/go-toaster.module'; 16 | import { GoActionSheetModule } from './components/go-action-sheet/go-action-sheet.module'; 17 | 18 | @NgModule({ 19 | imports: [ 20 | GoAccordionModule, 21 | GoActionSheetModule, 22 | GoButtonModule, 23 | GoCardModule, 24 | GoHeaderModule, 25 | GoIconButtonModule, 26 | GoIconModule, 27 | GoLayoutModule, 28 | GoLoaderModule, 29 | GoModalModule, 30 | GoSearchModule, 31 | GoSideNavModule, 32 | GoTableModule, 33 | GoToastModule, 34 | GoToasterModule 35 | ], 36 | exports: [ 37 | GoAccordionModule, 38 | GoButtonModule, 39 | GoCardModule, 40 | GoHeaderModule, 41 | GoIconButtonModule, 42 | GoIconModule, 43 | GoLayoutModule, 44 | GoLoaderModule, 45 | GoModalModule, 46 | GoSearchModule, 47 | GoSideNavModule, 48 | GoTableModule, 49 | GoToastModule, 50 | GoToasterModule 51 | ] 52 | }) 53 | 54 | export class GoSharedModule { } 55 | -------------------------------------------------------------------------------- /projects/go-tester/src/app/app.component.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | Another test 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-accordion/go-accordion.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, AfterContentInit, Input, QueryList, ContentChildren } from '@angular/core'; 2 | import { GoAccordionPanelComponent } from './go-accordion-panel.component'; 3 | 4 | @Component({ 5 | selector: 'go-accordion', 6 | templateUrl: './go-accordion.component.html', 7 | styleUrls: ['./go-accordion.component.scss'] 8 | }) 9 | export class GoAccordionComponent implements OnInit, AfterContentInit { 10 | 11 | @Input() expandAll: boolean = false; 12 | @Input() multiExpand: boolean = false; 13 | @Input() showIcons: boolean = false; 14 | @Input() slim: boolean = false; 15 | @Input() theme: string = 'light'; 16 | 17 | activeTheme: string; 18 | 19 | @ContentChildren(GoAccordionPanelComponent) panels: QueryList; 20 | 21 | constructor() { } 22 | 23 | ngOnInit() { 24 | this.multiExpand = this.expandAll || this.multiExpand; 25 | } 26 | 27 | ngAfterContentInit() { 28 | this.panels.toArray().forEach((p) => { 29 | p.toggle.subscribe(() => { 30 | if (!p.expanded && this.multiExpand) { 31 | this.openPanel(p); 32 | } else if (!p.expanded && !this.multiExpand) { 33 | this.openPanelCloseOthers(p); 34 | } else { 35 | this.closePanel(p); 36 | } 37 | }); 38 | 39 | p.expanded = this.expandAll || p.expanded; 40 | p.icon = !this.showIcons ? null : p.icon; 41 | }) 42 | } 43 | 44 | openPanelCloseOthers(panel: GoAccordionPanelComponent) { 45 | this.panels.toArray().forEach((p) => { 46 | this.closePanel(p); 47 | }); 48 | 49 | this.openPanel(panel); 50 | } 51 | 52 | openPanel(panel: GoAccordionPanelComponent) { 53 | panel.expanded = true; 54 | } 55 | 56 | closePanel(panel: GoAccordionPanelComponent) { 57 | panel.expanded = false; 58 | } 59 | 60 | accordionClasses(): object { 61 | return { 62 | 'go-accordion--theme-light': this.theme === 'light' && !this.slim, 63 | 'go-accordion--theme-dark': this.theme === 'dark' && !this.slim, 64 | 'go-accordion--slim': this.slim 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-off-canvas/go-off-canvas.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, ViewChild, ComponentFactoryResolver } from '@angular/core'; 2 | import { GoOffCanvasDirective } from './go-off-canvas.directive'; 3 | import { GoOffCanvasService } from './go-off-canvas.service'; 4 | import { GoOffCanvasItem } from './go-off-canvas.interface'; 5 | 6 | import { fadeAnimation } from '../../animations/fade.animation'; 7 | import { offCanvasAnimation } from '../../animations/off-canvas.animation'; 8 | 9 | @Component({ 10 | selector: 'go-off-canvas', 11 | templateUrl: './go-off-canvas.component.html', 12 | styleUrls: [ 13 | './go-off-canvas.component.scss' 14 | ], 15 | animations: [ 16 | fadeAnimation, 17 | offCanvasAnimation 18 | ] 19 | }) 20 | export class GoOffCanvasComponent implements OnInit { 21 | currentOffCanvasItem: GoOffCanvasItem; 22 | opened: boolean = false; 23 | 24 | @ViewChild(GoOffCanvasDirective) goOffCanvasHost: GoOffCanvasDirective; 25 | 26 | constructor( 27 | private componentFactoryResolver: ComponentFactoryResolver, 28 | private goOffCanvasService: GoOffCanvasService 29 | ) { } 30 | 31 | ngOnInit(): void { 32 | this.goOffCanvasService.activeOffCanvasComponent.subscribe((goOffCanvasItem) => { 33 | this.currentOffCanvasItem = goOffCanvasItem; 34 | this.loadComponent(); 35 | }); 36 | 37 | this.goOffCanvasService.offCanvasOpen.subscribe((value) => { 38 | this.opened = value; 39 | }); 40 | } 41 | 42 | public closeOffCanvas(): void { 43 | this.goOffCanvasService.closeOffCanvas(); 44 | } 45 | 46 | private loadComponent(): void { 47 | const componentFactory = this.componentFactoryResolver.resolveComponentFactory( 48 | this.currentOffCanvasItem.component 49 | ); 50 | const viewContainerRef = this.goOffCanvasHost.viewContainerRef; 51 | 52 | viewContainerRef.clear(); 53 | 54 | let componentRef = viewContainerRef.createComponent(componentFactory); 55 | 56 | Object.keys(this.currentOffCanvasItem.bindings).forEach(key => { 57 | componentRef.instance[key] = this.currentOffCanvasItem.bindings[key]; 58 | }); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-action-sheet/go-panel/go-panel.component.scss: -------------------------------------------------------------------------------- 1 | @import '~@tangoe/gosheets/base/_variables'; 2 | @import '~@tangoe/gosheets/base/_mixins'; 3 | $base-medium: #767676 !default; 4 | 5 | .go-panel { 6 | @include transition; 7 | 8 | background: $theme-light-bg; 9 | color: $theme-light-color; 10 | cursor: pointer; 11 | display: flex; 12 | font-size: 1rem; 13 | font-weight: normal; 14 | max-width: 20rem; 15 | position: relative; 16 | text-align: left; 17 | text-decoration: none; 18 | 19 | &:hover { 20 | background: $theme-light-bg-hover; 21 | } 22 | 23 | .material-icons { 24 | font-size: 1rem; 25 | } 26 | 27 | .go-panel__title { 28 | align-items: center; 29 | display: flex; 30 | flex-grow: 1; 31 | white-space: nowrap; 32 | 33 | .go-panel__icon { 34 | display: flex; 35 | flex-direction: column; 36 | justify-content: center; 37 | padding-left: 1rem; 38 | text-align: center; 39 | } 40 | 41 | .go-panel__title-text { 42 | padding: 1rem; 43 | width: 100%; 44 | } 45 | } 46 | } 47 | 48 | .go-panel--danger { 49 | border-top: 1px solid $theme-light-border; 50 | 51 | .material-icons { 52 | color: $ui-color-negative; 53 | } 54 | 55 | .go-panel__title { 56 | .go-panel__title-text { 57 | color: $ui-color-negative; 58 | } 59 | } 60 | } 61 | 62 | .go-panel--header { 63 | color: $base-medium; 64 | } 65 | 66 | .go-action-sheet__title-panel { 67 | .go-panel__title-text { 68 | color: $base-light-secondary; 69 | font-size: 10pt; 70 | letter-spacing: 0.02rem; 71 | text-align: center; 72 | text-transform: uppercase; 73 | } 74 | } 75 | 76 | go-panel.disabled { 77 | .go-panel__title { 78 | opacity: 0.5; 79 | } 80 | 81 | .table-action-sheet__row-hint { 82 | display: block; 83 | } 84 | } 85 | 86 | button { 87 | background: transparent; 88 | border: 0; 89 | padding: 0; 90 | width: 100%; 91 | 92 | &:hover { 93 | background: $theme-light-bg-hover; 94 | } 95 | 96 | &:focus { 97 | outline: none; 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-toaster/go-toaster.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { timer } from 'rxjs'; 3 | 4 | import { ToastInterface } from './go-toaster.model'; 5 | import { GoToastComponent } from '../go-toast/go-toast.component'; 6 | 7 | @Injectable({ 8 | providedIn: 'root' 9 | }) 10 | export class GoToasterService { 11 | 12 | toasts: GoToastComponent[] = []; 13 | 14 | constructor() { } 15 | 16 | /** 17 | * Use this method to display success toasts 18 | * @param toast 19 | * @param duration 20 | */ 21 | toastSuccess(toast?: ToastInterface, duration: number = 3000) : void { 22 | toast = toast !== null ? toast : { message: 'Success!' }; 23 | toast.type = 'positive'; 24 | this.addToast(this.setupComponent(toast), duration); 25 | } 26 | 27 | /** 28 | * Use this method to display informative toasts 29 | * __You must pass a message or header, there is no default text set__ 30 | * `this.goToastService.toastInfo({ message: 'This is a test!' });` 31 | * @param toast 32 | * @param duration 33 | */ 34 | toastInfo(toast?: ToastInterface, duration: number = 3000) : void { 35 | toast = toast !== null ? toast : { }; 36 | toast.type = 'neutral'; 37 | this.addToast(this.setupComponent(toast), duration); 38 | } 39 | 40 | /** 41 | * Use this method to display error toasts 42 | * @param toast 43 | * @param duration 44 | */ 45 | toastError(toast?: ToastInterface, duration: number = 3000) : void { 46 | toast = toast !== null ? toast : { message: 'Something went wrong' }; 47 | toast.type = 'negative'; 48 | this.addToast(this.setupComponent(toast), duration); 49 | } 50 | 51 | //#region Private Methods 52 | 53 | private setupComponent(toastInterface: ToastInterface) : GoToastComponent { 54 | let comp: GoToastComponent = new GoToastComponent(); 55 | comp.message = toastInterface.message; 56 | comp.type = toastInterface.type; 57 | comp.header = toastInterface.header; 58 | 59 | return comp; 60 | } 61 | 62 | private addToast(comp: GoToastComponent, showPeriod: number) : void { 63 | this.toasts.push(comp); 64 | this.setupTimer(comp, showPeriod); 65 | } 66 | 67 | private setupTimer(comp: GoToastComponent, showPeriod: number) :void { 68 | timer(showPeriod).subscribe(() => { 69 | this.toasts.splice(this.toasts.indexOf(comp), 1); 70 | }); 71 | } 72 | 73 | //#endregion 74 | } 75 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "goponents", 3 | "version": "0.1.0", 4 | "repository": { 5 | "type": "git", 6 | "url": "git+https://github.com/mwagz/tangoe-shared.git" 7 | }, 8 | "author": "Tangoe GoMobile", 9 | "license": "MIT", 10 | "scripts": { 11 | "ng": "ng", 12 | "start": "ng serve", 13 | "build": "ng build", 14 | "test": "npm run test_lib", 15 | "lint": "ng lint", 16 | "e2e": "ng e2e", 17 | "app": "ng build go-tester --prod", 18 | "build_lib": "ng build go-lib && npm run build_lib_scss", 19 | "build_lib_scss": "chmod +x ./sass-port.sh && ./sass-port.sh", 20 | "test_lib": "ng test go-lib", 21 | "test_app": "ng test go-tester", 22 | "npm_pack": "cd dist/go-lib && npm pack", 23 | "package": "npm run build_lib && npm run npm_pack", 24 | "publish": "npm run package && cd dist/go-lib && npm publish", 25 | "publish_local": "npm run package && node ./local_install.js" 26 | }, 27 | "private": true, 28 | "engines": { 29 | "npm": "^6.9.0", 30 | "node": "^8.11.4" 31 | }, 32 | "dependencies": { 33 | "@angular/animations": "~7.2.15", 34 | "@angular/common": "~7.2.15", 35 | "@angular/compiler": "^7.2.15", 36 | "@angular/core": "~7.2.15", 37 | "@angular/forms": "~7.2.15", 38 | "@angular/http": "~7.2.15", 39 | "@angular/platform-browser": "~7.2.15", 40 | "@angular/platform-browser-dynamic": "~7.2.15", 41 | "@angular/router": "~7.2.15", 42 | "@tangoe/gosheets": "^1.0.0", 43 | "classlist.js": "^1.1.20150312", 44 | "core-js": "^2.5.4", 45 | "npm": "^6.10.1", 46 | "rxjs": "~6.5.2", 47 | "web-animations-js": "^2.3.2", 48 | "zone.js": "~0.8.26" 49 | }, 50 | "devDependencies": { 51 | "@angular-devkit/build-angular": "^0.13.9", 52 | "@angular-devkit/build-ng-packagr": "~0.10.0", 53 | "@angular/cli": "~7.3.9", 54 | "@angular/compiler-cli": "^7.2.15", 55 | "@angular/language-service": "~7.2.15", 56 | "@types/jasmine": "~2.8.8", 57 | "@types/jasminewd2": "~2.0.3", 58 | "@types/node": "~8.9.4", 59 | "codelyzer": "^5.0.0", 60 | "jasmine-core": "~2.99.1", 61 | "jasmine-spec-reporter": "~4.2.1", 62 | "karma": "^4.1.0", 63 | "karma-chrome-launcher": "~2.2.0", 64 | "karma-jasmine": "~1.1.2", 65 | "ng-packagr": "^5.1.0", 66 | "protractor": "~5.4.0", 67 | "ts-node": "~7.0.0", 68 | "tsickle": ">=0.29.0", 69 | "tslib": "^1.9.0", 70 | "tslint": "^5.16.0", 71 | "tslint-angular": "^3.0.2", 72 | "typescript": "~3.2.4" 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-toast/go-toast.component.scss: -------------------------------------------------------------------------------- 1 | @import '~@tangoe/gosheets/base/_variables'; 2 | @import '../../../styles/mixins'; 3 | 4 | .go-toast { 5 | background: $theme-light-bg; 6 | border-radius: $global-radius; 7 | box-shadow: $global-box-shadow; 8 | display: flex; 9 | position: relative; 10 | } 11 | 12 | .go-toast-strip { 13 | background-color: $base-light-secondary; 14 | border-radius: $global-radius 0 0 $global-radius; 15 | flex-shrink: 0; 16 | width: $global-radius; 17 | } 18 | 19 | .go-toast-status { 20 | align-self: flex-start; 21 | padding: 1.5rem 1.2rem; 22 | } 23 | 24 | .go-toast-status__icon { 25 | align-items: center; 26 | background-color: $base-light-secondary; 27 | border-radius: 50%; 28 | box-shadow: $global-box-shadow; 29 | color: $base-light; 30 | display: flex; 31 | font-size: 1rem; 32 | height: 2rem; 33 | justify-content: center; 34 | user-select: none; 35 | width: 2rem; 36 | } 37 | 38 | .go-toast-status--positive { 39 | background-color: $ui-color-positive; 40 | background-image: $ui-color-positive-gradient; 41 | } 42 | 43 | .go-toast-status--neutral { 44 | background-color: $ui-color-neutral; 45 | background-image: $ui-color-neutral-gradient; 46 | } 47 | 48 | .go-toast-status--negative { 49 | background-color: $ui-color-negative; 50 | background-image: $ui-color-negative-gradient; 51 | } 52 | 53 | .go-toast-content { 54 | color: $theme-light-color; 55 | display: flex; 56 | flex: 1; 57 | flex-direction: column; 58 | justify-content: center; 59 | padding: 0 1.25rem 0.75rem 0; 60 | } 61 | 62 | .go-toast-content--no-title { 63 | padding: 1rem 1rem 1rem 0; 64 | } 65 | 66 | .go-toast-content__title { 67 | font-size: 1.25rem; 68 | margin-top: 1.2rem; 69 | } 70 | 71 | .go-toast-content__message { 72 | font-size: 0.875rem; 73 | margin: 0; 74 | } 75 | 76 | .go-toast-dismiss { 77 | padding: 0.25rem; 78 | position: absolute; 79 | right: 0; 80 | top: 0; 81 | } 82 | 83 | .go-toast-dismiss__button { 84 | border: 0; 85 | border-radius: 50%; 86 | color: $theme-light-border; 87 | cursor: pointer; 88 | display: block; 89 | outline: none; 90 | padding: 0.5rem; 91 | user-select: none; 92 | @include transition(all); 93 | 94 | &:hover, &:focus, &:active { 95 | background: $theme-light-bg-hover; 96 | color: darken($theme-light-border, 5%); 97 | } 98 | } 99 | 100 | .go-toast-dismiss__icon { 101 | display: block; 102 | font-size: 1rem; 103 | height: 1rem; 104 | } -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-icon/go-icon.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { GoIconComponent } from './go-icon.component'; 4 | 5 | describe('GoIconComponent', () => { 6 | let component: GoIconComponent; 7 | let fixture: ComponentFixture; 8 | 9 | beforeEach(async(() => { 10 | TestBed.configureTestingModule({ 11 | declarations: [ GoIconComponent ] 12 | }) 13 | .compileComponents(); 14 | })); 15 | 16 | beforeEach(() => { 17 | fixture = TestBed.createComponent(GoIconComponent); 18 | component = fixture.componentInstance; 19 | fixture.detectChanges(); 20 | }); 21 | 22 | it('should create', () => { 23 | expect(component).toBeTruthy(); 24 | }); 25 | 26 | describe('classObject()', () => { 27 | it('builds an object with a modifier class key if iconModifier exists', () => { 28 | expect(component.classObject()).toEqual({}); 29 | 30 | component.iconModifier = 'positive'; 31 | 32 | expect(component.classObject()).toEqual({ 33 | 'go-icon--positive': true 34 | }); 35 | }); 36 | 37 | it('builds an object with a additional classes key if iconClass exists', () => { 38 | expect(component.classObject()).toEqual({}); 39 | 40 | component.iconClass = 'odd multiple class use case'; 41 | 42 | expect(component.classObject()).toEqual({ 43 | 'odd multiple class use case': true 44 | }); 45 | }); 46 | }); 47 | 48 | describe('the template', () => { 49 | let goIconTemplate: HTMLElement; 50 | let iconElement: HTMLElement; 51 | 52 | beforeEach(() => { 53 | component.icon = 'sentiment_very_satisfied'; 54 | component.iconClass = 'awesome test classes'; 55 | component.iconModifier = 'positive'; 56 | 57 | fixture.detectChanges(); 58 | 59 | goIconTemplate = fixture.nativeElement; 60 | iconElement = goIconTemplate.querySelector('i'); 61 | }); 62 | 63 | it('sets the text of the element to the icon @input', () => { 64 | expect(iconElement.innerText).toBe(component.icon); 65 | }); 66 | 67 | it('adds additional classes if the iconClass @input is set', () => { 68 | expect(iconElement.classList).toContain('awesome'); 69 | expect(iconElement.classList).toContain('test'); 70 | expect(iconElement.classList).toContain('classes'); 71 | }); 72 | 73 | it('adds an additional modifier class if the iconModifier @input is set', () => { 74 | expect(iconElement.classList).toContain('go-icon--positive'); 75 | }); 76 | }); 77 | }); 78 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Goponents 2 | 3 | This project houses a set of UI components for Angular and designed around the 'Go' design system. 4 | 5 | ## Development server 6 | 7 | Run `npm run publish_local` to compile the `go-lib` project, and run a local `npm install` into the repo for `go-tester` to use. 8 | _then_ 9 | Run `ng serve --project=go-tester` to run the test project. 10 | 11 | ### Code scaffolding 12 | 13 | Run `ng generate lib/components/component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. 14 | 15 | ## Build 16 | 17 | Run `npm run package` to build and pack the the library locally. 18 | Run `npm run publish` to build and pack the library locally and also to push the package to npm. 19 | 20 | ## Other Useful Things 21 | 22 | ### Components Available 23 | 24 | | Component | Notes | 25 | |--------------|----------------------------------------| 26 | | accordion | Available | 27 | | button | Available | 28 | | card | Available | 29 | | icon | Available | 30 | | modal | Available | 31 | | off-canvas | Available | 32 | | table | Available | 33 | | toasts | Available | 34 | |--------------|----------------------------------------| 35 | | input | Priority | 36 | | textarea | Priority | 37 | | combobox | Priority | 38 | | checkbox | Priority | 39 | | copy button | Priority | 40 | | radio | Priority | 41 | | datepicker | Will Need | 42 | | autocomplete | Will Need | 43 | | masked input | Will Need | 44 | |--------------|----------------------------------------| 45 | | tabs | Idea | 46 | | badge | Idea | 47 | | tooltip | Idea | 48 | | slide toggle | Idea | 49 | | timepicker | Idea | 50 | 51 | ### Properly Exposing Files for Importing 52 | 53 | The `projects/go-lib/src/public_api.ts` file exposes files to the root of the node module. This allows for importing like: 54 | 55 | `import { GoTableConfig } from '@tangoe/goponents';` 56 | 57 | To do this properly, you must export each individual file within the `public_api.ts` file. 58 | 59 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-header/go-header.component.scss: -------------------------------------------------------------------------------- 1 | @import '~@tangoe/gosheets/base/_variables'; 2 | @import '../../../styles/variables'; 3 | @import '../../../styles/mixins'; 4 | @import '~@tangoe/gosheets/base/_mixins'; 5 | 6 | $breakpoint-header-mobile-small: 500px; 7 | 8 | .go-header { 9 | background: $theme-light-bg; 10 | box-shadow: $global-box-shadow; 11 | display: flex; 12 | height: 4rem; 13 | justify-content: space-between; 14 | position: relative; 15 | z-index: z-index(navigation); 16 | 17 | @media (max-width: $breakpoint-mobile) { 18 | flex-wrap: wrap; 19 | height: auto; 20 | } 21 | } 22 | 23 | .go-header__menu { 24 | @include transition(background); 25 | 26 | align-items: center; 27 | align-self: center; 28 | border-radius: 50%; 29 | cursor: pointer; 30 | display: flex; 31 | flex-shrink: 0; 32 | font-size: 1.5rem; 33 | height: calc(#{$side-nav-width--collapsed} - 1rem); 34 | justify-content: center; 35 | user-select: none; 36 | width: calc(#{$side-nav-width--collapsed} - 1rem); 37 | } 38 | 39 | .go-header__logo-container { 40 | align-items: center; 41 | display: flex; 42 | flex: 1; 43 | justify-content: flex-start; 44 | padding: 0.5rem 1rem; 45 | 46 | @media (max-width: $breakpoint-header-mobile-small) { 47 | padding: 0.5rem; 48 | } 49 | } 50 | 51 | .go-header__logo-container--collapsed { 52 | flex-shrink: 1; 53 | } 54 | 55 | .go-header__logo { 56 | display: block; 57 | flex: 0; 58 | height: 100%; 59 | max-width: 100%; 60 | } 61 | 62 | .go-header__left { 63 | @include transition(width); 64 | 65 | display: flex; 66 | padding: 0.5rem; 67 | width: 15.5rem; 68 | 69 | @media (max-width: $breakpoint-mobile) { 70 | height: 4rem; 71 | } 72 | } 73 | 74 | .go-header__left--collapsed { 75 | width: auto; 76 | } 77 | 78 | .go-header__middle { 79 | @include transition(padding); 80 | 81 | align-items: center; 82 | display: flex; 83 | flex: 1; 84 | justify-content: flex-start; 85 | padding: 0 1rem 0 2rem; 86 | 87 | @media (max-width: $breakpoint-mobile) { 88 | flex: auto; 89 | height: 4rem; 90 | order: 2; 91 | width: 100vw; 92 | } 93 | } 94 | 95 | .go-header__middle--collapsed { 96 | padding: 0 1rem; 97 | } 98 | 99 | .go-header__middle--hide { 100 | display: none; 101 | } 102 | 103 | .go-header__right { 104 | align-items: center; 105 | display: flex; 106 | padding: 0 2rem 0 1rem; 107 | 108 | @media (max-width: $breakpoint-mobile) { 109 | flex: 1; 110 | height: 4rem; 111 | justify-content: flex-end; 112 | padding: 0 1rem; 113 | } 114 | 115 | @media (max-width: $breakpoint-header-mobile-small) { 116 | justify-content: space-between; 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-side-nav/go-side-nav/go-side-nav.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit, Input } from '@angular/core'; 2 | import { Router, NavigationEnd } from '@angular/router'; 3 | import { filter } from 'rxjs/operators'; 4 | import { NavGroup } from '../nav-group.model'; 5 | import { NavItem } from '../nav-item.model'; 6 | import { GoSideNavService } from './go-side-nav.service'; 7 | 8 | @Component({ 9 | selector: 'go-side-nav', 10 | templateUrl: './go-side-nav.component.html', 11 | styleUrls: ['./go-side-nav.component.scss'] 12 | }) 13 | export class GoSideNavComponent implements OnInit { 14 | @Input() menuItems: Array; 15 | 16 | constructor (private router: Router, public navService: GoSideNavService) { } 17 | 18 | ngOnInit(): void { 19 | this.router.events 20 | .pipe( 21 | filter(event => event instanceof NavigationEnd) 22 | ).subscribe((event: NavigationEnd) => { 23 | this.menuItems.forEach(item => { 24 | (item as NavGroup).expanded = this.setExpanded(item, event.url); 25 | }); 26 | }); 27 | } 28 | 29 | closeNavs(navGroup: NavGroup): void { 30 | this.menuItems.forEach(group => { 31 | const g = group as NavGroup; 32 | g.expanded = this.openAccordion(g, navGroup); 33 | }); 34 | } 35 | 36 | //#region Private Methods 37 | 38 | private setExpanded(item: NavGroup | NavItem, url: string): boolean { 39 | if ((item as NavGroup).subRoutes) { 40 | return this.navGroupExpansion(item as NavGroup, url); 41 | } else { 42 | return url.includes((item as NavItem).route); 43 | } 44 | } 45 | 46 | private navGroupExpansion(group: NavGroup, url: string): boolean { 47 | group.expanded = group.subRoutes.some(subRoute => { 48 | return this.setExpanded(subRoute, url); 49 | }); 50 | return group.expanded; 51 | } 52 | 53 | /** 54 | * @description this goes through and opens the accordion of the group that was clicked on and 55 | * closes the other accordions that were previously open if they are not above the group that was 56 | * clicked on. It uses recursion to go through nested groups to make sure that if a child group 57 | * is open the parents of the child is also open. 58 | * @param group this is the group we are trying to decide if it should be open. 59 | * @param item this is the group that we are searching for that was clicked on and needs opened. 60 | */ 61 | 62 | private openAccordion(group: NavGroup, item: NavGroup): boolean { 63 | if (group.subRoutes) { 64 | if (group.routeTitle !== item.routeTitle) { 65 | group.expanded = group.subRoutes.some(subRoute => { 66 | return this.openAccordion((subRoute as NavGroup), item); 67 | }); 68 | } else { 69 | group.expanded = true; 70 | } 71 | 72 | return group.expanded; 73 | } 74 | return false; 75 | } 76 | //#endregion 77 | } 78 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-search/go-search.component.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Component, 3 | ElementRef, 4 | HostBinding, 5 | HostListener, 6 | OnInit 7 | } from '@angular/core'; 8 | import { AnimationEvent } from '@angular/animations'; 9 | import { FormBuilder, FormGroup } from '@angular/forms'; 10 | import { debounceTime, distinctUntilChanged } from 'rxjs/operators'; 11 | 12 | import { searchLoaderAnim, searchResultsAnim } from '../../animations/search.animation'; 13 | import { GoSearchService } from './go-search.service'; 14 | 15 | @Component({ 16 | selector: 'go-search', 17 | templateUrl: './go-search.component.html', 18 | styleUrls: ['./go-search.component.scss'], 19 | animations: [searchLoaderAnim, searchResultsAnim] 20 | }) 21 | export class GoSearchComponent implements OnInit { 22 | 23 | goSearchForm: FormGroup; 24 | searchActive: boolean = false; 25 | resultsOverflow: string = 'hidden'; 26 | 27 | @HostBinding('class.go-search__parent') 28 | @HostListener('document:click', ['$event.target']) 29 | onDocumentClick(target: HTMLElement) { 30 | this.closeSearchEvent(target); 31 | } 32 | 33 | constructor( 34 | public goSearchService: GoSearchService, 35 | private elementRef: ElementRef, 36 | private formBuilder: FormBuilder 37 | ) { 38 | this.goSearchForm = this.formBuilder.group({ 39 | term: '' 40 | }); 41 | } 42 | 43 | ngOnInit(): void { 44 | this.goSearchForm.valueChanges.pipe( 45 | debounceTime(500), 46 | distinctUntilChanged() 47 | ).subscribe(changes => { 48 | if (changes['term'].length >= this.goSearchService.termLength) { 49 | this.goSearchService.showNoResultsMessage = false; 50 | this.goSearchService.showLoader = true; 51 | this.goSearchService.updateSearchTerm(changes['term']); 52 | } else { 53 | this.goSearchService.showNoResultsMessage = false; 54 | this.goSearchService.hasResults = false; 55 | this.goSearchService.showLoader = false; 56 | } 57 | }); 58 | } 59 | 60 | resultsStarted(event: AnimationEvent): void { 61 | this.resultsOverflow = 'hidden'; 62 | } 63 | 64 | resultsEnded(event: AnimationEvent): void { 65 | this.resultsOverflow = event.toState === null ? 'auto' : 'hidden'; 66 | } 67 | 68 | toggleActive(): void { 69 | this.searchActive = true; 70 | } 71 | 72 | leaveInput(event: FocusEvent): void { 73 | if (event.relatedTarget && !this.elementRef.nativeElement.contains(event.relatedTarget)) { 74 | this.closeSearch(); 75 | } 76 | } 77 | 78 | private closeSearchEvent(target: HTMLElement): void { 79 | if (!this.elementRef.nativeElement.contains(target)) { 80 | this.closeSearch(); 81 | } 82 | } 83 | 84 | private closeSearch(): void { 85 | this.searchActive = false; 86 | this.goSearchService.hasResults = false; 87 | this.goSearchService.showNoResultsMessage = false; 88 | this.goSearchForm.reset('', {onlySelf: true, emitEvent: false}); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /projects/go-tester/src/app/components/test-page-2/test-page-2.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |

4 | Welcome to {{ title }}! 5 |

6 |
7 | 8 |
9 |

Action Sheet

10 | 11 | 12 | 13 | Click me to open Action Sheet 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | Another test 28 | 29 | 30 | 31 | 32 | 33 | 34 |
35 | 36 |
37 |

Loader

38 | 39 | Toggle Animation 40 | 41 |
42 |
43 |
44 |
45 | 46 | 47 | 48 |
49 |
50 |
51 | 52 |
53 |

Buttons

54 | 55 | Hey 56 | 57 | 58 | Hey 59 | 60 | 61 | Hey 62 | 63 | 64 | Nope 65 | 66 | 67 | Hey 68 | 69 | 70 | Dark 71 | 72 |
73 | 74 |
75 |

Toasts

76 | 79 | 80 |
81 |
82 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-toast/go-toast.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { GoToastComponent } from './go-toast.component'; 4 | import { GoIconModule } from '../go-icon/go-icon.module'; 5 | 6 | describe('GoToastComponent', () => { 7 | let component: GoToastComponent; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(async(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [ GoToastComponent ], 13 | imports: [ GoIconModule ] 14 | }) 15 | .compileComponents(); 16 | })); 17 | 18 | beforeEach(() => { 19 | fixture = TestBed.createComponent(GoToastComponent); 20 | component = fixture.componentInstance; 21 | }); 22 | 23 | it('should create', () => { 24 | expect(component).toBeTruthy(); 25 | }); 26 | 27 | describe('ngOnInit', () => { 28 | it('sets a default statusClass if no type is passed in', () => { 29 | fixture.detectChanges(); 30 | 31 | expect(component.statusClass).toEqual('go-toast-status--neutral'); 32 | }); 33 | 34 | it('sets a statusClass if type is passed in', () => { 35 | component.type = 'positive'; 36 | fixture.detectChanges(); 37 | 38 | expect(component.statusClass).toEqual('go-toast-status--positive'); 39 | }); 40 | 41 | it('sets a default icon if no type is passed in', () => { 42 | fixture.detectChanges(); 43 | 44 | expect(component.icon).toEqual('notifications_none'); 45 | }); 46 | 47 | it('should set an icon if type is passed in', () => { 48 | component.type = 'positive'; 49 | fixture.detectChanges(); 50 | 51 | expect(component.icon).toEqual('done'); 52 | }); 53 | }); 54 | 55 | describe('dismiss', () => { 56 | it('emits the handleClick event', () => { 57 | spyOn(component.handleDismiss, 'emit'); 58 | spyOn(component, 'dismiss').and.callThrough(); 59 | 60 | component.dismissable = true; 61 | fixture.detectChanges(); 62 | 63 | const goToastTemplate: HTMLElement = fixture.nativeElement; 64 | const buttonElement: HTMLElement = goToastTemplate.querySelector('.go-toast-dismiss__icon'); 65 | 66 | buttonElement.dispatchEvent(new Event('click')); 67 | fixture.detectChanges(); 68 | 69 | expect(component.dismiss).toHaveBeenCalled(); 70 | expect(component.handleDismiss.emit).toHaveBeenCalled(); 71 | }); 72 | }); 73 | 74 | describe('the template', () => { 75 | it('hides the dismiss button by default', () => { 76 | fixture.detectChanges(); 77 | 78 | const goToastTemplate: HTMLElement = fixture.nativeElement; 79 | const goToastDismissButton: HTMLElement = goToastTemplate.querySelector('.go-toast-dismiss__button'); 80 | 81 | expect(goToastDismissButton).toBeNull(); 82 | }); 83 | 84 | it('renders dismiss button if dismissable is true', () => { 85 | component.dismissable = true; 86 | fixture.detectChanges(); 87 | 88 | const goCardTemplate: HTMLElement = fixture.nativeElement; 89 | const goToastDismissButton: HTMLElement = goCardTemplate.querySelector('.go-toast-dismiss__button'); 90 | 91 | expect(goToastDismissButton).not.toBeNull(); 92 | }); 93 | }); 94 | }); 95 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-loader/go-loader.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { GoLoaderComponent } from './go-loader.component'; 4 | import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; 5 | 6 | describe('GoLoaderComponent', () => { 7 | let component: GoLoaderComponent; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(async(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [ GoLoaderComponent ], 13 | imports: [ BrowserAnimationsModule ] 14 | }) 15 | .compileComponents(); 16 | })); 17 | 18 | beforeEach(() => { 19 | fixture = TestBed.createComponent(GoLoaderComponent); 20 | component = fixture.componentInstance; 21 | fixture.detectChanges(); 22 | }); 23 | 24 | it('should create', () => { 25 | expect(component).toBeTruthy(); 26 | }); 27 | 28 | describe('loaderClasses()', () => { 29 | it('adds a small modifier class based on loaderSize', () => { 30 | component.loaderSize = 'small'; 31 | 32 | const containerClasses = component.loaderClasses(); 33 | expect(containerClasses['go-loader--small']).toBe(true); 34 | expect(containerClasses['go-loader--medium']).toBe(false); 35 | expect(containerClasses['go-loader--large']).toBe(false); 36 | }); 37 | 38 | it('adds a medium modifier class based on loaderSize', () => { 39 | component.loaderSize = 'medium'; 40 | 41 | const containerClasses = component.loaderClasses(); 42 | expect(containerClasses['go-loader--small']).toBe(false); 43 | expect(containerClasses['go-loader--medium']).toBe(true); 44 | expect(containerClasses['go-loader--large']).toBe(false); 45 | }); 46 | 47 | it('adds a large modifier class based on loaderSize', () => { 48 | component.loaderSize = 'large'; 49 | 50 | const containerClasses = component.loaderClasses(); 51 | expect(containerClasses['go-loader--small']).toBe(false); 52 | expect(containerClasses['go-loader--medium']).toBe(false); 53 | expect(containerClasses['go-loader--large']).toBe(true); 54 | }); 55 | 56 | it('adds a neutral modifier class based on loaderType', () => { 57 | component.loaderType = 'neutral'; 58 | 59 | const containerClasses = component.loaderClasses(); 60 | expect(containerClasses['go-loader--neutral']).toBe(true); 61 | expect(containerClasses['go-loader--negative']).toBe(false); 62 | expect(containerClasses['go-loader--positive']).toBe(false); 63 | }); 64 | 65 | it('adds a negative modifier class based on loaderType', () => { 66 | component.loaderType = 'negative'; 67 | 68 | const containerClasses = component.loaderClasses(); 69 | expect(containerClasses['go-loader--neutral']).toBe(false); 70 | expect(containerClasses['go-loader--negative']).toBe(true); 71 | expect(containerClasses['go-loader--positive']).toBe(false); 72 | }); 73 | 74 | it('adds a positive modifier class based on loaderType', () => { 75 | component.loaderType = 'positive'; 76 | 77 | const containerClasses = component.loaderClasses(); 78 | expect(containerClasses['go-loader--neutral']).toBe(false); 79 | expect(containerClasses['go-loader--negative']).toBe(false); 80 | expect(containerClasses['go-loader--positive']).toBe(true); 81 | }); 82 | }); 83 | }); 84 | -------------------------------------------------------------------------------- /projects/go-lib/src/public_api.ts: -------------------------------------------------------------------------------- 1 | /* 2 | * Public API Surface of go-lib 3 | */ 4 | 5 | export * from './lib/go-shared.module'; 6 | 7 | /***** Components *****/ 8 | // Accordion 9 | export * from './lib/components/go-accordion/go-accordion-panel.component'; 10 | export * from './lib/components/go-accordion/go-accordion.component'; 11 | export * from './lib/components/go-accordion/go-accordion.module'; 12 | 13 | // Action Sheet 14 | export * from './lib/components/go-action-sheet/go-action-sheet.component'; 15 | export * from './lib/components/go-action-sheet/go-action-sheet.module'; 16 | 17 | // Button 18 | export * from './lib/components/go-button/go-button.component'; 19 | export * from './lib/components/go-button/go-button.module'; 20 | 21 | // Card 22 | export * from './lib/components/go-card/go-card.component'; 23 | export * from './lib/components/go-card/go-card.module'; 24 | 25 | // Header 26 | export * from './lib/components/go-header/go-header.component'; 27 | export * from './lib/components/go-header/go-header.module'; 28 | 29 | // Icon 30 | export * from './lib/components/go-icon/go-icon.component'; 31 | export * from './lib/components/go-icon/go-icon.module'; 32 | 33 | // Icon Button 34 | export * from './lib/components/go-icon-button/go-icon-button.component'; 35 | export * from './lib/components/go-icon-button/go-icon-button.module'; 36 | 37 | // Layout 38 | export * from './lib/components/go-layout/go-layout.component'; 39 | export * from './lib/components/go-layout/go-layout.module'; 40 | 41 | // Loader 42 | export * from './lib/components/go-loader/go-loader.component'; 43 | export * from './lib/components/go-loader/go-loader.module'; 44 | 45 | // Modal 46 | export * from './lib/components/go-modal/go-modal.component'; 47 | export * from './lib/components/go-modal/go-modal.module'; 48 | export * from './lib/components/go-modal/go-modal.service'; 49 | 50 | // Off Canvas 51 | export * from './lib/components/go-off-canvas/go-off-canvas.component'; 52 | export * from './lib/components/go-off-canvas/go-off-canvas.module'; 53 | export * from './lib/components/go-off-canvas/go-off-canvas.service'; 54 | 55 | // Search 56 | export * from './lib/components/go-search/go-search.component'; 57 | export * from './lib/components/go-search/go-search.module'; 58 | export * from './lib/components/go-search/go-search.service'; 59 | 60 | // Side Nav 61 | export * from './lib/components/go-side-nav/go-side-nav.module'; 62 | export * from './lib/components/go-side-nav/nav-group.model'; 63 | export * from './lib/components/go-side-nav/nav-item.model'; 64 | export * from './lib/components/go-side-nav/go-side-nav/go-side-nav.component'; 65 | export * from './lib/components/go-side-nav/go-side-nav/go-side-nav.service'; 66 | 67 | // Table 68 | export * from './lib/components/go-table/go-table.component'; 69 | export * from './lib/components/go-table/go-table.module'; 70 | export * from './lib/components/go-table/go-table-config.model'; 71 | export * from './lib/components/go-table/go-table-sort.model'; 72 | export * from './lib/components/go-table/go-table-paging.model'; 73 | 74 | // Toast 75 | export * from './lib/components/go-toast/go-toast.component'; 76 | export * from './lib/components/go-toast/go-toast.module'; 77 | 78 | // Toaster 79 | export * from './lib/components/go-toaster/go-toaster.component'; 80 | export * from './lib/components/go-toaster/go-toaster.module'; 81 | export * from './lib/components/go-toaster/go-toaster.service'; 82 | -------------------------------------------------------------------------------- /projects/go-tester/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/guide/browser-support 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 | /** 38 | * If the application will be indexed by Google Search, the following is required. 39 | * Googlebot uses a renderer based on Chrome 41. 40 | * https://developers.google.com/search/docs/guides/rendering 41 | **/ 42 | // import 'core-js/es6/array'; 43 | 44 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */ 45 | import 'classlist.js'; // Run `npm install --save classlist.js`. 46 | 47 | /** IE10 and IE11 requires the following for the Reflect API. */ 48 | import 'core-js/es6/reflect'; 49 | 50 | /** 51 | * Web Animations `@angular/platform-browser/animations` 52 | * Only required if AnimationBuilder is used within the application and using IE/Edge or Safari. 53 | * Standard animation support in Angular DOES NOT require any polyfills (as of Angular 6.0). 54 | **/ 55 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`. 56 | 57 | /** 58 | * By default, zone.js will patch all possible macroTask and DomEvents 59 | * user can disable parts of macroTask/DomEvents patch by setting following flags 60 | */ 61 | 62 | // (window as any).__Zone_disable_requestAnimationFrame = true; // disable patch requestAnimationFrame 63 | // (window as any).__Zone_disable_on_property = true; // disable patch onProperty such as onclick 64 | // (window as any).__zone_symbol__BLACK_LISTED_EVENTS = ['scroll', 'mousemove']; // disable patch specified eventNames 65 | 66 | /* 67 | * in IE/Edge developer tools, the addEventListener will also be wrapped by zone.js 68 | * with the following flag, it will bypass `zone.js` patch for IE/Edge 69 | */ 70 | // (window as any).__Zone_enable_cross_context_check = true; 71 | 72 | /*************************************************************************************************** 73 | * Zone JS is required by default for Angular itself. 74 | */ 75 | import 'zone.js/dist/zone'; // Included with Angular CLI. 76 | 77 | 78 | /*************************************************************************************************** 79 | * APPLICATION IMPORTS 80 | */ 81 | 82 | import 'core-js/es7/array'; 83 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at alex.overbeck@tangoe.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-search/go-search.component.scss: -------------------------------------------------------------------------------- 1 | @import '~@tangoe/gosheets/base/variables'; 2 | @import '~@tangoe/gosheets/base/mixins'; 3 | @import '../../../styles/mixins'; 4 | 5 | .go-search { 6 | position: relative; 7 | 8 | @media (max-width: $breakpoint-tablet) { 9 | width: 100%; 10 | } 11 | } 12 | 13 | :host.go-search__parent { 14 | @media (max-width: $breakpoint-tablet) { 15 | width: 100%; 16 | } 17 | } 18 | 19 | .go-search__container { 20 | @include transition(all); 21 | 22 | background: $theme-light-bg; 23 | border: 1px solid $theme-light-border; 24 | border-radius: 1rem; 25 | box-shadow: none; 26 | color: $theme-light-border; 27 | display: flex; 28 | flex-direction: column; 29 | position: absolute; 30 | top: calc(50% - ((1.875rem + 2px) / 2)); 31 | // height of input + border, halfed 32 | width: 500px; 33 | z-index: z-index(search); 34 | 35 | &:hover { 36 | background: lighten($theme-light-app-bg, 3%); 37 | } 38 | 39 | @media (max-width: $breakpoint-tablet) { 40 | width: 100%; 41 | } 42 | } 43 | 44 | .go-search__container--active { 45 | border: 0; 46 | box-shadow: $global-box-shadow; 47 | padding: 0.5rem; 48 | top: calc(50% - (2.875rem / 2)); 49 | // height of input with padding, halfed 50 | 51 | &:hover { 52 | background: $theme-light-bg; 53 | } 54 | } 55 | 56 | .go-search__field { 57 | @include transition(all); 58 | 59 | align-items: center; 60 | display: flex; 61 | 62 | ::-ms-clear { 63 | display: none; 64 | } 65 | } 66 | 67 | .go-search__submit { 68 | align-items: center; 69 | background: transparent; 70 | border: 0; 71 | color: $theme-light-border; 72 | display: flex; 73 | font-size: 1rem; 74 | padding: 0 0.5rem; 75 | 76 | &:hover { 77 | cursor: pointer; 78 | } 79 | 80 | &:active, &:focus { 81 | outline: none; 82 | } 83 | } 84 | 85 | .go-search__icon { 86 | height: 1rem; 87 | } 88 | 89 | .go-search__input { 90 | background: transparent; 91 | border: 0; 92 | flex: 1; 93 | font-family: $base-font-stack; 94 | font-size: 0.875rem; 95 | font-weight: 300; 96 | letter-spacing: 0.02rem; 97 | min-width: 250px; 98 | padding: .5rem .5rem .5rem 0; 99 | 100 | &:-ms-input-placeholder { 101 | color: $theme-light-color; 102 | } 103 | 104 | &::placeholder { 105 | color: $theme-light-color; 106 | } 107 | 108 | &:active, &:focus { 109 | outline: none; 110 | } 111 | } 112 | 113 | .go-search__loader-container { 114 | display: flex; 115 | height: calc(4rem + 50px); 116 | justify-content: center; 117 | overflow: hidden; 118 | padding: 2rem; 119 | position: relative; 120 | } 121 | 122 | .go-search__loader { 123 | position: absolute; 124 | } 125 | 126 | .go-search__results { 127 | background: $theme-light-bg; 128 | color: $theme-light-color; 129 | font-size: 0.875rem; 130 | max-height: 400px; 131 | margin: 1rem 0 0.5rem 0; 132 | overflow-x: hidden; 133 | overflow-y: auto; 134 | padding: 0 0.5rem; 135 | } 136 | 137 | /** 138 | * This section should be included in gosheets as a global change. 139 | * Until that happens, we should keep this here. 140 | **/ 141 | ::-webkit-scrollbar { 142 | height: 12px; 143 | width: 12px; 144 | 145 | @media (max-width: 768px) { 146 | height: 0 !important; 147 | width: 0 !important; 148 | } 149 | } 150 | 151 | ::-webkit-scrollbar-track { 152 | background-color: $theme-light-app-bg; 153 | border-radius: 6px; 154 | } 155 | 156 | ::-webkit-scrollbar-thumb { 157 | background: $base-light-secondary; 158 | border: 2px solid $theme-light-app-bg; 159 | border-radius: 6px; 160 | @include transition(all); 161 | 162 | &:hover { 163 | background: $ui-color-neutral-gradient; 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-table/go-table.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
{{ tableTitle }}
4 |
5 | 6 |
7 |
8 |
9 | 13 | 14 | 15 | 30 | 31 | 32 | 33 | 37 | 49 | 50 | 51 |
20 |
21 | 22 | {{ col.title || col.field }} 23 | 24 | 25 | 26 | 27 | 28 |
29 |
42 | 43 | {{ col.getFieldData(item) }} 44 | 45 | 46 | 47 | 48 |
52 |
53 |
54 |
55 | 59 | 60 |
61 |
62 | {{ outputResultsPerPage() }} / 63 | {{ localTableConfig.totalCount | number : '1.0-0' }} Results 64 |
65 |
66 | 73 | 80 | 87 | 94 |
95 |
96 |
99 | 100 |
101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 |
 
 
{{ localTableConfig.noDataText }}
 
 
109 |
110 |
111 | -------------------------------------------------------------------------------- /angular.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json", 3 | "version": 1, 4 | "newProjectRoot": "projects", 5 | "projects": { 6 | "go-lib": { 7 | "root": "projects/go-lib", 8 | "sourceRoot": "projects/go-lib/src", 9 | "projectType": "library", 10 | "prefix": "go", 11 | "architect": { 12 | "build": { 13 | "builder": "@angular-devkit/build-ng-packagr:build", 14 | "options": { 15 | "tsConfig": "projects/go-lib/tsconfig.lib.json", 16 | "project": "projects/go-lib/ng-package.json" 17 | } 18 | }, 19 | "test": { 20 | "builder": "@angular-devkit/build-angular:karma", 21 | "options": { 22 | "main": "projects/go-lib/src/test.ts", 23 | "tsConfig": "projects/go-lib/tsconfig.spec.json", 24 | "karmaConfig": "projects/go-lib/karma.conf.js" 25 | } 26 | }, 27 | "lint": { 28 | "builder": "@angular-devkit/build-angular:tslint", 29 | "options": { 30 | "tsConfig": [ 31 | "projects/go-lib/tsconfig.lib.json", 32 | "projects/go-lib/tsconfig.spec.json" 33 | ], 34 | "exclude": [ 35 | "**/node_modules/**" 36 | ] 37 | } 38 | } 39 | } 40 | }, 41 | "go-tester": { 42 | "root": "projects/go-tester/", 43 | "sourceRoot": "projects/go-tester/src", 44 | "projectType": "application", 45 | "prefix": "app", 46 | "schematics": { 47 | "@schematics/angular:component": { 48 | "styleext": "scss" 49 | } 50 | }, 51 | "architect": { 52 | "build": { 53 | "builder": "@angular-devkit/build-angular:browser", 54 | "options": { 55 | "outputPath": "dist/go-tester", 56 | "index": "projects/go-tester/src/index.html", 57 | "main": "projects/go-tester/src/main.ts", 58 | "polyfills": "projects/go-tester/src/polyfills.ts", 59 | "tsConfig": "projects/go-tester/tsconfig.app.json", 60 | "assets": [ 61 | "projects/go-tester/src/favicon.ico", 62 | "projects/go-tester/src/assets" 63 | ], 64 | "styles": [ 65 | "projects/go-tester/src/styles.scss" 66 | ], 67 | "scripts": [] 68 | }, 69 | "configurations": { 70 | "production": { 71 | "fileReplacements": [ 72 | { 73 | "replace": "projects/go-tester/src/environments/environment.ts", 74 | "with": "projects/go-tester/src/environments/environment.prod.ts" 75 | } 76 | ], 77 | "optimization": true, 78 | "outputHashing": "all", 79 | "sourceMap": false, 80 | "extractCss": true, 81 | "namedChunks": false, 82 | "aot": true, 83 | "extractLicenses": true, 84 | "vendorChunk": false, 85 | "buildOptimizer": true, 86 | "budgets": [ 87 | { 88 | "type": "initial", 89 | "maximumWarning": "2mb", 90 | "maximumError": "5mb" 91 | } 92 | ] 93 | } 94 | } 95 | }, 96 | "serve": { 97 | "builder": "@angular-devkit/build-angular:dev-server", 98 | "options": { 99 | "browserTarget": "go-tester:build" 100 | }, 101 | "configurations": { 102 | "production": { 103 | "browserTarget": "go-tester:build:production" 104 | } 105 | } 106 | }, 107 | "extract-i18n": { 108 | "builder": "@angular-devkit/build-angular:extract-i18n", 109 | "options": { 110 | "browserTarget": "go-tester:build" 111 | } 112 | }, 113 | "test": { 114 | "builder": "@angular-devkit/build-angular:karma", 115 | "options": { 116 | "main": "projects/go-tester/src/test.ts", 117 | "polyfills": "projects/go-tester/src/polyfills.ts", 118 | "tsConfig": "projects/go-tester/tsconfig.spec.json", 119 | "karmaConfig": "projects/go-tester/karma.conf.js", 120 | "styles": [ 121 | "projects/go-tester/src/styles.css" 122 | ], 123 | "scripts": [], 124 | "assets": [ 125 | "projects/go-tester/src/favicon.ico", 126 | "projects/go-tester/src/assets" 127 | ] 128 | } 129 | }, 130 | "lint": { 131 | "builder": "@angular-devkit/build-angular:tslint", 132 | "options": { 133 | "tsConfig": [ 134 | "projects/go-tester/tsconfig.app.json", 135 | "projects/go-tester/tsconfig.spec.json" 136 | ], 137 | "exclude": [ 138 | "**/node_modules/**" 139 | ] 140 | } 141 | } 142 | } 143 | }, 144 | "go-tester-e2e": { 145 | "root": "projects/go-tester-e2e/", 146 | "projectType": "application", 147 | "prefix": "", 148 | "architect": { 149 | "e2e": { 150 | "builder": "@angular-devkit/build-angular:protractor", 151 | "options": { 152 | "protractorConfig": "projects/go-tester-e2e/protractor.conf.js", 153 | "devServerTarget": "go-tester:serve" 154 | }, 155 | "configurations": { 156 | "production": { 157 | "devServerTarget": "go-tester:serve:production" 158 | } 159 | } 160 | }, 161 | "lint": { 162 | "builder": "@angular-devkit/build-angular:tslint", 163 | "options": { 164 | "tsConfig": "projects/go-tester-e2e/tsconfig.e2e.json", 165 | "exclude": [ 166 | "**/node_modules/**" 167 | ] 168 | } 169 | } 170 | } 171 | } 172 | }, 173 | "defaultProject": "go-lib" 174 | } 175 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-accordion/go-accordion-panel.component.scss: -------------------------------------------------------------------------------- 1 | @import '~@tangoe/gosheets/base/_variables'; 2 | @import '../../../styles/variables'; 3 | @import '../../../styles/mixins'; 4 | 5 | .go-accordion-panel__title-bar { 6 | cursor: pointer; 7 | display: flex; 8 | font-size: 1.2rem; 9 | padding: 1.2rem 0; 10 | position: relative; 11 | @include transition(all); 12 | } 13 | 14 | .go-accordion-panel__title { 15 | align-items: center; 16 | display: flex; 17 | flex-grow: 1; 18 | } 19 | 20 | .go-accordion-panel__title-icon { 21 | display: flex; 22 | flex-direction: column; 23 | justify-content: center; 24 | padding-left: 1rem; 25 | text-align: center; 26 | } 27 | 28 | .go-accordion-panel__title-text { 29 | padding-left: 1rem; 30 | } 31 | 32 | .go-accordion-panel__control { 33 | display: flex; 34 | flex-direction: column; 35 | justify-content: center; 36 | padding: 0 1rem; 37 | text-align: center; 38 | } 39 | 40 | .go-accordion-panel__control-icon { 41 | @include transition(all); 42 | } 43 | 44 | .go-accordion-panel__content-container { 45 | max-height: 0; 46 | opacity: 0; 47 | overflow: hidden; 48 | visibility: hidden; 49 | @include transition(max-height opacity); 50 | } 51 | 52 | .go-accordion-panel__content { 53 | display: block; 54 | padding: 0 1rem; 55 | @include transition(all); 56 | } 57 | 58 | // ----- Light Theme Classes 59 | .go-accordion--theme-light { 60 | background: $theme-light-bg; 61 | border: 1px solid $theme-light-border; 62 | color: $theme-light-color; 63 | 64 | go-accordion-panel:not(:first-of-type) .go-accordion-panel__title-bar, 65 | go-accordion-panel:last-of-type .go-accordion-panel__title-bar { 66 | border-top: 1px solid $theme-light-border; 67 | } 68 | 69 | .go-accordion-panel--border-top .go-accordion-panel__title-bar { 70 | border-top: 1px solid $theme-light-border; 71 | } 72 | 73 | .go-accordion-panel--active .go-accordion-panel__title-bar { 74 | background: $theme-light-bg-active; 75 | } 76 | 77 | .go-accordion-panel--inactive .go-accordion-panel__title-bar { 78 | background: $theme-light-bg; 79 | } 80 | 81 | .go-accordion-panel__title-bar:hover { 82 | background: $theme-light-bg-hover; 83 | } 84 | 85 | .go-accordion-panel__content { 86 | color: $theme-light-color; 87 | } 88 | } 89 | 90 | // ----- Dark Theme Classes 91 | .go-accordion--theme-dark { 92 | background: $theme-dark-bg; 93 | border: 1px solid $theme-dark-border; 94 | color: $theme-dark-color; 95 | font-weight: 300; 96 | 97 | go-accordion-panel:not(:first-of-type) .go-accordion-panel__title-bar, 98 | go-accordion-panel:last-of-type .go-accordion-panel__title-bar { 99 | border-top: 1px solid $theme-dark-border; 100 | } 101 | 102 | .go-accordion-panel--border-top .go-accordion-panel__title-bar { 103 | border-top: 1px solid $theme-dark-border; 104 | } 105 | 106 | .go-accordion-panel--active .go-accordion-panel__title-bar { 107 | background: $theme-dark-bg-active; 108 | } 109 | 110 | .go-accordion-panel--inactive .go-accordion-panel__title-bar { 111 | background: $theme-dark-bg; 112 | } 113 | 114 | .go-accordion-panel__title-bar:hover { 115 | background: $theme-dark-bg-hover; 116 | } 117 | 118 | .go-accordion-panel__content { 119 | color: $theme-dark-color; 120 | font-weight: 300; 121 | } 122 | } 123 | 124 | .go-action-sheet__go-accordion { 125 | .go-accordion { 126 | border: none; 127 | } 128 | 129 | .go-accordion-panel__title-bar { 130 | font-size: 1rem; 131 | padding: 1rem 0; 132 | } 133 | 134 | .go-accordion-panel__control-icon { 135 | font-size: 1rem; 136 | } 137 | 138 | go-accordion-panel:not(:first-of-type) .go-accordion-panel__title-bar, 139 | go-accordion-panel:last-of-type .go-accordion-panel__title-bar { 140 | border-top: none; 141 | } 142 | 143 | .go-accordion-panel { 144 | &:first-of-type::before, 145 | .go-accordion-panel__title-bar { 146 | border-radius: 0; 147 | } 148 | } 149 | } 150 | 151 | go-accordion-panel { 152 | &:last-of-type { 153 | .go-accordion-panel::before { 154 | border-bottom-left-radius: calc(#{$global-radius} - 1px); 155 | } 156 | 157 | .go-accordion-panel__title-bar { 158 | border-radius: 0 0 $global-radius $global-radius; 159 | overflow: hidden; 160 | } 161 | } 162 | 163 | &:first-of-type { 164 | .go-accordion-panel::before { 165 | border-top-left-radius: calc(#{$global-radius} - 1px); 166 | } 167 | 168 | .go-accordion-panel__title-bar { 169 | border-radius: $global-radius $global-radius 0 0 ; 170 | overflow: hidden; 171 | } 172 | } 173 | } 174 | 175 | .go-accordion-panel { 176 | position: relative; 177 | 178 | &::before { 179 | background: $brand-color-gradient; 180 | background-color: $brand-color; 181 | content: " "; 182 | height: 100%; 183 | left: 0; 184 | opacity: 0; 185 | position: absolute; 186 | transition: all 0.25s ease-in; 187 | width: 4px; 188 | z-index: 1; 189 | } 190 | 191 | &.go-accordion-panel--active { 192 | 193 | &::before { 194 | opacity: 1; 195 | } 196 | 197 | .go-accordion-panel__control .material-icons { 198 | transform: rotate(180deg); 199 | } 200 | 201 | .go-accordion-panel__content-container { 202 | max-height: 1000000px; // this is arbitrary, used for animation 203 | opacity: 1; 204 | visibility: visible; 205 | } 206 | 207 | .go-accordion-panel__content { 208 | padding: 1.5rem 1rem; 209 | } 210 | } 211 | 212 | &.go-accordion-panel--inactive { 213 | &::before { 214 | opacity: 0; 215 | } 216 | 217 | .go-accordion-panel__control .material-icons { 218 | transform: rotate(0deg); 219 | } 220 | 221 | .go-accordion-panel__content-container { 222 | max-height: 0; 223 | opacity: 0; 224 | visibility: hidden; 225 | } 226 | } 227 | } 228 | 229 | // ----- Utility Classes 230 | .go-accordion--slim { 231 | .go-accordion-panel__title-icon { 232 | font-size: 1rem; 233 | } 234 | 235 | &:hover { 236 | background: $theme-light-bg-hover; 237 | } 238 | } 239 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-button/go-button.component.spec.ts: -------------------------------------------------------------------------------- 1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 2 | 3 | import { GoButtonComponent } from './go-button.component'; 4 | import { GoIconModule } from '../go-icon/go-icon.module'; 5 | 6 | describe('GoButtonComponent', () => { 7 | let component: GoButtonComponent; 8 | let fixture: ComponentFixture; 9 | 10 | beforeEach(async(() => { 11 | TestBed.configureTestingModule({ 12 | declarations: [ GoButtonComponent ], 13 | imports: [ GoIconModule ] 14 | }) 15 | .compileComponents(); 16 | })); 17 | 18 | beforeEach(() => { 19 | fixture = TestBed.createComponent(GoButtonComponent); 20 | component = fixture.componentInstance; 21 | fixture.detectChanges(); 22 | }); 23 | 24 | it('should create', () => { 25 | expect(component).toBeTruthy(); 26 | }); 27 | 28 | describe('clicked()', () => { 29 | it('sets isProcessing to false if useLoader is false', () => { 30 | expect(component.isProcessing).toBe(false); 31 | component.clicked(); 32 | expect(component.isProcessing).toBe(component.useLoader); 33 | }); 34 | 35 | it('sets isProcessing to useLoader', () => { 36 | component.useLoader = true; 37 | 38 | expect(component.isProcessing).not.toBe(component.useLoader); 39 | component.clicked(); 40 | expect(component.isProcessing).toBe(component.useLoader); 41 | }); 42 | 43 | it('emits the handleClick event with the isProcessing boolean', () => { 44 | spyOn(component.handleClick, 'emit'); 45 | spyOn(component, 'clicked').and.callThrough(); 46 | 47 | const goButtonTemplate: HTMLElement = fixture.nativeElement; 48 | const buttonElement: HTMLButtonElement = goButtonTemplate.querySelector('button'); 49 | 50 | buttonElement.dispatchEvent(new Event('click')); 51 | fixture.detectChanges(); 52 | 53 | expect(component.clicked).toHaveBeenCalled(); 54 | expect(component.handleClick.emit).toHaveBeenCalledWith(component.isProcessing); 55 | }); 56 | }); 57 | 58 | describe('reset()', () => { 59 | it('sets isProcessing to false', () => { 60 | component.isProcessing = true; 61 | 62 | expect(component.isProcessing).toBe(true); 63 | component.reset(); 64 | expect(component.isProcessing).toBe(false); 65 | }); 66 | }); 67 | 68 | describe('classObject()', () => { 69 | it('builds an object with all of the class values falsey', () => { 70 | const classes: object = component.classObject(); 71 | 72 | expect(Object.values(classes)).not.toContain(true); 73 | }); 74 | 75 | it('returns an object that sets go-button--negative to true based on buttonVariant', () => { 76 | expect(component.classObject()['go-button--negative']).toBe(false); 77 | 78 | component.buttonVariant = 'alert'; 79 | expect(component.classObject()['go-button--negative']).toBe(true); 80 | 81 | component.buttonVariant = 'negative'; 82 | expect(component.classObject()['go-button--negative']).toBe(true); 83 | }); 84 | 85 | it('returns an object that set go-button--neutral to true based on buttonVariant', () => { 86 | expect(component.classObject()['go-button--neutral']).toBe(false); 87 | 88 | component.buttonVariant = 'neutral'; 89 | expect(component.classObject()['go-button--neutral']).toBe(true); 90 | }); 91 | 92 | it('returns an object that set go-button--positive to true based on buttonVariant', () => { 93 | expect(component.classObject()['go-button--positive']).toBe(false); 94 | 95 | component.buttonVariant = 'positive'; 96 | expect(component.classObject()['go-button--positive']).toBe(true); 97 | }); 98 | 99 | it('returns an object that set other modifiers to true', () => { 100 | const before: object = component.classObject(); 101 | expect(before['go-button--dark']).toBe(false); 102 | expect(before['go-button--loading']).toBe(false); 103 | 104 | component.useDarkTheme = true; 105 | component.isProcessing = true; 106 | 107 | const after: object = component.classObject(); 108 | expect(after['go-button--dark']).toBe(true); 109 | expect(after['go-button--loading']).toBe(true); 110 | }); 111 | }); 112 | 113 | describe('the template', () => { 114 | it('does not include a by default', () => { 115 | const goButtonTemplate: HTMLElement = fixture.nativeElement; 116 | const iconComponent: HTMLElement = goButtonTemplate.querySelector('go-icon'); 117 | 118 | expect(iconComponent).toBeNull(); 119 | }); 120 | 121 | it('does include a if buttonIcon is set', () => { 122 | component.buttonIcon = 'test'; 123 | fixture.detectChanges(); 124 | 125 | const goButtonTemplate: HTMLElement = fixture.nativeElement; 126 | const iconComponent: HTMLElement = goButtonTemplate.querySelector('go-icon'); 127 | 128 | expect(iconComponent).not.toBeNull(); 129 | }); 130 | 131 | it('disables the button if buttonDisabled is set to true', () => { 132 | component.buttonDisabled = true; 133 | fixture.detectChanges(); 134 | 135 | const goButtonTemplate: HTMLElement = fixture.nativeElement; 136 | const buttonElement: HTMLButtonElement = goButtonTemplate.querySelector('button'); 137 | 138 | expect(buttonElement.disabled).toBe(true); 139 | }); 140 | 141 | it('disables the button if isProcessing is set to true', () => { 142 | component.isProcessing = true; 143 | fixture.detectChanges(); 144 | 145 | const goButtonTemplate: HTMLElement = fixture.nativeElement; 146 | const buttonElement: HTMLButtonElement = goButtonTemplate.querySelector('button'); 147 | 148 | expect(buttonElement.disabled).toBe(true); 149 | }); 150 | 151 | it('sets button type to button by default', () => { 152 | const goButtonTemplate: HTMLElement = fixture.nativeElement; 153 | const buttonElement: HTMLButtonElement = goButtonTemplate.querySelector('button'); 154 | 155 | expect(buttonElement.type).toBe('button'); 156 | }); 157 | 158 | it('sets the button type if buttonType is passed in', () => { 159 | component.buttonType = 'submit'; 160 | fixture.detectChanges(); 161 | 162 | const goButtonTemplate: HTMLElement = fixture.nativeElement; 163 | const buttonElement: HTMLButtonElement = goButtonTemplate.querySelector('button'); 164 | 165 | expect(buttonElement.type).toBe(component.buttonType); 166 | }); 167 | }); 168 | }); 169 | -------------------------------------------------------------------------------- /projects/go-lib/src/lib/components/go-table/go-table.component.ts: -------------------------------------------------------------------------------- 1 | import { 2 | Component, 3 | ContentChildren, 4 | EventEmitter, 5 | Input, 6 | OnChanges, 7 | OnInit, 8 | Output, 9 | QueryList 10 | } from '@angular/core'; 11 | 12 | import { GoTableColumnComponent } from './go-table-column.component'; 13 | import { GoTableConfig, GoTableDataSource, SortDirection } from './index'; 14 | import { sortBy } from './go-table-utils'; 15 | import { fadeTemplateAnimation } from '../../animations/fade.animation'; 16 | 17 | @Component({ 18 | animations: [fadeTemplateAnimation], 19 | selector: 'go-table', 20 | templateUrl: './go-table.component.html', 21 | styleUrls: ['./go-table.component.scss'] 22 | }) 23 | export class GoTableComponent implements OnInit, OnChanges { 24 | 25 | @Input() loadingData: boolean = false; 26 | @Input() showTableActions: boolean = false; 27 | @Input() stackHeader: boolean = false; 28 | @Input() tableConfig: GoTableConfig; 29 | @Input() tableTitle: string; 30 | 31 | @Output() tableChange: EventEmitter = new EventEmitter(); 32 | 33 | @ContentChildren(GoTableColumnComponent) columns: QueryList; 34 | 35 | localTableConfig: GoTableConfig; 36 | showTable: boolean = false; 37 | 38 | ngOnInit() { 39 | if (!this.tableConfig) { 40 | throw new Error("GoTableComponent: tableConfig is a required Input"); 41 | } else { 42 | this.renderTable(); 43 | } 44 | } 45 | 46 | ngOnChanges() { 47 | this.renderTable(); 48 | } 49 | 50 | renderTable() : void { 51 | if (this.tableConfig) { 52 | this.localTableConfig = JSON.parse(JSON.stringify(this.tableConfig)); 53 | 54 | this.setTotalCount(); 55 | this.handleSort(); 56 | } 57 | 58 | this.showTable = Boolean(this.tableConfig); 59 | this.loadingData = false; 60 | } 61 | 62 | hasData() : boolean { 63 | if (this.localTableConfig && this.localTableConfig.tableData) { 64 | return Boolean(this.localTableConfig.tableData.length); 65 | } 66 | 67 | return false; 68 | } 69 | 70 | sortIcons(columnField: string) : string { 71 | if (this.sortClasses(columnField, SortDirection.ascending)) { 72 | return 'arrow_upward'; 73 | } else if (this.sortClasses(columnField, SortDirection.descending)) { 74 | return 'arrow_downward'; 75 | } 76 | } 77 | 78 | showPaging() : boolean { 79 | return this.hasData() && this.localTableConfig.pageable; 80 | } 81 | 82 | toggleSort(columnField: string) : void { 83 | const { sortConfig, sortable, tableData } = this.localTableConfig; 84 | 85 | if (tableData && sortable) { 86 | this.loadingData = true; 87 | 88 | if (sortConfig && sortConfig.column === columnField) { 89 | this.localTableConfig.sortConfig.direction = this.toggleSortDir(sortConfig.direction); 90 | } else { 91 | this.localTableConfig.sortConfig = { column: columnField, direction: SortDirection.ascending }; 92 | } 93 | 94 | this.localTableConfig.pageConfig.offset = 0; 95 | 96 | if (this.isServerMode()) { 97 | this.tableChange.emit(this.localTableConfig); 98 | } else { 99 | this.handleSort(); 100 | this.loadingData = false; 101 | } 102 | } 103 | } 104 | 105 | nextPage() : void { 106 | this.loadingData = true; 107 | this.localTableConfig.pageConfig.offset = this.localTableConfig.pageConfig.offset + this.localTableConfig.pageConfig.perPage; 108 | 109 | this.tableChangeOutcome(); 110 | } 111 | 112 | isLastPage() : boolean { 113 | const { pageConfig, tableData, totalCount } = this.localTableConfig; 114 | 115 | return ((pageConfig.offset + pageConfig.perPage) >= tableData.length) && ((pageConfig.offset + pageConfig.perPage) >= totalCount); 116 | } 117 | 118 | setLastPage() : void { 119 | const { totalCount, pageConfig } = this.localTableConfig; 120 | 121 | this.loadingData = true; 122 | let offset = totalCount - (totalCount % pageConfig.perPage); 123 | this.localTableConfig.pageConfig.offset = offset === totalCount ? totalCount - pageConfig.perPage : offset; 124 | 125 | this.tableChangeOutcome(); 126 | } 127 | 128 | prevPage() : void { 129 | this.loadingData = true; 130 | this.localTableConfig.pageConfig.offset = this.localTableConfig.pageConfig.offset - this.localTableConfig.pageConfig.perPage; 131 | 132 | this.tableChangeOutcome(); 133 | } 134 | 135 | isFirstPage() : boolean { 136 | return this.localTableConfig.pageConfig.offset === 0; 137 | } 138 | 139 | setFirstPage() : void { 140 | this.loadingData = true; 141 | this.localTableConfig.pageConfig.offset = 0; 142 | 143 | this.tableChangeOutcome(); 144 | } 145 | 146 | setPerPage(event: any) : void { 147 | this.loadingData = true; 148 | this.localTableConfig.pageConfig.perPage = Number(event.target.value); 149 | this.localTableConfig.pageConfig.offset = 0; 150 | 151 | this.tableChangeOutcome(); 152 | } 153 | 154 | outputResultsPerPage() : string { 155 | const { pageConfig, totalCount } = this.localTableConfig; 156 | 157 | let beginning = this.localTableConfig.pageConfig.offset + 1; 158 | let endingEstimate = pageConfig.offset + pageConfig.perPage; 159 | let ending = endingEstimate <= totalCount ? endingEstimate : totalCount - pageConfig.offset; 160 | 161 | return beginning + " - " + ending; 162 | } 163 | 164 | setDisplayData() : any[] { 165 | const { pageConfig, tableData } = this.localTableConfig; 166 | 167 | if (this.isServerMode()) { 168 | return tableData; 169 | } else { 170 | return tableData.slice(pageConfig.offset, pageConfig.offset + pageConfig.perPage); 171 | } 172 | } 173 | 174 | /** Private Methods **/ 175 | private handleSort() : void { 176 | const { sortConfig, sortable, tableData } = this.localTableConfig; 177 | 178 | if (sortConfig && sortable && tableData && sortConfig.column) { 179 | this.localTableConfig.tableData.sort(sortBy(sortConfig.column, Boolean(sortConfig.direction))); 180 | } 181 | } 182 | 183 | private toggleSortDir(currDir: SortDirection) : SortDirection { 184 | return currDir === SortDirection.ascending ? SortDirection.descending : SortDirection.ascending; 185 | } 186 | 187 | private sortClasses(columnField: string, direction: SortDirection) : boolean { 188 | const { sortConfig } = this.localTableConfig; 189 | 190 | return sortConfig && sortConfig.column === columnField && sortConfig.direction === direction; 191 | } 192 | 193 | private setTotalCount() : void { 194 | const { totalCount, tableData } = this.localTableConfig; 195 | 196 | this.localTableConfig.totalCount = totalCount !== null ? totalCount : tableData.length; 197 | } 198 | 199 | private isServerMode() : boolean { 200 | return this.localTableConfig.dataMode === GoTableDataSource.server; 201 | } 202 | 203 | private tableChangeOutcome() : void { 204 | if (this.isServerMode()) { 205 | this.tableChange.emit(this.localTableConfig); 206 | } else { 207 | this.loadingData = false; 208 | } 209 | } 210 | } 211 | --------------------------------------------------------------------------------