Initial commit
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
@mixin mk-disable-scrollbar {
|
||||
scrollbar-width: none;
|
||||
-ms-overflow-style: none;
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
$mk-appbar-color: #E4E4E4 !default;
|
||||
$mk-appbar-background: #3C3E4B !default;
|
||||
@@ -0,0 +1,6 @@
|
||||
$mk-appbar-color: #dee2e6 !default;
|
||||
$mk-appbar-active: $o-brand-primary !default;
|
||||
$mk-appbar-background: #111827 !default;
|
||||
|
||||
$mk-sidebar-large-width: 146px !default;
|
||||
$mk-sidebar-small-width: 46px !default;
|
||||
@@ -0,0 +1,34 @@
|
||||
import { url } from '@web/core/utils/urls';
|
||||
import { useService } from '@web/core/utils/hooks';
|
||||
import { user } from "@web/core/user";
|
||||
|
||||
import { Component, onWillUnmount } from '@odoo/owl';
|
||||
|
||||
export class AppsBar extends Component {
|
||||
static template = 'muk_web_appsbar.AppsBar';
|
||||
static props = {};
|
||||
setup() {
|
||||
this.appMenuService = useService('app_menu');
|
||||
if (user.activeCompany.has_appsbar_image) {
|
||||
this.sidebarImageUrl = url('/web/image', {
|
||||
model: 'res.company',
|
||||
field: 'appbar_image',
|
||||
id: user.activeCompany.id,
|
||||
});
|
||||
}
|
||||
const renderAfterMenuChange = () => {
|
||||
this.render();
|
||||
};
|
||||
this.env.bus.addEventListener(
|
||||
'MENUS:APP-CHANGED', renderAfterMenuChange
|
||||
);
|
||||
onWillUnmount(() => {
|
||||
this.env.bus.removeEventListener(
|
||||
'MENUS:APP-CHANGED', renderAfterMenuChange
|
||||
);
|
||||
});
|
||||
}
|
||||
_onAppClick(app) {
|
||||
return this.appMenuService.selectApp(app);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
.mk_apps_sidebar_panel {
|
||||
@include mk-disable-scrollbar();
|
||||
background-color: $mk-appbar-background;
|
||||
width: var(--mk-sidebar-width, 0);
|
||||
overflow-y: auto;
|
||||
.mk_apps_sidebar {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
white-space: nowrap;
|
||||
.mk_apps_sidebar_menu {
|
||||
padding: 0;
|
||||
> li > a {
|
||||
cursor: pointer;
|
||||
font-size: 13px;
|
||||
font-weight: 300;
|
||||
overflow: hidden;
|
||||
padding: 8px 11px;
|
||||
text-decoration: none;
|
||||
color: $mk-appbar-color;
|
||||
text-overflow: ellipsis;
|
||||
.mk_apps_sidebar_icon {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
> li.active > a {
|
||||
background: $mk-appbar-active;
|
||||
}
|
||||
> li:hover > a {
|
||||
background: $mk-appbar-active;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mk_sidebar_type_large {
|
||||
--mk-sidebar-width: #{$mk-sidebar-large-width};
|
||||
}
|
||||
|
||||
.mk_sidebar_type_small {
|
||||
--mk-sidebar-width: #{$mk-sidebar-small-width};
|
||||
.mk_apps_sidebar_name {
|
||||
display: none;
|
||||
}
|
||||
.mk_apps_sidebar_icon {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
.mk_apps_sidebar_logo {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.mk_sidebar_type_invisible {
|
||||
--mk-sidebar-width: 0;
|
||||
}
|
||||
|
||||
.editor_has_snippets_hide_backend_navbar,
|
||||
.o_home_menu_background,
|
||||
.o_fullscreen {
|
||||
--mk-sidebar-width: 0;
|
||||
}
|
||||
|
||||
.editor_has_snippets_hide_backend_navbar .mk_apps_sidebar_panel {
|
||||
transition: width 300ms;
|
||||
}
|
||||
|
||||
@include media-breakpoint-only(md) {
|
||||
.mk_sidebar_type_large {
|
||||
--mk-sidebar-width: #{$mk-sidebar-small-width};
|
||||
.mk_apps_sidebar_name {
|
||||
display: none;
|
||||
}
|
||||
.mk_apps_sidebar_icon {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
.mk_apps_sidebar_logo {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(md) {
|
||||
.mk_sidebar_type_large, .mk_sidebar_type_small {
|
||||
--mk-sidebar-width: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media print {
|
||||
.mk_sidebar_type_large, .mk_sidebar_type_small {
|
||||
--mk-sidebar-width: 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t t-name="muk_web_appsbar.AppsBar">
|
||||
<div class="mk_apps_sidebar_panel">
|
||||
<div class="mk_apps_sidebar">
|
||||
<ul class="mk_apps_sidebar_menu">
|
||||
<t t-foreach="this.appMenuService.getAppsMenuItems()" t-as="app" t-key="app.id">
|
||||
<li t-attf-class="nav-item {{ app.id === this.appMenuService.getCurrentApp()?.id ? 'active' : '' }}">
|
||||
<a
|
||||
t-att-href="app.href"
|
||||
t-att-data-menu-id="app.id"
|
||||
t-att-data-menu-xmlid="app.xmlid"
|
||||
t-att-data-action-id="app.actionID"
|
||||
t-on-click.prevent="() => this._onAppClick(app)"
|
||||
class="nav-link"
|
||||
role="menuitem"
|
||||
>
|
||||
<img
|
||||
t-if="app.webIconData"
|
||||
class="mk_apps_sidebar_icon"
|
||||
t-att-src="app.webIconData"
|
||||
/>
|
||||
<img
|
||||
t-else=""
|
||||
class="mk_apps_sidebar_icon"
|
||||
src="/base/static/description/icon.png"
|
||||
/>
|
||||
<span class="mk_apps_sidebar_name">
|
||||
<t t-out="app.label"/>
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
<div t-if="sidebarImageUrl" class="mk_apps_sidebar_logo p-2">
|
||||
<img class="img-fluid mx-auto" t-att-src="sidebarImageUrl" alt="Logo"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
@@ -0,0 +1,33 @@
|
||||
import { registry } from "@web/core/registry";
|
||||
import { user } from "@web/core/user";
|
||||
|
||||
import { computeAppsAndMenuItems, reorderApps } from "@web/webclient/menus/menu_helpers";
|
||||
|
||||
export const appMenuService = {
|
||||
dependencies: ["menu"],
|
||||
async start(env, { menu }) {
|
||||
return {
|
||||
getCurrentApp () {
|
||||
return menu.getCurrentApp();
|
||||
},
|
||||
getAppsMenuItems() {
|
||||
const menuItems = computeAppsAndMenuItems(
|
||||
menu.getMenuAsTree('root')
|
||||
)
|
||||
const apps = menuItems.apps;
|
||||
const menuConfig = JSON.parse(
|
||||
user.settings?.homemenu_config || 'null'
|
||||
);
|
||||
if (menuConfig) {
|
||||
reorderApps(apps, menuConfig);
|
||||
}
|
||||
return apps;
|
||||
},
|
||||
selectApp(app) {
|
||||
menu.selectMenu(app);
|
||||
}
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
registry.category("services").add("app_menu", appMenuService);
|
||||
@@ -0,0 +1,11 @@
|
||||
import { patch } from '@web/core/utils/patch';
|
||||
|
||||
import { WebClient } from '@web/webclient/webclient';
|
||||
import { AppsBar } from '@muk_web_appsbar/webclient/appsbar/appsbar';
|
||||
|
||||
patch(WebClient, {
|
||||
components: {
|
||||
...WebClient.components,
|
||||
AppsBar,
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
.o_web_client {
|
||||
display: grid !important;
|
||||
grid-template-areas:
|
||||
"banner banner"
|
||||
"navbar navbar"
|
||||
"sidebar content"
|
||||
"components components";
|
||||
grid-template-rows: auto auto 1fr auto;
|
||||
grid-template-columns: auto 1fr;
|
||||
> div:has(#oe_neutralize_banner) {
|
||||
grid-area: banner;
|
||||
}
|
||||
> .o_navbar {
|
||||
grid-area: navbar;
|
||||
}
|
||||
> .mk_apps_sidebar_panel {
|
||||
grid-area: sidebar;
|
||||
}
|
||||
> .o_action_manager {
|
||||
grid-area: content;
|
||||
}
|
||||
> .o-main-components-container {
|
||||
grid-area: components;
|
||||
}
|
||||
> iframe {
|
||||
grid-column: 1 / -1;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
|
||||
<templates xml:space="preserve">
|
||||
|
||||
<t
|
||||
t-name="muk_web_appsbar.WebClient"
|
||||
t-inherit="web.WebClient"
|
||||
t-inherit-mode="extension"
|
||||
>
|
||||
<xpath expr="//NavBar" position="after">
|
||||
<AppsBar/>
|
||||
</xpath>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
Reference in New Issue
Block a user