Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
7da482fc97 | ||
|
8899a291fc | ||
b0a5376733 | |||
f5ccb0403e | |||
837a9c734e | |||
fad181c65e | |||
02d2fc1ad2 | |||
c037fc6eac | |||
|
da7c230927 | ||
|
9a8e22230d |
@ -1,6 +0,0 @@
|
||||
pipeline:
|
||||
build_ui:
|
||||
image: node
|
||||
commands:
|
||||
- npm install
|
||||
- npm run build
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,6 +1,4 @@
|
||||
*~
|
||||
/tags
|
||||
/node_modules
|
||||
/build/*
|
||||
!/build/lib.js
|
||||
!/build/lib.js.map
|
||||
/build
|
13
README.md
13
README.md
@ -1,5 +1,4 @@
|
||||
![build status](https://ci.drone1.basehosts.de/api/badges/panel/baseui/status.svg)
|
||||
|
||||
[![pipeline status](https://git.basehosts.de:20443/panel/basispanel-ui/badges/master/pipeline.svg)](https://git.basehosts.de:20443/panel/basispanel-ui/commits/master)
|
||||
# basispanel UI
|
||||
|
||||
|
||||
@ -17,8 +16,8 @@
|
||||
|
||||
```bash
|
||||
# falls nicht bereits vorhanden
|
||||
git clone ssh://git@gitbase.de:2222/panel/baseui.git
|
||||
cd baseui
|
||||
git clone ssh://git@git.basehosts.de:22234/panel/basispanel-ui.git
|
||||
cd basispanel-ui
|
||||
|
||||
# die Branch auschecken, für die man verantwortlich ist
|
||||
git checkout matdev # z.B. für Mathias
|
||||
@ -38,7 +37,7 @@ npm run serve
|
||||
### Windows
|
||||
|
||||
- z.B. SourceTree für GIT
|
||||
- Repository `ssh://git@gitbase.de:2222/panel/baseui.git` clonen
|
||||
- Repository `ssh://git@git.basehosts.de:22234/panel/basispanel-ui.git` clonen
|
||||
- Branch wechseln (`matdev` für Mathias)
|
||||
- Konsole (cmd oder PowerShell) aufrufen
|
||||
- ins Verzeichnis ..../basispanel-ui wechseln
|
||||
@ -81,7 +80,7 @@ git push
|
||||
|
||||
## Build-Prozess
|
||||
|
||||
- wird auf Drone-Server durch `.drone.yml` automatisch erledigt
|
||||
- wird auf Gitlab-Server/Runner durch `.gitlab-ci.yml` automatisch erledigt
|
||||
|
||||
```bash
|
||||
# Module installieren (erzeugt node_modules/)
|
||||
@ -103,6 +102,8 @@ npm run build
|
||||
- in `.gitlab.yml` ist der Deploy für alle Branches auf "http://ui.basispanel.de/" eingerichtet
|
||||
- master: http://ui.basispanel.de/master/
|
||||
- matdev: http://ui.basispanel.de/matdev/
|
||||
- die jeweiligen URL's sind auch unter Gitlab Environments im Projekt zu finden
|
||||
- sollte mal ein automatische Deploy (fltp mirror) nicht alle geänderten Dateien kopieren, gibt es einen `deploy_fullsync` in Gitlab Pipelines, den man manuell anstoßen kann
|
||||
|
||||
|
||||
## bei Problemen
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 133 KiB |
13
build/lib.js
13
build/lib.js
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -2,41 +2,46 @@
|
||||
"ui": {
|
||||
"title": "MyApp",
|
||||
"api": {
|
||||
"baseURL": "https://www.basispanel.de/api/v1/"
|
||||
"baseURL": "https://cx20.basehosts.de/api/v1/"
|
||||
},
|
||||
"navigation": {
|
||||
"main": [
|
||||
{
|
||||
"name": "Dashboard",
|
||||
"to": "/",
|
||||
"icon": "baseicon-compass"
|
||||
"icon": "icon-compass"
|
||||
},
|
||||
{
|
||||
"name": "Userlist",
|
||||
"to": "/userlist",
|
||||
"icon": "baseicon-contacts"
|
||||
"icon": "icon-contacts"
|
||||
},
|
||||
{
|
||||
"name": "Domainlist",
|
||||
"to": "/domainlist",
|
||||
"icon": "baseicon-contacts"
|
||||
"icon": "icon-world"
|
||||
},
|
||||
{
|
||||
"name": "Medien",
|
||||
"to": "/medialist",
|
||||
"icon": "icon-images"
|
||||
},
|
||||
{
|
||||
"name": "Settings",
|
||||
"to": "/settings",
|
||||
"icon": "baseicon-cog"
|
||||
"icon": "icon-cog"
|
||||
}
|
||||
],
|
||||
"profile": [
|
||||
{
|
||||
"name": "Profile anpassen",
|
||||
"to": "/profile",
|
||||
"icon": "baseicon-color-wand"
|
||||
"icon": "icon-color-wand"
|
||||
},
|
||||
{
|
||||
"name": "Logout",
|
||||
"to": "/logout",
|
||||
"icon": "baseicon-log-out"
|
||||
"icon": "icon-log-out"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -62,6 +67,11 @@
|
||||
"to": "/domainlist",
|
||||
"content": "<domainlist></domainlist>"
|
||||
},
|
||||
{
|
||||
"name": "Medialist",
|
||||
"to": "/medialist",
|
||||
"content": "<medialist></medialist>"
|
||||
},
|
||||
{
|
||||
"name": "Settings",
|
||||
"to": "/settings",
|
||||
|
@ -10,7 +10,7 @@
|
||||
<div id="vue-app">
|
||||
<div is="app">Lade, bitte warten...</div>
|
||||
</div>
|
||||
<script src="build/main.js"></script>
|
||||
<script src="build/baseui-main.bundle.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
9057
package-lock.json
generated
9057
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
40
package.json
40
package.json
@ -1,10 +1,9 @@
|
||||
{
|
||||
"name": "baseui",
|
||||
"name": "basispanel-ui",
|
||||
"repository": "ssh://git@git.basehosts.de:22234/panel/basispanel-ui.git",
|
||||
"version": "0.1.0",
|
||||
"description": "JS UI for Basispanel Server Management",
|
||||
"main": "build/lib.js",
|
||||
"jsnext:main": "build/lib.js",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"serve": "WEBPACK_ENV=dev webpack-dev-server --inline --hot --host 0.0.0.0",
|
||||
"dev": "WEBPACK_ENV=dev webpack --progress --colors --watch",
|
||||
@ -17,35 +16,34 @@
|
||||
"license": "UNLICENSED",
|
||||
"private": true,
|
||||
"devDependencies": {
|
||||
"babel-core": "^6.26.3",
|
||||
"babel-core": "^6.26.0",
|
||||
"babel-eslint": "^7.2.3",
|
||||
"babel-loader": "^7.1.5",
|
||||
"babel-loader": "^7.1.2",
|
||||
"babel-plugin-syntax-dynamic-import": "^6.18.0",
|
||||
"babel-preset-es2015": "^6.24.1",
|
||||
"css-loader": "^0.28.11",
|
||||
"eslint": "^4.19.1",
|
||||
"css-loader": "^0.28.5",
|
||||
"eslint": "^4.5.0",
|
||||
"eslint-loader": "^1.9.0",
|
||||
"eslint-plugin-vue": "^3.14.0",
|
||||
"less": "^3.8.1",
|
||||
"less-loader": "^4.1.0",
|
||||
"url-loader": "^0.6.2",
|
||||
"vue-hot-reload-api": "^2.3.1",
|
||||
"eslint-plugin-vue": "^3.12.0",
|
||||
"file-loader": "^0.11.2",
|
||||
"less": "^2.7.2",
|
||||
"less-loader": "^4.0.5",
|
||||
"vue-hot-reload-api": "^2.1.0",
|
||||
"vue-html-loader": "^1.2.4",
|
||||
"vue-loader": "^13.7.3",
|
||||
"vue-template-compiler": "^2.5.17",
|
||||
"webpack": "^3.12.0",
|
||||
"webpack-cli": "^3.1.2",
|
||||
"webpack-dev-server": "^3.1.10"
|
||||
"vue-loader": "^13.0.4",
|
||||
"vue-template-compiler": "^2.4.2",
|
||||
"webpack": "^3.5.5",
|
||||
"webpack-dev-server": "^2.7.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.16.2",
|
||||
"babel-polyfill": "^6.26.0",
|
||||
"intersection-observer": "^0.4.3",
|
||||
"intersection-observer": "^0.4.0",
|
||||
"jwt-decode": "^2.2.0",
|
||||
"vue": "^2.5.17",
|
||||
"vue": "^2.4.2",
|
||||
"vue-observe-visibility": "^0.1.3",
|
||||
"vue-router": "^2.8.1",
|
||||
"vuex": "^2.5.0"
|
||||
"vue-router": "^2.7.0",
|
||||
"vuex": "^2.3.1"
|
||||
},
|
||||
"babel": {
|
||||
"presets": [
|
||||
|
11
src/app.less
11
src/app.less
@ -82,6 +82,9 @@ strong {font-weight:700;}
|
||||
mark {color: @cms_brand_secondary;}
|
||||
a {text-decoration:none; color: @cms_brand_secondary;}
|
||||
a:hover {color:#901624;}
|
||||
a:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
@ -105,7 +108,7 @@ input, textarea, select {
|
||||
}
|
||||
textarea {padding:10px; height:auto;}
|
||||
input:focus, textarea:focus, select:focus {background:#FFF; border-color: @cms_brand_primary;}
|
||||
label {font-weight:600; color: @text_color; overflow: hidden; text-overflow: ellipsis;}
|
||||
label {font-weight:600; color: @text_color;}
|
||||
|
||||
.checkbox_holder {
|
||||
position: relative;
|
||||
@ -191,20 +194,20 @@ button{
|
||||
/*--------------------------------------------------------------
|
||||
# CMS CONTENT FORM
|
||||
--------------------------------------------------------------*/
|
||||
.cms_content_form {}
|
||||
/*.cms_content_form {}
|
||||
.cms_content_form_sidebar {background:#FFF; padding:25px; border:solid 1px #CCC;}
|
||||
.cms_fieldgroup {background:#f0f0f0; border:solid 1px #CCC; margin-bottom:20px;}
|
||||
.cms_fieldgroup_header {position:relative; color:#333; border-bottom:solid 1px #CCC; height:40px; line-height:40px; padding:0px 25px; font-weight:600;}
|
||||
.cms_fieldgroup_content {padding:25px; display:none;}
|
||||
.cms_fieldgroup_trigger {position:absolute; top:0px; width:100px; right:0px; padding-right:25px; cursor:pointer; height:40px; line-height:40px; text-align:right;}
|
||||
.cms_fieldgroup_trigger i {color:#333; font-size:18px;}
|
||||
.fieldgroup_open .cms_fieldgroup_content {display:block;}
|
||||
.fieldgroup_open .cms_fieldgroup_content {display:block;}*/
|
||||
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
# Content Area
|
||||
--------------------------------------------------------------*/
|
||||
.content_area {position:absolute; left:70px; top:40px; right:0px; height: 100%;}
|
||||
.content_area {position:absolute; left:70px; top:50px; right:0px; height: 100%;}
|
||||
.content_main {position:relative; top:0px; padding:25px;}
|
||||
|
||||
.cms_content_main_headline {margin-bottom:20px; position:relative;}
|
||||
|
@ -1,13 +0,0 @@
|
||||
import MyForm from 'components/my-form.vue';
|
||||
import MyInput from 'components/my-input.vue';
|
||||
import TextareaInput from 'components/textarea-input.vue';
|
||||
import MyTable from 'components/my-table.vue';
|
||||
import ScrollTable from 'components/scroll-table.vue';
|
||||
|
||||
export default {
|
||||
MyForm,
|
||||
MyInput,
|
||||
TextareaInput,
|
||||
MyTable,
|
||||
ScrollTable
|
||||
}
|
@ -1,17 +1,16 @@
|
||||
<!--
|
||||
<template>
|
||||
<form @submit.prevent="submit()">
|
||||
<div v-for="(el, idx) in elements" :key="idx">
|
||||
<div v-for="(item, key) in elements" :key="key">
|
||||
<component
|
||||
:is="el.element"
|
||||
:name="el.key"
|
||||
:label="el.label"
|
||||
:description="el.description"
|
||||
:props="el.props"
|
||||
v-model="formData[el.key]"
|
||||
@validate="validateData(el.key)"
|
||||
:invalid="formErrors[el.key]"
|
||||
:validatorMessage="formErrors[el.key] ? formErrors[el.key].message : ''"
|
||||
:is="item.element"
|
||||
:name="key"
|
||||
:label="item.label"
|
||||
:description="item.description"
|
||||
:props="item.props"
|
||||
v-model="formData[key]"
|
||||
@validate="validateData(key)"
|
||||
:invalid="formErrors[key]"
|
||||
:validatorMessage="formErrors[key] ? formErrors[key].message : ''"
|
||||
>
|
||||
</component>
|
||||
</div>
|
||||
@ -20,131 +19,13 @@
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
-->
|
||||
|
||||
<script>
|
||||
import MyInput from 'components/my-input.vue';
|
||||
|
||||
export default {
|
||||
name: "MyForm",
|
||||
render(createElement) {
|
||||
let self = this;
|
||||
let _cElCall;
|
||||
_cElCall = function(elements, formData) {
|
||||
let formEl = [ ];
|
||||
elements.forEach(el => {
|
||||
let n = el.name ? el.name : el.key;
|
||||
switch (el.element) {
|
||||
case "my-input":
|
||||
var inputClass = { };
|
||||
if (el.class) {
|
||||
inputClass = el.class;
|
||||
}
|
||||
formEl.push(createElement(MyInput, {
|
||||
props: {
|
||||
name: n,
|
||||
label: el.label,
|
||||
description: el.description,
|
||||
props: el.props,
|
||||
value: formData[n],
|
||||
validate: el.validate
|
||||
},
|
||||
class: inputClass,
|
||||
on: {
|
||||
input(val) {
|
||||
formData[n] = val;
|
||||
},
|
||||
validate(valid) {
|
||||
el.valid = valid;
|
||||
}
|
||||
}
|
||||
}));
|
||||
break;
|
||||
case "section":
|
||||
// formEl.push(createElement("h3", el.label));
|
||||
if (!formData[n]) {
|
||||
formData[n] = { };
|
||||
}
|
||||
formEl.push(
|
||||
createElement("div", {
|
||||
class: {
|
||||
cms_fieldgroup: true,
|
||||
fieldgroup_open: true,
|
||||
clear: true
|
||||
}
|
||||
}, [
|
||||
createElement("header", {
|
||||
class: {
|
||||
cms_fieldgroup_header: true
|
||||
}
|
||||
}, [
|
||||
el.label,
|
||||
createElement("div", {
|
||||
class: {
|
||||
cms_fieldgroup_trigger: true
|
||||
}
|
||||
} [
|
||||
createElement("i", {
|
||||
class: {
|
||||
"ion-chevron-down": true
|
||||
}
|
||||
})
|
||||
])
|
||||
]),
|
||||
createElement("div", {
|
||||
class: {
|
||||
cms_fieldgroup_content: true,
|
||||
clear: true
|
||||
}
|
||||
},
|
||||
_cElCall(el.subElements, formData[n])
|
||||
)
|
||||
])
|
||||
); //));
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
formEl.push(createElement("div", {
|
||||
class: {
|
||||
clear: true
|
||||
}
|
||||
})); // clearer as last element in group
|
||||
return formEl;
|
||||
}
|
||||
|
||||
let formElements = _cElCall(this.elements, self.formData);
|
||||
this.buttons.forEach(b => {
|
||||
formElements.push(createElement("button", {
|
||||
class: {
|
||||
button: true
|
||||
},
|
||||
on: {
|
||||
click(event) {
|
||||
event.preventDefault();
|
||||
self.buttonClick(b.type);
|
||||
}
|
||||
}
|
||||
}, b.label ? b.label : "OK"))
|
||||
})
|
||||
|
||||
return createElement('form', {
|
||||
on: {
|
||||
submit(e) {
|
||||
e.preventDefault();
|
||||
}
|
||||
}
|
||||
}, formElements)
|
||||
},
|
||||
props: {
|
||||
initData: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {};
|
||||
}
|
||||
},
|
||||
elements: {
|
||||
type: Array,
|
||||
type: Object,
|
||||
default: () => {
|
||||
return [];
|
||||
}
|
||||
@ -164,34 +45,16 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
formData: this.initData,
|
||||
// formErrors: {},
|
||||
// elementsMap: {}
|
||||
}
|
||||
},
|
||||
/*created() {
|
||||
this.setOrder();
|
||||
},*/
|
||||
watch: {
|
||||
/*elements() {
|
||||
this.setOrder();
|
||||
},*/
|
||||
initData() {
|
||||
this.formData = this.initData;
|
||||
formData: {},
|
||||
formErrors: {}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
/*setOrder() {
|
||||
this.elementsMap = {};
|
||||
for (let a in this.elements) {
|
||||
this.elementsMap[this.elements[a].key] = this.elements[a];
|
||||
}
|
||||
},*/
|
||||
/*validateData(name) {
|
||||
if (this.elementsMap[name].required) {
|
||||
validateData(name) {
|
||||
if (this.elements[name].required) {
|
||||
if (!this.formData[name]) {
|
||||
this.$set(this.formErrors, name, {
|
||||
message: this.elementsMap[name].requiredMessage
|
||||
message: this.elements[name].requiredMessage
|
||||
});
|
||||
|
||||
return false;
|
||||
@ -201,17 +64,6 @@ export default {
|
||||
}
|
||||
return true;
|
||||
},
|
||||
validateElement(el, val) {
|
||||
if (el.validate) {
|
||||
let v = el.validate;
|
||||
if (v.required && !val) {
|
||||
el.validatorMessage = v.requiredMessage ? v.requiredMessage : "input is required";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},*/
|
||||
buttonClick(type) {
|
||||
switch(type) {
|
||||
case 'submit':
|
||||
@ -220,40 +72,13 @@ export default {
|
||||
}
|
||||
},
|
||||
submit() {
|
||||
// bad hacky solution, but works
|
||||
this.$children.forEach(c => {
|
||||
c.validateValue();
|
||||
});
|
||||
|
||||
let _validateE;
|
||||
_validateE = function(eArr) {
|
||||
for (let i = 0; i< eArr.length; ++i) {
|
||||
if (eArr[i].valid === false) {
|
||||
return false;
|
||||
} else if (eArr[i].subElements) {
|
||||
// validate subElements
|
||||
let subValid = _validateE(eArr[i].subElements);
|
||||
if (!subValid) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_validateE(this.elements)) {
|
||||
this.submitHandler(this.formData);
|
||||
}
|
||||
|
||||
/*
|
||||
let valid = true;
|
||||
Object.keys(this.elementsMap).forEach(key => {
|
||||
Object.keys(this.elements).forEach(key => {
|
||||
valid = (this.validateData(key) && valid);
|
||||
});
|
||||
if (valid) {
|
||||
this.submitHandler(this.formData);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,27 +1,18 @@
|
||||
<template>
|
||||
<div class="input_holder">
|
||||
<div class="input_header" v-if="label || description">
|
||||
<label :for="name" v-if="label && props.type != 'checkbox'">{{ label }}<span v-if="validate && validate.required">*</span></label>
|
||||
<label :for="name" v-if="label">{{ label }}</label>
|
||||
<div class="input_description" v-if="description">{{ description }}</div>
|
||||
</div>
|
||||
|
||||
<!-- -->
|
||||
<input type="number" v-if="props && props.type == 'number'"
|
||||
v-model="currentValue"
|
||||
:class="{invalid}"
|
||||
:id="name"
|
||||
:name="name"
|
||||
:placeholder="props.placeholder"
|
||||
@blur="validateValue"
|
||||
@change="handleChange"
|
||||
>
|
||||
<input type="text" v-if="props && props.type == 'text'"
|
||||
v-model="currentValue"
|
||||
:class="{invalid}"
|
||||
:id="name"
|
||||
:name="name"
|
||||
:placeholder="props.placeholder"
|
||||
@blur="validateValue"
|
||||
@blur="validate"
|
||||
@change="handleChange"
|
||||
>
|
||||
<input type="password" v-else-if="props && props.type == 'password'"
|
||||
@ -30,7 +21,7 @@
|
||||
:id="name"
|
||||
:name="name"
|
||||
:placeholder="props.placeholder"
|
||||
@blur="validateValue"
|
||||
@blur="validate"
|
||||
@change="handleChange"
|
||||
>
|
||||
<div class="checkbox_holder" v-else-if="props && props.type == 'checkbox'">
|
||||
@ -39,11 +30,9 @@
|
||||
v-model="currentValue"
|
||||
:id="name"
|
||||
:name="name"
|
||||
@blur="validateValue"
|
||||
@change="handleChange"
|
||||
>
|
||||
<div class="check_checkbox"></div>
|
||||
<label :for="name" style="margin-left: 25px; width: 99%;" :title="label">{{ label }}<span v-if="validate && validate.required">*</span></label>
|
||||
</div>
|
||||
|
||||
<div v-if="invalid && validatorMessage">{{ validatorMessage }}</div>
|
||||
@ -65,29 +54,17 @@ export default {
|
||||
'name',
|
||||
'props',
|
||||
'value',
|
||||
// 'invalid',
|
||||
// 'validatorMessage',
|
||||
'validate'
|
||||
'invalid',
|
||||
'validatorMessage'
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
currentValue: this.value,
|
||||
invalid: false,
|
||||
validatorMessage: ""
|
||||
currentValue: this.value
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
validateValue() {
|
||||
var valid = true;
|
||||
let v = this.validate;
|
||||
if (v) {
|
||||
if (v.required && !this.currentValue) {
|
||||
valid = false;
|
||||
this.validatorMessage = (typeof v.requiredMessage == "string") ? v.requiredMessage : "input required";
|
||||
}
|
||||
}
|
||||
this.invalid = !valid;
|
||||
this.$emit('validate', valid);
|
||||
validate() {
|
||||
this.$emit('validate', this.currentValue);
|
||||
},
|
||||
handleChange() {
|
||||
this.$emit('change', this.currentValue);
|
||||
@ -95,30 +72,6 @@ export default {
|
||||
},
|
||||
watch: {
|
||||
currentValue(val) {
|
||||
if (this.props && this.props.datatype) {
|
||||
// convert
|
||||
let t = this.props.datatype;
|
||||
let newVal;
|
||||
switch (t) {
|
||||
case "int":
|
||||
newVal = parseInt(this.currentValue);
|
||||
if (isNaN(newVal)) {
|
||||
newVal = 0;
|
||||
}
|
||||
break;
|
||||
case "float":
|
||||
newVal = parseFloat(this.currentValue);
|
||||
if (isNaN(newVal)) {
|
||||
newVal = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (newVal !== this.currentValue) {
|
||||
this.currentValue = newVal;
|
||||
return; // prevent double input events
|
||||
}
|
||||
}
|
||||
this.$emit('input', val);
|
||||
}
|
||||
}
|
||||
|
@ -12,9 +12,9 @@
|
||||
<div @click="orderBy(col.orderBy)" v-if="col.orderBy">
|
||||
{{ col.heading }}
|
||||
|
||||
<i class="icon baseicon-angle-up" aria-hidden="true" v-if="currentOrderBy !== col.orderBy"></i>
|
||||
<i class="icon baseicon-angle-circled-down" aria-hidden="true" v-else-if="currentOrderDesc"></i>
|
||||
<i class="icon baseicon-angle-circled-up" aria-hidden="true" v-else></i>
|
||||
<i class="icon icon-angle-up" aria-hidden="true" v-if="currentOrderBy !== col.orderBy"></i>
|
||||
<i class="icon icon-angle-circled-down" aria-hidden="true" v-else-if="currentOrderDesc"></i>
|
||||
<i class="icon icon-angle-circled-up" aria-hidden="true" v-else></i>
|
||||
</div>
|
||||
|
||||
<!-- Column without sorting -->
|
||||
@ -45,7 +45,7 @@
|
||||
</li>
|
||||
</ul>
|
||||
<div title="Open actions" class="actions_btn" @click="toggleActions">
|
||||
<i class="icon baseicon-cog" aria-hidden="true"></i>
|
||||
<i class="icon icon-cog" aria-hidden="true"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
<style lang="less">
|
||||
@import "../mixins";
|
||||
@bar_height: 50px;
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
# Left Sidebar (Main Navigation)
|
||||
@ -26,7 +27,7 @@
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
left: 0px;
|
||||
top: 40px;
|
||||
top: @bar_height;
|
||||
bottom: 0px;
|
||||
background: @ui_bg;
|
||||
color: white;
|
||||
|
@ -6,9 +6,9 @@
|
||||
<!-- User Profile -->
|
||||
<div class="user_profile" ref="user_profile">
|
||||
<a class="trigger" @click.prevent="toggleMenu">
|
||||
<div class="image"><i class="icon baseicon-user" aria-hidden="true"></i></div>
|
||||
<!-- <div class="text"> {{ loginDisplay }} <div class="role"> {{ loginType }}</div></div> -->
|
||||
<div class="trigger_btn"><i class="icon baseicon-arrow-down" aria-hidden="true"></i></div>
|
||||
<div class="image"><i class="icon icon-user" aria-hidden="true"></i></div>
|
||||
<div class="text"> {{ loginDisplay }} <div class="role"> {{ loginType }}</div></div>
|
||||
<div class="trigger_btn"><i class="icon icon-arrow-down" aria-hidden="true"></i></div>
|
||||
</a>
|
||||
<nav class="user_menu">
|
||||
<ul>
|
||||
@ -81,7 +81,7 @@ export default {
|
||||
<style lang="less">
|
||||
@import "../mixins.less";
|
||||
|
||||
@bar_height: 40px;
|
||||
@bar_height: 50px;
|
||||
|
||||
/*--------------------------------------------------------------
|
||||
# Topbar (Sitename)
|
||||
@ -119,7 +119,7 @@ export default {
|
||||
width: 30px;
|
||||
height: auto;
|
||||
margin: 0 auto;
|
||||
padding-top: 4px;
|
||||
padding-top: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
@ -159,7 +159,7 @@ export default {
|
||||
&>.trigger {
|
||||
.clearfix();
|
||||
display: block;
|
||||
padding: 4px 10px;
|
||||
padding: 9px 10px;
|
||||
font-size: 0;
|
||||
color: white;
|
||||
user-select: none;
|
||||
@ -196,6 +196,8 @@ export default {
|
||||
font-size: 11px;
|
||||
color: fade(white, 50%);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -215,6 +217,7 @@ export default {
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
}
|
||||
/*.trigger_btn .icon:before {transition:all 0.3s;}*/
|
||||
.title {
|
||||
float: left;
|
||||
font-size: 14px;
|
||||
@ -239,4 +242,15 @@ export default {
|
||||
.trigger_btn .icon:before{transform: rotate(180deg);}
|
||||
}
|
||||
}
|
||||
|
||||
/*@media(max-width: @screen-md-max) {
|
||||
.user_profile {
|
||||
&>.trigger {
|
||||
.text {
|
||||
display:none;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}*/
|
||||
</style>
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "basefont",
|
||||
"css_prefix_text": "baseicon-",
|
||||
"name": "iconfont",
|
||||
"css_prefix_text": "icon-",
|
||||
"css_use_suffix": false,
|
||||
"hinting": true,
|
||||
"units_per_em": 1000,
|
||||
|
BIN
src/fonts/iconfont.eot
Normal file
BIN
src/fonts/iconfont.eot
Normal file
Binary file not shown.
80
src/fonts/iconfont.svg
Normal file
80
src/fonts/iconfont.svg
Normal file
@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<metadata>Copyright (C) 2017 by original authors @ fontello.com</metadata>
|
||||
<defs>
|
||||
<font id="iconfont" horiz-adv-x="1000" >
|
||||
<font-face font-family="iconfont" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
|
||||
<missing-glyph horiz-adv-x="1000" />
|
||||
<glyph glyph-name="search" unicode="" d="M643 386q0 103-73 176t-177 74-177-74-73-176 73-177 177-73 177 73 73 177z m286-465q0-29-22-50t-50-21q-30 0-50 21l-191 191q-100-69-223-69-80 0-153 31t-125 84-84 125-31 153 31 152 84 126 125 84 153 31 153-31 125-84 84-126 31-152q0-123-69-223l191-191q21-21 21-51z" horiz-adv-x="928.6" />
|
||||
|
||||
<glyph glyph-name="user" unicode="" d="M714 69q0-60-35-104t-84-44h-476q-49 0-84 44t-35 104q0 48 5 90t17 85 33 73 52 50 76 19q73-72 174-72t175 72q42 0 75-19t52-50 33-73 18-85 4-90z m-143 495q0-88-62-151t-152-63-151 63-63 151 63 152 151 63 152-63 62-152z" horiz-adv-x="714.3" />
|
||||
|
||||
<glyph glyph-name="key" unicode="" d="M464 564q0 45-31 76t-76 31-76-31-31-76q0-23 11-46-23 11-47 11-44 0-76-32t-31-76 31-75 76-32 76 32 31 75q0 24-10 47 23-11 46-11 45 0 76 31t31 76z m475-393q0-9-27-36t-37-28q-5 0-16 9t-20 19-22 22-13 14l-54-53 123-123q15-16 15-38 0-23-21-45t-46-22q-22 0-37 16l-375 374q-98-73-204-73-91 0-148 57t-57 149q0 89 53 174t138 139 175 53q91 0 148-58t57-148q0-105-73-203l198-199 54 54q-2 2-14 14t-23 21-18 21-9 15q0 10 27 37t37 28q7 0 13-6 3-3 26-25t45-44 49-48 40-44 16-23z" horiz-adv-x="1000" />
|
||||
|
||||
<glyph glyph-name="cog" unicode="" d="M571 350q0 59-41 101t-101 42-101-42-42-101 42-101 101-42 101 42 41 101z m286 61v-124q0-7-4-13t-11-7l-104-16q-10-30-21-51 19-27 59-77 6-6 6-13t-5-13q-15-21-55-61t-53-39q-7 0-14 5l-77 60q-25-13-51-21-9-76-16-104-4-16-20-16h-124q-8 0-14 5t-6 12l-16 103q-27 9-50 21l-79-60q-6-5-14-5-8 0-14 6-70 64-92 94-4 5-4 13 0 6 5 12 8 12 28 37t30 40q-15 28-23 55l-102 15q-7 1-11 7t-5 13v124q0 7 5 13t10 7l104 16q8 25 22 51-23 32-60 77-6 7-6 14 0 5 5 12 15 20 55 60t53 40q7 0 15-5l77-60q24 13 50 21 9 76 17 104 3 16 20 16h124q7 0 13-5t7-12l15-103q28-9 51-20l79 59q5 5 13 5 7 0 14-5 72-67 92-95 4-5 4-12 0-7-4-13-9-12-29-37t-30-40q15-28 23-54l102-16q7-1 12-7t4-13z" horiz-adv-x="857.1" />
|
||||
|
||||
<glyph glyph-name="pencil" unicode="" d="M203-7l50 51-131 131-51-51v-60h72v-71h60z m291 518q0 12-12 12-5 0-9-4l-303-302q-4-4-4-10 0-12 13-12 5 0 9 4l303 302q3 4 3 10z m-30 107l232-232-464-465h-232v233z m381-54q0-29-20-50l-93-93-232 233 93 92q20 21 50 21 29 0 51-21l131-131q20-22 20-51z" horiz-adv-x="857.1" />
|
||||
|
||||
<glyph glyph-name="eye-off" unicode="" d="M310 105l43 79q-48 35-76 88t-27 114q0 67 34 125-128-65-213-197 94-144 239-209z m217 424q0 11-8 19t-19 7q-70 0-120-50t-50-119q0-11 8-19t19-8 19 8 8 19q0 48 34 82t82 34q11 0 19 8t8 19z m202 106q0-4 0-5-59-105-176-316t-176-316l-28-50q-5-9-15-9-7 0-75 39-9 6-9 16 0 7 25 49-80 36-147 96t-117 137q-11 17-11 38t11 39q86 131 212 207t277 76q50 0 100-10l31 54q5 9 15 9 3 0 10-3t18-9 18-10 18-10 10-7q9-5 9-15z m21-249q0-78-44-142t-117-91l157 280q4-25 4-47z m250-72q0-19-11-38-22-36-61-81-84-96-194-149t-234-53l41 74q119 10 219 76t169 171q-65 100-158 164l35 63q53-36 102-85t81-103q11-19 11-39z" horiz-adv-x="1000" />
|
||||
|
||||
<glyph glyph-name="cancel" unicode="" d="M724 112q0-22-15-38l-76-76q-16-15-38-15t-38 15l-164 165-164-165q-16-15-38-15t-38 15l-76 76q-16 16-16 38t16 38l164 164-164 164q-16 16-16 38t16 38l76 76q16 16 38 16t38-16l164-164 164 164q16 16 38 16t38-16l76-76q15-15 15-38t-15-38l-164-164 164-164q15-15 15-38z" horiz-adv-x="785.7" />
|
||||
|
||||
<glyph glyph-name="ok" unicode="" d="M933 534q0-22-16-38l-404-404-76-76q-16-15-38-15t-38 15l-76 76-202 202q-15 16-15 38t15 38l76 76q16 16 38 16t38-16l164-165 366 367q16 16 38 16t38-16l76-76q16-15 16-38z" horiz-adv-x="1000" />
|
||||
|
||||
<glyph glyph-name="trash-empty" unicode="" d="M286 439v-321q0-8-5-13t-13-5h-36q-8 0-13 5t-5 13v321q0 8 5 13t13 5h36q8 0 13-5t5-13z m143 0v-321q0-8-5-13t-13-5h-36q-8 0-13 5t-5 13v321q0 8 5 13t13 5h36q8 0 13-5t5-13z m142 0v-321q0-8-5-13t-12-5h-36q-8 0-13 5t-5 13v321q0 8 5 13t13 5h36q7 0 12-5t5-13z m72-404v529h-500v-529q0-12 4-22t8-15 6-5h464q2 0 6 5t8 15 4 22z m-375 601h250l-27 65q-4 5-9 6h-177q-6-1-10-6z m518-18v-36q0-8-5-13t-13-5h-54v-529q0-46-26-80t-63-34h-464q-37 0-63 33t-27 79v531h-53q-8 0-13 5t-5 13v36q0 8 5 13t13 5h172l39 93q9 21 31 35t44 15h178q23 0 44-15t30-35l39-93h173q8 0 13-5t5-13z" horiz-adv-x="785.7" />
|
||||
|
||||
<glyph glyph-name="docs" unicode="" d="M946 636q23 0 38-16t16-38v-678q0-23-16-38t-38-16h-535q-23 0-38 16t-16 38v160h-303q-23 0-38 16t-16 38v375q0 22 11 49t27 42l228 228q15 16 42 27t49 11h232q23 0 38-16t16-38v-183q38 23 71 23h232z m-303-119l-167-167h167v167z m-357 214l-167-167h167v167z m109-361l176 176v233h-214v-233q0-22-15-37t-38-16h-233v-357h286v143q0 22 11 49t27 42z m534-449v643h-215v-232q0-22-15-38t-38-15h-232v-358h500z" horiz-adv-x="1000" />
|
||||
|
||||
<glyph glyph-name="menu" unicode="" d="M857 100v-71q0-15-10-25t-26-11h-785q-15 0-25 11t-11 25v71q0 15 11 25t25 11h785q15 0 26-11t10-25z m0 286v-72q0-14-10-25t-26-10h-785q-15 0-25 10t-11 25v72q0 14 11 25t25 10h785q15 0 26-10t10-25z m0 285v-71q0-14-10-25t-26-11h-785q-15 0-25 11t-11 25v71q0 15 11 26t25 10h785q15 0 26-10t10-26z" horiz-adv-x="857.1" />
|
||||
|
||||
<glyph glyph-name="angle-left" unicode="" d="M350 546q0-7-6-12l-219-220 219-219q6-6 6-13t-6-13l-28-28q-5-5-12-5t-13 5l-260 261q-6 5-6 12t6 13l260 260q5 6 13 6t12-6l28-28q6-5 6-13z" horiz-adv-x="357.1" />
|
||||
|
||||
<glyph glyph-name="angle-right" unicode="" d="M332 314q0-7-5-12l-261-261q-5-5-12-5t-13 5l-28 28q-6 6-6 13t6 13l219 219-219 220q-6 5-6 12t6 13l28 28q5 6 13 6t12-6l261-260q5-5 5-13z" horiz-adv-x="357.1" />
|
||||
|
||||
<glyph glyph-name="angle-up" unicode="" d="M600 189q0-7-6-12l-28-28q-5-6-12-6t-13 6l-220 219-219-219q-5-6-13-6t-12 6l-28 28q-6 5-6 12t6 13l260 260q5 6 12 6t13-6l260-260q6-5 6-13z" horiz-adv-x="642.9" />
|
||||
|
||||
<glyph glyph-name="angle-down" unicode="" d="M600 439q0-7-6-12l-260-261q-5-5-13-5t-12 5l-260 261q-6 5-6 12t6 13l28 28q5 6 12 6t13-6l219-219 220 219q5 6 13 6t12-6l28-28q6-5 6-13z" horiz-adv-x="642.9" />
|
||||
|
||||
<glyph glyph-name="chatbox" unicode="" d="M148 69c-82 0-148 60-148 138v409c0 78 66 140 148 140h516c82 0 149-62 149-140v-409c0-78-67-138-149-138h-8v-125s-154 105-168 115-13 10-41 10h-299z" horiz-adv-x="812.5" />
|
||||
|
||||
<glyph glyph-name="document-text" unicode="" d="M559 520c2-6 4-12 4-20v-478c0-26-20-47-43-47h-475c-23 0-45 21-45 47v656c0 26 22 47 45 47h312c6 0 12 0 18-4 4-2 10-6 14-10l164-179c4-4 4-8 6-12z m-465-20v-19c0-2 2-6 6-6h138c4 0 6 4 6 6v19c0 4-2 6-6 6h-138c-4 0-6-2-6-6z m0-250v-19c0-2 2-6 6-6h240c4 0 4 4 4 6v19c0 4 0 6-4 6h-240c-4 0-6-2-6-6z m312-144v19c0 4 0 6-4 6h-302c-4 0-6-2-6-6v-19c0-2 2-6 6-6h302c4 0 4 4 4 6z m63 250v19c0 4 0 6-4 6h-365c-4 0-6-2-6-6v-19c0-2 2-6 6-6h365c4 0 4 4 4 6z m-92 146h117l-138 153v-129c0-12 9-24 21-24z" horiz-adv-x="562.5" />
|
||||
|
||||
<glyph glyph-name="angle-circled-left" unicode="" d="M507 72l57 57q11 10 11 25t-11 25l-171 171 171 171q11 11 11 25t-11 26l-57 57q-10 10-25 10t-25-10l-253-254q-11-10-11-25t11-25l253-253q11-11 25-11t25 11z m350 278q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" />
|
||||
|
||||
<glyph glyph-name="angle-circled-right" unicode="" d="M400 72l254 253q10 11 10 25t-10 25l-254 254q-10 10-25 10t-25-10l-57-57q-11-11-11-26t11-25l171-171-171-171q-11-11-11-25t11-25l57-57q11-11 25-11t25 11z m457 278q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" />
|
||||
|
||||
<glyph glyph-name="angle-circled-up" unicode="" d="M650 214l57 57q11 11 11 25t-11 26l-253 253q-11 11-25 11t-25-11l-254-253q-10-11-10-26t10-25l57-57q11-10 25-10t25 10l172 172 171-172q11-10 25-10t25 10z m207 136q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" />
|
||||
|
||||
<glyph glyph-name="angle-circled-down" unicode="" d="M454 125l253 254q11 10 11 25t-11 25l-57 57q-10 10-25 10t-25-10l-171-172-172 172q-10 10-25 10t-25-10l-57-57q-10-11-10-25t10-25l254-254q10-10 25-10t25 10z m403 225q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" />
|
||||
|
||||
<glyph glyph-name="gear" unicode="" d="M678 350c0-47 29-84 72-109-8-26-19-51-31-75-49 12-88-5-121-39s-43-72-32-121c-23-12-48-23-74-31-25 43-70 72-117 72s-92-29-117-72c-26 8-53 19-76 31 11 49 4 88-30 121s-72 41-121 30c-11 23-23 50-31 76 43 25 72 70 72 117s-29 84-72 109c8 26 18 51 31 75 49-12 88 6 121 39s41 72 30 121c23 12 50 23 76 31 25-43 70-72 117-72s92 29 117 72c26-8 53-19 76-31-11-49-3-88 30-121s72-51 121-39c12-24 23-49 31-75-43-25-72-62-72-109z m-303-191c106 0 191 86 191 191s-85 191-191 191-191-85-191-191 86-191 191-191z" horiz-adv-x="750" />
|
||||
|
||||
<glyph glyph-name="images" unicode="" d="M832 577c25-2 45-24 43-47l-27-514c-2-25-24-43-49-41l-645 31c-25 2-45 20-43 45l4 90-29-2c-23-2-43 14-45 35l-41 461c-2 22 14 41 37 43l578 47c24 2 43-14 45-35l10-106z m-693-12c2 23 21 43 47 43l427-22-4 61h-2v2c-1 10-9 16-19 16l-510-43c-10 0-19-8-19-18v0-2l31-348 35 49z m652-461l20 387v2 0c0 11-10 19-22 19l-113 6-57 4-398 18c-12 0-22-8-24-18v0-2l-6-123-13-250v-14l12 14 199 213c8 8 15 12 27 12s22-6 27-14l84-96 6-6c4-4 12-8 20-8s10 2 17 6l34 24c7 6 13 8 21 8s18-4 22-10l52-65z m-125 234c-39 0-68 30-68 69s31 68 68 68c39 0 68-31 68-68s-31-69-68-69z" horiz-adv-x="875" />
|
||||
|
||||
<glyph glyph-name="log-out" unicode="" d="M654 217l102 102h-443v62h443l-102 102 43 45 178-178-178-178z m47-133c6 6 12 10 16 16h80c-78-113-211-188-359-188-243 0-438 196-438 438s195 438 438 438c148 0 281-75 359-188h-80c-4 6-10 10-16 16-70 70-164 109-263 109s-196-39-266-109-109-166-109-266 39-195 109-266 166-109 266-109 193 39 263 109z" horiz-adv-x="875" />
|
||||
|
||||
<glyph glyph-name="pie-graph" unicode="" d="M2 350c0 10-2 22-2 31 0 225 182 407 406 407 10 0 22-2 32-2v-63-373h-373-63z m150-285c-50 62-82 139-87 223h435v435c84-6 160-37 223-88 92-74 152-187 152-316 0-225-182-407-406-407-129 0-242 61-317 153z" horiz-adv-x="875" />
|
||||
|
||||
<glyph glyph-name="paper-airplane" unicode="" d="M0 319l875 469-219-876-218 219-157-219-31 313z m623-283l156 630-629-337 163-61 375 301-250-344z" horiz-adv-x="875" />
|
||||
|
||||
<glyph glyph-name="contacts" unicode="" d="M404 178c92-27 149-121 170-203h-574c22 82 78 176 170 203 35-19 74-31 117-31s82 12 117 31z m-117 438c113 0 207-94 207-207s-94-207-207-207-207 93-207 207 94 207 207 207z m0-366c67 0 121 45 145 100h-289c23-55 78-100 144-100z m281-150c-25 39-66 84-117 104 22 17 41 44 55 68 25-10 53-16 82-16 43 0 82 12 117 32 92-28 149-106 170-188h-307z m-31 359c-15 73-60 135-123 170 37 57 102 96 174 96 113 0 207-94 207-207s-94-207-207-207c-22 0-43 4-63 10 6 15 12 31 14 49 16-6 31-8 49-8 66 0 121 43 144 97h-195z" horiz-adv-x="875" />
|
||||
|
||||
<glyph glyph-name="cube" unicode="" d="M850 522c13 0 25-12 25-24v-357c0-18-12-33-27-43v-2l-342-180v-2c-4-2-8-2-12-2-13 0-25 12-25 24v361c0 18 10 34 25 43v0l6 4 336 174 4 2c4 2 6 2 10 2z m-26 96c0 0 16-6 16-18 0-14-16-21-16-21l-357-190-4-2c-8-4-16-6-25-6s-18 2-26 6l-4 2-357 188s-16 9-16 23c0 12 16 18 16 18l353 160s22 10 34 10 33-10 33-10z m-443-278c16-9 25-25 25-43v-361c0-12-11-24-25-24-4 0-8 2-12 4v0l-342 180v2c-15 10-27 25-27 43v357c0 12 12 24 25 24 4 0 8 0 10-2l4-2 334-174z" horiz-adv-x="875" />
|
||||
|
||||
<glyph glyph-name="compass" unicode="" d="M438 399c25 0 48-24 48-49s-23-49-48-49-49 24-49 49 23 49 49 49z m0 389c240 0 437-198 437-438s-197-438-437-438-438 198-438 438 197 438 438 438z m95-534l166 358-357-166-166-358z" horiz-adv-x="875" />
|
||||
|
||||
<glyph glyph-name="arrow-down" unicode="" d="M588 538l37-41-312-334-313 334 37 41 276-293z" horiz-adv-x="625" />
|
||||
|
||||
<glyph glyph-name="arrow-left" unicode="" d="M375 625l-293-275 293-275-41-37-334 312 334 313z" horiz-adv-x="375" />
|
||||
|
||||
<glyph glyph-name="arrow-right" unicode="" d="M0 625l41 38 334-313-334-312-41 37 293 275z" horiz-adv-x="375" />
|
||||
|
||||
<glyph glyph-name="arrow-up" unicode="" d="M588 163l-275 293-276-293-37 41 313 334 312-334z" horiz-adv-x="625" />
|
||||
|
||||
<glyph glyph-name="color-wand" unicode="" d="M273 540l500-502-66-67-500 502z m-31 64v125h63v-125h-63z m0-398v125h63v-125h-63z m180 234v62h125v-62h-125z m59 191l-88-88-45 43 88 90z m-415 0l45 45 88-90-45-43z m0-326l88 88 45-43-88-90z m-66 135v62h125v-62h-125z" horiz-adv-x="773.4" />
|
||||
|
||||
<glyph glyph-name="navigate" unicode="" d="M406 756c225 0 407-181 407-406s-182-406-407-406-406 181-406 406 182 406 406 406z m0-656l188 438-438-188h250v-250z" horiz-adv-x="812.5" />
|
||||
</font>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 12 KiB |
BIN
src/fonts/iconfont.ttf
Normal file
BIN
src/fonts/iconfont.ttf
Normal file
Binary file not shown.
BIN
src/fonts/iconfont.woff2
Normal file
BIN
src/fonts/iconfont.woff2
Normal file
Binary file not shown.
@ -1,53 +1,56 @@
|
||||
@import "mixins";
|
||||
|
||||
@iconfont_path: "fonts/";
|
||||
@iconfont_version: 4;
|
||||
|
||||
|
||||
@font-face {
|
||||
font-family: "basefont";
|
||||
src: url('@{iconfont_path}basefont.woff') format('woff');
|
||||
font-family: "iconfont";
|
||||
.fontPath(@iconfont_path, "iconfont", @iconfont_version);
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
text-rendering: optimizeLegibility;
|
||||
}
|
||||
|
||||
[class^="baseicon-"]::before,
|
||||
[class*=" baseicon-"]::before {
|
||||
.iconStyles("basefont");
|
||||
.icon:before {
|
||||
.iconStyles("iconfont");
|
||||
}
|
||||
|
||||
.baseicon-search:before { content: '\e800'; } /* '' */
|
||||
.baseicon-user:before { content: '\e801'; } /* '' */
|
||||
.baseicon-key:before { content: '\e802'; } /* '' */
|
||||
.baseicon-cog:before { content: '\e803'; } /* '' */
|
||||
.baseicon-pencil:before { content: '\e804'; } /* '' */
|
||||
.baseicon-eye-off:before { content: '\e805'; } /* '' */
|
||||
.baseicon-cancel:before { content: '\e806'; } /* '' */
|
||||
.baseicon-ok:before { content: '\e807'; } /* '' */
|
||||
.baseicon-trash-empty:before { content: '\e808'; } /* '' */
|
||||
.baseicon-docs:before { content: '\f0c5'; } /* '' */
|
||||
.baseicon-menu:before { content: '\f0c9'; } /* '' */
|
||||
.baseicon-angle-left:before { content: '\f104'; } /* '' */
|
||||
.baseicon-angle-right:before { content: '\f105'; } /* '' */
|
||||
.baseicon-angle-up:before { content: '\f106'; } /* '' */
|
||||
.baseicon-angle-down:before { content: '\f107'; } /* '' */
|
||||
.baseicon-chatbox:before { content: '\f11b'; } /* '' */
|
||||
.baseicon-document-text:before { content: '\f12e'; } /* '' */
|
||||
.baseicon-angle-circled-left:before { content: '\f137'; } /* '' */
|
||||
.baseicon-angle-circled-right:before { content: '\f138'; } /* '' */
|
||||
.baseicon-angle-circled-up:before { content: '\f139'; } /* '' */
|
||||
.baseicon-angle-circled-down:before { content: '\f13a'; } /* '' */
|
||||
.baseicon-gear:before { content: '\f13d'; } /* '' */
|
||||
.baseicon-images:before { content: '\f148'; } /* '' */
|
||||
.baseicon-log-out:before { content: '\f29f'; } /* '' */
|
||||
.baseicon-pie-graph:before { content: '\f2a5'; } /* '' */
|
||||
.baseicon-paper-airplane:before { content: '\f2c3'; } /* '' */
|
||||
.baseicon-contacts:before { content: '\f2d9'; } /* '' */
|
||||
.baseicon-cube:before { content: '\f318'; } /* '' */
|
||||
.baseicon-compass:before { content: '\f37c'; } /* '' */
|
||||
.baseicon-arrow-down:before { content: '\f3d0'; } /* '' */
|
||||
.baseicon-arrow-left:before { content: '\f3d2'; } /* '' */
|
||||
.baseicon-arrow-right:before { content: '\f3d3'; } /* '' */
|
||||
.baseicon-arrow-up:before { content: '\f3d8'; } /* '' */
|
||||
.baseicon-color-wand:before { content: '\f416'; } /* '' */
|
||||
.baseicon-navigate:before { content: '\f46e'; } /* '' */
|
||||
.icon-search:before { content: '\e800'; } /* '' */
|
||||
.icon-user:before { content: '\e801'; } /* '' */
|
||||
.icon-key:before { content: '\e802'; } /* '' */
|
||||
.icon-cog:before { content: '\e803'; } /* '' */
|
||||
.icon-pencil:before { content: '\e804'; } /* '' */
|
||||
.icon-eye-off:before { content: '\e805'; } /* '' */
|
||||
.icon-cancel:before { content: '\e806'; } /* '' */
|
||||
.icon-ok:before { content: '\e807'; } /* '' */
|
||||
.icon-trash-empty:before { content: '\e808'; } /* '' */
|
||||
.icon-docs:before { content: '\f0c5'; } /* '' */
|
||||
.icon-menu:before { content: '\f0c9'; } /* '' */
|
||||
.icon-angle-left:before { content: '\f104'; } /* '' */
|
||||
.icon-angle-right:before { content: '\f105'; } /* '' */
|
||||
.icon-angle-up:before { content: '\f106'; } /* '' */
|
||||
.icon-angle-down:before { content: '\f107'; } /* '' */
|
||||
.icon-chatbox:before { content: '\f11b'; } /* '' */
|
||||
.icon-document-text:before { content: '\f12e'; } /* '' */
|
||||
.icon-angle-circled-left:before { content: '\f137'; } /* '' */
|
||||
.icon-angle-circled-right:before { content: '\f138'; } /* '' */
|
||||
.icon-angle-circled-up:before { content: '\f139'; } /* '' */
|
||||
.icon-angle-circled-down:before { content: '\f13a'; } /* '' */
|
||||
.icon-gear:before { content: '\f13d'; } /* '' */
|
||||
.icon-images:before { content: '\f148'; } /* '' */
|
||||
.icon-log-out:before { content: '\f29f'; } /* '' */
|
||||
.icon-pie-graph:before { content: '\f2a5'; } /* '' */
|
||||
.icon-paper-airplane:before { content: '\f2c3'; } /* '' */
|
||||
.icon-contacts:before { content: '\f2d9'; } /* '' */
|
||||
.icon-world:before { content: '\f4d3'; } /* '' */
|
||||
.icon-cube:before { content: '\f318'; } /* '' */
|
||||
.icon-compass:before { content: '\f37c'; } /* '' */
|
||||
.icon-arrow-down:before { content: '\f3d0'; } /* '' */
|
||||
.icon-arrow-left:before { content: '\f3d2'; } /* '' */
|
||||
.icon-arrow-right:before { content: '\f3d3'; } /* '' */
|
||||
.icon-arrow-up:before { content: '\f3d8'; } /* '' */
|
||||
.icon-color-wand:before { content: '\f416'; } /* '' */
|
||||
.icon-navigate:before { content: '\f46e'; } /* '' */
|
||||
.icon-videocamera:before { content: '\f256'; } /* '' */
|
||||
.icon-stats-bars:before { content: '\f2b5'; } /* '' */
|
@ -1,13 +1,156 @@
|
||||
import Vue from 'vue';
|
||||
import Vuex from 'vuex';
|
||||
import VueRouter from 'vue-router';
|
||||
import Axios from 'axios';
|
||||
import JwtDecode from 'jwt-decode';
|
||||
|
||||
import App from 'app.vue';
|
||||
import GlobalComponents from 'components/components.js';
|
||||
|
||||
import MyForm from 'components/my-form.vue';
|
||||
import MyInput from 'components/my-input.vue';
|
||||
import TextareaInput from 'components/textarea-input.vue';
|
||||
import MyTable from 'components/my-table.vue';
|
||||
import ScrollTable from 'components/scroll-table.vue';
|
||||
|
||||
Vue.use(VueRouter);
|
||||
Vue.use(Vuex);
|
||||
|
||||
Vue.component('my-form', MyForm);
|
||||
Vue.component('my-input', MyInput);
|
||||
Vue.component('textarea-input', TextareaInput);
|
||||
Vue.component('my-table', MyTable);
|
||||
Vue.component('scroll-table', ScrollTable);
|
||||
|
||||
const globalConf = {
|
||||
loginEndpoint: 'login',
|
||||
loginRoute: '/login',
|
||||
authHeader: 'X-Auth-Token',
|
||||
responseType: 'json',
|
||||
initUrl: 'conf/init.json',
|
||||
el: '#my-app'
|
||||
}
|
||||
|
||||
const Router = new VueRouter();
|
||||
|
||||
const Store = new Vuex.Store({
|
||||
state: {
|
||||
ui: {},
|
||||
persist: {
|
||||
login: {},
|
||||
authToken: '',
|
||||
jwt: {},
|
||||
credentials: {}
|
||||
}
|
||||
},
|
||||
mutations: {
|
||||
setUI(state, payload) {
|
||||
state.ui = payload;
|
||||
},
|
||||
setCredentials(state, payload) {
|
||||
state.persist.credentials = payload;
|
||||
objectToPersist(state.persist, 'persistantStore');
|
||||
},
|
||||
setLogin(state, payload) {
|
||||
state.persist.login = payload.User;
|
||||
state.persist.authToken = payload.AuthToken;
|
||||
state.persist.jwt = JwtDecode(payload.AuthToken);
|
||||
objectToPersist(state.persist, 'persistantStore');
|
||||
},
|
||||
clearLogin(state) {
|
||||
state.persist.login = {};
|
||||
state.persist.authToken = '';
|
||||
state.persist.jwt = {};
|
||||
state.persist.credentials = {};
|
||||
objectToPersist(state.persist, 'persistantStore');
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
apiRequest(context, payload) {
|
||||
let doRequest = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const addHeader = {};
|
||||
addHeader[globalConf.authHeader] = context.state.persist.authToken;
|
||||
Axios({
|
||||
method: payload.method ? payload.method : 'get',
|
||||
baseURL: context.state.ui.api.baseURL,
|
||||
url: payload.endpoint,
|
||||
params: payload.params,
|
||||
data: payload.data,
|
||||
headers: addHeader,
|
||||
responseType: globalConf.responseType
|
||||
})
|
||||
.then(response => {
|
||||
console.log(response);
|
||||
resolve(response.data);
|
||||
})
|
||||
.catch(error => {
|
||||
console.dir(error);
|
||||
reject(error);
|
||||
})
|
||||
});
|
||||
};
|
||||
|
||||
if (payload.endpoint != globalConf.loginEndpoint) {
|
||||
// no jwt check for login call
|
||||
|
||||
if (!context.state.persist.jwt.exp) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// show login page
|
||||
Router.push(globalConf.loginRoute);
|
||||
reject(['not logged in']);
|
||||
});
|
||||
}
|
||||
|
||||
let now = Math.round(Date.now() / 1000);
|
||||
if (context.state.persist.jwt.exp < (now + 300)) {
|
||||
// too old jwt, logout
|
||||
return new Promise((resolve, reject) => {
|
||||
context.commit('clearLogin');
|
||||
Router.push(globalConf.loginRoute);
|
||||
reject(['jwt too old, logout']);
|
||||
});
|
||||
}
|
||||
|
||||
if ((context.state.persist.jwt.exp - 60) < now) {
|
||||
// jwt near expire, get new one
|
||||
console.log("getting new jwt");
|
||||
|
||||
return context.dispatch(globalConf.loginEndpoint, context.state.persist.credentials)
|
||||
.then(() => {
|
||||
console.log("LOOOGIIIINNN");
|
||||
return doRequest();
|
||||
})
|
||||
.catch(error => {
|
||||
throw error;
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return doRequest();
|
||||
},
|
||||
login(context, payload) {
|
||||
return new Promise((resolve, reject) => {
|
||||
context.dispatch('apiRequest', {
|
||||
method: 'post',
|
||||
endpoint: globalConf.loginEndpoint,
|
||||
data: payload
|
||||
})
|
||||
.then(data => {
|
||||
context.commit('setCredentials', payload);
|
||||
context.commit('setLogin', data);
|
||||
resolve(data.User);
|
||||
})
|
||||
.catch(error => {
|
||||
if (error.response && error.response.data && error.response.data.error) {
|
||||
reject(error.response.data.error);
|
||||
} else {
|
||||
reject([]);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function objectToPersist(obj, key) {
|
||||
try {
|
||||
@ -31,22 +174,20 @@ function persistToObject(key) {
|
||||
}
|
||||
}
|
||||
|
||||
// get store persist part from localStorage
|
||||
let persist = persistToObject('persistantStore');
|
||||
if (persist) {
|
||||
Store.state.persist = persist;
|
||||
}
|
||||
|
||||
export default {
|
||||
config: {
|
||||
loginEndpoint: 'login',
|
||||
loginRoute: '/login',
|
||||
authHeader: 'X-Auth-Token',
|
||||
tokenClaim: 'AuthToken',
|
||||
responseType: 'json',
|
||||
initUrl: 'conf/init.json',
|
||||
el: '#vue-app'
|
||||
},
|
||||
InitApp(vue, config) { // config: {initUrl, views, el}
|
||||
Object.assign(this.config, config);
|
||||
var $this = this;
|
||||
|
||||
Axios.get($this.config.initUrl)
|
||||
Vue,
|
||||
Router,
|
||||
Store,
|
||||
Axios,
|
||||
InitApp(config) { // config: {initUrl, views, el}
|
||||
Object.assign(globalConf, config);
|
||||
Axios.get(globalConf.initUrl)
|
||||
.then(results => {
|
||||
// set navigation
|
||||
if (!Array.isArray(results.data.routes)) {
|
||||
@ -54,145 +195,6 @@ export default {
|
||||
return;
|
||||
}
|
||||
|
||||
// register global components
|
||||
for (var prop in GlobalComponents) {
|
||||
vue.component(prop, GlobalComponents[prop]);
|
||||
}
|
||||
|
||||
vue.use(VueRouter);
|
||||
const Router = new VueRouter();
|
||||
|
||||
vue.use(Vuex);
|
||||
|
||||
const Store = new Vuex.Store({
|
||||
state: {
|
||||
ui: {},
|
||||
persist: {
|
||||
login: {},
|
||||
authToken: '',
|
||||
jwt: {},
|
||||
credentials: {}
|
||||
}
|
||||
},
|
||||
mutations: {
|
||||
setUI(state, payload) {
|
||||
state.ui = payload;
|
||||
},
|
||||
setCredentials(state, payload) {
|
||||
state.persist.credentials = payload;
|
||||
objectToPersist(state.persist, 'persistantStore');
|
||||
},
|
||||
setLogin(state, payload) {
|
||||
state.persist.login = payload.User;
|
||||
state.persist.authToken = payload[$this.config.tokenClaim];
|
||||
state.persist.jwt = JwtDecode(payload[$this.config.tokenClaim]);
|
||||
objectToPersist(state.persist, 'persistantStore');
|
||||
},
|
||||
clearLogin(state) {
|
||||
state.persist.login = {};
|
||||
state.persist.authToken = '';
|
||||
state.persist.jwt = {};
|
||||
state.persist.credentials = {};
|
||||
objectToPersist(state.persist, 'persistantStore');
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
apiRequest(context, payload) {
|
||||
let doRequest = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const addHeader = {};
|
||||
addHeader[$this.config.authHeader] = context.state.persist.authToken;
|
||||
Axios({
|
||||
method: payload.method ? payload.method : 'get',
|
||||
baseURL: context.state.ui.api.baseURL,
|
||||
url: payload.endpoint,
|
||||
params: payload.params,
|
||||
data: payload.data,
|
||||
headers: addHeader,
|
||||
responseType: $this.config.responseType
|
||||
})
|
||||
.then(response => {
|
||||
console.log(response);
|
||||
resolve(response);
|
||||
})
|
||||
.catch(error => {
|
||||
console.dir(error);
|
||||
reject(error);
|
||||
})
|
||||
});
|
||||
};
|
||||
|
||||
if (payload.endpoint != $this.config.loginEndpoint) {
|
||||
// no jwt check for login call
|
||||
|
||||
if (!context.state.persist.jwt.exp) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// show login page
|
||||
Router.push($this.config.loginRoute);
|
||||
reject(['not logged in']);
|
||||
});
|
||||
}
|
||||
|
||||
let now = Math.round(Date.now() / 1000);
|
||||
if (context.state.persist.jwt.exp < (now + 300)) {
|
||||
// too old jwt, logout
|
||||
return new Promise((resolve, reject) => {
|
||||
context.commit('clearLogin');
|
||||
Router.push($this.config.loginRoute);
|
||||
reject(['jwt too old, logout']);
|
||||
});
|
||||
}
|
||||
|
||||
if ((context.state.persist.jwt.exp - 60) < now) {
|
||||
// jwt near expire, get new one
|
||||
console.log("getting new jwt");
|
||||
|
||||
return context.dispatch($this.config.loginEndpoint, context.state.persist.credentials)
|
||||
.then(() => {
|
||||
console.log("LOOOGIIIINNN");
|
||||
return doRequest();
|
||||
})
|
||||
.catch(error => {
|
||||
throw error;
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return doRequest();
|
||||
},
|
||||
login(context, payload) {
|
||||
return new Promise((resolve, reject) => {
|
||||
context.dispatch('apiRequest', {
|
||||
method: 'post',
|
||||
endpoint: $this.config.loginEndpoint,
|
||||
data: payload
|
||||
})
|
||||
.then(response => {
|
||||
context.commit('setCredentials', payload);
|
||||
context.commit('setLogin', response.data);
|
||||
resolve(response.data.User);
|
||||
})
|
||||
.catch(error => {
|
||||
if (error.response && error.response.data && error.response.data.error) {
|
||||
reject(error.response.data.error);
|
||||
} else {
|
||||
reject([]);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// get store persist part from localStorage
|
||||
let persist = persistToObject('persistantStore');
|
||||
if (persist) {
|
||||
Store.state.persist = persist;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// set ui config in store
|
||||
Store.commit("setUI", results.data.ui);
|
||||
|
||||
@ -207,7 +209,7 @@ export default {
|
||||
},
|
||||
component: {
|
||||
template: '<div id="' + name + rIdx + '">' + content + '</div>',
|
||||
components: this.config.views,
|
||||
components: globalConf.views,
|
||||
data: function (data) {
|
||||
if (typeof data != 'object') {
|
||||
return () => { return {}; };
|
||||
@ -223,13 +225,12 @@ export default {
|
||||
});
|
||||
|
||||
// load app, when init finishs
|
||||
return new vue({
|
||||
el: this.config.el,
|
||||
new Vue({
|
||||
el: globalConf.el,
|
||||
render: h => h(App),
|
||||
router: Router,
|
||||
store: Store
|
||||
});
|
||||
|
||||
})
|
||||
.catch(error => {
|
||||
alert('error loading: ' + error.message);
|
||||
|
@ -1,10 +1,9 @@
|
||||
import Vue from 'vue';
|
||||
import BaseUI from './lib/baseui.js';
|
||||
import Views from './views/views.js';
|
||||
|
||||
|
||||
// load init
|
||||
BaseUI.InitApp(Vue, {
|
||||
BaseUI.InitApp({
|
||||
el: '#vue-app',
|
||||
initUrl: 'conf/init.json',
|
||||
views: Views
|
||||
|
@ -2,7 +2,12 @@
|
||||
|
||||
// font path mixin
|
||||
.fontPath(@path, @filename, @version){
|
||||
src: url('@{path}@{filename}.woff?@{version}') format('woff');
|
||||
src: url('@{path}@{filename}.eot?@{version}');
|
||||
src: url('@{path}@{filename}.eot?@{version}#iefix') format('embedded-opentype'),
|
||||
url('@{path}@{filename}.woff2?@{version}') format('woff2'),
|
||||
url('@{path}@{filename}.woff?@{version}') format('woff'),
|
||||
url('@{path}@{filename}.ttf?@{version}') format('truetype'),
|
||||
url('@{path}@{filename}.svg?@{version}#iconfont') format('svg');
|
||||
}
|
||||
|
||||
.iconStyles(@font-face){
|
||||
|
@ -23,34 +23,28 @@ export default {
|
||||
return {
|
||||
username: "",
|
||||
password: "",
|
||||
elements: [
|
||||
{
|
||||
key: "username",
|
||||
elements: {
|
||||
username: {
|
||||
element: "my-input",
|
||||
icon: "icon-user",
|
||||
validate: {
|
||||
required: true,
|
||||
requiredMessage: "Der Benutzername wird benötigt!"
|
||||
},
|
||||
required: true,
|
||||
requiredMessage: "Der Benutzername wird benötigt!",
|
||||
props: {
|
||||
type: "text",
|
||||
placeholder: "Benutzername"
|
||||
}
|
||||
},
|
||||
{
|
||||
key: "password",
|
||||
password: {
|
||||
element: "my-input",
|
||||
icon: "icon-key",
|
||||
validate: {
|
||||
required: true,
|
||||
requiredMessage: "Das Passwort wird benötigt!"
|
||||
},
|
||||
required: true,
|
||||
requiredMessage: "Das Passwort wird benötigt!",
|
||||
props: {
|
||||
type: "password",
|
||||
placeholder: "Passwort"
|
||||
}
|
||||
}
|
||||
],
|
||||
},
|
||||
buttons: [{
|
||||
label: "login",
|
||||
type: "submit"
|
||||
|
@ -68,9 +68,9 @@ export default {
|
||||
search
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
this.hasMore = (response.data.length >= limit);
|
||||
this.newRows = response.data;
|
||||
.then(rows => {
|
||||
this.hasMore = (rows.length >= limit);
|
||||
this.newRows = rows;
|
||||
this.loading = false;
|
||||
})
|
||||
.catch(error => {
|
||||
|
522
src/views/lists/medialist.vue
Normal file
522
src/views/lists/medialist.vue
Normal file
@ -0,0 +1,522 @@
|
||||
<template>
|
||||
<div class="Medialist">
|
||||
|
||||
<!-- Overlay -->
|
||||
<div id="overlay">
|
||||
<div class="overlay_inner">
|
||||
<div class="overlay_container">
|
||||
<div class="overlay_top">
|
||||
<ul>
|
||||
<li>< <i class="ion-chevron-left"></i></li>
|
||||
<li> > <i class="ion-chevron-right"></i></li>
|
||||
<li class="close"><i class="ion-android-close"></i>x</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="overlay_content">
|
||||
<div class="overlay_left">
|
||||
<div class="overlay_img"><img src="assets/images/placeholder_image.jpg" alt=""></div>
|
||||
</div>
|
||||
<div class="overlay_right">
|
||||
<table>
|
||||
<tr>
|
||||
<td width="150"><strong>Dateiname:</strong></td>
|
||||
<td>210_21.jpg</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Hochgeladen am:</strong></td>
|
||||
<td>14. September 2017</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Dateigröße:</strong></td>
|
||||
<td>64 KB</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Abmessungen:</strong></td>
|
||||
<td>600 × 600</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<section class="overlay_form">
|
||||
<form action="">
|
||||
<input type="text" placeholder="URL">
|
||||
<input type="text" placeholder="Titel">
|
||||
<input type="text" placeholder="Beschriftung">
|
||||
<input type="text" placeholder="Alternativtext">
|
||||
</form>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h1>Medien</h1>
|
||||
<div class="medialist_container">
|
||||
<!-- Media-File -->
|
||||
<div class="media image">
|
||||
<div class="media_inner">
|
||||
<img src="assets/images/placeholder_image.jpg" alt="">
|
||||
<i class="icon icon-images"></i>
|
||||
<a href=""></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Media-File -->
|
||||
<div class="media image">
|
||||
<div class="media_inner">
|
||||
<img src="assets/images/placeholder_image.jpg" alt="">
|
||||
<i class="icon icon-images"></i>
|
||||
<a href=""></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Media-File -->
|
||||
<div class="media file">
|
||||
<div class="media_inner">
|
||||
<div class="text">Das-Dokument.pdf</div>
|
||||
<i class="icon icon-document-text"></i>
|
||||
<a href=""></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Media-File -->
|
||||
<div class="media file">
|
||||
<div class="media_inner">
|
||||
<div class="text">Das-Dokument.pdf</div>
|
||||
<i class="icon icon-document-text"></i>
|
||||
<a href=""></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Media-File -->
|
||||
<div class="media file">
|
||||
<div class="media_inner">
|
||||
<div class="text">Das-Dokument.pdf</div>
|
||||
<i class="icon icon-document-text"></i>
|
||||
<a href=""></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Media-File -->
|
||||
<div class="media image">
|
||||
<div class="media_inner">
|
||||
<img src="assets/images/placeholder_image.jpg" alt="">
|
||||
<i class="icon icon-images"></i>
|
||||
<a href=""></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Media-File -->
|
||||
<div class="media image">
|
||||
<div class="media_inner">
|
||||
<img src="assets/images/placeholder_image.jpg" alt="">
|
||||
<i class="icon icon-images"></i>
|
||||
<a href=""></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Media-File -->
|
||||
<div class="media file">
|
||||
<div class="media_inner">
|
||||
<div class="text">Das-Dokument.pdf</div>
|
||||
<i class="icon icon-document-text"></i>
|
||||
<a href=""></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Media-File -->
|
||||
<div class="media audio">
|
||||
<div class="media_inner">
|
||||
<div class="text">Audiofile.mp3</div>
|
||||
<i class="icon icon-stats-bars"></i>
|
||||
<a href=""></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Media-File -->
|
||||
<div class="media video">
|
||||
<div class="media_inner">
|
||||
<div class="text">Videofile.avi</div>
|
||||
<i class="icon icon-videocamera"></i>
|
||||
<a href=""></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Media-File -->
|
||||
<div class="media image">
|
||||
<div class="media_inner">
|
||||
<img src="assets/images/placeholder_image.jpg" alt="">
|
||||
<i class="icon icon-images"></i>
|
||||
<a href=""></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Media-File -->
|
||||
<div class="media video">
|
||||
<div class="media_inner">
|
||||
<div class="text">Videofile.avi</div>
|
||||
<i class="icon icon-videocamera"></i>
|
||||
<a href=""></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Media-File -->
|
||||
<div class="media image">
|
||||
<div class="media_inner">
|
||||
<img src="assets/images/placeholder_image.jpg" alt="">
|
||||
<i class="icon icon-images"></i>
|
||||
<a href=""></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Media-File -->
|
||||
<div class="media audio">
|
||||
<div class="media_inner">
|
||||
<div class="text">Audiofile.mp3</div>
|
||||
<i class="icon icon-stats-bars"></i>
|
||||
<a href=""></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Media-File -->
|
||||
<div class="media image">
|
||||
<div class="media_inner">
|
||||
<img src="assets/images/placeholder_image.jpg" alt="">
|
||||
<i class="icon icon-images"></i>
|
||||
<a href=""></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Media-File -->
|
||||
<div class="media image">
|
||||
<div class="media_inner">
|
||||
<img src="assets/images/placeholder_image.jpg" alt="">
|
||||
<i class="icon icon-images"></i>
|
||||
<a href=""></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Media-File -->
|
||||
<div class="media image">
|
||||
<div class="media_inner">
|
||||
<img src="assets/images/placeholder_image.jpg" alt="">
|
||||
<i class="icon icon-images"></i>
|
||||
<a href=""></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Media-File -->
|
||||
<div class="media image">
|
||||
<div class="media_inner">
|
||||
<img src="assets/images/placeholder_image.jpg" alt="">
|
||||
<i class="icon icon-images"></i>
|
||||
<a href=""></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Media-File -->
|
||||
<div class="media file">
|
||||
<div class="media_inner">
|
||||
<div class="text">Dokument.pdf</div>
|
||||
<i class="icon icon-videocamera"></i>
|
||||
<a href=""></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Media-File -->
|
||||
<div class="media file">
|
||||
<div class="media_inner">
|
||||
<div class="text">Dokument.pdf</div>
|
||||
<i class="icon icon-document-text"></i>
|
||||
<a href=""></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Media-File -->
|
||||
<div class="media image">
|
||||
<div class="media_inner">
|
||||
<img src="assets/images/placeholder_image.jpg" alt="">
|
||||
<i class="icon icon-images"></i>
|
||||
<a href=""></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Media-File -->
|
||||
<div class="media image">
|
||||
<div class="media_inner">
|
||||
<img src="assets/images/placeholder_image.jpg" alt="">
|
||||
<i class="icon icon-images"></i>
|
||||
<a href=""></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Media-File -->
|
||||
<div class="media image">
|
||||
<div class="media_inner">
|
||||
<img src="assets/images/placeholder_image.jpg" alt="">
|
||||
<i class="icon icon-images"></i>
|
||||
<a href=""></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Media-File -->
|
||||
<div class="media image">
|
||||
<div class="media_inner">
|
||||
<img src="assets/images/placeholder_image.jpg" alt="">
|
||||
<i class="icon icon-images"></i>
|
||||
<a href=""></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Media-File -->
|
||||
<div class="media image">
|
||||
<div class="media_inner">
|
||||
<img src="assets/images/placeholder_image.jpg" alt="">
|
||||
<i class="icon icon-images"></i>
|
||||
<a href=""></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Media-File -->
|
||||
<div class="media image">
|
||||
<div class="media_inner">
|
||||
<img src="assets/images/placeholder_image.jpg" alt="">
|
||||
<i class="icon icon-images"></i>
|
||||
<a href=""></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Media-File -->
|
||||
<div class="media image">
|
||||
<div class="media_inner">
|
||||
<img src="assets/images/placeholder_image.jpg" alt="">
|
||||
<i class="icon icon-images"></i>
|
||||
<a href=""></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Media-File -->
|
||||
<div class="media image">
|
||||
<div class="media_inner">
|
||||
<img src="assets/images/placeholder_image.jpg" alt="">
|
||||
<i class="icon icon-images"></i>
|
||||
<a href=""></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Media-File -->
|
||||
<div class="media image">
|
||||
<div class="media_inner">
|
||||
<img src="assets/images/placeholder_image.jpg" alt="">
|
||||
<i class="icon icon-images"></i>
|
||||
<a href=""></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Media-File -->
|
||||
<div class="media image">
|
||||
<div class="media_inner">
|
||||
<img src="assets/images/placeholder_image.jpg" alt="">
|
||||
<i class="icon icon-images"></i>
|
||||
<a href=""></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Media-File -->
|
||||
<div class="media video">
|
||||
<div class="media_inner">
|
||||
<div class="text">Videofile.avi</div>
|
||||
<i class="icon icon-videocamera"></i>
|
||||
<a href=""></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div style="clear:both;"></div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/*
|
||||
|
||||
WIR HABEN KEIN JQUERY
|
||||
|
||||
$(document).ready(function() {
|
||||
$('.media a').on('click', function(e) {
|
||||
$('#overlay').show();
|
||||
});
|
||||
});
|
||||
*/
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
@import "~mixins";
|
||||
.medialist_container {margin:-6px;}
|
||||
.media {display:block; position:relative; width:10%; height:auto; line-height:0; float:left; padding:3px;}
|
||||
.media_inner {transition:all ease 0.2s; border:solid 5px transparent; width:100%; height:0; padding-bottom:100%; position:relative;}
|
||||
.media_inner a {position:absolute; top:0px; bottom:0px; left:0px; right:0px;}
|
||||
.media:hover .media_inner {border:solid 5px #28b78d;}
|
||||
|
||||
.media img {
|
||||
position:absolute;
|
||||
height:100%;
|
||||
width:100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
.media i {
|
||||
display:block;
|
||||
position:absolute;
|
||||
left:0px;
|
||||
bottom:0px;
|
||||
width:30px;
|
||||
height:30px;
|
||||
background:#28b78d;
|
||||
color:#FFF;
|
||||
text-align:center;
|
||||
font-size:20px;
|
||||
padding-top:5px;
|
||||
}
|
||||
.file i {background:#2868b7;}
|
||||
.video i {background:#ac1a0b;}
|
||||
.audio i {background:#c95c14;}
|
||||
|
||||
.media .text {
|
||||
position:absolute;
|
||||
top:0px; bottom:0px; left:0px; right:0px;
|
||||
background:#CCC;
|
||||
color:#FFF;
|
||||
font-weight:600;
|
||||
padding:20px;
|
||||
display:flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align:center;
|
||||
line-height:1.2;
|
||||
}
|
||||
.media .text i {
|
||||
line-height:1;
|
||||
}
|
||||
.file .text {background:#2868b7;}
|
||||
.video .text {background:#ac1a0b;}
|
||||
.audio .text {background:#c95c14;}
|
||||
/*.media .text i {
|
||||
position:relative;
|
||||
top:inherit; bottom:inherit; left:inherit; right:inherit;
|
||||
display:block;
|
||||
text-align:center;
|
||||
margin:0 auto 5px auto;
|
||||
background:none;
|
||||
font-size:30px;
|
||||
height:35px;
|
||||
line-height:1;
|
||||
}
|
||||
.media .text i:before {
|
||||
margin-left:0px!important;
|
||||
}*/
|
||||
|
||||
@media(max-width:1600px) {
|
||||
.media {width:20%;}
|
||||
}
|
||||
@media(max-width:1000px) {
|
||||
.media {width:33.33333%;}
|
||||
}
|
||||
@media(max-width:600px) {
|
||||
.media {width:50%;}
|
||||
}
|
||||
|
||||
/* Overlay */
|
||||
#overlay {
|
||||
position:fixed;
|
||||
top:0;
|
||||
bottom:0;
|
||||
right:0;
|
||||
left:0;
|
||||
z-index:2000;
|
||||
background:rgba(0,0,0,0.8);
|
||||
/*display:none;*/
|
||||
}
|
||||
.overlay_inner {
|
||||
position:absolute;
|
||||
top:0px;
|
||||
left:0px;
|
||||
right:0px;
|
||||
bottom:0px;
|
||||
display:flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align:center;
|
||||
line-height:1.2;
|
||||
}
|
||||
.overlay_container {
|
||||
background: #FFF;
|
||||
height: auto;
|
||||
width: 50%;
|
||||
margin-top: -50px;
|
||||
/*border: solid 5px #CCC;*/
|
||||
/*align-items: center;
|
||||
justify-content: center;
|
||||
text-align:center;*/
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.overlay_top {
|
||||
height:40px;
|
||||
width:100%;
|
||||
background:#FFF;
|
||||
border-bottom:solid 1px #CCC;
|
||||
}
|
||||
.overlay_top ul {list-style-type: none; float:right;}
|
||||
.overlay_top ul li {float:left; height:40px; line-height:40px; width:40px; text-align:center; color:#666; border-left:solid 1px #CCC;}
|
||||
.overlay_top ul li i:before {margin:0px;}
|
||||
|
||||
.overlay_content {
|
||||
text-align: center;
|
||||
display:flex;
|
||||
}
|
||||
|
||||
.overlay_left {
|
||||
float:left;
|
||||
width:60%;
|
||||
padding: 25px;
|
||||
display:flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
text-align:center;
|
||||
flex: 1;
|
||||
}
|
||||
.overlay_right {
|
||||
float:left;
|
||||
width:40%;
|
||||
padding: 25px;
|
||||
border-left:solid 1px #CCC;
|
||||
background:#eeeeee;
|
||||
/*display:flex;
|
||||
align-items: center;
|
||||
justify-content: center;*/
|
||||
text-align:left;
|
||||
flex: 1;
|
||||
font-weight:400;
|
||||
}
|
||||
.overlay_img {
|
||||
width:80%;
|
||||
}
|
||||
.overlay_img img {width:100%;}
|
||||
.overlay_form {
|
||||
border-top:solid 1px #CCC;
|
||||
padding-top:30px;
|
||||
margin-top:30px;
|
||||
}
|
||||
.overlay_form input {
|
||||
margin-bottom:10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: "Medialist"
|
||||
}
|
||||
</script>
|
@ -114,9 +114,9 @@ export default {
|
||||
search
|
||||
}
|
||||
})
|
||||
.then(response => {
|
||||
this.hasMore = (response.data.length >= limit);
|
||||
this.newRows = response.data;
|
||||
.then(rows => {
|
||||
this.hasMore = (rows.length >= limit);
|
||||
this.newRows = rows;
|
||||
this.loading = false;
|
||||
})
|
||||
.catch(error => {
|
||||
|
@ -3,6 +3,7 @@ import LoginForm from './forms/login.vue';
|
||||
import Logout from './forms/logout.vue';
|
||||
import Userlist from './lists/userlist.vue';
|
||||
import Domainlist from './lists/domainlist.vue';
|
||||
import Medialist from './lists/medialist.vue';
|
||||
import Settings from 'views/forms/settings.vue';
|
||||
|
||||
export default {
|
||||
@ -11,5 +12,6 @@ export default {
|
||||
Logout,
|
||||
Userlist,
|
||||
Domainlist,
|
||||
Medialist,
|
||||
Settings
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ module.exports = {
|
||||
output: {
|
||||
path: exportPath,
|
||||
publicPath: 'build/',
|
||||
filename: '[name].js',
|
||||
filename: 'baseui-[name].bundle.js',
|
||||
library: 'baseUI',
|
||||
libraryTarget: 'umd'
|
||||
},
|
||||
@ -57,8 +57,11 @@ module.exports = {
|
||||
loader: 'eslint-loader',
|
||||
exclude: /node_modules/
|
||||
}, {
|
||||
test: /\.woff(\?.*)?$/i,
|
||||
loader: 'url-loader',
|
||||
test: /\.(jpe?g|png|gif|woff|woff2|ttf|svg|eot)(\?.*)?$/i,
|
||||
loader: 'file-loader',
|
||||
options: {
|
||||
name: '[name].[sha512:hash:base64:7].[ext]'
|
||||
}
|
||||
}, {
|
||||
test: /\.vue$/,
|
||||
loader: 'vue-loader'
|
||||
@ -80,4 +83,4 @@ module.exports = {
|
||||
extensions: [".vue", ".js", ".less"]
|
||||
},
|
||||
plugins
|
||||
};
|
||||
};
|
Loading…
Reference in New Issue
Block a user