Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/static_site_editor')
-rw-r--r--app/assets/javascripts/static_site_editor/components/publish_toolbar.vue2
-rw-r--r--app/assets/javascripts/static_site_editor/graphql/index.js2
-rw-r--r--app/assets/javascripts/static_site_editor/graphql/mutations/has_submitted_changes.mutation.graphql5
-rw-r--r--app/assets/javascripts/static_site_editor/graphql/queries/app_data.query.graphql1
-rw-r--r--app/assets/javascripts/static_site_editor/graphql/resolvers/has_submitted_changes.js17
-rw-r--r--app/assets/javascripts/static_site_editor/graphql/resolvers/submit_content_changes.js31
-rw-r--r--app/assets/javascripts/static_site_editor/graphql/typedefs.graphql6
-rw-r--r--app/assets/javascripts/static_site_editor/index.js12
-rw-r--r--app/assets/javascripts/static_site_editor/pages/home.vue30
-rw-r--r--app/assets/javascripts/static_site_editor/pages/success.vue46
-rw-r--r--app/assets/javascripts/static_site_editor/services/front_matterify.js73
-rw-r--r--app/assets/javascripts/static_site_editor/services/parse_source_file.js17
-rw-r--r--app/assets/javascripts/static_site_editor/services/submit_content_changes.js18
-rw-r--r--app/assets/javascripts/static_site_editor/services/templater.js2
14 files changed, 210 insertions, 52 deletions
diff --git a/app/assets/javascripts/static_site_editor/components/publish_toolbar.vue b/app/assets/javascripts/static_site_editor/components/publish_toolbar.vue
index 2d62964cb3b..5f00f9f22f3 100644
--- a/app/assets/javascripts/static_site_editor/components/publish_toolbar.vue
+++ b/app/assets/javascripts/static_site_editor/components/publish_toolbar.vue
@@ -41,7 +41,7 @@ export default {
:disabled="savingChanges"
@click="$emit('editSettings')"
>
- {{ __('Settings') }}
+ {{ __('Page settings') }}
</gl-button>
<gl-button
ref="submit"
diff --git a/app/assets/javascripts/static_site_editor/graphql/index.js b/app/assets/javascripts/static_site_editor/graphql/index.js
index 0a5d8c07ad9..fbb3d7fbfcc 100644
--- a/app/assets/javascripts/static_site_editor/graphql/index.js
+++ b/app/assets/javascripts/static_site_editor/graphql/index.js
@@ -4,6 +4,7 @@ import createDefaultClient from '~/lib/graphql';
import typeDefs from './typedefs.graphql';
import fileResolver from './resolvers/file';
import submitContentChangesResolver from './resolvers/submit_content_changes';
+import hasSubmittedChangesResolver from './resolvers/has_submitted_changes';
Vue.use(VueApollo);
@@ -15,6 +16,7 @@ const createApolloProvider = appData => {
},
Mutation: {
submitContentChanges: submitContentChangesResolver,
+ hasSubmittedChanges: hasSubmittedChangesResolver,
},
},
{
diff --git a/app/assets/javascripts/static_site_editor/graphql/mutations/has_submitted_changes.mutation.graphql b/app/assets/javascripts/static_site_editor/graphql/mutations/has_submitted_changes.mutation.graphql
new file mode 100644
index 00000000000..1f47929556a
--- /dev/null
+++ b/app/assets/javascripts/static_site_editor/graphql/mutations/has_submitted_changes.mutation.graphql
@@ -0,0 +1,5 @@
+mutation hasSubmittedChanges($input: HasSubmittedChangesInput) {
+ hasSubmittedChanges(input: $input) @client {
+ hasSubmittedChanges
+ }
+}
diff --git a/app/assets/javascripts/static_site_editor/graphql/queries/app_data.query.graphql b/app/assets/javascripts/static_site_editor/graphql/queries/app_data.query.graphql
index 946d80efff0..9f4b0afe55f 100644
--- a/app/assets/javascripts/static_site_editor/graphql/queries/app_data.query.graphql
+++ b/app/assets/javascripts/static_site_editor/graphql/queries/app_data.query.graphql
@@ -1,6 +1,7 @@
query appData {
appData @client {
isSupportedContent
+ hasSubmittedChanges
project
sourcePath
username
diff --git a/app/assets/javascripts/static_site_editor/graphql/resolvers/has_submitted_changes.js b/app/assets/javascripts/static_site_editor/graphql/resolvers/has_submitted_changes.js
new file mode 100644
index 00000000000..ce55db7f3e5
--- /dev/null
+++ b/app/assets/javascripts/static_site_editor/graphql/resolvers/has_submitted_changes.js
@@ -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;
diff --git a/app/assets/javascripts/static_site_editor/graphql/resolvers/submit_content_changes.js b/app/assets/javascripts/static_site_editor/graphql/resolvers/submit_content_changes.js
index 0cb26f88785..694cf762e51 100644
--- a/app/assets/javascripts/static_site_editor/graphql/resolvers/submit_content_changes.js
+++ b/app/assets/javascripts/static_site_editor/graphql/resolvers/submit_content_changes.js
@@ -3,22 +3,27 @@ import savedContentMetaQuery from '../queries/saved_content_meta.query.graphql';
const submitContentChangesResolver = (
_,
- { input: { project: projectId, username, sourcePath, content, images } },
+ { input: { project: projectId, username, sourcePath, content, images, mergeRequestMeta } },
{ cache },
) => {
- return submitContentChanges({ projectId, username, sourcePath, content, images }).then(
- savedContentMeta => {
- cache.writeQuery({
- query: savedContentMetaQuery,
- data: {
- savedContentMeta: {
- __typename: 'SavedContentMeta',
- ...savedContentMeta,
- },
+ return submitContentChanges({
+ projectId,
+ username,
+ sourcePath,
+ content,
+ images,
+ mergeRequestMeta,
+ }).then(savedContentMeta => {
+ cache.writeQuery({
+ query: savedContentMetaQuery,
+ data: {
+ savedContentMeta: {
+ __typename: 'SavedContentMeta',
+ ...savedContentMeta,
},
- });
- },
- );
+ },
+ });
+ });
};
export default submitContentChangesResolver;
diff --git a/app/assets/javascripts/static_site_editor/graphql/typedefs.graphql b/app/assets/javascripts/static_site_editor/graphql/typedefs.graphql
index 78cc1746cdb..0ded1722d26 100644
--- a/app/assets/javascripts/static_site_editor/graphql/typedefs.graphql
+++ b/app/assets/javascripts/static_site_editor/graphql/typedefs.graphql
@@ -16,12 +16,17 @@ type SavedContentMeta {
type AppData {
isSupportedContent: Boolean!
+ hasSubmittedChanges: Boolean!
project: String!
returnUrl: String
sourcePath: String!
username: String!
}
+input HasSubmittedChangesInput {
+ hasSubmittedChanges: Boolean!
+}
+
input SubmitContentChangesInput {
project: String!
sourcePath: String!
@@ -40,4 +45,5 @@ extend type Query {
extend type Mutation {
submitContentChanges(input: SubmitContentChangesInput!): SavedContentMeta
+ hasSubmittedChanges(input: HasSubmittedChangesInput!): AppData
}
diff --git a/app/assets/javascripts/static_site_editor/index.js b/app/assets/javascripts/static_site_editor/index.js
index b7e5ea4eee3..fceef8f9084 100644
--- a/app/assets/javascripts/static_site_editor/index.js
+++ b/app/assets/javascripts/static_site_editor/index.js
@@ -12,13 +12,23 @@ const initStaticSiteEditor = el => {
namespace,
project,
mergeRequestsIllustrationPath,
+ // NOTE: The following variables are not yet used, but are supported by the config file,
+ // so we are adding them here as a convenience for future use.
+ // eslint-disable-next-line no-unused-vars
+ staticSiteGenerator,
+ // eslint-disable-next-line no-unused-vars
+ imageUploadPath,
+ mounts,
} = el.dataset;
+ // NOTE that the object in 'mounts' is a JSON string from the data attribute, so it must be parsed into an object.
+ // eslint-disable-next-line no-unused-vars
+ const mountsObject = JSON.parse(mounts);
const { current_username: username } = window.gon;
const returnUrl = el.dataset.returnUrl || null;
-
const router = createRouter(baseUrl);
const apolloProvider = createApolloProvider({
isSupportedContent: parseBoolean(isSupportedContent),
+ hasSubmittedChanges: false,
project: `${namespace}/${project}`,
returnUrl,
sourcePath,
diff --git a/app/assets/javascripts/static_site_editor/pages/home.vue b/app/assets/javascripts/static_site_editor/pages/home.vue
index eef2bd88f0e..d48917e8f36 100644
--- a/app/assets/javascripts/static_site_editor/pages/home.vue
+++ b/app/assets/javascripts/static_site_editor/pages/home.vue
@@ -1,13 +1,16 @@
<script>
+import { deprecatedCreateFlash as createFlash } from '~/flash';
+import { s__, sprintf } from '~/locale';
+import Tracking from '~/tracking';
+
import SkeletonLoader from '../components/skeleton_loader.vue';
import EditArea from '../components/edit_area.vue';
import InvalidContentMessage from '../components/invalid_content_message.vue';
import SubmitChangesError from '../components/submit_changes_error.vue';
import appDataQuery from '../graphql/queries/app_data.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 { deprecatedCreateFlash as createFlash } from '~/flash';
-import Tracking from '~/tracking';
import { LOAD_CONTENT_ERROR, TRACKING_ACTION_INITIALIZE_EDITOR } from '../constants';
import { SUCCESS_ROUTE } from '../router/constants';
@@ -74,6 +77,20 @@ export default {
submitChanges(images) {
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
.mutate({
mutation: submitContentChangesMutation,
@@ -84,12 +101,15 @@ export default {
sourcePath: this.appData.sourcePath,
content: this.content,
images,
+ mergeRequestMeta: {
+ title: sprintf(s__(`StaticSiteEditor|Update %{sourcePath} file`), {
+ sourcePath: this.appData.sourcePath,
+ }),
+ description: s__('StaticSiteEditor|Copy update'),
+ },
},
},
})
- .then(() => {
- this.$router.push(SUCCESS_ROUTE);
- })
.catch(e => {
this.submitChangesError = e.message;
})
diff --git a/app/assets/javascripts/static_site_editor/pages/success.vue b/app/assets/javascripts/static_site_editor/pages/success.vue
index f0d597d7c9b..5b013c27c35 100644
--- a/app/assets/javascripts/static_site_editor/pages/success.vue
+++ b/app/assets/javascripts/static_site_editor/pages/success.vue
@@ -1,5 +1,5 @@
<script>
-import { GlEmptyState, GlButton } from '@gitlab/ui';
+import { GlButton, GlEmptyState, GlLoadingIcon } from '@gitlab/ui';
import { s__, __, sprintf } from '~/locale';
import savedContentMetaQuery from '../graphql/queries/saved_content_meta.query.graphql';
@@ -8,8 +8,9 @@ import { HOME_ROUTE } from '../router/constants';
export default {
components: {
- GlEmptyState,
GlButton,
+ GlEmptyState,
+ GlLoadingIcon,
},
props: {
mergeRequestsIllustrationPath: {
@@ -33,7 +34,7 @@ export default {
},
},
created() {
- if (!this.savedContentMeta) {
+ if (!this.appData.hasSubmittedChanges) {
this.$router.push(HOME_ROUTE);
}
},
@@ -50,14 +51,21 @@ export default {
assignMergeRequestInstruction: s__(
'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>
<template>
- <div
- v-if="savedContentMeta"
- class="container gl-flex-grow-1 gl-display-flex gl-flex-direction-column"
- >
- <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-flex-grow-1 gl-display-flex gl-flex-direction-column">
+ <div
+ 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="container gl-py-4">
<gl-button
v-if="appData.returnUrl"
@@ -73,16 +81,24 @@ export default {
</div>
<gl-empty-state
class="gl-my-9"
- :primary-button-text="$options.primaryButtonText"
- :title="$options.title"
- :primary-button-link="savedContentMeta.mergeRequest.url"
+ :title="savedContentMeta ? $options.title : $options.submittingTitle"
+ :primary-button-text="savedContentMeta && $options.primaryButtonText"
+ :primary-button-link="savedContentMeta && savedContentMeta.mergeRequest.url"
:svg-path="mergeRequestsIllustrationPath"
+ :svg-height="146"
>
<template #description>
- <p>{{ $options.mergeRequestInstructionsHeading }}</p>
- <p>{{ $options.addTitleInstruction }}</p>
- <p>{{ $options.addDescriptionInstruction }}</p>
- <p>{{ $options.assignMergeRequestInstruction }}</p>
+ <div v-if="savedContentMeta">
+ <p>{{ $options.mergeRequestInstructionsHeading }}</p>
+ <p>{{ $options.addTitleInstruction }}</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>
</gl-empty-state>
</div>
diff --git a/app/assets/javascripts/static_site_editor/services/front_matterify.js b/app/assets/javascripts/static_site_editor/services/front_matterify.js
new file mode 100644
index 00000000000..cbf0fffd515
--- /dev/null
+++ b/app/assets/javascripts/static_site_editor/services/front_matterify.js
@@ -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}`;
+};
diff --git a/app/assets/javascripts/static_site_editor/services/parse_source_file.js b/app/assets/javascripts/static_site_editor/services/parse_source_file.js
index 640186ee1d0..d4fc8b2edb6 100644
--- a/app/assets/javascripts/static_site_editor/services/parse_source_file.js
+++ b/app/assets/javascripts/static_site_editor/services/parse_source_file.js
@@ -1,7 +1,7 @@
-import grayMatter from 'gray-matter';
+import { frontMatterify, stringify } from './front_matterify';
const parseSourceFile = raw => {
- const remake = source => grayMatter(source, {});
+ const remake = source => frontMatterify(source);
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.data;
+ const matter = () => editable.matter;
const syncMatter = settings => {
- const source = grayMatter.stringify(editable.content, settings);
- syncContent(source);
+ editable.matter = settings;
};
- const isModified = () => trimmedEditable() !== raw;
+ const isModified = () => stringify(editable) !== raw;
- const hasMatter = () => editable.matter.length > 0;
+ const hasMatter = () => Boolean(editable.matter);
return {
matter,
diff --git a/app/assets/javascripts/static_site_editor/services/submit_content_changes.js b/app/assets/javascripts/static_site_editor/services/submit_content_changes.js
index da62d3fa4fc..8623a671a7d 100644
--- a/app/assets/javascripts/static_site_editor/services/submit_content_changes.js
+++ b/app/assets/javascripts/static_site_editor/services/submit_content_changes.js
@@ -1,6 +1,5 @@
import Api from '~/api';
import Tracking from '~/tracking';
-import { s__, sprintf } from '~/locale';
import { convertObjectPropsToSnakeCase } from '~/lib/utils/common_utils';
import generateBranchName from '~/static_site_editor/services/generate_branch_name';
@@ -71,6 +70,7 @@ const commitContent = (projectId, message, branch, sourcePath, content, images)
const createMergeRequest = (
projectId,
title,
+ description,
sourceBranch,
targetBranch = DEFAULT_TARGET_BRANCH,
) => {
@@ -80,6 +80,7 @@ const createMergeRequest = (
projectId,
convertObjectPropsToSnakeCase({
title,
+ description,
sourceBranch,
targetBranch,
}),
@@ -88,11 +89,16 @@ const createMergeRequest = (
});
};
-const submitContentChanges = ({ username, projectId, sourcePath, content, images }) => {
+const submitContentChanges = ({
+ username,
+ projectId,
+ sourcePath,
+ content,
+ images,
+ mergeRequestMeta,
+}) => {
const branch = generateBranchName(username);
- const mergeRequestTitle = sprintf(s__(`StaticSiteEditor|Update %{sourcePath} file`), {
- sourcePath,
- });
+ const { title: mergeRequestTitle, description: mergeRequestDescription } = mergeRequestMeta;
const meta = {};
return createBranch(projectId, branch)
@@ -104,7 +110,7 @@ const submitContentChanges = ({ username, projectId, sourcePath, content, images
.then(({ data: { short_id: label, web_url: url } }) => {
Object.assign(meta, { commit: { label, url } });
- return createMergeRequest(projectId, mergeRequestTitle, branch);
+ return createMergeRequest(projectId, mergeRequestTitle, mergeRequestDescription, branch);
})
.then(({ data: { iid: label, web_url: url } }) => {
Object.assign(meta, { mergeRequest: { label: label.toString(), url } });
diff --git a/app/assets/javascripts/static_site_editor/services/templater.js b/app/assets/javascripts/static_site_editor/services/templater.js
index a1c1bb6b8d6..318f2099064 100644
--- a/app/assets/javascripts/static_site_editor/services/templater.js
+++ b/app/assets/javascripts/static_site_editor/services/templater.js
@@ -15,7 +15,7 @@ const markPrefix = `${marker}-${Date.now()}`;
const reHelpers = {
template: `.| |\\t|\\n(?!(\\n|${markPrefix}))`,
- openTag: '<[a-zA-Z]+.*?>',
+ openTag: '<(?!iframe)[a-zA-Z]+.*?>',
closeTag: '</.+>',
};
const reTemplated = new RegExp(`(^${wrapPrefix}(${reHelpers.template})+?${wrapPostfix}$)`, 'gm');