summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/ide
diff options
context:
space:
mode:
authorPhil Hughes <me@iamphill.com>2018-09-17 12:17:00 +0100
committerPhil Hughes <me@iamphill.com>2018-09-17 12:17:00 +0100
commit163ec966c18b88270223b2456f5ef9570b9cdda8 (patch)
treef0865deab9d4546ffed425ef66a33cabd1e3cfca /app/assets/javascripts/ide
parent4945b8bf7d7374d6c566b0eadd3f8ea4ef0d8f60 (diff)
downloadgitlab-ce-163ec966c18b88270223b2456f5ef9570b9cdda8.tar.gz
Decouple file row from IDE
This makes the file row component re-usable ouside of the Web IDE Pre-request for https://gitlab.com/gitlab-org/gitlab-ce/issues/14249
Diffstat (limited to 'app/assets/javascripts/ide')
-rw-r--r--app/assets/javascripts/ide/components/file_row_extra.vue104
-rw-r--r--app/assets/javascripts/ide/components/ide_tree_list.vue12
-rw-r--r--app/assets/javascripts/ide/components/repo_file.vue227
3 files changed, 112 insertions, 231 deletions
diff --git a/app/assets/javascripts/ide/components/file_row_extra.vue b/app/assets/javascripts/ide/components/file_row_extra.vue
new file mode 100644
index 00000000000..44a360ab909
--- /dev/null
+++ b/app/assets/javascripts/ide/components/file_row_extra.vue
@@ -0,0 +1,104 @@
+<script>
+import { mapGetters } from 'vuex';
+import { n__, __, sprintf } from '~/locale';
+import tooltip from '~/vue_shared/directives/tooltip';
+import Icon from '~/vue_shared/components/icon.vue';
+import NewDropdown from './new_dropdown/index.vue';
+import ChangedFileIcon from './changed_file_icon.vue';
+import MrFileIcon from './mr_file_icon.vue';
+
+export default {
+ name: 'FileRowExtra',
+ directives: {
+ tooltip,
+ },
+ components: {
+ Icon,
+ NewDropdown,
+ ChangedFileIcon,
+ MrFileIcon,
+ },
+ props: {
+ file: {
+ type: Object,
+ required: true,
+ },
+ mouseOver: {
+ type: Boolean,
+ required: true,
+ },
+ },
+ computed: {
+ ...mapGetters([
+ 'getChangesInFolder',
+ 'getUnstagedFilesCountForPath',
+ 'getStagedFilesCountForPath',
+ ]),
+ folderUnstagedCount() {
+ return this.getUnstagedFilesCountForPath(this.file.path);
+ },
+ folderStagedCount() {
+ return this.getStagedFilesCountForPath(this.file.path);
+ },
+ changesCount() {
+ return this.getChangesInFolder(this.file.path);
+ },
+ folderChangesTooltip() {
+ if (this.changesCount === 0) return undefined;
+
+ if (this.folderUnstagedCount > 0 && this.folderStagedCount === 0) {
+ return n__('%d unstaged change', '%d unstaged changes', this.folderUnstagedCount);
+ } else if (this.folderUnstagedCount === 0 && this.folderStagedCount > 0) {
+ return n__('%d staged change', '%d staged changes', this.folderStagedCount);
+ }
+
+ return sprintf(__('%{unstaged} unstaged and %{staged} staged changes'), {
+ unstaged: this.folderUnstagedCount,
+ staged: this.folderStagedCount,
+ });
+ },
+ showTreeChangesCount() {
+ return this.file.type === 'tree' && this.changesCount > 0 && !this.file.opened;
+ },
+ showChangedFileIcon() {
+ return this.file.changed || this.file.tempFile || this.file.staged;
+ },
+ },
+};
+</script>
+
+<template>
+ <div class="float-right ide-file-icon-holder">
+ <mr-file-icon
+ v-if="file.mrChange"
+ />
+ <span
+ v-if="showTreeChangesCount"
+ class="ide-tree-changes"
+ >
+ {{ changesCount }}
+ <icon
+ v-tooltip
+ :title="folderChangesTooltip"
+ :size="12"
+ data-container="body"
+ data-placement="right"
+ name="file-modified"
+ css-classes="prepend-left-5 ide-file-modified"
+ />
+ </span>
+ <changed-file-icon
+ v-else-if="showChangedFileIcon"
+ :file="file"
+ :show-tooltip="true"
+ :show-staged-icon="true"
+ :force-modified-icon="true"
+ />
+ <new-dropdown
+ :type="file.type"
+ :path="file.path"
+ :mouse-over="mouseOver"
+ class="prepend-left-8"
+ />
+ </div>
+</template>
diff --git a/app/assets/javascripts/ide/components/ide_tree_list.vue b/app/assets/javascripts/ide/components/ide_tree_list.vue
index 00ae5ea2c15..e658d1bf956 100644
--- a/app/assets/javascripts/ide/components/ide_tree_list.vue
+++ b/app/assets/javascripts/ide/components/ide_tree_list.vue
@@ -2,15 +2,16 @@
import { mapActions, mapGetters, mapState } from 'vuex';
import Icon from '~/vue_shared/components/icon.vue';
import SkeletonLoadingContainer from '~/vue_shared/components/skeleton_loading_container.vue';
-import RepoFile from './repo_file.vue';
+import FileRow from '~/vue_shared/components/file_row.vue';
import NavDropdown from './nav_dropdown.vue';
+import FileRowExtra from './file_row_extra.vue';
export default {
components: {
Icon,
- RepoFile,
SkeletonLoadingContainer,
NavDropdown,
+ FileRow,
},
props: {
viewerType: {
@@ -34,8 +35,9 @@ export default {
this.updateViewer(this.viewerType);
},
methods: {
- ...mapActions(['updateViewer']),
+ ...mapActions(['updateViewer', 'toggleTreeOpen']),
},
+ FileRowExtra,
};
</script>
@@ -63,11 +65,13 @@ export default {
<div
class="ide-tree-body h-100"
>
- <repo-file
+ <file-row
v-for="file in currentTree.tree"
:key="file.key"
:file="file"
:level="0"
+ :extra-component="$options.FileRowExtra"
+ @toggleTreeOpen="toggleTreeOpen"
/>
</div>
</template>
diff --git a/app/assets/javascripts/ide/components/repo_file.vue b/app/assets/javascripts/ide/components/repo_file.vue
deleted file mode 100644
index 110eda83bb4..00000000000
--- a/app/assets/javascripts/ide/components/repo_file.vue
+++ /dev/null
@@ -1,227 +0,0 @@
-<script>
-import { mapActions, mapGetters } from 'vuex';
-import { n__, __, sprintf } from '~/locale';
-import tooltip from '~/vue_shared/directives/tooltip';
-import SkeletonLoadingContainer from '~/vue_shared/components/skeleton_loading_container.vue';
-import Icon from '~/vue_shared/components/icon.vue';
-import FileIcon from '~/vue_shared/components/file_icon.vue';
-import router from '../ide_router';
-import NewDropdown from './new_dropdown/index.vue';
-import FileStatusIcon from './repo_file_status_icon.vue';
-import ChangedFileIcon from './changed_file_icon.vue';
-import MrFileIcon from './mr_file_icon.vue';
-
-export default {
- name: 'RepoFile',
- directives: {
- tooltip,
- },
- components: {
- SkeletonLoadingContainer,
- NewDropdown,
- FileStatusIcon,
- FileIcon,
- ChangedFileIcon,
- MrFileIcon,
- Icon,
- },
- props: {
- file: {
- type: Object,
- required: true,
- },
- level: {
- type: Number,
- required: true,
- },
- },
- data() {
- return {
- mouseOver: false,
- };
- },
- computed: {
- ...mapGetters([
- 'getChangesInFolder',
- 'getUnstagedFilesCountForPath',
- 'getStagedFilesCountForPath',
- ]),
- folderUnstagedCount() {
- return this.getUnstagedFilesCountForPath(this.file.path);
- },
- folderStagedCount() {
- return this.getStagedFilesCountForPath(this.file.path);
- },
- changesCount() {
- return this.getChangesInFolder(this.file.path);
- },
- folderChangesTooltip() {
- if (this.changesCount === 0) return undefined;
-
- if (this.folderUnstagedCount > 0 && this.folderStagedCount === 0) {
- return n__('%d unstaged change', '%d unstaged changes', this.folderUnstagedCount);
- } else if (this.folderUnstagedCount === 0 && this.folderStagedCount > 0) {
- return n__('%d staged change', '%d staged changes', this.folderStagedCount);
- }
-
- return sprintf(__('%{unstaged} unstaged and %{staged} staged changes'), {
- unstaged: this.folderUnstagedCount,
- staged: this.folderStagedCount,
- });
- },
- isTree() {
- return this.file.type === 'tree';
- },
- isBlob() {
- return this.file.type === 'blob';
- },
- levelIndentation() {
- return {
- marginLeft: `${this.level * 16}px`,
- };
- },
- fileClass() {
- return {
- 'file-open': this.isBlob && this.file.opened,
- 'file-active': this.isBlob && this.file.active,
- folder: this.isTree,
- 'is-open': this.file.opened,
- };
- },
- showTreeChangesCount() {
- return this.isTree && this.changesCount > 0 && !this.file.opened;
- },
- showChangedFileIcon() {
- return this.file.changed || this.file.tempFile || this.file.staged;
- },
- },
- watch: {
- 'file.active': function fileActiveWatch(active) {
- if (this.file.type === 'blob' && active) {
- this.scrollIntoView();
- }
- },
- },
- mounted() {
- if (this.hasPathAtCurrentRoute()) {
- this.scrollIntoView(true);
- }
- },
- methods: {
- ...mapActions(['toggleTreeOpen']),
- clickFile() {
- // Manual Action if a tree is selected/opened
- if (this.isTree && this.hasUrlAtCurrentRoute()) {
- this.toggleTreeOpen(this.file.path);
- }
-
- router.push(`/project${this.file.url}`);
- },
- scrollIntoView(isInit = false) {
- const block = isInit && this.isTree ? 'center' : 'nearest';
-
- this.$el.scrollIntoView({
- behavior: 'smooth',
- block,
- });
- },
- hasPathAtCurrentRoute() {
- if (!this.$router || !this.$router.currentRoute) {
- return false;
- }
-
- // - strip route up to "/-/" and ending "/"
- const routePath = this.$router.currentRoute.path
- .replace(/^.*?[/]-[/]/g, '')
- .replace(/[/]$/g, '');
-
- // - strip ending "/"
- const filePath = this.file.path.replace(/[/]$/g, '');
-
- return filePath === routePath;
- },
- hasUrlAtCurrentRoute() {
- return this.$router.currentRoute.path === `/project${this.file.url}`;
- },
- toggleHover(over) {
- this.mouseOver = over;
- },
- },
-};
-</script>
-
-<template>
- <div>
- <div
- :class="fileClass"
- class="file"
- role="button"
- @click="clickFile"
- @mouseover="toggleHover(true)"
- @mouseout="toggleHover(false)"
- >
- <div
- class="file-name"
- >
- <span
- :style="levelIndentation"
- class="ide-file-name str-truncated"
- >
- <file-icon
- :file-name="file.name"
- :loading="file.loading"
- :folder="isTree"
- :opened="file.opened"
- :size="16"
- />
- {{ file.name }}
- <file-status-icon
- :file="file"
- />
- </span>
- <span class="float-right ide-file-icon-holder">
- <mr-file-icon
- v-if="file.mrChange"
- />
- <span
- v-if="showTreeChangesCount"
- class="ide-tree-changes"
- >
- {{ changesCount }}
- <icon
- v-tooltip
- :title="folderChangesTooltip"
- :size="12"
- data-container="body"
- data-placement="right"
- name="file-modified"
- css-classes="prepend-left-5 ide-file-modified"
- />
- </span>
- <changed-file-icon
- v-else-if="showChangedFileIcon"
- :file="file"
- :show-tooltip="true"
- :show-staged-icon="true"
- :force-modified-icon="true"
- class="float-right"
- />
- </span>
- <new-dropdown
- :type="file.type"
- :path="file.path"
- :mouse-over="mouseOver"
- class="float-right prepend-left-8"
- />
- </div>
- </div>
- <template v-if="file.opened">
- <repo-file
- v-for="childFile in file.tree"
- :key="childFile.key"
- :file="childFile"
- :level="level + 1"
- />
- </template>
- </div>
-</template>