Commit 42ea9c4b authored by Benjamin Fischer's avatar Benjamin Fischer
Browse files

File2Extension: added

- intended to become a drop-in replacement of the old FileExtension
parent c3e2adf4
# -*- coding: utf-8 -*-
from vispa.controller import AbstractController
from vispa.server import AbstractExtension
class File2Controller(AbstractController):
pass
class File2Extension(AbstractExtension):
def name(self):
return 'file2'
def dependencies(self):
return []
def setup(self):
self.add_controller(File2Controller())
self.add_workspace_directoy()
#file2-File2Upload>div>h3{margin:5px 0}
#file2-File2Upload>div>h3>i{margin-right:7px}
#file2-File2Upload>div>.item{border-top:1px solid #fff;margin:4px 0}
#file2-File2Upload>div>.item>*{margin:3px 0}
#file2-File2Upload>div>.item>h4{white-space:nowrap;text-overflow:ellipsis}
#file2-File2Upload>div>.item>.probar{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap}
#file2-File2Upload>div>.item>.probar>.progress-bar{-webkit-box-flex:1;-webkit-flex:1 0 1px;-ms-flex:1 0 1px;flex:1 0 1px;border-radius:3px}
#file2-File2Upload>div>.item>.probar>button{-webkit-box-flex:0;-webkit-flex:0 0 auto;-ms-flex:0 0 auto;flex:0 0 auto}
#file2-File2Upload>div>.item>.container{display:none}
.fileselector2{height:70vh}
.file2.browser{position:absolute;top:0;right:0;bottom:0;left:0;overflow:hidden;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap}
.file2.browser a{cursor:pointer}
.file2.browser>.context-menu>button{display:none}
.file2.browser>.context-menu>ul{position:fixed;top:auto;right:auto;bottom:auto;left:auto}
.file2.browser>.navigation-bar{-webkit-box-flex:0;-webkit-flex:0 0 30px;-ms-flex:0 0 30px;flex:0 0 30px;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;background-color:#f5f5f5;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}
.file2.browser>.navigation-bar>.divider{-webkit-box-flex:0;-webkit-flex:0 0 0px;-ms-flex:0 0 0px;flex:0 0 0px;height:15px;border:1px solid #888}
.file2.browser>.navigation-bar>.bookmark-button{-webkit-box-flex:0;-webkit-flex:0 0 30px;-ms-flex:0 0 30px;flex:0 0 30px;text-align:center}
.file2.browser>.navigation-bar>.bookmark-button .bookmark-item>a{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;vertical-align:middle}
.file2.browser>.navigation-bar>.bookmark-button .bookmark-item>a>div{-webkit-box-flex:1;-webkit-flex:1 0 1px;-ms-flex:1 0 1px;flex:1 0 1px}
.file2.browser>.navigation-bar>.bookmark-button .bookmark-item>a>div>input{border:0;padding:0}
.file2.browser>.navigation-bar>.bookmark-button .bookmark-item>a>span{-webkit-box-flex:0;-webkit-flex:0 0 15px;-ms-flex:0 0 15px;flex:0 0 15px;opacity:.5}
.file2.browser>.navigation-bar>.bookmark-button .bookmark-item>a>span:hover{opacity:1}
.file2.browser>.navigation-bar>.path{-webkit-box-flex:1;-webkit-flex:1 0 1px;-ms-flex:1 0 1px;flex:1 0 1px}
.file2.browser>.navigation-bar>.path>.breadcrumb{margin:0;padding:0 15px}
.file2.browser>.navigation-bar>.path>.breadcrumb>.dropok>a{background-color:#bf6!important}
.file2.browser>.navigation-bar>.path>.path-edit{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;margin:5px;background-color:#fff}
.file2.browser>.navigation-bar>.path>.path-edit>*{padding:1px 6px}
.file2.browser>.navigation-bar>.path>.path-edit input{-webkit-box-flex:1;-webkit-flex:1 0 1px;-ms-flex:1 0 1px;flex:1 0 1px;border:none}
.file2.browser>.item-container{-webkit-box-flex:1;-webkit-flex:1 0 1px;-ms-flex:1 0 1px;flex:1 0 1px}
.file2.browser>.item-container.hide-actions .actions,.file2.browser>.item-container.hide-modified .modified,.file2.browser>.item-container.hide-size .size{display:none}
.file2.browser>.item-container.mini-actions .actions span{display:none}
.file2.browser>.item-container.detail{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap}
.file2.browser>.item-container.detail>.header{-webkit-box-flex:0;-webkit-flex:0 0 30px;-ms-flex:0 0 30px;flex:0 0 30px;border-bottom:1px solid #000}
.file2.browser>.item-container.detail>.items{-webkit-box-flex:1;-webkit-flex:1 0 1px;-ms-flex:1 0 1px;flex:1 0 1px;overflow-y:scroll}
.file2.browser>.item-container.detail>.items>.item{height:36px}
.file2.browser>.item-container.detail>.items.dropok{background-color:#bf6!important}
.file2.browser>.item-container.detail>.items.dropok>.item{background:0 0}
.file2.browser>.item-container.detail>.header,.file2.browser>.item-container.detail>.items>.item{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-flex-wrap:nowrap;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}
.file2.browser>.item-container.detail>.header>div,.file2.browser>.item-container.detail>.items>.item>div{margin:3px;overflow:hidden;cursor:pointer}
.file2.browser>.item-container.detail>.header>.icon,.file2.browser>.item-container.detail>.items>.item>.icon{-webkit-box-flex:0;-webkit-flex:0 0 36px;-ms-flex:0 0 36px;flex:0 0 36px;position:relative;text-align:center}
.file2.browser>.item-container.detail>.header>.icon>i,.file2.browser>.item-container.detail>.items>.item>.icon>i{font-size:28px}
.file2.browser>.item-container.detail>.header>.icon>input,.file2.browser>.item-container.detail>.items>.item>.icon>input{position:absolute;bottom:-1px;right:2px;opacity:.7}
.file2.browser>.item-container.detail>.header>.icon>input:checked,.file2.browser>.item-container.detail>.items>.item>.icon>input:checked{opacity:1}
.file2.browser>.item-container.detail>.header>.actions,.file2.browser>.item-container.detail>.items>.item>.actions{font-size:80%}
.file2.browser>.item-container.detail>.header>.actions>a,.file2.browser>.item-container.detail>.items>.item>.actions>a{margin-right:13px}
.file2.browser>.item-container.detail>.header>.actions>a>i,.file2.browser>.item-container.detail>.items>.item>.actions>a>i{margin-right:3px}
.file2.browser>.item-container.detail>.header:not(:hover)>.actions,.file2.browser>.item-container.detail>.items>.item:not(:hover)>.actions{opacity:.4}
.file2.browser>.item-container.detail>.header.selected>.actions,.file2.browser>.item-container.detail>.items>.item.selected>.actions{opacity:1}
.file2.browser>.item-container.detail>.header>.processing,.file2.browser>.item-container.detail>.items>.item>.processing{-webkit-box-flex:0;-webkit-flex:0 0 20px;-ms-flex:0 0 20px;flex:0 0 20px}
.file2.browser>.item-container.detail>.header>.name,.file2.browser>.item-container.detail>.items>.item>.name{-webkit-box-flex:1;-webkit-flex:1 1 0px;-ms-flex:1 1 0px;flex:1 1 0px;position:relative}
.file2.browser>.item-container.detail>.header>.name>.floater,.file2.browser>.item-container.detail>.items>.item>.name>.floater{display:inline-block;max-width:100%;position:relative;visibility:hidden;white-space:nowrap}
.file2.browser>.item-container.detail>.header>.name>.floater>.flex,.file2.browser>.item-container.detail>.items>.item>.name>.floater>.flex{top:0;position:absolute;width:100%;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;visibility:visible}
.file2.browser>.item-container.detail>.header>.name>.floater>.flex>.root,.file2.browser>.item-container.detail>.items>.item>.name>.floater>.flex>.root{position:relative;-webkit-box-flex:1;-webkit-flex:1 1 0px;-ms-flex:1 1 0px;flex:1 1 0px}
.file2.browser>.item-container.detail>.header>.name>.floater>.flex>.root>div,.file2.browser>.item-container.detail>.items>.item>.name>.floater>.flex>.root>div{position:absolute;max-width:100%;overflow:hidden;text-overflow:ellipsis}
.file2.browser>.item-container.detail>.header>.name>.floater>.flex>.ext,.file2.browser>.item-container.detail>.items>.item>.name>.floater>.flex>.ext{-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0}
.file2.browser>.item-container.detail>.header>.name>input,.file2.browser>.item-container.detail>.items>.item>.name>input{width:100%}
.file2.browser>.item-container.detail>.header>.size,.file2.browser>.item-container.detail>.items>.item>.size{-webkit-box-flex:0;-webkit-flex:0 0 70px;-ms-flex:0 0 70px;flex:0 0 70px;text-align:right}
.file2.browser>.item-container.detail>.header>.modified,.file2.browser>.item-container.detail>.items>.item>.modified{text-align:right;-webkit-box-flex:0;-webkit-flex:0 0 170px;-ms-flex:0 0 170px;flex:0 0 170px}
.file2.browser>.item-container.icons{overflow-y:scroll}
.file2.browser>.item-container.icons>.items{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-flow:row wrap;-ms-flex-flow:row wrap;flex-flow:row wrap;-webkit-box-pack:start;-webkit-justify-content:flex-start;-ms-flex-pack:start;justify-content:flex-start;-webkit-box-align:stretch;-webkit-align-items:stretch;-ms-flex-align:stretch;align-items:stretch;-webkit-align-content:flex-start;-ms-flex-line-pack:start;align-content:flex-start;padding:.5em}
.file2.browser>.item-container.icons>.items>.item{-webkit-box-flex:7.5em;-webkit-flex:7.5em 0 0;-ms-flex:7.5em 0 0;flex:7.5em 0 0;max-width:7.5em;margin:.36em;padding:.24em;border-radius:.6em}
.file2.browser>.item-container.icons>.items>.item:hover{background-color:#fafafa}
.file2.browser>.item-container.icons>.items>.item:hover>.icon>input{opacity:.7}
.file2.browser>.item-container.icons>.items>.item.selected{background-color:#ccf}
.file2.browser>.item-container.icons>.items>.item>.icon{height:3.72em;position:relative;text-align:center;padding:.36em}
.file2.browser>.item-container.icons>.items>.item>.icon>i{font-size:3em}
.file2.browser>.item-container.icons>.items>.item>.icon>input{width:1.2em;height:1.2em;position:absolute;top:0;left:0;margin:0;opacity:.2}
.file2.browser>.item-container.icons>.items>.item>.icon>input:checked{opacity:1}
.file2.browser>.item-container.icons>.items>.item>.name{text-align:center;overflow-wrap:break-word;display:block;display:-webkit-box;max-height:3.6em;margin:0 auto;line-height:1.2em;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis}
.file2.browser>.filter{position:absolute;background:#fff;z-index:25;bottom:0;left:25px;border:1px solid #000;border-radius:3px 3px 0 0;border-bottom:0;padding:2px}
.file2.browser>.filter>.count{display:inline-block;min-width:35px;padding:0 1px}
.file2.browser>.filter>.count>i{margin:0 2px}
.file2.browser>.filter.error{color:#900}
.file2.browser .item-container .item.selected.odd{background-color:#ccf}
.file2.browser .item-container .item.selected.even{background-color:#c2c2ff}
.file2.browser .item-container .item.odd{background-color:#fff}
.file2.browser .item-container .item.even{background-color:#fafafa}
.file2.browser .item-container .item.drag{background-color:#fb6!important}
.file2.browser .item-container .item.drop{background-color:#bf6!important}
\ No newline at end of file
.vispa-mainview.file2-filemainview {
}
@detail-line-height: 36px;
@detail-header-height: 30px;
@icons-width: 7.5em;
@icons-max-lines: 3;
@icons-icon-padding: 0.3;
@icons-icon-lines: 2.5;
@icons-line-height: 1.2em;
@icons-select-size: 1.2em;
@navbar-height: 30px;
@item-color-base: #ffffff;
@item-color-select: #ccccff;
@item-color-drag-src: #ffbb66;
@item-color-drag-dst: #bbff66;
@item-darken-even: 2%;
#file2-File2Upload > div {
> h3 {
> i {
margin-right: 7px;
}
margin: 5px 0px;
}
> .item {
border-top: 1px solid white;
margin: 4px 0px;
> * {
margin: 3px 0px;
}
> h4 {
white-space: nowrap;
text-overflow: ellipsis;
}
> .probar {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
> .progress-bar {
flex: 1 0 1px;
border-radius: 3px;
}
> button {
flex: 0 0 auto;
}
}
> .container {
display: none;
}
}
}
.fileselector2 {
height: 70vh;
}
.file2.browser {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
overflow: hidden;
display: flex;
flex-direction: column;
flex-wrap: nowrap;
a {
cursor: pointer;
}
> .context-menu {
> button {
display: none;
}
> ul {
position: fixed;
top: auto;
right: auto;
bottom: auto;
left: auto;
}
}
> .navigation-bar {
flex: 0 0 @navbar-height;
display: flex;
background-color: #f5f5f5;
align-items: center;
> .divider {
flex: 0 0 0px;
height: @navbar-height/2;
border: 1px solid #888888;
}
> .bookmark-button {
flex: 0 0 @navbar-height;
text-align: center;
.bookmark-item {
> a {
display: flex;
vertical-align: middle;
> div {
flex: 1 0 1px;
> input {
border: 0px;
padding: 0px;
}
}
> span {
flex: 0 0 15px;
opacity: 0.5;
&:hover {
opacity: 1;
}
}
}
}
}
> .path {
flex: 1 0 1px;
> .breadcrumb {
margin: 0px;
padding: 0 15px;
> .dropok > a {
background-color: @item-color-drag-dst !important;
}
}
> .path-edit {
display: flex;
margin: 5px;
background-color: white;
> * {
padding: 1px 6px;
}
input {
flex: 1 0 1px;
border: none;
}
button {
}
}
}
}
> .item-container {
flex: 1 0 1px;
&.hide-modified .modified,
&.hide-size .size,
&.hide-actions .actions {
display: none;
}
&.mini-actions .actions span {
display: none;
}
&.detail {
display: flex;
flex-direction: column;
flex-wrap: nowrap;
> .header {
flex: 0 0 @detail-header-height;
border-bottom: 1px solid black;
}
> .items {
flex: 1 0 1px;
overflow-y: scroll;
> .item {
height: @detail-line-height;
}
&.dropok {
background-color: @item-color-drag-dst !important;
> .item {
background: none;
}
}
}
> .items > .item, > .header {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
> div {
margin: 3px;
overflow: hidden;
cursor: pointer;
}
> .icon {
flex: 0 0 @detail-line-height;
position: relative;
text-align: center;
> i {
font-size: 28px
}
> input {
position: absolute;
bottom: -1px;
right: 2px;
opacity: 0.7;
&:checked {
opacity: 1.0;
}
// pointer-events: none;
}
}
> .actions {
font-size: 80%;
> a {
margin-right: 13px;
> i {
margin-right: 3px;
}
}
// opacity: 0.5;
}
&:not(:hover) > .actions {
opacity: 0.4;
}
&.selected > .actions {
opacity: 1.0;
}
> .processing {
flex: 0 0 20px;
}
> .name {
flex: 1 1 0px;
// below is the hack do get the ellipsis before the extension if needed
position: relative;
> .floater {
display: inline-block;
max-width: 100%;
position: relative;
visibility: hidden;
white-space: nowrap;
> .flex {
top: 0;
position: absolute;
width: 100%;
display: flex;
visibility: visible;
> .root {
position: relative;
flex: 1 1 0px;
> div {
position: absolute;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
}
}
> .ext {
flex-shrink: 0;
}
}
}
> input {
width: 100%;
}
}
> .size {
flex: 0 0 70px;
text-align: right;
}
> .modified {
text-align: right;
flex: 0 0 170px;
}
}
// color for the row
}
&.icons {
overflow-y: scroll;
> .items {
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
align-items: stretch;
align-content: flex-start;
padding: 0.5em;
> .item {
flex: @icons-width 0 0;
max-width: @icons-width;
margin: 0.3 * @icons-line-height;
padding: 0.2 * @icons-line-height;
border-radius: 0.5 * @icons-line-height;
&:hover {
background-color: darken(@item-color-base, @item-darken-even);
> .icon > input {
opacity: 0.7;
}
}
&.selected {
background-color: @item-color-select;
}
> .icon {
height: (@icons-icon-lines + 2 * @icons-icon-padding) * @icons-line-height;
position: relative;
text-align: center;
padding: @icons-icon-padding * @icons-line-height;
> i {
font-size: @icons-icon-lines * @icons-line-height;
}
> input {
width: @icons-select-size;
height: @icons-select-size;
position: absolute;
top: 0px;
left: 0px;
margin: 0px;
opacity: 0.2;
&:checked {
opacity: 1.0;
}
}
}
> .name {
text-align: center;
// word-break: break-all;
overflow-wrap: break-word;
display: block;
display: -webkit-box;
// max-width: 100%;
max-height: @icons-line-height * @icons-max-lines;
margin: 0 auto;
line-height: @icons-line-height;
-webkit-line-clamp: @icons-max-lines;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
}
}
}
}
}
> .filter {
position: absolute;
background: white;
z-index: 25;
bottom: 0px;
left: 25px;
border: 1px solid black;
border-radius: 3px 3px 0 0;
border-bottom: 0px;
padding: 2px;
> .count {
display: inline-block;
min-width: 35px;
padding: 0 1px;
> i {
margin: 0 2px;
}
}
> .error {
}
&.error {
color: darken(red, 20%);
}
}
.item-container .item {
&.selected.odd {background-color: @item-color-select;}
&.selected.even {background-color: darken(@item-color-select, @item-darken-even);}
&.odd {background-color: @item-color-base;}
&.even {background-color: darken(@item-color-base, @item-darken-even);}
&.drag {background-color: @item-color-drag-src !important;}
&.drop {background-color: @item-color-drag-dst !important;}
}
}
<input
v-model="filename"
debounce="100"
placeholder="Type filename"
@keyup.enter="open"
@keyup.esc="close"
>
<div>
<h3><i class="fa fa-upload"></i>File Upload</h4>
<item v-for="(i, j) in jobs" :job="j"></item>
</div>
<li class="bookmark-item">
<a
@click="$dispatch('nav', data.path)"
>
<renamer
:title="data.path"
:value="data.name"
v-ref:renamer
@renamed="rename"
><span
>{{data.name}}</span></renamer>
<span title="Rename" @click.stop="$refs.renamer.start"><i class="fa fa-pencil"></i></span>
<span title="Remove" @click.stop="remove"><i class="fa fa-times"></i></span>
</a>
</li>
<ul class="dropdown-menu">
<bookmark-item v-for="(i, bm) in bookmarks" :data="bm"></bookmark-item>
<menu-item v-for="item in items | orderBy 'position'" :data="item" :key="$key" v-ref:items></menu-item>
</ul>
<div class="file2 browser">
<menu-context
v-ref:menu
:items="menuItems"
></menu-context>
<navbar
:path="path"
:loading="loading"
:workspace-id="workspaceId"
></navbar>
<component
:is="displayType"
:dims="dims"
:path="path"
:items="filterItems"
></component>
<div
v-show="filterActive"
:class="{
'filter': true,
'error': filterError,
}"
>
<span
class="count"
@click="filterStart"
title="number of files hidden by the filter"
><i class="fa fa-filter"></i>{{filterNum}}</span>
<input
type="text"
v-el:filter
v-model="filterText"
@keyup.esc="filterActive = false"
title="examples: foo *.bar /ba[rz]/"
>
<button
class="btn-nostyle"
@click="filterActive = false"
title="close"
><i class="fa fa-times"></i></button>
<span
class="error"
>{{filterError}}</span>
</div>
</div>
<div :class="['item-container', 'detail'].concat(breakpoints)">
<div class="header">
<div class="icon" @click="allSelected = !allSelected">
<i class="fa fa-blank"></i>
<input
type="checkbox"
v-model="allSelected"
v-indeterminate="allSelected === undefined"
/>
</div>
<div
class="name"
@click="sortMod('name')">
<i :class="sortCurr('name')"></i>
Name
</div>
<div
class="size"
@click="sortMod('size')">
<i :class="sortCurr('size')"></i>
Size
</div>
<div
class="modified"
@click="sortMod('mtime')">
<i :class="sortCurr('mtime')"></i>
Modified
</div>
</div>
<div
:class="{
items: true,
dropok: dropok,
}"
v-drop:copy.dropok="dropFilter"
>