提交 d48cbe17 编写于 作者: G GitLab Bot

Add latest changes from gitlab-org/gitlab@master

上级 99c01aa6
import initProjectVisibilitySelector from '../../../project_visibility';
import initProjectNew from '../../../projects/project_new';
import { __ } from '~/locale';
import createFlash from '~/flash';
import Tracking from '~/tracking';
document.addEventListener('DOMContentLoaded', () => {
initProjectVisibilitySelector();
initProjectNew.bindEvents();
const { category, property } = gon.tracking_data ?? { category: 'projects:new' };
const hasNewCreateProjectUi = 'newCreateProjectUi' in gon?.features;
if (!hasNewCreateProjectUi) {
// Setting additional tracking for HAML template
Array.from(
document.querySelectorAll('.project-edit-container [data-experiment-track-label]'),
).forEach(node =>
node.addEventListener('click', event => {
const { experimentTrackLabel: label } = event.currentTarget.dataset;
Tracking.event(category, 'click_tab', { property, label });
}),
);
} else {
import(
/* webpackChunkName: 'experiment_new_project_creation' */ '../../../projects/experiment_new_project_creation'
)
.then(m => {
const el = document.querySelector('.js-experiment-new-project-creation');
if (!el) {
return;
}
const config = {
hasErrors: 'hasErrors' in el.dataset,
isCiCdAvailable: 'isCiCdAvailable' in el.dataset,
};
m.default(el, config);
})
.catch(() => {
createFlash(__('An error occurred while loading project creation UI'));
});
}
});
<script>
import WelcomePage from './welcome.vue';
import LegacyContainer from './legacy_container.vue';
import { GlBreadcrumb, GlIcon } from '@gitlab/ui';
import { __, s__ } from '~/locale';
import blankProjectIllustration from '../illustrations/blank-project.svg';
import createFromTemplateIllustration from '../illustrations/create-from-template.svg';
import importProjectIllustration from '../illustrations/import-project.svg';
import ciCdProjectIllustration from '../illustrations/ci-cd-project.svg';
const BLANK_PANEL = 'blank_project';
const CI_CD_PANEL = 'cicd_for_external_repo';
const PANELS = [
{
name: BLANK_PANEL,
selector: '#blank-project-pane',
title: s__('ProjectsNew|Create blank project'),
description: s__(
'ProjectsNew|Create a blank project to house your files, plan your work, and collaborate on code, among other things.',
),
illustration: blankProjectIllustration,
},
{
name: 'create_from_template',
selector: '#create-from-template-pane',
title: s__('ProjectsNew|Create from template'),
description: s__(
'Create a project pre-populated with the necessary files to get you started quickly.',
),
illustration: createFromTemplateIllustration,
},
{
name: 'import_project',
selector: '#import-project-pane',
title: s__('ProjectsNew|Import project'),
description: s__(
'Migrate your data from an external source like GitHub, Bitbucket, or another instance of GitLab.',
),
illustration: importProjectIllustration,
},
{
name: CI_CD_PANEL,
selector: '#ci-cd-project-pane',
title: s__('ProjectsNew|Run CI/CD for external repository'),
description: s__('ProjectsNew|Connect your external repository to GitLab CI/CD.'),
illustration: ciCdProjectIllustration,
},
];
export default {
components: {
GlBreadcrumb,
GlIcon,
WelcomePage,
LegacyContainer,
},
props: {
hasErrors: {
type: Boolean,
required: false,
default: false,
},
isCiCdAvailable: {
type: Boolean,
required: false,
default: false,
},
},
data() {
return {
activeTab: null,
};
},
computed: {
availablePanels() {
if (this.isCiCdAvailable) {
return PANELS;
}
return PANELS.filter(p => p.name !== CI_CD_PANEL);
},
activePanel() {
return PANELS.find(p => p.name === this.activeTab);
},
breadcrumbs() {
if (!this.activeTab || !this.activePanel) {
return null;
}
return [
{ text: __('New project'), href: '#' },
{ text: this.activePanel.title, href: `#${this.activeTab}` },
];
},
},
created() {
this.handleLocationHashChange();
if (this.hasErrors) {
this.activeTab = BLANK_PANEL;
}
window.addEventListener('hashchange', () => {
this.handleLocationHashChange();
this.resetProjectErrors();
});
this.$root.$on('clicked::link', e => {
window.location = e.target.href;
});
},
methods: {
resetProjectErrors() {
const errorsContainer = document.querySelector('.project-edit-errors');
if (errorsContainer) {
errorsContainer.innerHTML = '';
}
},
handleLocationHashChange() {
this.activeTab = window.location.hash.substring(1) || null;
},
},
PANELS,
};
</script>
<template>
<welcome-page v-if="activeTab === null" :panels="availablePanels" />
<div v-else class="row">
<div class="col-lg-3">
<div class="text-center" v-html="activePanel.illustration"></div>
<h4>{{ activePanel.title }}</h4>
<p>{{ activePanel.description }}</p>
</div>
<div class="col-lg-9">
<gl-breadcrumb v-if="breadcrumbs" :items="breadcrumbs">
<template #separator>
<gl-icon name="chevron-right" :size="8" />
</template>
</gl-breadcrumb>
<template v-for="panel in $options.PANELS">
<legacy-container
v-if="activeTab === panel.name"
:key="panel.name"
class="gl-mt-3"
:selector="panel.selector"
/>
</template>
</div>
</div>
</template>
<script>
export default {
inheritAttrs: false,
props: {
selector: {
type: String,
required: true,
},
},
mounted() {
const legacyEntry = document.querySelector(this.selector);
if (legacyEntry.tagName === 'TEMPLATE') {
this.$el.innerHTML = legacyEntry.innerHTML;
} else {
this.source = legacyEntry.parentNode;
this.$el.appendChild(legacyEntry);
}
},
beforeDestroy() {
if (this.source) {
this.source.appendChild(this.$el.firstChild);
}
},
};
</script>
<template>
<div></div>
</template>
<script>
import Tracking from '~/tracking';
import { GlPopover } from '@gitlab/ui';
import LegacyContainer from './legacy_container.vue';
const trackingMixin = Tracking.mixin(gon.tracking_data);
export default {
components: {
GlPopover,
LegacyContainer,
},
mixins: [trackingMixin],
props: {
panels: {
type: Array,
required: true,
},
},
};
</script>
<template>
<div class="container">
<div class="blank-state-welcome">
<h2 class="blank-state-welcome-title gl-mt-5! gl-mb-3!">
{{ s__('ProjectsNew|Create new project') }}
</h2>
<p div class="blank-state-text">&nbsp;</p>
</div>
<div class="row blank-state-row">
<a
v-for="panel in panels"
:key="panel.name"
:href="`#${panel.name}`"
class="blank-state blank-state-link experiment-new-project-page-blank-state"
@click="track('click_tab', { label: panel.name })"
>
<div class="blank-state-icon" v-html="panel.illustration"></div>
<div class="blank-state-body gl-pl-4!">
<h3 class="blank-state-title experiment-new-project-page-blank-state-title">
{{ panel.title }}
</h3>
<p class="blank-state-text">
{{ panel.description }}
</p>
</div>
</a>
</div>
<div class="blank-state-welcome">
<p>
{{ __('You can also create a project from the command line.') }}
<a
id="cli-tip"
href="#"
click.prevent
class="push-new-project-tip"
data-title="Push to create a project"
rel="noopener noreferrer"
>
{{ __('Show command') }}
</a>
<gl-popover target="cli-tip" triggers="click blur" placement="top">
<legacy-container selector=".push-new-project-tip-template" />
</gl-popover>
</p>
</div>
</div>
</template>
<?xml version="1.0" encoding="UTF-8"?>
<svg width="215px" height="115px" viewBox="0 0 215 115" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 61.2 (89653) - https://sketch.com -->
<title>create-new-project-md</title>
<desc>Created with Sketch.</desc>
<g id="create-new-project-md" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Group-3" transform="translate(71.000000, 18.000000)" fill-rule="nonzero">
<g id="New-Blank1">
<path d="M6.11141667,3.90697674 L62.6947849,3.90697674 C65.9485064,3.90697674 68.5891473,6.56494969 68.5891473,9.8400273 L68.5891473,78.0669494 C68.5891473,81.342027 65.9485064,84 62.6947849,84 L6.11141667,84 C2.85769514,84 0.217054264,81.342027 0.217054264,78.0669494 L0.217054264,9.8400273 C0.217054264,6.56494969 2.85769514,3.90697674 6.11141667,3.90697674 Z" id="Path" fill="#F9F9F9"></path>
<path d="M8.89436241,1 L65.4777306,1 C68.7314521,1 71.372093,3.65598929 71.372093,6.9286227 L71.372093,74.5132378 C71.372093,77.7858712 68.7314521,80.4418605 65.4777306,80.4418605 L8.89436241,80.4418605 C5.64064088,80.4418605 3,77.7858712 3,74.5132378 L3,6.9286227 C3.00209243,3.65598929 5.64064088,1 8.89436241,1 Z" id="Path" fill="#FFFFFF"></path>
<path d="M9.2677971,2.35980136 C6.65357171,2.35980136 4.53489427,4.47043114 4.53489427,7.07940407 L4.53489427,74.3201325 C4.53489427,76.9270116 6.65147193,79.0397352 9.2677971,79.0397352 L66.0500324,79.0397352 C68.6642577,79.0397352 70.7829352,76.9291055 70.7829352,74.3201325 L70.7829352,7.07731019 C70.7829352,4.47043114 68.6663575,2.35770748 66.0500324,2.35770748 L9.2677971,2.35980136 L9.2677971,2.35980136 Z M9.2677971,0 L66.0500324,0 C69.9724203,0 73.1472868,3.16803856 73.1472868,7.07731019 L73.1472868,74.3180386 C73.1472868,78.2294042 69.9703205,81.3953488 66.0500324,81.3953488 L9.2677971,81.3953488 C5.34540913,81.3953488 2.17054264,78.2273103 2.17054264,74.3180386 L2.17054264,7.07731019 C2.17054264,3.17222631 5.34750891,0 9.2677971,0 Z" id="Shape" fill="#EEEEEE"></path>
<path d="M21.6234891,28.6511628 L28.9501543,28.6511628 C29.6221266,28.6511628 30.1705426,29.2387129 30.1705426,29.9534884 C30.1705426,30.6682639 29.6199589,31.255814 28.9501543,31.255814 L21.6234891,31.255814 C20.9515168,31.255814 20.4031008,30.6682639 20.4031008,29.9534884 C20.4031008,29.2387129 20.9515168,28.6511628 21.6234891,28.6511628 Z" id="Path" fill="#E1DBF1"></path>
<path d="M33.9142229,35.8139535 L36.1943042,35.8139535 C36.8214783,35.8139535 37.3333333,36.4015036 37.3333333,37.1162791 C37.3333333,37.8333678 36.8194552,38.4186047 36.1943042,38.4186047 L33.9142229,38.4186047 C33.2870488,38.4186047 32.7751938,37.8310546 32.7751938,37.1162791 C32.7751938,36.4015036 33.2890719,35.8139535 33.9142229,35.8139535 Z" id="Path" fill="#FC6D26"></path>
<path d="M24.200844,42.9767442 L28.9774506,42.9767442 C29.6343929,42.9767442 30.1705426,43.5642943 30.1705426,44.2790698 C30.1705426,44.9961585 29.6322737,45.5813953 28.9774506,45.5813953 L24.200844,45.5813953 C23.5439017,45.5813953 23.0077519,44.9938453 23.0077519,44.2790698 C23.0077519,43.5642943 23.5439017,42.9767442 24.200844,42.9767442 Z" id="Path" fill="#E1DBF1"></path>
<path d="M41.0770181,35.8139535 L43.3570964,35.8139535 C43.9842697,35.8139535 44.496124,36.4015036 44.496124,37.1162791 C44.496124,37.8333678 43.9822466,38.4186047 43.3570964,38.4186047 L41.0770181,38.4186047 C40.4498448,38.4186047 39.9379845,37.8310546 39.9379845,37.1162791 C39.9359673,36.4015036 40.4498448,35.8139535 41.0770181,35.8139535 Z" id="Path" fill="#FC6D26"></path>
<path d="M33.9372473,28.6511628 L47.89221,28.6511628 C48.5320619,28.6511628 49.0542636,29.2387129 49.0542636,29.9534884 C49.0542636,30.6682639 48.5299978,31.255814 47.89221,31.255814 L33.9372473,31.255814 C33.2973955,31.255814 32.7751938,30.6682639 32.7751938,29.9534884 C32.7751938,29.2387129 33.2994595,28.6511628 33.9372473,28.6511628 Z" id="Path" fill="#C3B8E3"></path>
<path d="M33.9142229,42.9767442 L36.1943042,42.9767442 C36.8214783,42.9767442 37.3333333,43.5642943 37.3333333,44.2790698 C37.3333333,44.9961585 36.8194552,45.5813953 36.1943042,45.5813953 L33.9142229,45.5813953 C33.2870488,45.5813953 32.7751938,44.9938453 32.7751938,44.2790698 C32.7751938,43.5642943 33.2890719,42.9767442 33.9142229,42.9767442 Z" id="Path" fill="#6B4FBB"></path>
<g id="Group" transform="translate(16.000000, 19.000000)">
<circle id="Oval" fill="#FFFFFF" cx="20.8396947" cy="20.8396947" r="20.7533889"></circle>
<path d="M20.8396947,41.5930835 C9.3778626,41.5930835 0.0863058062,32.3015267 0.0863058062,20.8396947 C0.0863058062,9.3778626 9.3778626,0.0863058062 20.8396947,0.0863058062 C32.3015267,0.0863058062 41.5930835,9.3778626 41.5930835,20.8396947 C41.5930835,32.3015267 32.3015267,41.5930835 20.8396947,41.5930835 Z M20.8396947,39.2207263 C30.9922045,39.2207263 39.2207263,30.9900995 39.2207263,20.8396947 C39.2207263,10.6892898 30.9900995,2.45866297 20.8396947,2.45866297 C10.6892898,2.45866297 2.45866297,10.6892898 2.45866297,20.8396947 C2.45866297,30.9900995 10.6871848,39.2207263 20.8396947,39.2207263 Z" id="Shape" fill="#EEEEEE"></path>
<path d="M13.7647236,19.060953 L27.9967615,19.060953 C28.6493176,19.060953 29.1818876,19.595628 29.1818876,20.2460791 C29.1818876,20.8986352 28.6472126,21.4312052 27.9967615,21.4312052 L13.7647236,21.4312052 C13.1121675,21.4312052 12.5795975,20.8965302 12.5795975,20.2460791 C12.5795975,19.593523 13.1142725,19.060953 13.7647236,19.060953 Z" id="Path" fill="#6B4FBB"></path>
<path d="M22.0669211,13.1311127 L22.0669211,27.3631506 C22.0669211,28.0157067 21.5322461,28.5482767 20.881795,28.5482767 C20.231344,28.5482767 19.696669,28.0136017 19.696669,27.3631506 L19.696669,13.1311127 C19.696669,12.4785566 20.231344,11.9459866 20.881795,11.9459866 C21.5322461,11.9459866 22.0669211,12.4785566 22.0669211,13.1311127 Z" id="Path" fill="#6B4FBB"></path>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="215px" height="115px" viewBox="0 0 215 115" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 61.2 (89653) - https://sketch.com -->
<title>create-project-from-template-md</title>
<desc>Created with Sketch.</desc>
<g id="create-project-from-template-md" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="New-Template1" transform="translate(71.000000, 15.000000)">
<g id="Group">
<path d="M5.88230137,4.144 L61.8884384,4.144 C65.1195616,4.144 67.7155068,6.804 67.7155068,10.052 L67.7155068,78.064 C67.7155068,81.34 65.0919452,83.972 61.8884384,83.972 L5.88230137,83.972 C2.65117808,83.972 0.0552328767,81.312 0.0552328767,78.064 L0.0552328767,10.052 C0.0552328767,6.804 2.67879452,4.144 5.88230137,4.144 Z" id="Path" fill="#F9F9F9" fill-rule="nonzero"></path>
<path d="M8.82706849,1 L64.8332055,1 C68.0643288,1 70.660274,3.66 70.660274,6.908 L70.660274,74.332 C70.660274,77.608 68.0367123,80.24 64.8332055,80.24 L8.82706849,80.24 C5.59594521,80.24 3,77.58 3,74.332 L3,6.936 C3,3.66 5.59594521,1 8.82706849,1 Z" id="Path" fill="#FFFFFF" fill-rule="nonzero"></path>
<path d="M8.80964384,2.38 C6.24131507,2.38 4.14246575,4.508 4.14246575,7.112 L4.14246575,74.536 C4.14246575,77.14 6.24131507,79.268 8.80964384,79.268 L64.8157808,79.268 C67.3841096,79.268 69.4829589,77.14 69.4829589,74.536 L69.4829589,7.112 C69.4829589,4.508 67.3841096,2.38 64.8157808,2.38 L8.80964384,2.38 L8.80964384,2.38 Z M8.80964384,0 L64.8157808,0 C68.6820822,0 71.8027397,3.164 71.8027397,7.084 L71.8027397,74.508 C71.8027397,78.428 68.6820822,81.592 64.8157808,81.592 L8.80964384,81.592 C4.94334247,81.592 1.82250462,78.4 1.82250462,74.508 L1.82250462,7.112 C1.79506849,3.192 4.94334247,0 8.80964384,0 Z" id="Shape" fill="#EEEEEE" fill-rule="nonzero"></path>
<path d="M14.6367123,14.784 L21.6236712,14.784 C22.2588493,14.784 22.7835616,15.316 22.7835616,15.96 C22.7835616,16.604 22.2588493,17.136 21.6236712,17.136 L14.6367123,17.136 C14.0015342,17.136 13.4768219,16.604 13.4768219,15.96 C13.4768219,15.316 14.0015342,14.784 14.6367123,14.784 Z M33.3054247,21.896 L40.2923836,21.896 C40.9275616,21.896 41.452274,22.428 41.452274,23.072 C41.452274,23.716 40.9275616,24.248 40.2923836,24.248 L33.3054247,24.248 C32.6702466,24.248 32.1455342,23.716 32.1455342,23.072 C32.1455342,22.428 32.6702466,21.896 33.3054247,21.896 Z" id="Shape" fill="#E1DBF1" fill-rule="nonzero"></path>
<path d="M40.32,14.784 L47.3069589,14.784 C47.942137,14.784 48.4668493,15.316 48.4668493,15.96 C48.4668493,16.604 47.942137,17.136 47.3069589,17.136 L40.32,17.136 C39.6848219,17.136 39.1601096,16.604 39.1601096,15.96 C39.1324932,15.316 39.6572055,14.784 40.32,14.784 Z" id="Path" fill="#EEEEEE" fill-rule="nonzero"></path>
<path d="M21.6512877,28.98 L28.6382466,28.98 C29.2734247,28.98 29.798137,29.512 29.798137,30.156 C29.798137,30.8 29.2734247,31.332 28.6382466,31.332 L21.6512877,31.332 C21.0161096,31.332 20.4913973,30.8 20.4913973,30.156 C20.4637808,29.512 20.9884932,28.98 21.6512877,28.98 Z" id="Path" fill="#E1DBF1" fill-rule="nonzero"></path>
<path d="M26.2908493,14.784 L28.6382466,14.784 C29.2734247,14.784 29.798137,15.316 29.798137,15.96 C29.798137,16.604 29.2734247,17.136 28.6382466,17.136 L26.2908493,17.136 C25.6556712,17.136 25.1309589,16.604 25.1309589,15.96 C25.1309589,15.316 25.6556712,14.784 26.2908493,14.784 Z" id="Path" fill="#FEE1D3" fill-rule="nonzero"></path>
<path d="M33.3054247,36.092 L35.6528219,36.092 C36.288,36.092 36.8127123,36.624 36.8127123,37.268 C36.8127123,37.912 36.288,38.444 35.6528219,38.444 L33.3054247,38.444 C32.6702466,38.444 32.1455342,37.912 32.1455342,37.268 C32.1455342,36.624 32.6702466,36.092 33.3054247,36.092 Z" id="Path" fill="#FC6D26" fill-rule="nonzero"></path>
<path d="M44.9595616,21.896 L47.3069589,21.896 C47.942137,21.896 48.4668493,22.428 48.4668493,23.072 C48.4668493,23.716 47.942137,24.248 47.3069589,24.248 L44.9595616,24.248 C44.3243836,24.248 43.7996712,23.716 43.7996712,23.072 C43.7996712,22.428 44.3243836,21.896 44.9595616,21.896 Z M51.974137,14.784 L54.3215342,14.784 C54.9567123,14.784 55.4814247,15.316 55.4814247,15.96 C55.4814247,16.604 54.9567123,17.136 54.3215342,17.136 L51.974137,17.136 C51.3389589,17.136 50.8142466,16.604 50.8142466,15.96 C50.8142466,15.316 51.3389589,14.784 51.974137,14.784 Z" id="Shape" fill="#FEF0E8" fill-rule="nonzero"></path>
<path d="M23.9710685,43.176 L28.6382466,43.176 C29.2734247,43.176 29.798137,43.708 29.798137,44.352 C29.798137,44.996 29.2734247,45.528 28.6382466,45.528 L23.9710685,45.528 C23.3358904,45.528 22.8111781,44.996 22.8111781,44.352 C22.8111781,43.708 23.3358904,43.176 23.9710685,43.176 Z" id="Path" fill="#E1DBF1" fill-rule="nonzero"></path>
<path d="M40.32,36.092 L42.6673973,36.092 C43.3025753,36.092 43.8272877,36.624 43.8272877,37.268 C43.8272877,37.912 43.3025753,38.444 42.6673973,38.444 L40.32,38.444 C39.6848219,38.444 39.1601096,37.912 39.1601096,37.268 C39.1324932,36.624 39.6572055,36.092 40.32,36.092 Z" id="Path" fill="#FC6D26" fill-rule="nonzero"></path>
<path d="M52.2503014,33.712 C53.0511781,33.712 53.7139726,34.384 53.7139726,35.196 C53.7139726,36.008 53.0511781,36.68 52.2503014,36.68 C51.4494247,36.68 50.7866301,36.008 50.7866301,35.196 C50.8142466,34.384 51.4494247,33.712 52.2503014,33.712 Z M58.1049863,50.876 C58.905863,50.876 59.5686575,51.548 59.5686575,52.36 C59.5686575,53.172 58.905863,53.844 58.1049863,53.844 C57.3041096,53.844 56.6413151,53.172 56.6413151,52.36 C56.6413151,51.548 57.3041096,50.876 58.1049863,50.876 Z" id="Shape" fill="#E1DBF1" fill-rule="nonzero"></path>
<path d="M63.3521096,50.876 C64.1529863,50.876 64.8157808,51.548 64.8157808,52.36 C64.8157808,53.172 64.1529863,53.844 63.3521096,53.844 C62.5512329,53.844 61.8884384,53.172 61.8884384,52.36 C61.8884384,51.548 62.5512329,50.876 63.3521096,50.876 Z M33.3054247,14.784 L35.6528219,14.784 C36.288,14.784 36.8127123,15.316 36.8127123,15.96 C36.8127123,16.604 36.288,17.136 35.6528219,17.136 L33.3054247,17.136 C32.6702466,17.136 32.1455342,16.604 32.1455342,15.96 C32.1455342,15.316 32.6702466,14.784 33.3054247,14.784 Z" id="Shape" fill="#FC6D26" fill-rule="nonzero"></path>
<path d="M14.6367123,36.092 L28.6382466,36.092 C29.2734247,36.092 29.798137,36.624 29.798137,37.268 C29.798137,37.912 29.2734247,38.444 28.6382466,38.444 L14.6367123,38.444 C14.0015342,38.444 13.4768219,37.912 13.4768219,37.268 C13.4768219,36.624 14.0015342,36.092 14.6367123,36.092 Z M44.0482192,42 L61.0599452,42 C61.8332055,42 62.4683836,42.672 62.4683836,43.484 C62.4683836,44.296 61.8332055,44.968 61.0599452,44.968 L44.0758356,44.968 C43.3025753,44.968 42.6673973,44.296 42.6673973,43.484 C42.6673973,42.672 43.2749589,42 44.0482192,42 L44.0482192,42 L44.0482192,42 Z" id="Shape" fill="#EEEEEE" fill-rule="nonzero"></path>
<path d="M35.3214247,50.876 L52.3055342,50.876 C53.0787945,50.876 53.7139726,51.548 53.7139726,52.36 C53.7139726,53.172 53.0787945,53.844 52.3055342,53.844 L35.3214247,53.844 C34.5481644,53.844 33.9129863,53.172 33.9129863,52.36 C33.8853699,51.548 34.5205479,50.876 35.3214247,50.876 L35.3214247,50.876 L35.3214247,50.876 Z" id="Path" fill="#EFEDF8" fill-rule="nonzero"></path>
<path d="M14.6367123,21.896 L28.6382466,21.896 C29.2734247,21.896 29.798137,22.428 29.798137,23.072 C29.798137,23.716 29.2734247,24.248 28.6382466,24.248 L14.6367123,24.248 C14.0015342,24.248 13.4768219,23.716 13.4768219,23.072 C13.4768219,22.428 14.0015342,21.896 14.6367123,21.896 Z" id="Path" fill="#6B4FBB" fill-rule="nonzero"></path>
<path d="M33.3054247,28.98 L47.3069589,28.98 C47.942137,28.98 48.4668493,29.512 48.4668493,30.156 C48.4668493,30.8 47.942137,31.332 47.3069589,31.332 L33.3054247,31.332 C32.6702466,31.332 32.1455342,30.8 32.1455342,30.156 C32.1455342,29.512 32.6702466,28.98 33.3054247,28.98 Z" id="Path" fill="#C3B8E3" fill-rule="nonzero"></path>
<path d="M14.6367123,28.98 L16.9841096,28.98 C17.6192877,28.98 18.144,29.512 18.144,30.156 C18.144,30.8 17.6192877,31.332 16.9841096,31.332 L14.6367123,31.332 C14.0015342,31.332 13.4768219,30.8 13.4768219,30.156 C13.4768219,29.512 14.0015342,28.98 14.6367123,28.98 Z" id="Path" fill="#FEF0E8" fill-rule="nonzero"></path>
<path d="M33.3054247,43.176 L35.6528219,43.176 C36.288,43.176 36.8127123,43.708 36.8127123,44.352 C36.8127123,44.996 36.288,45.528 35.6528219,45.528 L33.3054247,45.528 C32.6702466,45.528 32.1455342,44.996 32.1455342,44.352 C32.1455342,43.708 32.6702466,43.176 33.3054247,43.176 Z" id="Path" fill="#6B4FBB" fill-rule="nonzero"></path>
<path d="M14.6367123,43.176 L19.3038904,43.176 C19.9390685,43.176 20.4637808,43.708 20.4637808,44.352 C20.4637808,44.996 19.9390685,45.528 19.3038904,45.528 L14.6367123,45.528 C14.0015342,45.528 13.4768219,44.996 13.4768219,44.352 C13.4768219,43.708 14.0015342,43.176 14.6367123,43.176 Z" id="Path" fill="#FC6D26" fill-rule="nonzero"></path>
<path d="M14.6367123,50.288 L19.3038904,50.288 C19.9390685,50.288 20.4637808,50.82 20.4637808,51.464 C20.4637808,52.108 19.9390685,52.64 19.3038904,52.64 L14.6367123,52.64 C14.0015342,52.64 13.4768219,52.108 13.4768219,51.464 C13.4768219,50.82 14.0015342,50.288 14.6367123,50.288 Z M23.9710685,50.288 L28.6382466,50.288 C29.2734247,50.288 29.798137,50.82 29.798137,51.464 C29.798137,52.108 29.2734247,52.64 28.6382466,52.64 L23.9710685,52.64 C23.3358904,52.64 22.8111781,52.108 22.8111781,51.464 C22.8111781,50.82 23.3358904,50.288 23.9710685,50.288 Z" id="Shape" fill="#FEF0E8" fill-rule="nonzero"></path>
<path d="M14.6367123,57.372 L21.6236712,57.372 C22.2588493,57.372 22.7835616,57.904 22.7835616,58.548 C22.7835616,59.192 22.2588493,59.724 21.6236712,59.724 L14.6367123,59.724 C14.0015342,59.724 13.4768219,59.192 13.4768219,58.548 C13.4768219,57.904 14.0015342,57.372 14.6367123,57.372 Z" id="Path" fill="#EFEDF8" fill-rule="nonzero"></path>
<path d="M25.3518904,64.484 L33.6644384,64.484 C34.4376986,64.484 35.0452603,65.016 35.0452603,65.66 C35.0452603,66.304 34.4376986,66.836 33.6644384,66.836 L25.3518904,66.836 C24.5786301,66.836 23.9710685,66.304 23.9710685,65.66 C23.9710685,65.016 24.5786301,64.484 25.3518904,64.484 Z" id="Path" fill="#FC6D26" fill-rule="nonzero"></path>
<path d="M44.0206027,59.136 L52.3331507,59.136 C53.106411,59.136 53.7139726,59.808 53.7139726,60.62 C53.7139726,61.432 53.106411,62.104 52.3331507,62.104 L44.0206027,62.104 C43.2473425,62.104 42.6397808,61.432 42.6397808,60.62 C42.6397808,59.808 43.2473425,59.136 44.0206027,59.136 Z" id="Path" fill="#6B4FBB" fill-rule="nonzero"></path>
<path d="M26.2908493,57.372 L28.6382466,57.372 C29.2734247,57.372 29.798137,57.904 29.798137,58.548 C29.798137,59.192 29.2734247,59.724 28.6382466,59.724 L26.2908493,59.724 C25.6556712,59.724 25.1309589,59.192 25.1309589,58.548 C25.1309589,57.904 25.6556712,57.372 26.2908493,57.372 Z" id="Path" fill="#FEE1D3" fill-rule="nonzero"></path>
<path d="M36.8127123,64.484 L39.1601096,64.484 C39.7952877,64.484 40.32,65.016 40.32,65.66 C40.32,66.304 39.7952877,66.836 39.1601096,66.836 L36.8127123,66.836 C36.1775342,66.836 35.6528219,66.304 35.6528219,65.66 C35.6528219,65.016 36.1775342,64.484 36.8127123,64.484 Z M58.1049863,59.136 L61.0323288,59.136 C61.8332055,59.136 62.496,59.808 62.496,60.62 C62.496,61.432 61.8332055,62.104 61.0323288,62.104 L58.1049863,62.104 C57.3041096,62.104 56.6413151,61.432 56.6413151,60.62 C56.6413151,59.808 57.3041096,59.136 58.1049863,59.136 Z" id="Shape" fill="#FEF0E8" fill-rule="nonzero"></path>
<path d="M35.3490411,59.136 L38.2763836,59.136 C39.0772603,59.136 39.7400548,59.808 39.7400548,60.62 C39.7400548,61.432 39.0772603,62.104 38.2763836,62.104 L35.3490411,62.104 C34.5481644,62.104 33.8853699,61.432 33.8853699,60.62 C33.8853699,59.808 34.5481644,59.136 35.3490411,59.136 Z" id="Path" fill="#FC6D26" fill-rule="nonzero"></path>
<path d="M14.6367123,64.484 L20.4637808,64.484 C21.0989589,64.484 21.6236712,65.016 21.6236712,65.66 C21.6236712,66.304 21.0989589,66.836 20.4637808,66.836 L14.6367123,66.836 C14.0015342,66.836 13.4768219,66.304 13.4768219,65.66 C13.4768219,65.016 14.0015342,64.484 14.6367123,64.484 Z" id="Path" fill="#EEEEEE" fill-rule="nonzero"></path>
<g id="Group-2" transform="translate(16.000000, 20.000000)">
<ellipse id="Oval" fill="#FFFFFF" fill-rule="nonzero" cx="20.4085479" cy="20.692" rx="20.4085479" ry="20.692"></ellipse>
<path d="M20.4085479,41.384 C9.1410411,41.384 8.17124146e-14,32.116 8.17124146e-14,20.692 C8.17124146e-14,9.268 9.1410411,1.0658141e-14 20.4085479,1.0658141e-14 C31.6760548,1.0658141e-14 40.8170959,9.268 40.8170959,20.692 C40.8170959,32.116 31.7036712,41.384 20.4085479,41.384 Z M20.4085479,39.032 C30.4056986,39.032 38.4973151,30.828 38.4973151,20.692 C38.4973151,10.556 30.4056986,2.352 20.4085479,2.352 C10.4113973,2.352 2.31978082,10.556 2.31978082,20.692 C2.31978082,30.828 10.4390137,39.032 20.4085479,39.032 Z" id="Shape" fill="#EEEEEE" fill-rule="nonzero"></path>
<g id="Group" transform="translate(10.439014, 11.480000)">
<path d="M19.7457534,10.528 L18.6410959,7.112 L16.4593973,0.336 C16.3489315,7.97972799e-15 15.8794521,7.97972799e-15 15.7413699,0.336 L13.5872877,7.112 L6.37939726,7.112 L4.19769863,0.336 C4.08723288,7.97972799e-15 3.61775342,7.97972799e-15 3.47967123,0.336 L1.2979726,7.112 L0.193315068,10.528 C0.0828493151,10.836 0.193315068,11.172 0.469479452,11.368 L9.94191781,18.34 L19.4143562,11.368 C19.718137,11.172 19.8286027,10.836 19.7457534,10.528" id="Path" fill="#FC6D26"></path>
<polygon id="Path" fill="#E24329" points="9.96953425 18.34 13.5596712 7.112 6.35178082 7.112"></polygon>
<polygon id="Path" fill="#FC6D26" points="9.96953425 18.34 6.37939726 7.112 1.32558904 7.112"></polygon>
<path d="M1.32558904,7.112 L0.220931507,10.528 C0.110465753,10.836 0.220931507,11.172 0.49709589,11.368 L9.96953425,18.34 L1.32558904,7.112 Z" id="Path" fill="#FCA326"></path>
<path d="M1.32558904,7.112 L6.37939726,7.112 L4.19769863,0.336 C4.08723288,7.9658502e-15 3.61775342,7.9658502e-15 3.47967123,0.336 L1.32558904,7.112 Z" id="Path" fill="#E24329"></path>
<polygon id="Path" fill="#FC6D26" points="9.96953425 18.34 13.5596712 7.112 18.6134795 7.112"></polygon>
<path d="M18.6410959,7.112 L19.7457534,10.528 C19.8562192,10.836 19.7457534,11.172 19.469589,11.368 L9.99715068,18.34 L18.6410959,7.112 Z" id="Path" fill="#FCA326"></path>
<path d="M18.6410959,7.112 L13.5872877,7.112 L15.7689863,0.336 C15.8794521,7.9658502e-15 16.3489315,7.9658502e-15 16.4870137,0.336 L18.6410959,7.112 Z" id="Path" fill="#E24329"></path>
</g>
</g>
</g>
</g>
</g>
</svg>
\ No newline at end of file
import Vue from 'vue';
import NewProjectCreationApp from './components/app.vue';
export default function(el, props) {
return new Vue({
el,
components: {
NewProjectCreationApp,
},
render(h) {
return h(NewProjectCreationApp, { props });
},
});
}
......@@ -116,3 +116,17 @@
}
}
}
.experiment-new-project-page-blank-state {
@include media-breakpoint-down(md) {
flex-direction: column;
justify-content: center;
text-align: center;
}
}
$experiment-new-project-indigo-700: #41419f;
.experiment-new-project-page-blank-state-title {
color: $experiment-new-project-indigo-700;
}
......@@ -34,6 +34,12 @@ class ProjectsController < Projects::ApplicationController
# Project Export Rate Limit
before_action :export_rate_limit, only: [:export, :download_export, :generate_new_export]
# Experiments
before_action only: [:new, :create] do
frontend_experimentation_tracking_data(:new_create_project_ui, 'click_tab')
push_frontend_feature_flag(:new_create_project_ui) if experiment_enabled?(:new_create_project_ui)
end
layout :determine_layout
def index
......
......@@ -95,7 +95,8 @@ module EnvironmentsHelper
'empty-loading-svg-path' => image_path('illustrations/monitoring/loading.svg'),
'empty-no-data-svg-path' => image_path('illustrations/monitoring/no_data.svg'),
'empty-no-data-small-svg-path' => image_path('illustrations/chart-empty-state-small.svg'),
'empty-unable-to-connect-svg-path' => image_path('illustrations/monitoring/unable_to_connect.svg')
'empty-unable-to-connect-svg-path' => image_path('illustrations/monitoring/unable_to_connect.svg'),
'custom-dashboard-base-path' => Metrics::Dashboard::CustomDashboardService::DASHBOARD_ROOT
}
end
end
......
......@@ -7,7 +7,11 @@
.project-edit-container.prepend-top-default
.project-edit-errors
= render 'projects/errors'
.row
- if experiment_enabled?(:new_create_project_ui)
.js-experiment-new-project-creation{ data: { is_ci_cd_available: ci_cd_projects_available?, has_errors: @project.errors.any? } }
.row{ 'v-cloak': experiment_enabled?(:new_create_project_ui) }
.col-lg-3.profile-settings-sidebar
%h4.gl-mt-0
= _('New project')
......@@ -32,15 +36,15 @@
.col-lg-9.js-toggle-container
%ul.nav.nav-tabs.nav-links.gitlab-tabs{ role: 'tablist' }
%li.nav-item{ role: 'presentation' }
%a.nav-link.active{ href: '#blank-project-pane', id: 'blank-project-tab', data: { toggle: 'tab', track_label: 'blank_project', track_event: "click_tab", track_value: "" }, role: 'tab' }
%a.nav-link.active{ href: '#blank-project-pane', id: 'blank-project-tab', data: { toggle: 'tab', experiment_track_label: 'blank_project' }, role: 'tab' }
%span.d-none.d-sm-block= s_('ProjectsNew|Blank project')
%span.d-block.d-sm-none= s_('ProjectsNew|Blank')
%li.nav-item{ role: 'presentation' }
%a.nav-link{ href: '#create-from-template-pane', id: 'create-from-template-tab', data: { toggle: 'tab', track_label: 'create_from_template', track_event: "click_tab", track_value: "" }, role: 'tab' }
%a.nav-link{ href: '#create-from-template-pane', id: 'create-from-template-tab', data: { toggle: 'tab', experiment_track_label: 'create_from_template' }, role: 'tab' }
%span.d-none.d-sm-block.qa-project-create-from-template-tab= s_('ProjectsNew|Create from template')
%span.d-block.d-sm-none= s_('ProjectsNew|Template')
%li.nav-item{ role: 'presentation' }
%a.nav-link{ href: '#import-project-pane', id: 'import-project-tab', data: { toggle: 'tab', track_label: 'import_project', track_event: "click_tab", track_value: "" }, role: 'tab' }
%a.nav-link{ href: '#import-project-pane', id: 'import-project-tab', data: { toggle: 'tab', experiment_track_label: 'import_project' }, role: 'tab' }
%span.d-none.d-sm-block= s_('ProjectsNew|Import project')
%span.d-block.d-sm-none= s_('ProjectsNew|Import')
= render_if_exists 'projects/new_ci_cd_only_project_tab', active_tab: active_tab
......
---
title: Specify tiers for SAML SSO at self-hosted plans
merge_request: 34040
author: Takuya Noguchi
type: other
......@@ -6,14 +6,12 @@
The access levels are defined in the `Gitlab::Access` module. Currently, these levels are recognized:
```plaintext
0 => No access
10 => Guest access
20 => Reporter access
30 => Developer access
40 => Maintainer access
50 => Owner access # Only valid for groups
```
- No access (`0`)
- Guest (`10`)
- Reporter (`20`)
- Developer (`30`)
- Maintainer (`40`)
- Owner (`50`) - Only valid to set for groups
## List access requests for a group or project
......
......@@ -4,13 +4,17 @@
The access levels are defined in the `Gitlab::Access` module. Currently, these levels are recognized:
```plaintext
10 => Guest access
20 => Reporter access
30 => Developer access
40 => Maintainer access
50 => Owner access # Only valid for groups
```
- No access (`0`)
- Guest (`10`)
- Reporter (`20`)
- Developer (`30`)
- Maintainer (`40`)
- Owner (`50`) - Only valid to set for groups
CAUTION: **Caution:**
Due to [an issue](https://gitlab.com/gitlab-org/gitlab/-/issues/219299),
projects in personal namespaces will not show owner (`50`) permission
for owner.
## List all members of a group or project
......
......@@ -41,11 +41,12 @@ can be accessed only by project members by default.
Users can be members of multiple groups and projects. The following access
levels are available (defined in the `Gitlab::Access` module):
- Guest
- Reporter
- Developer
- Maintainer
- Owner
- No access (`0`)
- Guest (`10`)
- Reporter (`20`)
- Developer (`30`)
- Maintainer (`40`)
- Owner (`50`)
If a user is the member of both a project and the project parent group, the
higher permission is taken into account for the project.
......@@ -56,6 +57,12 @@ can still view the groups and their entities (like epics).
Project membership (where the group membership is already taken into account)
is stored in the `project_authorizations` table.
CAUTION: **Caution:**
Due to [an issue](https://gitlab.com/gitlab-org/gitlab/-/issues/219299),
projects in personal namespace will not show owner (`50`) permission in
`project_authorizations` table. Note however that [`user.owned_projects`](https://gitlab.com/gitlab-org/gitlab/blob/0d63823b122b11abd2492bca47cc26858eee713d/app/models/user.rb#L906-916)
is calculated properly.
### Confidential issues
Confidential issues can be accessed only by project members who are at least
......
# SAML OmniAuth Provider
# SAML OmniAuth Provider **(CORE ONLY)**
Note that:
......
......@@ -203,7 +203,6 @@ The GitLab University curriculum is composed of GitLab videos, screencasts, pres
NOTE: **Note:**
Some content can only be accessed by GitLab team members.
1. [Support Path](support/README.md)
1. [Sales Path](https://about.gitlab.com/handbook/sales/onboarding/)
1. [User Training](training/user_training.md)
1. [GitLab Flow Training](training/gitlab_flow.md)
......
---
comments: false
type: reference
---
# Support Boot Camp
**Goal:** Prepare new Service Engineers at GitLab
For each stage, there are learning goals and content to support the learning of the engineer.
The goal of this boot camp is to have every Service Engineer prepared to help our customers
with whatever needs they might have and to also assist our awesome community with their
questions.
Always start with the [University Overview](../README.md) and then work
your way here for more advanced and specific training. Once you feel comfortable
with the topics of the current stage, move to the next.
## Stage 1
Follow the topics on the [University Overview](../README.md), concentrate on it
during your first Stage, but also:
- Perform the [first steps](https://about.gitlab.com/handbook/support/onboarding/#first-steps) of
the on-boarding process for new Service Engineers
### Goals
Aim to have a good overview of the Product and main features, Git and the Company
## Stage 2
Continue to look over remaining portions of the [University Overview](../README.md) and continue on to these topics:
### Set up your development machine
Get your development machine ready to familiarize yourself with the codebase, the components, and to be prepared to reproduce issues that our users encounter
- Install the [GDK](https://gitlab.com/gitlab-org/gitlab-development-kit)
- [Set up OpenLDAP as part of this](https://gitlab.com/gitlab-org/gitlab-development-kit#openldap)
### Become comfortable with the Installation processes that we support
It's important to understand how to install GitLab in the same way that our users do. Try installing different versions and upgrading and downgrading between them. Installation from source will give you a greater understanding of the components that we employ and how everything fits together.
Sometimes we need to upgrade customers from old versions of GitLab to latest, so it's good to get some experience of doing that now.
- [Installation Methods](https://about.gitlab.com/install/):
- [Omnibus](https://gitlab.com/gitlab-org/omnibus-gitlab/)
- [Docker](../../install/docker.md)
- [Source](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/install/installation.md)
- Get yourself a Digital Ocean droplet, where you can install and maintain your own instance of GitLab
- Ask in #infrastructure about this
- Populate with some test data
- Keep this up-to-date as patch and version releases become available, just like our customers would
- Try out the following installation path
- [Install GitLab 4.2 from source](https://gitlab.com/gitlab-org/gitlab-foss/blob/d67117b5a185cfb15a1d7e749588ff981ffbf779/doc/install/installation.md)
- External MySQL database
- External NGINX
- Create some test data
- Populated Repos
- Users
- Groups
- Projects
- [Back up using our backup Rake task](../../raketasks/backup_restore.md#back-up-gitlab)
- [Upgrade to 5.0 source using our Upgrade documentation](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/update/4.2-to-5.0.md)
- [Upgrade to 5.1 source](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/update/5.0-to-5.1.md)
- [Upgrade to 6.0 source](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/update/5.1-to-6.0.md)
- [Upgrade to 7.14 source](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/update/6.x-or-7.x-to-7.14.md)
- [Perform the MySQL to PostgreSQL migration to convert your backup](../../update/mysql_to_postgresql.md)
- [Upgrade to Omnibus 7.14](https://docs.gitlab.com/omnibus/update/README.html#upgrading-from-a-non-omnibus-installation-to-an-omnibus-installation)
- [Restore backup using our Restore Rake task](../../raketasks/backup_restore.md#restore-gitlab)
- [Upgrade to latest EE](https://about.gitlab.com/update/)
- (GitLab inc. only) Acquire and apply a license for the Enterprise Edition product, ask in #support
- Perform a downgrade from [EE to CE](../../downgrade_ee_to_ce/README.md)
### Start to learn about some of the integrations that we support
Our integrations add great value to GitLab. User questions often relate to integrating GitLab with existing external services and the configuration involved
- Learn about our Integrations (specially, not only):
- [LDAP](../../integration/ldap.md)
- [Jira](../../project_services/jira.md)
- [Jenkins](../../integration/jenkins.md)
- [SAML](../../integration/saml.md)
### Goals
- Aim to be comfortable with installation of the GitLab product and configuration of some of the major integrations
- Aim to have an installation available for reproducing customer reports
## Stage 3
### Understand the gathering of diagnostics for GitLab instances
- Learn about the GitLab checks that are available:
- [Environment Information and maintenance checks](../../raketasks/maintenance.md)
- [GitLab check](../../raketasks/check.md)
- Omnibus commands
- [Status](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/maintenance/README.md#get-service-status)
- [Starting and stopping services](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/maintenance/README.md#starting-and-stopping)
- [Starting a rails console](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/doc/maintenance/README.md#invoking-rake-tasks)
### Learn about the Support process
Zendesk is our Support Center and our main communication line with our Customers. We communicate with customers through several other channels too
- Familiarize yourself with ZenDesk:
- [UI Overview](https://support.zendesk.com/hc/en-us/articles/203661806-Introduction-to-the-Zendesk-agent-interface)
- [Updating Tickets](https://support.zendesk.com/hc/en-us/articles/212530318-Updating-and-solving-tickets)
- [Working w/ Tickets](https://support.zendesk.com/hc/en-us/articles/203690856-Working-with-tickets) *Read: avoiding agent collision.*
- Dive into our ZenDesk support process by reading how to [handle tickets](https://about.gitlab.com/handbook/support/onboarding/#handling-tickets)
- Start getting real world experience by handling real tickets, all the while gaining further experience with the Product.
- First, learn about our [Support Channels](https://about.gitlab.com/handbook/support/#support-channels)
- Ask other Service Engineers for help, when necessary, and to review your responses
- Start with [StackOverflow](https://about.gitlab.com/handbook/support/#stack-overflowa-namestack-overflowa) and the [GitLab forum](https://about.gitlab.com/handbook/support/#foruma-namegitlab-foruma)
- Here you will find a large variety of queries mainly from our Users who are self hosting GitLab CE
- Understand the questions that are asked and dig in to try to find a solution
- [Proceed on to the GitLab.com Support Forum](https://about.gitlab.com/handbook/support/#gitlabcom-support-trackera-namesupp-foruma)
- Here you will find queries regarding our own GitLab.com
- Helping Users here will give you an understanding of our Admin interface and other tools
- [Proceed on to the Twitter tickets in Zendesk](https://about.gitlab.com/handbook/support/#twitter)
- Here you will gain a great insight into our userbase
- Learn from any complaints and problems and feed them back to the team
- Tweets can range from help needed with GitLab installations, the API and just general queries
- [Proceed on to Regular email Support tickets](https://about.gitlab.com/handbook/support/#regular-zendesk-tickets-a-nameregulara)
- Here you will find tickets from our GitLab EE Customers and GitLab CE Users
- Tickets here are extremely varied and often very technical
- You should be prepared for these tickets, given the knowledge gained from previous tiers and your training
- Check out your colleagues' responses
- Hop on to the #support-live-feed channel in Slack and see the tickets as they come in and are updated
- Read through old tickets that your colleagues have worked on
- Start arranging to pair on calls with other Service Engineers. Aim to cover a few of each type of call
- [Learn about Cisco WebEx](https://about.gitlab.com/handbook/support/onboarding/#webexa-namewebexa)
- Training calls
- Information gathering calls
- It's good to find out how new and prospective customers are going to be using the product and how they will set up their infrastructure
- Diagnosis calls
- When email isn't enough we may need to hop on a call and do some debugging along side the customer
- These paired calls are a great learning experience
- Upgrade calls
- Emergency calls
### Learn about the Escalation process for tickets
Some tickets need specific knowledge or a deep understanding of a particular component and will need to be escalated to a Senior Service Engineer or Developer
- Read about [Escalation](https://about.gitlab.com/handbook/support/workflows/working-with-issues.html#functional-escalation-points)
- Find the macros in Zendesk for ticket escalations
- Take a look at the [GitLab.com Team page](https://about.gitlab.com/company/team/) to find the resident experts in their fields
### Learn about raising issues and fielding feature proposals
- Understand what's in the pipeline and proposed features at GitLab: [Direction Page](https://about.gitlab.com/direction/)
- Practice searching issues and filtering using [labels](https://gitlab.com/gitlab-org/gitlab/-/labels) to find existing feature proposals and bugs
- If raising a new issue always provide a relevant label and a link to the relevant ticket in Zendesk
- Add [customer labels](https://gitlab.com/gitlab-org/gitlab/-/issues?label_name%5B%5D=customer) for those issues relevant to our subscribers
- Take a look at the [existing issue templates](https://gitlab.com/gitlab-org/gitlab/blob/master/CONTRIBUTING.md#issue-tracker) to see what is expected
- Raise issues for bugs in a manner that would make the issue easily reproducible. A Developer or a contributor may work on your issue
### Goals
- Aim to have a good understanding of the problems that customers are facing
- Aim to have gained experience in scheduling and participating in calls with customers
- Aim to have a good understanding of ticket flow through Zendesk and how to interact with our various channels
## Stage 4
### Advanced GitLab topics
Move on to understanding some of GitLab's more advanced features. You can make use of GitLab.com to understand the features from an end-user perspective and then use your own instance to understand setup and configuration of the feature from an Administrative perspective
- Set up and try [Git LFS](../../topics/git/lfs/index.md)
- Get to know the [GitLab API](../../api/README.md), its capabilities and shortcomings
- Learn how to [migrate from SVN to Git](../../user/project/import/svn.md)
- Set up [GitLab CI/CD](../../ci/quick_start/README.md)
- Create your first [GitLab Page](../../administration/pages/index.md)
- Get to know the GitLab Codebase by reading through the source code:
- Find the differences between the [EE codebase](https://gitlab.com/gitlab-org/gitlab)
and the [CE codebase](https://gitlab.com/gitlab-org/gitlab-foss)
- Ask as many questions as you can think of on the `#support` chat channel
### Get initiated for on-call duty
- Read over the [public run-books to understand common tasks](https://gitlab.com/gitlab-com/runbooks)
- Create an issue on the internal Organization tracker to schedule time with the DevOps / Production team, so that you learn how to handle GitLab.com going down. Once you are trained for this, you are ready to be added to the on-call rotation.
### Goals
- Aim to become a fully-fledged Service Engineer!
<!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues
one might have when setting this up, or when something is changed, or on upgrading, it's
important to describe those, too. Think of things that may go wrong and include them here.
This is important to minimize requests for support, and to avoid doc comments with
questions that you know someone might ask.
Each scenario can be a third-level heading, e.g. `### Getting error message X`.
If you have none to add when creating a doc, leave this section in place
but commented out to help encourage others to add to it in the future. -->
......@@ -907,10 +907,10 @@ Major upgrades might require additional setup steps, please consult
the official [upgrade guide](https://docs.cilium.io/en/stable/install/upgrade/) for more
information.
By default, Cilium will drop all non-whitelisted packets upon policy
By default, Cilium will drop all disallowed packets upon policy
deployment. The audit mode is scheduled for release in
[Cilium 1.8](https://github.com/cilium/cilium/pull/9970). In the audit
mode, non-whitelisted packets will not be dropped, and audit
mode, disallowed packets will not be dropped, and audit
notifications will be generated instead. GitLab provides alternative Docker
images for Cilium with the audit patch included. You can switch to the
custom build and enable the audit mode by adding the following to
......
......@@ -1109,6 +1109,11 @@ These details <em>will</em> remain <strong>hidden</strong> until expanded.
Markdown inside these tags is supported as well.
NOTE: **Note:**
If your Markdown isn't rendering correctly, try adding
`{::options parse_block_html="true" /}` to the top of the page, and add
`markdown="span"` to the opening summary tag like this: `<summary markdown="span">`.
Remember to leave a blank line after the `</summary>` tag and before the `</details>` tag,
as shown in the example:
......
......@@ -92,9 +92,7 @@ module API
options[:with] = Entities::MergeRequestSimple
else
options[:issuable_metadata] = Gitlab::IssuableMetadata.new(current_user, merge_requests).data
if Feature.enabled?(:mr_list_api_skip_merge_status_recheck, default_enabled: true)
options[:skip_merge_status_recheck] = !declared_params[:with_merge_status_recheck]
end
options[:skip_merge_status_recheck] = !declared_params[:with_merge_status_recheck]
end
options
......
......@@ -50,6 +50,9 @@ module Gitlab
},
invite_members_version_a: {
tracking_category: 'Growth::Expansion::Experiment::InviteMembersVersionA'
},
new_create_project_ui: {
tracking_category: 'Manage::Import::Experiment::NewCreateProjectUi'
}
}.freeze
......
......@@ -2317,6 +2317,9 @@ msgstr ""
msgid "An error occurred while loading milestones"
msgstr ""
msgid "An error occurred while loading project creation UI"
msgstr ""
msgid "An error occurred while loading terraform report"
msgstr ""
......@@ -2658,6 +2661,9 @@ msgstr ""
msgid "Approved"
msgstr ""
msgid "Approved MRs"
msgstr ""
msgid "Approved by: "
msgstr ""
......@@ -6441,6 +6447,9 @@ msgstr ""
msgid "Create a personal access token on your account to pull or push via %{protocol}."
msgstr ""
msgid "Create a project pre-populated with the necessary files to get you started quickly."
msgstr ""
msgid "Create an account using:"
msgstr ""
......@@ -9614,6 +9623,9 @@ msgstr ""
msgid "FeatureFlags|There was an error fetching the feature flags."
msgstr ""
msgid "FeatureFlags|There was an error retrieving user lists"
msgstr ""
msgid "FeatureFlags|Try again in a few moments or contact your support team."
msgstr ""
......@@ -9623,9 +9635,18 @@ msgstr ""
msgid "FeatureFlag|Delete strategy"
msgstr ""
msgid "FeatureFlag|List"
msgstr ""
msgid "FeatureFlag|Percentage"
msgstr ""
msgid "FeatureFlag|Select a user list"
msgstr ""
msgid "FeatureFlag|There are no configured user lists"
msgstr ""
msgid "FeatureFlag|Type"
msgstr ""
......@@ -14044,6 +14065,9 @@ msgstr ""
msgid "Middleman project with Static Site Editor support"
msgstr ""
msgid "Migrate your data from an external source like GitHub, Bitbucket, or another instance of GitLab."
msgstr ""
msgid "Migrated %{success_count}/%{total_count} files."
msgstr ""
......@@ -17446,15 +17470,27 @@ msgstr ""
msgid "ProjectsNew|Blank project"
msgstr ""
msgid "ProjectsNew|Connect your external repository to GitLab CI/CD."
msgstr ""
msgid "ProjectsNew|Contact an administrator to enable options for importing your project."
msgstr ""
msgid "ProjectsNew|Create"
msgstr ""
msgid "ProjectsNew|Create a blank project to house your files, plan your work, and collaborate on code, among other things."
msgstr ""
msgid "ProjectsNew|Create blank project"
msgstr ""
msgid "ProjectsNew|Create from template"
msgstr ""
msgid "ProjectsNew|Create new project"
msgstr ""
msgid "ProjectsNew|Creating project & repository."
msgstr ""
......@@ -17479,6 +17515,9 @@ msgstr ""
msgid "ProjectsNew|Project description %{tag_start}(optional)%{tag_end}"
msgstr ""
msgid "ProjectsNew|Run CI/CD for external repository"
msgstr ""
msgid "ProjectsNew|Template"
msgstr ""
......
......@@ -40,8 +40,8 @@ then
fi
# Do not use 'README.md', instead use 'index.md'
# Number of 'README.md's as of 2018-03-26
NUMBER_READMES=46
# Number of 'README.md's as of 2020-05-28
NUMBER_READMES=45
FIND_READMES=$(find doc/ -name "README.md" | wc -l)
echo '=> Checking for new README.md files...'
echo
......
......@@ -41,6 +41,27 @@ RSpec.describe ProjectsController do
end
end
end
context 'with the new_create_project_ui experiment enabled and the user is part of the control group' do
before do
stub_experiment(new_create_project_ui: true)
stub_experiment_for_user(new_create_project_ui: false)
allow_any_instance_of(described_class).to receive(:experimentation_subject_id).and_return('uuid')
end
it 'passes the right tracking parameters to the frontend' do
get(:new)
expect(Gon.tracking_data).to eq(
{
category: 'Manage::Import::Experiment::NewCreateProjectUi',
action: 'click_tab',
label: 'uuid',
property: 'control_group'
}
)
end
end
end
end
......
import { shallowMount } from '@vue/test-utils';
import { GlBreadcrumb } from '@gitlab/ui';
import App from '~/projects/experiment_new_project_creation/components/app.vue';
import WelcomePage from '~/projects/experiment_new_project_creation/components/welcome.vue';
import LegacyContainer from '~/projects/experiment_new_project_creation/components/legacy_container.vue';
describe('Experimental new project creation app', () => {
let wrapper;
const createComponent = propsData => {
wrapper = shallowMount(App, { propsData });
};
afterEach(() => {
wrapper.destroy();
window.location.hash = '';
wrapper = null;
});
describe('with empty hash', () => {
beforeEach(() => {
createComponent();
});
it('renders welcome page', () => {
expect(wrapper.find(WelcomePage).exists()).toBe(true);
});
it('does not render breadcrumbs', () => {
expect(wrapper.find(GlBreadcrumb).exists()).toBe(false);
});
});
it('renders blank project container if there are errors', () => {
createComponent({ hasErrors: true });
expect(wrapper.find(WelcomePage).exists()).toBe(false);
expect(wrapper.find(LegacyContainer).exists()).toBe(true);
});
describe('when hash is not empty on load', () => {
beforeEach(() => {
window.location.hash = '#blank_project';
createComponent();
});
it('renders relevant container', () => {
expect(wrapper.find(WelcomePage).exists()).toBe(false);
expect(wrapper.find(LegacyContainer).exists()).toBe(true);
});
it('renders breadcrumbs', () => {
expect(wrapper.find(GlBreadcrumb).exists()).toBe(true);
});
});
it('renders relevant container when hash changes', () => {
createComponent();
expect(wrapper.find(WelcomePage).exists()).toBe(true);
window.location.hash = '#blank_project';
const ev = document.createEvent('HTMLEvents');
ev.initEvent('hashchange', false, false);
window.dispatchEvent(ev);
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.find(WelcomePage).exists()).toBe(false);
expect(wrapper.find(LegacyContainer).exists()).toBe(true);
});
});
});
import { shallowMount } from '@vue/test-utils';
import LegacyContainer from '~/projects/experiment_new_project_creation/components/legacy_container.vue';
import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
describe('Legacy container component', () => {
let wrapper;
let dummy;
const createComponent = propsData => {
wrapper = shallowMount(LegacyContainer, { propsData });
};
afterEach(() => {
wrapper.destroy();
resetHTMLFixture();
wrapper = null;
});
describe('when selector targets real node', () => {
beforeEach(() => {
setHTMLFixture('<div class="dummy-target"></div>');
dummy = document.querySelector('.dummy-target');
createComponent({ selector: '.dummy-target' });
});
it('moves node inside component when mounted', () => {
expect(dummy.parentNode).toBe(wrapper.element);
});
it('moves node back when unmounted', () => {
wrapper.destroy();
expect(dummy.parentNode).toBe(document.body);
});
});
describe('when selector targets template node', () => {
beforeEach(() => {
setHTMLFixture('<template class="dummy-target">content</template>');
dummy = document.querySelector('.dummy-target');
createComponent({ selector: '.dummy-target' });
});
it('copies node content when mounted', () => {
expect(dummy.innerHTML).toEqual(wrapper.element.innerHTML);
expect(dummy.parentNode).toBe(document.body);
});
});
});
import { shallowMount } from '@vue/test-utils';
import WelcomePage from '~/projects/experiment_new_project_creation/components/welcome.vue';
import { mockTracking } from 'helpers/tracking_helper';
describe('Welcome page', () => {
let wrapper;
let trackingSpy;
const createComponent = propsData => {
wrapper = shallowMount(WelcomePage, { propsData });
};
beforeEach(() => {
trackingSpy = mockTracking('_category_', document, jest.spyOn);
trackingSpy.mockImplementation(() => {});
});
afterEach(() => {
wrapper.destroy();
window.location.hash = '';
wrapper = null;
});
it('tracks link clicks', () => {
createComponent({ panels: [{ name: 'test', href: '#' }] });
wrapper.find('a').trigger('click');
return wrapper.vm.$nextTick().then(() => {
expect(trackingSpy).toHaveBeenCalledWith(undefined, 'click_tab', { label: 'test' });
});
});
});
......@@ -40,7 +40,8 @@ describe EnvironmentsHelper do
'validate-query-path' => validate_query_project_prometheus_metrics_path(project),
'custom-metrics-available' => 'true',
'alerts-endpoint' => project_prometheus_alerts_path(project, environment_id: environment.id, format: :json),
'prometheus-alerts-available' => 'true'
'prometheus-alerts-available' => 'true',
'custom-dashboard-base-path' => Metrics::Dashboard::CustomDashboardService::DASHBOARD_ROOT
)
end
......
......@@ -356,28 +356,35 @@ describe API::Commits do
}
end
shared_examples_for "successfully creates the commit" do
it "creates the commit" do
expect(response).to have_gitlab_http_status(:created)
expect(json_response['title']).to eq(message)
expect(json_response['committer_name']).to eq(user.name)
expect(json_response['committer_email']).to eq(user.email)
end
end
it 'does not increment the usage counters using access token authentication' do
expect(::Gitlab::UsageDataCounters::WebIdeCounter).not_to receive(:increment_commits_count)
post api(url, user), params: valid_c_params
end
it 'a new file in project repo' do
post api(url, user), params: valid_c_params
context 'a new file in project repo' do
before do
post api(url, user), params: valid_c_params
end
expect(response).to have_gitlab_http_status(:created)
expect(json_response['title']).to eq(message)
expect(json_response['committer_name']).to eq(user.name)
expect(json_response['committer_email']).to eq(user.email)
it_behaves_like "successfully creates the commit"
end
it 'a new file with utf8 chars in project repo' do
post api(url, user), params: valid_utf8_c_params
context 'a new file with utf8 chars in project repo' do
before do
post api(url, user), params: valid_utf8_c_params
end
expect(response).to have_gitlab_http_status(:created)
expect(json_response['title']).to eq(message)
expect(json_response['committer_name']).to eq(user.name)
expect(json_response['committer_email']).to eq(user.email)
it_behaves_like "successfully creates the commit"
end
it 'returns a 400 bad request if file exists' do
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册