Commit a1da7f50 authored by dindigala's avatar dindigala
Browse files

Merge branch 'feature/#51-panel-configurable' into 'develop'

Feature/#51 panel user configurable

See merge request subugoe/emo/Qviewer!44
parents 521f98fe 3dbace39
Pipeline #148816 passed with stages
in 2 minutes and 45 seconds
......@@ -50,6 +50,7 @@ module.exports = {
'prefer-promise-reject-errors': 'off',
// allow debugger during development only
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'max-len': 0
}
}
......@@ -5,13 +5,15 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.3.0] - 2020-08-03
## [1.3.0] - 2020-08-24
### Added
- rewrite of mainview template. components are dynamic now and the order is configurable
- Refactored mainview template. Components are dynamic now and the order is configurable
- New button to the toggle bar so that user can able to configure order of the panels dynamically.
- created a new re-usabla component to drag and drop panels.
### Changed
- several minors
- refactored toggleIndex component.
## [1.2.1] - 2020-08-12
......
......@@ -180,47 +180,65 @@ It's a json object. So if you are going to make any changes and you have to quot
"item": "Sheet",
"manifest": "Manuscript"
},
"panels": {
"annotations": {
"heading": "Annotations",
"order": 4,
"show": true,
"tab": false
},
"image": {
"heading": "Image",
"order": 2,
"show": true,
"tab": false
"standalone": true
}
</script>
```
The data structure of the panels are inside app.vue component. You can work on this data structure to make any required changes.
```html
data() {
return {
.
.
.
panels: [
{
component: null,
name: 'tabs',
show: true,
tabs: {
children: [
{
component: Treeviewtab,
label: 'Contents',
name: 'content',
},
{
component: Metadatatab,
label: 'Metadata',
name: 'meta',
},
],
model: 'content',
},
toolbar: 'Tabs',
},
"meta": {
"heading": "Metadata",
"order": 4,
"show": true,
"tab": true
{
component: OpenSeadragon,
name: 'image',
show: true,
tabs: [],
toolbar: 'Image',
},
"text": {
"heading": "Text",
"order": 3,
"show": true,
"tab": false
{
component: Content,
name: 'text',
show: true,
tabs: [],
toolbar: 'Content',
},
"tree": {
"heading": "Treeview",
"order": 5,
"show": true,
"tab": true
{
component: null,
name: 'annotations',
show: true,
tabs: [],
toolbar: 'Annotations',
},
"tabs": {
"default": "Treeview",
"heading": "Tabs",
"order": 1,
"show": true
}
},
"standalone": true
],
}
</script>
}
```
### The keys in detail
......@@ -269,32 +287,33 @@ It's a json object. So if you are going to make any changes and you have to quot
- **panels**
It's keys correspond to the panelnames, e.g. "contents", "text", "image" and so on.
<br />
**Note:** Pls **leave these keys UNTOUCHED** since these are for internal use only!
<br /><br />
Each of these keys consists of further sub-keys: `heading`, `order`, `show` and `tab`.
Change either sub-key according to your liking. (Set either show-key to **false** for instance, if you don't want the Viewer to show the appropriate panel/s)
<br />
**Note:** Pls **leave these keys UNTOUCHED** since these are for internal use only!
<br /><br />
Each object inside panels consists of keys: `component`, `name`, `show`, `tab` and `toolbar`.
Change either name-key according to your liking and set either show-key to **false** if you don't want the Viewer to show the appropriate panel/s.
Example given:
```json
{
"panels": {
"tree": {
"heading": "toC",
"order": 3,
"show": false,
"tab": false
}
panels: {
{
component: toC,
name: 'text',
show: false,
tabs: false,
toolbar: 'toC',
},
}
}
```
- **heading** refers to the caption in each panel's toolbar
- **order** means the order in which the panels will appear from left to right
- **show** toggles (show or rather hide) the appropriate panel respectively
- **tab** denotes, if the panel will be grouped together with others inside a single panel
- **Component** Refers to the required component that we are integrating.
- **name** Refers to the caption in each panel's toolbar.
- **show** toggles (show or rather hide) the appropriate panel respectively.
- **tabs** denotes, if the panel will be grouped together with others inside a single panel.
- **toolbar** displays the related component on toolbar and can able to toggle panels.
- **standalone**
......
{
"name": "viewer",
"version": "1.2.0",
"version": "1.3.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
......@@ -13449,6 +13449,11 @@
"is-plain-obj": "^1.0.0"
}
},
"sortablejs": {
"version": "1.10.2",
"resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.10.2.tgz",
"integrity": "sha512-YkPGufevysvfwn5rfdlGyrGjt7/CRHwvRPogD/lC+TnvcN29jDpCifKP+rBqf+LRldfXSTh+0CGLcSg0VIxq3A=="
},
"source-list-map": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
......@@ -15053,6 +15058,14 @@
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
"dev": true
},
"vuedraggable": {
"version": "2.24.0",
"resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-2.24.0.tgz",
"integrity": "sha512-IlslPpc+iZ2zPNSJbydFZIDrE+don5u+Nc/bjT2YaF+Azidc+wxxJKfKT0NwE68AKk0syb0YbZneAcnynqREZQ==",
"requires": {
"sortablejs": "^1.10.1"
}
},
"vuex": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/vuex/-/vuex-3.4.0.tgz",
......
......@@ -38,7 +38,8 @@
"dependencies": {
"@quasar/extras": "^1.9.3",
"openseadragon": "^2.4.2",
"quasar": "^1.12.13"
"quasar": "^1.12.13",
"vuedraggable": "^2.24.0"
},
"devDependencies": {
"@quasar/app": "^1.9.6",
......
......@@ -8,6 +8,7 @@
:itemlabel="itemlabel"
:itemurls="itemurls"
:manifests="manifests"
:panels="panels"
/>
<q-page-container>
......@@ -22,6 +23,7 @@
:labels="config.labels"
:language="itemlanguage"
:manifests="manifests"
:panels="panels"
:request="request"
:tree="tree"
/>
......@@ -33,8 +35,12 @@
</template>
<script>
import Header from '@/components/header.vue';
import Content from '@/components/content.vue';
import Footer from '@/components/footer.vue';
import Header from '@/components/header.vue';
import Metadatatab from '@/components/tab-panels/metadatatab.vue';
import OpenSeadragon from '@/components/openseadragon.vue';
import Treeviewtab from '@/components/tab-panels/treeviewtab.vue';
export default {
name: 'Viewer',
......@@ -59,6 +65,50 @@ export default {
label: '',
manifests: [],
tree: [],
panels: [
{
component: null,
name: 'tabs',
show: true,
tabs: {
children: [
{
component: Treeviewtab,
label: 'Contents',
name: 'content',
},
{
component: Metadatatab,
label: 'Metadata',
name: 'meta',
},
],
model: 'content',
},
toolbar: 'Tabs',
},
{
component: OpenSeadragon,
name: 'image',
show: true,
tabs: [],
toolbar: 'Image',
},
{
component: Content,
name: 'text',
show: true,
tabs: [],
toolbar: 'Content',
},
{
component: null,
name: 'annotations',
show: true,
tabs: [],
toolbar: 'Annotations',
},
],
};
},
methods: {
......@@ -306,6 +356,9 @@ export default {
this.$root.$on('update-fontsize', (fontsize) => {
this.fontsize = fontsize;
});
this.$root.$on('panels-position', (newPanels) => {
this.panels = newPanels;
});
/**
* listen to item change (user interaction).
* emitted in: *getItemurls*; handler for tree nodes. fired on user interaction
......
<template>
<div class="q-pa-md q-gutter-sm">
<div class="scroll">
<q-infinite-scroll>
<div class="row sticky">
<div>
<q-btn
class="q-mr-sm q-mb-sm cursor-pointer"
color="grey-8"
flat
round
size="md"
title="Increase Textsize"
@click="increase()"
>
<q-icon :name="fasSearchPlus" size="sm" />
</q-btn>
<div>
<div class="row sticky">
<div>
<q-btn
class="q-mr-sm q-mb-sm cursor-pointer"
color="grey-8"
flat
round
size="md"
title="Increase Textsize"
@click="increase()"
>
<q-icon :name="fasSearchPlus" size="sm" />
</q-btn>
<q-btn
class="q-mr-sm q-mb-sm cursor-pointer"
color="grey-8"
flat
round
size="md"
title="Decrease Textsize"
@click="decrease()"
>
<q-icon :name="fasSearchMinus" />
</q-btn>
</div>
</div>
<q-btn
class="q-mr-sm q-mb-sm cursor-pointer"
color="grey-8"
flat
round
size="md"
title="Decrease Textsize"
@click="decrease()"
>
<q-icon :name="fasSearchMinus" />
</q-btn>
</div>
</div>
<div class="row" style="display: contents">
<div :id="nodeid" :style="`font-size: ${fontsize}px`" v-html="content"></div>
</div>
</q-infinite-scroll>
<div class="row" style="display: contents">
<div class="scroll-panel" :id="nodeid" :style="`font-size: ${fontsize}px`" v-html="content" />
</div>
</div>
</template>
......
......@@ -25,6 +25,8 @@
/>
<ToggleIndex v-if="config.headers.toggle"
:config="config"
:panels="panels"
class="
col
col-md-auto
......@@ -34,7 +36,6 @@
justify-sm-evenly
row-sm"
:imageurl="imageurl"
:panelstates="config.panels"
/>
</div>
</q-header>
......@@ -59,6 +60,7 @@ export default {
itemlabel: String,
itemurls: Array,
manifests: Array,
panels: Array,
},
};
</script>
......
......@@ -51,6 +51,7 @@ export default {
button:first-of-type
@media (min-width: 600px)
margin-right: 8px
.q-input
width: 100%
@media (min-width: 600px)
......
......@@ -75,11 +75,10 @@ export default {
};
</script>
<style scoped>
figure {
display: inline-block;
height: 75vh;
margin: 0;
<style lang="sass" scoped>
figure
display: inline-block
height: 75vh
margin: 0
width: 95%
}
</style>
<template>
<div class="col-xs-auto" title="Project info">
<div class="softwareinfo col-xs-auto" title="Project info">
<q-btn
flat
color="grey"
......@@ -67,11 +67,12 @@
<script>
import {
fasInfoCircle,
fasBook,
fasBug,
fasCode,
fasBook,
} from '@quasar/extras/fontawesome-v5';
fasInfoCircle,
}
from '@quasar/extras/fontawesome-v5';
export default {
name: 'Softwareinfo',
......@@ -81,10 +82,10 @@ export default {
};
},
created() {
this.fasInfoCircle = fasInfoCircle;
this.fasBook = fasBook;
this.fasBug = fasBug;
this.fasCode = fasCode;
this.fasBook = fasBook;
this.fasInfoCircle = fasInfoCircle;
},
};
</script>
<template>
<div class="scroll-panel">
<Metadata v-if="manifests.length"
:collection="collection"
:config="config"
:itemlabel="itemlabel"
:language="language"
:manifests="manifests"
/>
</div>
</template>
<script>
import Metadata from '@/components/metadata.vue';
export default {
props: {
collection: Object,
config: Object,
itemlabel: String,
language: String,
manifests: Array,
},
components: {
Metadata,
},
};
</script>
<template>
<Tree v-if="tree.length && manifests.length"
:manifests="manifests"
:tree="tree"
/>
</template>
<script>
import Tree from '@/components/tree.vue';
export default {
props: {
tree: Array,
manifests: Array,
},
components: {
Tree,
},
};
</script>
<template>
<section class="panel-position">
<q-btn class="btn-panel" :icon="panelicon" @click="status = true" label="Configure" flat />
<q-dialog v-model="status" persistent transition-show="scale" transition-hide="scale">
<q-card class="bg-teal text-white" style="width: 450px">
<q-card-section>
<div class="text-h6 text-capitalize">Customize Panels</div>
</q-card-section>
<q-card-section class="q-pt-none">
<Dragboxes :boxs="panelboxes" @updated="(b) => $root.$emit('panels-position', b)" />
</q-card-section>
<q-card-actions align="right" class="bg-white text-teal">
<q-btn flat label="OK" v-close-popup />
</q-card-actions>
</q-card>
</q-dialog>
</section>
</template>
<script>
import Dragboxes from '@/components/util/dragboxes';
import { fasSolarPanel } from '@quasar/extras/fontawesome-v5';
export default {
components: {
Dragboxes,
},
props: {
panelboxes: Array,
},
data: () => ({
status: false,
}),
computed: {
panelicon() {
return fasSolarPanel;
},
},
};
</script>
<style lang="sass" scoped>
.btn-panel
height: 75%
.panel-position
display: flex
justify-content: center
</style>
<template>
<div>
<div class="q-d-flex">
<ToggleFilter>
<q-list>
<q-item v-for="(name, idx) in togglekeys" :key="idx"
<q-list class="toggle-list">
<q-item v-for="(p, i) in panels" :key="`toggle${i}`"
class="bg-grey-2"
clickable
v-close-popup
:aria-selected="toggleAria(idx)"
:title="toggleTitle(idx)"
@click="toggleIcon(idx); updateStatus(idx)"
:title="handleToggleTitle(i)"
@click="() => handleStatusPanel(i)"
>
<q-icon class="q-pr-xs q-mt-xs" size="xs" :name="toggleIcon(idx)" />
<q-item-section>{{ panelstates[name].heading | capitalize }}</q-item-section>
<q-icon class="q-pr-xs" size="xs" :name="renderCheckIcon(i)" />
{{ p.toolbar.toUpperCase() }}
</q-item>
<q-item
class="bg-grey-5"
clickable
v-close-popup
title="Reset panels to default view"
@click="resetPanelStatus"
v-close-popup
@click="()=> handleStatusPanel(-1, true)"
>
<q-icon class="q-pr-xs q-mt-xs" size="xs" :name="fasUndo" />
<q-item-section>{{ 'Reset Panels' | capitalize }}</q-item-section>
<q-icon class="q-pr-xs text-capitalize" size="xs" :name="fasUndo" />
{{ 'RESET' }}
</q-item>
</q-list>
</ToggleFilter>
<PanelsPosition :panelboxes="panels"/>
</div>