diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-09-30 12:10:11 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-09-30 12:10:11 +0300 |
commit | 418c3b29009dcc0a2c6b4872557d0274ba0b8077 (patch) | |
tree | 427b01c0b7942fd458b4f363f2d897912ec9e290 /app/assets/javascripts/static_site_editor | |
parent | 3c02fe83263991811e94e8126be8f065afe15372 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/assets/javascripts/static_site_editor')
11 files changed, 158 insertions, 29 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/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..bd7d5cf29d7 100644 --- a/app/assets/javascripts/static_site_editor/index.js +++ b/app/assets/javascripts/static_site_editor/index.js @@ -19,6 +19,7 @@ const initStaticSiteEditor = el => { 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..5c1af45b831 100644 --- a/app/assets/javascripts/static_site_editor/pages/home.vue +++ b/app/assets/javascripts/static_site_editor/pages/home.vue @@ -5,6 +5,7 @@ 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'; @@ -74,6 +75,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, @@ -87,9 +102,6 @@ export default { }, }, }) - .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..6a3f40cc1db 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,23 @@ 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" > <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, |