diff --git a/packages/app/src/components/Layout/sidebar/index.jsx b/packages/app/src/components/Layout/sidebar/index.jsx
index 8a44498d..cfb75cc8 100755
--- a/packages/app/src/components/Layout/sidebar/index.jsx
+++ b/packages/app/src/components/Layout/sidebar/index.jsx
@@ -1,5 +1,5 @@
import React from "react"
-import { Menu, Avatar } from "antd"
+import { Menu, Avatar, Button } from "antd"
import { Translation } from "react-i18next"
import classnames from "classnames"
@@ -70,6 +70,8 @@ export default class Sidebar extends React.Component {
toggleCollapse: this.toggleCollapse,
isVisible: () => this.state.visible,
isCollapsed: () => this.state.collapsed,
+ setCustomRender: this.setRender,
+ closeCustomRender: this.closeRender,
}
this.state = {
@@ -78,6 +80,9 @@ export default class Sidebar extends React.Component {
collapsed: window.app.settings.get("collapseOnLooseFocus") ?? false,
pathResolvers: null,
menus: null,
+
+ customRenderTitle: null,
+ customRender: null,
}
// handle sidedrawer open/close
@@ -99,6 +104,38 @@ export default class Sidebar extends React.Component {
}, 100)
}
+ setRender = (render, options = {}) => {
+ if (!typeof render === "function") {
+ throw new Error("Render is required to be a function")
+ }
+
+ this.setState({
+ customRenderTitle:
+ {
+ options.icon && createIconRender(options.icon)
+ }
+ {
+ options.title &&
+
+ {t => t(options.title)}
+
+
+ }
+ ,
+ customRender: React.createElement(render, {
+ ...options.props ?? {},
+ close: this.closeRender,
+ })
+ })
+ }
+
+ closeRender = () => {
+ this.setState({
+ customRenderTitle: null,
+ customRender: null,
+ })
+ }
+
loadItems = async () => {
const generation = generateItems()
@@ -213,62 +250,87 @@ export default class Sidebar extends React.Component {
classnames(
"app_sidebar",
{
+ ["customRender"]: this.state.customRender,
["floating"]: window.app?.settings.get("sidebar.floating"),
- ["collapsed"]: this.state.visible && this.state.collapsed,
- ["elevated"]: this.state.visible && this.state.elevated,
+ ["collapsed"]: !this.state.customRender && this.state.visible && this.state.collapsed,
+ ["elevated"]: !this.state.visible && this.state.elevated,
["hidden"]: !this.state.visible,
}
)
}
>
-
-
-

+
+ {
+ this.state.customRender &&
+
+
+ {
+ this.state.customRenderTitle ?? null
+ }
+
+
+
+ {this.state.customRender}
+
-
+ }
-
-
-
+ {
+ !this.state.customRender && <>
+
+
+

+
+
-
-
-
+
+
+
+
+
+
+
+ >
+ }
)
}
diff --git a/packages/app/src/components/Layout/sidebar/index.less b/packages/app/src/components/Layout/sidebar/index.less
index b81306b2..e0a3c535 100755
--- a/packages/app/src/components/Layout/sidebar/index.less
+++ b/packages/app/src/components/Layout/sidebar/index.less
@@ -44,6 +44,25 @@
}
}
+ &.customRender {
+ display: flex;
+ position: relative;
+
+ width: 100%;
+ min-width: 34vw;
+
+ padding: 20px;
+ max-width: 60vw;
+
+ .app_sidebar_menu_wrapper {
+ animation: disappear 0.3s ease-out forwards;
+ }
+
+ .render_content_wrapper {
+ animation: appear 0.3s ease-out forwards;
+ }
+ }
+
&.hidden {
flex: 0 !important;
min-width: 0 !important;
@@ -55,6 +74,52 @@
box-shadow: 0 0 5px 4px rgba(0, 0, 0, 0.1) !important;
}
+ .render_content_wrapper {
+ display: flex;
+ flex-direction: column;
+
+ opacity: 0;
+ transition: all 150ms ease-in-out;
+
+ overflow-y: hidden;
+
+ .render_content_header {
+ display: inline-flex;
+ flex-direction: row;
+
+ align-items: center;
+ justify-content: space-between;
+
+ .render_content_header_title {
+ display: inline-flex;
+ flex-direction: row;
+
+ align-items: center;
+
+ h1,
+ h2,
+ h3 {
+ font-size: 1.8;
+ margin: 0 !important;
+ }
+
+ svg {
+ font-size: 1.8rem;
+ }
+ }
+ }
+
+ .render_content {
+ height: 100%;
+
+ padding: 20px;
+ padding-left: 0;
+
+ overflow-x: hidden;
+ overflow-y: scroll;
+ }
+ }
+
.app_sidebar_header {
display: flex;
flex-direction: column;
@@ -178,4 +243,24 @@
margin: 0;
flex: 0;
}
+}
+
+@keyframes appear {
+ 0% {
+ opacity: 0;
+ width: 0px;
+ margin: 0;
+ }
+
+ 5% {
+ opacity: 0;
+ width: 0px;
+ margin: 0;
+ }
+
+ 100% {
+ opacity: 1;
+ width: 100%;
+ margin: 0;
+ }
}
\ No newline at end of file