Compare commits

...

67 Commits

Author SHA1 Message Date
Râu Cao 0bece35c44
Update README 2023-09-20 22:41:57 +02:00
Basti 9c48d30159
Update README 2021-02-25 19:52:16 +01:00
Basti a016b68355
Adjust resource limits
continuous-integration/drone/push Build is running Details
2019-03-04 13:52:35 +07:00
Basti afdef57808
Lower memory limit 2019-03-04 13:22:09 +07:00
Basti 4a3095625c
Add resource limits for Drone k8s jobs
continuous-integration/drone/push Build is running Details
2019-03-04 13:19:03 +07:00
Basti f1fc68e7bf
Fix Docker tag syntax
continuous-integration/drone/push Build was killed Details
2019-03-03 13:36:34 +07:00
Basti 825bbd63ea
Add Drone CI config
continuous-integration/drone/push Build was killed Details
2019-03-03 13:23:54 +07:00
Basti 25edfa775b Update rs.js 2018-12-09 09:12:50 +00:00
Basti 39686a55c3 0.9.0 2018-11-17 15:41:24 +00:00
Basti 9cfaedb1ea Remove macOS package from lockfile 2018-11-17 15:33:28 +00:00
Basti 2017da2af0 Render audio and video file preview
Audio and video files are not downloaded, but the element src is
fetching the content directly from storage. Unfortunately, one cannot
skip forward, when the RS server doesn't support content ranges.
2018-11-17 15:33:28 +00:00
Basti 4754bc4a89 Update README 2018-11-17 15:33:28 +00:00
Basti 96ddacae14 Style content buttons 2018-11-17 15:33:28 +00:00
Basti 3dbf1e1228 Formatting 2018-06-19 18:13:20 +02:00
Basti 2abd47712d For now only edit JSON
Plain text editing is not implemented yet.
2018-04-02 00:19:12 +02:00
Basti 4d8e25eaf7 Ensure previews are not opened in edit mode
Apparently component state can survive route changes there. o_O
2018-04-02 00:18:35 +02:00
Basti e3f1010d59 Make buttons fit with all possible buttons visible 2018-04-02 00:09:15 +02:00
Basti 6a63d63634 Fix button spacing for all possible combos 2018-04-02 00:04:58 +02:00
Basti 74e442ce8b Give delete button a warning color 2018-04-01 16:03:03 +02:00
Basti c7a4faf5b2 Disabled editor buttons while uploading changes 2018-04-01 15:55:57 +02:00
Basti f2fe1f5530 Reset JSON treeviews when editing is cancelled
And don't add all the event handlers by default.
2018-04-01 15:40:17 +02:00
Basti 103ccbdfdd Minimal styling for native content buttons 2018-04-01 15:39:55 +02:00
Basti 5748f83971 Use proper button groups
Improve styling of button groups, so they're more intuitive. Remove
button-group containers for single buttons.
2018-04-01 15:25:25 +02:00
Basti c979b13df5 Edit files via the JSON tree view editor 2018-04-01 13:59:34 +02:00
Basti ddecda8220 Add edit-content buttons and states 2018-03-31 19:35:46 +02:00
Basti 693769d41c Update remoteStorage.js 2018-03-31 19:04:56 +02:00
Basti 5cb30e384d Update README 2018-03-04 17:15:07 +02:00
Basti 0eaf248045 Update README 2018-03-04 17:09:48 +02:00
Basti 3cb6276f3b Lock custom tree-view dep 2018-02-25 17:06:41 +02:00
Basti 44b07c7dd1 Update RS widget 2018-02-25 17:04:54 +02:00
Basti 8db259d147 Add button for opening public docs in a new tab 2018-01-25 16:52:56 +00:00
Basti ade473d585 0.8.0 2018-01-19 21:32:29 +00:00
Basti 8725b3ffa8 Use icons for all buttons 2018-01-19 11:54:53 +00:00
Basti a5a77ac668 Basic button styles 2018-01-19 10:41:39 +00:00
Basti ebbe52c81d Use same grid for header as for inspect body 2018-01-06 15:53:18 +00:00
Basti 0ab2e9e732 Add button for hiding/showing metadata 2018-01-06 15:51:03 +00:00
Basti 3deca81c1d Give sidebar some bottom space 2018-01-06 15:23:06 +00:00
Basti 39789d365b Add some bottom margin to the inspect details 2018-01-06 15:21:05 +00:00
Basti c46f363316 Make file content scrollable 2018-01-06 15:15:52 +00:00
Basti 411613088a Add JSON tree view in addition to source preview 2018-01-06 14:56:19 +00:00
Basti cd8d32d812 Inject service in file-preview component 2018-01-06 13:03:04 +00:00
Basti 355cb3a4d3 Add JSON tree view lib 2018-01-06 12:53:32 +00:00
Basti a832f5614c Add buttons for switching JSON preview style 2018-01-06 12:53:14 +00:00
Basti 3c9bf3f322 Update README 2018-01-04 19:30:27 +00:00
Basti db87ecb76e 0.7.1 2018-01-03 19:57:26 +00:00
Basti afa1552ebf Fix race condition with documents filtering 2018-01-03 19:48:55 +00:00
Basti 174f69f84d 0.7.0 2018-01-03 19:36:29 +00:00
Basti 9f5d8bfb93 Delete all documents in current directory
Adds a new button to the top right for deleting all documents in a
directory.
2018-01-03 13:34:04 +00:00
Basti f9b4444763 Use published widget again
The necessary changes have been released in 1.2.0
2018-01-02 13:11:01 +00:00
Basti bdb0671171 0.6.1 2017-12-31 18:40:35 +00:00
Basti 14c39d292f Prevent error alert for discovery errors
They're handled by the widget
2017-12-31 18:40:08 +00:00
Basti 8f7b861347 0.6.0 2017-12-31 18:29:29 +00:00
Basti ab9ad2f354 Handle invalid RS auth tokens 2017-12-31 13:35:25 +01:00
Basti ab637deb33 Add delete button 2017-12-30 20:24:40 +01:00
Basti 220888a7c5 Move header to route templates, remove obsolete code 2017-12-30 20:05:41 +01:00
Basti f681524599 Update package lockfile 2017-12-30 20:05:27 +01:00
Basti 554e661ad6 0.5.1 2017-12-26 14:56:17 +01:00
Basti e4520d86c3 Fix file preview content not breaking 2017-12-26 14:55:37 +01:00
Basti a27d142b4b 0.5.0 2017-12-26 14:02:04 +01:00
Basti 89b846c511 Show disconnect link on hover 2017-12-26 14:01:43 +01:00
Basti b8604bacb5 Add basic disconnect link 2017-12-26 13:53:21 +01:00
Basti 36901b8006 Use new skipInitial widget option 2017-12-26 13:53:03 +01:00
Basti 2e4b5a0337 Add disconnect route 2017-12-26 12:16:18 +01:00
Basti f7142fa125 Fix widget style on connect page 2017-12-26 12:16:03 +01:00
Basti e38e873dd2 Style user address (with username seperate from host) 2017-12-26 12:03:40 +01:00
Basti 0a41be32fd Fix route test 2017-12-26 12:03:32 +01:00
Basti 5d533d2c08 More connect improvements
* Use extra route for disconnected/initial state
* Style connect screen properly
* Hide widget when connected in favor of custom UI
* Show account info in sidebar header
2017-12-25 10:50:03 +01:00
68 changed files with 1439 additions and 118 deletions

16
.drone.yml Normal file
View File

@ -0,0 +1,16 @@
kind: pipeline
name: test
steps:
- name: test
image: colthreepv/node-chrome:8
commands:
- npm install
- npm test
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
cpu: 250m
memory: 256Mi

View File

@ -199,7 +199,7 @@ linters:
style: one_space # or 'at_least_one_space', or 'no_space'
SpaceBeforeBrace:
enabled: true
enabled: false
style: space # or 'new_line'
allow_single_line_padding: false

View File

