Skip to content
Snippets Groups Projects
Commit cbfe03ae authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@master

parent 3fd97b4b
No related branches found
No related tags found
No related merge requests found
Showing
with 192 additions and 87 deletions
Loading
Loading
@@ -12,6 +12,11 @@ stages:
- post-qa
- pages
 
# always use `gitlab-org` runners
default:
tags:
- gitlab-org
workflow:
rules:
# If `$FORCE_GITLAB_CI` is set, create a pipeline.
Loading
Loading
.run-dev-fixtures:
extends:
- .default-tags
- .default-retry
- .default-cache
- .default-before_script
Loading
Loading
.review-docs:
extends:
- .default-tags
- .default-retry
- .docs:rules:review-docs
allow_failure: true
Loading
Loading
@@ -42,7 +41,6 @@ review-docs-cleanup:
 
docs lint:
extends:
- .default-tags
- .default-retry
- .docs:rules:docs-lint
image: "registry.gitlab.com/gitlab-org/gitlab-docs:lint"
Loading
Loading
@@ -64,7 +62,6 @@ docs lint:
 
graphql-reference-verify:
extends:
- .default-tags
- .default-retry
- .default-cache
- .default-before_script
Loading
Loading
Loading
Loading
@@ -10,7 +10,6 @@
 
.gitlab:assets:compile-metadata:
extends:
- .default-tags
- .default-retry
- .default-before_script
- .assets-compile-cache
Loading
Loading
@@ -64,7 +63,6 @@ gitlab:assets:compile pull-cache:
 
.compile-assets-metadata:
extends:
- .default-tags
- .default-retry
- .default-before_script
- .assets-compile-cache
Loading
Loading
@@ -122,7 +120,6 @@ compile-assets pull-cache as-if-foss:
 
.frontend-fixtures-base:
extends:
- .default-tags
- .default-retry
- .default-cache
- .default-before_script
Loading
Loading
@@ -160,7 +157,6 @@ frontend-fixtures-as-if-foss:
 
.frontend-job-base:
extends:
- .default-tags
- .default-retry
- .default-cache
- .default-before_script
Loading
Loading
@@ -242,7 +238,6 @@ jest-as-if-foss:
 
coverage-frontend:
extends:
- .default-tags
- .default-retry
- .frontend:rules:default-frontend-jobs
needs: ["jest"]
Loading
Loading
@@ -262,7 +257,6 @@ coverage-frontend:
 
.qa-frontend-node:
extends:
- .default-tags
- .default-retry
- .default-cache
- .frontend:rules:qa-frontend-node
Loading
Loading
@@ -290,7 +284,6 @@ qa-frontend-node:latest:
 
webpack-dev-server:
extends:
- .default-tags
- .default-retry
- .default-cache
- .frontend:rules:default-frontend-jobs
Loading
Loading
.default-tags:
tags:
- gitlab-org
.default-retry:
retry:
max: 2 # This is confusing but this means "3 runs at max".
Loading
Loading
.only-code-memory-job-base:
extends:
- .default-tags
- .default-retry
- .default-cache
- .default-before_script
Loading
Loading
pages:
extends:
- .default-tags
- .default-retry
- .default-cache
- .pages:rules
Loading
Loading
.qa-job-base:
extends:
- .default-tags
- .default-retry
stage: test
needs: []
Loading
Loading
Loading
Loading
@@ -7,7 +7,6 @@
 
.rails-job-base:
extends:
- .default-tags
- .default-retry
- .default-cache
- .default-before_script
Loading
Loading
.review-docker:
extends:
- .default-tags
- .default-retry
image: registry.gitlab.com/gitlab-org/gitlab-build-images:gitlab-qa-alpine-ruby-2.6
services:
Loading
Loading
@@ -29,7 +28,6 @@ build-qa-image:
 
review-cleanup:
extends:
- .default-tags
- .default-retry
- .review:rules:review-cleanup
stage: prepare
Loading
Loading
@@ -46,7 +44,6 @@ review-cleanup:
 
review-build-cng:
extends:
- .default-tags
- .default-retry
- .review:rules:mr-and-schedule
image: ruby:2.6-alpine
Loading
Loading
@@ -63,7 +60,6 @@ review-build-cng:
 
