removed x from test + merge
gitea/salix/dev This commit looks good
Details
gitea/salix/dev This commit looks good
Details
This commit is contained in:
commit
eb80721ec4
|
@ -1,12 +0,0 @@
|
||||||
<div class="check">
|
|
||||||
<div class="focus"></div>
|
|
||||||
<div class="mark"></div>
|
|
||||||
</div>
|
|
||||||
<span translate>
|
|
||||||
{{::$ctrl.label}}
|
|
||||||
</span>
|
|
||||||
<i class="material-icons"
|
|
||||||
ng-if="::$ctrl.hasInfo"
|
|
||||||
vn-tooltip="{{::$ctrl.info}}">
|
|
||||||
info_outline
|
|
||||||
</i>
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
<div class="check">
|
||||||
|
<div class="focus-mark"></div>
|
||||||
|
<div class="mark"></div>
|
||||||
|
</div>
|
||||||
|
<span translate>
|
||||||
|
{{::$ctrl.label}}
|
||||||
|
</span>
|
||||||
|
<vn-icon
|
||||||
|
ng-if="::$ctrl.info != null"
|
||||||
|
vn-tooltip="{{::$ctrl.info}}"
|
||||||
|
icon="info_outline">
|
||||||
|
</vn-icon>
|
|
@ -2,25 +2,32 @@ import ngModule from '../../module';
|
||||||
import Component from '../../lib/component';
|
import Component from '../../lib/component';
|
||||||
import './style.scss';
|
import './style.scss';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic element for user input. You can use this to supply a way for the user
|
||||||
|
* to toggle an option.
|
||||||
|
*
|
||||||
|
* @property {String} label Label to display along the component
|
||||||
|
* @property {any} field The value with which the element is linked
|
||||||
|
* @property {Boolean} checked Whether the checkbox is checked
|
||||||
|
* @property {Boolean} disabled Put component in disabled mode
|
||||||
|
* @property {Boolean} tripleState Switch between three states when clicked
|
||||||
|
* @property {Boolean} indeterminate Sets the element into indeterminate state
|
||||||
|
* @property {String} info Shows a text information tooltip to the user
|
||||||
|
*/
|
||||||
export default class Controller extends Component {
|
export default class Controller extends Component {
|
||||||
constructor($element, $, $attrs) {
|
constructor($element, $, $attrs) {
|
||||||
super($element, $);
|
super($element, $);
|
||||||
this.hasInfo = Boolean($attrs.info);
|
|
||||||
this.info = $attrs.info || null;
|
|
||||||
|
|
||||||
let element = this.element;
|
let element = this.element;
|
||||||
element.addEventListener('click', e => this.onClick(e));
|
element.addEventListener('click', e => this.onClick(e));
|
||||||
element.addEventListener('keydown', e => this.onClick(e));
|
element.addEventListener('keydown', e => this.onKeydown(e));
|
||||||
element.tabIndex = 0;
|
element.tabIndex = 0;
|
||||||
|
|
||||||
this.check = element.querySelector('.check');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set field(value) {
|
set field(value) {
|
||||||
this._field = value;
|
this._field = value;
|
||||||
let isIndeterminate = Boolean(value == null && this.tripleState);
|
this.element.classList.toggle('checked', Boolean(value));
|
||||||
this.check.classList.toggle('checked', Boolean(value));
|
this.indeterminate = Boolean(value == null && this.tripleState);
|
||||||
this.check.classList.toggle('indeterminate', isIndeterminate);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get field() {
|
get field() {
|
||||||
|
@ -29,7 +36,7 @@ export default class Controller extends Component {
|
||||||
|
|
||||||
set disabled(value) {
|
set disabled(value) {
|
||||||
this.element.tabIndex = !value ? 0 : -1;
|
this.element.tabIndex = !value ? 0 : -1;
|
||||||
this.check.classList.toggle('disabled', Boolean(value));
|
this.element.classList.toggle('disabled', Boolean(value));
|
||||||
this._disabled = value;
|
this._disabled = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +44,15 @@ export default class Controller extends Component {
|
||||||
return this._disabled;
|
return this._disabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
set indeterminate(value) {
|
||||||
|
this._indeterminate = value;
|
||||||
|
this.element.classList.toggle('indeterminate', Boolean(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
get indeterminate() {
|
||||||
|
return this._indeterminate;
|
||||||
|
}
|
||||||
|
|
||||||
set tripleState(value) {
|
set tripleState(value) {
|
||||||
this._tripleState = value;
|
this._tripleState = value;
|
||||||
this.field = this.field;
|
this.field = this.field;
|
||||||
|
@ -53,9 +69,9 @@ export default class Controller extends Component {
|
||||||
|
|
||||||
if (this.tripleState) {
|
if (this.tripleState) {
|
||||||
if (this.field == null)
|
if (this.field == null)
|
||||||
this.field = false;
|
|
||||||
else if (!this.field)
|
|
||||||
this.field = true;
|
this.field = true;
|
||||||
|
else if (this.field)
|
||||||
|
this.field = false;
|
||||||
else
|
else
|
||||||
this.field = null;
|
this.field = null;
|
||||||
} else
|
} else
|
||||||
|
@ -63,6 +79,7 @@ export default class Controller extends Component {
|
||||||
|
|
||||||
this.$.$applyAsync();
|
this.$.$applyAsync();
|
||||||
this.element.dispatchEvent(new Event('change'));
|
this.element.dispatchEvent(new Event('change'));
|
||||||
|
this.emit('change', {value: this.field});
|
||||||
}
|
}
|
||||||
|
|
||||||
onKeydown(event) {
|
onKeydown(event) {
|
||||||
|
@ -74,15 +91,16 @@ export default class Controller extends Component {
|
||||||
Controller.$inject = ['$element', '$scope', '$attrs'];
|
Controller.$inject = ['$element', '$scope', '$attrs'];
|
||||||
|
|
||||||
ngModule.component('vnCheck', {
|
ngModule.component('vnCheck', {
|
||||||
template: require('./check.html'),
|
template: require('./index.html'),
|
||||||
controller: Controller,
|
controller: Controller,
|
||||||
|
|
||||||
bindings: {
|
bindings: {
|
||||||
field: '=?',
|
|
||||||
label: '@?',
|
label: '@?',
|
||||||
disabled: '<?',
|
field: '=?',
|
||||||
checked: '<?',
|
checked: '<?',
|
||||||
|
disabled: '<?',
|
||||||
tripleState: '<?',
|
tripleState: '<?',
|
||||||
intermediate: '<?'
|
indeterminate: '<?',
|
||||||
|
info: '@?'
|
||||||
}
|
}
|
||||||
});
|
});
|
|
@ -38,20 +38,20 @@ describe('Component vnCheck', () => {
|
||||||
expect($ctrl.field).toEqual(false);
|
expect($ctrl.field).toEqual(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should check value and change to null when clicked`, () => {
|
it(`should check value and change to false when clicked`, () => {
|
||||||
$ctrl.field = true;
|
$ctrl.field = true;
|
||||||
$ctrl.tripleState = true;
|
$ctrl.tripleState = true;
|
||||||
element.click();
|
element.click();
|
||||||
|
|
||||||
expect($ctrl.field).toEqual(null);
|
expect($ctrl.field).toEqual(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should set value to null and change to false when clicked`, () => {
|
it(`should set value to null and change to true when clicked`, () => {
|
||||||
$ctrl.field = null;
|
$ctrl.field = null;
|
||||||
$ctrl.tripleState = true;
|
$ctrl.tripleState = true;
|
||||||
element.click();
|
element.click();
|
||||||
|
|
||||||
expect($ctrl.field).toEqual(false);
|
expect($ctrl.field).toEqual(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should cast value to boolean when clicked`, () => {
|
it(`should cast value to boolean when clicked`, () => {
|
|
@ -2,10 +2,13 @@
|
||||||
|
|
||||||
vn-check {
|
vn-check {
|
||||||
position: relative;
|
position: relative;
|
||||||
cursor: pointer;
|
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
outline: none;
|
outline: none;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&.disabled {
|
||||||
|
cursor: initial;
|
||||||
|
}
|
||||||
& > .check {
|
& > .check {
|
||||||
position: relative;
|
position: relative;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
@ -16,7 +19,7 @@ vn-check {
|
||||||
height: 20px;
|
height: 20px;
|
||||||
transition: background 250ms;
|
transition: background 250ms;
|
||||||
border: 2px solid #666;
|
border: 2px solid #666;
|
||||||
margin: 3px;
|
margin: 6px 0;
|
||||||
margin-right: .4em;
|
margin-right: .4em;
|
||||||
|
|
||||||
& > .mark {
|
& > .mark {
|
||||||
|
@ -25,15 +28,15 @@ vn-check {
|
||||||
display: block;
|
display: block;
|
||||||
border-width: 0;
|
border-width: 0;
|
||||||
}
|
}
|
||||||
&.checked {
|
}
|
||||||
background-color: $color-main;
|
&.checked > .check {
|
||||||
border-color: $color-main;
|
background-color: $color-main;
|
||||||
|
border-color: $color-main;
|
||||||
|
|
||||||
& > .focus {
|
& > .focus-mark {
|
||||||
background-color: rgba($color-main, .15);
|
background-color: rgba($color-main, .15);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
&.checked > .mark {
|
& > .mark {
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 4px;
|
left: 4px;
|
||||||
transform: rotate(45deg);
|
transform: rotate(45deg);
|
||||||
|
@ -43,16 +46,16 @@ vn-check {
|
||||||
border-top: 0;
|
border-top: 0;
|
||||||
border-left: 0;
|
border-left: 0;
|
||||||
}
|
}
|
||||||
&.indeterminate > .mark {
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
width: 12px;
|
|
||||||
height: 2px;
|
|
||||||
border-bottom: 2px solid #666;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
& > .check > .focus {
|
&.indeterminate > .check > .mark {
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
width: 12px;
|
||||||
|
height: 2px;
|
||||||
|
border-bottom: 2px solid #666;
|
||||||
|
}
|
||||||
|
& > .check > .focus-mark {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
|
@ -66,13 +69,12 @@ vn-check {
|
||||||
transition: transform 250ms;
|
transition: transform 250ms;
|
||||||
background-color: rgba(0, 0, 0, .1);
|
background-color: rgba(0, 0, 0, .1);
|
||||||
}
|
}
|
||||||
&:focus > .check:not(.disabled) > .focus {
|
&:focus:not(.disabled) > .check > .focus-mark {
|
||||||
transform: scale3d(1, 1, 1);
|
transform: scale3d(1, 1, 1);
|
||||||
}
|
}
|
||||||
& > i {
|
& > vn-icon {
|
||||||
padding-left: 5px;
|
margin-left: 5px;
|
||||||
position: absolute;
|
|
||||||
color: $color-font-secondary;
|
color: $color-font-secondary;
|
||||||
font-size: 20px;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,6 @@ import './menu/menu';
|
||||||
import './multi-check/multi-check';
|
import './multi-check/multi-check';
|
||||||
import './date-picker/date-picker';
|
import './date-picker/date-picker';
|
||||||
import './button/button';
|
import './button/button';
|
||||||
import './check/check';
|
|
||||||
import './radio-group/radio-group';
|
|
||||||
import './textarea/textarea';
|
import './textarea/textarea';
|
||||||
import './icon-button/icon-button';
|
import './icon-button/icon-button';
|
||||||
import './submit/submit';
|
import './submit/submit';
|
||||||
|
@ -31,16 +29,18 @@ import './label-value/label-value';
|
||||||
import './paging/paging';
|
import './paging/paging';
|
||||||
import './pagination/pagination';
|
import './pagination/pagination';
|
||||||
import './searchbar/searchbar';
|
import './searchbar/searchbar';
|
||||||
|
import './scroll-up/scroll-up';
|
||||||
import './table';
|
import './table';
|
||||||
import './td-editable';
|
import './td-editable';
|
||||||
import './th';
|
|
||||||
import './input-range';
|
import './input-range';
|
||||||
|
import './calendar';
|
||||||
|
import './check';
|
||||||
import './chip';
|
import './chip';
|
||||||
import './color-legend';
|
import './color-legend';
|
||||||
import './input-number';
|
import './input-number';
|
||||||
import './input-time';
|
import './input-time';
|
||||||
import './input-file';
|
import './input-file';
|
||||||
|
import './radio';
|
||||||
|
import './th';
|
||||||
import './treeview';
|
import './treeview';
|
||||||
import './treeview/child';
|
import './treeview/child';
|
||||||
import './calendar';
|
|
||||||
import './scroll-up/scroll-up';
|
|
||||||
|
|
|
@ -2,13 +2,6 @@
|
||||||
ng-class="{selected: $ctrl.hasFocus}">
|
ng-class="{selected: $ctrl.hasFocus}">
|
||||||
<div class="textField">
|
<div class="textField">
|
||||||
<div class="leftIcons">
|
<div class="leftIcons">
|
||||||
<vn-icon-button
|
|
||||||
ng-if="$ctrl.displayControls"
|
|
||||||
icon="remove"
|
|
||||||
ng-click="$ctrl.stepDown()"
|
|
||||||
tabindex="-1"
|
|
||||||
translate-attr="{title: 'Remove'}">
|
|
||||||
</vn-icon-button>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="infix">
|
<div class="infix">
|
||||||
<input
|
<input
|
||||||
|
@ -30,6 +23,13 @@
|
||||||
<div class="underline"></div>
|
<div class="underline"></div>
|
||||||
<div class="selected underline"></div>
|
<div class="selected underline"></div>
|
||||||
<div class="suffix">
|
<div class="suffix">
|
||||||
|
<vn-icon-button
|
||||||
|
ng-if="$ctrl.displayControls"
|
||||||
|
icon="remove"
|
||||||
|
ng-click="$ctrl.stepDown()"
|
||||||
|
tabindex="-1"
|
||||||
|
translate-attr="{title: 'Remove'}">
|
||||||
|
</vn-icon-button>
|
||||||
<vn-icon-button
|
<vn-icon-button
|
||||||
ng-if="$ctrl.displayControls"
|
ng-if="$ctrl.displayControls"
|
||||||
icon="add"
|
icon="add"
|
||||||
|
|
|
@ -17,17 +17,9 @@ export default class InputNumber extends Input {
|
||||||
*/
|
*/
|
||||||
registerEvents() {
|
registerEvents() {
|
||||||
this.input.addEventListener('change', event => {
|
this.input.addEventListener('change', event => {
|
||||||
if (!isNaN(this.value))
|
|
||||||
this.input.value = this.value;
|
|
||||||
|
|
||||||
this.validateValue();
|
this.validateValue();
|
||||||
|
|
||||||
this.emit('change', {event});
|
this.emit('change', {event});
|
||||||
});
|
});
|
||||||
|
|
||||||
this.input.addEventListener('focus', event => {
|
|
||||||
this.emit('focus', {event});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -49,12 +41,7 @@ export default class InputNumber extends Input {
|
||||||
this.input.value = value;
|
this.input.value = value;
|
||||||
|
|
||||||
this._value = value;
|
this._value = value;
|
||||||
|
this.element.classList.toggle('not-empty', this.hasValue);
|
||||||
if (this.hasValue)
|
|
||||||
this.element.classList.add('not-empty');
|
|
||||||
else
|
|
||||||
this.element.classList.remove('not-empty');
|
|
||||||
|
|
||||||
this.validateValue();
|
this.validateValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,6 +98,7 @@ export default class InputNumber extends Input {
|
||||||
*/
|
*/
|
||||||
stepUp() {
|
stepUp() {
|
||||||
this.input.stepUp();
|
this.input.stepUp();
|
||||||
|
this.input.dispatchEvent(new Event('change'));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -118,6 +106,7 @@ export default class InputNumber extends Input {
|
||||||
*/
|
*/
|
||||||
stepDown() {
|
stepDown() {
|
||||||
this.input.stepDown();
|
this.input.stepDown();
|
||||||
|
this.input.dispatchEvent(new Event('change'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
InputNumber.$inject = ['$element', '$scope', '$attrs', 'vnTemplate'];
|
InputNumber.$inject = ['$element', '$scope', '$attrs', 'vnTemplate'];
|
||||||
|
|
|
@ -3,18 +3,13 @@
|
||||||
|
|
||||||
vn-input-number {
|
vn-input-number {
|
||||||
@extend vn-textfield;
|
@extend vn-textfield;
|
||||||
input {
|
|
||||||
text-align: center !important;
|
|
||||||
}
|
|
||||||
vn-icon[icon=add],
|
vn-icon[icon=add],
|
||||||
vn-icon[icon=remove]{
|
vn-icon[icon=remove] {
|
||||||
&:not(:hover){
|
&:not(:hover){
|
||||||
color: $color-font-secondary;
|
color: $color-font-secondary;
|
||||||
}
|
}
|
||||||
i {
|
i {
|
||||||
-moz-user-select: none;
|
|
||||||
-webkit-user-select: none;
|
|
||||||
-ms-user-select: none;
|
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ export default class InputTime extends Input {
|
||||||
*/
|
*/
|
||||||
set value(value) {
|
set value(value) {
|
||||||
this.updateValue(value);
|
this.updateValue(value);
|
||||||
this.input.value = this.$filter('date')(value, 'HH:mm');
|
this.input.value = this.$filter('dateTime')(value, 'HH:mm');
|
||||||
}
|
}
|
||||||
|
|
||||||
updateValue(value) {
|
updateValue(value) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<vn-check field="$ctrl.checked"
|
<vn-check
|
||||||
|
field="$ctrl.checked"
|
||||||
intermediate="$ctrl.isIntermediate"
|
intermediate="$ctrl.isIntermediate"
|
||||||
vn-tooltip="Check all"
|
translate-attr="{title: 'Check all'}">
|
||||||
tooltip-position="up">
|
|
||||||
</vn-check>
|
</vn-check>
|
|
@ -1,5 +1,5 @@
|
||||||
vn-multi-check {
|
vn-multi-check {
|
||||||
md-checkbox {
|
vn-check {
|
||||||
margin-bottom: 0.8em
|
margin-bottom: 0.8em
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,8 +0,0 @@
|
||||||
<md-radio-group ng-model="$ctrl.model">
|
|
||||||
<md-radio-button aria-label="::option.label"
|
|
||||||
ng-repeat="option in $ctrl.options"
|
|
||||||
ng-value="option.value"
|
|
||||||
ng-disabled="$ctrl.disabled">
|
|
||||||
<span translate>{{::option.label}}</span>
|
|
||||||
</md-radio-button>
|
|
||||||
</md-radio-group>
|
|
|
@ -1,41 +0,0 @@
|
||||||
import ngModule from '../../module';
|
|
||||||
import Component from '../../lib/component';
|
|
||||||
import './style.scss';
|
|
||||||
|
|
||||||
export default class Controller extends Component {
|
|
||||||
constructor($element, $scope, $attrs) {
|
|
||||||
super($element, $scope);
|
|
||||||
this.hasInfo = Boolean($attrs.info);
|
|
||||||
this.info = $attrs.info || null;
|
|
||||||
}
|
|
||||||
|
|
||||||
get model() {
|
|
||||||
return this._model;
|
|
||||||
}
|
|
||||||
|
|
||||||
set model(value) {
|
|
||||||
this._model = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
get field() {
|
|
||||||
return this._model;
|
|
||||||
}
|
|
||||||
|
|
||||||
set field(value) {
|
|
||||||
this._model = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Controller.$inject = ['$element', '$scope', '$attrs'];
|
|
||||||
|
|
||||||
ngModule.component('vnRadioGroup', {
|
|
||||||
template: require('./radio-group.html'),
|
|
||||||
controller: Controller,
|
|
||||||
|
|
||||||
bindings: {
|
|
||||||
field: '=?',
|
|
||||||
options: '<?',
|
|
||||||
disabled: '<?',
|
|
||||||
checked: '<?'
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,11 +0,0 @@
|
||||||
@import "variables";
|
|
||||||
|
|
||||||
md-radio-group md-radio-button.md-checked .md-container {
|
|
||||||
.md-on {
|
|
||||||
background-color: $color-main
|
|
||||||
}
|
|
||||||
|
|
||||||
.md-off {
|
|
||||||
border-color: $color-main
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
<div class="radio">
|
||||||
|
<div class="focus-mark"></div>
|
||||||
|
<div class="mark"></div>
|
||||||
|
</div>
|
||||||
|
<span translate>
|
||||||
|
{{::$ctrl.label}}
|
||||||
|
</span>
|
|
@ -0,0 +1,93 @@
|
||||||
|
import ngModule from '../../module';
|
||||||
|
import Component from '../../lib/component';
|
||||||
|
import './style.scss';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic element for user input. You can use this to supply a way for the user
|
||||||
|
* to pick an option from multiple choices.
|
||||||
|
*
|
||||||
|
* @property {String} label Label to display along the component
|
||||||
|
* @property {any} field The value with which the element is linked
|
||||||
|
* @property {Boolean} checked Whether the radio is checked
|
||||||
|
* @property {String} val The actual value of the option
|
||||||
|
* @property {Boolean} disabled Put component in disabled mode
|
||||||
|
*/
|
||||||
|
export default class Controller extends Component {
|
||||||
|
constructor($element, $, $attrs) {
|
||||||
|
super($element, $);
|
||||||
|
this.hasInfo = Boolean($attrs.info);
|
||||||
|
this.info = $attrs.info || null;
|
||||||
|
|
||||||
|
let element = this.element;
|
||||||
|
element.addEventListener('click', e => this.onClick(e));
|
||||||
|
element.addEventListener('keydown', e => this.onKeydown(e));
|
||||||
|
element.tabIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
set field(value) {
|
||||||
|
this._field = value;
|
||||||
|
this.element.classList.toggle('checked',
|
||||||
|
Boolean(value) && value == this.val);
|
||||||
|
}
|
||||||
|
|
||||||
|
get field() {
|
||||||
|
return this._field;
|
||||||
|
}
|
||||||
|
|
||||||
|
set val(value) {
|
||||||
|
this._val = value;
|
||||||
|
this.field = this.field;
|
||||||
|
}
|
||||||
|
|
||||||
|
get val() {
|
||||||
|
return this._val;
|
||||||
|
}
|
||||||
|
|
||||||
|
set checked(value) {
|
||||||
|
this.field = value ? this.val : null;
|
||||||
|
this.$.$applyAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
get checked() {
|
||||||
|
return this.field == this.val;
|
||||||
|
}
|
||||||
|
|
||||||
|
set disabled(value) {
|
||||||
|
this.element.tabIndex = !value ? 0 : -1;
|
||||||
|
this.element.classList.toggle('disabled', Boolean(value));
|
||||||
|
this._disabled = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
get disabled() {
|
||||||
|
return this._disabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
onClick(event) {
|
||||||
|
if (this.disabled) return;
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
this.field = this.val;
|
||||||
|
this.$.$applyAsync();
|
||||||
|
this.element.dispatchEvent(new Event('change'));
|
||||||
|
}
|
||||||
|
|
||||||
|
onKeydown(event) {
|
||||||
|
if (event.code == 'Space')
|
||||||
|
this.onClick(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Controller.$inject = ['$element', '$scope', '$attrs'];
|
||||||
|
|
||||||
|
ngModule.component('vnRadio', {
|
||||||
|
template: require('./index.html'),
|
||||||
|
controller: Controller,
|
||||||
|
|
||||||
|
bindings: {
|
||||||
|
label: '@?',
|
||||||
|
field: '=?',
|
||||||
|
checked: '<?',
|
||||||
|
val: '@?',
|
||||||
|
disabled: '<?'
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,64 @@
|
||||||
|
describe('Component vnCheck', () => {
|
||||||
|
let $element;
|
||||||
|
let $ctrl;
|
||||||
|
let element;
|
||||||
|
|
||||||
|
beforeEach(angular.mock.module('vnCore', $translateProvider => {
|
||||||
|
$translateProvider.translations('en', {});
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(inject(($compile, $rootScope) => {
|
||||||
|
$element = $compile(`<vn-check></vn-check`)($rootScope);
|
||||||
|
$ctrl = $element.controller('vnCheck');
|
||||||
|
element = $element[0];
|
||||||
|
}));
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
$element.remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('field() setter', () => {
|
||||||
|
it(`should set model value`, () => {
|
||||||
|
$ctrl.field = true;
|
||||||
|
|
||||||
|
expect($ctrl.field).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should uncheck value and change to true when clicked`, () => {
|
||||||
|
$ctrl.field = false;
|
||||||
|
element.click();
|
||||||
|
|
||||||
|
expect($ctrl.field).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should check value and change to false when clicked`, () => {
|
||||||
|
$ctrl.field = true;
|
||||||
|
element.click();
|
||||||
|
|
||||||
|
expect($ctrl.field).toEqual(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should uncheck value and change to null when clicked`, () => {
|
||||||
|
$ctrl.field = false;
|
||||||
|
$ctrl.tripleState = true;
|
||||||
|
element.click();
|
||||||
|
|
||||||
|
expect($ctrl.field).toEqual(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should set value to null and change to true when clicked`, () => {
|
||||||
|
$ctrl.field = null;
|
||||||
|
$ctrl.tripleState = true;
|
||||||
|
element.click();
|
||||||
|
|
||||||
|
expect($ctrl.field).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should cast value to boolean when clicked`, () => {
|
||||||
|
$ctrl.field = 0;
|
||||||
|
element.click();
|
||||||
|
|
||||||
|
expect($ctrl.field).toEqual(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,62 @@
|
||||||
|
@import "variables";
|
||||||
|
|
||||||
|
vn-radio {
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-block;
|
||||||
|
outline: none;
|
||||||
|
|
||||||
|
&.disabled {
|
||||||
|
cursor: initial;
|
||||||
|
}
|
||||||
|
& > .radio {
|
||||||
|
position: relative;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border: 2px solid #666;
|
||||||
|
margin: 6px 0;
|
||||||
|
margin-right: .4em;
|
||||||
|
|
||||||
|
& > .mark {
|
||||||
|
transition: background 250ms;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.checked > .radio {
|
||||||
|
border-color: $color-main;
|
||||||
|
|
||||||
|
& > .mark {
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 50%;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
background-color: $color-main;
|
||||||
|
}
|
||||||
|
& > .focus-mark {
|
||||||
|
background-color: rgba($color-main, .15);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
& > .radio > .focus-mark {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
height: 38px;
|
||||||
|
width: 38px;
|
||||||
|
margin-top: -19px;
|
||||||
|
margin-left: -19px;
|
||||||
|
border-radius: 50%;
|
||||||
|
transform: scale3d(0, 0, 0);
|
||||||
|
transition: background 250ms;
|
||||||
|
transition: transform 250ms;
|
||||||
|
background-color: rgba(0, 0, 0, .1);
|
||||||
|
}
|
||||||
|
&:focus:not(.disabled) > .radio > .focus-mark {
|
||||||
|
transform: scale3d(1, 1, 1);
|
||||||
|
}
|
||||||
|
}
|
|
@ -184,7 +184,7 @@ vn-table {
|
||||||
float: right;
|
float: right;
|
||||||
margin: 0!important;
|
margin: 0!important;
|
||||||
}
|
}
|
||||||
md-checkbox {
|
vn-check {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,55 +1,61 @@
|
||||||
<ul ng-if="::$ctrl.items">
|
<ul ng-if="::$ctrl.items">
|
||||||
<li ng-repeat="item in $ctrl.items"
|
<li
|
||||||
ng-class="{
|
ng-repeat="item in $ctrl.items"
|
||||||
'expanded': item.active,
|
on-drop="$ctrl.onDrop(item, dragged, dropped)"
|
||||||
'collapsed': !item.active,
|
vn-draggable="{{::$ctrl.draggable}}"
|
||||||
'included': item.selected == 1,
|
vn-droppable="{{::$ctrl.droppable}}"
|
||||||
'excluded': item.selected == 0
|
ng-class="{expanded: item.active}">
|
||||||
}" vn-draggable="{{::$ctrl.draggable}}" vn-droppable="{{::$ctrl.droppable}}" on-drop="$ctrl.onDrop(item, dragged, dropped)">
|
<div
|
||||||
<vn-horizontal>
|
ng-click="$ctrl.toggle($event, item)"
|
||||||
<vn-auto class="actions">
|
class="node clickable">
|
||||||
<vn-icon icon="keyboard_arrow_down" title="{{'Toggle' | translate}}"
|
<vn-icon
|
||||||
ng-click="$ctrl.toggle(item, $event)">
|
class="arrow"
|
||||||
</vn-icon>
|
ng-class="{invisible: item.sons == 0}"
|
||||||
</vn-auto>
|
icon="keyboard_arrow_down"
|
||||||
<vn-check vn-auto vn-acl="{{$ctrl.aclRole}}"
|
translate-attr="{title: 'Toggle'}">
|
||||||
ng-if="$ctrl.selectable"
|
</vn-icon>
|
||||||
field="item.selected"
|
<vn-check
|
||||||
disabled="$ctrl.disabled"
|
vn-acl="{{$ctrl.aclRole}}"
|
||||||
on-change="$ctrl.select(item, value)"
|
ng-if="$ctrl.selectable"
|
||||||
triple-state="true">
|
field="item.selected"
|
||||||
</vn-check>
|
disabled="$ctrl.disabled"
|
||||||
<vn-one class="description">{{::item.name}}</vn-one>
|
on-change="$ctrl.select(item, value)"
|
||||||
<vn-auto>
|
triple-state="true"
|
||||||
<vn-icon-button icon="{{icon.icon}}"
|
label="{{::item.name}}">
|
||||||
ng-repeat="icon in $ctrl.icons"
|
</vn-check>
|
||||||
ng-click="$ctrl.onIconClick(icon, item, $ctrl.parent, $parent.$index)"
|
<vn-icon-button
|
||||||
vn-acl="{{$ctrl.aclRole}}" vn-acl-action="remove">
|
icon="{{icon.icon}}"
|
||||||
</vn-icon-button>
|
ng-repeat="icon in $ctrl.icons"
|
||||||
</vn-auto>
|
ng-click="$ctrl.onIconClick(icon, item, $ctrl.parent, $parent.$index)"
|
||||||
</vn-horizontal>
|
vn-acl="{{$ctrl.aclRole}}"
|
||||||
<vn-treeview-child items="item.childs" parent="item"
|
vn-acl-action="remove">
|
||||||
selectable="$ctrl.selectable"
|
</vn-icon-button>
|
||||||
disabled="$ctrl.disabled"
|
</div>
|
||||||
editable="$ctrl.editable"
|
<vn-treeview-child
|
||||||
draggable="::$ctrl.draggable"
|
items="item.childs"
|
||||||
droppable="::$ctrl.droppable"
|
parent="item"
|
||||||
icons="::$ctrl.icons"
|
selectable="$ctrl.selectable"
|
||||||
parent-scope="::$ctrl.parentScope"
|
disabled="$ctrl.disabled"
|
||||||
acl-role="$ctrl.aclRole">
|
editable="$ctrl.editable"
|
||||||
</vn-treeview-child>
|
draggable="::$ctrl.draggable"
|
||||||
</li>
|
droppable="::$ctrl.droppable"
|
||||||
<li ng-if="$ctrl.isInsertable && $ctrl.editable"
|
icons="::$ctrl.icons"
|
||||||
ng-click="$ctrl.onCreate($ctrl.parent)"
|
parent-scope="::$ctrl.parentScope"
|
||||||
vn-acl="{{$ctrl.aclRole}}"
|
acl-role="$ctrl.aclRole">
|
||||||
vn-acl-action="remove">
|
</vn-treeview-child>
|
||||||
<vn-horizontal>
|
</li>
|
||||||
<vn-auto>
|
<li
|
||||||
<vn-icon-button icon="add_circle"></vn-icon-button>
|
ng-if="$ctrl.isInsertable && $ctrl.editable"
|
||||||
</vn-auto>
|
ng-click="$ctrl.onCreate($ctrl.parent)"
|
||||||
<div class="description" translate>
|
vn-acl="{{$ctrl.aclRole}}"
|
||||||
Create new one
|
vn-acl-action="remove">
|
||||||
</div>
|
<div class="node">
|
||||||
</vn-horizontal>
|
<vn-icon-button
|
||||||
</li>
|
icon="add_circle">
|
||||||
</ul>
|
</vn-icon-button>
|
||||||
|
<div class="description" translate>
|
||||||
|
Create new one
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
|
@ -7,7 +7,9 @@ class Controller extends Component {
|
||||||
this.$scope = $scope;
|
this.$scope = $scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
toggle(item) {
|
toggle(event, item) {
|
||||||
|
if (event.defaultPrevented || !item.sons) return;
|
||||||
|
event.preventDefault();
|
||||||
this.treeview.onToggle(item);
|
this.treeview.onToggle(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<vn-treeview-child acl-role="$ctrl.aclRole"
|
<vn-treeview-child
|
||||||
|
acl-role="$ctrl.aclRole"
|
||||||
items="$ctrl.data"
|
items="$ctrl.data"
|
||||||
parent="$ctrl.data"
|
parent="$ctrl.data"
|
||||||
selectable="$ctrl.selectable"
|
selectable="$ctrl.selectable"
|
||||||
|
|
|
@ -1,80 +1,46 @@
|
||||||
@import "variables";
|
@import "effects";
|
||||||
|
|
||||||
vn-treeview {
|
vn-treeview {
|
||||||
vn-treeview-child {
|
vn-treeview-child {
|
||||||
display: block
|
display: block
|
||||||
}
|
}
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
line-height: 24px;
|
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
||||||
|
|
||||||
li {
|
li {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
|
||||||
.actions {
|
& > div > .arrow {
|
||||||
min-width: 24px;
|
min-width: 24px;
|
||||||
margin-right: 10px
|
margin-right: 10px;
|
||||||
|
transition: transform 200ms;
|
||||||
}
|
}
|
||||||
|
&.expanded > div > .arrow {
|
||||||
.description {
|
transform: rotate(180deg);
|
||||||
pointer-events: none;
|
|
||||||
padding-left: 5px
|
|
||||||
}
|
}
|
||||||
}
|
& > .node {
|
||||||
|
@extend %clickable;
|
||||||
li vn-icon {
|
display: flex;
|
||||||
cursor: pointer;
|
padding: 5px;
|
||||||
}
|
align-items: center;
|
||||||
|
|
||||||
li ul {
|
& > vn-check:not(.indeterminate) {
|
||||||
padding-left: 1.8em;
|
color: $color-main;
|
||||||
}
|
|
||||||
|
& > .check {
|
||||||
li > vn-horizontal {
|
border-color: $color-main;
|
||||||
padding: 5px
|
}
|
||||||
}
|
}
|
||||||
|
& > vn-check.checked {
|
||||||
li > vn-horizontal:hover {
|
color: $color-main;
|
||||||
background-color: $color-hover-cd
|
}
|
||||||
}
|
|
||||||
|
|
||||||
li.expanded > vn-horizontal > .actions > vn-icon[icon="keyboard_arrow_down"] {
|
|
||||||
transition: all 0.2s;
|
|
||||||
transform: rotate(180deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
li.collapsed > vn-horizontal > .actions > vn-icon[icon="keyboard_arrow_down"] {
|
|
||||||
transition: all 0.2s;
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
li.included {
|
|
||||||
& > vn-horizontal > .description {
|
|
||||||
color: $color-notice;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
}
|
||||||
|
ul {
|
||||||
& > vn-horizontal > vn-check .md-icon {
|
padding-left: 2.2em;
|
||||||
background-color: $color-notice
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
li.excluded {
|
|
||||||
& > vn-horizontal > .description {
|
|
||||||
color: $color-alert;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
& > vn-horizontal > vn-check .md-icon {
|
|
||||||
background-color: $color-alert;
|
|
||||||
border-color: transparent
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vn-icon-button {
|
vn-icon-button {
|
||||||
padding: 0
|
padding: 0
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,10 +80,23 @@
|
||||||
on-response="$ctrl.onSave(response)">
|
on-response="$ctrl.onSave(response)">
|
||||||
<tpl-body>
|
<tpl-body>
|
||||||
<vn-vertical>
|
<vn-vertical>
|
||||||
<vn-radio-group
|
<vn-vertical>
|
||||||
field="$ctrl.eventType"
|
<vn-radio
|
||||||
options="$ctrl.options">
|
field="$ctrl.eventType"
|
||||||
</vn-radio-group>
|
label="One day"
|
||||||
|
val="day">
|
||||||
|
</vn-radio>
|
||||||
|
<vn-radio
|
||||||
|
field="$ctrl.eventType"
|
||||||
|
label="Range of dates"
|
||||||
|
val="range">
|
||||||
|
</vn-radio>
|
||||||
|
<vn-radio
|
||||||
|
field="$ctrl.eventType"
|
||||||
|
label="Indefinitely"
|
||||||
|
val="indefinitely">
|
||||||
|
</vn-radio>
|
||||||
|
</vn-vertical>
|
||||||
<div
|
<div
|
||||||
ng-if="$ctrl.eventType != 'day'"
|
ng-if="$ctrl.eventType != 'day'"
|
||||||
class="week-days">
|
class="week-days">
|
||||||
|
|
|
@ -41,19 +41,6 @@ class Controller {
|
||||||
wday.abr = locale.substr(0, 1);
|
wday.abr = locale.substr(0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.options = [
|
|
||||||
{
|
|
||||||
label: 'One day',
|
|
||||||
value: 'day'
|
|
||||||
}, {
|
|
||||||
label: 'Range of dates',
|
|
||||||
value: 'range'
|
|
||||||
}, {
|
|
||||||
label: 'Indefinitely',
|
|
||||||
value: 'indefinitely'
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
this.$http.get(`/api/Zones/${$stateParams.id}/exclusions`)
|
this.$http.get(`/api/Zones/${$stateParams.id}/exclusions`)
|
||||||
.then(res => this.$.exclusions = res.data);
|
.then(res => this.$.exclusions = res.data);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue