Add latest changes from gitlab-org/gitlab@master
|
@ -35,7 +35,6 @@ export function membersBeforeSave(members) {
|
||||||
: '';
|
: '';
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: member.type,
|
|
||||||
username: member.username,
|
username: member.username,
|
||||||
avatarTag: autoCompleteAvatar.length === 1 ? txtAvatar : imgAvatar,
|
avatarTag: autoCompleteAvatar.length === 1 ? txtAvatar : imgAvatar,
|
||||||
title: sanitize(title),
|
title: sanitize(title),
|
||||||
|
@ -280,11 +279,7 @@ class GfmAutoComplete {
|
||||||
|
|
||||||
if (command === MEMBER_COMMAND.ASSIGN) {
|
if (command === MEMBER_COMMAND.ASSIGN) {
|
||||||
// Only include members which are not assigned to Issuable currently
|
// Only include members which are not assigned to Issuable currently
|
||||||
return data.filter(
|
return data.filter(member => !assignees.includes(member.search));
|
||||||
member => member.type === 'User' && !assignees.includes(member.search),
|
|
||||||
);
|
|
||||||
} else if (command === MEMBER_COMMAND.REASSIGN) {
|
|
||||||
return data.filter(member => member.type === 'User');
|
|
||||||
} else if (command === MEMBER_COMMAND.UNASSIGN) {
|
} else if (command === MEMBER_COMMAND.UNASSIGN) {
|
||||||
// Only include members which are assigned to Issuable currently
|
// Only include members which are assigned to Issuable currently
|
||||||
return data.filter(member => assignees.includes(member.search));
|
return data.filter(member => assignees.includes(member.search));
|
||||||
|
|
|
@ -41,7 +41,7 @@ export default {
|
||||||
:disabled="savingChanges"
|
:disabled="savingChanges"
|
||||||
@click="$emit('editSettings')"
|
@click="$emit('editSettings')"
|
||||||
>
|
>
|
||||||
{{ __('Settings') }}
|
{{ __('Page settings') }}
|
||||||
</gl-button>
|
</gl-button>
|
||||||
<gl-button
|
<gl-button
|
||||||
ref="submit"
|
ref="submit"
|
||||||
|
|
|
@ -4,6 +4,7 @@ import createDefaultClient from '~/lib/graphql';
|
||||||
import typeDefs from './typedefs.graphql';
|
import typeDefs from './typedefs.graphql';
|
||||||
import fileResolver from './resolvers/file';
|
import fileResolver from './resolvers/file';
|
||||||
import submitContentChangesResolver from './resolvers/submit_content_changes';
|
import submitContentChangesResolver from './resolvers/submit_content_changes';
|
||||||
|
import hasSubmittedChangesResolver from './resolvers/has_submitted_changes';
|
||||||
|
|
||||||
Vue.use(VueApollo);
|
Vue.use(VueApollo);
|
||||||
|
|
||||||
|
@ -15,6 +16,7 @@ const createApolloProvider = appData => {
|
||||||
},
|
},
|
||||||
Mutation: {
|
Mutation: {
|
||||||
submitContentChanges: submitContentChangesResolver,
|
submitContentChanges: submitContentChangesResolver,
|
||||||
|
hasSubmittedChanges: hasSubmittedChangesResolver,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
mutation hasSubmittedChanges($input: HasSubmittedChangesInput) {
|
||||||
|
hasSubmittedChanges(input: $input) @client {
|
||||||
|
hasSubmittedChanges
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
query appData {
|
query appData {
|
||||||
appData @client {
|
appData @client {
|
||||||
isSupportedContent
|
isSupportedContent
|
||||||
|
hasSubmittedChanges
|
||||||
project
|
project
|
||||||
sourcePath
|
sourcePath
|
||||||
username
|
username
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
import query from '../queries/app_data.query.graphql';
|
||||||
|
|
||||||
|
const hasSubmittedChangesResolver = (_, { input: { hasSubmittedChanges } }, { cache }) => {
|
||||||
|
const { appData } = cache.readQuery({ query });
|
||||||
|
cache.writeQuery({
|
||||||
|
query,
|
||||||
|
data: {
|
||||||
|
appData: {
|
||||||
|
__typename: 'AppData',
|
||||||
|
...appData,
|
||||||
|
hasSubmittedChanges,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export default hasSubmittedChangesResolver;
|
|
@ -16,12 +16,17 @@ type SavedContentMeta {
|
||||||
|
|
||||||
type AppData {
|
type AppData {
|
||||||
isSupportedContent: Boolean!
|
isSupportedContent: Boolean!
|
||||||
|
hasSubmittedChanges: Boolean!
|
||||||
project: String!
|
project: String!
|
||||||
returnUrl: String
|
returnUrl: String
|
||||||
sourcePath: String!
|
sourcePath: String!
|
||||||
username: String!
|
username: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input HasSubmittedChangesInput {
|
||||||
|
hasSubmittedChanges: Boolean!
|
||||||
|
}
|
||||||
|
|
||||||
input SubmitContentChangesInput {
|
input SubmitContentChangesInput {
|
||||||
project: String!
|
project: String!
|
||||||
sourcePath: String!
|
sourcePath: String!
|
||||||
|
@ -40,4 +45,5 @@ extend type Query {
|
||||||
|
|
||||||
extend type Mutation {
|
extend type Mutation {
|
||||||
submitContentChanges(input: SubmitContentChangesInput!): SavedContentMeta
|
submitContentChanges(input: SubmitContentChangesInput!): SavedContentMeta
|
||||||
|
hasSubmittedChanges(input: HasSubmittedChangesInput!): AppData
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ const initStaticSiteEditor = el => {
|
||||||
const router = createRouter(baseUrl);
|
const router = createRouter(baseUrl);
|
||||||
const apolloProvider = createApolloProvider({
|
const apolloProvider = createApolloProvider({
|
||||||
isSupportedContent: parseBoolean(isSupportedContent),
|
isSupportedContent: parseBoolean(isSupportedContent),
|
||||||
|
hasSubmittedChanges: false,
|
||||||
project: `${namespace}/${project}`,
|
project: `${namespace}/${project}`,
|
||||||
returnUrl,
|
returnUrl,
|
||||||
sourcePath,
|
sourcePath,
|
||||||
|
|
|
@ -5,6 +5,7 @@ import InvalidContentMessage from '../components/invalid_content_message.vue';
|
||||||
import SubmitChangesError from '../components/submit_changes_error.vue';
|
import SubmitChangesError from '../components/submit_changes_error.vue';
|
||||||
import appDataQuery from '../graphql/queries/app_data.query.graphql';
|
import appDataQuery from '../graphql/queries/app_data.query.graphql';
|
||||||
import sourceContentQuery from '../graphql/queries/source_content.query.graphql';
|
import sourceContentQuery from '../graphql/queries/source_content.query.graphql';
|
||||||
|
import hasSubmittedChangesMutation from '../graphql/mutations/has_submitted_changes.mutation.graphql';
|
||||||
import submitContentChangesMutation from '../graphql/mutations/submit_content_changes.mutation.graphql';
|
import submitContentChangesMutation from '../graphql/mutations/submit_content_changes.mutation.graphql';
|
||||||
import { deprecatedCreateFlash as createFlash } from '~/flash';
|
import { deprecatedCreateFlash as createFlash } from '~/flash';
|
||||||
import Tracking from '~/tracking';
|
import Tracking from '~/tracking';
|
||||||
|
@ -74,6 +75,20 @@ export default {
|
||||||
submitChanges(images) {
|
submitChanges(images) {
|
||||||
this.isSavingChanges = true;
|
this.isSavingChanges = true;
|
||||||
|
|
||||||
|
// eslint-disable-next-line promise/catch-or-return
|
||||||
|
this.$apollo
|
||||||
|
.mutate({
|
||||||
|
mutation: hasSubmittedChangesMutation,
|
||||||
|
variables: {
|
||||||
|
input: {
|
||||||
|
hasSubmittedChanges: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.$router.push(SUCCESS_ROUTE);
|
||||||
|
});
|
||||||
|
|
||||||
this.$apollo
|
this.$apollo
|
||||||
.mutate({
|
.mutate({
|
||||||
mutation: submitContentChangesMutation,
|
mutation: submitContentChangesMutation,
|
||||||
|
@ -87,9 +102,6 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
.then(() => {
|
|
||||||
this.$router.push(SUCCESS_ROUTE);
|
|
||||||
})
|
|
||||||
.catch(e => {
|
.catch(e => {
|
||||||
this.submitChangesError = e.message;
|
this.submitChangesError = e.message;
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import { GlEmptyState, GlButton } from '@gitlab/ui';
|
import { GlButton, GlEmptyState, GlLoadingIcon } from '@gitlab/ui';
|
||||||
import { s__, __, sprintf } from '~/locale';
|
import { s__, __, sprintf } from '~/locale';
|
||||||
|
|
||||||
import savedContentMetaQuery from '../graphql/queries/saved_content_meta.query.graphql';
|
import savedContentMetaQuery from '../graphql/queries/saved_content_meta.query.graphql';
|
||||||
|
@ -8,8 +8,9 @@ import { HOME_ROUTE } from '../router/constants';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
GlEmptyState,
|
|
||||||
GlButton,
|
GlButton,
|
||||||
|
GlEmptyState,
|
||||||
|
GlLoadingIcon,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
mergeRequestsIllustrationPath: {
|
mergeRequestsIllustrationPath: {
|
||||||
|
@ -33,7 +34,7 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
if (!this.savedContentMeta) {
|
if (!this.appData.hasSubmittedChanges) {
|
||||||
this.$router.push(HOME_ROUTE);
|
this.$router.push(HOME_ROUTE);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -50,14 +51,21 @@ export default {
|
||||||
assignMergeRequestInstruction: s__(
|
assignMergeRequestInstruction: s__(
|
||||||
'StaticSiteEditor|3. Assign a person to review and accept the merge request.',
|
'StaticSiteEditor|3. Assign a person to review and accept the merge request.',
|
||||||
),
|
),
|
||||||
|
submittingTitle: s__('StaticSiteEditor|Creating your merge request'),
|
||||||
|
submittingNotePrimary: s__(
|
||||||
|
'StaticSiteEditor|You can set an assignee to get your changes reviewed and deployed once your merge request is created.',
|
||||||
|
),
|
||||||
|
submittingNoteSecondary: s__(
|
||||||
|
'StaticSiteEditor|A link to view the merge request will appear once ready.',
|
||||||
|
),
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div class="container gl-flex-grow-1 gl-display-flex gl-flex-direction-column">
|
||||||
v-if="savedContentMeta"
|
<div
|
||||||
class="container gl-flex-grow-1 gl-display-flex gl-flex-direction-column"
|
v-if="savedContentMeta"
|
||||||
>
|
class="gl-fixed gl-left-0 gl-right-0 gl-border-b-solid gl-border-b-1 gl-border-b-gray-100"
|
||||||
<div class="gl-fixed gl-left-0 gl-right-0 gl-border-b-solid gl-border-b-1 gl-border-b-gray-100">
|
>
|
||||||
<div class="container gl-py-4">
|
<div class="container gl-py-4">
|
||||||
<gl-button
|
<gl-button
|
||||||
v-if="appData.returnUrl"
|
v-if="appData.returnUrl"
|
||||||
|
@ -73,16 +81,23 @@ export default {
|
||||||
</div>
|
</div>
|
||||||
<gl-empty-state
|
<gl-empty-state
|
||||||
class="gl-my-9"
|
class="gl-my-9"
|
||||||
:primary-button-text="$options.primaryButtonText"
|
:title="savedContentMeta ? $options.title : $options.submittingTitle"
|
||||||
:title="$options.title"
|
:primary-button-text="savedContentMeta && $options.primaryButtonText"
|
||||||
:primary-button-link="savedContentMeta.mergeRequest.url"
|
:primary-button-link="savedContentMeta && savedContentMeta.mergeRequest.url"
|
||||||
:svg-path="mergeRequestsIllustrationPath"
|
:svg-path="mergeRequestsIllustrationPath"
|
||||||
>
|
>
|
||||||
<template #description>
|
<template #description>
|
||||||
<p>{{ $options.mergeRequestInstructionsHeading }}</p>
|
<div v-if="savedContentMeta">
|
||||||
<p>{{ $options.addTitleInstruction }}</p>
|
<p>{{ $options.mergeRequestInstructionsHeading }}</p>
|
||||||
<p>{{ $options.addDescriptionInstruction }}</p>
|
<p>{{ $options.addTitleInstruction }}</p>
|
||||||
<p>{{ $options.assignMergeRequestInstruction }}</p>
|
<p>{{ $options.addDescriptionInstruction }}</p>
|
||||||
|
<p>{{ $options.assignMergeRequestInstruction }}</p>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<p>{{ $options.submittingNotePrimary }}</p>
|
||||||
|
<p>{{ $options.submittingNoteSecondary }}</p>
|
||||||
|
<gl-loading-icon size="xl" />
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</gl-empty-state>
|
</gl-empty-state>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
import jsYaml from 'js-yaml';
|
||||||
|
|
||||||
|
const NEW_LINE = '\n';
|
||||||
|
|
||||||
|
const hasMatter = (firstThreeChars, fourthChar) => {
|
||||||
|
const isYamlDelimiter = firstThreeChars === '---';
|
||||||
|
const isFourthCharNewline = fourthChar === NEW_LINE;
|
||||||
|
return isYamlDelimiter && isFourthCharNewline;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const frontMatterify = source => {
|
||||||
|
let index = 3;
|
||||||
|
let offset;
|
||||||
|
const delimiter = source.slice(0, index);
|
||||||
|
const type = 'yaml';
|
||||||
|
const NO_FRONTMATTER = {
|
||||||
|
source,
|
||||||
|
matter: null,
|
||||||
|
spacing: null,
|
||||||
|
content: source,
|
||||||
|
delimiter: null,
|
||||||
|
type: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!hasMatter(delimiter, source.charAt(index))) {
|
||||||
|
return NO_FRONTMATTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset = source.indexOf(delimiter, index);
|
||||||
|
|
||||||
|
// Finds the end delimiter that starts at a new line
|
||||||
|
while (offset !== -1 && source.charAt(offset - 1) !== NEW_LINE) {
|
||||||
|
index = offset + delimiter.length;
|
||||||
|
offset = source.indexOf(delimiter, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset === -1) {
|
||||||
|
return NO_FRONTMATTER;
|
||||||
|
}
|
||||||
|
|
||||||
|
const matterStr = source.slice(index, offset);
|
||||||
|
const matter = jsYaml.safeLoad(matterStr);
|
||||||
|
|
||||||
|
let content = source.slice(offset + delimiter.length);
|
||||||
|
let spacing = '';
|
||||||
|
let idx = 0;
|
||||||
|
while (content.charAt(idx).match(/(\s|\n)/)) {
|
||||||
|
spacing += content.charAt(idx);
|
||||||
|
idx += 1;
|
||||||
|
}
|
||||||
|
content = content.replace(spacing, '');
|
||||||
|
|
||||||
|
return {
|
||||||
|
source,
|
||||||
|
matter,
|
||||||
|
spacing,
|
||||||
|
content,
|
||||||
|
delimiter,
|
||||||
|
type,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
export const stringify = ({ matter, spacing, content, delimiter }, newMatter) => {
|
||||||
|
const matterObj = newMatter || matter;
|
||||||
|
|
||||||
|
if (!matterObj) {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
const header = `${delimiter}${NEW_LINE}${jsYaml.safeDump(matterObj)}${delimiter}`;
|
||||||
|
const body = `${spacing}${content}`;
|
||||||
|
return `${header}${body}`;
|
||||||
|
};
|
|
@ -1,7 +1,7 @@
|
||||||
import grayMatter from 'gray-matter';
|
import { frontMatterify, stringify } from './front_matterify';
|
||||||
|
|
||||||
const parseSourceFile = raw => {
|
const parseSourceFile = raw => {
|
||||||
const remake = source => grayMatter(source, {});
|
const remake = source => frontMatterify(source);
|
||||||
|
|
||||||
let editable = remake(raw);
|
let editable = remake(raw);
|
||||||
|
|
||||||
|
@ -13,20 +13,17 @@ const parseSourceFile = raw => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const trimmedEditable = () => grayMatter.stringify(editable).trim();
|
const content = (isBody = false) => (isBody ? editable.content : stringify(editable));
|
||||||
|
|
||||||
const content = (isBody = false) => (isBody ? editable.content.trim() : trimmedEditable()); // gray-matter internally adds an eof newline so we trim to bypass, open issue: https://github.com/jonschlinkert/gray-matter/issues/96
|
const matter = () => editable.matter;
|
||||||
|
|
||||||
const matter = () => editable.data;
|
|
||||||
|
|
||||||
const syncMatter = settings => {
|
const syncMatter = settings => {
|
||||||
const source = grayMatter.stringify(editable.content, settings);
|
editable.matter = settings;
|
||||||
syncContent(source);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const isModified = () => trimmedEditable() !== raw;
|
const isModified = () => stringify(editable) !== raw;
|
||||||
|
|
||||||
const hasMatter = () => editable.matter.length > 0;
|
const hasMatter = () => Boolean(editable.matter);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
matter,
|
matter,
|
||||||
|
|
|
@ -66,12 +66,10 @@ const autoCompleteMap = {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doesCurrentLineStartWith('/assign', fullText, selectionStart)) {
|
if (doesCurrentLineStartWith('/assign', fullText, selectionStart)) {
|
||||||
return this.members.filter(
|
return this.members.filter(member => !this.assignees.includes(member.username));
|
||||||
member => member.type === 'User' && !this.assignees.includes(member.username),
|
}
|
||||||
);
|
|
||||||
} else if (doesCurrentLineStartWith('/reassign', fullText, selectionStart)) {
|
if (doesCurrentLineStartWith('/unassign', fullText, selectionStart)) {
|
||||||
return this.members.filter(member => member.type === 'User');
|
|
||||||
} else if (doesCurrentLineStartWith('/unassign', fullText, selectionStart)) {
|
|
||||||
return this.members.filter(member => this.assignees.includes(member.username));
|
return this.members.filter(member => this.assignees.includes(member.username));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,3 +62,5 @@ export const MEMBER_TYPES = {
|
||||||
invite: 'invite',
|
invite: 'invite',
|
||||||
accessRequest: 'accessRequest',
|
accessRequest: 'accessRequest',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const DAYS_TO_EXPIRE_SOON = 7;
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
<script>
|
||||||
|
import { GlSprintf } from '@gitlab/ui';
|
||||||
|
import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'CreatedAt',
|
||||||
|
components: { GlSprintf, TimeAgoTooltip },
|
||||||
|
props: {
|
||||||
|
date: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
createdBy: {
|
||||||
|
type: Object,
|
||||||
|
required: false,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
showCreatedBy() {
|
||||||
|
return this.createdBy?.name && this.createdBy?.webUrl;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<span>
|
||||||
|
<gl-sprintf v-if="showCreatedBy" :message="s__('Members|%{time} by %{user}')">
|
||||||
|
<template #time>
|
||||||
|
<time-ago-tooltip :time="date" />
|
||||||
|
</template>
|
||||||
|
<template #user>
|
||||||
|
<a :href="createdBy.webUrl">{{ createdBy.name }}</a>
|
||||||
|
</template>
|
||||||
|
</gl-sprintf>
|
||||||
|
<time-ago-tooltip v-else :time="date" />
|
||||||
|
</span>
|
||||||
|
</template>
|
|
@ -0,0 +1,66 @@
|
||||||
|
<script>
|
||||||
|
import { GlSprintf, GlTooltipDirective } from '@gitlab/ui';
|
||||||
|
import {
|
||||||
|
approximateDuration,
|
||||||
|
differenceInSeconds,
|
||||||
|
formatDate,
|
||||||
|
getDayDifference,
|
||||||
|
} from '~/lib/utils/datetime_utility';
|
||||||
|
import { DAYS_TO_EXPIRE_SOON } from '../constants';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'ExpiresAt',
|
||||||
|
components: { GlSprintf },
|
||||||
|
directives: {
|
||||||
|
GlTooltip: GlTooltipDirective,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
date: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
noExpirationSet() {
|
||||||
|
return this.date === null;
|
||||||
|
},
|
||||||
|
parsed() {
|
||||||
|
return new Date(this.date);
|
||||||
|
},
|
||||||
|
differenceInSeconds() {
|
||||||
|
return differenceInSeconds(new Date(), this.parsed);
|
||||||
|
},
|
||||||
|
isExpired() {
|
||||||
|
return this.differenceInSeconds <= 0;
|
||||||
|
},
|
||||||
|
inWords() {
|
||||||
|
return approximateDuration(this.differenceInSeconds);
|
||||||
|
},
|
||||||
|
formatted() {
|
||||||
|
return formatDate(this.parsed);
|
||||||
|
},
|
||||||
|
expiresSoon() {
|
||||||
|
return getDayDifference(new Date(), this.parsed) < DAYS_TO_EXPIRE_SOON;
|
||||||
|
},
|
||||||
|
cssClass() {
|
||||||
|
return {
|
||||||
|
'gl-text-red-500': this.isExpired,
|
||||||
|
'gl-text-orange-500': this.expiresSoon,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<span v-if="noExpirationSet">{{ s__('Members|No expiration set') }}</span>
|
||||||
|
<span v-else v-gl-tooltip.hover :title="formatted" :class="cssClass">
|
||||||
|
<template v-if="isExpired">{{ s__('Members|Expired') }}</template>
|
||||||
|
<gl-sprintf v-else :message="s__('Members|in %{time}')">
|
||||||
|
<template #time>
|
||||||
|
{{ inWords }}
|
||||||
|
</template>
|
||||||
|
</gl-sprintf>
|
||||||
|
</span>
|
||||||
|
</template>
|
|
@ -5,6 +5,8 @@ import { FIELDS } from '../constants';
|
||||||
import initUserPopovers from '~/user_popovers';
|
import initUserPopovers from '~/user_popovers';
|
||||||
import MemberAvatar from './member_avatar.vue';
|
import MemberAvatar from './member_avatar.vue';
|
||||||
import MemberSource from './member_source.vue';
|
import MemberSource from './member_source.vue';
|
||||||
|
import CreatedAt from './created_at.vue';
|
||||||
|
import ExpiresAt from './expires_at.vue';
|
||||||
import MembersTableCell from './members_table_cell.vue';
|
import MembersTableCell from './members_table_cell.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -12,6 +14,8 @@ export default {
|
||||||
components: {
|
components: {
|
||||||
GlTable,
|
GlTable,
|
||||||
MemberAvatar,
|
MemberAvatar,
|
||||||
|
CreatedAt,
|
||||||
|
ExpiresAt,
|
||||||
MembersTableCell,
|
MembersTableCell,
|
||||||
MemberSource,
|
MemberSource,
|
||||||
},
|
},
|
||||||
|
@ -51,6 +55,22 @@ export default {
|
||||||
</members-table-cell>
|
</members-table-cell>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template #cell(granted)="{ item: { createdAt, createdBy } }">
|
||||||
|
<created-at :date="createdAt" :created-by="createdBy" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #cell(invited)="{ item: { createdAt, createdBy } }">
|
||||||
|
<created-at :date="createdAt" :created-by="createdBy" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #cell(requested)="{ item: { createdAt } }">
|
||||||
|
<created-at :date="createdAt" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #cell(expires)="{ item: { expiresAt } }">
|
||||||
|
<expires-at :date="expiresAt" />
|
||||||
|
</template>
|
||||||
|
|
||||||
<template #head(actions)="{ label }">
|
<template #head(actions)="{ label }">
|
||||||
<span data-testid="col-actions" class="gl-sr-only">{{ label }}</span>
|
<span data-testid="col-actions" class="gl-sr-only">{{ label }}</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
<script>
|
<script>
|
||||||
import { mapState, mapActions } from 'vuex';
|
import { mapState, mapActions } from 'vuex';
|
||||||
import { GlDrawer, GlBadge, GlIcon, GlLink } from '@gitlab/ui';
|
import { GlDrawer, GlBadge, GlIcon, GlLink } from '@gitlab/ui';
|
||||||
|
import Tracking from '~/tracking';
|
||||||
|
|
||||||
|
const trackingMixin = Tracking.mixin();
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
@ -9,6 +12,7 @@ export default {
|
||||||
GlIcon,
|
GlIcon,
|
||||||
GlLink,
|
GlLink,
|
||||||
},
|
},
|
||||||
|
mixins: [trackingMixin],
|
||||||
props: {
|
props: {
|
||||||
features: {
|
features: {
|
||||||
type: String,
|
type: String,
|
||||||
|
@ -37,6 +41,11 @@ export default {
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.openDrawer(this.storageKey);
|
this.openDrawer(this.storageKey);
|
||||||
|
|
||||||
|
const body = document.querySelector('body');
|
||||||
|
const namespaceId = body.getAttribute('data-namespace-id');
|
||||||
|
|
||||||
|
this.track('click_whats_new_drawer', { label: 'namespace_id', value: namespaceId });
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(['openDrawer', 'closeDrawer']),
|
...mapActions(['openDrawer', 'closeDrawer']),
|
||||||
|
@ -52,7 +61,14 @@ export default {
|
||||||
</template>
|
</template>
|
||||||
<div class="pb-6">
|
<div class="pb-6">
|
||||||
<div v-for="feature in parsedFeatures" :key="feature.title" class="mb-6">
|
<div v-for="feature in parsedFeatures" :key="feature.title" class="mb-6">
|
||||||
<gl-link :href="feature.url" target="_blank">
|
<gl-link
|
||||||
|
:href="feature.url"
|
||||||
|
target="_blank"
|
||||||
|
data-testid="whats-new-title-link"
|
||||||
|
data-track-event="click_whats_new_item"
|
||||||
|
:data-track-label="feature.title"
|
||||||
|
:data-track-property="feature.url"
|
||||||
|
>
|
||||||
<h5 class="gl-font-base">{{ feature.title }}</h5>
|
<h5 class="gl-font-base">{{ feature.title }}</h5>
|
||||||
</gl-link>
|
</gl-link>
|
||||||
<div class="mb-2">
|
<div class="mb-2">
|
||||||
|
@ -62,7 +78,13 @@ export default {
|
||||||
</gl-badge>
|
</gl-badge>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<gl-link :href="feature.url" target="_blank">
|
<gl-link
|
||||||
|
:href="feature.url"
|
||||||
|
target="_blank"
|
||||||
|
data-track-event="click_whats_new_item"
|
||||||
|
:data-track-label="feature.title"
|
||||||
|
:data-track-property="feature.url"
|
||||||
|
>
|
||||||
<img
|
<img
|
||||||
:alt="feature.title"
|
:alt="feature.title"
|
||||||
:src="feature.image_url"
|
:src="feature.image_url"
|
||||||
|
@ -70,7 +92,14 @@ export default {
|
||||||
/>
|
/>
|
||||||
</gl-link>
|
</gl-link>
|
||||||
<p class="pt-2">{{ feature.body }}</p>
|
<p class="pt-2">{{ feature.body }}</p>
|
||||||
<gl-link :href="feature.url" target="_blank">{{ __('Learn more') }}</gl-link>
|
<gl-link
|
||||||
|
:href="feature.url"
|
||||||
|
target="_blank"
|
||||||
|
data-track-event="click_whats_new_item"
|
||||||
|
:data-track-label="feature.title"
|
||||||
|
:data-track-property="feature.url"
|
||||||
|
>{{ __('Learn more') }}</gl-link
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</gl-drawer>
|
</gl-drawer>
|
||||||
|
|
|
@ -36,17 +36,6 @@
|
||||||
// EE-only stylesheets
|
// EE-only stylesheets
|
||||||
@import 'application_ee';
|
@import 'application_ee';
|
||||||
|
|
||||||
// CSS util classes
|
|
||||||
/**
|
|
||||||
These are deprecated in favor of the Gitlab UI utilities imported below.
|
|
||||||
Please check https://unpkg.com/browse/@gitlab/ui/src/scss/utilities.scss
|
|
||||||
to see the available utility classes.
|
|
||||||
**/
|
|
||||||
@import 'utilities';
|
|
||||||
|
|
||||||
// Gitlab UI util classes
|
|
||||||
@import '@gitlab/ui/src/scss/utilities';
|
|
||||||
|
|
||||||
/* print styles */
|
/* print styles */
|
||||||
@media print {
|
@media print {
|
||||||
@import 'print';
|
@import 'print';
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
@import 'page_bundles/mixins_and_variables_and_functions';
|
||||||
|
|
||||||
|
// CSS util classes
|
||||||
|
/**
|
||||||
|
These are deprecated in favor of the Gitlab UI utilities imported below.
|
||||||
|
Please check https://unpkg.com/browse/@gitlab/ui/src/scss/utilities.scss
|
||||||
|
to see the available utility classes.
|
||||||
|
**/
|
||||||
|
@import 'utilities';
|
||||||
|
|
||||||
|
// Gitlab UI util classes
|
||||||
|
@import '@gitlab/ui/src/scss/utilities';
|
|
@ -0,0 +1,3 @@
|
||||||
|
@import './themes/dark';
|
||||||
|
|
||||||
|
@import 'application_utilities';
|
|
@ -357,6 +357,12 @@ module ApplicationHelper
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def add_page_specific_style(path)
|
||||||
|
content_for :page_specific_styles do
|
||||||
|
stylesheet_link_tag_defer path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def page_startup_api_calls
|
def page_startup_api_calls
|
||||||
@api_startup_calls
|
@api_startup_calls
|
||||||
end
|
end
|
||||||
|
|
|
@ -69,7 +69,7 @@ module QuickActions
|
||||||
def extract_users(params)
|
def extract_users(params)
|
||||||
return [] if params.nil?
|
return [] if params.nil?
|
||||||
|
|
||||||
users = extract_references(params, :mentioned_user)
|
users = extract_references(params, :user)
|
||||||
|
|
||||||
if users.empty?
|
if users.empty?
|
||||||
users =
|
users =
|
||||||
|
|
|
@ -80,7 +80,7 @@ class AddressableUrlValidator < ActiveModel::EachValidator
|
||||||
|
|
||||||
value = strip_value!(record, attribute, value)
|
value = strip_value!(record, attribute, value)
|
||||||
|
|
||||||
Gitlab::UrlBlocker.validate!(value, blocker_args)
|
Gitlab::UrlBlocker.validate!(value, **blocker_args)
|
||||||
rescue Gitlab::UrlBlocker::BlockedUrlError => e
|
rescue Gitlab::UrlBlocker::BlockedUrlError => e
|
||||||
record.errors.add(attribute, options.fetch(:blocked_message) % { exception_message: e.message })
|
record.errors.add(attribute, options.fetch(:blocked_message) % { exception_message: e.message })
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
- @hide_top_links = true
|
- @hide_top_links = true
|
||||||
- page_title _('Milestones')
|
- page_title _('Milestones')
|
||||||
- header_title _('Milestones'), dashboard_milestones_path
|
- header_title _('Milestones'), dashboard_milestones_path
|
||||||
= stylesheet_link_tag 'page_bundles/milestone'
|
- add_page_specific_style 'page_bundles/milestone'
|
||||||
|
|
||||||
.page-title-holder.d-flex.align-items-center
|
.page-title-holder.d-flex.align-items-center
|
||||||
%h1.page-title= _('Milestones')
|
%h1.page-title= _('Milestones')
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
- header_title _("To-Do List"), dashboard_todos_path
|
- header_title _("To-Do List"), dashboard_todos_path
|
||||||
|
|
||||||
= render_dashboard_gold_trial(current_user)
|
= render_dashboard_gold_trial(current_user)
|
||||||
= stylesheet_link_tag 'page_bundles/todos'
|
- add_page_specific_style 'page_bundles/todos'
|
||||||
|
|
||||||
.page-title-holder.d-flex.align-items-center
|
.page-title-holder.d-flex.align-items-center
|
||||||
%h1.page-title= _('To-Do List')
|
%h1.page-title= _('To-Do List')
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
- page_title _("Milestones")
|
- page_title _("Milestones")
|
||||||
= stylesheet_link_tag 'page_bundles/milestone'
|
- add_page_specific_style 'page_bundles/milestone'
|
||||||
|
|
||||||
.top-area
|
.top-area
|
||||||
= render 'shared/milestones_filter', counts: @milestone_states
|
= render 'shared/milestones_filter', counts: @milestone_states
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
= stylesheet_link_tag 'page_bundles/milestone'
|
- add_page_specific_style 'page_bundles/milestone'
|
||||||
= render "header_title"
|
= render "header_title"
|
||||||
= render 'shared/milestones/top', milestone: @milestone, group: @group
|
= render 'shared/milestones/top', milestone: @milestone, group: @group
|
||||||
= render 'shared/milestones/tabs', milestone: @milestone, show_project_name: true
|
= render 'shared/milestones/tabs', milestone: @milestone, show_project_name: true
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
- @body_class = 'ide-layout'
|
- @body_class = 'ide-layout'
|
||||||
- page_title _('IDE')
|
- page_title _('IDE')
|
||||||
|
|
||||||
- content_for :page_specific_javascripts do
|
- add_page_specific_style 'page_bundles/ide'
|
||||||
= stylesheet_link_tag 'page_bundles/ide'
|
|
||||||
|
|
||||||
#ide.ide-loading{ data: ide_data }
|
#ide.ide-loading{ data: ide_data }
|
||||||
.text-center
|
.text-center
|
||||||
|
|
|
@ -25,4 +25,4 @@
|
||||||
%td= link_to 'Remove', jira_connect_subscription_path(subscription), class: 'remove-subscription'
|
%td= link_to 'Remove', jira_connect_subscription_path(subscription), class: 'remove-subscription'
|
||||||
|
|
||||||
= page_specific_javascript_tag('jira_connect.js')
|
= page_specific_javascript_tag('jira_connect.js')
|
||||||
= stylesheet_link_tag 'page_bundles/jira_connect'
|
- add_page_specific_style 'page_bundles/jira_connect'
|
||||||
|
|
|
@ -50,8 +50,14 @@
|
||||||
= render 'layouts/startup_css'
|
= render 'layouts/startup_css'
|
||||||
- if user_application_theme == 'gl-dark'
|
- if user_application_theme == 'gl-dark'
|
||||||
= stylesheet_link_tag_defer "application_dark"
|
= stylesheet_link_tag_defer "application_dark"
|
||||||
|
- if content_for?(:page_specific_styles)
|
||||||
|
= yield :page_specific_styles
|
||||||
|
= stylesheet_link_tag_defer "application_utilities_dark"
|
||||||
- else
|
- else
|
||||||
= stylesheet_link_tag_defer "application"
|
= stylesheet_link_tag_defer "application"
|
||||||
|
- if content_for?(:page_specific_styles)
|
||||||
|
= yield :page_specific_styles
|
||||||
|
= stylesheet_link_tag_defer "application_utilities"
|
||||||
- unless use_startup_css?
|
- unless use_startup_css?
|
||||||
= stylesheet_link_tag_defer "themes/#{user_application_theme_css_filename}" if user_application_theme_css_filename
|
= stylesheet_link_tag_defer "themes/#{user_application_theme_css_filename}" if user_application_theme_css_filename
|
||||||
= stylesheet_link_tag "disable_animations", media: "all" if Rails.env.test? || Gitlab.config.gitlab['disable_animations']
|
= stylesheet_link_tag "disable_animations", media: "all" if Rails.env.test? || Gitlab.config.gitlab['disable_animations']
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
= stylesheet_link_tag 'https://unpkg.com/@atlaskit/reduced-ui-pack@10.5.5/dist/bundle.css'
|
= stylesheet_link_tag 'https://unpkg.com/@atlaskit/reduced-ui-pack@10.5.5/dist/bundle.css'
|
||||||
= javascript_include_tag 'https://connect-cdn.atl-paas.net/all.js'
|
= javascript_include_tag 'https://connect-cdn.atl-paas.net/all.js'
|
||||||
= javascript_include_tag 'https://unpkg.com/jquery@3.3.1/dist/jquery.min.js'
|
= javascript_include_tag 'https://unpkg.com/jquery@3.3.1/dist/jquery.min.js'
|
||||||
|
- if content_for?(:page_specific_styles)
|
||||||
|
= yield :page_specific_styles
|
||||||
= yield :head
|
= yield :head
|
||||||
%body
|
%body
|
||||||
.ac-content
|
.ac-content
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
- page_title _("Value Stream Analytics")
|
- page_title _("Value Stream Analytics")
|
||||||
- content_for :page_specific_javascripts do
|
- add_page_specific_style 'page_bundles/cycle_analytics'
|
||||||
= stylesheet_link_tag 'page_bundles/cycle_analytics'
|
|
||||||
|
|
||||||
#cycle-analytics{ "v-cloak" => "true", data: { request_path: project_cycle_analytics_path(@project) } }
|
#cycle-analytics{ "v-cloak" => "true", data: { request_path: project_cycle_analytics_path(@project) } }
|
||||||
- if @cycle_analytics_no_data
|
- if @cycle_analytics_no_data
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
- add_to_breadcrumbs _("Environments"), project_environments_path(@project)
|
- add_to_breadcrumbs _("Environments"), project_environments_path(@project)
|
||||||
- breadcrumb_title @environment.name
|
- breadcrumb_title @environment.name
|
||||||
- page_title _("Environments")
|
- page_title _("Environments")
|
||||||
|
- add_page_specific_style 'page_bundles/xterm'
|
||||||
- content_for :page_specific_javascripts do
|
|
||||||
= stylesheet_link_tag 'page_bundles/xterm'
|
|
||||||
|
|
||||||
#environments-detail-view{ data: { name: @environment.name, id: @environment.id, delete_path: environment_delete_path(@environment)} }
|
#environments-detail-view{ data: { name: @environment.name, id: @environment.id, delete_path: environment_delete_path(@environment)} }
|
||||||
- if @environment.available? && can?(current_user, :stop_environment, @environment)
|
- if @environment.available? && can?(current_user, :stop_environment, @environment)
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
- page_title _("Issues")
|
- page_title _("Issues")
|
||||||
- new_issue_email = @project.new_issuable_address(current_user, 'issue')
|
- new_issue_email = @project.new_issuable_address(current_user, 'issue')
|
||||||
= stylesheet_link_tag 'page_bundles/issues'
|
- add_page_specific_style 'page_bundles/issues'
|
||||||
|
|
||||||
= content_for :meta_tags do
|
= content_for :meta_tags do
|
||||||
= auto_discovery_link_tag(:atom, safe_params.merge(rss_url_options).to_h, title: "#{@project.name} issues")
|
= auto_discovery_link_tag(:atom, safe_params.merge(rss_url_options).to_h, title: "#{@project.name} issues")
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
- can_report_spam = @issue.submittable_as_spam_by?(current_user)
|
- can_report_spam = @issue.submittable_as_spam_by?(current_user)
|
||||||
- can_create_issue = show_new_issue_link?(@project)
|
- can_create_issue = show_new_issue_link?(@project)
|
||||||
- related_branches_path = related_branches_project_issue_path(@project, @issue)
|
- related_branches_path = related_branches_project_issue_path(@project, @issue)
|
||||||
= stylesheet_link_tag 'page_bundles/issues'
|
- add_page_specific_style 'page_bundles/issues'
|
||||||
|
|
||||||
= render_if_exists "projects/issues/alert_blocked", issue: @issue, current_user: current_user
|
= render_if_exists "projects/issues/alert_blocked", issue: @issue, current_user: current_user
|
||||||
= render "projects/issues/alert_moved_from_service_desk", issue: @issue
|
= render "projects/issues/alert_moved_from_service_desk", issue: @issue
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
- add_to_breadcrumbs _("Jobs"), project_jobs_path(@project)
|
- add_to_breadcrumbs _("Jobs"), project_jobs_path(@project)
|
||||||
- breadcrumb_title "##{@build.id}"
|
- breadcrumb_title "##{@build.id}"
|
||||||
- page_title "#{@build.name} (##{@build.id})", _("Jobs")
|
- page_title "#{@build.name} (##{@build.id})", _("Jobs")
|
||||||
|
- add_page_specific_style 'page_bundles/xterm'
|
||||||
- content_for :page_specific_javascripts do
|
|
||||||
= stylesheet_link_tag 'page_bundles/xterm'
|
|
||||||
|
|
||||||
= render_if_exists "shared/shared_runners_minutes_limit_flash_message"
|
= render_if_exists "shared/shared_runners_minutes_limit_flash_message"
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
- page_title _('Milestones')
|
- page_title _('Milestones')
|
||||||
= stylesheet_link_tag 'page_bundles/milestone'
|
- add_page_specific_style 'page_bundles/milestone'
|
||||||
|
|
||||||
.top-area
|
.top-area
|
||||||
= render 'shared/milestones_filter', counts: milestone_counts(@project.milestones)
|
= render 'shared/milestones_filter', counts: milestone_counts(@project.milestones)
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
- breadcrumb_title @milestone.title
|
- breadcrumb_title @milestone.title
|
||||||
- page_title @milestone.title, _('Milestones')
|
- page_title @milestone.title, _('Milestones')
|
||||||
- page_description @milestone.description
|
- page_description @milestone.description
|
||||||
= stylesheet_link_tag 'page_bundles/milestone'
|
- add_page_specific_style 'page_bundles/milestone'
|
||||||
|
|
||||||
= render 'shared/milestones/header', milestone: @milestone
|
= render 'shared/milestones/header', milestone: @milestone
|
||||||
= render 'shared/milestones/description', milestone: @milestone
|
= render 'shared/milestones/description', milestone: @milestone
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
- @content_class = "issue-boards-content js-focus-mode-board"
|
- @content_class = "issue-boards-content js-focus-mode-board"
|
||||||
- breadcrumb_title _("Issue Boards")
|
- breadcrumb_title _("Issue Boards")
|
||||||
- page_title("#{board.name}", _("Boards"))
|
- page_title("#{board.name}", _("Boards"))
|
||||||
= stylesheet_link_tag 'page_bundles/boards'
|
- add_page_specific_style 'page_bundles/boards'
|
||||||
|
|
||||||
- content_for :page_specific_javascripts do
|
- content_for :page_specific_javascripts do
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Add projects_creating_incidents to usage ping counts
|
||||||
|
merge_request: 42934
|
||||||
|
author:
|
||||||
|
type: added
|
|
@ -1,5 +0,0 @@
|
||||||
---
|
|
||||||
title: Prevent assignment of groups using quick actions
|
|
||||||
merge_request: 42810
|
|
||||||
author:
|
|
||||||
type: fixed
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Update user feedback to a dedicated page as opposed to solely a button with a loader
|
||||||
|
merge_request: 43189
|
||||||
|
author:
|
||||||
|
type: changed
|
|
@ -0,0 +1,6 @@
|
||||||
|
---
|
||||||
|
title: Add a database column to enable or disable the setting that puts newly registered
|
||||||
|
users in a pending state, requiring admin approval for their activation
|
||||||
|
merge_request: 43661
|
||||||
|
author:
|
||||||
|
type: added
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Update programming language colors and metadata
|
||||||
|
merge_request: 43111
|
||||||
|
author:
|
||||||
|
type: changed
|
|
@ -174,6 +174,8 @@ module Gitlab
|
||||||
config.assets.paths << Gemojione.images_path
|
config.assets.paths << Gemojione.images_path
|
||||||
config.assets.paths << "#{config.root}/vendor/assets/fonts"
|
config.assets.paths << "#{config.root}/vendor/assets/fonts"
|
||||||
|
|
||||||
|
config.assets.precompile << "application_utilities.css"
|
||||||
|
config.assets.precompile << "application_utilities_dark.css"
|
||||||
config.assets.precompile << "application_dark.css"
|
config.assets.precompile << "application_dark.css"
|
||||||
|
|
||||||
config.assets.precompile << "startup/*.css"
|
config.assets.precompile << "startup/*.css"
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
require 'yaml'
|
||||||
|
|
||||||
|
class UpdateProgrammingLanguageColors < ActiveRecord::Migration[6.0]
|
||||||
|
DOWNTIME = false
|
||||||
|
|
||||||
|
class ProgrammingLanguage < ActiveRecord::Base; end
|
||||||
|
|
||||||
|
def up
|
||||||
|
YAML.load_file("vendor/languages.yml").each do |name, metadata|
|
||||||
|
color = metadata["color"]
|
||||||
|
next unless color.present?
|
||||||
|
|
||||||
|
ProgrammingLanguage.where(name: name).update(color: color)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
# noop
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,20 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class AddIncidentIssueTypeIndexToIssues < ActiveRecord::Migration[6.0]
|
||||||
|
include Gitlab::Database::MigrationHelpers
|
||||||
|
|
||||||
|
DOWNTIME = false
|
||||||
|
|
||||||
|
disable_ddl_transaction!
|
||||||
|
|
||||||
|
INCIDENT_ISSUE_TYPE = 1
|
||||||
|
INDEX_NAME = 'index_issues_project_id_issue_type_incident'
|
||||||
|
|
||||||
|
def up
|
||||||
|
add_concurrent_index :issues, :project_id, where: "issue_type = #{INCIDENT_ISSUE_TYPE}", name: INDEX_NAME
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
remove_concurrent_index_by_name(:issues, INDEX_NAME)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,9 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class AddRequireAdminApprovalAfterUserSignupToApplicationSettings < ActiveRecord::Migration[6.0]
|
||||||
|
DOWNTIME = false
|
||||||
|
|
||||||
|
def change
|
||||||
|
add_column :application_settings, :require_admin_approval_after_user_signup, :boolean, default: false, null: false
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1 @@
|
||||||
|
f19e61e3863905885c8b5b2129be2586d912d616a5b3b54e99a72c5760082059
|
|
@ -0,0 +1 @@
|
||||||
|
8e0c5be3d6fe2d0d718c7b7a99d84b14dfc6006f780ec0622eb5aae937e6b367
|
|
@ -0,0 +1 @@
|
||||||
|
9ef08404b964ccae3e12332340f16c6b8bb2bbdb2c04ba105fe1c0c7e6bf84f2
|
|
@ -9270,6 +9270,7 @@ CREATE TABLE application_settings (
|
||||||
gitpod_enabled boolean DEFAULT false NOT NULL,
|
gitpod_enabled boolean DEFAULT false NOT NULL,
|
||||||
gitpod_url text DEFAULT 'https://gitpod.io/'::text,
|
gitpod_url text DEFAULT 'https://gitpod.io/'::text,
|
||||||
abuse_notification_email character varying,
|
abuse_notification_email character varying,
|
||||||
|
require_admin_approval_after_user_signup boolean DEFAULT false NOT NULL,
|
||||||
CONSTRAINT check_2dba05b802 CHECK ((char_length(gitpod_url) <= 255)),
|
CONSTRAINT check_2dba05b802 CHECK ((char_length(gitpod_url) <= 255)),
|
||||||
CONSTRAINT check_51700b31b5 CHECK ((char_length(default_branch_name) <= 255)),
|
CONSTRAINT check_51700b31b5 CHECK ((char_length(default_branch_name) <= 255)),
|
||||||
CONSTRAINT check_9c6c447a13 CHECK ((char_length(maintenance_mode_message) <= 255)),
|
CONSTRAINT check_9c6c447a13 CHECK ((char_length(maintenance_mode_message) <= 255)),
|
||||||
|
@ -20372,6 +20373,8 @@ CREATE INDEX index_issues_on_updated_at ON issues USING btree (updated_at);
|
||||||
|
|
||||||
CREATE INDEX index_issues_on_updated_by_id ON issues USING btree (updated_by_id) WHERE (updated_by_id IS NOT NULL);
|
CREATE INDEX index_issues_on_updated_by_id ON issues USING btree (updated_by_id) WHERE (updated_by_id IS NOT NULL);
|
||||||
|
|
||||||
|
CREATE INDEX index_issues_project_id_issue_type_incident ON issues USING btree (project_id) WHERE (issue_type = 1);
|
||||||
|
|
||||||
CREATE UNIQUE INDEX index_jira_connect_installations_on_client_key ON jira_connect_installations USING btree (client_key);
|
CREATE UNIQUE INDEX index_jira_connect_installations_on_client_key ON jira_connect_installations USING btree (client_key);
|
||||||
|
|
||||||
CREATE INDEX index_jira_connect_subscriptions_on_namespace_id ON jira_connect_subscriptions USING btree (namespace_id);
|
CREATE INDEX index_jira_connect_subscriptions_on_namespace_id ON jira_connect_subscriptions USING btree (namespace_id);
|
||||||
|
|
|
@ -21,6 +21,9 @@ Updating Geo nodes involves performing:
|
||||||
NOTE: **Note:**
|
NOTE: **Note:**
|
||||||
These general update steps are not intended for [high-availability deployments](https://docs.gitlab.com/omnibus/update/README.html#multi-node--ha-deployment), and will cause downtime. If you want to avoid downtime, consider using [zero downtime updates](https://docs.gitlab.com/omnibus/update/README.html#zero-downtime-updates).
|
These general update steps are not intended for [high-availability deployments](https://docs.gitlab.com/omnibus/update/README.html#multi-node--ha-deployment), and will cause downtime. If you want to avoid downtime, consider using [zero downtime updates](https://docs.gitlab.com/omnibus/update/README.html#zero-downtime-updates).
|
||||||
|
|
||||||
|
DANGER: **Danger:**
|
||||||
|
In GitLab 13.2 and later versions, promoting a secondary node to a primary while the secondary is paused fails. We are [investigating the issue](https://gitlab.com/gitlab-org/gitlab/-/issues/225173). Do not pause replication before promoting a secondary. If the node is paused, please resume before promoting.
|
||||||
|
|
||||||
To update the Geo nodes when a new GitLab version is released, update **primary**
|
To update the Geo nodes when a new GitLab version is released, update **primary**
|
||||||
and all **secondary** nodes:
|
and all **secondary** nodes:
|
||||||
|
|
||||||
|
|
Before Width: | Height: | Size: 124 KiB After Width: | Height: | Size: 46 KiB |
|
@ -1,3 +1,9 @@
|
||||||
|
---
|
||||||
|
stage: Enablement
|
||||||
|
group: Database
|
||||||
|
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
|
||||||
|
---
|
||||||
|
|
||||||
# Configure GitLab using an external PostgreSQL service
|
# Configure GitLab using an external PostgreSQL service
|
||||||
|
|
||||||
If you're hosting GitLab on a cloud provider, you can optionally use a
|
If you're hosting GitLab on a cloud provider, you can optionally use a
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
---
|
---
|
||||||
|
stage: Enablement
|
||||||
|
group: Database
|
||||||
|
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
|
||||||
type: reference
|
type: reference
|
||||||
---
|
---
|
||||||
|
|
||||||
# Configuring PostgreSQL for scaling
|
# Configuring PostgreSQL for scaling
|
||||||
|
|
||||||
In this section, you'll be guided through configuring a PostgreSQL database to
|
In this section, you'll be guided through configuring a PostgreSQL database to
|
||||||
be used with GitLab in one of our [Scalable and Highly Available Setups](../reference_architectures/index.md).
|
be used with GitLab in one of our [reference architectures](../reference_architectures/index.md).
|
||||||
There are essentially three setups to choose from.
|
There are essentially three setups to choose from.
|
||||||
|
|
||||||
## PostgreSQL replication and failover with Omnibus GitLab **(PREMIUM ONLY)**
|
## PostgreSQL replication and failover with Omnibus GitLab **(PREMIUM ONLY)**
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
---
|
---
|
||||||
|
stage: Enablement
|
||||||
|
group: Database
|
||||||
|
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
|
||||||
type: reference
|
type: reference
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,16 @@
|
||||||
|
---
|
||||||
|
stage: Enablement
|
||||||
|
group: Database
|
||||||
|
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
|
||||||
|
---
|
||||||
|
|
||||||
# PostgreSQL replication and failover with Omnibus GitLab **(PREMIUM ONLY)**
|
# PostgreSQL replication and failover with Omnibus GitLab **(PREMIUM ONLY)**
|
||||||
|
|
||||||
This document will focus only on configuration supported with [GitLab Premium](https://about.gitlab.com/pricing/), using the Omnibus GitLab package.
|
This document focuses on configuration supported with [GitLab Premium](https://about.gitlab.com/pricing/), using the Omnibus GitLab package.
|
||||||
If you are a Community Edition or Starter user, consider using a cloud hosted solution.
|
If you're a Community Edition or Starter user, consider using a cloud hosted solution.
|
||||||
This document will not cover installations from source.
|
This document doesn't cover installations from source.
|
||||||
|
|
||||||
If a setup with replication and failover is not what you were looking for, see
|
If a setup with replication and failover isn't what you were looking for, see
|
||||||
the [database configuration document](https://docs.gitlab.com/omnibus/settings/database.html)
|
the [database configuration document](https://docs.gitlab.com/omnibus/settings/database.html)
|
||||||
for the Omnibus GitLab packages.
|
for the Omnibus GitLab packages.
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,21 @@
|
||||||
|
---
|
||||||
|
stage: Enablement
|
||||||
|
group: Database
|
||||||
|
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
|
||||||
|
---
|
||||||
|
|
||||||
# Standalone PostgreSQL using Omnibus GitLab **(CORE ONLY)**
|
# Standalone PostgreSQL using Omnibus GitLab **(CORE ONLY)**
|
||||||
|
|
||||||
If you wish to have your database service hosted separately from your GitLab
|
If you wish to have your database service hosted separately from your GitLab
|
||||||
application server(s), you can do this using the PostgreSQL binaries packaged
|
application servers, you can do this using the PostgreSQL binaries packaged
|
||||||
together with Omnibus GitLab. This is recommended as part of our
|
together with Omnibus GitLab. This is recommended as part of our
|
||||||
[reference architecture for up to 2,000 users](../reference_architectures/2k_users.md).
|
[reference architecture for up to 2,000 users](../reference_architectures/2k_users.md).
|
||||||
|
|
||||||
## Setting it up
|
## Setting it up
|
||||||
|
|
||||||
1. SSH into the PostgreSQL server.
|
1. SSH in to the PostgreSQL server.
|
||||||
1. [Download/install](https://about.gitlab.com/install/) the Omnibus GitLab
|
1. [Download and install](https://about.gitlab.com/install/) the Omnibus GitLab
|
||||||
package you want using **steps 1 and 2** from the GitLab downloads page.
|
package you want using *steps 1 and 2* from the GitLab downloads page.
|
||||||
- Do not complete any other steps on the download page.
|
- Do not complete any other steps on the download page.
|
||||||
1. Generate a password hash for PostgreSQL. This assumes you will use the default
|
1. Generate a password hash for PostgreSQL. This assumes you will use the default
|
||||||
username of `gitlab` (recommended). The command will request a password
|
username of `gitlab` (recommended). The command will request a password
|
||||||
|
|
|
@ -223,6 +223,58 @@ Example response:
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## List all billable members of a group
|
||||||
|
|
||||||
|
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/217384) in GitLab 13.5.
|
||||||
|
|
||||||
|
Gets a list of group members who counts as billable, including members in the sub group/project.
|
||||||
|
|
||||||
|
This function takes [pagination](README.md#pagination) parameters `page` and `per_page` to restrict the list of users.
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
GET /groups/:id/billable_members
|
||||||
|
```
|
||||||
|
|
||||||
|
| Attribute | Type | Required | Description |
|
||||||
|
| --------- | ---- | -------- | ----------- |
|
||||||
|
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) owned by the authenticated user |
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/:id/billable_members"
|
||||||
|
```
|
||||||
|
|
||||||
|
Example response:
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"username": "raymond_smith",
|
||||||
|
"name": "Raymond Smith",
|
||||||
|
"state": "active",
|
||||||
|
"avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon",
|
||||||
|
"web_url": "http://192.168.1.8:3000/root",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"username": "john_doe",
|
||||||
|
"name": "John Doe",
|
||||||
|
"state": "active",
|
||||||
|
"avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon",
|
||||||
|
"web_url": "http://192.168.1.8:3000/root",
|
||||||
|
"email": "john@example.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"username": "foo_bar",
|
||||||
|
"name": "Foo bar",
|
||||||
|
"state": "active",
|
||||||
|
"avatar_url": "https://www.gravatar.com/avatar/c2525a7f58ae3776070e44c106c48e15?s=80&d=identicon",
|
||||||
|
"web_url": "http://192.168.1.8:3000/root"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
## Add a member to a group or project
|
## Add a member to a group or project
|
||||||
|
|
||||||
Adds a member to a group or project.
|
Adds a member to a group or project.
|
||||||
|
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 6.7 KiB |
Before Width: | Height: | Size: 121 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 236 KiB After Width: | Height: | Size: 54 KiB |
|
@ -780,6 +780,25 @@ to advertise the need for lookahead:
|
||||||
For an example of real world use, please
|
For an example of real world use, please
|
||||||
see [`ResolvesMergeRequests`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/graphql/resolvers/concerns/resolves_merge_requests.rb).
|
see [`ResolvesMergeRequests`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/graphql/resolvers/concerns/resolves_merge_requests.rb).
|
||||||
|
|
||||||
|
### Negated arguments
|
||||||
|
|
||||||
|
Negated filters can filter some resources (for example, find all issues that
|
||||||
|
have the `bug` label, but don't have the `bug2` label assigned). The `not`
|
||||||
|
argument is the preferred syntax to pass negated arguments:
|
||||||
|
|
||||||
|
```graphql
|
||||||
|
issues(labelName: "bug", not: {labelName: "bug2"}) {
|
||||||
|
nodes {
|
||||||
|
id
|
||||||
|
title
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
To avoid duplicated argument definitions, you can place these arguments in a reusable module (or
|
||||||
|
class, if the arguments are nested). Alternatively, you can consider to add a
|
||||||
|
[helper resolver method](https://gitlab.com/gitlab-org/gitlab/-/issues/258969).
|
||||||
|
|
||||||
## Pass a parent object into a child Presenter
|
## Pass a parent object into a child Presenter
|
||||||
|
|
||||||
Sometimes you need to access the resolved query parent in a child context to compute fields. Usually the parent is only
|
Sometimes you need to access the resolved query parent in a child context to compute fields. Usually the parent is only
|
||||||
|
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 45 KiB |
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 164 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 30 KiB |
Before Width: | Height: | Size: 115 KiB After Width: | Height: | Size: 33 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 9.5 KiB |
Before Width: | Height: | Size: 133 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 85 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 144 KiB After Width: | Height: | Size: 52 KiB |
Before Width: | Height: | Size: 165 KiB After Width: | Height: | Size: 68 KiB |
Before Width: | Height: | Size: 152 KiB After Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 161 KiB After Width: | Height: | Size: 60 KiB |
Before Width: | Height: | Size: 292 KiB After Width: | Height: | Size: 70 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 7.6 KiB |
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 31 KiB |
|
@ -16,7 +16,7 @@ module Gitlab
|
||||||
) do
|
) do
|
||||||
include Gitlab::Utils::StrongMemoize
|
include Gitlab::Utils::StrongMemoize
|
||||||
|
|
||||||
def initialize(**params)
|
def initialize(params = {})
|
||||||
params.each do |key, value|
|
params.each do |key, value|
|
||||||
self[key] = value
|
self[key] = value
|
||||||
end
|
end
|
||||||
|
|
|
@ -36,9 +36,9 @@ module Gitlab
|
||||||
def self.fabricate(resource)
|
def self.fabricate(resource)
|
||||||
case resource
|
case resource
|
||||||
when Hash
|
when Hash
|
||||||
self.new(resource.symbolize_keys)
|
self.new(**resource.symbolize_keys)
|
||||||
when ::Ci::HasVariable
|
when ::Ci::HasVariable
|
||||||
self.new(resource.to_runner_variable)
|
self.new(**resource.to_runner_variable)
|
||||||
when self
|
when self
|
||||||
resource.dup
|
resource.dup
|
||||||
else
|
else
|
||||||
|
|
|
@ -79,7 +79,7 @@ module Gitlab
|
||||||
end
|
end
|
||||||
|
|
||||||
def fabricate(entry_class, value = nil)
|
def fabricate(entry_class, value = nil)
|
||||||
entry_class.new(value, @metadata) do |node|
|
entry_class.new(value, **@metadata) do |node|
|
||||||
node.key = @attributes[:key]
|
node.key = @attributes[:key]
|
||||||
node.parent = @attributes[:parent]
|
node.parent = @attributes[:parent]
|
||||||
node.default = @attributes[:default]
|
node.default = @attributes[:default]
|
||||||
|
|
|
@ -19,7 +19,7 @@ module Gitlab
|
||||||
|
|
||||||
entry = self.class.entry_class(strategy)
|
entry = self.class.entry_class(strategy)
|
||||||
|
|
||||||
@subject = entry.new(config, metadata, &blk)
|
@subject = entry.new(config, **metadata, &blk)
|
||||||
|
|
||||||
super(@subject)
|
super(@subject)
|
||||||
end
|
end
|
||||||
|
|
|
@ -138,6 +138,7 @@ module Gitlab
|
||||||
pages_domains: count(PagesDomain),
|
pages_domains: count(PagesDomain),
|
||||||
pool_repositories: count(PoolRepository),
|
pool_repositories: count(PoolRepository),
|
||||||
projects: count(Project),
|
projects: count(Project),
|
||||||
|
projects_creating_incidents: distinct_count(Issue.incident, :project_id),
|
||||||
projects_imported_from_github: count(Project.where(import_type: 'github')),
|
projects_imported_from_github: count(Project.where(import_type: 'github')),
|
||||||
projects_with_repositories_enabled: count(ProjectFeature.where('repository_access_level > ?', ProjectFeature::DISABLED)),
|
projects_with_repositories_enabled: count(ProjectFeature.where('repository_access_level > ?', ProjectFeature::DISABLED)),
|
||||||
projects_with_error_tracking_enabled: count(::ErrorTracking::ProjectErrorTrackingSetting.where(enabled: true)),
|
projects_with_error_tracking_enabled: count(::ErrorTracking::ProjectErrorTrackingSetting.where(enabled: true)),
|
||||||
|
|
|
@ -8,8 +8,6 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: gitlab 1.0.0\n"
|
"Project-Id-Version: gitlab 1.0.0\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2020-09-22 19:32+0200\n"
|
|
||||||
"PO-Revision-Date: 2020-09-22 19:32+0200\n"
|
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
"Language: \n"
|
"Language: \n"
|
||||||
|
@ -15700,6 +15698,18 @@ msgstr ""
|
||||||
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
|
msgid "Members with access to %{strong_start}%{group_name}%{strong_end}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Members|%{time} by %{user}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Members|Expired"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Members|No expiration set"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "Members|in %{time}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "Memory Usage"
|
msgid "Memory Usage"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -24434,6 +24444,9 @@ msgstr ""
|
||||||
msgid "StaticSiteEditor|3. Assign a person to review and accept the merge request."
|
msgid "StaticSiteEditor|3. Assign a person to review and accept the merge request."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "StaticSiteEditor|A link to view the merge request will appear once ready."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "StaticSiteEditor|An error occurred while submitting your changes."
|
msgid "StaticSiteEditor|An error occurred while submitting your changes."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -24446,6 +24459,9 @@ msgstr ""
|
||||||
msgid "StaticSiteEditor|Could not create merge request."
|
msgid "StaticSiteEditor|Could not create merge request."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "StaticSiteEditor|Creating your merge request"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "StaticSiteEditor|Incompatible file content"
|
msgid "StaticSiteEditor|Incompatible file content"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -24467,6 +24483,9 @@ msgstr ""
|
||||||
msgid "StaticSiteEditor|View documentation"
|
msgid "StaticSiteEditor|View documentation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "StaticSiteEditor|You can set an assignee to get your changes reviewed and deployed once your merge request is created."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "StaticSiteEditor|Your merge request has been created"
|
msgid "StaticSiteEditor|Your merge request has been created"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,6 @@
|
||||||
"glob": "^7.1.6",
|
"glob": "^7.1.6",
|
||||||
"graphql": "^14.7.0",
|
"graphql": "^14.7.0",
|
||||||
"graphql-tag": "^2.10.1",
|
"graphql-tag": "^2.10.1",
|
||||||
"gray-matter": "^4.0.2",
|
|
||||||
"immer": "^7.0.7",
|
"immer": "^7.0.7",
|
||||||
"imports-loader": "^0.8.0",
|
"imports-loader": "^0.8.0",
|
||||||
"ipaddr.js": "^1.9.1",
|
"ipaddr.js": "^1.9.1",
|
||||||
|
|