.review-workflow-base:
extends:
- .default-tags
- .default-retry
image: registry.gitlab.com/gitlab-org/gitlab-build-images:gitlab-charts-build-base
variables:
Loading
Loading
@@ -217,7 +213,6 @@ review-performance:
 
parallel-spec-reports:
extends:
- .default-tags
- .review:rules:mr-only-manual
image: ruby:2.6-alpine
stage: post-qa
Loading
Loading
@@ -244,7 +239,6 @@ parallel-spec-reports:
 
danger-review:
extends:
- .default-tags
- .default-retry
- .default-cache
- .review:rules:danger
Loading
Loading
Loading
Loading
@@ -2,7 +2,6 @@
# rubygems.org in the future.
cache gems:
extends:
- .default-tags
- .default-retry
- .default-cache
- .default-before_script
Loading
Loading
@@ -21,7 +20,6 @@ cache gems:
 
.minimal-job:
extends:
- .default-tags
- .default-retry
needs: []
 
Loading
Loading
Loading
Loading
@@ -2,7 +2,6 @@
# This uses rules from project root `.yamllint`.
lint-ci-gitlab:
extends:
- .default-tags
- .default-retry
- .yaml:rules
image: sdesbure/yamllint:latest
Loading
Loading
Loading
Loading
@@ -59,6 +59,10 @@ See the test engineering planning process and reach out to your counterpart Soft
 
<!-- Which leads to: in which enterprise tier should this feature go? See https://about.gitlab.com/handbook/product/pricing/#four-tiers -->
 
### Is this a cross-stage feature?
<!-- Communicate if this change will affect multiple Stage Groups or product areas. We recommend always start with the assumption that a feature request will have an impact into another Group. Loop in the most relevant PM and Product Designer from that Group to provide strategic support to help align the Group's broader plan and vision, as well as to avoid UX and technical debt. https://about.gitlab.com/handbook/product/#cross-stage-features -->
### Links / references
 
/label ~feature
import flash from '~/flash';
import $ from 'jquery';
import { sprintf, __ } from '../../locale';
import { __, sprintf } from '~/locale';
import { once } from 'lodash';
 
// Renders diagrams and flowcharts from text using Mermaid in any element with the
// `js-render-mermaid` class.
Loading
Loading
@@ -18,14 +19,10 @@ import { sprintf, __ } from '../../locale';
 
// This is an arbitrary number; Can be iterated upon when suitable.
const MAX_CHAR_LIMIT = 5000;
let mermaidModule = {};
 
