mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-07-24 17:32:15 +00:00
demo shell (ng2)
basic angular2-based demo shell
This commit is contained in:
109
demo-shell-ng2/app/app.component.html
Normal file
109
demo-shell-ng2/app/app.component.html
Normal file
@@ -0,0 +1,109 @@
|
||||
<side-menu #elementsMenu title="Elements">
|
||||
<form-design-toolbar></form-design-toolbar>
|
||||
</side-menu>
|
||||
|
||||
<side-menu #actionMenu title="Actions">
|
||||
<div class="p-10">
|
||||
<button type="button" class="btn btn-success btn-block">
|
||||
Upload <i class="fa fa-plus"></i>
|
||||
</button>
|
||||
<button type="button" class="btn btn-default btn-block">
|
||||
Folder <i class="fa fa-plus"></i>
|
||||
</button>
|
||||
</div>
|
||||
</side-menu>
|
||||
|
||||
<side-menu #propertiesMenu title="Properties" direction="right">
|
||||
<a href="#">Property 1</a>
|
||||
<a href="#">Property 2</a>
|
||||
<a href="#">Property 3</a>
|
||||
<a href="#">Property 4</a>
|
||||
<a href="#">Property 5</a>
|
||||
<a href="#">Property 6</a>
|
||||
</side-menu>
|
||||
|
||||
<app-navbar>
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand navbar-alfresco-logo" [routerLink]="['Home']">
|
||||
<img src="app/img/blank.gif">
|
||||
</a>
|
||||
</div>
|
||||
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
|
||||
<ul class="nav navbar-nav">
|
||||
<li [class.active]="actionMenu.isOpen">
|
||||
<a href="#" (click)="toggleMenu(actionMenu, $event)" class="image-button">
|
||||
<i class="fa fa-tasks fa-2x"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li [class.active]="isActive(['Home'])">
|
||||
<a [routerLink]="['Home']">Home <span class="sr-only">(current)</span></a>
|
||||
</li>
|
||||
<!--
|
||||
<li [class.active]="isActive(['Child1', {id: 1}])">
|
||||
<a [routerLink]="['Child1', {id: 1}]">Child 1</a>
|
||||
</li>
|
||||
<li [class.active]="isActive(['Child2'])">
|
||||
<a [routerLink]="['Child2']">Child 2</a>
|
||||
</li>
|
||||
-->
|
||||
<li [class.active]="isActive(['Page1'])">
|
||||
<a [routerLink]="['Page1']">Page 1</a>
|
||||
</li>
|
||||
<li [class.active]="isActive(['Page2'])">
|
||||
<a [routerLink]="['Page2']">Page 2</a>
|
||||
</li>
|
||||
<li [class.active]="isActive(['Forms'])">
|
||||
<a [routerLink]="['Forms']">Forms</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<form class="navbar-form navbar-left" role="search">
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control" placeholder="Search files and folders">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-default">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li class="dropdown">
|
||||
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="glyphicon glyphicon-menu-hamburger"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="#">Action</a></li>
|
||||
<li><a href="#">Another action</a></li>
|
||||
<li><a href="#">Something else here</a></li>
|
||||
<li role="separator" class="divider"></li>
|
||||
<li><a *ngIf="!isLoggedIn()" [routerLink]="['Login']">Login</a></li>
|
||||
<li><a *ngIf="isLoggedIn()" href="#" (click)="onLogout($event)">Logout</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul *ngIf="isActive(['Forms'])" class="nav navbar-nav navbar-right">
|
||||
<li [class.active]="elementsMenu.isOpen">
|
||||
<a href="#" (click)="toggleMenu(elementsMenu, $event)" class="image-button">
|
||||
<i class="fa fa-cubes fa-2x"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li [class.active]="propertiesMenu.isOpen">
|
||||
<a href="#" (click)="toggleMenu(propertiesMenu, $event)" class="image-button">
|
||||
<i class="fa fa-edit fa-2x"></i>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</app-navbar>
|
||||
<!--<router-outlet></router-outlet>-->
|
||||
<auth-router-outlet></auth-router-outlet>
|
||||
|
||||
<!-- Caches -->
|
||||
<div id="drag-images-cache"></div>
|
67
demo-shell-ng2/app/app.component.ts
Normal file
67
demo-shell-ng2/app/app.component.ts
Normal file
@@ -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();
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
36
demo-shell-ng2/app/components/AuthRouterOutlet.ts
Normal file
36
demo-shell-ng2/app/components/AuthRouterOutlet.ts
Normal file
@@ -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<string>;
|
||||
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();
|
||||
}
|
||||
}
|
47
demo-shell-ng2/app/components/core/SideMenu.ts
Normal file
47
demo-shell-ng2/app/components/core/SideMenu.ts
Normal file
@@ -0,0 +1,47 @@
|
||||
import {Component, Input, ElementRef} from "angular2/core";
|
||||
|
||||
@Component({
|
||||
selector: 'side-menu',
|
||||
host: {
|
||||
'(click)': 'onClick($event)',
|
||||
//'(document:click)': 'onOutsideClick($event)'
|
||||
},
|
||||
template: `
|
||||
<nav class="cbp-spmenu cbp-spmenu-vertical cbp-spmenu-{{direction}} inline-menu"
|
||||
[ngClass]="{ 'cbp-spmenu-open': isOpen }">
|
||||
<h3>
|
||||
{{title}}
|
||||
<a href="#" class="menu-close pull-right" (click)="close()">
|
||||
<i class="glyphicon glyphicon-remove"></i>
|
||||
</a>
|
||||
</h3>
|
||||
<ng-content></ng-content>
|
||||
</nav>
|
||||
`
|
||||
})
|
||||
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;
|
||||
}
|
||||
}
|
24
demo-shell-ng2/app/components/core/navbar.component.ts
Normal file
24
demo-shell-ng2/app/components/core/navbar.component.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import {Component} from "angular2/core";
|
||||
|
||||
@Component({
|
||||
selector: 'app-navbar',
|
||||
template: `
|
||||
<nav class="navbar navbar-default navbar-fixed-top">
|
||||
<div class="container-fluid">
|
||||
<ng-content></ng-content>
|
||||
</div>
|
||||
</nav>
|
||||
`,
|
||||
styles: [
|
||||
`
|
||||
:host .image-button {
|
||||
padding-bottom: 10px;
|
||||
padding-top: 12px;
|
||||
max-height: 50px;
|
||||
}
|
||||
`
|
||||
]
|
||||
})
|
||||
export class AppNavBar {
|
||||
|
||||
}
|
51
demo-shell-ng2/app/components/core/tabs.ts
Normal file
51
demo-shell-ng2/app/components/core/tabs.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import {Component, Input} from 'angular2/core';
|
||||
|
||||
@Component({
|
||||
selector: 'tabs',
|
||||
template: `
|
||||
<ul class="nav nav-tabs">
|
||||
<li *ngFor="#tab of tabs" (click)="selectTab(tab, $event)" [class.active]="tab.active">
|
||||
<a href="#">{{tab.title}}</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ng-content></ng-content>
|
||||
`
|
||||
})
|
||||
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: `
|
||||
<div [hidden]="!active">
|
||||
<ng-content></ng-content>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
export class Tab {
|
||||
@Input('tabTitle') title;
|
||||
active: Boolean;
|
||||
|
||||
constructor(tabs: Tabs) {
|
||||
tabs.addTab(this);
|
||||
}
|
||||
}
|
@@ -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: '<div></div>'
|
||||
})
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -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: `
|
||||
<template ngFor #category [ngForOf]="categories">
|
||||
<h3 class="category-header">{{category.name}}</h3>
|
||||
<a *ngFor="#widget of category.widgets" class="toolbar-item" attr.data-widget-type="{{widget.type}}" draggable="true"
|
||||
(dragstart)="onElementDragStart($event)" (dragend)="onElementDragEnd($event)">
|
||||
<i class="{{widget.iconClass || 'fa fa-puzzle-piece'}}"></i> {{widget.name}}
|
||||
</a>
|
||||
</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 = '';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
23
demo-shell-ng2/app/components/forms.view.ts
Normal file
23
demo-shell-ng2/app/components/forms.view.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import {Component} from 'angular2/core';
|
||||
import {FormDesignSurface} from "./form-design-surface.component";
|
||||
|
||||
@Component({
|
||||
selector: 'forms-view',
|
||||
template: `
|
||||
<div class="container" style="width:970px;">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<!-- Design surface -->
|
||||
<form-design-surface></form-design-surface>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
directives: [FormDesignSurface]
|
||||
})
|
||||
export class FormsView {
|
||||
/*
|
||||
@ViewChild(FormDesignSurface)
|
||||
private _surface: FormDesignSurface;
|
||||
*/
|
||||
}
|
17
demo-shell-ng2/app/components/home.view.ts
Normal file
17
demo-shell-ng2/app/components/home.view.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import {Component} from 'angular2/core';
|
||||
|
||||
@Component({
|
||||
selector: 'home-view',
|
||||
template: `
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<h1>Home View</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
directives: []
|
||||
})
|
||||
export class HomeView {
|
||||
}
|
48
demo-shell-ng2/app/components/login.ts
Normal file
48
demo-shell-ng2/app/components/login.ts
Normal file
@@ -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: `
|
||||
<div class="row">
|
||||
<div class="col-md-4 col-md-offset-4">
|
||||
<form [ngFormModel]="form" (submit)="onSubmit(form.value, $event)">
|
||||
<div *ngIf="error">Check your password</div>
|
||||
<div class="form-group">
|
||||
<label for="username">Username</label>
|
||||
<input class="form-control" type="text" ngControl="username">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="password">Password</label>
|
||||
<input class="form-control" type="password" ngControl="password">
|
||||
</div>
|
||||
<button type="submit" class="btn btn-default" [disabled]="!form.valid">Login</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
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; }
|
||||
);
|
||||
}
|
||||
}
|
14
demo-shell-ng2/app/components/page1.view.ts
Normal file
14
demo-shell-ng2/app/components/page1.view.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import {Component} from "angular2/core";
|
||||
@Component({
|
||||
selector: 'page1-view',
|
||||
template: `
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<h1>Page 1</h1>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
export class Page1View {
|
||||
|
||||
}
|
14
demo-shell-ng2/app/components/page2.view.ts
Normal file
14
demo-shell-ng2/app/components/page2.view.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import {Component} from "angular2/core";
|
||||
@Component({
|
||||
selector: 'page2-view',
|
||||
template: `
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<h1>Page 2</h1>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
})
|
||||
export class Page2View {
|
||||
|
||||
}
|
7
demo-shell-ng2/app/css/app.css
Normal file
7
demo-shell-ng2/app/css/app.css
Normal file
@@ -0,0 +1,7 @@
|
||||
body { padding-top: 70px; }
|
||||
|
||||
/* Utils */
|
||||
|
||||
.p-10 {
|
||||
padding: 10px;
|
||||
}
|
116
demo-shell-ng2/app/css/designer.css
Normal file
116
demo-shell-ng2/app/css/designer.css
Normal file
@@ -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;
|
||||
}
|
201
demo-shell-ng2/app/css/menu.css
Normal file
201
demo-shell-ng2/app/css/menu.css
Normal file
@@ -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;
|
||||
}
|
25
demo-shell-ng2/app/css/theme/navbar.css
Normal file
25
demo-shell-ng2/app/css/theme/navbar.css
Normal file
File diff suppressed because one or more lines are too long
148
demo-shell-ng2/app/css/widgets.css
Normal file
148
demo-shell-ng2/app/css/widgets.css
Normal file
@@ -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;
|
||||
}
|
BIN
demo-shell-ng2/app/img/blank.gif
Normal file
BIN
demo-shell-ng2/app/img/blank.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 43 B |
60
demo-shell-ng2/app/js/dropZone.js
Normal file
60
demo-shell-ng2/app/js/dropZone.js
Normal file
@@ -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
|
||||
};
|
||||
}
|
9
demo-shell-ng2/app/main.ts
Normal file
9
demo-shell-ng2/app/main.ts
Normal file
@@ -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
|
||||
]);
|
32
demo-shell-ng2/app/services/authentication.ts
Normal file
32
demo-shell-ng2/app/services/authentication.ts
Normal file
@@ -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);
|
||||
}
|
||||
}
|
55
demo-shell-ng2/app/services/form-service.ts
Normal file
55
demo-shell-ng2/app/services/form-service.ts
Normal file
@@ -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;
|
||||
}
|
||||
}
|
16
demo-shell-ng2/app/widgets/template.js
Normal file
16
demo-shell-ng2/app/widgets/template.js
Normal file
@@ -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 || {});
|
30
demo-shell-ng2/app/widgets/widgetUtils.js
Normal file
30
demo-shell-ng2/app/widgets/widgetUtils.js
Normal file
@@ -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 || {});
|
95
demo-shell-ng2/app/widgets/widgets-button.js
Normal file
95
demo-shell-ng2/app/widgets/widgets-button.js
Normal file
@@ -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);
|
18
demo-shell-ng2/app/widgets/widgets-col-12.js
Normal file
18
demo-shell-ng2/app/widgets/widgets-col-12.js
Normal file
@@ -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);
|
20
demo-shell-ng2/app/widgets/widgets-col-2x6x4.js
Normal file
20
demo-shell-ng2/app/widgets/widgets-col-2x6x4.js
Normal file
@@ -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);
|
20
demo-shell-ng2/app/widgets/widgets-col-4x4x4.js
Normal file
20
demo-shell-ng2/app/widgets/widgets-col-4x4x4.js
Normal file
@@ -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);
|
19
demo-shell-ng2/app/widgets/widgets-col-6x6.js
Normal file
19
demo-shell-ng2/app/widgets/widgets-col-6x6.js
Normal file
@@ -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);
|
20
demo-shell-ng2/app/widgets/widgets-col-8x4.js
Normal file
20
demo-shell-ng2/app/widgets/widgets-col-8x4.js
Normal file
@@ -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);
|
22
demo-shell-ng2/app/widgets/widgets-container.js
Normal file
22
demo-shell-ng2/app/widgets/widgets-container.js
Normal file
@@ -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);
|
71
demo-shell-ng2/app/widgets/widgets-input.js
Normal file
71
demo-shell-ng2/app/widgets/widgets-input.js
Normal file
@@ -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);
|
18
demo-shell-ng2/app/widgets/widgets-row.js
Normal file
18
demo-shell-ng2/app/widgets/widgets-row.js
Normal file
@@ -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);
|
Reference in New Issue
Block a user