Initial commit: OCA Technical packages (595 packages)

This commit is contained in:
Ernad Husremovic 2025-08-29 15:43:03 +02:00
commit 2cc02aac6e
24950 changed files with 2318079 additions and 0 deletions

View file

@ -0,0 +1,62 @@
/** @odoo-module **/
import {one} from "@mail/model/model_field";
import {registerModel} from "@mail/model/model_core";
import session from "web.session";
const {Component} = owl;
registerModel({
name: "QueueJobBatch",
modelMethods: {
convertData(data) {
return {
irModel: {
id: data.id,
name: data.name,
job_count: data.job_count,
completeness: data.completeness,
failed_percentage: data.failed_percentage,
finished_job_count: data.finished_job_count,
failed_job_count: data.failed_job_count,
state: data.state,
},
};
},
},
recordMethods: {
_hideJobBatch: function () {
var res_id = this.irModel.id;
this.queueJobBatchMenuView.close();
this.delete();
Component.env.services.rpc({
model: "queue.job.batch",
method: "set_read",
args: [res_id],
kwargs: {
context: session.user_context,
},
});
},
_onQueueJobBatchClick: function () {
var res_id = this.irModel.id;
this._hideJobBatch();
this.env.services.action.doAction({
type: "ir.actions.act_window",
name: "Job batches",
res_model: "queue.job.batch",
views: [[false, "form"]],
res_id: res_id,
});
},
},
fields: {
queueJobBatchMenuView: one("QueueJobBatchMenuView", {
identifying: true,
inverse: "queueJobBatches",
}),
irModel: one("ir.model.queuejobbatch", {
identifying: true,
inverse: "queueJobBatch",
}),
},
});

View file

@ -0,0 +1,26 @@
/** @odoo-module **/
// ensure components are registered beforehand.
import "./batch_menu_view.esm";
import {getMessagingComponent} from "@mail/utils/messaging_component";
const {Component} = owl;
export class QueueJobBatchMenuContainer extends Component {
/**
* @override
*/
setup() {
super.setup();
this.env.services.messaging.modelManager.messagingCreatedPromise.then(() => {
this.queueJobBatchMenuView =
this.env.services.messaging.modelManager.messaging.models.QueueJobBatchMenuView.insert();
this.render();
});
}
}
Object.assign(QueueJobBatchMenuContainer, {
components: {QueueJobBatchMenuView: getMessagingComponent("QueueJobBatchMenuView")},
template: "queue_job_batch.QueueJobBatchMenuContainer",
});

View file

@ -0,0 +1,104 @@
/** @odoo-module **/
import {attr, many} from "@mail/model/model_field";
import {registerModel} from "@mail/model/model_core";
import session from "web.session";
registerModel({
name: "QueueJobBatchMenuView",
lifecycleHooks: {
_created() {
this.fetchData();
document.addEventListener("click", this._onClickCaptureGlobal, true);
},
_willDelete() {
document.removeEventListener("click", this._onClickCaptureGlobal, true);
},
},
recordMethods: {
close() {
this.update({isOpen: false});
},
async fetchData() {
const data = await this.messaging.rpc({
model: "queue.job.batch",
method: "search_read",
args: [
[
["user_id", "=", session.uid],
"|",
["state", "in", ["draft", "progress"]],
["is_read", "=", false],
],
[
"name",
"job_count",
"completeness",
"failed_percentage",
"finished_job_count",
"failed_job_count",
"state",
],
],
kwargs: {context: session.user_context},
});
this.update({
queueJobBatches: data.map((vals) =>
this.messaging.models.QueueJobBatch.convertData(vals)
),
});
},
/**
* @param {MouseEvent} ev
*/
onClickDropdownToggle(ev) {
ev.preventDefault();
if (this.isOpen) {
this.update({isOpen: false});
} else {
this.update({isOpen: true});
this.fetchData();
}
},
/**
* Closes the menu when clicking outside, if appropriate.
*
* @private
* @param {MouseEvent} ev
*/
_onClickCaptureGlobal(ev) {
if (!this.exists()) {
return;
}
if (!this.component || !this.component.root.el) {
return;
}
if (this.component.root.el.contains(ev.target)) {
return;
}
this.close();
},
_viewAllQueueJobBatches: function () {
this.close();
this.env.services.action.doAction(
"queue_job_batch.action_view_your_queue_job_batch"
);
},
},
fields: {
queueJobBatches: many("QueueJobBatch", {
sort: [["greater-first", "irModel.id"]],
inverse: "queueJobBatchMenuView",
}),
component: attr(),
counter: attr({
compute() {
return this.queueJobBatches.length;
},
}),
isOpen: attr({
default: false,
}),
},
});

