Commit 2f663903 authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents d110aee5 3e4f2dcc
...@@ -78,9 +78,9 @@ ports: ...@@ -78,9 +78,9 @@ ports:
vscode: vscode:
extensions: extensions:
- rebornix.ruby@0.27.0:QyGBeRyslOfdRgOPRGm6PQ== - rebornix.ruby@0.28.0
- wingrunr21.vscode-ruby@0.27.0:beIqQUhLRuJ5Vao4B2Lyng== - wingrunr21.vscode-ruby@0.27.0
- karunamurti.haml@1.1.0:twCwOYt3/Ttfb3+iwblPDA== - karunamurti.haml@1.3.1
- octref.vetur@0.25.0:UofirBhedyhdx/jCnPeJDg== - octref.vetur@0.34.1
- dbaeumer.vscode-eslint@2.1.3:1NRvj3UKNTNwmYjptmUmIw== - dbaeumer.vscode-eslint@2.1.8
- GitLab.gitlab-workflow@3.3.0:50q1byIi4M01G9qrTCCAYQ== - gitlab.gitlab-workflow@3.24.0
...@@ -2,6 +2,23 @@ ...@@ -2,6 +2,23 @@
documentation](doc/development/changelog.md) for instructions on adding your own documentation](doc/development/changelog.md) for instructions on adding your own
entry. entry.
## 14.0.3 (2021-07-06)
### Fixed (7 changes)
- [Fix deploy keys not working with LFS auth check](gitlab-org/gitlab@134b244c7f59f8a20cb191bc0d2aaa43171f3d6e) ([merge request](gitlab-org/gitlab!65498))
- [DevOps Adoption - ensure displayNamespaceId is included](gitlab-org/gitlab@1166130f1e6786a8c96735b6518241fb704047b1) ([merge request](gitlab-org/gitlab!65498)) **GitLab Enterprise Edition**
- [Geo - Fix state value in the lfs_object_registry table](gitlab-org/gitlab@b6f30299d255949b79d149ee71ee50025ac0c8c2) ([merge request](gitlab-org/gitlab!65498)) **GitLab Enterprise Edition**
- [Fix broken Time Tracking Reports on Issuable sidebar](gitlab-org/gitlab@da0b4a92f791a3f621ec8da8e2fbb0ad4e39d399) ([merge request](gitlab-org/gitlab!65498))
- [Fix bug where Milestone page led to console error](gitlab-org/gitlab@179948d489ed92f5d8158c23190430e819941a29) ([merge request](gitlab-org/gitlab!65498))
- [Fix frequent items timestamps not updated](gitlab-org/gitlab@481d4d36252dc91291afe9dacd7d48558878d27f) ([merge request](gitlab-org/gitlab!65498))
- [Fix pages deployment storage migration](gitlab-org/gitlab@0eab6e579890c557bf97dd48dd6a2a7adaf97358) ([merge request](gitlab-org/gitlab!65498))
### Changed (2 changes)
- [Geo - Move migration to a pre-deployment migration](gitlab-org/gitlab@84327652855cafe36c574df798322b63d0649561) ([merge request](gitlab-org/gitlab!65498)) **GitLab Enterprise Edition**
- [Reintroduce recursive_approach_for_all_projects default-enabled](gitlab-org/gitlab@14b3aa69cad85541ae6b845b346c80d1eaea099b) ([merge request](gitlab-org/gitlab!65498))
## 14.0.2 (2021-07-01) ## 14.0.2 (2021-07-01)
### Added (1 change) ### Added (1 change)
......
...@@ -398,7 +398,9 @@ module.exports = { ...@@ -398,7 +398,9 @@ module.exports = {
new VueLoaderPlugin(), new VueLoaderPlugin(),
// automatically configure monaco editor web workers // automatically configure monaco editor web workers
new MonacoWebpackPlugin(), new MonacoWebpackPlugin({
globalAPI: true,
}),
// fix legacy jQuery plugins which depend on globals // fix legacy jQuery plugins which depend on globals
new webpack.ProvidePlugin({ new webpack.ProvidePlugin({
......
...@@ -118,19 +118,12 @@ export default { ...@@ -118,19 +118,12 @@ export default {
}; };
}, },
}, },
mounted() {
this.setChartEnabled({
chartKey: chartKeys.scatterplot,
isEnabled: this.isScatterplotFeatureEnabled(),
});
},
methods: { methods: {
...mapActions('charts', [ ...mapActions('charts', [
'fetchChartData', 'fetchChartData',
'setMetricType', 'setMetricType',
'updateSelectedItems', 'updateSelectedItems',
'resetMainChartSelection', 'resetMainChartSelection',
'setChartEnabled',
]), ]),
...mapActions('table', ['setSortField', 'setPage', 'toggleSortOrder', 'setColumnMetric']), ...mapActions('table', ['setSortField', 'setPage', 'toggleSortOrder', 'setColumnMetric']),
onMainChartItemClicked({ params }) { onMainChartItemClicked({ params }) {
...@@ -148,9 +141,6 @@ export default { ...@@ -148,9 +141,6 @@ export default {
...this.getColumnChartDatazoomOption(chartKey), ...this.getColumnChartDatazoomOption(chartKey),
}; };
}, },
isScatterplotFeatureEnabled() {
return this.glFeatures.productivityAnalyticsScatterplotEnabled;
},
}, },
}; };
</script> </script>
......
...@@ -16,9 +16,6 @@ class Groups::Analytics::ProductivityAnalyticsController < Groups::Analytics::Ap ...@@ -16,9 +16,6 @@ class Groups::Analytics::ProductivityAnalyticsController < Groups::Analytics::Ap
before_action -> { before_action -> {
authorize_view_by_action!(:view_productivity_analytics) authorize_view_by_action!(:view_productivity_analytics)
} }
before_action -> {
push_frontend_feature_flag(:productivity_analytics_scatterplot_enabled, default_enabled: true)
}
before_action :validate_params, only: :show, if: -> { request.format.json? } before_action :validate_params, only: :show, if: -> { request.format.json? }
......
---
name: productivity_analytics_scatterplot_enabled
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/17735
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/13412
milestone: '12.4'
type: development
group: group::optimize
default_enabled: true
...@@ -49,7 +49,7 @@ describe('ProductivityApp component', () => { ...@@ -49,7 +49,7 @@ describe('ProductivityApp component', () => {
const mainChartData = { 1: 2, 2: 3 }; const mainChartData = { 1: 2, 2: 3 };
const createComponent = ({ props = {}, options = {}, scatterplotEnabled = true } = {}) => { const createComponent = ({ props = {}, options = {} } = {}) => {
const { const {
modules: { charts, table, ...modules }, modules: { charts, table, ...modules },
...storeConfig ...storeConfig
...@@ -82,9 +82,6 @@ describe('ProductivityApp component', () => { ...@@ -82,9 +82,6 @@ describe('ProductivityApp component', () => {
...propsData, ...propsData,
...props, ...props,
}, },
provide: {
glFeatures: { productivityAnalyticsScatterplotEnabled: scatterplotEnabled },
},
...options, ...options,
}); });
...@@ -330,75 +327,55 @@ describe('ProductivityApp component', () => { ...@@ -330,75 +327,55 @@ describe('ProductivityApp component', () => {
}); });
describe('Scatterplot', () => { describe('Scatterplot', () => {
describe('when the feature flag is enabled', () => { it('renders a metric chart component', () => {
it('isScatterplotFeatureEnabled returns true', () => { expect(findScatterplotMetricChart().exists()).toBe(true);
expect(wrapper.vm.isScatterplotFeatureEnabled()).toBe(true); });
});
it('renders a metric chart component', () => {
expect(findScatterplotMetricChart().exists()).toBe(true);
});
describe('when chart finished loading', () => { describe('when chart finished loading', () => {
describe('and the chart has data', () => { describe('and the chart has data', () => {
beforeEach(() => { beforeEach(() => {
mockStore.dispatch('charts/receiveChartDataSuccess', { mockStore.dispatch('charts/receiveChartDataSuccess', {
chartKey: chartKeys.scatterplot, chartKey: chartKeys.scatterplot,
data: { data: {
1: { metric: 2, merged_at: '2019-09-01T07:06:23.193Z' }, 1: { metric: 2, merged_at: '2019-09-01T07:06:23.193Z' },
2: { metric: 3, merged_at: '2019-09-05T08:27:42.411Z' }, 2: { metric: 3, merged_at: '2019-09-05T08:27:42.411Z' },
}, },
transformedData: [ transformedData: [
[{ metric: 2, merged_at: '2019-09-01T07:06:23.193Z' }], [{ metric: 2, merged_at: '2019-09-01T07:06:23.193Z' }],
[{ metric: 3, merged_at: '2019-09-05T08:27:42.411Z' }], [{ metric: 3, merged_at: '2019-09-05T08:27:42.411Z' }],
], ],
});
}); });
});
it('sets isLoading=false on the metric chart', () => { it('sets isLoading=false on the metric chart', () => {
expect(findScatterplotMetricChart().props('isLoading')).toBe(false); expect(findScatterplotMetricChart().props('isLoading')).toBe(false);
}); });
it('passes non-empty chartData to the metric chart', () => { it('passes non-empty chartData to the metric chart', () => {
expect(findScatterplotMetricChart().props('chartData')).not.toEqual([]); expect(findScatterplotMetricChart().props('chartData')).not.toEqual([]);
}); });
describe('when the user changes the metric', () => { describe('when the user changes the metric', () => {
beforeEach(() => { beforeEach(() => {
jest.spyOn(mockStore, 'dispatch'); jest.spyOn(mockStore, 'dispatch');
findScatterplotMetricChart().vm.$emit('metricTypeChange', 'loc_per_commit'); findScatterplotMetricChart().vm.$emit('metricTypeChange', 'loc_per_commit');
return wrapper.vm.$nextTick(); return wrapper.vm.$nextTick();
}); });
it('should call setMetricType when `metricTypeChange` is emitted on the metric chart', () => { it('should call setMetricType when `metricTypeChange` is emitted on the metric chart', () => {
expect(mockStore.dispatch).toHaveBeenCalledWith('charts/setMetricType', { expect(mockStore.dispatch).toHaveBeenCalledWith('charts/setMetricType', {
metricType: 'loc_per_commit', metricType: 'loc_per_commit',
chartKey: chartKeys.scatterplot, chartKey: chartKeys.scatterplot,
});
}); });
});
it("should update the chart's y axis label", () => { it("should update the chart's y axis label", () => {
const scatterplot = findScatterplotMetricChart().find(Scatterplot); const scatterplot = findScatterplotMetricChart().find(Scatterplot);
expect(scatterplot.props('yAxisTitle')).toBe('Number of LOCs per commit'); expect(scatterplot.props('yAxisTitle')).toBe('Number of LOCs per commit');
});
}); });
}); });
}); });
}); });
describe('when the feature flag is disabled', () => {
beforeEach(() => {
createComponent({ scatterplotEnabled: false });
});
it('isScatterplotFeatureEnabled returns false', () => {
expect(wrapper.vm.isScatterplotFeatureEnabled()).toBe(false);
});
it("doesn't render a metric chart component", () => {
expect(findScatterplotMetricChart().exists()).toBe(false);
});
});
}); });
describe('MR table', () => { describe('MR table', () => {
......
...@@ -144,8 +144,8 @@ ...@@ -144,8 +144,8 @@
"mathjax": "3", "mathjax": "3",
"mermaid": "^8.10.2", "mermaid": "^8.10.2",
"minimatch": "^3.0.4", "minimatch": "^3.0.4",
"monaco-editor": "^0.20.0", "monaco-editor": "^0.25.2",
"monaco-editor-webpack-plugin": "^1.9.1", "monaco-editor-webpack-plugin": "^4.0.0",
"monaco-yaml": "^2.5.1", "monaco-yaml": "^2.5.1",
"mousetrap": "1.6.5", "mousetrap": "1.6.5",
"pdfjs-dist": "^2.0.943", "pdfjs-dist": "^2.0.943",
...@@ -263,7 +263,7 @@ ...@@ -263,7 +263,7 @@
}, },
"resolutions": { "resolutions": {
"chokidar": "^3.4.0", "chokidar": "^3.4.0",
"monaco-editor": "0.20.0" "monaco-editor": "0.24.0"
}, },
"engines": { "engines": {
"node": ">=10.13.0", "node": ">=10.13.0",
......
...@@ -246,7 +246,7 @@ describe('Base editor', () => { ...@@ -246,7 +246,7 @@ describe('Base editor', () => {
let editorEl2; let editorEl2;
let inst1; let inst1;
let inst2; let inst2;
const readOnlyIndex = '68'; // readOnly option has the internal index of 68 in the editor's options const readOnlyIndex = '78'; // readOnly option has the internal index of 78 in the editor's options
beforeEach(() => { beforeEach(() => {
setFixtures('<div id="editor1"></div><div id="editor2"></div>'); setFixtures('<div id="editor1"></div><div id="editor2"></div>');
......
...@@ -67,6 +67,24 @@ class CustomEnvironment extends JSDOMEnvironment { ...@@ -67,6 +67,24 @@ class CustomEnvironment extends JSDOMEnvironment {
getEntriesByName: () => [], getEntriesByName: () => [],
}); });
//
// Monaco-related environment variables
//
this.global.MonacoEnvironment = { globalAPI: true };
Object.defineProperty(this.global, 'matchMedia', {
writable: true,
value: (query) => ({
matches: false,
media: query,
onchange: null,
addListener: () => null, // deprecated
removeListener: () => null, // deprecated
addEventListener: () => null,
removeEventListener: () => null,
dispatchEvent: () => null,
}),
});
this.global.PerformanceObserver = class { this.global.PerformanceObserver = class {
/* eslint-disable no-useless-constructor, no-unused-vars, no-empty-function, class-methods-use-this */ /* eslint-disable no-useless-constructor, no-unused-vars, no-empty-function, class-methods-use-this */
constructor(callback) {} constructor(callback) {}
......
...@@ -7,6 +7,7 @@ import { ...@@ -7,6 +7,7 @@ import {
screen, screen,
findByText, findByText,
} from '@testing-library/dom'; } from '@testing-library/dom';
import { editor as monacoEditor } from 'monaco-editor';
const isFolderRowOpen = (row) => row.matches('.folder.is-open'); const isFolderRowOpen = (row) => row.matches('.folder.is-open');
...@@ -23,7 +24,10 @@ export const switchLeftSidebarTab = (name) => { ...@@ -23,7 +24,10 @@ export const switchLeftSidebarTab = (name) => {
export const getStatusBar = () => document.querySelector('.ide-status-bar'); export const getStatusBar = () => document.querySelector('.ide-status-bar');
export const waitForMonacoEditor = () => export const waitForMonacoEditor = () =>
new Promise((resolve) => window.monaco.editor.onDidCreateEditor(resolve)); new Promise((resolve) => monacoEditor.onDidCreateEditor(resolve));
export const waitForEditorDispose = (instance) =>
new Promise((resolve) => instance.onDidDispose(resolve));
export const waitForEditorModelChange = (instance) => export const waitForEditorModelChange = (instance) =>
new Promise((resolve) => instance.onDidChangeModel(resolve)); new Promise((resolve) => instance.onDidChangeModel(resolve));
...@@ -38,14 +42,14 @@ export const findAndSetEditorValue = async (value) => { ...@@ -38,14 +42,14 @@ export const findAndSetEditorValue = async (value) => {
const editor = await findMonacoEditor(); const editor = await findMonacoEditor();
const uri = editor.getAttribute('data-uri'); const uri = editor.getAttribute('data-uri');
window.monaco.editor.getModel(uri).setValue(value); monacoEditor.getModel(uri).setValue(value);
}; };
export const getEditorValue = async () => { export const getEditorValue = async () => {
const editor = await findMonacoEditor(); const editor = await findMonacoEditor();
const uri = editor.getAttribute('data-uri'); const uri = editor.getAttribute('data-uri');
return window.monaco.editor.getModel(uri).getValue(); return monacoEditor.getModel(uri).getValue();
}; };
const findTreeBody = () => screen.findByTestId('ide-tree-body'); const findTreeBody = () => screen.findByTestId('ide-tree-body');
......
...@@ -8560,17 +8560,22 @@ moment-mini@^2.22.1: ...@@ -8560,17 +8560,22 @@ moment-mini@^2.22.1:
resolved "https://registry.yarnpkg.com/moment-mini/-/moment-mini-2.22.1.tgz#bc32d73e43a4505070be6b53494b17623183420d" resolved "https://registry.yarnpkg.com/moment-mini/-/moment-mini-2.22.1.tgz#bc32d73e43a4505070be6b53494b17623183420d"
integrity sha512-OUCkHOz7ehtNMYuZjNciXUfwTuz8vmF1MTbAy59ebf+ZBYZO5/tZKuChVWCX+uDo+4idJBpGltNfV8st+HwsGw== integrity sha512-OUCkHOz7ehtNMYuZjNciXUfwTuz8vmF1MTbAy59ebf+ZBYZO5/tZKuChVWCX+uDo+4idJBpGltNfV8st+HwsGw==
monaco-editor-webpack-plugin@^1.9.1: monaco-editor-webpack-plugin@^4.0.0:
version "1.9.1" version "4.0.0"
resolved "https://registry.yarnpkg.com/monaco-editor-webpack-plugin/-/monaco-editor-webpack-plugin-1.9.1.tgz#eb4bbb1c5e5bfb554541c1ae1542e74c2a9f43fd" resolved "https://registry.yarnpkg.com/monaco-editor-webpack-plugin/-/monaco-editor-webpack-plugin-4.0.0.tgz#95be3f48f4220999b909266a9997727f0deab947"
integrity sha512-x7fx1w3i/uwZERIgztHAAK3VQMsL8+ku0lFXXbO81hKDg8IieACqjGEa2mqEueg0c/fX+wd0oI+75wB19KJAsA== integrity sha512-4BT9XDRQXraMQjxEUjR+uuubRe3RIPkvVoGw8zwWG++s7wq6TAiXaSOMdkdS9TrjCREgSnygCOlVzY6MS8RPuA==
dependencies: dependencies:
loader-utils "^1.2.3" loader-utils "^2.0.0"
monaco-editor@0.20.0, monaco-editor@^0.20.0: monaco-editor@0.24.0:
version "0.20.0" version "0.24.0"
resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.20.0.tgz#5d5009343a550124426cb4d965a4d27a348b4dea" resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.24.0.tgz#990b55096bcc95d08d8d28e55264c6eb17707269"
integrity sha512-hkvf4EtPJRMQlPC3UbMoRs0vTAFAYdzFQ+gpMb8A+9znae1c43q8Mab9iVsgTcg/4PNiLGGn3SlDIa8uvK1FIQ== integrity sha512-o1f0Lz6ABFNTtnEqqqvlY9qzNx24rQZx1RgYNQ8SkWkE+Ka63keHH/RqxQ4QhN4fs/UYOnvAtEUZsPrzccH++A==
monaco-editor@^0.25.2:
version "0.25.2"
resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.25.2.tgz#119e2b15bbd968a1a99c03cac9c329316d7c37e9"
integrity sha512-5iylzSJevCnzJn9UVsW8yOZ3yHjmAs4TfvH3zsbftKiFKmHG0xirGN6DK9Kk04VSWxYCZZAIafYJoNJJMAU1KA==
monaco-yaml@^2.5.1: monaco-yaml@^2.5.1:
version "2.5.1" version "2.5.1"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment