summaryrefslogtreecommitdiff
path: root/app/assets
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets')
-rw-r--r--app/assets/javascripts/dispatcher.js2
-rw-r--r--app/assets/javascripts/pipeline_schedules/pipeline_schedule_form_bundle.js3
-rw-r--r--app/assets/javascripts/pipeline_schedules/setup_pipeline_variable_list.js71
-rw-r--r--app/assets/stylesheets/framework/variables.scss8
-rw-r--r--app/assets/stylesheets/pages/pipeline_schedules.scss81
5 files changed, 164 insertions, 1 deletions
diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js
index 8f716696605..ae19592ecbe 100644
--- a/app/assets/javascripts/dispatcher.js
+++ b/app/assets/javascripts/dispatcher.js
@@ -322,7 +322,7 @@ import PerformanceBar from './performance_bar';
new gl.Members();
new UsersSelect();
break;
- case 'projects:settings:members:show':
+ case 'projects:project_members:index':
new gl.MemberExpirationDate('.js-access-expiration-date-groups');
new GroupsSelect();
new gl.MemberExpirationDate();
diff --git a/app/assets/javascripts/pipeline_schedules/pipeline_schedule_form_bundle.js b/app/assets/javascripts/pipeline_schedules/pipeline_schedule_form_bundle.js
index b424e7f205d..50c725aa3d5 100644
--- a/app/assets/javascripts/pipeline_schedules/pipeline_schedule_form_bundle.js
+++ b/app/assets/javascripts/pipeline_schedules/pipeline_schedule_form_bundle.js
@@ -3,6 +3,7 @@ import Translate from '../vue_shared/translate';
import intervalPatternInput from './components/interval_pattern_input.vue';
import TimezoneDropdown from './components/timezone_dropdown';
import TargetBranchDropdown from './components/target_branch_dropdown';
+import { setupPipelineVariableList } from './setup_pipeline_variable_list';
Vue.use(Translate);
@@ -39,4 +40,6 @@ document.addEventListener('DOMContentLoaded', () => {
gl.timezoneDropdown = new TimezoneDropdown();
gl.targetBranchDropdown = new TargetBranchDropdown();
gl.pipelineScheduleFieldErrors = new gl.GlFieldErrors(formElement);
+
+ setupPipelineVariableList($('.js-pipeline-variable-list'));
});
diff --git a/app/assets/javascripts/pipeline_schedules/setup_pipeline_variable_list.js b/app/assets/javascripts/pipeline_schedules/setup_pipeline_variable_list.js
new file mode 100644
index 00000000000..644efd10509
--- /dev/null
+++ b/app/assets/javascripts/pipeline_schedules/setup_pipeline_variable_list.js
@@ -0,0 +1,71 @@
+function insertRow($row) {
+ const $rowClone = $row.clone();
+ $rowClone.removeAttr('data-is-persisted');
+ $rowClone.find('input, textarea').val('');
+ $row.after($rowClone);
+}
+
+function removeRow($row) {
+ const isPersisted = gl.utils.convertPermissionToBoolean($row.attr('data-is-persisted'));
+
+ if (isPersisted) {
+ $row.hide();
+ $row
+ .find('.js-destroy-input')
+ .val(1);
+ } else {
+ $row.remove();
+ }
+}
+
+function checkIfRowTouched($row) {
+ return $row.find('.js-user-input').toArray().some(el => $(el).val().length > 0);
+}
+
+function setupPipelineVariableList(parent = document) {
+ const $parent = $(parent);
+
+ $parent.on('click', '.js-row-remove-button', (e) => {
+ const $row = $(e.currentTarget).closest('.js-row');
+ removeRow($row);
+
+ e.preventDefault();
+ });
+
+ // Remove any empty rows except the last r
+ $parent.on('blur', '.js-user-input', (e) => {
+ const $row = $(e.currentTarget).closest('.js-row');
+
+ const isTouched = checkIfRowTouched($row);
+ if ($row.is(':not(:last-child)') && !isTouched) {
+ removeRow($row);
+ }
+ });
+
+ // Always make sure there is an empty last row
+ $parent.on('input', '.js-user-input', () => {
+ const $lastRow = $parent.find('.js-row').last();
+
+ const isTouched = checkIfRowTouched($lastRow);
+ if (isTouched) {
+ insertRow($lastRow);
+ }
+ });
+
+ // Clear out the empty last row so it
+ // doesn't get submitted and throw validation errors
+ $parent.closest('form').on('submit', () => {
+ const $lastRow = $parent.find('.js-row').last();
+
+ const isTouched = checkIfRowTouched($lastRow);
+ if (!isTouched) {
+ $lastRow.find('input, textarea').attr('name', '');
+ }
+ });
+}
+
+export {
+ setupPipelineVariableList,
+ insertRow,
+ removeRow,
+};
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index 2e4b1280a97..8b4ea0fbff2 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -153,6 +153,7 @@ $code_line_height: 1.6;
* Padding
*/
$gl-padding: 16px;
+$gl-col-padding: 15px;
$gl-btn-padding: 10px;
$gl-input-padding: 10px;
$gl-vert-padding: 6px;
@@ -443,6 +444,7 @@ $logs-p-color: #333;
/*
* Forms
*/
+$input-height: 34px;
$input-danger-bg: #f2dede;
$input-danger-border: $red-400;
$input-group-addon-bg: #f7f8fa;
@@ -575,6 +577,12 @@ $stage-hover-border: #d1e7fc;
$action-icon-color: #d6d6d6;
/*
+Pipeline Schedules
+*/
+$pipeline-variable-remove-button-width: calc(1em + #{2 * $gl-padding});
+
+
+/*
Filtered Search
*/
$filter-name-resting-color: #f8f8f8;
diff --git a/app/assets/stylesheets/pages/pipeline_schedules.scss b/app/assets/stylesheets/pages/pipeline_schedules.scss
index 595eb40fec7..dc719a6ba94 100644
--- a/app/assets/stylesheets/pages/pipeline_schedules.scss
+++ b/app/assets/stylesheets/pages/pipeline_schedules.scss
@@ -74,3 +74,84 @@
margin-right: 3px;
}
}
+
+.pipeline-variable-list {
+ margin-left: 0;
+ margin-bottom: 0;
+ padding-left: 0;
+ list-style: none;
+ clear: both;
+}
+
+.pipeline-variable-row {
+ display: flex;
+ align-items: flex-end;
+
+ &:not(:last-child) {
+ margin-bottom: $gl-btn-padding;
+ }
+
+ @media (max-width: $screen-sm-max) {
+ padding-right: $gl-col-padding;
+ }
+
+ &:last-child {
+ & .pipeline-variable-row-remove-button {
+ display: none;
+ }
+
+ @media (max-width: $screen-sm-max) {
+ & .pipeline-variable-value-input {
+ margin-right: $pipeline-variable-remove-button-width;
+ }
+ }
+
+ @media (max-width: $screen-xs-max) {
+ .pipeline-variable-row-body {
+ margin-right: $pipeline-variable-remove-button-width;
+ }
+ }
+ }
+}
+
+.pipeline-variable-row-body {
+ display: flex;
+ width: calc(75% - #{$gl-col-padding});
+ padding-left: $gl-col-padding;
+
+ @media (max-width: $screen-sm-max) {
+ width: 100%;
+ }
+
+ @media (max-width: $screen-xs-max) {
+ display: block;
+ }
+}
+
+.pipeline-variable-key-input {
+ margin-right: $gl-btn-padding;
+
+ @media (max-width: $screen-xs-max) {
+ margin-bottom: $gl-btn-padding;
+ }
+}
+
+.pipeline-variable-row-remove-button {
+ flex-shrink: 0;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: $pipeline-variable-remove-button-width;
+ height: $input-height;
+ padding: 0;
+ background: transparent;
+ border: 0;
+ color: $gl-text-color-secondary;
+ @include transition(color);
+
+ &:hover,
+ &:focus {
+ outline: none;
+ color: $gl-text-color;
+ }
+}