Instance Groups Instances List styling fixes (#3846)

* Instance Groups Instances slider renders properly, and that list wraps properly.

* Instance Groups responds properly

* assorted container groups ui fixes
updated responsiveness of instance groups and instances list
fix layout of container group form
update help text for container group form elements
update text for tech preview top bar

* update container group doclink

* list styling updates based on feedback
This commit is contained in:
Alex Corey
2019-10-22 13:31:53 -04:00
committed by Ryan Petrello
parent 321aa3b01d
commit b74bf9f266
12 changed files with 178 additions and 204 deletions

View File

@@ -208,6 +208,7 @@
max-width: none !important; max-width: none !important;
width: 100% !important; width: 100% !important;
padding-right: 0px !important; padding-right: 0px !important;
margin-top: 10px;
} }
.Form-formGroup--checkbox{ .Form-formGroup--checkbox{

View File

@@ -15,7 +15,9 @@
title="{{ label || vm.strings.get('code_mirror.label.VARIABLES') }}" title="{{ label || vm.strings.get('code_mirror.label.VARIABLES') }}"
tabindex="-1" tabindex="-1"
ng-if="tooltip"> ng-if="tooltip">
<i class="fa fa-question-circle"></i> <span class="at-Popover-icon" ng-class="{ 'at-Popover-icon--defaultCursor': popover.on === 'mouseenter' && !popover.click }">
<i class="fa fa-question-circle"></i>
</span>
</a> </a>
<div class="atCodeMirror-toggleContainer FormToggle-container"> <div class="atCodeMirror-toggleContainer FormToggle-container">
<div id="{{ name }}_parse_type" class="btn-group"> <div id="{{ name }}_parse_type" class="btn-group">

View File

@@ -202,6 +202,7 @@
.at-Row-toggle { .at-Row-toggle {
align-self: flex-start; align-self: flex-start;
margin-right: @at-space-4x; margin-right: @at-space-4x;
margin-left: 15px;
} }
.at-Row-actions { .at-Row-actions {
@@ -385,29 +386,3 @@
margin-right: @at-margin-right-list-row-item-inline-label; margin-right: @at-margin-right-list-row-item-inline-label;
} }
} }
@media screen and (max-width: @at-breakpoint-instances-wrap) {
.at-Row-items--instances {
margin-bottom: @at-padding-bottom-instances-wrap;
}
}
@media screen and (max-width: @at-breakpoint-compact-list) {
.at-Row-actions {
align-items: center;
}
.at-RowAction {
margin: @at-margin-list-row-action-mobile;
}
.at-RowItem--inline {
display: flex;
margin-right: inherit;
.at-RowItem-label {
width: @at-width-list-row-item-label;
margin-right: inherit;
}
}
}

View File