View file

@ -0,0 +1,29 @@
/** @odoo-module **/
import {registerMessagingComponent} from "@mail/utils/messaging_component";
import {useComponentToModel} from "@mail/component_hooks/use_component_to_model";
const {Component} = owl;
export class QueueJobBatchMenuView extends Component {
/**
* @override
*/
setup() {
super.setup();
useComponentToModel({fieldName: "component"});
}
/**
* @returns {QueueJobBatchMenuView}
*/
get queueJobBatchMenuView() {
return this.props.record;
}
}
Object.assign(QueueJobBatchMenuView, {
props: {record: Object},
template: "queue_job_batch.QueueJobBatchMenuView",
});
registerMessagingComponent(QueueJobBatchMenuView);

View file

@ -0,0 +1,31 @@
/** @odoo-module **/
import {attr, one} from "@mail/model/model_field";
import {registerModel} from "@mail/model/model_core";
registerModel({
name: "ir.model.queuejobbatch",
fields: {
/**
* Determines the name of the views that are available for this model.
*/
availableWebViews: attr({
compute() {
return ["kanban", "list", "form", "activity"];
},
}),
queueJobBatch: one("QueueJobBatch", {
inverse: "irModel",
}),
id: attr({
identifying: true,
}),
name: attr(),
job_count: attr(),
completeness: attr(),
failed_percentage: attr(),
finished_job_count: attr(),
failed_job_count: attr(),
state: attr(),
},
});

View file

@ -0,0 +1,26 @@
/** @odoo-module **/
import {QueueJobBatchMenuContainer} from "./batch_menu_container_view.esm";
import {registry} from "@web/core/registry";
import session from "web.session";
const systrayRegistry = registry.category("systray");
export const systrayService = {
start() {
session
.user_has_group("queue_job_batch.group_queue_job_batch_user")
.then(function (has_group) {
if (has_group) {
systrayRegistry.add(
"queue_job_batch.QueueJobBatchMenu",
{Component: QueueJobBatchMenuContainer},
{sequence: 99}
);
}
});
},
};
const serviceRegistry = registry.category("services");
serviceRegistry.add("queuebatch_systray_service", systrayService);

View file

@ -0,0 +1,38 @@
.o_job_batch_navbar_item {
.o_notification_counter {
margin-top: -0.8rem;
margin-right: 0;
margin-left: -0.6rem;
background: $o-enterprise-primary-color;
color: white;
vertical-align: super;
font-size: 0.7em;
}
.o_job_batch_navbar_dropdown {
width: 350px;
padding: 0;
}
.o_view_all_batch_jobs {
padding: 5px;
}
.o_job_queue_failed {
color: red;
}
.o_job_queue_finished {
color: green;
}
.o_job_queue_progress {
color: gray;
}
.o_progressbar_complete {
&.o_queue_job_finished_progressbar {
background-color: green;
float: left;
}
&.o_queue_job_failed_progressbar {
background-color: red;
float: right;
}
}
}

