mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-09 10:34:17 +00:00
fix unmount
This commit is contained in:
parent
dacca7021c
commit
ac93563a5e
@ -9,261 +9,287 @@ import NavMenu from "./components/NavMenu"
|
||||
import "./index.less"
|
||||
|
||||
export class Tab extends React.Component {
|
||||
state = {
|
||||
error: null
|
||||
}
|
||||
state = {
|
||||
error: null,
|
||||
}
|
||||
|
||||
// handle on error
|
||||
componentDidCatch(err) {
|
||||
this.setState({ error: err })
|
||||
}
|
||||
// handle on error
|
||||
componentDidCatch(err) {
|
||||
this.setState({ error: err })
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.error) {
|
||||
return <antd.Result
|
||||
status="error"
|
||||
title="Error"
|
||||
subTitle={this.state.error}
|
||||
/>
|
||||
}
|
||||
render() {
|
||||
if (this.state.error) {
|
||||
return (
|
||||
<antd.Result
|
||||
status="error"
|
||||
title="Error"
|
||||
subTitle={this.state.error}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
return <>
|
||||
{this.props.children}
|
||||
</>
|
||||
}
|
||||
return <>{this.props.children}</>
|
||||
}
|
||||
}
|
||||
|
||||
export const Panel = (props) => {
|
||||
return <div
|
||||
{...props.props ?? {}}
|
||||
className={classnames(
|
||||
"panel",
|
||||
props.align,
|
||||
props.className
|
||||
)}
|
||||
>
|
||||
{props.children}
|
||||
</div>
|
||||
return (
|
||||
<div
|
||||
{...(props.props ?? {})}
|
||||
className={classnames("panel", props.align, props.className)}
|
||||
>
|
||||
{props.children}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export class PagePanelWithNavMenu extends React.Component {
|
||||
state = {
|
||||
activeTab: new URLSearchParams(window.location.search).get("type") ?? this.props.defaultTab ?? this.props.tabs[0].key,
|
||||
renders: [],
|
||||
}
|
||||
state = {
|
||||
activeTab:
|
||||
new URLSearchParams(window.location.search).get("type") ??
|
||||
this.props.defaultTab ??
|
||||
this.props.tabs[0].key,
|
||||
renders: [],
|
||||
}
|
||||
|
||||
primaryPanelRef = React.createRef()
|
||||
primaryPanelRef = React.createRef()
|
||||
|
||||
interface = {
|
||||
attachComponent: (id, component, options) => {
|
||||
const renders = this.state.renders
|
||||
interface = {
|
||||
attachComponent: (id, component, options) => {
|
||||
const renders = this.state.renders
|
||||
|
||||
renders.push({
|
||||
id: id,
|
||||
component: component,
|
||||
options: options,
|
||||
ref: React.createRef()
|
||||
})
|
||||
renders.push({
|
||||
id: id,
|
||||
component: component,
|
||||
options: options,
|
||||
ref: React.createRef(),
|
||||
})
|
||||
|
||||
this.setState({
|
||||
renders: renders,
|
||||
})
|
||||
},
|
||||
detachComponent: (id) => {
|
||||
const renders = this.state.renders
|
||||
this.setState({
|
||||
renders: renders,
|
||||
})
|
||||
},
|
||||
detachComponent: (id) => {
|
||||
const renders = this.state.renders
|
||||
|
||||
const index = renders.findIndex((render) => render.id === id)
|
||||
const index = renders.findIndex((render) => render.id === id)
|
||||
|
||||
renders.splice(index, 1)
|
||||
renders.splice(index, 1)
|
||||
|
||||
this.setState({
|
||||
renders: renders,
|
||||
})
|
||||
}
|
||||
}
|
||||
this.setState({
|
||||
renders: renders,
|
||||
})
|
||||
},
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
app.layout.page_panels = this.interface
|
||||
componentDidMount() {
|
||||
app.layout.page_panels = this.interface
|
||||
|
||||
if (app.isMobile) {
|
||||
app.layout.top_bar.shouldUseTopBarSpacer(true)
|
||||
app.layout.toggleCenteredContent(false)
|
||||
}
|
||||
if (app.isMobile) {
|
||||
app.layout.top_bar.shouldUseTopBarSpacer(true)
|
||||
app.layout.toggleCenteredContent(false)
|
||||
}
|
||||
|
||||
app.layout.toggleCenteredContent(true)
|
||||
}
|
||||
app.layout.toggleCenteredContent(true)
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
delete app.layout.page_panels
|
||||
componentWillUnmount() {
|
||||
delete app.layout.page_panels
|
||||
|
||||
if (!app.isMobile) {
|
||||
app.layout.header.render(null)
|
||||
} else {
|
||||
app.layout.top_bar.renderDefault()
|
||||
}
|
||||
}
|
||||
if (!app.isMobile) {
|
||||
if (app.layout.header) {
|
||||
app.layout.header.render(null)
|
||||
}
|
||||
} else {
|
||||
app.layout.top_bar.renderDefault()
|
||||
}
|
||||
}
|
||||
|
||||
renderActiveTab() {
|
||||
if (!Array.isArray(this.props.tabs)) {
|
||||
console.error("PagePanelWithNavMenu: tabs must be an array")
|
||||
return <></>
|
||||
}
|
||||
renderActiveTab() {
|
||||
if (!Array.isArray(this.props.tabs)) {
|
||||
console.error("PagePanelWithNavMenu: tabs must be an array")
|
||||
return <></>
|
||||
}
|
||||
|
||||
if (this.props.tabs.length === 0) {
|
||||
return <></>
|
||||
}
|
||||
if (this.props.tabs.length === 0) {
|
||||
return <></>
|
||||
}
|
||||
|
||||
// slip the active tab by splitting on "."
|
||||
if (!this.state.activeTab) {
|
||||
console.error("PagePanelWithNavMenu: activeTab is not defined")
|
||||
return <></>
|
||||
}
|
||||
// slip the active tab by splitting on "."
|
||||
if (!this.state.activeTab) {
|
||||
console.error("PagePanelWithNavMenu: activeTab is not defined")
|
||||
return <></>
|
||||
}
|
||||
|
||||
let tab = null
|
||||
let tab = null
|
||||
|
||||
const activeTabDirectory = this.state.activeTab.split(".")
|
||||
const activeTabDirectory = this.state.activeTab.split(".")
|
||||
|
||||
activeTabDirectory.forEach((key, index) => {
|
||||
if (!tab) {
|
||||
tab = this.props.tabs.find((children) => children.key === key)
|
||||
} else {
|
||||
if (!tab.children) {
|
||||
console.error("PagePanelWithNavMenu: tab.children is not defined")
|
||||
activeTabDirectory.forEach((key, index) => {
|
||||
if (!tab) {
|
||||
tab = this.props.tabs.find((children) => children.key === key)
|
||||
} else {
|
||||
if (!tab.children) {
|
||||
console.error(
|
||||
"PagePanelWithNavMenu: tab.children is not defined",
|
||||
)
|
||||
|
||||
return tab = null
|
||||
}
|
||||
return (tab = null)
|
||||
}
|
||||
|
||||
tab = tab.children.find((children) => children.key === `${activeTabDirectory[index - 1]}.${key}`)
|
||||
}
|
||||
})
|
||||
tab = tab.children.find(
|
||||
(children) =>
|
||||
children.key ===
|
||||
`${activeTabDirectory[index - 1]}.${key}`,
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
if (!tab) {
|
||||
if (this.props.onNotFound) {
|
||||
return this.props.onNotFound()
|
||||
}
|
||||
if (!tab) {
|
||||
if (this.props.onNotFound) {
|
||||
return this.props.onNotFound()
|
||||
}
|
||||
|
||||
return <antd.Result
|
||||
status="404"
|
||||
title="404"
|
||||
subTitle="Sorry, the tab you visited does not exist."
|
||||
/>
|
||||
}
|
||||
return (
|
||||
<antd.Result
|
||||
status="404"
|
||||
title="404"
|
||||
subTitle="Sorry, the tab you visited does not exist."
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
const componentProps = tab.props ?? this.props.tabProps
|
||||
const componentProps = tab.props ?? this.props.tabProps
|
||||
|
||||
return React.createElement(tab.component, {
|
||||
...componentProps,
|
||||
})
|
||||
}
|
||||
return React.createElement(tab.component, {
|
||||
...componentProps,
|
||||
})
|
||||
}
|
||||
|
||||
replaceQueryTypeToCurrentTab = (key) => {
|
||||
history.pushState(undefined, "", `?type=${key ?? this.state.activeTab}`)
|
||||
}
|
||||
replaceQueryTypeToCurrentTab = (key) => {
|
||||
history.pushState(undefined, "", `?type=${key ?? this.state.activeTab}`)
|
||||
}
|
||||
|
||||
tabChange = async (key) => {
|
||||
if (this.props.beforeTabChange) {
|
||||
await this.props.beforeTabChange(key)
|
||||
}
|
||||
tabChange = async (key) => {
|
||||
if (this.props.beforeTabChange) {
|
||||
await this.props.beforeTabChange(key)
|
||||
}
|
||||
|
||||
await this.setState({ activeTab: key })
|
||||
await this.setState({ activeTab: key })
|
||||
|
||||
if (this.props.useSetQueryType) {
|
||||
this.replaceQueryTypeToCurrentTab(key)
|
||||
}
|
||||
if (this.props.useSetQueryType) {
|
||||
this.replaceQueryTypeToCurrentTab(key)
|
||||
}
|
||||
|
||||
if (this.props.onTabChange) {
|
||||
this.props.onTabChange(key)
|
||||
}
|
||||
}
|
||||
if (this.props.onTabChange) {
|
||||
this.props.onTabChange(key)
|
||||
}
|
||||
}
|
||||
|
||||
handleTabChange = async (key) => {
|
||||
if (this.state.activeTab === key) return
|
||||
handleTabChange = async (key) => {
|
||||
if (this.state.activeTab === key) return
|
||||
|
||||
if (this.props.transition) {
|
||||
if (document.startViewTransition) {
|
||||
return document.startViewTransition(() => {
|
||||
this.tabChange(key)
|
||||
})
|
||||
}
|
||||
if (this.props.transition) {
|
||||
if (document.startViewTransition) {
|
||||
return document.startViewTransition(() => {
|
||||
this.tabChange(key)
|
||||
})
|
||||
}
|
||||
|
||||
console.warn("PagePanelWithNavMenu: transition is enabled but document.startViewTransition is not compatible with your browser")
|
||||
console.warn(
|
||||
"PagePanelWithNavMenu: transition is enabled but document.startViewTransition is not compatible with your browser",
|
||||
)
|
||||
|
||||
if (this.primaryPanelRef.current && this.primaryPanelRef.current?.classList) {
|
||||
// set to primary panel fade-opacity-leave class
|
||||
this.primaryPanelRef.current.classList.add("fade-opacity-leave")
|
||||
if (
|
||||
this.primaryPanelRef.current &&
|
||||
this.primaryPanelRef.current?.classList
|
||||
) {
|
||||
// set to primary panel fade-opacity-leave class
|
||||
this.primaryPanelRef.current.classList.add("fade-opacity-leave")
|
||||
|
||||
// remove fade-opacity-leave class after animation
|
||||
setTimeout(() => {
|
||||
this.primaryPanelRef.current.classList.remove("fade-opacity-leave")
|
||||
}, 300)
|
||||
}
|
||||
// remove fade-opacity-leave class after animation
|
||||
setTimeout(() => {
|
||||
this.primaryPanelRef.current.classList.remove(
|
||||
"fade-opacity-leave",
|
||||
)
|
||||
}, 300)
|
||||
}
|
||||
|
||||
await new Promise(resolve => setTimeout(resolve, 200))
|
||||
}
|
||||
await new Promise((resolve) => setTimeout(resolve, 200))
|
||||
}
|
||||
|
||||
return this.tabChange(key)
|
||||
}
|
||||
return this.tabChange(key)
|
||||
}
|
||||
|
||||
getItems = (items) => {
|
||||
if (!Array.isArray(items)) {
|
||||
console.error(`[items] is not an (array), received (${typeof items})`)
|
||||
return []
|
||||
}
|
||||
getItems = (items) => {
|
||||
if (!Array.isArray(items)) {
|
||||
console.error(
|
||||
`[items] is not an (array), received (${typeof items})`,
|
||||
)
|
||||
return []
|
||||
}
|
||||
|
||||
items = items.map((item) => {
|
||||
return {
|
||||
key: item.key,
|
||||
icon: createIconRender(item.icon),
|
||||
label: item.label,
|
||||
children: item.children && this.getItems(item.children),
|
||||
disabled: item.disabled,
|
||||
props: item.props ?? {},
|
||||
}
|
||||
})
|
||||
items = items.map((item) => {
|
||||
return {
|
||||
key: item.key,
|
||||
icon: createIconRender(item.icon),
|
||||
label: item.label,
|
||||
children: item.children && this.getItems(item.children),
|
||||
disabled: item.disabled,
|
||||
props: item.props ?? {},
|
||||
}
|
||||
})
|
||||
|
||||
return items
|
||||
}
|
||||
return items
|
||||
}
|
||||
|
||||
render() {
|
||||
return <>
|
||||
{
|
||||
app.isMobile && app.layout.top_bar.render(<NavMenu
|
||||
activeKey={this.state.activeTab}
|
||||
items={this.getItems(this.props.tabs)}
|
||||
onClickItem={(key) => this.handleTabChange(key)}
|
||||
/>)
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<>
|
||||
{app.isMobile &&
|
||||
app.layout.top_bar.render(
|
||||
<NavMenu
|
||||
activeKey={this.state.activeTab}
|
||||
items={this.getItems(this.props.tabs)}
|
||||
onClickItem={(key) => this.handleTabChange(key)}
|
||||
/>,
|
||||
)}
|
||||
|
||||
{
|
||||
!app.isMobile && app.layout.header.render(<NavMenu
|
||||
header={this.props.navMenuHeader}
|
||||
activeKey={this.state.activeTab}
|
||||
items={this.getItems([...this.props.tabs ?? [], ...this.props.extraItems ?? []])}
|
||||
onClickItem={(key) => this.handleTabChange(key)}
|
||||
renderNames
|
||||
>
|
||||
{
|
||||
Array.isArray(this.state.renders) && [
|
||||
this.state.renders.map((render, index) => {
|
||||
return React.createElement(render.component, {
|
||||
...render.options.props,
|
||||
ref: render.ref
|
||||
})
|
||||
})
|
||||
]
|
||||
}
|
||||
</NavMenu>)
|
||||
}
|
||||
{!app.isMobile &&
|
||||
app.layout.header.render(
|
||||
<NavMenu
|
||||
header={this.props.navMenuHeader}
|
||||
activeKey={this.state.activeTab}
|
||||
items={this.getItems([
|
||||
...(this.props.tabs ?? []),
|
||||
...(this.props.extraItems ?? []),
|
||||
])}
|
||||
onClickItem={(key) => this.handleTabChange(key)}
|
||||
renderNames
|
||||
>
|
||||
{Array.isArray(this.state.renders) && [
|
||||
this.state.renders.map((render, index) => {
|
||||
return React.createElement(
|
||||
render.component,
|
||||
{
|
||||
...render.options.props,
|
||||
ref: render.ref,
|
||||
},
|
||||
)
|
||||
}),
|
||||
]}
|
||||
</NavMenu>,
|
||||
)}
|
||||
|
||||
<div className="pagePanels">
|
||||
<div className="panel" ref={this.primaryPanelRef}>
|
||||
{
|
||||
this.renderActiveTab()
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
}
|
||||
<div className="pagePanels">
|
||||
<div className="panel" ref={this.primaryPanelRef}>
|
||||
{this.renderActiveTab()}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default PagePanelWithNavMenu
|
Loading…
x
Reference in New Issue
Block a user