From f9e1ad80a9c85a71786537a73b23245ec7a17a9f Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Wed, 6 Apr 2016 14:35:46 +0100 Subject: [PATCH] demo shell (ng2) basic angular2-based demo shell --- demo-shell-ng2/.gitignore | 7 + demo-shell-ng2/LICENSE | 21 ++ demo-shell-ng2/README.md | 21 ++ demo-shell-ng2/app/app.component.html | 109 ++++++++++ demo-shell-ng2/app/app.component.ts | 67 ++++++ .../app/components/AuthRouterOutlet.ts | 36 ++++ .../app/components/core/SideMenu.ts | 47 ++++ .../app/components/core/navbar.component.ts | 24 +++ demo-shell-ng2/app/components/core/tabs.ts | 51 +++++ .../form-design-surface.component.ts | 96 +++++++++ .../form-design-toolbar.component.ts | 91 ++++++++ demo-shell-ng2/app/components/forms.view.ts | 23 ++ demo-shell-ng2/app/components/home.view.ts | 17 ++ demo-shell-ng2/app/components/login.ts | 48 +++++ demo-shell-ng2/app/components/page1.view.ts | 14 ++ demo-shell-ng2/app/components/page2.view.ts | 14 ++ demo-shell-ng2/app/css/app.css | 7 + demo-shell-ng2/app/css/designer.css | 116 ++++++++++ demo-shell-ng2/app/css/menu.css | 201 ++++++++++++++++++ demo-shell-ng2/app/css/theme/navbar.css | 25 +++ demo-shell-ng2/app/css/widgets.css | 148 +++++++++++++ demo-shell-ng2/app/img/blank.gif | Bin 0 -> 43 bytes demo-shell-ng2/app/js/dropZone.js | 60 ++++++ demo-shell-ng2/app/main.ts | 9 + demo-shell-ng2/app/services/authentication.ts | 32 +++ demo-shell-ng2/app/services/form-service.ts | 55 +++++ demo-shell-ng2/app/widgets/template.js | 16 ++ demo-shell-ng2/app/widgets/widgetUtils.js | 30 +++ demo-shell-ng2/app/widgets/widgets-button.js | 95 +++++++++ demo-shell-ng2/app/widgets/widgets-col-12.js | 18 ++ .../app/widgets/widgets-col-2x6x4.js | 20 ++ .../app/widgets/widgets-col-4x4x4.js | 20 ++ demo-shell-ng2/app/widgets/widgets-col-6x6.js | 19 ++ demo-shell-ng2/app/widgets/widgets-col-8x4.js | 20 ++ .../app/widgets/widgets-container.js | 22 ++ demo-shell-ng2/app/widgets/widgets-input.js | 71 +++++++ demo-shell-ng2/app/widgets/widgets-row.js | 18 ++ demo-shell-ng2/index.html | 61 ++++++ demo-shell-ng2/package.json | 30 +++ demo-shell-ng2/tsconfig.json | 17 ++ demo-shell-ng2/typings.json | 7 + 41 files changed, 1803 insertions(+) create mode 100644 demo-shell-ng2/.gitignore create mode 100644 demo-shell-ng2/LICENSE create mode 100644 demo-shell-ng2/README.md create mode 100644 demo-shell-ng2/app/app.component.html create mode 100644 demo-shell-ng2/app/app.component.ts create mode 100644 demo-shell-ng2/app/components/AuthRouterOutlet.ts create mode 100644 demo-shell-ng2/app/components/core/SideMenu.ts create mode 100644 demo-shell-ng2/app/components/core/navbar.component.ts create mode 100644 demo-shell-ng2/app/components/core/tabs.ts create mode 100644 demo-shell-ng2/app/components/form-design-surface.component.ts create mode 100644 demo-shell-ng2/app/components/form-design-toolbar.component.ts create mode 100644 demo-shell-ng2/app/components/forms.view.ts create mode 100644 demo-shell-ng2/app/components/home.view.ts create mode 100644 demo-shell-ng2/app/components/login.ts create mode 100644 demo-shell-ng2/app/components/page1.view.ts create mode 100644 demo-shell-ng2/app/components/page2.view.ts create mode 100644 demo-shell-ng2/app/css/app.css create mode 100644 demo-shell-ng2/app/css/designer.css create mode 100644 demo-shell-ng2/app/css/menu.css create mode 100644 demo-shell-ng2/app/css/theme/navbar.css create mode 100644 demo-shell-ng2/app/css/widgets.css create mode 100644 demo-shell-ng2/app/img/blank.gif create mode 100644 demo-shell-ng2/app/js/dropZone.js create mode 100644 demo-shell-ng2/app/main.ts create mode 100644 demo-shell-ng2/app/services/authentication.ts create mode 100644 demo-shell-ng2/app/services/form-service.ts create mode 100644 demo-shell-ng2/app/widgets/template.js create mode 100644 demo-shell-ng2/app/widgets/widgetUtils.js create mode 100644 demo-shell-ng2/app/widgets/widgets-button.js create mode 100644 demo-shell-ng2/app/widgets/widgets-col-12.js create mode 100644 demo-shell-ng2/app/widgets/widgets-col-2x6x4.js create mode 100644 demo-shell-ng2/app/widgets/widgets-col-4x4x4.js create mode 100644 demo-shell-ng2/app/widgets/widgets-col-6x6.js create mode 100644 demo-shell-ng2/app/widgets/widgets-col-8x4.js create mode 100644 demo-shell-ng2/app/widgets/widgets-container.js create mode 100644 demo-shell-ng2/app/widgets/widgets-input.js create mode 100644 demo-shell-ng2/app/widgets/widgets-row.js create mode 100644 demo-shell-ng2/index.html create mode 100644 demo-shell-ng2/package.json create mode 100644 demo-shell-ng2/tsconfig.json create mode 100644 demo-shell-ng2/typings.json diff --git a/demo-shell-ng2/.gitignore b/demo-shell-ng2/.gitignore new file mode 100644 index 0000000000..dc8ef00369 --- /dev/null +++ b/demo-shell-ng2/.gitignore @@ -0,0 +1,7 @@ +typings/ +node_modules/ +*.js +*.js.map +.idea +!app/widgets/*.js +!app/js/*.js diff --git a/demo-shell-ng2/LICENSE b/demo-shell-ng2/LICENSE new file mode 100644 index 0000000000..6d9cb0c109 --- /dev/null +++ b/demo-shell-ng2/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Alfresco + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/demo-shell-ng2/README.md b/demo-shell-ng2/README.md new file mode 100644 index 0000000000..9bafbdae51 --- /dev/null +++ b/demo-shell-ng2/README.md @@ -0,0 +1,21 @@ +### Start development + +Install the npm packages described in the `package.json` and verify that it works: + +```bash +$ npm install +$ npm start +``` +You're ready to write your application. + +Remember the npm scripts in `package.json`: + +* `npm start` - runs the compiler and a server at the same time, both in "watch mode". +* `npm run tsc` - runs the TypeScript compiler once. +* `npm run tsc:w` - runs the TypeScript compiler in watch mode; the process keeps running, awaiting changes to TypeScript files and re-compiling when it sees them. +* `npm run lite` - runs the [lite-server](https://www.npmjs.com/package/lite-server), a light-weight, static file server, written and maintained by +[John Papa](https://github.com/johnpapa) and +[Christopher Martin](https://github.com/cgmartin) +with excellent support for Angular apps that use routing. +* `npm run typings` - runs the typings tool. +* `npm run postinstall` - called by *npm* automatically *after* it successfully completes package installation. This script installs the TypeScript definition files this app requires. diff --git a/demo-shell-ng2/app/app.component.html b/demo-shell-ng2/app/app.component.html new file mode 100644 index 0000000000..ece8142775 --- /dev/null +++ b/demo-shell-ng2/app/app.component.html @@ -0,0 +1,109 @@ + + + + + +
+ + +
+
+ + + Property 1 + Property 2 + Property 3 + Property 4 + Property 5 + Property 6 + + + + + + + + + + +
diff --git a/demo-shell-ng2/app/app.component.ts b/demo-shell-ng2/app/app.component.ts new file mode 100644 index 0000000000..adb1ce2f22 --- /dev/null +++ b/demo-shell-ng2/app/app.component.ts @@ -0,0 +1,67 @@ +import {Component} from 'angular2/core'; +import {FormService} from './services/form-service'; +import {Router, RouteConfig, ROUTER_DIRECTIVES} from "angular2/router"; +import {Login} from "./components/login"; +import {Authentication} from "./services/authentication"; +import {AuthRouterOutlet} from "./components/AuthRouterOutlet"; +import {SideMenu} from "./components/core/SideMenu"; +import {AppNavBar} from "./components/core/navbar.component"; +import {FormDesignToolbar} from "./components/form-design-toolbar.component"; +import {HomeView} from "./components/home.view"; +import {FormsView} from "./components/forms.view"; +import {Page1View} from "./components/page1.view"; +import {Page2View} from "./components/page2.view"; + +@Component({ + selector: 'my-app', + templateUrl: 'app/app.component.html', + directives: [ROUTER_DIRECTIVES, AuthRouterOutlet, SideMenu, AppNavBar, FormDesignToolbar], + providers: [FormService] +}) +@RouteConfig([ + {path: '/', name: 'Home', component: HomeView, useAsDefault: true}, + {path: '/login', name: 'Login', component: Login}, + {path: '/forms', name: 'Forms', component: FormsView}, + {path: '/page1', name: 'Page1', component: Page1View}, + {path: '/page2', name: 'Page2', component: Page2View} +]) +export class AppComponent { + + constructor( + public auth: Authentication, + public router: Router + ){} + + toggleMenu(menu: SideMenu, $event) { + if (menu) { + menu.toggle(); + } + if ($event) { + $event.preventDefault(); + } + } + + isActive(instruction: any[]): boolean { + return this.router.isRouteActive(this.router.generate(instruction)); + } + + isLoggedIn(): boolean { + return this.auth.isLoggedIn(); + } + + onLogout(event) { + event.preventDefault(); + this.auth.logout() + .subscribe( + () => this.router.navigate(['Login']) + ); + } + + /* + hideMenu(menu: SideMenu) { + if (menu && menu.isOpen) { + menu.close(); + } + } + */ +} diff --git a/demo-shell-ng2/app/components/AuthRouterOutlet.ts b/demo-shell-ng2/app/components/AuthRouterOutlet.ts new file mode 100644 index 0000000000..592be07d13 --- /dev/null +++ b/demo-shell-ng2/app/components/AuthRouterOutlet.ts @@ -0,0 +1,36 @@ +import { ElementRef, DynamicComponentLoader, Directive, Attribute } from 'angular2/core'; +import { Router, RouterOutlet, ComponentInstruction } from 'angular2/router'; +import {Authentication} from '../services/authentication'; + +@Directive({selector: 'auth-router-outlet'}) +export class AuthRouterOutlet extends RouterOutlet { + + publicRoutes: Array; + private router: Router; + + constructor( + _elementRef: ElementRef, _loader: DynamicComponentLoader, + _parentRouter: Router, @Attribute('name') nameAttr: string, + private authentication: Authentication + ) { + super(_elementRef, _loader, _parentRouter, nameAttr); + + this.router = _parentRouter; + this.publicRoutes = [ + '', 'login', 'signup' + ]; + } + + activate(instruction: ComponentInstruction) { + if (this._canActivate(instruction.urlPath)) { + return super.activate(instruction); + } + + this.router.navigate(['Login']); + } + + _canActivate(url) { + return this.publicRoutes.indexOf(url) !== -1 + || this.authentication.isLoggedIn(); + } +} diff --git a/demo-shell-ng2/app/components/core/SideMenu.ts b/demo-shell-ng2/app/components/core/SideMenu.ts new file mode 100644 index 0000000000..42be3f9c93 --- /dev/null +++ b/demo-shell-ng2/app/components/core/SideMenu.ts @@ -0,0 +1,47 @@ +import {Component, Input, ElementRef} from "angular2/core"; + +@Component({ + selector: 'side-menu', + host: { + '(click)': 'onClick($event)', + //'(document:click)': 'onOutsideClick($event)' + }, + template: ` + + ` +}) +export class SideMenu { + @Input() title: string = ''; + @Input() direction: string = 'left'; + isOpen: boolean = false; + + constructor(private el: ElementRef) { + + } + + onClick(event) { + event.preventDefault(); + event.stopPropagation(); + } + + toggle() { + this.isOpen = !this.isOpen; + } + + open() { + this.isOpen = true; + } + + close() { + this.isOpen = false; + } +} diff --git a/demo-shell-ng2/app/components/core/navbar.component.ts b/demo-shell-ng2/app/components/core/navbar.component.ts new file mode 100644 index 0000000000..3a997c996a --- /dev/null +++ b/demo-shell-ng2/app/components/core/navbar.component.ts @@ -0,0 +1,24 @@ +import {Component} from "angular2/core"; + +@Component({ + selector: 'app-navbar', + template: ` + + `, + styles: [ + ` + :host .image-button { + padding-bottom: 10px; + padding-top: 12px; + max-height: 50px; + } + ` + ] +}) +export class AppNavBar { + +} diff --git a/demo-shell-ng2/app/components/core/tabs.ts b/demo-shell-ng2/app/components/core/tabs.ts new file mode 100644 index 0000000000..ba2d09b31a --- /dev/null +++ b/demo-shell-ng2/app/components/core/tabs.ts @@ -0,0 +1,51 @@ +import {Component, Input} from 'angular2/core'; + +@Component({ + selector: 'tabs', + template: ` + + + ` +}) +export class Tabs { + tabs: Tab[] = []; + + selectTab(tab:Tab, $event) { + this.tabs.forEach(tab => { + tab.active = false; + }); + tab.active = true; + if ($event) { + $event.preventDefault(); + } + } + + addTab(tab:Tab) { + if (this.tabs.length === 0) { + tab.active = true; + } + this.tabs.push(tab); + } +} + + +@Component({ + selector: 'tab', + template: ` +
+ +
+ ` +}) +export class Tab { + @Input('tabTitle') title; + active: Boolean; + + constructor(tabs: Tabs) { + tabs.addTab(this); + } +} diff --git a/demo-shell-ng2/app/components/form-design-surface.component.ts b/demo-shell-ng2/app/components/form-design-surface.component.ts new file mode 100644 index 0000000000..e213eb479b --- /dev/null +++ b/demo-shell-ng2/app/components/form-design-surface.component.ts @@ -0,0 +1,96 @@ +import {Component, ElementRef, OnInit} from "angular2/core"; + +declare var dropZone: any; +declare var widgets: any; + +@Component({ + selector: 'form-design-surface', + template: '
' +}) +export class FormDesignSurface implements OnInit { + + private _selectedWidget: Element; + + constructor(public elementRef: ElementRef) { + //el.nativeElement.style.backgroundColor = 'yellow'; + } + + get selectedWidget(): Element { + return this._selectedWidget; + } + + set selectedWidget(val: Element) { + if (this.selectedWidget && this.selectedWidget != val) { + this._selectedWidget.classList.remove('selected'); + } + this._selectedWidget = val; + if (this._selectedWidget) { + this._selectedWidget.classList.add('selected'); + } + } + + ngOnInit() { + // Create root container + var container = widgets.container.create(); + container.dataset.widgetType = 'container'; + this.setupWidget(container); + this.elementRef.nativeElement.appendChild(container); + } + + private setupWidget(widget: HTMLElement) { + // initialize all drop placeholders + var dropPlaceholders = widget.querySelectorAll('.drop-zone'); + for (var i = 0; i < dropPlaceholders.length; i++) { + var placeholder = dropPlaceholders[i]; + var z = new dropZone({ + element: placeholder, + onDrop: this.onWidgetDrop.bind(this) + }); + } + + // initialize clicks + if (widget.dataset['widgetId']) { + widget.addEventListener('mouseup', this.onWidgetMouseUp.bind(this), false); + } + + // wire child element clicks + var nested = widget.querySelectorAll('[data-widget-id]'); + for (var x = 0; x < nested.length; x++) { + nested[x].addEventListener('mouseup', this.onWidgetMouseUp.bind(this), false); + } + } + + private onWidgetMouseUp(e) { + var wid = e.currentTarget.dataset.widgetId; + if (wid) { + console.log('Selected Widget Id: ' + wid); + this.selectedWidget = e.currentTarget; + e.stopPropagation(); + } + } + + private onWidgetDrop(dz, opts) { + var widgetType = opts.widgetType; + if (widgetType) { + var component = widgets[widgetType]; + if (component) { + var widget = component.create(); + if (widget) { + widget.dataset.widgetType = widgetType; + this.setupWidget(widget); + + // insert widget before drop zone + var container = dz.parentElement; + container.insertBefore(widget, dz); + // create new drop zone + var zone = new dropZone({ + onDrop: this.onWidgetDrop.bind(this), + minHeight: '5px' + }); + // insert new drop zone before widget + container.insertBefore(zone.element, widget); + } + } + } + } +} diff --git a/demo-shell-ng2/app/components/form-design-toolbar.component.ts b/demo-shell-ng2/app/components/form-design-toolbar.component.ts new file mode 100644 index 0000000000..53ad6d6be9 --- /dev/null +++ b/demo-shell-ng2/app/components/form-design-toolbar.component.ts @@ -0,0 +1,91 @@ +import {Component, OnInit} from "angular2/core"; +import {FormService} from "../services/form-service"; + +@Component({ + selector: 'form-design-toolbar', + providers: [FormService], + //encapsulation: ViewEncapsulation.Native, + styles: [` + .category-header { + color: #555; + padding: 11px; + margin: 0; + background: #e7e7e7; + cursor: default; + font-size: 14px; + font-weight: bold; + } + + a.toolbar-item { + cursor: move; + + display: block; + color: #777; + font-size: 1.1em; + font-weight: 300; + text-decoration: none; + + border-bottom: 1px solid #e7e7e7; + padding: 1em; + } + + a.toolbar-item:hover { + color: #555; + background: #f8f8f8; + } + + a.toolbar-item:active, a.toolbar-item.active { + color: #fff; + border-color: #428bca; + background-color: #428bca; + } + `], + template: ` + + ` +}) +export class FormDesignToolbar implements OnInit { + + categories: any[]; + private dragCache; + + constructor( + private _formService: FormService + ) {} + + ngOnInit() { + this.categories = this._formService.getWidgetCategories(); + // Stores drag ghost elements + this.dragCache = document.getElementById('drag-images-cache'); + } + + onElementDragStart(e) { + e.dataTransfer.effectAllowed = 'move'; + + var widgetType = e.target.dataset.widgetType; + + var payload = { "widgetType": widgetType }; + e.dataTransfer.setData('text', JSON.stringify(payload)); + + //var dragImage = getDragImage(widgetType); + var dragImage = this._formService.getDragImage(widgetType); + this.dragCache.appendChild(dragImage); + //e.dataTransfer.setDragImage(dragImage, dragImage.offsetWidth / 2, 0); + e.dataTransfer.setDragImage(dragImage, 0, 0); + + e.stopPropagation(); + } + + onElementDragEnd(e) { + if (this.dragCache) { + this.dragCache.innerHTML = ''; + } + } + +} diff --git a/demo-shell-ng2/app/components/forms.view.ts b/demo-shell-ng2/app/components/forms.view.ts new file mode 100644 index 0000000000..2efdfdf7aa --- /dev/null +++ b/demo-shell-ng2/app/components/forms.view.ts @@ -0,0 +1,23 @@ +import {Component} from 'angular2/core'; +import {FormDesignSurface} from "./form-design-surface.component"; + +@Component({ + selector: 'forms-view', + template: ` +
+
+
+ + +
+
+
+ `, + directives: [FormDesignSurface] +}) +export class FormsView { + /* + @ViewChild(FormDesignSurface) + private _surface: FormDesignSurface; + */ +} diff --git a/demo-shell-ng2/app/components/home.view.ts b/demo-shell-ng2/app/components/home.view.ts new file mode 100644 index 0000000000..7b5f345768 --- /dev/null +++ b/demo-shell-ng2/app/components/home.view.ts @@ -0,0 +1,17 @@ +import {Component} from 'angular2/core'; + +@Component({ + selector: 'home-view', + template: ` +
+
+
+

Home View

+
+
+
+ `, + directives: [] +}) +export class HomeView { +} diff --git a/demo-shell-ng2/app/components/login.ts b/demo-shell-ng2/app/components/login.ts new file mode 100644 index 0000000000..f8db849843 --- /dev/null +++ b/demo-shell-ng2/app/components/login.ts @@ -0,0 +1,48 @@ +import {Component} from "angular2/core"; +import {Router, ROUTER_DIRECTIVES} from "angular2/router"; +import {FORM_DIRECTIVES, ControlGroup, FormBuilder, Validators} from "angular2/common"; +import {Authentication} from "../services/authentication"; + +@Component({ + selector: 'login', + directives: [ROUTER_DIRECTIVES, FORM_DIRECTIVES], + template: ` +
+
+
+
Check your password
+
+ + +
+
+ + +
+ +
+
+
+ ` +}) +export class Login { + form: ControlGroup; + error: boolean = false; + + constructor(fb: FormBuilder, public auth: Authentication, public router: Router) { + this.form = fb.group({ + username: ['', Validators.required], + password: ['', Validators.required] + }); + } + + onSubmit(value: any, event) { + //event.preventDefault(); + this.auth.login(value.username, value.password) + .subscribe( + //(token: any) => this.router.navigate(['../Home']), + (token: any) => this.router.navigate(['Home']), + () => { this.error = true; } + ); + } +} diff --git a/demo-shell-ng2/app/components/page1.view.ts b/demo-shell-ng2/app/components/page1.view.ts new file mode 100644 index 0000000000..95be92bcd6 --- /dev/null +++ b/demo-shell-ng2/app/components/page1.view.ts @@ -0,0 +1,14 @@ +import {Component} from "angular2/core"; +@Component({ + selector: 'page1-view', + template: ` +
+
+

Page 1

+
+
+ ` +}) +export class Page1View { + +} diff --git a/demo-shell-ng2/app/components/page2.view.ts b/demo-shell-ng2/app/components/page2.view.ts new file mode 100644 index 0000000000..0c1b3031bf --- /dev/null +++ b/demo-shell-ng2/app/components/page2.view.ts @@ -0,0 +1,14 @@ +import {Component} from "angular2/core"; +@Component({ + selector: 'page2-view', + template: ` +
+
+

Page 2

+
+
+ ` +}) +export class Page2View { + +} diff --git a/demo-shell-ng2/app/css/app.css b/demo-shell-ng2/app/css/app.css new file mode 100644 index 0000000000..f52219b4a0 --- /dev/null +++ b/demo-shell-ng2/app/css/app.css @@ -0,0 +1,7 @@ +body { padding-top: 70px; } + +/* Utils */ + +.p-10 { + padding: 10px; +} diff --git a/demo-shell-ng2/app/css/designer.css b/demo-shell-ng2/app/css/designer.css new file mode 100644 index 0000000000..21f29e9bfa --- /dev/null +++ b/demo-shell-ng2/app/css/designer.css @@ -0,0 +1,116 @@ +/* Generated by less 2.2.0 */ +.drag-image { + left: 0; + position: absolute; + top: 0; + z-index: -1; +} +.drop-zone { + border-radius: 4px; + visibility: visible; +} +.drop-zone.over { + outline: 1px dashed #ddd; +} +.widget-button { + cursor: default; +} +.widget-button[contenteditable="true"] { + cursor: text; +} +.widget-input:read-only { + background-color: #ffffff; + cursor: default; +} +.widget-row { + background-color: #F5F5F5; + border: 1px solid #dddddd; + border-radius: 4px; + margin: 5px 0; + padding: 25px 14px 0; + position: relative; +} +.widget-row:before { + background-color: #F5F5F5; + border: 1px solid #dddddd; + border-radius: 4px 0 4px 0; + color: #9DA0A4; + content: "Row"; + font-size: 12px; + font-weight: bold; + left: -1px; + padding: 3px 7px; + position: absolute; + top: -1px; +} +.widget-row.selected { + border-color: green; + transition: border-color 0.5s; +} +.widget-row.selected:before { + background-color: green; + border-color: green; + color: white; +} +.widget-col { + background-color: #ffffff; + border: 1px solid #dddddd; + border-radius: 4px; + margin: 15px 0; + padding: 39px 19px 24px; + position: relative; +} +.widget-col:before { + background-color: #F5F5F5; + border: 1px solid #dddddd; + border-radius: 4px 0 4px 0; + color: #9DA0A4; + content: "Column"; + font-size: 12px; + font-weight: bold; + left: -1px; + padding: 3px 7px; + position: absolute; + top: -1px; +} +.widget-col.selected { + border-color: green; + transition: border-color 0.5s; +} +.widget-col.selected:before { + background-color: green; + border-color: green; + color: white; +} +.widget-container { + border: 1px solid #dddddd; + border-radius: 4px; + margin-left: 0; + margin-top: 10px; + padding: 30px 15px 15px; + position: relative; + width: 100%; + word-wrap: break-word; +} +.widget-container:before { + background-color: #F5F5F5; + border: 1px solid #dddddd; + border-radius: 4px 0 4px 0; + color: #9DA0A4; + content: "Container"; + font-size: 12px; + font-weight: bold; + left: -1px; + padding: 3px 7px; + position: absolute; + top: -1px; +} +.widget-container.selected { + border-color: green; + transition: border-color 0.5s; +} +.widget-container.selected:before { + background-color: green; + border-color: green; + color: white; +} diff --git a/demo-shell-ng2/app/css/menu.css b/demo-shell-ng2/app/css/menu.css new file mode 100644 index 0000000000..1a1e670d04 --- /dev/null +++ b/demo-shell-ng2/app/css/menu.css @@ -0,0 +1,201 @@ +/* General styles for all menus */ + +.cbp-spmenu { + background-color: #fff; + position: fixed; + border-color: #e7e7e7; +} + +.cbp-spmenu > h3 { + color: #555; + font-size: 1.9em; + padding: 11px; + margin: 0; + font-weight: 300; + background: #e7e7e7; + cursor: default; +} + +.cbp-spmenu > a { + display: block; + color: #777; + font-size: 1.1em; + font-weight: 300; + text-decoration: none; +} + +.cbp-spmenu > a:hover { + color: #555; + background: #f8f8f8; +} + +.cbp-spmenu > a:active, +.cbp-spmenu > a.active { + color: #fff; + border-color: #428bca; + background-color: #428bca; +} + +/* Orientation-dependent styles for the content of the menu */ + +.cbp-spmenu-vertical { + width: 240px; + height: 100%; + top: 0; + /*z-index: 1000;*/ + z-index: 1040; /* default TBS navbar index is 1030 */ + overflow-y: auto; /* vertical scrollbar */ + overflow-x: hidden; +} + +.cbp-spmenu-vertical > a { + border-bottom: 1px solid #e7e7e7; + padding: 1em; +} + +.cbp-spmenu-horizontal { + width: 100%; + height: 150px; + left: 0; + z-index: 1000; + overflow: hidden; +} + +.cbp-spmenu-horizontal > h3 { + height: 100%; + width: 20%; + float: left; +} + +.cbp-spmenu-horizontal > a { + float: left; + width: 20%; + padding: 0.8em; + border-left: 1px solid #258ecd; +} + +/* Vertical menu that slides from the left or right */ + +.cbp-spmenu-left { + left: -240px; + border-right: 1px solid #e7e7e7; +} + +.cbp-spmenu-right { + right: -240px; + border-left: 1px solid #e7e7e7; +} + +.cbp-spmenu-left.cbp-spmenu-open { + left: 0; +} + +.cbp-spmenu-right.cbp-spmenu-open { + right: 0; +} + +/* Horizontal menu that slides from the top or bottom */ + +.cbp-spmenu-top { + top: -150px; +} + +.cbp-spmenu-bottom { + bottom: -150px; +} + +.cbp-spmenu-top.cbp-spmenu-open { + top: 0; +} + +.cbp-spmenu-bottom.cbp-spmenu-open { + bottom: 0; +} + +/* Push classes applied to the body */ + +.cbp-spmenu-push { + overflow-x: hidden; + position: relative; + left: 0; +} + +.cbp-spmenu-push-toright { + left: 240px; +} + +.cbp-spmenu-push-toleft { + left: -240px; +} + +/* Transitions */ + +.cbp-spmenu, +.cbp-spmenu-push { + -webkit-transition: all 0.3s ease; + -moz-transition: all 0.3s ease; + transition: all 0.3s ease; +} + +/* Example media queries */ + +@media screen and (max-width: 55.1875em){ + + .cbp-spmenu-horizontal { + font-size: 75%; + height: 110px; + } + + .cbp-spmenu-top { + top: -110px; + } + + .cbp-spmenu-bottom { + bottom: -110px; + } +} + +@media screen and (max-height: 26.375em){ + + .cbp-spmenu-vertical { + font-size: 90%; + width: 190px; + } + + .cbp-spmenu-left, + .cbp-spmenu-push-toleft { + left: -190px; + } + + .cbp-spmenu-right { + right: -190px; + } + + .cbp-spmenu-push-toright { + left: 190px; + } +} + +/* Extra stuff */ + +/* move scrollbar for right menu to the right */ + +.cbp-spmenu-right { direction: rtl; } +.cbp-spmenu-right > * { direction: ltr; } + +/* misc */ + +a.menu-close { + color: #555; +} + +/* Show menu inside main content rather than page */ +.inline-menu { + padding-bottom: 50px; + margin-top: 50px; +} + +.inline-menu > h3 { + font-size: 14px; + font-weight: bold; +} diff --git a/demo-shell-ng2/app/css/theme/navbar.css b/demo-shell-ng2/app/css/theme/navbar.css new file mode 100644 index 0000000000..00bee7d787 --- /dev/null +++ b/demo-shell-ng2/app/css/theme/navbar.css @@ -0,0 +1,25 @@ +/* Custom theme for AppNavBar component */ + +app-navbar .navbar-default { + background-color: #0c79bf; +} + +app-navbar .navbar-default .navbar-nav > li > a, +app-navbar .navbar-default .navbar-nav > li > a:focus { + color: #ffffff; +} + +app-navbar .navbar-alfresco-logo { + padding: 0; +} + +app-navbar .navbar-alfresco-logo > img { + border: none; + background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCEtLSBHZW5lcmF0b3I6IEFkb2JlIElsbHVzdHJhdG9yIDE5LjEuMCwgU1ZHIEV4cG9ydCBQbHVnLUluIC4gU1ZHIFZlcnNpb246IDYuMDAgQnVpbGQgMCkgIC0tPgo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IgoJIHZpZXdCb3g9IjAgMCAxNDUgNDIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDE0NSA0MjsiIHdpZHRoPSIxNDUiIGhlaWdodD0iNDIiIHhtbDpzcGFjZT0icHJlc2VydmUiPgo8c3R5bGUgdHlwZT0idGV4dC9jc3MiPgoJLnN0MHtmaWxsOiNGRkZGRkY7fQoJLnN0MXtmaWxsOiM4QkRDMDE7fQoJLnN0MntmaWxsOiNGQkExMDA7fQoJLnN0M3tmaWxsOiMzM0FBRkY7fQoJLnN0NHtmaWxsOiMwMTdERkY7fQoJLnN0NXtmaWxsOiNGRkUwMDA7fQoJLnN0NntmaWxsOiM0N0I0MUI7fQoJLnN0N3tmaWxsLXJ1bGU6ZXZlbm9kZDtjbGlwLXJ1bGU6ZXZlbm9kZDtmaWxsOiNGRkZGRkY7fQo8L3N0eWxlPgo8Zz4KCTxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik0yMSwyMWwtNS44LTUuOGwtMC4yLTAuMmMtMy40LTMuNC04LjgtMy40LTEyLjEsMGMtMy40LDMuNC0zLjQsOC44LDAsMTIuMWMzLjQsMy40LDguOCwzLjMsMTIuMSwwTDIxLDIxCgkJTDIxLDIxeiIvPgoJPHBhdGggY2xhc3M9InN0MCIgZD0iTTIxLDIxbDAsOC4zbDAsMC4zYzAsNC43LTMuOCw4LjYtOC42LDguNmMtNC43LDAtOC42LTMuOC04LjYtOC42YzAtNC43LDMuOC04LjYsOC42LTguNkwyMSwyMUwyMSwyMXoiLz4KCTxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik0yMSwyMWwwLDguM2wwLDAuM2MwLDQuNy0zLjgsOC42LTguNiw4LjZjLTQuNywwLTguNi0zLjgtOC42LTguNmMwLTQuNywzLjgtOC42LDguNi04LjZMMjEsMjFMMjEsMjF6Ii8+Cgk8cGF0aCBjbGFzcz0ic3QwIiBkPSJNMjEsMjFsMCw4LjNsMCwwLjNjMCw0LjctMy44LDguNi04LjYsOC42Yy00LjcsMC04LjYtMy44LTguNi04LjZjMC0wLjUsMC0xLDAuMS0xLjVjMy4zLDIuMyw4LDIsMTEtMUwyMSwyMQoJCUwyMSwyMUwyMSwyMXoiLz4KCTxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0xMi40LDIyLjFjLTQuMSwwLTcuNSwzLjQtNy41LDcuNWMwLDQuMSwzLjQsNy41LDcuNSw3LjVjNC4xLDAsNy41LTMuNCw3LjUtNy41bDAtMC4zbDAtNy4yTDEyLjQsMjIuMQoJCUwxMi40LDIyLjFMMTIuNCwyMi4xeiIvPgoJPHBhdGggY2xhc3M9InN0MCIgZD0iTTIxLDIxbDUuOCw1LjhsMC4yLDAuMmMzLjQsMy40LDMuNCw4LjgsMCwxMi4xYy0zLjQsMy40LTguOCwzLjQtMTIuMSwwYy0zLjQtMy40LTMuMy04LjgsMC0xMi4xTDIxLDIxTDIxLDIxegoJCSIvPgoJPHBhdGggY2xhc3M9InN0MSIgZD0iTTE1LjcsMjcuOGMtMi45LDIuOS0yLjksNy43LDAsMTAuNmMyLjksMi45LDcuNywyLjksMTAuNiwwYzIuOS0yLjksMi45LTcuNywwLTEwLjZsLTAuMi0wLjJMMjEsMjIuNQoJCUwxNS43LDI3LjhMMTUuNywyNy44TDE1LjcsMjcuOHoiLz4KCTxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik0yMSwyMWw4LjMsMGwwLjMsMGM0LjcsMCw4LjYsMy44LDguNiw4LjZjMCw0LjctMy44LDguNi04LjYsOC42Yy00LjcsMC04LjYtMy44LTguNi04LjZMMjEsMjFMMjEsMjF6Ii8+Cgk8cGF0aCBjbGFzcz0ic3QxIiBkPSJNMjIuMSwyOS42YzAsNC4xLDMuNCw3LjUsNy41LDcuNWM0LjEsMCw3LjUtMy40LDcuNS03LjVjMC00LjEtMy40LTcuNS03LjUtNy41bC0wLjMsMGwtNy4yLDBMMjIuMSwyOS42CgkJTDIyLjEsMjkuNkwyMi4xLDI5LjZ6Ii8+Cgk8cGF0aCBjbGFzcz0ic3QwIiBkPSJNMjEsMjFsNS44LTUuOGwwLjItMC4yYzMuNC0zLjQsOC44LTMuNCwxMi4xLDBjMy40LDMuNCwzLjQsOC44LDAsMTIuMWMtMy40LDMuNC04LjgsMy4zLTEyLjEsMEwyMSwyMUwyMSwyMXoiCgkJLz4KCTxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik0yNy44LDI2LjNjMi45LDIuOSw3LjcsMi45LDEwLjYsMGMyLjktMi45LDIuOS03LjcsMC0xMC42Yy0yLjktMi45LTcuNy0yLjktMTAuNiwwbC0wLjIsMC4yTDIyLjUsMjEKCQlMMjcuOCwyNi4zTDI3LjgsMjYuM0wyNy44LDI2LjN6Ii8+Cgk8cGF0aCBjbGFzcz0ic3QwIiBkPSJNMjEsMjFsMC04LjNsMC0wLjNjMC00LjcsMy44LTguNiw4LjYtOC42YzQuNywwLDguNiwzLjgsOC42LDguNmMwLDQuNy0zLjgsOC42LTguNiw4LjZMMjEsMjFMMjEsMjF6Ii8+Cgk8cGF0aCBjbGFzcz0ic3QyIiBkPSJNMjkuNiwxOS45YzQuMSwwLDcuNS0zLjQsNy41LTcuNWMwLTQuMS0zLjQtNy41LTcuNS03LjVjLTQuMSwwLTcuNSwzLjQtNy41LDcuNWwwLDAuM2wwLDcuMkgyOS42TDI5LjYsMTkuOQoJCUwyOS42LDE5Ljl6Ii8+Cgk8cGF0aCBjbGFzcz0ic3QwIiBkPSJNMjEsMjFsLTUuOC01LjhsLTAuMi0wLjJjLTMuNC0zLjQtMy40LTguOCwwLTEyLjFjMy40LTMuNCw4LjgtMy40LDEyLjEsMGMzLjQsMy40LDMuMyw4LjgsMCwxMi4xTDIxLDIxTDIxLDIxCgkJeiIvPgoJPHBhdGggY2xhc3M9InN0MyIgZD0iTTI2LjMsMTQuMmMyLjktMi45LDIuOS03LjcsMC0xMC42Yy0yLjktMi45LTcuNy0yLjktMTAuNiwwYy0yLjksMi45LTIuOSw3LjcsMCwxMC42bDAuMiwwLjJsNS4xLDUuMQoJCUwyNi4zLDE0LjJMMjYuMywxNC4yTDI2LjMsMTQuMnoiLz4KCTxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik0yMSwyMWwtOC4zLDBsLTAuMywwYy00LjcsMC04LjYtMy44LTguNi04LjZjMC00LjcsMy44LTguNiw4LjYtOC42YzQuNywwLDguNiwzLjgsOC42LDguNkwyMSwyMUwyMSwyMXoiLz4KCTxwYXRoIGNsYXNzPSJzdDMiIGQ9Ik0xOS45LDEyLjRjMC00LjEtMy40LTcuNS03LjUtNy41Yy00LjEsMC03LjUsMy40LTcuNSw3LjVjMCw0LjEsMy40LDcuNSw3LjUsNy41bDAuMywwbDcuMiwwTDE5LjksMTIuNAoJCUwxOS45LDEyLjRMMTkuOSwxMi40eiIvPgoJPHBhdGggY2xhc3M9InN0MCIgZD0iTTIxLDIxTDAuMywyMWMwLTIuMiwwLjgtNC40LDIuNS02LjFjMy40LTMuNCw4LjgtMy4zLDEyLjEsMEwyMSwyMUwyMSwyMXoiLz4KCTxwYXRoIGNsYXNzPSJzdDMiIGQ9Ik0xNC4yLDE1LjdsNS4zLDUuM2wtNywwYy0zLjgsMC03LDIuNS04LjIsNS45Yy0wLjItMC4yLTAuNS0wLjQtMC43LTAuNmMtMi45LTIuOS0yLjktNy43LDAtMTAuNgoJCUM2LjUsMTIuOCwxMS4yLDEyLjgsMTQuMiwxNS43TDE0LjIsMTUuN3oiLz4KCTxwYXRoIGNsYXNzPSJzdDQiIGQ9Ik0xNC4yLDE1LjdsNC4yLDQuMmgtNS42bC0wLjMsMGMtMy40LDAtNi4zLTIuMy03LjItNS40QzguMSwxMi45LDExLjcsMTMuMywxNC4yLDE1LjdMMTQuMiwxNS43TDE0LjIsMTUuN3oiLz4KCTxwYXRoIGNsYXNzPSJzdDQiIGQ9Ik0xOS45LDEyLjRsMCw1LjlsLTQtNGwtMC4yLTAuMmMtMi40LTIuNC0yLjgtNi4xLTEuMi04LjlDMTcuNiw2LjEsMTkuOSw5LDE5LjksMTIuNEwxOS45LDEyLjRMMTkuOSwxMi40eiIvPgoJPHBhdGggY2xhc3M9InN0NCIgZD0iTTI2LjMsMTQuMmwtNC4yLDQuMmwwLTUuNmwwLTAuM2MwLTMuNCwyLjMtNi4zLDUuNC03LjJDMjkuMiw4LDI4LjcsMTEuNywyNi4zLDE0LjJMMjYuMywxNC4yTDI2LjMsMTQuMnoiLz4KCTxwYXRoIGNsYXNzPSJzdDUiIGQ9Ik0yOS42LDE5LjlsLTUuOSwwbDQtNGwwLjItMC4yYzIuNC0yLjQsNi4xLTIuOCw5LTEuMkMzNS45LDE3LjYsMzMsMTkuOSwyOS42LDE5LjlMMjkuNiwxOS45TDI5LjYsMTkuOXoiLz4KCTxwYXRoIGNsYXNzPSJzdDYiIGQ9Ik0yNy44LDI2LjNsLTQuMi00LjJsNS42LDBsMC4zLDBjMy40LDAsNi4zLDIuMyw3LjIsNS40QzMzLjksMjkuMSwzMC4yLDI4LjcsMjcuOCwyNi4zTDI3LjgsMjYuM0wyNy44LDI2LjN6IgoJCS8+Cgk8cGF0aCBjbGFzcz0ic3Q2IiBkPSJNMjIuMSwyOS41bDAtNS45bDQsNGwwLjIsMC4yYzIuNCwyLjQsMi44LDYuMSwxLjIsOC45QzI0LjQsMzUuOSwyMi4xLDMzLDIyLjEsMjkuNUwyMi4xLDI5LjVMMjIuMSwyOS41eiIvPgoJPHBhdGggY2xhc3M9InN0NiIgZD0iTTE1LjcsMjcuOGw0LjItNC4ybDAsNS42bDAsMC4zYzAsMy40LTIuMyw2LjMtNS40LDcuMkMxMi45LDM0LDEzLjMsMzAuMywxNS43LDI3LjhMMTUuNywyNy44TDE1LjcsMjcuOHoiLz4KCTxwYXRoIGNsYXNzPSJzdDYiIGQ9Ik0xMi40LDIyLjFsNS45LDBsLTQsNGwtMC4yLDAuMmMtMi40LDIuNC02LjEsMi44LTksMS4yQzYuMSwyNC40LDksMjIuMSwxMi40LDIyLjFMMTIuNCwyMi4xTDEyLjQsMjIuMXoiLz4KCTxwYXRoIGNsYXNzPSJzdDciIGQ9Ik00My4yLDMyLjRoMi4zbDIuNy02LjloMTAuMmwyLjcsNi45aDIuM2wtOC44LTIyLjNoLTIuNEw0My4yLDMyLjRMNDMuMiwzMi40eiBNNTMuMywxMi4ybDQuMywxMS40aC04LjgKCQlMNTMuMywxMi4yTDUzLjMsMTIuMnoiLz4KCTxwb2x5Z29uIGNsYXNzPSJzdDAiIHBvaW50cz0iNjQuMSwzMi40IDY2LjEsMzIuNCA2Ni4xLDEwLjEgNjQuMSwxMC4xIDY0LjEsMzIuNCAJIi8+Cgk8cGF0aCBjbGFzcz0ic3QwIiBkPSJNNzQuNSwxNi4zaC0zLjJ2LTEuNGMwLTAuNCwwLTAuOCwwLTEuMmMwLTAuNCwwLjEtMC43LDAuMi0xYzAuMS0wLjMsMC4zLTAuNSwwLjYtMC43YzAuMy0wLjIsMC43LTAuMywxLjMtMC4zCgkJYzAuMiwwLDAuNSwwLDAuNywwYzAuMiwwLDAuNSwwLjEsMC44LDAuMXYtMS43Yy0wLjMsMC0wLjYtMC4xLTAuOC0wLjFjLTAuMywwLTAuNSwwLTAuOCwwYy0wLjgsMC0xLjQsMC4xLTIsMC4zCgkJYy0wLjUsMC4yLTAuOSwwLjYtMS4yLDFjLTAuMywwLjQtMC41LDAuOS0wLjYsMS41Yy0wLjEsMC42LTAuMiwxLjItMC4yLDEuOXYxLjVoLTIuOFYxOGgyLjh2MTQuNWgyVjE4aDMuMlYxNi4zTDc0LjUsMTYuM3oiLz4KCTxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik03NS4xLDMyLjRoMlYyNGMwLTAuOCwwLjEtMS42LDAuNC0yLjNjMC4zLTAuNywwLjctMS4zLDEuMi0xLjhjMC41LTAuNSwxLjItMC45LDEuOS0xLjIKCQljMC43LTAuMywxLjUtMC40LDIuNC0wLjR2LTJjLTEuNS0wLjEtMi43LDAuMi0zLjgsMC45Yy0xLjEsMC42LTEuOCwxLjYtMi4zLDIuOWgtMC4xdi0zLjhoLTEuOFYzMi40TDc1LjEsMzIuNHoiLz4KCTxwYXRoIGNsYXNzPSJzdDciIGQ9Ik05Ni40LDI0LjljMC0xLjEtMC4xLTIuMS0wLjMtMy4yYy0wLjMtMS0wLjctMi0xLjItMi44Yy0wLjYtMC44LTEuMy0xLjQtMi4yLTEuOWMtMC45LTAuNS0yLTAuNy0zLjMtMC43CgkJYy0xLjMsMC0yLjQsMC4yLTMuMywwLjdjLTAuOSwwLjUtMS43LDEuMS0yLjMsMS44Yy0wLjYsMC44LTEsMS42LTEuMywyLjZjLTAuMywxLTAuNCwxLjktMC40LDNjMCwxLjEsMC4xLDIuMSwwLjQsMy4xCgkJYzAuMywxLDAuNywxLjgsMS4zLDIuNmMwLjYsMC43LDEuMywxLjMsMi4zLDEuOGMwLjksMC40LDIsMC42LDMuMywwLjZjMiwwLDMuNi0wLjUsNC43LTEuNWMxLjEtMSwxLjktMi40LDIuMy00LjNoLTIKCQljLTAuMywxLjItMC45LDIuMi0xLjcsM2MtMC44LDAuOC0xLjksMS4xLTMuNCwxLjFjLTAuOSwwLTEuNy0wLjItMi40LTAuNWMtMC43LTAuNC0xLjItMC44LTEuNi0xLjRjLTAuNC0wLjYtMC43LTEuMi0wLjktMS45CgkJYy0wLjItMC43LTAuMy0xLjQtMC4zLTIuMUg5Ni40TDk2LjQsMjQuOXogTTg0LDIzLjJjMC4xLTAuNywwLjMtMS4zLDAuNS0yYzAuMy0wLjYsMC42LTEuMiwxLTEuN2MwLjQtMC41LDEtMC45LDEuNi0xLjIKCQljMC42LTAuMywxLjMtMC40LDIuMi0wLjRjMC44LDAsMS41LDAuMSwyLjEsMC40YzAuNiwwLjMsMS4yLDAuNywxLjYsMS4yYzAuNCwwLjUsMC44LDEsMSwxLjdjMC4yLDAuNiwwLjQsMS4zLDAuNCwySDg0TDg0LDIzLjJ6IgoJCS8+Cgk8cGF0aCBjbGFzcz0ic3QwIiBkPSJNMTA5LjUsMjFjMC0wLjktMC4yLTEuNi0wLjUtMi4zYy0wLjMtMC42LTAuNy0xLjItMS4zLTEuNmMtMC41LTAuNC0xLjEtMC44LTEuOC0xYy0wLjctMC4yLTEuNS0wLjMtMi4zLTAuMwoJCWMtMC43LDAtMS40LDAuMS0yLjEsMC4zYy0wLjcsMC4yLTEuNCwwLjQtMiwwLjhjLTAuNiwwLjQtMS4xLDAuOC0xLjQsMS40Yy0wLjQsMC42LTAuNSwxLjMtMC41LDIuMWMwLDAuNywwLjEsMS4zLDAuMywxLjcKCQljMC4yLDAuNSwwLjUsMC45LDEsMS4yYzAuNCwwLjMsMC45LDAuNiwxLjQsMC44YzAuNSwwLjIsMS4xLDAuNCwxLjgsMC42bDIuNSwwLjZjMC40LDAuMSwwLjksMC4yLDEuMywwLjRjMC40LDAuMSwwLjgsMC4zLDEuMSwwLjUKCQljMC4zLDAuMiwwLjYsMC41LDAuOCwwLjhjMC4yLDAuMywwLjMsMC43LDAuMywxLjJjMCwwLjYtMC4xLDEtMC40LDEuNGMtMC4zLDAuNC0wLjYsMC43LTEuMSwxYy0wLjQsMC4zLTAuOSwwLjQtMS40LDAuNQoJCWMtMC41LDAuMS0xLDAuMi0xLjUsMC4yYy0xLjMsMC0yLjQtMC4zLTMuMy0xYy0wLjktMC43LTEuNC0xLjctMS41LTNoLTJjMC4yLDIsMC44LDMuNCwyLDQuM2MxLjIsMC45LDIuNywxLjQsNC42LDEuNAoJCWMwLjgsMCwxLjUtMC4xLDIuMy0wLjNjMC44LTAuMiwxLjUtMC41LDIuMS0wLjhjMC42LTAuNCwxLjEtMC45LDEuNS0xLjVjMC40LTAuNiwwLjYtMS40LDAuNi0yLjJjMC0wLjctMC4xLTEuMy0wLjQtMS44CgkJYy0wLjMtMC41LTAuNi0xLTEtMS4zYy0wLjQtMC40LTAuOS0wLjYtMS41LTAuOWMtMC42LTAuMi0xLjEtMC40LTEuNy0wLjVsLTIuNi0wLjZjLTAuMy0wLjEtMC43LTAuMi0xLjEtMC4zCgkJYy0wLjQtMC4xLTAuOC0wLjMtMS4xLTAuNWMtMC4zLTAuMi0wLjYtMC41LTAuOC0wLjhjLTAuMi0wLjMtMC4zLTAuNy0wLjMtMS4xYzAtMC41LDAuMS0xLDAuMy0xLjNjMC4yLTAuNCwwLjUtMC42LDAuOS0wLjkKCQljMC40LTAuMiwwLjgtMC40LDEuMi0wLjVjMC40LTAuMSwwLjktMC4xLDEuMy0wLjFjMC42LDAsMS4xLDAuMSwxLjYsMC4yYzAuNSwwLjEsMC45LDAuMywxLjMsMC42YzAuNCwwLjMsMC43LDAuNywwLjksMS4xCgkJYzAuMiwwLjQsMC40LDEsMC40LDEuNkgxMDkuNUwxMDkuNSwyMXoiLz4KCTxwYXRoIGNsYXNzPSJzdDAiIGQ9Ik0xMjQuNCwyMS44Yy0wLjItMS45LTAuOS0zLjItMi4xLTQuMmMtMS4yLTAuOS0yLjctMS40LTQuNC0xLjRjLTEuMiwwLTIuMywwLjItMy4zLDAuNgoJCWMtMC45LDAuNC0xLjcsMS0yLjQsMS43Yy0wLjYsMC43LTEuMSwxLjYtMS41LDIuNmMtMC4zLDEtMC41LDItMC41LDMuMWMwLDEuMSwwLjIsMi4xLDAuNSwzLjFjMC4zLDEsMC44LDEuOCwxLjUsMi42CgkJYzAuNiwwLjcsMS40LDEuMywyLjQsMS43YzAuOSwwLjQsMiwwLjYsMy4zLDAuNmMxLjgsMCwzLjMtMC42LDQuNS0xLjdjMS4yLTEuMSwxLjktMi42LDIuMi00LjZoLTJjLTAuMSwwLjctMC4yLDEuMy0wLjUsMS44CgkJYy0wLjMsMC42LTAuNiwxLTEsMS41Yy0wLjQsMC40LTAuOSwwLjctMS40LDFjLTAuNSwwLjItMS4xLDAuMy0xLjcsMC4zYy0wLjksMC0xLjgtMC4yLTIuNS0wLjZjLTAuNy0wLjQtMS4zLTAuOS0xLjgtMS41CgkJYy0wLjUtMC42LTAuOC0xLjMtMS4xLTIuMWMtMC4yLTAuOC0wLjQtMS41LTAuNC0yLjNjMC0wLjgsMC4xLTEuNiwwLjQtMi4zYzAuMi0wLjgsMC42LTEuNSwxLjEtMi4xYzAuNS0wLjYsMS4xLTEuMSwxLjgtMS41CgkJYzAuNy0wLjQsMS41LTAuNiwyLjUtMC42YzEuMywwLDIuMywwLjMsMywxYzAuNywwLjcsMS4yLDEuNiwxLjUsMi44SDEyNC40TDEyNC40LDIxLjh6Ii8+Cgk8cGF0aCBjbGFzcz0ic3Q3IiBkPSJNMTMyLjgsMTYuM2MtMS4yLDAtMi4zLDAuMi0zLjMsMC42Yy0wLjksMC40LTEuNywxLTIuNCwxLjdjLTAuNiwwLjctMS4xLDEuNi0xLjUsMi42Yy0wLjMsMS0wLjUsMi0wLjUsMy4xCgkJYzAsMS4xLDAuMiwyLjEsMC41LDMuMWMwLjMsMSwwLjgsMS44LDEuNSwyLjZjMC42LDAuNywxLjQsMS4zLDIuNCwxLjdjMC45LDAuNCwyLDAuNiwzLjMsMC42YzEuMiwwLDIuMy0wLjIsMy4zLTAuNgoJCWMwLjktMC40LDEuNy0xLDIuNC0xLjdjMC42LTAuNywxLjEtMS42LDEuNS0yLjZjMC4zLTEsMC41LTIsMC41LTMuMWMwLTEuMS0wLjItMi4xLTAuNS0zLjFjLTAuMy0xLTAuOC0xLjgtMS41LTIuNgoJCWMtMC42LTAuNy0xLjQtMS4zLTIuNC0xLjdDMTM1LjEsMTYuNSwxMzQuMSwxNi4zLDEzMi44LDE2LjNMMTMyLjgsMTYuM3ogTTEzMi44LDE4YzAuOSwwLDEuOCwwLjIsMi41LDAuNmMwLjcsMC40LDEuMywwLjksMS44LDEuNQoJCWMwLjUsMC42LDAuOCwxLjMsMS4xLDIuMWMwLjIsMC44LDAuNCwxLjUsMC40LDIuM2MwLDAuOC0wLjEsMS42LTAuNCwyLjNjLTAuMiwwLjgtMC42LDEuNS0xLjEsMi4xYy0wLjUsMC42LTEuMSwxLjEtMS44LDEuNQoJCWMtMC43LDAuNC0xLjUsMC42LTIuNSwwLjZjLTAuOSwwLTEuOC0wLjItMi41LTAuNmMtMC43LTAuNC0xLjMtMC45LTEuOC0xLjVjLTAuNS0wLjYtMC44LTEuMy0xLjEtMi4xYy0wLjItMC44LTAuNC0xLjUtMC40LTIuMwoJCWMwLTAuOCwwLjEtMS42LDAuNC0yLjNjMC4yLTAuOCwwLjYtMS41LDEuMS0yLjFjMC41LTAuNiwxLjEtMS4xLDEuOC0xLjVDMTMxLjEsMTguMSwxMzEuOSwxOCwxMzIuOCwxOEwxMzIuOCwxOHoiLz4KCTxwb2x5Z29uIGNsYXNzPSJzdDAiIHBvaW50cz0iMTM5LjUsMTYuNCAxNDAuMywxNi40IDE0MC4zLDE4LjUgMTQwLjUsMTguNSAxNDAuNSwxNi40IDE0MS4zLDE2LjQgMTQxLjMsMTYuMiAxMzkuNSwxNi4yIAoJCTEzOS41LDE2LjQgCSIvPgoJPHBvbHlnb24gY2xhc3M9InN0MCIgcG9pbnRzPSIxNDEuNSwxOC41IDE0MS44LDE4LjUgMTQxLjgsMTYuNiAxNDEuOCwxNi42IDE0Mi41LDE4LjUgMTQyLjgsMTguNSAxNDMuNSwxNi42IDE0My41LDE2LjYgCgkJMTQzLjUsMTguNSAxNDMuOCwxOC41IDE0My44LDE2LjIgMTQzLjQsMTYuMiAxNDIuNiwxOC4yIDE0MS45LDE2LjIgMTQxLjUsMTYuMiAxNDEuNSwxOC41IAkiLz4KPC9nPgo8L3N2Zz4K); + margin-top: 2px; + width: 155px; + height: 48px; + background-size: auto auto; + background-position: 5px 0; + background-repeat: no-repeat; +} diff --git a/demo-shell-ng2/app/css/widgets.css b/demo-shell-ng2/app/css/widgets.css new file mode 100644 index 0000000000..f190616a75 --- /dev/null +++ b/demo-shell-ng2/app/css/widgets.css @@ -0,0 +1,148 @@ +/* Layout */ + +.drag-image { + position: absolute; + left: 0; + top: 0; + z-index: -1; +} + +.drop-zone { + border-radius: 4px; + /*height: 20px;*/ + visibility: visible /*!Important*/; +} + +.drop-zone.over { + /*height: 100px;*/ + outline: 1px dashed #ddd; +} + +ul.toolbar { + list-style: none; + margin: 0 0 1em; + padding: 0; +} + +ul.toolbar li { + background: #F7F7F7; + border: 1px solid #D9D9D9; + border-radius: 3px; + display: inline-block; + margin: 0 1em 1em 0; + padding: 0.5em 1em; +} + +/* Widgets */ + +/*.widget {}*/ + +.widget.widget-button { + cursor: default; +} + +.widget.widget-button[contentEditable="true"] { + cursor: text; +} + +/*.widget.widget-input {}*/ + +.widget.widget-input:read-only { + background-color: #fff; + cursor: default; +} + +/*.widget.widget-input.drag:before { + content: "Input"; +}*/ + +.widget.widget-input:before { + content: "Input"; +} + +.widget.widget-row { + background-color: #F5F5F5; + border: 1px solid #DDDDDD; + border-radius: 4px; + margin: 5px 0; + padding: 25px 14px 0; + position: relative; +} + +.widget.widget-row:before { + background-color: #F5F5F5; + border: 1px solid #DDDDDD; + border-radius: 4px 0 4px 0; + color: #9DA0A4; + content: "Row"; + font-size: 12px; + font-weight: bold; + left: -1px; + line-height: 2; + padding: 3px 7px; + position: absolute; + top: -1px; +} + +.widget.widget-col { + background-color: #FFFFFF; + border: 1px solid #DDDDDD; + border-radius: 4px; + margin: 15px 0; + padding: 39px 19px 24px; + position: relative; +} + +.widget.widget-col:before { + background-color: #F5F5F5; + border: 1px solid #DDDDDD; + border-radius: 4px 0 4px 0; + color: #9DA0A4; + content: "Column"; + font-size: 12px; + font-weight: bold; + left: -1px; + padding: 3px 7px; + position: absolute; + top: -1px; +} + +.widget.widget-container { + margin-left: 0; + margin-top: 10px; + padding: 30px 15px 15px; + border: 1px solid #DDDDDD; + border-radius: 4px; + position: relative; + width: 100%; + word-wrap: break-word; +} + +.widget.widget-container:before { + background-color: #F5F5F5; + border: 1px solid #DDDDDD; + border-radius: 4px 0 4px 0; + color: #9DA0A4; + content: "Container"; + font-size: 12px; + font-weight: bold; + left: -1px; + padding: 3px 7px; + position: absolute; + top: -1px; +} + +.widget.widget-row.selected, +.widget.widget-container.selected, +.widget.widget-col.selected { + border-color: green; + transition: border-color .5s; +} + +.widget.widget-row.selected:before, +.widget.widget-container.selected:before, +.widget.widget-col.selected:before { + border-color: green; + background-color: green; + color: white; +} diff --git a/demo-shell-ng2/app/img/blank.gif b/demo-shell-ng2/app/img/blank.gif new file mode 100644 index 0000000000000000000000000000000000000000..e565824aafafe632011b281cba976baf8b3ba89a GIT binary patch literal 43 qcmZ?wbhEHbWMp7uXkcLY4+e@qSs1y10y+#p0Fq%~V)9{Rum%7ZWeN!Z literal 0 HcmV?d00001 diff --git a/demo-shell-ng2/app/js/dropZone.js b/demo-shell-ng2/app/js/dropZone.js new file mode 100644 index 0000000000..84177a2478 --- /dev/null +++ b/demo-shell-ng2/app/js/dropZone.js @@ -0,0 +1,60 @@ +function dropZone(opts) { + var options = opts || {}, + element = opts.element || document.createElement('div'), + minHeight = opts.minHeight || '20px', + maxHeight = opts.maxHeight || '100px'; + + element.className = 'drop-zone'; + element.style.height = minHeight; + element.textAlign = 'center'; + + // Event listener for when the dragged element enters the drop zone. + element.addEventListener('dragenter', function (e) { + this.classList.add('over'); + this.style.height = maxHeight; + }); + + // Event listener for when the dragged element is over the drop zone. + element.addEventListener('dragover', function (e) { + if (e.preventDefault) { + e.preventDefault(); + } + e.dataTransfer.dropEffect = 'move'; + return false; + }); + + // Event listener for when the dragged element leaves the drop zone. + element.addEventListener('dragleave', function (e) { + this.classList.remove('over'); + this.style.height = minHeight; + }); + + // Event listener for when the dragged element dropped in the drop zone. + element.addEventListener('drop', function (e) { + if (e.preventDefault) e.preventDefault(); + if (e.stopPropagation) e.stopPropagation(); + + this.classList.remove('over'); + this.style.height = minHeight; + + if (typeof opts.onDrop === 'function') { + var dropData = e.dataTransfer.getData('text'); + var payload = {}; + if (dropData) { + try { + payload = JSON.parse(dropData); + } catch (err) { + payload = {}; + } + } + + opts.onDrop(this, payload); + } + + return false; + }); + + return { + "element": element + }; +} \ No newline at end of file diff --git a/demo-shell-ng2/app/main.ts b/demo-shell-ng2/app/main.ts new file mode 100644 index 0000000000..0800830073 --- /dev/null +++ b/demo-shell-ng2/app/main.ts @@ -0,0 +1,9 @@ +import {bootstrap} from 'angular2/platform/browser'; +import {AppComponent} from './app.component'; +import {ROUTER_PROVIDERS} from "angular2/router"; +import {Authentication} from "./services/authentication"; + +bootstrap(AppComponent, [ + ROUTER_PROVIDERS, + Authentication +]); diff --git a/demo-shell-ng2/app/services/authentication.ts b/demo-shell-ng2/app/services/authentication.ts new file mode 100644 index 0000000000..3ccf2c7be6 --- /dev/null +++ b/demo-shell-ng2/app/services/authentication.ts @@ -0,0 +1,32 @@ +import {Injectable} from "angular2/core"; +import {Observable} from 'rxjs/Rx'; + +@Injectable() +export class Authentication { + token: string; + + constructor() { + this.token = localStorage.getItem('token'); + } + + isLoggedIn() { + return !!localStorage.getItem('token'); + } + + login(username: String, password: String) { + if (username === 'test' && password === 'test') { + this.token = 'token'; + localStorage.setItem('token', this.token); + return Observable.of('token'); + } + + return Observable.throw('authentication failure'); + } + + logout() { + this.token = undefined; + localStorage.removeItem('token'); + + return Observable.of(true); + } +} diff --git a/demo-shell-ng2/app/services/form-service.ts b/demo-shell-ng2/app/services/form-service.ts new file mode 100644 index 0000000000..8ad1ac68fc --- /dev/null +++ b/demo-shell-ng2/app/services/form-service.ts @@ -0,0 +1,55 @@ +import {Injectable} from 'angular2/core'; + +// TODO: move to some namespace +declare var widgets: any; + +@Injectable() +export class FormService { + getWidgetCategories() { + var result = []; + var categories = {}; + var keys = Object.keys(widgets); + keys.forEach(function (key) { + var w = widgets[key]; + var categoryName = w.category || 'Misc'; + var category = categories[categoryName]; + if (!category) { + category = { + name: categoryName, + widgets: [] + }; + categories[categoryName] = category; + //result.push(category); + } + category.widgets.push({ + type: key, + name: w.name, + iconClass: w.iconClass + }); + }); + + Object.keys(categories).sort().forEach(function (key) { + result.push(categories[key]); + }); + + return result; + } + + getDragImage(widgetType: string): Element { + var w = widgets[widgetType]; + // try getting exported drag image + if (w && typeof w.getDragImage === 'function') { + var img = w.getDragImage(); + if (img) { + return img; + } + } + + // create default drag image + var dragImage = document.createElement('button'); + dragImage.className = 'btn btn-default drag-image'; + dragImage.textContent = w.name; + dragImage.style.minWidth = '100px'; + return dragImage; + } +} diff --git a/demo-shell-ng2/app/widgets/template.js b/demo-shell-ng2/app/widgets/template.js new file mode 100644 index 0000000000..92ffa05a3f --- /dev/null +++ b/demo-shell-ng2/app/widgets/template.js @@ -0,0 +1,16 @@ +var widgets = (function (widgets) { + widgets.COMPONENT = { + create: createComponent, + name: 'COMPONENT NAME', + iconClass: 'fa fa-puzzle-piece' + }; + + function createComponent() { + var widget = document.createElement('button'); + widget.textContent = 'Button'; + widget.classList.add('btn', 'btn-default', 'widget', 'widget-button'); + return widget; + } + + return widgets; +})(widgets || {}); \ No newline at end of file diff --git a/demo-shell-ng2/app/widgets/widgetUtils.js b/demo-shell-ng2/app/widgets/widgetUtils.js new file mode 100644 index 0000000000..e141bc7eca --- /dev/null +++ b/demo-shell-ng2/app/widgets/widgetUtils.js @@ -0,0 +1,30 @@ +var widgetUtils = (function (utils) { + utils.col = function(className) { + var col = document.createElement('div'); + col.dataset.widgetId = utils.uid(); + col.classList.add(className, 'widget', 'widget-col'); + + var dropPlaceholder = document.createElement('div'); + dropPlaceholder.className = 'drop-zone'; + col.appendChild(dropPlaceholder); + + return col; + }; + + utils.getRandomColor = function () { + var color = '#'+(0x1000000+(Math.random())*0xffffff).toString(16).substr(1,6); + return color; + }; + + utils.uid = (function(){ + var id = 0; + return function(){ + if (arguments[0] === 0) { + id = 0; + } + return id++; + }; + })(); + + return utils; +})(widgetUtils || {}); \ No newline at end of file diff --git a/demo-shell-ng2/app/widgets/widgets-button.js b/demo-shell-ng2/app/widgets/widgets-button.js new file mode 100644 index 0000000000..c4385b8cb2 --- /dev/null +++ b/demo-shell-ng2/app/widgets/widgets-button.js @@ -0,0 +1,95 @@ +var widgets = (function (widgets, utils) { + widgets.button = { + create: createComponent, + name: 'Button', + iconClass: 'fa fa-square', + category: 'Components' + }; + + function createComponent() { + var widget = document.createElement('button'); + widget.textContent = 'Button'; + widget.classList.add('btn', 'btn-default', 'widget', 'widget-button'); + widget.dataset.widgetId = utils.uid(); + + widget.addEventListener('dblclick', function (e) { + if (this.contentEditable !== 'true') { + this.dataset.originalValue = this.textContent; + } + + this.contentEditable = true; + selectElementContents(this); + }); + + widget.addEventListener('blur', function (e) { + if (!this.textContent) { + this.textContent = 'Button'; + } + this.contentEditable = false; + }); + + widget.addEventListener('input', function (e) { + // when button has no text - place the stub and autoselect it + if (!this.textContent) { + this.textContent = 'Button'; + selectElementContents(this); + } + }); + + widget.addEventListener('keydown', function (e) { + // special handling of 'spacebar' key + if (e.keyCode == 32) { + insertHtmlAtCursor(' '); + e.stopPropagation(); + e.preventDefault(); + return false; + } + + // 'Enter' key + if (e.keyCode == 13) { + e.stopPropagation(); + e.preventDefault(); + this.blur(); + return false; + } + + // 'Esc' key + if (e.keyCode == 27) { + var originalValue = this.dataset.originalValue || 'Button'; + this.textContent = originalValue; + delete this.dataset.originalValue; + this.blur(); + return false; + } + }); + + return widget; + } + + // TODO: move to shared library + function selectElementContents(el) { + var range = document.createRange(); + range.selectNodeContents(el); + var sel = window.getSelection(); + sel.removeAllRanges(); + sel.addRange(range); + } + + // TODO: move to shared library + function insertHtmlAtCursor(html) { + var range, node; + if (window.getSelection && window.getSelection().getRangeAt) { + range = window.getSelection().getRangeAt(0); + node = range.createContextualFragment(html); + range.insertNode(node); + window.getSelection().collapseToEnd(); + window.getSelection().modify('move', 'forward', 'character'); + } else if (document.selection && document.selection.createRange) { + document.selection.createRange().pasteHTML(html); + document.selection.collapseToEnd(); + document.selection.modify('move', 'forward', 'character'); + } + } + + return widgets; +})(widgets || {}, widgetUtils); \ No newline at end of file diff --git a/demo-shell-ng2/app/widgets/widgets-col-12.js b/demo-shell-ng2/app/widgets/widgets-col-12.js new file mode 100644 index 0000000000..9090dc7a30 --- /dev/null +++ b/demo-shell-ng2/app/widgets/widgets-col-12.js @@ -0,0 +1,18 @@ +var widgets = (function (widgets, utils) { + widgets.col12 = { + create: createComponent, + name: 'column 12', + iconClass: 'fa fa-puzzle-piece', + category: 'Grid system' + }; + + function createComponent() { + var widget = document.createElement('div'); + widget.dataset.widgetId = utils.uid(); + widget.classList.add('row', 'widget', 'widget-row'); + widget.appendChild(utils.col('col-md-12')); + return widget; + } + + return widgets; +})(widgets || {}, widgetUtils); \ No newline at end of file diff --git a/demo-shell-ng2/app/widgets/widgets-col-2x6x4.js b/demo-shell-ng2/app/widgets/widgets-col-2x6x4.js new file mode 100644 index 0000000000..6d2cee88ce --- /dev/null +++ b/demo-shell-ng2/app/widgets/widgets-col-2x6x4.js @@ -0,0 +1,20 @@ +var widgets = (function (widgets, utils) { + widgets.col2x6x4 = { + create: createComponent, + name: 'column 2:6:4', + iconClass: 'fa fa-puzzle-piece', + category: 'Grid system' + }; + + function createComponent() { + var widget = document.createElement('div'); + widget.dataset.widgetId = utils.uid(); + widget.classList.add('row', 'widget', 'widget-row'); + widget.appendChild(utils.col('col-md-2')); + widget.appendChild(utils.col('col-md-6')); + widget.appendChild(utils.col('col-md-4')); + return widget; + } + + return widgets; +})(widgets || {}, widgetUtils); \ No newline at end of file diff --git a/demo-shell-ng2/app/widgets/widgets-col-4x4x4.js b/demo-shell-ng2/app/widgets/widgets-col-4x4x4.js new file mode 100644 index 0000000000..7bc2568125 --- /dev/null +++ b/demo-shell-ng2/app/widgets/widgets-col-4x4x4.js @@ -0,0 +1,20 @@ +var widgets = (function (widgets, utils) { + widgets.col4x4x4 = { + create: createComponent, + name: 'column 4:4:4', + iconClass: 'fa fa-puzzle-piece', + category: 'Grid system' + }; + + function createComponent() { + var widget = document.createElement('div'); + widget.dataset.widgetId = utils.uid(); + widget.classList.add('row', 'widget', 'widget-row'); + widget.appendChild(utils.col('col-md-4')); + widget.appendChild(utils.col('col-md-4')); + widget.appendChild(utils.col('col-md-4')); + return widget; + } + + return widgets; +})(widgets || {}, widgetUtils); \ No newline at end of file diff --git a/demo-shell-ng2/app/widgets/widgets-col-6x6.js b/demo-shell-ng2/app/widgets/widgets-col-6x6.js new file mode 100644 index 0000000000..a2f2ca3575 --- /dev/null +++ b/demo-shell-ng2/app/widgets/widgets-col-6x6.js @@ -0,0 +1,19 @@ +var widgets = (function (widgets, utils) { + widgets.col6x6 = { + create: createComponent, + name: 'column 6:6', + iconClass: 'fa fa-puzzle-piece', + category: 'Grid system' + }; + + function createComponent() { + var widget = document.createElement('div'); + widget.dataset.widgetId = utils.uid(); + widget.classList.add('row', 'widget', 'widget-row'); + widget.appendChild(utils.col('col-md-6')); + widget.appendChild(utils.col('col-md-6')); + return widget; + } + + return widgets; +})(widgets || {}, widgetUtils); \ No newline at end of file diff --git a/demo-shell-ng2/app/widgets/widgets-col-8x4.js b/demo-shell-ng2/app/widgets/widgets-col-8x4.js new file mode 100644 index 0000000000..6b45b2cac6 --- /dev/null +++ b/demo-shell-ng2/app/widgets/widgets-col-8x4.js @@ -0,0 +1,20 @@ +var widgets = (function (widgets, utils) { + widgets.col8x4 = { + create: createComponent, + name: 'column 8:4', + iconClass: 'fa fa-puzzle-piece', + category: 'Grid system' + }; + + function createComponent() { + var widget = document.createElement('div'); + widget.dataset.widgetId = utils.uid(); + widget.classList.add('row', 'widget', 'widget-row'); + widget.appendChild(utils.col('col-md-8')); + widget.appendChild(utils.col('col-md-4')); + + return widget; + } + + return widgets; +})(widgets || {}, widgetUtils); \ No newline at end of file diff --git a/demo-shell-ng2/app/widgets/widgets-container.js b/demo-shell-ng2/app/widgets/widgets-container.js new file mode 100644 index 0000000000..f1fe6a53ef --- /dev/null +++ b/demo-shell-ng2/app/widgets/widgets-container.js @@ -0,0 +1,22 @@ +var widgets = (function (widgets, utils) { + widgets.container = { + create: createComponent, + name: 'container', + iconClass: 'fa fa-puzzle-piece' + }; + + function createComponent() { + var widget = document.createElement('div'); + widget.className = 'container widget widget-container'; + widget.dataset.widgetId = utils.uid(); + //widget.style.borderColor = utils.getRandomColor(); + + var dropPlaceholder = document.createElement('div'); + dropPlaceholder.className = 'drop-zone'; + widget.appendChild(dropPlaceholder); + + return widget; + } + + return widgets; +})(widgets || {}, widgetUtils); \ No newline at end of file diff --git a/demo-shell-ng2/app/widgets/widgets-input.js b/demo-shell-ng2/app/widgets/widgets-input.js new file mode 100644 index 0000000000..36faf40d87 --- /dev/null +++ b/demo-shell-ng2/app/widgets/widgets-input.js @@ -0,0 +1,71 @@ +var widgets = (function (widgets, utils) { + widgets.input = { + create: createComponent, + name: 'Input', + iconClass: 'fa fa-file-text-o', + category: 'Components', + getDragImage: getDragImage + }; + + function createComponent() { + var widget = document.createElement('input'); + widget.type = 'text'; + widget.readOnly = true; + widget.classList.add('form-control', 'widget', 'widget-input'); + widget.dataset.widgetId = utils.uid(); + return widget; + } + + /*function getDragImage() { + var container = document.createElement('div'); + container.style.width = '200px'; + + var label = document.createElement('label'); + label.textContent = "Input"; + label.style.display = 'block'; + label.style.margin = '0'; + label.style.fontSize = '12px'; + container.appendChild(label); + + var element = document.createElement('input'); + element.className = 'form-control'; + element.style.display = 'block'; + container.appendChild(element); + + return container; + }*/ + + function getDragImage() { + var element = document.createElement('input'); + element.style.width = '200px'; + element.className = 'form-control'; + return element; + } + + // TODO: move to shared library + function moveCaretToEnd(el) { + if (typeof el.selectionStart == "number") { + el.selectionStart = el.selectionEnd = el.value.length; + } else if (typeof el.createTextRange != "undefined") { + el.focus(); + var range = el.createTextRange(); + range.collapse(false); + range.select(); + } + } + + // TODO: move to shared library + function setCursorPosition (element, pos) { + if (element.setSelectionRange) { + element.setSelectionRange(pos, pos); + } else if (element.createTextRange) { + var range = element.createTextRange(); + range.collapse(true); + range.moveEnd('character', pos); + range.moveStart('character', pos); + range.select(); + } + } + + return widgets; +})(widgets || {}, widgetUtils); \ No newline at end of file diff --git a/demo-shell-ng2/app/widgets/widgets-row.js b/demo-shell-ng2/app/widgets/widgets-row.js new file mode 100644 index 0000000000..7cb116234c --- /dev/null +++ b/demo-shell-ng2/app/widgets/widgets-row.js @@ -0,0 +1,18 @@ +var widgets = (function (widgets, utils) { + widgets.row = { + create: createComponent, + name: 'row', + iconClass: 'fa fa-puzzle-piece', + category: 'Grid system' + }; + + function createComponent() { + var widget = document.createElement('div'); + widget.classList.add('row', 'widget', 'widget-row'); + widget.dataset.widgetId = utils.uid(); + widget.appendChild(utils.col('col-md-12')); + return widget; + } + + return widgets; +})(widgets || {}, widgetUtils); \ No newline at end of file diff --git a/demo-shell-ng2/index.html b/demo-shell-ng2/index.html new file mode 100644 index 0000000000..f87bee8a62 --- /dev/null +++ b/demo-shell-ng2/index.html @@ -0,0 +1,61 @@ + + + + Angular 2 QuickStart + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Loading... + + + diff --git a/demo-shell-ng2/package.json b/demo-shell-ng2/package.json new file mode 100644 index 0000000000..cf1b1228df --- /dev/null +++ b/demo-shell-ng2/package.json @@ -0,0 +1,30 @@ +{ + "name": "angular2-quickstart", + "version": "1.0.0", + "scripts": { + "start": "concurrently \"npm run tsc:w\" \"npm run lite\" ", + "tsc": "tsc", + "tsc:w": "tsc -w", + "lite": "lite-server", + "typings": "typings", + "postinstall": "typings install" + }, + "license": "ISC", + "dependencies": { + "angular2": "2.0.0-beta.13", + "bootstrap": "^3.3.6", + "es6-shim": "^0.35.0", + "font-awesome": "^4.5.0", + "jquery": "^2.2.2", + "reflect-metadata": "0.1.2", + "rxjs": "5.0.0-beta.2", + "systemjs": "0.19.25", + "zone.js": "0.6.6" + }, + "devDependencies": { + "concurrently": "^2.0.0", + "lite-server": "^2.1.0", + "typescript": "^1.8.9", + "typings": "^0.7.11" + } +} diff --git a/demo-shell-ng2/tsconfig.json b/demo-shell-ng2/tsconfig.json new file mode 100644 index 0000000000..9be71e4c6e --- /dev/null +++ b/demo-shell-ng2/tsconfig.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "target": "es5", + "module": "system", + "moduleResolution": "node", + "sourceMap": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "removeComments": false, + "noImplicitAny": false + }, + "exclude": [ + "node_modules", + "typings/main", + "typings/main.d.ts" + ] +} diff --git a/demo-shell-ng2/typings.json b/demo-shell-ng2/typings.json new file mode 100644 index 0000000000..5ad6252b13 --- /dev/null +++ b/demo-shell-ng2/typings.json @@ -0,0 +1,7 @@ +{ + "ambientDependencies": { + "es6-shim": "github:DefinitelyTyped/DefinitelyTyped/es6-shim/es6-shim.d.ts#4de74cb527395c13ba20b438c3a7a419ad931f1c", + "jasmine": "github:DefinitelyTyped/DefinitelyTyped/jasmine/jasmine.d.ts#d594ef506d1efe2fea15f8f39099d19b39436b71", + "jquery": "registry:dt/jquery#1.10.0+20160316155526" + } +}