Add WIP implementation of Lookup

This commit is contained in:
gconsidine 2017-06-20 17:42:16 -04:00
parent f11aef01ef
commit d7e78a5884
23 changed files with 362 additions and 95 deletions

View File

@ -24,11 +24,6 @@ function AddCredentialsController (models, $state) {
});
vm.form.organization._placeholder = DEFAULT_ORGANIZATION_PLACEHOLDER;
vm.form.organization._data = organization.get('results');
vm.form.organization._format = 'objects';
vm.form.organization._exp = 'org as org.name for org in state._data';
vm.form.organization._display = 'name';
vm.form.organization._key = 'id';
vm.form.credential_type._data = credentialType.get('results');
vm.form.credential_type._placeholder = 'SELECT A TYPE';

View File

@ -10,7 +10,7 @@
<at-form state="vm.form">
<at-input-text col="4" tab="1" state="vm.form.name"></at-input-text>
<at-input-text col="4" tab="2" state="vm.form.description"></at-input-text>
<at-input-select col="4" tab="3" state="vm.form.organization"></at-input-select>
<at-input-lookup col="4" tab="3" state="vm.form.organization"></at-input-lookup>
<at-divider></at-divider>

View File

@ -1,7 +1,8 @@
@import 'action/_index';
@import 'input/_index';
@import 'panel/_index';
@import 'modal/_index';
@import 'panel/_index';
@import 'popover/_index';
@import 'tabs/_index';
@import 'table/_index';
@import 'utility/_index';

View File

@ -2,6 +2,9 @@ function atFormLink (scope, el, attrs, controllers) {
let formController = controllers[0];
let form = el[0];
scope.ns = 'form';
scope[scope.ns] = { modal: {} };
formController.init(scope, form);
}
@ -9,10 +12,10 @@ function AtFormController (eventService) {
let vm = this || {};
let scope;
let modal;
let form;
vm.components = [];
vm.modal = {};
vm.state = {
isValid: false,
disabled: false,
@ -22,6 +25,7 @@ function AtFormController (eventService) {
vm.init = (_scope_, _form_) => {
scope = _scope_;
form = _form_;
modal = scope[scope.ns].modal;
vm.setListeners();
};
@ -102,7 +106,7 @@ function AtFormController (eventService) {
message = err.data;
}
vm.modal.show('Unable to Submit', `Unexpected Error: ${message}`);
modal.show('Unable to Submit', `Unexpected Error: ${message}`);
}
};
@ -110,7 +114,7 @@ function AtFormController (eventService) {
let title = 'Unable to Submit';
let message = 'Unexpected server error. View the console for more information';
vm.modal.show(title, message);
modal.show(title, message);
return true;
};

View File

@ -5,5 +5,5 @@
</div>
</form>
<at-modal state="vm.modal"></at-modal>
<at-modal></at-modal>
</div>

View File

@ -10,6 +10,7 @@ import inputMessage from './input/message.directive';
import inputNumber from './input/number.directive';
import inputSelect from './input/select.directive';
import inputSecret from './input/secret.directive';
import inputSearch from './input/search.directive';
import inputText from './input/text.directive';
import inputTextarea from './input/textarea.directive';
import inputTextareaSecret from './input/textarea-secret.directive';
@ -20,6 +21,7 @@ import panelBody from './panel/body.directive';
import popover from './popover/popover.directive';
import tab from './tabs/tab.directive';
import tabGroup from './tabs/group.directive';
import table from './table/table.directive';
import BaseInputController from './input/base.controller';
@ -37,6 +39,7 @@ angular
.directive('atInputNumber', inputNumber)
.directive('atInputSecret', inputSecret)
.directive('atInputSelect', inputSelect)
.directive('atInputSearch', inputSearch)
.directive('atInputText', inputText)
.directive('atInputTextarea', inputTextarea)
.directive('atInputTextareaSecret', inputTextareaSecret)
@ -47,6 +50,7 @@ angular
.directive('atPopover', popover)
.directive('atTab', tab)
.directive('atTabGroup', tabGroup)
.directive('atTable', table)
.service('BaseInputController', BaseInputController);

View File

@ -13,6 +13,10 @@
&:focus {
border-color: @at-color-input-focus;
}
&[disabled] {
background: @at-color-input-disabled;
}
}
.at-InputCheckbox {
@ -94,6 +98,7 @@
height: 100%;
border-right: none;
color: @at-color-button-text-default;
min-width: @at-input-button-width;
}
}
@ -167,6 +172,42 @@
margin: 0;
}
.at-InputSearch-group--left {
padding-right: @at-margin-item-column;
}
.at-InputSearch-group--right {
padding-left: 0;
}
.at-InputSearch-well {
margin: @at-margin-top-search-key 0 0 0;
padding: @at-padding-well;
}
.at-InputSearch-well {
margin: @at-margin-top-search-key 0 0 0;
padding: @at-padding-well;
}
.at-InputSearch-toggle {
width: 100%;
&, &:focus, &:visited, &:active {
background: @at-color-default;
cursor: pointer;
}
}
.at-InputSearch-toggle--active {
&, &:hover, &:focus, &:visited, &:active {
border: @at-color-search-key-active;
background: @at-color-search-key-active;
color: @at-color-default;
cursor: pointer;
}
}
.at-InputSelect {
position: relative;
width: 100%;
@ -178,7 +219,7 @@
pointer-events: none;
top: @at-height-input / 3;
right: @at-height-input / 3;
color: @at-color-icon;
color: @at-color-input-icon;
}
}

