Add option to magnify certain page blocks

This commit is contained in:
Atanas Yonkov
2022-12-12 12:23:53 +02:00
parent 78b49a6411
commit de61dc936e
19 changed files with 237 additions and 30 deletions
@@ -113,6 +113,16 @@
</b-input-group>
</b-col>
</b-form-group>
<b-form-group
v-if="block.options.magnifyOption !== undefined"
:label="$t('general.magnifyLabel')"
>
<b-form-select
v-model="block.options.magnifyOption"
:options="magnifyOptions"
/>
</b-form-group>
</div>
</b-tab>
@@ -172,6 +182,14 @@ export default {
isNew () {
return this.block.blockID === NoID
},
magnifyOptions () {
return [
{ value: '', text: this.$t('general.magnifyOptions.disabled') },
{ value: 'modal', text: this.$t('general.magnifyOptions.modal') },
{ value: 'fullscreen', text: this.$t('general.magnifyOptions.fullscreen') },
]
},
},
methods: {
@@ -1,25 +1,22 @@
<template>
<div class="h-100 p-2">
<div class="h-100">
<b-card
no-body
class="h-100 border-0 shadow"
:class="blockClass"
>
<b-card-header
v-if="headerSet || block.title || block.description"
v-if="headerSet || block.title || block.description || hasMagnifyIcon || block.options.refreshRate >= 5"
class="border-0 text-nowrap px-3"
:class="{ 'p-0': !(block.title || block.description)}"
header-bg-variant="white"
:header-text-variant="block.style.variants.headerText"
>
<div
v-if="!headerSet"
>
<div
v-if="block.title"
class="d-flex justify-content-between align-items-center"
>
<div class="d-flex">
<h5
v-if="block.title"
class="text-truncate mb-0"
>
{{ block.title }}
@@ -27,13 +24,27 @@
<slot name="title-badge" />
</h5>
<font-awesome-icon
v-if="block.options.refreshRate >= 5"
:icon="['fa', 'sync']"
class="h6 text-secondary mb-0"
role="button"
@click="$emit('refreshBlock')"
/>
<div
v-if="block.options.refreshRate >= 5 || hasMagnifyIcon"
class="ml-auto"
>
<font-awesome-icon
v-if="block.options.refreshRate >= 5"
:icon="['fa', 'sync']"
class="h6 text-secondary"
role="button"
@click="$emit('refreshBlock')"
/>
<font-awesome-icon
v-if="hasMagnifyIcon"
:icon="['fas', isBlockOpened ? 'times' : 'search-plus']"
:title="$t(isBlockOpened ? '' : 'general.label.magnify')"
class="h6 text-secondary ml-2"
role="button"
@click="$root.$emit('magnify-page-block', isBlockOpened ? undefined : block.blockID)"
/>
</div>
</div>
<b-card-text
@@ -105,6 +116,14 @@ export default {
]
},
hasMagnifyIcon () {
return this.block.options.magnifyOption
},
isBlockOpened () {
return this.block.blockID === this.$route.query.blockID
},
headerSet () {
return !!this.$scopedSlots.header
},
@@ -1,19 +1,18 @@
<template>
<div class="h-100 p-2">
<div class="h-100">
<div
class="d-flex flex-column position-relative h-100 border-0"
:class="blockClass"
>
<div
v-if="headerSet || block.title || block.description"
v-if="(headerSet || block.title || block.description || hasMagnifyIcon || block.options.refreshRate >= 5)"
:class="`card-header bg-transparent border-0 text-nowrap px-3 text-${block.style.variants.headerText}`"
>
<div
v-if="!headerSet"
>
<div
v-if="block.title"
class="d-flex justify-content-between align-items-center"
class="d-flex"
>
<h5
class="text-truncate mb-0"
@@ -23,13 +22,27 @@
<slot name="title-badge" />
</h5>
<font-awesome-icon
v-if="block.options.refreshRate >= 5"
:icon="['fa', 'sync']"
class="h6 text-secondary mb-0"
role="button"
@click="$emit('refreshBlock')"
/>
<div
v-if="block.options.refreshRate >= 5 || hasMagnifyIcon"
class="ml-auto"
>
<font-awesome-icon
v-if="block.options.refreshRate >= 5"
:icon="['fa', 'sync']"
class="h6 text-secondary"
role="button"
@click="$emit('refreshBlock')"
/>
<font-awesome-icon
v-if="hasMagnifyIcon"
:icon="['fas', isBlockOpened ? 'times' : 'search-plus']"
:title="$t(isBlockOpened ? '' : 'general.label.magnify')"
class="h6 text-secondary ml-2"
role="button"
@click="$root.$emit('magnify-page-block', isBlockOpened ? undefined : block.blockID)"
/>
</div>
</div>
<b-card-text
@@ -101,6 +114,14 @@ export default {
]
},
hasMagnifyIcon () {
return this.block.options.magnifyOption
},
isBlockOpened () {
return this.block.blockID === this.$route.query.blockID
},
headerSet () {
return !!this.$scopedSlots.header
},
@@ -0,0 +1,107 @@
<template>
<b-modal
v-model="showBlockModal"
scrollable
body-class="card p-0"
footer-class="p-0"
:content-class="contentClass"
:dialog-class="dialogClass"
hide-header
hide-footer
size="xl"
@hidden="hideModal"
>
<page-block
v-if="showBlockModal"
:block="block"
v-bind="$props"
v-on="$listeners"
/>
</b-modal>
</template>
<script>
import { compose } from '@cortezaproject/corteza-js'
import PageBlock from 'corteza-webapp-compose/src/components/PageBlocks'
export default {
i18nOptions: {
namespaces: 'block',
},
name: 'MagnificationModal',
components: {
PageBlock,
},
props: {
namespace: {
type: compose.Namespace,
required: true,
},
page: {
type: compose.Page,
required: true,
},
},
data () {
return {
showBlockModal: false,
block: undefined,
}
},
computed: {
dialogClass () {
return this.block && this.block.options.magnifyOption === 'fullscreen' ? 'h-100 mw-100 m-0 mh-100' : 'h-100'
},
contentClass () {
return this.block && this.block.options.magnifyOption === 'fullscreen' ? 'mh-100' : ''
},
},
watch: {
'$route.query.blockID': {
immediate: true,
handler (blockID, oldBlockID) {
if (blockID && !oldBlockID) {
this.showModal(blockID)
} else if (!blockID && oldBlockID) {
this.hideModal()
}
},
},
},
created () {
this.$root.$on('magnify-page-block', this.showModal)
},
beforeDestroy () {
this.$root.$off('magnify-page-block')
},
methods: {
showModal (blockID) {
if (blockID) {
this.block = this.page.blocks.find(block => block.blockID === blockID)
this.showBlockModal = true
this.$router.push({ query: { blockID } })
} else {
this.hideModal()
}
},
hideModal () {
this.showBlockModal = false
this.$router.push({ query: {} })
this.block = undefined
},
},
}
</script>
@@ -10,6 +10,7 @@
>
<page-block
v-bind="{ ...$attrs, block, page, boundingRect, blockIndex: index }"
class="p-2"
v-on="$listeners"
/>
</template>
@@ -8,6 +8,7 @@ import {
faDownload,
faFileExport,
faSearch,
faSearchPlus,
faBars,
faCloudDownloadAlt,
faTimes,
@@ -104,6 +105,7 @@ library.add(
faEdit,
faTrashAlt,
faSearch,
faSearchPlus,
faBars,
faCloudDownloadAlt,
faTimes,
@@ -103,6 +103,7 @@
v-bind="{ ...$attrs, ...$props, page, block, boundingRect, blockIndex: index }"
:record="record"
:module="module"
class="p-2"
/>
</div>
</template>
@@ -66,6 +66,11 @@
:namespace="namespace"
/>
<magnification-modal
:namespace="namespace"
:page="page"
/>
<attachment-modal />
</div>
</template>
@@ -74,6 +79,7 @@ import { mapActions } from 'vuex'
import Grid from 'corteza-webapp-compose/src/components/Public/Page/Grid'
import AttachmentModal from 'corteza-webapp-compose/src/components/Public/Page/Attachment/Modal'
import RecordModal from 'corteza-webapp-compose/src/components/Public/Record/Modal'
import MagnificationModal from 'corteza-webapp-compose/src/components/Public/Page/Block/Modal'
import PageTranslator from 'corteza-webapp-compose/src/components/Admin/Page/PageTranslator'
import { compose, NoID } from '@cortezaproject/corteza-js'
@@ -87,6 +93,7 @@ export default {
AttachmentModal,
RecordModal,
PageTranslator,
MagnificationModal,
},
props: {
@@ -28,6 +28,7 @@ export class PageBlock {
kind = ''
public options = {}
public style: PageBlockStyle = {
variants: {
headerText: 'dark',
@@ -36,6 +36,7 @@ class CalendarOptions {
public header: Partial<CalendarOptionsHeader> = {}
public locale = 'en-gb'
public refreshRate = 0
public magnifyOption = ''
}
/**
@@ -58,6 +59,9 @@ export class PageBlockCalendar extends PageBlock {
applyOptions (o?: Partial<CalendarOptions>): void {
if (!o) return
Apply(this.options, o, Number, 'refreshRate')
Apply(this.options, o, String, 'magnifyOption')
this.options.defaultView = PageBlockCalendar.handleLegacyView(o.defaultView) || 'dayGridMonth'
this.options.feeds = (o.feeds || []).map(f => new Feed(f))
this.options.header = merge(
@@ -6,11 +6,13 @@ const kind = 'Chart'
interface Options {
chartID: string;
refreshRate: number;
magnifyOption: string
}
const defaults: Readonly<Options> = Object.freeze({
chartID: NoID,
refreshRate: 0,
magnifyOption: ''
})
export class PageBlockChart extends PageBlock {
@@ -28,6 +30,8 @@ export class PageBlockChart extends PageBlock {
Apply(this.options, o, CortezaID, 'chartID')
Apply(this.options, o, Number, 'refreshRate')
Apply(this.options, o, String, 'magnifyOption')
}
}
@@ -10,6 +10,7 @@ interface Options {
referenceField: string;
sortDirection: string;
refreshRate: number;
magnifyOption: string
}
const defaults: Readonly<Options> = Object.freeze({
@@ -20,6 +21,7 @@ const defaults: Readonly<Options> = Object.freeze({
sortDirection: '',
referenceField: '',
refreshRate: 0,
magnifyOption: ''
})
export class PageBlockComment extends PageBlock {
@@ -35,7 +37,7 @@ export class PageBlockComment extends PageBlock {
applyOptions (o?: Partial<Options>): void {
if (!o) return
Apply(this.options, o, CortezaID, 'moduleID')
Apply(this.options, o, String, 'titleField', 'contentField', 'referenceField', 'filter', 'sortDirection')
Apply(this.options, o, String, 'titleField', 'contentField', 'referenceField', 'filter', 'sortDirection', 'magnifyOption')
Apply(this.options, o, Number, 'refreshRate')
}
}
@@ -5,10 +5,12 @@ const kind = 'Content'
interface Options {
body: string;
magnifyOption: string
}
const defaults: Readonly<Options> = Object.freeze({
body: '',
magnifyOption: ''
})
export class PageBlockContent extends PageBlock {
@@ -24,7 +26,7 @@ export class PageBlockContent extends PageBlock {
applyOptions (o?: Partial<Options>): void {
if (!o) return
Apply(this.options, o, String, 'body')
Apply(this.options, o, String, 'body', 'magnifyOption')
}
}
+3 -1
View File
@@ -14,6 +14,7 @@ interface Options {
borderRadius?: number;
margin?: number;
backgroundColor?: string;
magnifyOption: string;
}
const PageBlockFileDefaultMode = 'list'
@@ -39,6 +40,7 @@ const defaults: Readonly<Options> = Object.freeze({
borderRadius: undefined,
margin: undefined,
backgroundColor: undefined,
magnifyOption: ''
})
export class PageBlockFile extends PageBlock {
@@ -59,7 +61,7 @@ export class PageBlockFile extends PageBlock {
}
Apply(this.options, o, Boolean, 'hideFileName')
Apply(this.options, o, String, 'backgroundColor')
Apply(this.options, o, String, 'backgroundColor', 'magnifyOption')
Apply(this.options, o, Number, 'height', 'width', 'maxHeight', 'maxWidth', 'borderRadius', 'margin')
if (o.mode) {
@@ -8,6 +8,7 @@ interface Options {
src: string;
wrap: PageBlockWrap;
refreshRate: number;
magnifyOption: string;
}
const defaults: Readonly<Options> = Object.freeze({
@@ -15,6 +16,7 @@ const defaults: Readonly<Options> = Object.freeze({
src: '',
wrap: 'Plain',
refreshRate: 0,
magnifyOption: '',
})
export class PageBlockIFrame extends PageBlock {
@@ -30,7 +32,7 @@ export class PageBlockIFrame extends PageBlock {
applyOptions (o?: Partial<Options>): void {
if (!o) return
Apply(this.options, o, String, 'srcField', 'src', 'wrap')
Apply(this.options, o, String, 'srcField', 'src', 'wrap', 'magnifyOption')
Apply(this.options, o, Number, 'refreshRate')
}
}
@@ -24,6 +24,7 @@ interface Options {
allowExport: boolean;
perPage: number;
recordDisplayOption: string;
magnifyOption: string;
fullPageNavigation: boolean;
showTotalCount: boolean;
@@ -70,6 +71,7 @@ const defaults: Readonly<Options> = Object.freeze({
allowExport: false,
perPage: 20,
recordDisplayOption: 'sameTab',
magnifyOption: '',
fullPageNavigation: true,
showTotalCount: true,
@@ -105,7 +107,7 @@ export class PageBlockRecordList extends PageBlock {
if (!o) return
Apply(this.options, o, CortezaID, 'moduleID')
Apply(this.options, o, String, 'prefilter', 'presort', 'selectMode', 'positionField', 'refField')
Apply(this.options, o, String, 'prefilter', 'presort', 'selectMode', 'positionField', 'refField', 'recordDisplayOption', 'magnifyOption')
Apply(this.options, o, Number, 'perPage', 'refreshRate')
if (o.fields) {
@@ -17,6 +17,7 @@ interface Options {
// referenced fields (records, users) we want to expand
expRefFields: string[];
refreshRate: number;
magnifyOption: string;
}
const defaults: Readonly<Options> = Object.freeze({
@@ -24,6 +25,7 @@ const defaults: Readonly<Options> = Object.freeze({
displayedFields: [],
expRefFields: [],
refreshRate: 0,
magnifyOption: '',
})
export class PageBlockRecordRevisions extends PageBlock {
@@ -41,6 +43,7 @@ export class PageBlockRecordRevisions extends PageBlock {
Apply(this.options, o, Boolean, 'preload')
Apply(this.options, o, Number, 'refreshRate')
Apply(this.options, o, String, 'magnifyOption')
// set new values to displayed fields
if (Array.isArray(o?.displayedFields)) {
@@ -8,6 +8,7 @@ interface Options {
scenarioID: string;
elementID: string;
refreshRate: number;
magnifyOption: string;
}
const defaults: Readonly<Options> = Object.freeze({
@@ -15,6 +16,7 @@ const defaults: Readonly<Options> = Object.freeze({
scenarioID: NoID,
elementID: NoID,
refreshRate: 0,
magnifyOption: ''
})
export class PageBlockReport extends PageBlock {
@@ -32,6 +34,7 @@ export class PageBlockReport extends PageBlock {
Apply(this.options, o, CortezaID, 'reportID', 'scenarioID', 'elementID')
Apply(this.options, o, Number, 'refreshRate')
Apply(this.options, o, String, 'magnifyOption')
}
}
@@ -112,6 +112,11 @@ general:
descriptionLabel: Description
descriptionPlaceholder: Block description
headerStyle: Block header style (color)
magnifyLabel: Block Magnification
magnifyOptions:
disabled: Disabled
modal: Modal
fullscreen: Fullscreen
wrap: Display block as a card
refresh:
label: Block auto-refresh interval
@@ -130,6 +135,7 @@ general:
remove: Remove
save: Save
search: Search
magnify: Magnify Block
module: Module
style:
danger: Danger variant