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/repository/components')
-rw-r--r--app/assets/javascripts/repository/components/blob_viewers/index.js2
-rw-r--r--app/assets/javascripts/repository/components/blob_viewers/notebook_viewer.vue31
-rw-r--r--app/assets/javascripts/repository/components/blob_viewers/openapi_viewer.vue24
-rw-r--r--app/assets/javascripts/repository/components/fork_info.vue146
-rw-r--r--app/assets/javascripts/repository/components/tree_content.vue17
5 files changed, 217 insertions, 3 deletions
diff --git a/app/assets/javascripts/repository/components/blob_viewers/index.js b/app/assets/javascripts/repository/components/blob_viewers/index.js
index 3e6d2e675ed..a480710f8ac 100644
--- a/app/assets/javascripts/repository/components/blob_viewers/index.js
+++ b/app/assets/javascripts/repository/components/blob_viewers/index.js
@@ -10,6 +10,8 @@ const viewers = {
audio: () => import('./audio_viewer.vue'),
svg: () => import('./image_viewer.vue'),
sketch: () => import('./sketch_viewer.vue'),
+ notebook: () => import('./notebook_viewer.vue'),
+ openapi: () => import('./openapi_viewer.vue'),
};
export const loadViewer = (type, isUsingLfs) => {
diff --git a/app/assets/javascripts/repository/components/blob_viewers/notebook_viewer.vue b/app/assets/javascripts/repository/components/blob_viewers/notebook_viewer.vue
new file mode 100644
index 00000000000..1114a0942ec
--- /dev/null
+++ b/app/assets/javascripts/repository/components/blob_viewers/notebook_viewer.vue
@@ -0,0 +1,31 @@
+<script>
+import { GlLoadingIcon } from '@gitlab/ui';
+import notebookLoader from '~/blob/notebook';
+import { stripPathTail } from '~/lib/utils/url_utility';
+
+export default {
+ components: {
+ GlLoadingIcon,
+ },
+ props: {
+ blob: {
+ type: Object,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ url: this.blob.rawPath,
+ };
+ },
+ mounted() {
+ notebookLoader({ el: this.$refs.viewer, relativeRawPath: stripPathTail(this.url) });
+ },
+};
+</script>
+
+<template>
+ <div ref="viewer" :data-endpoint="url" data-testid="notebook">
+ <gl-loading-icon class="gl-my-4" size="lg" />
+ </div>
+</template>
diff --git a/app/assets/javascripts/repository/components/blob_viewers/openapi_viewer.vue b/app/assets/javascripts/repository/components/blob_viewers/openapi_viewer.vue
new file mode 100644
index 00000000000..5665e4b0ec4
--- /dev/null
+++ b/app/assets/javascripts/repository/components/blob_viewers/openapi_viewer.vue
@@ -0,0 +1,24 @@
+<script>
+import renderOpenApi from '~/blob/openapi';
+
+export default {
+ props: {
+ blob: {
+ type: Object,
+ required: true,
+ },
+ },
+ data() {
+ return {
+ url: this.blob.rawPath,
+ };
+ },
+ mounted() {
+ renderOpenApi(this.$refs.viewer);
+ },
+};
+</script>
+
+<template>
+ <div ref="viewer" class="file-content" :data-endpoint="url" data-testid="openapi"></div>
+</template>
diff --git a/app/assets/javascripts/repository/components/fork_info.vue b/app/assets/javascripts/repository/components/fork_info.vue
new file mode 100644
index 00000000000..980fa140eb5
--- /dev/null
+++ b/app/assets/javascripts/repository/components/fork_info.vue
@@ -0,0 +1,146 @@
+<script>
+import { GlIcon, GlLink, GlSkeletonLoader } from '@gitlab/ui';
+import { s__, sprintf, n__ } from '~/locale';
+import { createAlert } from '~/flash';
+import forkDetailsQuery from '../queries/fork_details.query.graphql';
+
+export const i18n = {
+ forkedFrom: s__('ForkedFromProjectPath|Forked from'),
+ inaccessibleProject: s__('ForkedFromProjectPath|Forked from an inaccessible project.'),
+ upToDate: s__('ForksDivergence|Up to date with the upstream repository.'),
+ unknown: s__('ForksDivergence|This fork has diverged from the upstream repository.'),
+ behind: s__('ForksDivergence|%{behind} %{commit_word} behind'),
+ ahead: s__('ForksDivergence|%{ahead} %{commit_word} ahead of'),
+ behindAndAhead: s__('ForksDivergence|%{messages} the upstream repository.'),
+ error: s__('ForksDivergence|Failed to fetch fork details. Try again later.'),
+};
+
+export default {
+ i18n,
+ components: {
+ GlIcon,
+ GlLink,
+ GlSkeletonLoader,
+ },
+ apollo: {
+ project: {
+ query: forkDetailsQuery,
+ variables() {
+ return {
+ projectPath: this.projectPath,
+ ref: this.selectedRef,
+ };
+ },
+ skip() {
+ return !this.sourceName;
+ },
+ error(error) {
+ createAlert({
+ message: this.$options.i18n.error,
+ captureError: true,
+ error,
+ });
+ },
+ },
+ },
+ props: {
+ projectPath: {
+ type: String,
+ required: true,
+ },
+ selectedRef: {
+ type: String,
+ required: true,
+ },
+ sourceName: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ sourcePath: {
+ type: String,
+ required: false,
+ default: '',
+ },
+ },
+ data() {
+ return {
+ project: {
+ forkDetails: {
+ ahead: null,
+ behind: null,
+ },
+ },
+ };
+ },
+ computed: {
+ isLoading() {
+ return this.$apollo.queries.project.loading;
+ },
+ ahead() {
+ return this.project?.forkDetails?.ahead;
+ },
+ behind() {
+ return this.project?.forkDetails?.behind;
+ },
+ behindText() {
+ return sprintf(this.$options.i18n.behind, {
+ behind: this.behind,
+ commit_word: n__('commit', 'commits', this.behind),
+ });
+ },
+ aheadText() {
+ return sprintf(this.$options.i18n.ahead, {
+ ahead: this.ahead,
+ commit_word: n__('commit', 'commits', this.ahead),
+ });
+ },
+ isUnknownDivergence() {
+ return (!this.ahead && this.ahead !== 0) || (!this.behind && this.behind !== 0);
+ },
+ behindAheadMessage() {
+ const messages = [];
+ if (this.behind > 0) {
+ messages.push(this.behindText);
+ }
+ if (this.ahead > 0) {
+ messages.push(this.aheadText);
+ }
+ return messages.join(', ');
+ },
+ hasBehindAheadMessage() {
+ return this.behindAheadMessage.length > 0;
+ },
+ forkDivergenceMessage() {
+ if (this.isUnknownDivergence) {
+ return this.$options.i18n.unknown;
+ }
+ if (this.hasBehindAheadMessage) {
+ return sprintf(this.$options.i18n.behindAndAhead, {
+ messages: this.behindAheadMessage,
+ });
+ }
+ return this.$options.i18n.upToDate;
+ },
+ },
+};
+</script>
+
+<template>
+ <div class="info-well gl-sm-display-flex gl-flex-direction-column">
+ <div class="well-segment gl-p-5 gl-w-full gl-display-flex">
+ <gl-icon name="fork" :size="16" class="gl-display-block gl-m-4 gl-text-center" />
+ <div v-if="sourceName">
+ {{ $options.i18n.forkedFrom }}
+ <gl-link data-qa-selector="forked_from_link" :href="sourcePath">{{ sourceName }}</gl-link>
+ <gl-skeleton-loader v-if="isLoading" :lines="1" />
+ <div v-else class="gl-text-secondary">
+ {{ forkDivergenceMessage }}
+ </div>
+ </div>
+ <div v-else data-testid="inaccessible-project" class="gl-align-items-center gl-display-flex">
+ {{ $options.i18n.inaccessibleProject }}
+ </div>
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/repository/components/tree_content.vue b/app/assets/javascripts/repository/components/tree_content.vue
index 4a8f83458f4..f6d6004ba96 100644
--- a/app/assets/javascripts/repository/components/tree_content.vue
+++ b/app/assets/javascripts/repository/components/tree_content.vue
@@ -2,12 +2,13 @@
import paginatedTreeQuery from 'shared_queries/repository/paginated_tree.query.graphql';
import { createAlert } 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,
COMMIT_BATCH_SIZE,
+ GITALY_UNAVAILABLE_CODE,
+ i18n,
} from '../constants';
import getRefMixin from '../mixins/get_ref';
import projectPathQuery from '../queries/project_path.query.graphql';
@@ -17,6 +18,7 @@ import FilePreview from './preview/index.vue';
import FileTable from './table/index.vue';
export default {
+ i18n,
components: {
FileTable,
FilePreview,
@@ -142,10 +144,19 @@ export default {
}
})
.catch((error) => {
+ let gitalyUnavailableError;
+ if (error.graphQLErrors) {
+ gitalyUnavailableError = error.graphQLErrors.find(
+ (e) => e?.extensions?.code === GITALY_UNAVAILABLE_CODE,
+ );
+ }
+ const message = gitalyUnavailableError
+ ? this.$options.i18n.gitalyError
+ : this.$options.i18n.generalError;
createAlert({
- message: __('An error occurred while fetching folder content.'),
+ message,
+ captureError: true,
});
- throw error;
});
},
normalizeData(key, data) {