View File

@ -2,6 +2,13 @@ function atInputLookupLink (scope, element, attrs, controllers) {
let formController = controllers[0];
let inputController = controllers[1];
scope.ns = 'lookup';
scope[scope.ns] = {
modal: {},
search: {},
table: {}
};
if (scope.tab === '1') {
element.find('input')[0].focus();
}
@ -12,36 +19,25 @@ function atInputLookupLink (scope, element, attrs, controllers) {
function AtInputLookupController (baseInputController) {
let vm = this || {};
vm.lookup = {};
let scope;
let modal;
let search;
let table;
vm.init = (scope, element, form) => {
baseInputController.call(vm, 'input', scope, element, form);
vm.init = (_scope_, element, form) => {
baseInputController.call(vm, 'input', _scope_, element, form);
vm.lookup.modal = {
title: 'Select Organization',
buttons: [
{
type: 'cancel'
},
{
type: 'select'
}
]
};
scope = _scope_;
vm.lookup.search = {
placeholder: 'test'
};
vm.lookup.table = {
};
modal = scope.lookup.modal;
search = scope.lookup.search;
table = scope.lookup.table;
vm.check();
};
vm.search = () => {
vm.modal.show('test');
modal.show(`Select ${scope.state.label}`);
};
}

View File

@ -23,8 +23,8 @@
<at-input-message></at-input-message>
</div>
<at-modal state="vm.lookup">
<at-search></at-search>
<at-table></at-table>
<at-modal>
<at-input-search></at-input-search>
<at-table namespace></at-table>
</at-modal>
</div>

View File

@ -0,0 +1,54 @@
const DEFAULT_PLACEHOLDER = 'SEARCH';
function atInputSearchLink (scope, element, attrs, controllers) {
let inputController = controllers[0];
let property = `scope.${scope.ns}.search`;
let done = scope.$watch(property, () => {
inputController.init(scope, element);
done();
});
}
function AtInputSearchController (baseInputController) {
let vm = this || {};
let toggleButton;
let input;
vm.init = (scope, element) => {
toggleButton = element.find('.at-InputSearch-toggle')[0];
input = element.find('.at-Input')[0];
vm.placeholder = DEFAULT_PLACEHOLDER;
vm.search = scope[scope.ns].search;
// baseInputController.call(vm, 'input', scope, element, form);
//vm.check();
};
vm.toggle = () => {
input.focus();
vm.isToggleActive = !vm.isToggleActive;
};
}
AtInputSearchController.$inject = ['BaseInputController'];
function atInputSearch (pathService) {
return {
restrict: 'E',
transclude: true,
replace: true,
require: ['atInputSearch'],
templateUrl: pathService.getPartialPath('components/input/search'),
controller: AtInputSearchController,
controllerAs: 'vm',
link: atInputSearchLink,
scope: true
};
}
atInputSearch.$inject = ['PathService'];
export default atInputSearch;

View File

@ -0,0 +1,31 @@
<div class="at-InputContainer">
<div class="row">
<div class="col-xs-10 at-InputSearch-group--left">
<div class="form-group at-u-flat">
<div class="input-group">
<input type="text" class="form-control at-Input"
ng-attr-placeholder="{{ vm.placeholder }}" autofocus />
<span class="input-group-btn">
<button class="btn at-ButtonHollow--default at-Input-button">
<i class="fa fa-search"></i>
</button>
</span>
</div>
</div>
</div>
<div class="col-xs-2 at-InputSearch-group--right">
<button class="btn at-ButtonHollow--default at-InputSearch-toggle"
ng-class="{ 'at-InputSearch-toggle--active': vm.isToggleActive }"
ng-click="vm.toggle()">
KEY
</button>
</div>
</div>
<div class="row" ng-show="vm.isToggleActive">
<div class="col-xs-12">
<div class="well at-InputSearch-well">
<p>Some info here</p>
</div>
</div>
</div>
</div>

View File

@ -1,10 +1,28 @@
.at-Modal-body {
font-size: @at-font-size;
padding: 0;
}
.at-Modal-dismiss {
.at-mixin-ButtonIcon();
font-size: @at-font-size-modal-dismiss;
color: @at-color-icon-dismiss;
text-align: right;
}
.at-Modal-heading {
margin: 0;
overflow: visible;
& > .at-Modal-dismiss {
margin: 0;
}
}
.at-Modal-title {
margin: 0;
padding: 0;
.at-mixin-Heading(@at-font-size-3x);
.at-mixin-Heading(@at-font-size-modal-heading);
}
.at-Modal-body {
font-size: @at-font-size;
}

View File

@ -1,29 +1,39 @@
const DEFAULT_ANIMATION_DURATION = 150;
function atModalLink (scope, el, attr, controllers) {
function atModalLink (scope, el, attrs, controllers) {
let modalController = controllers[0];
let container = el[0];
let property = `scope.${scope.ns}.modal`;
modalController.init(scope, container);
let done = scope.$watch(property, () => {
modalController.init(scope, container);
done();
});
}
function AtModalController () {
function AtModalController (eventService) {
let vm = this;
let scope;
let container;
let listeners;
vm.init = (_scope_, _container_) => {
scope = _scope_;
vm.init = (scope, _container_) => {
container = _container_;
scope.state.show = vm.show;
scope.state.hide = vm.hide;
vm.modal = scope[scope.ns].modal;
vm.modal.show = vm.show;
vm.modal.hide = vm.hide;
};
vm.show = (title, message) => {
scope.title = title;
scope.message = message;
vm.modal.title = title;
vm.modal.message = message;
event.stopPropagation();
listeners = eventService.addListeners([
[window, 'click', vm.clickToHide]
]);
container.style.display = 'block';
container.style.opacity = 1;
@ -32,14 +42,34 @@ function AtModalController () {
vm.hide = () => {
container.style.opacity = 0;
eventService.remove(listeners);
setTimeout(() => {
container.style.display = 'none';
scope.message = '';
scope.title = '';
vm.modal.message = '';
vm.modal.title = '';
}, DEFAULT_ANIMATION_DURATION);
};
vm.clickToHide = event => {
if (vm.clickIsOutsideContainer(event)) {
console.log('outside');
} else {
console.log('inside');
}
};
vm.clickIsOutsideContainer = e => {
let pos = container.getBoundingClientRect();
let ex = e.clientX;
let ey = e.clientY;
console.log(e, pos);
};
}
AtModalController.$inject = ['EventService'];
function atModal (pathService) {
return {
restrict: 'E',
@ -50,9 +80,7 @@ function atModal (pathService) {
controller: AtModalController,
controllerAs: 'vm',
link: atModalLink,
scope: {
state: '='
}
scope: true
};
}

View File

@ -1,20 +1,31 @@
<div class="modal at-Modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" ng-click="vm.hide()">
<i class="fa fa-times"></i>
</button>
<h4 class="modal-title at-Modal-title">{{ title }}</h4>
<div class="row">
<div class="col-xs-10">
<div class="at-Modal-heading">
<h4 class="modal-title at-Modal-title">{{ vm.modal.title }}</h4>
</div>
</div>
<div class="col-xs-2">
<div type="button" class="at-Modal-dismiss" ng-click="vm.hide()">
<i class="fa fa-lg fa-times-circle"></i>
</div>
</div>
</div>
<div class="modal-body at-Modal-body">
<p ng-show="message">{{ message }}</p>
<ng-transclude></ng-transclude>
</div>
<div class="modal-footer">
<button type="button" class="btn at-ButtonHollow--white" ng-click="vm.hide()">
OK
</button>
<ng-transclude></ng-transclude>
<div ng-show="vm.modal.message">
<div class="modal-body at-Modal-body">
<p>{{ vm.modal.message }}</p>
</div>
<div class="modal-footer">
<button type="button" class="btn at-ButtonHollow--default"
ng-click="vm.hide()">
OK
</button>
</div>
</div>
</div>
</div>

View File

@ -11,6 +11,7 @@
.at-Panel-dismiss {
.at-mixin-ButtonIcon();
color: @at-color-icon-dismiss;
text-align: right;
}

View File

@ -8,6 +8,7 @@
.at-Popover-icon {
.at-mixin-ButtonIcon();
color: @at-color-icon-popover;
font-size: @at-font-size-icon;
padding: 0;
margin: 0;

View File

@ -0,0 +1,3 @@
.at-Table {
margin-top: @at-margin-panel;
}

View File

@ -0,0 +1,36 @@
function atTableLink (scope, element, attrs, controllers) {
let tableController = controllers[0];
tableController.init(scope, element);
}
function AtTableController (baseInputController) {
let vm = this || {};
vm.init = (scope, element) => {
};
}
AtTableController.$inject = ['BaseInputController'];
function atTable (pathService) {
return {
restrict: 'E',
transclude: true,
replace: true,
require: ['atTable'],
templateUrl: pathService.getPartialPath('components/table/table'),
controller: AtTableController,
controllerAs: 'vm',
link: atTableLink,
scope: {
state: '=',
col: '@'
}
};
}
atTable.$inject = ['PathService'];
export default atTable;

View File

@ -0,0 +1,27 @@
<table class="table table-hover table-striped at-Table">
<tr>
<th></th>
<th>Name</th>
<th>Kind</th>
</tr>
<tr>
<td><input type="radio" /></td>
<td>Cell One</td>
<td>Cell Two</td>
</tr>
<tr>
<td><input type="radio" /></td>
<td>Cell One</td>
<td>Cell Two</td>
</tr>
<tr>
<td><input type="radio" /></td>
<td>Cell One</td>
<td>Cell Two</td>
</tr>
<tr>
<td><input type="radio" /></td>
<td>Cell One</td>
<td>Cell Two</td>
</tr>
</table>

View File

@ -25,9 +25,10 @@
@at-gray: #e1e1e1;
@at-gray-dark: #d7d7d7;
@at-gray-dark-2x: #b7b7b7;
@at-gray-dark-3x: #848992;
@at-gray-dark-4x: #707070;
@at-gray-dark-5x: #161b1f;
@at-gray-dark-3x: #A9A9A9;
@at-gray-dark-4x: #848992;
@at-gray-dark-5x: #707070;
@at-gray-dark-6x: #161b1f;
@at-white: #ffffff;
@at-white-hover: #f2f2f2;

View File

@ -12,7 +12,8 @@
* 1. Colors
* 2. Typography
* 3. Layout
* 4. Misc
* 4. Buttons
* 5. Misc
*
*/
@ -38,13 +39,13 @@
@at-color-disabled: @at-gray-dark;
@at-color-body-background-dark: @at-gray-dark-4x;
@at-color-body-background-dark: @at-gray-dark-5x;
@at-color-body-text-dark: @at-white;
@at-color-body-background: @at-gray-light-3x;
@at-color-body-text: @at-gray-dark-4x;
@at-color-body-text: @at-gray-dark-5x;
@at-color-button-border-default: @at-gray-dark-2x;
@at-color-button-text-default: @at-gray-dark-4x;
@at-color-button-text-default: @at-gray-dark-5x;
@at-color-tab-default-active: @at-gray-dark-2x;
@at-color-tab-border-default-active: @at-gray-dark-2x;
@ -52,43 +53,47 @@
@at-color-tab-default-disabled: @at-white;
@at-color-tab-border-default-disabled: @at-gray-dark-2x;
@at-color-tab-text-default-disabled: @at-gray-dark-4x;
@at-color-tab-text-default-disabled: @at-gray-dark-5x;
@at-color-form-label: @at-gray-dark-4x;
@at-color-form-label: @at-gray-dark-5x;
@at-color-input-border: @at-gray-dark-2x;
@at-color-input-error: @at-color-error;
@at-color-input-focus: @at-color-info;
@at-color-input-placeholder: @at-gray-dark-3x;
@at-color-input-hint: @at-gray-dark-3x;
@at-color-input-text: @at-gray-dark-5x;
@at-color-input-background: @at-white;
@at-color-input-hint: @at-gray-dark-4x;
@at-color-input-icon: @at-gray-dark-2x;
@at-color-input-placeholder: @at-gray-dark-4x;
@at-color-input-text: @at-gray-dark-6x;
@at-color-input-background: @at-gray-light-3x;
@at-color-input-disabled: @at-gray-light-2x;
@at-color-icon: @at-gray-dark-2x;
@at-color-icon-hover: @at-gray-dark-3x;
@at-color-icon-dismiss: @at-gray-dark;
@at-color-icon-popover: @at-gray-dark-3x;
@at-color-icon-hover: @at-gray-dark-5x;
@at-color-panel-heading: @at-gray-dark-4x;
@at-color-panel-heading: @at-gray-dark-5x;
@at-color-panel-border: @at-gray-dark;
@at-color-search-key-active: @at-blue;
@at-color-table-header-background: @at-gray-light;
@at-color-line-separator: @at-gray;
// 2. Typography ----------------------------------------------------------------------------------
@at-font-size-help-text: @at-font-size;
@at-font-size-body: @at-font-size-3x;
@at-font-size-button: @at-font-size;
@at-font-size-form-label: @at-font-size-2x;
@at-font-size-breadcrumb: @at-font-size-3x;
@at-font-size-form-label: @at-font-size-2x;
@at-font-size-help-text: @at-font-size;
@at-font-size-icon: @at-font-size-4x;
@at-font-size-input: @at-font-size-3x;
@at-font-size-panel-heading: @at-font-size-3x;
@at-font-size-panel-inset-heading: @at-font-size-2x;
@at-font-size-modal-heading: @at-font-size-3x;
@at-font-size-modal-dismiss: @at-font-size-3x;
@at-font-size-navigation: @at-font-size-3x;
@at-font-size-table-heading: @at-font-size-3x;
@at-font-size-body: @at-font-size-3x;
@at-font-size-panel-inset-heading: @at-font-size-2x;
@at-font-size-icon: @at-font-size-4x;
@at-font-size-menu-icon: @at-font-size-5x;
@at-font-weight-body: @at-font-weight;
@ -101,6 +106,7 @@
@at-padding-inset: @at-space-3x;
@at-padding-panel: @at-space-4x;
@at-padding-popover: @at-space-2x;
@at-padding-well: @at-space-2x;
@at-margin-input-message: @at-space;
@at-margin-item-column: @at-space-3x;
@ -118,11 +124,16 @@
@at-height-button: 30px;
@at-height-tab: 30px;
// 4. Misc ----------------------------------------------------------------------------------------
// 4. Transitions ---------------------------------------------------------------------------------
@at-transition-icon-button: 0.2s;
// 5. Misc ----------------------------------------------------------------------------------------
@at-border-radius: 5px;
@at-popover-maxwidth: 320px;
@at-line-height-short: 0.9;
@at-line-height-tall: 2;
@at-line-height: 24px;
@at-input-button-width: 72px;

View File

@ -39,3 +39,7 @@
padding: 4px @at-padding-button-horizontal;
font-size: @at-font-size-body;
}
.at-Button--expand {
width: 100%;
}

View File

@ -70,10 +70,10 @@
.at-mixin-ButtonIcon () {
line-height: @at-line-height-short;
color: @at-color-icon;
& > i {
cursor: pointer;
transition: color @at-transition-icon-button;
}
& > i:hover {