mirror of
https://github.com/ansible/awx.git
synced 2026-05-19 23:07:42 -02:30
Add form, text, and custom dropdown components
This commit is contained in:
38
awx/ui/client/components/form/form.directive.js
Normal file
38
awx/ui/client/components/form/form.directive.js
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
function track (element) {
|
||||||
|
let vm = this;
|
||||||
|
|
||||||
|
let input = {
|
||||||
|
el: element,
|
||||||
|
tabindex: vm.form.inputs.length + 1,
|
||||||
|
autofocus: vm.form.inputs.length === 0
|
||||||
|
};
|
||||||
|
|
||||||
|
vm.form.inputs.push(input);
|
||||||
|
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
function controller () {
|
||||||
|
let vm = this;
|
||||||
|
|
||||||
|
vm.form = {
|
||||||
|
inputs: []
|
||||||
|
};
|
||||||
|
|
||||||
|
vm.track = track;
|
||||||
|
}
|
||||||
|
|
||||||
|
function atForm () {
|
||||||
|
return {
|
||||||
|
restrict: 'E',
|
||||||
|
transclude: true,
|
||||||
|
templateUrl: 'static/partials/components/form/form.partial.html',
|
||||||
|
controller,
|
||||||
|
controllerAs: 'vm',
|
||||||
|
scope: {
|
||||||
|
config: '='
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default atForm;
|
||||||
5
awx/ui/client/components/form/form.partial.html
Normal file
5
awx/ui/client/components/form/form.partial.html
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<form>
|
||||||
|
<div class="row">
|
||||||
|
<ng-transclude></ng-transclude>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
import badge from './badge/badge.directive';
|
import badge from './badge/badge.directive';
|
||||||
|
import form from './form/form.directive';
|
||||||
|
import inputDropdown from './input/dropdown.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 inputText from './input/text.directive';
|
import inputText from './input/text.directive';
|
||||||
@@ -11,6 +13,8 @@ import toggleContent from './toggle/content.directive';
|
|||||||
angular
|
angular
|
||||||
.module('at.components', [])
|
.module('at.components', [])
|
||||||
.directive('atBadge', badge)
|
.directive('atBadge', badge)
|
||||||
|
.directive('atForm', form)
|
||||||
|
.directive('atInputDropdown', inputDropdown)
|
||||||
.directive('atInputSearch', inputSearch)
|
.directive('atInputSearch', inputSearch)
|
||||||
.directive('atInputSelect', inputSelect)
|
.directive('atInputSelect', inputSelect)
|
||||||
.directive('atInputText', inputText)
|
.directive('atInputText', inputText)
|
||||||
|
|||||||
@@ -5,9 +5,13 @@
|
|||||||
border-radius: @at-border-radius-md;
|
border-radius: @at-border-radius-md;
|
||||||
color: @at-gray-darkest;
|
color: @at-gray-darkest;
|
||||||
|
|
||||||
&, &:focus, &:active {
|
&, &:active {
|
||||||
border-color: @at-gray-light;
|
border-color: @at-gray-light;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
border-color: @at-link;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.at-Input-label {
|
.at-Input-label {
|
||||||
@@ -28,8 +32,36 @@
|
|||||||
color: @at-gray;
|
color: @at-gray;
|
||||||
}
|
}
|
||||||
|
|
||||||
.at-Dropdown-option--placeholder {
|
.at-Input--focus {
|
||||||
&[value=""] {
|
border-color: @at-link;
|
||||||
display: none;
|
}
|
||||||
|
|
||||||
|
.at-InputGroup {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
& > i {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 4;
|
||||||
|
pointer-events: none;
|
||||||
|
right: @at-padding-sm;
|
||||||
|
top: @at-padding-sm;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.at-Dropdown {
|
||||||
|
height: @at-input-height-md;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.at-Dropdown-input {
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.at-Dropdown-select {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|||||||
41
awx/ui/client/components/input/dropdown.directive.js
Normal file
41
awx/ui/client/components/input/dropdown.directive.js
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
function link (scope, el, attrs, form) {
|
||||||
|
scope.form = form.track(el);
|
||||||
|
|
||||||
|
scope.open = false;
|
||||||
|
|
||||||
|
let input = el.find('input')[0];
|
||||||
|
let select = el.find('select')[0];
|
||||||
|
|
||||||
|
input.addEventListener('focus', () => select.focus());
|
||||||
|
select.addEventListener('focus', () => input.classList.add('at-Input--focus'));
|
||||||
|
|
||||||
|
select.addEventListener('mousedown', () => {
|
||||||
|
scope.open = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
select.addEventListener('blur', () => {
|
||||||
|
input.classList.remove('at-Input--focus');
|
||||||
|
scope.open = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
select.addEventListener('change', () => {
|
||||||
|
scope.open = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function atInputDropdown () {
|
||||||
|
return {
|
||||||
|
restrict: 'E',
|
||||||
|
transclude: true,
|
||||||
|
replace: true,
|
||||||
|
require: '^^at-form',
|
||||||
|
templateUrl: 'static/partials/components/input/dropdown.partial.html',
|
||||||
|
link,
|
||||||
|
scope: {
|
||||||
|
config: '=',
|
||||||
|
col: '@'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default atInputDropdown;
|
||||||
24
awx/ui/client/components/input/dropdown.partial.html
Normal file
24
awx/ui/client/components/input/dropdown.partial.html
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<div class="col-sm-{{ col }}">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="at-Input-label">
|
||||||
|
<span ng-if="config.required" class="at-Input-label--required">*</span>
|
||||||
|
<span>{{ config.label }}</span>
|
||||||
|
</label>
|
||||||
|
<div class="at-InputGroup at-Dropdown">
|
||||||
|
<input type="text" class="form-control at-Input at-Dropdown-input"
|
||||||
|
ng-attr-autofocus="{{ form.autofocus || undefined }}"
|
||||||
|
placeholder="{{ config.placeholder | uppercase }}" ng-model="config.input" />
|
||||||
|
|
||||||
|
<select class="form-control at-Dropdown-select" ng-model="config.input"
|
||||||
|
tabindex="{{ form.tabindex }}">
|
||||||
|
<optgroup ng-repeat="group in config.data" label="{{ group.category | uppercase }}">
|
||||||
|
<option ng-repeat="item in group.data" value="{{ item.name }}">
|
||||||
|
{{ item.name }}
|
||||||
|
</option>
|
||||||
|
</optgroup>
|
||||||
|
</select>
|
||||||
|
<i ng-hide="open" class="fa fa-caret-down"></i>
|
||||||
|
<i ng-show="open" class="fa fa-caret-up"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
function atInputSelect () {
|
function atInputSelect () {
|
||||||
function link (scope, element, attrs) {
|
function link (scope, element, attrs) {
|
||||||
scope.active = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -3,16 +3,23 @@
|
|||||||
<span ng-if="config.required" class="at-Input-label--required">*</span>
|
<span ng-if="config.required" class="at-Input-label--required">*</span>
|
||||||
<span>{{ config.label }}</span>
|
<span>{{ config.label }}</span>
|
||||||
</label>
|
</label>
|
||||||
<select class="form-control at-Input at-Dropdown" ng-model="config.input"
|
<div class="input-group">
|
||||||
ng-mousedown="opened = opened || true"
|
<select class="form-control at-Input at-Select" ng-model="config.input"
|
||||||
ng-class="{ 'at-Input--placeholder': input === undefined && !opened }">
|
ng-mousedown="opened = opened || true"
|
||||||
<option class="at-Dropdown-option--placeholder" value="" disabled selected>
|
ng-class="{ 'at-Input--placeholder': input === undefined && !opened }">
|
||||||
SELECT A TYPE
|
<option class="at-Select-option--placeholder" value="" disabled selected>
|
||||||
</option>
|
SELECT A TYPE
|
||||||
<optgroup ng-repeat="group in config.data" label="{{ group.category | uppercase }}">
|
|
||||||
<option ng-repeat="item in group.data" value="{{ item.id }}">
|
|
||||||
{{ item.name }}
|
|
||||||
</option>
|
</option>
|
||||||
</optgroup>
|
<optgroup ng-repeat="group in config.data" label="{{ group.category | uppercase }}">
|
||||||
</select>
|
<option ng-repeat="item in group.data" value="{{ item.id }}">
|
||||||
|
{{ item.name }}
|
||||||
|
</option>
|
||||||
|
</optgroup>
|
||||||
|
</select>
|
||||||
|
<span class="input-group-btn">
|
||||||
|
<button class="btn at-Button--default at-Select-button">
|
||||||
|
<i class="fa fa-caret-down"></i>
|
||||||
|
</button>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,12 +1,19 @@
|
|||||||
// TODO: i18n
|
function link (scope, el, attrs, form) {
|
||||||
|
scope.form = form.track(el);
|
||||||
|
console.log('text', scope.form);
|
||||||
|
}
|
||||||
|
|
||||||
function atInputText () {
|
function atInputText () {
|
||||||
return {
|
return {
|
||||||
restrict: 'E',
|
restrict: 'E',
|
||||||
transclude: true,
|
transclude: true,
|
||||||
|
replace: true,
|
||||||
|
require: '^^at-form',
|
||||||
templateUrl: 'static/partials/components/input/text.partial.html',
|
templateUrl: 'static/partials/components/input/text.partial.html',
|
||||||
|
link,
|
||||||
scope: {
|
scope: {
|
||||||
config: '='
|
config: '=',
|
||||||
|
col: '@'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
<div class="form-group">
|
<div class="col-sm-{{ col }}">
|
||||||
<label class="at-Input-label">
|
<div class="form-group">
|
||||||
<span ng-if="config.required" class="at-Input-label--required">*</span>
|
<label class="at-Input-label">
|
||||||
<span>{{ config.label | uppercase }}</span>
|
<span ng-if="config.required" class="at-Input-label--required">*</span>
|
||||||
</label>
|
<span>{{ config.label | uppercase }}</span>
|
||||||
<input type="text" class="form-control at-Input" ng-model="config.input"
|
</label>
|
||||||
placeholder="{{ config.placeholder }}" />
|
<input type="text" class="form-control at-Input" ng-model="config.input"
|
||||||
|
ng-attr-autofocus="{{ form.autofocus || undefined }}" tabindex="{{ form.tabindex }}"
|
||||||
|
placeholder="{{ config.placeholder }}" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -136,9 +136,9 @@ var tower = angular.module('Tower', [
|
|||||||
'features',
|
'features',
|
||||||
|
|
||||||
'ngResource',
|
'ngResource',
|
||||||
'at.component',
|
'at.components',
|
||||||
'at.model',
|
'at.models',
|
||||||
'at.feature.credentials'
|
'at.features.credentials'
|
||||||
])
|
])
|
||||||
|
|
||||||
.constant('AngularScheduler.partials', urlPrefix + 'lib/angular-scheduler/lib/')
|
.constant('AngularScheduler.partials', urlPrefix + 'lib/angular-scheduler/lib/')
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ function AddCredentialsController (credentialType) {
|
|||||||
|
|
||||||
vm.kind = {
|
vm.kind = {
|
||||||
label: 'Type',
|
label: 'Type',
|
||||||
|
placeholder: 'Select a Type',
|
||||||
required: true,
|
required: true,
|
||||||
text: 'kind',
|
text: 'kind',
|
||||||
value: 'id',
|
value: 'id',
|
||||||
|
|||||||
@@ -4,23 +4,10 @@
|
|||||||
</at-panel-heading>
|
</at-panel-heading>
|
||||||
|
|
||||||
<at-panel-body>
|
<at-panel-body>
|
||||||
<at-tab-navigation>
|
<at-form>
|
||||||
<at-tab>Details</at-tab>
|
<at-input-text col="4" config="vm.name"></at-input-text>
|
||||||
<at-tab>Permissions</at-tab>
|
<at-input-text col="4" config="vm.description"></at-input-text>
|
||||||
</at-tab-navigation>
|
<at-input-dropdown col="4" config="vm.kind"></at-input-dropdown>
|
||||||
|
</at-form>
|
||||||
<div class="row">
|
|
||||||
<div class="col-sm-4">
|
|
||||||
<at-input-text config="vm.name"></at-input-text>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-sm-4">
|
|
||||||
<at-input-text config="vm.description"></at-input-text>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="col-sm-4">
|
|
||||||
<at-input-select config="vm.kind"></at-input-select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</at-panel-body>
|
</at-panel-body>
|
||||||
</at-panel>
|
</at-panel>
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ config.$inject = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
angular
|
angular
|
||||||
.module('at.feature.credentials', [])
|
.module('at.features.credentials', [])
|
||||||
.config(config)
|
.config(config)
|
||||||
.factory('CredentialList', CredentialList)
|
.factory('CredentialList', CredentialList)
|
||||||
.controller('ListController', ListController)
|
.controller('ListController', ListController)
|
||||||
|
|||||||
@@ -28,3 +28,5 @@
|
|||||||
@at-margin-md: 20px;
|
@at-margin-md: 20px;
|
||||||
|
|
||||||
@at-border-radius-md: 5px;
|
@at-border-radius-md: 5px;
|
||||||
|
|
||||||
|
@at-input-height-md: 34px;
|
||||||
|
|||||||
Reference in New Issue
Block a user