@@ -1,9 +1,11 @@
.CapacityAdjuster { .CapacityAdjuster {
margin-right: @at-space-4x; margin-right: @at-space-4x;
margin-top: 15px;
margin-left: -10px;
position: relative; position: relative;
&-valueLabel { &-valueLabel {
bottom: @at-space-5x; top: -10px;
color: @at-color-body-text; color: @at-color-body-text;
font-size: @at-font-size; font-size: @at-font-size;
position: absolute; position: absolute;

View File

@@ -5,6 +5,8 @@ capacity-bar {
font-size: @at-font-size; font-size: @at-font-size;
min-width: 100px; min-width: 100px;
white-space: nowrap; white-space: nowrap;
margin-top: 5px;
margin-bottom: 5px;
.CapacityBar { .CapacityBar {
background-color: @default-bg; background-color: @default-bg;
@@ -42,12 +44,4 @@ capacity-bar {
text-align: right; text-align: right;
text-transform: uppercase; text-transform: uppercase;
} }
.Capacity-details--percentage {
width: 40px;
}
&:only-child {
margin-right: 50px;
}
} }

View File

@@ -12,6 +12,7 @@ function AddContainerGroupController(ToJSON, $scope, $state, models, strings, i1
vm.form = instanceGroup.createFormSchema('post'); vm.form = instanceGroup.createFormSchema('post');
vm.form.name.required = true; vm.form.name.required = true;
delete vm.form.name.help_text;
vm.form.credential = { vm.form.credential = {
type: 'field', type: 'field',
@@ -22,6 +23,7 @@ function AddContainerGroupController(ToJSON, $scope, $state, models, strings, i1
vm.form.credential._route = "instanceGroups.addContainerGroup.credentials"; vm.form.credential._route = "instanceGroups.addContainerGroup.credentials";
vm.form.credential._model = credential; vm.form.credential._model = credential;
vm.form.credential._placeholder = strings.get('container.CREDENTIAL_PLACEHOLDER'); vm.form.credential._placeholder = strings.get('container.CREDENTIAL_PLACEHOLDER');
vm.form.credential.help_text = strings.get('container.CREDENTIAL_HELP_TEXT');
vm.form.credential.required = true; vm.form.credential.required = true;
vm.form.extraVars = { vm.form.extraVars = {
@@ -29,6 +31,7 @@ function AddContainerGroupController(ToJSON, $scope, $state, models, strings, i1
value: DataSet.data.actions.POST.pod_spec_override.default, value: DataSet.data.actions.POST.pod_spec_override.default,
name: 'extraVars', name: 'extraVars',
toggleLabel: strings.get('container.POD_SPEC_TOGGLE'), toggleLabel: strings.get('container.POD_SPEC_TOGGLE'),
tooltip: strings.get('container.EXTRA_VARS_HELP_TEXT')
}; };
vm.tab = { vm.tab = {

View File

@@ -1,8 +1,8 @@
<div ui-view="credentials"></div> <div ui-view="credentials"></div>
<a class="containerGroups-messageBar-link" href="https://docs.ansible.com/ansible-tower/latest/html/administration/external_execution_envs.html#container-group-considerations" target="_blank" style="color: white"> <a class="containerGroups-messageBar-link" href="https://docs.ansible.com/ansible-tower/latest/html/administration/external_execution_envs.html#container-groups" target="_blank" style="color: white">
<div class="Section-messageBar"> <div class="Section-messageBar">
<i class="Section-messageBar-warning fa fa-warning"></i> <i class="Section-messageBar-warning fa fa-warning"></i>
<span class="Section-messageBar-text">This feature is tech preview, and is subject to change in a future release. Click here for documentation.</span> <span class="Section-messageBar-text">This feature is currently in tech preview and is subject to change in a future release. Click here for documentation.</span>
</div> </div>
</a> </a>
<at-panel> <at-panel>
@@ -34,6 +34,7 @@
variables="vm.form.extraVars.value" variables="vm.form.extraVars.value"
label="{{ vm.form.extraVars.label }}" label="{{ vm.form.extraVars.label }}"
name="{{ vm.form.extraVars.name }}" name="{{ vm.form.extraVars.name }}"
tooltip="{{ vm.form.extraVars.tooltip }}"
> >
</at-code-mirror> </at-code-mirror>
</div> </div>

View File

@@ -27,6 +27,7 @@ function EditContainerGroupController($rootScope, $scope, $state, models, string
vm.switchDisabled = false; vm.switchDisabled = false;
vm.form.disabled = !instanceGroup.has('options', 'actions.PUT'); vm.form.disabled = !instanceGroup.has('options', 'actions.PUT');
vm.form.name.required = true; vm.form.name.required = true;
delete vm.form.name.help_text;
vm.form.credential = { vm.form.credential = {
type: 'field', type: 'field',
label: i18n._('Credential'), label: i18n._('Credential'),
@@ -38,6 +39,7 @@ function EditContainerGroupController($rootScope, $scope, $state, models, string
vm.form.credential._displayValue = EditContainerGroupDataset.data.summary_fields.credential.name; vm.form.credential._displayValue = EditContainerGroupDataset.data.summary_fields.credential.name;
vm.form.credential.required = true; vm.form.credential.required = true;
vm.form.credential._value = EditContainerGroupDataset.data.summary_fields.credential.id; vm.form.credential._value = EditContainerGroupDataset.data.summary_fields.credential.id;
vm.form.credential.help_text = strings.get('container.CREDENTIAL_HELP_TEXT');
vm.tab = { vm.tab = {
details: { details: {
@@ -59,7 +61,8 @@ function EditContainerGroupController($rootScope, $scope, $state, models, string
label: strings.get('container.POD_SPEC_LABEL'), label: strings.get('container.POD_SPEC_LABEL'),
value: EditContainerGroupDataset.data.pod_spec_override || "---", value: EditContainerGroupDataset.data.pod_spec_override || "---",
name: 'extraVars', name: 'extraVars',
disabled: true disabled: true,
tooltip: strings.get('container.EXTRA_VARS_HELP_TEXT')
}; };
vm.switchDisabled = true; vm.switchDisabled = true;
} else { } else {
@@ -67,7 +70,8 @@ function EditContainerGroupController($rootScope, $scope, $state, models, string
label: strings.get('container.POD_SPEC_LABEL'), label: strings.get('container.POD_SPEC_LABEL'),
value: EditContainerGroupDataset.data.pod_spec_override || instanceGroup.model.OPTIONS.actions.PUT.pod_spec_override.default, value: EditContainerGroupDataset.data.pod_spec_override || instanceGroup.model.OPTIONS.actions.PUT.pod_spec_override.default,
name: 'extraVars', name: 'extraVars',
toggleLabel: strings.get('container.POD_SPEC_TOGGLE') toggleLabel: strings.get('container.POD_SPEC_TOGGLE'),
tooltip: strings.get('container.EXTRA_VARS_HELP_TEXT')
}; };
} }

View File

@@ -1,135 +1,100 @@
.InstanceGroups { .at-Row--instances {
.at-Row-actions{ .at-Row-content {
justify-content: flex-start; flex-wrap: nowrap;
width: 300px;
& > capacity-bar:only-child{
margin-left: 0px;
margin-top: 5px
}
}
.at-RowAction{
margin: 0;
}
.at-Row-links{
justify-content: flex-start;
} }
.BreadCrumb-menuLinkImage:hover { .at-Row-toggle {
color: @default-link; align-self: auto;
flex: initial;
} }
.List-details { .at-Row-itemGroup {
align-self: flex-end;
color: @default-interface-txt;
display: flex; display: flex;
flex: 0 0 auto; flex: 1;
font-size: 12px; flex-wrap: wrap;
margin-right:20px;
text-transform: uppercase;
} }
.Capacity-details { .at-Row-items--instances {
display: flex; display: flex;
margin-right: 20px; flex-wrap: wrap;
align-items: center; align-items: center;
align-content: center;
.Capacity-details--label { flex: 1;
color: @default-interface-txt;
margin: 0 10px 0 0;
width: 100px;
}
} }
.RunningJobs-details { .at-RowItem--isHeader {
align-items: center; min-width: 250px;
display: flex;
.RunningJobs-details--label {
margin: 0 10px 0 0;
}
} }
.List-tableCell--capacityColumn { .at-Row-items--capacity {
display: flex; display: flex;
height: 40px; flex-wrap: wrap;
align-items: center; align-items: center;
} }
.List-noItems { .CapacityAdjuster {
margin-top: 20px; padding-bottom: 15px;
}
.List-tableRow .List-titleBadge {
margin: 0 0 0 5px;
}
.Panel-docsLink {
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
padding: 7px;
background: @at-white;
border-radius: @at-border-radius;
height: 30px;
width: 30px;
margin: 0 20px 0 auto;
i {
font-size: @at-font-size-icon;
color: @at-gray-646972;
}
}
.Panel-docsLink:hover {
background-color: @at-blue;
i {
color: @at-white;
}
}
.at-Row-toggle{
margin-top: 20px;
padding-left: 15px;
}
.ContainerGroups-codeMirror{
margin-bottom: 10px;
}
.at-Row-container{
flex-wrap: wrap;
}
.containerGroups-messageBar-link:hover{
text-decoration: underline;
}
@media screen and (max-width: 1060px) and (min-width: 769px){
.at-Row-links {
justify-content: flex-start;
flex-wrap: wrap;
}
}
@media screen and (min-width: 1061px){
.at-Row-actions{
justify-content: flex-end;
& > capacity-bar:only-child {
margin-right: 30px;
}
}
.instanceGroupsList-details{
display: flex;
}
.at-Row-links {
justify-content: flex-end;
display: flex;
width: 445px;
}
} }
} }
.at-Row--instanceGroups {
.at-Row-content {
flex-wrap: nowrap;
}
.at-Row-itemGroup {
display: flex;
flex: 1;
flex-wrap: wrap;
}
.at-Row-items--instanceGroups {
display: flex;
flex-wrap: wrap;
align-items: center;
flex: 1;
max-width: 100%;
}
.at-Row-itemHeaderGroup {
min-width: 320px;
display: flex;
}
.at-Row-items--capacity {
display: flex;
flex-wrap: wrap;
align-items: center;
margin-right: 5px;
min-width: 215px;
}
.at-Row--instanceSpacer {
width: 140px;
}
.at-Row--capacitySpacer {
flex: .6;
}
.at-Row-actions {
min-width: 50px;
}
}
@media screen and (max-width: 1260px) {
.at-Row--instances .at-Row-items--capacity {
flex: 1
}
.at-Row--instances .CapacityAdjuster {
padding-bottom: 5px;
}
}
@media screen and (max-width: 600px) {
.at-Row--instanceGroups .at-Row-itemHeaderGroup,
.at-Row--instanceGroups .at-Row-itemGroup {
max-width: 270px;
}
}

View File

@@ -72,8 +72,9 @@ function InstanceGroupsStrings(BaseString) {
CREDENTIAL_PLACEHOLDER: t.s('SELECT A CREDENTIAL'), CREDENTIAL_PLACEHOLDER: t.s('SELECT A CREDENTIAL'),
POD_SPEC_LABEL: t.s('Pod Spec Override'), POD_SPEC_LABEL: t.s('Pod Spec Override'),
BADGE_TEXT: t.s('Container Group'), BADGE_TEXT: t.s('Container Group'),
POD_SPEC_TOGGLE: t.s('Customize Pod Spec') POD_SPEC_TOGGLE: t.s('Customize Pod Spec'),
CREDENTIAL_HELP_TEXT: t.s('Credential to authenticate with Kubernetes or OpenShift.  Must be of type \"Kubernetes/OpenShift API Bearer Token\”.'),
EXTRA_VARS_HELP_TEXT: t.s('Field for passing a custom Kubernetes or OpenShift Pod specification.')
}; };
} }

View File

@@ -43,35 +43,45 @@
</at-list-toolbar> </at-list-toolbar>
<at-list results='vm.instances'> <at-list results='vm.instances'>
<at-row ng-repeat="instance in vm.instances" <at-row ng-repeat="instance in vm.instances"
ng-class="{'at-Row--active': (instance.id === vm.activeId)}"> ng-class="{'at-Row--active': (instance.id === vm.activeId)}"
class="at-Row--instances">
<div class="at-Row-toggle"> <div class="at-Row-toggle">
<at-switch on-toggle="vm.toggle(instance)" switch-on="instance.enabled" switch-disabled="vm.rowAction.toggle._disabled"></at-switch> <at-switch on-toggle="vm.toggle(instance)" switch-on="instance.enabled" switch-disabled="vm.rowAction.toggle._disabled"></at-switch>
</div> </div>
<div class="at-Row-itemGroup">
<div class="at-Row-items at-Row-items--instances"> <div class="at-Row-items at-Row-items--instances">
<at-row-item <at-row-item
header-value="{{ instance.hostname }}" header-value="{{ instance.hostname }}"
header-tag="{{ instance.managed_by_policy ? '' : vm.strings.get('list.MANUAL') }}"> header-tag="{{ instance.managed_by_policy ? '' : vm.strings.get('list.MANUAL') }}">
</at-row-item> </at-row-item>
<at-row-item <div class="at-Row-nonHeaderItems">
label-value="{{:: vm.strings.get('list.ROW_ITEM_LABEL_RUNNING_JOBS') }}" <at-row-item
label-state="instanceGroups.instanceJobs({instance_group_id: {{vm.instance_group_id}}, instance_id: {{instance.id}}, job_search: {status__in: ['running,waiting']}})" label-value="{{:: vm.strings.get('list.ROW_ITEM_LABEL_RUNNING_JOBS') }}"
value="{{ instance.jobs_running }}" label-state="instanceGroups.instanceJobs({instance_group_id: {{vm.instance_group_id}}, instance_id: {{instance.id}}, job_search: {status__in: ['running,waiting']}})"
inline="true" value="{{ instance.jobs_running }}"
badge="true"> inline="true"
</at-row-item> badge="true">
<at-row-item </at-row-item>
label-value="{{:: vm.strings.get('list.ROW_ITEM_LABEL_TOTAL_JOBS') }}" <at-row-item
label-state="instanceGroups.instanceJobs({instance_group_id: {{vm.instance_group_id}}, instance_id: {{instance.id}}})" label-value="{{:: vm.strings.get('list.ROW_ITEM_LABEL_TOTAL_JOBS') }}"
value="{{ instance.jobs_total }}" label-state="instanceGroups.instanceJobs({instance_group_id: {{vm.instance_group_id}}, instance_id: {{instance.id}}})"
inline="true" value="{{ instance.jobs_total }}"
badge="true"> inline="true"
</at-row-item> badge="true">
</div> </at-row-item>
</div>
<div class="at-Row-actions"> </div>
<capacity-adjuster state="instance" disabled="{{vm.rowAction.capacity_adjustment._disabled}}"></capacity-adjuster> <div class="at-Row-items--capacity">
<capacity-bar label-value="{{:: vm.strings.get('list.ROW_ITEM_LABEL_USED_CAPACITY') }}" capacity="instance.consumed_capacity" total-capacity="instance.capacity"></capacity-bar> <capacity-adjuster
state="instance"
disabled="{{vm.rowAction.capacity_adjustment._disabled}}">
</capacity-adjuster>
<capacity-bar
label-value="{{:: vm.strings.get('list.ROW_ITEM_LABEL_USED_CAPACITY') }}"
capacity="instance.consumed_capacity"
total-capacity="instance.capacity">
</capacity-bar>
</div>
</div> </div>
</at-row> </at-row>
</at-list> </at-list>

View File

@@ -41,10 +41,11 @@
</at-list-toolbar> </at-list-toolbar>
<at-list results="instance_groups"> <at-list results="instance_groups">
<at-row ng-repeat="instance_group in instance_groups" <at-row ng-repeat="instance_group in instance_groups"
ng-class="{'at-Row--active': (instance_group.id === vm.activeId)}" > ng-class="{'at-Row--active': (instance_group.id === vm.activeId)}"
<div class="at-Row-items"> class="at-Row--instanceGroups">
<div class="at-Row-container"> <div class="at-Row-itemGroup">
<div class="at-Row-content"> <div class="at-Row-items at-Row-items--instanceGroups">
<div class="at-Row-itemHeaderGroup">
<at-row-item <at-row-item
ng-if="!instance_group.credential" ng-if="!instance_group.credential"
header-value="{{ instance_group.name }}" header-value="{{ instance_group.name }}"
@@ -67,23 +68,14 @@
</div> </div>
</div> </div>
<div class="at-RowItem--labels" ng-if="!instance_group.credential"> <div class="at-RowItem--labels" ng-if="!instance_group.credential">
<div class="LabelList-tagContainer"> <div class="LabelList-tagContainer">
<div class="LabelList-tag" ng-class="{'LabelList-tag--deletable' : (showDelete && template.summary_fields.user_capabilities.edit)}"> <div class="LabelList-tag" ng-class="{'LabelList-tag--deletable' : (showDelete && template.summary_fields.user_capabilities.edit)}">
<span class="LabelList-name">{{vm.strings.get('instance.BADGE_TEXT') }}</span> <span class="LabelList-name">{{vm.strings.get('instance.BADGE_TEXT') }}</span>
</div>
</div> </div>
</div> </div>
</div>
</div> </div>
<div class="instanceGroupsList-details"> <div class="at-Row-nonHeaderItems">
<div class="at-Row-links">
<at-row-item
ng-if="!instance_group.credential"
label-value="{{:: vm.strings.get('list.ROW_ITEM_LABEL_INSTANCES') }}"
label-state="instanceGroups.instances({instance_group_id: {{ instance_group.id }}})"
value="{{ instance_group.instances }}"
inline="true"
badge="true">
</at-row-item>
<at-row-item <at-row-item
label-value="{{:: vm.strings.get('list.ROW_ITEM_LABEL_RUNNING_JOBS') }}" label-value="{{:: vm.strings.get('list.ROW_ITEM_LABEL_RUNNING_JOBS') }}"
label-state="instanceGroups.jobs({instance_group_id: {{ instance_group.id }}, job_search: {status__in: ['running,waiting']}})" label-state="instanceGroups.jobs({instance_group_id: {{ instance_group.id }}, job_search: {status__in: ['running,waiting']}})"
@@ -98,14 +90,38 @@
inline="true" inline="true"
badge="true"> badge="true">
</at-row-item> </at-row-item>
</div> <at-row-item
<div class="at-Row-actions" > ng-if="!instance_group.credential"
<capacity-bar ng-show="!instance_group.credential" label-value="{{:: vm.strings.get('list.ROW_ITEM_LABEL_USED_CAPACITY') }}" capacity="instance_group.consumed_capacity" total-capacity="instance_group.capacity"></capacity-bar> label-value="{{:: vm.strings.get('list.ROW_ITEM_LABEL_INSTANCES') }}"
<at-row-action icon="fa-trash" ng-click="vm.deleteInstanceGroup(instance_group)" ng-if="vm.rowAction.trash(instance_group)"> label-state="instanceGroups.instances({instance_group_id: {{ instance_group.id }}})"
</at-row-action> value="{{ instance_group.instances }}"
</div> inline="true"
badge="true">
</at-row-item>
<div
ng-if="instance_group.credential"
class="at-Row--instanceSpacer">
</div>
</div> </div>
</div> </div>
<div class="at-Row-items--capacity" ng-if="!instance_group.credential">
<capacity-bar
label-value="{{:: vm.strings.get('list.ROW_ITEM_LABEL_USED_CAPACITY') }}"
capacity="instance_group.consumed_capacity"
total-capacity="instance_group.capacity">
</capacity-bar>
</div>
<div
ng-if="instance_group.credential"
class="at-Row--capacitySpacer">
</div>
</div>
<div class="at-Row-actions" >
<at-row-action
icon="fa-trash"
ng-click="vm.deleteInstanceGroup(instance_group)"
ng-if="vm.rowAction.trash(instance_group)">
</at-row-action>
</div> </div>
</at-row> </at-row>
</at-list> </at-list>