diff options
-rw-r--r-- | app/css/style.css | 4 | ||||
-rw-r--r-- | app/index.html | 31 | ||||
-rw-r--r-- | app/js/app.js | 51 |
3 files changed, 73 insertions, 13 deletions
diff --git a/app/css/style.css b/app/css/style.css index c75e038..b7e5742 100644 --- a/app/css/style.css +++ b/app/css/style.css | |||
@@ -29,3 +29,7 @@ pre { | |||
29 | [v-cloak] { | 29 | [v-cloak] { |
30 | display: none; | 30 | display: none; |
31 | } | 31 | } |
32 | |||
33 | .hand { | ||
34 | cursor: hand; | ||
35 | } \ No newline at end of file | ||
diff --git a/app/index.html b/app/index.html index 5807724..773b5cf 100644 --- a/app/index.html +++ b/app/index.html | |||
@@ -2,6 +2,7 @@ | |||
2 | <head> | 2 | <head> |
3 | <title> Cloudron Surfer </title> | 3 | <title> Cloudron Surfer </title> |
4 | 4 | ||
5 | <link rel="stylesheet" href="/admin/css/font-awesome.min.css"> | ||
5 | <link rel="stylesheet" href="/admin/css/bootstrap.min.css"> | 6 | <link rel="stylesheet" href="/admin/css/bootstrap.min.css"> |
6 | <link rel="stylesheet" href="/admin/css/style.css"> | 7 | <link rel="stylesheet" href="/admin/css/style.css"> |
7 | 8 | ||
@@ -63,27 +64,39 @@ | |||
63 | <div class="row"> | 64 | <div class="row"> |
64 | <div class="col-lg-12"> | 65 | <div class="col-lg-12"> |
65 | <ol class="breadcrumb"> | 66 | <ol class="breadcrumb"> |
66 | <li><a href="#">Home</a></li> | 67 | <li><i class="fa fa-home"></i> </li> |
67 | <li><a href="#">Library</a></li> | 68 | <li v-for="part in pathParts"> |
68 | <li class="active">Data</li> | 69 | {{ part }} |
70 | </li> | ||
69 | </ol> | 71 | </ol> |
70 | </div> | 72 | </div> |
71 | <div class="col-lg-12"> | 73 | <div class="col-lg-12"> |
72 | <table class="table table-hover"> | 74 | <table class="table table-hover table-condensed"> |
73 | <thead> | 75 | <thead> |
74 | <tr> | 76 | <tr> |
75 | <th>Type</th> | 77 | <th>Type</th> |
76 | <th>Name</th> | 78 | <th>Name</th> |
77 | <th>Size</th> | 79 | <th>Size</th> |
78 | <th>Modified</th> | 80 | <th>Modified</th> |
81 | <th style="text-align: right;">Action</th> | ||
79 | </tr> | 82 | </tr> |
80 | </thead> | 83 | </thead> |
81 | <tbody> | 84 | <tbody> |
82 | <tr> | 85 | <tr v-show="path !== '/'" v-on:click="up()" class="hand"> |
83 | <th>Type</th> | 86 | <th><i class="fa fa-chevron-up"></i></th> |
84 | <th>Name</th> | 87 | <th>..</th> |
85 | <th>Size</th> | 88 | <th></th> |
86 | <th>Modified</th> | 89 | <th></th> |
90 | </tr> | ||
91 | <tr v-for="entry in entries" v-on:click="open(entry)" class="hand"> | ||
92 | <th> | ||
93 | <i class="fa fa-folder-o" v-show="entry.isDirectory"></i> | ||
94 | <i class="fa fa-file-o" v-show="entry.isFile"></i> | ||
95 | </th> | ||
96 | <th>{{ entry.filePath }}</th> | ||
97 | <th>{{ entry.size }}</th> | ||
98 | <th>{{ entry.mtime }}</th> | ||
99 | <th style="text-align: right;"><button class="btn btn-sm btn-danger"><i class="fa fa-trash"></i></button></th> | ||
87 | </tr> | 100 | </tr> |
88 | </tbody> | 101 | </tbody> |
89 | </table> | 102 | </table> |
diff --git a/app/js/app.js b/app/js/app.js index 55153d4..10a489c 100644 --- a/app/js/app.js +++ b/app/js/app.js | |||
@@ -20,6 +20,8 @@ function login(username, password) { | |||
20 | // clearly not the best option | 20 | // clearly not the best option |
21 | localStorage.username = username; | 21 | localStorage.username = username; |
22 | localStorage.password = password; | 22 | localStorage.password = password; |
23 | |||
24 | loadDirectory(app.path); | ||
23 | }); | 25 | }); |
24 | } | 26 | } |
25 | 27 | ||
@@ -32,20 +34,61 @@ function logout() { | |||
32 | delete localStorage.password; | 34 | delete localStorage.password; |
33 | } | 35 | } |
34 | 36 | ||
37 | function sanitize(filePath) { | ||
38 | filePath = '/' + filePath; | ||
39 | return filePath.replace(/\/+/g, '/'); | ||
40 | } | ||
41 | |||
42 | function loadDirectory(filePath) { | ||
43 | app.busy = true; | ||
44 | |||
45 | filePath = filePath ? sanitize(filePath) : '/'; | ||
46 | |||
47 | console.log(filePath); | ||
48 | |||
49 | superagent.get('/api/files/' + filePath).query({ username: app.session.username, password: app.session.password }).end(function (error, result) { | ||
50 | app.busy = false; | ||
51 | |||
52 | if (error) return console.error(error); | ||
53 | if (result.statusCode === 401) return logout(); | ||
54 | |||
55 | app.entries = result.body.entries; | ||
56 | app.path = filePath; | ||
57 | app.pathParts = filePath.split('/').filter(function (e) { return !!e; }); | ||
58 | console.log(app.pathParts) | ||
59 | }); | ||
60 | } | ||
61 | |||
62 | function open(entry) { | ||
63 | var path = sanitize(app.path + '/' + entry.filePath); | ||
64 | |||
65 | if (entry.isDirectory) return loadDirectory(path); | ||
66 | |||
67 | window.location.href = window.location.origin + path; | ||
68 | } | ||
69 | |||
70 | function up() { | ||
71 | loadDirectory(app.path.split('/').slice(0, -1).filter(function (p) { return !!p; }).join('/')); | ||
72 | } | ||
73 | |||
35 | var app = new Vue({ | 74 | var app = new Vue({ |
36 | el: '#app', | 75 | el: '#app', |
37 | data: { | 76 | data: { |
38 | busy: true, | 77 | busy: true, |
78 | path: '/', | ||
79 | pathParts: [], | ||
39 | session: { | 80 | session: { |
40 | valid: false | 81 | valid: false |
41 | }, | 82 | }, |
42 | loginData: { | 83 | loginData: {}, |
43 | 84 | entries: [] | |
44 | } | ||
45 | }, | 85 | }, |
46 | methods: { | 86 | methods: { |
47 | login: login, | 87 | login: login, |
48 | logout: logout | 88 | logout: logout, |
89 | loadDirectory: loadDirectory, | ||
90 | open: open, | ||
91 | up: up | ||
49 | } | 92 | } |
50 | }); | 93 | }); |
51 | 94 | ||