From cc9e91fe90f9a4d3d1ac14ef1e1f2821ec84c98a Mon Sep 17 00:00:00 2001 From: Ming Hay Luk Date: Fri, 14 Jun 2024 11:02:44 -0700 Subject: [PATCH] Power select component for parameters --- .../parameters/selectable/component.js | 41 +++++++ .../parameters/selectable/template.hbs | 16 +++ .../parameters/selectable/component-test.js | 114 ++++++++++++++++++ 3 files changed, 171 insertions(+) create mode 100644 app/components/pipeline/parameters/selectable/component.js create mode 100644 app/components/pipeline/parameters/selectable/template.hbs create mode 100644 tests/integration/components/pipeline/parameters/selectable/component-test.js diff --git a/app/components/pipeline/parameters/selectable/component.js b/app/components/pipeline/parameters/selectable/component.js new file mode 100644 index 000000000..5fd7fc723 --- /dev/null +++ b/app/components/pipeline/parameters/selectable/component.js @@ -0,0 +1,41 @@ +import Component from '@glimmer/component'; +import { tracked } from '@glimmer/tracking'; +import { action } from '@ember/object'; + +export default class PipelineParametersSelectableComponent extends Component { + @tracked value; + + inputValue; + + constructor() { + super(...arguments); + + this.value = this.args.parameter.value; + } + + @action + selectOption(value) { + this.value = value; + this.args.onSelectValue(this.args.parameter, value); + } + + @action + handleInput(value) { + this.inputValue = value; + } + + @action + handleKeydown(_dropdown, e) { + switch (e.keyCode) { + case 13: + this.selectOption(this.inputValue); + break; + case 27: + // Escape key pressed - prevent further propagation of event + e.stopImmediatePropagation(); + break; + default: + break; + } + } +} diff --git a/app/components/pipeline/parameters/selectable/template.hbs b/app/components/pipeline/parameters/selectable/template.hbs new file mode 100644 index 000000000..0b1f1cbbf --- /dev/null +++ b/app/components/pipeline/parameters/selectable/template.hbs @@ -0,0 +1,16 @@ + + {{selectedValue}} + diff --git a/tests/integration/components/pipeline/parameters/selectable/component-test.js b/tests/integration/components/pipeline/parameters/selectable/component-test.js new file mode 100644 index 000000000..0d00dc2ae --- /dev/null +++ b/tests/integration/components/pipeline/parameters/selectable/component-test.js @@ -0,0 +1,114 @@ +import { module, test } from 'qunit'; +import { setupRenderingTest } from 'screwdriver-ui/tests/helpers'; +import { click, render, triggerKeyEvent } from '@ember/test-helpers'; +import { hbs } from 'ember-cli-htmlbars'; +import { selectChoose, selectSearch } from 'ember-power-select/test-support'; +import sinon from 'sinon'; + +module( + 'Integration | Component | pipeline/parameters/selectable', + function (hooks) { + setupRenderingTest(hooks); + + test('it renders', async function (assert) { + this.setProperties({ + parameter: { + defaultValues: ['foo', 'bar'], + value: 'foo' + }, + onOpen: () => {}, + onSelectValue: () => {} + }); + + await render( + hbs`` + ); + + assert.dom(this.element).hasText('foo'); + }); + + test('it calls onOpen callback', async function (assert) { + const onOpen = sinon.spy(); + + this.setProperties({ + parameter: { + defaultValues: ['foo', 'bar'], + value: 'foo' + }, + onOpen, + onSelectValue: () => {} + }); + + await render( + hbs`` + ); + await click('.ember-power-select-trigger'); + + assert.equal(onOpen.callCount, 1); + }); + + test('it calls onSelectValue callback when selection is made', async function (assert) { + const parameter = { + defaultValues: ['foo', 'bar'], + value: 'foo' + }; + const onSelectValue = sinon.spy(); + + this.setProperties({ + parameter, + onOpen: () => {}, + onSelectValue + }); + + await render( + hbs`` + ); + + await selectChoose('.parameter-selector', parameter.defaultValues[1]); + + assert.equal(onSelectValue.callCount, 1); + assert.equal( + onSelectValue.calledWith(parameter, parameter.defaultValues[1]), + true + ); + }); + + test('it overrides default values when enter key is pressed', async function (assert) { + const parameter = { defaultValues: ['foo', 'bar'], value: 'foo' }; + const newValue = 'abc123'; + const onSelectValue = sinon.spy(); + + this.setProperties({ + parameter, + onOpen: () => {}, + onSelectValue + }); + + await render( + hbs`` + ); + + await selectSearch('.parameter-selector', newValue); + await triggerKeyEvent('input', 'keydown', 13); + + await assert.equal(onSelectValue.callCount, 1); + assert.equal(onSelectValue.calledWith(parameter, newValue), true); + }); + } +);