+
\ No newline at end of file
diff --git a/packages/frontend/js/components/file/video.riot b/packages/frontend/js/components/file/video.riot
new file mode 100644
index 0000000..d6d7824
--- /dev/null
+++ b/packages/frontend/js/components/file/video.riot
@@ -0,0 +1,65 @@
+
+
+
+
+
+
handleParentClick(evnet) } if={ state.path.length > 0 }>
+
+
+
+
+
+
+ { file.name }
+
+
{ handleDirectoryClick(event, file) } }>
+
+
+
+ { file.name }
+
+
+
+
+
+
+
+
+
+
+ { handleDownload(event, file) } }>
+
+
+
+
+ { handleDelete(event, file) } }>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/packages/frontend/js/hub.js b/packages/frontend/js/hub.js
index 847b647..729d21d 100644
--- a/packages/frontend/js/hub.js
+++ b/packages/frontend/js/hub.js
@@ -3,10 +3,14 @@ import * as riot from 'riot'
import TinyNotification from '@tiny-components/notification/src/notification.riot'
riot.register('tiny-notification', TinyNotification)
+import AppFileParent from './components/file/parent.riot'
import AppFileIndex from './components/file/index.riot'
+import AppFileFiles from './components/file/files.riot'
// register components
riot.register('app-file-index', AppFileIndex)
+riot.register('app-file-parent', AppFileParent)
+riot.register('app-file-files', AppFileFiles)
// mount components
riot.mount('app-file-index')
\ No newline at end of file
diff --git a/packages/frontend/js/mixins/file.js b/packages/frontend/js/mixins/file.js
new file mode 100644
index 0000000..5875162
--- /dev/null
+++ b/packages/frontend/js/mixins/file.js
@@ -0,0 +1,99 @@
+import fileStore from './../stores/file.js'
+
+/**
+ * Mixin to Extend a Sidebar
+ *
+ * @author Björn Hase
+ * @license http://opensource.org/licenses/MIT The MIT License
+ * @link https://gitea.node001.net/tiny-components/sidebar-form
+ *
+ */
+
+export default {
+
+ state: {
+ files: [],
+ path: [],
+ marked: []
+ },
+
+ onMounted() {
+ fileStore.on('update', (data) => {
+ this.state.files = data
+ this.update()
+ })
+
+ fileStore.get(this.props.hubId)
+ },
+
+ /**
+ *
+ *
+ *
+ */
+ handleParentClick(event) {
+ this.state.path.pop()
+ fileStore.get(this.props.hubId, this.state.path)
+ },
+
+ /**
+ *
+ *
+ *
+ *
+ */
+ handleMarked(event, file) {
+
+ let exists = this.isFileInArray(file)
+
+ if (exists === false) {
+ this.state.marked.push(file)
+ } else {
+ this.state.marked.splice(this.state.marked.indexOf(file), 1)
+ }
+
+ this.update()
+ },
+
+ /**
+ *
+ * @return {Boolean} [description]
+ */
+ isFileInArray(file)
+ {
+ let exists = false
+
+ this.state.marked.forEach((f, index) => {
+ if (file.name === f.name) {
+ exists = true
+ }
+ })
+
+ return exists
+ },
+
+ handleDirectoryClick(event, file) {
+ this.state.path.push(file.name)
+ fileStore.get(this.props.hubId, this.state.path)
+ },
+
+ /**
+ *
+ * @param {[type]} event [description]
+ * @param {[type]} file [description]
+ * @return {[type]} [description]
+ */
+ handleDownload(event, file) {
+
+ },
+
+ /**
+ *
+ * @param {[type]} event [description]
+ * @param {[type]} file [description]
+ * @return {[type]} [description]
+ */
+ handleDelete(event, file) {
+
+ }
+}
\ No newline at end of file
diff --git a/packages/frontend/js/stores/file.js b/packages/frontend/js/stores/file.js
index 0de5747..075325b 100644
--- a/packages/frontend/js/stores/file.js
+++ b/packages/frontend/js/stores/file.js
@@ -20,9 +20,17 @@
* @param {object} data
*
*/
- get(id)
+ get(id, path)
{
- fetch('/api/files/v1/' + id)
+ let url = '/api/files/v1/' + id
+
+ if (path && path.length > 0) {
+ url += '?' + new URLSearchParams({
+ 'path': path.join('/')
+ })
+ }
+
+ fetch(url)
.then((response) => response.json())
.then((response) => {
this.trigger('update', response.data)
diff --git a/packages/frontend/scss/components/_file.scss b/packages/frontend/scss/components/_file.scss
new file mode 100644
index 0000000..299d8b7
--- /dev/null
+++ b/packages/frontend/scss/components/_file.scss
@@ -0,0 +1,98 @@
+/**
+ *
+ *
+ *
+ */
+
+$file__color-hover: #e3e3e3;
+
+.file {
+
+ // table to show files
+ &__table {
+ display: block;
+ width: 100%;
+
+ &-row {
+ display: flex;
+ flex-wrap: wrap;
+
+ padding: 0.25em;
+ border-bottom: $border;
+
+ &:hover {
+ background-color: $file__color-hover;
+ }
+
+ &--selected {
+ background-color: #02acff;
+
+ &:hover {
+ background-color: darken(#02acff, 10%);
+ }
+ }
+ }
+
+ &-column {
+ display: flex;
+ flex: 2;
+ align-items: center;
+
+ padding: 5px;
+
+ &--select {
+ max-width: 30px;
+
+ input[type=checkbox] {
+ position: relative;
+ display: none;
+
+ + label {
+ margin: -4px 0 0 0;
+
+ .checked {
+ display: none;
+ }
+
+ &:hover {
+ cursor: pointer;
+ }
+ }
+
+ &:checked + label .checked {
+ display: inline-block;
+ }
+
+ &:checked + label .unchecked {
+ display: none;
+ }
+ }
+
+ .checked, .unchecked {
+ vertical-align: bottom;
+ }
+ }
+
+ &--back {
+ padding: 8px 2px;
+ }
+
+ &--actions {
+ line-height: 0;
+
+ button {
+ &:disabled {
+ .icon {
+ opacity: 0.3;
+
+ &:hover {
+ cursor: not-allowed;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/packages/frontend/scss/styles.scss b/packages/frontend/scss/styles.scss
index 05b5d64..7f303df 100644
--- a/packages/frontend/scss/styles.scss
+++ b/packages/frontend/scss/styles.scss
@@ -1,6 +1,7 @@
@import
'@tiny-components/plain-ui/src/scss/plain-ui',
-
+
'components/field-error',
+ 'components/file',
'components/breadcrumb';
\ No newline at end of file
diff --git a/packages/frontend/webpack.mix.js b/packages/frontend/webpack.mix.js
index 3e98265..7b436a2 100644
--- a/packages/frontend/webpack.mix.js
+++ b/packages/frontend/webpack.mix.js
@@ -31,7 +31,10 @@ mix.webpackConfig({
}
]},
plugins: [
- new SvgSpritemapPlugin('./node_modules/@tiny-components/plain-ui/src/icons/mono-icons/svg/*.svg', {
+ new SvgSpritemapPlugin([
+ './node_modules/@tiny-components/plain-ui/src/icons/mono-icons/svg/*.svg',
+ './icons/*.svg'
+ ], {
output: {
filename: 'public/symbol-defs.svg',
chunk: {
diff --git a/packages/server/package-lock.json b/packages/server/package-lock.json
index 3d10f4a..e1457d1 100644
--- a/packages/server/package-lock.json
+++ b/packages/server/package-lock.json
@@ -190,6 +190,11 @@
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
"integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="
},
+ "dayjs": {
+ "version": "1.11.3",
+ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.3.tgz",
+ "integrity": "sha512-xxwlswWOlGhzgQ4TKzASQkUhqERI3egRNqgV4ScR8wlANA/A9tZ7miXa44vTTKEq5l7vWoL5G57bG3zA+Kow0A=="
+ },
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
diff --git a/packages/server/package.json b/packages/server/package.json
index afb8a98..4ad3cab 100644
--- a/packages/server/package.json
+++ b/packages/server/package.json
@@ -9,6 +9,7 @@
"dependencies": {
"@fastify/static": "^6.4.0",
"@fastify/view": "^7.0.0",
+ "dayjs": "^1.11.3",
"dotenv": "^16.0.1",
"fastify": "^4.0.1",
"fastify-formbody": "^5.3.0",
diff --git a/packages/server/store/file.js b/packages/server/store/file.js
index 7270954..4d0bc6e 100644
--- a/packages/server/store/file.js
+++ b/packages/server/store/file.js
@@ -1,4 +1,5 @@
-import { readdir } from 'fs/promises'
+import { readdir, stat } from 'fs/promises'
+import dayjs from 'dayjs'
/**
* getting files
@@ -33,6 +34,8 @@ class File {
errors: false
}
+ const files = []
+
try {
const files = await readdir(this.path, {
withFileTypes: true
@@ -40,18 +43,53 @@ class File {
// run through all files, add options
for (const file of files) {
+
+ // getting meta
+ const meta = await stat(this.path + '/' + file.name)
+
result['files'].push({
name: file.name,
- isDirectory: file.isDirectory()
+ is_directory: file.isDirectory(),
+ size: this.formatBytes(meta.size),
+ created_at: dayjs(meta.ctime).format('DD.MM.YYYY HH:mm'),
+ updated_at: dayjs(meta.mtime).format('DD.MM.YYYY HH:mm')
})
}
+
+ result['files'].sort(function(a, b) {
+ if (a.is_directory) {
+ return -1
+ } else {
+ return 0
+ }
+ })
} catch (error) {
- result['errors'] = error
+ result['error'] = error
}
return result
}
+ /**
+ * getting size of file
+ *
+ * @param float size
+ * @param integer precision
+ * @return string
+ */
+ formatBytes(size) {
+
+ if (size === 0) {
+ return '0 bytes'
+ }
+
+ // getting base of size
+ const base = Math.log(size) / Math.log(1024);
+ const suffixes = ['Bytes', 'KB', 'MB', 'G', 'T']
+
+ return Math.round(Math.pow(1024, base - Math.floor(base))) + ' ' + suffixes[Math.floor(base)]
+ }
+
}
export default File
\ No newline at end of file
diff --git a/public/css/styles.css b/public/css/styles.css
index 5a65ac0..56ae0b6 100644
--- a/public/css/styles.css
+++ b/public/css/styles.css
@@ -14801,6 +14801,74 @@ svg.field-choice__checked {
padding: 0 0 0 1em;
}
+/**
+ *
+ *
+ *
+ */
+.file__table {
+ display: block;
+ width: 100%;
+}
+.file__table-row {
+ display: flex;
+ flex-wrap: wrap;
+ padding: 0.25em;
+ border-bottom: 1px solid var(--border);
+}
+.file__table-row:hover {
+ background-color: #e3e3e3;
+}
+.file__table-row--selected {
+ background-color: #02acff;
+}
+.file__table-row--selected:hover {
+ background-color: #008ace;
+}
+.file__table-column {
+ display: flex;
+ flex: 2;
+ align-items: center;
+ padding: 5px;
+}
+.file__table-column--select {
+ max-width: 30px;
+}
+.file__table-column--select input[type=checkbox] {
+ position: relative;
+ display: none;
+}
+.file__table-column--select input[type=checkbox] + label {
+ margin: -4px 0 0 0;
+}
+.file__table-column--select input[type=checkbox] + label .checked {
+ display: none;
+}
+.file__table-column--select input[type=checkbox] + label:hover {
+ cursor: pointer;
+}
+.file__table-column--select input[type=checkbox]:checked + label .checked {
+ display: inline-block;
+}
+.file__table-column--select input[type=checkbox]:checked + label .unchecked {
+ display: none;
+}
+.file__table-column--select .checked, .file__table-column--select .unchecked {
+ vertical-align: bottom;
+}
+.file__table-column--back {
+ padding: 8px 2px;
+}
+.file__table-column--actions {
+ line-height: 0;
+}
+.file__table-column--actions button:disabled .icon {
+ opacity: 0.3;
+}
+.file__table-column--actions button:disabled .icon:hover {
+ cursor: not-allowed;
+}
+
.breadcrumb ul {
list-style: none;
display: flex;
diff --git a/public/js/app.js b/public/js/app.js
index 48bbf3a..c7a630a 100644
--- a/public/js/app.js
+++ b/public/js/app.js
@@ -146,11 +146,11 @@ __webpack_require__.r(__webpack_exports__);
bindingTypes,
getComponent
) => template(
- '
',
+ '
',
[
{
- redundantAttribute: 'expr18',
- selector: '[expr18]',
+ redundantAttribute: 'expr6',
+ selector: '[expr6]',
expressions: [
{
@@ -355,7 +355,7 @@ riot__WEBPACK_IMPORTED_MODULE_5__.register('field-error', _tiny_components_valid
bindingTypes,
getComponent
) => template(
- '
',
+ '
',
[
{
type: bindingTypes.TAG,
@@ -365,14 +365,14 @@ riot__WEBPACK_IMPORTED_MODULE_5__.register('field-error', _tiny_components_valid
slots: [
{
id: 'title',
- html: '
',
+ html: '
',
bindings: [
{
type: bindingTypes.IF,
evaluate: _scope => _scope.state.current._id,
- redundantAttribute: 'expr7',
- selector: '[expr7]',
+ redundantAttribute: 'expr8',
+ selector: '[expr8]',
template: template(
null,
@@ -415,8 +415,8 @@ riot__WEBPACK_IMPORTED_MODULE_5__.register('field-error', _tiny_components_valid
{
type: bindingTypes.IF,
evaluate: _scope => !_scope.state.current._id,
- redundantAttribute: 'expr8',
- selector: '[expr8]',
+ redundantAttribute: 'expr9',
+ selector: '[expr9]',
template: template(
null,
@@ -443,12 +443,12 @@ riot__WEBPACK_IMPORTED_MODULE_5__.register('field-error', _tiny_components_valid
},
{
id: 'form',
- html: '
',
+ html: '
\n name\n
\n directory\n
\n description\n
',
bindings: [
{
- redundantAttribute: 'expr9',
- selector: '[expr9]',
+ redundantAttribute: 'expr10',
+ selector: '[expr10]',
expressions: [
{
@@ -461,8 +461,8 @@ riot__WEBPACK_IMPORTED_MODULE_5__.register('field-error', _tiny_components_valid
{
type: bindingTypes.IF,
evaluate: _scope => _scope.state.current._id,
- redundantAttribute: 'expr10',
- selector: '[expr10]',
+ redundantAttribute: 'expr11',
+ selector: '[expr11]',
template: template(
null,
@@ -482,8 +482,8 @@ riot__WEBPACK_IMPORTED_MODULE_5__.register('field-error', _tiny_components_valid
{
type: bindingTypes.IF,
evaluate: _scope => _scope.state.current._rev,
- redundantAttribute: 'expr11',
- selector: '[expr11]',
+ redundantAttribute: 'expr12',
+ selector: '[expr12]',
template: template(
null,
@@ -501,8 +501,8 @@ riot__WEBPACK_IMPORTED_MODULE_5__.register('field-error', _tiny_components_valid
)
},
{
- redundantAttribute: 'expr12',
- selector: '[expr12]',
+ redundantAttribute: 'expr13',
+ selector: '[expr13]',
expressions: [
{
@@ -517,12 +517,12 @@ riot__WEBPACK_IMPORTED_MODULE_5__.register('field-error', _tiny_components_valid
evaluate: _scope => 'field-error',
slots: [],
attributes: [],
- redundantAttribute: 'expr13',
- selector: '[expr13]'
+ redundantAttribute: 'expr14',
+ selector: '[expr14]'
},
{
- redundantAttribute: 'expr14',
- selector: '[expr14]',
+ redundantAttribute: 'expr15',
+ selector: '[expr15]',
expressions: [
{
@@ -537,12 +537,12 @@ riot__WEBPACK_IMPORTED_MODULE_5__.register('field-error', _tiny_components_valid
evaluate: _scope => 'field-error',
slots: [],
attributes: [],
- redundantAttribute: 'expr15',
- selector: '[expr15]'
+ redundantAttribute: 'expr16',
+ selector: '[expr16]'
},
{
- redundantAttribute: 'expr16',
- selector: '[expr16]',
+ redundantAttribute: 'expr17',
+ selector: '[expr17]',
expressions: [
{
@@ -558,8 +558,8 @@ riot__WEBPACK_IMPORTED_MODULE_5__.register('field-error', _tiny_components_valid
evaluate: _scope => 'field-error',
slots: [],
attributes: [],
- redundantAttribute: 'expr17',
- selector: '[expr17]'
+ redundantAttribute: 'expr18',
+ selector: '[expr18]'
}
]
}
@@ -583,8 +583,8 @@ riot__WEBPACK_IMPORTED_MODULE_5__.register('field-error', _tiny_components_valid
}
],
- redundantAttribute: 'expr6',
- selector: '[expr6]'
+ redundantAttribute: 'expr7',
+ selector: '[expr7]'
}
]
),
@@ -755,13 +755,13 @@ __webpack_require__.r(__webpack_exports__);
bindingTypes,
getComponent
) => template(
- '
',
+ '
',
[
{
type: bindingTypes.IF,
evaluate: _scope => _scope.props.active,
- redundantAttribute: 'expr33',
- selector: '[expr33]',
+ redundantAttribute: 'expr47',
+ selector: '[expr47]',
template: template(
'
',
@@ -909,16 +909,16 @@ __webpack_require__.r(__webpack_exports__);
bindingTypes,
getComponent
) => template(
- '
',
+ '
',
[
{
type: bindingTypes.IF,
evaluate: _scope => _scope.state.items.length > 0,
- redundantAttribute: 'expr28',
- selector: '[expr28]',
+ redundantAttribute: 'expr35',
+ selector: '[expr35]',
template: template(
- '
',
+ '
',
[
{
expressions: [
@@ -941,7 +941,7 @@ __webpack_require__.r(__webpack_exports__);
condition: null,
template: template(
- '
',
+ '
',
[
{
expressions: [
@@ -963,8 +963,8 @@ __webpack_require__.r(__webpack_exports__);
]
},
{
- redundantAttribute: 'expr30',
- selector: '[expr30]',
+ redundantAttribute: 'expr37',
+ selector: '[expr37]',
expressions: [
{
@@ -982,8 +982,8 @@ __webpack_require__.r(__webpack_exports__);
]
),
- redundantAttribute: 'expr29',
- selector: '[expr29]',
+ redundantAttribute: 'expr36',
+ selector: '[expr36]',
itemName: 'item',
indexName: null,
evaluate: _scope => _scope.state.items
@@ -1055,11 +1055,11 @@ riot__WEBPACK_IMPORTED_MODULE_1__.register('tiny-loading', _tiny_components_load
bindingTypes,
getComponent
) => template(
- '
',
+ '
',
[
{
- redundantAttribute: 'expr19',
- selector: '[expr19]',
+ redundantAttribute: 'expr38',
+ selector: '[expr38]',
expressions: [
{
@@ -1073,12 +1073,12 @@ riot__WEBPACK_IMPORTED_MODULE_1__.register('tiny-loading', _tiny_components_load
type: bindingTypes.SLOT,
attributes: [],
name: 'title',
- redundantAttribute: 'expr20',
- selector: '[expr20]'
+ redundantAttribute: 'expr39',
+ selector: '[expr39]'
},
{
- redundantAttribute: 'expr21',
- selector: '[expr21]',
+ redundantAttribute: 'expr40',
+ selector: '[expr40]',
expressions: [
{
@@ -1092,8 +1092,8 @@ riot__WEBPACK_IMPORTED_MODULE_1__.register('tiny-loading', _tiny_components_load
type: bindingTypes.SLOT,
attributes: [],
name: 'form',
- redundantAttribute: 'expr22',
- selector: '[expr22]'
+ redundantAttribute: 'expr41',
+ selector: '[expr41]'
},
{
type: bindingTypes.TAG,
@@ -1109,12 +1109,12 @@ riot__WEBPACK_IMPORTED_MODULE_1__.register('tiny-loading', _tiny_components_load
}
],
- redundantAttribute: 'expr23',
- selector: '[expr23]'
+ redundantAttribute: 'expr42',
+ selector: '[expr42]'
},
{
- redundantAttribute: 'expr24',
- selector: '[expr24]',
+ redundantAttribute: 'expr43',
+ selector: '[expr43]',
expressions: [
{
@@ -1130,8 +1130,8 @@ riot__WEBPACK_IMPORTED_MODULE_1__.register('tiny-loading', _tiny_components_load
]
},
{
- redundantAttribute: 'expr25',
- selector: '[expr25]',
+ redundantAttribute: 'expr44',
+ selector: '[expr44]',
expressions: [
{
@@ -1276,16 +1276,16 @@ __webpack_require__.r(__webpack_exports__);
bindingTypes,
getComponent
) => template(
- '
',
+ '
',
[
{
type: bindingTypes.IF,
evaluate: _scope => _scope.state.errors.length > 0,
- redundantAttribute: 'expr31',
- selector: '[expr31]',
+ redundantAttribute: 'expr45',
+ selector: '[expr45]',
template: template(
- '
',
+ '
',
[
{
type: bindingTypes.EACH,
@@ -1312,8 +1312,8 @@ __webpack_require__.r(__webpack_exports__);
]
),
- redundantAttribute: 'expr32',
- selector: '[expr32]',
+ redundantAttribute: 'expr46',
+ selector: '[expr46]',
itemName: 'error',
indexName: null,
evaluate: _scope => _scope.state.errors
diff --git a/public/js/hub.js b/public/js/hub.js
index 62f10b1..143fa77 100644
--- a/public/js/hub.js
+++ b/public/js/hub.js
@@ -93,9 +93,9 @@ const observable = function(el) { // eslint-disable-line
/***/ }),
-/***/ "./js/components/file/index.riot":
+/***/ "./js/components/file/files.riot":
/*!***************************************!*\
- !*** ./js/components/file/index.riot ***!
+ !*** ./js/components/file/files.riot ***!
\***************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
@@ -104,26 +104,30 @@ __webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
-/* harmony import */ var _stores_file_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./../../stores/file.js */ "./js/stores/file.js");
+/* harmony import */ var _mixins_file_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./../../mixins/file.js */ "./js/mixins/file.js");
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
css: null,
- exports: {
- state: {
- files: []
- },
+ exports: () => {
+ return {
- onMounted()
- {
- _stores_file_js__WEBPACK_IMPORTED_MODULE_0__["default"].on('update', (data) => {
- this.state.files = data
- this.update()
- })
+ ..._mixins_file_js__WEBPACK_IMPORTED_MODULE_0__["default"], // adding basic funtion for sidebar
- _stores_file_js__WEBPACK_IMPORTED_MODULE_0__["default"].get(this.props.hubId)
- }
+ rowClasses(file) {
+ const classes = [
+ 'file__table-row'
+ ]
+
+ if (this.isFileInArray(file)) {
+ classes.push('file__table-row--selected')
+ }
+
+ return classes.join(' ')
+ }
+
+ }
},
template: (
@@ -132,61 +136,467 @@ __webpack_require__.r(__webpack_exports__);
bindingTypes,
getComponent
) => template(
- '
',
+ '
',
[
+ {
+ type: bindingTypes.IF,
+ evaluate: _scope => _scope.state.path.length > 0,
+ redundantAttribute: 'expr24',
+ selector: '[expr24]',
+
+ template: template(
+ null,
+ [
+ {
+ type: bindingTypes.TAG,
+ getComponent: getComponent,
+ evaluate: _scope => 'app-file-parent',
+ slots: [],
+
+ attributes: [
+ {
+ type: expressionTypes.ATTRIBUTE,
+ name: 'handleClick',
+ evaluate: _scope => (event) => _scope.handleParentClick(_scope.evnet)
+ }
+ ]
+ }
+ ]
+ )
+ },
{
type: bindingTypes.EACH,
getKey: null,
condition: null,
template: template(
- '
',
+ '
',
[
+ {
+ expressions: [
+ {
+ type: expressionTypes.ATTRIBUTE,
+ name: 'class',
+ evaluate: _scope => _scope.rowClasses(_scope.file)
+ }
+ ]
+ },
+ {
+ redundantAttribute: 'expr26',
+ selector: '[expr26]',
+
+ expressions: [
+ {
+ type: expressionTypes.EVENT,
+ name: 'onchange',
+ evaluate: _scope => (event) => { _scope.handleMarked(event, _scope.file) }
+ }
+ ]
+ },
{
redundantAttribute: 'expr27',
selector: '[expr27]',
expressions: [
{
- type: expressionTypes.TEXT,
- childNodeIndex: 0,
+ type: expressionTypes.ATTRIBUTE,
+ name: 'id',
evaluate: _scope => [
- _scope.file.name
+ 'marked_',
+ _scope.index
].join(
''
)
- },
+ }
+ ]
+ },
+ {
+ redundantAttribute: 'expr28',
+ selector: '[expr28]',
+
+ expressions: [
{
type: expressionTypes.ATTRIBUTE,
- name: 'href',
+ name: 'for',
evaluate: _scope => [
- '/file/',
- _scope.file.name
+ 'marked_',
+ _scope.index
].join(
''
)
}
]
+ },
+ {
+ type: bindingTypes.IF,
+ evaluate: _scope => !_scope.file.is_directory,
+ redundantAttribute: 'expr29',
+ selector: '[expr29]',
+
+ template: template(
+ ' ',
+ [
+ {
+ expressions: [
+ {
+ type: expressionTypes.TEXT,
+ childNodeIndex: 0,
+
+ evaluate: _scope => [
+ _scope.file.name
+ ].join(
+ ''
+ )
+ }
+ ]
+ }
+ ]
+ )
+ },
+ {
+ type: bindingTypes.IF,
+ evaluate: _scope => _scope.file.is_directory,
+ redundantAttribute: 'expr30',
+ selector: '[expr30]',
+
+ template: template(
+ '
',
+ [
+ {
+ expressions: [
+ {
+ type: expressionTypes.TEXT,
+ childNodeIndex: 1,
+
+ evaluate: _scope => [
+ _scope.file.name
+ ].join(
+ ''
+ )
+ },
+ {
+ type: expressionTypes.EVENT,
+ name: 'onclick',
+ evaluate: _scope => (event) => { _scope.handleDirectoryClick(event, _scope.file) }
+ }
+ ]
+ }
+ ]
+ )
+ },
+ {
+ type: bindingTypes.IF,
+ evaluate: _scope => !_scope.file.is_directory,
+ redundantAttribute: 'expr31',
+ selector: '[expr31]',
+
+ template: template(
+ ' ',
+ [
+ {
+ expressions: [
+ {
+ type: expressionTypes.TEXT,
+ childNodeIndex: 0,
+ evaluate: _scope => _scope.file.size
+ }
+ ]
+ }
+ ]
+ )
+ },
+ {
+ redundantAttribute: 'expr32',
+ selector: '[expr32]',
+
+ expressions: [
+ {
+ type: expressionTypes.TEXT,
+ childNodeIndex: 0,
+ evaluate: _scope => _scope.file.updated_at
+ }
+ ]
+ },
+ {
+ redundantAttribute: 'expr33',
+ selector: '[expr33]',
+
+ expressions: [
+ {
+ type: expressionTypes.EVENT,
+ name: 'onclick',
+ evaluate: _scope => (event) => { _scope.handleDownload(event, _scope.file) }
+ }
+ ]
+ },
+ {
+ redundantAttribute: 'expr34',
+ selector: '[expr34]',
+
+ expressions: [
+ {
+ type: expressionTypes.EVENT,
+ name: 'onclick',
+ evaluate: _scope => (event) => { _scope.handleDelete(event, _scope.file) }
+ }
+ ]
}
]
),
- redundantAttribute: 'expr26',
- selector: '[expr26]',
+ redundantAttribute: 'expr25',
+ selector: '[expr25]',
itemName: 'file',
- indexName: null,
+ indexName: 'index',
evaluate: _scope => _scope.state.files
}
]
),
+ name: 'app-file-files'
+});
+
+/***/ }),
+
+/***/ "./js/components/file/index.riot":
+/*!***************************************!*\
+ !*** ./js/components/file/index.riot ***!
+ \***************************************/
+/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
+/* harmony export */ });
+/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
+ css: null,
+
+ exports: {
+ state: {
+ view: 'files',
+ types: [
+ 'files',
+ 'audio',
+ 'video',
+ 'image',
+ 'document'
+ ]
+ },
+
+ /**
+ * add selected-class if type match
+ *
+ * @param {string} type
+ * @return {string}
+ *
+ */
+ tabClasses(type) {
+ const classes = [
+ 'tabs__item'
+ ]
+
+ if (type === this.state.view) {
+ classes.push('tabs__item--selected')
+ }
+
+ return classes.join(' ')
+ },
+
+ /**
+ * change type
+ *
+ * @param {object} event
+ * @param {string} type
+ * @return {string}
+ *
+ */
+ handleTabClick(event, type) {
+ this.state.view = type
+ this.update()
+ }
+ },
+
+ template: (
+ template,
+ expressionTypes,
+ bindingTypes,
+ getComponent
+ ) => template(
+ '
',
+ [
+ {
+ type: bindingTypes.EACH,
+ getKey: null,
+ condition: null,
+
+ template: template(
+ ' ',
+ [
+ {
+ expressions: [
+ {
+ type: expressionTypes.TEXT,
+ childNodeIndex: 0,
+
+ evaluate: _scope => [
+ _scope.type
+ ].join(
+ ''
+ )
+ },
+ {
+ type: expressionTypes.ATTRIBUTE,
+ name: 'class',
+ evaluate: _scope => _scope.tabClasses(_scope.type)
+ },
+ {
+ type: expressionTypes.EVENT,
+ name: 'onclick',
+ evaluate: _scope => (event) => { _scope.handleTabClick(event, _scope.type) }
+ }
+ ]
+ }
+ ]
+ ),
+
+ redundantAttribute: 'expr20',
+ selector: '[expr20]',
+ itemName: 'type',
+ indexName: null,
+ evaluate: _scope => _scope.state.types
+ },
+ {
+ type: bindingTypes.IF,
+ evaluate: _scope => _scope.state.view === 'files',
+ redundantAttribute: 'expr21',
+ selector: '[expr21]',
+
+ template: template(
+ null,
+ [
+ {
+ type: bindingTypes.TAG,
+ getComponent: getComponent,
+ evaluate: _scope => 'app-file-files',
+ slots: [],
+
+ attributes: [
+ {
+ type: expressionTypes.ATTRIBUTE,
+ name: 'hub-id',
+ evaluate: _scope => _scope.props.hubId
+ }
+ ]
+ }
+ ]
+ )
+ },
+ {
+ type: bindingTypes.IF,
+ evaluate: _scope => _scope.state.view === 'video',
+ redundantAttribute: 'expr22',
+ selector: '[expr22]',
+
+ template: template(
+ null,
+ [
+ {
+ type: bindingTypes.TAG,
+ getComponent: getComponent,
+ evaluate: _scope => 'app-file-audio',
+ slots: [],
+
+ attributes: [
+ {
+ type: expressionTypes.ATTRIBUTE,
+ name: 'hub-id',
+ evaluate: _scope => _scope.props.hubId
+ }
+ ]
+ }
+ ]
+ )
+ },
+ {
+ type: bindingTypes.IF,
+ evaluate: _scope => _scope.state.view === 'audio',
+ redundantAttribute: 'expr23',
+ selector: '[expr23]',
+
+ template: template(
+ null,
+ [
+ {
+ type: bindingTypes.TAG,
+ getComponent: getComponent,
+ evaluate: _scope => 'app-file-video',
+ slots: [],
+
+ attributes: [
+ {
+ type: expressionTypes.ATTRIBUTE,
+ name: 'hub-id',
+ evaluate: _scope => _scope.props.hubId
+ }
+ ]
+ }
+ ]
+ )
+ }
+ ]
+ ),
+
name: 'app-file-index'
});
/***/ }),
+/***/ "./js/components/file/parent.riot":
+/*!****************************************!*\
+ !*** ./js/components/file/parent.riot ***!
+ \****************************************/
+/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
+/* harmony export */ });
+/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
+ css: null,
+ exports: {},
+
+ template: (
+ template,
+ expressionTypes,
+ bindingTypes,
+ getComponent
+ ) => template(
+ '
',
+ [
+ {
+ redundantAttribute: 'expr19',
+ selector: '[expr19]',
+
+ expressions: [
+ {
+ type: expressionTypes.EVENT,
+ name: 'onclick',
+ evaluate: _scope => (event) => { _scope.props.handleClick(event, _scope) }
+ }
+ ]
+ }
+ ]
+ ),
+
+ name: 'app-file-parent'
+});
+
+/***/ }),
+
/***/ "./node_modules/@tiny-components/notification/src/notification.riot":
/*!**************************************************************************!*\
!*** ./node_modules/@tiny-components/notification/src/notification.riot ***!
@@ -320,16 +730,16 @@ __webpack_require__.r(__webpack_exports__);
bindingTypes,
getComponent
) => template(
- '
',
+ '
',
[
{
type: bindingTypes.IF,
evaluate: _scope => _scope.state.items.length > 0,
- redundantAttribute: 'expr28',
- selector: '[expr28]',
+ redundantAttribute: 'expr35',
+ selector: '[expr35]',
template: template(
- '
',
+ '
',
[
{
expressions: [
@@ -352,7 +762,7 @@ __webpack_require__.r(__webpack_exports__);
condition: null,
template: template(
- '
',
+ '
',
[
{
expressions: [
@@ -374,8 +784,8 @@ __webpack_require__.r(__webpack_exports__);
]
},
{
- redundantAttribute: 'expr30',
- selector: '[expr30]',
+ redundantAttribute: 'expr37',
+ selector: '[expr37]',
expressions: [
{
@@ -393,8 +803,8 @@ __webpack_require__.r(__webpack_exports__);
]
),
- redundantAttribute: 'expr29',
- selector: '[expr29]',
+ redundantAttribute: 'expr36',
+ selector: '[expr36]',
itemName: 'item',
indexName: null,
evaluate: _scope => _scope.state.items
@@ -478,6 +888,110 @@ __webpack_require__.r(__webpack_exports__);
/***/ }),
+/***/ "./js/mixins/file.js":
+/*!***************************!*\
+ !*** ./js/mixins/file.js ***!
+ \***************************/
+/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export */ __webpack_require__.d(__webpack_exports__, {
+/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
+/* harmony export */ });
+/* harmony import */ var _stores_file_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./../stores/file.js */ "./js/stores/file.js");
+
+/**
+ * Mixin to Extend a Sidebar
+ *
+ * @author Björn Hase
+ * @license http://opensource.org/licenses/MIT The MIT License
+ * @link https://gitea.node001.net/tiny-components/sidebar-form
+ *
+ */
+
+/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
+ state: {
+ files: [],
+ path: [],
+ marked: []
+ },
+ onMounted: function onMounted() {
+ var _this = this;
+
+ _stores_file_js__WEBPACK_IMPORTED_MODULE_0__["default"].on('update', function (data) {
+ _this.state.files = data;
+
+ _this.update();
+ });
+ _stores_file_js__WEBPACK_IMPORTED_MODULE_0__["default"].get(this.props.hubId);
+ },
+
+ /**
+ *
+ *
+ *
+ */
+ handleParentClick: function handleParentClick(event) {
+ this.state.path.pop();
+ _stores_file_js__WEBPACK_IMPORTED_MODULE_0__["default"].get(this.props.hubId, this.state.path);
+ },
+
+ /**
+ *
+ *
+ *
+ *
+ */
+ handleMarked: function handleMarked(event, file) {
+ var exists = this.isFileInArray(file);
+
+ if (exists === false) {
+ this.state.marked.push(file);
+ } else {
+ this.state.marked.splice(this.state.marked.indexOf(file), 1);
+ }
+
+ this.update();
+ },
+
+ /**
+ *
+ * @return {Boolean} [description]
+ */
+ isFileInArray: function isFileInArray(file) {
+ var exists = false;
+ this.state.marked.forEach(function (f, index) {
+ if (file.name === f.name) {
+ exists = true;
+ }
+ });
+ return exists;
+ },
+ handleDirectoryClick: function handleDirectoryClick(event, file) {
+ this.state.path.push(file.name);
+ _stores_file_js__WEBPACK_IMPORTED_MODULE_0__["default"].get(this.props.hubId, this.state.path);
+ },
+
+ /**
+ *
+ * @param {[type]} event [description]
+ * @param {[type]} file [description]
+ * @return {[type]} [description]
+ */
+ handleDownload: function handleDownload(event, file) {},
+
+ /**
+ *
+ * @param {[type]} event [description]
+ * @param {[type]} file [description]
+ * @return {[type]} [description]
+ */
+ handleDelete: function handleDelete(event, file) {}
+});
+
+/***/ }),
+
/***/ "./js/stores/file.js":
/*!***************************!*\
!*** ./js/stores/file.js ***!
@@ -511,10 +1025,18 @@ __webpack_require__.r(__webpack_exports__);
* @param {object} data
*
*/
- get: function get(id) {
+ get: function get(id, path) {
var _this = this;
- fetch('/api/files/v1/' + id).then(function (response) {
+ var url = '/api/files/v1/' + id;
+
+ if (path && path.length > 0) {
+ url += '?' + new URLSearchParams({
+ 'path': path.join('/')
+ });
+ }
+
+ fetch(url).then(function (response) {
return response.json();
}).then(function (response) {
_this.trigger('update', response.data);
@@ -3289,13 +3811,19 @@ var __webpack_exports__ = {};
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var riot__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! riot */ "./node_modules/riot/riot.esm.js");
/* harmony import */ var _tiny_components_notification_src_notification_riot__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @tiny-components/notification/src/notification.riot */ "./node_modules/@tiny-components/notification/src/notification.riot");
-/* harmony import */ var _components_file_index_riot__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./components/file/index.riot */ "./js/components/file/index.riot");
+/* harmony import */ var _components_file_parent_riot__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./components/file/parent.riot */ "./js/components/file/parent.riot");
+/* harmony import */ var _components_file_index_riot__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./components/file/index.riot */ "./js/components/file/index.riot");
+/* harmony import */ var _components_file_files_riot__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./components/file/files.riot */ "./js/components/file/files.riot");
riot__WEBPACK_IMPORTED_MODULE_1__.register('tiny-notification', _tiny_components_notification_src_notification_riot__WEBPACK_IMPORTED_MODULE_0__["default"]);
+
+
// register components
-riot__WEBPACK_IMPORTED_MODULE_1__.register('app-file-index', _components_file_index_riot__WEBPACK_IMPORTED_MODULE_2__["default"]); // mount components
+riot__WEBPACK_IMPORTED_MODULE_1__.register('app-file-index', _components_file_index_riot__WEBPACK_IMPORTED_MODULE_3__["default"]);
+riot__WEBPACK_IMPORTED_MODULE_1__.register('app-file-parent', _components_file_parent_riot__WEBPACK_IMPORTED_MODULE_2__["default"]);
+riot__WEBPACK_IMPORTED_MODULE_1__.register('app-file-files', _components_file_files_riot__WEBPACK_IMPORTED_MODULE_4__["default"]); // mount components
riot__WEBPACK_IMPORTED_MODULE_1__.mount('app-file-index');
})();
diff --git a/public/symbol-defs.svg b/public/symbol-defs.svg
index 250cd5e..b05daad 100644
--- a/public/symbol-defs.svg
+++ b/public/symbol-defs.svg
@@ -1 +1 @@
-
add archive arrow-down arrow-left-down arrow-left-up arrow-left arrow-right-down arrow-right-up arrow-right arrow-up attachment backspace ban bar-chart-alt bar-chart board bold book bookmark calendar call camera caret-down caret-left caret-right caret-up check checkbox-checked checkbox chevron-double-down chevron-double-left chevron-double-right chevron-double-up chevron-down chevron-left chevron-right chevron-up circle-add circle-arrow-down circle-arrow-left circle-arrow-right circle-arrow-up circle-check circle-error circle-help circle-information circle-remove circle-warning circle clipboard-check clipboard-list clipboard clock close cloud-download cloud-upload cloud cloudy compass computer copy credit-card database delete-alt delete document-add document-check document-download document-empty document-remove document download drag drop edit-alt edit email enter expand export external-link eye-off eye favorite filter-1 filter-alt filter flag fog folder-add folder-check folder-download folder-remove folder grid heart home image inbox italic laptop layers layout link-alt link list location lock log-in log-out map megaphone message-alt message minimize mobile moon next notification-off notification options-horizontal options-vertical pause pen percentage pin play previous print rain refresh remove reorder-alt reorder repeat save search select send settings share shopping-cart-add shopping-cart shuffle snow snowflake sort speakers stop storm strikethrough sun sunrise-alt sunrise sunset switch table tablet tag temperature text three-rows two-columns two-rows underline undo unlock user-add user-check user-remove user users volume-off volume-up warning webcam wind window zoom-in zoom-out
\ No newline at end of file
+
add archive arrow-down arrow-left-down arrow-left-up arrow-left arrow-right-down arrow-right-up arrow-right arrow-up attachment backspace ban bar-chart-alt bar-chart board bold book bookmark calendar call camera caret-down caret-left caret-right caret-up check checkbox-checked checkbox chevron-double-down chevron-double-left chevron-double-right chevron-double-up chevron-down chevron-left chevron-right chevron-up circle-add circle-arrow-down circle-arrow-left circle-arrow-right circle-arrow-up circle-check circle-error circle-help circle-information circle-remove circle-warning circle clipboard-check clipboard-list clipboard clock close cloud-download cloud-upload cloud cloudy compass computer copy credit-card database delete-alt delete document-add document-check document-download document-empty document-remove document download drag drop edit-alt edit email enter expand export external-link eye-off eye favorite filter-1 filter-alt filter flag fog folder-add folder-check folder-download folder-remove folder grid heart home image inbox italic laptop layers layout link-alt link list location lock log-in log-out map megaphone message-alt message minimize mobile moon next notification-off notification options-horizontal options-vertical pause pen percentage pin play previous print rain refresh remove reorder-alt reorder repeat save search select send settings share shopping-cart-add shopping-cart shuffle snow snowflake sort speakers stop storm strikethrough sun sunrise-alt sunrise sunset switch table tablet tag temperature text three-rows two-columns two-rows underline undo unlock user-add user-check user-remove user users volume-off volume-up warning webcam wind window zoom-in zoom-out back checkbox_checked checkbox
\ No newline at end of file