Add support for page icon and the option to expand sub-pages in the sidebar
This commit is contained in:
committed by
Jože Fortun
parent
c9740a6527
commit
72d44713f2
@@ -24,9 +24,7 @@
|
||||
label-cols="2"
|
||||
class="mb-0"
|
||||
>
|
||||
<b-input-group>
|
||||
<b-form-input v-model="pageAttachmentWhitelist" />
|
||||
</b-input-group>
|
||||
<b-form-input v-model="pageAttachmentWhitelist" />
|
||||
</b-form-group>
|
||||
|
||||
<hr>
|
||||
@@ -36,13 +34,11 @@
|
||||
:label="$t('attachments.max-size')"
|
||||
label-cols="2"
|
||||
>
|
||||
<b-input-group>
|
||||
<b-form-input
|
||||
v-model="basic['compose.record.attachments.max-size']"
|
||||
type="number"
|
||||
number
|
||||
/>
|
||||
</b-input-group>
|
||||
<b-form-input
|
||||
v-model="basic['compose.record.attachments.max-size']"
|
||||
type="number"
|
||||
number
|
||||
/>
|
||||
</b-form-group>
|
||||
<b-form-group
|
||||
:label="$t('attachments.type.whitelist')"
|
||||
@@ -50,9 +46,29 @@
|
||||
label-cols="2"
|
||||
class="mb-0"
|
||||
>
|
||||
<b-input-group class="m-0">
|
||||
<b-form-input v-model="recordAttachmentWhitelist" />
|
||||
</b-input-group>
|
||||
<b-form-input v-model="recordAttachmentWhitelist" />
|
||||
</b-form-group>
|
||||
|
||||
<hr>
|
||||
|
||||
<h5>{{ $t('attachments.icon') }}</h5>
|
||||
<b-form-group
|
||||
:label="$t('attachments.max-size')"
|
||||
label-cols="2"
|
||||
>
|
||||
<b-form-input
|
||||
v-model="basic['compose.icon.attachments.max-size']"
|
||||
type="number"
|
||||
number
|
||||
/>
|
||||
</b-form-group>
|
||||
<b-form-group
|
||||
:label="$t('attachments.type.whitelist')"
|
||||
:description="$t('attachments.type.description')"
|
||||
label-cols="2"
|
||||
class="mb-0"
|
||||
>
|
||||
<b-form-input v-model="iconAttachmentWhitelist" />
|
||||
</b-form-group>
|
||||
</b-form>
|
||||
|
||||
@@ -131,6 +147,16 @@ export default {
|
||||
this.basic['compose.record.attachments.mimetypes'] = this.convertToExternal(value)
|
||||
},
|
||||
},
|
||||
|
||||
iconAttachmentWhitelist: {
|
||||
get () {
|
||||
return (this.basic['compose.icon.attachments.mimetypes'] || []).join(',')
|
||||
},
|
||||
|
||||
set (value) {
|
||||
this.basic['compose.icon.attachments.mimetypes'] = this.convertToExternal(value)
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
@@ -103,36 +103,6 @@ import { Portal } from 'portal-vue'
|
||||
import { VueSelect } from 'vue-select'
|
||||
const { CSidebarNavItems, CInputSearch } = components
|
||||
|
||||
const publicPageWrap = ({ pageID, selfID, title, visible }) => ({
|
||||
page: {
|
||||
// name omitted as default is provided
|
||||
pageID,
|
||||
selfID,
|
||||
title,
|
||||
visible,
|
||||
},
|
||||
children: [],
|
||||
params: {
|
||||
pageID,
|
||||
},
|
||||
})
|
||||
|
||||
const adminPageWrap = (page) => {
|
||||
return {
|
||||
page: {
|
||||
name: 'admin.pages.builder',
|
||||
pageID: `page-${page.pageID}`,
|
||||
selfID: page.selfID !== NoID ? `page-${page.selfID}` : 'pages',
|
||||
rootSelfID: 'pages',
|
||||
title: page.title || page.handle,
|
||||
visible: true,
|
||||
},
|
||||
children: [],
|
||||
params: {
|
||||
pageID: page.pageID,
|
||||
},
|
||||
}
|
||||
}
|
||||
const moduleWrap = (module) => {
|
||||
return {
|
||||
page: {
|
||||
@@ -241,8 +211,7 @@ export default {
|
||||
filteredPages () {
|
||||
if (this.namespace) {
|
||||
// If on admin page, show admin pages. Otherwise show public pages
|
||||
const pages = [...(this.isAdminPage ? this.adminRoutes() : this.publicRoutes.map(publicPageWrap))]
|
||||
|
||||
const pages = [...(this.isAdminPage ? this.adminRoutes() : this.publicPageWrap(this.publicRoutes))]
|
||||
if (!this.query) {
|
||||
return pages
|
||||
}
|
||||
@@ -259,7 +228,7 @@ export default {
|
||||
|
||||
navItems () {
|
||||
const current = this.filteredPages
|
||||
const ax = this.pageIndex(this.isAdminPage ? this.adminRoutes() : this.pages.map(publicPageWrap))
|
||||
const ax = this.pageIndex(this.isAdminPage ? this.adminRoutes() : this.publicPageWrap(this.pages))
|
||||
|
||||
// Correct potentially missing parent references
|
||||
for (const cp of current) {
|
||||
@@ -374,7 +343,7 @@ export default {
|
||||
},
|
||||
children: [],
|
||||
},
|
||||
...this.pages.map(adminPageWrap),
|
||||
...this.adminPageWrap(this.pages),
|
||||
{
|
||||
page: {
|
||||
pageID: 'charts',
|
||||
@@ -388,6 +357,68 @@ export default {
|
||||
...this.charts.map(chartWrap),
|
||||
]
|
||||
},
|
||||
|
||||
publicPageWrap (pages) {
|
||||
return pages.map(({ pageID, selfID, title, visible, config }) => {
|
||||
const { navItem = {} } = config
|
||||
const { icon = {}, expanded = '' } = navItem
|
||||
const { type = '', src = '' } = icon
|
||||
|
||||
const iconType = 'attachment'
|
||||
let iconSrc = src
|
||||
|
||||
if (type === iconType) {
|
||||
iconSrc = `${this.$ComposeAPI.baseURL}${src}`
|
||||
}
|
||||
|
||||
return {
|
||||
page: {
|
||||
// name omitted as default is provided
|
||||
pageID,
|
||||
selfID,
|
||||
title,
|
||||
visible,
|
||||
expanded,
|
||||
icon: iconSrc,
|
||||
},
|
||||
children: [],
|
||||
params: {
|
||||
pageID,
|
||||
},
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
adminPageWrap (pages) {
|
||||
return pages.map(({ pageID, selfID, title, handle, config }) => {
|
||||
const { navItem = {} } = config
|
||||
const { icon = {} } = navItem
|
||||
const { type = '', src = '' } = icon
|
||||
|
||||
const iconType = 'attachment'
|
||||
let iconSrc = src
|
||||
|
||||
if (type === iconType) {
|
||||
iconSrc = `${this.$ComposeAPI.baseURL}${src}`
|
||||
}
|
||||
|
||||
return {
|
||||
page: {
|
||||
name: 'admin.pages.builder',
|
||||
pageID: `page-${pageID}`,
|
||||
selfID: selfID !== NoID ? `page-${selfID}` : 'pages',
|
||||
rootSelfID: 'pages',
|
||||
title: title || handle,
|
||||
visible: true,
|
||||
icon: iconSrc,
|
||||
},
|
||||
children: [],
|
||||
params: {
|
||||
pageID: pageID,
|
||||
},
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -81,6 +81,10 @@ export default {
|
||||
required: false,
|
||||
default: () => ({}),
|
||||
},
|
||||
paramName: {
|
||||
type: String,
|
||||
default: 'upload',
|
||||
},
|
||||
},
|
||||
|
||||
data () {
|
||||
@@ -100,7 +104,7 @@ export default {
|
||||
const vm = this
|
||||
|
||||
return {
|
||||
paramName: 'upload',
|
||||
paramName: this.paramName,
|
||||
maxFilesize: this.maxFilesize, // mb
|
||||
url: () => this.baseUrl + this.endpoint,
|
||||
thumbnailMethod: 'contain',
|
||||
|
||||
@@ -111,6 +111,33 @@
|
||||
/>
|
||||
</b-form-group>
|
||||
|
||||
<b-form-group
|
||||
:label="$t('icon.page')"
|
||||
label-class="text-primary"
|
||||
>
|
||||
<img
|
||||
v-if="icon.src"
|
||||
:src="pageIcon"
|
||||
width="50"
|
||||
heigth="50"
|
||||
class="d-block"
|
||||
>
|
||||
<span
|
||||
v-else
|
||||
class="d-block"
|
||||
>
|
||||
{{ $t('icon.not-set') }}
|
||||
</span>
|
||||
<b-button
|
||||
variant="light"
|
||||
size="md"
|
||||
class="mt-2 text-dark"
|
||||
@click="showIconModal = true"
|
||||
>
|
||||
{{ $t('icon.set') }}
|
||||
</b-button>
|
||||
</b-form-group>
|
||||
|
||||
<b-form-group
|
||||
v-if="!isRecordPage"
|
||||
>
|
||||
@@ -122,6 +149,118 @@
|
||||
{{ $t('edit.visible') }}
|
||||
</b-form-checkbox>
|
||||
</b-form-group>
|
||||
|
||||
<b-form-group
|
||||
data-test-id="checkbox-show-sub-pages-in-sidebar"
|
||||
class="d-flex"
|
||||
>
|
||||
<b-form-checkbox
|
||||
v-model="page.config.navItem.expanded"
|
||||
switch
|
||||
>
|
||||
{{ $t('showSubPages') }}
|
||||
</b-form-checkbox>
|
||||
</b-form-group>
|
||||
|
||||
<b-modal
|
||||
v-model="showIconModal"
|
||||
:title="$t('icon.configure')"
|
||||
:ok-title="$t('label.saveAndClose')"
|
||||
ok-only
|
||||
size="lg"
|
||||
label-class="text-primary"
|
||||
@show="openIconModal"
|
||||
@close="closeIconModal"
|
||||
>
|
||||
<b-form-group
|
||||
:label="$t('icon.upload')"
|
||||
label-class="text-primary"
|
||||
class="mb-0"
|
||||
>
|
||||
<uploader
|
||||
:endpoint="endpoint"
|
||||
:accepted-files="['image/*']"
|
||||
:param-name="'icon'"
|
||||
@uploaded="uploadAttachment"
|
||||
/>
|
||||
|
||||
<b-form-group
|
||||
:label="$t('url.label')"
|
||||
label-class="text-primary"
|
||||
class="my-2"
|
||||
>
|
||||
<b-input-group>
|
||||
<b-input
|
||||
v-model="linkUrl"
|
||||
:disabled="isIconSet"
|
||||
:style="{ 'cursor': isIconSet ? 'not-allowed' : 'default' }"
|
||||
/>
|
||||
<b-input-group-append>
|
||||
<b-button
|
||||
v-b-modal.logo
|
||||
:title="$t('tooltip.preview-link')"
|
||||
:disabled="!linkUrl"
|
||||
variant="light"
|
||||
rounded
|
||||
class="d-flex align-items-center btn-light"
|
||||
>
|
||||
<font-awesome-icon :icon="['fas', 'external-link-alt']" />
|
||||
</b-button>
|
||||
</b-input-group-append>
|
||||
</b-input-group>
|
||||
</b-form-group>
|
||||
</b-form-group>
|
||||
|
||||
<template v-if="attachments.length > 0">
|
||||
<hr>
|
||||
|
||||
<b-form-group
|
||||
:label="$t('icon.list')"
|
||||
label-class="text-primary"
|
||||
>
|
||||
<div
|
||||
v-if="processing"
|
||||
class="d-flex align-items-center justify-content-center h-100"
|
||||
>
|
||||
<b-spinner />
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-else
|
||||
class="d-flex flex-wrap px-2"
|
||||
>
|
||||
<div
|
||||
v-for="a in attachments"
|
||||
:key="a.attachmentID"
|
||||
:class="[selectedIconID === a.attachmentID ? 'border-success' : '2px solid']"
|
||||
class="mt-2 mr-2 p-2 border rounded-circle"
|
||||
>
|
||||
<img
|
||||
:src="a.src"
|
||||
:alt="a.name"
|
||||
:style="{ 'cursor': !!linkUrl ? 'not-allowed' : 'pointer' }"
|
||||
class="rounded"
|
||||
style="height: 2.3em; width: 2.3em;"
|
||||
@click="toggleSelectedIcon(a.attachmentID)"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</b-form-group>
|
||||
</template>
|
||||
</b-modal>
|
||||
|
||||
<b-modal
|
||||
id="logo"
|
||||
hide-header
|
||||
hide-footer
|
||||
centered
|
||||
body-class="p-1"
|
||||
>
|
||||
<b-img
|
||||
:src="linkUrl"
|
||||
fluid-grow
|
||||
/>
|
||||
</b-modal>
|
||||
</b-form>
|
||||
</b-card>
|
||||
</b-col>
|
||||
@@ -171,6 +310,7 @@ import { mapGetters, mapActions } from 'vuex'
|
||||
import EditorToolbar from 'corteza-webapp-compose/src/components/Admin/EditorToolbar'
|
||||
import PageTranslator from 'corteza-webapp-compose/src/components/Admin/Page/PageTranslator'
|
||||
import pages from 'corteza-webapp-compose/src/mixins/pages'
|
||||
import Uploader from 'corteza-webapp-compose/src/components/Public/Page/Attachment/Uploader'
|
||||
import { compose, NoID } from '@cortezaproject/corteza-js'
|
||||
import { handle } from '@cortezaproject/corteza-vue'
|
||||
|
||||
@@ -184,6 +324,7 @@ export default {
|
||||
components: {
|
||||
EditorToolbar,
|
||||
PageTranslator,
|
||||
Uploader,
|
||||
},
|
||||
|
||||
mixins: [
|
||||
@@ -206,6 +347,13 @@ export default {
|
||||
return {
|
||||
modulesList: [],
|
||||
page: new compose.Page(),
|
||||
showIconModal: false,
|
||||
attachments: [],
|
||||
selectedIconID: '',
|
||||
isSelected: false,
|
||||
linkUrl: '',
|
||||
|
||||
processing: false,
|
||||
}
|
||||
},
|
||||
|
||||
@@ -250,6 +398,29 @@ export default {
|
||||
return this.hasChildren && this.page.canDeletePage && !this.page.deletedAt
|
||||
},
|
||||
|
||||
endpoint () {
|
||||
return this.$ComposeAPI.iconUploadEndpoint({
|
||||
namespaceID: this.namespace.namespaceID,
|
||||
})
|
||||
},
|
||||
|
||||
icon: {
|
||||
get () {
|
||||
return this.page.config.navItem.icon || {}
|
||||
},
|
||||
|
||||
set (icon) {
|
||||
this.page.config.navItem = icon
|
||||
},
|
||||
},
|
||||
|
||||
isIconSet () {
|
||||
return !!this.attachments.find(a => a.attachmentID === this.selectedIconID)
|
||||
},
|
||||
|
||||
pageIcon () {
|
||||
return this.icon.type === 'link' ? this.icon.src : this.makeAttachmentUrl(this.icon.src)
|
||||
},
|
||||
},
|
||||
|
||||
watch: {
|
||||
@@ -257,8 +428,7 @@ export default {
|
||||
immediate: true,
|
||||
handler (pageID) {
|
||||
if (pageID) {
|
||||
const { namespaceID } = this.namespace
|
||||
this.findPageByID({ namespaceID, pageID }).then((page) => {
|
||||
this.findPageByID({ namespaceID: this.namespace.namespaceID, pageID }).then((page) => {
|
||||
this.page = page.clone()
|
||||
}).catch(this.toastErrorHandler(this.$t('notification:page.loadFailed')))
|
||||
}
|
||||
@@ -275,14 +445,14 @@ export default {
|
||||
loadPages: 'page/load',
|
||||
}),
|
||||
|
||||
handleSave ({ closeOnSuccess = false } = {}) {
|
||||
async handleSave ({ closeOnSuccess = false } = {}) {
|
||||
/**
|
||||
* Pass a special tag alongside payload that
|
||||
* instructs store layer to add content-language header to the API request
|
||||
*/
|
||||
const resourceTranslationLanguage = this.currentLanguage
|
||||
const { namespaceID } = this.namespace
|
||||
this.updatePage({ namespaceID, ...this.page, resourceTranslationLanguage }).then((page) => {
|
||||
await this.setIcon().then(icon => { this.page.config.navItem = { icon, expanded: this.page.config.navItem.expanded } })
|
||||
this.updatePage({ namespaceID: this.namespace.namespaceID, ...this.page, resourceTranslationLanguage }).then((page) => {
|
||||
this.page = page.clone()
|
||||
this.toastSuccess(this.$t('notification:page.saved'))
|
||||
if (closeOnSuccess) {
|
||||
@@ -296,6 +466,95 @@ export default {
|
||||
this.$router.push({ name: 'admin.pages' })
|
||||
}).catch(this.toastErrorHandler(this.$t('notification:page.deleteFailed')))
|
||||
},
|
||||
|
||||
uploadAttachment () {
|
||||
this.fetchAttachments()
|
||||
},
|
||||
|
||||
fetchAttachments () {
|
||||
this.processing = true
|
||||
|
||||
this.$ComposeAPI.iconList({ sort: 'id DESC' })
|
||||
.then(({ set: attachments = [] }) => {
|
||||
const baseURL = this.$ComposeAPI.baseURL
|
||||
this.attachments = []
|
||||
|
||||
if (attachments) {
|
||||
attachments.forEach(a => {
|
||||
const src = !a.url.includes(baseURL) ? this.makeAttachmentUrl(a.url) : a.url
|
||||
const currSelectedIcon = a.url === this.icon.src
|
||||
|
||||
if (currSelectedIcon) {
|
||||
this.selectedIconID = a.attachmentID
|
||||
}
|
||||
|
||||
this.attachments.push({ ...a, src })
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch(this.toastErrorHandler(this.$t('notification:page.iconFetchFailed')))
|
||||
.finally(() => {
|
||||
this.processing = false
|
||||
})
|
||||
},
|
||||
|
||||
async setIcon () {
|
||||
const selectedAttachmentUrl = this.isSelected ? this.attachments.find(att => att.attachmentID === this.selectedIconID).url : ''
|
||||
|
||||
let attachmentType = 'link'
|
||||
let attachmentSource = this.linkUrl
|
||||
|
||||
if (!attachmentSource) {
|
||||
attachmentType = 'attachment'
|
||||
attachmentSource = selectedAttachmentUrl
|
||||
}
|
||||
|
||||
const navItem = {
|
||||
icon: {
|
||||
type: '',
|
||||
src: '',
|
||||
},
|
||||
}
|
||||
|
||||
if (attachmentType && attachmentSource) {
|
||||
await this.$ComposeAPI.pageUpdateIcon({
|
||||
namespaceID: this.namespace.namespaceID,
|
||||
pageID: this.pageID,
|
||||
type: attachmentType,
|
||||
source: attachmentSource,
|
||||
}).then(({ type, src }) => {
|
||||
navItem.icon.type = type
|
||||
navItem.icon.src = src
|
||||
})
|
||||
}
|
||||
|
||||
return !this.icon.src ? navItem.icon : this.icon
|
||||
},
|
||||
|
||||
toggleSelectedIcon (attachmentID = '') {
|
||||
if (!this.linkUrl) {
|
||||
this.isSelected = this.selectedIconID !== attachmentID
|
||||
this.selectedIconID = this.isSelected ? attachmentID : ''
|
||||
}
|
||||
},
|
||||
|
||||
closeIconModal () {
|
||||
this.isSelected = this.icon.src
|
||||
this.selectedIconID = this.isSelected ? this.isIconSet : ''
|
||||
if (this.icon.type === 'link') {
|
||||
this.linkUrl = this.icon.src
|
||||
}
|
||||
},
|
||||
|
||||
makeAttachmentUrl (src) {
|
||||
return `${this.$ComposeAPI.baseURL}${src}`
|
||||
},
|
||||
|
||||
openIconModal () {
|
||||
this.linkUrl = this.icon.type === 'link' ? this.icon.src : ''
|
||||
|
||||
this.fetchAttachments()
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -919,6 +919,94 @@ export default class Compose {
|
||||
return `/namespace/${namespaceID}/page/${pageID}/translation`
|
||||
}
|
||||
|
||||
// Update icon for page
|
||||
async pageUpdateIcon (a: KV, extra: AxiosRequestConfig = {}): Promise<KV> {
|
||||
const {
|
||||
namespaceID,
|
||||
pageID,
|
||||
type,
|
||||
source,
|
||||
style,
|
||||
} = (a as KV) || {}
|
||||
if (!namespaceID) {
|
||||
throw Error('field namespaceID is empty')
|
||||
}
|
||||
if (!pageID) {
|
||||
throw Error('field pageID is empty')
|
||||
}
|
||||
if (!type) {
|
||||
throw Error('field type is empty')
|
||||
}
|
||||
const cfg: AxiosRequestConfig = {
|
||||
...extra,
|
||||
method: 'patch',
|
||||
url: this.pageUpdateIconEndpoint({
|
||||
namespaceID, pageID,
|
||||
}),
|
||||
}
|
||||
cfg.data = {
|
||||
type,
|
||||
source,
|
||||
style,
|
||||
}
|
||||
return this.api().request(cfg).then(result => stdResolve(result))
|
||||
}
|
||||
|
||||
pageUpdateIconEndpoint (a: KV): string {
|
||||
const {
|
||||
namespaceID,
|
||||
pageID,
|
||||
} = a || {}
|
||||
return `/namespace/${namespaceID}/page/${pageID}/icon`
|
||||
}
|
||||
|
||||
// List icons
|
||||
async iconList (a: KV, extra: AxiosRequestConfig = {}): Promise<KV> {
|
||||
const {
|
||||
limit,
|
||||
incTotal,
|
||||
pageCursor,
|
||||
sort,
|
||||
} = (a as KV) || {}
|
||||
const cfg: AxiosRequestConfig = {
|
||||
...extra,
|
||||
method: 'get',
|
||||
url: this.iconListEndpoint(),
|
||||
}
|
||||
cfg.params = {
|
||||
limit,
|
||||
incTotal,
|
||||
pageCursor,
|
||||
sort,
|
||||
}
|
||||
|
||||
return this.api().request(cfg).then(result => stdResolve(result))
|
||||
}
|
||||
|
||||
iconListEndpoint (): string {
|
||||
return '/icon/'
|
||||
}
|
||||
|
||||
// Upload icon
|
||||
async iconUpload (a: KV, extra: AxiosRequestConfig = {}): Promise<KV> {
|
||||
const {
|
||||
icon,
|
||||
} = (a as KV) || {}
|
||||
const cfg: AxiosRequestConfig = {
|
||||
...extra,
|
||||
method: 'post',
|
||||
url: this.iconUploadEndpoint(),
|
||||
}
|
||||
cfg.data = {
|
||||
icon,
|
||||
}
|
||||
return this.api().request(cfg).then(result => stdResolve(result))
|
||||
}
|
||||
|
||||
iconUploadEndpoint (): string {
|
||||
return '/icon/'
|
||||
}
|
||||
|
||||
// List modules
|
||||
async moduleList (a: KV, extra: AxiosRequestConfig = {}): Promise<KV> {
|
||||
const {
|
||||
|
||||
@@ -22,6 +22,14 @@ interface PageConfig {
|
||||
clone: Button;
|
||||
back: Button;
|
||||
};
|
||||
attachments: [];
|
||||
navItem: {
|
||||
icon: {
|
||||
type: string;
|
||||
src: string;
|
||||
};
|
||||
expanded: false;
|
||||
};
|
||||
}
|
||||
|
||||
export class Page {
|
||||
@@ -52,6 +60,14 @@ export class Page {
|
||||
clone: { enabled: true },
|
||||
back: { enabled: true },
|
||||
},
|
||||
attachments: [],
|
||||
navItem: {
|
||||
icon: {
|
||||
type: '',
|
||||
src: '',
|
||||
},
|
||||
expanded: false,
|
||||
},
|
||||
}
|
||||
|
||||
public createdAt?: Date = undefined;
|
||||
|
||||
@@ -7,7 +7,6 @@ export default {
|
||||
props: {
|
||||
inline: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
@@ -25,12 +25,11 @@ export default {
|
||||
|
||||
props: {
|
||||
alt: {
|
||||
required: false,
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
|
||||
title: {
|
||||
required: false,
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
@@ -81,6 +80,7 @@ export default {
|
||||
<style scoped lang="scss">
|
||||
div {
|
||||
object-fit: contain;
|
||||
|
||||
img {
|
||||
&.loaded {
|
||||
width: auto;
|
||||
@@ -88,6 +88,7 @@ div {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
&.inline {
|
||||
img {
|
||||
cursor: zoom-in;
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
export default {
|
||||
props: {
|
||||
labels: {
|
||||
required: false,
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
@@ -14,7 +13,6 @@ export default {
|
||||
},
|
||||
|
||||
mime: {
|
||||
required: false,
|
||||
type: String,
|
||||
default: undefined,
|
||||
},
|
||||
@@ -25,26 +23,22 @@ export default {
|
||||
},
|
||||
|
||||
name: {
|
||||
required: false,
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
|
||||
previewStyle: {
|
||||
required: false,
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
|
||||
previewClass: {
|
||||
required: false,
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
|
||||
inline: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -13,11 +13,22 @@
|
||||
class="d-inline-block w-75 text-nowrap text-truncate"
|
||||
@click="closeSidebar()"
|
||||
>
|
||||
<font-awesome-icon
|
||||
<template
|
||||
v-if="page.icon"
|
||||
class="icon"
|
||||
:icon="page.icon"
|
||||
/>
|
||||
>
|
||||
<font-awesome-icon
|
||||
v-if="Array.isArray(page.icon)"
|
||||
class="icon"
|
||||
:icon="page.icon"
|
||||
/>
|
||||
<template v-else>
|
||||
<img
|
||||
:src="page.icon"
|
||||
class="rounded-circle mr-1"
|
||||
style="height: 1.5em; width: 1.5em;"
|
||||
/>
|
||||
</template>
|
||||
</template>
|
||||
<span
|
||||
class="title"
|
||||
>
|
||||
@@ -102,9 +113,7 @@ export default {
|
||||
items.forEach(({ page }) => {
|
||||
const px = this.pageIndex(page)
|
||||
// Apply startExpanded only if page isn't currently expanded
|
||||
if (!this.collapses[px]) {
|
||||
this.$set(this.collapses, px, this.startExpanded)
|
||||
}
|
||||
this.$set(this.collapses, px, this.startExpanded || page.expanded)
|
||||
})
|
||||
},
|
||||
},
|
||||
|
||||
@@ -5,6 +5,7 @@ editor:
|
||||
max-size: Max size (MB)
|
||||
page: Page attachments
|
||||
record: Record attachments
|
||||
icon: Icon attachments
|
||||
type:
|
||||
description: 'MIME types, separated with ",". Example: "text/plain,text/csv"'
|
||||
whitelist: File type whitelist
|
||||
|
||||
@@ -73,6 +73,7 @@ page:
|
||||
createFailed: Could not create a page
|
||||
cloneFailed: Could not clone this page
|
||||
deleteFailed: Could not delete this page
|
||||
iconFetchFailed: Could not fetch list of icons
|
||||
loadFailed: Could not load the page tree
|
||||
noPages: No pages found
|
||||
saveFailed: Could not save this page
|
||||
|
||||
@@ -23,6 +23,15 @@ edit:
|
||||
edit: Edit page
|
||||
pageDescription: Page description
|
||||
visible: Page visibility
|
||||
icon:
|
||||
configure: Configure page icon
|
||||
not-set: No icon set
|
||||
page: Page icon
|
||||
set: Set icon
|
||||
upload: Upload icon
|
||||
list: List of uploaded icons
|
||||
url:
|
||||
label: Or add URL to icon
|
||||
import: 'Import page(s):'
|
||||
instructions: Drag and drop pages to adjust the order and hierarchy
|
||||
invalid: Invalid configuration
|
||||
@@ -45,6 +54,7 @@ noPages: No pages
|
||||
notVisible: Hidden
|
||||
pageMoveFailed: Could not move this page
|
||||
reordered: Page reordered
|
||||
showSubPages: Expand sub-pages in the sidebar
|
||||
title: List of Pages
|
||||
tooltip:
|
||||
unsavedChanges: Unsaved Changes
|
||||
@@ -56,6 +66,7 @@ tooltip:
|
||||
block: Copy block
|
||||
clone:
|
||||
block: Clone block
|
||||
preview-link: Preview link
|
||||
saveAsCopy: Cannot duplicate record page
|
||||
view: View
|
||||
visible: Visible
|
||||
|
||||
Reference in New Issue
Block a user