function renderMermaids($els) {
if (!$els.length) return;
// A diagram may have been truncated in search results which will cause errors, so abort the render.
if (document.querySelector('body').dataset.page === 'search:show') return;
import(/* webpackChunkName: 'mermaid' */ 'mermaid')
function importMermaidModule() {
return import(/* webpackChunkName: 'mermaid' */ 'mermaid')
.then(mermaid => {
mermaid.initialize({
// mermaid core options
Loading
Loading
@@ -41,63 +38,127 @@ function renderMermaids($els) {
securityLevel: 'strict',
});
 
mermaidModule = mermaid;
return mermaid;
})
.catch(err => {
flash(sprintf(__("Can't load mermaid module: %{err}"), { err }));
// eslint-disable-next-line no-console
console.error(err);
});
}
function fixElementSource(el) {
// Mermaid doesn't like `<br />` tags, so collapse all like tags into `<br>`, which is parsed correctly.
const source = el.textContent.replace(/<br\s*\/>/g, '<br>');
// Remove any extra spans added by the backend syntax highlighting.
Object.assign(el, { textContent: source });
return { source };
}
function renderMermaidEl(el) {
mermaidModule.init(undefined, el, id => {
const source = el.textContent;
const svg = document.getElementById(id);
// As of https://github.com/knsv/mermaid/commit/57b780a0d,
// Mermaid will make two init callbacks:one to initialize the
// flow charts, and another to initialize the Gannt charts.
// Guard against an error caused by double initialization.
if (svg.classList.contains('mermaid')) {
return;
}
svg.classList.add('mermaid');
// pre > code > svg
svg.closest('pre').replaceWith(svg);
// We need to add the original source into the DOM to allow Copy-as-GFM
// to access it.
const sourceEl = document.createElement('text');
sourceEl.classList.add('source');
sourceEl.setAttribute('display', 'none');
sourceEl.textContent = source;
svg.appendChild(sourceEl);
});
}
function renderMermaids($els) {
if (!$els.length) return;
// A diagram may have been truncated in search results which will cause errors, so abort the render.
if (document.querySelector('body').dataset.page === 'search:show') return;
importMermaidModule()
.then(() => {
let renderedChars = 0;
 
$els.each((i, el) => {
// Mermaid doesn't like `<br />` tags, so collapse all like tags into `<br>`, which is parsed correctly.
const source = el.textContent.replace(/<br\s*\/>/g, '<br>');
const { source } = fixElementSource(el);
/**
* Restrict the rendering to a certain amount of character to
* prevent mermaidjs from hanging up the entire thread and
* causing a DoS.
*/
if ((source && source.length > MAX_CHAR_LIMIT) || renderedChars > MAX_CHAR_LIMIT) {
el.textContent = sprintf(
__(
'Cannot render the image. Maximum character count (%{charLimit}) has been exceeded.',
),
{ charLimit: MAX_CHAR_LIMIT },
);
const html = `
<div class="alert gl-alert gl-alert-warning alert-dismissible lazy-render-mermaid-container js-lazy-render-mermaid-container fade show" role="alert">
<div>
<div class="display-flex">
<div>${__(
'Warning: Displaying this diagram might cause performance issues on this page.',
)}</div>
<div class="gl-alert-actions">
<button class="js-lazy-render-mermaid btn gl-alert-action btn-warning btn-md new-gl-button">Display</button>
</div>
</div>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>
</div>
`;
const $parent = $(el).parent();
if (!$parent.hasClass('lazy-alert-shown')) {
$parent.after(html);
$parent.addClass('lazy-alert-shown');
}
return;
}
 
renderedChars += source.length;
// Remove any extra spans added by the backend syntax highlighting.
Object.assign(el, { textContent: source });
mermaid.init(undefined, el, id => {
const svg = document.getElementById(id);
// As of https://github.com/knsv/mermaid/commit/57b780a0d,
// Mermaid will make two init callbacks:one to initialize the
// flow charts, and another to initialize the Gannt charts.
// Guard against an error caused by double initialization.
if (svg.classList.contains('mermaid')) {
return;
}
svg.classList.add('mermaid');
// pre > code > svg
svg.closest('pre').replaceWith(svg);
 
// We need to add the original source into the DOM to allow Copy-as-GFM
// to access it.
const sourceEl = document.createElement('text');
sourceEl.classList.add('source');
sourceEl.setAttribute('display', 'none');
sourceEl.textContent = source;
svg.appendChild(sourceEl);
});
renderMermaidEl(el);
});
})
.catch(err => {
flash(`Can't load mermaid module: ${err}`);
flash(sprintf(__('Encountered an error while rendering: %{err}'), { err }));
// eslint-disable-next-line no-console
console.error(err);
});
}
 
const hookLazyRenderMermaidEvent = once(() => {
$(document.body).on('click', '.js-lazy-render-mermaid', function eventHandler() {
const parent = $(this).closest('.js-lazy-render-mermaid-container');
const pre = parent.prev();
const el = pre.find('.js-render-mermaid');
parent.remove();
renderMermaidEl(el);
});
});
export default function renderMermaid($els) {
if (!$els.length) return;
 
Loading
Loading
@@ -112,4 +173,6 @@ export default function renderMermaid($els) {
renderMermaids($(this).find('.js-render-mermaid'));
}
});
hookLazyRenderMermaidEvent();
}
Loading
Loading
@@ -308,6 +308,7 @@ export default {
'is-added': file.tempFile,
}"
class="multi-file-editor-holder"
data-qa-selector="editor_container"
@focusout="triggerFilesChange"
></div>
<content-viewer
Loading
Loading
Loading
Loading
@@ -39,6 +39,7 @@ const populateUserInfo = user => {
location: userData.location,
bio: userData.bio,
organization: userData.organization,
jobTitle: userData.job_title,
loaded: true,
});
}
Loading
Loading
Loading
Loading
@@ -121,6 +121,7 @@ export default {
data-placement="bottom"
tabindex="0"
role="button"
data-qa-selector="open_in_web_ide_button"
>
{{ s__('mrWidget|Open in Web IDE') }}
</a>
Loading
Loading
<script>
import { GlPopover, GlSkeletonLoading } from '@gitlab/ui';
import { GlPopover, GlSkeletonLoading, GlSprintf } from '@gitlab/ui';
import Icon from '~/vue_shared/components/icon.vue';
import UserAvatarImage from '../user_avatar/user_avatar_image.vue';
import { glEmojiTag } from '../../../emoji';
import { s__ } from '~/locale';
import { isString } from 'lodash';
 
export default {
name: 'UserPopover',
Loading
Loading
@@ -10,6 +12,7 @@ export default {
Icon,
GlPopover,
GlSkeletonLoading,
GlSprintf,
UserAvatarImage,
},
props: {
Loading
Loading
@@ -45,8 +48,27 @@ export default {
nameIsLoading() {
return !this.user.name;
},
jobInfoIsLoading() {
return !this.user.loaded && this.user.organization === null;
workInformationIsLoading() {
return !this.user.loaded && this.workInformation === null;
},
workInformation() {
const { jobTitle, organization } = this.user;
if (organization && jobTitle) {
return {
message: s__('Profile|%{job_title} at %{organization}'),
placeholders: { job_title: jobTitle, organization },
};
} else if (organization) {
return organization;
} else if (jobTitle) {
return jobTitle;
}
return null;
},
workInformationShouldUseSprintf() {
return !isString(this.workInformation);
},
locationIsLoading() {
return !this.user.loaded && this.user.location === null;
Loading
Loading
@@ -72,16 +94,30 @@ export default {
<gl-skeleton-loading v-else :lines="1" class="animation-container-small mb-1" />
</div>
<div class="text-secondary">
<div v-if="user.bio" class="js-bio d-flex mb-1">
<div v-if="user.bio" class="d-flex mb-1">
<icon name="profile" class="category-icon flex-shrink-0" />
<span class="ml-1">{{ user.bio }}</span>
<span ref="bio" class="ml-1">{{ user.bio }}</span>
</div>
<div v-if="user.organization" class="js-organization d-flex mb-1">
<icon v-show="!jobInfoIsLoading" name="work" class="category-icon flex-shrink-0" />
<span class="ml-1">{{ user.organization }}</span>
<div v-if="workInformation" class="d-flex mb-1">
<icon
v-show="!workInformationIsLoading"
name="work"
class="category-icon flex-shrink-0"
/>
<span ref="workInformation" class="ml-1">
<gl-sprintf v-if="workInformationShouldUseSprintf" :message="workInformation.message">
<template
v-for="(placeholder, slotName) in workInformation.placeholders"
v-slot:[slotName]
>
<span :key="slotName">{{ placeholder }}</span>
</template>
</gl-sprintf>
<span v-else>{{ workInformation }}</span>
</span>
</div>
<gl-skeleton-loading
v-if="jobInfoIsLoading"
v-if="workInformationIsLoading"
:lines="1"
class="animation-container-small mb-1"
/>
Loading
Loading
Loading
Loading
@@ -161,13 +161,17 @@
}
 
.cover-controls {
position: absolute;
top: 10px;
right: 10px;
@include media-breakpoint-up(sm) {
position: absolute;
top: 1rem;
right: 1.25rem;
}
 
&.left {
left: 10px;
right: auto;
@include media-breakpoint-up(sm) {
left: 1.25rem;
right: auto;
}
}
}
 
Loading
Loading
Loading
Loading
@@ -401,3 +401,21 @@
line-height: 16px;
text-align: center;
}
@mixin middle-dot-divider {
&::after {
// Duplicate `content` property used as a fallback
// scss-lint:disable DuplicateProperty
content: '\00B7'; // middle dot fallback if browser does not support alternative content
content: '\00B7' / ''; // tell screen readers to ignore the content https://www.w3.org/TR/css-content-3/#accessibility
padding: 0 0.375rem;
font-weight: $gl-font-weight-bold;
}
&:last-child {
&::after {
content: '';
padding: 0;
}
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment