Feat router page embedded view toggle (#1010)
* feat(canvas, toolbar/view-setting): add router view setting view mode switcher, support embedded and standalone mode in canvas * fix(canvas/render): fix switch locale failed * feat(canvas): add window.onpopstate listener * fix(toolbars/view-setting): fix init view mode value no fallback cause next view mode label error * fix: using enum instead of multiple time literal string declaration, add fallback for cache value getter in toolbar, fix typo mistake * fix: simplify return value using enum, remove unnecessary style code * fix(toolbars/view-setting): fix package.json wrong repository directory
This commit is contained in:
parent
4c1c4c49f4
commit
ab4e7dc2ed
|
|
@ -14,6 +14,7 @@ import {
|
|||
Breadcrumb,
|
||||
Fullscreen,
|
||||
Lang,
|
||||
ViewSetting,
|
||||
Logo,
|
||||
Lock,
|
||||
Media,
|
||||
|
|
@ -70,7 +71,8 @@ export default {
|
|||
collapse: [
|
||||
['engine.toolbars.collaboration'],
|
||||
['engine.toolbars.refresh', 'engine.toolbars.fullscreen'],
|
||||
['engine.toolbars.lang']
|
||||
['engine.toolbars.lang'],
|
||||
['engine.toolbars.viewSetting']
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -96,7 +98,8 @@ export default {
|
|||
GenerateCode,
|
||||
Save,
|
||||
Fullscreen,
|
||||
Lang
|
||||
Lang,
|
||||
ViewSetting
|
||||
],
|
||||
plugins: [Materials, Tree, Page, Block, Datasource, Bridge, I18n, Script, State, Schema, Help, Robot],
|
||||
dsls: [{ id: 'engine.dsls.dslvue' }],
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
"@opentiny/tiny-engine-toolbar-breadcrumb": ["packages/toolbars/breadcrumb/index"],
|
||||
"@opentiny/tiny-engine-toolbar-fullscreen": ["packages/toolbars/fullscreen/index"],
|
||||
"@opentiny/tiny-engine-toolbar-lang": ["packages/toolbars/lang/index"],
|
||||
"@opentiny/tiny-engine-toolbar-view-setting": ["packages/toolbars/view-setting/index"],
|
||||
"@opentiny/tiny-engine-toolbar-layout": ["packages/toolbars/layout/index"],
|
||||
"@opentiny/tiny-engine-toolbar-lock": ["packages/toolbars/lock/index"],
|
||||
"@opentiny/tiny-engine-toolbar-logo": ["packages/toolbars/logo/index"],
|
||||
|
|
@ -51,6 +52,7 @@
|
|||
"@opentiny/tiny-engine-toolbar-breadcrumb/*": ["packages/toolbars/breadcrumb/*"],
|
||||
"@opentiny/tiny-engine-toolbar-fullscreen/*": ["packages/toolbars/fullscreen/*"],
|
||||
"@opentiny/tiny-engine-toolbar-lang/*": ["packages/toolbars/lang/*"],
|
||||
"@opentiny/tiny-engine-toolbar-view-setting/*": ["packages/toolbars/view-setting/*"],
|
||||
"@opentiny/tiny-engine-toolbar-layout/*": ["packages/toolbars/layout/*"],
|
||||
"@opentiny/tiny-engine-toolbar-lock/*": ["packages/toolbars/lock/*"],
|
||||
"@opentiny/tiny-engine-toolbar-logo/*": ["packages/toolbars/logo/*"],
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ const getDevAlias = (useSourceAlias) => {
|
|||
'@opentiny/tiny-engine-toolbar-breadcrumb': path.resolve(basePath, 'packages/toolbars/breadcrumb/index.js'),
|
||||
'@opentiny/tiny-engine-toolbar-fullscreen': path.resolve(basePath, 'packages/toolbars/fullscreen/index.js'),
|
||||
'@opentiny/tiny-engine-toolbar-lang': path.resolve(basePath, 'packages/toolbars/lang/index.js'),
|
||||
'@opentiny/tiny-engine-toolbar-view-setting': path.resolve(basePath, 'packages/toolbars/view-setting/index.js'),
|
||||
'@opentiny/tiny-engine-toolbar-layout': path.resolve(basePath, 'packages/toolbars/layout/index.js'),
|
||||
'@opentiny/tiny-engine-toolbar-lock': path.resolve(basePath, 'packages/toolbars/lock/index.js'),
|
||||
'@opentiny/tiny-engine-toolbar-logo': path.resolve(basePath, 'packages/toolbars/logo/index.js'),
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@
|
|||
:canvas-src-doc="canvasSrcDoc"
|
||||
@remove="removeNode"
|
||||
@selected="nodeSelected"
|
||||
></component>
|
||||
>
|
||||
</component>
|
||||
</template>
|
||||
<template #footer>
|
||||
<component :is="CanvasBreadcrumb" :data="footData"></component>
|
||||
|
|
@ -209,6 +210,17 @@ export default {
|
|||
}
|
||||
})()
|
||||
|
||||
// TODO: 待挪到 getBaseInfo
|
||||
const postUrlChanged = () => {
|
||||
usePage().postLocationHistoryChanged(Object.fromEntries(new URLSearchParams(window.location.search)))
|
||||
}
|
||||
onMounted(() => {
|
||||
window.addEventListener('popstate', postUrlChanged)
|
||||
})
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('popstate', postUrlChanged)
|
||||
})
|
||||
|
||||
return {
|
||||
removeNode,
|
||||
canvasSrc,
|
||||
|
|
|
|||
|
|
@ -11,7 +11,15 @@
|
|||
*/
|
||||
|
||||
import { provide, watch, defineComponent, PropType, ref, inject, onUnmounted, h, Ref } from 'vue'
|
||||
import { getDesignMode, setDesignMode, setController, useCustomRenderer, getController } from './canvas-function'
|
||||
import {
|
||||
getDesignMode,
|
||||
setDesignMode,
|
||||
setController,
|
||||
useCustomRenderer,
|
||||
getController,
|
||||
useRouterViewSetting,
|
||||
useLocale
|
||||
} from './canvas-function'
|
||||
import { removeBlockCompsCache, setConfigure } from './material-function'
|
||||
import { useUtils, useBridge, useDataSourceMap, useGlobalState } from './application-function'
|
||||
import { IPageSchema, useContext, usePageContext, useSchema } from './page-block-function'
|
||||
|
|
@ -79,6 +87,9 @@ const throttleUpdateSchema = useThrottleFn(
|
|||
true
|
||||
)
|
||||
|
||||
const pageRenderer = getRenderer()
|
||||
const { routerViewSetting } = useRouterViewSetting()
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
entry: {
|
||||
|
|
@ -120,23 +131,39 @@ export default defineComponent({
|
|||
pageContext.pageId = props.pageId || pageIdFromPath
|
||||
pageContext.active = props.active || !pageIdFromPath
|
||||
pageContext.setCssScopeId(props.cssScopeId || (props.entry ? null : `data-te-page-${pageContext.pageId}`))
|
||||
|
||||
if (props.entry) {
|
||||
provide('page-ancestors', pageAncestors)
|
||||
getPageAncestors(pageContext.pageId).then((value) => {
|
||||
pageAncestors.value = value
|
||||
})
|
||||
const updatePageAncestor = () => {
|
||||
if (routerViewSetting.viewMode === 'standalone') {
|
||||
pageAncestors.value = []
|
||||
return
|
||||
}
|
||||
getPageAncestors(pageContext.pageId).then((value) => {
|
||||
pageAncestors.value = value
|
||||
})
|
||||
}
|
||||
updatePageAncestor()
|
||||
|
||||
const cancel = getController().addHistoryDataChangedCallback(() => {
|
||||
const pageIdFromPath = getController().getBaseInfo().pageId
|
||||
pageContext.pageId = props.pageId || pageIdFromPath
|
||||
pageContext.active = props.active || !pageIdFromPath
|
||||
getPageAncestors(pageContext.pageId).then((value) => {
|
||||
pageAncestors.value = value
|
||||
})
|
||||
updatePageAncestor()
|
||||
})
|
||||
onUnmounted(() => {
|
||||
cancel()
|
||||
})
|
||||
|
||||
watch(
|
||||
() => routerViewSetting.viewMode,
|
||||
() => {
|
||||
updatePageAncestor()
|
||||
}
|
||||
)
|
||||
|
||||
useLocale()
|
||||
|
||||
window.host.subscribe({
|
||||
topic: 'schemaChange',
|
||||
subscriber: 'canvasRenderer',
|
||||
|
|
@ -245,11 +272,16 @@ export default defineComponent({
|
|||
)
|
||||
}
|
||||
|
||||
const renderer = getRenderer()
|
||||
return () =>
|
||||
pageAncestors.value === null
|
||||
? h(CanvasEmpty, { placeholderText: '页面分析加载中' })
|
||||
: renderer(schema, refreshKey, props.entry, pageContext.active, !!pageContext.pageId)
|
||||
: pageRenderer(
|
||||
schema,
|
||||
refreshKey,
|
||||
props.entry,
|
||||
pageContext.active,
|
||||
!!pageContext.pageId && pageAncestors.value.length
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -3,3 +3,4 @@ export * from './design-mode'
|
|||
export * from './global-notify'
|
||||
export * from './custom-renderer'
|
||||
export * from './locale'
|
||||
export * from './router-view-setting'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
import { reactive, watch } from 'vue'
|
||||
import { useBroadcastChannel } from '@vueuse/core'
|
||||
import { constants } from '@opentiny/tiny-engine-utils'
|
||||
|
||||
const { BROADCAST_CHANNEL, CANVAS_ROUTER_VIEW_SETTING_VIEW_MODE_KEY } = constants
|
||||
|
||||
export enum ViewMode {
|
||||
EMBEDDED = 'embedded',
|
||||
STANDALONE = 'standalone'
|
||||
}
|
||||
export interface IRouterViewSetting {
|
||||
viewMode: ViewMode
|
||||
}
|
||||
|
||||
function getCacheValue() {
|
||||
const value = localStorage.getItem(CANVAS_ROUTER_VIEW_SETTING_VIEW_MODE_KEY)
|
||||
if (!(Object.values(ViewMode) as string[]).includes(value)) {
|
||||
return ViewMode.EMBEDDED
|
||||
}
|
||||
return value as ViewMode
|
||||
}
|
||||
|
||||
export function useRouterViewSetting() {
|
||||
const routerViewSetting = reactive<IRouterViewSetting>({
|
||||
viewMode: getCacheValue()
|
||||
})
|
||||
|
||||
const { data } = useBroadcastChannel<IRouterViewSetting, IRouterViewSetting>({
|
||||
name: BROADCAST_CHANNEL.CanvasRouterViewSetting
|
||||
})
|
||||
|
||||
watch(data, () => {
|
||||
routerViewSetting.viewMode = data.value.viewMode
|
||||
})
|
||||
|
||||
return {
|
||||
routerViewSetting
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ export { init } from './src/init'
|
|||
export { default as Breadcrumb, BreadcrumbService } from '@opentiny/tiny-engine-toolbar-breadcrumb'
|
||||
export { default as Fullscreen } from '@opentiny/tiny-engine-toolbar-fullscreen'
|
||||
export { default as Lang } from '@opentiny/tiny-engine-toolbar-lang'
|
||||
export { default as ViewSetting } from '@opentiny/tiny-engine-toolbar-view-setting'
|
||||
export { default as Logo } from '@opentiny/tiny-engine-toolbar-logo'
|
||||
export { default as Lock } from '@opentiny/tiny-engine-toolbar-lock'
|
||||
export { default as Media } from '@opentiny/tiny-engine-toolbar-media'
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@
|
|||
"@opentiny/tiny-engine-toolbar-fullscreen": "workspace:*",
|
||||
"@opentiny/tiny-engine-toolbar-generate-code": "workspace:*",
|
||||
"@opentiny/tiny-engine-toolbar-lang": "workspace:*",
|
||||
"@opentiny/tiny-engine-toolbar-view-setting": "workspace:*",
|
||||
"@opentiny/tiny-engine-toolbar-layout": "workspace:*",
|
||||
"@opentiny/tiny-engine-toolbar-lock": "workspace:*",
|
||||
"@opentiny/tiny-engine-toolbar-logo": "workspace:*",
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import {
|
|||
Breadcrumb,
|
||||
Fullscreen,
|
||||
Lang,
|
||||
ViewSetting,
|
||||
Logo,
|
||||
Lock,
|
||||
Media,
|
||||
|
|
@ -70,7 +71,8 @@ export default {
|
|||
collapse: [
|
||||
['engine.toolbars.collaboration'],
|
||||
['engine.toolbars.refresh', 'engine.toolbars.fullscreen'],
|
||||
['engine.toolbars.lang']
|
||||
['engine.toolbars.lang'],
|
||||
['engine.toolbars.viewSetting']
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -96,7 +98,8 @@ export default {
|
|||
GenerateCode,
|
||||
Save,
|
||||
Fullscreen,
|
||||
Lang
|
||||
Lang,
|
||||
ViewSetting
|
||||
],
|
||||
plugins: [Materials, Tree, Page, Block, Datasource, Bridge, I18n, Script, State, Schema, Help, Robot],
|
||||
dsls: [{ id: 'engine.dsls.dslvue' }],
|
||||
|
|
|
|||
|
|
@ -23,7 +23,8 @@ export default {
|
|||
collapse: [
|
||||
['engine.toolbars.collaboration'],
|
||||
['engine.toolbars.refresh', 'engine.toolbars.fullscreen'],
|
||||
['engine.toolbars.lang']
|
||||
['engine.toolbars.lang'],
|
||||
['engine.toolbars.viewSetting']
|
||||
]
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
/**
|
||||
* Copyright (c) 2023 - present TinyEngine Authors.
|
||||
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
*/
|
||||
|
||||
import entry from './src/Main.vue'
|
||||
import metaData from './meta'
|
||||
|
||||
export default {
|
||||
...metaData,
|
||||
entry
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
export default {
|
||||
id: 'engine.toolbars.viewSetting',
|
||||
type: 'toolbars',
|
||||
title: 'viewSetting',
|
||||
options: {
|
||||
icon: {
|
||||
default: 'routerview'
|
||||
},
|
||||
renderType: 'icon',
|
||||
collapsed: true
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
{
|
||||
"name": "@opentiny/tiny-engine-toolbar-view-setting",
|
||||
"version": "2.1.0",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "vite build"
|
||||
},
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.js",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/opentiny/tiny-engine",
|
||||
"directory": "packages/toolbars/view-setting"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/opentiny/tiny-engine/issues"
|
||||
},
|
||||
"author": "OpenTiny Team",
|
||||
"license": "MIT",
|
||||
"homepage": "https://opentiny.design/tiny-engine",
|
||||
"dependencies": {
|
||||
"@opentiny/tiny-engine-common": "workspace:*",
|
||||
"@opentiny/tiny-engine-utils": "workspace:*",
|
||||
"@vueuse/core": "^9.6.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@opentiny/tiny-engine-vite-plugin-meta-comments": "workspace:*",
|
||||
"@vitejs/plugin-vue": "^5.1.2",
|
||||
"@vitejs/plugin-vue-jsx": "^4.0.1",
|
||||
"vite": "^5.4.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@opentiny/vue": "^3.14.0",
|
||||
"vue": "^3.4.15"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
<template>
|
||||
<toolbar-base
|
||||
:content="`切换到${nextViewMode.label}`"
|
||||
:icon="options.icon.default || options.icon"
|
||||
:options="options"
|
||||
@click-api="changeViewMode"
|
||||
>
|
||||
</toolbar-base>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import { useBroadcastChannel } from '@vueuse/core'
|
||||
import { ToolbarBase } from '@opentiny/tiny-engine-common'
|
||||
|
||||
import { constants } from '@opentiny/tiny-engine-utils'
|
||||
|
||||
const { BROADCAST_CHANNEL, CANVAS_ROUTER_VIEW_SETTING_VIEW_MODE_KEY } = constants
|
||||
|
||||
function getCacheValue() {
|
||||
const value = localStorage.getItem(CANVAS_ROUTER_VIEW_SETTING_VIEW_MODE_KEY)
|
||||
if (!['embedded', 'standalone'].includes(value)) {
|
||||
return 'embedded'
|
||||
}
|
||||
return value
|
||||
}
|
||||
function setCacheValue(value) {
|
||||
localStorage.setItem(CANVAS_ROUTER_VIEW_SETTING_VIEW_MODE_KEY, value)
|
||||
}
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ToolbarBase
|
||||
},
|
||||
props: {
|
||||
options: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
setup() {
|
||||
const viewMode = ref(getCacheValue())
|
||||
const { post, data } = useBroadcastChannel({ name: BROADCAST_CHANNEL.CanvasRouterViewSetting })
|
||||
watch(data, () => {
|
||||
viewMode.value = data.value
|
||||
})
|
||||
|
||||
const viewModeOptions = [
|
||||
{
|
||||
value: 'embedded',
|
||||
label: '嵌套视图'
|
||||
},
|
||||
{
|
||||
value: 'standalone',
|
||||
label: '单页视图'
|
||||
}
|
||||
]
|
||||
|
||||
const nextViewMode = computed(
|
||||
() => viewModeOptions.find(({ value }) => value !== viewMode.value) || viewModeOptions[1]
|
||||
)
|
||||
|
||||
const changeViewMode = () => {
|
||||
viewMode.value = viewMode.value === viewModeOptions[0].value ? viewModeOptions[1].value : viewModeOptions[0].value
|
||||
setCacheValue(viewMode.value)
|
||||
post({ viewMode: viewMode.value })
|
||||
}
|
||||
return {
|
||||
viewModeOptions,
|
||||
viewMode,
|
||||
changeViewMode,
|
||||
nextViewMode
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/**
|
||||
* Copyright (c) 2023 - present TinyEngine Authors.
|
||||
* Copyright (c) 2023 - present Huawei Cloud Computing Technologies Co., Ltd.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license.
|
||||
*
|
||||
* THE OPEN SOURCE SOFTWARE IN THIS PRODUCT IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL,
|
||||
* BUT WITHOUT ANY WARRANTY, WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. SEE THE APPLICABLE LICENSES FOR MORE DETAILS.
|
||||
*
|
||||
*/
|
||||
|
||||
import { defineConfig } from 'vite'
|
||||
import path from 'path'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import vueJsx from '@vitejs/plugin-vue-jsx'
|
||||
import generateComment from '@opentiny/tiny-engine-vite-plugin-meta-comments'
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [generateComment(), vue(), vueJsx()],
|
||||
publicDir: false,
|
||||
resolve: {},
|
||||
build: {
|
||||
lib: {
|
||||
entry: path.resolve(__dirname, './index.js'),
|
||||
name: 'toolbar-view-setting',
|
||||
fileName: () => 'index.js',
|
||||
formats: ['es']
|
||||
},
|
||||
rollupOptions: {
|
||||
output: {
|
||||
banner: 'import "./style.css"'
|
||||
},
|
||||
external: ['vue', /@opentiny\/tiny-engine.*/, /@opentiny\/vue.*/]
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
@ -93,10 +93,12 @@ if (typeof sessionStorage !== 'undefined') {
|
|||
|
||||
export const BROADCAST_CHANNEL = {
|
||||
CanvasLang: `tiny-lowcode-canvas-lang-${CHANNEL_UID}`,
|
||||
Notify: `global-notify-${CHANNEL_UID}`
|
||||
Notify: `global-notify-${CHANNEL_UID}`,
|
||||
CanvasRouterViewSetting: `tiny-lowcode-canvas-router-view-setting-${CHANNEL_UID}`
|
||||
}
|
||||
|
||||
export const STORAGE_KEY_FIXED_PANELS = `tiny-engine-fixed-panels-${CHANNEL_UID}`
|
||||
export const CANVAS_ROUTER_VIEW_SETTING_VIEW_MODE_KEY = `tiny-engine-canvas-router-view-setting-view-mode`
|
||||
|
||||
export const TYPES = {
|
||||
ErrorType: 'error',
|
||||
|
|
|
|||
Loading…
Reference in New Issue