diff options
Diffstat (limited to 'app/assets/javascripts/snippets')
14 files changed, 89 insertions, 72 deletions
diff --git a/app/assets/javascripts/snippets/components/edit.vue b/app/assets/javascripts/snippets/components/edit.vue index 1a539aa0876..dd77d49803f 100644 --- a/app/assets/javascripts/snippets/components/edit.vue +++ b/app/assets/javascripts/snippets/components/edit.vue @@ -6,7 +6,12 @@ import { __, sprintf } from '~/locale'; import TitleField from '~/vue_shared/components/form/title.vue'; import { redirectTo, joinPaths } from '~/lib/utils/url_utility'; import FormFooterActions from '~/vue_shared/components/form/form_footer_actions.vue'; -import { SNIPPET_MARK_EDIT_APP_START } from '~/performance_constants'; +import { + SNIPPET_MARK_EDIT_APP_START, + SNIPPET_MEASURE_BLOBS_CONTENT, +} from '~/performance_constants'; +import eventHub from '~/blob/components/eventhub'; +import { performanceMarkAndMeasure } from '~/performance_utils'; import UpdateSnippetMutation from '../mutations/updateSnippet.mutation.graphql'; import CreateSnippetMutation from '../mutations/createSnippet.mutation.graphql'; @@ -17,11 +22,14 @@ import { SNIPPET_VISIBILITY_PRIVATE, } from '../constants'; import defaultVisibilityQuery from '../queries/snippet_visibility.query.graphql'; +import { markBlobPerformance } from '../utils/blob'; import SnippetBlobActionsEdit from './snippet_blob_actions_edit.vue'; import SnippetVisibilityEdit from './snippet_visibility_edit.vue'; import SnippetDescriptionEdit from './snippet_description_edit.vue'; +eventHub.$on(SNIPPET_MEASURE_BLOBS_CONTENT, markBlobPerformance); + export default { components: { SnippetDescriptionEdit, @@ -104,12 +112,6 @@ export default { } return this.snippet.webUrl; }, - titleFieldId() { - return `${this.isProjectSnippet ? 'project' : 'personal'}_snippet_title`; - }, - descriptionFieldId() { - return `${this.isProjectSnippet ? 'project' : 'personal'}_snippet_description`; - }, newSnippetSchema() { return { title: '', @@ -119,7 +121,7 @@ export default { }, }, beforeCreate() { - performance.mark(SNIPPET_MARK_EDIT_APP_START); + performanceMarkAndMeasure({ mark: SNIPPET_MARK_EDIT_APP_START }); }, created() { window.addEventListener('beforeunload', this.onBeforeUnload); @@ -151,7 +153,7 @@ export default { this.newSnippet = false; }, onSnippetFetch(snippetRes) { - if (snippetRes.data.snippets.edges.length === 0) { + if (snippetRes.data.snippets.nodes.length === 0) { this.onNewSnippetFetched(); } else { this.onExistingSnippetFetched(); @@ -220,14 +222,13 @@ export default { /> <template v-else> <title-field - :id="titleFieldId" + id="snippet-title" v-model="snippet.title" data-qa-selector="snippet_title_field" required :autofocus="true" /> <snippet-description-edit - :id="descriptionFieldId" v-model="snippet.description" :markdown-preview-path="markdownPreviewPath" :markdown-docs-path="markdownDocsPath" diff --git a/app/assets/javascripts/snippets/components/embed_dropdown.vue b/app/assets/javascripts/snippets/components/embed_dropdown.vue index 589754a8b19..a5d2c337d67 100644 --- a/app/assets/javascripts/snippets/components/embed_dropdown.vue +++ b/app/assets/javascripts/snippets/components/embed_dropdown.vue @@ -60,7 +60,7 @@ export default { class="gl-dropdown-text-py-0 gl-dropdown-text-block" data-testid="input" > - <gl-form-input-group :value="value" readonly select-on-click> + <gl-form-input-group :value="value" readonly select-on-click :aria-label="name"> <template #append> <gl-button v-gl-tooltip.hover diff --git a/app/assets/javascripts/snippets/components/show.vue b/app/assets/javascripts/snippets/components/show.vue index 43be2cb7ed8..4a2f060ff7c 100644 --- a/app/assets/javascripts/snippets/components/show.vue +++ b/app/assets/javascripts/snippets/components/show.vue @@ -5,11 +5,18 @@ import SnippetHeader from './snippet_header.vue'; import SnippetTitle from './snippet_title.vue'; import SnippetBlob from './snippet_blob_view.vue'; import CloneDropdownButton from '~/vue_shared/components/clone_dropdown.vue'; +import { SNIPPET_VISIBILITY_PUBLIC } from '~/snippets/constants'; +import { + SNIPPET_MARK_VIEW_APP_START, + SNIPPET_MEASURE_BLOBS_CONTENT, +} from '~/performance_constants'; +import { performanceMarkAndMeasure } from '~/performance_utils'; +import eventHub from '~/blob/components/eventhub'; import { getSnippetMixin } from '../mixins/snippets'; -import { SNIPPET_VISIBILITY_PUBLIC } from '~/snippets/constants'; +import { markBlobPerformance } from '../utils/blob'; -import { SNIPPET_MARK_VIEW_APP_START } from '~/performance_constants'; +eventHub.$on(SNIPPET_MEASURE_BLOBS_CONTENT, markBlobPerformance); export default { components: { @@ -30,7 +37,7 @@ export default { }, }, beforeCreate() { - performance.mark(SNIPPET_MARK_VIEW_APP_START); + performanceMarkAndMeasure({ mark: SNIPPET_MARK_VIEW_APP_START }); }, }; </script> diff --git a/app/assets/javascripts/snippets/components/snippet_blob_actions_edit.vue b/app/assets/javascripts/snippets/components/snippet_blob_actions_edit.vue index 55cd13a6930..ab2553265a2 100644 --- a/app/assets/javascripts/snippets/components/snippet_blob_actions_edit.vue +++ b/app/assets/javascripts/snippets/components/snippet_blob_actions_edit.vue @@ -2,7 +2,6 @@ import { GlButton } from '@gitlab/ui'; import { cloneDeep } from 'lodash'; import { s__, sprintf } from '~/locale'; -import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import SnippetBlobEdit from './snippet_blob_edit.vue'; import { SNIPPET_MAX_BLOBS } from '../constants'; import { createBlob, decorateBlob, diffAll } from '../utils/blob'; @@ -12,7 +11,6 @@ export default { SnippetBlobEdit, GlButton, }, - mixins: [glFeatureFlagsMixin()], props: { initBlobs: { type: Array, @@ -52,12 +50,6 @@ export default { canAdd() { return this.count < SNIPPET_MAX_BLOBS; }, - hasMultiFilesEnabled() { - return this.glFeatures.snippetMultipleFiles; - }, - filesLabel() { - return this.hasMultiFilesEnabled ? s__('Snippets|Files') : s__('Snippets|File'); - }, firstInputId() { const blobId = this.blobIds[0]; @@ -131,24 +123,23 @@ export default { }; </script> <template> - <div class="form-group file-editor"> - <label :for="firstInputId">{{ filesLabel }}</label> + <div class="form-group"> + <label :for="firstInputId">{{ s__('Snippets|Files') }}</label> <snippet-blob-edit v-for="(blobId, index) in blobIds" :key="blobId" :class="{ 'gl-mt-3': index > 0 }" :blob="blobs[blobId]" :can-delete="canDelete" - :show-delete="hasMultiFilesEnabled" @blob-updated="updateBlob(blobId, $event)" @delete="deleteBlob(blobId)" /> <gl-button - v-if="hasMultiFilesEnabled" :disabled="!canAdd" data-testid="add_button" class="gl-my-3" variant="dashed" + data-qa-selector="add_file_button" @click="addBlob" >{{ addLabel }}</gl-button > diff --git a/app/assets/javascripts/snippets/components/snippet_blob_edit.vue b/app/assets/javascripts/snippets/components/snippet_blob_edit.vue index f3f894ed649..6a10dc38f2c 100644 --- a/app/assets/javascripts/snippets/components/snippet_blob_edit.vue +++ b/app/assets/javascripts/snippets/components/snippet_blob_edit.vue @@ -1,7 +1,7 @@ <script> import { GlLoadingIcon } from '@gitlab/ui'; import BlobHeaderEdit from '~/blob/components/blob_edit_header.vue'; -import BlobContentEdit from '~/blob/components/blob_edit_content.vue'; +import EditorLite from '~/vue_shared/components/editor_lite.vue'; import { getBaseURL, joinPaths } from '~/lib/utils/url_utility'; import axios from '~/lib/utils/axios_utils'; import { SNIPPET_BLOB_CONTENT_FETCH_ERROR } from '~/snippets/constants'; @@ -11,8 +11,8 @@ import { sprintf } from '~/locale'; export default { components: { BlobHeaderEdit, - BlobContentEdit, GlLoadingIcon, + EditorLite, }, inheritAttrs: false, props: { @@ -28,7 +28,7 @@ export default { showDelete: { type: Boolean, required: false, - default: false, + default: true, }, }, computed: { @@ -69,7 +69,7 @@ export default { }; </script> <template> - <div class="file-holder snippet"> + <div class="file-holder snippet" data-qa-selector="file_holder_container"> <blob-header-edit :id="inputId" :value="blob.path" @@ -85,7 +85,7 @@ export default { size="lg" class="loading-animation prepend-top-20 gl-mb-6" /> - <blob-content-edit + <editor-lite v-else :value="blob.content" :file-global-id="blob.id" diff --git a/app/assets/javascripts/snippets/components/snippet_blob_view.vue b/app/assets/javascripts/snippets/components/snippet_blob_view.vue index b38be5bb9a4..e88126ea56a 100644 --- a/app/assets/javascripts/snippets/components/snippet_blob_view.vue +++ b/app/assets/javascripts/snippets/components/snippet_blob_view.vue @@ -23,6 +23,7 @@ export default { return { ids: this.snippet.id, rich: this.activeViewerType === RICH_BLOB_VIEWER, + paths: [this.blob.path], }; }, update(data) { @@ -79,8 +80,10 @@ export default { }, onContentUpdate(data) { const { path: blobPath } = this.blob; - const { blobs } = data.snippets.edges[0].node; - const updatedBlobData = blobs.find(blob => blob.path === blobPath); + const { + blobs: { nodes: dataBlobs }, + } = data.snippets.nodes[0]; + const updatedBlobData = dataBlobs.find(blob => blob.path === blobPath); return updatedBlobData.richData || updatedBlobData.plainData; }, }, diff --git a/app/assets/javascripts/snippets/components/snippet_description_edit.vue b/app/assets/javascripts/snippets/components/snippet_description_edit.vue index 737845d09b8..5e6caf27bdd 100644 --- a/app/assets/javascripts/snippets/components/snippet_description_edit.vue +++ b/app/assets/javascripts/snippets/components/snippet_description_edit.vue @@ -49,6 +49,7 @@ export default { :add-spacing-classes="false" :markdown-preview-path="markdownPreviewPath" :markdown-docs-path="markdownDocsPath" + :textarea-value="value" > <template #textarea> <textarea diff --git a/app/assets/javascripts/snippets/components/snippet_header.vue b/app/assets/javascripts/snippets/components/snippet_header.vue index 0ca69f3161a..30de5a9d0e0 100644 --- a/app/assets/javascripts/snippets/components/snippet_header.vue +++ b/app/assets/javascripts/snippets/components/snippet_header.vue @@ -18,6 +18,7 @@ import DeleteSnippetMutation from '../mutations/deleteSnippet.mutation.graphql'; import CanCreatePersonalSnippet from '../queries/userPermissions.query.graphql'; import CanCreateProjectSnippet from '../queries/projectPermissions.query.graphql'; import { joinPaths } from '~/lib/utils/url_utility'; +import { fetchPolicies } from '~/lib/graphql'; export default { components: { @@ -37,6 +38,7 @@ export default { }, apollo: { canCreateSnippet: { + fetchPolicy: fetchPolicies.NO_CACHE, query() { return this.snippet.project ? CanCreateProjectSnippet : CanCreatePersonalSnippet; }, diff --git a/app/assets/javascripts/snippets/fragments/snippetBase.fragment.graphql b/app/assets/javascripts/snippets/fragments/snippetBase.fragment.graphql index 2cca71708ca..d75b4011d1c 100644 --- a/app/assets/javascripts/snippets/fragments/snippetBase.fragment.graphql +++ b/app/assets/javascripts/snippets/fragments/snippetBase.fragment.graphql @@ -12,18 +12,20 @@ fragment SnippetBase on Snippet { httpUrlToRepo sshUrlToRepo blobs { - binary - name - path - rawPath - size - externalStorage - renderedAsText - simpleViewer { - ...BlobViewer - } - richViewer { - ...BlobViewer + nodes { + binary + name + path + rawPath + size + externalStorage + renderedAsText + simpleViewer { + ...BlobViewer + } + richViewer { + ...BlobViewer + } } } userPermissions { diff --git a/app/assets/javascripts/snippets/index.js b/app/assets/javascripts/snippets/index.js index c70ad9b95f8..b55e1baf41e 100644 --- a/app/assets/javascripts/snippets/index.js +++ b/app/assets/javascripts/snippets/index.js @@ -3,20 +3,18 @@ import VueApollo from 'vue-apollo'; import Translate from '~/vue_shared/translate'; import createDefaultClient from '~/lib/graphql'; -import SnippetsShow from './components/show.vue'; -import SnippetsEdit from './components/edit.vue'; import { SNIPPET_LEVELS_MAP, SNIPPET_VISIBILITY_PRIVATE } from '~/snippets/constants'; Vue.use(VueApollo); Vue.use(Translate); -function appFactory(el, Component) { +export default function appFactory(el, Component) { if (!el) { return false; } const apolloProvider = new VueApollo({ - defaultClient: createDefaultClient(), + defaultClient: createDefaultClient({}, { batchMax: 1 }), }); const { @@ -46,11 +44,3 @@ function appFactory(el, Component) { }, }); } - -export const SnippetShowInit = () => { - appFactory(document.getElementById('js-snippet-view'), SnippetsShow); -}; - -export const SnippetEditInit = () => { - appFactory(document.getElementById('js-snippet-edit'), SnippetsEdit); -}; diff --git a/app/assets/javascripts/snippets/mixins/snippets.js b/app/assets/javascripts/snippets/mixins/snippets.js index 15daaa8d84a..d5e69e2a889 100644 --- a/app/assets/javascripts/snippets/mixins/snippets.js +++ b/app/assets/javascripts/snippets/mixins/snippets.js @@ -11,9 +11,16 @@ export const getSnippetMixin = { ids: this.snippetGid, }; }, - update: data => data.snippets.edges[0]?.node, + update: data => { + const res = data.snippets.nodes[0]; + if (res) { + res.blobs = res.blobs.nodes; + } + + return res; + }, result(res) { - this.blobs = res.data.snippets.edges[0]?.node?.blobs || blobsDefault; + this.blobs = res.data.snippets.nodes[0]?.blobs || blobsDefault; if (this.onSnippetFetch) { this.onSnippetFetch(res); } diff --git a/app/assets/javascripts/snippets/queries/snippet.blob.content.query.graphql b/app/assets/javascripts/snippets/queries/snippet.blob.content.query.graphql index 8f1f16b76c2..0e04ee9b7b8 100644 --- a/app/assets/javascripts/snippets/queries/snippet.blob.content.query.graphql +++ b/app/assets/javascripts/snippets/queries/snippet.blob.content.query.graphql @@ -1,9 +1,9 @@ -query SnippetBlobContent($ids: [ID!], $rich: Boolean!) { +query SnippetBlobContent($ids: [ID!], $rich: Boolean!, $paths: [String!]) { snippets(ids: $ids) { - edges { - node { - id - blobs { + nodes { + id + blobs(paths: $paths) { + nodes { path richData @include(if: $rich) plainData @skip(if: $rich) diff --git a/app/assets/javascripts/snippets/queries/snippet.query.graphql b/app/assets/javascripts/snippets/queries/snippet.query.graphql index b23ab862439..2f385050d89 100644 --- a/app/assets/javascripts/snippets/queries/snippet.query.graphql +++ b/app/assets/javascripts/snippets/queries/snippet.query.graphql @@ -4,13 +4,11 @@ query GetSnippetQuery($ids: [ID!]) { snippets(ids: $ids) { - edges { - node { - ...SnippetBase - ...SnippetProject - author { - ...Author - } + nodes { + ...SnippetBase + ...SnippetProject + author { + ...Author } } } diff --git a/app/assets/javascripts/snippets/utils/blob.js b/app/assets/javascripts/snippets/utils/blob.js index 21f52671801..c47559b82b8 100644 --- a/app/assets/javascripts/snippets/utils/blob.js +++ b/app/assets/javascripts/snippets/utils/blob.js @@ -7,6 +7,8 @@ import { SNIPPET_LEVELS_MAP, SNIPPET_VISIBILITY, } from '../constants'; +import { performanceMarkAndMeasure } from '~/performance_utils'; +import { SNIPPET_MARK_BLOBS_CONTENT, SNIPPET_MEASURE_BLOBS_CONTENT } from '~/performance_constants'; const createLocalId = () => uniqueId('blob_local_'); @@ -79,3 +81,16 @@ export const defaultSnippetVisibilityLevels = arr => { } return []; }; + +export const markBlobPerformance = () => { + performanceMarkAndMeasure({ + mark: SNIPPET_MARK_BLOBS_CONTENT, + measures: [ + { + name: SNIPPET_MEASURE_BLOBS_CONTENT, + start: undefined, + end: SNIPPET_MARK_BLOBS_CONTENT, + }, + ], + }); +}; |