refactor: 💡 Migrate Target form to use HDS components (#1562)

* refactor: 💡 Migrate Target form to use HDS components

* chore: 🤖 add ember-test-selectors to remove data-test attribute

Removes data-test attributes in production builds

* refactor: 💡 Default Port marked requried or optional by type
This commit is contained in:
Cameron Perera authored and GitHub committed 2023-01-10 16:18:28 -06:00
1 parent 63f619b1ff
commit ad37b489b7
6 files changed
+874 -1564

No files matched your search

+3 -3
View File
@@ -36,8 +36,8 @@ started:
status: status:
label: Status label: Status
session_max_seconds: session_max_seconds:
label: Maximum Duration (in seconds) label: Maximum Duration
help: The maximum duration of a session. help: The maximum duration of a session, in seconds.
session_connection_limit: session_connection_limit:
label: Maximum Connections label: Maximum Connections
help: The maximum number of connections allowed per session. For unlimited, specify "-1". help: The maximum number of connections allowed per session. For unlimited, specify "-1".
@@ -55,7 +55,7 @@ worker_type:
help: Type of worker help: Type of worker
worker_filter: worker_filter:
label: Worker Filter label: Worker Filter
help: Optional boolean expression to filter the workers that are allowed to satisfy this request. help: Deprecated. Optional boolean expression to filter the workers that are allowed to satisfy this request.
host_set: host_set:
label: Host Set label: Host Set
grant_scope: grant_scope:
+1
View File
@@ -45,6 +45,7 @@
"ember-focus-trap": "^1.0.1", "ember-focus-trap": "^1.0.1",
"ember-named-blocks-polyfill": "^0.2.5", "ember-named-blocks-polyfill": "^0.2.5",
"ember-radio-button": "github:yapplabs/ember-radio-button.git#b2ab65f", "ember-radio-button": "github:yapplabs/ember-radio-button.git#b2ab65f",
"ember-test-selectors": "^6.0.0",
"ember-uuid": "^2.1.0", "ember-uuid": "^2.1.0",
"jsonlint": "^1.6.3", "jsonlint": "^1.6.3",
"sass": "^1.55.0" "sass": "^1.55.0"
@@ -5,41 +5,47 @@
@showEditToggle={{if @model.isNew false true}} @showEditToggle={{if @model.isNew false true}}
as |form| as |form|
> >
<form.input <Hds::Form::TextInput::Field
@name='name' @isRequired={{true}}
@type='text' @isOptional={{false}}
@value={{@model.name}} @value={{@model.name}}
@label={{t 'form.name.label'}} @isInvalid={{@model.errors.name}}
@helperText={{t 'form.name.help'}}
@error={{@model.errors.name}}
as |field|
>
{{#if @model.errors.name}}
<field.errors as |errors|>
{{#each @model.errors.name as |error|}}
<errors.message>{{error.message}}</errors.message>
{{/each}}
</field.errors>
{{/if}}
</form.input>
<form.textarea
@name='description'
@type='text' @type='text'
@value={{@model.description}} name='name'
@label={{t 'form.description.label'}} disabled={{form.disabled}}
@helperText={{t 'form.description.help'}} {{on 'input' (set-from-event @model 'name')}}
@error={{@model.errors.description}} as |F|
as |field|
> >
{{#if @model.errors.description}} <F.Label>{{t 'form.name.label'}}</F.Label>
<field.errors as |errors|> <F.HelperText>{{t 'form.name.help'}}</F.HelperText>
{{#each @model.errors.description as |error|}} {{#if @model.errors.name}}
<errors.message>{{error.message}}</errors.message> <F.Error as |E|>
{{#each @model.errors.name as |error|}}
<E.Message>{{error.message}}</E.Message>
{{/each}} {{/each}}
</field.errors> </F.Error>
{{/if}} {{/if}}
</form.textarea> </Hds::Form::TextInput::Field>
<Hds::Form::Textarea::Field
@isRequired={{false}}
@isOptional={{true}}
@value={{@model.description}}
@isInvalid={{@model.errors.description}}
name='description'
disabled={{form.disabled}}
as |F|
>
<F.Label>{{t 'form.description.label'}}</F.Label>
<F.HelperText>{{t 'form.description.help'}}</F.HelperText>
{{#if @model.errors.description}}
<F.Error as |E|>
{{#each @model.errors.description as |error|}}
<E.Message>{{error.message}}</E.Message>
{{/each}}
</F.Error>
{{/if}}
</Hds::Form::Textarea::Field>
{{#if (and @model.isNew (feature-flag 'ssh-target'))}} {{#if (and @model.isNew (feature-flag 'ssh-target'))}}
<Hds::Form::RadioCard::Group @name='type' @alignment='center' as |G|> <Hds::Form::RadioCard::Group @name='type' @alignment='center' as |G|>
@@ -75,86 +81,97 @@
</InfoField> </InfoField>
{{/if}} {{/if}}
<form.input <Hds::Form::TextInput::Field
@name='session_max_seconds' @isRequired={{false}}
@type='number' @isOptional={{true}}
@value={{@model.session_max_seconds}} @value={{@model.session_max_seconds}}
@label={{t 'form.session_max_seconds.label'}} @isInvalid={{@model.errors.session_max_seconds}}
@error={{@model.errors.session_max_seconds}}
@helperText={{t 'form.session_max_seconds.help'}}
min='0'
step='1'
as |field|
>
{{#if @model.errors.session_max_seconds}}
<field.errors as |errors|>
{{#each @model.errors.session_max_seconds as |error|}}
<errors.message>{{error.message}}</errors.message>
{{/each}}
</field.errors>
{{/if}}
</form.input>
<form.input
@name='session_connection_limit'
@type='number'
@value={{@model.session_connection_limit}}
@label={{t 'form.session_connection_limit.label'}}
@error={{@model.errors.session_connection_limit}}
@helperText={{t 'form.session_connection_limit.help'}}
min='-1'
step='1'
as |field|
>
{{#if @model.errors.session_connection_limit}}
<field.errors as |errors|>
{{#each @model.errors.session_connection_limit as |error|}}
<errors.message>{{error.message}}</errors.message>
{{/each}}
</field.errors>
{{/if}}
</form.input>
<form.input
@name='worker_filter'
@type='text' @type='text'
@value={{@model.worker_filter}} name='session_max_seconds'
@label={{t 'form.worker_filter.label'}} disabled={{form.disabled}}
@error={{@model.errors.worker_filter}} {{on 'input' (set-from-event @model 'session_max_seconds')}}
@helperText={{t 'form.worker_filter.help'}} as |F|
@linkText={{t 'actions.learn-more'}}
@link={{doc-url 'target.worker-filters'}}
as |field|
> >
{{#if @model.errors.worker_filter}} <F.Label>{{t 'form.session_max_seconds.label'}}</F.Label>
<field.errors as |errors|> <F.HelperText>{{t 'form.session_max_seconds.help'}}</F.HelperText>
{{#each @model.errors.worker_filter as |error|}} {{#if @model.errors.session_max_seconds}}
<errors.message>{{error.message}}</errors.message> <F.Error as |E|>
{{#each @model.errors.session_max_seconds as |error|}}
<E.Message>{{error.message}}</E.Message>
{{/each}} {{/each}}
</field.errors> </F.Error>
{{/if}} {{/if}}
</form.input> </Hds::Form::TextInput::Field>
<form.input <Hds::Form::TextInput::Field
@name='default_port' @isRequired={{false}}
@type='number' @isOptional={{true}}
@value={{@model.default_port}} @value={{@model.session_connection_limit}}
@label={{t 'form.default_port.label'}} @isInvalid={{@model.errors.session_connection_limit}}
@error={{@model.errors.default_port}} @type='text'
@helperText={{t 'form.default_port.help'}} name='session_connection_limit'
placeholder={{@defaultPort}} disabled={{form.disabled}}
min='0' {{on 'input' (set-from-event @model 'session_connection_limit')}}
step='1' as |F|
as |field|
> >
{{#if @model.errors.default_port}} <F.Label>{{t 'form.session_connection_limit.label'}}</F.Label>
<field.errors as |errors|> <F.HelperText>{{t 'form.session_connection_limit.help'}}</F.HelperText>
{{#each @model.errors.default_port as |error|}} {{#if @model.errors.session_connection_limit}}
<errors.message>{{error.message}}</errors.message> <F.Error as |E|>
{{#each @model.errors.session_connection_limit as |error|}}
<E.Message>{{error.message}}</E.Message>
{{/each}} {{/each}}
</field.errors> </F.Error>
{{/if}} {{/if}}
</form.input> </Hds::Form::TextInput::Field>
<Hds::Form::TextInput::Field
@isRequired={{false}}
@isOptional={{true}}
@value={{@model.worker_filter}}
@isInvalid={{@model.errors.worker_filter}}
@type='text'
name='worker_filter'
disabled={{form.disabled}}
{{on 'input' (set-from-event @model 'worker_filter')}}
as |F|
>
<F.Label>{{t 'form.worker_filter.label'}}</F.Label>
<F.HelperText>{{t 'form.worker_filter.help'}}</F.HelperText>
{{#if @model.errors.worker_filter}}
<F.Error as |E|>
{{#each @model.errors.worker_filter as |error|}}
<E.Message>{{error.message}}</E.Message>
{{/each}}
</F.Error>
{{/if}}
</Hds::Form::TextInput::Field>
<Hds::Form::TextInput::Field
@isRequired={{@model.isTCP}}
@isOptional={{not @model.isTCP}}
@value={{@model.default_port}}
@isInvalid={{@model.errors.default_port}}
@type='text'
name='default_port'
disabled={{form.disabled}}
placeholder={{@defaultPort}}
{{on 'input' (set-from-event @model 'default_port')}}
as |F|
>
<F.Label data-test-default-port-label>{{t
'form.default_port.label'
}}</F.Label>
<F.HelperText>{{t 'form.default_port.help'}}</F.HelperText>
{{#if @model.errors.default_port}}
<F.Error as |E|>
{{#each @model.errors.default_port as |error|}}
<E.Message>{{error.message}}</E.Message>
{{/each}}
</F.Error>
{{/if}}
</Hds::Form::TextInput::Field>
{{#if (can 'save model' @model)}} {{#if (can 'save model' @model)}}
<form.actions <form.actions
@enableEditText={{t 'actions.edit-form'}} @enableEditText={{t 'actions.edit-form'}}
@@ -134,6 +134,20 @@ module('Acceptance | targets | create', function (hooks) {
); );
}); });
test('defualt port is not marked required for SSH targets', async function (assert) {
assert.expect(1);
await visit(urls.newTarget);
assert.dom('[data-test-default-port-label]').includesText('Optional');
});
test('defualt port is marked required for TCP targets', async function (assert) {
assert.expect(1);
await visit(urls.newTarget);
await click('[value="tcp"]');
assert.dom('[data-test-default-port-label]').includesText('Required');
});
test('can navigate to new targets route with proper authorization', async function (assert) { test('can navigate to new targets route with proper authorization', async function (assert) {
assert.expect(2); assert.expect(2);
await visit(urls.projectScope); await visit(urls.projectScope);
@@ -179,7 +193,7 @@ module('Acceptance | targets | create', function (hooks) {
) )
); );
assert.dom('.info-field').exists({ count: 1 }); assert.dom('.info-field').exists({ count: 1 });
assert.dom('.hds-form-helper-text').includesText('TCP'); assert.dom('.info-field .hds-form-helper-text').includesText('TCP');
}); });
test('can cancel create new TCP target', async function (assert) { test('can cancel create new TCP target', async function (assert) {
@@ -239,7 +253,7 @@ module('Acceptance | targets | create', function (hooks) {
await click('[type="submit"]'); await click('[type="submit"]');
assert.dom('[role="alert"] div').hasText('The request was invalid.'); assert.dom('[role="alert"] div').hasText('The request was invalid.');
assert.dom('.rose-form-error-message').hasText('Name is required.'); assert.dom('.hds-form-error__message').hasText('Name is required.');
}); });
test('saving a new SSH target with invalid fields displays error messages', async function (assert) { test('saving a new SSH target with invalid fields displays error messages', async function (assert) {
@@ -267,6 +281,6 @@ module('Acceptance | targets | create', function (hooks) {
await click('[type="submit"]'); await click('[type="submit"]');
assert.dom('[role="alert"] div').hasText('The request was invalid.'); assert.dom('[role="alert"] div').hasText('The request was invalid.');
assert.dom('.rose-form-error-message').hasText('Name is required.'); assert.dom('.hds-form-error__message').hasText('Name is required.');
}); });
}); });
@@ -120,7 +120,7 @@ module('Acceptance | targets | update', function (hooks) {
await click('[type="submit"]'); await click('[type="submit"]');
assert.dom('[role="alert"] div').hasText('The request was invalid.'); assert.dom('[role="alert"] div').hasText('The request was invalid.');
assert.dom('.rose-form-error-message').hasText('Name is required.'); assert.dom('.hds-form-error__message').hasText('Name is required.');
}); });
test('can discard unsaved target changes via dialog', async function (assert) { test('can discard unsaved target changes via dialog', async function (assert) {
+734 -1456
View File
File diff suppressed because it is too large. Load diff