diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-02-13 15:08:52 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-02-13 15:08:52 +0000 |
commit | 0ab47b994caa80c5587f33dc818626b66cfdafe2 (patch) | |
tree | 5ef3976d2f84e3368903a67ba2dbd87a74b9a43c /app/assets | |
parent | 1308dc5eb484ab0f8064989fc551ebdb4b1a7976 (diff) | |
download | gitlab-ce-0ab47b994caa80c5587f33dc818626b66cfdafe2.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets')
10 files changed, 198 insertions, 210 deletions
diff --git a/app/assets/javascripts/clusters/stores/clusters_store.js b/app/assets/javascripts/clusters/stores/clusters_store.js index 26456fb28db..939c396e1b9 100644 --- a/app/assets/javascripts/clusters/stores/clusters_store.js +++ b/app/assets/javascripts/clusters/stores/clusters_store.js @@ -257,6 +257,7 @@ export default class ClusterStore { name: environment.name, project: environment.project, environmentPath: environment.environment_path, + logsPath: environment.logs_path, lastDeployment: environment.last_deployment, rolloutStatus: { status: environment.rollout_status ? environment.rollout_status.status : null, diff --git a/app/assets/javascripts/diffs/components/diff_line_gutter_content.vue b/app/assets/javascripts/diffs/components/diff_line_gutter_content.vue deleted file mode 100644 index 9eaceb8893c..00000000000 --- a/app/assets/javascripts/diffs/components/diff_line_gutter_content.vue +++ /dev/null @@ -1,150 +0,0 @@ -<script> -import { mapState, mapGetters, mapActions } from 'vuex'; -import { getParameterByName, parseBoolean } from '~/lib/utils/common_utils'; -import Icon from '~/vue_shared/components/icon.vue'; -import DiffGutterAvatars from './diff_gutter_avatars.vue'; -import { LINE_POSITION_RIGHT } from '../constants'; - -export default { - components: { - DiffGutterAvatars, - Icon, - }, - props: { - line: { - type: Object, - required: true, - }, - fileHash: { - type: String, - required: true, - }, - contextLinesPath: { - type: String, - required: true, - }, - lineNumber: { - type: Number, - required: false, - default: 0, - }, - linePosition: { - type: String, - required: false, - default: '', - }, - showCommentButton: { - type: Boolean, - required: false, - default: false, - }, - isBottom: { - type: Boolean, - required: false, - default: false, - }, - isMatchLine: { - type: Boolean, - required: false, - default: false, - }, - isMetaLine: { - type: Boolean, - required: false, - default: false, - }, - isContextLine: { - type: Boolean, - required: false, - default: false, - }, - isHover: { - type: Boolean, - required: false, - default: false, - }, - }, - computed: { - ...mapState({ - diffViewType: state => state.diffs.diffViewType, - diffFiles: state => state.diffs.diffFiles, - }), - ...mapGetters(['isLoggedIn']), - lineCode() { - return ( - this.line.line_code || - (this.line.left && this.line.left.line_code) || - (this.line.right && this.line.right.line_code) - ); - }, - lineHref() { - return `#${this.line.line_code || ''}`; - }, - shouldShowCommentButton() { - return ( - this.isHover && - !this.isMatchLine && - !this.isContextLine && - !this.isMetaLine && - !this.hasDiscussions - ); - }, - hasDiscussions() { - return this.line.discussions && this.line.discussions.length > 0; - }, - shouldShowAvatarsOnGutter() { - if (!this.line.type && this.linePosition === LINE_POSITION_RIGHT) { - return false; - } - return this.showCommentButton && this.hasDiscussions; - }, - shouldRenderCommentButton() { - const isDiffHead = parseBoolean(getParameterByName('diff_head')); - return !isDiffHead && this.isLoggedIn && this.showCommentButton; - }, - }, - methods: { - ...mapActions('diffs', [ - 'loadMoreLines', - 'showCommentForm', - 'setHighlightedRow', - 'toggleLineDiscussions', - 'toggleLineDiscussionWrappers', - ]), - handleCommentButton() { - this.showCommentForm({ lineCode: this.line.line_code, fileHash: this.fileHash }); - }, - }, -}; -</script> - -<template> - <div> - <button - v-if="shouldRenderCommentButton" - v-show="shouldShowCommentButton" - type="button" - class="add-diff-note js-add-diff-note-button qa-diff-comment" - title="Add a comment to this line" - @click="handleCommentButton" - > - <icon :size="12" name="comment" /> - </button> - <a - v-if="lineNumber" - ref="lineNumberRef" - :data-linenumber="lineNumber" - :href="lineHref" - @click="setHighlightedRow(lineCode)" - > - </a> - <diff-gutter-avatars - v-if="shouldShowAvatarsOnGutter" - :discussions="line.discussions" - :discussions-expanded="line.discussionsExpanded" - @toggleLineDiscussions=" - toggleLineDiscussions({ lineCode, fileHash, expanded: !line.discussionsExpanded }) - " - /> - </div> -</template> diff --git a/app/assets/javascripts/diffs/components/diff_table_cell.vue b/app/assets/javascripts/diffs/components/diff_table_cell.vue index 0f3e9208d21..9544fbe9fc5 100644 --- a/app/assets/javascripts/diffs/components/diff_table_cell.vue +++ b/app/assets/javascripts/diffs/components/diff_table_cell.vue @@ -1,21 +1,24 @@ <script> import { mapGetters, mapActions } from 'vuex'; -import DiffLineGutterContent from './diff_line_gutter_content.vue'; +import { GlIcon } from '@gitlab/ui'; +import { getParameterByName, parseBoolean } from '~/lib/utils/common_utils'; +import DiffGutterAvatars from './diff_gutter_avatars.vue'; import { MATCH_LINE_TYPE, CONTEXT_LINE_TYPE, + LINE_POSITION_RIGHT, EMPTY_CELL_TYPE, OLD_LINE_TYPE, OLD_NO_NEW_LINE_TYPE, NEW_NO_NEW_LINE_TYPE, LINE_HOVER_CLASS_NAME, LINE_UNFOLD_CLASS_NAME, - INLINE_DIFF_VIEW_TYPE, } from '../constants'; export default { components: { - DiffLineGutterContent, + DiffGutterAvatars, + GlIcon, }, props: { line: { @@ -33,12 +36,6 @@ export default { isHighlighted: { type: Boolean, required: true, - default: false, - }, - diffViewType: { - type: String, - required: false, - default: INLINE_DIFF_VIEW_TYPE, }, showCommentButton: { type: Boolean, @@ -73,6 +70,38 @@ export default { }, computed: { ...mapGetters(['isLoggedIn']), + lineCode() { + return ( + this.line.line_code || + (this.line.left && this.line.left.line_code) || + (this.line.right && this.line.right.line_code) + ); + }, + lineHref() { + return `#${this.line.line_code || ''}`; + }, + shouldShowCommentButton() { + return ( + this.isHover && + !this.isMatchLine && + !this.isContextLine && + !this.isMetaLine && + !this.hasDiscussions + ); + }, + hasDiscussions() { + return this.line.discussions && this.line.discussions.length > 0; + }, + shouldShowAvatarsOnGutter() { + if (!this.line.type && this.linePosition === LINE_POSITION_RIGHT) { + return false; + } + return this.showCommentButton && this.hasDiscussions; + }, + shouldRenderCommentButton() { + const isDiffHead = parseBoolean(getParameterByName('diff_head')); + return !isDiffHead && this.isLoggedIn && this.showCommentButton; + }, isMatchLine() { return this.line.type === MATCH_LINE_TYPE; }, @@ -107,24 +136,45 @@ export default { return this.lineType === OLD_LINE_TYPE ? this.line.old_line : this.line.new_line; }, }, - methods: mapActions('diffs', ['setHighlightedRow']), + methods: { + ...mapActions('diffs', ['showCommentForm', 'setHighlightedRow', 'toggleLineDiscussions']), + handleCommentButton() { + this.showCommentForm({ lineCode: this.line.line_code, fileHash: this.fileHash }); + }, + }, }; </script> <template> - <td :class="classNameMap"> - <diff-line-gutter-content - :line="line" - :file-hash="fileHash" - :context-lines-path="contextLinesPath" - :line-position="linePosition" - :line-number="lineNumber" - :show-comment-button="showCommentButton" - :is-hover="isHover" - :is-bottom="isBottom" - :is-match-line="isMatchLine" - :is-context-line="isContentLine" - :is-meta-line="isMetaLine" - /> + <td ref="td" :class="classNameMap"> + <div> + <button + v-if="shouldRenderCommentButton" + v-show="shouldShowCommentButton" + ref="addDiffNoteButton" + type="button" + class="add-diff-note js-add-diff-note-button qa-diff-comment" + title="Add a comment to this line" + @click="handleCommentButton" + > + <gl-icon :size="12" name="comment" /> + </button> + <a + v-if="lineNumber" + ref="lineNumberRef" + :data-linenumber="lineNumber" + :href="lineHref" + @click="setHighlightedRow(lineCode)" + > + </a> + <diff-gutter-avatars + v-if="shouldShowAvatarsOnGutter" + :discussions="line.discussions" + :discussions-expanded="line.discussionsExpanded" + @toggleLineDiscussions=" + toggleLineDiscussions({ lineCode, fileHash, expanded: !line.discussionsExpanded }) + " + /> + </div> </td> </template> diff --git a/app/assets/javascripts/environments/components/environments_table.vue b/app/assets/javascripts/environments/components/environments_table.vue index 8abc927c500..3f316643784 100644 --- a/app/assets/javascripts/environments/components/environments_table.vue +++ b/app/assets/javascripts/environments/components/environments_table.vue @@ -162,8 +162,7 @@ export default { :is-loading="model.isLoadingDeployBoard" :is-empty="model.isEmptyDeployBoard" :has-legacy-app-label="model.hasLegacyAppLabel" - :project-path="model.project_path" - :environment-name="model.name" + :logs-path="model.logs_path" /> </div> </div> diff --git a/app/assets/javascripts/error_tracking/details.js b/app/assets/javascripts/error_tracking/details.js index 1a92681374b..55ab362f805 100644 --- a/app/assets/javascripts/error_tracking/details.js +++ b/app/assets/javascripts/error_tracking/details.js @@ -8,28 +8,30 @@ import csrf from '~/lib/utils/csrf'; Vue.use(VueApollo); export default () => { + const selector = '#js-error_details'; + + const domEl = document.querySelector(selector); + const { + issueId, + projectPath, + issueUpdatePath, + issueStackTracePath, + projectIssuesPath, + } = domEl.dataset; + const apolloProvider = new VueApollo({ defaultClient: createDefaultClient(), }); // eslint-disable-next-line no-new new Vue({ - el: '#js-error_details', + el: selector, apolloProvider, components: { ErrorDetails, }, store, render(createElement) { - const domEl = document.querySelector(this.$options.el); - const { - issueId, - projectPath, - issueUpdatePath, - issueStackTracePath, - projectIssuesPath, - } = domEl.dataset; - return createElement('error-details', { props: { issueId, diff --git a/app/assets/javascripts/error_tracking/list.js b/app/assets/javascripts/error_tracking/list.js index 8f3700249da..cb656a9ef13 100644 --- a/app/assets/javascripts/error_tracking/list.js +++ b/app/assets/javascripts/error_tracking/list.js @@ -4,27 +4,29 @@ import store from './store'; import ErrorTrackingList from './components/error_tracking_list.vue'; export default () => { + const selector = '#js-error_tracking'; + + const domEl = document.querySelector(selector); + const { + indexPath, + enableErrorTrackingLink, + illustrationPath, + projectPath, + listPath, + } = domEl.dataset; + let { errorTrackingEnabled, userCanEnableErrorTracking } = domEl.dataset; + + errorTrackingEnabled = parseBoolean(errorTrackingEnabled); + userCanEnableErrorTracking = parseBoolean(userCanEnableErrorTracking); + // eslint-disable-next-line no-new new Vue({ - el: '#js-error_tracking', + el: selector, components: { ErrorTrackingList, }, store, render(createElement) { - const domEl = document.querySelector(this.$options.el); - const { - indexPath, - enableErrorTrackingLink, - illustrationPath, - projectPath, - listPath, - } = domEl.dataset; - let { errorTrackingEnabled, userCanEnableErrorTracking } = domEl.dataset; - - errorTrackingEnabled = parseBoolean(errorTrackingEnabled); - userCanEnableErrorTracking = parseBoolean(userCanEnableErrorTracking); - return createElement('error-tracking-list', { props: { indexPath, diff --git a/app/assets/javascripts/monitoring/components/charts/time_series.vue b/app/assets/javascripts/monitoring/components/charts/time_series.vue index 8b2c5e44bb5..eaf0780d9e1 100644 --- a/app/assets/javascripts/monitoring/components/charts/time_series.vue +++ b/app/assets/javascripts/monitoring/components/charts/time_series.vue @@ -18,6 +18,17 @@ import { import { makeDataSeries } from '~/helpers/monitor_helper'; import { graphDataValidatorForValues } from '../../utils'; +/** + * A "virtual" coordinates system for the deployment icons. + * Deployment icons are displayed along the [min, max] + * range at height `pos`. + */ +const deploymentYAxisCoords = { + min: 0, + pos: 3, // 3% height of chart's grid + max: 100, +}; + const THROTTLED_DATAZOOM_WAIT = 1000; // miliseconds const timestampToISODate = timestamp => new Date(timestamp).toISOString(); @@ -145,10 +156,33 @@ export default { }, []); }, chartOptionSeries() { - return (this.option.series || []).concat(this.scatterSeries ? [this.scatterSeries] : []); + return (this.option.series || []).concat( + this.deploymentSeries ? [this.deploymentSeries] : [], + ); }, chartOptions() { const option = omit(this.option, 'series'); + + const dataYAxis = { + name: this.yAxisLabel, + nameGap: 50, // same as gitlab-ui's default + nameLocation: 'center', // same as gitlab-ui's default + boundaryGap: [0.1, 0.1], + scale: true, + axisLabel: { + formatter: num => roundOffFloat(num, 3).toString(), + }, + }; + const deploymentsYAxis = { + show: false, + min: deploymentYAxisCoords.min, + max: deploymentYAxisCoords.max, + axisLabel: { + // formatter fn required to trigger tooltip re-positioning + formatter: () => {}, + }, + }; + return { series: this.chartOptionSeries, xAxis: { @@ -161,12 +195,7 @@ export default { snap: true, }, }, - yAxis: { - name: this.yAxisLabel, - axisLabel: { - formatter: num => roundOffFloat(num, 3).toString(), - }, - }, + yAxis: [dataYAxis, deploymentsYAxis], dataZoom: [this.dataZoomConfig], ...option, }; @@ -228,10 +257,16 @@ export default { return acc; }, []); }, - scatterSeries() { + deploymentSeries() { return { type: graphTypes.deploymentData, - data: this.recentDeployments.map(deployment => [deployment.createdAt, 0]), + + yAxisIndex: 1, // deploymentsYAxis index + data: this.recentDeployments.map(deployment => [ + deployment.createdAt, + deploymentYAxisCoords.pos, + ]), + symbol: this.svgs.rocket, symbolSize: symbolSizes.default, itemStyle: { @@ -265,6 +300,7 @@ export default { formatTooltipText(params) { this.tooltip.title = dateFormat(params.value, dateFormats.default); this.tooltip.content = []; + params.seriesData.forEach(dataPoint => { if (dataPoint.value) { const [xVal, yVal] = dataPoint.value; diff --git a/app/assets/javascripts/registry/shared/components/expiration_policy_fields.vue b/app/assets/javascripts/registry/shared/components/expiration_policy_fields.vue index 84d1c5ccc6a..a15b854cb9b 100644 --- a/app/assets/javascripts/registry/shared/components/expiration_policy_fields.vue +++ b/app/assets/javascripts/registry/shared/components/expiration_policy_fields.vue @@ -82,7 +82,7 @@ export default { regexHelpText() { return sprintf( s__( - 'ContainerRegistry|Wildcards such as %{codeStart}*-stable%{codeEnd} or %{codeStart}production/*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}', + 'ContainerRegistry|Wildcards such as %{codeStart}.*-stable%{codeEnd} or %{codeStart}production/.*%{codeEnd} are supported. To select all tags, use %{codeStart}.*%{codeEnd}', ), { codeStart: '<code>', diff --git a/app/assets/javascripts/snippet/collapsible_input.js b/app/assets/javascripts/snippet/collapsible_input.js new file mode 100644 index 00000000000..e7225162f86 --- /dev/null +++ b/app/assets/javascripts/snippet/collapsible_input.js @@ -0,0 +1,45 @@ +const hide = el => el.classList.add('d-none'); +const show = el => el.classList.remove('d-none'); + +const setupCollapsibleInput = el => { + const collapsedEl = el.querySelector('.js-collapsed'); + const expandedEl = el.querySelector('.js-expanded'); + const collapsedInputEl = collapsedEl.querySelector('textarea,input,select'); + const expandedInputEl = expandedEl.querySelector('textarea,input,select'); + const formEl = el.closest('form'); + + const collapse = () => { + hide(expandedEl); + show(collapsedEl); + }; + + const expand = () => { + hide(collapsedEl); + show(expandedEl); + }; + + // NOTE: + // We add focus listener to all form inputs so that we can collapse + // when something is focused that's not the expanded input. + formEl.addEventListener('focusin', e => { + if (e.target === collapsedInputEl) { + expand(); + expandedInputEl.focus(); + } else if (!el.contains(e.target) && !expandedInputEl.value) { + collapse(); + } + }); +}; + +/** + * Usage in HAML + * + * .js-collapsible-input + * .js-collapsed{ class: ('d-none' if is_expanded) } + * = input + * .js-expanded{ class: ('d-none' if !is_expanded) } + * = big_input + */ +export default () => { + Array.from(document.querySelectorAll('.js-collapsible-input')).forEach(setupCollapsibleInput); +}; diff --git a/app/assets/javascripts/snippet/snippet_bundle.js b/app/assets/javascripts/snippet/snippet_bundle.js index dcee17453b8..652531a1289 100644 --- a/app/assets/javascripts/snippet/snippet_bundle.js +++ b/app/assets/javascripts/snippet/snippet_bundle.js @@ -1,6 +1,7 @@ /* global ace */ import $ from 'jquery'; +import setupCollapsibleInputs from './collapsible_input'; export default () => { const editor = ace.edit('editor'); @@ -8,4 +9,6 @@ export default () => { $('.snippet-form-holder form').on('submit', () => { $('.snippet-file-content').val(editor.getValue()); }); + + setupCollapsibleInputs(); }; |