@ -4,8 +4,11 @@ Inspektor is a simple file browser for inspecting the contents of a
[remoteStorage](https://remotestorage.io) account. It is intended for RS app
developers and power users.
Inspektor is beta software and currently under development. You're invited to
contribute and/or give feedback: https://gitlab.com/skddc/inspektor
You're invited to contribute to this app and/or submit feedback to improve it. Please use the
[RS Discourse forums](https://community.remotestorage.io/t/rs-inspektor-a-simple-remotestorage-file-browser/428)
to post issues or ideas, and/or to request an account for gitea.kosmos.org
if you want to submit pull requests directly to the upstream repository. You
may also submit Git patches via [e-mail](mailto:raucao@kip.pe).
## Features
@ -13,15 +16,18 @@ contribute and/or give feedback: https://gitlab.com/skddc/inspektor
* [x] Traverse/inspect directories
* [x] View document details
* [x] Render images in details
* [x] Render text content in details (e.g. JSON)
* [ ] Render other types content (e.g. audio and video)
* [ ] Edit text content (and save changes)
* [ ] Delete documents
* [ ] Delete directories
* [x] Render text content in details
* [x] Render JSON content tree view (optional source view)
* [x] Delete documents
* [x] Edit JSON content in tree view
* [x] Delete directories
* [ ] Edit content source
* [ ] Render other types of content (e.g. audio and video)
* [ ] Copy/move documents
* [ ] Copy/move directories (and enclosed files)
* [ ] Loading indicator for any view change that loads remote data
* [ ] Logo/icon
* [ ] Layout/support for small screens
## Prerequisites

View File

@ -0,0 +1,18 @@
import Component from '@ember/component';
import { computed } from '@ember/object';
export default Component.extend({
classNames: ['account-info'],
userAddress: null,
username: computed('userAddress', function() {
return this.get('userAddress').split('@')[0];
}),
host: computed('userAddress', function() {
return '@' + this.get('userAddress').split('@')[1];
})
});

View File

@ -0,0 +1,4 @@
<span class="username">{{username}}</span>
<br><span class="host">{{host}}</span>
{{#link-to "disconnect" class="disconnect"}}disconnect{{/link-to}}

View File

@ -1,23 +1,43 @@
import Component from '@ember/component';
import { alias } from '@ember/object/computed';
import { inject as service } from '@ember/service';
import { observer } from '@ember/object';
import { alias, none, not } from '@ember/object/computed';
import { scheduleOnce } from '@ember/runloop';
import JSONTreeView from 'npm:json-tree-view';
export default Component.extend({
storage: null,
storage: service(),
classNames: ['file-preview'],
fileLoaded: false,
uploadingChanges: false,
showEditor: null,
hideEditor: not('showEditor'),
fileContent: null,
objectURL: null,
metaData: null,
isJSON: null,
type: alias('metaData.type'),
isBinary: alias('metaData.isBinary'),
isUnknownBinary: none('isImage', 'isAudio', 'isVideo'),
isImage: function() {
return this.get('type').match(/^image\/.+$/);
}.property('type'),
isAudio: function() {
return this.get('type').match(/^audio\/.+$/);
}.property('type'),
isVideo: function() {
return this.get('type').match(/^video\/.+$/);
}.property('type'),
isText: function() {
return !this.get('isBinary');
}.property('isBinary'),
@ -25,8 +45,16 @@ export default Component.extend({
loadFile: function() {
let path = this.get('metaData.path');
if (this.get('isAudio') || this.get('isVideo')) {
this.set('fileLoaded', true);
this.set('objectURL', this.get('storage.client')
.getItemURL(path));
return;
}
// TODO don't fetch is size above certain limit
console.debug(`[file-preview] Loading file ${this.get('metaData.name')}`)
this.get('storage.client').getFile(path).then(file => {
if (this.get('isImage')) {
let view = new window.Uint8Array(file.data);
@ -35,8 +63,115 @@ export default Component.extend({
} else {
this.set('fileContent', file.data);
}
this.set('fileLoaded', true);
});
}.on('init')
}.on('didInsertElement'),
onFileLoaded: observer('fileLoaded', function(){
if (this.get('fileLoaded') && this.get('isJSON') && this.get('jsonShowTree')) {
scheduleOnce('afterRender', this, 'renderJsonTree');
}
}),
onJsonViewChanged: observer('jsonShowTree', function(){
if (this.get('fileLoaded') && this.get('isJSON') && this.get('jsonShowTree')) {
scheduleOnce('afterRender', this, 'renderJsonTree');
}
}),
renderJsonTree () {
let value = JSON.parse(this.get('fileContent'));
let view = new JSONTreeView('content', value);
// this.attachJsonTreeEventHandlers(view);
const containerElement = document.getElementById('json-tree-view');
containerElement.innerHTML = ''; // Throw away any existing treeviews
containerElement.appendChild(view.dom);
window.jsonview = view;
view.expand(true);
view.withRootName = false;
view.readonly = this.get('hideEditor');
this.set('jsonTreeView', view);
},
attachJsonTreeEventHandlers (view) {
view.on('change', function(self, key, oldValue, newValue){
console.log('change', key, oldValue, '=>', newValue);
});
view.on('rename', function(self, key, oldName, newName) {
console.log('rename', key, oldName, '=>', newName);
});
view.on('delete', function(self, key) {
console.log('delete', key);
});
view.on('append', function(self, key, nameOrValue, newValue) {
console.log('append', key, nameOrValue, '=>', newValue);
});
view.on('click', function(self, key, value) {
console.log('click', key, '=', value);
});
view.on('expand', function(self, key, value) {
console.log('expand', key, '=', value);
});
view.on('collapse', function(self, key, value) {
console.log('collapse', key, '=', value);
});
view.on('refresh', function(self, key, value) {
console.log('refresh', key, '=', value);
});
},
onShowEditor: observer('showEditor', function(){
if (this.get('fileLoaded') && this.get('isJSON') && this.get('jsonShowTree')) {
const showEditor = this.get('showEditor');
if (showEditor) {
this.set('jsonTreeView.readonly', false);
} else {
this.set('jsonTreeView.readonly', true);
this.renderJsonTree();
}
}
}),
actions: {
saveChanges () {
const path = this.get('metaData.path');
if (this.get('isJSON') && this.get('jsonShowTree')) {
const content = JSON.stringify(this.get('jsonTreeView.value'));
this.set('uploadingChanges', true);
this.get('storage.client')
.storeFile('application/json', path, content)
.then(etag => {
this.setProperties({
'metaData.etag': etag,
fileContent: content,
showEditor: false
});
}).catch(err => {
alert('Failed to update the file. Check the console for more info.');
console.error(err);
}).finally(() => {
this.set('uploadingChanges', false);
});
} else {
console.warn('not implemented');
}
},
cancelEditor () {
this.set('showEditor', false);
}
}
});

View File

@ -1,13 +1,43 @@
{{#if fileLoaded}}
{{#if isBinary}}
{{#if isUnkownBinary}}
<p>No preview available for this content type.</p>
{{/if}}
{{#if isImage}}
<img src={{objectURL}} alt={{metaData.name}}>
{{else}}
<p>No preview available for this content type.</p>
{{/if}}
{{#if isAudio}}
<audio src={{objectURL}} controls />
{{/if}}
{{#if isVideo}}
<video src={{objectURL}} controls />
{{/if}}
{{/if}}
{{#if isText}}
<code>{{fileContent}}</code>
{{#if isJSON}}
{{#if jsonShowTree}}
<div id="json-tree-view"></div>
{{else}}
<code>{{fileContent}}</code>
{{/if}}
{{else}}
<code>{{fileContent}}</code>
{{/if}}
{{/if}}
{{#if showEditor}}
<div class="actions">
<button {{action "saveChanges"}}
disabled={{uploadingChanges}}
class="primary">
Save changes
</button>
<button {{action "cancelEditor"}}
disabled={{uploadingChanges}}
class="secondary">
Cancel editing
</button>
</div>
{{/if}}
{{/if}}

View File

@ -1,6 +1,6 @@
import Controller from '@ember/controller';
import EmberObject from '@ember/object';
import { observer } from '@ember/object';
import { computed, observer } from '@ember/object';
import { inject as service } from '@ember/service';
import { alias } from '@ember/object/computed';
import { isEmpty } from '@ember/utils';
@ -11,9 +11,14 @@ export default Controller.extend({
connecting: alias('storage.connecting'),
connected: alias('storage.connected'),
userAddress: alias('storage.userAddress'),
rootListing: alias('storage.rootListing'),
currentDirPath: null,
connectedClass: computed('connected', function() {
return this.get('connected') ? 'connected' : 'disconnected';
}),
categories: function() {
let categories = [];
let rootListing = this.get('rootListing');

View File

@ -1,9 +1,10 @@
import Controller from '@ember/controller';
import { inject as controller } from '@ember/controller';
import { observer } from '@ember/object';
import { inject as service } from '@ember/service';
import { computed, observer } from '@ember/object';
import { alias } from '@ember/object/computed';
import { isPresent } from '@ember/utils';
import { isPresent, isEmpty } from '@ember/utils';
import { all } from 'rsvp';
export default Controller.extend({
@ -16,7 +17,7 @@ export default Controller.extend({
queryParams: ['path'],
currentListing: function() {
currentListing: function () {
if (isPresent(this.get('model.currentListing'))) {
return this.get('model.currentListing').sortBy('name');
} else {
@ -24,7 +25,34 @@ export default Controller.extend({
}
}.property('rootListing.[]', 'model.[]'),
connectedChange: observer('connected', function() {
documents: computed('currentListing.[]', function () {
if (isEmpty(this.get('currentListing'))) { return []; }
return this.get('currentListing')
.reject(item => item.path.substr(-1) === '/');
}),
currentListingContainsDocuments: computed('documents.[]', function () {
return isPresent(this.get('documents'));
}),
documentCount: computed('documents.[]', function () {
if (isPresent(this.get('documents'))) {
return this.get('documents').length;
} else {
return 0;
}
}),
parentDir: computed('currentDirPath', function () {
const dirs = this.get('currentDirPath')
.split('/')
.reject(p => isEmpty(p));
return dirs.splice(0, dirs.length - 1).join('/') + '/';
}),
connectedChange: observer('connected', function () {
if (this.get('connected')) {
// console.debug('connectedChange connected');
} else {
@ -33,4 +61,27 @@ export default Controller.extend({
}
}),
actions: {
deleteDocuments () {
const documentCount = this.get('documentCount');
const msg = `Delete all ${documentCount} documents/files in the current directory?`;
if (! window.confirm(msg)) { return false; }
const client = this.get('storage.client');
let promises = this.get('documents').map(item => {
console.debug('removing ' + item.path);
return client.remove(item.path);
});
all(promises).then(() => {
this.transitionToRoute('index', {
queryParams: { path: this.get('parentDir') }
});
});
}
}
});

View File

@ -1,7 +1,9 @@
import Controller from '@ember/controller';
import { inject as controller } from '@ember/controller';
import { inject as service } from '@ember/service';
import { computed } from '@ember/object';
import { alias } from '@ember/object/computed';
import { isEmpty } from '@ember/utils';
export default Controller.extend({
@ -12,4 +14,70 @@ export default Controller.extend({
queryParams: ['path'],
// documentIsEditable: computed.not('model.documentMetaData.isBinary'),
documentIsEditable: alias('documentIsJSON'),
documentShowEditor: false,
documentHideEditor: computed.not('documentShowEditor'),
documentIsJSON: computed('model.documentMetaData.type', function(){
if (isEmpty(this.get('model.documentMetaData'))) { return false; }
return !!this.get('model.documentMetaData.type').match(/application\/json/i);
}),
jsonView: 'tree',
jsonShowTree: computed.equal('jsonView', 'tree'),
jsonShowSource: computed.equal('jsonView', 'source'),
publicItemURL: computed('model.documentMetaData.path', function(){
let path = this.get('model.documentMetaData.path');
if (path.match(/public\//)) {
return this.get('storage.client').getItemURL(path);
} else {
return null;
}
}),
metadataHidden: false,
actions: {
showJsonTree () {
this.set('jsonView', 'tree');
},
showJsonSource () {
this.set('jsonView', 'source');
},
showEditor () {
this.set('documentShowEditor', true);
},
cancelEditor () {
this.set('documentShowEditor', false);
// TODO remove changes from tree/source
},
toggleMetadata () {
this.toggleProperty('metadataHidden');
},
deleteItem () {
if (window.confirm('Delete?')) {
this.get('storage.client')
.remove(this.get('path')).then(() => {
this.transitionToRoute('index', {
queryParams: {
path: this.get('currentDirPath')
}
});
});
}
}
}
});

View File

@ -8,6 +8,8 @@ const Router = EmberRouter.extend({
Router.map(function() {
this.route('inspect');
this.route('connect');
this.route('disconnect');
});
export default Router;

View File

@ -1,5 +1,38 @@
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
import BodyClassMixin from 'ember-body-class/mixins/body-class';
export default Route.extend({
export default Route.extend(BodyClassMixin, {
storage: service(),
beforeModel () {
this.get('storage.rs').on('error', (error) => {
console.debug('rs.on error', error);
if (error.name === 'Unauthorized') {
this.handleUnauthorized();
} else if (error.name === 'DiscoveryError') {
// Do nothing, because the widget will handle it
} else {
alert('An unknown error occured. Please check the browser console for details.');
}
});
},
// We need to handle this here, so we can transitionTo
// the connect route
handleUnauthorized () {
// Ignore additional unauthorized events after the
// first one
if (this.get('storage.unauthorized')) { return; }
this.get('storage').setProperties({
unauthorized: true,
connecting: false,
connected: false
});
this.transitionTo('connect');
}
});

33
app/routes/connect.js Normal file
View File

@ -0,0 +1,33 @@
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
import { later } from '@ember/runloop';
import { Promise } from 'rsvp';
export default Route.extend({
storage: service(),
beforeModel() {
return this.waitForConnectionState().then(() => {
if (this.get('storage.connected')) {
this.transitionTo('index');
}
});
},
waitForConnectionState() {
let self = this;
return new Promise(resolve => {
function checkConnectingDone() {
if (self.get('storage.connecting')) {
later(checkConnectingDone, 20);
} else {
resolve();
}
}
checkConnectingDone();
});
}
});

13
app/routes/disconnect.js Normal file
View File

@ -0,0 +1,13 @@
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
export default Route.extend({
storage: service(),
beforeModel() {
this.get('storage.rs').disconnect();
this.transitionTo('connect');
}
});

View File

@ -15,12 +15,14 @@ export default Route.extend({
},
beforeModel() {
return this.waitForConnectionState();
return this.waitForConnectionState().then(() => {
if (this.get('storage.disconnected')) {
this.transitionTo('connect');
}
});
},
model(params) {
if (this.get('storage.disconnected')) { return null; }
let path = params.path;
if (isEmpty(params.path)) { return null; }
@ -35,7 +37,6 @@ export default Route.extend({
setupController(controller, model) {
this._super(controller, model);
if (this.get('storage.disconnected')) { return true; }
if (isEmpty(this.get('storage.categories')) && this.get('storage.connected')) {
this.get('storage').fetchRootListing();
@ -43,6 +44,12 @@ export default Route.extend({
if (isPresent(model)) {
controller.set('currentDirPath', model.currentDirPath);
if (isEmpty(model.currentListing)) {
this.transitionTo('index', {
queryParams: { path: controller.get('parentDir') }
});
}
}
},

View File

@ -32,7 +32,8 @@ export default Route.extend({
}).then(metaData => {
return {
documentMetaData: metaData,
currentDirPath: parentDirPath
// documentPublicURL: this.get()
currentDirPath: parentDirPath,
};
});
},
@ -47,6 +48,8 @@ export default Route.extend({
if (isPresent(model)) {
controller.set('currentDirPath', model.currentDirPath);
}
controller.set('documentShowEditor', false);
}
});

View File

@ -1,6 +1,7 @@
import EmberObject from '@ember/object';
import { computed, observer } from '@ember/object';
import Service from '@ember/service';
import { computed, observer } from '@ember/object';
import { isEmpty } from '@ember/utils';
import RemoteStorage from 'npm:remotestoragejs';
import Widget from 'npm:remotestorage-widget';
import simpleContentType from 'inspektor/utils/simple-content-type';
@ -11,6 +12,8 @@ export default Service.extend({
widget: null,
connecting: true,
connected: false,
unauthorized: false,
userAddress: null,
disconnected: computed.not('connected'),
client: null,
rootListing: null,
@ -28,7 +31,7 @@ export default Service.extend({
// });
const widget = new Widget(rs, {
// leaveOpen: true
skipInitial: true
});
// Attach widget to DOM
@ -43,6 +46,7 @@ export default Service.extend({
console.debug('rs.on connected');
this.set('connecting', false);
this.set('connected', true);
this.set('userAddress', this.get('rs').remote.userAddress);
});
rs.on('not-connected', () => {
@ -78,10 +82,17 @@ export default Service.extend({
if (this.get('connected')) {
this.fetchRootListing();
} else {
this.set('rootListing', null);
this.clearLocalData();
}
}),
clearLocalData() {
this.setProperties({
userAddress: null,
rootListing: null
});
},
fetchRootListing() {
this.fetchListing('').then(items => {
this.set('rootListing', items.sortBy('name'));
@ -92,6 +103,8 @@ export default Service.extend({
let items = [];
return this.get('client').getListing(path).then(listing => {
if (isEmpty(listing)) { return []; }
Object.keys(listing).forEach(name => {
let item = listing[name];
let type = item['Content-Type'] || 'folder';

138
app/styles/_buttons.scss Normal file
View File

@ -0,0 +1,138 @@
button {
font-family: Open Sans, sans-serif;
font-size: 1rem;
color: #fff;
background-color: $dark-blue;
border: 1px solid $dark-blue;
&:hover, &:active {
background-color: lighten($dark-blue, 5%);
}
&.delete {
background-color: transparent;
border-color: $dark-red;
color: $dark-red;
svg { path { fill: $dark-red; }
}
&:hover {
background-color: $dark-red;
color: #fff;
svg { path { fill: #fff; } }
}
}
&.primary {
// main button
}
&.secondary {
background-color: transparent;
color: $dark-blue;
&:hover {
background-color: $dark-blue;
color: #fff;
svg { path { fill: #fff; } }
}
}
}
header {
button, a.button {
display: inline-block;
padding: 0.4rem 0 0.3rem;
width: 3rem;
border: 1px solid $dark-grey-2;
border-radius: 0.2em;
background-color: #fff;
color: $dark-grey-2;
text-align: center;
text-transform: uppercase;
svg {
height: 1rem;
path { fill: $dark-grey-2; }
}
&:hover {
background-color: $dark-grey-2;
color: #fff;
svg {
path {
fill: #fff;
}
}
}
&:disabled:not(.active),
&:disabled:not(.active):hover {
border-color: $dark-grey-3;
background-color: #fff;
color: $dark-grey-3;
svg {
path {
fill: $dark-grey-3;
}
}
}
&.active {
border-color: lighten($dark-grey-2, 10%);
background-color: lighten($dark-grey-2, 10%);
color: lighten($dark-grey-2, 10%);
svg { path { fill: #fff; } }
}
}
button + button,
button + .button,
.button + .button,
button + .button-group,
.button + .button-group,
.button-group + button,
.button-group + .button-group {
margin-left: 0.5rem;
}
.button-group {
position: relative;
display: inline-flex;
flex-direction: row;
button {
position: relative;
margin-right: 0;
flex: 0 1 auto;
&:not(:last-child) {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
}
button + button {
margin-left: -1px;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
}
}
main section.content {
button {
font-size: 0.86rem;
padding: 0.4rem 1rem;
border-radius: 3px;
}
button + button {
margin-left: 0.5rem;
}
}

View File

@ -3,8 +3,17 @@ $dark-grey-2: #344453;
$dark-grey-3: #aaa;
$light-grey-1: #b5c3d1;
$light-grey-2: #ececec;
$dark-red: #8b0000;
$dark-blue: #0067c7;
body {
background-color: #fff;
transition: background-color 0.2s linear;
}
#app-container {
background-color: #fff;
> aside {
background-color: $dark-grey-1;
color: $light-grey-1;
@ -19,7 +28,6 @@ $light-grey-2: #ececec;
}
> main {
// background-color: $dark-grey-2;
background-color: #fff;
> header {
@ -32,4 +40,8 @@ $light-grey-2: #ececec;
}
}
}
&.disconnected main {
background-color: $light-grey-2;
}
}

View File

@ -3,12 +3,24 @@
}
#remotestorage-widget {
position: fixed;
top: 1rem;
right: 3rem;
z-index: 1;
display: none;
position: absolute;
top: 20%;
left: 50%;
margin-left: -200px;
z-index: 23;
}
.connect #remotestorage-widget {
display: block;
}
// .index #remotestorage-widget {
// position: fixed;
// top: 1rem;
// right: 3rem;
// }
#app-container {
position: absolute;
top: 0;
@ -21,14 +33,30 @@
justify-content: flex-start;
align-items: stretch;
&.disconnected {
> aside {
flex: 0;
overflow: hidden;
}
}
&.connected {
> aside {
flex: 0 0 16rem;
overflow: auto;
padding: 2rem;
}
}
> aside {
flex: 0 0 16rem;
overflow: auto;
padding: 2rem;
transition: flex 0.2s ease-in;
.account-info {
height: 5rem;
}
nav {
margin-top: 5rem;
margin-bottom: 4rem;
margin-bottom: 3rem;
}
}
@ -38,7 +66,19 @@
padding: 3rem 4rem;
> header {
height: 4em;
height: 4rem;
width: 100%;
display: grid;
grid-template-columns: 1.618fr 3rem 1fr;
// nav.breadcrumb-nav {
// }
nav.actions {
grid-column-start: 3;
text-align: right;
margin-top: -0.4rem;
}
}
}
}
@ -47,17 +87,24 @@
width: 100%;
display: grid;
grid-template-columns: 1.618fr 3rem 1fr;
margin-bottom: 3rem;
transition: all 0.3s ease-out;
&.hide-metadata {
grid-template-columns: 1.618fr 0 0;
}
section {
border-top: 1px solid $light-grey-2;
padding: 1.5rem 1px;
&.content {
// foo
overflow: hidden;
}
&.meta {
grid-column-start: 3;
overflow: hidden;
dl {
margin: 0;

6
app/styles/_resets.scss Normal file
View File

@ -0,0 +1,6 @@
* {
-moz-outline: none;
outline: none;
}
:focus { outline:none; }
::-moz-focus-inner { border: 0; }

View File

@ -1,23 +1,29 @@
@import "bourbon";
@import "resets";
@import "colors";
@import "layout";
* {
-moz-outline: none;
outline: none;
html {
font-family: Open Sans, sans-serif;
font-size: 15px;
}
body {
background-color: white;
font-size: 16px;
font-size: 15px;
font-family: Open Sans, sans-serif;
color: $dark-grey-1;
margin: 0;
padding: 0;
}
@import "buttons";
@import "components/account-info";
@import "components/breadcrumb-nav";
@import "components/categories-nav";
@import "components/directory-listing";
@import "components/item-icon";
@import "components/file-preview";
@import "components/item-icon";
@import "vendor/json-tree-view";

View File

@ -0,0 +1,28 @@
.account-info {
position: relative;
.username {
font-size: 1.4rem;
}
.host {
font-size: 0.8rem;
opacity: 0.7;
}
.disconnect {
display: inline-block;
margin-left: 0.5rem;
font-size: 0.8rem;
opacity: 0;
transition: opacity 0.2s linear;
}
&:hover {
.disconnect {
font-size: 0.8rem;
opacity: 1;
}
}
}

View File

@ -1,12 +1,22 @@
.file-preview {
code {
overflow-wrap: break-word;
word-wrap: break-word;
word-break: break-all;
line-height: 1.5rem;
hyphens: none;
}
img {
img, audio, video {
max-width: 100%;
}
#json-tree-view {
overflow: auto;
}
.actions {
margin-top: 2rem;
}
}

149
app/styles/vendor/_json-tree-view.scss vendored Normal file
View File

@ -0,0 +1,149 @@
.jsonView{
margin-left: 20px;
font-family: Consolas, "Lucida Console", Menlo, "dejavu sans mono", monospace;
font-size: 15px;
line-height: 15px;
padding: 2px;
cursor: default;
color: rgb(66, 66, 66);
white-space: nowrap;
-webkit-user-select: none;
}
.jsonView>div{
display: inline-block;
}
.jsonView.hidden{
display: none;
}
.jsonView>.children, .jsonView.insert{
display: block;
}
.jsonView>.name{
color: rgb(136, 19, 145);
}
.jsonView>.separator:before{
content: ":";
}
.jsonView>.separator{
padding-right: 5px;
}
.jsonView>.spacing{
display:inline-block;
width:15px;
}
.jsonView>.spacing::before{
content: '1';
visibility:hidden;
}
.jsonView>.value.null, .jsonView>.value.undefined{
color: rgb(128, 128, 128);
}
.jsonView>.value.boolean, .jsonView>.value.number{
color: rgb(28, 0, 207);
}
.jsonView>.value.string:not(.edit):before, .jsonView>.value.string:not(.edit):after{
content: "\"";
}
.jsonView>.value.string {
color: rgb(196, 26, 22);
}
.jsonView>.name:hover, .jsonView>.value:hover{
background-color: rgba(56, 121, 217, 0.1);
}
.jsonView>.expand, .jsonView>.collapse{
min-width: 20px;
margin-left: -20px;
cursor: pointer;
}
.jsonView>.expand:before{
content: '\25B6';
}
.jsonView>.collapse:before{
content: '\25BC';
}
.jsonView>.edit{
padding: 0px 5px 0px 5px;
white-space: nowrap;
overflow: hidden;
background-color: transparent;
}
.jsonView>.edit br{
display: none;
}
.jsonView>.edit *{
display: inline;
white-space: nowrap;
}
.jsonView>.value.edit{
color: rgb(0, 0, 0);
}
.jsonView>.delete:before{
content: '+';
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
-o-transform: rotate(45deg);
-ms-transform: rotate(45deg);
display: inline-block;
}
.jsonView>.delete{
opacity: 0;
display: inline;
padding: 3px;
cursor: pointer;
color: rgb(150, 150, 150);
}
.jsonView>.item:hover~.delete{
opacity: 1;
color: rgb(150, 150, 150);
}
.jsonView>.delete:hover{
opacity: 1;
color: rgb(0, 0, 0);
background: rgb(220, 220, 220);
}
.jsonView.readonly>.insert,.jsonView.readonly>.delete{
display: none !important;
}
.jsonView>.insert:before{
content: '+';
}
.jsonView>.insert{
display: none;
color: rgb(150, 150, 150);
cursor: pointer;
}
.jsonView.expanded>.insert, .jsonView.expanded>.insert{
display: inline-block;
margin-left: 20px;
padding: 3px;
}
.jsonView>.insert:hover{
color: rgb(0, 0, 0);
background: rgb(220, 220, 220);
}

View File

@ -1,22 +1,11 @@
<div id="app-container">
<div id="app-container" class={{connectedClass}}>
<aside>
{{#if connected}}
{{account-info userAddress=userAddress}}
{{categories-nav categories=categories}}
{{/if}}
</aside>
<main>
<header>
{{#if connecting}}
<!-- Connecting... -->
{{else}}
{{#if connected}}
{{breadcrumb-nav currentDirPath=currentDirPath}}
{{else}}
Not connected.
{{/if}}
{{/if}}
</header>
{{outlet}}
</main>
</div>

View File

View File

@ -0,0 +1 @@
{{outlet}}

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M296 99.5l148.5 148c4.7 4.7 4.7 12.3 0 17L296 412.5c-4.7 4.7-12.3 4.7-17 0l-7.1-7.1c-4.7-4.7-4.7-12.3 0-17l116-115.4H76c-6.6 0-12-5.4-12-12v-10c0-6.6 5.4-12 12-12h311.9L272 123.6c-4.7-4.7-4.7-12.3 0-17l7.1-7.1c4.6-4.7 12.2-4.7 16.9 0zM12 448h8c6.6 0 12-5.4 12-12V76c0-6.6-5.4-12-12-12h-8C5.4 64 0 69.4 0 76v360c0 6.6 5.4 12 12 12z"/></svg>

After

Width:  |  Height:  |  Size: 410 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M152 412.5L3.5 264.5c-4.7-4.7-4.7-12.3 0-17L152 99.5c4.7-4.7 12.3-4.7 17 0l7.1 7.1c4.7 4.7 4.7 12.3 0 17L60.1 239H372c6.6 0 12 5.4 12 12v10c0 6.6-5.4 12-12 12H60.1L176 388.4c4.7 4.7 4.7 12.3 0 17l-7.1 7.1c-4.6 4.7-12.2 4.7-16.9 0zM436 64h-8c-6.6 0-12 5.4-12 12v360c0 6.6 5.4 12 12 12h8c6.6 0 12-5.4 12-12V76c0-6.6-5.4-12-12-12z"/></svg>

After

Width:  |  Height:  |  Size: 407 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M216 412.5l-148.5-148c-4.7-4.7-4.7-12.3 0-17L216 99.5c4.7-4.7 12.3-4.7 17 0l7.1 7.1c4.7 4.7 4.7 12.3 0 17L124.1 239H436c6.6 0 12 5.4 12 12v10c0 6.6-5.4 12-12 12H124.1L240 388.4c4.7 4.7 4.7 12.3 0 17l-7.1 7.1c-4.6 4.7-12.2 4.7-16.9 0zM12 448h8c6.6 0 12-5.4 12-12V76c0-6.6-5.4-12-12-12h-8C5.4 64 0 69.4 0 76v360c0 6.6 5.4 12 12 12z"/></svg>

After

Width:  |  Height:  |  Size: 409 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M215 99.5l-7.1 7.1c-4.7 4.7-4.7 12.3 0 17l116 115.4H12c-6.6 0-12 5.4-12 12v10c0 6.6 5.4 12 12 12h311.9L208 388.4c-4.7 4.7-4.7 12.3 0 17l7.1 7.1c4.7 4.7 12.3 4.7 17 0l148.5-148c4.7-4.7 4.7-12.3 0-17L232 99.5c-4.7-4.7-12.3-4.7-17 0zM448 76v360c0 6.6-5.4 12-12 12h-8c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h8c6.6 0 12 5.4 12 12z"/></svg>

After

Width:  |  Height:  |  Size: 407 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M464 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM32 80c0-8.8 7.2-16 16-16h48v64H32V80zm448 352c0 8.8-7.2 16-16 16H48c-8.8 0-16-7.2-16-16V160h448v272zm0-304H128V64h336c8.8 0 16 7.2 16 16v48z"/></svg>

After

Width:  |  Height:  |  Size: 326 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M228.5 511.8l-25-7.1c-3.2-.9-5-4.2-4.1-7.4L340.1 4.4c.9-3.2 4.2-5 7.4-4.1l25 7.1c3.2.9 5 4.2 4.1 7.4L235.9 507.6c-.9 3.2-4.3 5.1-7.4 4.2zm-75.6-125.3l18.5-20.9c1.9-2.1 1.6-5.3-.5-7.1L49.9 256l121-102.5c2.1-1.8 2.4-5 .5-7.1l-18.5-20.9c-1.8-2.1-5-2.3-7.1-.4L1.7 252.3c-2.3 2-2.3 5.5 0 7.5L145.8 387c2.1 1.8 5.3 1.6 7.1-.5zm277.3.4l144.1-127.2c2.3-2 2.3-5.5 0-7.5L430.2 125.1c-2.1-1.8-5.2-1.6-7.1.4l-18.5 20.9c-1.9 2.1-1.6 5.3.5 7.1l121 102.5-121 102.5c-2.1 1.8-2.4 5-.5 7.1l18.5 20.9c1.8 2.1 5 2.3 7.1.4z"/></svg>

After

Width:  |  Height:  |  Size: 582 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M417.8 315.5l20-20c3.8-3.8 10.2-1.1 10.2 4.2V464c0 26.5-21.5 48-48 48H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48h292.3c5.3 0 8 6.5 4.2 10.2l-20 20c-1.1 1.1-2.7 1.8-4.2 1.8H48c-8.8 0-16 7.2-16 16v352c0 8.8 7.2 16 16 16h352c8.8 0 16-7.2 16-16V319.7c0-1.6.6-3.1 1.8-4.2zm145.9-191.2L251.2 436.8l-99.9 11.1c-13.4 1.5-24.7-9.8-23.2-23.2l11.1-99.9L451.7 12.3c16.4-16.4 43-16.4 59.4 0l52.6 52.6c16.4 16.4 16.4 43 0 59.4zm-93.6 48.4L403.4 106 169.8 339.5l-8.3 75.1 75.1-8.3 233.5-233.6zm71-85.2l-52.6-52.6c-3.8-3.8-10.2-4-14.1 0L426 83.3l66.7 66.7 48.4-48.4c3.9-3.8 3.9-10.2 0-14.1z"/></svg>

After

Width:  |  Height:  |  Size: 661 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M569.354 231.631C512.969 135.948 407.808 72 288 72 168.14 72 63.004 135.994 6.646 231.63a47.999 47.999 0 0 0 0 48.739C63.032 376.053 168.192 440 288 440c119.86 0 224.996-63.994 281.354-159.631a48.002 48.002 0 0 0 0-48.738zM416 228c0 68.483-57.308 124-128 124s-128-55.517-128-124 57.308-124 128-124 128 55.517 128 124zm125.784 36.123C489.837 352.277 393.865 408 288 408c-106.291 0-202.061-56.105-253.784-143.876a16.006 16.006 0 0 1 0-16.247c29.072-49.333 73.341-90.435 127.66-115.887C140.845 158.191 128 191.568 128 228c0 85.818 71.221 156 160 156 88.77 0 160-70.178 160-156 0-36.411-12.833-69.794-33.875-96.01 53.76 25.189 98.274 66.021 127.66 115.887a16.006 16.006 0 0 1-.001 16.246zM224 224c0-10.897 2.727-21.156 7.53-30.137v.02c0 14.554 11.799 26.353 26.353 26.353 14.554 0 26.353-11.799 26.353-26.353s-11.799-26.353-26.353-26.353h-.02c8.981-4.803 19.24-7.53 30.137-7.53 35.346 0 64 28.654 64 64s-28.654 64-64 64-64-28.654-64-64z"/></svg>

After

Width:  |  Height:  |  Size: 1012 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M506 114H134a6 6 0 0 1-6-6V84a6 6 0 0 1 6-6h372a6 6 0 0 1 6 6v24a6 6 0 0 1-6 6zm6 154v-24a6 6 0 0 0-6-6H134a6 6 0 0 0-6 6v24a6 6 0 0 0 6 6h372a6 6 0 0 0 6-6zm0 160v-24a6 6 0 0 0-6-6H134a6 6 0 0 0-6 6v24a6 6 0 0 0 6 6h372a6 6 0 0 0 6-6zM84 120V72c0-6.627-5.373-12-12-12H24c-6.627 0-12 5.373-12 12v48c0 6.627 5.373 12 12 12h48c6.627 0 12-5.373 12-12zm0 160v-48c0-6.627-5.373-12-12-12H24c-6.627 0-12 5.373-12 12v48c0 6.627 5.373 12 12 12h48c6.627 0 12-5.373 12-12zm0 160v-48c0-6.627-5.373-12-12-12H24c-6.627 0-12 5.373-12 12v48c0 6.627 5.373 12 12 12h48c6.627 0 12-5.373 12-12z"/></svg>

After

Width:  |  Height:  |  Size: 654 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M564.907 196.35L388.91 12.366C364.216-13.45 320 3.746 320 40.016v88.154C154.548 130.155 0 160.103 0 331.19c0 94.98 55.84 150.231 89.13 174.571 24.233 17.722 58.021-4.992 49.68-34.51C100.937 336.887 165.575 321.972 320 320.16V408c0 36.239 44.19 53.494 68.91 27.65l175.998-184c14.79-15.47 14.79-39.83-.001-55.3zm-23.127 33.18l-176 184c-4.933 5.16-13.78 1.73-13.78-5.53V288c-171.396 0-295.313 9.707-243.98 191.7C72 453.36 32 405.59 32 331.19 32 171.18 194.886 160 352 160V40c0-7.262 8.851-10.69 13.78-5.53l176 184a7.978 7.978 0 0 1 0 11.06z"/></svg>

After

Width:  |  Height:  |  Size: 617 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path d="M616 320h-72v-48c0-26.468-21.532-48-48-48H336v-32h56c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24H248c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h56v32H144c-26.467 0-48 21.532-48 48v48H24c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24V344c0-13.255-10.745-24-24-24h-40v-48c0-8.822 7.178-16 16-16h160v64h-56c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24V344c0-13.255-10.745-24-24-24h-56v-64h160c8.822 0 16 7.178 16 16v48h-40c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24V344c0-13.255-10.745-24-24-24zm-456 32v128H32V352h128zm224 0v128H256V352h128zM256 160V32h128v128H256zm352 320H480V352h128v128z"/></svg>

After

Width:  |  Height:  |  Size: 806 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M336 64l-33.6-44.8C293.3 7.1 279.1 0 264 0h-80c-15.1 0-29.3 7.1-38.4 19.2L112 64H24C10.7 64 0 74.7 0 88v2c0 3.3 2.7 6 6 6h26v368c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V96h26c3.3 0 6-2.7 6-6v-2c0-13.3-10.7-24-24-24h-88zM184 32h80c5 0 9.8 2.4 12.8 6.4L296 64H152l19.2-25.6c3-4 7.8-6.4 12.8-6.4zm200 432c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V96h320v368zm-176-44V156c0-6.6 5.4-12 12-12h8c6.6 0 12 5.4 12 12v264c0 6.6-5.4 12-12 12h-8c-6.6 0-12-5.4-12-12zm-80 0V156c0-6.6 5.4-12 12-12h8c6.6 0 12 5.4 12 12v264c0 6.6-5.4 12-12 12h-8c-6.6 0-12-5.4-12-12zm160 0V156c0-6.6 5.4-12 12-12h8c6.6 0 12 5.4 12 12v264c0 6.6-5.4 12-12 12h-8c-6.6 0-12-5.4-12-12z"/></svg>

After

Width:  |  Height:  |  Size: 734 B

View File

@ -1,3 +1,13 @@
<header>
{{breadcrumb-nav currentDirPath=currentDirPath}}
<nav class="actions">
{{#if currentListingContainsDocuments}}
<button class="delete-all" title="Delete documents/files"
{{action "deleteDocuments"}}>{{partial 'icons/trash'}}</button>
{{/if}}
</nav>
</header>
{{#if currentListing}}
{{directory-listing items=currentListing}}
{{/if}}

View File

@ -1,18 +1,81 @@
<div class="inspect-details">
<header>
{{breadcrumb-nav currentDirPath=currentDirPath}}
<nav class="actions">
{{#if metadataHidden}}
<button {{action "toggleMetadata"}}
title="Show metadata">
{{partial "icons/arrow-from-right"}}
</button>
{{else}}
<button {{action "toggleMetadata"}}
title="Hide metadata">
{{partial "icons/arrow-to-right"}}
</button>
{{/if}}
{{#if publicItemURL}}
<a class="button" href={{publicItemURL}} target="_blank"
title="Open document in new tab">
{{partial "icons/share"}}
</a>
{{/if}}
{{#if documentIsJSON}}
<div class="button-group json-view">
<button disabled={{jsonShowTree}}
class="{{if jsonShowTree "active"}}"
title="Tree view"
{{action "showJsonTree"}}>
{{partial "icons/list"}}
</button>
<button disabled={{jsonShowSource}}
class="{{if jsonShowSource "active"}}"
title="Show source"
{{action "showJsonSource"}}>
{{partial "icons/code"}}
</button>
</div>
{{/if}}
{{#if documentIsEditable}}
<div class="button-group editable">
<button disabled={{documentHideEditor}}
class="{{if documentHideEditor "active"}}"
title="{{if documentHideEditor "Cancel editing"}}"
{{action "cancelEditor"}}>
{{partial "icons/eye"}}
</button>
<button disabled={{documentShowEditor}}
class="{{if documentShowEditor "active"}}"
{{action "showEditor"}}>
{{partial "icons/edit"}}
</button>
</div>
{{/if}}
<button class="delete" title="Delete"
{{action "deleteItem"}}>{{partial "icons/trash"}}</button>
</nav>
</header>
<div class="inspect-details {{if metadataHidden "hide-metadata"}}">
<section class="content">
{{file-preview metaData=model.documentMetaData
storage=storage}}
</section>
<section class="meta">
<dl>
<dt>Name</dt>
<dd>{{model.documentMetaData.name}}</dd>
<dt>Content type</dt>
<dd>{{model.documentMetaData.type}}</dd>
<dt>Size</dt>
<dd>{{human-file-size model.documentMetaData.size}}</dd>
<dt>Revision (ETag)</dt>
<dd>{{model.documentMetaData.etag}}</dd>
</dl>
isJSON=documentIsJSON
isEditable=documentIsEditableHide
showEditor=documentShowEditor
jsonShowTree=jsonShowTree
jsonShowSource=jsonShowSource}}
</section>
{{#unless metadataHidden}}
<section class="meta">
<dl>
<dt>Name</dt>
<dd>{{model.documentMetaData.name}}</dd>
<dt>Content type</dt>
<dd>{{model.documentMetaData.type}}</dd>
<dt>Size</dt>
<dd>{{human-file-size model.documentMetaData.size}}</dd>
<dt>Revision (ETag)</dt>
<dd>{{model.documentMetaData.etag}}</dd>
</dl>
</section>
{{/unless}}
</div>

252
package-lock.json generated
View File

@ -1,6 +1,6 @@
{
"name": "inspektor",
"version": "0.4.0",
"version": "0.9.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@ -3563,6 +3563,232 @@
"ember-cli-babel": "6.8.2"
}
},
"ember-body-class": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/ember-body-class/-/ember-body-class-0.4.0.tgz",
"integrity": "sha1-CZQkP51JeMyuwofP2+3LeLRuKMU=",
"dev": true,
"requires": {
"ember-cli-babel": "5.2.4"
},
"dependencies": {
"babel-core": {
"version": "5.8.38",
"resolved": "https://registry.npmjs.org/babel-core/-/babel-core-5.8.38.tgz",
"integrity": "sha1-H8ruedfmG3ULALjlT238nQr4ZVg=",
"dev": true,
"requires": {
"babel-plugin-constant-folding": "1.0.1",
"babel-plugin-dead-code-elimination": "1.0.2",
"babel-plugin-eval": "1.0.1",
"babel-plugin-inline-environment-variables": "1.0.1",
"babel-plugin-jscript": "1.0.4",
"babel-plugin-member-expression-literals": "1.0.1",
"babel-plugin-property-literals": "1.0.1",
"babel-plugin-proto-to-assign": "1.0.4",
"babel-plugin-react-constant-elements": "1.0.3",
"babel-plugin-react-display-name": "1.0.3",
"babel-plugin-remove-console": "1.0.1",
"babel-plugin-remove-debugger": "1.0.1",
"babel-plugin-runtime": "1.0.7",
"babel-plugin-undeclared-variables-check": "1.0.2",
"babel-plugin-undefined-to-void": "1.1.6",
"babylon": "5.8.38",
"bluebird": "2.11.0",
"chalk": "1.1.3",
"convert-source-map": "1.5.0",
"core-js": "1.2.7",
"debug": "2.6.9",
"detect-indent": "3.0.1",
"esutils": "2.0.2",
"fs-readdir-recursive": "0.1.2",
"globals": "6.4.1",
"home-or-tmp": "1.0.0",
"is-integer": "1.0.7",
"js-tokens": "1.0.1",
"json5": "0.4.0",
"lodash": "3.10.1",
"minimatch": "2.0.10",
"output-file-sync": "1.1.2",
"path-exists": "1.0.0",
"path-is-absolute": "1.0.1",
"private": "0.1.8",
"regenerator": "0.8.40",
"regexpu": "1.3.0",
"repeating": "1.1.3",
"resolve": "1.5.0",
"shebang-regex": "1.0.0",
"slash": "1.0.0",
"source-map": "0.5.7",
"source-map-support": "0.2.10",
"to-fast-properties": "1.0.3",
"trim-right": "1.0.1",
"try-resolve": "1.0.1"
}
},
"babylon": {
"version": "5.8.38",
"resolved": "https://registry.npmjs.org/babylon/-/babylon-5.8.38.tgz",
"integrity": "sha1-7JsSCxG/bM1Bc6GL8hfmC3mFn/0=",
"dev": true
},
"bluebird": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz",
"integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=",
"dev": true
},
"broccoli-babel-transpiler": {
"version": "5.7.2",
"resolved": "https://registry.npmjs.org/broccoli-babel-transpiler/-/broccoli-babel-transpiler-5.7.2.tgz",
"integrity": "sha512-vFQ+aSR9J81fm3MXXQGgDxswYINHl2p5duLvRLVnpmgPDNdpdsa30gh3xnmhzR/GwWFBfUNle7aYxthlgvsN0w==",
"dev": true,
"requires": {
"babel-core": "5.8.38",
"broccoli-funnel": "1.2.0",
"broccoli-merge-trees": "1.2.4",
"broccoli-persistent-filter": "1.4.3",
"clone": "0.2.0",
"hash-for-dep": "1.2.2",
"heimdalljs-logger": "0.1.9",
"json-stable-stringify": "1.0.1",
"rsvp": "3.6.2",
"workerpool": "2.3.0"
},
"dependencies": {
"clone": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/clone/-/clone-0.2.0.tgz",
"integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=",
"dev": true
}
}
},
"core-js": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
"integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=",
"dev": true
},
"detect-indent": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-3.0.1.tgz",
"integrity": "sha1-ncXl3bzu+DJXZLlFGwK8bVQIT3U=",
"dev": true,
"requires": {
"get-stdin": "4.0.1",
"minimist": "1.2.0",
"repeating": "1.1.3"
}
},
"ember-cli-babel": {
"version": "5.2.4",
"resolved": "https://registry.npmjs.org/ember-cli-babel/-/ember-cli-babel-5.2.4.tgz",
"integrity": "sha1-XOT0awjtb20h6Hhhn7aJcZ1ujhM=",
"dev": true,
"requires": {
"broccoli-babel-transpiler": "5.7.2",
"broccoli-funnel": "1.2.0",
"clone": "2.1.1",
"ember-cli-version-checker": "1.3.1",
"resolve": "1.5.0"
}
},
"ember-cli-version-checker": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/ember-cli-version-checker/-/ember-cli-version-checker-1.3.1.tgz",
"integrity": "sha1-C8LRNMgwFC2mS/lieg7e0QthrnI=",
"dev": true,
"requires": {
"semver": "5.4.1"
}
},
"globals": {
"version": "6.4.1",
"resolved": "https://registry.npmjs.org/globals/-/globals-6.4.1.tgz",
"integrity": "sha1-hJgDKzttHMge68X3lpDY/in6v08=",
"dev": true
},
"home-or-tmp": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-1.0.0.tgz",
"integrity": "sha1-S58eQIAMPlDGwn94FnavzOcfOYU=",
"dev": true,
"requires": {
"os-tmpdir": "1.0.2",
"user-home": "1.1.1"
}
},
"js-tokens": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-1.0.1.tgz",
"integrity": "sha1-zENaXIuUrRWst5gxQPyAGCyJrq4=",
"dev": true
},
"json5": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/json5/-/json5-0.4.0.tgz",
"integrity": "sha1-BUNS5MTIDIbAkjh31EneF2pzLI0=",
"dev": true
},
"lodash": {
"version": "3.10.1",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
"integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
"dev": true
},
"minimatch": {
"version": "2.0.10",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz",
"integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=",
"dev": true,
"requires": {
"brace-expansion": "1.1.8"
}
},
"minimist": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
"dev": true
},
"path-exists": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-1.0.0.tgz",
"integrity": "sha1-1aiZjrce83p0w06w2eum6HjuoIE=",
"dev": true
},
"repeating": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/repeating/-/repeating-1.1.3.tgz",
"integrity": "sha1-PUEUIYh3U3SU+X93+Xhfq4EPpKw=",
"dev": true,
"requires": {
"is-finite": "1.0.2"
}
},
"source-map-support": {
"version": "0.2.10",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.2.10.tgz",
"integrity": "sha1-6lo5AKHByyUJagrozFwrSxDe09w=",
"dev": true,
"requires": {
"source-map": "0.1.32"
},
"dependencies": {
"source-map": {
"version": "0.1.32",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.32.tgz",
"integrity": "sha1-yLbBZ3l7pHQKjqMyUhYv8IWRsmY=",
"dev": true,
"requires": {
"amdefine": "1.0.1"
}
}
}
}
}
},
"ember-browserify": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/ember-browserify/-/ember-browserify-1.2.0.tgz",
@ -6880,6 +7106,10 @@
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
"dev": true
},
"json-tree-view": {
"version": "github:skddc/json-tree-view#55cb3b866083bf99e1895481fb73cf9186154c5e",
"dev": true
},
"json3": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz",
@ -9177,19 +9407,19 @@
}
},
"remotestorage-widget": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/remotestorage-widget/-/remotestorage-widget-1.0.0.tgz",
"integrity": "sha512-m1zbsjvDHveJIqETzF3oaQwr4m5I7jg4vLETa7eKrXpgV7HBC5nyYv8GBclBoKrhONY4ZWzUX+3GRLyUNDdIcA==",
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/remotestorage-widget/-/remotestorage-widget-1.3.0.tgz",
"integrity": "sha512-RV9SjrSIXOcg/O6FkZzhlKTpB10vnxygErwi7ID+7urxxybTv8rPLvabsx8ahWjEHLfAeHXznmtuoz4clNc0Xw==",
"dev": true
},
"remotestoragejs": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/remotestoragejs/-/remotestoragejs-1.0.0.tgz",
"integrity": "sha512-Sq6Mj3fcGFhXFC9B1HuJR034x1Rq/7ECagSu/Z3z0FcCq2d+iM3zVVFR5zmvilbkwgYduzPZ+orOOhwK9QSCnQ==",
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/remotestoragejs/-/remotestoragejs-1.1.0.tgz",
"integrity": "sha512-No4HnSjrHYRv9m2UWGDPJjb0dyOC0F1Lhfr32dNw2PdQIXlp7pg7eJOGw/hHR6SPBkbkl6P0YEkhiFuSH7yY6g==",
"dev": true,
"requires": {
"tv4": "1.3.0",
"webfinger.js": "2.6.6",
"webfinger.js": "2.7.0",
"xhr2": "0.1.4"
}
},
@ -10981,9 +11211,9 @@
"dev": true
},
"webfinger.js": {
"version": "2.6.6",
"resolved": "https://registry.npmjs.org/webfinger.js/-/webfinger.js-2.6.6.tgz",
"integrity": "sha512-dQpuL01XtluQ9Ndgu62o3pEmIe/ssDoIE0CQsOyavGl04xyHal+Ge4gFerw5V0BFoLTQpD8ZZqaDzb43hG9atw==",
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/webfinger.js/-/webfinger.js-2.7.0.tgz",
"integrity": "sha512-l+UtsuV4zrBKyVAj9VCtwWgscTgadCsdGgL1OvbV102cvydWwJCGXlFIXauzWLzfheIDHfPNRWfgMuwyC6ZfIA==",
"dev": true,
"requires": {
"xhr2": "0.1.4"

View File

@ -1,6 +1,6 @@
{
"name": "inspektor",
"version": "0.4.0",
"version": "0.9.0",
"private": true,
"description": "Inspect the contents of your remote storage",
"license": "MIT",
@ -21,6 +21,7 @@
"devDependencies": {
"broccoli-asset-rev": "^2.4.5",
"ember-ajax": "^3.0.0",
"ember-body-class": "^0.4.0",
"ember-browserify": "^1.2.0",
"ember-cli": "~2.16.2",
"ember-cli-app-version": "^3.0.0",
@ -41,9 +42,10 @@
"ember-load-initializers": "^1.0.0",
"ember-resolver": "^4.0.0",
"ember-source": "~2.16.0",
"json-tree-view": "github:skddc/json-tree-view#bugfix/setters",
"loader.js": "^4.2.3",
"remotestorage-widget": "^1.0.0",
"remotestoragejs": "^1.0.0"
"remotestorage-widget": "^1.3.0",
"remotestoragejs": "^1.1.0"
},
"engines": {
"node": "6.* || >= 7.*"

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M296 99.5l148.5 148c4.7 4.7 4.7 12.3 0 17L296 412.5c-4.7 4.7-12.3 4.7-17 0l-7.1-7.1c-4.7-4.7-4.7-12.3 0-17l116-115.4H76c-6.6 0-12-5.4-12-12v-10c0-6.6 5.4-12 12-12h311.9L272 123.6c-4.7-4.7-4.7-12.3 0-17l7.1-7.1c4.6-4.7 12.2-4.7 16.9 0zM12 448h8c6.6 0 12-5.4 12-12V76c0-6.6-5.4-12-12-12h-8C5.4 64 0 69.4 0 76v360c0 6.6 5.4 12 12 12z"/></svg>

After

Width:  |  Height:  |  Size: 410 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M152 412.5L3.5 264.5c-4.7-4.7-4.7-12.3 0-17L152 99.5c4.7-4.7 12.3-4.7 17 0l7.1 7.1c4.7 4.7 4.7 12.3 0 17L60.1 239H372c6.6 0 12 5.4 12 12v10c0 6.6-5.4 12-12 12H60.1L176 388.4c4.7 4.7 4.7 12.3 0 17l-7.1 7.1c-4.6 4.7-12.2 4.7-16.9 0zM436 64h-8c-6.6 0-12 5.4-12 12v360c0 6.6 5.4 12 12 12h8c6.6 0 12-5.4 12-12V76c0-6.6-5.4-12-12-12z"/></svg>

After

Width:  |  Height:  |  Size: 407 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M216 412.5l-148.5-148c-4.7-4.7-4.7-12.3 0-17L216 99.5c4.7-4.7 12.3-4.7 17 0l7.1 7.1c4.7 4.7 4.7 12.3 0 17L124.1 239H436c6.6 0 12 5.4 12 12v10c0 6.6-5.4 12-12 12H124.1L240 388.4c4.7 4.7 4.7 12.3 0 17l-7.1 7.1c-4.6 4.7-12.2 4.7-16.9 0zM12 448h8c6.6 0 12-5.4 12-12V76c0-6.6-5.4-12-12-12h-8C5.4 64 0 69.4 0 76v360c0 6.6 5.4 12 12 12z"/></svg>

After

Width:  |  Height:  |  Size: 409 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M215 99.5l-7.1 7.1c-4.7 4.7-4.7 12.3 0 17l116 115.4H12c-6.6 0-12 5.4-12 12v10c0 6.6 5.4 12 12 12h311.9L208 388.4c-4.7 4.7-4.7 12.3 0 17l7.1 7.1c4.7 4.7 12.3 4.7 17 0l148.5-148c4.7-4.7 4.7-12.3 0-17L232 99.5c-4.7-4.7-12.3-4.7-17 0zM448 76v360c0 6.6-5.4 12-12 12h-8c-6.6 0-12-5.4-12-12V76c0-6.6 5.4-12 12-12h8c6.6 0 12 5.4 12 12z"/></svg>

After

Width:  |  Height:  |  Size: 407 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M464 32H48C21.5 32 0 53.5 0 80v352c0 26.5 21.5 48 48 48h416c26.5 0 48-21.5 48-48V80c0-26.5-21.5-48-48-48zM32 80c0-8.8 7.2-16 16-16h48v64H32V80zm448 352c0 8.8-7.2 16-16 16H48c-8.8 0-16-7.2-16-16V160h448v272zm0-304H128V64h336c8.8 0 16 7.2 16 16v48z"/></svg>

After

Width:  |  Height:  |  Size: 326 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M228.5 511.8l-25-7.1c-3.2-.9-5-4.2-4.1-7.4L340.1 4.4c.9-3.2 4.2-5 7.4-4.1l25 7.1c3.2.9 5 4.2 4.1 7.4L235.9 507.6c-.9 3.2-4.3 5.1-7.4 4.2zm-75.6-125.3l18.5-20.9c1.9-2.1 1.6-5.3-.5-7.1L49.9 256l121-102.5c2.1-1.8 2.4-5 .5-7.1l-18.5-20.9c-1.8-2.1-5-2.3-7.1-.4L1.7 252.3c-2.3 2-2.3 5.5 0 7.5L145.8 387c2.1 1.8 5.3 1.6 7.1-.5zm277.3.4l144.1-127.2c2.3-2 2.3-5.5 0-7.5L430.2 125.1c-2.1-1.8-5.2-1.6-7.1.4l-18.5 20.9c-1.9 2.1-1.6 5.3.5 7.1l121 102.5-121 102.5c-2.1 1.8-2.4 5-.5 7.1l18.5 20.9c1.8 2.1 5 2.3 7.1.4z"/></svg>

After

Width:  |  Height:  |  Size: 582 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M301.148 394.702l-79.2 79.19c-50.778 50.799-133.037 50.824-183.84 0-50.799-50.778-50.824-133.037 0-183.84l79.19-79.2a132.833 132.833 0 0 1 3.532-3.403c7.55-7.005 19.795-2.004 20.208 8.286.193 4.807.598 9.607 1.216 14.384.481 3.717-.746 7.447-3.397 10.096-16.48 16.469-75.142 75.128-75.3 75.286-36.738 36.759-36.731 96.188 0 132.94 36.759 36.738 96.188 36.731 132.94 0l79.2-79.2.36-.36c36.301-36.672 36.14-96.07-.37-132.58-8.214-8.214-17.577-14.58-27.585-19.109-4.566-2.066-7.426-6.667-7.134-11.67a62.197 62.197 0 0 1 2.826-15.259c2.103-6.601 9.531-9.961 15.919-7.28 15.073 6.324 29.187 15.62 41.435 27.868 50.688 50.689 50.679 133.17 0 183.851zm-90.296-93.554c12.248 12.248 26.362 21.544 41.435 27.868 6.388 2.68 13.816-.68 15.919-7.28a62.197 62.197 0 0 0 2.826-15.259c.292-5.003-2.569-9.604-7.134-11.67-10.008-4.528-19.371-10.894-27.585-19.109-36.51-36.51-36.671-95.908-.37-132.58l.36-.36 79.2-79.2c36.752-36.731 96.181-36.738 132.94 0 36.731 36.752 36.738 96.181 0 132.94-.157.157-58.819 58.817-75.3 75.286-2.651 2.65-3.878 6.379-3.397 10.096a163.156 163.156 0 0 1 1.216 14.384c.413 10.291 12.659 15.291 20.208 8.286a131.324 131.324 0 0 0 3.532-3.403l79.19-79.2c50.824-50.803 50.799-133.062 0-183.84-50.802-50.824-133.062-50.799-183.84 0l-79.2 79.19c-50.679 50.682-50.688 133.163 0 183.851z"/></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M506 114H134a6 6 0 0 1-6-6V84a6 6 0 0 1 6-6h372a6 6 0 0 1 6 6v24a6 6 0 0 1-6 6zm6 154v-24a6 6 0 0 0-6-6H134a6 6 0 0 0-6 6v24a6 6 0 0 0 6 6h372a6 6 0 0 0 6-6zm0 160v-24a6 6 0 0 0-6-6H134a6 6 0 0 0-6 6v24a6 6 0 0 0 6 6h372a6 6 0 0 0 6-6zM84 120V72c0-6.627-5.373-12-12-12H24c-6.627 0-12 5.373-12 12v48c0 6.627 5.373 12 12 12h48c6.627 0 12-5.373 12-12zm0 160v-48c0-6.627-5.373-12-12-12H24c-6.627 0-12 5.373-12 12v48c0 6.627 5.373 12 12 12h48c6.627 0 12-5.373 12-12zm0 160v-48c0-6.627-5.373-12-12-12H24c-6.627 0-12 5.373-12 12v48c0 6.627 5.373 12 12 12h48c6.627 0 12-5.373 12-12z"/></svg>

After

Width:  |  Height:  |  Size: 654 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M388.5 46.3C457.9 90.3 504 167.8 504 256c0 136.8-110.8 247.7-247.5 248C120 504.3 8.2 393 8 256.4 7.9 168 54 90.3 123.5 46.3c5.8-3.7 13.5-1.8 16.9 4.2l3.9 7c3.1 5.6 1.3 12.6-4.1 16C79.9 112 40 179.6 40 256c0 119.9 97.3 216 216 216 119.9 0 216-97.3 216-216 0-77-40.1-144.2-100.3-182.4-5.4-3.4-7.2-10.5-4.1-16l3.9-7c3.4-6.1 11.2-7.9 17-4.3zM272 276V12c0-6.6-5.4-12-12-12h-8c-6.6 0-12 5.4-12 12v264c0 6.6 5.4 12 12 12h8c6.6 0 12-5.4 12-12z"/></svg>

After

Width:  |  Height:  |  Size: 515 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M508.5 481.6l-129-129c-2.3-2.3-5.3-3.5-8.5-3.5h-10.3C395 312 416 262.5 416 208 416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c54.5 0 104-21 141.1-55.2V371c0 3.2 1.3 6.2 3.5 8.5l129 129c4.7 4.7 12.3 4.7 17 0l9.9-9.9c4.7-4.7 4.7-12.3 0-17zM208 384c-97.3 0-176-78.7-176-176S110.7 32 208 32s176 78.7 176 176-78.7 176-176 176z"/></svg>

After

Width:  |  Height:  |  Size: 407 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M564.907 196.35L388.91 12.366C364.216-13.45 320 3.746 320 40.016v88.154C154.548 130.155 0 160.103 0 331.19c0 94.98 55.84 150.231 89.13 174.571 24.233 17.722 58.021-4.992 49.68-34.51C100.937 336.887 165.575 321.972 320 320.16V408c0 36.239 44.19 53.494 68.91 27.65l175.998-184c14.79-15.47 14.79-39.83-.001-55.3zm-23.127 33.18l-176 184c-4.933 5.16-13.78 1.73-13.78-5.53V288c-171.396 0-295.313 9.707-243.98 191.7C72 453.36 32 405.59 32 331.19 32 171.18 194.886 160 352 160V40c0-7.262 8.851-10.69 13.78-5.53l176 184a7.978 7.978 0 0 1 0 11.06z"/></svg>

After

Width:  |  Height:  |  Size: 617 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M48 64h132c6.6 0 12 5.4 12 12v8c0 6.6-5.4 12-12 12H48c-8.8 0-16 7.2-16 16v288c0 8.8 7.2 16 16 16h132c6.6 0 12 5.4 12 12v8c0 6.6-5.4 12-12 12H48c-26.5 0-48-21.5-48-48V112c0-26.5 21.5-48 48-48zm279 19.5l-7.1 7.1c-4.7 4.7-4.7 12.3 0 17l132 131.4H172c-6.6 0-12 5.4-12 12v10c0 6.6 5.4 12 12 12h279.9L320 404.4c-4.7 4.7-4.7 12.3 0 17l7.1 7.1c4.7 4.7 12.3 4.7 17 0l164.5-164c4.7-4.7 4.7-12.3 0-17L344 83.5c-4.7-4.7-12.3-4.7-17 0z"/></svg>

After

Width:  |  Height:  |  Size: 502 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><path d="M616 320h-72v-48c0-26.468-21.532-48-48-48H336v-32h56c13.255 0 24-10.745 24-24V24c0-13.255-10.745-24-24-24H248c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h56v32H144c-26.467 0-48 21.532-48 48v48H24c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24V344c0-13.255-10.745-24-24-24h-40v-48c0-8.822 7.178-16 16-16h160v64h-56c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24V344c0-13.255-10.745-24-24-24h-56v-64h160c8.822 0 16 7.178 16 16v48h-40c-13.255 0-24 10.745-24 24v144c0 13.255 10.745 24 24 24h144c13.255 0 24-10.745 24-24V344c0-13.255-10.745-24-24-24zm-456 32v128H32V352h128zm224 0v128H256V352h128zM256 160V32h128v128H256zm352 320H480V352h128v128z"/></svg>

After

Width:  |  Height:  |  Size: 806 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M204.485 392l-84 84.485c-4.686 4.686-12.284 4.686-16.971 0l-84-84.485c-4.686-4.686-4.686-12.284 0-16.97l7.07-7.071c4.686-4.686 12.284-4.686 16.971 0L95 419.887V44c0-6.627 5.373-12 12-12h10c6.627 0 12 5.373 12 12v375.887l51.444-51.928c4.686-4.686 12.284-4.686 16.971 0l7.07 7.071c4.687 4.686 4.687 12.284 0 16.97zm100.492-220.355h61.547l15.5 44.317A12 12 0 0 0 393.351 224h11.552c8.31 0 14.105-8.243 11.291-16.062l-60.441-168A11.999 11.999 0 0 0 344.462 32h-16.924a11.999 11.999 0 0 0-11.291 7.938l-60.441 168c-2.813 7.82 2.981 16.062 11.291 16.062h11.271c5.12 0 9.676-3.248 11.344-8.088l15.265-44.267zm10.178-31.067l18.071-51.243c.853-2.56 1.776-5.626 2.668-8.743.871 3.134 1.781 6.219 2.644 8.806l17.821 51.18h-41.204zm-3.482 307.342c4.795-6.044-1.179 2.326 92.917-133.561a12.011 12.011 0 0 0 2.136-6.835V300c0-6.627-5.373-12-12-12h-113.84c-6.627 0-12 5.373-12 12v8.068c0 6.644 5.393 12.031 12.037 12.031 81.861.001 76.238.011 78.238-.026-2.973 3.818 4.564-7.109-92.776 133.303a12.022 12.022 0 0 0-2.142 6.847V468c0 6.627 5.373 12 12 12h119.514c6.627 0 12-5.373 12-12v-8.099c0-6.627-5.373-12-12-12-87.527-.001-81.97-.01-84.084.019z"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M19.515 120l84-84.485c4.686-4.686 12.284-4.686 16.971 0l84 84.485c4.686 4.686 4.686 12.284 0 16.97l-7.07 7.071c-4.686 4.686-12.284 4.686-16.971 0L129 92.113V468c0 6.627-5.373 12-12 12h-10c-6.627 0-12-5.373-12-12V92.113l-51.444 51.928c-4.686 4.686-12.284 4.686-16.971 0l-7.07-7.071c-4.687-4.686-4.687-12.284 0-16.97zm285.462 51.645h61.547l15.5 44.317A12 12 0 0 0 393.351 224h11.552c8.31 0 14.105-8.243 11.291-16.062l-60.441-168A11.999 11.999 0 0 0 344.462 32h-16.924a11.999 11.999 0 0 0-11.291 7.938l-60.441 168c-2.813 7.82 2.981 16.062 11.291 16.062h11.271c5.12 0 9.676-3.248 11.344-8.088l15.265-44.267zm10.178-31.067l18.071-51.243c.853-2.56 1.776-5.626 2.668-8.743.871 3.134 1.781 6.219 2.644 8.806l17.821 51.18h-41.204zm-3.482 307.342c4.795-6.044-1.179 2.326 92.917-133.561a12.011 12.011 0 0 0 2.136-6.835V300c0-6.627-5.373-12-12-12h-113.84c-6.627 0-12 5.373-12 12v8.068c0 6.644 5.393 12.031 12.037 12.031 81.861.001 76.238.011 78.238-.026-2.973 3.818 4.564-7.109-92.776 133.303a12.022 12.022 0 0 0-2.142 6.847V468c0 6.627 5.373 12 12 12h119.514c6.627 0 12-5.373 12-12v-8.099c0-6.627-5.373-12-12-12-87.527-.001-81.97-.01-84.084.019z"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M492 8h-10c-6.627 0-12 5.373-12 12v110.627C426.929 57.261 347.224 8 256 8 123.228 8 14.824 112.338 8.31 243.493 7.971 250.311 13.475 256 20.301 256h10.016c6.353 0 11.646-4.949 11.977-11.293C48.157 132.216 141.097 42 256 42c82.862 0 154.737 47.077 190.289 116H332c-6.627 0-12 5.373-12 12v10c0 6.627 5.373 12 12 12h160c6.627 0 12-5.373 12-12V20c0-6.627-5.373-12-12-12zm-.301 248h-10.015c-6.352 0-11.647 4.949-11.977 11.293C463.841 380.158 370.546 470 256 470c-82.608 0-154.672-46.952-190.299-116H180c6.627 0 12-5.373 12-12v-10c0-6.627-5.373-12-12-12H20c-6.627 0-12 5.373-12 12v160c0 6.627 5.373 12 12 12h10c6.627 0 12-5.373 12-12V381.373C85.071 454.739 164.777 504 256 504c132.773 0 241.176-104.338 247.69-235.493.339-6.818-5.165-12.507-11.991-12.507z"/></svg>

After

Width:  |  Height:  |  Size: 829 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M336 64l-33.6-44.8C293.3 7.1 279.1 0 264 0h-80c-15.1 0-29.3 7.1-38.4 19.2L112 64H24C10.7 64 0 74.7 0 88v2c0 3.3 2.7 6 6 6h26v368c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V96h26c3.3 0 6-2.7 6-6v-2c0-13.3-10.7-24-24-24h-88zM184 32h80c5 0 9.8 2.4 12.8 6.4L296 64H152l19.2-25.6c3-4 7.8-6.4 12.8-6.4zm200 432c0 8.8-7.2 16-16 16H80c-8.8 0-16-7.2-16-16V96h320v368zm-176-44V156c0-6.6 5.4-12 12-12h8c6.6 0 12 5.4 12 12v264c0 6.6-5.4 12-12 12h-8c-6.6 0-12-5.4-12-12zm-80 0V156c0-6.6 5.4-12 12-12h8c6.6 0 12 5.4 12 12v264c0 6.6-5.4 12-12 12h-8c-6.6 0-12-5.4-12-12zm160 0V156c0-6.6 5.4-12 12-12h8c6.6 0 12 5.4 12 12v264c0 6.6-5.4 12-12 12h-8c-6.6 0-12-5.4-12-12z"/></svg>

After

Width:  |  Height:  |  Size: 734 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path d="M368 64l-33.6-44.8C325.3 7.1 311.1 0 296 0h-80c-15.1 0-29.3 7.1-38.4 19.2L144 64H40c-13.3 0-24 10.7-24 24v2c0 3.3 2.7 6 6 6h20.9l33.2 372.3C78.3 493 99 512 123.9 512h264.2c24.9 0 45.6-19 47.8-43.7L469.1 96H490c3.3 0 6-2.7 6-6v-2c0-13.3-10.7-24-24-24H368zM216 32h80c5 0 9.8 2.4 12.8 6.4L328 64H184l19.2-25.6c3-4 7.8-6.4 12.8-6.4zm188 433.4c-.7 8.3-7.6 14.6-15.9 14.6H123.9c-8.3 0-15.2-6.3-15.9-14.6L75 96h362l-33 369.4z"/></svg>

After

Width:  |  Height:  |  Size: 498 B

View File

@ -0,0 +1,14 @@
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
moduleForComponent('account-info', 'Integration | Component | account info', {
integration: true
});
test('it splits the user address into username and host', function(assert) {
this.set('userAddress', 'michielbdejong@unhosted.org');
this.render(hbs`{{account-info userAddress=userAddress}}`);
assert.equal(this.$('.username').text().trim(), 'michielbdejong');
assert.equal(this.$('.host').text().trim(), '@unhosted.org');
});

View File

@ -1,24 +1,22 @@
// import { moduleForComponent, test } from 'ember-qunit';
// import hbs from 'htmlbars-inline-precompile';
//
// moduleForComponent('file-preview', 'Integration | Component | file preview', {
// integration: true
// });
//
// test('it renders', function(assert) {
// // Set any properties with this.set('myProperty', 'value');
// // Handle any actions with this.on('myAction', function(val) { ... });
//
// this.render(hbs`{{file-preview}}`);
//
// assert.equal(this.$().text().trim(), '');
//
// // Template block usage:
// this.render(hbs`
// {{#file-preview}}
// template block text
// {{/file-preview}}
// `);
//
// assert.equal(this.$().text().trim(), 'template block text');
// });
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
moduleForComponent('file-preview', 'Integration | Component | file preview', {
integration: true
});
test('it renders', function(assert) {
this.set('metaData', {
etag: "714148227",
isBinary: false,
isFolder: false,
name: "fra-pdx",
path: "trips/2018/06/19/fra-pdx",
size: 92086791,
type: "application/json"
});
this.render(hbs`{{file-preview metaData=metaData}}`);
assert.equal(this.$().text().trim(), '');
});

View File

@ -4,8 +4,89 @@ moduleFor('controller:index', 'Unit | Controller | index', {
needs: ['controller:application', 'service:storage']
});
// Replace this with your real tests.
test('it exists', function(assert) {
test('#parentDir', function(assert) {
let controller = this.subject();
assert.ok(controller);
controller.set('currentDirPath', 'islands/spain/canaries/tenerife/');
assert.equal(controller.get('parentDir'), 'islands/spain/canaries/');
});
test('#currentListingContainsDocuments', function(assert) {
let controller = this.subject();
controller.set('currentListing', [
{
"name": "spain/",
"type": "folder",
"isBinary": false,
"isFolder": true,
"size": null,
"path": "/islands/spain/",
"etag": "885098000"
}
]);
assert.notOk(controller.get('currentListingContainsDocuments'),
'returns false when no documents are present');
controller.set('currentListing', [
{
"name": "spain/",
"type": "folder",
"isBinary": false,
"isFolder": true,
"size": null,
"path": "/islands/spain/",
"etag": "885098000"
},
{
"name": "lamu",
"type": "application/json",
"isBinary": false,
"isFolder": false,
"size": 202,
"path": "/islands/lamu",
"etag": "478058546"
}
]);
assert.ok(controller.get('currentListingContainsDocuments'),
'returns true when no documents are present');
});
test('#documentCount', function(assert) {
let controller = this.subject();
controller.set('currentListing', [
{
"name": "spain/",
"type": "folder",
"isBinary": false,
"isFolder": true,
"size": null,
"path": "/islands/spain/",
"etag": "885098000"
},
{
"name": "lamu",
"type": "application/json",
"isBinary": false,
"isFolder": false,
"size": 202,
"path": "/islands/lamu",
"etag": "478058546"
},
{
"name": "dominica",
"type": "application/json",
"isBinary": false,
"isFolder": false,
"size": 202,
"path": "/islands/dominica",
"etag": "929838541"
}
]);
assert.equal(controller.get('documentCount'), 2,
'returns the number of documents in the current listing');
});

View File

@ -4,8 +4,58 @@ moduleFor('controller:inspect', 'Unit | Controller | inspect', {
needs: ['controller:application', 'service:storage']
});
// Replace this with your real tests.
test('it exists', function(assert) {
test('#publicItemURL', function(assert) {
let controller = this.subject();
assert.ok(controller);
controller.set('model', {});
controller.set('model.documentMetaData', {
"name": "banjul-the-gambia",
"path": "/documents/notes/banjul-the-gambia",
});
assert.equal(controller.get('publicItemURL'), null, 'returns null when item is not in public folder');
});
test('#documentIsJSON', function(assert) {
let controller = this.subject();
controller.set('model', {});
controller.set('model.documentMetaData', {
"name": "869575AF-84AE-49B3-8752-5782E9CA2BC5",
"type": "application/json",
"isBinary": false,
"isFolder": false,
"size": 202,
"path": "/documents/notes/869575AF-84AE-49B3-8752-5782E9CA2BC5",
"etag": "776662336"
});
assert.ok(controller.get('documentIsJSON'), 'is true when content type is JSON');
controller.set('model.documentMetaData', {
"name": "171127-1708-32c3.png",
"type": "image/png",
"isBinary": true,
"isFolder": false,
"size": 42624,
"path": "public/shares/171127-1708-32c3.png",
"etag": "894001114"
});
assert.notOk(controller.get('documentIsJSON'), 'is false when content type is not JSON');
});
test('jsonView - switch between source and tree view', function(assert) {
let controller = this.subject();
controller.set('jsonView', null);
controller.send('showJsonTree');
assert.ok(controller.get('jsonShowTree'));
assert.notOk(controller.get('jsonShowSource'));
controller.send('showJsonSource');
assert.ok(controller.get('jsonShowSource'));
assert.notOk(controller.get('jsonShowTree'));
});

View File

@ -0,0 +1,10 @@
import { moduleFor, test } from 'ember-qunit';
moduleFor('route:connect', 'Unit | Route | connect', {
needs: ['service:storage']
});
test('it exists', function(assert) {
let route = this.subject();
assert.ok(route);
});

View File

@ -0,0 +1,10 @@
import { moduleFor, test } from 'ember-qunit';
moduleFor('route:disconnect', 'Unit | Route | disconnect', {
needs: ['service:storage']
});
test('it exists', function(assert) {
let route = this.subject();
assert.ok(route);
});