Введение
В статье я постараюсь описать создание модуля для Odoo который позволит внедрить страницу iframe и пункт меню к нему. С данной задачей я столкнулся, когда меня попросили встраиваить мониторинг на базе Grafana, в стандартный интерфейс Odoo
Я много лазил по интернету но приемлемое решение я нашел только в одном стороннем модуле, и чтобы его не потерять решил завиксировать это здесь.
Реализация модуля
Для начала создадим модуль со следующей структурой (базовой для Odoo):
grafana_monitoring/
├── __init__.py
├── __manifest__.py
├── data
│ └── init.xml
├── models
│ ├── __init__.py
│ ├── monitoring.py
├── static
│ └── src
│ └── js
│ └── grafana.js
└── views
└── view.xml
Модуль будет писаться под Odoo 10.
Создание модели
В файле monitoring.py
создадим модель, которая будет хранить ip адрес и порт сервера мониторинга:
# -*- coding: utf-8 -*-
from odoo import models, fields, api
class Grafana(models.Model):
"""
Модель мониторинга
"""
_name = "monitoring.grafana"
server = fields.Char("Адрес сервера")
port = fields.Char("Порт")
@api.model
def get_grafana_url(self):
"""
Получает url сервера grafana для вставки в iframe
:return:
"""
record = self.browse(1)
return "http://{}:{}".format(record.server, record.port)
В данной моделе также содержится метод get_grafana_url
, который формирует полный url сервера. Также можно заметить что тут всегда берется запись c id = 1, так как в моем случае сервер один и очень универсальный код тут будет лишним.
Инициализация модели
Далее в файл init.xml
я добавил запись с сервером и портом (она как раз будет иметь id=1):
<odoo>
<data>
<record id="monitoring_grafana_1" model="monitoring.grafana">
<field name="server">localhost</field>
<field name="port">3000</field>
</record>
</data>
</odoo>
Создание js виджета
Теперь можно перейти к реализации виджета, который будет отвечать за отображение iframe в интерфейсе. Он будет содержаться в файле grafana.js
:
odoo.define('grafana', function (require) {
'use strict';
var core = require('web.core');
var Widget = require('web.Widget');
var Model = require('web.Model');
/* Full user interface widget. */
var HomePage = Widget.extend({
start: function () {
var el = this.$el;
el.height("calc(100% - 34px)");
var model = new Model("monitoring.grafana");
model.call("get_grafana_url")
.then(function (result) {
el.append(
'<iframe src="' + result + '" width="100%" height="100%" marginwidth="0" ' +
'marginheight="0" frameborder="no" scrolling="yes" style="border-width:0px;"/>'
);
});
}
});
core.action_registry.add('grafana.homepage', HomePage);
});
Описанный код работает с версией Odoo 10, так как в 11 версии js api изменилось, но модифицировать этот код под него задача не очень трудная.
Настройка представлений отображения
После того как все приготовления сделаны, нужно описать отображение в интерфейсе нашего модуля (view.xml
):
<odoo>
<data>
<!-- Вкладка в верхнем меню -->
<menuitem name="Мониторинг" id="grafana_monitoring_root_menu" sequence="250"/>
<!-- Раздел бокового меню -->
<menuitem name="Дашборды" id="grafana_monitoring_menu" parent="grafana_monitoring_root_menu"/>
<!-- Подключаем js файл с нашим виджетом -->
<template id="assets_backend" name="grafana_assets" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<script type="text/javascript" src="/grafana_monitoring/static/src/js/grafana.js"/>
</xpath>
</template>
<!-- назначаем действие которое будет вызывать js виджет -->
<record id="grafana_monitoring_action_window" model="ir.actions.client">
<field name="name">Grafana home page</field>
<field name="tag">grafana.homepage</field>
</record>
<!-- добавляем пункт меню и привязывем к действию вызова виджета -->
<menuitem name="Grafana" id="grafana_monitoring_grafana_menu" parent="grafana_monitoring_menu"
action="grafana_monitoring_grafana_action_window"/>
<!-- отрисоваем отображение настройки сервера-->
<record id="grafana_monitoring_setting_tree" model="ir.ui.view">
<field name="name">monitoring.grafana.tree</field>
<field name="model">monitoring.grafana</field>
<field name="arch" type="xml">
<tree string="Grafana server" editable="top" create="false">
<field name="server"/>
<field name="port"/>
</tree>
</field>
</record>
<!-- заводим для настройки сервера отдельный пункт меню в администрировании -->
<record model="ir.actions.act_window" id="grafana_monitoring_setting_action_window">
<field name="name">Grafana</field>
<field name="res_model">monitoring.grafana</field>
<field name="view_mode">tree</field>
</record>
<menuitem id="menu_monitoring" name="Мониторинг" parent="base.menu_administration" sequence="100"
groups="base.group_user"/>
<menuitem id="menu_grafana_cfg" name="Grafana" parent="menu_monitoring" sequence="1"
action="grafana_monitoring_setting_action_window"/>
</data>
</odoo>
Описание всех разделов представления обозначены в комментариях к коду. Если в кратце, то мы создаем пункт меню для вызова нашего js виджета, и пункт меню для редактирования модели с настройками сервера.
Заключение
В результе после установки модуль будет выглядеть приблизительно так:
В целом полученный результат меня вполне устроил, хотя можно было бы сделать некоторые вещи более оптимально.
comments powered by Disqus