mirror of
https://github.com/kemko/nomad.git
synced 2026-01-04 09:25:46 +03:00
Merge pull request #8314 from hashicorp/f-ui/scaling-ux
UI: Scaling UI UX Improvements
This commit is contained in:
@@ -9,7 +9,7 @@ const ESC = 27;
|
||||
|
||||
@classic
|
||||
@classNames('stepper-input')
|
||||
@classNameBindings('class', 'disabled:is-disabled')
|
||||
@classNameBindings('class', 'disabled:is-disabled', 'disabled:tooltip', 'disabled:multiline')
|
||||
export default class StepperInput extends Component {
|
||||
min = 0;
|
||||
max = 10;
|
||||
@@ -40,9 +40,13 @@ export default class StepperInput extends Component {
|
||||
|
||||
@action
|
||||
setValue(e) {
|
||||
const newValue = Math.min(this.max, Math.max(this.min, e.target.value));
|
||||
this.set('internalValue', newValue);
|
||||
this.update(this.internalValue);
|
||||
if (e.target.value !== '') {
|
||||
const newValue = Math.floor(Math.min(this.max, Math.max(this.min, e.target.value)));
|
||||
this.set('internalValue', newValue);
|
||||
this.update(this.internalValue);
|
||||
} else {
|
||||
e.target.value = this.internalValue;
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
@@ -52,6 +56,15 @@ export default class StepperInput extends Component {
|
||||
}
|
||||
}
|
||||
|
||||
@action
|
||||
selectValue(e) {
|
||||
e.target.select();
|
||||
}
|
||||
|
||||
@action focusInput() {
|
||||
this.element.querySelector('.stepper-input-input').focus();
|
||||
}
|
||||
|
||||
update(value) {
|
||||
debounce(this, sendUpdateAction, value, this.debounce);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import Component from '@ember/component';
|
||||
import { inject as service } from '@ember/service';
|
||||
import { computed, action } from '@ember/object';
|
||||
import { alias, oneWay } from '@ember/object/computed';
|
||||
import { debounce } from '@ember/runloop';
|
||||
@@ -10,12 +11,21 @@ import { lazyClick } from '../helpers/lazy-click';
|
||||
@tagName('tr')
|
||||
@classNames('task-group-row', 'is-interactive')
|
||||
export default class TaskGroupRow extends Component {
|
||||
@service can;
|
||||
|
||||
taskGroup = null;
|
||||
debounce = 500;
|
||||
|
||||
@oneWay('taskGroup.count') count;
|
||||
@alias('taskGroup.job.runningDeployment') runningDeployment;
|
||||
|
||||
@computed('runningDeployment')
|
||||
get tooltipText() {
|
||||
if (this.can.cannot('scale job')) return "You aren't allowed to scale task groups";
|
||||
if (this.runningDeployment) return 'You cannot scale task groups during a deployment';
|
||||
return undefined;
|
||||
}
|
||||
|
||||
onClick() {}
|
||||
|
||||
click(event) {
|
||||
|
||||
@@ -14,6 +14,7 @@ export default class TaskGroupController extends Controller.extend(
|
||||
WithNamespaceResetting
|
||||
) {
|
||||
@service userSettings;
|
||||
@service can;
|
||||
|
||||
queryParams = [
|
||||
{
|
||||
@@ -50,6 +51,13 @@ export default class TaskGroupController extends Controller.extend(
|
||||
@alias('listSorted') listToSearch;
|
||||
@alias('listSearched') sortedAllocations;
|
||||
|
||||
@computed('model.job.runningDeployment')
|
||||
get tooltipText() {
|
||||
if (this.can.cannot('scale job')) return "You aren't allowed to scale task groups";
|
||||
if (this.model.job.runningDeployment) return 'You cannot scale task groups during a deployment';
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@action
|
||||
gotoAllocation(allocation) {
|
||||
this.transitionToRoute('allocations.allocation', allocation);
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
display: flex;
|
||||
align-self: center;
|
||||
padding-right: 0.75em;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.stepper-input-input {
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
max-width: 250px;
|
||||
color: $white;
|
||||
font-size: $size-7;
|
||||
font-weight: $weight-normal;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
line-height: 1.25;
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<label data-test-stepper-label class="stepper-input-label">{{yield}}</label>
|
||||
<label
|
||||
data-test-stepper-label
|
||||
class="stepper-input-label"
|
||||
onClick={{action "focusInput"}}>{{yield}}</label>
|
||||
<input
|
||||
data-test-stepper-input
|
||||
type="number"
|
||||
@@ -7,11 +10,13 @@
|
||||
value={{internalValue}}
|
||||
disabled={{disabled}}
|
||||
class="stepper-input-input"
|
||||
onFocus={{action "selectValue"}}
|
||||
onKeyDown={{action "resetTextInput"}}
|
||||
onChange={{action "setValue"}}>
|
||||
<button
|
||||
data-test-stepper-decrement
|
||||
role="button"
|
||||
aria-label="decrement"
|
||||
class="stepper-input-stepper button {{class}}"
|
||||
disabled={{or disabled (lte internalValue min)}}
|
||||
onclick={{action "decrement"}}>
|
||||
@@ -20,6 +25,7 @@
|
||||
<button
|
||||
data-test-stepper-increment
|
||||
role="button"
|
||||
aria-label="increment"
|
||||
class="stepper-input-stepper button {{class}}"
|
||||
disabled={{or disabled (gte internalValue max)}}
|
||||
onclick={{action "increment"}}>
|
||||
|
||||
@@ -8,11 +8,12 @@
|
||||
{{#if taskGroup.scaling}}
|
||||
<div
|
||||
data-test-scale-controls
|
||||
class="button-bar is-shadowless is-text bumper-left {{if (cannot "scale job") "tooltip"}}"
|
||||
aria-label={{if (cannot "scale job") "You aren't allowed to scale task groups"}}>
|
||||
class="button-bar is-shadowless is-text bumper-left {{if (or runningDeployment (cannot "scale job")) "tooltip multiline"}}"
|
||||
aria-label={{tooltipText}}>
|
||||
<button
|
||||
data-test-scale="decrement"
|
||||
role="button"
|
||||
aria-label="decrement"
|
||||
class="button is-xsmall is-light"
|
||||
disabled={{or isMinimum runningDeployment (cannot "scale job")}}
|
||||
onclick={{action "countDown"}}>
|
||||
@@ -21,6 +22,7 @@
|
||||
<button
|
||||
data-test-scale="increment"
|
||||
role="button"
|
||||
aria-label="increment"
|
||||
class="button is-xsmall is-light"
|
||||
disabled={{or isMaximum runningDeployment (cannot "scale job")}}
|
||||
onclick={{action "countUp"}}>
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
{{#if model.scaling}}
|
||||
<StepperInput
|
||||
data-test-task-group-count-stepper
|
||||
aria-label={{tooltipText}}
|
||||
@min={{model.scaling.min}}
|
||||
@max={{model.scaling.max}}
|
||||
@value={{model.count}}
|
||||
|
||||
@@ -164,4 +164,55 @@ module('Integration | Component | stepper input', function(hooks) {
|
||||
await StepperInput.input.esc();
|
||||
assert.equal(StepperInput.input.value, this.value);
|
||||
});
|
||||
|
||||
test('clicking the label focuses in the input', async function(assert) {
|
||||
this.setProperties(commonProperties());
|
||||
|
||||
await render(commonTemplate);
|
||||
await StepperInput.clickLabel();
|
||||
|
||||
const input = find('[data-test-stepper-input]');
|
||||
assert.equal(document.activeElement, input);
|
||||
});
|
||||
|
||||
test('focusing the input selects the input value', async function(assert) {
|
||||
this.setProperties(commonProperties());
|
||||
|
||||
await render(commonTemplate);
|
||||
await StepperInput.input.focus();
|
||||
|
||||
assert.equal(
|
||||
window
|
||||
.getSelection()
|
||||
.toString()
|
||||
.trim(),
|
||||
this.value.toString()
|
||||
);
|
||||
});
|
||||
|
||||
test('entering a fractional value floors the value', async function(assert) {
|
||||
this.setProperties(commonProperties());
|
||||
const newValue = 3.14159;
|
||||
|
||||
await render(commonTemplate);
|
||||
|
||||
await StepperInput.input.fill(newValue);
|
||||
|
||||
await settled();
|
||||
assert.equal(StepperInput.input.value, Math.floor(newValue));
|
||||
assert.ok(this.onChange.calledWith(Math.floor(newValue)));
|
||||
});
|
||||
|
||||
test('entering an invalid value reverts the value', async function(assert) {
|
||||
this.setProperties(commonProperties());
|
||||
const newValue = 'NaN';
|
||||
|
||||
await render(commonTemplate);
|
||||
|
||||
await StepperInput.input.fill(newValue);
|
||||
|
||||
await settled();
|
||||
assert.equal(StepperInput.input.value, this.value);
|
||||
assert.notOk(this.onChange.called);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -14,6 +14,7 @@ export default scope => ({
|
||||
scope,
|
||||
|
||||
label: text('[data-test-stepper-label]'),
|
||||
clickLabel: clickable('[data-test-stepper-label]'),
|
||||
|
||||
input: {
|
||||
scope: '[data-test-stepper-input]',
|
||||
|
||||
Reference in New Issue
Block a user