feat(DockViewV2): support Renderer parameter (#4153)

* fix: 修复dockview切换tab或拖动时iframe重新加载

* fix: 给拖动时新增的group添加ResizeObserver

* fix: 修复把floating group拖入结构中时浮动按钮显示状态异常

* refactor:panel添加内边距

* refactor: 代码格式化

* refactor: 增加异常保护

* fix:修复title拼接错误导致自定义布局页面报错

* chore: bump version 8.1.1

* doc: 更新依赖包

---------

Co-authored-by: Argo-AscioTech <argo@live.ca>
This commit is contained in:
chengKun 2024-08-26 17:15:43 +08:00 committed by GitHub
parent 08141de52b
commit 5945b0fb3c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 85 additions and 40 deletions

View File

@ -36,7 +36,7 @@
<PackageReference Include="BootstrapBlazor.CherryMarkdown" Version="8.0.0" />
<PackageReference Include="BootstrapBlazor.CodeEditor" Version="8.0.2" />
<PackageReference Include="BootstrapBlazor.Dock" Version="8.1.7" />
<PackageReference Include="BootstrapBlazor.DockView" Version="8.1.0" />
<PackageReference Include="BootstrapBlazor.DockView" Version="8.1.1" />
<PackageReference Include="BootstrapBlazor.DriverJs" Version="8.0.1" />
<PackageReference Include="BootstrapBlazor.ElementIcon" Version="8.0.0" />
<PackageReference Include="BootstrapBlazor.FileViewer" Version="8.0.3" />

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<Version>8.1.0</Version>
<Version>8.1.1</Version>
</PropertyGroup>
<PropertyGroup>

View File

@ -49,7 +49,7 @@
width: 100%;
}
.bb-dockview .groupview > .content-container {
.bb-dockview .groupview > .content-container, .dv-render-overlay {
padding: var(--bb-dockview-padding);
}

View File

@ -118,8 +118,8 @@ const removeEmptyLeafViews = (branch, floatingGroups, delPanels, parent) => {
else if (branch.type == 'leaf') {
if (
branch.data.views.length == 0
&& !floatingGroups.find(fg => fg.data.id.split('_')[0] == branch.data.id)
&& !delPanels.find(p => p.groupId == branch.data.id)
&& !floatingGroups.find(fg => fg.data.id.split('_')[0] == branch.data.id.split('_')[0])
&& !delPanels.find(p => p.groupId?.split('_')[0] == branch.data.id?.split('_')[0])
) {
parent && (parent.data = parent.data.filter(item => item.data.id != branch.data.id))
}
@ -199,7 +199,7 @@ const getConfigFromContent = options => {
const getGroupId = getGroupIdFunc()
const panels = {}, rootType = options.content[0].type
const orientation = rootType === 'column' ? 'VERTICAL' : 'HORIZONTAL';
const root = getTree(options.content[0], { width, height, orientation }, options, panels, getGroupId)
const root = getTree(options.content[0], { width, height, orientation }, options, panels, getGroupId, options)
return fixObject({
activeGroup: '1',
grid: { width, height, orientation, root },
@ -212,7 +212,7 @@ const getGroupIdFunc = () => {
return () => `${currentId++}`;
}
const getTree = (contentItem, { width, height, orientation }, parent, panels, getGroupId) => {
const getTree = (contentItem, { width, height, orientation }, parent, panels, getGroupId, options) => {
const length = parent.content.length;
const boxSize = orientation === 'HORIZONTAL' ? width : height;
let size;
@ -232,13 +232,13 @@ const getTree = (contentItem, { width, height, orientation }, parent, panels, ge
if (contentItem.type === 'row' || contentItem.type === 'column') {
obj.type = 'branch';
obj.size = getSize(boxSize, contentItem.width || contentItem.height) || size
obj.data = contentItem.content.map(item => getTree(item, { width, height, orientation }, contentItem, panels, getGroupId))
obj.data = contentItem.content.map(item => getTree(item, { width, height, orientation }, contentItem, panels, getGroupId, options))
}
else if (contentItem.type === 'group') {
obj = getGroupNode(contentItem, size, boxSize, parent, panels, getGroupId);
obj = getGroupNode(contentItem, size, boxSize, parent, panels, getGroupId, options);
}
else if (contentItem.type === 'component') {
obj = getLeafNode(contentItem, size, boxSize, parent, panels, getGroupId);
obj = getLeafNode(contentItem, size, boxSize, parent, panels, getGroupId, options);
}
return obj
}
@ -251,7 +251,7 @@ const getActualSize = (width, height, widthRate, heightRate, defaultSize) => (wi
? defaultSize
: width ? width * widthRate / 100 : height * heightRate / 100;
const getGroupNode = (contentItem, size, boxSize, parent, panels, getGroupId) => {
const getGroupNode = (contentItem, size, boxSize, parent, panels, getGroupId, options) => {
return {
type: 'leaf',
size: getSize(boxSize, contentItem.width || contentItem.height) || size,
@ -266,6 +266,7 @@ const getGroupNode = (contentItem, size, boxSize, parent, panels, getGroupId) =>
title: item.title,
tabComponent: item.componentName,
contentComponent: item.componentName,
renderer: item.renderer || options.renderer,
params: { ...item, parentId: parent.id }
}
return item.id
@ -274,7 +275,7 @@ const getGroupNode = (contentItem, size, boxSize, parent, panels, getGroupId) =>
}
}
const getLeafNode = (contentItem, size, boxSize, parent, panels, getGroupId) => {
const getLeafNode = (contentItem, size, boxSize, parent, panels, getGroupId, options) => {
const visible = contentItem.visible !== false;
const data = {
type: 'leaf',
@ -291,6 +292,7 @@ const getLeafNode = (contentItem, size, boxSize, parent, panels, getGroupId) =>
panels[contentItem.id] = {
id: contentItem.id,
title: contentItem.title,
renderer: contentItem.renderer || options.renderer,
tabComponent: contentItem.componentName,
contentComponent: contentItem.componentName,
params: { ...contentItem, parentId: parent.id }

View File

@ -11,7 +11,7 @@
if (template) {
this._element = key
? template.querySelector(`[data-bb-key="${key}"]`)
: (template.querySelector(`#${this.option.id}`) ?? template.querySelector(`[data-bb-title="${title}]"`))
: (template.querySelector(`#${this.option.id}`) ?? template.querySelector(`[data-bb-title="${title}"]`))
}
if (titleClass) {

View File

@ -1,6 +1,7 @@
import { getIcons, getIcon } from "./dockview-icon.js"
import { deletePanel, findContentFromPanels } from "./dockview-panel.js"
import { saveConfig } from "./dockview-config.js"
import { observeGroup } from "./dockview-utils.js"
import EventHandler from '../../BootstrapBlazor/modules/event-handler.js'
const onAddGroup = group => {
@ -22,6 +23,7 @@ const onAddGroup = group => {
saveConfig(dockview)
})
createGroupActions(group);
dockview._inited && observeGroup(group)
}
const addGroupWithPanel = (dockview, panel, panels, index) => {
@ -64,6 +66,7 @@ const addPanelWidthGroupId = (dockview, panel, index) => {
dockview.addPanel({
id: panel.id,
title: panel.title,
renderer: panel.renderer,
component: panel.component,
position: { referenceGroup: group, index: index || 0 },
params: { ...panel.params, isPackup, packupHeight, isMaximized, position }
@ -100,6 +103,7 @@ const addPanelWidthCreatGroup = (dockview, panel, panels) => {
let option = {
id: panel.id,
title: panel.title,
renderer: panel.renderer,
component: panel.component,
position: { referenceGroup: group },
params: { ...panel.params, isPackup, packupHeight, isMaximized, position }
@ -144,8 +148,11 @@ const createGroupActions = group => {
}
const disposeGroup = group => {
group.api.accessor.params.observer.unobserve(group.header.element);
group.api.accessor.params.observer.unobserve(group.header.tabContainer);
const { observer } = group.api.accessor.params;
if (observer) {
observer.unobserve(group.header.element);
observer.unobserve(group.header.tabContainer);
}
removeActionEvent(group);
}
@ -299,7 +306,7 @@ const float = group => {
const dockview = group.api.accessor;
const x = (dockview.width - 500) / 2
const y = (dockview.height - 460) / 2
const gridGroups = dockview.groups.filter(group => group.panels.length > 0 && group.type === 'grid')
const gridGroups = dockview.groups.filter(g => g.panels.length > 0 && g.model.location.type === 'grid')
if (gridGroups.length <= 1) return;
const { position = {} } = group.getParams()
@ -310,7 +317,9 @@ const float = group => {
height: position.height || 460
}
const floatingGroup = dockview.createGroup({ id: `${group.id}_floating` });
const floatingGroup = dockview.createGroup({ id: getFloatingId(group.id) });
observeFloatingGroupLocationChange(floatingGroup)
group.panels.slice(0).forEach((panel, index) => {
dockview.moveGroupOrPanel({
@ -324,12 +333,34 @@ const float = group => {
createGroupActions(floatingGroup);
saveConfig(dockview)
}
const observeFloatingGroupLocationChange = fg => {
const dockview = fg.api.accessor
fg.api.onDidLocationChange(e => {
if (e.location.type == 'grid') {
setTimeout(() => {
let originalGroup = dockview.groups.find(g => g.id.split('_')[0] == fg.id.split('_')[0])
if (originalGroup) {
dockview.isClearing = true
dockview.removeGroup(originalGroup)
dockview.isClearing = false
fg.header.rightActionsContainer.classList.remove('bb-float')
saveConfig(dockview)
}
}, 0)
}
})
}
const getFloatingId = id => {
const arr = id.split('_')
return arr.length == 1 ? id + '_floating' : arr[0]
}
const dock = group => {
if (group.locked) return;
const dockview = group.api.accessor
const originGroup = dockview.groups.find(item => `${item.id}_floating` === group.id)
if(!originGroup) return
const originGroup = dockview.groups.find(g => g.id.split('_')[0] == group.id.split('_')[0] && g.id != group.id)
if (!originGroup) return
dockview.setVisible(originGroup, true)
let { isPackup, packupHeight, isMaximized, position } = group.getParams()
@ -439,4 +470,4 @@ const setWidth = (observerList) => {
})
}
export { onAddGroup, addGroupWithPanel, toggleLock, disposeGroup };
export { onAddGroup, addGroupWithPanel, toggleLock, disposeGroup, observeFloatingGroupLocationChange };

View File

@ -5,12 +5,15 @@ const onAddPanel = panel => {
updateCloseButton(panel);
updateTitle(panel);
panel.api.onDidActiveChange(({ isActive }) => {
if (panel.group.panels.length < 2) return
if (isActive) {
// if (panel.group.panels.length < 2)
// if (isActive) {
// saveConfig(panel.accessor)
// panel.group.panels.filter(p => p != panel.group.activePanel).forEach(p => {
// appendTemplatePanelEle(p)
// })
// }
if(isActive){
saveConfig(panel.accessor)
panel.group.panels.filter(p => p != panel.group.activePanel).forEach(p => {
appendTemplatePanelEle(p)
})
}
})
}
@ -21,6 +24,7 @@ const onRemovePanel = event => {
id: event.id,
title: event.title,
component: event.view.contentComponent,
renderer: event.renderer,
groupId: event.group.id,
params: {
...event.params,
@ -100,22 +104,23 @@ const updateTitle = panel => {
}
const getPanelsFromOptions = options => {
return getPanels(options.content[0])
return getPanels(options.content[0], options)
}
const getPanels = (contentItem, parent = {}, panels = []) => {
const getPanels = (contentItem, options, parent = {}, panels = []) => {
if (contentItem.type === 'component') {
panels.push({
id: contentItem.id,
groupId: contentItem.groupId,
title: contentItem.title,
renderer: contentItem.renderer || options.renderer,
tabComponent: contentItem.componentName,
contentComponent: contentItem.componentName,
params: { ...contentItem, parentType: parent.type, parentId: parent.id }
});
}
else {
contentItem.content?.forEach(item => getPanels(item, contentItem, panels))
contentItem.content?.forEach(item => getPanels(item, options, contentItem, panels))
}
return panels
}

View File

@ -1,6 +1,6 @@
import { DockviewComponent } from "./dockview-core.esm.js"
import { DockviewPanelContent } from "./dockview-content.js"
import { onAddGroup, addGroupWithPanel, toggleLock } from "./dockview-group.js"
import { onAddGroup, addGroupWithPanel, toggleLock, observeFloatingGroupLocationChange } from "./dockview-group.js"
import { onAddPanel, onRemovePanel, getPanelsFromOptions, findContentFromPanels } from "./dockview-panel.js"
import { getConfig, reloadFromConfig, loadPanelsFromLocalstorage, saveConfig } from './dockview-config.js'
import './dockview-extensions.js'
@ -83,22 +83,14 @@ const initDockview = (dockview, options, template) => {
const style = group.element.parentElement.style
style.top = top + 'px'
style.left = left + 'px'
observeFloatingGroupLocationChange(group)
})
dockview._inited = true;
dockview._initialized?.fire()
dockview.groups.forEach(group => {
if (dockview.params.observer === null) {
dockview.params.observer = new ResizeObserver(observerList => resizeObserverHandle(observerList, dockview));
}
dockview.params.observer.observe(group.header.element)
dockview.params.observer.observe(group.header.tabContainer)
for (let panel of group.panels) {
if (panel.params.isActive) {
panel.api.setActive()
break
}
}
observeGroup(group)
})
}, 100);
})
@ -114,6 +106,21 @@ const initDockview = (dockview, options, template) => {
}
export const observeGroup = (group) => {
const dockview = group.api.accessor
if (dockview.params.observer === null) {
dockview.params.observer = new ResizeObserver(observerList => resizeObserverHandle(observerList, dockview));
}
dockview.params.observer.observe(group.header.element)
dockview.params.observer.observe(group.header.tabContainer)
for (let panel of group.panels) {
if (panel.params.isActive) {
panel.api.setActive()
break
}
}
}
const resizeObserverHandle = (observerList, dockview) => {
observerList.forEach(({ target }) => {
setWidth(target, dockview)