diff options
Diffstat (limited to 'app/assets/javascripts')
12 files changed, 115 insertions, 101 deletions
diff --git a/app/assets/javascripts/ide/components/error_message.vue b/app/assets/javascripts/ide/components/error_message.vue index 500f6737839..d36adbd798e 100644 --- a/app/assets/javascripts/ide/components/error_message.vue +++ b/app/assets/javascripts/ide/components/error_message.vue @@ -1,9 +1,10 @@ <script> import { mapActions } from 'vuex'; -import { GlLoadingIcon } from '@gitlab/ui'; +import { GlAlert, GlLoadingIcon } from '@gitlab/ui'; export default { components: { + GlAlert, GlLoadingIcon, }, props: { @@ -17,9 +18,14 @@ export default { isLoading: false, }; }, + computed: { + canDismiss() { + return !this.message.action; + }, + }, methods: { ...mapActions(['setErrorMessage']), - clickAction() { + doAction() { if (this.isLoading) return; this.isLoading = true; @@ -33,28 +39,23 @@ export default { this.isLoading = false; }); }, - clickFlash() { - if (!this.message.action) { - this.setErrorMessage(null); - } + dismiss() { + this.setErrorMessage(null); }, }, }; </script> <template> - <div class="flash-container flash-container-page" @click="clickFlash"> - <div class="flash-alert" data-qa-selector="flash_alert"> - <span v-html="message.text"> </span> - <button - v-if="message.action" - type="button" - class="flash-action text-white p-0 border-top-0 border-right-0 border-left-0 bg-transparent" - @click.stop.prevent="clickAction" - > - {{ message.actionText }} - <gl-loading-icon v-show="isLoading" inline /> - </button> - </div> - </div> + <gl-alert + data-qa-selector="flash_alert" + variant="danger" + :dismissible="canDismiss" + :primary-button-text="message.actionText" + @dismiss="dismiss" + @primaryAction="doAction" + > + <span v-html="message.text"></span> + <gl-loading-icon v-show="isLoading" inline class="vertical-align-middle ml-1" /> + </gl-alert> </template> diff --git a/app/assets/javascripts/pipelines/components/graph/graph_component.vue b/app/assets/javascripts/pipelines/components/graph/graph_component.vue index 4dc6e51d2fc..6a836adba01 100644 --- a/app/assets/javascripts/pipelines/components/graph/graph_component.vue +++ b/app/assets/javascripts/pipelines/components/graph/graph_component.vue @@ -1,5 +1,4 @@ <script> -import _ from 'underscore'; import { GlLoadingIcon } from '@gitlab/ui'; import StageColumnComponent from './stage_column_component.vue'; import GraphMixin from '../../mixins/graph_component_mixin'; @@ -70,7 +69,7 @@ export default { expandedTriggeredBy() { return ( this.pipeline.triggered_by && - _.isArray(this.pipeline.triggered_by) && + Array.isArray(this.pipeline.triggered_by) && this.pipeline.triggered_by.find(el => el.isExpanded) ); }, diff --git a/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue b/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue index db7714808fd..3d3dabbdf22 100644 --- a/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue +++ b/app/assets/javascripts/pipelines/components/graph/stage_column_component.vue @@ -1,5 +1,5 @@ <script> -import _ from 'underscore'; +import { isEmpty, escape as esc } from 'lodash'; import stageColumnMixin from '../../mixins/stage_column_mixin'; import JobItem from './job_item.vue'; import JobGroupDropdown from './job_group_dropdown.vue'; @@ -39,12 +39,12 @@ export default { }, computed: { hasAction() { - return !_.isEmpty(this.action); + return !isEmpty(this.action); }, }, methods: { groupId(group) { - return `ci-badge-${_.escape(group.name)}`; + return `ci-badge-${esc(group.name)}`; }, pipelineActionRequestComplete() { this.$emit('refreshPipelineGraph'); diff --git a/app/assets/javascripts/pipelines/components/pipeline_stop_modal.vue b/app/assets/javascripts/pipelines/components/pipeline_stop_modal.vue index 6ca96bbba5e..f604edd8859 100644 --- a/app/assets/javascripts/pipelines/components/pipeline_stop_modal.vue +++ b/app/assets/javascripts/pipelines/components/pipeline_stop_modal.vue @@ -1,5 +1,5 @@ <script> -import _ from 'underscore'; +import { isEmpty } from 'lodash'; import { GlLink } from '@gitlab/ui'; import DeprecatedModal2 from '~/vue_shared/components/deprecated_modal_2.vue'; import CiIcon from '~/vue_shared/components/ci_icon.vue'; @@ -43,7 +43,7 @@ export default { ); }, hasRef() { - return !_.isEmpty(this.pipeline.ref); + return !isEmpty(this.pipeline.ref); }, }, methods: { diff --git a/app/assets/javascripts/pipelines/components/pipeline_url.vue b/app/assets/javascripts/pipelines/components/pipeline_url.vue index 743c3ea271d..0c9d242f509 100644 --- a/app/assets/javascripts/pipelines/components/pipeline_url.vue +++ b/app/assets/javascripts/pipelines/components/pipeline_url.vue @@ -1,11 +1,11 @@ <script> import { GlLink, GlTooltipDirective } from '@gitlab/ui'; -import _ from 'underscore'; +import { escape } from 'lodash'; import { __, sprintf } from '~/locale'; import popover from '~/vue_shared/directives/popover'; const popoverTitle = sprintf( - _.escape( + escape( __( `This pipeline makes use of a predefined CI/CD configuration enabled by %{strongStart}Auto DevOps.%{strongEnd}`, ), @@ -49,7 +49,7 @@ export default { href="${this.autoDevopsHelpPath}" target="_blank" rel="noopener noreferrer nofollow"> - ${_.escape(__('Learn more about Auto DevOps'))} + ${escape(__('Learn more about Auto DevOps'))} </a>`, }; }, diff --git a/app/assets/javascripts/pipelines/components/pipelines.vue b/app/assets/javascripts/pipelines/components/pipelines.vue index d730ef41b1a..accd6bf71f4 100644 --- a/app/assets/javascripts/pipelines/components/pipelines.vue +++ b/app/assets/javascripts/pipelines/components/pipelines.vue @@ -1,5 +1,5 @@ <script> -import _ from 'underscore'; +import { isEqual } from 'lodash'; import { __, sprintf, s__ } from '../../locale'; import createFlash from '../../flash'; import PipelinesService from '../services/pipelines_service'; @@ -218,7 +218,7 @@ export default { successCallback(resp) { // Because we are polling & the user is interacting verify if the response received // matches the last request made - if (_.isEqual(resp.config.params, this.requestData)) { + if (isEqual(resp.config.params, this.requestData)) { this.store.storeCount(resp.data.count); this.store.storePagination(resp.headers); this.setCommonData(resp.data.pipelines); diff --git a/app/assets/javascripts/pipelines/mixins/graph_component_mixin.js b/app/assets/javascripts/pipelines/mixins/graph_component_mixin.js index f383a4b3368..53b7a174517 100644 --- a/app/assets/javascripts/pipelines/mixins/graph_component_mixin.js +++ b/app/assets/javascripts/pipelines/mixins/graph_component_mixin.js @@ -1,4 +1,4 @@ -import _ from 'underscore'; +import { escape } from 'lodash'; export default { props: { @@ -18,7 +18,7 @@ export default { }, methods: { capitalizeStageName(name) { - const escapedName = _.escape(name); + const escapedName = escape(name); return escapedName.charAt(0).toUpperCase() + escapedName.slice(1); }, isFirstColumn(index) { diff --git a/app/assets/javascripts/pipelines/stores/pipeline_store.js b/app/assets/javascripts/pipelines/stores/pipeline_store.js index 441c9f3c25f..69e3579a3c7 100644 --- a/app/assets/javascripts/pipelines/stores/pipeline_store.js +++ b/app/assets/javascripts/pipelines/stores/pipeline_store.js @@ -1,5 +1,4 @@ import Vue from 'vue'; -import _ from 'underscore'; export default class PipelineStore { constructor() { @@ -61,7 +60,7 @@ export default class PipelineStore { Vue.set(newPipeline, 'isLoading', false); if (newPipeline.triggered_by) { - if (!_.isArray(newPipeline.triggered_by)) { + if (!Array.isArray(newPipeline.triggered_by)) { Object.assign(newPipeline, { triggered_by: [newPipeline.triggered_by] }); } this.parseTriggeredByPipelines(oldPipeline, newPipeline.triggered_by[0]); diff --git a/app/assets/javascripts/serverless/components/function_details.vue b/app/assets/javascripts/serverless/components/function_details.vue index d542dad8119..2ac57ac5bcb 100644 --- a/app/assets/javascripts/serverless/components/function_details.vue +++ b/app/assets/javascripts/serverless/components/function_details.vue @@ -1,5 +1,5 @@ <script> -import _ from 'underscore'; +import { isString } from 'lodash'; import { mapState, mapActions, mapGetters } from 'vuex'; import PodBox from './pod_box.vue'; import Url from './url.vue'; @@ -42,7 +42,7 @@ export default { return this.func.name; }, description() { - return _.isString(this.func.description) ? this.func.description : ''; + return isString(this.func.description) ? this.func.description : ''; }, funcUrl() { return this.func.url; diff --git a/app/assets/javascripts/serverless/components/function_row.vue b/app/assets/javascripts/serverless/components/function_row.vue index dca0e01b250..bbafdd7f8f1 100644 --- a/app/assets/javascripts/serverless/components/function_row.vue +++ b/app/assets/javascripts/serverless/components/function_row.vue @@ -1,5 +1,5 @@ <script> -import _ from 'underscore'; +import { isString } from 'lodash'; import Timeago from '~/vue_shared/components/time_ago_tooltip.vue'; import Url from './url.vue'; import { visitUrl } from '~/lib/utils/url_utility'; @@ -20,7 +20,7 @@ export default { return this.func.name; }, description() { - if (!_.isString(this.func.description)) { + if (!isString(this.func.description)) { return ''; } diff --git a/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker.vue b/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker.vue index 932ca8e002e..9ac687f5e2c 100644 --- a/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker.vue +++ b/app/assets/javascripts/vue_shared/components/date_time_picker/date_time_picker.vue @@ -5,6 +5,7 @@ import { __, sprintf } from '~/locale'; import { convertToFixedRange, isEqualTimeRanges, findTimeRange } from '~/lib/utils/datetime_range'; import Icon from '~/vue_shared/components/icon.vue'; +import TooltipOnTruncate from '~/vue_shared/components/tooltip_on_truncate.vue'; import DateTimePickerInput from './date_time_picker_input.vue'; import { defaultTimeRanges, @@ -24,6 +25,7 @@ const events = { export default { components: { Icon, + TooltipOnTruncate, DateTimePickerInput, GlFormGroup, GlButton, @@ -149,61 +151,68 @@ export default { }; </script> <template> - <gl-dropdown - :text="timeWindowText" - class="date-time-picker" - menu-class="date-time-picker-menu" - v-bind="$attrs" - toggle-class="w-100 text-truncate" + <tooltip-on-truncate + :title="timeWindowText" + :truncate-target="elem => elem.querySelector('.date-time-picker-toggle')" + placement="top" + class="d-inline-block" > - <div class="d-flex justify-content-between gl-p-2"> - <gl-form-group - :label="__('Custom range')" - label-for="custom-from-time" - label-class="gl-pb-1" - class="custom-time-range-form-group col-md-7 gl-pl-1 gl-pr-0 m-0" - > - <div class="gl-pt-2"> - <date-time-picker-input - id="custom-time-from" - v-model="startInput" - :label="__('From')" - :state="startInputValid" - /> - <date-time-picker-input - id="custom-time-to" - v-model="endInput" - :label="__('To')" - :state="endInputValid" - /> - </div> - <gl-form-group> - <gl-button @click="closeDropdown">{{ __('Cancel') }}</gl-button> - <gl-button variant="success" :disabled="!isValid" @click="setFixedRange()"> - {{ __('Apply') }} - </gl-button> + <gl-dropdown + :text="timeWindowText" + v-bind="$attrs" + class="date-time-picker w-100" + menu-class="date-time-picker-menu" + toggle-class="date-time-picker-toggle text-truncate" + > + <div class="d-flex justify-content-between gl-p-2"> + <gl-form-group + :label="__('Custom range')" + label-for="custom-from-time" + label-class="gl-pb-1" + class="custom-time-range-form-group col-md-7 gl-pl-1 gl-pr-0 m-0" + > + <div class="gl-pt-2"> + <date-time-picker-input + id="custom-time-from" + v-model="startInput" + :label="__('From')" + :state="startInputValid" + /> + <date-time-picker-input + id="custom-time-to" + v-model="endInput" + :label="__('To')" + :state="endInputValid" + /> + </div> + <gl-form-group> + <gl-button @click="closeDropdown">{{ __('Cancel') }}</gl-button> + <gl-button variant="success" :disabled="!isValid" @click="setFixedRange()"> + {{ __('Apply') }} + </gl-button> + </gl-form-group> </gl-form-group> - </gl-form-group> - <gl-form-group label-for="group-id-dropdown" class="col-md-5 gl-pl-1 gl-pr-1 m-0"> - <template #label> - <span class="gl-pl-5">{{ __('Quick range') }}</span> - </template> + <gl-form-group label-for="group-id-dropdown" class="col-md-5 gl-pl-1 gl-pr-1 m-0"> + <template #label> + <span class="gl-pl-5">{{ __('Quick range') }}</span> + </template> - <gl-dropdown-item - v-for="(option, index) in options" - :key="index" - :active="isOptionActive(option)" - active-class="active" - @click="setQuickRange(option)" - > - <icon - name="mobile-issue-close" - class="align-bottom" - :class="{ invisible: !isOptionActive(option) }" - /> - {{ option.label }} - </gl-dropdown-item> - </gl-form-group> - </div> - </gl-dropdown> + <gl-dropdown-item + v-for="(option, index) in options" + :key="index" + :active="isOptionActive(option)" + active-class="active" + @click="setQuickRange(option)" + > + <icon + name="mobile-issue-close" + class="align-bottom" + :class="{ invisible: !isOptionActive(option) }" + /> + {{ option.label }} + </gl-dropdown-item> + </gl-form-group> + </div> + </gl-dropdown> + </tooltip-on-truncate> </template> diff --git a/app/assets/javascripts/vue_shared/components/tooltip_on_truncate.vue b/app/assets/javascripts/vue_shared/components/tooltip_on_truncate.vue index 69eb791d195..4ea3d162da2 100644 --- a/app/assets/javascripts/vue_shared/components/tooltip_on_truncate.vue +++ b/app/assets/javascripts/vue_shared/components/tooltip_on_truncate.vue @@ -1,5 +1,5 @@ <script> -import _ from 'underscore'; +import { isFunction } from 'lodash'; import tooltip from '../directives/tooltip'; export default { @@ -28,16 +28,18 @@ export default { showTooltip: false, }; }, + watch: { + title() { + // Wait on $nextTick in case of slot width changes + this.$nextTick(this.updateTooltip); + }, + }, mounted() { - const target = this.selectTarget(); - - if (target && target.scrollWidth > target.offsetWidth) { - this.showTooltip = true; - } + this.updateTooltip(); }, methods: { selectTarget() { - if (_.isFunction(this.truncateTarget)) { + if (isFunction(this.truncateTarget)) { return this.truncateTarget(this.$el); } else if (this.truncateTarget === 'child') { return this.$el.childNodes[0]; @@ -45,6 +47,10 @@ export default { return this.$el; }, + updateTooltip() { + const target = this.selectTarget(); + this.showTooltip = Boolean(target && target.scrollWidth > target.offsetWidth); + }, }, }; </script> |