debian-mirror-gitlab/app/assets/javascripts/repository/components/breadcrumbs.vue

260 lines
6.3 KiB
Vue
Raw Normal View History

2019-09-04 21:01:54 +05:30
<script>
2019-09-30 21:07:59 +05:30
import { GlDropdown, GlDropdownDivider, GlDropdownHeader, GlDropdownItem } from '@gitlab/ui';
2020-04-22 19:07:51 +05:30
import { joinPaths, escapeFileUrl } from '~/lib/utils/url_utility';
2019-09-30 21:07:59 +05:30
import { __ } from '../../locale';
import Icon from '../../vue_shared/components/icon.vue';
2019-09-04 21:01:54 +05:30
import getRefMixin from '../mixins/get_ref';
2019-09-30 21:07:59 +05:30
import getProjectShortPath from '../queries/getProjectShortPath.query.graphql';
import getProjectPath from '../queries/getProjectPath.query.graphql';
import getPermissions from '../queries/getPermissions.query.graphql';
const ROW_TYPES = {
header: 'header',
divider: 'divider',
};
2019-09-04 21:01:54 +05:30
export default {
2019-09-30 21:07:59 +05:30
components: {
GlDropdown,
GlDropdownDivider,
GlDropdownHeader,
GlDropdownItem,
Icon,
},
2019-09-04 21:01:54 +05:30
apollo: {
projectShortPath: {
query: getProjectShortPath,
},
2019-09-30 21:07:59 +05:30
projectPath: {
query: getProjectPath,
},
userPermissions: {
query: getPermissions,
variables() {
return {
projectPath: this.projectPath,
};
},
2020-03-13 15:44:24 +05:30
update: data => data.project?.userPermissions,
error(error) {
throw error;
},
2019-09-30 21:07:59 +05:30
},
2019-09-04 21:01:54 +05:30
},
mixins: [getRefMixin],
props: {
currentPath: {
type: String,
required: false,
2020-03-13 15:44:24 +05:30
default: '',
2019-09-04 21:01:54 +05:30
},
2019-09-30 21:07:59 +05:30
canCollaborate: {
type: Boolean,
required: false,
default: false,
},
canEditTree: {
type: Boolean,
required: false,
default: false,
},
newBranchPath: {
type: String,
required: false,
default: null,
},
newTagPath: {
type: String,
required: false,
default: null,
},
newBlobPath: {
type: String,
required: false,
default: null,
},
forkNewBlobPath: {
type: String,
required: false,
default: null,
},
forkNewDirectoryPath: {
type: String,
required: false,
default: null,
},
forkUploadBlobPath: {
type: String,
required: false,
default: null,
},
2019-09-04 21:01:54 +05:30
},
data() {
return {
projectShortPath: '',
2019-09-30 21:07:59 +05:30
projectPath: '',
userPermissions: {},
2019-09-04 21:01:54 +05:30
};
},
computed: {
pathLinks() {
return this.currentPath
.split('/')
.filter(p => p !== '')
.reduce(
(acc, name, i) => {
2020-04-22 19:07:51 +05:30
const path = joinPaths(i > 0 ? acc[i].path : '', escapeFileUrl(name));
2019-09-04 21:01:54 +05:30
return acc.concat({
name,
path,
2020-04-22 19:07:51 +05:30
to: `/-/tree/${joinPaths(escapeFileUrl(this.ref), path)}`,
2019-09-04 21:01:54 +05:30
});
},
2020-03-13 15:44:24 +05:30
[
{
name: this.projectShortPath,
path: '/',
2020-04-22 19:07:51 +05:30
to: `/-/tree/${escapeFileUrl(this.ref)}/`,
2020-03-13 15:44:24 +05:30
},
],
2019-09-30 21:07:59 +05:30
);
},
canCreateMrFromFork() {
return this.userPermissions.forkProject && this.userPermissions.createMergeRequestIn;
},
dropdownItems() {
const items = [];
if (this.canEditTree) {
items.push(
{
type: ROW_TYPES.header,
text: __('This directory'),
},
{
attrs: {
2020-04-22 19:07:51 +05:30
href: `${this.newBlobPath}/${
this.currentPath ? encodeURIComponent(this.currentPath) : ''
}`,
2019-09-30 21:07:59 +05:30
class: 'qa-new-file-option',
},
text: __('New file'),
},
{
attrs: {
href: '#modal-upload-blob',
'data-target': '#modal-upload-blob',
'data-toggle': 'modal',
},
text: __('Upload file'),
},
{
attrs: {
href: '#modal-create-new-dir',
'data-target': '#modal-create-new-dir',
'data-toggle': 'modal',
},
text: __('New directory'),
},
);
} else if (this.canCreateMrFromFork) {
items.push(
{
attrs: {
href: this.forkNewBlobPath,
'data-method': 'post',
},
text: __('New file'),
},
{
attrs: {
href: this.forkUploadBlobPath,
'data-method': 'post',
},
text: __('Upload file'),
},
{
attrs: {
href: this.forkNewDirectoryPath,
'data-method': 'post',
},
text: __('New directory'),
},
);
}
2020-03-13 15:44:24 +05:30
if (this.userPermissions?.pushCode) {
2019-09-30 21:07:59 +05:30
items.push(
{
type: ROW_TYPES.divider,
},
{
type: ROW_TYPES.header,
text: __('This repository'),
},
{
attrs: {
href: this.newBranchPath,
},
text: __('New branch'),
},
{
attrs: {
href: this.newTagPath,
},
text: __('New tag'),
},
2019-09-04 21:01:54 +05:30
);
2019-09-30 21:07:59 +05:30
}
return items;
},
renderAddToTreeDropdown() {
return this.canCollaborate || this.canCreateMrFromFork;
2019-09-04 21:01:54 +05:30
},
},
methods: {
isLast(i) {
return i === this.pathLinks.length - 1;
},
2019-09-30 21:07:59 +05:30
getComponent(type) {
switch (type) {
case ROW_TYPES.divider:
return 'gl-dropdown-divider';
case ROW_TYPES.header:
return 'gl-dropdown-header';
default:
return 'gl-dropdown-item';
}
},
2019-09-04 21:01:54 +05:30
},
};
</script>
<template>
<nav :aria-label="__('Files breadcrumb')">
<ol class="breadcrumb repo-breadcrumb">
<li v-for="(link, i) in pathLinks" :key="i" class="breadcrumb-item">
<router-link :to="link.to" :aria-current="isLast(i) ? 'page' : null">
{{ link.name }}
</router-link>
</li>
2019-09-30 21:07:59 +05:30
<li v-if="renderAddToTreeDropdown" class="breadcrumb-item">
<gl-dropdown toggle-class="add-to-tree qa-add-to-tree ml-1">
<template slot="button-content">
<span class="sr-only">{{ __('Add to tree') }}</span>
<icon name="plus" :size="16" class="float-left" />
2020-03-13 15:44:24 +05:30
<icon name="chevron-down" :size="16" class="float-left" />
2019-09-30 21:07:59 +05:30
</template>
<template v-for="(item, i) in dropdownItems">
<component :is="getComponent(item.type)" :key="i" v-bind="item.attrs">
{{ item.text }}
</component>
</template>
</gl-dropdown>
</li>
2019-09-04 21:01:54 +05:30
</ol>
</nav>
</template>