2020-06-23 00:09:42 +05:30
|
|
|
<script>
|
|
|
|
import { debounce } from 'lodash';
|
|
|
|
import { mapActions, mapState, mapGetters } from 'vuex';
|
|
|
|
import {
|
2020-07-28 23:09:34 +05:30
|
|
|
GlButton,
|
2020-06-23 00:09:42 +05:30
|
|
|
GlIcon,
|
|
|
|
GlDeprecatedButton,
|
|
|
|
GlDropdown,
|
|
|
|
GlDropdownItem,
|
|
|
|
GlDropdownHeader,
|
|
|
|
GlDropdownDivider,
|
2020-07-28 23:09:34 +05:30
|
|
|
GlNewDropdown,
|
|
|
|
GlNewDropdownDivider,
|
|
|
|
GlNewDropdownItem,
|
2020-06-23 00:09:42 +05:30
|
|
|
GlModal,
|
|
|
|
GlLoadingIcon,
|
|
|
|
GlSearchBoxByType,
|
|
|
|
GlModalDirective,
|
|
|
|
GlTooltipDirective,
|
|
|
|
} from '@gitlab/ui';
|
|
|
|
import { s__ } from '~/locale';
|
|
|
|
import CustomMetricsFormFields from '~/custom_metrics/components/custom_metrics_form_fields.vue';
|
|
|
|
import { mergeUrlParams, redirectTo } from '~/lib/utils/url_utility';
|
|
|
|
import invalidUrl from '~/lib/utils/invalid_url';
|
|
|
|
import Icon from '~/vue_shared/components/icon.vue';
|
|
|
|
import DateTimePicker from '~/vue_shared/components/date_time_picker/date_time_picker.vue';
|
|
|
|
|
|
|
|
import DashboardsDropdown from './dashboards_dropdown.vue';
|
2020-07-28 23:09:34 +05:30
|
|
|
import RefreshButton from './refresh_button.vue';
|
|
|
|
import CreateDashboardModal from './create_dashboard_modal.vue';
|
|
|
|
import DuplicateDashboardModal from './duplicate_dashboard_modal.vue';
|
2020-06-23 00:09:42 +05:30
|
|
|
|
|
|
|
import TrackEventDirective from '~/vue_shared/directives/track_event';
|
|
|
|
import { getAddMetricTrackingOptions, timeRangeToUrl } from '../utils';
|
|
|
|
import { timeRanges } from '~/vue_shared/constants';
|
|
|
|
import { timezones } from '../format_date';
|
|
|
|
|
|
|
|
export default {
|
|
|
|
components: {
|
|
|
|
Icon,
|
2020-07-28 23:09:34 +05:30
|
|
|
GlButton,
|
2020-06-23 00:09:42 +05:30
|
|
|
GlIcon,
|
|
|
|
GlDeprecatedButton,
|
|
|
|
GlDropdown,
|
|
|
|
GlLoadingIcon,
|
|
|
|
GlDropdownItem,
|
|
|
|
GlDropdownHeader,
|
|
|
|
GlDropdownDivider,
|
2020-07-28 23:09:34 +05:30
|
|
|
GlNewDropdown,
|
|
|
|
GlNewDropdownDivider,
|
|
|
|
GlNewDropdownItem,
|
2020-06-23 00:09:42 +05:30
|
|
|
GlSearchBoxByType,
|
|
|
|
GlModal,
|
|
|
|
CustomMetricsFormFields,
|
|
|
|
|
|
|
|
DateTimePicker,
|
|
|
|
DashboardsDropdown,
|
2020-07-28 23:09:34 +05:30
|
|
|
RefreshButton,
|
|
|
|
DuplicateDashboardModal,
|
|
|
|
CreateDashboardModal,
|
2020-06-23 00:09:42 +05:30
|
|
|
},
|
|
|
|
directives: {
|
|
|
|
GlModal: GlModalDirective,
|
|
|
|
GlTooltip: GlTooltipDirective,
|
|
|
|
TrackEvent: TrackEventDirective,
|
|
|
|
},
|
|
|
|
props: {
|
|
|
|
defaultBranch: {
|
|
|
|
type: String,
|
|
|
|
required: true,
|
|
|
|
},
|
|
|
|
rearrangePanelsAvailable: {
|
|
|
|
type: Boolean,
|
|
|
|
required: false,
|
|
|
|
default: false,
|
|
|
|
},
|
|
|
|
customMetricsAvailable: {
|
|
|
|
type: Boolean,
|
|
|
|
required: false,
|
|
|
|
default: false,
|
|
|
|
},
|
|
|
|
customMetricsPath: {
|
|
|
|
type: String,
|
|
|
|
required: false,
|
|
|
|
default: invalidUrl,
|
|
|
|
},
|
|
|
|
validateQueryPath: {
|
|
|
|
type: String,
|
|
|
|
required: false,
|
|
|
|
default: invalidUrl,
|
|
|
|
},
|
|
|
|
externalDashboardUrl: {
|
|
|
|
type: String,
|
|
|
|
required: false,
|
|
|
|
default: '',
|
|
|
|
},
|
|
|
|
hasMetrics: {
|
|
|
|
type: Boolean,
|
|
|
|
required: false,
|
|
|
|
default: true,
|
|
|
|
},
|
|
|
|
isRearrangingPanels: {
|
|
|
|
type: Boolean,
|
|
|
|
required: true,
|
|
|
|
},
|
|
|
|
selectedTimeRange: {
|
|
|
|
type: Object,
|
|
|
|
required: true,
|
|
|
|
},
|
2020-07-28 23:09:34 +05:30
|
|
|
addDashboardDocumentationPath: {
|
|
|
|
type: String,
|
|
|
|
required: true,
|
|
|
|
},
|
2020-06-23 00:09:42 +05:30
|
|
|
},
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
formIsValid: null,
|
|
|
|
};
|
|
|
|
},
|
|
|
|
computed: {
|
|
|
|
...mapState('monitoringDashboard', [
|
2020-07-28 23:09:34 +05:30
|
|
|
'emptyState',
|
2020-06-23 00:09:42 +05:30
|
|
|
'environmentsLoading',
|
|
|
|
'currentEnvironmentName',
|
|
|
|
'isUpdatingStarredValue',
|
|
|
|
'dashboardTimezone',
|
2020-07-28 23:09:34 +05:30
|
|
|
'projectPath',
|
|
|
|
'canAccessOperationsSettings',
|
|
|
|
'operationsSettingsPath',
|
|
|
|
'currentDashboard',
|
2020-06-23 00:09:42 +05:30
|
|
|
]),
|
|
|
|
...mapGetters('monitoringDashboard', ['selectedDashboard', 'filteredEnvironments']),
|
2020-07-28 23:09:34 +05:30
|
|
|
isOutOfTheBoxDashboard() {
|
|
|
|
return this.selectedDashboard?.out_of_the_box_dashboard;
|
|
|
|
},
|
|
|
|
shouldShowEmptyState() {
|
|
|
|
return Boolean(this.emptyState);
|
|
|
|
},
|
2020-06-23 00:09:42 +05:30
|
|
|
shouldShowEnvironmentsDropdownNoMatchedMsg() {
|
|
|
|
return !this.environmentsLoading && this.filteredEnvironments.length === 0;
|
|
|
|
},
|
|
|
|
addingMetricsAvailable() {
|
|
|
|
return (
|
|
|
|
this.customMetricsAvailable &&
|
2020-07-28 23:09:34 +05:30
|
|
|
!this.shouldShowEmptyState &&
|
2020-06-23 00:09:42 +05:30
|
|
|
// Custom metrics only avaialble on system dashboards because
|
|
|
|
// they are stored in the database. This can be improved. See:
|
|
|
|
// https://gitlab.com/gitlab-org/gitlab/-/issues/28241
|
|
|
|
this.selectedDashboard?.system_dashboard
|
|
|
|
);
|
|
|
|
},
|
|
|
|
showRearrangePanelsBtn() {
|
2020-07-28 23:09:34 +05:30
|
|
|
return !this.shouldShowEmptyState && this.rearrangePanelsAvailable;
|
2020-06-23 00:09:42 +05:30
|
|
|
},
|
|
|
|
displayUtc() {
|
|
|
|
return this.dashboardTimezone === timezones.UTC;
|
|
|
|
},
|
2020-07-28 23:09:34 +05:30
|
|
|
shouldShowActionsMenu() {
|
|
|
|
return Boolean(this.projectPath);
|
|
|
|
},
|
|
|
|
shouldShowSettingsButton() {
|
|
|
|
return this.canAccessOperationsSettings && this.operationsSettingsPath;
|
|
|
|
},
|
2020-06-23 00:09:42 +05:30
|
|
|
},
|
|
|
|
methods: {
|
2020-07-28 23:09:34 +05:30
|
|
|
...mapActions('monitoringDashboard', ['filterEnvironments', 'toggleStarredValue']),
|
2020-06-23 00:09:42 +05:30
|
|
|
selectDashboard(dashboard) {
|
2020-07-28 23:09:34 +05:30
|
|
|
// Once the sidebar See metrics link is updated to the new URL,
|
|
|
|
// this sort of hardcoding will not be necessary.
|
|
|
|
// https://gitlab.com/gitlab-org/gitlab/-/issues/229277
|
|
|
|
const baseURL = `${this.projectPath}/-/metrics`;
|
|
|
|
const dashboardPath = encodeURIComponent(
|
|
|
|
dashboard.out_of_the_box_dashboard ? dashboard.path : dashboard.display_name,
|
|
|
|
);
|
|
|
|
redirectTo(`${baseURL}/${dashboardPath}`);
|
2020-06-23 00:09:42 +05:30
|
|
|
},
|
|
|
|
debouncedEnvironmentsSearch: debounce(function environmentsSearchOnInput(searchTerm) {
|
|
|
|
this.filterEnvironments(searchTerm);
|
|
|
|
}, 500),
|
|
|
|
onDateTimePickerInput(timeRange) {
|
|
|
|
redirectTo(timeRangeToUrl(timeRange));
|
|
|
|
},
|
|
|
|
onDateTimePickerInvalid() {
|
|
|
|
this.$emit('dateTimePickerInvalid');
|
|
|
|
},
|
|
|
|
|
|
|
|
toggleRearrangingPanels() {
|
|
|
|
this.$emit('setRearrangingPanels', !this.isRearrangingPanels);
|
|
|
|
},
|
|
|
|
setFormValidity(isValid) {
|
|
|
|
this.formIsValid = isValid;
|
|
|
|
},
|
|
|
|
hideAddMetricModal() {
|
|
|
|
this.$refs.addMetricModal.hide();
|
|
|
|
},
|
|
|
|
getAddMetricTrackingOptions,
|
|
|
|
submitCustomMetricsForm() {
|
|
|
|
this.$refs.customMetricsForm.submit();
|
|
|
|
},
|
2020-07-28 23:09:34 +05:30
|
|
|
getEnvironmentPath(environment) {
|
|
|
|
// Once the sidebar See metrics link is updated to the new URL,
|
|
|
|
// this sort of hardcoding will not be necessary.
|
|
|
|
// https://gitlab.com/gitlab-org/gitlab/-/issues/229277
|
|
|
|
const baseURL = `${this.projectPath}/-/metrics`;
|
|
|
|
const dashboardPath = encodeURIComponent(this.currentDashboard || '');
|
|
|
|
// The environment_metrics_spec.rb requires the URL to not have
|
|
|
|
// slashes. Hence, this additional check.
|
|
|
|
const url = dashboardPath ? `${baseURL}/${dashboardPath}` : baseURL;
|
|
|
|
return mergeUrlParams({ environment }, url);
|
|
|
|
},
|
2020-06-23 00:09:42 +05:30
|
|
|
},
|
2020-07-28 23:09:34 +05:30
|
|
|
modalIds: {
|
|
|
|
addMetric: 'addMetric',
|
|
|
|
createDashboard: 'createDashboard',
|
|
|
|
duplicateDashboard: 'duplicateDashboard',
|
2020-06-23 00:09:42 +05:30
|
|
|
},
|
|
|
|
i18n: {
|
|
|
|
starDashboard: s__('Metrics|Star dashboard'),
|
|
|
|
unstarDashboard: s__('Metrics|Unstar dashboard'),
|
2020-07-28 23:09:34 +05:30
|
|
|
addMetric: s__('Metrics|Add metric'),
|
2020-06-23 00:09:42 +05:30
|
|
|
},
|
|
|
|
timeRanges,
|
|
|
|
};
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<template>
|
|
|
|
<div ref="prometheusGraphsHeader">
|
2020-07-28 23:09:34 +05:30
|
|
|
<div class="mb-2 mr-2 d-flex d-sm-block">
|
2020-06-23 00:09:42 +05:30
|
|
|
<dashboards-dropdown
|
|
|
|
id="monitor-dashboards-dropdown"
|
|
|
|
data-qa-selector="dashboards_filter_dropdown"
|
|
|
|
class="flex-grow-1"
|
|
|
|
toggle-class="dropdown-menu-toggle"
|
|
|
|
:default-branch="defaultBranch"
|
2020-07-28 23:09:34 +05:30
|
|
|
:modal-id="$options.modalIds.duplicateDashboard"
|
2020-06-23 00:09:42 +05:30
|
|
|
@selectDashboard="selectDashboard"
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
|
2020-07-28 23:09:34 +05:30
|
|
|
<span aria-hidden="true" class="gl-pl-3 border-left gl-mb-3 d-none d-sm-block"></span>
|
|
|
|
|
2020-06-23 00:09:42 +05:30
|
|
|
<div class="mb-2 pr-2 d-flex d-sm-block">
|
|
|
|
<gl-dropdown
|
|
|
|
id="monitor-environments-dropdown"
|
|
|
|
ref="monitorEnvironmentsDropdown"
|
|
|
|
class="flex-grow-1"
|
|
|
|
data-qa-selector="environments_dropdown"
|
|
|
|
toggle-class="dropdown-menu-toggle"
|
|
|
|
menu-class="monitor-environment-dropdown-menu"
|
|
|
|
:text="currentEnvironmentName"
|
|
|
|
>
|
|
|
|
<div class="d-flex flex-column overflow-hidden">
|
|
|
|
<gl-dropdown-header class="monitor-environment-dropdown-header text-center">
|
|
|
|
{{ __('Environment') }}
|
|
|
|
</gl-dropdown-header>
|
|
|
|
<gl-dropdown-divider />
|
|
|
|
<gl-search-box-by-type
|
|
|
|
ref="monitorEnvironmentsDropdownSearch"
|
|
|
|
class="m-2"
|
|
|
|
@input="debouncedEnvironmentsSearch"
|
|
|
|
/>
|
|
|
|
<gl-loading-icon
|
|
|
|
v-if="environmentsLoading"
|
|
|
|
ref="monitorEnvironmentsDropdownLoading"
|
|
|
|
:inline="true"
|
|
|
|
/>
|
|
|
|
<div v-else class="flex-fill overflow-auto">
|
|
|
|
<gl-dropdown-item
|
|
|
|
v-for="environment in filteredEnvironments"
|
|
|
|
:key="environment.id"
|
|
|
|
:active="environment.name === currentEnvironmentName"
|
|
|
|
active-class="is-active"
|
2020-07-28 23:09:34 +05:30
|
|
|
:href="getEnvironmentPath(environment.id)"
|
2020-06-23 00:09:42 +05:30
|
|
|
>{{ environment.name }}</gl-dropdown-item
|
|
|
|
>
|
|
|
|
</div>
|
|
|
|
<div
|
|
|
|
v-show="shouldShowEnvironmentsDropdownNoMatchedMsg"
|
|
|
|
ref="monitorEnvironmentsDropdownMsg"
|
|
|
|
class="text-secondary no-matches-message"
|
|
|
|
>
|
|
|
|
{{ __('No matching results') }}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</gl-dropdown>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="mb-2 pr-2 d-flex d-sm-block">
|
|
|
|
<date-time-picker
|
|
|
|
ref="dateTimePicker"
|
|
|
|
class="flex-grow-1 show-last-dropdown"
|
|
|
|
data-qa-selector="range_picker_dropdown"
|
|
|
|
:value="selectedTimeRange"
|
|
|
|
:options="$options.timeRanges"
|
|
|
|
:utc="displayUtc"
|
|
|
|
@input="onDateTimePickerInput"
|
|
|
|
@invalid="onDateTimePickerInvalid"
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="mb-2 pr-2 d-flex d-sm-block">
|
2020-07-28 23:09:34 +05:30
|
|
|
<refresh-button />
|
2020-06-23 00:09:42 +05:30
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="flex-grow-1"></div>
|
|
|
|
|
|
|
|
<div class="d-sm-flex">
|
|
|
|
<div v-if="selectedDashboard" class="mb-2 mr-2 d-flex">
|
|
|
|
<!--
|
|
|
|
wrapper for tooltip as button can be `disabled`
|
|
|
|
https://bootstrap-vue.org/docs/components/tooltip#disabled-elements
|
|
|
|
-->
|
|
|
|
<div
|
|
|
|
v-gl-tooltip
|
|
|
|
class="flex-grow-1"
|
|
|
|
:title="
|
|
|
|
selectedDashboard.starred ? $options.i18n.unstarDashboard : $options.i18n.starDashboard
|
|
|
|
"
|
|
|
|
>
|
|
|
|
<gl-deprecated-button
|
|
|
|
ref="toggleStarBtn"
|
|
|
|
class="w-100"
|
|
|
|
:disabled="isUpdatingStarredValue"
|
|
|
|
variant="default"
|
|
|
|
@click="toggleStarredValue()"
|
|
|
|
>
|
|
|
|
<gl-icon :name="selectedDashboard.starred ? 'star' : 'star-o'" />
|
|
|
|
</gl-deprecated-button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div v-if="showRearrangePanelsBtn" class="mb-2 mr-2 d-flex">
|
|
|
|
<gl-deprecated-button
|
|
|
|
:pressed="isRearrangingPanels"
|
|
|
|
variant="default"
|
|
|
|
class="flex-grow-1 js-rearrange-button"
|
|
|
|
@click="toggleRearrangingPanels"
|
|
|
|
>
|
|
|
|
{{ __('Arrange charts') }}
|
|
|
|
</gl-deprecated-button>
|
|
|
|
</div>
|
|
|
|
<div v-if="addingMetricsAvailable" class="mb-2 mr-2 d-flex d-sm-block">
|
|
|
|
<gl-deprecated-button
|
|
|
|
ref="addMetricBtn"
|
2020-07-28 23:09:34 +05:30
|
|
|
v-gl-modal="$options.modalIds.addMetric"
|
2020-06-23 00:09:42 +05:30
|
|
|
variant="outline-success"
|
|
|
|
data-qa-selector="add_metric_button"
|
|
|
|
class="flex-grow-1"
|
|
|
|
>
|
2020-07-28 23:09:34 +05:30
|
|
|
{{ $options.i18n.addMetric }}
|
2020-06-23 00:09:42 +05:30
|
|
|
</gl-deprecated-button>
|
|
|
|
<gl-modal
|
|
|
|
ref="addMetricModal"
|
2020-07-28 23:09:34 +05:30
|
|
|
:modal-id="$options.modalIds.addMetric"
|
|
|
|
:title="$options.i18n.addMetric"
|
2020-06-23 00:09:42 +05:30
|
|
|
>
|
|
|
|
<form ref="customMetricsForm" :action="customMetricsPath" method="post">
|
|
|
|
<custom-metrics-form-fields
|
|
|
|
:validate-query-path="validateQueryPath"
|
|
|
|
form-operation="post"
|
|
|
|
@formValidation="setFormValidity"
|
|
|
|
/>
|
|
|
|
</form>
|
|
|
|
<div slot="modal-footer">
|
|
|
|
<gl-deprecated-button @click="hideAddMetricModal">
|
|
|
|
{{ __('Cancel') }}
|
|
|
|
</gl-deprecated-button>
|
|
|
|
<gl-deprecated-button
|
|
|
|
ref="submitCustomMetricsFormBtn"
|
|
|
|
v-track-event="getAddMetricTrackingOptions()"
|
|
|
|
:disabled="!formIsValid"
|
|
|
|
variant="success"
|
|
|
|
@click="submitCustomMetricsForm"
|
|
|
|
>
|
|
|
|
{{ __('Save changes') }}
|
|
|
|
</gl-deprecated-button>
|
|
|
|
</div>
|
|
|
|
</gl-modal>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div
|
|
|
|
v-if="selectedDashboard && selectedDashboard.can_edit"
|
|
|
|
class="mb-2 mr-2 d-flex d-sm-block"
|
|
|
|
>
|
|
|
|
<gl-deprecated-button
|
|
|
|
class="flex-grow-1 js-edit-link"
|
|
|
|
:href="selectedDashboard.project_blob_path"
|
|
|
|
data-qa-selector="edit_dashboard_button"
|
|
|
|
>
|
|
|
|
{{ __('Edit dashboard') }}
|
|
|
|
</gl-deprecated-button>
|
|
|
|
</div>
|
|
|
|
|
2020-07-28 23:09:34 +05:30
|
|
|
<div
|
|
|
|
v-if="externalDashboardUrl && externalDashboardUrl.length"
|
|
|
|
class="mb-2 mr-2 d-flex d-sm-block"
|
|
|
|
>
|
2020-06-23 00:09:42 +05:30
|
|
|
<gl-deprecated-button
|
|
|
|
class="flex-grow-1 js-external-dashboard-link"
|
|
|
|
variant="primary"
|
|
|
|
:href="externalDashboardUrl"
|
|
|
|
target="_blank"
|
|
|
|
rel="noopener noreferrer"
|
|
|
|
>
|
|
|
|
{{ __('View full dashboard') }} <icon name="external-link" />
|
|
|
|
</gl-deprecated-button>
|
|
|
|
</div>
|
2020-07-28 23:09:34 +05:30
|
|
|
|
|
|
|
<!-- This separator should be displayed only if at least one of the action menu or settings button are displayed -->
|
|
|
|
<span
|
|
|
|
v-if="shouldShowActionsMenu || shouldShowSettingsButton"
|
|
|
|
aria-hidden="true"
|
|
|
|
class="gl-pl-3 border-left gl-mb-3 d-none d-sm-block"
|
|
|
|
></span>
|
|
|
|
|
|
|
|
<div v-if="shouldShowActionsMenu" class="gl-mb-3 gl-mr-3 d-flex d-sm-block">
|
|
|
|
<gl-new-dropdown
|
|
|
|
v-gl-tooltip
|
|
|
|
right
|
|
|
|
class="gl-flex-grow-1"
|
|
|
|
data-testid="actions-menu"
|
|
|
|
:title="s__('Metrics|Create dashboard')"
|
|
|
|
:icon="'plus-square'"
|
|
|
|
>
|
|
|
|
<gl-new-dropdown-item
|
|
|
|
v-gl-modal="$options.modalIds.createDashboard"
|
|
|
|
data-testid="action-create-dashboard"
|
|
|
|
>{{ s__('Metrics|Create new dashboard') }}</gl-new-dropdown-item
|
|
|
|
>
|
|
|
|
|
|
|
|
<create-dashboard-modal
|
|
|
|
data-testid="create-dashboard-modal"
|
|
|
|
:add-dashboard-documentation-path="addDashboardDocumentationPath"
|
|
|
|
:modal-id="$options.modalIds.createDashboard"
|
|
|
|
:project-path="projectPath"
|
|
|
|
/>
|
|
|
|
|
|
|
|
<template v-if="isOutOfTheBoxDashboard">
|
|
|
|
<gl-new-dropdown-divider />
|
|
|
|
<gl-new-dropdown-item
|
|
|
|
ref="duplicateDashboardItem"
|
|
|
|
v-gl-modal="$options.modalIds.duplicateDashboard"
|
|
|
|
data-testid="action-duplicate-dashboard"
|
|
|
|
>
|
|
|
|
{{ s__('Metrics|Duplicate current dashboard') }}
|
|
|
|
</gl-new-dropdown-item>
|
|
|
|
</template>
|
|
|
|
</gl-new-dropdown>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div v-if="shouldShowSettingsButton" class="mb-2 mr-2 d-flex d-sm-block">
|
|
|
|
<gl-button
|
|
|
|
v-gl-tooltip
|
|
|
|
data-testid="metrics-settings-button"
|
|
|
|
icon="settings"
|
|
|
|
:href="operationsSettingsPath"
|
|
|
|
:title="s__('Metrics|Metrics Settings')"
|
|
|
|
/>
|
|
|
|
</div>
|
2020-06-23 00:09:42 +05:30
|
|
|
</div>
|
2020-07-28 23:09:34 +05:30
|
|
|
<duplicate-dashboard-modal
|
|
|
|
:default-branch="defaultBranch"
|
|
|
|
:modal-id="$options.modalIds.duplicateDashboard"
|
|
|
|
@dashboardDuplicated="selectDashboard"
|
|
|
|
/>
|
2020-06-23 00:09:42 +05:30
|
|
|
</div>
|
|
|
|
</template>
|