Commit 8f4850e1 authored by Jacob Schatz's avatar Jacob Schatz

Add file and tab switching.

parent ebec90a0
import Tabs from './repo_tabs'
import Sidebar from './repo_sidebar' import Sidebar from './repo_sidebar'
import Editor from './repo_editor' import Editor from './repo_editor'
import Service from './repo_service' import Service from './repo_service'
...@@ -10,6 +11,7 @@ export default class RepoBundle { ...@@ -10,6 +11,7 @@ export default class RepoBundle {
const url = document.getElementById('ide').dataset.url; const url = document.getElementById('ide').dataset.url;
Store.service = Service; Store.service = Service;
Store.service.url = url; Store.service.url = url;
Store.tabs = new Tabs();
Store.sidebar = new Sidebar(url); Store.sidebar = new Sidebar(url);
Store.editor = new Editor(); Store.editor = new Editor();
Helper.getContent(); Helper.getContent();
......
...@@ -39,16 +39,23 @@ export default class RepoEditor { ...@@ -39,16 +39,23 @@ export default class RepoEditor {
watch: { watch: {
isTree() { isTree() {
if(this.isTree) { if(this.isTree && !this.openedFiles.length) {
self.el.style.display = 'none'; self.el.style.display = 'none';
} else { } else {
self.el.style.display = 'inline-block'; self.el.style.display = 'inline-block';
} }
}, },
blobRaw() { openedFiles() {
if(this.isTree) { if(this.isTree && !this.openedFiles.length) {
self.el.style.display = 'none';
} else { } else {
self.el.style.display = 'inline-block';
}
},
blobRaw() {
if(!this.isTree) {
self.monacoEditor.setModel( self.monacoEditor.setModel(
monaco.editor.createModel( monaco.editor.createModel(
this.blobRaw, this.blobRaw,
......
...@@ -2,13 +2,13 @@ let RepoFile = { ...@@ -2,13 +2,13 @@ let RepoFile = {
template: ` template: `
<tr> <tr>
<td> <td>
<i class='fa' :class='file.icon'></i> <i class='fa' :class='file.icon' :style='{"margin-left": file.level * 10 + "px"}'></i>
<a :href='file.url' @click.prevent='linkClicked(file)'>{{file.name}}</a> <a :href='file.url' @click.prevent='linkClicked(file)' :title='file.url'>{{file.name}}</a>
</td> </td>
<td v-if='isTree'> <td v-if='!isMini'>
<div class='ellipsis'>{{file.lastCommitMessage}}</div> <div class='ellipsis'>{{file.lastCommitMessage}}</div>
</td> </td>
<td v-if='isTree'> <td v-if='!isMini'>
<span>{{file.lastCommitUpdate}}</span> <span>{{file.lastCommitUpdate}}</span>
</td> </td>
</tr> </tr>
...@@ -16,7 +16,8 @@ let RepoFile = { ...@@ -16,7 +16,8 @@ let RepoFile = {
props: { props: {
name: 'repo-file', name: 'repo-file',
file: Object, file: Object,
isTree: Boolean isTree: Boolean,
isMini: Boolean
}, },
methods: { methods: {
......
...@@ -36,8 +36,56 @@ let RepoHelper = { ...@@ -36,8 +36,56 @@ let RepoHelper = {
return split.join('/'); return split.join('/');
}, },
insertNewFilesIntoParentDir(inDirectory, oldList, newList) {
let indexOfFile;
if(!inDirectory) {
return newList;
}
oldList.find((file, i) => {
if(file.url === inDirectory.url){
indexOfFile = i+1;
return true;
}
return false;
});
if(indexOfFile){
// insert new list into old list
newList.forEach((newFile) => {
newFile.level = inDirectory.level + 1;
oldList.splice(indexOfFile, 0, newFile);
});
return oldList;
}
return newList;
},
setActiveFile(file) {
Store.openedFiles = Store.openedFiles.map((openedFile) => {
openedFile.active = file.url === openedFile.url;
return openedFile;
});
Store.blobRaw = file.plain;
this.toURL(file.url);
},
removeFromOpenedFiles(file) {
if(file.type === 'tree') return;
Store.openedFiles = Store.openedFiles.filter((openedFile) => {
return openedFile.url !== file.url;
});
},
addToOpenedFiles(file) {
const openedFilesAlreadyExists = Store.openedFiles.some((openedFile) => {
return openedFile.url === file.url
});
if(!openedFilesAlreadyExists) {
Store.openedFiles.push(file);
}
},
// may be tree or file. // may be tree or file.
getContent() { getContent(file) {
Service.getContent() Service.getContent()
.then((response) => { .then((response) => {
let data = response.data; let data = response.data;
...@@ -47,16 +95,14 @@ let RepoHelper = { ...@@ -47,16 +95,14 @@ let RepoHelper = {
const parentURL = this.blobURLtoParent(Service.url); const parentURL = this.blobURLtoParent(Service.url);
Store.blobRaw = data.plain; Store.blobRaw = data.plain;
Store.prevURL = this.blobURLtoParent(parentURL); Store.prevURL = this.blobURLtoParent(parentURL);
Service.getContent(parentURL) data.url = file.url;
.then((response) => { this.addToOpenedFiles(data);
Store.files = this.dataToListOfFiles(response.data); this.setActiveFile(data);
}) console.log(data);
.catch((response) => {
});
} else { } else {
// it's a tree // it's a tree
Store.files = this.dataToListOfFiles(data); let newDirectory = this.dataToListOfFiles(data);
Store.files = this.insertNewFilesIntoParentDir(file, Store.files, newDirectory);
Store.prevURL = this.blobURLtoParent(Service.url); Store.prevURL = this.blobURLtoParent(Service.url);
} }
}) })
...@@ -80,7 +126,8 @@ let RepoHelper = { ...@@ -80,7 +126,8 @@ let RepoHelper = {
url: blob.url, url: blob.url,
icon: this.toFA(blob.icon), icon: this.toFA(blob.icon),
lastCommitMessage: blob.last_commit.message, lastCommitMessage: blob.last_commit.message,
lastCommitUpdate: blob.last_commit.committed_date lastCommitUpdate: blob.last_commit.committed_date,
level: 0
}) })
}); });
...@@ -89,7 +136,8 @@ let RepoHelper = { ...@@ -89,7 +136,8 @@ let RepoHelper = {
type: 'tree', type: 'tree',
name: tree.name, name: tree.name,
url: tree.url, url: tree.url,
icon: this.toFA(tree.icon) icon: this.toFA(tree.icon),
level: 0
}) })
}); });
...@@ -98,7 +146,8 @@ let RepoHelper = { ...@@ -98,7 +146,8 @@ let RepoHelper = {
type: 'submodule', type: 'submodule',
name: submodule.name, name: submodule.name,
url: submodule.url, url: submodule.url,
icon: this.toFA(submodule.icon) icon: this.toFA(submodule.icon),
level: 0
}) })
}); });
......
import Store from './repo_store'
let RepoMiniMixin = {
computed: {
isMini() {
console.log('checking', Store.openedFiles.length)
return !!Store.openedFiles.length;
}
},
};
export default RepoMiniMixin;
\ No newline at end of file
...@@ -4,6 +4,7 @@ import Vue from 'vue' ...@@ -4,6 +4,7 @@ import Vue from 'vue'
import Store from './repo_store' import Store from './repo_store'
import RepoPreviousDirectory from './repo_prev_directory' import RepoPreviousDirectory from './repo_prev_directory'
import RepoFile from './repo_file' import RepoFile from './repo_file'
import RepoMiniMixin from './repo_mini_mixin'
export default class RepoSidebar { export default class RepoSidebar {
constructor(url) { constructor(url) {
...@@ -16,6 +17,7 @@ export default class RepoSidebar { ...@@ -16,6 +17,7 @@ export default class RepoSidebar {
initVue() { initVue() {
this.vue = new Vue({ this.vue = new Vue({
el: '#sidebar', el: '#sidebar',
mixins: [RepoMiniMixin],
components: { components: {
'repo-previous-directory': RepoPreviousDirectory, 'repo-previous-directory': RepoPreviousDirectory,
'repo-file': RepoFile, 'repo-file': RepoFile,
...@@ -45,8 +47,9 @@ export default class RepoSidebar { ...@@ -45,8 +47,9 @@ export default class RepoSidebar {
url = file.url; url = file.url;
} }
Service.url = url; Service.url = url;
Helper.getContent(); if(typeof file === 'object') {
Helper.toURL(url); Helper.getContent(file);
}
} }
}, },
}); });
......
...@@ -9,7 +9,7 @@ let RepoStore = { ...@@ -9,7 +9,7 @@ let RepoStore = {
submodules: [], submodules: [],
blobRaw: '', blobRaw: '',
blobRendered: '', blobRendered: '',
openedFiles: [],
files: [] files: []
}; };
export default RepoStore; export default RepoStore;
import RepoHelper from './repo_helper'
let RepoTab = {
template: `
<li>
<a href='#' @click.prevent='xClicked(tab)'>
<i class="fa fa-times" :class="{'fa-times':saved, 'dot-circle-o': !saved}"></i>
</a>
<a href='#' :title='tab.url' @click.prevent='tabClicked(tab)'>{{tab.name}}</a>
</li>
`,
props: {
name: 'repo-tab',
tab: Object,
saved: true,
},
methods: {
tabClicked(file) {
RepoHelper.setActiveFile(file);
},
xClicked(file) {
RepoHelper.removeFromOpenedFiles(file);
}
}
};
export default RepoTab;
\ No newline at end of file
import Vue from 'vue';
import Store from './repo_store'
import RepoTab from './repo_tab'
import RepoMiniMixin from './repo_mini_mixin'
export default class RepoTabs {
constructor() {
this.initVue();
}
initVue() {
this.vue = new Vue({
el: '#tabs',
mixins: [RepoMiniMixin],
components: {
'repo-tab': RepoTab,
},
data: () => Store,
});
}
}
\ No newline at end of file
...@@ -26,17 +26,56 @@ header { ...@@ -26,17 +26,56 @@ header {
padding: 10px 15px; padding: 10px 15px;
} }
#ide { .panel-right{
display: inline-block; display: inline-block;
width: 85%; width: 85%;
#tabs {
height: 41px;
border-bottom: 1px solid #f0f0f0;
padding-left: 0;
margin-bottom: 0;
background: $gray-light;
li {
list-style-type: none;
background: $gray-normal;
display: inline-block;
padding: 10px 18px;
border-right: 1px solid $border-color;
&.active {
background: $white-light;
}
a {
color: black;
}
i.fa.fa-times {
float: right;
margin-top: 3px;
margin-left: 15px;
}
}
}
#ide {
height: 70vh;
}
} }
#sidebar { #sidebar {
&.sidebar-mini { &.sidebar-mini {
display: inline-block; display: inline-block;
vertical-align: top; vertical-align: top;
width: 15%; width: 15%;
border-right: 1px solid $white-normal; border-right: 1px solid $white-normal;
height: 75vh;
overflow: auto;
}
a {
color: $almost-black;
} }
ul { ul {
......
...@@ -5,4 +5,4 @@ ...@@ -5,4 +5,4 @@
.nav-block .nav-block
= render 'projects/tree/tree_header', tree: @tree = render 'projects/tree/tree_header', tree: @tree
= render 'projects/tree/tree_content', tree: @tree = render 'projects/tree/tree_content'
...@@ -11,9 +11,4 @@ ...@@ -11,9 +11,4 @@
- else - else
- viewer.prepare! - viewer.prepare!
-# In the rare case where the first kilobyte of the file looks like text, = render 'projects/tree/tree_content'
-# but the file turns out to actually be binary after loading all data,
-# we fall back on the binary Download viewer.
- viewer = BlobViewer::Download.new(viewer.blob) if viewer.binary_detected_after_load?
= render viewer.partial_path, viewer: viewer
.tree-content-holder .tree-content-holder
#sidebar{ ":class" => "{'sidebar-mini' : !isTree}" }< #sidebar{ ":class" => "{'sidebar-mini' : isMini}" }<
%table.table %table.table
%thead{"v-if" => "isTree"} %thead{"v-if" => "!isMini"}
%th{"v-if" => "isTree"} %th{"v-if" => "!isMini"}
Name Name
%th{"v-else"} %th{"v-else" => "1"}
Project Project
%th{"v-if" => "isTree"} %th{"v-if" => "!isMini"}
Last Commit Last Commit
%th{"v-if" => "isTree"} %th{"v-if" => "!isMini"}
Last Update Last Update
%tr{ is: "repo-previous-directory", ":prevurl" => "prevURL", "@linkclicked" => "linkClicked" } %tr{ is: "repo-previous-directory", ":prevurl" => "prevURL", "@linkclicked" => "linkClicked" }
%tr{ is: "repo-file", "v-for" => "file in files", ":key" => "file.id", ":file" => "file","@linkclicked" => "linkClicked(file)", ":is-tree" => "isTree" } %tr{ is: "repo-file", "v-for" => "file in files", ":key" => "file.id", ":file" => "file",":is-mini" => "isMini", "@linkclicked" => "linkClicked(file)", ":is-tree" => "isTree" }
#ide{ data: { url: repo_url }, style: "height:400px;" }> .panel-right>
%ul#tabs{"v-if" => "isMini"}
%li{ is: "repo-tab", "v-for" => "tab in openedFiles", ":key" => "tab.id", ":tab" => "tab", ":class" => "{'active' : tab.active}" }
#ide{ data: { url: repo_url } }
- if can_edit_tree? - if can_edit_tree?
= render 'projects/blob/upload', title: _('Upload New File'), placeholder: _('Upload New File'), button_title: _('Upload file'), form_path: namespace_project_create_blob_path(@project.namespace, @project, @id), method: :post = render 'projects/blob/upload', title: _('Upload New File'), placeholder: _('Upload New File'), button_title: _('Upload file'), form_path: namespace_project_create_blob_path(@project.namespace, @project, @id), method: :post
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment