mirror of
https://github.com/bringout/oca-technical.git
synced 2026-04-21 06:12:03 +02:00
Initial commit: OCA Technical packages (595 packages)
This commit is contained in:
commit
2cc02aac6e
24950 changed files with 2318079 additions and 0 deletions
|
|
@ -0,0 +1,8 @@
|
|||
/* @odoo-module */
|
||||
/* Copyright 2024 Tecnativa - Carlos Roca
|
||||
* License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). */
|
||||
import {ConfirmationDialog} from "@web/core/confirmation_dialog/confirmation_dialog";
|
||||
|
||||
// Defined AnnouncementDialog to allow make possible changes in other modules
|
||||
// like announcement_dialog_size
|
||||
export class AnnouncementDialog extends ConfirmationDialog {}
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
/* @odoo-module */
|
||||
/* Copyright 2024 Tecnativa - David Vidal
|
||||
* Copyright 2024 Tecnativa - Carlos Roca
|
||||
* License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). */
|
||||
import {Component, markup, onMounted, useState} from "@odoo/owl";
|
||||
import {_lt} from "@web/core/l10n/translation";
|
||||
import {Dropdown} from "@web/core/dropdown/dropdown";
|
||||
import {DropdownItem} from "@web/core/dropdown/dropdown_item";
|
||||
import {session} from "@web/session";
|
||||
import {registry} from "@web/core/registry";
|
||||
import {useService} from "@web/core/utils/hooks";
|
||||
import {AnnouncementDialog} from "../announcement_dialog/announcement_dialog.esm";
|
||||
|
||||
export class AnnouncementMenu extends Component {
|
||||
setup() {
|
||||
this.orm = useService("orm");
|
||||
this.dialogService = useService("dialog");
|
||||
const announcements_service = useService("announcementService");
|
||||
this.announcements = useState(announcements_service.announcements);
|
||||
this.announcementMenuView = useState({isOpen: false});
|
||||
// When the user logs in we show him his unread announcements
|
||||
onMounted(async () => {
|
||||
document.addEventListener(
|
||||
"click",
|
||||
this._onClickCaptureGlobal.bind(this),
|
||||
true
|
||||
);
|
||||
// Let's check if the user just logged in and to decide if we popup the
|
||||
// announcements. This delay is hardcoded to 5 minutes, although we could
|
||||
// allow to configure it in the future.
|
||||
const user = await this.orm.call("res.users", "read", [
|
||||
session.uid,
|
||||
["login_date"],
|
||||
]);
|
||||
const login_date = !_.isEmpty(user) && user[0].login_date;
|
||||
const minutes_since_last_login =
|
||||
(moment.utc(new Date()).valueOf() - moment.utc(login_date).valueOf()) /
|
||||
1000 /
|
||||
60;
|
||||
const popup_announcement = Boolean(minutes_since_last_login < 5);
|
||||
const launchPopUp = () => {
|
||||
if (odoo.isReady) {
|
||||
if (popup_announcement && this.announcements.count > 0) {
|
||||
this.openAnnouncement(this.announcements.data[0]);
|
||||
}
|
||||
} else {
|
||||
setTimeout(launchPopUp, 500);
|
||||
}
|
||||
};
|
||||
setTimeout(launchPopUp, 500);
|
||||
});
|
||||
}
|
||||
|
||||
async getDialogAnnouncementProps(announcement) {
|
||||
return {
|
||||
title: announcement.name,
|
||||
body: markup(announcement.content || ""),
|
||||
confirm: async () => {
|
||||
await this.orm.call(
|
||||
"res.users",
|
||||
"mark_announcement_as_read",
|
||||
[announcement.id],
|
||||
{context: session.user_context}
|
||||
);
|
||||
this.announcements.data = this.announcements.data.filter(
|
||||
(el) => el.id !== announcement.id
|
||||
);
|
||||
this.announcements.count--;
|
||||
if (this.announcements.count > 0) {
|
||||
this.openAnnouncement(this.announcements.data[0]);
|
||||
}
|
||||
},
|
||||
confirmLabel: _lt("Mark as read"),
|
||||
};
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Handlers
|
||||
// ------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Toggle dropdown when clicking it
|
||||
* @private
|
||||
*/
|
||||
onClickDropdownToggle() {
|
||||
this.announcementMenuView.isOpen = !this.announcementMenuView.isOpen;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide dropdown when clicking outside
|
||||
* @private
|
||||
* @param {MouseEvent} ev
|
||||
*/
|
||||
_onClickCaptureGlobal(ev) {
|
||||
if (this.__owl__.refs.root.contains(ev.target)) {
|
||||
return;
|
||||
}
|
||||
this.announcementMenuView.isOpen = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show announcement popup
|
||||
* @private
|
||||
* @param {MouseEvent} event
|
||||
*/
|
||||
async openAnnouncement(announcement) {
|
||||
this.dialogService.add(
|
||||
AnnouncementDialog,
|
||||
await this.getDialogAnnouncementProps(announcement)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
AnnouncementMenu.components = {Dropdown, DropdownItem};
|
||||
AnnouncementMenu.props = [];
|
||||
AnnouncementMenu.template = "announcement.AnnouncementMenu";
|
||||
|
||||
export const systrayAnnouncement = {
|
||||
Component: AnnouncementMenu,
|
||||
};
|
||||
|
||||
registry
|
||||
.category("systray")
|
||||
.add("announcement.announcement_menu", systrayAnnouncement, {sequence: 100});
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<templates>
|
||||
<t t-name="announcement.AnnouncementMenu" owl="1">
|
||||
<div class="o_ActivityMenuView dropdown" t-ref="root">
|
||||
<a
|
||||
class="o_ActivityMenuView_dropdownToggle dropdown-toggle o-no-caret o-dropdown--narrow"
|
||||
t-att-aria-expanded="announcementMenuView.isOpen ? 'true' : 'false'"
|
||||
title="Announcements"
|
||||
href="#"
|
||||
role="button"
|
||||
t-on-click="onClickDropdownToggle"
|
||||
>
|
||||
<i
|
||||
class="fa fa-lg fa-bullhorn"
|
||||
role="img"
|
||||
aria-label="Announcements"
|
||||
/> <span
|
||||
t-if="announcements.count > 0"
|
||||
class="badge bg-warning"
|
||||
t-out="announcements.count"
|
||||
/>
|
||||
</a>
|
||||
<div
|
||||
t-if="announcementMenuView.isOpen"
|
||||
class="o_ActivityMenuView_dropdownMenu o-dropdown-menu dropdown-menu-end show bg-view"
|
||||
role="menu"
|
||||
>
|
||||
<div class="o_ActivityMenuView_activityGroups">
|
||||
<t t-if="announcements.count > 0">
|
||||
<t
|
||||
t-foreach="announcements.data"
|
||||
t-as="announcement"
|
||||
t-key="announcement.id"
|
||||
>
|
||||
<div
|
||||
class="o_ActivityMenuView_activityGroup"
|
||||
t-on-click="() => this.openAnnouncement(announcement)"
|
||||
>
|
||||
<div
|
||||
class="o_ActivityMenuView_activityGroupIconContainer"
|
||||
>
|
||||
<img
|
||||
src="/announcement/static/description/icon.png"
|
||||
alt="Announcement"
|
||||
/>
|
||||
</div>
|
||||
<div class="o_ActivityMenuView_activityGroupInfo">
|
||||
<div class="o_ActivityMenuView_activityGroupTitle">
|
||||
<span
|
||||
class="o_ActivityMenuView_activityGroupName"
|
||||
>
|
||||
<t t-esc="announcement.name" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div
|
||||
class="o_ActivityMenuView_noActivity dropdown-item-text text-center d-flex justify-content-center"
|
||||
>
|
||||
<span>No announcements.</span>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
<!-- -->
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/** @odoo-module */
|
||||
/* Copyright 2024 Tecnativa - David Vidal
|
||||
* Copyright 2024 Tecnativa - Carlos Roca
|
||||
* License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). */
|
||||
import {registry} from "@web/core/registry";
|
||||
import {session} from "@web/session";
|
||||
|
||||
const {reactive} = owl;
|
||||
|
||||
export const announcementService = {
|
||||
dependencies: ["orm"],
|
||||
async start(env, {orm}) {
|
||||
const announcements = reactive({});
|
||||
if (session.announcements) {
|
||||
Object.assign(announcements, session.announcements);
|
||||
} else {
|
||||
Object.assign(
|
||||
announcements,
|
||||
await orm.call("res.users", "get_announcements", [], {
|
||||
context: session.user_context,
|
||||
})
|
||||
);
|
||||
}
|
||||
setInterval(async () => {
|
||||
Object.assign(
|
||||
announcements,
|
||||
await orm.call("res.users", "get_announcements", [], {
|
||||
context: session.user_context,
|
||||
})
|
||||
);
|
||||
}, 60000);
|
||||
return {
|
||||
announcements,
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
registry.category("services").add("announcementService", announcementService);
|
||||
Loading…
Add table
Add a link
Reference in a new issue