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:
vscode:
extensions:
- rebornix.ruby@0.27.0:QyGBeRyslOfdRgOPRGm6PQ==
- wingrunr21.vscode-ruby@0.27.0:beIqQUhLRuJ5Vao4B2Lyng==
- karunamurti.haml@1.1.0:twCwOYt3/Ttfb3+iwblPDA==
- octref.vetur@0.25.0:UofirBhedyhdx/jCnPeJDg==
- dbaeumer.vscode-eslint@2.1.3:1NRvj3UKNTNwmYjptmUmIw==
- GitLab.gitlab-workflow@3.3.0:50q1byIi4M01G9qrTCCAYQ==
- rebornix.ruby@0.28.0
- wingrunr21.vscode-ruby@0.27.0
- karunamurti.haml@1.3.1
- octref.vetur@0.34.1
- dbaeumer.vscode-eslint@2.1.8
- gitlab.gitlab-workflow@3.24.0
......@@ -2,6 +2,23 @@
documentation](doc/development/changelog.md) for instructions on adding your own
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)
### Added (1 change)
......
......@@ -398,7 +398,9 @@ module.exports = {
new VueLoaderPlugin(),
// automatically configure monaco editor web workers
new MonacoWebpackPlugin(),
new MonacoWebpackPlugin({
globalAPI: true,
}),
// fix legacy jQuery plugins which depend on globals
new webpack.ProvidePlugin({
......
......@@ -118,19 +118,12 @@ export default {
};
},
},
mounted() {
this.setChartEnabled({
chartKey: chartKeys.scatterplot,
isEnabled: this.isScatterplotFeatureEnabled(),
});
},
methods: {
...mapActions('charts', [
'fetchChartData',
'setMetricType',
'updateSelectedItems',
'resetMainChartSelection',
'setChartEnabled',
]),
...mapActions('table', ['setSortField', 'setPage', 'toggleSortOrder', 'setColumnMetric']),
onMainChartItemClicked({ params }) {
......@@ -148,9 +141,6 @@ export default {
...this.getColumnChartDatazoomOption(chartKey),
};
},
isScatterplotFeatureEnabled() {
return this.glFeatures.productivityAnalyticsScatterplotEnabled;
},
},
};
</script>
......
......@@ -16,9 +16,6 @@ class Groups::Analytics::ProductivityAnalyticsController < Groups::Analytics::Ap
before_action -> {
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? }
......
---
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', () => {
const mainChartData = { 1: 2, 2: 3 };
const createComponent = ({ props = {}, options = {}, scatterplotEnabled = true } = {}) => {
const createComponent = ({ props = {}, options = {} } = {}) => {
const {
modules: { charts, table, ...modules },
...storeConfig
......@@ -82,9 +82,6 @@ describe('ProductivityApp component', () => {
...propsData,
...props,
},
provide: {
glFeatures: { productivityAnalyticsScatterplotEnabled: scatterplotEnabled },
},
...options,
});
......@@ -330,75 +327,55 @@ describe('ProductivityApp component', () => {
});
describe('Scatterplot', () => {
describe('when the feature flag is enabled', () => {
it('isScatterplotFeatureEnabled returns true', () => {
expect(wrapper.vm.isScatterplotFeatureEnabled()).toBe(true);
});
it('renders a metric chart component', () => {
expect(findScatterplotMetricChart().exists()).toBe(true);
});
it('renders a metric chart component', () => {
expect(findScatterplotMetricChart().exists()).toBe(true);
});
describe('when chart finished loading', () => {
describe('and the chart has data', () => {
beforeEach(() => {
mockStore.dispatch('charts/receiveChartDataSuccess', {
chartKey: chartKeys.scatterplot,
data: {
1: { metric: 2, merged_at: '2019-09-01T07:06:23.193Z' },
2: { metric: 3, merged_at: '2019-09-05T08:27:42.411Z' },
},
transformedData: [
[{ metric: 2, merged_at: '2019-09-01T07:06:23.193Z' }],
[{ metric: 3, merged_at: '2019-09-05T08:27:42.411Z' }],
],
});
describe('when chart finished loading', () => {
describe('and the chart has data', () => {
beforeEach(() => {
mockStore.dispatch('charts/receiveChartDataSuccess', {
chartKey: chartKeys.scatterplot,
data: {
1: { metric: 2, merged_at: '2019-09-01T07:06:23.193Z' },
2: { metric: 3, merged_at: '2019-09-05T08:27:42.411Z' },
},
transformedData: [
[{ metric: 2, merged_at: '2019-09-01T07:06:23.193Z' }],
[{ metric: 3, merged_at: '2019-09-05T08:27:42.411Z' }],
],
});
});
it('sets isLoading=false on the metric chart', () => {
expect(findScatterplotMetricChart().props('isLoading')).toBe(false);
});
it('sets isLoading=false on the metric chart', () => {
expect(findScatterplotMetricChart().props('isLoading')).toBe(false);
});
it('passes non-empty chartData to the metric chart', () => {
expect(findScatterplotMetricChart().props('chartData')).not.toEqual([]);
});
it('passes non-empty chartData to the metric chart', () => {
expect(findScatterplotMetricChart().props('chartData')).not.toEqual([]);
});
describe('when the user changes the metric', () => {
beforeEach(() => {
jest.spyOn(mockStore, 'dispatch');
findScatterplotMetricChart().vm.$emit('metricTypeChange', 'loc_per_commit');
return wrapper.vm.$nextTick();
});
describe('when the user changes the metric', () => {
beforeEach(() => {
jest.spyOn(mockStore, 'dispatch');
findScatterplotMetricChart().vm.$emit('metricTypeChange', 'loc_per_commit');
return wrapper.vm.$nextTick();
});
it('should call setMetricType when `metricTypeChange` is emitted on the metric chart', () => {
expect(mockStore.dispatch).toHaveBeenCalledWith('charts/setMetricType', {
metricType: 'loc_per_commit',
chartKey: chartKeys.scatterplot,
});
it('should call setMetricType when `metricTypeChange` is emitted on the metric chart', () => {
expect(mockStore.dispatch).toHaveBeenCalledWith('charts/setMetricType', {
metricType: 'loc_per_commit',
chartKey: chartKeys.scatterplot,
});
});
it("should update the chart's y axis label", () => {
const scatterplot = findScatterplotMetricChart().find(Scatterplot);
expect(scatterplot.props('yAxisTitle')).toBe('Number of LOCs per commit');
});
it("should update the chart's y axis label", () => {
const scatterplot = findScatterplotMetricChart().find(Scatterplot);
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', () => {
......
......@@ -144,8 +144,8 @@
"mathjax": "3",
"mermaid": "^8.10.2",
"minimatch": "^3.0.4",
"monaco-editor": "^0.20.0",
"monaco-editor-webpack-plugin": "^1.9.1",
"monaco-editor": "^0.25.2",
"monaco-editor-webpack-plugin": "^4.0.0",
"monaco-yaml": "^2.5.1",
"mousetrap": "1.6.5",
"pdfjs-dist": "^2.0.943",
......@@ -263,7 +263,7 @@
},
"resolutions": {
"chokidar": "^3.4.0",
"monaco-editor": "0.20.0"
"monaco-editor": "0.24.0"
},
"engines": {
"node": ">=10.13.0",
......
......@@ -246,7 +246,7 @@ describe('Base editor', () => {
let editorEl2;
let inst1;
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(() => {
setFixtures('<div id="editor1"></div><div id="editor2"></div>');
......
......@@ -67,6 +67,24 @@ class CustomEnvironment extends JSDOMEnvironment {
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 {
/* eslint-disable no-useless-constructor, no-unused-vars, no-empty-function, class-methods-use-this */
constructor(callback) {}
......
......@@ -7,6 +7,7 @@ import {
screen,
findByText,
} from '@testing-library/dom';
import { editor as monacoEditor } from 'monaco-editor';
const isFolderRowOpen = (row) => row.matches('.folder.is-open');
......@@ -23,7 +24,10 @@ export const switchLeftSidebarTab = (name) => {
export const getStatusBar = () => document.querySelector('.ide-status-bar');
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) =>
new Promise((resolve) => instance.onDidChangeModel(resolve));
......@@ -38,14 +42,14 @@ export const findAndSetEditorValue = async (value) => {
const editor = await findMonacoEditor();
const uri = editor.getAttribute('data-uri');
window.monaco.editor.getModel(uri).setValue(value);
monacoEditor.getModel(uri).setValue(value);
};
export const getEditorValue = async () => {
const editor = await findMonacoEditor();
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');
......
......@@ -8560,17 +8560,22 @@ moment-mini@^2.22.1:
resolved "https://registry.yarnpkg.com/moment-mini/-/moment-mini-2.22.1.tgz#bc32d73e43a4505070be6b53494b17623183420d"
integrity sha512-OUCkHOz7ehtNMYuZjNciXUfwTuz8vmF1MTbAy59ebf+ZBYZO5/tZKuChVWCX+uDo+4idJBpGltNfV8st+HwsGw==
monaco-editor-webpack-plugin@^1.9.1:
version "1.9.1"
resolved "https://registry.yarnpkg.com/monaco-editor-webpack-plugin/-/monaco-editor-webpack-plugin-1.9.1.tgz#eb4bbb1c5e5bfb554541c1ae1542e74c2a9f43fd"
integrity sha512-x7fx1w3i/uwZERIgztHAAK3VQMsL8+ku0lFXXbO81hKDg8IieACqjGEa2mqEueg0c/fX+wd0oI+75wB19KJAsA==
monaco-editor-webpack-plugin@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/monaco-editor-webpack-plugin/-/monaco-editor-webpack-plugin-4.0.0.tgz#95be3f48f4220999b909266a9997727f0deab947"
integrity sha512-4BT9XDRQXraMQjxEUjR+uuubRe3RIPkvVoGw8zwWG++s7wq6TAiXaSOMdkdS9TrjCREgSnygCOlVzY6MS8RPuA==
dependencies:
loader-utils "^1.2.3"
loader-utils "^2.0.0"
monaco-editor@0.20.0, monaco-editor@^0.20.0:
version "0.20.0"
resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.20.0.tgz#5d5009343a550124426cb4d965a4d27a348b4dea"
integrity sha512-hkvf4EtPJRMQlPC3UbMoRs0vTAFAYdzFQ+gpMb8A+9znae1c43q8Mab9iVsgTcg/4PNiLGGn3SlDIa8uvK1FIQ==
monaco-editor@0.24.0:
version "0.24.0"
resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.24.0.tgz#990b55096bcc95d08d8d28e55264c6eb17707269"
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:
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