summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-08-06 09:09:42 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-08-06 09:09:42 +0000
commitdeb069c0c1afe18cb4ce3a94623272628e11674e (patch)
tree0d6141fc4b1e60233f4b561082ee8576743b5eb7
parent145295d7b3390c14bd5766ae95f00c4acf290f23 (diff)
downloadgitlab-ce-deb069c0c1afe18cb4ce3a94623272628e11674e.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--GITALY_SERVER_VERSION2
-rw-r--r--app/assets/javascripts/alert_management/components/alert_management_table.vue5
-rw-r--r--app/assets/javascripts/incidents/components/incidents_list.vue38
-rw-r--r--app/assets/javascripts/incidents/constants.js4
-rw-r--r--app/assets/javascripts/incidents/graphql/queries/get_incidents.query.graphql2
-rw-r--r--app/assets/javascripts/monitoring/components/dashboard_panel_builder.vue9
-rw-r--r--app/assets/javascripts/monitoring/components/dashboards_dropdown.vue54
-rw-r--r--app/assets/javascripts/monitoring/requests/index.js9
-rw-r--r--app/assets/javascripts/monitoring/stores/actions.js50
-rw-r--r--app/assets/javascripts/monitoring/stores/mutation_types.js6
-rw-r--r--app/assets/javascripts/monitoring/stores/mutations.js46
-rw-r--r--app/assets/stylesheets/pages/incident_management_list.scss22
-rw-r--r--app/assets/stylesheets/pages/prometheus.scss3
-rw-r--r--changelogs/unreleased/229534-column-sort.yml5
-rw-r--r--locale/gitlab.pot30
-rw-r--r--package.json6
-rw-r--r--spec/frontend/incidents/components/incidents_list_spec.js22
-rw-r--r--spec/frontend/monitoring/components/dashboards_dropdown_spec.js30
-rw-r--r--spec/frontend/monitoring/graph_data.js27
-rw-r--r--spec/frontend/monitoring/store/actions_spec.js63
-rw-r--r--spec/frontend/monitoring/store/mutations_spec.js111
-rw-r--r--spec/requests/api/graphql/project/packages_spec.rb50
-rw-r--r--yarn.lock91
23 files changed, 465 insertions, 220 deletions
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION
index 5ba3ab3e11b..f729df9c13e 100644
--- a/GITALY_SERVER_VERSION
+++ b/GITALY_SERVER_VERSION
@@ -1 +1 @@
-0f3b4b0b121f611fac2a613ec0273864d5f38c8b
+9e5dfd987388c905b584f58b48afede245721ec7
diff --git a/app/assets/javascripts/alert_management/components/alert_management_table.vue b/app/assets/javascripts/alert_management/components/alert_management_table.vue
index bd3d0c11022..ff0834ed532 100644
--- a/app/assets/javascripts/alert_management/components/alert_management_table.vue
+++ b/app/assets/javascripts/alert_management/components/alert_management_table.vue
@@ -332,7 +332,10 @@ export default {
<p v-html="errorMessage || $options.i18n.errorMsg"></p>
</gl-alert>
- <gl-tabs content-class="gl-p-0" @input="filterAlertsByStatus">
+ <gl-tabs
+ content-class="gl-p-0 gl-border-b-solid gl-border-b-1 gl-border-gray-100"
+ @input="filterAlertsByStatus"
+ >
<gl-tab v-for="tab in $options.statusTabs" :key="tab.status">
<template slot="title">
<span>{{ tab.title }}</span>
diff --git a/app/assets/javascripts/incidents/components/incidents_list.vue b/app/assets/javascripts/incidents/components/incidents_list.vue
index 3291f2aa8b6..f570aa87b6e 100644
--- a/app/assets/javascripts/incidents/components/incidents_list.vue
+++ b/app/assets/javascripts/incidents/components/incidents_list.vue
@@ -14,13 +14,15 @@ import {
GlTabs,
GlTab,
} from '@gitlab/ui';
-import { debounce, trim } from 'lodash';
+import { debounce } from 'lodash';
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
+import { convertToSnakeCase } from '~/lib/utils/text_utility';
import { s__ } from '~/locale';
import { mergeUrlParams, joinPaths, visitUrl } from '~/lib/utils/url_utility';
import getIncidents from '../graphql/queries/get_incidents.query.graphql';
import { I18N, DEFAULT_PAGE_SIZE, INCIDENT_SEARCH_DELAY, INCIDENT_STATE_TABS } from '../constants';
+const TH_TEST_ID = { 'data-testid': 'incident-management-created-at-sort' };
const tdClass =
'table-col gl-display-flex d-md-table-cell gl-align-items-center gl-white-space-nowrap';
const thClass = 'gl-hover-bg-blue-50';
@@ -48,8 +50,10 @@ export default {
{
key: 'createdAt',
label: s__('IncidentManagement|Date created'),
- thClass: `${thClass} gl-pointer-events-none`,
- tdClass,
+ thClass,
+ tdClass: `${tdClass} sortable-cell`,
+ sortable: true,
+ thAttr: TH_TEST_ID,
},
{
key: 'assignees',
@@ -93,6 +97,7 @@ export default {
state: this.stateFilter,
projectPath: this.projectPath,
issueTypes: ['INCIDENT'],
+ sort: this.sort,
firstPageSize: this.pagination.firstPageSize,
lastPageSize: this.pagination.lastPageSize,
prevPageCursor: this.pagination.prevPageCursor,
@@ -119,6 +124,9 @@ export default {
pagination: initialPaginationState,
incidents: {},
stateFilter: '',
+ sort: 'created_desc',
+ sortBy: 'createdAt',
+ sortDesc: true,
};
},
computed: {
@@ -168,7 +176,7 @@ export default {
},
methods: {
onInputChange: debounce(function debounceSearch(input) {
- const trimmedInput = trim(input);
+ const trimmedInput = input.trim();
if (trimmedInput !== this.searchTerm) {
this.searchTerm = trimmedInput;
}
@@ -205,6 +213,12 @@ export default {
resetPagination() {
this.pagination = initialPaginationState;
},
+ fetchSortedData({ sortBy, sortDesc }) {
+ const sortingDirection = sortDesc ? 'desc' : 'asc';
+ const sortingColumn = convertToSnakeCase(sortBy).replace(/_.*/, '');
+
+ this.sort = `${sortingColumn}_${sortingDirection}`;
+ },
},
};
</script>
@@ -214,7 +228,9 @@ export default {
{{ $options.i18n.errorMsg }}
</gl-alert>
- <div class="incident-management-list-header gl-display-flex gl-justify-content-space-between">
+ <div
+ class="incident-management-list-header gl-display-flex gl-justify-content-space-between gl-border-b-solid gl-border-b-1 gl-border-gray-100"
+ >
<gl-tabs content-class="gl-p-0" @input="filterIncidentsByState">
<gl-tab v-for="tab in $options.stateTabs" :key="tab.state" :data-testid="tab.state">
<template #title>
@@ -224,7 +240,7 @@ export default {
</gl-tabs>
<gl-button
- class="gl-my-3 create-incident-button"
+ class="gl-my-3 gl-mr-5 create-incident-button"
data-testid="createIncidentBtn"
:loading="redirecting"
:disabled="redirecting"
@@ -257,16 +273,22 @@ export default {
stacked="md"
:tbody-tr-class="tbodyTrClass"
:no-local-sorting="true"
+ :sort-direction="'desc'"
+ :sort-desc.sync="sortDesc"
+ :sort-by.sync="sortBy"
+ sort-icon-left
fixed
@row-clicked="navigateToIncidentDetails"
+ @sort-changed="fetchSortedData"
>
<template #cell(title)="{ item }">
- <div class="gl-display-sm-flex gl-align-items-center">
+ <div class="incident-management-list-title gl-display-flex gl-align-items-center">
<div class="gl-max-w-full text-truncate" :title="item.title">{{ item.title }}</div>
<gl-icon
v-if="item.state === 'closed'"
name="issue-close"
- class="gl-ml-1 gl-fill-blue-500"
+ class="gl-mx-1 gl-fill-blue-500"
+ :size="16"
data-testid="incident-closed"
/>
</div>
diff --git a/app/assets/javascripts/incidents/constants.js b/app/assets/javascripts/incidents/constants.js
index 9908a04f9b5..fe92f131738 100644
--- a/app/assets/javascripts/incidents/constants.js
+++ b/app/assets/javascripts/incidents/constants.js
@@ -6,7 +6,7 @@ export const I18N = {
unassigned: s__('IncidentManagement|Unassigned'),
createIncidentBtnLabel: s__('IncidentManagement|Create incident'),
unPublished: s__('IncidentManagement|Unpublished'),
- searchPlaceholder: __('Search results...'),
+ searchPlaceholder: __('Search results…'),
};
export const INCIDENT_STATE_TABS = [
@@ -21,7 +21,7 @@ export const INCIDENT_STATE_TABS = [
filters: 'closed',
},
{
- title: s__('IncidentManagement|All incidents'),
+ title: s__('IncidentManagement|All'),
state: 'ALL',
filters: 'all',
},
diff --git a/app/assets/javascripts/incidents/graphql/queries/get_incidents.query.graphql b/app/assets/javascripts/incidents/graphql/queries/get_incidents.query.graphql
index 789086ab43c..6e8e6a1254c 100644
--- a/app/assets/javascripts/incidents/graphql/queries/get_incidents.query.graphql
+++ b/app/assets/javascripts/incidents/graphql/queries/get_incidents.query.graphql
@@ -1,6 +1,7 @@
query getIncidents(
$projectPath: ID!
$issueTypes: [IssueType!]
+ $sort: IssueSort
$state: IssuableState
$firstPageSize: Int
$lastPageSize: Int
@@ -13,6 +14,7 @@ query getIncidents(
search: $searchTerm
state: $state
types: $issueTypes
+ sort: $sort
first: $firstPageSize
last: $lastPageSize
after: $nextPageCursor
diff --git a/app/assets/javascripts/monitoring/components/dashboard_panel_builder.vue b/app/assets/javascripts/monitoring/components/dashboard_panel_builder.vue
index 1f878a113fe..4ff29cd581b 100644
--- a/app/assets/javascripts/monitoring/components/dashboard_panel_builder.vue
+++ b/app/assets/javascripts/monitoring/components/dashboard_panel_builder.vue
@@ -11,12 +11,13 @@ import {
} from '@gitlab/ui';
import DashboardPanel from './dashboard_panel.vue';
-const initialYml = `title:
-y_label:
+const initialYml = `title: Go heap size
type: area-chart
+y_axis:
+ format: 'bytes'
metrics:
-- query_range:
- label:
+ - metric_id: 'go_memstats_alloc_bytes_1'
+ query_range: 'go_memstats_alloc_bytes'
`;
export default {
diff --git a/app/assets/javascripts/monitoring/components/dashboards_dropdown.vue b/app/assets/javascripts/monitoring/components/dashboards_dropdown.vue
index 040fce1bec2..aed27b5ea51 100644
--- a/app/assets/javascripts/monitoring/components/dashboards_dropdown.vue
+++ b/app/assets/javascripts/monitoring/components/dashboards_dropdown.vue
@@ -2,10 +2,10 @@
import { mapState, mapGetters } from 'vuex';
import {
GlIcon,
- GlDeprecatedDropdown,
- GlDeprecatedDropdownItem,
- GlDeprecatedDropdownHeader,
- GlDeprecatedDropdownDivider,
+ GlNewDropdown,
+ GlNewDropdownItem,
+ GlNewDropdownHeader,
+ GlNewDropdownDivider,
GlSearchBoxByType,
GlModalDirective,
} from '@gitlab/ui';
@@ -17,10 +17,10 @@ const events = {
export default {
components: {
GlIcon,
- GlDeprecatedDropdown,
- GlDeprecatedDropdownItem,
- GlDeprecatedDropdownHeader,
- GlDeprecatedDropdownDivider,
+ GlNewDropdown,
+ GlNewDropdownItem,
+ GlNewDropdownHeader,
+ GlNewDropdownDivider,
GlSearchBoxByType,
},
directives: {
@@ -73,16 +73,13 @@ export default {
};
</script>
<template>
- <gl-deprecated-dropdown
+ <gl-new-dropdown
toggle-class="dropdown-menu-toggle"
menu-class="monitor-dashboard-dropdown-menu"
:text="selectedDashboardText"
>
<div class="d-flex flex-column overflow-hidden">
- <gl-deprecated-dropdown-header class="monitor-dashboard-dropdown-header text-center">{{
- __('Dashboard')
- }}</gl-deprecated-dropdown-header>
- <gl-deprecated-dropdown-divider />
+ <gl-new-dropdown-header>{{ __('Dashboard') }}</gl-new-dropdown-header>
<gl-search-box-by-type
ref="monitorDashboardsDropdownSearch"
v-model="searchTerm"
@@ -90,33 +87,36 @@ export default {
/>
<div class="flex-fill overflow-auto">
- <gl-deprecated-dropdown-item
+ <gl-new-dropdown-item
v-for="dashboard in starredDashboards"
:key="dashboard.path"
- :active="dashboard.path === selectedDashboardPath"
- active-class="is-active"
+ :is-check-item="true"
+ :is-checked="dashboard.path === selectedDashboardPath"
@click="selectDashboard(dashboard)"
>
- <div class="d-flex">
- {{ dashboardDisplayName(dashboard) }}
- <gl-icon class="text-muted ml-auto" name="star" />
+ <div class="gl-display-flex">
+ <div class="gl-flex-grow-1 gl-min-w-0">
+ <div class="gl-word-break-all">
+ {{ dashboardDisplayName(dashboard) }}
+ </div>
+ </div>
+ <gl-icon class="text-muted gl-flex-shrink-0" name="star" />
</div>
- </gl-deprecated-dropdown-item>
-
- <gl-deprecated-dropdown-divider
+ </gl-new-dropdown-item>
+ <gl-new-dropdown-divider
v-if="starredDashboards.length && nonStarredDashboards.length"
ref="starredListDivider"
/>
- <gl-deprecated-dropdown-item
+ <gl-new-dropdown-item
v-for="dashboard in nonStarredDashboards"
:key="dashboard.path"
- :active="dashboard.path === selectedDashboardPath"
- active-class="is-active"
+ :is-check-item="true"
+ :is-checked="dashboard.path === selectedDashboardPath"
@click="selectDashboard(dashboard)"
>
{{ dashboardDisplayName(dashboard) }}
- </gl-deprecated-dropdown-item>
+ </gl-new-dropdown-item>
</div>
<div
@@ -127,5 +127,5 @@ export default {
{{ __('No matching results') }}
</div>
</div>
- </gl-deprecated-dropdown>
+ </gl-new-dropdown>
</template>
diff --git a/app/assets/javascripts/monitoring/requests/index.js b/app/assets/javascripts/monitoring/requests/index.js
index 962620862e6..2be8048327f 100644
--- a/app/assets/javascripts/monitoring/requests/index.js
+++ b/app/assets/javascripts/monitoring/requests/index.js
@@ -41,12 +41,3 @@ export const getPrometheusQueryData = (prometheusEndpoint, params) =>
}
throw error;
});
-
-// eslint-disable-next-line no-unused-vars
-export function getPanelJson(panelPreviewEndpoint, panelPreviewYml) {
- // TODO Use a real backend when it's available
- // https://gitlab.com/gitlab-org/gitlab/-/issues/228758
-
- // eslint-disable-next-line @gitlab/require-i18n-strings
- return Promise.reject(new Error('API Not implemented.'));
-}
diff --git a/app/assets/javascripts/monitoring/stores/actions.js b/app/assets/javascripts/monitoring/stores/actions.js
index a569eec6f91..509f8edeb2f 100644
--- a/app/assets/javascripts/monitoring/stores/actions.js
+++ b/app/assets/javascripts/monitoring/stores/actions.js
@@ -15,7 +15,8 @@ import getAnnotations from '../queries/getAnnotations.query.graphql';
import getDashboardValidationWarnings from '../queries/getDashboardValidationWarnings.query.graphql';
import { convertObjectPropsToCamelCase } from '../../lib/utils/common_utils';
import { s__, sprintf } from '../../locale';
-import { getDashboard, getPrometheusQueryData, getPanelJson } from '../requests';
+import { getDashboard, getPrometheusQueryData } from '../requests';
+import { defaultTimeRange } from '~/vue_shared/constants';
import { ENVIRONMENT_AVAILABLE_STATE, OVERVIEW_DASHBOARD_PATH, VARIABLE_TYPES } from '../constants';
@@ -33,6 +34,20 @@ function prometheusMetricQueryParams(timeRange) {
};
}
+/**
+ * Extract error messages from API or HTTP request errors.
+ *
+ * - API errors are in `error.response.data.message`
+ * - HTTP (axios) errors are in `error.messsage`
+ *
+ * @param {Object} error
+ * @returns {String} User friendly error message
+ */
+function extractErrorMessage(error) {
+ const message = error?.response?.data?.message;
+ return message ?? error.message;
+}
+
// Setup
export const setGettingStartedEmptyState = ({ commit }) => {
@@ -482,21 +497,38 @@ export const fetchPanelPreview = ({ state, commit, dispatch }, panelPreviewYml)
}
commit(types.REQUEST_PANEL_PREVIEW, panelPreviewYml);
- return getPanelJson(state.panelPreviewEndpoint, panelPreviewYml)
- .then(data => {
+ return axios
+ .post(state.panelPreviewEndpoint, { panel_yaml: panelPreviewYml })
+ .then(({ data }) => {
commit(types.RECEIVE_PANEL_PREVIEW_SUCCESS, data);
dispatch('fetchPanelPreviewMetrics');
})
.catch(error => {
- commit(types.RECEIVE_PANEL_PREVIEW_FAILURE, error);
+ commit(types.RECEIVE_PANEL_PREVIEW_FAILURE, extractErrorMessage(error));
});
};
-export const fetchPanelPreviewMetrics = () => {
- // TODO Use a axios mock instead of spy when backend is implemented
- // https://gitlab.com/gitlab-org/gitlab/-/issues/228758
+export const fetchPanelPreviewMetrics = ({ state, commit }) => {
+ const defaultQueryParams = prometheusMetricQueryParams(defaultTimeRange);
+
+ state.panelPreviewGraphData.metrics.forEach((metric, index) => {
+ commit(types.REQUEST_PANEL_PREVIEW_METRIC_RESULT, { index });
- // eslint-disable-next-line @gitlab/require-i18n-strings
- throw new Error('Not implemented');
+ const params = { ...defaultQueryParams };
+ if (metric.step) {
+ params.step = metric.step;
+ }
+ return getPrometheusQueryData(metric.prometheusEndpointPath, params)
+ .then(data => {
+ commit(types.RECEIVE_PANEL_PREVIEW_METRIC_RESULT_SUCCESS, { index, data });
+ })
+ .catch(error => {
+ Sentry.captureException(error);
+
+ commit(types.RECEIVE_PANEL_PREVIEW_METRIC_RESULT_FAILURE, { index, error });
+ // Continue to throw error so the panel builder can notify using createFlash
+ throw error;
+ });
+ });
};
diff --git a/app/assets/javascripts/monitoring/stores/mutation_types.js b/app/assets/javascripts/monitoring/stores/mutation_types.js
index 657ceea8644..ccb2b075012 100644
--- a/app/assets/javascripts/monitoring/stores/mutation_types.js
+++ b/app/assets/javascripts/monitoring/stores/mutation_types.js
@@ -51,3 +51,9 @@ export const SET_EXPANDED_PANEL = 'SET_EXPANDED_PANEL';
export const REQUEST_PANEL_PREVIEW = 'REQUEST_PANEL_PREVIEW';
export const RECEIVE_PANEL_PREVIEW_SUCCESS = 'RECEIVE_PANEL_PREVIEW_SUCCESS';
export const RECEIVE_PANEL_PREVIEW_FAILURE = 'RECEIVE_PANEL_PREVIEW_FAILURE';
+
+export const REQUEST_PANEL_PREVIEW_METRIC_RESULT = 'REQUEST_PANEL_PREVIEW_METRIC_RESULT';
+export const RECEIVE_PANEL_PREVIEW_METRIC_RESULT_SUCCESS =
+ 'RECEIVE_PANEL_PREVIEW_METRIC_RESULT_SUCCESS';
+export const RECEIVE_PANEL_PREVIEW_METRIC_RESULT_FAILURE =
+ 'RECEIVE_PANEL_PREVIEW_METRIC_RESULT_FAILURE';
diff --git a/app/assets/javascripts/monitoring/stores/mutations.js b/app/assets/javascripts/monitoring/stores/mutations.js
index d71b9eaa928..5fe005be40e 100644
--- a/app/assets/javascripts/monitoring/stores/mutations.js
+++ b/app/assets/javascripts/monitoring/stores/mutations.js
@@ -53,6 +53,14 @@ const emptyStateFromError = error => {
return metricStates.UNKNOWN_ERROR;
};
+export const metricStateFromData = data => {
+ if (data?.result?.length) {
+ const result = normalizeQueryResponseData(data);
+ return { state: metricStates.OK, result: Object.freeze(result) };
+ }
+ return { state: metricStates.NO_DATA, result: null };
+};
+
export default {
/**
* Dashboard panels structure and global state
@@ -154,17 +162,11 @@ export default {
},
[types.RECEIVE_METRIC_RESULT_SUCCESS](state, { metricId, data }) {
const metric = findMetricInDashboard(metricId, state.dashboard);
- metric.loading = false;
-
- if (!data.result || data.result.length === 0) {
- metric.state = metricStates.NO_DATA;
- metric.result = null;
- } else {
- const result = normalizeQueryResponseData(data);
+ const metricState = metricStateFromData(data);
- metric.state = metricStates.OK;
- metric.result = Object.freeze(result);
- }
+ metric.loading = false;
+ metric.state = metricState.state;
+ metric.result = metricState.result;
},
[types.RECEIVE_METRIC_RESULT_FAILURE](state, { metricId, error }) {
const metric = findMetricInDashboard(metricId, state.dashboard);
@@ -238,4 +240,28 @@ export default {
state.panelPreviewGraphData = null;
state.panelPreviewError = error;
},
+
+ [types.REQUEST_PANEL_PREVIEW_METRIC_RESULT](state, { index }) {
+ const metric = state.panelPreviewGraphData.metrics[index];
+
+ metric.loading = true;
+ if (!metric.result) {
+ metric.state = metricStates.LOADING;
+ }
+ },
+ [types.RECEIVE_PANEL_PREVIEW_METRIC_RESULT_SUCCESS](state, { index, data }) {
+ const metric = state.panelPreviewGraphData.metrics[index];
+ const metricState = metricStateFromData(data);
+
+ metric.loading = false;
+ metric.state = metricState.state;
+ metric.result = metricState.result;
+ },
+ [types.RECEIVE_PANEL_PREVIEW_METRIC_RESULT_FAILURE](state, { index, error }) {
+ const metric = state.panelPreviewGraphData.metrics[index];
+
+ metric.loading = false;
+ metric.state = emptyStateFromError(error);
+ metric.result = null;
+ },
};
diff --git a/app/assets/stylesheets/pages/incident_management_list.scss b/app/assets/stylesheets/pages/incident_management_list.scss
index 5d1594ddf26..c2f36978409 100644
--- a/app/assets/stylesheets/pages/incident_management_list.scss
+++ b/app/assets/stylesheets/pages/incident_management_list.scss
@@ -76,23 +76,31 @@
}
}
}
+
+ .incident-management-list-title {
+ @include gl-flex-direction-row-reverse;
+ }
}
}
- .gl-tab-nav-item {
- color: $gl-gray-600;
+ .gl-tabs-nav {
+ border-bottom-width: 0;
+
+ .gl-tab-nav-item {
+ color: $gl-gray-600;
- > .gl-tab-counter-badge {
- color: inherit;
- @include gl-font-sm;
- background-color: $white-normal;
+ > .gl-tab-counter-badge {
+ color: inherit;
+ @include gl-font-sm;
+ background-color: $gray-50;
+ }
}
}
@include media-breakpoint-down(xs) {
.incident-management-list-header {
flex-direction: column-reverse;
- };
+ }
.create-incident-button {
@include gl-w-full;
diff --git a/app/assets/stylesheets/pages/prometheus.scss b/app/assets/stylesheets/pages/prometheus.scss
index cc5a63c512f..0ecc1d57496 100644
--- a/app/assets/stylesheets/pages/prometheus.scss
+++ b/app/assets/stylesheets/pages/prometheus.scss
@@ -63,8 +63,7 @@
}
.prometheus-graphs-header {
- .monitor-environment-dropdown-header header,
- .monitor-dashboard-dropdown-header header {
+ .monitor-environment-dropdown-header header {
font-size: $gl-font-size;
}
diff --git a/changelogs/unreleased/229534-column-sort.yml b/changelogs/unreleased/229534-column-sort.yml
new file mode 100644
index 00000000000..807196d4f1f
--- /dev/null
+++ b/changelogs/unreleased/229534-column-sort.yml
@@ -0,0 +1,5 @@
+---
+title: Add sorting by date for incident list
+merge_request: 38178
+author:
+type: changed
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 540ffe815d9..100f697c15b 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -10269,6 +10269,11 @@ msgstr ""
msgid "Feature flag was successfully removed."
msgstr ""
+msgid "FeatureFlags|%d user"
+msgid_plural "FeatureFlags|%d users"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "FeatureFlags|* (All Environments)"
msgstr ""
@@ -10284,6 +10289,12 @@ msgstr ""
msgid "FeatureFlags|Add strategy"
msgstr ""
+msgid "FeatureFlags|All Environments"
+msgstr ""
+
+msgid "FeatureFlags|All Users"
+msgstr ""
+
msgid "FeatureFlags|All users"
msgstr ""
@@ -10398,6 +10409,9 @@ msgstr ""
msgid "FeatureFlags|New list"
msgstr ""
+msgid "FeatureFlags|Percent of users"
+msgstr ""
+
msgid "FeatureFlags|Percent rollout (logged in users)"
msgstr ""
@@ -10440,6 +10454,9 @@ msgstr ""
msgid "FeatureFlags|User IDs"
msgstr ""
+msgid "FeatureFlags|User List"
+msgstr ""
+
msgid "FeatureFlag|Delete strategy"
msgstr ""
@@ -12811,7 +12828,7 @@ msgstr ""
msgid "Incident Management Limits"
msgstr ""
-msgid "IncidentManagement|All incidents"
+msgid "IncidentManagement|All"
msgstr ""
msgid "IncidentManagement|Assignees"
@@ -21108,7 +21125,7 @@ msgstr ""
msgid "Search requirements"
msgstr ""
-msgid "Search results..."
+msgid "Search results…"
msgstr ""
msgid "Search users"
@@ -21410,15 +21427,9 @@ msgstr ""
msgid "SecurityReports|No vulnerabilities found for this pipeline"
msgstr ""
-msgid "SecurityReports|No vulnerabilities found for this project"
-msgstr ""
-
msgid "SecurityReports|Oops, something doesn't seem right."
msgstr ""
-msgid "SecurityReports|Pipeline %{pipelineLink} triggered %{timeago} by %{user}"
-msgstr ""
-
msgid "SecurityReports|Project"
msgstr ""
@@ -21512,9 +21523,6 @@ msgstr ""
msgid "SecurityReports|While it's rare to have no vulnerabilities for your pipeline, it can happen. In any event, we ask that you double check your settings to make sure all security scanning jobs have passed successfully."
msgstr ""
-msgid "SecurityReports|While it's rare to have no vulnerabilities for your project, it can happen. In any event, we ask that you double check your settings to make sure you've set up your dashboard correctly."
-msgstr ""
-
msgid "SecurityReports|While it's rare to have no vulnerabilities, it can happen. In any event, we ask that you double check your settings to make sure you've set up your dashboard correctly."
msgstr ""
diff --git a/package.json b/package.json
index 32afade73a5..a8e10279796 100644
--- a/package.json
+++ b/package.json
@@ -42,8 +42,8 @@
"@babel/plugin-syntax-import-meta": "^7.10.1",
"@babel/preset-env": "^7.10.1",
"@gitlab/at.js": "1.5.5",
- "@gitlab/svgs": "1.156.0",
- "@gitlab/ui": "18.0.0",
+ "@gitlab/svgs": "1.157.0",
+ "@gitlab/ui": "18.1.0",
"@gitlab/visual-review-tools": "1.6.1",
"@rails/actioncable": "^6.0.3-1",
"@sentry/browser": "^5.10.2",
@@ -198,7 +198,7 @@
"karma-mocha-reporter": "^2.2.5",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^4.0.2",
- "markdownlint-cli": "0.18.0",
+ "markdownlint-cli": "0.23.2",
"md5": "^2.2.1",
"node-sass": "^4.12.0",
"nodemon": "^2.0.4",
diff --git a/spec/frontend/incidents/components/incidents_list_spec.js b/spec/frontend/incidents/components/incidents_list_spec.js
index 7956a8e07a0..ec42df0b0c3 100644
--- a/spec/frontend/incidents/components/incidents_list_spec.js
+++ b/spec/frontend/incidents/components/incidents_list_spec.js
@@ -30,9 +30,11 @@ describe('Incidents List', () => {
const findAlert = () => wrapper.find(GlAlert);
const findLoader = () => wrapper.find(GlLoadingIcon);
const findTimeAgo = () => wrapper.findAll(TimeAgoTooltip);
+ const findDateColumnHeader = () =>
+ wrapper.find('[data-testid="incident-management-created-at-sort"]');
+ const findSearch = () => wrapper.find(GlSearchBoxByType);
const findAssingees = () => wrapper.findAll('[data-testid="incident-assignees"]');
const findCreateIncidentBtn = () => wrapper.find('[data-testid="createIncidentBtn"]');
- const findSearch = () => wrapper.find(GlSearchBoxByType);
const findClosedIcon = () => wrapper.findAll("[data-testid='incident-closed']");
const findPagination = () => wrapper.find(GlPagination);
const findStatusFilterTabs = () => wrapper.findAll(GlTab);
@@ -304,4 +306,22 @@ describe('Incidents List', () => {
});
});
});
+
+ describe('sorting the incident list by column', () => {
+ beforeEach(() => {
+ mountComponent({
+ data: { incidents: mockIncidents },
+ loading: false,
+ });
+ });
+
+ it('updates sort with new direction and column key', () => {
+ expect(findDateColumnHeader().attributes('aria-sort')).toBe('descending');
+
+ findDateColumnHeader().trigger('click');
+ return wrapper.vm.$nextTick(() => {
+ expect(findDateColumnHeader().attributes('aria-sort')).toBe('ascending');
+ });
+ });
+ });
});
diff --git a/spec/frontend/monitoring/components/dashboards_dropdown_spec.js b/spec/frontend/monitoring/components/dashboards_dropdown_spec.js
index cc1849b4426..89adbad386f 100644
--- a/spec/frontend/monitoring/components/dashboards_dropdown_spec.js
+++ b/spec/frontend/monitoring/components/dashboards_dropdown_spec.js
@@ -1,5 +1,5 @@
import { shallowMount } from '@vue/test-utils';
-import { GlDeprecatedDropdownItem, GlIcon } from '@gitlab/ui';
+import { GlNewDropdownItem, GlIcon } from '@gitlab/ui';
import DashboardsDropdown from '~/monitoring/components/dashboards_dropdown.vue';
@@ -22,7 +22,7 @@ describe('DashboardsDropdown', () => {
},
};
- return shallowMount(DashboardsDropdown, {
+ wrapper = shallowMount(DashboardsDropdown, {
propsData: {
...props,
defaultBranch,
@@ -33,8 +33,8 @@ describe('DashboardsDropdown', () => {
});
}
- const findItems = () => wrapper.findAll(GlDeprecatedDropdownItem);
- const findItemAt = i => wrapper.findAll(GlDeprecatedDropdownItem).at(i);
+ const findItems = () => wrapper.findAll(GlNewDropdownItem);
+ const findItemAt = i => wrapper.findAll(GlNewDropdownItem).at(i);
const findSearchInput = () => wrapper.find({ ref: 'monitorDashboardsDropdownSearch' });
const findNoItemsMsg = () => wrapper.find({ ref: 'monitorDashboardsDropdownMsg' });
const findStarredListDivider = () => wrapper.find({ ref: 'starredListDivider' });
@@ -47,7 +47,7 @@ describe('DashboardsDropdown', () => {
describe('when it receives dashboards data', () => {
beforeEach(() => {
- wrapper = createComponent();
+ createComponent();
});
it('displays an item for each dashboard', () => {
@@ -91,10 +91,22 @@ describe('DashboardsDropdown', () => {
});
});
+ describe('when a dashboard is selected', () => {
+ beforeEach(() => {
+ [mockSelectedDashboard] = starredDashboards;
+ createComponent();
+ });
+
+ it('dashboard item is selected', () => {
+ expect(findItemAt(0).props('isChecked')).toBe(true);
+ expect(findItemAt(1).props('isChecked')).toBe(false);
+ });
+ });
+
describe('when the dashboard is missing a display name', () => {
beforeEach(() => {
mockDashboards = dashboardGitResponse.map(d => ({ ...d, display_name: undefined }));
- wrapper = createComponent();
+ createComponent();
});
it('displays items with the dashboard path, with starred dashboards first', () => {
@@ -107,7 +119,7 @@ describe('DashboardsDropdown', () => {
describe('when it receives starred dashboards', () => {
beforeEach(() => {
mockDashboards = starredDashboards;
- wrapper = createComponent();
+ createComponent();
});
it('displays an item for each dashboard', () => {
@@ -128,7 +140,7 @@ describe('DashboardsDropdown', () => {
describe('when it receives only not-starred dashboards', () => {
beforeEach(() => {
mockDashboards = notStarredDashboards;
- wrapper = createComponent();
+ createComponent();
});
it('displays an item for each dashboard', () => {
@@ -147,7 +159,7 @@ describe('DashboardsDropdown', () => {
describe('when a dashboard gets selected by the user', () => {
beforeEach(() => {
- wrapper = createComponent();
+ createComponent();
findItemAt(1).vm.$emit('click');
});
diff --git a/spec/frontend/monitoring/graph_data.js b/spec/frontend/monitoring/graph_data.js
index fcdca95ac09..7e26db52132 100644
--- a/spec/frontend/monitoring/graph_data.js
+++ b/spec/frontend/monitoring/graph_data.js
@@ -7,6 +7,33 @@ const intervalSeconds = 120;
const makeValue = val => [initTime, val];
const makeValues = vals => vals.map((val, i) => [initTime + intervalSeconds * i, val]);
+// Raw Promethues Responses
+
+export const prometheusMatrixMultiResult = ({
+ values1 = ['1', '2', '3'],
+ values2 = ['4', '5', '6'],
+} = {}) => ({
+ resultType: 'matrix',
+ result: [
+ {
+ metric: {
+ __name__: 'up',
+ job: 'prometheus',
+ instance: 'localhost:9090',
+ },
+ values: makeValues(values1),
+ },
+ {
+ metric: {
+ __name__: 'up',
+ job: 'node',
+ instance: 'localhost:9091',
+ },
+ values: makeValues(values2),
+ },
+ ],
+});
+
// Normalized Prometheus Responses
const scalarResult = ({ value = '1' } = {}) =>
diff --git a/spec/frontend/monitoring/store/actions_spec.js b/spec/frontend/monitoring/store/actions_spec.js
index 4b7b733720c..b444ad14b0f 100644
--- a/spec/frontend/monitoring/store/actions_spec.js
+++ b/spec/frontend/monitoring/store/actions_spec.js
@@ -9,7 +9,6 @@ import { defaultTimeRange } from '~/vue_shared/constants';
import * as getters from '~/monitoring/stores/getters';
import { ENVIRONMENT_AVAILABLE_STATE } from '~/monitoring/constants';
import { backoffMockImplementation } from 'jest/helpers/backoff_helper';
-import * as requests from '~/monitoring/requests';
import { createStore } from '~/monitoring/stores';
import * as types from '~/monitoring/stores/mutation_types';
@@ -1158,54 +1157,64 @@ describe('Monitoring store actions', () => {
});
describe('fetchPanelPreview', () => {
+ const panelPreviewEndpoint = '/builder.json';
const mockYmlContent = 'mock yml content';
+ beforeEach(() => {
+ state.panelPreviewEndpoint = panelPreviewEndpoint;
+ });
+
it('should not commit or dispatch if payload is empty', () => {
testAction(fetchPanelPreview, '', state, [], []);
});
- it('should store the yml content and panel in the store and fetch corresponding metrics', () => {
+ it('should store the panel and fetch metric results', () => {
const mockPanel = {
- title: 'title',
+ title: 'Go heap size',
type: 'area-chart',
};
- // TODO Use a axios mock instead of spy when backend is implemented
- // https://gitlab.com/gitlab-org/gitlab/-/issues/228758
- jest.spyOn(requests, 'getPanelJson').mockResolvedValue(mockPanel);
+ mock
+ .onPost(panelPreviewEndpoint, { panel_yaml: mockYmlContent })
+ .reply(statusCodes.OK, mockPanel);
testAction(
fetchPanelPreview,
- 'mock yml content',
+ mockYmlContent,
state,
[
{ type: types.REQUEST_PANEL_PREVIEW, payload: mockYmlContent },
{ type: types.RECEIVE_PANEL_PREVIEW_SUCCESS, payload: mockPanel },
],
- [
- {
- type: 'fetchPanelPreviewMetrics',
- },
- ],
+ [{ type: 'fetchPanelPreviewMetrics' }],
);
});
- it('should commit a failure when backend fails', () => {
- const mockError = 'error';
- // TODO Use a axios mock instead of spy when backend is implemented
- // https://gitlab.com/gitlab-org/gitlab/-/issues/228758
- jest.spyOn(requests, 'getPanelJson').mockRejectedValue(mockError);
+ it('should display a validation error when the backend cannot process the yml', () => {
+ const mockErrorMsg = 'Each "metric" must define one of :query or :query_range';
- testAction(
- fetchPanelPreview,
- mockYmlContent,
- state,
- [
- { type: types.REQUEST_PANEL_PREVIEW, payload: mockYmlContent },
- { type: types.RECEIVE_PANEL_PREVIEW_FAILURE, payload: mockError },
- ],
- [],
- );
+ mock
+ .onPost(panelPreviewEndpoint, { panel_yaml: mockYmlContent })
+ .reply(statusCodes.UNPROCESSABLE_ENTITY, {
+ message: mockErrorMsg,
+ });
+
+ testAction(fetchPanelPreview, mockYmlContent, state, [
+ { type: types.REQUEST_PANEL_PREVIEW, payload: mockYmlContent },
+ { type: types.RECEIVE_PANEL_PREVIEW_FAILURE, payload: mockErrorMsg },
+ ]);
+ });
+
+ it('should display a generic error when the backend fails', () => {
+ mock.onPost(panelPreviewEndpoint, { panel_yaml: mockYmlContent }).reply(500);
+
+ testAction(fetchPanelPreview, mockYmlContent, state, [
+ { type: types.REQUEST_PANEL_PREVIEW, payload: mockYmlContent },
+ {
+ type: types.RECEIVE_PANEL_PREVIEW_FAILURE,
+ payload: 'Request failed with status code 500',
+ },
+ ]);
});
});
});
diff --git a/spec/frontend/monitoring/store/mutations_spec.js b/spec/frontend/monitoring/store/mutations_spec.js
index 8ffd23641a4..8d1351fc909 100644
--- a/spec/frontend/monitoring/store/mutations_spec.js
+++ b/spec/frontend/monitoring/store/mutations_spec.js
@@ -4,8 +4,8 @@ import mutations from '~/monitoring/stores/mutations';
import * as types from '~/monitoring/stores/mutation_types';
import state from '~/monitoring/stores/state';
import { dashboardEmptyStates, metricStates } from '~/monitoring/constants';
-
import { deploymentData, dashboardGitResponse, storeTextVariables } from '../mock_data';
+import { prometheusMatrixMultiResult } from '../graph_data';
import { metricsDashboardPayload } from '../fixture_data';
describe('Monitoring mutations', () => {
@@ -259,27 +259,6 @@ describe('Monitoring mutations', () => {
describe('Individual panel/metric results', () => {
const metricId = 'NO_DB_response_metrics_nginx_ingress_throughput_status_code';
- const data = {
- resultType: 'matrix',
- result: [
- {
- metric: {
- __name__: 'up',
- job: 'prometheus',
- instance: 'localhost:9090',
- },
- values: [[1435781430.781, '1'], [1435781445.781, '1'], [1435781460.781, '1']],
- },
- {
- metric: {
- __name__: 'up',
- job: 'node',
- instance: 'localhost:9091',
- },
- values: [[1435781430.781, '0'], [1435781445.781, '0'], [1435781460.781, '1']],
- },
- ],
- };
const dashboard = metricsDashboardPayload;
const getMetric = () => stateCopy.dashboard.panelGroups[1].panels[0].metrics[0];
@@ -307,6 +286,8 @@ describe('Monitoring mutations', () => {
});
it('adds results to the store', () => {
+ const data = prometheusMatrixMultiResult();
+
expect(getMetric().result).toBe(null);
mutations[types.RECEIVE_METRIC_RESULT_SUCCESS](stateCopy, {
@@ -526,4 +507,90 @@ describe('Monitoring mutations', () => {
expect(stateCopy.panelPreviewError).toBe('Error!');
});
});
+
+ describe('panel preview metric', () => {
+ const getPreviewMetricAt = i => stateCopy.panelPreviewGraphData.metrics[i];
+
+ beforeEach(() => {
+ stateCopy.panelPreviewGraphData = {
+ title: 'Preview panel title',
+ metrics: [
+ {
+ query: 'query',
+ },
+ ],
+ };
+ });
+
+ describe('REQUEST_PANEL_PREVIEW_METRIC_RESULT', () => {
+ it('sets the metric to loading for the first time', () => {
+ mutations[types.REQUEST_PANEL_PREVIEW_METRIC_RESULT](stateCopy, { index: 0 });
+
+ expect(getPreviewMetricAt(0).loading).toBe(true);
+ expect(getPreviewMetricAt(0).state).toBe(metricStates.LOADING);
+ });
+
+ it('sets the metric to loading and keeps the result', () => {
+ getPreviewMetricAt(0).result = [[0, 1]];
+ getPreviewMetricAt(0).state = metricStates.OK;
+
+ mutations[types.REQUEST_PANEL_PREVIEW_METRIC_RESULT](stateCopy, { index: 0 });
+
+ expect(getPreviewMetricAt(0)).toMatchObject({
+ loading: true,
+ result: [[0, 1]],
+ state: metricStates.OK,
+ });
+ });
+ });
+
+ describe('RECEIVE_PANEL_PREVIEW_METRIC_RESULT_SUCCESS', () => {
+ it('saves the result in the metric', () => {
+ const data = prometheusMatrixMultiResult();
+
+ mutations[types.RECEIVE_PANEL_PREVIEW_METRIC_RESULT_SUCCESS](stateCopy, {
+ index: 0,
+ data,
+ });
+
+ expect(getPreviewMetricAt(0)).toMatchObject({
+ loading: false,
+ state: metricStates.OK,
+ result: expect.any(Array),
+ });
+ expect(getPreviewMetricAt(0).result).toHaveLength(data.result.length);
+ });
+ });
+
+ describe('RECEIVE_PANEL_PREVIEW_METRIC_RESULT_FAILURE', () => {
+ it('stores an error in the metric', () => {
+ mutations[types.RECEIVE_PANEL_PREVIEW_METRIC_RESULT_FAILURE](stateCopy, {
+ index: 0,
+ });
+
+ expect(getPreviewMetricAt(0).loading).toBe(false);
+ expect(getPreviewMetricAt(0).state).toBe(metricStates.UNKNOWN_ERROR);
+ expect(getPreviewMetricAt(0).result).toBe(null);
+
+ expect(getPreviewMetricAt(0)).toMatchObject({
+ loading: false,
+ result: null,
+ state: metricStates.UNKNOWN_ERROR,
+ });
+ });
+
+ it('stores a timeout error in a metric', () => {
+ mutations[types.RECEIVE_PANEL_PREVIEW_METRIC_RESULT_FAILURE](stateCopy, {
+ index: 0,
+ error: { message: 'BACKOFF_TIMEOUT' },
+ });
+
+ expect(getPreviewMetricAt(0)).toMatchObject({
+ loading: false,
+ result: null,
+ state: metricStates.TIMEOUT,
+ });
+ });
+ });
+ });
});
diff --git a/spec/requests/api/graphql/project/packages_spec.rb b/spec/requests/api/graphql/project/packages_spec.rb
index 88f97f9256b..5df98ed1e6b 100644
--- a/spec/requests/api/graphql/project/packages_spec.rb
+++ b/spec/requests/api/graphql/project/packages_spec.rb
@@ -28,42 +28,40 @@ RSpec.describe 'getting a package list for a project' do
)
end
- context 'without the need for a license' do
- context 'when user has access to the project' do
- before do
- project.add_reporter(current_user)
- post_graphql(query, current_user: current_user)
- end
+ context 'when user has access to the project' do
+ before do
+ project.add_reporter(current_user)
+ post_graphql(query, current_user: current_user)
+ end
- it_behaves_like 'a working graphql query'
+ it_behaves_like 'a working graphql query'
- it 'returns packages successfully' do
- expect(packages_data[0]['node']['name']).to eq package.name
- end
+ it 'returns packages successfully' do
+ expect(packages_data[0]['node']['name']).to eq package.name
end
+ end
- context 'when the user does not have access to the project/packages' do
- before do
- post_graphql(query, current_user: current_user)
- end
+ context 'when the user does not have access to the project/packages' do
+ before do
+ post_graphql(query, current_user: current_user)
+ end
- it_behaves_like 'a working graphql query'
+ it_behaves_like 'a working graphql query'
- it 'returns nil' do
- expect(graphql_data['project']).to be_nil
- end
+ it 'returns nil' do
+ expect(graphql_data['project']).to be_nil
end
+ end
- context 'when the user is not autenthicated' do
- before do
- post_graphql(query)
- end
+ context 'when the user is not autenthicated' do
+ before do
+ post_graphql(query)
+ end
- it_behaves_like 'a working graphql query'
+ it_behaves_like 'a working graphql query'
- it 'returns nil' do
- expect(graphql_data['project']).to be_nil
- end
+ it 'returns nil' do
+ expect(graphql_data['project']).to be_nil
end
end
end
diff --git a/yarn.lock b/yarn.lock
index 55c107cae3e..391ee036ef2 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -843,15 +843,15 @@
eslint-plugin-vue "^6.2.1"
vue-eslint-parser "^7.0.0"
-"@gitlab/svgs@1.156.0":
- version "1.156.0"
- resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.156.0.tgz#2af56246b5d71000ec81abb1281e811a921cdfd1"
- integrity sha512-+b670Sxkjo80Wb4GKMZQ+xvuwu9sVvql8aS9nzw63FLn84QyqXS+jMjvyDqPAW5kly6B1Eg4Kljq0YawJ0ySBg==
+"@gitlab/svgs@1.157.0":
+ version "1.157.0"
+ resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.157.0.tgz#ada33c2b706836a2f5baa2c539f1348791d74859"
+ integrity sha512-H07Rn4Cy2QW+wnadvuFBSIWrtn8l4hGFLn62f1fT0iYZy58zb/q5/FsShxk9cSKnZYNkXp8I4Nnk/4R7y1MEOw==
-"@gitlab/ui@18.0.0":
- version "18.0.0"
- resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-18.0.0.tgz#5cba4054332d279e5e32c356524c8cf44633ba57"
- integrity sha512-HEn+HEi5EjSKOpNP5r8wUXpnMAskJ51RB7KHz+p7ULx93/2t6iXFC5lU2ta/TVxEonCpJmFmtIeGuYl8DtG54g==
+"@gitlab/ui@18.1.0":
+ version "18.1.0"
+ resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-18.1.0.tgz#36c1e292cae47d1580d2a3918fe5dd16893e2219"
+ integrity sha512-oXKTJ07hMFYxXZiJOgbNzVCpz/ooz0rY7D3ISG9ocawGVFVjrwLj41wgNtOzYAnQntxUcgvxNeBt3X6SS/zeTg==
dependencies:
"@babel/standalone" "^7.0.0"
"@gitlab/vue-toasted" "^1.3.0"
@@ -4364,10 +4364,10 @@ entities@^1.1.1, entities@~1.1.1:
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0"
integrity sha1-blwtClYhtdra7O+AuQ7ftc13cvA=
-entities@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4"
- integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==
+entities@^2.0.0, entities@~2.0.0:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.3.tgz#5c487e5742ab93c15abb5da22759b8590ec03b7f"
+ integrity sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==
entity-decode@^2.0.2:
version "2.0.2"
@@ -5946,10 +5946,10 @@ ignore@^4.0.3, ignore@^4.0.6:
resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
-ignore@^5.0.6:
- version "5.1.2"
- resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.2.tgz#e28e584d43ad7e92f96995019cc43b9e1ac49558"
- integrity sha512-vdqWBp7MyzdmHkkRWV5nY+PfGRbYbahfuvsBCh277tq+w9zyNi7h5CYJCK0kmzti9kU+O/cB7sE8HvKv6aXAKQ==
+ignore@^5.0.6, ignore@~5.1.4:
+ version "5.1.8"
+ resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57"
+ integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==
immediate@~3.0.5:
version "3.0.6"
@@ -7101,10 +7101,10 @@ js-cookie@^2.2.1:
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
-js-yaml@^3.12.0, js-yaml@^3.13.1:
- version "3.14.0"
- resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482"
- integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==
+js-yaml@^3.12.0, js-yaml@^3.13.1, js-yaml@~3.13.1:
+ version "3.13.1"
+ resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
+ integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==
dependencies:
argparse "^1.0.7"
esprima "^4.0.0"
@@ -7267,10 +7267,10 @@ json5@^1.0.1:
dependencies:
minimist "^1.2.0"
-jsonc-parser@^2.2.1:
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.3.0.tgz#7c7fc988ee1486d35734faaaa866fadb00fa91ee"
- integrity sha512-b0EBt8SWFNnixVdvoR2ZtEGa9ZqLhbJnOjezn+WP+8kspFm+PFYDN8Z4Bc7pRlDjvuVcADSUkroIuTWWn/YiIA==
+jsonc-parser@^2.2.1, jsonc-parser@~2.2.0:
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-2.2.1.tgz#db73cd59d78cce28723199466b2a03d1be1df2bc"
+ integrity sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w==
jsonfile@^4.0.0:
version "4.0.0"
@@ -7837,13 +7837,13 @@ markdown-escapes@^1.0.0:
resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.2.tgz#e639cbde7b99c841c0bacc8a07982873b46d2122"
integrity sha512-lbRZ2mE3Q9RtLjxZBZ9+IMl68DKIXaVAhwvwn9pmjnPLS0h/6kyBMgNhqi1xFJ/2yv6cSyv0jbiZavZv93JkkA==
-markdown-it@9.0.1:
- version "9.0.1"
- resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-9.0.1.tgz#aafe363c43718720b6575fd10625cde6e4ff2d47"
- integrity sha512-XC9dMBHg28Xi7y5dPuLjM61upIGPJG8AiHNHYqIaXER2KNnn7eKnM5/sF0ImNnyoV224Ogn9b1Pck8VH4k0bxw==
+markdown-it@10.0.0:
+ version "10.0.0"
+ resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-10.0.0.tgz#abfc64f141b1722d663402044e43927f1f50a8dc"
+ integrity sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==
dependencies:
argparse "^1.0.7"
- entities "~1.1.1"
+ entities "~2.0.0"
linkify-it "^2.0.0"
mdurl "^1.0.1"
uc.micro "^1.0.5"
@@ -7864,28 +7864,37 @@ markdown-table@^1.1.0:
resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-1.1.2.tgz#c78db948fa879903a41bce522e3b96f801c63786"
integrity sha512-NcWuJFHDA8V3wkDgR/j4+gZx+YQwstPgfQDV8ndUeWWzta3dnDTBxpVzqS9lkmJAuV5YX35lmyojl6HO5JXAgw==
-markdownlint-cli@0.18.0:
- version "0.18.0"
- resolved "https://registry.yarnpkg.com/markdownlint-cli/-/markdownlint-cli-0.18.0.tgz#bd1cee72739049d42dcea5f6db0c0f57c6eb8096"
- integrity sha512-mQ2zvjMLoy0P2kb9Y03SqC24WPH4fTRN0/CyCorB122c4Chg9vWJKgUKBz3KR7swpzqmlI0SYq/7Blbqe4kb2g==
+markdownlint-cli@0.23.2:
+ version "0.23.2"
+ resolved "https://registry.yarnpkg.com/markdownlint-cli/-/markdownlint-cli-0.23.2.tgz#43f0a96e2699542b74fb5e6188c025e4934357fc"
+ integrity sha512-OSl5OZ8xzGN6z355cqRkiq67zPi3reJimklaF72p0554q85Dng5ToOjjSB9tDKZebSt85jX8cp+ruoQlPqOsPA==
dependencies:
commander "~2.9.0"
deep-extend "~0.5.1"
get-stdin "~5.0.1"
glob "~7.1.2"
- js-yaml "^3.13.1"
+ ignore "~5.1.4"
+ js-yaml "~3.13.1"
+ jsonc-parser "~2.2.0"
lodash.differencewith "~4.5.0"
lodash.flatten "~4.4.0"
- markdownlint "~0.16.0"
+ markdownlint "~0.20.4"
+ markdownlint-rule-helpers "~0.11.0"
minimatch "~3.0.4"
+ minimist "~1.2.5"
rc "~1.2.7"
-markdownlint@~0.16.0:
- version "0.16.0"
- resolved "https://registry.yarnpkg.com/markdownlint/-/markdownlint-0.16.0.tgz#69f73cc755a44231fbe5dc7c37a5909cedc0ac6e"
- integrity sha512-Zo+iPezP3eM6lLhKepkUw+X98H44lipIdx4d6faaugfB0+7VuDB3R0hXmx7z9F1N3/ypn46oOFgAD9iF++Ie6A==
+markdownlint-rule-helpers@~0.11.0:
+ version "0.11.0"
+ resolved "https://registry.yarnpkg.com/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.11.0.tgz#faaaae4337771c7d88ca38ef6265afb4fbe0fb3f"
+ integrity sha512-PhGii9dOiDJDXxiRMpK8N0FM9powprvRPsXALgkjlSPTwLh6ymH+iF3iUe3nq8KGu26tclFBlLL5xAGy/zb7FA==
+
+markdownlint@~0.20.4:
+ version "0.20.4"
+ resolved "https://registry.yarnpkg.com/markdownlint/-/markdownlint-0.20.4.tgz#3b34681494cdad174e14a27182b5cdefaa537823"
+ integrity sha512-jpfaPgjT0OpeBbemjYNZbzGG3hCLcAIvrm/pEY3+q/szDScG6ZonDacqySVRJAv9glbo8y4wBPJ0wgW17+9GGA==
dependencies:
- markdown-it "9.0.1"
+ markdown-it "10.0.0"
marked@^0.3.12, marked@~0.3.6:
version "0.3.19"
@@ -8157,7 +8166,7 @@ minimist@1.1.x:
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.1.3.tgz#3bedfd91a92d39016fcfaa1c681e8faa1a1efda8"
integrity sha1-O+39kaktOQFvz6ocaB6Pqhoe/ag=
-minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5:
+minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5, minimist@~1.2.5:
version "1.2.5"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==