diff options
author | Clement Ho <clemmakesapps@gmail.com> | 2019-05-07 17:46:34 +0000 |
---|---|---|
committer | Clement Ho <clemmakesapps@gmail.com> | 2019-05-07 17:46:34 +0000 |
commit | 12752f3d15a7e47ae2f12cee5489542c57e4f28c (patch) | |
tree | e6e33b48b829abd4957fb8d4d4c0072d28dae56f | |
parent | f6ca3b1ad980a82afa0e7c4caf075f4159a4352a (diff) | |
parent | 78d3f94cee23318abdffc39ce3c604eafbd2ecd9 (diff) | |
download | gitlab-ce-12752f3d15a7e47ae2f12cee5489542c57e4f28c.tar.gz |
Merge branch 'ce-4452-in-line-chart-designer-mvc' into 'master'
Backport EE Add custom metrics form to dashboard to CE
See merge request gitlab-org/gitlab-ce!27868
-rw-r--r-- | app/assets/javascripts/monitoring/components/dashboard.vue | 168 | ||||
-rw-r--r-- | app/assets/stylesheets/framework/common.scss | 24 | ||||
-rw-r--r-- | app/assets/stylesheets/framework/variables.scss | 8 | ||||
-rw-r--r-- | locale/gitlab.pot | 3 | ||||
-rw-r--r-- | spec/javascripts/monitoring/dashboard_spec.js | 7 |
5 files changed, 150 insertions, 60 deletions
diff --git a/app/assets/javascripts/monitoring/components/dashboard.vue b/app/assets/javascripts/monitoring/components/dashboard.vue index a2bf58d007c..ff1e1805948 100644 --- a/app/assets/javascripts/monitoring/components/dashboard.vue +++ b/app/assets/javascripts/monitoring/components/dashboard.vue @@ -1,5 +1,12 @@ <script> -import { GlButton, GlDropdown, GlDropdownItem, GlLink } from '@gitlab/ui'; +import { + GlButton, + GlDropdown, + GlDropdownItem, + GlModal, + GlModalDirective, + GlLink, +} from '@gitlab/ui'; import _ from 'underscore'; import { s__ } from '~/locale'; import Icon from '~/vue_shared/components/icon.vue'; @@ -27,8 +34,11 @@ export default { GlDropdown, GlDropdownItem, GlLink, + GlModal, + }, + directives: { + GlModalDirective, }, - props: { externalDashboardPath: { type: String, @@ -102,6 +112,19 @@ export default { type: Boolean, required: true, }, + customMetricsAvailable: { + type: Boolean, + required: false, + default: false, + }, + customMetricsPath: { + type: String, + required: true, + }, + validateQueryPath: { + type: String, + required: true, + }, }, data() { return { @@ -111,8 +134,14 @@ export default { elWidth: 0, selectedTimeWindow: '', selectedTimeWindowKey: '', + formIsValid: null, }; }, + computed: { + canAddMetrics() { + return this.customMetricsAvailable && this.customMetricsPath.length; + }, + }, created() { this.service = new MonitoringService({ metricsEndpoint: this.metricsEndpoint, @@ -193,11 +222,20 @@ export default { this.state = 'unableToConnect'; }); }, + hideAddMetricModal() { + this.$refs.addMetricModal.hide(); + }, onSidebarMutation() { setTimeout(() => { this.elWidth = this.$el.clientWidth; }, sidebarAnimationDuration); }, + setFormValidity(isValid) { + this.formIsValid = isValid; + }, + submitCustomMetricsForm() { + this.$refs.customMetricsForm.submit(); + }, activeTimeWindow(key) { return this.timeWindows[key] === this.selectedTimeWindow; }, @@ -205,57 +243,97 @@ export default { return `?time_window=${key}`; }, }, + addMetric: { + title: s__('Metrics|Add metric'), + modalId: 'add-metric', + }, }; </script> <template> - <div v-if="!showEmptyState" class="prometheus-graphs prepend-top-default"> - <div - v-if="environmentsEndpoint" - class="dropdowns d-flex align-items-center justify-content-between" - > - <div class="d-flex align-items-center"> - <strong>{{ s__('Metrics|Environment') }}</strong> - <gl-dropdown - class="prepend-left-10 js-environments-dropdown" - toggle-class="dropdown-menu-toggle" - :text="currentEnvironmentName" - :disabled="store.environmentsData.length === 0" - > - <gl-dropdown-item - v-for="environment in store.environmentsData" - :key="environment.id" - :href="environment.metrics_path" - :active="environment.name === currentEnvironmentName" - active-class="is-active" - >{{ environment.name }}</gl-dropdown-item + <div v-if="!showEmptyState" class="prometheus-graphs"> + <div class="gl-p-3 border-bottom bg-gray-light d-flex justify-content-between"> + <div + v-if="environmentsEndpoint" + class="dropdowns d-flex align-items-center justify-content-between" + > + <div class="d-flex align-items-center"> + <strong>{{ s__('Metrics|Environment') }}</strong> + <gl-dropdown + class="prepend-left-10 js-environments-dropdown" + toggle-class="dropdown-menu-toggle" + :text="currentEnvironmentName" + :disabled="store.environmentsData.length === 0" + > + <gl-dropdown-item + v-for="environment in store.environmentsData" + :key="environment.id" + :active="environment.name === currentEnvironmentName" + active-class="is-active" + >{{ environment.name }}</gl-dropdown-item + > + </gl-dropdown> + </div> + <div v-if="showTimeWindowDropdown" class="d-flex align-items-center"> + <strong>{{ s__('Metrics|Show last') }}</strong> + <gl-dropdown + class="prepend-left-10 js-time-window-dropdown" + toggle-class="dropdown-menu-toggle" + :text="selectedTimeWindow" > - </gl-dropdown> + <gl-dropdown-item + v-for="(value, key) in timeWindows" + :key="key" + :active="activeTimeWindow(key)" + ><gl-link :href="setTimeWindowParameter(key)">{{ value }}</gl-link></gl-dropdown-item + > + </gl-dropdown> + </div> </div> - <div v-if="showTimeWindowDropdown" class="d-flex align-items-center"> - <strong>{{ s__('Metrics|Show last') }}</strong> - <gl-dropdown - class="prepend-left-10 js-time-window-dropdown" - toggle-class="dropdown-menu-toggle" - :text="selectedTimeWindow" - > - <gl-dropdown-item - v-for="(value, key) in timeWindows" - :key="key" - :active="activeTimeWindow(key)" - ><gl-link :href="setTimeWindowParameter(key)">{{ value }}</gl-link></gl-dropdown-item + <div class="d-flex"> + <div v-if="isEE && canAddMetrics"> + <gl-button + v-gl-modal-directive="$options.addMetric.modalId" + class="js-add-metric-button text-success border-success" > - </gl-dropdown> + {{ $options.addMetric.title }} + </gl-button> + <gl-modal + ref="addMetricModal" + :modal-id="$options.addMetric.modalId" + :title="$options.addMetric.title" + > + <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-button @click="hideAddMetricModal"> + {{ __('Cancel') }} + </gl-button> + <gl-button + :disabled="!formIsValid" + variant="success" + @click="submitCustomMetricsForm" + > + {{ __('Save changes') }} + </gl-button> + </div> + </gl-modal> + </div> + <gl-button + v-if="externalDashboardPath.length" + class="js-external-dashboard-link prepend-left-8" + variant="primary" + :href="externalDashboardPath" + > + {{ __('View full dashboard') }} + <icon name="external-link" /> + </gl-button> </div> - <gl-button - v-if="externalDashboardPath.length" - class="js-external-dashboard-link" - variant="primary" - :href="externalDashboardPath" - > - {{ __('View full dashboard') }} - <icon name="external-link" /> - </gl-button> </div> <graph-group v-for="(groupData, index) in store.groups" diff --git a/app/assets/stylesheets/framework/common.scss b/app/assets/stylesheets/framework/common.scss index dffd5e70edb..2b499e50ea3 100644 --- a/app/assets/stylesheets/framework/common.scss +++ b/app/assets/stylesheets/framework/common.scss @@ -48,6 +48,10 @@ color: $brand-info; } +.bg-gray-light { + background-color: $gray-light; +} + .text-break-word { word-break: break-all; } @@ -446,19 +450,13 @@ img.emoji { } /** COMMON SPACING CLASSES **/ -.gl-pl-0 { padding-left: 0; } -.gl-pl-1 { padding-left: #{0.5 * $grid-size}; } -.gl-pl-2 { padding-left: $grid-size; } -.gl-pl-3 { padding-left: #{2 * $grid-size}; } -.gl-pl-4 { padding-left: #{3 * $grid-size}; } -.gl-pl-5 { padding-left: #{4 * $grid-size}; } - -.gl-pr-0 { padding-right: 0; } -.gl-pr-1 { padding-right: #{0.5 * $grid-size}; } -.gl-pr-2 { padding-right: $grid-size; } -.gl-pr-3 { padding-right: #{2 * $grid-size}; } -.gl-pr-4 { padding-right: #{3 * $grid-size}; } -.gl-pr-5 { padding-right: #{4 * $grid-size}; } +@each $index, $padding in $spacing-scale { + #{'.gl-p-#{$index}'} { padding: $padding; } + #{'.gl-pl-#{$index}'} { padding-left: $padding; } + #{'.gl-pr-#{$index}'} { padding-right: $padding; } + #{'.gl-pt-#{$index}'} { padding-top: $padding; } + #{'.gl-pb-#{$index}'} { padding-bottom: $padding; } +} /** * Removes browser specific clear icon from input fields in diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss index da1f196afdb..4a034e1e547 100644 --- a/app/assets/stylesheets/framework/variables.scss +++ b/app/assets/stylesheets/framework/variables.scss @@ -11,6 +11,14 @@ $default-transition-duration: 0.15s; $contextual-sidebar-width: 220px; $contextual-sidebar-collapsed-width: 50px; $toggle-sidebar-height: 48px; +$spacing-scale: ( + 0: 0, + 1: #{0.5 * $grid-size}, + 2: $grid-size, + 3: #{2 * $grid-size}, + 4: #{3 * $grid-size}, + 5: #{4 * $grid-size} +); /* * Color schema diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 4d253fa6043..2907430bd51 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -5911,6 +5911,9 @@ msgstr "" msgid "Metrics for environment" msgstr "" +msgid "Metrics|Add metric" +msgstr "" + msgid "Metrics|Check out the CI/CD documentation on deploying to an environment" msgstr "" diff --git a/spec/javascripts/monitoring/dashboard_spec.js b/spec/javascripts/monitoring/dashboard_spec.js index fc722867b0b..e9bd6050d68 100644 --- a/spec/javascripts/monitoring/dashboard_spec.js +++ b/spec/javascripts/monitoring/dashboard_spec.js @@ -20,6 +20,9 @@ const propsData = { emptyUnableToConnectSvgPath: '/path/to/unable-to-connect.svg', environmentsEndpoint: '/root/hello-prometheus/environments/35', currentEnvironmentName: 'production', + customMetricsAvailable: false, + customMetricsPath: '', + validateQueryPath: '', }; export default propsData; @@ -163,7 +166,7 @@ describe('Dashboard', () => { }); }); - it('renders the environments dropdown with a single is-active element', done => { + it('renders the environments dropdown with a single active element', done => { const component = new DashboardComponent({ el: document.querySelector('.prometheus-graphs'), propsData: { @@ -178,7 +181,7 @@ describe('Dashboard', () => { setTimeout(() => { const dropdownItems = component.$el.querySelectorAll( - '.js-environments-dropdown .dropdown-item.is-active', + '.js-environments-dropdown .dropdown-item[active="true"]', ); expect(dropdownItems.length).toEqual(1); |