diff --git a/src/main.js b/src/main.js
index 3b7cec98f..dbcea092a 100644
--- a/src/main.js
+++ b/src/main.js
@@ -17,8 +17,8 @@ import Viewer from './views/Viewer.vue';
const routes = [
{ path: '/', redirect: '/home' },
- { path: '/home/:appId?/:cwd*', component: Home },
- { path: '/viewer/:appId/:filePath*', component: Viewer },
+ { path: '/home/:type/:resourceId?/:cwd*', component: Home },
+ { path: '/viewer/:type/:resourceId/:filePath*', component: Viewer },
{ path: '/login', component: Login },
];
diff --git a/src/models/DirectoryModel.js b/src/models/DirectoryModel.js
index bc00dbd9c..0492cc658 100644
--- a/src/models/DirectoryModel.js
+++ b/src/models/DirectoryModel.js
@@ -3,11 +3,12 @@ import superagent from 'superagent';
import safe from 'safetydance';
import { sanitize } from 'pankow/utils';
-export function createDirectoryModel(origin, accessToken, appId) {
+export function createDirectoryModel(origin, accessToken, api) {
+
return {
name: 'DirectoryModel',
async listFiles(path) {
- const [error, result] = await safe(superagent.get(`${origin}/api/v1/apps/${appId}/files/${path}`).query({ access_token: accessToken }));
+ const [error, result] = await safe(superagent.get(`${origin}/api/v1/${api}/files/${path}`).query({ access_token: accessToken }));
if (error) {
console.error('Failed to list files', error);
return [];
@@ -17,7 +18,7 @@ export function createDirectoryModel(origin, accessToken, appId) {
result.body.entries.forEach(item => {
// if we have an image, attach previewUrl
if (item.mimeType.indexOf('image/') === 0) {
- item.previewUrl = `${origin}/api/v1/apps/${appId}/files/${encodeURIComponent(path + '/' + item.fileName)}?access_token=${accessToken}`
+ item.previewUrl = `${origin}/api/v1/${api}/files/${encodeURIComponent(path + '/' + item.fileName)}?access_token=${accessToken}`
}
item.folderPath = path;
@@ -26,18 +27,18 @@ export function createDirectoryModel(origin, accessToken, appId) {
return result.body.entries;
},
async remove(filePath) {
- const [error] = await safe(superagent.del(`${origin}/api/v1/apps/${appId}/files/${filePath}`)
+ const [error] = await safe(superagent.del(`${origin}/api/v1/${api}/files/${filePath}`)
.query({ access_token: accessToken }));
if (error) throw error;
},
async rename(fromFilePath, toFilePath) {
- const [error] = await safe(superagent.put(`${origin}/api/v1/apps/${appId}/files/${fromFilePath}`)
+ const [error] = await safe(superagent.put(`${origin}/api/v1/${api}/files/${fromFilePath}`)
.send({ action: 'rename', newFilePath: sanitize(toFilePath) })
.query({ access_token: accessToken }));
if (error) throw error;
},
async getFile(path) {
- const [error, result] = await safe(fetch(`${origin}/api/v1/apps/${appId}/files/${path}?access_token=${accessToken}`));
+ const [error, result] = await safe(fetch(`${origin}/api/v1/${api}/files/${path}?access_token=${accessToken}`));
if (error) {
console.error('Failed to get file', error);
return null;
@@ -47,7 +48,7 @@ export function createDirectoryModel(origin, accessToken, appId) {
return text;
},
getFileUrl(path) {
- return `${origin}/api/v1/apps/${appId}/files/${path}?access_token=${accessToken}`;
+ return `${origin}/api/v1/${api}/files/${path}?access_token=${accessToken}`;
}
};
}
diff --git a/src/views/Home.vue b/src/views/Home.vue
index 3c8bc1767..456a12667 100644
--- a/src/views/Home.vue
+++ b/src/views/Home.vue
@@ -11,7 +11,7 @@
-
+
@@ -84,8 +84,10 @@ export default {
accessToken: localStorage.accessToken,
baseUrl: BASE_URL || '',
apps: [],
+ volumes: [],
+ resources: [],
selectedAppId: '',
- activeApp: null,
+ activeResource: null,
// contextMenuModel will have activeItem attached if any command() is called
createMenuModel: [{
@@ -116,7 +118,7 @@ export default {
},
watch: {
cwd(newCwd, oldCwd) {
- if (this.activeApp) this.$router.push(`/home/${this.activeApp.id}${this.cwd}`);
+ if (this.activeResource) this.$router.push(`/home/${this.activeResource.type}/${this.activeResource.id}${this.cwd}`);
this.loadCwd();
}
},
@@ -131,9 +133,9 @@ export default {
this.loadCwd();
},
onAppChange(event) {
- this.$router.push(`/home/${event.value}`);
+ this.$router.push(`/home/${event.value.type}/${event.value.id}`);
this.cwd = '/';
- this.loadApp(event.value);
+ this.loadResource(event.value);
},
onLogout() {
delete localStorage.accessToken;
@@ -150,7 +152,7 @@ export default {
if (!item) return;
if (item.type === 'directory') this.cwd = sanitize(this.cwd + '/' + item.name);
- else this.$router.push(`/viewer/${this.activeApp.id}${sanitize(this.cwd + '/' + item.name)}`);
+ else this.$router.push(`/viewer/${this.activeResource.type}/${this.activeResource.id}${sanitize(this.cwd + '/' + item.name)}`);
},
async deleteHandler(files) {
if (!files) return;
@@ -199,7 +201,7 @@ export default {
});
const tmp = this.cwd.split('/').slice(1);
- let name = this.activeApp.fqdn;
+ let name = this.activeResource.fqdn;
if (tmp.length > 1) name = tmp[tmp.length-2];
this.activeDirectoryItem = {
@@ -210,11 +212,9 @@ export default {
icon: '/mime-types/inode-directory.svg'
};
},
- async loadApp(appId) {
- this.activeApp = this.apps.find(a => a.id === appId);
- if (!this.activeApp) return console.error('Unable to find app', appId);
-
- this.directoryModel = createDirectoryModel(BASE_URL, localStorage.accessToken, appId);
+ async loadResource(resource) {
+ this.activeResource = resource;
+ this.directoryModel = createDirectoryModel(BASE_URL, localStorage.accessToken, resource.type === 'volume' ? `volumes/${resource.id}` : `apps/${resource.id}`);
this.loadCwd();
}
},
@@ -222,28 +222,55 @@ export default {
useConfirm();
// load all apps
- const [error, result] = await safe(superagent.get(`${BASE_URL}/api/v1/apps`).query({ access_token: localStorage.accessToken }));
+ let [error, result] = await safe(superagent.get(`${BASE_URL}/api/v1/apps`).query({ access_token: localStorage.accessToken }));
if (error) {
console.error('Failed to list apps', error);
this.apps = [];
} else {
this.apps = result.body ? result.body.apps.filter(a => !!a.manifest.addons.localstorage) : [];
}
+ this.apps.forEach(function (a) { a.type = 'app'; });
- const appId = this.$route.params.appId;
+ // load all volumes
+ [error, result] = await safe(superagent.get(`${BASE_URL}/api/v1/volumes`).query({ access_token: localStorage.accessToken }));
+ if (error) {
+ console.error('Failed to list volumes', error);
+ this.volumes = [];
+ } else {
+ this.volumes = result.body ? result.body.volumes : [];
+ }
+ this.volumes.forEach(function (a) { a.type = 'volume'; a.fqdn = 'Volume: ' + a.name; });
- this.activeApp = this.apps.find(a => a.id === appId);
- if (!this.activeApp) this.activeApp = this.apps[0];
- if (!this.activeApp) return console.error('Unable to find app', appId);
+ this.resources = this.apps.concat(this.volumes);
- this.selectedAppId = this.activeApp.id;
+ const type = this.$route.params.type || 'app';
+ const resourceId = this.$route.params.resourceId;
+
+ if (type === 'volume') {
+ this.activeResource = this.volumes.find(a => a.id === resourceId);
+ if (!this.activeResource) this.activeResource = this.volumes[0];
+ if (!this.activeResource) return console.error('Unable to find volumes', resourceId);
+ } else if (type === 'app') {
+ this.activeResource = this.apps.find(a => a.id === resourceId);
+ if (!this.activeResource) this.activeResource = this.apps[0];
+ if (!this.activeResource) return console.error('Unable to find app', resourceId);
+ } else {
+ this.activeResource = this.apps[0];
+ }
this.cwd = sanitize('/' + (this.$route.params.cwd ? this.$route.params.cwd.join('/') : '/'));
- this.loadApp(this.activeApp.id);
+ this.loadResource(this.activeResource);
this.$watch(() => this.$route.params, (toParams, previousParams) => {
- this.activeApp = this.apps.find(a => a.id === toParams.appId);
+ if (toParams.type === 'volume') {
+ this.activeResource = this.volumes.find(a => a.id === toParams.resourceId);
+ } else if (toParams.type === 'app') {
+ this.activeResource = this.apps.find(a => a.id === toParams.resourceId);
+ } else {
+ console.error(`Unknown type ${toParams.type}`);
+ }
+
this.cwd = toParams.cwd ? `/${toParams.cwd.join('/')}` : '/';
});
}
diff --git a/src/views/Viewer.vue b/src/views/Viewer.vue
index 0a09e8beb..06065aa66 100644
--- a/src/views/Viewer.vue
+++ b/src/views/Viewer.vue
@@ -21,7 +21,8 @@ export default {
},
data() {
return {
- appId: '',
+ resourceId: '',
+ resourceType: '',
item: null,
active: ''
};
@@ -32,13 +33,14 @@ export default {
}
},
async mounted() {
- this.appId = this.$route.params.appId;
+ this.resourceId = this.$route.params.resourceId;
+ this.resourceType = this.$route.params.type;
const filePath = this.$route.params.filePath.join('/');
const fileName = this.$route.params.filePath[this.$route.params.filePath.length-1];
const parentDirectoryPath = sanitize(filePath.split('/').slice(0, -1).join('/'));
- this.directoryModel = createDirectoryModel(BASE_URL, localStorage.accessToken, this.appId);
+ this.directoryModel = createDirectoryModel(BASE_URL, localStorage.accessToken, (this.resourceType === 'volume' ? 'volumes/' : 'apps/') + this.resourceId);
const files = await this.directoryModel.listFiles(parentDirectoryPath);
this.item = files.find(i => i.fileName === fileName);