View file

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates>
<t t-name="queue_job_batch.QueueJobBatchMenuView" owl="1">
<div class="o_ActivityMenuView dropdown o_job_batch_navbar_item" t-ref="root">
<a
class="o_ActivityMenuView_dropdownToggle dropdown-toggle o-no-caret o-dropdown--narrow"
title="Job batches"
t-att-aria-expanded="queueJobBatchMenuView.isOpen ? 'true' : 'false'"
href="#"
role="button"
t-on-click="queueJobBatchMenuView.onClickDropdownToggle"
>
<i class="fa fa-list" role="img" aria-label="Job batches" />
<span
t-if="queueJobBatchMenuView.counter > 0"
class="o_ActivityMenuView_counter badge"
t-esc="queueJobBatchMenuView.counter"
/>
</a>
<div
t-if="queueJobBatchMenuView.isOpen"
class="o_ActivityMenuView_dropdownMenu o-dropdown-menu dropdown-menu-end show bg-view"
role="menu"
>
<div
class="border-bottom d-flex flex-shrink-0"
bis_skin_checked="1"
t-if="queueJobBatchMenuView.counter > 0"
>
<button
class="o-desktop btn btn-link o-active fw-bolder"
type="button"
>Job
Batches</button>
<div class="flex-grow-1" bis_skin_checked="1" />
<button
class="btn btn-link"
type="button"
t-on-click="queueJobBatchMenuView._viewAllQueueJobBatches"
>View All</button>
</div>
<t t-if="queueJobBatchMenuView.queueJobBatches.length === 0">
<div class="o_ActivityMenuView_activityGroups">
<div
class="o_ActivityMenuView_noActivity dropdown-item-text text-center d-flex justify-content-center"
>
<span>No jobs to view.</span>
</div>
</div>
</t>
<div
t-if="queueJobBatchMenuView.queueJobBatches.length > 0"
class="row"
style="width:100%"
>
<t
t-foreach="queueJobBatchMenuView.queueJobBatches"
t-as="queueJobBatch"
t-key="queueJobBatch.localId"
name="activityGroupLoop"
>
<div
class="col-2 m-2"
t-on-click="queueJobBatch._onQueueJobBatchClick"
>
<span
class="fa fa-list fa-3x o_job_queue_failed"
t-if="queueJobBatch.irModel.failed_job_count > 0"
/>
<span
class="fa fa-list fa-3x o_job_queue_finished"
t-if="queueJobBatch.irModel.failed_job_count == 0 and queueJobBatch.irModel.finished_job_count == queueJobBatch.irModel.job_count"
/>
<span
class="fa fa-list fa-3x o_job_queue_progress"
t-if="queueJobBatch.irModel.failed_job_count == 0 and queueJobBatch.irModel.finished_job_count != queueJobBatch.irModel.job_count"
/>
</div>
<div
class="col-8"
t-on-click="queueJobBatch._onQueueJobBatchClick"
>
<strong
class="o_NotificationListItem_name o_NotificationGroup_name text-truncate"
>
<t t-esc="queueJobBatch.irModel.name" />
</strong>
<div class="progress">
<div
class="progress-bar o_queue_job_finished_progressbar"
role="progressbar"
t-att-style="'width: '+ (100 * queueJobBatch.irModel.completeness) + '%'"
t-att-aria-valuenow="100 * queueJobBatch.irModel.completeness"
/>
<div
class="progress-bar o_queue_job_failed_progressbar"
role="progressbar"
t-att-style="'width: '+ (100 * queueJobBatch.irModel.failed_percentage) + '%'"
t-att-aria-valuenow="100 * queueJobBatch.irModel.failed_percentage"
/>
</div>
<span
t-out="queueJobBatch.irModel.finished_job_count + '/' + queueJobBatch.irModel.failed_job_count + '/' + queueJobBatch.irModel.job_count"
/>
</div>
<div
class="col-1 mt-3"
t-on-click="queueJobBatch._hideJobBatch"
>
<span
title="Mark as Read"
class="fa fa-check"
t-if="queueJobBatch.irModel.state === 'finished'"
t-att-data-job-batch-id="queueJobBatch.irModel.id"
/>
</div>
</t>
</div>
</div>
</div>
</t>
</templates>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates xml:space="preserve">
<t t-name="queue_job_batch.QueueJobBatchMenuContainer" owl="1">
<t t-if="queueJobBatchMenuView">
<QueueJobBatchMenuView record="queueJobBatchMenuView" />
</t>
</t>
</templates>