diff options
Diffstat (limited to 'app/assets')
-rw-r--r-- | app/assets/images/ci_favicons/canary/favicon_status_scheduled.ico | bin | 0 -> 5430 bytes | |||
-rw-r--r-- | app/assets/images/ci_favicons/favicon_status_scheduled.png | bin | 0 -> 1072 bytes | |||
-rw-r--r-- | app/assets/javascripts/lib/utils/datetime_utility.js | 21 | ||||
-rw-r--r-- | app/assets/javascripts/pipelines/components/pipelines_actions.vue | 38 | ||||
-rw-r--r-- | app/assets/javascripts/pipelines/components/pipelines_table_row.vue | 14 | ||||
-rw-r--r-- | app/assets/stylesheets/framework/buttons.scss | 4 | ||||
-rw-r--r-- | app/assets/stylesheets/framework/icons.scss | 1 | ||||
-rw-r--r-- | app/assets/stylesheets/pages/pipelines.scss | 1 | ||||
-rw-r--r-- | app/assets/stylesheets/pages/status.scss | 1 |
9 files changed, 73 insertions, 7 deletions
diff --git a/app/assets/images/ci_favicons/canary/favicon_status_scheduled.ico b/app/assets/images/ci_favicons/canary/favicon_status_scheduled.ico Binary files differnew file mode 100644 index 00000000000..5444b8e41dc --- /dev/null +++ b/app/assets/images/ci_favicons/canary/favicon_status_scheduled.ico diff --git a/app/assets/images/ci_favicons/favicon_status_scheduled.png b/app/assets/images/ci_favicons/favicon_status_scheduled.png Binary files differnew file mode 100644 index 00000000000..d198c255fdd --- /dev/null +++ b/app/assets/images/ci_favicons/favicon_status_scheduled.png diff --git a/app/assets/javascripts/lib/utils/datetime_utility.js b/app/assets/javascripts/lib/utils/datetime_utility.js index 1f66fa811ea..833dbefd3dc 100644 --- a/app/assets/javascripts/lib/utils/datetime_utility.js +++ b/app/assets/javascripts/lib/utils/datetime_utility.js @@ -370,3 +370,24 @@ window.gl.utils = { getTimeago, localTimeAgo, }; + +/** + * Formats milliseconds as timestamp (e.g. 01:02:03). + * This takes durations longer than a day into account (e.g. two days would be 48:00:00). + * + * @param milliseconds + * @returns {string} + */ +export const formatTime = milliseconds => { + const remainingSeconds = Math.floor(milliseconds / 1000) % 60; + const remainingMinutes = Math.floor(milliseconds / 1000 / 60) % 60; + const remainingHours = Math.floor(milliseconds / 1000 / 60 / 60); + let formattedTime = ''; + if (remainingHours < 10) formattedTime += '0'; + formattedTime += `${remainingHours}:`; + if (remainingMinutes < 10) formattedTime += '0'; + formattedTime += `${remainingMinutes}:`; + if (remainingSeconds < 10) formattedTime += '0'; + formattedTime += remainingSeconds; + return formattedTime; +}; diff --git a/app/assets/javascripts/pipelines/components/pipelines_actions.vue b/app/assets/javascripts/pipelines/components/pipelines_actions.vue index 017dd560621..16e69759091 100644 --- a/app/assets/javascripts/pipelines/components/pipelines_actions.vue +++ b/app/assets/javascripts/pipelines/components/pipelines_actions.vue @@ -1,4 +1,6 @@ <script> +import { s__, sprintf } from '~/locale'; +import { formatTime } from '~/lib/utils/datetime_utility'; import eventHub from '../event_hub'; import icon from '../../vue_shared/components/icon.vue'; import tooltip from '../../vue_shared/directives/tooltip'; @@ -22,10 +24,24 @@ export default { }; }, methods: { - onClickAction(endpoint) { + onClickAction(action) { + if (action.scheduled_at) { + const confirmationMessage = sprintf( + s__( + "DelayedJobs|Are you sure you want to run %{jobName} immediately? This job will run automatically after it's timer finishes.", + ), + { jobName: action.name }, + ); + // https://gitlab.com/gitlab-org/gitlab-ce/issues/52156 + // eslint-disable-next-line no-alert + if (!window.confirm(confirmationMessage)) { + return; + } + } + this.isLoading = true; - eventHub.$emit('postAction', endpoint); + eventHub.$emit('postAction', action.path); }, isActionDisabled(action) { @@ -35,6 +51,11 @@ export default { return !action.playable; }, + + remainingTime(action) { + const remainingMilliseconds = new Date(action.scheduled_at).getTime() - Date.now(); + return formatTime(Math.max(0, remainingMilliseconds)); + }, }, }; </script> @@ -63,17 +84,24 @@ export default { <ul class="dropdown-menu dropdown-menu-right"> <li - v-for="(action, i) in actions" - :key="i" + v-for="action in actions" + :key="action.path" > <button :class="{ disabled: isActionDisabled(action) }" :disabled="isActionDisabled(action)" type="button" class="js-pipeline-action-link no-btn btn" - @click="onClickAction(action.path)" + @click="onClickAction(action)" > {{ action.name }} + <span + v-if="action.scheduled_at" + class="pull-right" + > + <icon name="clock" /> + {{ remainingTime(action) }} + </span> </button> </li> </ul> diff --git a/app/assets/javascripts/pipelines/components/pipelines_table_row.vue b/app/assets/javascripts/pipelines/components/pipelines_table_row.vue index a39cc265601..09ee190b8ca 100644 --- a/app/assets/javascripts/pipelines/components/pipelines_table_row.vue +++ b/app/assets/javascripts/pipelines/components/pipelines_table_row.vue @@ -59,6 +59,16 @@ export default { }; }, computed: { + actions() { + if (!this.pipeline || !this.pipeline.details) { + return []; + } + const { details } = this.pipeline; + return [ + ...(details.manual_actions || []), + ...(details.scheduled_actions || []), + ]; + }, /** * If provided, returns the commit tag. * Needed to render the commit component column. @@ -321,8 +331,8 @@ export default { > <div class="btn-group table-action-buttons"> <pipelines-actions-component - v-if="pipeline.details.manual_actions.length" - :actions="pipeline.details.manual_actions" + v-if="actions.length > 0" + :actions="actions" /> <pipelines-artifacts-component diff --git a/app/assets/stylesheets/framework/buttons.scss b/app/assets/stylesheets/framework/buttons.scss index 686ce0c63a4..c4296c7a88a 100644 --- a/app/assets/stylesheets/framework/buttons.scss +++ b/app/assets/stylesheets/framework/buttons.scss @@ -360,6 +360,10 @@ i { color: $gl-text-color-secondary; } + + svg { + fill: $gl-text-color-secondary; + } } .clone-dropdown-btn a { diff --git a/app/assets/stylesheets/framework/icons.scss b/app/assets/stylesheets/framework/icons.scss index f002edced8a..abd26e38d18 100644 --- a/app/assets/stylesheets/framework/icons.scss +++ b/app/assets/stylesheets/framework/icons.scss @@ -64,6 +64,7 @@ } } +.ci-status-icon-scheduled, .ci-status-icon-manual { svg { fill: $gl-text-color; diff --git a/app/assets/stylesheets/pages/pipelines.scss b/app/assets/stylesheets/pages/pipelines.scss index 8bb8b83dc5e..14395cc59b0 100644 --- a/app/assets/stylesheets/pages/pipelines.scss +++ b/app/assets/stylesheets/pages/pipelines.scss @@ -760,6 +760,7 @@ } &.ci-status-icon-canceled, + &.ci-status-icon-scheduled, &.ci-status-icon-disabled, &.ci-status-icon-not-found, &.ci-status-icon-manual { diff --git a/app/assets/stylesheets/pages/status.scss b/app/assets/stylesheets/pages/status.scss index 620297e589d..7d59dd3b5d1 100644 --- a/app/assets/stylesheets/pages/status.scss +++ b/app/assets/stylesheets/pages/status.scss @@ -27,6 +27,7 @@ &.ci-canceled, &.ci-disabled, + &.ci-scheduled, &.ci-manual { color: $gl-text-color; border-color: $gl-text-color; |