mirror of
https://github.com/ansible/awx.git
synced 2026-03-21 10:57:36 -02:30
Add component controller inheritance and new inputs
This commit is contained in:
@@ -12,7 +12,9 @@
|
|||||||
<at-input-text col="4" tab="2" state="vm.description"></at-input-text>
|
<at-input-text col="4" tab="2" state="vm.description"></at-input-text>
|
||||||
<at-input-select col="4" tab="3" state="vm.kind"></at-input-select>
|
<at-input-select col="4" tab="3" state="vm.kind"></at-input-select>
|
||||||
|
|
||||||
<at-dynamic-input-group col="4" tab="4" state="vm.dynamic"></at-dynamic-input-group>
|
<at-dynamic-input-group col="4" tab="4" state="vm.dynamic">
|
||||||
|
Type Details
|
||||||
|
</at-dynamic-input-group>
|
||||||
|
|
||||||
<at-action-group col="12" pos="right">
|
<at-action-group col="12" pos="right">
|
||||||
<at-form-action type="cancel"></at-form-action>
|
<at-form-action type="cancel"></at-form-action>
|
||||||
|
|||||||
@@ -1,12 +1,27 @@
|
|||||||
.at-DynamicInputGroup {
|
.at-DynamicInputGroup {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
margin: @at-space-6x 0 0 0;
|
margin: @at-space-6x 0 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.at-DynamicInputGroup-inset {
|
.at-DynamicInputGroup-border {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: @at-inset-width;
|
width: @at-inset-width;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: @at-gray;
|
background: @at-gray;
|
||||||
left: -@at-inset-width;
|
left: -@at-inset-width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.at-DynamicInputGroup-title {
|
||||||
|
.at-mixin-Heading(@at-font-size-2x);
|
||||||
|
margin-top: 0;
|
||||||
|
margin-left: @at-space-5x;
|
||||||
|
margin-bottom: @at-space-4x;
|
||||||
|
}
|
||||||
|
|
||||||
|
.at-DynamicInputGroup-divider {
|
||||||
|
clear: both;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
height: @at-space-6x;
|
||||||
|
}
|
||||||
|
|||||||
@@ -52,7 +52,9 @@ function AtDynamicInputGroupController ($scope, $compile) {
|
|||||||
|
|
||||||
inputs.forEach((input, i) => {
|
inputs.forEach((input, i) => {
|
||||||
if (input.type === 'string') {
|
if (input.type === 'string') {
|
||||||
if (input.secret) {
|
if (input.secret && input.multiline) {
|
||||||
|
input.component = 'at-input-textarea';
|
||||||
|
} else if (input.secret) {
|
||||||
input.component = 'at-input-secret';
|
input.component = 'at-input-secret';
|
||||||
} else if (input.multiline) {
|
} else if (input.multiline) {
|
||||||
input.component = 'at-input-textarea';
|
input.component = 'at-input-textarea';
|
||||||
@@ -61,10 +63,9 @@ function AtDynamicInputGroupController ($scope, $compile) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
components.push({
|
components.push(Object.assign({
|
||||||
options: input,
|
|
||||||
element: vm.createElement(input, i)
|
element: vm.createElement(input, i)
|
||||||
});
|
}, input));
|
||||||
});
|
});
|
||||||
|
|
||||||
return components;
|
return components;
|
||||||
@@ -83,10 +84,15 @@ function AtDynamicInputGroupController ($scope, $compile) {
|
|||||||
|
|
||||||
vm.insert = components => {
|
vm.insert = components => {
|
||||||
let group = document.createElement('div');
|
let group = document.createElement('div');
|
||||||
|
let divider = angular.element(`<div class="at-DynamicInputGroup-divider"></div>`)[0];
|
||||||
|
|
||||||
components.forEach(component => {
|
for (let i = 0; i < components.length; i++) {
|
||||||
group.appendChild(component.element[0]);
|
if (i !== 0 && (i % (12 / scope.col)) === 0) {
|
||||||
});
|
group.appendChild(divider);
|
||||||
|
}
|
||||||
|
|
||||||
|
group.appendChild(components[i].element[0]);
|
||||||
|
}
|
||||||
|
|
||||||
element.appendChild(group);
|
element.appendChild(group);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
<div class="col-sm-12 at-DynamicInputGroup">
|
<div ng-show="state.value" class="col-sm-12 at-DynamicInputGroup">
|
||||||
<div class="at-DynamicInputGroup-inset"></div>
|
<div class="at-DynamicInputGroup-border"></div>
|
||||||
<div class="at-DynamicInputGroup-container"></div>
|
<div class="at-DynamicInputGroup-inset">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-xs-12">
|
||||||
|
<h4 class="at-DynamicInputGroup-title"><ng-transclude></ng-transclude></h4>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="at-DynamicInputGroup-container"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ import formAction from './form/action.directive';
|
|||||||
import inputLabel from './input/label.directive';
|
import inputLabel from './input/label.directive';
|
||||||
import inputSearch from './input/search.directive';
|
import inputSearch from './input/search.directive';
|
||||||
import inputSelect from './input/select.directive';
|
import inputSelect from './input/select.directive';
|
||||||
|
import inputSecret from './input/secret.directive';
|
||||||
import inputText from './input/text.directive';
|
import inputText from './input/text.directive';
|
||||||
|
import inputTextarea from './input/textarea.directive';
|
||||||
import panel from './panel/panel.directive';
|
import panel from './panel/panel.directive';
|
||||||
import panelHeading from './panel/heading.directive';
|
import panelHeading from './panel/heading.directive';
|
||||||
import panelBody from './panel/body.directive';
|
import panelBody from './panel/body.directive';
|
||||||
@@ -14,6 +16,9 @@ import popover from './popover/popover.directive';
|
|||||||
import toggleButton from './toggle/button.directive';
|
import toggleButton from './toggle/button.directive';
|
||||||
import toggleContent from './toggle/content.directive';
|
import toggleContent from './toggle/content.directive';
|
||||||
|
|
||||||
|
import BaseInputController from './input/base.controller';
|
||||||
|
|
||||||
|
|
||||||
angular
|
angular
|
||||||
.module('at.lib.components', [])
|
.module('at.lib.components', [])
|
||||||
.directive('atActionGroup', actionGroup)
|
.directive('atActionGroup', actionGroup)
|
||||||
@@ -23,13 +28,16 @@ angular
|
|||||||
.directive('atFormAction', formAction)
|
.directive('atFormAction', formAction)
|
||||||
.directive('atInputLabel', inputLabel)
|
.directive('atInputLabel', inputLabel)
|
||||||
.directive('atInputSearch', inputSearch)
|
.directive('atInputSearch', inputSearch)
|
||||||
|
.directive('atInputSecret', inputSecret)
|
||||||
.directive('atInputSelect', inputSelect)
|
.directive('atInputSelect', inputSelect)
|
||||||
.directive('atInputText', inputText)
|
.directive('atInputText', inputText)
|
||||||
|
.directive('atInputTextarea', inputTextarea)
|
||||||
.directive('atPanel', panel)
|
.directive('atPanel', panel)
|
||||||
.directive('atPanelHeading', panelHeading)
|
.directive('atPanelHeading', panelHeading)
|
||||||
.directive('atPanelBody', panelBody)
|
.directive('atPanelBody', panelBody)
|
||||||
.directive('atPopover', popover)
|
.directive('atPopover', popover)
|
||||||
.directive('atToggleButton', toggleButton)
|
.directive('atToggleButton', toggleButton)
|
||||||
.directive('atToggleContent', toggleContent);
|
.directive('atToggleContent', toggleContent)
|
||||||
|
.service('BaseInputController', BaseInputController);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.at-InputLabel {
|
.at-InputLabel {
|
||||||
|
}
|
||||||
|
|
||||||
|
.at-InputLabel-name {
|
||||||
color: @at-gray-dark-4x;
|
color: @at-gray-dark-4x;
|
||||||
font-size: @at-font-size-2x;
|
font-size: @at-font-size-2x;
|
||||||
font-weight: @at-font-weight;
|
font-weight: @at-font-weight;
|
||||||
|
|||||||
38
awx/ui/client/lib/components/input/base.controller.js
Normal file
38
awx/ui/client/lib/components/input/base.controller.js
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
function BaseInputController () {
|
||||||
|
return function extend (type, scope, form) {
|
||||||
|
let vm = this;
|
||||||
|
|
||||||
|
scope.state = scope.state || {};
|
||||||
|
|
||||||
|
scope.state.required = scope.state.required || false;
|
||||||
|
scope.state.isValid = scope.state.isValid || false;
|
||||||
|
scope.state.disabled = scope.state.disabled || false;
|
||||||
|
|
||||||
|
form.use(type, scope);
|
||||||
|
|
||||||
|
vm.validate = () => {
|
||||||
|
let isValid = true;
|
||||||
|
|
||||||
|
if (scope.state.required && !scope.state.value) {
|
||||||
|
isValid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scope.state.validate && !scope.state.validate(scope.state.value)) {
|
||||||
|
isValid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return isValid;
|
||||||
|
};
|
||||||
|
|
||||||
|
vm.check = () => {
|
||||||
|
let isValid = vm.validate();
|
||||||
|
|
||||||
|
if (isValid !== scope.state.isValid) {
|
||||||
|
scope.state.isValid = isValid;
|
||||||
|
form.check();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default BaseInputController;
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<label class="at-InputLabel at-u-flat">
|
<label class="at-InputLabel at-u-flat">
|
||||||
<span ng-if="config.options.required" class="pull-left at-InputLabel-required">*</span>
|
<span ng-if="state.required" class="pull-left at-InputLabel-required">*</span>
|
||||||
<span class="pull-left">{{::state.options.label}}</span>
|
<span class="pull-left at-InputLabel-name">{{::state.label}}</span>
|
||||||
<at-popover class="pull-left" state="state"></at-popover>
|
<at-popover class="pull-left" state="state"></at-popover>
|
||||||
</label>
|
</label>
|
||||||
|
|||||||
44
awx/ui/client/lib/components/input/secret.directive.js
Normal file
44
awx/ui/client/lib/components/input/secret.directive.js
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
function atInputSecretLink (scope, el, attrs, controllers) {
|
||||||
|
let formController = controllers[0];
|
||||||
|
let inputController = controllers[1];
|
||||||
|
|
||||||
|
if (scope.tab === '1') {
|
||||||
|
el.find('input')[0].focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
inputController.init(scope, formController);
|
||||||
|
}
|
||||||
|
|
||||||
|
function AtInputSecretController (baseInputController) {
|
||||||
|
let vm = this || {};
|
||||||
|
|
||||||
|
vm.init = (scope, form) => {
|
||||||
|
baseInputController.call(vm, 'input', scope, form);
|
||||||
|
|
||||||
|
vm.check();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
AtInputSecretController.$inject = ['BaseInputController'];
|
||||||
|
|
||||||
|
function atInputSecret (pathService) {
|
||||||
|
return {
|
||||||
|
restrict: 'E',
|
||||||
|
transclude: true,
|
||||||
|
replace: true,
|
||||||
|
require: ['^^atForm', 'atInputSecret'],
|
||||||
|
templateUrl: pathService.getPartialPath('components/input/secret'),
|
||||||
|
controller: AtInputSecretController,
|
||||||
|
controllerAs: 'vm',
|
||||||
|
link: atInputSecretLink,
|
||||||
|
scope: {
|
||||||
|
state: '=',
|
||||||
|
col: '@',
|
||||||
|
tab: '@'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
atInputSecret.$inject = ['PathService'];
|
||||||
|
|
||||||
|
export default atInputSecret;
|
||||||
10
awx/ui/client/lib/components/input/secret.partial.html
Normal file
10
awx/ui/client/lib/components/input/secret.partial.html
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<div class="col-sm-{{::col}}">
|
||||||
|
<div class="form-group at-u-flat">
|
||||||
|
<at-input-label state="state"></at-input-label>
|
||||||
|
<input type="text" class="form-control at-Input" ng-model="state.value"
|
||||||
|
ng-attr-maxlength="{{ state.options.max_length || undefined }}"
|
||||||
|
ng-attr-tabindex="{{ tab || undefined }}"
|
||||||
|
ng-attr-placeholder="{{::state.placeholder || undefined }}"
|
||||||
|
ng-change="vm.check()" ng-disabled="state.disabled" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -13,27 +13,19 @@ function atInputSelectLink (scope, el, attrs, controllers) {
|
|||||||
inputController.init(formController, scope, elements);
|
inputController.init(formController, scope, elements);
|
||||||
}
|
}
|
||||||
|
|
||||||
function AtInputSelectController (eventService) {
|
function AtInputSelectController (baseInputController, eventService) {
|
||||||
let vm = this || {};
|
let vm = this || {};
|
||||||
|
|
||||||
let scope;
|
let scope;
|
||||||
let state;
|
|
||||||
let form;
|
|
||||||
let input;
|
let input;
|
||||||
let select;
|
let select;
|
||||||
|
|
||||||
vm.init = (_form_, _scope_, elements) => {
|
vm.init = (form, _scope_, elements) => {
|
||||||
form = _form_;
|
baseInputController.call(vm, 'input', _scope_, form);
|
||||||
|
|
||||||
|
scope = _scope_;
|
||||||
input = elements.input;
|
input = elements.input;
|
||||||
select = elements.select;
|
select = elements.select;
|
||||||
scope = _scope_;
|
|
||||||
state = scope.state || {};
|
|
||||||
|
|
||||||
state.required = state.required || false;
|
|
||||||
state.isValid = state.isValid || false;
|
|
||||||
state.disabled = state.disabled || false;
|
|
||||||
|
|
||||||
form.use('input', scope);
|
|
||||||
|
|
||||||
vm.setListeners();
|
vm.setListeners();
|
||||||
vm.check();
|
vm.check();
|
||||||
@@ -56,32 +48,9 @@ function AtInputSelectController (eventService) {
|
|||||||
|
|
||||||
scope.$on('$destroy', () => eventService.remove(listeners));
|
scope.$on('$destroy', () => eventService.remove(listeners));
|
||||||
};
|
};
|
||||||
|
|
||||||
vm.validate = () => {
|
|
||||||
let isValid = true;
|
|
||||||
|
|
||||||
if (state.required && !state.value) {
|
|
||||||
isValid = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.validate && !state.validate(state.value)) {
|
|
||||||
isValid = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return isValid;
|
|
||||||
};
|
|
||||||
|
|
||||||
vm.check = () => {
|
|
||||||
let isValid = vm.validate();
|
|
||||||
|
|
||||||
if (isValid !== state.isValid) {
|
|
||||||
state.isValid = isValid;
|
|
||||||
form.check();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AtInputSelectController.$inject = ['EventService'];
|
AtInputSelectController.$inject = ['BaseInputController', 'EventService'];
|
||||||
|
|
||||||
function atInputSelect (pathService) {
|
function atInputSelect (pathService) {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -6,54 +6,21 @@ function atInputTextLink (scope, el, attrs, controllers) {
|
|||||||
el.find('input')[0].focus();
|
el.find('input')[0].focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
inputController.init(formController, scope);
|
inputController.init(scope, formController);
|
||||||
}
|
}
|
||||||
|
|
||||||
function AtInputTextController () {
|
function AtInputTextController (baseInputController) {
|
||||||
let vm = this || {};
|
let vm = this || {};
|
||||||
|
|
||||||
let scope;
|
vm.init = (scope, form) => {
|
||||||
let state;
|
baseInputController.call(vm, 'input', scope, form);
|
||||||
let form;
|
|
||||||
|
|
||||||
vm.init = (_form_, _scope_) => {
|
|
||||||
form = _form_;
|
|
||||||
scope = _scope_;
|
|
||||||
state = scope.state || {};
|
|
||||||
|
|
||||||
state.required = state.required || false;
|
|
||||||
state.isValid = state.isValid || false;
|
|
||||||
state.disabled = state.disabled || false;
|
|
||||||
|
|
||||||
form.use('input', scope);
|
|
||||||
|
|
||||||
vm.check();
|
vm.check();
|
||||||
};
|
};
|
||||||
|
|
||||||
vm.validate = () => {
|
|
||||||
let isValid = true;
|
|
||||||
|
|
||||||
if (state.required && !state.value) {
|
|
||||||
isValid = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (state.validate && !state.validate(state.value)) {
|
|
||||||
isValid = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return isValid;
|
|
||||||
};
|
|
||||||
|
|
||||||
vm.check = () => {
|
|
||||||
let isValid = vm.validate();
|
|
||||||
|
|
||||||
if (isValid !== state.isValid) {
|
|
||||||
state.isValid = isValid;
|
|
||||||
form.check();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AtInputTextController.$inject = ['BaseInputController'];
|
||||||
|
|
||||||
function atInputText (pathService) {
|
function atInputText (pathService) {
|
||||||
return {
|
return {
|
||||||
restrict: 'E',
|
restrict: 'E',
|
||||||
|
|||||||
44
awx/ui/client/lib/components/input/textarea.directive.js
Normal file
44
awx/ui/client/lib/components/input/textarea.directive.js
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
function atInputTextareaLink (scope, el, attrs, controllers) {
|
||||||
|
let formController = controllers[0];
|
||||||
|
let inputController = controllers[1];
|
||||||
|
|
||||||
|
if (scope.tab === '1') {
|
||||||
|
el.find('input')[0].focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
inputController.init(scope, formController);
|
||||||
|
}
|
||||||
|
|
||||||
|
function AtInputTextareaController (baseInputController) {
|
||||||
|
let vm = this || {};
|
||||||
|
|
||||||
|
vm.init = (scope, form) => {
|
||||||
|
baseInputController.call(vm, 'input', scope, form);
|
||||||
|
|
||||||
|
vm.check();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
AtInputTextareaController.$inject = ['BaseInputController'];
|
||||||
|
|
||||||
|
function atInputTextarea (pathService) {
|
||||||
|
return {
|
||||||
|
restrict: 'E',
|
||||||
|
transclude: true,
|
||||||
|
replace: true,
|
||||||
|
require: ['^^atForm', 'atInputTextarea'],
|
||||||
|
templateUrl: pathService.getPartialPath('components/input/textarea'),
|
||||||
|
controller: AtInputTextareaController,
|
||||||
|
controllerAs: 'vm',
|
||||||
|
link: atInputTextareaLink,
|
||||||
|
scope: {
|
||||||
|
state: '=',
|
||||||
|
col: '@',
|
||||||
|
tab: '@'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
atInputTextarea.$inject = ['PathService'];
|
||||||
|
|
||||||
|
export default atInputTextarea;
|
||||||
11
awx/ui/client/lib/components/input/textarea.partial.html
Normal file
11
awx/ui/client/lib/components/input/textarea.partial.html
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<div class="col-sm-{{::col}}">
|
||||||
|
<div class="form-group at-u-flat">
|
||||||
|
<at-input-label state="state"></at-input-label>
|
||||||
|
<textarea class="form-control at-Input" ng-model="state.value"
|
||||||
|
ng-attr-maxlength="{{ state.options.max_length || undefined }}"
|
||||||
|
ng-attr-tabindex="{{ tab || undefined }}"
|
||||||
|
ng-attr-placeholder="{{::state.placeholder || undefined }}"
|
||||||
|
ng-change="vm.check()" ng-disabled="state.disabled" />
|
||||||
|
</textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -20,11 +20,5 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.at-Panel-headingTitle {
|
.at-Panel-headingTitle {
|
||||||
color: @at-gray-dark-4x;
|
.at-mixin-Heading(@at-font-size-3x);
|
||||||
font-size: @at-font-size-3x;
|
|
||||||
font-weight: @at-font-weight-2x;
|
|
||||||
line-height: @at-line-height-short;
|
|
||||||
text-transform: uppercase;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
border-radius: @at-border-radius;
|
border-radius: @at-border-radius;
|
||||||
box-shadow: 0 5px 10px rgba(0,0,0, 0.2);
|
box-shadow: 0 5px 10px rgba(0,0,0, 0.2);
|
||||||
transition: opacity .15s linear;
|
transition: opacity .15s linear;
|
||||||
|
font-weight: @at-font-weight
|
||||||
}
|
}
|
||||||
|
|
||||||
.at-Popover-arrow {
|
.at-Popover-arrow {
|
||||||
|
|||||||
@@ -1,64 +1,91 @@
|
|||||||
let pathService;
|
function atPopoverLink (scope, el, attr, controllers) {
|
||||||
|
let popoverController = controllers[0];
|
||||||
function link (scope, el, attr) {
|
|
||||||
let icon = el[0];
|
let icon = el[0];
|
||||||
let popover = icon.getElementsByClassName('at-Popover-container')[0];
|
let popover = icon.getElementsByClassName('at-Popover-container')[0];
|
||||||
|
|
||||||
el.on('click', createDisplayListener(icon, popover));
|
popoverController.init(icon, popover);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createDisplayListener (icon, popover) {
|
function AtPopoverController () {
|
||||||
return event => {
|
let vm = this;
|
||||||
let arrow = popover.getElementsByClassName('at-Popover-arrow')[0];
|
|
||||||
|
|
||||||
let iPos = icon.getBoundingClientRect();
|
let icon;
|
||||||
let pPos = popover.getBoundingClientRect();
|
let popover;
|
||||||
|
|
||||||
let wHeight = window.clientHeight;
|
vm.init = (_icon_, _popover_) => {
|
||||||
let pHeight = pPos.height;
|
icon = _icon_;
|
||||||
|
popover = _popover_;
|
||||||
|
|
||||||
let cx = Math.floor(iPos.left + (iPos.width / 2));
|
icon.addEventListener('click', vm.createDisplayListener());
|
||||||
let cy = Math.floor(iPos.top + (iPos.height / 2));
|
};
|
||||||
|
|
||||||
if (cy < (pHeight / 2)) {
|
vm.createDismissListener = (createEvent) => {
|
||||||
popover.style.top = '10px';
|
return event => {
|
||||||
} else {
|
event.stopPropagation();
|
||||||
popover.style.top = (cy - pHeight / 2) + 'px';
|
|
||||||
}
|
|
||||||
|
|
||||||
popover.style.left = cx + 'px';
|
vm.open = false;
|
||||||
|
|
||||||
arrow.style.top = iPos.top + 'px';
|
popover.style.visibility = 'hidden';
|
||||||
arrow.style.left = iPos.left + 20 + 'px';
|
popover.style.opacity = 0;
|
||||||
|
|
||||||
popover.style.visibility = 'visible';
|
window.removeEventListener('click', vm.dismissListener);
|
||||||
popover.style.opacity = 1;
|
window.removeEventListener('resize', vm.dismissListener);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
let dismissListener = createDismissListener(popover);
|
vm.createDisplayListener = () => {
|
||||||
|
return event => {
|
||||||
|
if (vm.open) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
window.addEventListener('mousedown', dismissListener);
|
event.stopPropagation();
|
||||||
window.addEventListener('resize', dismissListener);
|
|
||||||
|
vm.open = true;
|
||||||
|
|
||||||
|
let arrow = popover.getElementsByClassName('at-Popover-arrow')[0];
|
||||||
|
|
||||||
|
let iPos = icon.getBoundingClientRect();
|
||||||
|
let pPos = popover.getBoundingClientRect();
|
||||||
|
|
||||||
|
let wHeight = window.clientHeight;
|
||||||
|
let pHeight = pPos.height;
|
||||||
|
|
||||||
|
let cx = Math.floor(iPos.left + (iPos.width / 2));
|
||||||
|
let cy = Math.floor(iPos.top + (iPos.height / 2));
|
||||||
|
|
||||||
|
if (cy < (pHeight / 2)) {
|
||||||
|
popover.style.top = '10px';
|
||||||
|
} else {
|
||||||
|
popover.style.top = (cy - pHeight / 2) + 'px';
|
||||||
|
}
|
||||||
|
|
||||||
|
popover.style.left = cx + 'px';
|
||||||
|
|
||||||
|
arrow.style.top = iPos.top + 'px';
|
||||||
|
arrow.style.left = iPos.left + 20 + 'px';
|
||||||
|
|
||||||
|
popover.style.visibility = 'visible';
|
||||||
|
popover.style.opacity = 1;
|
||||||
|
|
||||||
|
vm.dismissListener = vm.createDismissListener(event);
|
||||||
|
|
||||||
|
window.addEventListener('click', vm.dismissListener);
|
||||||
|
window.addEventListener('resize', vm.dismissListener);
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function createDismissListener (popover) {
|
function atPopover (pathService) {
|
||||||
return function dismissListener () {
|
|
||||||
popover.style.visibility = 'hidden';
|
|
||||||
popover.style.opacity = 0;
|
|
||||||
|
|
||||||
window.removeEventListener('mousedown', dismissListener);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function atPopover (_pathService_) {
|
|
||||||
pathService = _pathService_;
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
restrict: 'E',
|
restrict: 'E',
|
||||||
replace: true,
|
replace: true,
|
||||||
transclude: true,
|
transclude: true,
|
||||||
|
require: ['atPopover'],
|
||||||
templateUrl: pathService.getPartialPath('components/popover/popover'),
|
templateUrl: pathService.getPartialPath('components/popover/popover'),
|
||||||
link,
|
controller: AtPopoverController,
|
||||||
|
controllerAs: 'vm',
|
||||||
|
link: atPopoverLink,
|
||||||
scope: {
|
scope: {
|
||||||
state: '='
|
state: '='
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<div ng-show="state.options.help_text" class="at-Popover">
|
<div ng-show="state.help_text" class="at-Popover">
|
||||||
<span class="at-Popover-icon">
|
<span class="at-Popover-icon">
|
||||||
<i class="fa fa-question-circle"></i>
|
<i class="fa fa-question-circle"></i>
|
||||||
</span>
|
</span>
|
||||||
@@ -6,6 +6,6 @@
|
|||||||
<div class="at-Popover-arrow">
|
<div class="at-Popover-arrow">
|
||||||
<i class="fa fa-caret-left fa-2x"></i>
|
<i class="fa fa-caret-left fa-2x"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="at-Popover-content">{{::state.options.help_text}}</div>
|
<div class="at-Popover-content">{{::state.help_text}}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -10,6 +10,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.at-mixin-Heading (@size) {
|
||||||
|
color: @at-gray-dark-4x;
|
||||||
|
font-size: @size;
|
||||||
|
font-weight: @at-font-weight-2x;
|
||||||
|
line-height: @at-line-height-short;
|
||||||
|
text-transform: uppercase;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
.at-mixin-Button () {
|
.at-mixin-Button () {
|
||||||
padding: @at-space-2x @at-space-4x;
|
padding: @at-space-2x @at-space-4x;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user