summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/repository/components
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/repository/components')
-rw-r--r--app/assets/javascripts/repository/components/blob_button_group.vue9
-rw-r--r--app/assets/javascripts/repository/components/blob_content_viewer.vue15
-rw-r--r--app/assets/javascripts/repository/components/blob_viewers/index.js16
-rw-r--r--app/assets/javascripts/repository/components/blob_viewers/pdf_viewer.vue50
-rw-r--r--app/assets/javascripts/repository/components/blob_viewers/text_viewer.vue25
-rw-r--r--app/assets/javascripts/repository/components/delete_blob_modal.vue14
-rw-r--r--app/assets/javascripts/repository/components/last_commit.vue2
-rw-r--r--app/assets/javascripts/repository/components/table/row.vue16
-rw-r--r--app/assets/javascripts/repository/components/tree_content.vue21
-rw-r--r--app/assets/javascripts/repository/components/upload_blob_modal.vue4
10 files changed, 125 insertions, 47 deletions
diff --git a/app/assets/javascripts/repository/components/blob_button_group.vue b/app/assets/javascripts/repository/components/blob_button_group.vue
index 4e7ca7b17e4..6f540bf8ece 100644
--- a/app/assets/javascripts/repository/components/blob_button_group.vue
+++ b/app/assets/javascripts/repository/components/blob_button_group.vue
@@ -53,6 +53,10 @@ export default {
type: Boolean,
required: true,
},
+ canPushToBranch: {
+ type: Boolean,
+ required: true,
+ },
emptyRepo: {
type: Boolean,
required: true,
@@ -83,6 +87,9 @@ export default {
deleteModalTitle() {
return sprintf(__('Delete %{name}'), { name: this.name });
},
+ lockBtnQASelector() {
+ return this.canLock ? 'lock_button' : 'disabled_lock_button';
+ },
},
};
</script>
@@ -98,6 +105,7 @@ export default {
:is-locked="isLocked"
:can-lock="canLock"
data-testid="lock"
+ :data-qa-selector="lockBtnQASelector"
/>
<gl-button v-gl-modal="replaceModalId" data-testid="replace">
{{ $options.i18n.replace }}
@@ -125,6 +133,7 @@ export default {
:target-branch="targetBranch || ref"
:original-branch="originalBranch || ref"
:can-push-code="canPushCode"
+ :can-push-to-branch="canPushToBranch"
:empty-repo="emptyRepo"
/>
</div>
diff --git a/app/assets/javascripts/repository/components/blob_content_viewer.vue b/app/assets/javascripts/repository/components/blob_content_viewer.vue
index 2cc5a8a79d2..f3fa4526999 100644
--- a/app/assets/javascripts/repository/components/blob_content_viewer.vue
+++ b/app/assets/javascripts/repository/components/blob_content_viewer.vue
@@ -106,6 +106,7 @@ export default {
ideForkAndEditPath: '',
storedExternally: false,
canModifyBlob: false,
+ canCurrentUserPushToBranch: false,
rawPath: '',
externalStorageUrl: '',
replacePath: '',
@@ -156,11 +157,18 @@ export default {
},
canLock() {
const { pushCode, downloadCode } = this.project.userPermissions;
+ const currentUsername = window.gon?.current_username;
+
+ if (this.pathLockedByUser && this.pathLockedByUser.username !== currentUsername) {
+ return false;
+ }
return pushCode && downloadCode;
},
- isLocked() {
- return this.project.pathLocks.nodes.some((node) => node.path === this.path);
+ pathLockedByUser() {
+ const pathLock = this.project.pathLocks.nodes.find((node) => node.path === this.path);
+
+ return pathLock ? pathLock.user : null;
},
showForkSuggestion() {
const { createMergeRequestIn, forkProject } = this.project.userPermissions;
@@ -266,9 +274,10 @@ export default {
:replace-path="blobInfo.replacePath"
:delete-path="blobInfo.webPath"
:can-push-code="project.userPermissions.pushCode"
+ :can-push-to-branch="blobInfo.canCurrentUserPushToBranch"
:empty-repo="project.repository.empty"
:project-path="projectPath"
- :is-locked="isLocked"
+ :is-locked="Boolean(pathLockedByUser)"
:can-lock="canLock"
/>
</template>
diff --git a/app/assets/javascripts/repository/components/blob_viewers/index.js b/app/assets/javascripts/repository/components/blob_viewers/index.js
index c5209d97abb..8f6f2d15215 100644
--- a/app/assets/javascripts/repository/components/blob_viewers/index.js
+++ b/app/assets/javascripts/repository/components/blob_viewers/index.js
@@ -3,8 +3,11 @@ export const loadViewer = (type) => {
case 'empty':
return () => import(/* webpackChunkName: 'blob_empty_viewer' */ './empty_viewer.vue');
case 'text':
- return gon.features.refactorTextViewer
- ? () => import(/* webpackChunkName: 'blob_text_viewer' */ './text_viewer.vue')
+ return gon.features.highlightJs
+ ? () =>
+ import(
+ /* webpackChunkName: 'blob_text_viewer' */ '~/vue_shared/components/source_viewer.vue'
+ )
: null;
case 'download':
return () => import(/* webpackChunkName: 'blob_download_viewer' */ './download_viewer.vue');
@@ -12,6 +15,8 @@ export const loadViewer = (type) => {
return () => import(/* webpackChunkName: 'blob_image_viewer' */ './image_viewer.vue');
case 'video':
return () => import(/* webpackChunkName: 'blob_video_viewer' */ './video_viewer.vue');
+ case 'pdf':
+ return () => import(/* webpackChunkName: 'blob_pdf_viewer' */ './pdf_viewer.vue');
default:
return null;
}
@@ -21,8 +26,7 @@ export const viewerProps = (type, blob) => {
return {
text: {
content: blob.rawTextBlob,
- fileName: blob.name,
- readOnly: true,
+ autoDetect: true, // We'll eventually disable autoDetect and pass the language explicitly to reduce the footprint (https://gitlab.com/gitlab-org/gitlab/-/issues/348145)
},
download: {
fileName: blob.name,
@@ -36,5 +40,9 @@ export const viewerProps = (type, blob) => {
video: {
url: blob.rawPath,
},
+ pdf: {
+ url: blob.rawPath,
+ fileSize: blob.rawSize,
+ },
}[type];
};
diff --git a/app/assets/javascripts/repository/components/blob_viewers/pdf_viewer.vue b/app/assets/javascripts/repository/components/blob_viewers/pdf_viewer.vue
new file mode 100644
index 00000000000..803a357df52
--- /dev/null
+++ b/app/assets/javascripts/repository/components/blob_viewers/pdf_viewer.vue
@@ -0,0 +1,50 @@
+<script>
+import { GlButton } from '@gitlab/ui';
+import PdfViewer from '~/blob/pdf/pdf_viewer.vue';
+import { __ } from '~/locale';
+import { PDF_MAX_FILE_SIZE, PDF_MAX_PAGE_LIMIT } from '../../constants';
+
+export default {
+ components: { GlButton, PdfViewer },
+ i18n: {
+ tooLargeDescription: __('This PDF is too large to display. Please download to view.'),
+ tooLargeButtonText: __('Download PDF'),
+ },
+ props: {
+ url: {
+ type: String,
+ required: true,
+ },
+ fileSize: {
+ type: Number,
+ required: true,
+ },
+ },
+ data() {
+ return { totalPages: 0 };
+ },
+ computed: {
+ tooLargeToDisplay() {
+ return this.fileSize > PDF_MAX_FILE_SIZE || this.totalPages > PDF_MAX_PAGE_LIMIT;
+ },
+ },
+ methods: {
+ handleOnLoad(totalPages) {
+ this.totalPages = totalPages;
+ },
+ },
+};
+</script>
+<template>
+ <div>
+ <pdf-viewer v-if="!tooLargeToDisplay" :pdf="url" @pdflabload="handleOnLoad" />
+
+ <div v-else class="gl-display-flex gl-flex-direction-column gl-align-items-center gl-p-5">
+ <p>{{ $options.i18n.tooLargeDescription }}</p>
+
+ <gl-button icon="download" category="secondary" variant="confirm" :href="url" download>{{
+ $options.i18n.tooLargeButtonText
+ }}</gl-button>
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/repository/components/blob_viewers/text_viewer.vue b/app/assets/javascripts/repository/components/blob_viewers/text_viewer.vue
deleted file mode 100644
index 57fc979a56e..00000000000
--- a/app/assets/javascripts/repository/components/blob_viewers/text_viewer.vue
+++ /dev/null
@@ -1,25 +0,0 @@
-<script>
-export default {
- components: {
- SourceEditor: () =>
- import(/* webpackChunkName: 'SourceEditor' */ '~/vue_shared/components/source_editor.vue'),
- },
- props: {
- content: {
- type: String,
- required: true,
- },
- fileName: {
- type: String,
- required: true,
- },
- readOnly: {
- type: Boolean,
- required: true,
- },
- },
-};
-</script>
-<template>
- <source-editor :value="content" :file-name="fileName" :editor-options="{ readOnly }" />
-</template>
diff --git a/app/assets/javascripts/repository/components/delete_blob_modal.vue b/app/assets/javascripts/repository/components/delete_blob_modal.vue
index 4a8cedb60b4..0d3dc06c2c8 100644
--- a/app/assets/javascripts/repository/components/delete_blob_modal.vue
+++ b/app/assets/javascripts/repository/components/delete_blob_modal.vue
@@ -71,6 +71,10 @@ export default {
type: Boolean,
required: true,
},
+ canPushToBranch: {
+ type: Boolean,
+ required: true,
+ },
emptyRepo: {
type: Boolean,
required: true,
@@ -176,9 +180,12 @@ export default {
</template>
<template v-else>
<input type="hidden" name="original_branch" :value="originalBranch" />
- <!-- Once "push to branch" permission is made available, will need to add to conditional
- Follow-up issue: https://gitlab.com/gitlab-org/gitlab/-/issues/335462 -->
- <input v-if="createNewMr" type="hidden" name="create_merge_request" value="1" />
+ <input
+ v-if="createNewMr || !canPushToBranch"
+ type="hidden"
+ name="create_merge_request"
+ value="1"
+ />
<gl-form-group
:label="$options.i18n.COMMIT_LABEL"
label-for="commit_message"
@@ -188,6 +195,7 @@ export default {
v-model="form.fields['commit_message'].value"
v-validation:[form.showValidation]
name="commit_message"
+ data-qa-selector="commit_message_field"
:state="form.fields['commit_message'].state"
:disabled="loading"
required
diff --git a/app/assets/javascripts/repository/components/last_commit.vue b/app/assets/javascripts/repository/components/last_commit.vue
index 62066973ee6..43e114a91d3 100644
--- a/app/assets/javascripts/repository/components/last_commit.vue
+++ b/app/assets/javascripts/repository/components/last_commit.vue
@@ -111,7 +111,7 @@ export default {
</script>
<template>
- <div class="info-well d-none d-sm-flex project-last-commit commit p-3">
+ <div class="well-segment commit gl-p-5 gl-w-full">
<gl-loading-icon v-if="isLoading" size="md" color="dark" class="m-auto" />
<template v-else-if="commit">
<user-avatar-link
diff --git a/app/assets/javascripts/repository/components/table/row.vue b/app/assets/javascripts/repository/components/table/row.vue
index bd06c064ab7..8fcec5fb893 100644
--- a/app/assets/javascripts/repository/components/table/row.vue
+++ b/app/assets/javascripts/repository/components/table/row.vue
@@ -13,7 +13,7 @@ import {
import { escapeRegExp } from 'lodash';
import paginatedTreeQuery from 'shared_queries/repository/paginated_tree.query.graphql';
import { escapeFileUrl } from '~/lib/utils/url_utility';
-import { TREE_PAGE_SIZE } from '~/repository/constants';
+import { TREE_PAGE_SIZE, ROW_APPEAR_DELAY } from '~/repository/constants';
import FileIcon from '~/vue_shared/components/file_icon.vue';
import TimeagoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
@@ -128,6 +128,7 @@ export default {
return {
commit: null,
hasRowAppeared: false,
+ delayedRowAppear: null,
};
},
computed: {
@@ -202,14 +203,19 @@ export default {
rowAppeared() {
this.hasRowAppeared = true;
+ if (this.commitInfo) {
+ return;
+ }
+
if (this.glFeatures.lazyLoadCommits) {
- this.$emit('row-appear', {
- rowNumber: this.rowNumber,
- hasCommit: Boolean(this.commitInfo),
- });
+ this.delayedRowAppear = setTimeout(
+ () => this.$emit('row-appear', this.rowNumber),
+ ROW_APPEAR_DELAY,
+ );
}
},
rowDisappeared() {
+ clearTimeout(this.delayedRowAppear);
this.hasRowAppeared = false;
},
},
diff --git a/app/assets/javascripts/repository/components/tree_content.vue b/app/assets/javascripts/repository/components/tree_content.vue
index ffe8d5531f8..130ebf77361 100644
--- a/app/assets/javascripts/repository/components/tree_content.vue
+++ b/app/assets/javascripts/repository/components/tree_content.vue
@@ -3,7 +3,12 @@ import paginatedTreeQuery from 'shared_queries/repository/paginated_tree.query.g
import createFlash from '~/flash';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { __ } from '../../locale';
-import { TREE_PAGE_SIZE, TREE_INITIAL_FETCH_COUNT, TREE_PAGE_LIMIT } from '../constants';
+import {
+ TREE_PAGE_SIZE,
+ TREE_INITIAL_FETCH_COUNT,
+ TREE_PAGE_LIMIT,
+ COMMIT_BATCH_SIZE,
+} from '../constants';
import getRefMixin from '../mixins/get_ref';
import projectPathQuery from '../queries/project_path.query.graphql';
import { readmeFile } from '../utils/readme';
@@ -151,11 +156,19 @@ export default {
.concat(data.trees.pageInfo, data.submodules.pageInfo, data.blobs.pageInfo)
.find(({ hasNextPage }) => hasNextPage);
},
- loadCommitData({ rowNumber = 0, hasCommit } = {}) {
- if (!this.glFeatures.lazyLoadCommits || hasCommit || isRequested(rowNumber)) {
+ handleRowAppear(rowNumber) {
+ if (!this.glFeatures.lazyLoadCommits || isRequested(rowNumber)) {
return;
}
+ // Since a user could scroll either up or down, we want to support lazy loading in both directions
+ this.loadCommitData(rowNumber);
+
+ if (rowNumber - COMMIT_BATCH_SIZE >= 0) {
+ this.loadCommitData(rowNumber - COMMIT_BATCH_SIZE);
+ }
+ },
+ loadCommitData(rowNumber) {
loadCommits(this.projectPath, this.path, this.ref, rowNumber)
.then(this.setCommitData)
.catch(() => {});
@@ -182,7 +195,7 @@ export default {
:has-more="hasShowMore"
:commits="commits"
@showMore="handleShowMore"
- @row-appear="loadCommitData"
+ @row-appear="handleRowAppear"
/>
<file-preview v-if="readme" :blob="readme" />
</div>
diff --git a/app/assets/javascripts/repository/components/upload_blob_modal.vue b/app/assets/javascripts/repository/components/upload_blob_modal.vue
index 11e5b5608cb..b56c9ce5247 100644
--- a/app/assets/javascripts/repository/components/upload_blob_modal.vue
+++ b/app/assets/javascripts/repository/components/upload_blob_modal.vue
@@ -24,10 +24,10 @@ import {
} from '../constants';
const PRIMARY_OPTIONS_TEXT = __('Upload file');
-const MODAL_TITLE = __('Upload New File');
+const MODAL_TITLE = __('Upload new file');
const REMOVE_FILE_TEXT = __('Remove file');
const NEW_BRANCH_IN_FORK = __(
- 'A new branch will be created in your fork and a new merge request will be started.',
+ 'GitLab will create a branch in your fork and start a merge request.',
);
const ERROR_MESSAGE = __('Error uploading file. Please try again.');